|
|
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: ! 24: #include <mach/vm_types.h> ! 25: #include <mach/vm_param.h> ! 26: #include <mach/thread_status.h> ! 27: #include <kern/misc_protos.h> ! 28: #include <kern/assert.h> ! 29: #include <kern/cpu_number.h> ! 30: ! 31: #include <ppc/proc_reg.h> ! 32: #include <ppc/boot.h> ! 33: #include <ppc/misc_protos.h> ! 34: #include <ppc/pmap.h> ! 35: #include <ppc/pmap_internals.h> ! 36: #include <ppc/mem.h> ! 37: #include <ppc/exception.h> ! 38: #include <ppc/gdb_defs.h> ! 39: #include <ppc/POWERMAC/video_board.h> ! 40: #include <ppc/POWERMAC/video_pdm.h> ! 41: ! 42: #ifdef __MACHO__ ! 43: #include <mach-o/mach_header.h> ! 44: #endif ! 45: ! 46: /* External references */ ! 47: ! 48: extern unsigned int intstack[]; /* declared in start.s */ ! 49: extern unsigned int intstack_top_ss; /* declared in start.s */ ! 50: #if MACH_KGDB ! 51: extern unsigned int gdbstackptr; /* declared in start.s */ ! 52: extern unsigned int gdbstack_top_ss; /* declared in start.s */ ! 53: #endif /* MACH_KGDB */ ! 54: ! 55: /* Stuff declared in kern/bootstrap.c which we may need to initialise */ ! 56: ! 57: extern vm_offset_t boot_start; ! 58: extern vm_size_t boot_size; ! 59: extern vm_offset_t boot_region_desc; ! 60: extern vm_size_t boot_region_count; ! 61: extern int boot_thread_state_flavor; ! 62: extern thread_state_t boot_thread_state; ! 63: extern unsigned int boot_thread_state_count; ! 64: ! 65: /* Trap handling function prototypes */ ! 66: ! 67: extern void thandler(void); /* trap handler */ ! 68: extern void ihandler(void); /* interrupt handler */ ! 69: extern void shandler(void); /* syscall handler */ ! 70: extern void gdbhandler(void); /* debugger handler */ ! 71: extern void fpu_switch(void); /* fp handler */ ! 72: extern void atomic_switch_trap(void); /* fast path atomic thread switch */ ! 73: ! 74: /* definitions */ ! 75: ! 76: struct ppc_thread_state boot_task_thread_state; ! 77: ! 78: ! 79: ! 80: ! 81: ! 82: #if 1 /* TODO NMGS - vm_map_steal_memory shouldn't use these - remove */ ! 83: vm_offset_t avail_start; ! 84: vm_offset_t avail_end; ! 85: #endif ! 86: unsigned int avail_remaining = 0; ! 87: vm_offset_t first_avail; ! 88: ! 89: /* ! 90: * Mach-O Support ! 91: */ ! 92: ! 93: ! 94: #ifdef __MACHO__ ! 95: extern struct mach_header _mh_execute_header; ! 96: void *sectTEXTB; ! 97: int sectSizeTEXT; ! 98: void *sectDATAB; ! 99: int sectSizeDATA; ! 100: void *sectOBJCB; ! 101: int sectSizeOBJC; ! 102: void *sectLINKB; ! 103: int sectSizeLINK; ! 104: ! 105: vm_offset_t end, etext, edata; ! 106: #define ETEXT etext ! 107: #endif ! 108: ! 109: ! 110: ! 111: void ppc_vm_init(unsigned int memory_size, boot_args *args) ! 112: { ! 113: unsigned int htabmask; ! 114: unsigned int i; ! 115: vm_offset_t addr; ! 116: int boot_task_end_offset; ! 117: #if NCPUS > 1 ! 118: const char *cpus; ! 119: #endif /* NCPUS > 1 */ ! 120: ! 121: printf("mem_size = %d M\n",memory_size / (1024 * 1024)); ! 122: ! 123: #ifdef __MACHO__ ! 124: /* Now retrieve addresses for end, edata, and etext ! 125: * from MACH-O headers. ! 126: */ ! 127: ! 128: ! 129: etext = (vm_offset_t) sectTEXTB + sectSizeTEXT; ! 130: edata = (vm_offset_t) sectDATAB + sectSizeDATA; ! 131: end = getlastaddr(); ! 132: #endif ! 133: ! 134: /* Stitch valid memory regions together - they may be contiguous ! 135: * even though they're not already glued together ! 136: */ ! 137: ! 138: /* Go through the list of memory regions passed in via the args ! 139: * and copy valid entries into the pmap_mem_regions table, adding ! 140: * further calculated entries. ! 141: */ ! 142: ! 143: ! 144: /* Initialise the pmap system, using space above `first_avail'*/ ! 145: ! 146: #ifndef __MACHO__ ! 147: free_regions[free_regions_count].start = ! 148: round_page((unsigned int)&_ExceptionVectorsEnd - ! 149: (unsigned int)&_ExceptionVectorsStart); ! 150: #else ! 151: /* On MACH-O generated kernels, the Exception Vectors ! 152: * are already mapped and loaded at 0 -- no relocation ! 153: * or freeing of memory is needed ! 154: */ ! 155: ! 156: free_regions[free_regions_count].start = round_page((unsigned int)&_ExceptionVectorsEnd) + 4096; ! 157: #endif ! 158: ! 159: /* If we are on a PDM machine memory at 1M might be used ! 160: * for video. TODO NMGS call video driver to do this ! 161: * somehow ! 162: */ ! 163: ! 164: ! 165: /* For PowerMac, first_avail is set to above the bootstrap task. ! 166: * TODO NMGS - different screen modes - might free mem? ! 167: */ ! 168: ! 169: first_avail = round_page(args->first_avail); ! 170: ! 171: ! 172: /* map in the exception vectors */ ! 173: /* ! 174: * map the kernel text, data and bss. Don't forget other regions too ! 175: */ ! 176: for (i = 0; i < args->kern_info.region_count; i++) { ! 177: #if MACH_KDB ! 178: if (args->kern_info.regions[i].prot == VM_PROT_NONE && ! 179: i == args->kern_info.region_count - 1) { ! 180: /* assume that's the kernel symbol table */ ! 181: kern_sym_start = args->kern_info.regions[i].addr; ! 182: kern_sym_size = args->kern_info.regions[i].size; ! 183: printf("kernel symbol table at 0x%x size 0x%x\n", ! 184: kern_sym_start, kern_sym_size); ! 185: args->kern_info.regions[i].prot |= ! 186: (VM_PROT_WRITE|VM_PROT_READ); ! 187: } ! 188: #endif /* MACH_KDB */ ! 189: ! 190: #ifdef __MACHO__ ! 191: /* Skip the VECTORS segment */ ! 192: if (args->kern_info.regions[i].addr == 0) ! 193: continue; ! 194: #endif ! 195: ! 196: boot_region_count = args->task_info.region_count; ! 197: boot_size = 0; ! 198: boot_task_end_offset = 0; ! 199: /* Map bootstrap task pages 1-1 so that user_bootstrap can find it */ ! 200: for (i = 0; i < boot_region_count; i++) { ! 201: if (args->task_info.regions[i].mapped) { ! 202: /* kernel requires everything page aligned */ ! 203: #if DEBUG ! 204: printf("mapping virt 0x%08x to phys 0x%08x end 0x%x, prot=0x%b\n", ! 205: ppc_trunc_page(args->task_info.base_addr + ! 206: args->task_info.regions[i].offset), ! 207: ppc_trunc_page(args->task_info.base_addr + ! 208: args->task_info.regions[i].offset), ! 209: ppc_round_page(args->task_info.base_addr + ! 210: args->task_info.regions[i].offset + ! 211: args->task_info.regions[i].size), ! 212: args->task_info.regions[i].prot, ! 213: "\x10\1READ\2WRITE\3EXEC"); ! 214: #endif /* DEBUG */ ! 215: ! 216: (void)pmap_map( ! 217: ppc_trunc_page(args->task_info.base_addr + ! 218: args->task_info.regions[i].offset), ! 219: ppc_trunc_page(args->task_info.base_addr + ! 220: args->task_info.regions[i].offset), ! 221: ppc_round_page(args->task_info.base_addr + ! 222: args->task_info.regions[i].offset + ! 223: args->task_info.regions[i].size), ! 224: args->task_info.regions[i].prot); ! 225: ! 226: /* Count the size of mapped space */ ! 227: boot_size += args->task_info.regions[i].size; ! 228: ! 229: /* There may be an overlapping physical page ! 230: * mapped to two different virtual addresses ! 231: */ ! 232: if (boot_task_end_offset > ! 233: args->task_info.regions[i].offset) { ! 234: boot_size -= boot_task_end_offset - ! 235: args->task_info.regions[i].offset; ! 236: #if DEBUG ! 237: printf("WARNING - bootstrap overlaps regions\n"); ! 238: #endif /* DEBUG */ ! 239: } ! 240: ! 241: boot_task_end_offset = ! 242: args->task_info.regions[i].offset + ! 243: args->task_info.regions[i].size; ! 244: } ! 245: } ! 246: ! 247: if (boot_region_count) { ! 248: ! 249: /* Add a new region to the bootstrap task for it's stack */ ! 250: args->task_info.regions[boot_region_count].addr = ! 251: BOOT_STACK_BASE; ! 252: args->task_info.regions[boot_region_count].size = ! 253: BOOT_STACK_SIZE; ! 254: args->task_info.regions[boot_region_count].mapped = FALSE; ! 255: boot_region_count++; ! 256: ! 257: boot_start = args->task_info.base_addr; ! 258: boot_region_desc = (vm_offset_t) args->task_info.regions; ! 259: /* TODO NMGS need to put param info onto top of boot stack */ ! 260: boot_task_thread_state.r1 = BOOT_STACK_PTR-0x100; ! 261: boot_task_thread_state.srr0 = args->task_info.entry; ! 262: boot_task_thread_state.srr1 = ! 263: MSR_MARK_SYSCALL(MSR_EXPORT_MASK_SET); ! 264: ! 265: boot_thread_state_flavor = PPC_THREAD_STATE; ! 266: boot_thread_state_count = PPC_THREAD_STATE_COUNT; ! 267: boot_thread_state = ! 268: (thread_state_t)&boot_task_thread_state; ! 269: } ! 270: ! 271: ! 272: ! 273: } ! 274:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.