svn commit: r183906 - in projects/releng_6_xen/sys/i386: conf i386
include include/xen xen
Kip Macy
kmacy at FreeBSD.org
Wed Oct 15 05:44:09 UTC 2008
Author: kmacy
Date: Wed Oct 15 05:44:08 2008
New Revision: 183906
URL: http://svn.freebsd.org/changeset/base/183906
Log:
Add i386 specific xen support
Added:
projects/releng_6_xen/sys/i386/conf/XEN
projects/releng_6_xen/sys/i386/include/xen/
projects/releng_6_xen/sys/i386/include/xen/evtchn.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/features.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/hypercall.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/hypervisor.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/synch_bitops.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xen-os.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xen_intr.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xenbus.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xenfunc.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xenpmap.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xenstored.h (contents, props changed)
projects/releng_6_xen/sys/i386/include/xen/xenvar.h (contents, props changed)
projects/releng_6_xen/sys/i386/xen/
projects/releng_6_xen/sys/i386/xen/clock.c (contents, props changed)
projects/releng_6_xen/sys/i386/xen/exception.s (contents, props changed)
projects/releng_6_xen/sys/i386/xen/locore.s (contents, props changed)
projects/releng_6_xen/sys/i386/xen/machdep.c (contents, props changed)
projects/releng_6_xen/sys/i386/xen/pmap.c (contents, props changed)
projects/releng_6_xen/sys/i386/xen/xen_bus.c (contents, props changed)
projects/releng_6_xen/sys/i386/xen/xen_machdep.c (contents, props changed)
Modified:
projects/releng_6_xen/sys/i386/conf/DEFAULTS
projects/releng_6_xen/sys/i386/i386/genassym.c
projects/releng_6_xen/sys/i386/i386/machdep.c
projects/releng_6_xen/sys/i386/include/asmacros.h
projects/releng_6_xen/sys/i386/include/pcpu.h
projects/releng_6_xen/sys/i386/include/pmap.h
projects/releng_6_xen/sys/i386/include/segments.h
Modified: projects/releng_6_xen/sys/i386/conf/DEFAULTS
==============================================================================
--- projects/releng_6_xen/sys/i386/conf/DEFAULTS Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/conf/DEFAULTS Wed Oct 15 05:44:08 2008 (r183906)
@@ -15,3 +15,5 @@ device npx
# Pseudo devices.
device mem # Memory and kernel memory devices
device io # I/O device
+
+options NATIVE
Added: projects/releng_6_xen/sys/i386/conf/XEN
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/releng_6_xen/sys/i386/conf/XEN Wed Oct 15 05:44:08 2008 (r183906)
@@ -0,0 +1,153 @@
+#
+# GENERIC -- Generic kernel configuration file for FreeBSD/i386
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+machine i386
+cpu I686_CPU
+ident XEN
+
+# To statically compile in device wiring instead of /boot/device.hints
+#hints "GENERIC.hints" # Default places to look for devices.
+
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+makeoptions MODULES_OVERRIDE=""
+
+#options SCHED_ULE # ULE scheduler
+#options PREEMPTION # Enable kernel thread preemption
+options SCHED_4BSD
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options FFS # Berkeley Fast Filesystem
+options SOFTUPDATES # Enable FFS soft updates support
+options UFS_ACL # Support for access control lists
+options UFS_DIRHASH # Improve performance on big directories
+options MD_ROOT # MD is a potential root device
+options NFSCLIENT # Network Filesystem Client
+options NFSSERVER # Network Filesystem Server
+options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options GEOM_LABEL # Provides labelization
+options COMPAT_FREEBSD4 # Compatible with FreeBSD4
+options COMPAT_FREEBSD5 # Compatible with FreeBSD5
+options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
+options KTRACE # ktrace(1) support
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options AUDIT # Security event auditing
+
+# Debugging for use in -current
+options KDB # Enable kernel debugger support.
+options DDB # Support DDB.
+options GDB # Support remote GDB.
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+
+# To make an SMP kernel, the next two lines are needed
+#options SMP # Symmetric MultiProcessor Kernel
+#device apic # I/O APIC
+options PAE
+
+
+# CPU frequency control
+#device cpufreq # native only
+
+# Bus support.
+#device pci
+
+# SCSI peripherals
+device scbus # SCSI bus (required for SCSI)
+device ch # SCSI media changers
+device da # Direct Access (disks)
+device sa # Sequential Access (tape etc)
+device cd # CD
+device pass # Passthrough device (direct SCSI access)
+device ses # SCSI Environmental Services (and SAF-TE)
+
+# atkbdc0 controls both the keyboard and the PS/2 mouse
+device atkbdc # AT keyboard controller
+device atkbd # AT keyboard
+device psm # PS/2 mouse
+device kbdmux # keyboard multiplexer
+#device vga # VGA video card driver
+device splash # Splash screen and screen saver support
+
+# syscons is the default console driver, resembling an SCO console
+
+#device agp # support several AGP chipsets
+
+# Power management support (see NOTES for more options)
+#device apm
+# Add suspend/resume support for the i8254.
+#device pmtimer # native
+
+# Serial (COM) ports
+device uart # Generic UART driver
+
+# If you've got a "dumb" serial or parallel PCI card that is
+# supported by the puc(4) glue driver, uncomment the following
+# line to enable it (connects to sio, uart and/or ppc drivers):
+#device puc
+
+# PCI Ethernet NICs.
+device em # Intel PRO/1000 adapter Gigabit Ethernet Card
+
+# PCI Ethernet NICs that use the common MII bus controller code.
+# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
+device miibus # MII bus support
+
+# Pseudo devices.
+device loop # Network loopback
+device random # Entropy device
+device ether # Ethernet support
+device sl # Kernel SLIP
+device ppp # Kernel PPP
+device tun # Packet tunnel.
+device pty # Pseudo-ttys (telnet etc)
+device md # Memory "disks"
+device gif # IPv6 and IPv4 tunneling
+device faith # IPv6-to-IPv4 relaying (translation)
+device firmware # firmware assist module
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter
+
+
+options XEN
+nooption NATIVE
+nodevice atpic
+options MCLSHIFT=12
+
+nodevice isa
+nooption ISAPNP
+
+options KTR
+options KTR_COMPILE=(KTR_PMAP)
+options KTR_CPUMASK=0xff
+options KTR_ENTRIES=65536
+options KTR_MASK=(KTR_PMAP)
Modified: projects/releng_6_xen/sys/i386/i386/genassym.c
==============================================================================
--- projects/releng_6_xen/sys/i386/i386/genassym.c Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/i386/genassym.c Wed Oct 15 05:44:08 2008 (r183906)
@@ -227,3 +227,9 @@ ASSYM(MTX_RECURSECNT, offsetof(struct mt
ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base));
ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat));
#endif
+
+#ifdef XEN
+#include <machine/xen/hypervisor.h>
+ASSYM(PC_CR3, offsetof(struct pcpu, pc_cr3));
+ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START);
+#endif
Modified: projects/releng_6_xen/sys/i386/i386/machdep.c
==============================================================================
--- projects/releng_6_xen/sys/i386/i386/machdep.c Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/i386/machdep.c Wed Oct 15 05:44:08 2008 (r183906)
@@ -141,6 +141,25 @@ int arch_i386_is_xbox = 0;
uint32_t arch_i386_xbox_memsize = 0;
#endif
+#ifdef XEN
+/* XEN includes */
+#include <machine/xen/hypervisor.h>
+#include <machine/xen/xen-os.h>
+#include <machine/xen/xenvar.h>
+#include <machine/xen/xenfunc.h>
+#include <machine/xen/xen_intr.h>
+
+void Xhypervisor_callback(void);
+void failsafe_callback(void);
+
+int gdt_set;
+extern trap_info_t trap_table[];
+struct proc_ldt default_proc_ldt;
+extern int init_first;
+int running_xen = 1;
+extern unsigned long physfree;
+#endif /* XEN */
+
/* Sanity check for __curthread() */
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
@@ -282,8 +301,9 @@ cpu_startup(dummy)
*/
bufinit();
vm_pager_bufferinit();
-
+#ifndef XEN
cpu_setregs();
+#endif
}
/*
@@ -1108,6 +1128,25 @@ cpu_est_clockrate(int cpu_id, uint64_t *
return (0);
}
+static int cpu_idle_hlt = 1;
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
+ &cpu_idle_hlt, 0, "Idle loop HLT enable");
+#ifdef XEN
+
+void
+cpu_halt(void)
+{
+ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+}
+
+static void
+cpu_idle_default(void)
+{
+ idle_block();
+}
+
+#else
+
/*
* Shutdown the CPU as much as possible
*/
@@ -1133,9 +1172,6 @@ cpu_halt(void)
* XXX I'm turning it on for SMP as well by default for now. It seems to
* help lock contention somewhat, and this is critical for HTT. -Peter
*/
-static int cpu_idle_hlt = 1;
-SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
- &cpu_idle_hlt, 0, "Idle loop HLT enable");
static void
cpu_idle_default(void)
@@ -1147,6 +1183,7 @@ cpu_idle_default(void)
*/
__asm __volatile("sti; hlt");
}
+#endif /* !XEN */
/*
* Note that we have to be careful here to avoid a race between checking
@@ -1317,10 +1354,16 @@ SYSCTL_ULONG(_machdep, OID_AUTO, guessed
*/
int _default_ldt;
+
+#ifdef XEN
+union descriptor *gdt;
+union descriptor *ldt;
+#else
union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */
+union descriptor ldt[NLDT]; /* local descriptor table */
+#endif
static struct gate_descriptor idt0[NIDT];
struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
-union descriptor ldt[NLDT]; /* local descriptor table */
struct region_descriptor r_gdt, r_idt; /* table descriptors */
int private_tss; /* flag indicating private tss */
@@ -1355,7 +1398,7 @@ struct soft_segment_descriptor gdt_segs[
{ 0x0, /* segment base address */
0xfffff, /* length - all address space */
SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
+ SEL_KPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0, 0,
1, /* default 32 vs 16 bit size */
@@ -1382,7 +1425,7 @@ struct soft_segment_descriptor gdt_segs[
{ 0x0, /* segment base address */
0xfffff, /* length - all address space */
SDT_MEMERA, /* segment type */
- 0, /* segment descriptor priority level */
+ SEL_KPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0, 0,
1, /* default 32 vs 16 bit size */
@@ -1391,7 +1434,7 @@ struct soft_segment_descriptor gdt_segs[
{ 0x0, /* segment base address */
0xfffff, /* length - all address space */
SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
+ SEL_KPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0, 0,
1, /* default 32 vs 16 bit size */
@@ -1418,11 +1461,12 @@ struct soft_segment_descriptor gdt_segs[
{ 0x400, /* segment base address */
0xfffff, /* length */
SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
+ SEL_KPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0, 0,
1, /* default 32 vs 16 bit size */
1 /* limit granularity (byte/page units)*/ },
+#ifndef XEN
/* GPROC0_SEL 9 Proc 0 Tss Descriptor */
{
0x0, /* segment base address */
@@ -1514,6 +1558,7 @@ struct soft_segment_descriptor gdt_segs[
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
+#endif /* !XEN */
};
static struct soft_segment_descriptor ldt_segs[] = {
@@ -1735,7 +1780,17 @@ getmemsize(int first)
goto physmap_done;
}
#endif
-
+#ifdef XEN
+ has_smap = 0;
+ Maxmem = xen_start_info->nr_pages - init_first;
+ physmem = Maxmem;
+ basemem = 0;
+ physmap[0] = init_first << PAGE_SHIFT;
+ physmap[1] = ptoa(Maxmem) - round_page(MSGBUF_SIZE);
+ physmap_idx = 0;
+ goto physmap_done;
+#endif
+
hasbrokenint12 = 0;
TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12);
bzero(&vmf, sizeof(vmf));
@@ -1898,7 +1953,7 @@ int15e820:
vmf.vmf_ah = 0x88;
vm86_intcall(0x15, &vmf);
extmem = vmf.vmf_ax;
-#else
+#elif !defined(XEN)
/*
* Prefer the RTC value for extended memory.
*/
@@ -1988,7 +2043,7 @@ physmap_done:
if (getenv_quad("dcons.addr", &dcons_addr) == 0 ||
getenv_quad("dcons.size", &dcons_size) == 0)
dcons_addr = 0;
-
+#ifndef XEN
/*
* physmap is in bytes, so when converting to page boundaries,
* round up the start address and round down the end address.
@@ -2106,7 +2161,10 @@ do_next:
}
*pte = 0;
invltlb();
-
+#else
+ phys_avail[0] = physfree;
+ phys_avail[1] = xen_start_info->nr_pages*PAGE_SIZE;
+#endif
/*
* XXX
* The last chunk must contain at least one page plus the message
@@ -2128,6 +2186,257 @@ do_next:
avail_end = phys_avail[pa_indx];
}
+#ifdef XEN
+
+#define MTOPSIZE (1<<(14 + PAGE_SHIFT))
+void
+init386(int first)
+{
+ int error, gsel_tss, metadata_missing, x;
+ unsigned long off, gdtmachpfn;
+ struct pcpu *pc;
+ struct callback_register event = {
+ .type = CALLBACKTYPE_event,
+ .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback },
+ };
+ struct callback_register failsafe = {
+ .type = CALLBACKTYPE_failsafe,
+ .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback },
+ };
+
+ thread0.td_kstack = proc0kstack;
+ thread0.td_pcb = (struct pcb *)
+ (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+
+ /*
+ * This may be done better later if it gets more high level
+ * components in it. If so just link td->td_proc here.
+ */
+ proc_linkup(&proc0, &ksegrp0, &thread0);
+
+ metadata_missing = 0;
+ if (xen_start_info->mod_start) {
+ preload_metadata = (caddr_t)xen_start_info->mod_start;
+ preload_bootstrap_relocate(KERNBASE);
+ } else {
+ metadata_missing = 1;
+ }
+ if (envmode == 1)
+ kern_envp = static_env;
+ else if ((caddr_t)xen_start_info->cmd_line)
+ kern_envp = xen_setbootenv((caddr_t)xen_start_info->cmd_line);
+
+ boothowto |= xen_boothowto(kern_envp);
+
+ /* Init basic tunables, hz etc */
+ init_param1();
+
+ /*
+ * XEN occupies a portion of the upper virtual address space
+ * At its base it manages an array mapping machine page frames
+ * to physical page frames - hence we need to be able to
+ * access 4GB - (64MB - 4MB + 64k)
+ */
+ gdt_segs[GPRIV_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GUFS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GUGS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GUCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GUDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+ gdt_segs[GBIOSLOWMEM_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
+
+ pc = &__pcpu[0];
+ gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
+ gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
+
+ PT_SET_MA(gdt, xpmap_ptom(VTOP(gdt)) | PG_V | PG_RW);
+ bzero(gdt, PAGE_SIZE);
+ for (x = 0; x < NGDT; x++)
+ ssdtosd(&gdt_segs[x], &gdt[x].sd);
+
+
+ printk("gdt=%p\n", gdt);
+ printk("PTmap=%p\n", PTmap);
+ printk("addr=%p\n", *vtopte((unsigned long)gdt) & ~PG_RW);
+
+ gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT;
+ PT_SET_MA(gdt, *vtopte((unsigned long)gdt) & ~(PG_RW|PG_M|PG_A));
+ PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0);
+ lgdt(&r_gdt /* unused */);
+ gdt_set = 1;
+
+ if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) {
+ panic("set_trap_table failed - error %d\n", error);
+ }
+
+ error = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
+ if (error == 0)
+ error = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
+#if CONFIG_XEN_COMPAT <= 0x030002
+ if (error == -ENOXENSYS)
+ HYPERVISOR_set_callbacks(GSEL(GCODE_SEL, SEL_KPL),
+ (unsigned long)Xhypervisor_callback,
+ GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback);
+#endif
+ pcpu_init(pc, 0, sizeof(struct pcpu));
+ PCPU_SET(prvspace, pc);
+ PCPU_SET(curthread, &thread0);
+ PCPU_SET(curpcb, thread0.td_pcb);
+ PCPU_SET(pdir, (unsigned long)IdlePTD);
+
+ /*
+ * Initialize mutexes.
+ *
+ * icu_lock: in order to allow an interrupt to occur in a critical
+ * section, to set pcpu->ipending (etc...) properly, we
+ * must be able to get the icu lock, so it can't be
+ * under witness.
+ */
+ mutex_init();
+ mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS);
+
+ /* make ldt memory segments */
+ PT_SET_MA(ldt, xpmap_ptom(VTOP(ldt)) | PG_V | PG_RW);
+ bzero(ldt, PAGE_SIZE);
+ ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1);
+ ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1);
+ for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++)
+ ssdtosd(&ldt_segs[x], &ldt[x].sd);
+
+ default_proc_ldt.ldt_base = (caddr_t)ldt;
+ default_proc_ldt.ldt_len = 6;
+ _default_ldt = (int)&default_proc_ldt;
+ PCPU_SET(currentldt, _default_ldt)
+ PT_SET_MA(ldt, *vtopte((unsigned long)ldt) & ~PG_RW);
+ xen_set_ldt((unsigned long) ldt, (sizeof ldt_segs / sizeof ldt_segs[0]));
+
+#ifdef XBOX
+ /*
+ * The following code queries the PCI ID of 0:0:0. For the XBOX,
+ * This should be 0x10de / 0x02a5.
+ *
+ * This is exactly what Linux does.
+ */
+ outl(0xcf8, 0x80000000);
+ if (inl(0xcfc) == 0x02a510de) {
+ arch_i386_is_xbox = 1;
+ pic16l_setled(XBOX_LED_GREEN);
+
+ /*
+ * We are an XBOX, but we may have either 64MB or 128MB of
+ * memory. The PCI host bridge should be programmed for this,
+ * so we just query it.
+ */
+ outl(0xcf8, 0x80000084);
+ arch_i386_xbox_memsize = (inl(0xcfc) == 0x7FFFFFF) ? 128 : 64;
+ }
+#endif /* XBOX */
+#if defined (XEN_PRIVILEGED)
+ /*
+ * Initialize the i8254 before the console so that console
+ * initialization can use DELAY().
+ */
+ i8254_init();
+#endif
+ /*
+ * Initialize the console before we print anything out.
+ */
+ cninit();
+
+ if (metadata_missing)
+ printf("WARNING: loader(8) metadata is missing!\n");
+
+#ifdef DEV_ISA
+ if (xen_start_info->flags & SIF_PRIVILEGED) {
+ elcr_probe();
+#ifdef DEV_ATPIC
+ atpic_startup();
+#endif
+ }
+#endif
+
+#ifdef DDB
+ ksym_start = bootinfo.bi_symtab;
+ ksym_end = bootinfo.bi_esymtab;
+#endif
+
+ kdb_init();
+
+#ifdef KDB
+ if (boothowto & RB_KDB)
+ kdb_enter("Boot flags requested debugger");
+#endif
+
+ finishidentcpu(); /* Final stage of CPU initialization */
+ setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL,
+ GSEL(GCODE_SEL, SEL_KPL));
+ setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL,
+ GSEL(GCODE_SEL, SEL_KPL));
+ initializecpu(); /* Initialize CPU registers */
+
+ /* make an initial tss so cpu can get interrupt stack on syscall! */
+ /* Note: -16 is so we can grow the trapframe if we came from vm86 */
+ PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
+ KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
+ PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
+ gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
+ HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL),
+ PCPU_GET(common_tss.tss_esp0));
+
+
+ /* pointer to selector slot for %fs/%gs */
+ PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd);
+
+ dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 =
+ dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)];
+ dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 =
+ dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL);
+#ifdef PAE
+ dblfault_tss.tss_cr3 = (int)IdlePDPT;
+#else
+ dblfault_tss.tss_cr3 = (int)IdlePTD;
+#endif
+ dblfault_tss.tss_eip = (int)dblfault_handler;
+ dblfault_tss.tss_eflags = PSL_KERNEL;
+ dblfault_tss.tss_ds = dblfault_tss.tss_es =
+ dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL);
+ dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL);
+ dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
+ dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
+
+ vm86_initialize();
+ getmemsize(first);
+ init_param2(physmem);
+
+
+ /* Map the message buffer. */
+ for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
+ pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
+
+ /* now running on new page tables, configured,and u/iom is accessible */
+
+ msgbufinit(msgbufp, MSGBUF_SIZE);
+
+ /* transfer to user mode */
+
+ _ucodesel = GSEL(GUCODE_SEL, SEL_UPL);
+ _udatasel = GSEL(GUDATA_SEL, SEL_UPL);
+
+ /* setup proc 0's pcb */
+ thread0.td_pcb->pcb_flags = 0;
+#ifdef PAE
+ thread0.td_pcb->pcb_cr3 = (int)IdlePDPT;
+#else
+ thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
+#endif
+ thread0.td_pcb->pcb_ext = 0;
+ thread0.td_frame = &proc0_tf;
+ thread0.td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0];
+ thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1];
+}
+
+#else
void
init386(first)
int first;
@@ -2389,6 +2698,7 @@ init386(first)
thread0.td_pcb->pcb_ext = 0;
thread0.td_frame = &proc0_tf;
}
+#endif /* !XEN */
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
Modified: projects/releng_6_xen/sys/i386/include/asmacros.h
==============================================================================
--- projects/releng_6_xen/sys/i386/include/asmacros.h Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/include/asmacros.h Wed Oct 15 05:44:08 2008 (r183906)
@@ -134,6 +134,46 @@
#define MEXITCOUNT
#endif /* GPROF */
+/*
+ * Setup the kernel segment registers.
+ */
+#define SET_KERNEL_SREGS \
+ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \
+ movl %eax, %ds ; \
+ movl %eax, %es ; \
+ movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \
+ movl %eax, %fs
+
+#ifdef XEN
+#define LOAD_CR3(reg) \
+ movl reg,PCPU(CR3); \
+ pushl %ecx ; \
+ pushl %edx ; \
+ pushl %esi ; \
+ pushl reg ; \
+ call xen_load_cr3 ; \
+ addl $4,%esp ; \
+ popl %esi ; \
+ popl %edx ; \
+ popl %ecx ; \
+
+#define READ_CR3(reg) movl PCPU(CR3),reg;
+#define LLDT(arg) \
+ pushl %edx ; \
+ pushl %eax ; \
+ xorl %eax,%eax ; \
+ movl %eax,%gs ; \
+ call i386_reset_ldt ; \
+ popl %eax ; \
+ popl %edx
+#define CLI call ni_cli
+#else
+#define LOAD_CR3(reg) movl reg,%cr3;
+#define READ_CR3(reg) movl %cr3,reg;
+#define LLDT(arg) lldt arg;
+#define CLI cli
+#endif /* !XEN */
+
#ifdef LOCORE
/*
* Convenience macros for declaring interrupt entry points and trap
@@ -145,4 +185,30 @@
#endif /* LOCORE */
+#ifdef __STDC__
+#define ELFNOTE(name, type, desctype, descdata...) \
+.pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
+ .long 4f - 3f /* descsz */ ; \
+ .long type ; \
+1:.asciz #name ; \
+2:.align 4 ; \
+3:desctype descdata ; \
+4:.align 4 ; \
+.popsection
+#else /* !__STDC__, i.e. -traditional */
+#define ELFNOTE(name, type, desctype, descdata) \
+.pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
+ .long 4f - 3f /* descsz */ ; \
+ .long type ; \
+1:.asciz "name" ; \
+2:.align 4 ; \
+3:desctype descdata ; \
+4:.align 4 ; \
+.popsection
+#endif /* __STDC__ */
+
#endif /* !_MACHINE_ASMACROS_H_ */
Modified: projects/releng_6_xen/sys/i386/include/pcpu.h
==============================================================================
--- projects/releng_6_xen/sys/i386/include/pcpu.h Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/include/pcpu.h Wed Oct 15 05:44:08 2008 (r183906)
@@ -45,6 +45,28 @@
* to each CPU's data can be set up for things like "check curproc on all
* other processors"
*/
+
+#ifdef XEN
+#define PCPU_MD_FIELDS \
+ struct pcpu *pc_prvspace; /* Self-reference */ \
+ struct pmap *pc_curpmap; \
+ struct i386tss pc_common_tss; \
+ struct segment_descriptor pc_common_tssd; \
+ struct segment_descriptor *pc_tss_gdt; \
+ struct segment_descriptor *pc_fsgs_gdt; \
+ vm_paddr_t *pc_pdir_shadow; \
+ int pc_currentldt; \
+ u_int pc_acpi_id; /* ACPI CPU id */ \
+ u_int pc_apic_id; \
+ int pc_private_tss; /* Flag indicating private tss*/\
+ u_int pc_cr3; /* track cr3 for R1/R3*/ \
+ u_int pc_pdir; \
+ u_int pc_lazypmap; \
+ u_int pc_rendezvous; \
+ u_int pc_cpuast
+
+
+#else
#define PCPU_MD_FIELDS \
struct pcpu *pc_prvspace; /* Self-reference */ \
struct pmap *pc_curpmap; \
@@ -55,7 +77,7 @@
int pc_currentldt; \
u_int pc_acpi_id; \
u_int pc_apic_id
-
+#endif
#if defined(lint)
extern struct pcpu *pcpup;
Modified: projects/releng_6_xen/sys/i386/include/pmap.h
==============================================================================
--- projects/releng_6_xen/sys/i386/include/pmap.h Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/include/pmap.h Wed Oct 15 05:44:08 2008 (r183906)
@@ -68,7 +68,14 @@
/* Our various interpretations of the above */
#define PG_W PG_AVAIL1 /* "Wired" pseudoflag */
#define PG_MANAGED PG_AVAIL2
+
+#ifdef PAE
+#define PG_FRAME (0x000ffffffffff000ull)
+#define PG_PS_FRAME (0x000fffffffe00000ull)
+#else
#define PG_FRAME (~((vm_paddr_t)PAGE_MASK))
+#define PG_PS_FRAME (0xffc00000)
+#endif
#define PG_PROT (PG_RW|PG_U) /* all protection bits . */
#define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */
@@ -175,6 +182,77 @@ extern pd_entry_t *IdlePTD; /* physical
* the corresponding pde that in turn maps it.
*/
#define vtopte(va) (PTmap + i386_btop(va))
+#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
+
+#ifdef XEN
+#include <machine/xen/xen-os.h>
+#include <machine/xen/xenvar.h>
+#include <machine/xen/xenpmap.h>
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define PG_KERNEL (PG_V | PG_A | PG_RW | PG_M)
+
+#define MACH_TO_VM_PAGE(ma) PHYS_TO_VM_PAGE(xpmap_mtop((ma)))
+#define VM_PAGE_TO_MACH(m) xpmap_ptom(VM_PAGE_TO_PHYS((m)))
+
+static __inline vm_paddr_t
+pmap_kextract_ma(vm_offset_t va)
+{
+ vm_paddr_t ma;
+ if ((ma = PTD[va >> PDRSHIFT]) & PG_PS) {
+ ma = (ma & ~(NBPDR - 1)) | (va & (NBPDR - 1));
+ } else {
+ ma = (*vtopte(va) & PG_FRAME) | (va & PAGE_MASK);
+ }
+ return ma;
+}
+
+static __inline vm_paddr_t
+pmap_kextract(vm_offset_t va)
+{
+ return xpmap_mtop(pmap_kextract_ma(va));
+}
+#define vtomach(va) pmap_kextract_ma(((vm_offset_t) (va)))
+
+vm_paddr_t pmap_extract_ma(struct pmap *pmap, vm_offset_t va);
+
+void pmap_kenter_ma(vm_offset_t va, vm_paddr_t pa);
+void pmap_map_readonly(struct pmap *pmap, vm_offset_t va, int len);
+void pmap_map_readwrite(struct pmap *pmap, vm_offset_t va, int len);
+
+static __inline pt_entry_t
+pte_load_store(pt_entry_t *ptep, pt_entry_t v)
+{
+ pt_entry_t r;
+
+ v = xpmap_ptom(v);
+ r = *ptep;
+ PT_SET_VA(ptep, v, TRUE);
+ return (r);
+}
+
+static __inline pt_entry_t
+pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v)
+{
+ pt_entry_t r;
+
+ r = *ptep;
+ PT_SET_VA_MA(ptep, v, TRUE);
+ return (r);
+}
+
+#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
+
+#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
+#define pte_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte)
+#define pde_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte)
+
+#elif !defined(XEN)
/*
* Routine: pmap_kextract
@@ -195,10 +273,9 @@ pmap_kextract(vm_offset_t va)
}
return pa;
}
+#endif
-#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
-
-#ifdef PAE
+#if defined(PAE) && !defined(XEN)
static __inline pt_entry_t
pte_load(pt_entry_t *ptep)
@@ -231,7 +308,7 @@ pte_load_store(pt_entry_t *ptep, pt_entr
#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
-#else /* PAE */
+#elif !defined (PAE) && !defined(XEN)
static __inline pt_entry_t
pte_load(pt_entry_t *ptep)
Modified: projects/releng_6_xen/sys/i386/include/segments.h
==============================================================================
--- projects/releng_6_xen/sys/i386/include/segments.h Wed Oct 15 05:43:13 2008 (r183905)
+++ projects/releng_6_xen/sys/i386/include/segments.h Wed Oct 15 05:44:08 2008 (r183906)
@@ -47,7 +47,11 @@
*/
#define ISPL(s) ((s)&3) /* what is the priority level of a selector */
+#ifndef XEN
#define SEL_KPL 0 /* kernel priority level */
+#else
+#define SEL_KPL 1 /* kernel priority level */
+#endif
#define SEL_UPL 3 /* user priority level */
#define ISLDT(s) ((s)&SEL_LDT) /* is it local or global */
#define SEL_LDT 4 /* local descriptor table */
@@ -222,8 +226,11 @@ struct region_descriptor {
#define GBIOSARGS_SEL 17 /* BIOS interface (Arguments) */
#define GNDIS_SEL 18 /* For the NDIS layer */
+#ifndef XEN
#define NGDT 19
-
+#else
+#define NGDT 9
+#endif
/*
* Entries in the Local Descriptor Table (LDT)
*/
@@ -240,10 +247,16 @@ struct region_descriptor {
#ifdef _KERNEL
extern int _default_ldt;
+#ifndef XEN
+extern union descriptor ldt[NLDT];
extern union descriptor gdt[];
+#else
+extern union descriptor *ldt;
+extern union descriptor *gdt;
+#endif
+
extern struct soft_segment_descriptor gdt_segs[];
extern struct gate_descriptor *idt;
-extern union descriptor ldt[NLDT];
extern struct region_descriptor r_gdt, r_idt;
void lgdt(struct region_descriptor *rdp);
Added: projects/releng_6_xen/sys/i386/include/xen/evtchn.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/releng_6_xen/sys/i386/include/xen/evtchn.h Wed Oct 15 05:44:08 2008 (r183906)
@@ -0,0 +1,81 @@
+/******************************************************************************
+ * evtchn.h
+ *
+ * Communication via Xen event channels.
+ * Also definitions for the device that demuxes notifications to userspace.
+ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#ifndef __ASM_EVTCHN_H__
+#define __ASM_EVTCHN_H__
+#include <machine/pcpu.h>
+#include <machine/xen/hypervisor.h>
+#include <machine/xen/synch_bitops.h>
+#include <machine/frame.h>
+
+/*
+ * LOW-LEVEL DEFINITIONS
+ */
+
+/*
+ * Unlike notify_remote_via_evtchn(), this is safe to use across
+ * save/restore. Notifications on a broken connection are silently dropped.
+ */
+void notify_remote_via_irq(int irq);
+
+
+/* Entry point for notifications into Linux subsystems. */
+void evtchn_do_upcall(struct intrframe *frame);
+
+/* Entry point for notifications into the userland character device. */
+void evtchn_device_upcall(int port);
+
+void mask_evtchn(int port);
+
+void unmask_evtchn(int port);
+
+
+
+static inline void
+clear_evtchn(int port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ synch_clear_bit(port, &s->evtchn_pending[0]);
+}
+
+static inline void
+notify_remote_via_evtchn(int port)
+{
+ struct evtchn_send send = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
+}
+
+/*
+ * Use these to access the event channel underlying the IRQ handle returned
+ * by bind_*_to_irqhandler().
+ */
+int irq_to_evtchn_port(int irq);
+
+void ipi_pcpu(unsigned int cpu, int vector);
+
+/*
+ * CHARACTER-DEVICE DEFINITIONS
+ */
+
+#define PORT_NORMAL 0x0000
+#define PORT_EXCEPTION 0x8000
+#define PORTIDX_MASK 0x7fff
+
+/* /dev/xen/evtchn resides at device number major=10, minor=200 */
+#define EVTCHN_MINOR 200
+
+/* /dev/xen/evtchn ioctls: */
+/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list