[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Create viosapic handling for IPF.



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID d54bcabd0624ceb692d40ed19586c7cedfa283d4
# Parent  775fea0a4f164f5d17b77429d8c021626c10668b
[IA64] Create viosapic handling for IPF.

There are three reasons to do this.
1. IOSAPIC is different with IOAPIC 
   such as:
       1. IOAPIC implement broadcast, but IOSAPIC doesn't
       2. IOSAPIC doesn't implement dest_mode and remote irr bits.
       3. IOSAPIC implement EOI but IOAPIC doesn't
       etc.
2. In IA32 side there are I8259 and LAPIC who are
    related to IOAPIC, but In IPF there is no I8259 and has LSAPIC.
3. after creating this file, all header files under asm-ia64/hvm, which
   are linked from IA32 side, are not needed.

Signed-off-by:  Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/Makefile              |   16 -
 xen/arch/ia64/Rules.mk              |    2 
 xen/arch/ia64/vmx/Makefile          |    2 
 xen/arch/ia64/vmx/mmio.c            |    8 
 xen/arch/ia64/vmx/viosapic.c        |  354 ++++++++++++++++++++++++++++++++++++
 xen/arch/ia64/vmx/vlsapic.c         |   47 +---
 xen/arch/ia64/vmx/vmx_hypercall.c   |    3 
 xen/arch/ia64/vmx/vmx_init.c        |    8 
 xen/include/asm-ia64/config.h       |    5 
 xen/include/asm-ia64/domain.h       |    2 
 xen/include/asm-ia64/viosapic.h     |   96 +++++++++
 xen/include/asm-ia64/vlsapic.h      |   35 +++
 xen/include/asm-ia64/vmx.h          |    1 
 xen/include/asm-ia64/vmx_platform.h |   47 ----
 xen/include/asm-ia64/vmx_vpd.h      |   11 -
 15 files changed, 506 insertions(+), 131 deletions(-)

diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile    Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/Makefile    Wed Nov 29 11:05:02 2006 -0700
@@ -58,17 +58,6 @@ asm-xsi-offsets.s: asm-xsi-offsets.c $(H
         || ln -sf $(BASEDIR)/include/xen $(BASEDIR)/include/linux
        [ -e $(BASEDIR)/include/asm-ia64/xen ] \
         || ln -sf $(BASEDIR)/include/asm-ia64/linux 
$(BASEDIR)/include/asm-ia64/xen
-# Link to HVM files in Xen for ia64/vti
-       [ -e $(BASEDIR)/include/asm-ia64/hvm/support.h ] \
-        || ln -sf ../../../include/asm-x86/hvm/support.h 
$(BASEDIR)/include/asm-ia64/hvm/support.h
-       [ -e $(BASEDIR)/include/asm-ia64/hvm/io.h ] \
-        || ln -sf ../../../include/asm-x86/hvm/io.h 
$(BASEDIR)/include/asm-ia64/hvm/io.h
-       [ -e $(BASEDIR)/include/asm-ia64/hvm/vpic.h ] \
-        || ln -sf ../../../include/asm-x86/hvm/vpic.h 
$(BASEDIR)/include/asm-ia64/hvm/vpic.h
-       [ -e $(BASEDIR)/include/asm-ia64/hvm/vioapic.h ] \
-        || ln -sf ../../../include/asm-x86/hvm/vioapic.h 
$(BASEDIR)/include/asm-ia64/hvm/vioapic.h
-       [ -e $(BASEDIR)/arch/ia64/vmx/hvm_vioapic.c ] \
-        || ln -sf ../../../arch/x86/hvm/vioapic.c 
$(BASEDIR)/arch/ia64/vmx/hvm_vioapic.c
 
 # I'm sure a Makefile wizard would know a better way to do this
 xen.lds.s: xen/xen.lds.S
@@ -80,8 +69,3 @@ clean::
        rm -f *.o *~ core  xen.lds.s 
$(BASEDIR)/include/asm-ia64/.offsets.h.stamp asm-offsets.s map.out
        rm -f asm-xsi-offsets.s $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h
        rm -f $(BASEDIR)/System.map
-       rm -f vmx/hvm_*.c
-       rm -f $(BASEDIR)/include/asm-ia64/hvm/support.h
-       rm -f $(BASEDIR)/include/asm-ia64/hvm/io.h
-       rm -f $(BASEDIR)/include/asm-ia64/hvm/vpic.h
-       rm -f $(BASEDIR)/include/asm-ia64/hvm/vioapic.h
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk    Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/Rules.mk    Wed Nov 29 11:05:02 2006 -0700
@@ -33,7 +33,7 @@ CPPFLAGS+= -I$(BASEDIR)/include                               
                \
           -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
 CFLAGS += $(CPPFLAGS)
 #CFLAGS  += -Wno-pointer-arith -Wredundant-decls
-CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
+CFLAGS += -DIA64 -DXEN -DLINUX_2_6
 CFLAGS += -ffixed-r13 -mfixed-range=f2-f5,f12-f127
 CFLAGS += -g
 #CFLAGS  += -DVTI_DEBUG
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile        Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/vmx/Makefile        Wed Nov 29 11:05:02 2006 -0700
@@ -1,4 +1,4 @@ obj-y += hvm_vioapic.o
-obj-y += hvm_vioapic.o
+obj-y += viosapic.o
 #obj-y += mm.o
 obj-y += mmio.o
 obj-y += pal_emul.o
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/vmx/mmio.c  Wed Nov 29 11:05:02 2006 -0700
@@ -36,6 +36,8 @@
 #include <public/xen.h>
 #include <linux/event.h>
 #include <xen/domain.h>
+#include <asm/viosapic.h>
+
 /*
 struct mmio_list *lookup_mmio(u64 gpa, struct mmio_list *mio_base)
 {
@@ -271,13 +273,11 @@ static void legacy_io_access(VCPU *vcpu,
     return;
 }
 
-extern struct vmx_mmio_handler vioapic_mmio_handler;
 static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, 
int dir)
 {
     struct virtual_platform_def *v_plat;
     //mmio_type_t iot;
     unsigned long iot;
-    struct vmx_mmio_handler *vioapic_handler = &vioapic_mmio_handler;
     iot=__gpfn_is_io(vcpu->domain, src_pa>>PAGE_SHIFT);
     v_plat = vmx_vcpu_get_plat(vcpu);
 
@@ -293,9 +293,9 @@ static void mmio_access(VCPU *vcpu, u64 
         break;
     case GPFN_IOSAPIC:
        if (!dir)
-           vioapic_handler->write_handler(vcpu, src_pa, s, *dest);
+           viosapic_write(vcpu, src_pa, s, *dest);
        else
-           *dest = vioapic_handler->read_handler(vcpu, src_pa, s);
+           *dest = viosapic_read(vcpu, src_pa, s);
        break;
     case GPFN_FRAME_BUFFER:
     case GPFN_LOW_MMIO:
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/vmx/vlsapic.c       Wed Nov 29 11:05:02 2006 -0700
@@ -38,7 +38,7 @@
 #include <asm/vmx_pal_vsa.h>
 #include <asm/kregs.h>
 #include <asm/vmx_platform.h>
-#include <asm/hvm/vioapic.h>
+#include <asm/viosapic.h>
 #include <asm/linux/jiffies.h>
 
 //u64  fire_itc;
@@ -330,29 +330,6 @@ void vtm_domain_in(VCPU *vcpu)
 }
  */
 
-#ifdef V_IOSAPIC_READY
-int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest)
-{
-    return (VLAPIC_ID(vlapic) == dest);
-}
-
-struct vlapic* apic_round_robin(struct domain *d,
-                               uint8_t vector,
-                               uint32_t bitmap)
-{
-    uint8_t bit = 0;
-    
-    if (!bitmap) {
-       printk("<apic_round_robin> no bit on bitmap\n");
-       return NULL;
-    }
-
-    while (!(bitmap & (1 << bit)))
-        bit++;
-
-    return vcpu_vlapic(d->vcpu[bit]);
-}
-#endif
 
 void vlsapic_reset(VCPU *vcpu)
 {
@@ -375,9 +352,6 @@ void vlsapic_reset(VCPU *vcpu)
         VLSAPIC_INSVC(vcpu,i) = 0;
     }
 
-#ifdef V_IOSAPIC_READY
-    vcpu->arch.arch_vmx.vlapic.vcpu = vcpu;
-#endif
     dprintk(XENLOG_INFO, "VLSAPIC inservice base=%p\n", &VLSAPIC_INSVC(vcpu,0) 
);
 }
 
