summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/apic_vector.s19
-rw-r--r--sys/i386/i386/machdep.c17
-rw-r--r--sys/i386/i386/mp_machdep.c9
-rw-r--r--sys/i386/include/apicvar.h1
-rw-r--r--sys/i386/include/intr_machdep.h24
-rw-r--r--sys/i386/include/pcpu.h16
-rw-r--r--sys/i386/include/pmap.h4
-rw-r--r--sys/i386/include/xen/xen-os.h168
-rw-r--r--sys/i386/include/xen/xenfunc.h6
-rw-r--r--sys/i386/include/xen/xenvar.h3
-rw-r--r--sys/i386/isa/npx.c2
-rw-r--r--sys/i386/xen/clock.c58
-rw-r--r--sys/i386/xen/exception.s2
-rw-r--r--sys/i386/xen/mp_machdep.c89
-rw-r--r--sys/i386/xen/mptable.c2
-rw-r--r--sys/i386/xen/xen_clock_util.c3
-rw-r--r--sys/i386/xen/xen_machdep.c48
-rw-r--r--sys/i386/xen/xen_rtc.c10
18 files changed, 252 insertions, 229 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 618436d..adedbc4 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -138,6 +138,25 @@ IDTVEC(errorint)
MEXITCOUNT
jmp doreti
+#ifdef XENHVM
+/*
+ * Xen event channel upcall interrupt handler.
+ * Only used when the hypervisor supports direct vector callbacks.
+ */
+ .text
+ SUPERALIGN_TEXT
+IDTVEC(xen_intr_upcall)
+ PUSH_FRAME
+ SET_KERNEL_SREGS
+ cld
+ FAKE_MCOUNT(TF_EIP(%esp))
+ pushl %esp
+ call xen_intr_handle_upcall
+ add $4, %esp
+ MEXITCOUNT
+ jmp doreti
+#endif
+
#ifdef SMP
/*
* Global address space TLB shootdown.
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 9a710e5..c430316 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -160,9 +160,8 @@ uint32_t arch_i386_xbox_memsize = 0;
#ifdef XEN
/* XEN includes */
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <xen/hypervisor.h>
-#include <machine/xen/xen-os.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
#include <xen/xen_intr.h>
@@ -1216,6 +1215,13 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
#ifdef XEN
+static void
+idle_block(void)
+{
+
+ HYPERVISOR_sched_op(SCHEDOP_block, 0);
+}
+
void
cpu_halt(void)
{
@@ -1960,6 +1966,9 @@ extern inthand_t
#ifdef KDTRACE_HOOKS
IDTVEC(dtrace_ret),
#endif
+#ifdef XENHVM
+ IDTVEC(xen_intr_upcall),
+#endif
IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall);
#ifdef DDB
@@ -2948,6 +2957,10 @@ init386(first)
setidt(IDT_DTRACE_RET, &IDTVEC(dtrace_ret), SDT_SYS386TGT, SEL_UPL,
GSEL(GCODE_SEL, SEL_KPL));
#endif
+#ifdef XENHVM
+ setidt(IDT_EVTCHN, &IDTVEC(xen_intr_upcall), SDT_SYS386IGT, SEL_UPL,
+ GSEL(GCODE_SEL, SEL_KPL));
+#endif
r_idt.rd_limit = sizeof(idt0) - 1;
r_idt.rd_base = (int) idt;
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 19e67cf..479168b 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -82,6 +82,10 @@ __FBSDID("$FreeBSD$");
#include <machine/smp.h>
#include <machine/specialreg.h>
+#ifdef XENHVM
+#include <xen/hvm.h>
+#endif
+
#define WARMBOOT_TARGET 0
#define WARMBOOT_OFF (KERNBASE + 0x0467)
#define WARMBOOT_SEG (KERNBASE + 0x0469)
@@ -747,6 +751,11 @@ init_secondary(void)
/* set up SSE registers */
enable_sse();
+#ifdef XENHVM
+ /* register vcpu_info area */
+ xen_hvm_init_cpu();
+#endif
+
#ifdef PAE
/* Enable the PTE no-execute bit. */
if ((amd_feature & AMDID_NX) != 0) {
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index a0e622e..5d1f522 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -226,6 +226,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
enum intr_trigger trigger);
void lapic_set_tpr(u_int vector);
void lapic_setup(int boot);
+void xen_intr_handle_upcall(struct trapframe *frame);
#endif /* !LOCORE */
#endif /* _MACHINE_APICVAR_H_ */
diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h
index b3dd122..6bbe378 100644
--- a/sys/i386/include/intr_machdep.h
+++ b/sys/i386/include/intr_machdep.h
@@ -44,12 +44,30 @@
* allocate IDT vectors.
*
* The first 255 IRQs (0 - 254) are reserved for ISA IRQs and PCI intline IRQs.
- * IRQ values beyond 256 are used by MSI. We leave 255 unused to avoid
- * confusion since 255 is used in PCI to indicate an invalid IRQ.
+ * IRQ values from 256 to 767 are used by MSI. When running under the Xen
+ * Hypervisor, IRQ values from 768 to 4863 are available for binding to
+ * event channel events. We leave 255 unused to avoid confusion since 255 is
+ * used in PCI to indicate an invalid IRQ.
*/
#define NUM_MSI_INTS 512
#define FIRST_MSI_INT 256
-#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS)
+#ifdef XENHVM
+#include <xen/xen-os.h>
+#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS
+#define FIRST_EVTCHN_INT \
+ (FIRST_MSI_INT + NUM_MSI_INTS)
+#define LAST_EVTCHN_INT \
+ (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1)
+#elif defined(XEN)
+#include <xen/xen-os.h>
+#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS
+#define FIRST_EVTCHN_INT 0
+#define LAST_EVTCHN_INT \
+ (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1)
+#else /* !XEN && !XENHVM */
+#define NUM_EVTCHN_INTS 0
+#endif
+#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS + NUM_EVTCHN_INTS)
/*
* Default base address for MSI messages on x86 platforms.
diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h
index 3606d12..3a684bf 100644
--- a/sys/i386/include/pcpu.h
+++ b/sys/i386/include/pcpu.h
@@ -71,21 +71,9 @@ struct shadow_time_info {
vm_paddr_t *pc_pdir_shadow; \
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]; \
- char __pad[77]
+ char __pad[189]
-#elif defined(XENHVM)
-
-#define PCPU_XEN_FIELDS \
- ; \
- unsigned int pc_last_processed_l1i; \
- unsigned int pc_last_processed_l2i; \
- char __pad[229]
-
-#else /* !XEN && !XENHVM */
+#else /* !XEN */
#define PCPU_XEN_FIELDS \
; \
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 94b63ca..0303c60 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -213,7 +213,9 @@ extern pd_entry_t *IdlePTD; /* physical address of "Idle" state directory */
#if defined(XEN)
#include <sys/param.h>
-#include <machine/xen/xen-os.h>
+
+#include <xen/xen-os.h>
+
#include <machine/xen/xenvar.h>
#include <machine/xen/xenpmap.h>
diff --git a/sys/i386/include/xen/xen-os.h b/sys/i386/include/xen/xen-os.h
index 257202e..e15d668 100644
--- a/sys/i386/include/xen/xen-os.h
+++ b/sys/i386/include/xen/xen-os.h
@@ -1,52 +1,64 @@
-/******************************************************************************
- * os.h
+/*****************************************************************************
+ * i386/xen/xen-os.h
*
- * random collection of macros and definition
+ * Random collection of macros and definition
+ *
+ * Copyright (c) 2003, 2004 Keir Fraser (on behalf of the Xen team)
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
*/
-#ifndef _XEN_OS_H_
-#define _XEN_OS_H_
-#include <machine/param.h>
+#ifndef _MACHINE_XEN_XEN_OS_H_
+#define _MACHINE_XEN_XEN_OS_H_
#ifdef PAE
#define CONFIG_X86_PAE
#endif
-#ifdef LOCORE
-#define __ASSEMBLY__
-#endif
-
-#if !defined(__XEN_INTERFACE_VERSION__)
-#define __XEN_INTERFACE_VERSION__ 0x00030208
-#endif
-
-#define GRANT_REF_INVALID 0xffffffff
-
-#include <xen/interface/xen.h>
-
/* Everything below this point is not included by assembler (.S) files. */
#ifndef __ASSEMBLY__
/* 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)
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline void rep_nop(void)
+{
+ __asm__ __volatile__ ( "rep;nop" : : : "memory" );
+}
+#define cpu_relax() rep_nop()
-#ifndef vtophys
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#endif
+#ifndef XENHVM
+void xc_printf(const char *fmt, ...);
-extern int gdtset;
#ifdef SMP
+extern int gdtset;
+
#include <sys/time.h> /* XXX for pcpu.h */
#include <sys/pcpu.h> /* XXX for PCPU_GET */
static inline int
smp_processor_id(void)
{
- if (likely(gdtset))
+ if (__predict_true(gdtset))
return PCPU_GET(cpuid);
return 0;
}
@@ -55,50 +67,16 @@ smp_processor_id(void)
#define smp_processor_id() 0
#endif
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
#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
-
-extern shared_info_t *HYPERVISOR_shared_info;
-
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
- a mechanism by which the user can annotate likely branch directions and
- expect the blocks to be reordered appropriately. Define __builtin_expect
- to nothing for earlier compilers. */
-
-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-static inline void rep_nop(void)
-{
- __asm__ __volatile__ ( "rep;nop" : : : "memory" );
-}
-#define cpu_relax() rep_nop()
-
-
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
+#define PANIC_IF(exp) if (__predict_false(exp)) {printf("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);}
#endif
-#define per_cpu(var, cpu) (pcpu_find((cpu))->pc_ ## var)
-
-/* crude memory allocator for memory allocation early in
- * boot
+/*
+ * Crude memory allocator for memory allocation early in boot.
*/
void *bootmem_alloc(unsigned int size);
void bootmem_free(void *ptr, unsigned int size);
-#include <sys/types.h>
-
-void printk(const char *fmt, ...);
-
-/* some function prototypes */
-void trap_init(void);
-
-#ifndef XENHVM
-
/*
* STI/CLI equivalents. These basically set and clear the virtual
* event_enable flag in the shared_info structure. Note that when
@@ -106,7 +84,6 @@ void trap_init(void);
* We may therefore call into do_hypervisor_callback() directly.
*/
-
#define __cli() \
do { \
vcpu_info_t *_vcpu; \
@@ -122,7 +99,7 @@ do { \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
_vcpu->evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
- if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
+ if (__predict_false(_vcpu->evtchn_upcall_pending)) \
force_evtchn_callback(); \
} while (0)
@@ -133,7 +110,7 @@ do { \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
barrier(); /* unmask then check (avoid races) */ \
- if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
+ if (__predict_false(_vcpu->evtchn_upcall_pending)) \
force_evtchn_callback(); \
} \
} while (0)
@@ -168,31 +145,7 @@ do { \
#define spin_lock_irqsave mtx_lock_irqsave
#define spin_unlock_irqrestore mtx_unlock_irqrestore
-#endif
-
-#ifndef xen_mb
-#define xen_mb() mb()
-#endif
-#ifndef xen_rmb
-#define xen_rmb() rmb()
-#endif
-#ifndef xen_wmb
-#define xen_wmb() wmb()
-#endif
-#ifdef SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_read_barrier_depends() read_barrier_depends()
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_read_barrier_depends() do { } while(0)
-#define set_mb(var, value) do { var = value; barrier(); } while (0)
-#endif
-
+#endif /* !XENHVM */
/* This is a barrier for the compiler only, NOT the processor! */
#define barrier() __asm__ __volatile__("": : :"memory")
@@ -207,8 +160,6 @@ do { \
*/
typedef struct { volatile int counter; } atomic_t;
-
-
#define xen_xchg(ptr,v) \
((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
struct __xchg_dummy { unsigned long a[100]; };
@@ -335,33 +286,6 @@ static __inline__ void atomic_inc(atomic_t *v)
#define rdtscll(val) \
__asm__ __volatile__("rdtsc" : "=A" (val))
-
-
-/*
- * Kernel pointers have redundant information, so we can use a
- * scheme where we can return either an error code or a dentry
- * pointer with the same return value.
- *
- * This should be a per-architecture thing, to allow different
- * error and pointer decisions.
- */
-#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L)
-
-static inline void *ERR_PTR(long error)
-{
- return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
- return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
- return IS_ERR_VALUE((unsigned long)ptr);
-}
-
#endif /* !__ASSEMBLY__ */
-#endif /* _OS_H_ */
+#endif /* _MACHINE_XEN_XEN_OS_H_ */
diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h
index 47f0405..f02ee12 100644
--- a/sys/i386/include/xen/xenfunc.h
+++ b/sys/i386/include/xen/xenfunc.h
@@ -29,10 +29,14 @@
#ifndef _XEN_XENFUNC_H_
#define _XEN_XENFUNC_H_
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <xen/hypervisor.h>
+
+#include <vm/pmap.h>
+
#include <machine/xen/xenpmap.h>
#include <machine/segments.h>
+
#include <sys/pcpu.h>
#define BKPT __asm__("int3");
#define XPQ_CALL_DEPTH 5
diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h
index b1a0a4d..2742613 100644
--- a/sys/i386/include/xen/xenvar.h
+++ b/sys/i386/include/xen/xenvar.h
@@ -37,7 +37,8 @@
#define XPMAP 0x2
extern int xendebug_flags;
#ifndef NOXENDEBUG
-#define XENPRINTF printk
+/* Print directly to the Xen console during debugging. */
+#define XENPRINTF xc_printf
#else
#define XENPRINTF printf
#endif
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 3b86d84..622e5b7 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#ifdef XEN
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <xen/hypervisor.h>
#endif
diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c
index a10b546..524fa14 100644
--- a/sys/i386/xen/clock.c
+++ b/sys/i386/xen/clock.c
@@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/pmap.h>
#include <xen/hypervisor.h>
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <machine/xen/xenfunc.h>
#include <xen/interface/vcpu.h>
#include <machine/cpu.h>
@@ -133,6 +133,8 @@ 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};
+int ap_cpu_initclocks(int cpu);
+
SYSCTL_INT(_machdep, OID_AUTO, independent_wallclock,
CTLFLAG_RW, &independent_wallclock, 0, "");
SYSCTL_INT(_machdep, OID_AUTO, xen_disable_rtc_set,
@@ -257,9 +259,11 @@ static void __get_time_values_from_xen(void)
struct vcpu_time_info *src;
struct shadow_time_info *dst;
uint32_t pre_version, post_version;
+ struct pcpu *pc;
+ pc = pcpu_find(smp_processor_id());
src = &s->vcpu_info[smp_processor_id()].time;
- dst = &per_cpu(shadow_time, smp_processor_id());
+ dst = &pc->pc_shadow_time;
spinlock_enter();
do {
@@ -283,9 +287,11 @@ static inline int time_values_up_to_date(int cpu)
{
struct vcpu_time_info *src;
struct shadow_time_info *dst;
+ struct pcpu *pc;
src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
- dst = &per_cpu(shadow_time, cpu);
+ pc = pcpu_find(cpu);
+ dst = &pc->pc_shadow_time;
rmb();
return (dst->version == src->version);
@@ -320,7 +326,8 @@ clkintr(void *arg)
{
int64_t now;
int cpu = smp_processor_id();
- struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
+ struct pcpu *pc = pcpu_find(cpu);
+ struct shadow_time_info *shadow = &pc->pc_shadow_time;
struct xen_et_state *state = DPCPU_PTR(et_state);
do {
@@ -364,8 +371,10 @@ getit(void)
struct shadow_time_info *shadow;
uint64_t time;
uint32_t local_time_version;
+ struct pcpu *pc;
- shadow = &per_cpu(shadow_time, smp_processor_id());
+ pc = pcpu_find(smp_processor_id());
+ shadow = &pc->pc_shadow_time;
do {
local_time_version = shadow->version;
@@ -492,12 +501,14 @@ void
timer_restore(void)
{
struct xen_et_state *state = DPCPU_PTR(et_state);
+ struct pcpu *pc;
/* Get timebases for new environment. */
__get_time_values_from_xen();
/* Reset our own concept of passage of system time. */
- processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
+ pc = pcpu_find(0);
+ processed_system_time = pc->pc_shadow_time.system_timestamp;
state->next = processed_system_time;
}
@@ -508,10 +519,13 @@ startrtclock()
uint64_t __cpu_khz;
uint32_t cpu_khz;
struct vcpu_time_info *info;
+ struct pcpu *pc;
+
+ pc = pcpu_find(0);
/* initialize xen values */
__get_time_values_from_xen();
- processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
+ processed_system_time = pc->pc_shadow_time.system_timestamp;
__cpu_khz = 1000000ULL << 32;
info = &HYPERVISOR_shared_info->vcpu_info[0].time;
@@ -594,8 +608,10 @@ domu_resettodr(void)
int s;
dom0_op_t op;
struct shadow_time_info *shadow;
+ struct pcpu *pc;
- shadow = &per_cpu(shadow_time, smp_processor_id());
+ pc = pcpu_find(smp_processor_id());
+ shadow = &pc->pc_shadow_time;
if (xen_disable_rtc_set)
return;
@@ -773,6 +789,7 @@ xen_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
struct xen_et_state *state = DPCPU_PTR(et_state);
struct shadow_time_info *shadow;
int64_t fperiod;
+ struct pcpu *pc;
__get_time_values_from_xen();
@@ -788,7 +805,8 @@ xen_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
else
fperiod = state->period;
- shadow = &per_cpu(shadow_time, smp_processor_id());
+ pc = pcpu_find(smp_processor_id());
+ shadow = &pc->pc_shadow_time;
state->next = shadow->system_timestamp + get_nsec_offset(shadow);
state->next += fperiod;
HYPERVISOR_set_timer_op(state->next + 50000);
@@ -811,11 +829,11 @@ xen_et_stop(struct eventtimer *et)
void
cpu_initclocks(void)
{
- unsigned int time_irq;
+ xen_intr_handle_t time_irq;
int error;
HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, 0, NULL);
- error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "cpu0:timer",
+ error = xen_intr_bind_virq(root_bus, VIRQ_TIMER, 0,
clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq);
if (error)
panic("failed to register clock interrupt\n");
@@ -840,13 +858,11 @@ cpu_initclocks(void)
int
ap_cpu_initclocks(int cpu)
{
- char buf[MAXCOMLEN + 1];
- unsigned int time_irq;
+ xen_intr_handle_t time_irq;
int error;
HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL);
- snprintf(buf, sizeof(buf), "cpu%d:timer", cpu);
- error = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, buf,
+ error = xen_intr_bind_virq(root_bus, VIRQ_TIMER, cpu,
clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq);
if (error)
panic("failed to register clock interrupt\n");
@@ -859,7 +875,10 @@ xen_get_timecount(struct timecounter *tc)
{
uint64_t clk;
struct shadow_time_info *shadow;
- shadow = &per_cpu(shadow_time, smp_processor_id());
+ struct pcpu *pc;
+
+ pc = pcpu_find(smp_processor_id());
+ shadow = &pc->pc_shadow_time;
__get_time_values_from_xen();
@@ -876,13 +895,6 @@ get_system_time(int ticks)
return processed_system_time + (ticks * NS_PER_TICK);
}
-void
-idle_block(void)
-{
-
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
-}
-
int
timer_spkr_acquire(void)
{
diff --git a/sys/i386/xen/exception.s b/sys/i386/xen/exception.s
index e965ffd..95f1c0e 100644
--- a/sys/i386/xen/exception.s
+++ b/sys/i386/xen/exception.s
@@ -168,7 +168,7 @@ call_evtchn_upcall:
jb critical_region_fixup
10: pushl %esp
- call evtchn_do_upcall
+ call xen_intr_handle_upcall
addl $4,%esp
/*
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index 05531cb..407731a 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$");
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <xen/evtchn.h>
#include <xen/xen_intr.h>
#include <xen/hypervisor.h>
@@ -102,9 +102,6 @@ extern struct pcpu __pcpu[];
static int bootAP;
static union descriptor *bootAPgdt;
-static char resched_name[NR_CPUS][15];
-static char callfunc_name[NR_CPUS][15];
-
/* Free these after use */
void *bootstacks[MAXCPU];
@@ -156,6 +153,10 @@ static cpuset_t hyperthreading_cpus_mask;
extern void Xhypervisor_callback(void);
extern void failsafe_callback(void);
extern void pmap_lazyfix_action(void);
+extern int ap_cpu_initclocks(int cpu);
+
+DPCPU_DEFINE(xen_intr_handle_t, ipi_port[NR_IPIS]);
+DPCPU_DEFINE(struct vcpu_info *, vcpu_info);
struct cpu_group *
cpu_topo(void)
@@ -461,49 +462,49 @@ cpu_mp_announce(void)
}
static int
-xen_smp_intr_init(unsigned int cpu)
+xen_smp_cpu_init(unsigned int cpu)
{
int rc;
- unsigned int irq;
-
- per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1;
+ xen_intr_handle_t irq_handle;
- sprintf(resched_name[cpu], "resched%u", cpu);
- rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR,
- cpu,
- resched_name[cpu],
- smp_reschedule_interrupt,
- INTR_TYPE_TTY, &irq);
+ DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL);
+ DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL);
- printf("[XEN] IPI cpu=%d irq=%d vector=RESCHEDULE_VECTOR (%d)\n",
- cpu, irq, RESCHEDULE_VECTOR);
-
- per_cpu(resched_irq, cpu) = irq;
-
- sprintf(callfunc_name[cpu], "callfunc%u", cpu);
- rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
- cpu,
- callfunc_name[cpu],
- smp_call_function_interrupt,
- INTR_TYPE_TTY, &irq);
+ /*
+ * The PCPU variable pc_device is not initialized on i386 PV,
+ * so we have to use the root_bus device in order to setup
+ * the IPIs.
+ */
+ rc = xen_intr_bind_ipi(root_bus, RESCHEDULE_VECTOR,
+ cpu, smp_reschedule_interrupt, INTR_TYPE_TTY, &irq_handle);
if (rc < 0)
goto fail;
- per_cpu(callfunc_irq, cpu) = irq;
+ xen_intr_describe(irq_handle, "resched%u", cpu);
+ DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], irq_handle);
- printf("[XEN] IPI cpu=%d irq=%d vector=CALL_FUNCTION_VECTOR (%d)\n",
- cpu, irq, CALL_FUNCTION_VECTOR);
+ printf("[XEN] IPI cpu=%d port=%d vector=RESCHEDULE_VECTOR (%d)\n",
+ cpu, xen_intr_port(irq_handle), RESCHEDULE_VECTOR);
+
+ rc = xen_intr_bind_ipi(root_bus, CALL_FUNCTION_VECTOR,
+ cpu, smp_call_function_interrupt, INTR_TYPE_TTY, &irq_handle);
+ if (rc < 0)
+ goto fail;
+ xen_intr_describe(irq_handle, "callfunc%u", cpu);
+ DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], irq_handle);
+
+ printf("[XEN] IPI cpu=%d port=%d vector=CALL_FUNCTION_VECTOR (%d)\n",
+ cpu, xen_intr_port(irq_handle), CALL_FUNCTION_VECTOR);
-
if ((cpu != 0) && ((rc = ap_cpu_initclocks(cpu)) != 0))
goto fail;
return 0;
fail:
- if (per_cpu(resched_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(resched_irq, cpu));
- if (per_cpu(callfunc_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(callfunc_irq, cpu));
+ xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[RESCHEDULE_VECTOR]));
+ DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL);
+ xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[CALL_FUNCTION_VECTOR]));
+ DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL);
return rc;
}
@@ -513,7 +514,17 @@ xen_smp_intr_init_cpus(void *unused)
int i;
for (i = 0; i < mp_ncpus; i++)
- xen_smp_intr_init(i);
+ xen_smp_cpu_init(i);
+}
+
+static void
+xen_smp_intr_setup_cpus(void *unused)
+{
+ int i;
+
+ for (i = 0; i < mp_ncpus; i++)
+ DPCPU_ID_SET(i, vcpu_info,
+ &HYPERVISOR_shared_info->vcpu_info[i]);
}
#define MTOPSIZE (1<<(14 + PAGE_SHIFT))
@@ -959,6 +970,13 @@ start_ap(int apic_id)
return 0; /* return FAILURE */
}
+static void
+ipi_pcpu(int cpu, u_int ipi)
+{
+ KASSERT((ipi <= NR_IPIS), ("invalid IPI"));
+ xen_intr_signal(DPCPU_ID_GET(cpu, ipi_port[ipi]));
+}
+
/*
* send an IPI to a specific CPU.
*/
@@ -1246,5 +1264,6 @@ release_aps(void *dummy __unused)
ia32_pause();
}
SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
-SYSINIT(start_ipis, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL);
+SYSINIT(start_ipis, SI_SUB_SMP, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL);
+SYSINIT(start_cpu, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_setup_cpus, NULL);
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
index 0c1efe8..74cb9ab 100644
--- a/sys/i386/xen/mptable.c
+++ b/sys/i386/xen/mptable.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/apicvar.h>
#include <xen/hypervisor.h>
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <machine/smp.h>
#include <xen/interface/vcpu.h>
diff --git a/sys/i386/xen/xen_clock_util.c b/sys/i386/xen/xen_clock_util.c
index c14a627..c124515 100644
--- a/sys/i386/xen/xen_clock_util.c
+++ b/sys/i386/xen/xen_clock_util.c
@@ -39,12 +39,13 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/time.h>
+#include <xen/xen-os.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/io/xenbus.h>
#include <xen/interface/vcpu.h>
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index 9b5edd3..7049be6 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rwlock.h>
#include <sys/sysproto.h>
-#include <machine/xen/xen-os.h>
+#include <xen/xen-os.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -96,6 +96,8 @@ xen_pfn_t *xen_pfn_to_mfn_frame_list[16];
xen_pfn_t *xen_pfn_to_mfn_frame_list_list;
int preemptable, init_first;
extern unsigned int avail_space;
+int xen_vector_callback_enabled = 0;
+enum xen_domain_type xen_domain_type = XEN_PV_DOMAIN;
void ni_cli(void);
void ni_sti(void);
@@ -129,6 +131,12 @@ ni_sti(void)
);
}
+void
+force_evtchn_callback(void)
+{
+ (void)HYPERVISOR_xen_version(0, NULL);
+}
+
/*
* Modify the cmd_line by converting ',' to NULLs so that it is in a format
* suitable for the static env vars.
@@ -141,7 +149,7 @@ xen_setbootenv(char *cmd_line)
/* Skip leading spaces */
for (; *cmd_line == ' '; cmd_line++);
- printk("xen_setbootenv(): cmd_line='%s'\n", cmd_line);
+ xc_printf("xen_setbootenv(): cmd_line='%s'\n", cmd_line);
for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;);
return cmd_line;
@@ -177,16 +185,16 @@ xen_boothowto(char *envp)
return howto;
}
-#define PRINTK_BUFSIZE 1024
+#define XC_PRINTF_BUFSIZE 1024
void
-printk(const char *fmt, ...)
+xc_printf(const char *fmt, ...)
{
__va_list ap;
int retval;
- static char buf[PRINTK_BUFSIZE];
+ static char buf[XC_PRINTF_BUFSIZE];
va_start(ap, fmt);
- retval = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap);
+ retval = vsnprintf(buf, XC_PRINTF_BUFSIZE - 1, fmt, ap);
va_end(ap);
buf[retval] = 0;
(void)HYPERVISOR_console_write(buf, retval);
@@ -239,9 +247,10 @@ xen_dump_queue(void)
if (_xpq_idx <= 1)
return;
- printk("xen_dump_queue(): %u entries\n", _xpq_idx);
+ xc_printf("xen_dump_queue(): %u entries\n", _xpq_idx);
for (i = 0; i < _xpq_idx; i++) {
- printk(" val: %llx ptr: %llx\n", XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr);
+ xc_printf(" val: %llx ptr: %llx\n", XPQ_QUEUE[i].val,
+ XPQ_QUEUE[i].ptr);
}
}
#endif
@@ -955,9 +964,10 @@ initvalues(start_info_t *startinfo)
cur_space = xen_start_info->pt_base +
(l3_pages + l2_pages + l1_pages + 1)*PAGE_SIZE;
- printk("initvalues(): wooh - availmem=%x,%x\n", avail_space, cur_space);
+ xc_printf("initvalues(): wooh - availmem=%x,%x\n", avail_space,
+ cur_space);
- printk("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n",
+ xc_printf("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n",
KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base),
xen_start_info->nr_pt_frames);
xendebug_flags = 0; /* 0xffffffff; */
@@ -1007,7 +1017,7 @@ initvalues(start_info_t *startinfo)
/* Map proc0's KSTACK */
proc0kstack = cur_space; cur_space += (KSTACK_PAGES * PAGE_SIZE);
- printk("proc0kstack=%u\n", proc0kstack);
+ xc_printf("proc0kstack=%u\n", proc0kstack);
/* vm86/bios stack */
cur_space += PAGE_SIZE;
@@ -1106,18 +1116,18 @@ initvalues(start_info_t *startinfo)
shinfo = xen_start_info->shared_info;
PT_SET_MA(HYPERVISOR_shared_info, shinfo | PG_KERNEL);
- printk("#4\n");
+ xc_printf("#4\n");
xen_store_ma = (((vm_paddr_t)xen_start_info->store_mfn) << PAGE_SHIFT);
PT_SET_MA(xen_store, xen_store_ma | PG_KERNEL);
console_page_ma = (((vm_paddr_t)xen_start_info->console.domU.mfn) << PAGE_SHIFT);
PT_SET_MA(console_page, console_page_ma | PG_KERNEL);
- printk("#5\n");
+ xc_printf("#5\n");
set_iopl.iopl = 1;
PANIC_IF(HYPERVISOR_physdev_op(PHYSDEVOP_SET_IOPL, &set_iopl));
- printk("#6\n");
+ xc_printf("#6\n");
#if 0
/* add page table for KERNBASE */
xen_queue_pt_update(IdlePTDma + KPTDI*sizeof(vm_paddr_t),
@@ -1132,7 +1142,7 @@ initvalues(start_info_t *startinfo)
#endif
xen_flush_queue();
cur_space += PAGE_SIZE;
- printk("#6\n");
+ xc_printf("#6\n");
#endif /* 0 */
#ifdef notyet
if (xen_start_info->flags & SIF_INITDOMAIN) {
@@ -1150,13 +1160,13 @@ initvalues(start_info_t *startinfo)
i < (((vm_offset_t)&etext) & ~PAGE_MASK); i += PAGE_SIZE)
PT_SET_MA(i, VTOM(i) | PG_V | PG_A);
- printk("#7\n");
+ xc_printf("#7\n");
physfree = VTOP(cur_space);
init_first = physfree >> PAGE_SHIFT;
IdlePTD = (pd_entry_t *)VTOP(IdlePTD);
IdlePDPT = (pd_entry_t *)VTOP(IdlePDPT);
setup_xen_features();
- printk("#8, proc0kstack=%u\n", proc0kstack);
+ xc_printf("#8, proc0kstack=%u\n", proc0kstack);
}
@@ -1200,9 +1210,9 @@ HYPERVISOR_multicall(struct multicall_entry * call_list, int nr_calls)
/* Check the results of individual hypercalls. */
for (i = 0; i < nr_calls; i++)
- if (unlikely(call_list[i].result < 0))
+ if (__predict_false(call_list[i].result < 0))
ret++;
- if (unlikely(ret > 0))
+ if (__predict_false(ret > 0))
panic("%d multicall(s) failed: cpu %d\n",
ret, smp_processor_id());
diff --git a/sys/i386/xen/xen_rtc.c b/sys/i386/xen/xen_rtc.c
index 8e1e017..8dc3ecb 100644
--- a/sys/i386/xen/xen_rtc.c
+++ b/sys/i386/xen/xen_rtc.c
@@ -39,15 +39,17 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/time.h>
+#include <xen/xen-os.h>
#include <xen/xen_intr.h>
+#include <xen/hypervisor.h>
+#include <xen/interface/io/xenbus.h>
+#include <xen/interface/vcpu.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/io/xenbus.h>
-#include <xen/interface/vcpu.h>
#include <machine/cpu.h>
#include <machine/xen/xen_clock_util.h>
OpenPOWER on IntegriCloud