|
|
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: #include <debug.h> ! 27: #include <mach_kdb.h> ! 28: #include <mach_kdp.h> ! 29: ! 30: #include <kern/misc_protos.h> ! 31: #include <kern/thread.h> ! 32: #include <kern/processor.h> ! 33: #include <machine/machine_routines.h> ! 34: #include <ppc/boot.h> ! 35: #include <ppc/proc_reg.h> ! 36: #include <ppc/misc_protos.h> ! 37: #include <ppc/pmap.h> ! 38: #include <ppc/new_screen.h> ! 39: #include <ppc/exception.h> ! 40: #include <ppc/Firmware.h> ! 41: #include <ppc/savearea.h> ! 42: ! 43: #include <pexpert/pexpert.h> ! 44: ! 45: extern const char version[]; ! 46: ! 47: extern unsigned int intstack_top_ss; /* declared in start.s */ ! 48: #if MACH_KDP || MACH_KDB ! 49: extern unsigned int debstackptr; /* declared in start.s */ ! 50: extern unsigned int debstack_top_ss; /* declared in start.s */ ! 51: #endif /* MACH_KDP || MACH_KDB */ ! 52: ! 53: unsigned int kernel_seg_regs[] = { ! 54: KERNEL_SEG_REG0_VALUE, /* 0 */ ! 55: KERNEL_SEG_REG0_VALUE + 1, /* 1 */ ! 56: KERNEL_SEG_REG0_VALUE + 2, /* 2 */ ! 57: SEG_REG_INVALID, /* 3 */ ! 58: SEG_REG_INVALID, /* 4 */ ! 59: KERNEL_SEG_REG5_VALUE, /* 5 - I/O segment */ ! 60: SEG_REG_INVALID, /* 6 */ ! 61: SEG_REG_INVALID, /* 7 */ ! 62: KERNEL_SEG_REG8_VALUE, /* 8-F are possible IO space */ ! 63: KERNEL_SEG_REG9_VALUE, ! 64: KERNEL_SEG_REG10_VALUE, ! 65: KERNEL_SEG_REG11_VALUE, ! 66: KERNEL_SEG_REG12_VALUE, ! 67: KERNEL_SEG_REG13_VALUE, ! 68: KERNEL_SEG_REG14_VALUE, /* 14 - A/V video */ ! 69: KERNEL_SEG_REG15_VALUE /* 15 - NuBus etc */ ! 70: }; ! 71: ! 72: extern void thandler(void); /* trap handler */ ! 73: extern void ihandler(void); /* interrupt handler */ ! 74: extern void shandler(void); /* syscall handler */ ! 75: extern void fpu_switch(void); /* fp handler */ ! 76: extern void vec_switch(void); /* vector handler */ ! 77: extern void atomic_switch_trap(void); /* fast path atomic thread switch */ ! 78: ! 79: void (*exception_handlers[])(void) = { ! 80: thandler, /* 0x000 INVALID EXCEPTION */ ! 81: thandler, /* 0x100 System reset */ ! 82: thandler, /* 0x200 Machine check */ ! 83: thandler, /* 0x300 Data access */ ! 84: thandler, /* 0x400 Instruction access */ ! 85: ihandler, /* 0x500 External interrupt */ ! 86: thandler, /* 0x600 Alignment */ ! 87: thandler, /* 0x700 fp exc, ill/priv instr, trap */ ! 88: fpu_switch, /* 0x800 Floating point disabled */ ! 89: ihandler, /* 0x900 Decrementer */ ! 90: thandler, /* 0xA00 I/O controller interface */ ! 91: thandler, /* 0xB00 INVALID EXCEPTION */ ! 92: shandler, /* 0xC00 System call exception */ ! 93: thandler, /* 0xD00 Trace */ ! 94: thandler, /* 0xE00 FP assist */ ! 95: thandler, /* 0xF00 Performance monitor */ ! 96: vec_switch, /* 0xF20 VMX */ ! 97: thandler, /* 0x1000 INVALID EXCEPTION */ ! 98: thandler, /* 0x1100 INVALID EXCEPTION */ ! 99: thandler, /* 0x1200 INVALID EXCEPTION */ ! 100: thandler, /* 0x1300 instruction breakpoint */ ! 101: thandler, /* 0x1400 system management */ ! 102: thandler, /* 0x1500 INVALID EXCEPTION */ ! 103: thandler, /* 0x1600 Altivec Assist */ ! 104: thandler, /* 0x1700 INVALID EXCEPTION */ ! 105: thandler, /* 0x1800 INVALID EXCEPTION */ ! 106: thandler, /* 0x1900 INVALID EXCEPTION */ ! 107: thandler, /* 0x1A00 INVALID EXCEPTION */ ! 108: thandler, /* 0x1B00 INVALID EXCEPTION */ ! 109: thandler, /* 0x1C00 INVALID EXCEPTION */ ! 110: thandler, /* 0x1D00 INVALID EXCEPTION */ ! 111: thandler, /* 0x1E00 INVALID EXCEPTION */ ! 112: thandler, /* 0x1F00 INVALID EXCEPTION */ ! 113: thandler, /* 0x2000 Run Mode/Trace */ ! 114: ihandler, /* 0x2100 Signal processor */ ! 115: thandler /* 0x2200 Preemption */ ! 116: }; ! 117: ! 118: /* ! 119: * per_proc_info is accessed with VM switched off via sprg0 ! 120: * Note that we always get enough space for an extra cache line. ! 121: * That is because for performance, we need to align the struct ! 122: * on a cache boundary. With the extra space, we can shift the ! 123: * array up to 31 bytes to align ! 124: */ ! 125: unsigned char per_proc_area[NCPUS*sizeof(struct per_proc_info)+32] = {0}; ! 126: struct per_proc_info *per_proc_info; ! 127: ! 128: void ppc_init(boot_args *args) ! 129: { ! 130: int i; ! 131: unsigned long *src,*dst; ! 132: char *str; ! 133: unsigned long addr, videoAddr; ! 134: unsigned int maxmem; ! 135: bat_t bat; ! 136: extern vm_offset_t static_memory_end; ! 137: ! 138: /* ! 139: * Setup per_proc info for first cpu. ! 140: */ ! 141: ! 142: /* First align the per_proc_info to a cache line */ ! 143: per_proc_info = (struct per_proc_info *)(((unsigned int) ! 144: (&per_proc_area[0])+31) ! 145: &(-32)); ! 146: per_proc_info[0].cpu_number = 0; ! 147: per_proc_info[0].cpu_flags = 0; ! 148: per_proc_info[0].istackptr = 0; /* we're on the interrupt stack */ ! 149: per_proc_info[0].intstack_top_ss = intstack_top_ss; ! 150: #if MACH_KDP || MACH_KDB ! 151: per_proc_info[0].debstackptr = debstackptr; ! 152: per_proc_info[0].debstack_top_ss = debstack_top_ss; ! 153: #endif /* MACH_KDP || MACH_KDB */ ! 154: per_proc_info[0].phys_exception_handlers = ! 155: (vm_offset_t)&exception_handlers; ! 156: per_proc_info[0].get_interrupts_enabled = ! 157: fake_get_interrupts_enabled; ! 158: per_proc_info[0].set_interrupts_enabled = ! 159: fake_set_interrupts_enabled; ! 160: per_proc_info[0].virt_per_proc_info = (unsigned int) ! 161: &per_proc_info[0]; ! 162: per_proc_info[0].active_kloaded = (unsigned int) ! 163: &active_kloaded[0]; ! 164: per_proc_info[0].cpu_data = (unsigned int) ! 165: &cpu_data[0]; ! 166: per_proc_info[0].active_stacks = (unsigned int) ! 167: &active_stacks[0]; ! 168: per_proc_info[0].need_ast = (unsigned int) ! 169: &need_ast[0]; ! 170: per_proc_info[0].FPU_thread = 0; ! 171: ! 172: machine_slot[0].is_cpu = TRUE; ! 173: ! 174: mtsprg(0, (unsigned int)&per_proc_info[0]); /* Point sprg 0 at it */ ! 175: ! 176: cpu_init(); ! 177: ! 178: /* ! 179: * Setup some processor related structures to satisfy funnels. ! 180: * Must be done before using unparallelized device drivers. ! 181: */ ! 182: processor_ptr[0] = &processor_array[0]; ! 183: master_cpu = 0; ! 184: master_processor = cpu_to_processor(master_cpu); ! 185: ! 186: /* Set up segment registers as VM through space 0 */ ! 187: for (i=0; i<=15; i++) { ! 188: isync(); ! 189: mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000); ! 190: sync(); ! 191: } ! 192: ! 193: static_memory_end = round_page(args->topOfKernelData);; ! 194: /* Get platform expert set up */ ! 195: PE_init_platform(FALSE, args); ! 196: ! 197: ! 198: /* This is how the BATs get configured */ ! 199: /* IBAT[0] maps Segment 0 1:1 */ ! 200: /* DBAT[0] maps Segment 0 1:1 */ ! 201: /* DBAT[2] maps the I/O Segment 1:1 */ ! 202: /* DBAT[3] maps the Video Segment 1:1 */ ! 203: ! 204: /* If v_baseAddr is non zero, use DBAT3 to map the video segment */ ! 205: videoAddr = args->Video.v_baseAddr & 0xF0000000; ! 206: if (videoAddr) { ! 207: /* start off specifying 1-1 mapping of video seg */ ! 208: bat.upper.word = videoAddr; ! 209: bat.lower.word = videoAddr; ! 210: ! 211: bat.upper.bits.bl = 0x7ff; /* size = 256M */ ! 212: bat.upper.bits.vs = 1; ! 213: bat.upper.bits.vp = 0; ! 214: ! 215: bat.lower.bits.wimg = PTE_WIMG_IO; ! 216: bat.lower.bits.pp = 2; /* read/write access */ ! 217: ! 218: sync();isync(); ! 219: mtdbatu(3, BAT_INVALID); /* invalidate old mapping */ ! 220: mtdbatl(3, bat.lower.word); ! 221: mtdbatu(3, bat.upper.word); ! 222: sync();isync(); ! 223: } ! 224: ! 225: /* Use DBAT2 to map the io segment */ ! 226: addr = get_io_base_addr() & 0xF0000000; ! 227: if (addr != videoAddr) { ! 228: /* start off specifying 1-1 mapping of io seg */ ! 229: bat.upper.word = addr; ! 230: bat.lower.word = addr; ! 231: ! 232: bat.upper.bits.bl = 0x7ff; /* size = 256M */ ! 233: bat.upper.bits.vs = 1; ! 234: bat.upper.bits.vp = 0; ! 235: ! 236: bat.lower.bits.wimg = PTE_WIMG_IO; ! 237: bat.lower.bits.pp = 2; /* read/write access */ ! 238: ! 239: sync();isync(); ! 240: mtdbatu(2, BAT_INVALID); /* invalidate old mapping */ ! 241: mtdbatl(2, bat.lower.word); ! 242: mtdbatu(2, bat.upper.word); ! 243: sync();isync(); ! 244: } ! 245: ! 246: #if 0 ! 247: GratefulDebInit((bootBumbleC *)&(args->Video)); /* Initialize the GratefulDeb debugger */ ! 248: #endif ! 249: ! 250: /* setup debugging output if one has been chosen */ ! 251: PE_init_kprintf(FALSE); ! 252: kprintf("kprintf initialized\n"); ! 253: ! 254: /* create the console for verbose or pretty mode */ ! 255: PE_create_console(); ! 256: ! 257: /* setup console output */ ! 258: PE_init_printf(FALSE); ! 259: ! 260: #if DEBUG ! 261: printf("\n\n\nThis program was compiled using gcc %d.%d for powerpc\n", ! 262: __GNUC__,__GNUC_MINOR__); ! 263: ! 264: /* Processor version information */ ! 265: { ! 266: unsigned int pvr; ! 267: __asm__ ("mfpvr %0" : "=r" (pvr)); ! 268: printf("processor version register : 0x%08x\n",pvr); ! 269: } ! 270: for (i = 0; i < kMaxDRAMBanks; i++) { ! 271: if (args->PhysicalDRAM[i].size) ! 272: printf("DRAM at 0x%08x size 0x%08x\n", ! 273: args->PhysicalDRAM[i].base, ! 274: args->PhysicalDRAM[i].size); ! 275: } ! 276: #endif /* DEBUG */ ! 277: ! 278: /* ! 279: * VM initialization, after this we're using page tables... ! 280: */ ! 281: if (!PE_parse_boot_arg("maxmem", &maxmem)) ! 282: maxmem=0; ! 283: else ! 284: maxmem = maxmem * (1024 * 1024); ! 285: ! 286: ppc_vm_init(maxmem, args); ! 287: ! 288: PE_init_platform(TRUE, args); ! 289: ! 290: machine_startup(args); ! 291: } ! 292: ! 293: ppc_init_cpu( ! 294: struct per_proc_info *proc_info) ! 295: { ! 296: int i; ! 297: unsigned int gph; ! 298: savectl *sctl; /* Savearea controls */ ! 299: ! 300: mtsprg(0, (unsigned int)proc_info); /* Point sprg 0 at the per_proc_area */ ! 301: ! 302: gph = save_get_phys(); /* Get a savearea (physical addressing) */ ! 303: mtsprg(1, gph); /* Set physical address of savearea */ ! 304: ! 305: cpu_init(); ! 306: ! 307: /* Set up segment registers as VM through space 0 */ ! 308: for (i=0; i<=15; i++) { ! 309: isync(); ! 310: mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000); ! 311: sync(); ! 312: } ! 313: ! 314: ppc_vm_cpu_init(proc_info); ! 315: ! 316: slave_main(); ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.