Annotation of Gnu-Mach/i386/i386at/model_dep.c, revision 1.1.1.7

1.1.1.3   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.3   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.3   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.3   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.3   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.3   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File:   model_dep.c
                     28:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     29:  *
                     30:  *     Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
                     31:  *
                     32:  *     Basic initialization for I386 - ISA bus machines.
                     33:  */
                     34: 
1.1.1.4   root       35: #include <string.h>
                     36: 
                     37: #include <device/cons.h>
1.1       root       38: 
                     39: #include <mach/vm_param.h>
                     40: #include <mach/vm_prot.h>
                     41: #include <mach/machine.h>
                     42: #include <mach/machine/multiboot.h>
1.1.1.4   root       43: #include <mach/xen.h>
1.1       root       44: 
1.1.1.4   root       45: #include <i386/vm_param.h>
1.1.1.3   root       46: #include <kern/assert.h>
                     47: #include <kern/cpu_number.h>
1.1.1.4   root       48: #include <kern/debug.h>
                     49: #include <kern/mach_clock.h>
1.1.1.7 ! root       50: #include <kern/macros.h>
1.1.1.4   root       51: #include <kern/printf.h>
1.1.1.5   root       52: #include <kern/startup.h>
1.1       root       53: #include <sys/time.h>
1.1.1.4   root       54: #include <sys/types.h>
1.1       root       55: #include <vm/vm_page.h>
1.1.1.4   root       56: #include <i386/fpu.h>
                     57: #include <i386/gdt.h>
                     58: #include <i386/ktss.h>
                     59: #include <i386/ldt.h>
1.1       root       60: #include <i386/machspl.h>
1.1.1.4   root       61: #include <i386/pic.h>
                     62: #include <i386/pit.h>
1.1       root       63: #include <i386/pmap.h>
1.1.1.4   root       64: #include <i386/proc_reg.h>
                     65: #include <i386/locore.h>
                     66: #include <i386/model_dep.h>
                     67: #include <i386at/autoconf.h>
1.1.1.7 ! root       68: #include <i386at/biosmem.h>
1.1.1.4   root       69: #include <i386at/idt.h>
                     70: #include <i386at/int_init.h>
                     71: #include <i386at/kd.h>
                     72: #include <i386at/rtc.h>
1.1.1.5   root       73: #include <i386at/model_dep.h>
                     74: #include <i386at/acpihalt.h>
1.1.1.4   root       75: #ifdef MACH_XEN
                     76: #include <xen/console.h>
                     77: #include <xen/store.h>
                     78: #include <xen/evt.h>
                     79: #include <xen/xen.h>
                     80: #endif /* MACH_XEN */
1.1       root       81: 
1.1.1.6   root       82: #if    ENABLE_IMMEDIATE_CONSOLE
                     83: #include "immc.h"
                     84: #endif /* ENABLE_IMMEDIATE_CONSOLE */
                     85: 
1.1       root       86: /* Location of the kernel's symbol table.
                     87:    Both of these are 0 if none is available.  */
                     88: #if MACH_KDB
1.1.1.5   root       89: #include <ddb/db_sym.h>
                     90: #include <i386/db_interface.h>
                     91: 
                     92: /* a.out symbol table */
1.1       root       93: static vm_offset_t kern_sym_start, kern_sym_end;
1.1.1.5   root       94: 
                     95: /* ELF section header */
                     96: static unsigned elf_shdr_num;
                     97: static vm_size_t elf_shdr_size;
                     98: static vm_offset_t elf_shdr_addr;
                     99: static unsigned elf_shdr_shndx;
                    100: 
                    101: #else /* MACH_KDB */
1.1       root      102: #define kern_sym_start 0
                    103: #define kern_sym_end   0
1.1.1.5   root      104: #endif /* MACH_KDB */
1.1       root      105: 
1.1.1.6   root      106: #define RESERVED_BIOS 0x10000
                    107: 
1.1       root      108: /* These indicate the total extent of physical memory addresses we're using.
                    109:    They are page-aligned.  */
                    110: vm_offset_t phys_first_addr = 0;
                    111: vm_offset_t phys_last_addr;
                    112: 