@@ -667,13 +641,12 @@ void vmx_vexirq(VCPU *vcpu)
     generate_exirq (vcpu);
 }
 
-
-void vmx_vioapic_set_irq(struct domain *d, int irq, int level)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&d->arch.arch_vmx.virq_assist_lock, flags);
-    vioapic_set_irq(d, irq, level);
-    spin_unlock_irqrestore(&d->arch.arch_vmx.virq_assist_lock, flags);
-}
-
+struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest)
+{
+    struct vcpu * v;
+    for_each_vcpu ( d, v ) {
+        if ( (v->arch.privregs->lid >> 16) == dest )
+            return v;
+    }
+    return NULL;
+}                                     
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Wed Nov 29 11:05:02 2006 -0700
@@ -35,6 +35,7 @@
 #include <asm/dom_fw.h>
 #include <xen/domain.h>
 #include <asm/vmx.h> 
+#include <asm/viosapic.h> 
 
 long
 do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
@@ -96,7 +97,7 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
 
         rc = -EINVAL;
         if (is_hvm_domain(d)) {
-            vmx_vioapic_set_irq(d, op.irq, op.level);
+            viosapic_set_irq(d, op.irq, op.level);
             rc = 0;
         }
 
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/arch/ia64/vmx/vmx_init.c      Wed Nov 29 11:05:02 2006 -0700
@@ -48,13 +48,12 @@
 #include <asm/processor.h>
 #include <asm/vmx.h>
 #include <xen/mm.h>
