Annotation of kernel/machdep/i386/i386_init.c, revision 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.