Annotation of XNU/osfmk/i386/AT386/model_dep.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:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: 
                     51: /*
                     52:  */
                     53: 
                     54: /*
                     55:  *     File:   model_dep.c
                     56:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     57:  *
                     58:  *     Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
                     59:  *
                     60:  *     Basic initialization for I386 - ISA bus machines.
                     61:  */
                     62: 
                     63: #include <cpus.h>
                     64: #include <platforms.h>
                     65: #include <mp_v1_1.h>
                     66: #include <mach_kdb.h>
                     67: #include <himem.h>
                     68: #include <fast_idle.h>
                     69: 
                     70: #include <mach/i386/vm_param.h>
                     71: 
                     72: #include <string.h>
                     73: #include <mach/vm_param.h>
                     74: #include <mach/vm_prot.h>
                     75: #include <mach/machine.h>
                     76: #include <mach/time_value.h>
                     77: #include <kern/etap_macros.h>
                     78: #include <kern/spl.h>
                     79: #include <kern/assert.h>
                     80: #include <kern/debug.h>
                     81: #include <kern/misc_protos.h>
                     82: #include <kern/startup.h>
                     83: #include <kern/clock.h>
                     84: #include <kern/time_out.h>
                     85: #include <kern/xpr.h>
                     86: #include <kern/cpu_data.h>
                     87: #include <vm/vm_page.h>
                     88: #include <vm/pmap.h>
                     89: #include <vm/vm_kern.h>
                     90: #include <i386/fpu.h>
                     91: #include <i386/pmap.h>
                     92: #include <i386/ipl.h>
                     93: #include <i386/pio.h>
                     94: #include <i386/misc_protos.h>
                     95: #include <i386/cpuid.h>
                     96: #include <i386/rtclock_entries.h>
                     97: #include <i386/AT386/mp/mp.h>
                     98: #if    MACH_KDB
                     99: #include <ddb/db_aout.h>
                    100: #endif /* MACH_KDB */
                    101: #include <ddb/tr.h>
                    102: #ifdef __MACHO__
                    103: #include <i386/AT386/kernBootStruct.h>
                    104: #include <mach/boot_info.h>
                    105: #include <mach/thread_status.h>
                    106: #endif
                    107: 
                    108: #if    NCPUS > 1
                    109: #include <i386/mp_desc.h>
                    110: #endif /* NCPUS */
                    111: 
                    112: #if    MP_V1_1
                    113: #include <i386/AT386/mp/mp_v1_1.h>
                    114: #endif /* MP_V1_1 */
                    115: 
                    116: vm_size_t      mem_size = 0; 
                    117: vm_offset_t    first_addr = 0; /* set by start.s - keep out of bss */
                    118: vm_offset_t    first_avail = 0;/* first after page tables */
                    119: vm_offset_t    last_addr;
                    120: 
                    121: vm_offset_t    avail_start, avail_end;
                    122: vm_offset_t    virtual_avail, virtual_end;
                    123: vm_offset_t    hole_start, hole_end;
                    124: vm_offset_t    avail_next;
                    125: unsigned int   avail_remaining;
                    126: 
                    127: /* parameters passed from bootstrap loader */
                    128: int            cnvmem = 0;             /* must be in .data section */
                    129: int            extmem = 0;
                    130: 
                    131: /* FIXME!! REMOVE WHEN OSFMK DEVICES ARE COMPLETELY PULLED OUT */
                    132: int            dev_name_count = 0;
                    133: int            dev_name_list = 0;
                    134: 
                    135: #ifndef __MACHO__
                    136: extern char    edata, end;
                    137: #endif
                    138: 
                    139: extern char    version[];
                    140: 
                    141: int            rebootflag = 0; /* exported to kdintr */
                    142: 
                    143: 
                    144: void           parse_arguments(void);
                    145: const char     *getenv(const char *);
                    146: 
                    147: #define        BOOT_LINE_LENGTH 160
                    148: char           boot_string_store[BOOT_LINE_LENGTH] = {0};
                    149: char           *boot_string = (char *)0;
                    150: int            boot_string_sz = BOOT_LINE_LENGTH;
                    151: int            boottype = 0;
                    152: 
                    153: #if    __MACHO__
                    154: #include       <mach-o/loader.h>
                    155: vm_offset_t    edata, etext, end;
                    156: 
                    157: extern struct mach_header _mh_execute_header;
                    158: void *sectTEXTB; int sectSizeTEXT;
                    159: void *sectDATAB; int sectSizeDATA;
                    160: void *sectOBJCB; int sectSizeOBJC;
                    161: void *sectLINKB; int sectSizeLINK;
                    162: 
                    163: /* Kernel boot information */
                    164: KERNBOOTSTRUCT kernBootStructData;
                    165: KERNBOOTSTRUCT *kernBootStruct;
                    166: #endif
                    167: 
                    168: extern vm_offset_t kern_args_start;
                    169: extern vm_size_t kern_args_size;
                    170: 
                    171: #ifdef __MACHO__
                    172: 
                    173: unsigned long
                    174: i386_preinit()
                    175: {
                    176:        int i;
                    177:        struct segment_command  *sgp;
                    178:        struct section          *sp;
                    179: 
                    180:        sgp = (struct segment_command *) getsegbyname("__DATA");
                    181:        if (sgp) {
                    182:                sp = (struct section *) firstsect(sgp);
                    183:                if (sp) {
                    184:                        do {
                    185:                                if (sp->flags & S_ZEROFILL)
                    186:                                        bzero((char *) sp->addr, sp->size);
                    187:                        } while (sp = (struct section *)nextsect(sgp, sp));
                    188:                }
                    189:        }
                    190: 
                    191: 
                    192:        bcopy((char *) KERNSTRUCT_ADDR, (char *) &kernBootStructData,
                    193:                                        sizeof(kernBootStructData));
                    194: 
                    195:        kernBootStruct = &kernBootStructData;
                    196: 
                    197:        end = getlastaddr();
                    198:        
                    199:        for (i = 0; i < kernBootStruct->numBootDrivers; i++)
                    200:                end += kernBootStruct->driverConfig[i].size;
                    201: 
                    202:        end = round_page(end);
                    203: 
                    204:        return  end;
                    205: }
                    206: #endif
                    207: 
                    208: /*
                    209:  *     Cpu initialization.  Running virtual, but without MACH VM
                    210:  *     set up.  First C routine called.
                    211:  */
                    212: void
                    213: machine_startup(void)
                    214: {
                    215: 
                    216: #ifdef __MACHO__
                    217: 
                    218: 
                    219:        /* Now copy over various bits.. */
                    220:        cnvmem = kernBootStruct->convmem;
                    221:        extmem = kernBootStruct->extmem;
                    222:        kern_args_start = (vm_offset_t) kernBootStruct->bootString;
                    223:        kern_args_size = strlen(kernBootStruct->bootString);
                    224:        boottype = kernBootStruct->rootdev;
                    225: 
                    226:        /* Now retrieve addresses for end, edata, and etext 
                    227:         * from MACH-O headers.
                    228:         */
                    229: 
                    230:        sectTEXTB = (void *) getsegdatafromheader(
                    231:                &_mh_execute_header, "__TEXT", &sectSizeTEXT);
                    232:        sectDATAB = (void *) getsegdatafromheader(
                    233:                &_mh_execute_header, "__DATA", &sectSizeDATA);
                    234:        sectOBJCB = (void *) getsegdatafromheader(
                    235:                &_mh_execute_header, "__OBJC", &sectSizeOBJC);
                    236:        sectLINKB = (void *) getsegdatafromheader(
                    237:                &_mh_execute_header, "__LINKEDIT", &sectSizeLINK);
                    238: 
                    239:        etext = (vm_offset_t) sectTEXTB + sectSizeTEXT;
                    240:        edata = (vm_offset_t) sectDATAB + sectSizeDATA;
                    241: #endif
                    242: 
                    243:        /*
                    244:         * Parse startup arguments
                    245:         */
                    246:        parse_arguments();
                    247: 
                    248:        disableDebugOuput = FALSE;
                    249:        debug_mode = TRUE;
                    250: 
                    251:        PE_init_platform(FALSE, kernBootStruct);
                    252:        PE_init_kprintf(FALSE);
                    253:        PE_init_printf(FALSE);
                    254: 
                    255:        /*
                    256:         * Do basic VM initialization
                    257:         */
                    258:        i386_init();
                    259: 
                    260:        PE_init_platform(TRUE, kernBootStruct);
                    261:        PE_init_kprintf(TRUE);
                    262:        PE_init_printf(TRUE);
                    263: 
                    264: #if    MACH_KDB
                    265: 
                    266:        /*
                    267:         * Initialize the kernel debugger.
                    268:         */
                    269:        ddb_init();
                    270: 
                    271:        /*
                    272:         * Cause a breakpoint trap to the debugger before proceeding
                    273:         * any further if the proper option bit was specified in
                    274:         * the boot flags.
                    275:         *
                    276:         * XXX use -a switch to invoke kdb, since there's no
                    277:         *     boot-program switch to turn on RB_HALT!
                    278:         */
                    279: 
                    280:        if (halt_in_debugger) {
                    281:                printf("inline call to debugger(machine_startup)\n");
                    282:                Debugger("inline call");
                    283:        }
                    284: #endif /* MACH_KDB */
                    285:        TR_INIT();
                    286: 
                    287:        printf(version);
                    288: 
                    289:        machine_slot[0].is_cpu = TRUE;
                    290:        machine_slot[0].running = TRUE;
                    291: #ifdef MACH_BSD
                    292:        /* FIXME */
                    293:        machine_slot[0].cpu_type = CPU_TYPE_I386;
                    294:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_PENTPRO;
                    295: #else
                    296:        machine_slot[0].cpu_type = cpuid_cputype(0);
                    297:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_AT386;
                    298: #endif
                    299: 
                    300:        /*
                    301:         * Start the system.
                    302:         */
                    303: #if    NCPUS > 1
                    304:        mp_desc_init(0);
                    305: #endif /* NCPUS */
                    306: 
                    307:        setup_main();
                    308: }
                    309: 
                    310: 
                    311: extern vm_offset_t env_start;
                    312: extern vm_size_t env_size;
                    313: /*
                    314:  * Parse command line arguments.
                    315:  */
                    316: void
                    317: parse_arguments(void)
                    318: {
                    319:        char *p = (char *) kern_args_start;
                    320:        char *endp = (char *) kern_args_start + kern_args_size - 1;
                    321:        char ch;
                    322: 
                    323:        if (kern_args_start == 0)
                    324:            return;
                    325:        while (p < endp) {
                    326:            if (*p++ != '-') {
                    327:                while (*p++ != '\0')
                    328:                    ;
                    329:                continue;
                    330:            }
                    331:            while (ch = *p++) {
                    332:                switch (ch) {
                    333:                case 'h':
                    334:                    halt_in_debugger = 1;
                    335:                    break;
                    336:                case 'm':       /* -m??:  memory size Mbytes*/
                    337:                    mem_size = atoi_term(p, &p)*1024*1024;
                    338:                    break;
                    339:                case 'k':       /* -k??:  memory size Kbytes */
                    340:                    mem_size = atoi_term(p, &p)*1024;
                    341:                    break;
                    342:                default:
                    343: #if    NCPUS > 1 && AT386
                    344:                    if (ch > '0' && ch <= '9')
                    345:                        wncpu = ch - '0';
                    346: #endif /* NCPUS > 1 && AT386 */
                    347:                    break;
                    348:                }
                    349:            }
                    350:        }
                    351: }
                    352: 
                    353: const char *
                    354: getenv(const char *name)
                    355: {
                    356:        int len = strlen(name);
                    357:        const char *p = (const char *)env_start;
                    358:        const char *endp = p + env_size;
                    359: 
                    360:        while (p < endp) {
                    361:                if (len >= endp - p)
                    362:                        break;
                    363:                if (strncmp(name, p, len) == 0 && *(p + len) == '=')
                    364:                        return p + len + 1;
                    365:                while (*p++)
                    366:                        ;
                    367:        }
                    368:        return NULL;
                    369: }
                    370: 
                    371: extern void
                    372: calibrate_delay(void);
                    373: 
                    374: /*
                    375:  * Find devices.  The system is alive.
                    376:  */
                    377: void
                    378: machine_init(void)
                    379: {
                    380:        int unit;
                    381:        const char *p;
                    382:        int n;
                    383: 
                    384:        /*
                    385:         * Adjust delay count before entering drivers
                    386:         */
                    387: 
                    388:        calibrate_delay();
                    389: 
                    390:        /*
                    391:         * Display CPU identification
                    392:         */
                    393:        cpuid_cpu_display("CPU identification", 0);
                    394:        cpuid_cache_display("CPU configuration", 0);
                    395: 
                    396: #if    MP_V1_1
                    397:        mp_v1_1_init();
                    398: #endif /* MP_V1_1 */
                    399: 
                    400:        /*
                    401:         * Set up to use floating point.
                    402:         */
                    403:        init_fpu();
                    404: 
                    405: #if 0
                    406: #if    NPCI > 0
                    407:        dma_zones_init();
                    408: #endif /* NPCI > 0 */
                    409: #endif
                    410: 
                    411:        /*
                    412:         * Configure clock devices.
                    413:         */
                    414:        clock_config();
                    415: }
                    416: 
                    417: /*
                    418:  * Halt a cpu.
                    419:  */
                    420: void
                    421: halt_cpu(void)
                    422: {
                    423:        halt_all_cpus(FALSE);
                    424: }
                    425: 
                    426: int reset_mem_on_reboot = 1;
                    427: 
                    428: /*
                    429:  * Halt the system or reboot.
                    430:  */
                    431: void
                    432: halt_all_cpus(
                    433:        boolean_t       reboot)
                    434: {
                    435:        if (reboot) {
                    436:            /*
                    437:             * Tell the BIOS not to clear and test memory.
                    438:             */
                    439:            if (! reset_mem_on_reboot)
                    440:                *(unsigned short *)phystokv(0x472) = 0x1234;
                    441: 
                    442:            kdreboot();
                    443:        }
                    444:        else {
                    445:            rebootflag = 1;
                    446:            printf("In tight loop: hit ctl-alt-del to reboot\n");
                    447:            (void) spllo();
                    448:        }
                    449:        for (;;)
                    450:            continue;
                    451: }
                    452: 
                    453: 
                    454: /*
                    455:  * Basic VM initialization.
                    456:  */
                    457: 
                    458: void
                    459: i386_init(void)
                    460: {
                    461:        int i,j;                        /* Standard index vars. */
                    462:        vm_size_t       bios_hole_size; 
                    463: 
                    464: #ifndef        __MACHO__
                    465:        /*
                    466:         * Zero the BSS.
                    467:         */
                    468: 
                    469:        bzero((char *)&edata,(unsigned)(&end - &edata));
                    470: #endif
                    471: 
                    472:        boot_string = &boot_string_store[0];
                    473: 
                    474:        /*
                    475:         * Initialize the pic prior to any possible call to an spl.
                    476:         */
                    477: 
                    478:        set_cpu_model();
                    479:        vm_set_page_size();
                    480: 
                    481:        /*
                    482:         * Initialize the Event Trace Analysis Package
                    483:         * Static Phase: 1 of 2
                    484:         */
                    485:        etap_init_phase1();
                    486: 
                    487:        /*
                    488:         * Compute the memory size.
                    489:         */
                    490: 
                    491: #if  1
                    492:        /* FIXME 
                    493:         * fdisk needs to change to use a sysctl instead of
                    494:         * opening /dev/kmem and reading out the kernboot structure
                    495:         */
                    496: 
                    497:        first_addr = 0x11000 + sizeof(KERNBOOTSTRUCT);
                    498: #else
                    499: #if NCPUS > 1
                    500:        first_addr = 0x1000;
                    501: #else
                    502:        /* First two pages are used to boot the other cpus. */
                    503:        /* TODO - reclaim pages after all cpus have booted */
                    504: 
                    505:        first_addr = 0x3000;
                    506: #endif
                    507: #endif
                    508: 
                    509:                /* BIOS leaves data in low memory */
                    510:        last_addr = 1024*1024 + extmem*1024;
                    511:        /* extended memory starts at 1MB */
                    512:        
                    513:        bios_hole_size = 1024*1024 - trunc_page((vm_offset_t)(1024 * cnvmem));
                    514: 
                    515:        /*
                    516:         *      Initialize for pmap_free_pages and pmap_next_page.
                    517:         *      These guys should be page-aligned.
                    518:         */
                    519: 
                    520:        hole_start = trunc_page((vm_offset_t)(1024 * cnvmem));
                    521:        hole_end = round_page((vm_offset_t)first_avail);
                    522: 
                    523:        /*
                    524:         * compute mem_size
                    525:         */
                    526: 
                    527:        if (mem_size != 0) {
                    528:            if (mem_size < (last_addr) - bios_hole_size)
                    529:                last_addr = mem_size + bios_hole_size;
                    530:        }
                    531: 
                    532:        first_addr = round_page(first_addr);
                    533:        last_addr = trunc_page(last_addr);
                    534:        mem_size = last_addr - bios_hole_size;
                    535: 
                    536:        avail_start = first_addr;
                    537:        avail_end = last_addr;
                    538:        avail_next = avail_start;
                    539: 
                    540:        /*
                    541:         *      Initialize kernel physical map, mapping the
                    542:         *      region from loadpt to avail_start.
                    543:         *      Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
                    544:         */
                    545: 
                    546: 
                    547: #if    NCPUS > 1 && AT386
                    548:        /*
                    549:         * Must Allocate interrupt stacks before kdb is called and also
                    550:         * before vm is initialized. Must find out number of cpus first.
                    551:         */
                    552:        /*
                    553:         * Get number of cpus to boot, passed as an optional argument
                    554:         * boot: mach [-sah#]   # from 0 to 9 is the number of cpus to boot
                    555:         */
                    556:        if (wncpu == -1) {
                    557:                /*
                    558:                 * "-1" check above is to allow for old boot loader to pass
                    559:                 * wncpu through boothowto. New boot loader uses environment.
                    560:                 */
                    561:                const char *cpus;
                    562:                if ((cpus = getenv("cpus")) != NULL) {
                    563:                        /* only a single digit for now */
                    564:                        if ((*cpus > '0') && (*cpus <= '9'))
                    565:                                wncpu = *cpus - '0';
                    566:                } else
                    567:                        wncpu = NCPUS;
                    568:        }
                    569:        mp_probe_cpus();
                    570:        interrupt_stack_alloc();
                    571: 
                    572: #endif /* NCPUS > 1 && AT386 */
                    573: 
                    574:        pmap_bootstrap(0);
                    575: 
                    576:        avail_remaining = atop((avail_end - avail_start) -
                    577:                               (hole_end - hole_start));
                    578: }
                    579: 
                    580: unsigned int
                    581: pmap_free_pages(void)
                    582: {
                    583:        return avail_remaining;
                    584: }
                    585: 
                    586: boolean_t
                    587: pmap_next_page(
                    588:        vm_offset_t *addrp)
                    589: {
                    590:        if (avail_next == avail_end) 
                    591:                return FALSE;
                    592: 
                    593:        /* skip the hole */
                    594: 
                    595:        if (avail_next == hole_start)
                    596:                avail_next = hole_end;
                    597: 
                    598:        *addrp = avail_next;
                    599:        avail_next += PAGE_SIZE;
                    600:        avail_remaining--;
                    601: 
                    602:        return TRUE;
                    603: }
                    604: 
                    605: boolean_t
                    606: pmap_valid_page(
                    607:        vm_offset_t x)
                    608: {
                    609:        return ((avail_start <= x) && (x < avail_end));
                    610: }
                    611: 
                    612: /*XXX*/
                    613: void fc_get(mach_timespec_t *ts);
                    614: #include <kern/clock.h>
                    615: #include <i386/rtclock_entries.h>
                    616: extern kern_return_t   sysclk_gettime(
                    617:                        mach_timespec_t *cur_time);
                    618: void fc_get(mach_timespec_t *ts) {
                    619:        (void )sysclk_gettime(ts);
                    620: }
                    621: 
                    622: void
                    623: Debugger(
                    624:        const char      *message)
                    625: {
                    626:        printf("Debugger called: <%s>\n", message);
                    627: 
                    628:        __asm__("int3");
                    629: }
                    630: 
                    631: void
                    632: display_syscall(int syscall)
                    633: {
                    634:        printf("System call happened %d\n", syscall);
                    635: }
                    636: 
                    637: #if    XPR_DEBUG && (NCPUS == 1 || MP_V1_1)
                    638: 
                    639: extern kern_return_t   sysclk_gettime_interrupts_disabled(
                    640:                                mach_timespec_t *cur_time);
                    641: 
                    642: int    xpr_time(void)
                    643: {
                    644:         mach_timespec_t        time;
                    645: 
                    646:        sysclk_gettime_interrupts_disabled(&time);
                    647:        return(time.tv_sec*1000000 + time.tv_nsec/1000);
                    648: }
                    649: #endif /* XPR_DEBUG && (NCPUS == 1 || MP_V1_1) */
                    650: 
                    651: enable_bluebox()
                    652: {
                    653: }
                    654: disable_bluebox()
                    655: {
                    656: }
                    657: 
                    658: char *
                    659: machine_boot_info(char *buf, vm_size_t size)
                    660: {
                    661:        *buf ='\0';
                    662:        return buf;
                    663: }
                    664: 

unix.superglobalmegacorp.com

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