-#include <asm/hvm/vioapic.h>
+#include <asm/viosapic.h>
 #include <xen/event.h>
 #include <asm/vlsapic.h>
 
 /* Global flag to identify whether Intel vmx feature is on */
 u32 vmx_enabled = 0;
-unsigned int opt_vmx_debug_level = 0;
 static u32 vm_order;
 static u64 buffer_size;
 static u64 vp_env_info;
@@ -396,11 +395,8 @@ void vmx_setup_platform(struct domain *d
        memset(&d->shared_info->evtchn_mask[0], 0xff,
               sizeof(d->shared_info->evtchn_mask));
 
-       /* initiate spinlock for pass virq */
-       spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
-
        /* Initialize iosapic model within hypervisor */
-       vioapic_init(d);
+       viosapic_init(d);
 }
 
 void vmx_do_launch(struct vcpu *v)
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/config.h     Wed Nov 29 11:05:02 2006 -0700
@@ -283,9 +283,4 @@ struct screen_info { };
 /* Define CONFIG_PRIVIFY to support privified OS (deprecated).  */
 #undef CONFIG_PRIVIFY
 
-/* Necessary for hvm_vioapic.c */
-#define vcpu_vlapic(vcpu)   (&(vcpu)->arch.arch_vmx.vlapic)
-#define vlapic_vcpu(vpic)   (container_of((vpic), struct vcpu, \
-                                          arch.arch_vmx.vlapic))
-
 #endif /* _IA64_CONFIG_H_ */
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/domain.h     Wed Nov 29 11:05:02 2006 -0700
@@ -124,8 +124,6 @@ struct arch_domain {
 
     struct last_vcpu last_vcpu[NR_CPUS];
 
-    struct arch_vmx_domain arch_vmx; /* Virtual Machine Extensions */
-
 #ifdef CONFIG_XEN_IA64_TLB_TRACK
     struct tlb_track*   tlb_track;
 #endif
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/vlsapic.h
--- a/xen/include/asm-ia64/vlsapic.h    Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/vlsapic.h    Wed Nov 29 11:05:02 2006 -0700
@@ -23,6 +23,37 @@
 #ifndef _LSAPIC_H
 #define _LSAPIC_H
 #include <xen/sched.h>
+#include <asm/vmx_vcpu.h>
+/*
+ *Delivery mode
+ */
+#define SAPIC_DELIV_SHIFT      8
+#define SAPIC_FIXED            0x0
+#define SAPIC_LOWEST_PRIORITY  0x1
+#define SAPIC_PMI              0x2
+#define SAPIC_NMI              0x4
+#define SAPIC_INIT             0x5
+#define SAPIC_EXTINT           0x7
+
+/*
+ *Interrupt polarity
+ */
+#define SAPIC_POLARITY_SHIFT   13
+#define SAPIC_POL_HIGH         0
+#define SAPIC_POL_LOW          1
+
+/*
+ *Trigger mode
+ */
+#define SAPIC_TRIGGER_SHIFT    15
+#define SAPIC_EDGE             0
+#define SAPIC_LEVEL            1
+
+/*
+ *Mask bit
+ */
+#define SAPIC_MASK_SHIFT       16
+#define SAPIC_MASK             (1 << SAPIC_MASK_SHIFT)
 
 extern void vtm_init(struct vcpu *vcpu);
 extern void vtm_set_itc(struct  vcpu *vcpu, uint64_t new_itc);
@@ -30,5 +61,7 @@ extern void vtm_set_itv(struct vcpu *vcp
 extern void vtm_set_itv(struct vcpu *vcpu, uint64_t val);
 extern void vmx_vexirq(struct vcpu  *vcpu);
 extern void vhpi_detection(struct vcpu *vcpu);
-
+extern int vmx_vcpu_pend_interrupt(VCPU * vcpu, uint8_t vector);
+extern struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest);
+#define vlsapic_set_irq vmx_vcpu_pend_interrupt
 #endif
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/vmx.h
--- a/xen/include/asm-ia64/vmx.h        Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/vmx.h        Wed Nov 29 11:05:02 2006 -0700
@@ -55,7 +55,6 @@ extern void vmx_relinquish_vcpu_resource
 extern void vmx_relinquish_vcpu_resources(struct vcpu *v);
 extern void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err);
 extern void vmx_send_assist_req(struct vcpu *v);