1.1.1.3   root      113: /* A copy of the multiboot info structure passed by the boot loader.  */
1.1.1.4   root      114: #ifdef MACH_XEN
                    115: struct start_info boot_info;
                    116: #ifdef MACH_PSEUDO_PHYS
                    117: unsigned long *mfn_list;
                    118: #if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    119: unsigned long *pfn_list = (void*) PFN_LIST;
                    120: #endif
                    121: #endif /* MACH_PSEUDO_PHYS */
                    122: #if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    123: unsigned long la_shift = VM_MIN_KERNEL_ADDRESS;
                    124: #endif
                    125: #else  /* MACH_XEN */
1.1.1.3   root      126: struct multiboot_info boot_info;
1.1.1.4   root      127: #endif /* MACH_XEN */
1.1       root      128: 
                    129: /* Command line supplied to kernel.  */
                    130: char *kernel_cmdline = "";
                    131: 
                    132: extern char    version[];
                    133: 
1.1.1.6   root      134: /* If set, reboot the system on ctrl-alt-delete.  */
1.1.1.5   root      135: boolean_t      rebootflag = FALSE;     /* exported to kdintr */
1.1       root      136: 
1.1.1.7 ! root      137: /* Interrupt stack.  */
        !           138: static char int_stack[KERNEL_STACK_SIZE] __aligned(KERNEL_STACK_SIZE);
        !           139: vm_offset_t int_stack_top, int_stack_base;
1.1       root      140: 
                    141: #ifdef LINUX_DEV
                    142: extern void linux_init(void);
                    143: #endif
                    144: 
                    145: /*
                    146:  * Find devices.  The system is alive.
                    147:  */
1.1.1.4   root      148: void machine_init(void)
1.1       root      149: {
                    150:        /*
                    151:         * Initialize the console.
                    152:         */
                    153:        cninit();
                    154: 
                    155:        /*
                    156:         * Set up to use floating point.
                    157:         */
                    158:        init_fpu();
                    159: 
1.1.1.4   root      160: #ifdef MACH_HYP
                    161:        hyp_init();
                    162: #else  /* MACH_HYP */
1.1       root      163: #ifdef LINUX_DEV
                    164:        /*
                    165:         * Initialize Linux drivers.
                    166:         */
                    167:        linux_init();
                    168: #endif
                    169: 
                    170:        /*
                    171:         * Find the devices
                    172:         */
                    173:        probeio();
1.1.1.4   root      174: #endif /* MACH_HYP */
1.1       root      175: 
                    176:        /*
                    177:         * Get the time
                    178:         */
                    179:        inittodr();
                    180: 
1.1.1.4   root      181: #ifndef MACH_HYP
1.1       root      182:        /*
                    183:         * Tell the BIOS not to clear and test memory.
                    184:         */
                    185:        *(unsigned short *)phystokv(0x472) = 0x1234;
1.1.1.4   root      186: #endif /* MACH_HYP */
1.1       root      187: 
1.1.1.5   root      188: #if VM_MIN_KERNEL_ADDRESS == 0
1.1       root      189:        /*
                    190:         * Unmap page 0 to trap NULL references.
1.1.1.5   root      191:         *
                    192:         * Note that this breaks accessing some BIOS areas stored there.
1.1       root      193:         */
                    194:        pmap_unmap_page_zero();
1.1.1.5   root      195: #endif
1.1       root      196: }
                    197: 
1.1.1.3   root      198: /* Conserve power on processor CPU.  */
                    199: void machine_idle (int cpu)
                    200: {
1.1.1.4   root      201: #ifdef MACH_HYP
                    202:   hyp_idle();
                    203: #else  /* MACH_HYP */
1.1.1.3   root      204:   assert (cpu == cpu_number ());
                    205:   asm volatile ("hlt" : : : "memory");
1.1.1.4   root      206: #endif /* MACH_HYP */
                    207: }
                    208: 
1.1.1.5   root      209: void machine_relax (void)
1.1.1.4   root      210: {
                    211:        asm volatile ("rep; nop" : : : "memory");
1.1.1.3   root      212: }
                    213: 
