Annotation of XNU/osfmk/ppc/ppc_init.c, revision 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.