Annotation of XNU/osfmk/ppc/ppc_init.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.