1.1       root      214: /*
                    215:  * Halt a cpu.
                    216:  */
1.1.1.3   root      217: void halt_cpu(void)
1.1       root      218: {
1.1.1.4   root      219: #ifdef MACH_HYP
                    220:        hyp_halt();
                    221: #else  /* MACH_HYP */
1.1       root      222:        asm volatile("cli");
1.1.1.4   root      223:        while (TRUE)
                    224:          machine_idle (cpu_number ());
                    225: #endif /* MACH_HYP */
1.1       root      226: }
                    227: 
                    228: /*
                    229:  * Halt the system or reboot.
                    230:  */
1.1.1.5   root      231: void halt_all_cpus(boolean_t reboot)
1.1       root      232: {
                    233:        if (reboot) {
1.1.1.4   root      234: #ifdef MACH_HYP
                    235:            hyp_reboot();
                    236: #endif /* MACH_HYP */
1.1       root      237:            kdreboot();
                    238:        }
                    239:        else {
1.1.1.5   root      240:            rebootflag = TRUE;
1.1.1.4   root      241: #ifdef MACH_HYP
                    242:            hyp_halt();
                    243: #endif /* MACH_HYP */
1.1.1.5   root      244:            grub_acpi_halt();
1.1       root      245:            printf("In tight loop: hit ctl-alt-del to reboot\n");
                    246:            (void) spl0();
                    247:        }
1.1.1.4   root      248:        while (TRUE)
                    249:          machine_idle (cpu_number ());
1.1       root      250: }
                    251: 
                    252: void exit(int rc)
                    253: {
                    254:        halt_all_cpus(0);
                    255: }
                    256: 
1.1.1.5   root      257: void db_halt_cpu(void)
                    258: {
                    259:        halt_all_cpus(0);
                    260: }
                    261: 
1.1.1.4   root      262: void db_reset_cpu(void)
1.1       root      263: {
                    264:        halt_all_cpus(1);
                    265: }
                    266: 
                    267: /*
                    268:  * Basic PC VM initialization.
                    269:  * Turns on paging and changes the kernel segments to use high linear addresses.
                    270:  */
1.1.1.4   root      271: void
                    272: i386at_init(void)
