|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: #include <mach/std_types.h> ! 23: #include <ppc/proc_reg.h> ! 24: #include <ppc/boot.h> ! 25: #include <ppc/mem.h> ! 26: ! 27: #ifdef XXX_LOADER ! 28: unsigned int kernel_seg_regs[] = { ! 29: KERNEL_SEG_REG0_VALUE, ! 30: KERNEL_SEG_REG1_VALUE, ! 31: SEG_REG_INVALID, /* 2 */ ! 32: SEG_REG_INVALID, /* 3 */ ! 33: SEG_REG_INVALID, /* 4 */ ! 34: KERNEL_SEG_REG5_VALUE, /* 5 - I/O segment */ ! 35: SEG_REG_INVALID, /* 6 */ ! 36: SEG_REG_INVALID, /* 7 */ ! 37: KERNEL_SEG_REG8_VALUE, /* 8-F are possible IO space */ ! 38: KERNEL_SEG_REG9_VALUE, ! 39: KERNEL_SEG_REG10_VALUE, ! 40: KERNEL_SEG_REG11_VALUE, ! 41: KERNEL_SEG_REG12_VALUE, ! 42: KERNEL_SEG_REG13_VALUE, ! 43: KERNEL_SEG_REG14_VALUE, /* 14 - A/V video */ ! 44: KERNEL_SEG_REG15_VALUE /* 15 - NuBus etc */ ! 45: }; ! 46: #else ! 47: extern unsigned int kernel_seg_regs[]; ! 48: #endif ! 49: ! 50: // The sophisticated BAT manager ! 51: ! 52: unsigned int mappedSegments = 0; ! 53: unsigned int availableBATs = 0xE; // BAT0 used, 1-3 available ! 54: ! 55: vm_offset_t ! 56: PEResidentAddress( vm_offset_t address, vm_size_t length ) ! 57: { ! 58: if( mappedSegments & (1 << (15 & (address >> 28)))) ! 59: return( address); ! 60: else ! 61: return( 0); ! 62: } ! 63: ! 64: vm_offset_t ! 65: PEMapSegment( vm_offset_t address, vm_size_t length ) ! 66: { ! 67: vm_offset_t retAddress; ! 68: bat_t bat; ! 69: int batNum; ! 70: ! 71: retAddress = PEResidentAddress( address, length ); ! 72: if( retAddress) ! 73: return( retAddress); ! 74: ! 75: if( length < (256 * 1024)) ! 76: return( 0); ! 77: if( availableBATs == 0) ! 78: return( 0); ! 79: ! 80: for( batNum = 0; ! 81: (0 == (availableBATs & (1 << batNum))); ! 82: batNum++); ! 83: ! 84: bat.upper.word = address & 0xf0000000; ! 85: bat.lower.word = bat.upper.word; ! 86: ! 87: bat.upper.bits.bl = 0x7ff; /* size = 256M */ ! 88: bat.upper.bits.vs = 1; ! 89: bat.upper.bits.vp = 0; /* user disabled */ ! 90: ! 91: bat.lower.bits.wimg = PTE_WIMG_IO; ! 92: bat.lower.bits.pp = 2; /* read/write access */ ! 93: ! 94: // Update the shadow bats. ! 95: shadow_BAT.DBATs[batNum].upper = bat.upper.word; ! 96: shadow_BAT.DBATs[batNum].lower = bat.lower.word; ! 97: ! 98: sync();isync(); ! 99: switch( batNum) { // !%$@!! mtdbat needs literal ! 100: case 0: ! 101: mtdbatu( 0, BAT_INVALID); /* invalidate old mapping */ ! 102: mtdbatl( 0, bat.lower.word); ! 103: mtdbatu( 0, bat.upper.word); ! 104: break; ! 105: case 1: ! 106: mtdbatu( 1, BAT_INVALID); ! 107: mtdbatl( 1, bat.lower.word); ! 108: mtdbatu( 1, bat.upper.word); ! 109: break; ! 110: case 2: ! 111: mtdbatu( 2, BAT_INVALID); ! 112: mtdbatl( 2, bat.lower.word); ! 113: mtdbatu( 2, bat.upper.word); ! 114: break; ! 115: case 3: ! 116: mtdbatu( 3, BAT_INVALID); ! 117: mtdbatl( 3, bat.lower.word); ! 118: mtdbatu( 3, bat.upper.word); ! 119: break; ! 120: } ! 121: sync();isync(); ! 122: ! 123: availableBATs &= ~(1 << batNum); ! 124: mappedSegments |= (1 << (15 & (address >> 28))); ! 125: ! 126: return( address); ! 127: } ! 128: ! 129: void initialize_bats(boot_args *args) ! 130: { ! 131: int i; ! 132: ! 133: /* Give ourselves the virtual map that we would like */ ! 134: bat_t bat; ! 135: ! 136: /* Make sure that the BATs map what we expect. Note ! 137: * that we assume BAT0 maps kernel text & data. ! 138: * ! 139: * Except, oops, none of the BATs have ever been set. ! 140: * Developer worked only by fluke. ! 141: */ ! 142: ! 143: bat.upper.word = 0; ! 144: bat.upper.bits.bepi = 0x0; /* start at logical addr 0M */ ! 145: /* ! 146: * We should be smarter here about picking an ! 147: * amount to map ! 148: */ ! 149: bat.upper.bits.bl = 0x7ff; /* size = 256M */ ! 150: bat.upper.bits.vs = 1; ! 151: bat.upper.bits.vp = 0; ! 152: ! 153: bat.lower.word = 0; ! 154: bat.lower.bits.brpn = 0x0; /* start at physical addr 0 */ ! 155: bat.lower.bits.wimg = PTE_WIMG_DEFAULT; ! 156: bat.lower.bits.pp = 2; /* read/write access */ ! 157: ! 158: /* Mustn't cause any data traffic here, ! 159: * we're modifying our data BAT register! ! 160: */ ! 161: ! 162: sync(); ! 163: mtdbatu(0, BAT_INVALID); /* invalidate old mapping */ ! 164: isync(); ! 165: mtdbatl(0, bat.lower.word); ! 166: isync(); ! 167: mtdbatu(0, bat.upper.word); /* update with new mapping */ ! 168: isync(); ! 169: mtibatl(0, bat.lower.word); ! 170: isync(); ! 171: mtibatu(0, bat.upper.word); /* update with new mapping */ ! 172: isync(); ! 173: ! 174: sync();isync(); ! 175: mtdbatu(1,BAT_INVALID); mtdbatl(1,BAT_INVALID); ! 176: mtibatu(1,BAT_INVALID); mtibatl(1,BAT_INVALID); ! 177: mtdbatu(2,BAT_INVALID); mtdbatl(2,BAT_INVALID); ! 178: mtibatu(2,BAT_INVALID); mtibatl(2,BAT_INVALID); ! 179: mtdbatu(3,BAT_INVALID); mtdbatl(3,BAT_INVALID); ! 180: mtibatu(3,BAT_INVALID); mtibatl(3,BAT_INVALID); ! 181: sync();isync(); ! 182: ! 183: PEMapSegment( 0xf0000000, 0x10000000); ! 184: if( args->Video.v_baseAddr) ! 185: PEMapSegment( args->Video.v_baseAddr, 0x10000000); ! 186: ! 187: /* Set up segment registers as VM through space 0 */ ! 188: isync(); ! 189: for (i=0; i<=15; i++) { ! 190: mtsrin(KERNEL_SEG_REG0_VALUE | i, i * 0x10000000); ! 191: } ! 192: isync(); ! 193: } ! 194: ! 195: /* ! 196: * Adjust the size of the region mapped by a BAT ! 197: * to to be just large enough to include the specified ! 198: * offset, and return the offset of the new end of the region. ! 199: * Note that both 'offsets' are really *lengths*, i.e. the ! 200: * offset of the end of the mapped region from the beginning. ! 201: * Either the instruction or data BATs (or both) can be specified. ! 202: * If the new length is greater than the size mappable by a BAT, ! 203: * then that value is just returned and no changes are made. ! 204: */ ! 205: vm_offset_t ! 206: adjust_bat_limit( ! 207: vm_offset_t new_minimum, ! 208: int batn, ! 209: boolean_t ibat, ! 210: boolean_t dbat ! 211: ) ! 212: { ! 213: vm_offset_t new_limit; ! 214: ! 215: if (new_minimum <= 256*1024*1024) { ! 216: unsigned int bl = 0; ! 217: ! 218: new_limit = 128*1024; ! 219: while (new_limit < new_minimum) { ! 220: new_limit *= 2; ! 221: bl = (bl << 1) | 1; ! 222: } ! 223: ! 224: { ! 225: batu_t batu; ! 226: ! 227: if (dbat) switch (batn) { ! 228: ! 229: case 0: ! 230: mfdbatu(batu, 0 ); ! 231: batu.bits.bl = bl; ! 232: ! 233: sync(); isync(); ! 234: mtdbatu( 0, batu); ! 235: sync(); isync(); ! 236: ! 237: break; ! 238: ! 239: case 1: ! 240: mfdbatu(batu, 1 ); ! 241: batu.bits.bl = bl; ! 242: ! 243: sync(); isync(); ! 244: mtdbatu( 1, batu); ! 245: sync(); isync(); ! 246: ! 247: break; ! 248: ! 249: case 2: ! 250: mfdbatu(batu, 2 ); ! 251: batu.bits.bl = bl; ! 252: ! 253: sync(); isync(); ! 254: mtdbatu( 2, batu); ! 255: sync(); isync(); ! 256: ! 257: break; ! 258: ! 259: case 3: ! 260: mfdbatu(batu, 3 ); ! 261: batu.bits.bl = bl; ! 262: ! 263: sync(); isync(); ! 264: mtdbatu( 3, batu); ! 265: sync(); isync(); ! 266: ! 267: break; ! 268: } ! 269: ! 270: if (ibat) switch (batn) { ! 271: ! 272: case 0: ! 273: mfibatu(batu, 0 ); ! 274: batu.bits.bl = bl; ! 275: ! 276: sync(); isync(); ! 277: mtibatu( 0, batu); ! 278: sync(); isync(); ! 279: ! 280: break; ! 281: ! 282: case 1: ! 283: mfibatu(batu, 1 ); ! 284: batu.bits.bl = bl; ! 285: ! 286: sync(); isync(); ! 287: mtibatu( 1, batu); ! 288: sync(); isync(); ! 289: ! 290: break; ! 291: ! 292: case 2: ! 293: mfibatu(batu, 2 ); ! 294: batu.bits.bl = bl; ! 295: ! 296: sync(); isync(); ! 297: mtibatu( 2, batu); ! 298: sync(); isync(); ! 299: ! 300: break; ! 301: ! 302: case 3: ! 303: mfibatu(batu, 3 ); ! 304: batu.bits.bl = bl; ! 305: ! 306: sync(); isync(); ! 307: mtibatu( 3, batu); ! 308: sync(); isync(); ! 309: ! 310: break; ! 311: } ! 312: } ! 313: } ! 314: else ! 315: new_limit = new_minimum; ! 316: ! 317: return (new_limit); ! 318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.