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

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.8 ! root       69: #include <i386at/elf.h>
1.1.1.4   root       70: #include <i386at/idt.h>
                     71: #include <i386at/int_init.h>
                     72: #include <i386at/kd.h>
                     73: #include <i386at/rtc.h>
1.1.1.5   root       74: #include <i386at/model_dep.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.1.3   root      108: /* A copy of the multiboot info structure passed by the boot loader.  */
1.1.1.4   root      109: #ifdef MACH_XEN
                    110: struct start_info boot_info;
                    111: #ifdef MACH_PSEUDO_PHYS
                    112: unsigned long *mfn_list;
                    113: #if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    114: unsigned long *pfn_list = (void*) PFN_LIST;
                    115: #endif
                    116: #endif /* MACH_PSEUDO_PHYS */
                    117: #if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    118: unsigned long la_shift = VM_MIN_KERNEL_ADDRESS;
                    119: #endif
                    120: #else  /* MACH_XEN */
1.1.1.3   root      121: struct multiboot_info boot_info;
1.1.1.4   root      122: #endif /* MACH_XEN */
1.1       root      123: 
                    124: /* Command line supplied to kernel.  */
                    125: char *kernel_cmdline = "";
                    126: 
                    127: extern char    version[];
                    128: 
1.1.1.6   root      129: /* If set, reboot the system on ctrl-alt-delete.  */
1.1.1.5   root      130: boolean_t      rebootflag = FALSE;     /* exported to kdintr */
1.1       root      131: 
1.1.1.7   root      132: /* Interrupt stack.  */
                    133: static char int_stack[KERNEL_STACK_SIZE] __aligned(KERNEL_STACK_SIZE);
                    134: vm_offset_t int_stack_top, int_stack_base;
1.1       root      135: 
                    136: #ifdef LINUX_DEV
                    137: extern void linux_init(void);
                    138: #endif
                    139: 
                    140: /*
                    141:  * Find devices.  The system is alive.
                    142:  */
1.1.1.4   root      143: void machine_init(void)
1.1       root      144: {
                    145:        /*
                    146:         * Initialize the console.
                    147:         */
                    148:        cninit();
                    149: 
                    150:        /*
1.1.1.8 ! root      151:         * Make more free memory.
        !           152:         *
        !           153:         * This is particularly important for the Linux drivers which
        !           154:         * require available DMA memory.
        !           155:         */
        !           156:        biosmem_free_usable();
        !           157: 
        !           158:        /*
1.1       root      159:         * Set up to use floating point.
                    160:         */
                    161:        init_fpu();
                    162: 
1.1.1.4   root      163: #ifdef MACH_HYP
                    164:        hyp_init();
                    165: #else  /* MACH_HYP */
1.1       root      166: #ifdef LINUX_DEV
                    167:        /*
                    168:         * Initialize Linux drivers.
                    169:         */
                    170:        linux_init();
                    171: #endif
                    172: 
                    173:        /*
                    174:         * Find the devices
                    175:         */
                    176:        probeio();
1.1.1.4   root      177: #endif /* MACH_HYP */
1.1       root      178: 
                    179:        /*
                    180:         * Get the time
                    181:         */
                    182:        inittodr();
                    183: 
1.1.1.4   root      184: #ifndef MACH_HYP
1.1       root      185:        /*
                    186:         * Tell the BIOS not to clear and test memory.
                    187:         */
                    188:        *(unsigned short *)phystokv(0x472) = 0x1234;
1.1.1.4   root      189: #endif /* MACH_HYP */
1.1       root      190: 
1.1.1.5   root      191: #if VM_MIN_KERNEL_ADDRESS == 0
1.1       root      192:        /*
                    193:         * Unmap page 0 to trap NULL references.
1.1.1.5   root      194:         *
                    195:         * Note that this breaks accessing some BIOS areas stored there.
1.1       root      196:         */
                    197:        pmap_unmap_page_zero();
1.1.1.5   root      198: #endif
1.1       root      199: }
                    200: 