1.1       root      273: {
                    274:        /* XXX move to intel/pmap.h */
                    275:        extern pt_entry_t *kernel_page_dir;
1.1.1.4   root      276:        int nb_direct, i;
                    277:        vm_offset_t addr, delta;
1.1       root      278: 
                    279:        /*
                    280:         * Initialize the PIC prior to any possible call to an spl.
                    281:         */
1.1.1.4   root      282: #ifndef        MACH_HYP
1.1       root      283:        picinit();
1.1.1.4   root      284: #else  /* MACH_HYP */
                    285:        hyp_intrinit();
                    286: #endif /* MACH_HYP */
1.1       root      287: 
                    288:        /*
1.1.1.7 ! root      289:         * Read memory map and load it into the physical page allocator.
1.1       root      290:         */
1.1.1.7 ! root      291: #ifdef MACH_HYP
        !           292:        biosmem_xen_bootstrap();
        !           293: #else /* MACH_HYP */
        !           294:        biosmem_bootstrap((struct multiboot_raw_info *) &boot_info);
        !           295: #endif /* MACH_HYP */
1.1       root      296: 
1.1.1.4   root      297: #ifdef MACH_XEN
                    298:        kernel_cmdline = (char*) boot_info.cmd_line;
                    299: #else  /* MACH_XEN */
                    300:        /* Copy content pointed by boot_info before losing access to it when it
                    301:         * is too far in physical memory.  */
                    302:        if (boot_info.flags & MULTIBOOT_CMDLINE) {
                    303:                int len = strlen ((char*)phystokv(boot_info.cmdline)) + 1;
1.1.1.7 ! root      304:                if (! init_alloc_aligned(round_page(len), &addr))
        !           305:                  panic("could not allocate memory for multiboot command line");
1.1.1.4   root      306:                kernel_cmdline = (char*) phystokv(addr);
1.1.1.5   root      307:                memcpy(kernel_cmdline, (void *)phystokv(boot_info.cmdline), len);
1.1.1.4   root      308:                boot_info.cmdline = addr;
                    309:        }
                    310: 
                    311:        if (boot_info.flags & MULTIBOOT_MODS) {
                    312:                struct multiboot_module *m;
                    313:                int i;
                    314: 
1.1.1.7 ! root      315:                if (! init_alloc_aligned(
        !           316:                        round_page(boot_info.mods_count * sizeof(*m)), &addr))
        !           317:                  panic("could not allocate memory for multiboot modules");
1.1.1.4   root      318:                m = (void*) phystokv(addr);
                    319:                memcpy(m, (void*) phystokv(boot_info.mods_addr), boot_info.mods_count * sizeof(*m));
                    320:                boot_info.mods_addr = addr;
                    321: 
                    322:                for (i = 0; i < boot_info.mods_count; i++) {
                    323:                        vm_size_t size = m[i].mod_end - m[i].mod_start;
1.1.1.7 ! root      324:                        if (! init_alloc_aligned(round_page(size), &addr))
        !           325:                          panic("could not allocate memory for multiboot "
        !           326:                                "module %d", i);
1.1.1.4   root      327:                        memcpy((void*) phystokv(addr), (void*) phystokv(m[i].mod_start), size);
                    328:                        m[i].mod_start = addr;
                    329:                        m[i].mod_end = addr + size;
                    330: 
                    331:                        size = strlen((char*) phystokv(m[i].string)) + 1;
1.1.1.7 ! root      332:                        if (! init_alloc_aligned(round_page(size), &addr))
        !           333:                          panic("could not allocate memory for multiboot "
        !           334:                                "module command line %d", i);
1.1.1.4   root      335:                        memcpy((void*) phystokv(addr), (void*) phystokv(m[i].string), size);
                    336:                        m[i].string = addr;
                    337:                }
                    338:        }
                    339: #endif /* MACH_XEN */
                    340: 
1.1       root      341:        /*
                    342:         *      Initialize kernel physical map, mapping the
                    343:         *      region from loadpt to avail_start.
                    344:         *      Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
                    345:         *      XXX make the BIOS page (page 0) read-only.
                    346:         */
                    347:        pmap_bootstrap();
                    348: 
                    349:        /*
1.1.1.7 ! root      350:         *      Load physical segments into the VM system.
        !           351:         *      The early allocation functions become unusable after
        !           352:         *      this point.
        !           353:         */
        !           354:        biosmem_setup();
        !           355: 
        !           356:        /*
1.1       root      357:         * We'll have to temporarily install a direct mapping
                    358:         * between physical memory and low linear memory,
                    359:         * until we start using our new kernel segment descriptors.
                    360:         */
1.1.1.4   root      361: #if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    362:        delta = INIT_VM_MIN_KERNEL_ADDRESS - LINEAR_MIN_KERNEL_ADDRESS;
                    363:        if ((vm_offset_t)(-delta) < delta)
                    364:                delta = (vm_offset_t)(-delta);
                    365:        nb_direct = delta >> PDESHIFT;
                    366:        for (i = 0; i < nb_direct; i++)
                    367:                kernel_page_dir[lin2pdenum(INIT_VM_MIN_KERNEL_ADDRESS) + i] =
                    368:                        kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS) + i];
                    369: #endif
                    370:        /* We need BIOS memory mapped at 0xc0000 & co for Linux drivers */
                    371: #ifdef LINUX_DEV
                    372: #if VM_MIN_KERNEL_ADDRESS != 0
                    373:        kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] =
