From owner-svn-src-projects@FreeBSD.ORG Tue Apr 3 05:42:51 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EFCDA1065672; Tue, 3 Apr 2012 05:42:51 +0000 (UTC) (envelope-from cherry@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D8A2C8FC08; Tue, 3 Apr 2012 05:42:51 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q335gp3t033598; Tue, 3 Apr 2012 05:42:51 GMT (envelope-from cherry@svn.freebsd.org) Received: (from cherry@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q335gpVH033582; Tue, 3 Apr 2012 05:42:51 GMT (envelope-from cherry@svn.freebsd.org) Message-Id: <201204030542.q335gpVH033582@svn.freebsd.org> From: "Cherry G. Mathew" Date: Tue, 3 Apr 2012 05:42:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: 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 X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Apr 2012 05:42:52 -0000 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 +ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START); +ASSYM(EVTCHN_UPCALL_MASK, offsetof(struct vcpu_info, evtchn_upcall_mask)); +#include +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 +#include +#include +#include + +#include /* 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 #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 +#include +#include +#endif + extern int gdtset; +#ifdef SMP +#include /* XXX for pcpu.h */ +#include /* 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 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 - 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 +#include + #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 +#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 +__FBSDID("$FreeBSD$"); + +/* #define DELAYDEBUG */ +/* + * Routines to handle clock hardware. + */ + +#include "opt_ddb.h" +#include "opt_clock.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#if defined(SMP) +#include +#endif +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 ***