1.1.1.3   root      201: /* Conserve power on processor CPU.  */
                    202: void machine_idle (int cpu)
                    203: {
1.1.1.4   root      204: #ifdef MACH_HYP
                    205:   hyp_idle();
                    206: #else  /* MACH_HYP */
1.1.1.3   root      207:   assert (cpu == cpu_number ());
                    208:   asm volatile ("hlt" : : : "memory");
1.1.1.4   root      209: #endif /* MACH_HYP */
                    210: }
                    211: 
1.1.1.5   root      212: void machine_relax (void)
1.1.1.4   root      213: {
                    214:        asm volatile ("rep; nop" : : : "memory");
1.1.1.3   root      215: }
                    216: 
1.1       root      217: /*
                    218:  * Halt a cpu.
                    219:  */
1.1.1.3   root      220: void halt_cpu(void)
1.1       root      221: {
1.1.1.4   root      222: #ifdef MACH_HYP
                    223:        hyp_halt();
                    224: #else  /* MACH_HYP */
1.1       root      225:        asm volatile("cli");
1.1.1.4   root      226:        while (TRUE)
                    227:          machine_idle (cpu_number ());
                    228: #endif /* MACH_HYP */
1.1       root      229: }
                    230: 
                    231: /*
                    232:  * Halt the system or reboot.
                    233:  */
1.1.1.5   root      234: void halt_all_cpus(boolean_t reboot)
1.1       root      235: {
                    236:        if (reboot) {
1.1.1.4   root      237: #ifdef MACH_HYP
                    238:            hyp_reboot();
                    239: #endif /* MACH_HYP */
1.1       root      240:            kdreboot();
                    241:        }
                    242:        else {
1.1.1.5   root      243:            rebootflag = TRUE;
1.1.1.4   root      244: #ifdef MACH_HYP
                    245:            hyp_halt();
                    246: #endif /* MACH_HYP */
1.1       root      247:            printf("In tight loop: hit ctl-alt-del to reboot\n");
                    248:            (void) spl0();
                    249:        }
1.1.1.4   root      250:        while (TRUE)
                    251:          machine_idle (cpu_number ());
1.1       root      252: }
                    253: 
                    254: void exit(int rc)
                    255: {
                    256:        halt_all_cpus(0);
                    257: }
                    258: 
1.1.1.5   root      259: void db_halt_cpu(void)
                    260: {
                    261:        halt_all_cpus(0);
                    262: }
                    263: 
1.1.1.4   root      264: void db_reset_cpu(void)
1.1       root      265: {
                    266:        halt_all_cpus(1);
                    267: }
                    268: 