1.1       root      374:                kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS)];
1.1.1.4   root      375: #endif
                    376: #endif
                    377: 
                    378: #ifdef MACH_PV_PAGETABLES
                    379:        for (i = 0; i < PDPNUM; i++)
                    380:                pmap_set_page_readonly_init((void*) kernel_page_dir + i * INTEL_PGBYTES);
                    381: #if PAE
                    382:        pmap_set_page_readonly_init(kernel_pmap->pdpbase);
                    383: #endif /* PAE */
                    384: #endif /* MACH_PV_PAGETABLES */
                    385: #if PAE
                    386:        set_cr3((unsigned)_kvtophys(kernel_pmap->pdpbase));
                    387: #ifndef        MACH_HYP
                    388:        if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE))
                    389:                panic("CPU doesn't have support for PAE.");
                    390:        set_cr4(get_cr4() | CR4_PAE);
                    391: #endif /* MACH_HYP */
                    392: #else
                    393:        set_cr3((unsigned)_kvtophys(kernel_page_dir));
                    394: #endif /* PAE */
                    395: #ifndef        MACH_HYP
                    396:        /* Turn paging on.
                    397:         * Also set the WP bit so that on 486 or better processors
                    398:         * page-level write protection works in kernel mode.
                    399:         */
1.1       root      400:        set_cr0(get_cr0() | CR0_PG | CR0_WP);
1.1.1.4   root      401:        set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));
                    402:        if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
                    403:                set_cr4(get_cr4() | CR4_PGE);
                    404: #endif /* MACH_HYP */
1.1       root      405:        flush_instr_queue();
1.1.1.4   root      406: #ifdef MACH_PV_PAGETABLES
                    407:        pmap_clear_bootstrap_pagetable((void *)boot_info.pt_base);
                    408: #endif /* MACH_PV_PAGETABLES */
                    409: 
1.1       root      410:        /*
                    411:         * Initialize and activate the real i386 protected-mode structures.
                    412:         */
                    413:        gdt_init();
                    414:        idt_init();
1.1.1.4   root      415: #ifndef        MACH_HYP
1.1       root      416:        int_init();
1.1.1.4   root      417: #endif /* MACH_HYP */
1.1       root      418:        ldt_init();
                    419:        ktss_init();
                    420: 
1.1.1.4   root      421: #if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
1.1       root      422:        /* Get rid of the temporary direct mapping and flush it out of the TLB.  */
1.1.1.4   root      423:        for (i = 0 ; i < nb_direct; i++) {
                    424: #ifdef MACH_XEN
                    425: #ifdef MACH_PSEUDO_PHYS
                    426:                if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + i]), 0))
                    427: #else  /* MACH_PSEUDO_PHYS */
                    428:                if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL))
                    429: #endif /* MACH_PSEUDO_PHYS */
                    430:                        printf("couldn't unmap frame %d\n", i);
                    431: #else  /* MACH_XEN */
                    432:                kernel_page_dir[lin2pdenum(INIT_VM_MIN_KERNEL_ADDRESS) + i] = 0;
                    433: #endif /* MACH_XEN */
                    434:        }
                    435: #endif
                    436:        /* Keep BIOS memory mapped */
                    437: #ifdef LINUX_DEV
                    438: #if VM_MIN_KERNEL_ADDRESS != 0
                    439:        kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] =
                    440:                kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS)];
                    441: #endif
                    442: #endif
1.1       root      443: 
1.1.1.4   root      444:        /* Not used after boot, better give it back.  */
                    445: #ifdef MACH_XEN
                    446:        hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS);
                    447: #endif /* MACH_XEN */
                    448: 
                    449:        flush_tlb();
                    450: 
                    451: #ifdef MACH_XEN
                    452:        hyp_p2m_init();
                    453: #endif /* MACH_XEN */
1.1       root      454: 
1.1.1.7 ! root      455:        int_stack_base = (vm_offset_t)&int_stack;
        !           456:        int_stack_top = int_stack_base + KERNEL_STACK_SIZE - 4;
