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