1.1.1.8 ! root      269: #ifndef        MACH_HYP
        !           270: 
        !           271: static void
        !           272: register_boot_data(const struct multiboot_raw_info *mbi)
        !           273: {
        !           274:        struct multiboot_raw_module *mod;
        !           275:        struct elf_shdr *shdr;
        !           276:        unsigned long tmp;
        !           277:        unsigned int i;
        !           278: 
        !           279:        extern char _start[], _end[];
        !           280: 
        !           281:        biosmem_register_boot_data(_kvtophys(&_start), _kvtophys(&_end), FALSE);
        !           282: 
        !           283:        /* cmdline and modules are moved to a safe place by i386at_init.  */
        !           284: 
        !           285:        if ((mbi->flags & MULTIBOOT_LOADER_CMDLINE) && (mbi->cmdline != 0)) {
        !           286:                biosmem_register_boot_data(mbi->cmdline,
        !           287:                                           mbi->cmdline
        !           288:                                           + strlen((void *)phystokv(mbi->cmdline)) + 1, TRUE);
        !           289:        }
        !           290: 
        !           291:        if (mbi->flags & MULTIBOOT_LOADER_MODULES) {
        !           292:                i = mbi->mods_count * sizeof(struct multiboot_raw_module);
        !           293:                biosmem_register_boot_data(mbi->mods_addr, mbi->mods_addr + i, TRUE);
        !           294: 
        !           295:                tmp = phystokv(mbi->mods_addr);
        !           296: 
        !           297:                for (i = 0; i < mbi->mods_count; i++) {
        !           298:                        mod = (struct multiboot_raw_module *)tmp + i;
        !           299:                        biosmem_register_boot_data(mod->mod_start, mod->mod_end, TRUE);
        !           300: 
        !           301:                        if (mod->string != 0) {
        !           302:                                biosmem_register_boot_data(mod->string,
        !           303:                                                           mod->string
        !           304:                                                           + strlen((void *)phystokv(mod->string)) + 1,
        !           305:                                                           TRUE);
        !           306:                        }
        !           307:                }
        !           308:        }
        !           309: 
        !           310:        if (mbi->flags & MULTIBOOT_LOADER_SHDR) {
        !           311:                tmp = mbi->shdr_num * mbi->shdr_size;
        !           312:                biosmem_register_boot_data(mbi->shdr_addr, mbi->shdr_addr + tmp, FALSE);
        !           313: 
        !           314:                tmp = phystokv(mbi->shdr_addr);
        !           315: 
        !           316:                for (i = 0; i < mbi->shdr_num; i++) {
        !           317:                        shdr = (struct elf_shdr *)(tmp + (i * mbi->shdr_size));
        !           318: 
        !           319:                        if ((shdr->type != ELF_SHT_SYMTAB)
        !           320:                            && (shdr->type != ELF_SHT_STRTAB))
        !           321:                                continue;
        !           322: 
        !           323:                        biosmem_register_boot_data(shdr->addr, shdr->addr + shdr->size, FALSE);
        !           324:                }
        !           325:        }
        !           326: }
        !           327: 
        !           328: #endif /* MACH_HYP */
        !           329: 
1.1       root      330: /*
                    331:  * Basic PC VM initialization.
                    332:  * Turns on paging and changes the kernel segments to use high linear addresses.
                    333:  */
1.1.1.4   root      334: void
                    335: i386at_init(void)
