|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.