Annotation of kernel/machdep/i386/i386_init.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1992, 1993, 1994 NeXT Computer, Inc.
                     27:  *
                     28:  * Early machine initialization.
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 20 May 1992 ? at NeXT
                     33:  *     Created.
                     34:  */
                     35: 
                     36: #import <mach/mach_types.h>
                     37: 
                     38: #import <kern/mach_header.h>
                     39: 
                     40: #import <vm/vm_page.h>
                     41: 
                     42: #import <machdep/i386/cpu_inline.h>
                     43: 
                     44: #import        <machdep/i386/pmap.h>
                     45: #import <machdep/i386/gdt.h>
                     46: #import <machdep/i386/idt.h>
                     47: #import <machdep/i386/configure.h>
                     48: #import <machdep/i386/kernBootStruct.h>
                     49: #include <sys/reboot.h>
                     50: #include <sys/errno.h>
                     51: #import "uxpr.h"
                     52: #import "xpr_debug.h"
                     53: 
                     54: extern char rootdevice[];
                     55: extern int nbuf;
                     56: extern int srv;
                     57: extern int ncl;
                     58: static unsigned int maxmem;
                     59: static int subtype = 0;
                     60: 
                     61: struct kernargs {
                     62:        char *name;
                     63:        int *i_ptr;
                     64: } kernargs[] = {
                     65:        "nbuf", &nbuf,
                     66:        "rootdev", (int*) rootdevice,
                     67:        "maxmem", &maxmem,
                     68:        "subtype", &subtype,
                     69:        "srv", &srv,
                     70:        "ncl", &ncl,
                     71:        0,0,
                     72: };
                     73: 
                     74: #define        NBOOTFILE       64
                     75: char   boot_file[NBOOTFILE + 1];
                     76: 
                     77: int                    master_cpu;
                     78: cpu_conf_t             cpu_config;
                     79: 
                     80: static vm_offset_t     first_addr, last_addr;
                     81: static vm_offset_t     first_addr0, last_addr0;
                     82: 
                     83: vm_offset_t            virtual_avail, virtual_end;
                     84: 
                     85: struct mem_region      mem_region[2];
                     86: int                    num_regions;
                     87: 
                     88: vm_size_t              mem_size;
                     89: 
                     90: /* parameters passed from bootstrap loader */
                     91: int cnvmem = 0;                /* must be in .data section */
                     92: int extmem = 0;
                     93: 
                     94: #import <sys/msgbuf.h>
                     95: 
                     96: static void    zero_fill_data(void), size_memory(void),
                     97:                machine_configure(void), idt_page_protect(void);
                     98: 
                     99: vm_offset_t    alloc_cnvmem(
                    100:                        vm_size_t       size,
                    101:                        vm_offset_t     align);
                    102: 
                    103: thread_saved_state_t   *___xxx_state;  /* Just a placeholder */
                    104: 
                    105: /*
                    106:  * Called from Protected mode,
                    107:  * flat 3G segmentation, paging disabled,
                    108:  * interrupts disabled.
                    109:  */
                    110: i386_init(void)
                    111: {
                    112:     register mem_region_t      rp;
                    113:        KERNBOOTSTRUCT *kernBootStruct = KERNSTRUCT_ADDR;
                    114: 
                    115:     cnvmem = kernBootStruct->convmem;
                    116:     extmem = kernBootStruct->extmem;
                    117: 
                    118:     // Clear "zero fill" data sections.
                    119: 
                    120:     zero_fill_data();
                    121:     
                    122:     getargs(kernBootStruct->bootString);
                    123: 
                    124:     // Figure out what kind of cpu is present
                    125:     
                    126:     machine_configure();
                    127:        
                    128:     // Initialize the interrupt system.
                    129: 
                    130:     intr_initialize();
                    131:     
                    132:     // Calibrate the constant for us_spin().
                    133: 
                    134:     us_spin_calibrate();
                    135: 
                    136:     // Set the MI system page size     
                    137: 
                    138:     page_size = 2*I386_PGBYTES;
                    139:     vm_set_page_size();
                    140: 
                    141:     // Enable DDM tracing
                    142: #if    UXPR && XPR_DEBUG
                    143:        IOInitDDM(512);
                    144: #endif UXPR && XPR_DEBUG
                    145: 
                    146:     // Figure out how much extended memory the system contains.
                    147: 
                    148:     size_memory();
                    149: 
                    150:     // Configure memory regions.
                    151: 
                    152:     num_regions                        = 1;
                    153: 
                    154:     rp                         = (mem_region_t) &mem_region[0];
                    155:     rp->base_phys_addr =
                    156:        rp->first_phys_addr     = first_addr;
                    157:     rp->last_phys_addr         = last_addr;
                    158: 
                    159:     /*
                    160:      * Place the idt on its own page to
                    161:      * enable working around the 'f00f' bug.
                    162:      */
                    163:     idt_copy(alloc_cnvmem(I386_PGBYTES, I386_PGBYTES), I386_PGBYTES);
                    164: 
                    165:     // Initialize kernel physical map.
                    166: 
                    167:     pmap_bootstrap(mem_region, num_regions, &virtual_avail, &virtual_end);
                    168: 
                    169:     //
                    170:     // Relocate the GDT & IDT
                    171:     // to reside in the kernel
                    172:     // address space.
                    173: 
                    174:     locate_gdt((vm_offset_t) gdt + KERNEL_LINEAR_BASE);
                    175:     locate_idt((vm_offset_t) idt + KERNEL_LINEAR_BASE);
                    176:     
                    177:     //
                    178:     // Set up the handler
                    179:     // for double bus faults
                    180:     
                    181:     dbf_init();
                    182: 
                    183:     /*
                    184:      * Write protect the page containing
                    185:      * the IDT as part of the 'f00f'
                    186:      * hack/workaround.
                    187:      */
                    188:     idt_page_protect();
                    189: 
                    190:     // Specify address of console message buffer.
                    191: 
                    192:     mem_region[0].last_phys_addr -= round_page(sizeof (struct msgbuf));
                    193:     msgbufp =
                    194:        (struct msgbuf *)pmap_phys_to_kern(mem_region[0].last_phys_addr);
                    195: }
                    196: 
                    197: static void
                    198: idt_page_protect(void)
                    199: {
                    200:     pt_entry_t *pte = pmap_pt_entry(kernel_pmap, (vm_offset_t) idt);
                    201: 
                    202:     pte->prot = PT_PROT_KR;
                    203:     flush_cache(); flush_tlb();
                    204: }
                    205: 
                    206: static
                    207: void
                    208: zero_fill_data(void)
                    209: {
                    210:     struct segment_command     *sgp;
                    211:     struct section             *sp;
                    212:     
                    213:     sgp = getsegbyname("__DATA");
                    214:     if (!sgp)
                    215:        return;
                    216:        
                    217:     sp = firstsect(sgp);
                    218:     if (!sp)
                    219:        return;
                    220:        
                    221:     do {
                    222:        if (sp->flags & S_ZEROFILL)
                    223:            bzero(sp->addr, sp->size);
                    224:     } while (sp = nextsect(sgp, sp));
                    225: }
                    226: 
                    227: static inline
                    228: boolean_t
                    229: is486_or_higher(void)
                    230: {
                    231:     unsigned int       efl;
                    232:     
                    233:     efl = eflags();
                    234: 
                    235:     efl |= EFL_AC;
                    236:     set_eflags(efl);
                    237:     
                    238:     if ((efl & EFL_AC) == 0)
                    239:        return (FALSE);
                    240:        
                    241:     efl &= ~EFL_AC;
                    242:     set_eflags(efl);
                    243: 
                    244:     return (TRUE);
                    245: }
                    246: 
                    247: /*
                    248:  * This stuff belongs elsewhere
                    249:  * (.h files), but I can't put
                    250:  * it there due to the confidentiality
                    251:  * of P5 information.
                    252:  *     - 17 September 92
                    253:  */
                    254: typedef struct _cpuid {
                    255:     unsigned int       step    :4,
                    256:                        model   :4,
                    257:                        family  :4,
                    258:                        type    :2,
                    259:                                :18;
                    260: } cpuid_t;
                    261: 
                    262: static
                    263: cpuid_t
                    264: cpuid(void)
                    265: {
                    266:     cpuid_t    value;
                    267:     
                    268:     asm volatile(
                    269:        "movl $1,%%eax; cpuid"
                    270:            : "=a" (value)
                    271:            :
                    272:            : "ebx", "ecx", "edx");
                    273:            
                    274:     return (value);
                    275: }
                    276: 
                    277: #define EFL_ID         0x200000        /* P5 specific */
                    278: 
                    279: static
                    280: cpuid_t
                    281: get_cpuid(void)
                    282: {
                    283:     unsigned int       efl;
                    284:     cpuid_t            pid = { 0 };
                    285: 
                    286:     if (subtype != 0) {
                    287:        /*
                    288:        * This is a hack, intended only
                    289:        * for testing purposes.
                    290:        */
                    291:        pid.family = CPU_SUBTYPE_INTEL_FAMILY(subtype);
                    292:        pid.model = CPU_SUBTYPE_INTEL_MODEL(subtype);
                    293: 
                    294:        return pid;
                    295:     }
                    296:     
                    297:     efl = eflags();
                    298: 
                    299:     efl |= EFL_ID;
                    300:     set_eflags(efl);
                    301:     
                    302:     efl = eflags();
                    303:     
                    304:     if ((efl & EFL_ID) == 0)
                    305:        return pid;
                    306:        
                    307:     pid = cpuid();
                    308:        
                    309:     efl &= ~EFL_ID;
                    310:     set_eflags(efl);
                    311: 
                    312:     return pid;
                    313: }
                    314: 
                    315: char cpu_model[65];
                    316: char machine[65];
                    317: 
                    318: static
                    319: void
                    320: machine_configure(void)
                    321: {
                    322:     cpuid_t    pid;
                    323: 
                    324:     while (!is486_or_higher())
                    325:        asm volatile("hlt");
                    326:                        
                    327:     enable_cache();
                    328:     
                    329:     fp_configure();
                    330: 
                    331:     machine_slot[0].is_cpu = TRUE;
                    332:     machine_slot[0].running = TRUE;
                    333: 
                    334:     machine_slot[0].cpu_type = CPU_TYPE_I386;
                    335:     (void) strcpy(machine, "i386");
                    336: 
                    337:     pid = get_cpuid();
                    338:     switch (pid.family) {
                    339:     
                    340:     case 0:
                    341:        if (cpu_config.fpu_type == FPU_HDW) {
                    342:            machine_slot[0].cpu_subtype = CPU_SUBTYPE_486;
                    343:            (void) strcpy(cpu_model, "486");
                    344:        }
                    345:        else {
                    346:            machine_slot[0].cpu_subtype = CPU_SUBTYPE_486SX;
                    347:            (void) strcpy(cpu_model, "486SX");
                    348:        }
                    349:        break;
                    350: 
                    351:     case 5:
                    352:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_586;
                    353:        (void) strcpy(cpu_model, "586");
                    354:        break;
                    355: 
                    356:     default:
                    357:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_INTEL(pid.family, pid.model);
                    358:        (void) sprintf(cpu_model, "i86 family %d, model %d",
                    359:                       pid.family, pid.model);
                    360:        break;
                    361:     }
                    362: }
                    363: 
                    364: static
                    365: void
                    366: size_memory(void)
                    367: {
                    368:     KERNBOOTSTRUCT     *kernBootStruct = (KERNBOOTSTRUCT *)KERNSTRUCT_ADDR;
                    369:     vm_offset_t                end_of_image, end_of_memory;
                    370:     int                        i;
                    371: #define KB(x)          ((x)*1024)
                    372: 
                    373:     end_of_image = getlastaddr();
                    374: 
                    375:     for (i=0; i < kernBootStruct->numBootDrivers; i++)
                    376:        end_of_image += kernBootStruct->driverConfig[i].size;
                    377:     
                    378:     if (maxmem)
                    379:        end_of_memory = KB(maxmem);
                    380:     else
                    381:        end_of_memory = KB(extmem);
                    382: 
                    383:     /*
                    384:      * This is the Mach notion of
                    385:      * how much physical memory the
                    386:      * machine contains.  This value
                    387:      * is only used for informational
                    388:      * purposes.
                    389:      */
                    390: 
                    391:     mem_size = end_of_memory;
                    392:     
                    393:     first_addr0 = round_page(kernBootStruct->first_addr0);
                    394:     last_addr0 = trunc_page(KB(cnvmem));
                    395: 
                    396:     first_addr = round_page(end_of_image);
                    397:     last_addr = trunc_page(end_of_memory);
                    398: #undef KB
                    399: }
                    400: 
                    401: vm_offset_t
                    402: bios_extdata_addr(void)
                    403: {
                    404:     return (cnvmem * 1024);
                    405: }
                    406: 
                    407: vm_offset_t
                    408: alloc_cnvmem(
                    409:     vm_size_t  size,
                    410:     vm_offset_t        align
                    411: )
                    412: {
                    413:     static vm_offset_t free_ptr, end_ptr;
                    414:     vm_offset_t                p;
                    415:     
                    416:     if (!free_ptr) {
                    417:        free_ptr = pmap_phys_to_kern(first_addr0);
                    418:        end_ptr = pmap_phys_to_kern(last_addr0);
                    419:     }
                    420:        
                    421:     p = (free_ptr + (align - 1)) & ~(align - 1);
                    422:     if ((p + size) > end_ptr)
                    423:        return ((vm_offset_t) 0);
                    424:        
                    425:     free_ptr = (p + size);
                    426:     
                    427:     return (p);
                    428: }
                    429: 
                    430: vm_offset_t
                    431: alloc_pages(
                    432:     vm_size_t  size
                    433: )
                    434: {
                    435:     vm_offset_t                p;
                    436: 
                    437:     {  /* XXX */
                    438:        extern boolean_t        pmap_initialized;
                    439:     
                    440:        if (pmap_initialized)
                    441:            panic("alloc_pages");
                    442: 
                    443:        /* XXX */
                    444:     }
                    445:     
                    446:     size = round_page(size);
                    447:     p = pmap_phys_to_kern(mem_region[0].first_phys_addr);
                    448:     mem_region[0].first_phys_addr += size;
                    449:     
                    450:     return (p);
                    451: }
                    452: 
                    453: #define        NUM     0
                    454: #define        STR     1
                    455: 
                    456: getargs(char *args)
                    457: {
                    458:        extern char init_args[];
                    459:        char            *cp, c;
                    460:        char            *namep;
                    461:        struct kernargs *kp;
                    462:        extern int boothowto;
                    463:        int i;
                    464:        int val;
                    465: 
                    466:        KERNBOOTSTRUCT *kernBootStruct = (KERNBOOTSTRUCT *)KERNSTRUCT_ADDR;
                    467:        strncpy(boot_file, kernBootStruct->boot_file, NBOOTFILE);
                    468: 
                    469:        if (*args == 0) return 1;
                    470: 
                    471:        while(isargsep(*args)) args++;
                    472: 
                    473:        while (*args)
                    474:        {
                    475:                if (*args == '-')
                    476:                {
                    477:                        char *ia = init_args;
                    478: 
                    479:                        argstrcpy(args, init_args);
                    480:                        do {
                    481:                                switch (*ia) {
                    482:                                    case 'a':
                    483:                                        boothowto |= RB_ASKNAME;
                    484:                                        break;
                    485:                                    case 's':
                    486:                                        boothowto |= RB_SINGLE;
                    487:                                        break;
                    488:                                    case 'd':
                    489:                                        boothowto |= RB_KDB;
                    490:                                        break;
                    491:                                    case 'f':
                    492: #define RB_NOFP                0x00200000      /* don't use floating point */
                    493:                                        boothowto |= RB_NOFP;
                    494:                                        break;
                    495:                                }
                    496:                        } while (*ia && !isargsep(*ia++));
                    497:                }
                    498:                else
                    499:                {
                    500:                        cp = args;
                    501:                        while (!isargsep (*cp) && *cp != '=')
                    502:                                cp++;
                    503:                        if (*cp != '=')
                    504:                                goto gotit;
                    505: 
                    506:                        c = *cp;
                    507:                        for(kp=kernargs;kp->name;kp++) {
                    508:                                i = cp-args;
                    509:                                if (strncmp(args, kp->name, i))
                    510:                                        continue;
                    511:                                while (isargsep (*cp))
                    512:                                        cp++;
                    513:                                if (*cp == '=' && c != '=') {
                    514:                                        args = cp+1;
                    515:                                        goto gotit;
                    516:                                }
                    517: 
                    518:                                switch (getval(cp, &val)) 
                    519:                                {
                    520:                                        case NUM:
                    521:                                                *kp->i_ptr = val;
                    522:                                                break;
                    523:                                        case STR:
                    524:                                                argstrcpy(++cp, kp->i_ptr);
                    525:                                                break;
                    526:                                }
                    527:                                goto gotit;
                    528:                        }
                    529:                }
                    530: gotit:
                    531:                /* Skip over current arg */
                    532:                while(!isargsep(*args)) args++;
                    533: 
                    534:                /* Skip leading white space (catch end of args) */
                    535:                while(*args && isargsep(*args)) args++;
                    536:        }
                    537: 
                    538:        return 0;
                    539: }
                    540: 
                    541: isargsep(c)
                    542: char c;
                    543: {
                    544:        if (c == ' ' || c == '\0' || c == '\t' || c == ',')
                    545:                return(1);
                    546:        else
                    547:                return(0);
                    548: }
                    549: 
                    550: argstrcpy(from, to)
                    551: char *from, *to;
                    552: {
                    553:        int i = 0;
                    554: 
                    555:        while (!isargsep(*from)) {
                    556:                i++;
                    557:                *to++ = *from++;
                    558:        }
                    559:        *to = 0;
                    560:        return(i);
                    561: }
                    562: 
                    563: getval(s, val)
                    564: register char *s;
                    565: int *val;
                    566: {
                    567:        register unsigned radix, intval;
                    568:        register unsigned char c;
                    569:        int sign = 1;
                    570: 
                    571:        if (*s == '=') {
                    572:                s++;
                    573:                if (*s == '-')
                    574:                        sign = -1, s++;
                    575:                intval = *s++-'0';
                    576:                radix = 10;
                    577:                if (intval == 0)
                    578:                        switch(*s) {
                    579: 
                    580:                        case 'x':
                    581:                                radix = 16;
                    582:                                s++;
                    583:                                break;
                    584: 
                    585:                        case 'b':
                    586:                                radix = 2;
                    587:                                s++;
                    588:                                break;
                    589: 
                    590:                        case '0': case '1': case '2': case '3':
                    591:                        case '4': case '5': case '6': case '7':
                    592:                                intval = *s-'0';
                    593:                                s++;
                    594:                                radix = 8;
                    595:                                break;
                    596: 
                    597:                        default:
                    598:                                if (!isargsep(*s))
                    599:                                        return (STR);
                    600:                        }
                    601:                for(;;) {
                    602:                        if (((c = *s++) >= '0') && (c <= '9'))
                    603:                                c -= '0';
                    604:                        else if ((c >= 'a') && (c <= 'f'))
                    605:                                c -= 'a' - 10;
                    606:                        else if ((c >= 'A') && (c <= 'F'))
                    607:                                c -= 'A' - 10;
                    608:                        else if (isargsep(c))
                    609:                                break;
                    610:                        else
                    611:                                return (STR);
                    612:                        if (c >= radix)
                    613:                                return (STR);
                    614:                        intval *= radix;
                    615:                        intval += c;
                    616:                }
                    617:                *val = intval * sign;
                    618:                return (NUM);
                    619:        }
                    620:        *val = 1;
                    621:        return (NUM);
                    622: }
                    623: 
                    624: /* i386 specific sysctl calls */
                    625: int
                    626: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    627:        int *name;
                    628:        u_int namelen;
                    629:        void *oldp;
                    630:        size_t *oldlenp;
                    631:        void *newp;
                    632:        size_t newlen;
                    633:        struct proc *p;
                    634: {
                    635:        /*
                    636:         * nothing defined yet
                    637:         */
                    638:        return (EOPNOTSUPP);
                    639: }
                    640: 

unix.superglobalmegacorp.com

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