1.1       root      336: {
                    337:        /* XXX move to intel/pmap.h */
                    338:        extern pt_entry_t *kernel_page_dir;
1.1.1.4   root      339:        int nb_direct, i;
                    340:        vm_offset_t addr, delta;
1.1       root      341: 
                    342:        /*
                    343:         * Initialize the PIC prior to any possible call to an spl.
                    344:         */
1.1.1.4   root      345: #ifndef        MACH_HYP
1.1       root      346:        picinit();
1.1.1.4   root      347: #else  /* MACH_HYP */
                    348:        hyp_intrinit();
                    349: #endif /* MACH_HYP */
1.1       root      350: 
                    351:        /*
1.1.1.7   root      352:         * Read memory map and load it into the physical page allocator.
1.1       root      353:         */
1.1.1.7   root      354: #ifdef MACH_HYP
                    355:        biosmem_xen_bootstrap();
                    356: #else /* MACH_HYP */
1.1.1.8 ! root      357:        register_boot_data((struct multiboot_raw_info *) &boot_info);
1.1.1.7   root      358:        biosmem_bootstrap((struct multiboot_raw_info *) &boot_info);
                    359: #endif /* MACH_HYP */
1.1       root      360: 
1.1.1.4   root      361: #ifdef MACH_XEN
                    362:        kernel_cmdline = (char*) boot_info.cmd_line;
                    363: #else  /* MACH_XEN */
                    364:        /* Copy content pointed by boot_info before losing access to it when it
1.1.1.8 ! root      365:         * is too far in physical memory.
        !           366:         * Also avoids leaving them in precious areas such as DMA memory.  */
1.1.1.4   root      367:        if (boot_info.flags & MULTIBOOT_CMDLINE) {
                    368:                int len = strlen ((char*)phystokv(boot_info.cmdline)) + 1;
1.1.1.7   root      369:                if (! init_alloc_aligned(round_page(len), &addr))
                    370:                  panic("could not allocate memory for multiboot command line");
1.1.1.4   root      371:                kernel_cmdline = (char*) phystokv(addr);
1.1.1.5   root      372:                memcpy(kernel_cmdline, (void *)phystokv(boot_info.cmdline), len);
1.1.1.4   root      373:                boot_info.cmdline = addr;
                    374:        }
                    375: 
                    376:        if (boot_info.flags & MULTIBOOT_MODS) {
                    377:                struct multiboot_module *m;
                    378:                int i;
                    379: 
1.1.1.7   root      380:                if (! init_alloc_aligned(
                    381:                        round_page(boot_info.mods_count * sizeof(*m)), &addr))
                    382:                  panic("could not allocate memory for multiboot modules");
1.1.1.4   root      383:                m = (void*) phystokv(addr);
                    384:                memcpy(m, (void*) phystokv(boot_info.mods_addr), boot_info.mods_count * sizeof(*m));
                    385:                boot_info.mods_addr = addr;
                    386: 
                    387:                for (i = 0; i < boot_info.mods_count; i++) {
                    388:                        vm_size_t size = m[i].mod_end - m[i].mod_start;
1.1.1.7   root      389:                        if (! init_alloc_aligned(round_page(size), &addr))
                    390:                          panic("could not allocate memory for multiboot "
                    391:                                "module %d", i);
1.1.1.4   root      392:                        memcpy((void*) phystokv(addr), (void*) phystokv(m[i].mod_start), size);
                    393:                        m[i].mod_start = addr;
                    394:                        m[i].mod_end = addr + size;
                    395: 
                    396:                        size = strlen((char*) phystokv(m[i].string)) + 1;
1.1.1.7   root      397:                        if (! init_alloc_aligned(round_page(size), &addr))
                    398:                          panic("could not allocate memory for multiboot "
                    399:                                "module command line %d", i);
1.1.1.4   root      400:                        memcpy((void*) phystokv(addr), (void*) phystokv(m[i].string), size);
                    401:                        m[i].string = addr;
                    402:                }
                    403:        }
                    404: #endif /* MACH_XEN */
                    405: 
1.1       root      406:        /*
                    407:         *      Initialize kernel physical map, mapping the
                    408:         *      region from loadpt to avail_start.
                    409:         *      Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
                    410:         *      XXX make the BIOS page (page 0) read-only.
                    411:         */
                    412:        pmap_bootstrap();
                    413: 
                    414:        /*
1.1.1.7   root      415:         *      Load physical segments into the VM system.
                    416:         *      The early allocation functions become unusable after
                    417:         *      this point.
                    418:         */
                    419:        biosmem_setup();
                    420: 
                    421:        /*
1.1       root      422:         * We'll have to temporarily install a direct mapping
                    423:         * between physical memory and low linear memory,
                    424:         * until we start using our new kernel segment descriptors.
                    425:         */
1.1.1.4   root      426: #if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
                    427:        delta = INIT_VM_MIN_KERNEL_ADDRESS - LINEAR_MIN_KERNEL_ADDRESS;
                    428:        if ((vm_offset_t)(-delta) < delta)
                    429:                delta = (vm_offset_t)(-delta);
                    430:        nb_direct = delta >> PDESHIFT;
                    431:        for (i = 0; i < nb_direct; i++)
1.1.1.8 ! root      432:                kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] =
        !           433:                        kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i];
1.1.1.4   root      434: #endif
                    435:        /* We need BIOS memory mapped at 0xc0000 & co for Linux drivers */
                    436: #ifdef LINUX_DEV
                    437: #if VM_MIN_KERNEL_ADDRESS != 0
1.1.1.8 ! root      438:        kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] =
        !           439:                kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
