Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Apr 2012 05:42:51 +0000 (UTC)
From:      "Cherry G. Mathew" <cherry@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r233823 - in projects/amd64_xen_pv/sys: amd64/amd64 amd64/conf amd64/include amd64/include/xen amd64/xen conf dev/xen/control x86/include x86/x86
Message-ID:  <201204030542.q335gpVH033582@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cherry
Date: Tue Apr  3 05:42:51 2012
New Revision: 233823
URL: http://svn.freebsd.org/changeset/base/233823

Log:
  This is a first cut at publishing heavily WIP work to port FreeBSD
  64bit to run as a XEN paravirtualised kernel.
  
  It is very early days and therefore only has a guarantee of
  compilability on the branch. The following have been deferred for
  later review:
  
   - style nits.
   - comments
  
  What would be really helpful for review would be:
   - design errors
   - bugs
   - file organisation, API use etc.
  
  The primary focus of the branch at this point is functionality.
  
  We use a config(5) option:
  options	 	NATIVE
  
  to indicate "baremetal" support. The intent of this option is to
  exclude files from the PV kernel that only the "baremetal" kernel
  needs. This is similar to how the i386 port implements this. An
  alternative method is needed before merge to -current
  
  Reviewed by: attilio, gibbs
  
  Approved by: gibbs

Added:
  projects/amd64_xen_pv/sys/amd64/conf/XEN
  projects/amd64_xen_pv/sys/amd64/include/xen/xen_clock_util.h   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/
  projects/amd64_xen_pv/sys/amd64/xen/clock.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/exception.S
  projects/amd64_xen_pv/sys/amd64/xen/locore.S
  projects/amd64_xen_pv/sys/amd64/xen/machdep.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/mm.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/mp_machdep.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/mpboot.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/pmap.c   (contents, props changed)
  projects/amd64_xen_pv/sys/amd64/xen/xen_clock_util.c   (contents, props changed)
Modified:
  projects/amd64_xen_pv/sys/amd64/amd64/genassym.c
  projects/amd64_xen_pv/sys/amd64/amd64/support.S
  projects/amd64_xen_pv/sys/amd64/conf/DEFAULTS
  projects/amd64_xen_pv/sys/amd64/include/asmacros.h
  projects/amd64_xen_pv/sys/amd64/include/cpufunc.h
  projects/amd64_xen_pv/sys/amd64/include/pcpu.h
  projects/amd64_xen_pv/sys/amd64/include/pmap.h
  projects/amd64_xen_pv/sys/amd64/include/smp.h
  projects/amd64_xen_pv/sys/amd64/include/xen/xen-os.h
  projects/amd64_xen_pv/sys/amd64/include/xen/xenpmap.h
  projects/amd64_xen_pv/sys/amd64/include/xen/xenvar.h
  projects/amd64_xen_pv/sys/conf/files.amd64
  projects/amd64_xen_pv/sys/conf/options.amd64
  projects/amd64_xen_pv/sys/dev/xen/control/control.c
  projects/amd64_xen_pv/sys/x86/include/segments.h
  projects/amd64_xen_pv/sys/x86/x86/nexus.c

Modified: projects/amd64_xen_pv/sys/amd64/amd64/genassym.c
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/amd64/genassym.c	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/amd64/genassym.c	Tue Apr  3 05:42:51 2012	(r233823)
@@ -243,3 +243,11 @@ ASSYM(SEL_RPL_MASK, SEL_RPL_MASK);
 #ifdef	HWPMC_HOOKS
 ASSYM(PMC_FN_USER_CALLCHAIN, PMC_FN_USER_CALLCHAIN);
 #endif
+
+#ifdef XEN
+#include <xen/hypervisor.h>
+ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START);
+ASSYM(EVTCHN_UPCALL_MASK, offsetof(struct vcpu_info, evtchn_upcall_mask));
+#include <xen/interface/xen.h>
+ASSYM(__HYPERVISOR_iret, __HYPERVISOR_iret);
+#endif

Modified: projects/amd64_xen_pv/sys/amd64/amd64/support.S
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/amd64/support.S	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/amd64/support.S	Tue Apr  3 05:42:51 2012	(r233823)
@@ -632,9 +632,11 @@ END(copystr)
  */
 /* void lgdt(struct region_descriptor *rdp); */
 ENTRY(lgdt)
