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