1.1.1.4   root      440: #endif
                    441: #endif
                    442: 
                    443: #ifdef MACH_PV_PAGETABLES
                    444:        for (i = 0; i < PDPNUM; i++)
                    445:                pmap_set_page_readonly_init((void*) kernel_page_dir + i * INTEL_PGBYTES);
                    446: #if PAE
                    447:        pmap_set_page_readonly_init(kernel_pmap->pdpbase);
                    448: #endif /* PAE */
                    449: #endif /* MACH_PV_PAGETABLES */
                    450: #if PAE
                    451:        set_cr3((unsigned)_kvtophys(kernel_pmap->pdpbase));
                    452: #ifndef        MACH_HYP
                    453:        if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE))
                    454:                panic("CPU doesn't have support for PAE.");
                    455:        set_cr4(get_cr4() | CR4_PAE);
                    456: #endif /* MACH_HYP */
                    457: #else
                    458:        set_cr3((unsigned)_kvtophys(kernel_page_dir));
                    459: #endif /* PAE */
                    460: #ifndef        MACH_HYP
                    461:        /* Turn paging on.
                    462:         * Also set the WP bit so that on 486 or better processors
                    463:         * page-level write protection works in kernel mode.
                    464:         */
1.1       root      465:        set_cr0(get_cr0() | CR0_PG | CR0_WP);
1.1.1.4   root      466:        set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));
                    467:        if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
                    468:                set_cr4(get_cr4() | CR4_PGE);
                    469: #endif /* MACH_HYP */
1.1       root      470:        flush_instr_queue();
1.1.1.4   root      471: #ifdef MACH_PV_PAGETABLES
                    472:        pmap_clear_bootstrap_pagetable((void *)boot_info.pt_base);
                    473: #endif /* MACH_PV_PAGETABLES */
                    474: 
1.1       root      475:        /*
                    476:         * Initialize and activate the real i386 protected-mode structures.
                    477:         */
                    478:        gdt_init();
                    479:        idt_init();
1.1.1.4   root      480: #ifndef        MACH_HYP
1.1       root      481:        int_init();
1.1.1.4   root      482: #endif /* MACH_HYP */
1.1       root      483:        ldt_init();
                    484:        ktss_init();
                    485: 
1.1.1.4   root      486: #if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
1.1       root      487:        /* Get rid of the temporary direct mapping and flush it out of the TLB.  */
1.1.1.4   root      488:        for (i = 0 ; i < nb_direct; i++) {
                    489: #ifdef MACH_XEN
                    490: #ifdef MACH_PSEUDO_PHYS
1.1.1.8 ! root      491:                if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum_cont(VM_MIN_KERNEL_ADDRESS) + i]), 0))
1.1.1.4   root      492: #else  /* MACH_PSEUDO_PHYS */
                    493:                if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL))
                    494: #endif /* MACH_PSEUDO_PHYS */
                    495:                        printf("couldn't unmap frame %d\n", i);
                    496: #else  /* MACH_XEN */
1.1.1.8 ! root      497:                kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] = 0;
1.1.1.4   root      498: #endif /* MACH_XEN */
                    499:        }
                    500: #endif
                    501:        /* Keep BIOS memory mapped */
                    502: #ifdef LINUX_DEV
                    503: #if VM_MIN_KERNEL_ADDRESS != 0
1.1.1.8 ! root      504:        kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] =
        !           505:                kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
1.1.1.4   root      506: #endif
                    507: #endif
1.1       root      508: 
1.1.1.4   root      509:        /* Not used after boot, better give it back.  */
                    510: #ifdef MACH_XEN
                    511:        hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS);
                    512: #endif /* MACH_XEN */
                    513: 
                    514:        flush_tlb();
                    515: 
                    516: #ifdef MACH_XEN
                    517:        hyp_p2m_init();
                    518: #endif /* MACH_XEN */
1.1       root      519: 
1.1.1.7   root      520:        int_stack_base = (vm_offset_t)&int_stack;
                    521:        int_stack_top = int_stack_base + KERNEL_STACK_SIZE - 4;