+#ifndef XEN
 	/* reload the descriptor table */
 	lgdt	(%rdi)
-
+#endif /* !XEN */
+	
 	/* flush the prefetch q */
 	jmp	1f
 	nop

Modified: projects/amd64_xen_pv/sys/amd64/conf/DEFAULTS
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/conf/DEFAULTS	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/conf/DEFAULTS	Tue Apr  3 05:42:51 2012	(r233823)
@@ -21,4 +21,7 @@ options 	GEOM_PART_EBR
 options 	GEOM_PART_EBR_COMPAT
 options 	GEOM_PART_MBR
 
+# enable support for native hardware
+options	 	NATIVE
+
 options 	NEW_PCIB

Added: projects/amd64_xen_pv/sys/amd64/conf/XEN
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/amd64_xen_pv/sys/amd64/conf/XEN	Tue Apr  3 05:42:51 2012	(r233823)
@@ -0,0 +1,174 @@
+#
+# XEN -- Kernel configuration for amd64 XEN DomU
+#
+# $FreeBSD: releng/9.0/sys/i386/conf/XEN 224699 2011-08-07 20:16:46Z rmacklem $
+
+cpu		HAMMER
+ident		XEN
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WITHOUT_MODULES="aha ahb amd cxgb dpt drm hptmv ida malo mps mwl nve sound sym trm xfs"
+
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+#options 	SCHED_4BSD		 
+
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+options 	GEOM_LABEL		# Provides labelization
+options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
+options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) 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 	DEADLKRES		# Enable the deadlock resolver
+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
+
+nooption	NATIVE
+option		XEN
+nodevice	atpic
+nodevice	isa
+options 	MCLSHIFT=12
+
+# To make an SMP kernel, the next line is needed
+options 	SMP			# Symmetric MultiProcessor Kernel
+
+#device		atkbdc		# AT keyboard controller
+#device		atkbd		# AT keyboard
+device		psm		# PS/2 mouse
+device		pci
+
+#device		kbdmux		# keyboard multiplexer
+
+# Pseudo devices.
+device		loop		# Network loopback
+device		random		# Entropy device
+device		ether		# Ethernet support
+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)
+
+# 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
+
+#
+# XEN -- Kernel configuration for amd64 XEN DomU
+#
+# $FreeBSD: releng/9.0/sys/i386/conf/XEN 224699 2011-08-07 20:16:46Z rmacklem $
+
+cpu		HAMMER
+ident		XEN
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WITHOUT_MODULES="aha ahb amd cxgb dpt drm hptmv ida malo mps mwl nve sound sym trm xfs"
+
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+#options 	SCHED_4BSD		 
+
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+options 	GEOM_LABEL		# Provides labelization
+options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
+options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) 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 	DEADLKRES		# Enable the deadlock resolver
+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
+
+nooption	NATIVE
+option		XEN
+nodevice	atpic
+nodevice	isa
+options 	MCLSHIFT=12
+
+# To make an SMP kernel, the next line is needed
+options 	SMP			# Symmetric MultiProcessor Kernel
+
+#device		atkbdc		# AT keyboard controller
+#device		atkbd		# AT keyboard
+device		psm		# PS/2 mouse
+device		pci
+
+#device		kbdmux		# keyboard multiplexer
+
+# Pseudo devices.
+device		loop		# Network loopback
+device		random		# Entropy device
+device		ether		# Ethernet support
+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)
+
+# 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
+

Modified: projects/amd64_xen_pv/sys/amd64/include/asmacros.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/asmacros.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/asmacros.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -201,4 +201,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/amd64_xen_pv/sys/amd64/include/cpufunc.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/cpufunc.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/cpufunc.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -43,6 +43,13 @@
 #error this file needs sys/cdefs.h as a prerequisite
 #endif
 
+#ifdef XEN
+extern void xen_load_cr3(u_int data);
+extern void xen_tlb_flush(void);
+extern void xen_invlpg(vm_offset_t addr);
+extern u_long read_rflags(void);
+#endif /* XEN */
+
 struct region_descriptor;
 
 #define readb(va)	(*(volatile uint8_t *) (va))