1.1       root      457: }
                    458: 
                    459: /*
                    460:  *     C boot entrypoint - called by boot_entry in boothdr.S.
                    461:  *     Running in 32-bit flat mode, but without paging yet.
                    462:  */
                    463: void c_boot_entry(vm_offset_t bi)
                    464: {
1.1.1.6   root      465: #if    ENABLE_IMMEDIATE_CONSOLE
                    466:        romputc = immc_romputc;
                    467: #endif /* ENABLE_IMMEDIATE_CONSOLE */
                    468: 
1.1       root      469:        /* Stash the boot_image_info pointer.  */
1.1.1.4   root      470:        boot_info = *(typeof(boot_info)*)phystokv(bi);
                    471:        int cpu_type;
1.1       root      472: 
                    473:        /* Before we do _anything_ else, print the hello message.
                    474:           If there are no initialized console devices yet,
                    475:           it will be stored and printed at the first opportunity.  */
1.1.1.4   root      476:        printf("%s", version);
1.1       root      477:        printf("\n");
                    478: 
1.1.1.4   root      479: #ifdef MACH_XEN
                    480:        printf("Running on %s.\n", boot_info.magic);
                    481:        if (boot_info.flags & SIF_PRIVILEGED)
                    482:                panic("Mach can't run as dom0.");
                    483: #ifdef MACH_PSEUDO_PHYS
                    484:        mfn_list = (void*)boot_info.mfn_list;
                    485: #endif
                    486: #else  /* MACH_XEN */
1.1       root      487: 
                    488: #if    MACH_KDB
                    489:        /*
                    490:         * Locate the kernel's symbol table, if the boot loader provided it.
                    491:         * We need to do this before i386at_init()
                    492:         * so that the symbol table's memory won't be stomped on.
                    493:         */
1.1.1.3   root      494:        if ((boot_info.flags & MULTIBOOT_AOUT_SYMS)
                    495:            && boot_info.syms.a.addr)
1.1       root      496:        {
                    497:                vm_size_t symtab_size, strtab_size;
                    498: 
1.1.1.3   root      499:                kern_sym_start = (vm_offset_t)phystokv(boot_info.syms.a.addr);
                    500:                symtab_size = (vm_offset_t)phystokv(boot_info.syms.a.tabsize);
                    501:                strtab_size = (vm_offset_t)phystokv(boot_info.syms.a.strsize);
1.1       root      502:                kern_sym_end = kern_sym_start + 4 + symtab_size + strtab_size;
                    503: 
1.1.1.4   root      504:                printf("kernel symbol table at %08lx-%08lx (%d,%d)\n",
1.1       root      505:                       kern_sym_start, kern_sym_end,
                    506:                       symtab_size, strtab_size);
                    507:        }
1.1.1.5   root      508: 
                    509:        if ((boot_info.flags & MULTIBOOT_ELF_SHDR)
                    510:            && boot_info.syms.e.num)
                    511:        {
                    512:                elf_shdr_num = boot_info.syms.e.num;
                    513:                elf_shdr_size = boot_info.syms.e.size;
                    514:                elf_shdr_addr = (vm_offset_t)phystokv(boot_info.syms.e.addr);
                    515:                elf_shdr_shndx = boot_info.syms.e.shndx;
                    516: 
                    517:                printf("ELF section header table at %08lx\n", elf_shdr_addr);
                    518:        }
1.1.1.3   root      519: #endif /* MACH_KDB */
1.1.1.4   root      520: #endif /* MACH_XEN */
                    521: 
                    522:        cpu_type = discover_x86_cpu_type ();
1.1       root      523: 
                    524:        /*
                    525:         * Do basic VM initialization
                    526:         */
                    527:        i386at_init();
                    528: 
                    529: #if    MACH_KDB
                    530:        /*
                    531:         * Initialize the kernel debugger's kernel symbol table.
                    532:         */
                    533:        if (kern_sym_start)
                    534:        {
1.1.1.5   root      535:                aout_db_sym_init((char *)kern_sym_start, (char *)kern_sym_end, "mach", (char *)0);
                    536:        }
                    537: 
                    538:        if (elf_shdr_num)
                    539:        {
                    540:                elf_db_sym_init(elf_shdr_num,elf_shdr_size,
                    541:                                elf_shdr_addr, elf_shdr_shndx,
                    542:                                "mach", NULL);
1.1       root      543:        }
1.1.1.3   root      544: #endif /* MACH_KDB */
1.1       root      545: 
                    546:        machine_slot[0].is_cpu = TRUE;
                    547:        machine_slot[0].running = TRUE;
                    548:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_AT386;
                    549: 
1.1.1.4   root      550:        switch (cpu_type)
1.1.1.2   root      551:          {
                    552:          default:
1.1.1.4   root      553:            printf("warning: unknown cpu type %d, assuming i386\n", cpu_type);
                    554:          case 3:
1.1.1.2   root      555:            machine_slot[0].cpu_type = CPU_TYPE_I386;
                    556:            break;
                    557:          case 4:
                    558:            machine_slot[0].cpu_type = CPU_TYPE_I486;
                    559:            break;
                    560:          case 5:
                    561:            machine_slot[0].cpu_type = CPU_TYPE_PENTIUM;
                    562:            break;
                    563:          case 6:
1.1.1.4   root      564:          case 15:
1.1.1.2   root      565:            machine_slot[0].cpu_type = CPU_TYPE_PENTIUMPRO;
                    566:            break;
                    567:          }
                    568: 
1.1       root      569:        /*
                    570:         * Start the system.
                    571:         */
                    572:        setup_main();
                    573: 
                    574: }
                    575: 
                    576: #include <mach/vm_prot.h>
                    577: #include <vm/pmap.h>
                    578: #include <mach/time_value.h>
                    579: 