1.1       root      522: }
                    523: 
                    524: /*
                    525:  *     C boot entrypoint - called by boot_entry in boothdr.S.
                    526:  *     Running in 32-bit flat mode, but without paging yet.
                    527:  */
                    528: void c_boot_entry(vm_offset_t bi)
                    529: {
1.1.1.6   root      530: #if    ENABLE_IMMEDIATE_CONSOLE
                    531:        romputc = immc_romputc;
                    532: #endif /* ENABLE_IMMEDIATE_CONSOLE */
                    533: 
1.1       root      534:        /* Stash the boot_image_info pointer.  */
1.1.1.4   root      535:        boot_info = *(typeof(boot_info)*)phystokv(bi);
                    536:        int cpu_type;
1.1       root      537: 
                    538:        /* Before we do _anything_ else, print the hello message.
                    539:           If there are no initialized console devices yet,
                    540:           it will be stored and printed at the first opportunity.  */
1.1.1.4   root      541:        printf("%s", version);
1.1       root      542:        printf("\n");
                    543: 
1.1.1.4   root      544: #ifdef MACH_XEN
                    545:        printf("Running on %s.\n", boot_info.magic);
                    546:        if (boot_info.flags & SIF_PRIVILEGED)
                    547:                panic("Mach can't run as dom0.");
                    548: #ifdef MACH_PSEUDO_PHYS
                    549:        mfn_list = (void*)boot_info.mfn_list;
                    550: #endif
                    551: #else  /* MACH_XEN */
1.1       root      552: 
                    553: #if    MACH_KDB
                    554:        /*
                    555:         * Locate the kernel's symbol table, if the boot loader provided it.
                    556:         * We need to do this before i386at_init()
                    557:         * so that the symbol table's memory won't be stomped on.
                    558:         */
1.1.1.3   root      559:        if ((boot_info.flags & MULTIBOOT_AOUT_SYMS)
                    560:            && boot_info.syms.a.addr)
1.1       root      561:        {
                    562:                vm_size_t symtab_size, strtab_size;
                    563: 
1.1.1.3   root      564:                kern_sym_start = (vm_offset_t)phystokv(boot_info.syms.a.addr);
                    565:                symtab_size = (vm_offset_t)phystokv(boot_info.syms.a.tabsize);
                    566:                strtab_size = (vm_offset_t)phystokv(boot_info.syms.a.strsize);
1.1       root      567:                kern_sym_end = kern_sym_start + 4 + symtab_size + strtab_size;
                    568: 
1.1.1.4   root      569:                printf("kernel symbol table at %08lx-%08lx (%d,%d)\n",
1.1       root      570:                       kern_sym_start, kern_sym_end,
                    571:                       symtab_size, strtab_size);
                    572:        }
1.1.1.5   root      573: 
                    574:        if ((boot_info.flags & MULTIBOOT_ELF_SHDR)
                    575:            && boot_info.syms.e.num)
                    576:        {
                    577:                elf_shdr_num = boot_info.syms.e.num;
                    578:                elf_shdr_size = boot_info.syms.e.size;
                    579:                elf_shdr_addr = (vm_offset_t)phystokv(boot_info.syms.e.addr);
                    580:                elf_shdr_shndx = boot_info.syms.e.shndx;
                    581: 
                    582:                printf("ELF section header table at %08lx\n", elf_shdr_addr);
                    583:        }
1.1.1.3   root      584: #endif /* MACH_KDB */
1.1.1.4   root      585: #endif /* MACH_XEN */
                    586: 
                    587:        cpu_type = discover_x86_cpu_type ();
1.1       root      588: 
                    589:        /*
                    590:         * Do basic VM initialization
                    591:         */
                    592:        i386at_init();
                    593: 
                    594: #if    MACH_KDB
                    595:        /*
                    596:         * Initialize the kernel debugger's kernel symbol table.
                    597:         */
                    598:        if (kern_sym_start)
                    599:        {
1.1.1.5   root      600:                aout_db_sym_init((char *)kern_sym_start, (char *)kern_sym_end, "mach", (char *)0);
                    601:        }
                    602: 
                    603:        if (elf_shdr_num)
                    604:        {
                    605:                elf_db_sym_init(elf_shdr_num,elf_shdr_size,
                    606:                                elf_shdr_addr, elf_shdr_shndx,
                    607:                                "mach", NULL);
1.1       root      608:        }
1.1.1.3   root      609: #endif /* MACH_KDB */
1.1       root      610: 
                    611:        machine_slot[0].is_cpu = TRUE;
                    612:        machine_slot[0].running = TRUE;
                    613:        machine_slot[0].cpu_subtype = CPU_SUBTYPE_AT386;
                    614: 
1.1.1.4   root      615:        switch (cpu_type)
1.1.1.2   root      616:          {
                    617:          default:
1.1.1.4   root      618:            printf("warning: unknown cpu type %d, assuming i386\n", cpu_type);
                    619:          case 3:
1.1.1.2   root      620:            machine_slot[0].cpu_type = CPU_TYPE_I386;
                    621:            break;
                    622:          case 4:
                    623:            machine_slot[0].cpu_type = CPU_TYPE_I486;
                    624:            break;
                    625:          case 5:
                    626:            machine_slot[0].cpu_type = CPU_TYPE_PENTIUM;
                    627:            break;
                    628:          case 6:
1.1.1.4   root      629:          case 15:
1.1.1.2   root      630:            machine_slot[0].cpu_type = CPU_TYPE_PENTIUMPRO;
                    631:            break;
                    632:          }
                    633: 
1.1       root      634:        /*
                    635:         * Start the system.
                    636:         */
                    637:        setup_main();
                    638: 
                    639: }
                    640: 
                    641: #include <mach/vm_prot.h>
                    642: #include <vm/pmap.h>
                    643: #include <mach/time_value.h>
                    644: 