@@ -287,7 +294,11 @@ ia32_pause(void)
 }
 
 static __inline u_long
+#ifdef XEN
+_read_rflags(void)
+#else
 read_rflags(void)
+#endif
 {
 	u_long	rf;
 

Modified: projects/amd64_xen_pv/sys/amd64/include/pcpu.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/pcpu.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/pcpu.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -42,12 +42,33 @@
 #endif
 #endif
 
-#ifdef XENHVM
+#if defined(XEN)
+
+/* These are peridically updated in shared_info, and then copied here. */
+struct shadow_time_info {
+	uint64_t tsc_timestamp;     /* TSC at last update of time vals.  */
+	uint64_t system_timestamp;  /* Time, in nanosecs, since boot.    */
+	uint32_t tsc_to_nsec_mul;
+	uint32_t tsc_to_usec_mul;
+	int tsc_shift;
+	uint32_t version;
+};
+
+#define	PCPU_XEN_FIELDS							\
+	;								\
+	uint64_t pc_processed_system_time;				\
+	struct shadow_time_info pc_shadow_time;				\
+	int	pc_resched_irq;						\
+	int	pc_callfunc_irq;					\
+	int	pc_virq_to_irq[NR_VIRQS];				\
+	int	pc_ipi_to_irq[NR_IPIS]	
+
+#elif defined(XENHVM)
 #define PCPU_XEN_FIELDS							\
 	;								\
 	unsigned int pc_last_processed_l1i;				\
 	unsigned int pc_last_processed_l2i
-#else
+#else /* !XEN && !XENHVM */
 #define PCPU_XEN_FIELDS
 #endif
 

Modified: projects/amd64_xen_pv/sys/amd64/include/pmap.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/pmap.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/pmap.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -229,6 +229,43 @@ pte_store(pt_entry_t *ptep, pt_entry_t p
 
 #define	pde_store(pdep, pde)	pte_store((pdep), (pde))
 
+#if defined(XEN)
+#include <machine/atomic.h>
+#include <machine/xen/xen-os.h>
+#include <machine/xen/xenvar.h>
+#include <machine/xen/xenpmap.h>
+
+#include <sys/systm.h> /* XXX: for KASSERT() remove, when done */
+
+#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)))
+
+#define VTOM(va) xpmap_ptom(VTOP(va))
+
+static __inline vm_paddr_t
+pmap_kextract_ma(vm_offset_t va)
+{
+        vm_paddr_t ma = 0;
+	KASSERT(0, ("XXX: Please implement"));
+        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);
+
+#endif /* XEN */
+
 extern pt_entry_t pg_nx;
 
 #endif /* _KERNEL */
@@ -317,7 +354,9 @@ void	pmap_demote_DMAP(vm_paddr_t base, v
 void	pmap_init_pat(void);
 void	pmap_kenter(vm_offset_t va, vm_paddr_t pa);
 void	*pmap_kenter_temporary(vm_paddr_t pa, int i);
+#ifndef XEN
 vm_paddr_t pmap_kextract(vm_offset_t);
+#endif /* XEN */
 void	pmap_kremove(vm_offset_t);
 void	*pmap_mapbios(vm_paddr_t, vm_size_t);
 void	*pmap_mapdev(vm_paddr_t, vm_size_t);

Modified: projects/amd64_xen_pv/sys/amd64/include/smp.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/smp.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/smp.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -74,6 +74,13 @@ void	smp_masked_invlpg_range(cpuset_t ma
 void	smp_invltlb(void);
 void	smp_masked_invltlb(cpuset_t mask);
 
+#ifdef XEN
+#define RESCHEDULE_VECTOR	0
+#define CALL_FUNCTION_VECTOR	1
+#define NR_IPIS			2
+
+#endif
+
 #endif /* !LOCORE */
 #endif /* SMP */
 

Modified: projects/amd64_xen_pv/sys/amd64/include/xen/xen-os.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/xen/xen-os.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/xen/xen-os.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -6,6 +6,7 @@
 
 #ifndef _XEN_OS_H_
 #define _XEN_OS_H_
+#include <machine/param.h>
 
 #ifdef PAE
 #define CONFIG_X86_PAE
@@ -24,10 +25,35 @@
 /* Force a proper event-channel callback from Xen. */
 void force_evtchn_callback(void);
 
+#define likely(x)  __builtin_expect((x),1)
+#define unlikely(x)  __builtin_expect((x),0)
+
+#ifndef vtophys
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#endif
+
 extern int gdtset;
+#ifdef SMP
+#include <sys/time.h> /* XXX for pcpu.h */
+#include <sys/pcpu.h> /* XXX for PCPU_GET */
+static inline int 
+smp_processor_id(void)  
+{
+	return PCPU_GET(cpuid);
+}
+
+#else
+#define smp_processor_id() 0
+#endif /* SMP */
 
 extern shared_info_t *HYPERVISOR_shared_info;
 
+#ifndef PANIC_IF
+#define PANIC_IF(exp) if (unlikely(exp)) {printk("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);} 
+#endif
+
 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
 static inline void rep_nop(void)
 {
@@ -35,6 +61,8 @@ static inline void rep_nop(void)
 }
 #define cpu_relax() rep_nop()
 
+#define per_cpu(var, cpu)           (pcpu_find((cpu))->pc_ ## var)
+
 /* crude memory allocator for memory allocation early in 
  *  boot
  */
@@ -44,6 +72,7 @@ void bootmem_free(void *ptr, unsigned in
 
 /* Everything below this point is not included by assembler (.S) files. */
 #ifndef __ASSEMBLY__
+#include <sys/types.h>
 
 void printk(const char *fmt, ...);
 

Added: projects/amd64_xen_pv/sys/amd64/include/xen/xen_clock_util.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/amd64_xen_pv/sys/amd64/include/xen/xen_clock_util.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 2009 Adrian Chadd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	__XEN_CLOCK_UTIL_H__
+#define	__XEN_CLOCK_UTIL_H__
+
+extern void xen_fetch_wallclock(struct timespec *ts);
+extern void xen_fetch_uptime(struct timespec *ts);
+
+#endif	/* __XEN_CLOCK_UTIL_H__ */

Modified: projects/amd64_xen_pv/sys/amd64/include/xen/xenpmap.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/xen/xenpmap.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/xen/xenpmap.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -34,17 +34,21 @@
 #ifndef _XEN_XENPMAP_H_
 #define _XEN_XENPMAP_H_
 
-#include <machine/xen/features.h>
-
 void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
 void xen_pt_switch(vm_paddr_t);
 void xen_set_ldt(vm_paddr_t, unsigned long);
+void xen_pgdir_pin(vm_paddr_t);
+void xen_pgdir_unpin(vm_paddr_t);
 void xen_pgdpt_pin(vm_paddr_t);
+void xen_pgdpt_unpin(vm_paddr_t);
 void xen_pgd_pin(vm_paddr_t);
 void xen_pgd_unpin(vm_paddr_t);
 void xen_pt_pin(vm_paddr_t);
 void xen_pt_unpin(vm_paddr_t);
 void xen_flush_queue(void);
+void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
+void pmap_suspend(void);
+void pmap_resume(void);
 void xen_check_queue(void);
 #if 0
 void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
@@ -56,6 +60,10 @@ void pmap_ref(pt_entry_t *pte, vm_paddr_
 #define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
 #endif	
 
+
+#include <sys/param.h>
+#include <sys/pcpu.h>
+
 #ifdef PMAP_DEBUG
 #define PMAP_REF pmap_ref
 #define PMAP_DEC_REF_PAGE pmap_dec_ref_page
@@ -221,7 +229,10 @@ set_phys_to_machine(unsigned long pfn, u
         xen_phys_machine[pfn] = mfn;
 }
 
-
-
+static __inline int
+phys_to_machine_mapping_valid(unsigned long pfn)
+{
+	return xen_phys_machine[pfn] != INVALID_P2M_ENTRY;
+}
 
 #endif /* _XEN_XENPMAP_H_ */

Modified: projects/amd64_xen_pv/sys/amd64/include/xen/xenvar.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/xen/xenvar.h	Tue Apr  3 02:16:21 2012	(r233822)
+++ projects/amd64_xen_pv/sys/amd64/include/xen/xenvar.h	Tue Apr  3 05:42:51 2012	(r233823)
@@ -37,6 +37,8 @@ extern int xendebug_flags;
 #endif
 #include <xen/features.h>
 
+#define NR_CPUS      MAX_VIRT_CPUS
+
 #if 0
 #define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__)
 #define TRACE_EXIT XENPRINTF("(file=%s, line=%d) exiting %s\n", __FILE__, __LINE__, __FUNCTION__)
@@ -64,7 +66,6 @@ machtophys(vm_paddr_t ma)
 	return (ma);
 }
 
-#define vtomach(va)	pmap_kextract((vm_offset_t) (va))
 #define PFNTOMFN(pa)	(pa)
 #define MFNTOPFN(ma)	(ma)
 
@@ -75,7 +76,8 @@ machtophys(vm_paddr_t ma)
 #else
 
 extern	xen_pfn_t *xen_phys_machine;
-
+extern	xen_pfn_t *xen_pfn_to_mfn_frame_list[16]; /* XXX: why 16 ? review this. */
+extern	xen_pfn_t *xen_pfn_to_mfn_frame_list_list;
 
 extern xen_pfn_t *xen_machine_phys;
 /* Xen starts physical pages after the 4MB ISA hole -

Added: projects/amd64_xen_pv/sys/amd64/xen/clock.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/amd64_xen_pv/sys/amd64/xen/clock.c	Tue Apr  3 05:42:51 2012	(r233823)
@@ -0,0 +1,918 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)clock.c	7.2 (Berkeley) 5/12/91
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* #define DELAYDEBUG */
+/*
+ * Routines to handle clock hardware.
+ */
+
+#include "opt_ddb.h"
+#include "opt_clock.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/time.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/sysctl.h>
+#include <sys/cons.h>
+#include <sys/power.h>
+
+#include <machine/clock.h>
+#include <machine/cputypes.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
+#include <machine/psl.h>
+#if defined(SMP)
+#include <machine/smp.h>
+#endif
+#include <machine/specialreg.h>
+#include <machine/timerreg.h>
+
+#include <x86/isa/icu.h>
+#include <x86/isa/isa.h>
+#include <isa/rtc.h>
+
+#include <xen/xen_intr.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+#include <xen/hypervisor.h>
+#include <machine/xen/xen-os.h>
+#include <machine/xen/xenfunc.h>
+#include <xen/interface/vcpu.h>
+#include <machine/cpu.h>
+#include <machine/xen/xen_clock_util.h>
+
+/*
+ * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
+ * can use a simple formula for leap years.
+ */
+#define	LEAPYEAR(y)	(!((y) % 4))
+#define	DAYSPERYEAR	(28+30*4+31*7)
+
+#ifndef TIMER_FREQ
+#define	TIMER_FREQ	1193182
+#endif
+
+#ifdef CYC2NS_SCALE_FACTOR
+#undef	CYC2NS_SCALE_FACTOR
+#endif
+#define CYC2NS_SCALE_FACTOR	10
+
+/* Values for timerX_state: */
+#define	RELEASED	0
+#define	RELEASE_PENDING	1
+#define	ACQUIRED	2
+#define	ACQUIRE_PENDING	3
+
+struct mtx clock_lock;
+#define	RTC_LOCK_INIT							\
+	mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE)
+#define	RTC_LOCK	mtx_lock_spin(&clock_lock)
+#define	RTC_UNLOCK	mtx_unlock_spin(&clock_lock)
+
+int adjkerntz;		/* local offset from GMT in seconds */
+int clkintr_pending;
+int pscnt = 1;
+int psdiv = 1;
+int wall_cmos_clock;
+u_int timer_freq = TIMER_FREQ;
+static int independent_wallclock;
+static int xen_disable_rtc_set;
+static u_long cyc2ns_scale; 
+static struct timespec shadow_tv;
+static uint32_t shadow_tv_version;	/* XXX: lazy locking */
+static uint64_t processed_system_time;	/* stime (ns) at last processing. */
+
+static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
+
+SYSCTL_INT(_machdep, OID_AUTO, independent_wallclock,
+    CTLFLAG_RW, &independent_wallclock, 0, "");
+SYSCTL_INT(_machdep, OID_AUTO, xen_disable_rtc_set,
+    CTLFLAG_RW, &xen_disable_rtc_set, 1, "");
+
+#ifndef __amd64__
+#define do_div(n,base) ({ \
+        unsigned long __upper, __low, __high, __mod, __base; \
+        __base = (base); \
+        __asm("":"=a" (__low), "=d" (__high):"A" (n)); \
+        __upper = __high; \
+        if (__high) { \
+                __upper = __high % (__base); \
+                __high = __high / (__base); \
+        } \
+        __asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
+        __asm("":"=A" (n):"a" (__low),"d" (__high)); \
+        __mod; \
+})
+
+
+#define NS_PER_TICK (1000000000ULL/hz)
+
+#define rdtscll(val) \
+    __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#else /* !__amd64__ */
+#define do_div(n,base) do {} while(0); /* XXX: TODO */
+#define NS_PER_TICK (1000000000ULL/hz)
+#endif /* !__amd64__ */
+
+/* convert from cycles(64bits) => nanoseconds (64bits)
+ *  basic equation:
+ *		ns = cycles / (freq / ns_per_sec)
+ *		ns = cycles * (ns_per_sec / freq)
+ *		ns = cycles * (10^9 / (cpu_mhz * 10^6))
+ *		ns = cycles * (10^3 / cpu_mhz)
+ *
+ *	Then we use scaling math (suggested by george@mvista.com) to get:
+ *		ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ *		ns = cycles * cyc2ns_scale / SC
+ *
+ *	And since SC is a constant power of two, we can convert the div
+ *  into a shift.   
+ *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
+ */
+static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+{
+	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+}
+
+static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+{
+	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline uint64_t 
+scale_delta(uint64_t delta, uint32_t mul_frac, int shift)
+{
+	uint64_t product;
+	uint32_t tmp1, tmp2;
+
+	if ( shift < 0 )
+		delta >>= -shift;
+	else
+		delta <<= shift;
+
+	__asm__ (
+		"mul  %5       ; "
+		"mov  %4,%%eax ; "
+		"mov  %%edx,%4 ; "
+		"mul  %5       ; "
+		"xor  %5,%5    ; "
+		"add  %4,%%eax ; "
+		"adc  %5,%%edx ; "
+		: "=A" (product), "=r" (tmp1), "=r" (tmp2)
+		: "a" ((uint32_t)delta), "1" ((uint32_t)(delta >> 32)), "2" (mul_frac) );
+
+	return product;
+}
+
+static uint64_t
+get_nsec_offset(struct shadow_time_info *shadow)
+{
+	uint64_t now, delta;
+	rdtscll(now);
+	delta = now - shadow->tsc_timestamp;
+	return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
+}
+
+static void update_wallclock(void)
+{
+	shared_info_t *s = HYPERVISOR_shared_info;
+
+	do {
+		shadow_tv_version = s->wc_version;
+		rmb();
+		shadow_tv.tv_sec  = s->wc_sec;
+		shadow_tv.tv_nsec = s->wc_nsec;
+		rmb();
+	}
+	while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
+
+}
+
+static void
+add_uptime_to_wallclock(void)
+{
+	struct timespec ut;
+
+	xen_fetch_uptime(&ut);
+	timespecadd(&shadow_tv, &ut);
+}
+
+/*
+ * Reads a consistent set of time-base values from Xen, into a shadow data
+ * area. Must be called with the xtime_lock held for writing.
+ */
+static void __get_time_values_from_xen(void)
+{
+	shared_info_t           *s = HYPERVISOR_shared_info;
+	struct vcpu_time_info   *src;
+	struct shadow_time_info *dst;
+	uint32_t pre_version, post_version;
+
+	src = &s->vcpu_info[smp_processor_id()].time;
+	dst = &per_cpu(shadow_time, smp_processor_id());
+
+	spinlock_enter();
+	do {
+	        pre_version = dst->version = src->version;
+		rmb();
+		dst->tsc_timestamp     = src->tsc_timestamp;
+		dst->system_timestamp  = src->system_time;
+		dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
+		dst->tsc_shift         = src->tsc_shift;
+		rmb();
+		post_version = src->version;
+	}
+	while ((pre_version & 1) | (pre_version ^ post_version));
+
+	dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
+	spinlock_exit();
+}
+
+
+static inline int time_values_up_to_date(int cpu)
+{
+	struct vcpu_time_info   *src;
+	struct shadow_time_info *dst;
+
+	src = &HYPERVISOR_shared_info->vcpu_info[cpu].time; 
+	dst = &per_cpu(shadow_time, cpu); 
+
+	rmb();
+	return (dst->version == src->version);
+}
+
+static	unsigned xen_get_timecount(struct timecounter *tc);
+
+static struct timecounter xen_timecounter = {
+	xen_get_timecount,	/* get_timecount */
+	0,			/* no poll_pps */
+	~0u,			/* counter_mask */
+	0,			/* frequency */
+	"ixen",			/* name */
+	0			/* quality */
+};
+
+static struct eventtimer xen_et;
+
+struct xen_et_state {
+	int		mode;
+#define	MODE_STOP	0
+#define	MODE_PERIODIC	1
+#define	MODE_ONESHOT	2
+	int64_t		period;
+	int64_t		next;
+};
+
+static DPCPU_DEFINE(struct xen_et_state, et_state);
+
+static int
+clkintr(void *arg)
+{
+	int64_t now;
+	int cpu = smp_processor_id();
+	struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
+	struct xen_et_state *state = DPCPU_PTR(et_state);
+
+	do {
+		__get_time_values_from_xen();
+		now = shadow->system_timestamp + get_nsec_offset(shadow);
+	} while (!time_values_up_to_date(cpu));
+
+	/* Process elapsed ticks since last call. */
+	processed_system_time = now;
+	if (state->mode == MODE_PERIODIC) {
+		while (now >= state->next) {
+		        state->next += state->period;
+			if (xen_et.et_active)
+				xen_et.et_event_cb(&xen_et, xen_et.et_arg);
+		}
+		HYPERVISOR_set_timer_op(state->next + 50000);
+	} else if (state->mode == MODE_ONESHOT) {
+		if (xen_et.et_active)
+			xen_et.et_event_cb(&xen_et, xen_et.et_arg);
+	}
+	/*
+	 * Take synchronised time from Xen once a minute if we're not
+	 * synchronised ourselves, and we haven't chosen to keep an independent
+	 * time base.
+	 */
+	
+	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version &&
+	    !independent_wallclock) {
+		printf("[XEN] hypervisor wallclock nudged; nudging TOD.\n");
+		update_wallclock();
+		add_uptime_to_wallclock();
+		tc_setclock(&shadow_tv);
+	}
+	
+	/* XXX TODO */
+	return (FILTER_HANDLED);
+}
+static uint32_t
+getit(void)
+{
+	struct shadow_time_info *shadow;
+	uint64_t time;
+	uint32_t local_time_version;
+
+	shadow = &per_cpu(shadow_time, smp_processor_id());
+
+	do {
+	  local_time_version = shadow->version;
+	  barrier();
+	  time = shadow->system_timestamp + get_nsec_offset(shadow);
+	  if (!time_values_up_to_date(smp_processor_id()))
+	    __get_time_values_from_xen(/*cpu */);
+	  barrier();
+	} while (local_time_version != shadow->version);
+
+	  return (time);
+}
+
+
+/*
+ * XXX: timer needs more SMP work.
+ */
+void
+i8254_init(void)
+{
+
+	RTC_LOCK_INIT;
+}
+
+/*
+ * Wait "n" microseconds.
+ * Relies on timer 1 counting down from (timer_freq / hz)
+ * Note: timer had better have been programmed before this is first used!
+ */
+void
+DELAY(int n)
+{
+	int delta, ticks_left;
+	uint32_t tick, prev_tick;
+#ifdef DELAYDEBUG
+	int getit_calls = 1;
+	int n1;
+	static int state = 0;
+
+	if (state == 0) {
+		state = 1;
+		for (n1 = 1; n1 <= 10000000; n1 *= 10)
+			DELAY(n1);
+		state = 2;
+	}
+	if (state == 1)
+		printf("DELAY(%d)...", n);
+#endif
+	/*
+	 * Read the counter first, so that the rest of the setup overhead is
+	 * counted.  Guess the initial overhead is 20 usec (on most systems it
+	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
+	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
+	 * multiplications and divisions to scale the count take a while).
+	 *
+	 * However, if ddb is active then use a fake counter since reading
+	 * the i8254 counter involves acquiring a lock.  ddb must not go

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204030542.q335gpVH033582>