-extern void vmx_vioapic_set_irq(struct domain *d, int irq, int level);
 
 static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
 {
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h       Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/vmx_platform.h       Wed Nov 29 11:05:02 2006 -0700
@@ -21,7 +21,7 @@
 
 #include <public/xen.h>
 #include <public/hvm/params.h>
-#include <asm/hvm/vioapic.h>
+#include <asm/viosapic.h>
 struct mmio_list;
 typedef struct virtual_platform_def {
     unsigned long          buffered_io_va;
@@ -32,7 +32,7 @@ typedef struct virtual_platform_def {
     unsigned long       params[HVM_NR_PARAMS];
     struct mmio_list    *mmio;
     /* One IOSAPIC now... */
-    struct vioapic      vioapic;
+    struct viosapic     viosapic;
 } vir_plat_t;
 
 static inline int __fls(uint32_t word)
@@ -43,47 +43,4 @@ static inline int __fls(uint32_t word)
     __asm__ __volatile__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
     return word ? (exp - 0xffff) : -1;
 }
-
-/* This is a connect structure between vIOSAPIC model and vLSAPIC model.
- * vlapic is required by vIOSAPIC model to manipulate pending bits, and
- * we just map them into vpd here
- */
-typedef struct vlapic {
-    struct vcpu        *vcpu;  /* Link to current vcpu */
-} vlapic_t;
-
-extern uint64_t dummy_tmr[];
-#define VLAPIC_ID(l) (uint16_t)(((l)->vcpu->arch.privregs->lid) >> 16)
-#define VLAPIC_IRR(l) ((l)->vcpu->arch.privregs->irr[0])
-struct vlapic *apic_round_robin(struct domain *d, uint8_t vector, uint32_t 
bitmap);
-extern int vmx_vcpu_pend_interrupt(struct vcpu *vcpu, uint8_t vector);
-static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
-{
-    return vmx_vcpu_pend_interrupt(t->vcpu, vec);
-}
-
-enum ioapic_irq_destination_types {
-       dest_Fixed = 0,
-       dest_LowestPrio = 1,
-       dest_SMI = 2,
-       dest__reserved_1 = 3,
-       dest_NMI = 4,
-       dest_INIT = 5,
-       dest__reserved_2 = 6,
-       dest_ExtINT = 7
-};
-
-#define vlapic_enabled(l) 1
-
-#define VLAPIC_DELIV_MODE_FIXED                0x0
-#define VLAPIC_DELIV_MODE_REDIR                0x1
-#define VLAPIC_DELIV_MODE_LPRI         VLAPIC_DELIV_MODE_REDIR
-#define VLAPIC_DELIV_MODE_PMI          0x2
-#define VLAPIC_DELIV_MODE_SMI          0x2 /* For IA32 */
-#define VLAPIC_DELIV_MODE_RESERVED     0x3
-#define VLAPIC_DELIV_MODE_NMI          0x4
-#define VLAPIC_DELIV_MODE_INIT         0x5
-#define VLAPIC_DELIV_MODE_STARTUP      0x6 /* For IA32 */
-#define VLAPIC_DELIV_MODE_EXT          0x7
-
 #endif
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/vmx_vpd.h
--- a/xen/include/asm-ia64/vmx_vpd.h    Wed Nov 29 09:16:46 2006 -0700
+++ b/xen/include/asm-ia64/vmx_vpd.h    Wed Nov 29 11:05:02 2006 -0700
@@ -74,14 +74,9 @@ struct ivt_debug{
 #define IVT_DEBUG_MAX 128
 #endif
 
-struct arch_vmx_domain {
-    spinlock_t virq_assist_lock; /* spinlock for pass virq */
-};
-
 struct arch_vmx_struct {
 //     vpd_t       *vpd;
     vtime_t        vtm;
-    struct vlapic   vlapic;
     unsigned long   vrr[8];
     /* if the corresponding bit is 1, then this page size is
        used in this region */
@@ -118,12 +113,6 @@ struct arch_vmx_struct {
 #define ARCH_VMX_IO_WAIT        3       /* Waiting for I/O completion */
 #define ARCH_VMX_DOMAIN         5       /* Need it to indicate VTi domain */
 
-
-#define VMX_DEBUG 1
-#if VMX_DEBUG
-
-extern unsigned int opt_vmx_debug_level;
-#endif
 #endif //__ASSEMBLY__
 
 // VPD field offset
diff -r 775fea0a4f16 -r d54bcabd0624 xen/arch/ia64/vmx/viosapic.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/vmx/viosapic.c      Wed Nov 29 11:05:02 2006 -0700
@@ -0,0 +1,354 @@
+/*
+ *  Copyright (C) 2001  MandrakeSoft S.A.
+ *
+ *    MandrakeSoft S.A.
+ *    43, rue d'Aboukir
+ *    75002 Paris - France
+ *    http://www.linux-mandrake.com/
+ *    http://www.mandrakesoft.com/
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
+ *  Ported to xen by using virtual IRQ line.
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/mm.h>
+#include <xen/xmalloc.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <public/hvm/ioreq.h>
+#include <asm/vlsapic.h>
+#include <asm/viosapic.h>
+#include <asm/current.h>
+#include <asm/event.h>
+
+static void viosapic_deliver(struct viosapic *viosapic, int irq)
+{
+    uint16_t dest = viosapic->redirtbl[irq].dest_id;
+    uint8_t delivery_mode = viosapic->redirtbl[irq].delivery_mode;
+    uint8_t vector = viosapic->redirtbl[irq].vector;
+    struct vcpu *v;
+
+    switch ( delivery_mode )
+    {
+    // don't support interrupt direct currently
+    case SAPIC_FIXED:
+    case SAPIC_LOWEST_PRIORITY:
+    {
+        v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest);
+        vlsapic_set_irq(v, vector);
+        vcpu_kick(v);
+        break;
+    }
+    case SAPIC_PMI:
+    case SAPIC_NMI:
+    case SAPIC_INIT:
+    case SAPIC_EXTINT:
+    default:
+        gdprintk(XENLOG_WARNING, "Unsupported delivery mode %d\n",
+                 delivery_mode);
+        break;
+    }
+}
+
+
+static int iosapic_get_highest_irq(struct viosapic *viosapic)
+{
+    uint32_t irqs = viosapic->irr | viosapic->irr_xen;
+    irqs &= ~viosapic->isr & ~viosapic->imr;
+    return fls(irqs) - 1;
+}
+
+
+/* XXX If level interrupt, use vector->irq table for performance */
+static int get_redir_num(struct viosapic *viosapic, int vector)
+{
+    int i;
+
+    for ( i = 0; i < VIOSAPIC_NUM_PINS; i++ )
+        if ( viosapic->redirtbl[i].vector == vector )
+            return i;
+
+    return -1;
+}
+
+
+static void service_iosapic(struct viosapic *viosapic)
+{
+    int irq;
+
+    while ( (irq = iosapic_get_highest_irq(viosapic)) != -1 )
+    {
+        if ( !test_bit(irq, &viosapic->imr) )
+            viosapic_deliver(viosapic, irq);
+
+        if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL )
+            viosapic->isr |= (1 << irq);
+
+        viosapic->irr &= ~(1 << irq);
+        viosapic->irr_xen &= ~(1 << irq);
+    }
+}
+
+
+static void viosapic_update_EOI(struct viosapic *viosapic, int vector)
+{
+    int redir_num;
+
+    if ( (redir_num = get_redir_num(viosapic, vector)) == -1 )
+    {
+        gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector);
+        return;
+    }
+
+    if ( !test_and_clear_bit(redir_num, &viosapic->isr) )
+    {
+        gdprintk(XENLOG_WARNING, "redir %d not set for %d EOI\n",
+                 redir_num, vector);
+        return;
+    }
+    service_iosapic(viosapic);
+}
+
+
+static unsigned long viosapic_read_indirect(struct viosapic *viosapic,
+                                            unsigned long addr,
+                                            unsigned long length)
+{
+    unsigned long result = 0;
+
+    switch ( viosapic->ioregsel )
+    {
+    case VIOSAPIC_VERSION:
+        result = ((((VIOSAPIC_NUM_PINS - 1) & 0xff) << 16)
+                  | (VIOSAPIC_VERSION_ID & 0xff));
+        break;
+
+    default:
+    {
+        uint32_t redir_index = (viosapic->ioregsel - 0x10) >> 1;
+        uint64_t redir_content;
+
+        if ( redir_index >= VIOSAPIC_NUM_PINS )
+        {
+            gdprintk(XENLOG_WARNING, "viosapic_read_indirect:undefined "
+                     "ioregsel %x\n", viosapic->ioregsel);
+            break;
+        }
+
+        redir_content = viosapic->redirtbl[redir_index].bits;
+        result = (viosapic->ioregsel & 0x1) ?
+                 (redir_content >> 32) & 0xffffffff :
+                 redir_content & 0xffffffff;
+        break;
+    }
+    }
+
+    return result;
+}
+
+
+unsigned long viosapic_read(struct vcpu *v,
+                            unsigned long addr,
+                            unsigned long length)
+{
+    struct viosapic *viosapic = vcpu_viosapic(v);
+    uint32_t result;
+
+    addr &= 0xff;
+
+    switch ( addr )
+    {
+    case VIOSAPIC_REG_SELECT:
+        result = viosapic->ioregsel;
+        break;
+
+    case VIOSAPIC_WINDOW:
+        result = viosapic_read_indirect(viosapic, addr, length);
+        break;
+
+    default:
+        result = 0;
+        break;
+    }
+
+    return result;
+}
+
+
+static inline void viosapic_update_imr(struct viosapic *viosapic, int index)
+{
+    if ( viosapic->redirtbl[index].mask )
+        set_bit(index, &viosapic->imr);
+    else
+        clear_bit(index, &viosapic->imr);
+}
+
+
+static void viosapic_write_indirect(struct viosapic *viosapic,
+                                    unsigned long addr,
+                                    unsigned long length,
+                                    unsigned long val)
+{
+    switch ( viosapic->ioregsel )
+    {
+    case VIOSAPIC_VERSION:
+        /* Writes are ignored. */
+        break;
+
+    default:
+    {
+        uint32_t redir_index = (viosapic->ioregsel - 0x10) >> 1;
+        uint64_t redir_content;
+
+        if ( redir_index >= VIOSAPIC_NUM_PINS )
+        {
+            gdprintk(XENLOG_WARNING, "viosapic_write_indirect "
+                     "error register %x\n", viosapic->ioregsel);
+            break;
+        }
+
+        redir_content = viosapic->redirtbl[redir_index].bits;
+
+        if ( viosapic->ioregsel & 0x1 )
+        {
+            redir_content = (((uint64_t)val & 0xffffffff) << 32) |
+                            (redir_content & 0xffffffff);
+        }
+        else
+        {
+            redir_content = ((redir_content >> 32) << 32) |
+                            (val & 0xffffffff);
+        }
+        viosapic->redirtbl[redir_index].bits = redir_content;
+        viosapic_update_imr(viosapic, redir_index);
+        break;
+    }
+    } /* switch */
+}
+
+
+void viosapic_write(struct vcpu *v,
+                      unsigned long addr,
+                      unsigned long length,
+                      unsigned long val)
+{
+    struct viosapic *viosapic = vcpu_viosapic(v);
+
+    addr &= 0xff;
+
+    switch ( addr )
+    {
+    case VIOSAPIC_REG_SELECT:
+        viosapic->ioregsel = val;
+        break;
+
+    case VIOSAPIC_WINDOW:
+        viosapic_write_indirect(viosapic, addr, length, val);
+        break;
+
+    case VIOSAPIC_EOI:
+        viosapic_update_EOI(viosapic, val);
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+static void viosapic_reset(struct viosapic *viosapic)
+{
+    int i;
+
+    memset(viosapic, 0, sizeof(*viosapic));
+
+    for ( i = 0; i < VIOSAPIC_NUM_PINS; i++ )
+    {
+        viosapic->redirtbl[i].mask = 0x1;
+        viosapic_update_imr(viosapic, i);
+    }
+    spin_lock_init(&viosapic->lock);
+}
+
+
+// this is used by VBD/VNIF to inject interrupt for VTI-domain
+void viosapic_set_xen_irq(struct domain *d, int irq, int level)
+{
+    struct viosapic *viosapic = domain_viosapic(d);
+
+    spin_lock(&viosapic->lock);
+    if ( viosapic->redirtbl[irq].mask )
+        goto out;
+
+    if ( viosapic->redirtbl[irq].trig_mode == SAPIC_EDGE)
+        gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq);
+
+    if ( level )
+        viosapic->irr_xen |= 1 << irq;
+    else
+        viosapic->irr_xen &= ~(1 << irq);
+
+    service_iosapic(viosapic);
+out:
+    spin_unlock(&viosapic->lock);
+}
+
+
+void viosapic_set_irq(struct domain *d, int irq, int level)
+{
+    struct viosapic *viosapic = domain_viosapic(d);
+    uint32_t bit;
+
+    spin_lock(&viosapic->lock);
+    if ( (irq < 0) || (irq >= VIOSAPIC_NUM_PINS) )
+        goto out;
+
+    if ( viosapic->redirtbl[irq].mask )
+        goto out;
+
+    bit = 1 << irq;
+    if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL )
+    {
+        if ( level )
+            viosapic->irr |= bit;
+        else
+            viosapic->irr &= ~bit;
+    }
+    else
+    {
+        if ( level )
+            /* XXX No irr clear for edge interrupt */
+            viosapic->irr |= bit;
+    }
+
+    service_iosapic(viosapic);
+out:    
+    spin_unlock(&viosapic->lock);
+}
+
+
+void viosapic_init(struct domain *d)
+{
+    struct viosapic *viosapic = domain_viosapic(d);
+
+    viosapic_reset(viosapic);
+
+    viosapic->base_address = VIOSAPIC_DEFAULT_BASE_ADDRESS;
+}
diff -r 775fea0a4f16 -r d54bcabd0624 xen/include/asm-ia64/viosapic.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-ia64/viosapic.h   Wed Nov 29 11:05:02 2006 -0700
@@ -0,0 +1,96 @@
+/*
+ *
+ *  Copyright (C) 2001  MandrakeSoft S.A.
+ *
+ *    MandrakeSoft S.A.
+ *    43, rue d'Aboukir
+ *    75002 Paris - France
+ *    http://www.linux-mandrake.com/
+ *    http://www.mandrakesoft.com/
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef __ASM_IA64_VMX_VIOSAPIC_H__
+#define __ASM_IA64_VMX_VIOSAPIC_H__
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/smp.h>
+
+/* Direct registers. */
+#define VIOSAPIC_REG_SELECT   0x00
+#define VIOSAPIC_WINDOW       0x10
+#define VIOSAPIC_EOI          0x40
+
+#define VIOSAPIC_VERSION      0x1
+
+#define VIOSAPIC_DEST_SHIFT   16
+
+
+#define VIOSAPIC_VERSION_ID   0x21 /* IOSAPIC version */
+
+#define VIOSAPIC_NUM_PINS     24
+
+#define VIOSAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
+#define VIOSAPIC_MEM_LENGTH            0x100
+
+#define domain_viosapic(d) (&(d)->arch.hvm_domain.viosapic)
+#define viosapic_domain(v) (container_of((v), struct domain, \
+                                        arch.hvm_domain.viosapic))
+#define vcpu_viosapic(v) (&(v)->domain->arch.hvm_domain.viosapic)
+
+union viosapic_rte
+{
+    uint64_t bits;
+    struct {
+        uint8_t vector;
+
+        uint8_t delivery_mode  : 3;
+        uint8_t reserve1       : 1;
+        uint8_t delivery_status: 1;
+        uint8_t polarity       : 1;
+        uint8_t reserve2       : 1;
+        uint8_t trig_mode      : 1;
+
+        uint8_t mask           : 1;
+        uint8_t reserve3       : 7;
+
+        uint8_t reserved[3];
+        uint16_t dest_id;
+    }; 
+};
+
+struct viosapic {
+    uint32_t irr;
+    uint32_t irr_xen; /* interrupts forced on by the hypervisor. */
+    uint32_t isr;     /* This is used for level trigger */
+    uint32_t imr;
+    uint32_t ioregsel;
+    spinlock_t lock;
+    unsigned long base_address;
+    union viosapic_rte redirtbl[VIOSAPIC_NUM_PINS];
+};
+
+void viosapic_init(struct domain *d);
+void viosapic_set_xen_irq(struct domain *d, int irq, int level);
+void viosapic_set_irq(struct domain *d, int irq, int level);
+void viosapic_write(struct vcpu *v, unsigned long addr,
+                    unsigned long length, unsigned long val);
+
+unsigned long viosapic_read(struct vcpu *v, unsigned long addr,
+                            unsigned long length);
+
+#endif /* __ASM_IA64_VMX_VIOSAPIC_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.