1.1.1.4   root      645: int
1.1.1.5   root      646: timemmap(dev, off, prot)
                    647:        dev_t dev;
                    648:        vm_offset_t off;
1.1       root      649:        vm_prot_t prot;
                    650: {
                    651:        extern time_value_t *mtime;
                    652: 
                    653:        if (prot & VM_PROT_WRITE) return (-1);
                    654: 
                    655:        return (i386_btop(pmap_extract(pmap_kernel(), (vm_offset_t) mtime)));
                    656: }
                    657: 
1.1.1.4   root      658: void
                    659: startrtclock(void)
1.1       root      660: {
                    661:        clkstart();
                    662: }
                    663: 
                    664: void
1.1.1.4   root      665: inittodr(void)
1.1       root      666: {
                    667:        time_value_t    new_time;
                    668: 
                    669:        new_time.seconds = 0;
                    670:        new_time.microseconds = 0;
                    671: 
1.1.1.4   root      672:        (void) readtodc((u_int *)&new_time.seconds);
1.1       root      673: 
                    674:        {
                    675:            spl_t       s = splhigh();
                    676:            time = new_time;
                    677:            splx(s);
                    678:        }
                    679: }
                    680: 
                    681: void
1.1.1.4   root      682: resettodr(void)
1.1       root      683: {
                    684:        writetodc();
                    685: }
                    686: 
1.1.1.4   root      687: boolean_t
1.1       root      688: init_alloc_aligned(vm_size_t size, vm_offset_t *addrp)
                    689: {
1.1.1.7   root      690:        *addrp = biosmem_bootalloc(vm_page_atop(vm_page_round(size)));
1.1       root      691: 
1.1.1.7   root      692:        if (*addrp == 0)
1.1       root      693:                return FALSE;
                    694: 
                    695:        return TRUE;
                    696: }
                    697: 
                    698: /* Grab a physical page:
                    699:    the standard memory allocation mechanism
                    700:    during system initialization.  */
                    701: vm_offset_t
1.1.1.4   root      702: pmap_grab_page(void)
1.1       root      703: {
                    704:        vm_offset_t addr;
1.1.1.7   root      705:        if (!init_alloc_aligned(PAGE_SIZE, &addr))
1.1       root      706:                panic("Not enough memory to initialize Mach");
                    707:        return addr;
                    708: }

unix.superglobalmegacorp.com

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