|
|
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: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * @APPLE_FREE_COPYRIGHT@ ! 27: */ ! 28: ! 29: #include <mach_debug.h> ! 30: #include <mach_kdb.h> ! 31: #include <mach_kdp.h> ! 32: #include <debug.h> ! 33: #include <cpus.h> ! 34: ! 35: #include <mach/vm_types.h> ! 36: #include <mach/vm_param.h> ! 37: #include <mach/thread_status.h> ! 38: #include <kern/misc_protos.h> ! 39: #include <kern/assert.h> ! 40: #include <kern/cpu_number.h> ! 41: ! 42: #include <ppc/proc_reg.h> ! 43: #include <ppc/Firmware.h> ! 44: #include <ppc/boot.h> ! 45: #include <ppc/misc_protos.h> ! 46: #include <ppc/pmap.h> ! 47: #include <ppc/pmap_internals.h> ! 48: #include <ppc/mem.h> ! 49: #include <ppc/mappings.h> ! 50: #include <ppc/exception.h> ! 51: #include <ppc/mp.h> ! 52: ! 53: #ifdef __MACHO__ ! 54: #include <mach-o/mach_header.h> ! 55: #endif ! 56: ! 57: extern unsigned int intstack[]; /* declared in start.s */ ! 58: extern unsigned int intstack_top_ss; /* declared in start.s */ ! 59: ! 60: vm_offset_t mem_size; /* Size of actual physical memory present ! 61: minus any performance buffer and possibly limited ! 62: by mem_limit in bytes */ ! 63: vm_offset_t mem_actual; /* The "One True" physical memory size ! 64: actually, it's the highest physical address + 1 */ ! 65: ! 66: ! 67: mem_region_t pmap_mem_regions[PMAP_MEM_REGION_MAX]; ! 68: int pmap_mem_regions_count = 0; /* No non-contiguous memory regions */ ! 69: ! 70: mem_region_t free_regions[FREE_REGION_MAX]; ! 71: int free_regions_count; ! 72: ! 73: #ifndef __MACHO__ ! 74: extern unsigned long etext; ! 75: #endif ! 76: ! 77: unsigned int avail_remaining = 0; ! 78: vm_offset_t first_avail; ! 79: vm_offset_t static_memory_end; ! 80: extern vm_offset_t avail_next; ! 81: ! 82: #ifdef __MACHO__ ! 83: extern struct mach_header _mh_execute_header; ! 84: vm_offset_t sectTEXTB; ! 85: int sectSizeTEXT; ! 86: vm_offset_t sectDATAB; ! 87: int sectSizeDATA; ! 88: vm_offset_t sectOBJCB; ! 89: int sectSizeOBJC; ! 90: vm_offset_t sectLINKB; ! 91: int sectSizeLINK; ! 92: ! 93: vm_offset_t end, etext, edata; ! 94: #endif ! 95: ! 96: extern unsigned long exception_entry; ! 97: extern unsigned long exception_end; ! 98: ! 99: ! 100: void ppc_vm_init(unsigned int mem_limit, boot_args *args) ! 101: { ! 102: unsigned int htabmask; ! 103: unsigned int i, j, batsize, kmapsize; ! 104: vm_offset_t addr; ! 105: int boot_task_end_offset; ! 106: const char *cpus; ! 107: mapping *mp; ! 108: vm_offset_t first_phys_avail; ! 109: vm_offset_t sizeadj, oldstart; ! 110: ! 111: #ifdef __MACHO__ ! 112: /* Now retrieve addresses for end, edata, and etext ! 113: * from MACH-O headers. ! 114: */ ! 115: sectTEXTB = (vm_offset_t)getsegdatafromheader( ! 116: &_mh_execute_header, "__TEXT", §SizeTEXT); ! 117: sectDATAB = (vm_offset_t)getsegdatafromheader( ! 118: &_mh_execute_header, "__DATA", §SizeDATA); ! 119: sectOBJCB = (vm_offset_t)getsegdatafromheader( ! 120: &_mh_execute_header, "__OBJC", §SizeOBJC); ! 121: sectLINKB = (vm_offset_t)getsegdatafromheader( ! 122: &_mh_execute_header, "__LINKEDIT", §SizeLINK); ! 123: ! 124: etext = (vm_offset_t) sectTEXTB + sectSizeTEXT; ! 125: edata = (vm_offset_t) sectDATAB + sectSizeDATA; ! 126: end = getlastaddr(); ! 127: #if DEBUG ! 128: printf("sectTEXT: %x, size: %x\n", sectTEXTB, sectSizeTEXT); ! 129: printf("sectDATA: %x, size: %x\n", sectDATAB, sectSizeDATA); ! 130: printf("sectOBJC: %x, size: %x\n", sectOBJCB, sectSizeOBJC); ! 131: printf("sectLINK: %x, size: %x\n", sectLINKB, sectSizeLINK); ! 132: printf("end: %x\n", end); ! 133: #endif ! 134: #endif /* __MACHO__ */ ! 135: ! 136: /* Stitch valid memory regions together - they may be contiguous ! 137: * even though they're not already glued together ! 138: */ ! 139: mem_actual = mem_actual = args->PhysicalDRAM[0].base + args->PhysicalDRAM[0].size; /* Initialize to the first region size */ ! 140: addr = 0; /* temp use as pointer to previous memory region... */ ! 141: for (i = 1; i < kMaxDRAMBanks; i++) { ! 142: ! 143: if (args->PhysicalDRAM[i].size == 0) continue; /* If region is empty, skip it */ ! 144: ! 145: if((args->PhysicalDRAM[i].base + args->PhysicalDRAM[i].size) > mem_actual) { /* New high? */ ! 146: mem_actual = args->PhysicalDRAM[i].base + args->PhysicalDRAM[i].size; /* Take the high bid */ ! 147: } ! 148: ! 149: if (args->PhysicalDRAM[i].base == /* Does the end of the last hit the start of the next? */ ! 150: args->PhysicalDRAM[addr].base + ! 151: args->PhysicalDRAM[addr].size) { ! 152: printf("region 0x%08x size 0x%08x joining region 0x%08x size 0x%08x\n", ! 153: args->PhysicalDRAM[addr].base, args->PhysicalDRAM[addr].size, ! 154: args->PhysicalDRAM[i].base, args->PhysicalDRAM[i].size); ! 155: ! 156: args->PhysicalDRAM[addr].size += args->PhysicalDRAM[i].size; /* Join them */ ! 157: args->PhysicalDRAM[i].size = 0; ! 158: continue; ! 159: } ! 160: /* This is now last non-zero region to compare against */ ! 161: addr = i; ! 162: } ! 163: ! 164: /* Go through the list of memory regions passed in via the args ! 165: * and copy valid entries into the pmap_mem_regions table, adding ! 166: * further calculated entries. ! 167: */ ! 168: ! 169: pmap_mem_regions_count = 0; ! 170: mem_size = 0; /* Will use to total memory found so far */ ! 171: ! 172: for (i = 0; i < kMaxDRAMBanks; i++) { ! 173: if (args->PhysicalDRAM[i].size == 0) ! 174: continue; ! 175: ! 176: /* The following should only happen if memory size has ! 177: been artificially reduced with -m */ ! 178: if (mem_limit > 0 && ! 179: mem_size + args->PhysicalDRAM[i].size > mem_limit) ! 180: args->PhysicalDRAM[i].size = mem_limit - mem_size; ! 181: ! 182: /* We've found a region, tally memory */ ! 183: ! 184: pmap_mem_regions[pmap_mem_regions_count].start = ! 185: args->PhysicalDRAM[i].base; ! 186: pmap_mem_regions[pmap_mem_regions_count].end = ! 187: args->PhysicalDRAM[i].base + ! 188: args->PhysicalDRAM[i].size; ! 189: ! 190: /* Regions must be provided in ascending order */ ! 191: assert ((pmap_mem_regions_count == 0) || ! 192: pmap_mem_regions[pmap_mem_regions_count].start > ! 193: pmap_mem_regions[pmap_mem_regions_count-1].start); ! 194: ! 195: if (pmap_mem_regions_count > 0) { ! 196: /* we add on any pages not in the first memory ! 197: * region to the avail_remaining count. The first ! 198: * memory region is used for mapping everything for ! 199: * bootup and is taken care of specially. ! 200: */ ! 201: avail_remaining += ! 202: args->PhysicalDRAM[i].size / PPC_PGBYTES; ! 203: } ! 204: ! 205: /* Keep track of how much memory we've found */ ! 206: ! 207: mem_size += args->PhysicalDRAM[i].size; ! 208: ! 209: /* incremement number of regions found */ ! 210: pmap_mem_regions_count++; ! 211: } ! 212: ! 213: printf("mem_size: %d M\n",mem_size / (1024 * 1024)); ! 214: ! 215: /* ! 216: * Initialize the pmap system, using space above `first_avail' ! 217: * for the necessary data structures. ! 218: * NOTE : assume that we'll have enough space mapped in already ! 219: */ ! 220: ! 221: first_phys_avail = static_memory_end; ! 222: first_avail = adjust_bat_limit(first_phys_avail, 0, FALSE, FALSE); ! 223: ! 224: kmapsize = (round_page(exception_end) - trunc_page(exception_entry)) + /* Get size we will map later */ ! 225: (round_page(sectTEXTB+sectSizeTEXT) - trunc_page(sectTEXTB)) + ! 226: (round_page(sectDATAB+sectSizeDATA) - trunc_page(sectDATAB)) + ! 227: (round_page(sectOBJCB+sectSizeOBJC) - trunc_page(sectOBJCB)) + ! 228: (round_page(sectLINKB+sectSizeLINK) - trunc_page(sectLINKB)) + ! 229: (round_page(static_memory_end) - trunc_page(end)); ! 230: ! 231: pmap_bootstrap(mem_size,&first_avail,&first_phys_avail, kmapsize); ! 232: ! 233: #ifdef __MACHO__ ! 234: #if DEBUG ! 235: printf("Mapping memory:\n"); ! 236: printf(" exception vector: %08X, %08X - %08X\n", trunc_page(exception_entry), ! 237: trunc_page(exception_entry), round_page(exception_end)); ! 238: printf(" sectTEXTB: %08X, %08X - %08X\n", trunc_page(sectTEXTB), ! 239: trunc_page(sectTEXTB), round_page(sectTEXTB+sectSizeTEXT)); ! 240: printf(" sectDATAB: %08X, %08X - %08X\n", trunc_page(sectDATAB), ! 241: trunc_page(sectDATAB), round_page(sectDATAB+sectSizeDATA)); ! 242: printf(" sectOBJCB: %08X, %08X - %08X\n", trunc_page(sectOBJCB), ! 243: trunc_page(sectOBJCB), round_page(sectOBJCB+sectSizeOBJC)); ! 244: printf(" sectLINKB: %08X, %08X - %08X\n", trunc_page(sectLINKB), ! 245: trunc_page(sectLINKB), round_page(sectLINKB+sectSizeLINK)); ! 246: printf(" end: %08X, %08X - %08X\n", trunc_page(end), ! 247: trunc_page(end), static_memory_end); ! 248: #endif /* DEBUG */ ! 249: pmap_map(trunc_page(exception_entry), trunc_page(exception_entry), ! 250: round_page(exception_end), VM_PROT_READ|VM_PROT_EXECUTE); ! 251: pmap_map(trunc_page(sectTEXTB), trunc_page(sectTEXTB), ! 252: round_page(sectTEXTB+sectSizeTEXT), VM_PROT_READ|VM_PROT_EXECUTE); ! 253: pmap_map(trunc_page(sectDATAB), trunc_page(sectDATAB), ! 254: round_page(sectDATAB+sectSizeDATA), VM_PROT_READ|VM_PROT_WRITE); ! 255: pmap_map(trunc_page(sectOBJCB), trunc_page(sectOBJCB), ! 256: round_page(sectOBJCB+sectSizeOBJC), VM_PROT_READ|VM_PROT_WRITE); ! 257: pmap_map(trunc_page(sectLINKB), trunc_page(sectLINKB), ! 258: round_page(sectLINKB+sectSizeLINK), VM_PROT_READ|VM_PROT_WRITE); ! 259: pmap_map(trunc_page(end), trunc_page(end), ! 260: round_page(static_memory_end), VM_PROT_READ|VM_PROT_WRITE); ! 261: #endif /* __MACHO__ */ ! 262: ! 263: #if DEBUG ! 264: for (i=0 ; i < free_regions_count; i++) { ! 265: printf("Free region start 0x%08x end 0x%08x\n", ! 266: free_regions[i].start,free_regions[i].end); ! 267: } ! 268: #endif ! 269: ! 270: /* Initialize shadow IBATs */ ! 271: shadow_BAT.IBATs[0].upper=BAT_INVALID; ! 272: shadow_BAT.IBATs[0].lower=BAT_INVALID; ! 273: shadow_BAT.IBATs[1].upper=BAT_INVALID; ! 274: shadow_BAT.IBATs[1].lower=BAT_INVALID; ! 275: shadow_BAT.IBATs[2].upper=BAT_INVALID; ! 276: shadow_BAT.IBATs[2].lower=BAT_INVALID; ! 277: shadow_BAT.IBATs[3].upper=BAT_INVALID; ! 278: shadow_BAT.IBATs[3].lower=BAT_INVALID; ! 279: ! 280: LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]); /* Load up real IBATs from shadows */ ! 281: ! 282: /* Initialize shadow DBATs */ ! 283: shadow_BAT.DBATs[0].upper=BAT_INVALID; ! 284: shadow_BAT.DBATs[0].lower=BAT_INVALID; ! 285: shadow_BAT.DBATs[1].upper=BAT_INVALID; ! 286: shadow_BAT.DBATs[1].lower=BAT_INVALID; ! 287: mfdbatu(shadow_BAT.DBATs[2].upper,2); ! 288: mfdbatl(shadow_BAT.DBATs[2].lower,2); ! 289: mfdbatu(shadow_BAT.DBATs[3].upper,3); ! 290: mfdbatl(shadow_BAT.DBATs[3].lower,3); ! 291: ! 292: LoadDBATs((unsigned int *)&shadow_BAT.DBATs[0]); /* Load up real DBATs from shadows */ ! 293: ! 294: sync();isync(); ! 295: #if DEBUG ! 296: for(i=0; i<4; i++) printf("DBAT%1d: %08X %08X\n", ! 297: i, shadow_BAT.DBATs[i].upper, shadow_BAT.DBATs[i].lower); ! 298: for(i=0; i<4; i++) printf("IBAT%1d: %08X %08X\n", ! 299: i, shadow_BAT.IBATs[i].upper, shadow_BAT.IBATs[i].lower); ! 300: #endif ! 301: } ! 302: ! 303: void ppc_vm_cpu_init( ! 304: struct per_proc_info *proc_info) ! 305: { ! 306: hash_table_init(hash_table_base, hash_table_size); ! 307: ! 308: LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]); ! 309: LoadDBATs((unsigned int *)&shadow_BAT.DBATs[0]); ! 310: ! 311: sync();isync(); ! 312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.