1.1.1.4   root      580: int
1.1.1.5   root      581: timemmap(dev, off, prot)
                    582:        dev_t dev;
                    583:        vm_offset_t off;
1.1       root      584:        vm_prot_t prot;
                    585: {
                    586:        extern time_value_t *mtime;
                    587: 
                    588:        if (prot & VM_PROT_WRITE) return (-1);
                    589: 
                    590:        return (i386_btop(pmap_extract(pmap_kernel(), (vm_offset_t) mtime)));
                    591: }
                    592: 
1.1.1.4   root      593: void
                    594: startrtclock(void)
1.1       root      595: {
                    596:        clkstart();
                    597: }
                    598: 
                    599: void
1.1.1.4   root      600: inittodr(void)
1.1       root      601: {
                    602:        time_value_t    new_time;
                    603: 
                    604:        new_time.seconds = 0;
                    605:        new_time.microseconds = 0;
                    606: 
1.1.1.4   root      607:        (void) readtodc((u_int *)&new_time.seconds);
1.1       root      608: 
                    609:        {
                    610:            spl_t       s = splhigh();
                    611:            time = new_time;
                    612:            splx(s);
                    613:        }
                    614: }
                    615: 
                    616: void
1.1.1.4   root      617: resettodr(void)
1.1       root      618: {
                    619:        writetodc();
                    620: }
                    621: 
1.1.1.4   root      622: unsigned int pmap_free_pages(void)
1.1       root      623: {
1.1.1.7 ! root      624:        return vm_page_atop(phys_last_addr); /* XXX */
1.1       root      625: }
                    626: 
1.1.1.4   root      627: boolean_t
1.1       root      628: init_alloc_aligned(vm_size_t size, vm_offset_t *addrp)
                    629: {
1.1.1.7 ! root      630:        *addrp = biosmem_bootalloc(vm_page_atop(vm_page_round(size)));
1.1       root      631: 
1.1.1.7 ! root      632:        if (*addrp == 0)
1.1       root      633:                return FALSE;
                    634: 
                    635:        return TRUE;
                    636: }
                    637: 
                    638: /* Grab a physical page:
                    639:    the standard memory allocation mechanism
                    640:    during system initialization.  */
                    641: vm_offset_t
1.1.1.4   root      642: pmap_grab_page(void)
1.1       root      643: {
                    644:        vm_offset_t addr;
1.1.1.7 ! root      645:        if (!init_alloc_aligned(PAGE_SIZE, &addr))
1.1       root      646:                panic("Not enough memory to initialize Mach");
                    647:        return addr;
                    648: }
                    649: 
1.1.1.5   root      650: boolean_t pmap_valid_page(vm_offset_t x)
1.1       root      651: {
                    652:        /* XXX is this OK?  What does it matter for?  */
1.1.1.4   root      653:        return (((phys_first_addr <= x) && (x < phys_last_addr))
                    654: #ifndef MACH_HYP
                    655:                && !(
                    656:                ((boot_info.mem_lower * 1024) <= x) && 
                    657:                (x < 1024*1024))
                    658: #endif /* MACH_HYP */
                    659:                );
1.1       root      660: }

unix.superglobalmegacorp.com

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