diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2009-12-16 01:11:51 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2009-12-16 01:11:51 +0100 |
commit | 55dbc2b5d857d35262ad3116803dfb31b733d031 (patch) | |
tree | 9b9a7d7952ff74855de2a6c348e9c856a531158d /i386/i386at | |
parent | 870925205c78415dc4c594bfae9de8eb31745b81 (diff) |
Add Xen support
2009-03-11 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/i386/vm_param.h (VM_MIN_KERNEL_ADDRESS) [MACH_XEN]: Set to
0x20000000.
* i386/i386/i386asm.sym (pfn_list) [VM_MIN_KERNEL_ADDRESS ==
LINEAR_MIN_KERNEL_ADDRESS]: Define to constant PFN_LIST.
2009-02-27 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/intel/pmap.c [MACH_HYP] (INVALIDATE_TLB): Call hyp_invlpg
instead of flush_tlb when e - s is compile-time known to be
PAGE_SIZE.
2008-11-27 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/configfrag.ac (enable_pae): Enable by default on the Xen
platform.
2007-11-14 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/i386at/model_dep.c (machine_relax): New function.
(c_boot_entry): Refuse to boot as dom0.
2007-10-17 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/i386/fpu.c [MACH_XEN]: Disable unused fpintr().
2007-08-12 Samuel Thibault <samuel.thibault@ens-lyon.org>
* Makefile.am (clib_routines): Add _START.
* i386/xen/xen_boothdr: Use _START for VIRT_BASE and PADDR_OFFSET. Add
GUEST_VERSION and XEN_ELFNOTE_FEATURES.
2007-06-13 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/i386/user_ldt.h (user_ldt) [MACH_XEN]: Add alloc field.
* i386/i386/user_ldt.c (i386_set_ldt) [MACH_XEN]: Round allocation of
LDT to a page, set back LDT pages read/write before freeing them.
(user_ldt_free) [MACH_XEN]: Likewise.
2007-04-18 Samuel Thibault <samuel.thibault@ens-lyon.org>
* device/ds_routines.c [MACH_HYP]: Add hypervisor block and net devices.
2007-02-19 Thomas Schwinge <tschwinge@gnu.org>
* i386/xen/Makefrag.am [PLATFORM_xen] (gnumach_LINKFLAGS): Define.
* Makefrag.am: Include `xen/Makefrag.am'.
* configure.ac: Include `xen/configfrag.ac'.
(--enable-platform): Support the `xen' platform.
* i386/configfrag.ac: Likewise.
* i386/Makefrag.am [PLATFORM_xen]: Include `i386/xen/Makefrag.am'.
2007-02-19 Samuel Thibault <samuel.thibault@ens-lyon.org>
Thomas Schwinge <tschwinge@gnu.org>
* i386/xen/Makefrag.am: New file.
* xen/Makefrag.am: Likewise.
* xen/configfrag.ac: Likewise.
2007-02-11 (and later dates) Samuel Thibault <samuel.thibault@ens-lyon.org>
Xen support
* Makefile.am (clib_routines): Add _start.
* Makefrag.am (include_mach_HEADERS): Add include/mach/xen.h.
* device/cons.c (cnputc): Call hyp_console_write.
* i386/Makefrag.am (libkernel_a_SOURCES): Move non-Xen source to
[PLATFORM_at].
* i386/i386/debug_trace.S: Include <i386/xen.h>
* i386/i386/fpu.c [MACH_HYP] (init_fpu): Call set_ts() and clear_ts(),
do not enable CR0_EM.
* i386/i386/gdt.c: Include <mach/xen.h> and <intel/pmap.h>.
[MACH_XEN]: Make gdt array extern.
[MACH_XEN] (gdt_init): Register gdt with hypervisor. Request 4gb
segments assist. Shift la_shift.
[MACH_PSEUDO_PHYS] (gdt_init): Shift pfn_list.
* i386/i386/gdt.h [MACH_XEN]: Don't define KERNEL_LDT and LINEAR_DS.
* i386/i386/i386asm.sym: Include <i386/xen.h>.
[MACH_XEN]: Remove KERNEL_LDT, Add shared_info's CPU_CLI, CPU_PENDING,
CPU_PENDING_SEL, PENDING, EVTMASK and CR2.
* i386/i386/idt.c [MACH_HYP] (idt_init): Register trap table with
hypervisor.
* i386/i386/idt_inittab.S: Include <i386/i386asm.h>.
[MACH_XEN]: Set IDT_ENTRY() for hypervisor. Set trap table terminator.
* i386/i386/ktss.c [MACH_XEN] (ktss_init): Request exception task switch
from hypervisor.
* i386/i386/ldt.c: Include <mach/xen.h> and <intel/pmap.h>
[MACH_XEN]: Make ldt array extern.
[MACH_XEN] (ldt_init): Set ldt readwrite.
[MACH_HYP] (ldt_init): Register ldt with hypervisor.
* i386/i386/locore.S: Include <i386/xen.h>. Handle KERNEL_RING == 1
case.
[MACH_XEN]: Read hyp_shared_info's CR2 instead of %cr2.
[MACH_PSEUDO_PHYS]: Add mfn_to_pfn computation.
[MACH_HYP]: Drop Cyrix I/O-based detection. Read cr3 instead of %cr3.
Make hypervisor call for pte invalidation.
* i386/i386/mp_desc.c: Include <mach/xen.h>.
[MACH_HYP] (mp_desc_init): Panic.
* i386/i386/pcb.c: Include <mach/xen.h>.
[MACH_XEN] (switch_ktss): Request stack switch from hypervisor.
[MACH_HYP] (switch_ktss): Request ldt and gdt switch from hypervisor.
* i386/i386/phys.c: Include <mach/xen.h>
[MACH_PSEUDO_PHYS] (kvtophys): Do page translation.
* i386/i386/proc_reg.h [MACH_HYP] (cr3): New declaration.
(set_cr3, get_cr3, set_ts, clear_ts): Implement macros.
* i386/i386/seg.h [MACH_HYP]: Define KERNEL_RING macro. Include
<mach/xen.h>
[MACH_XEN] (fill_descriptor): Register descriptor with hypervisor.
* i386/i386/spl.S: Include <i386/xen.h> and <i386/i386/asm.h>
[MACH_XEN] (pic_mask): #define to int_mask.
[MACH_XEN] (SETMASK): Implement.
* i386/i386/vm_param.h [MACH_XEN] (HYP_VIRT_START): New macro.
[MACH_XEN]: Set VM_MAX_KERNEL_ADDRESS to HYP_VIRT_START-
LINEAR_MIN_KERNEL_ADDRESS + VM_MIN_KERNEL_ADDRESS. Increase
KERNEL_STACK_SIZE and INTSTACK_SIZE to 4 pages.
* i386/i386at/conf.c [MACH_HYP]: Remove hardware devices, add hypervisor
console device.
* i386/i386at/cons_conf.c [MACH_HYP]: Add hypervisor console device.
* i386/i386at/model_dep.c: Include <sys/types.h>, <mach/xen.h>.
[MACH_XEN] Include <xen/console.h>, <xen/store.h>, <xen/evt.h>,
<xen/xen.h>.
[MACH_PSEUDO_PHYS]: New boot_info, mfn_list, pfn_list variables.
[MACH_XEN]: New la_shift variable.
[MACH_HYP] (avail_next, mem_size_init): Drop BIOS skipping mecanism.
[MACH_HYP] (machine_init): Call hyp_init(), drop hardware
initialization.
[MACH_HYP] (machine_idle): Call hyp_idle().
[MACH_HYP] (halt_cpu): Call hyp_halt().
[MACH_HYP] (halt_all_cpus): Call hyp_reboot() or hyp_halt().
[MACH_HYP] (i386at_init): Initialize with hypervisor.
[MACH_XEN] (c_boot_entry): Add Xen-specific initialization.
[MACH_HYP] (init_alloc_aligned, pmap_valid_page): Drop zones skipping
mecanism.
* i386/intel/pmap.c: Include <mach/xen.h>.
[MACH_PSEUDO_PHYS] (WRITE_PTE): Do page translation.
[MACH_HYP] (INVALIDATE_TLB): Request invalidation from hypervisor.
[MACH_XEN] (pmap_map_bd, pmap_create, pmap_destroy, pmap_remove_range)
(pmap_page_protect, pmap_protect, pmap_enter, pmap_change_wiring)
(pmap_attribute_clear, pmap_unmap_page_zero, pmap_collect): Request MMU
update from hypervisor.
[MACH_XEN] (pmap_bootstrap): Request pagetable initialization from
hypervisor.
[MACH_XEN] (pmap_set_page_readwrite, pmap_set_page_readonly)
(pmap_set_page_readonly_init, pmap_clear_bootstrap_pagetable)
(pmap_map_mfn): New functions.
* i386/intel/pmap.h [MACH_XEN] (INTEL_PTE_GLOBAL): Disable global page
support.
[MACH_PSEUDO_PHYS] (pte_to_pa): Do page translation.
[MACH_XEN] (pmap_set_page_readwrite, pmap_set_page_readonly)
(pmap_set_page_readonly_init, pmap_clear_bootstrap_pagetable)
(pmap_map_mfn): Declare functions.
* i386/i386/xen.h: New file.
* i386/xen/xen.c: New file.
* i386/xen/xen_boothdr.S: New file.
* i386/xen/xen_locore.S: New file.
* include/mach/xen.h: New file.
* kern/bootstrap.c [MACH_XEN] (boot_info): Declare variable.
[MACH_XEN] (bootstrap_create): Rebase multiboot header.
* kern/debug.c: Include <mach/xen.h>.
[MACH_HYP] (panic): Call hyp_crash() without delay.
* linux/dev/include/asm-i386/segment.h [MACH_HYP] (KERNEL_CS)
(KERNEL_DS): Use ring 1.
* xen/block.c: New file.
* xen/block.h: Likewise.
* xen/console.c: Likewise.
* xen/console.h: Likewise.
* xen/evt.c: Likewise.
* xen/evt.h: Likewise.
* xen/grant.c: Likewise.
* xen/grant.h: Likewise.
* xen/net.c: Likewise.
* xen/net.h: Likewise.
* xen/ring.c: Likewise.
* xen/ring.h: Likewise.
* xen/store.c: Likewise.
* xen/store.h: Likewise.
* xen/time.c: Likewise.
* xen/time.h: Likewise.
* xen/xen.c: Likewise.
* xen/xen.h: Likewise.
* xen/public/COPYING: Import file from Xen.
* xen/public/callback.h: Likewise.
* xen/public/dom0_ops.h: Likewise.
* xen/public/domctl.h: Likewise.
* xen/public/elfnote.h: Likewise.
* xen/public/elfstructs.h: Likewise.
* xen/public/event_channel.h: Likewise.
* xen/public/features.h: Likewise.
* xen/public/grant_table.h: Likewise.
* xen/public/kexec.h: Likewise.
* xen/public/libelf.h: Likewise.
* xen/public/memory.h: Likewise.
* xen/public/nmi.h: Likewise.
* xen/public/physdev.h: Likewise.
* xen/public/platform.h: Likewise.
* xen/public/sched.h: Likewise.
* xen/public/sysctl.h: Likewise.
* xen/public/trace.h: Likewise.
* xen/public/vcpu.h: Likewise.
* xen/public/version.h: Likewise.
* xen/public/xen-compat.h: Likewise.
* xen/public/xen.h: Likewise.
* xen/public/xencomm.h: Likewise.
* xen/public/xenoprof.h: Likewise.
* xen/public/arch-x86/xen-mca.h: Likewise.
* xen/public/arch-x86/xen-x86_32.h: Likewise.
* xen/public/arch-x86/xen-x86_64.h: Likewise.
* xen/public/arch-x86/xen.h: Likewise.
* xen/public/arch-x86_32.h: Likewise.
* xen/public/arch-x86_64.h: Likewise.
* xen/public/io/blkif.h: Likewise.
* xen/public/io/console.h: Likewise.
* xen/public/io/fbif.h: Likewise.
* xen/public/io/fsif.h: Likewise.
* xen/public/io/kbdif.h: Likewise.
* xen/public/io/netif.h: Likewise.
* xen/public/io/pciif.h: Likewise.
* xen/public/io/protocols.h: Likewise.
* xen/public/io/ring.h: Likewise.
* xen/public/io/tpmif.h: Likewise.
* xen/public/io/xenbus.h: Likewise.
* xen/public/io/xs_wire.h: Likewise.
Diffstat (limited to 'i386/i386at')
-rw-r--r-- | i386/i386at/conf.c | 21 | ||||
-rw-r--r-- | i386/i386at/cons_conf.c | 8 | ||||
-rw-r--r-- | i386/i386at/model_dep.c | 180 |
3 files changed, 195 insertions, 14 deletions
diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c index 23c2a6f..f5ab36c 100644 --- a/i386/i386at/conf.c +++ b/i386/i386at/conf.c @@ -34,6 +34,7 @@ extern int timeopen(), timeclose(); extern vm_offset_t timemmap(); #define timename "time" +#ifndef MACH_HYP extern int kdopen(), kdclose(), kdread(), kdwrite(); extern int kdgetstat(), kdsetstat(), kdportdeath(); extern vm_offset_t kdmmap(); @@ -50,17 +51,26 @@ extern int lpropen(), lprclose(), lprread(), lprwrite(); extern int lprgetstat(), lprsetstat(), lprportdeath(); #define lprname "lpr" #endif /* NLPR > 0 */ +#endif /* MACH_HYP */ extern int kbdopen(), kbdclose(), kbdread(); extern int kbdgetstat(), kbdsetstat(); #define kbdname "kbd" +#ifndef MACH_HYP extern int mouseopen(), mouseclose(), mouseread(), mousegetstat(); #define mousename "mouse" +#endif /* MACH_HYP */ extern int kmsgopen(), kmsgclose(), kmsgread(), kmsggetstat(); #define kmsgname "kmsg" +#ifdef MACH_HYP +extern int hypcnopen(), hypcnclose(), hypcnread(), hypcnwrite(); +extern int hypcngetstat(), hypcnsetstat(), hypcnportdeath(); +#define hypcnname "hyp" +#endif /* MACH_HYP */ + /* * List of devices - console must be at slot 0 */ @@ -79,16 +89,19 @@ struct dev_ops dev_name_list[] = nodev, nulldev, nulldev, 0, nodev }, +#ifndef MACH_HYP { kdname, kdopen, kdclose, kdread, kdwrite, kdgetstat, kdsetstat, kdmmap, nodev, nulldev, kdportdeath, 0, nodev }, +#endif /* MACH_HYP */ { timename, timeopen, timeclose, nulldev, nulldev, nulldev, nulldev, timemmap, nodev, nulldev, nulldev, 0, nodev }, +#ifndef MACH_HYP #if NCOM > 0 { comname, comopen, comclose, comread, comwrite, comgetstat, comsetstat, nomap, @@ -107,6 +120,7 @@ struct dev_ops dev_name_list[] = nodev, mousegetstat, nulldev, nomap, nodev, nulldev, nulldev, 0, nodev }, +#endif /* MACH_HYP */ { kbdname, kbdopen, kbdclose, kbdread, nodev, kbdgetstat, kbdsetstat, nomap, @@ -120,6 +134,13 @@ struct dev_ops dev_name_list[] = nodev }, #endif +#ifdef MACH_HYP + { hypcnname, hypcnopen, hypcnclose, hypcnread, + hypcnwrite, hypcngetstat, hypcnsetstat, nomap, + nodev, nulldev, hypcnportdeath, 0, + nodev }, +#endif /* MACH_HYP */ + }; int dev_name_count = sizeof(dev_name_list)/sizeof(dev_name_list[0]); diff --git a/i386/i386at/cons_conf.c b/i386/i386at/cons_conf.c index 8784ed9..ea8ccb5 100644 --- a/i386/i386at/cons_conf.c +++ b/i386/i386at/cons_conf.c @@ -30,19 +30,27 @@ #include <sys/types.h> #include <device/cons.h> +#ifdef MACH_HYP +extern int hypcnprobe(), hypcninit(), hypcngetc(), hypcnputc(); +#else /* MACH_HYP */ extern int kdcnprobe(), kdcninit(), kdcngetc(), kdcnputc(); #if NCOM > 0 && RCLINE >= 0 extern int comcnprobe(), comcninit(), comcngetc(), comcnputc(); #endif +#endif /* MACH_HYP */ /* * The rest of the consdev fields are filled in by the respective * cnprobe routine. */ struct consdev constab[] = { +#ifdef MACH_HYP + {"hyp", hypcnprobe, hypcninit, hypcngetc, hypcnputc}, +#else /* MACH_HYP */ {"kd", kdcnprobe, kdcninit, kdcngetc, kdcnputc}, #if NCOM > 0 && RCLINE >= 0 && 1 {"com", comcnprobe, comcninit, comcngetc, comcnputc}, #endif +#endif /* MACH_HYP */ {0} }; diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index 3ebe2e6..61605a1 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -40,6 +40,7 @@ #include <mach/vm_prot.h> #include <mach/machine.h> #include <mach/machine/multiboot.h> +#include <mach/xen.h> #include <i386/vm_param.h> #include <kern/assert.h> @@ -48,6 +49,7 @@ #include <kern/mach_clock.h> #include <kern/printf.h> #include <sys/time.h> +#include <sys/types.h> #include <vm/vm_page.h> #include <i386/fpu.h> #include <i386/gdt.h> @@ -65,6 +67,12 @@ #include <i386at/int_init.h> #include <i386at/kd.h> #include <i386at/rtc.h> +#ifdef MACH_XEN +#include <xen/console.h> +#include <xen/store.h> +#include <xen/evt.h> +#include <xen/xen.h> +#endif /* MACH_XEN */ /* Location of the kernel's symbol table. Both of these are 0 if none is available. */ @@ -81,7 +89,20 @@ vm_offset_t phys_first_addr = 0; vm_offset_t phys_last_addr; /* A copy of the multiboot info structure passed by the boot loader. */ +#ifdef MACH_XEN +struct start_info boot_info; +#ifdef MACH_PSEUDO_PHYS +unsigned long *mfn_list; +#if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS +unsigned long *pfn_list = (void*) PFN_LIST; +#endif +#endif /* MACH_PSEUDO_PHYS */ +#if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS +unsigned long la_shift = VM_MIN_KERNEL_ADDRESS; +#endif +#else /* MACH_XEN */ struct multiboot_info boot_info; +#endif /* MACH_XEN */ /* Command line supplied to kernel. */ char *kernel_cmdline = ""; @@ -90,7 +111,11 @@ char *kernel_cmdline = ""; it gets bumped up through physical memory that exists and is not occupied by boot gunk. It is not necessarily page-aligned. */ -static vm_offset_t avail_next = 0x1000; /* XX end of BIOS data area */ +static vm_offset_t avail_next +#ifndef MACH_HYP + = 0x1000 /* XX end of BIOS data area */ +#endif /* MACH_HYP */ + ; /* Possibly overestimated amount of available memory still remaining to be handed to the VM system. */ @@ -135,6 +160,9 @@ void machine_init(void) */ init_fpu(); +#ifdef MACH_HYP + hyp_init(); +#else /* MACH_HYP */ #ifdef LINUX_DEV /* * Initialize Linux drivers. @@ -146,16 +174,19 @@ void machine_init(void) * Find the devices */ probeio(); +#endif /* MACH_HYP */ /* * Get the time */ inittodr(); +#ifndef MACH_HYP /* * Tell the BIOS not to clear and test memory. */ *(unsigned short *)phystokv(0x472) = 0x1234; +#endif /* MACH_HYP */ /* * Unmap page 0 to trap NULL references. @@ -166,8 +197,17 @@ void machine_init(void) /* Conserve power on processor CPU. */ void machine_idle (int cpu) { +#ifdef MACH_HYP + hyp_idle(); +#else /* MACH_HYP */ assert (cpu == cpu_number ()); asm volatile ("hlt" : : : "memory"); +#endif /* MACH_HYP */ +} + +void machine_relax () +{ + asm volatile ("rep; nop" : : : "memory"); } /* @@ -175,9 +215,13 @@ void machine_idle (int cpu) */ void halt_cpu(void) { +#ifdef MACH_HYP + hyp_halt(); +#else /* MACH_HYP */ asm volatile("cli"); while (TRUE) machine_idle (cpu_number ()); +#endif /* MACH_HYP */ } /* @@ -187,10 +231,16 @@ void halt_all_cpus(reboot) boolean_t reboot; { if (reboot) { +#ifdef MACH_HYP + hyp_reboot(); +#endif /* MACH_HYP */ kdreboot(); } else { rebootflag = 1; +#ifdef MACH_HYP + hyp_halt(); +#endif /* MACH_HYP */ printf("In tight loop: hit ctl-alt-del to reboot\n"); (void) spl0(); } @@ -215,22 +265,26 @@ void db_reset_cpu(void) void mem_size_init(void) { - vm_size_t phys_last_kb; - /* Physical memory on all PCs starts at physical address 0. XX make it a constant. */ phys_first_addr = 0; - phys_last_kb = 0x400 + boot_info.mem_upper; +#ifdef MACH_HYP + if (boot_info.nr_pages >= 0x100000) { + printf("Truncating memory size to 4GiB\n"); + phys_last_addr = 0xffffffffU; + } else + phys_last_addr = boot_info.nr_pages * 0x1000; +#else /* MACH_HYP */ + /* TODO: support mmap */ + vm_size_t phys_last_kb = 0x400 + boot_info.mem_upper; /* Avoid 4GiB overflow. */ if (phys_last_kb < 0x400 || phys_last_kb >= 0x400000) { printf("Truncating memory size to 4GiB\n"); - phys_last_kb = 0x400000 - 1; - } - - /* TODO: support mmap */ - - phys_last_addr = phys_last_kb * 0x400; + phys_last_addr = 0xffffffffU; + } else + phys_last_addr = phys_last_kb * 0x400; +#endif /* MACH_HYP */ printf("AT386 boot: physical memory from 0x%x to 0x%x\n", phys_first_addr, phys_last_addr); @@ -240,14 +294,20 @@ mem_size_init(void) if (phys_last_addr > ((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 6) * 5) { phys_last_addr = ((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 6) * 5; printf("Truncating memory size to %dMiB\n", (phys_last_addr - phys_first_addr) / (1024 * 1024)); + /* TODO Xen: free lost memory */ } phys_first_addr = round_page(phys_first_addr); phys_last_addr = trunc_page(phys_last_addr); +#ifdef MACH_HYP + /* Memory is just contiguous */ + avail_remaining = phys_last_addr; +#else /* MACH_HYP */ avail_remaining = phys_last_addr - (0x100000 - (boot_info.mem_lower * 0x400) - 0x1000); +#endif /* MACH_HYP */ } /* @@ -263,13 +323,20 @@ i386at_init(void) /* * Initialize the PIC prior to any possible call to an spl. */ +#ifndef MACH_HYP picinit(); +#else /* MACH_HYP */ + hyp_intrinit(); +#endif /* MACH_HYP */ /* * Find memory size parameters. */ mem_size_init(); +#ifdef MACH_XEN + kernel_cmdline = (char*) boot_info.cmd_line; +#else /* MACH_XEN */ /* Copy content pointed by boot_info before losing access to it when it * is too far in physical memory. */ if (boot_info.flags & MULTIBOOT_CMDLINE) { @@ -304,6 +371,7 @@ i386at_init(void) m[i].string = addr; } } +#endif /* MACH_XEN */ /* * Initialize kernel physical map, mapping the @@ -325,19 +393,42 @@ i386at_init(void) kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS)] = kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS)]; #if PAE + /* PAE page tables are 2MB only */ kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 1] = kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS) + 1]; + kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 2] = + kernel_page_dir[lin2pdenum(LINEAR_MIN_KERNEL_ADDRESS) + 2]; +#endif /* PAE */ +#ifdef MACH_XEN + { + int i; + for (i = 0; i < PDPNUM; i++) + pmap_set_page_readonly_init((void*) kernel_page_dir + i * INTEL_PGBYTES); +#if PAE + pmap_set_page_readonly_init(kernel_pmap->pdpbase); +#endif /* PAE */ + } +#endif /* MACH_XEN */ +#if PAE set_cr3((unsigned)_kvtophys(kernel_pmap->pdpbase)); +#ifndef MACH_HYP if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE)) panic("CPU doesn't have support for PAE."); set_cr4(get_cr4() | CR4_PAE); +#endif /* MACH_HYP */ #else set_cr3((unsigned)_kvtophys(kernel_page_dir)); #endif /* PAE */ +#ifndef MACH_HYP if (CPU_HAS_FEATURE(CPU_FEATURE_PGE)) set_cr4(get_cr4() | CR4_PGE); + /* already set by Hypervisor */ set_cr0(get_cr0() | CR0_PG | CR0_WP); +#endif /* MACH_HYP */ flush_instr_queue(); +#ifdef MACH_XEN + pmap_clear_bootstrap_pagetable((void *)boot_info.pt_base); +#endif /* MACH_XEN */ /* Interrupt stacks are allocated in physical memory, while kernel stacks are allocated in kernel virtual memory, @@ -349,18 +440,47 @@ i386at_init(void) */ gdt_init(); idt_init(); +#ifndef MACH_HYP int_init(); +#endif /* MACH_HYP */ ldt_init(); ktss_init(); /* Get rid of the temporary direct mapping and flush it out of the TLB. */ +#ifdef MACH_XEN +#ifdef MACH_PSEUDO_PHYS + if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS)]), 0)) +#else /* MACH_PSEUDO_PHYS */ + if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS, 0, UVMF_INVLPG | UVMF_ALL)) +#endif /* MACH_PSEUDO_PHYS */ + printf("couldn't unmap frame 0\n"); +#if PAE +#ifdef MACH_PSEUDO_PHYS + if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 1]), 0)) +#else /* MACH_PSEUDO_PHYS */ + if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL)) +#endif /* MACH_PSEUDO_PHYS */ + printf("couldn't unmap frame 1\n"); +#ifdef MACH_PSEUDO_PHYS + if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 2]), 0)) +#else /* MACH_PSEUDO_PHYS */ + if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + 2*INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL)) +#endif /* MACH_PSEUDO_PHYS */ + printf("couldn't unmap frame 2\n"); +#endif /* PAE */ + hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS); +#else /* MACH_XEN */ kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS)] = 0; #if PAE kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 1] = 0; + kernel_page_dir[lin2pdenum(VM_MIN_KERNEL_ADDRESS) + 2] = 0; #endif /* PAE */ +#endif /* MACH_XEN */ flush_tlb(); - +#ifdef MACH_XEN + hyp_p2m_init(); +#endif /* MACH_XEN */ /* XXX We'll just use the initialization stack we're already running on as the interrupt stack for now. Later this will have to change, @@ -384,6 +504,15 @@ void c_boot_entry(vm_offset_t bi) printf(version); printf("\n"); +#ifdef MACH_XEN + printf("Running on %s.\n", boot_info.magic); + if (boot_info.flags & SIF_PRIVILEGED) + panic("Mach can't run as dom0."); +#ifdef MACH_PSEUDO_PHYS + mfn_list = (void*)boot_info.mfn_list; +#endif +#else /* MACH_XEN */ + #if MACH_KDB /* * Locate the kernel's symbol table, if the boot loader provided it. @@ -405,6 +534,7 @@ void c_boot_entry(vm_offset_t bi) symtab_size, strtab_size); } #endif /* MACH_KDB */ +#endif /* MACH_XEN */ cpu_type = discover_x86_cpu_type (); @@ -525,6 +655,12 @@ boolean_t init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) { vm_offset_t addr; + +#ifdef MACH_HYP + /* There is none */ + if (!avail_next) + avail_next = _kvtophys(boot_info.pt_base) + (boot_info.nr_pt_frames + 3) * 0x1000; +#else /* MACH_HYP */ extern char start[], end[]; int i; static int wrapped = 0; @@ -543,11 +679,14 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) : 0; retry: +#endif /* MACH_HYP */ /* Page-align the start address. */ avail_next = round_page(avail_next); +#ifndef MACH_HYP /* Start with memory above 16MB, reserving the low memory for later. */ + /* Don't care on Xen */ if (!wrapped && phys_last_addr > 16 * 1024*1024) { if (avail_next < 16 * 1024*1024) @@ -563,9 +702,15 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) wrapped = 1; } } +#endif /* MACH_HYP */ /* Check if we have reached the end of memory. */ - if (avail_next == (wrapped ? 16 * 1024*1024 : phys_last_addr)) + if (avail_next == + ( +#ifndef MACH_HYP + wrapped ? 16 * 1024*1024 : +#endif /* MACH_HYP */ + phys_last_addr)) return FALSE; /* Tentatively assign the current location to the caller. */ @@ -575,6 +720,7 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) and see where that puts us. */ avail_next += size; +#ifndef MACH_HYP /* Skip past the I/O and ROM area. */ if ((avail_next > (boot_info.mem_lower * 0x400)) && (addr < 0x100000)) { @@ -620,6 +766,7 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) /* XXX string */ } } +#endif /* MACH_HYP */ avail_remaining -= size; @@ -649,6 +796,11 @@ boolean_t pmap_valid_page(x) vm_offset_t x; { /* XXX is this OK? What does it matter for? */ - return (((phys_first_addr <= x) && (x < phys_last_addr)) && - !(((boot_info.mem_lower * 1024) <= x) && (x < 1024*1024))); + return (((phys_first_addr <= x) && (x < phys_last_addr)) +#ifndef MACH_HYP + && !( + ((boot_info.mem_lower * 1024) <= x) && + (x < 1024*1024)) +#endif /* MACH_HYP */ + ); } |