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

[Xen-changelog] [xen-unstable] [IA64] Implement irq redirection of IOSAPIC



# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Node ID 3bd97b4fe77d2b751e2ef5beb4e0be4966e7dca3
# Parent  4f1a3ae07dbc11683f2f8064449c96aa590112b1
[IA64] Implement irq redirection of IOSAPIC

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/vmx/mmio.c            |  299 ---------------------------------
 xen/arch/ia64/vmx/viosapic.c        |   20 +-
 xen/arch/ia64/vmx/vlsapic.c         |  323 +++++++++++++++++++++++++-----------
 xen/include/asm-ia64/viosapic.h     |    1 
 xen/include/asm-ia64/vlsapic.h      |   11 +
 xen/include/asm-ia64/vmx_platform.h |    1 
 xen/include/asm-ia64/vmx_vpd.h      |    2 
 7 files changed, 265 insertions(+), 392 deletions(-)

diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/arch/ia64/vmx/mmio.c  Thu Dec 07 05:34:07 2006 -0700
@@ -23,7 +23,6 @@
 
 #include <linux/sched.h>
 #include <xen/mm.h>
-#include <asm/tlb.h>
 #include <asm/vmx_mm_def.h>
 #include <asm/gcc_intrin.h>
 #include <linux/interrupt.h>
@@ -37,22 +36,7 @@
 #include <linux/event.h>
 #include <xen/domain.h>
 #include <asm/viosapic.h>
-
-/*
-struct mmio_list *lookup_mmio(u64 gpa, struct mmio_list *mio_base)
-{
-    int     i;
-    for (i=0; mio_base[i].iot != NOT_IO; i++ ) {
-        if ( gpa >= mio_base[i].start && gpa <= mio_base[i].end )
-            return &mio_base[i];
-    }
-    return NULL;
-}
-*/
-
-#define        PIB_LOW_HALF(ofst)      !(ofst&(1<<20))
-#define PIB_OFST_INTA           0x1E0000
-#define PIB_OFST_XTP            0x1E0008
+#include <asm/vlsapic.h>
 
 #define HVM_BUFFERED_IO_RANGE_NR 1
 
@@ -118,87 +102,6 @@ int hvm_buffered_io_intercept(ioreq_t *p
     return 1;
 }
 
-static void write_ipi (VCPU *vcpu, uint64_t addr, uint64_t value);
-
-static void pib_write(VCPU *vcpu, void *src, uint64_t pib_off, size_t s, int 
ma)
-{
-    switch (pib_off) {
-    case PIB_OFST_INTA:
-        panic_domain(NULL,"Undefined write on PIB INTA\n");
-        break;
-    case PIB_OFST_XTP:
-        if ( s == 1 && ma == 4 /* UC */) {
-            vmx_vcpu_get_plat(vcpu)->xtp = *(uint8_t *)src;
-        }
-        else {
-            panic_domain(NULL,"Undefined write on PIB XTP\n");
-        }
-        break;
-    default:
-        if ( PIB_LOW_HALF(pib_off) ) {   // lower half
-            if ( s != 8 || ma != 0x4 /* UC */ ) {
-                panic_domain
-                 (NULL,"Undefined IPI-LHF write with s %ld, ma %d!\n", s, ma);
-            }
-            else {
-                write_ipi(vcpu, pib_off, *(uint64_t *)src);
-                // TODO for SM-VP
-            }
-        }
-        else {      // upper half
-            printk("IPI-UHF write %lx\n",pib_off);
-            panic_domain(NULL,"Not support yet for SM-VP\n");
-        }
-        break;
-    }
-}
-
-static void pib_read(VCPU *vcpu, uint64_t pib_off, void *dest, size_t s, int 
ma)
-{
-    switch (pib_off) {
-    case PIB_OFST_INTA:
-        // todo --- emit on processor system bus.
-        if ( s == 1 && ma == 4) { // 1 byte load
-            // TODO: INTA read from IOSAPIC
-        }
-        else {
-            panic_domain(NULL,"Undefined read on PIB INTA\n");
-        }
-        break;
-    case PIB_OFST_XTP:
-        if ( s == 1 && ma == 4) {
-            *((uint8_t*)dest) = vmx_vcpu_get_plat(vcpu)->xtp;
-        }
-        else {
-            panic_domain(NULL,"Undefined read on PIB XTP\n");
-        }
-        break;
-    default:
-        if ( PIB_LOW_HALF(pib_off) ) {   // lower half
-            if ( s != 8 || ma != 4 ) {
-                panic_domain(NULL,"Undefined IPI-LHF read!\n");
-            }
-            else {
-#ifdef  IPI_DEBUG
-                printk("IPI-LHF read %lx\n",pib_off);
-#endif
-                *(uint64_t *)dest = 0;  // TODO for SM-VP
-            }
-        }
-        else {      // upper half
-            if ( s != 1 || ma != 4 ) {
-                panic_domain(NULL,"Undefined PIB-UHF read!\n");
-            }
-            else {
-#ifdef  IPI_DEBUG
-                printk("IPI-UHF read %lx\n",pib_off);
-#endif
-                *(uint8_t *)dest = 0;   // TODO for SM-VP
-            }
-        }
-        break;
-    }
-}
 
 static void low_mmio_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
 {
@@ -283,11 +186,14 @@ static void mmio_access(VCPU *vcpu, u64 
 
     perfc_incra(vmx_mmio_access, iot >> 56);
     switch (iot) {
-    case GPFN_PIB:
-        if(!dir)
-            pib_write(vcpu, dest, src_pa - v_plat->pib_base, s, ma);
+    case GPFN_PIB:       
+        if (ma != 4)
+            panic_domain(NULL, "Access PIB not with UC attribute\n");
+
+        if (!dir)
+            vlsapic_write(vcpu, src_pa, s, *dest);
         else
-            pib_read(vcpu, src_pa - v_plat->pib_base, dest, s, ma);
+            *dest = vlsapic_read(vcpu, src_pa, s);
         break;
     case GPFN_GFW:
         break;
@@ -310,195 +216,6 @@ static void mmio_access(VCPU *vcpu, u64 
     }
     return;
 }
-
-/*
- * Read or write data in guest virtual address mode.
- */
-/*
-void
-memwrite_v(VCPU *vcpu, thash_data_t *vtlb, u64 *src, u64 *dest, size_t s)
-{
-    uint64_t pa;
-
-    if (!vtlb->nomap)
-        panic("Normal memory write shouldn't go to this point!");
-    pa = PPN_2_PA(vtlb->ppn);
-    pa += POFFSET((u64)dest, vtlb->ps);
-    mmio_write (vcpu, src, pa, s, vtlb->ma);
-}
-
-
-void
-memwrite_p(VCPU *vcpu, u64 *src, u64 *dest, size_t s)
-{
-    uint64_t pa = (uint64_t)dest;
-    int    ma;
-
-    if ( pa & (1UL <<63) ) {
-        // UC
-        ma = 4;
-        pa <<=1;
-        pa >>=1;
-    }
-    else {
-        // WBL
-        ma = 0;     // using WB for WBL
-    }
-    mmio_write (vcpu, src, pa, s, ma);
-}
-
-void
-memread_v(VCPU *vcpu, thash_data_t *vtlb, u64 *src, u64 *dest, size_t s)
-{
-    uint64_t pa;
-
-    if (!vtlb->nomap)
-        panic_domain(NULL,"Normal memory write shouldn't go to this point!");
-    pa = PPN_2_PA(vtlb->ppn);
-    pa += POFFSET((u64)src, vtlb->ps);
-
-    mmio_read(vcpu, pa, dest, s, vtlb->ma);
-}
-
-void
-memread_p(VCPU *vcpu, u64 *src, u64 *dest, size_t s)
-{
-    uint64_t pa = (uint64_t)src;
-    int    ma;
-
-    if ( pa & (1UL <<63) ) {
-        // UC
-        ma = 4;
-        pa <<=1;
-        pa >>=1;
-    }
-    else {
-        // WBL
-        ma = 0;     // using WB for WBL
-    }
-    mmio_read(vcpu, pa, dest, s, ma);
-}
-*/
-
-/*
- * To inject INIT to guest, we must set the PAL_INIT entry 
- * and set psr to switch to physical mode
- */
-#define PAL_INIT_ENTRY 0x80000000ffffffa0
-#define PSR_SET_BITS (IA64_PSR_DT | IA64_PSR_IT | IA64_PSR_RT |        \
-                      IA64_PSR_IC | IA64_PSR_RI)
-
-static void vmx_inject_guest_pal_init(VCPU *vcpu)
-{
-    REGS *regs = vcpu_regs(vcpu);
-    uint64_t psr = vmx_vcpu_get_psr(vcpu);
-
-    regs->cr_iip = PAL_INIT_ENTRY;
-
-    psr = psr & (~PSR_SET_BITS);
-    vmx_vcpu_set_psr(vcpu,psr);
-}
-
-/*
- * Deliver IPI message. (Only U-VP is supported now)
- *  offset: address offset to IPI space.
- *  value:  deliver value.
- */
-static void deliver_ipi (VCPU *vcpu, uint64_t dm, uint64_t vector)
-{
-#ifdef  IPI_DEBUG
-  printk ("deliver_ipi %lx %lx\n",dm,vector);
-#endif
-    switch ( dm ) {
-    case 0:     // INT
-        vmx_vcpu_pend_interrupt (vcpu, vector);
-        break;
-    case 2:     // PMI
-        // TODO -- inject guest PMI
-        panic_domain (NULL, "Inject guest PMI!\n");
-        break;
-    case 4:     // NMI
-        vmx_vcpu_pend_interrupt (vcpu, 2);
-        break;
-    case 5:     // INIT
-        vmx_inject_guest_pal_init(vcpu);
-        break;
-    case 7:     // ExtINT
-        vmx_vcpu_pend_interrupt (vcpu, 0);
-        break;
-    case 1:
-    case 3:
-    case 6:
-    default:
-        panic_domain (NULL, "Deliver reserved IPI!\n");
-        break;
-    }
-}
-
-/*
- * TODO: Use hash table for the lookup.
- */
-static inline VCPU *lid_2_vcpu (struct domain *d, u64 id, u64 eid)
-{
-    int   i;
-    VCPU  *vcpu;
-    LID   lid;
-    for (i=0; i<MAX_VIRT_CPUS; i++) {
-        vcpu = d->vcpu[i];
-        if (!vcpu)
-            continue;
-        lid.val = VCPU_LID(vcpu);
-        if ( lid.id == id && lid.eid == eid )
-            return vcpu;
-    }
-    return NULL;
-}
-
-/*
- * execute write IPI op.
- */
-static void write_ipi (VCPU *vcpu, uint64_t addr, uint64_t value)
-{
-    VCPU   *targ;
-    struct domain *d=vcpu->domain; 
-    targ = lid_2_vcpu(vcpu->domain, 
-           ((ipi_a_t)addr).id, ((ipi_a_t)addr).eid);
-    if ( targ == NULL ) panic_domain (NULL,"Unknown IPI cpu\n");
-
-    if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
-        struct pt_regs *targ_regs = vcpu_regs (targ);
-        struct vcpu_guest_context c;
-
-        memset (&c, 0, sizeof (c));
-
-        if (arch_set_info_guest (targ, &c) != 0) {
-            printk ("arch_boot_vcpu: failure\n");
-            return;
-        }
-        /* First or next rendez-vous: set registers.  */
-        vcpu_init_regs (targ);
-        targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip;
-        targ_regs->r1 = d->arch.sal_data->boot_rdv_r1;
-
-        if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) {
-            vcpu_wake(targ);
-            printk ("arch_boot_vcpu: vcpu %d awaken %016lx!\n",
-                    targ->vcpu_id, targ_regs->cr_iip);
-        }
-        else
-            printk ("arch_boot_vcpu: huu, already awaken!");
-    }
-    else {
-        int running = test_bit(_VCPUF_running,&targ->vcpu_flags);
-        deliver_ipi (targ, ((ipi_d_t)value).dm, 
-                    ((ipi_d_t)value).vector);
-        vcpu_unblock(targ);
-        if (running)
-            smp_send_event_check_cpu(targ->processor);
-    }
-    return;
-}
-
 
 /*
    dir 1: read 0:write
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c      Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/arch/ia64/vmx/viosapic.c      Thu Dec 07 05:34:07 2006 -0700
@@ -31,7 +31,6 @@
 #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>
@@ -47,11 +46,18 @@ static void viosapic_deliver(struct vios
 
     switch ( delivery_mode )
     {
-    // don't support interrupt direct currently
     case SAPIC_FIXED:
+    {
+        v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest);
+        vlsapic_set_irq(v, vector);
+        vcpu_kick(v);
+        break;
+    }
     case SAPIC_LOWEST_PRIORITY:
     {
         v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest);
+        if (viosapic->lowest_vcpu)
+            v = viosapic->lowest_vcpu;
         vlsapic_set_irq(v, vector);
         vcpu_kick(v);
         break;
@@ -72,10 +78,10 @@ static int iosapic_get_highest_irq(struc
 {
     uint64_t irqs = viosapic->irr & ~viosapic->isr ;
    
-    if (irqs >> 32)
-        return (fls(irqs >> 32) - 1 + 32);
-    else
-        return fls(irqs) - 1;
+    if (irqs)
+        return ia64_fls(irqs);
+
+    return -1;
 }
 
 
@@ -327,5 +333,7 @@ void viosapic_init(struct domain *d)
 
     viosapic_reset(viosapic);
 
+    viosapic->lowest_vcpu = NULL;
+    
     viosapic->base_address = VIOSAPIC_DEFAULT_BASE_ADDRESS;
 }
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/arch/ia64/vmx/vlsapic.c       Thu Dec 07 05:34:07 2006 -0700
@@ -25,10 +25,8 @@
 #include <asm/ia64_int.h>
 #include <asm/vcpu.h>
 #include <asm/regionreg.h>
-#include <asm/tlb.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
-#include <asm/vmx_vcpu.h>
 #include <asm/vmx_vcpu.h>
 #include <asm/regs.h>
 #include <asm/gcc_intrin.h>
@@ -39,7 +37,15 @@
 #include <asm/kregs.h>
 #include <asm/vmx_platform.h>
 #include <asm/viosapic.h>
+#include <asm/vlsapic.h>
 #include <asm/linux/jiffies.h>
+#include <xen/domain.h>
+
+#ifdef IPI_DEBUG
+#define IPI_DPRINTK(x...) printk(x)
+#else
+#define IPI_DPRINTK(x...)
+#endif
 
 //u64  fire_itc;
 //u64  fire_itc2;
@@ -116,16 +122,13 @@ static int vmx_vcpu_unpend_interrupt(VCP
  */
 static uint64_t now_itc(vtime_t *vtm)
 {
-        uint64_t guest_itc=vtm->vtm_offset+ia64_get_itc();
-        
-        if ( vtm->vtm_local_drift ) {
-//          guest_itc -= vtm->vtm_local_drift;
-        }       
-        if (guest_itc >= vtm->last_itc)
-            return guest_itc;
-        else
-            /* guest ITC backwarded due after LP switch */
-            return vtm->last_itc;
+    uint64_t guest_itc = vtm->vtm_offset + ia64_get_itc();
+
+    if (guest_itc >= vtm->last_itc)
+        return guest_itc;
+    else
+        /* guest ITC went backward due to LP switch */
+        return vtm->last_itc;
 }
 
 /*
@@ -175,7 +178,7 @@ void vtm_init(VCPU *vcpu)
 {
     vtime_t     *vtm;
     uint64_t    itc_freq;
-    
+
     vtm = &VMX(vcpu, vtm);
 
     itc_freq = local_cpu_data->itc_freq;
@@ -261,76 +264,6 @@ void vtm_set_itv(VCPU *vcpu, uint64_t va
         vtm->pending = 0;
     }
 }
-
-
-/*
- * Update interrupt or hook the vtm timer for fire
- * At this point vtm_timer should be removed if itv is masked.
- */
-/* Interrupt must be disabled at this point */
-/*
-void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
-{
-    uint64_t    cur_itc,vitm,vitv;
-    uint64_t    expires;
-    long        diff_now, diff_last;
-    uint64_t    spsr;
-    
-    vitv = VCPU(vcpu, itv);
-    if ( ITV_IRQ_MASK(vitv) ) {
-        return;
-    }
-    
-    vitm =VCPU(vcpu, itm);
-    local_irq_save(spsr);
-    cur_itc =now_itc(vtm);
-    diff_last = vtm->last_itc - vitm;
-    diff_now = cur_itc - vitm;
-
-    if ( diff_last >= 0 ) {
-        // interrupt already fired.
-        stop_timer(&vtm->vtm_timer);
-    }
-    else if ( diff_now >= 0 ) {
-        // ITV is fired.
-        vmx_vcpu_pend_interrupt(vcpu, vitv&0xff);
-    }
-*/
-    /* Both last_itc & cur_itc < itm, wait for fire condition */
-/*    else {
-        expires = NOW() + cycle_to_ns(0-diff_now) + TIMER_SLOP;
-        set_timer(&vtm->vtm_timer, expires);
-    }
-    local_irq_restore(spsr);
-}
- */
-
-/*
- * Action for vtm when the domain is scheduled out.
- * Remove the timer for vtm.
- */
-/*
-void vtm_domain_out(VCPU *vcpu)
-{
-    if(!is_idle_domain(vcpu->domain))
-       stop_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
-}
- */
-/*
- * Action for vtm when the domain is scheduled in.
- * Fire vtm IRQ or add the timer for vtm.
- */
-/*
-void vtm_domain_in(VCPU *vcpu)
-{
-    vtime_t     *vtm;
-
-    if(!is_idle_domain(vcpu->domain)) {
-       vtm=&(vcpu->arch.arch_vmx.vtm);
-       vtm_interruption_update(vcpu, vtm);
-    }
-}
- */
 
 
 void vlsapic_reset(VCPU *vcpu)
@@ -350,6 +283,7 @@ void vlsapic_reset(VCPU *vcpu)
     VCPU(vcpu, lrr0) = 0x10000;   // default reset value?
     VCPU(vcpu, lrr1) = 0x10000;   // default reset value?
     update_vhpi(vcpu, NULL_VECTOR);
+    VLSAPIC_XTP(vcpu) = 0x80;   // disabled
     for ( i=0; i<4; i++) {
         VLSAPIC_INSVC(vcpu,i) = 0;
     }
@@ -367,7 +301,7 @@ static __inline__ int highest_bits(uint6
 {
     uint64_t  bits, bitnum;
     int i;
-    
+
     /* loop for all 256 bits */
     for ( i=3; i >= 0 ; i -- ) {
         bits = dat[i];
@@ -411,12 +345,6 @@ static int is_higher_class(int pending, 
 {
     return ( (pending >> 4) > mic );
 }
-#if 0
-static int is_invalid_irq(int vec)
-{
-    return (vec == 1 || ((vec <= 14 && vec >= 3)));
-}
-#endif //shadow it due to no use currently
 
 #define   IRQ_NO_MASKED         0
 #define   IRQ_MASKED_BY_VTPR    1
@@ -427,7 +355,7 @@ _xirq_masked(VCPU *vcpu, int h_pending, 
 _xirq_masked(VCPU *vcpu, int h_pending, int h_inservice)
 {
     tpr_t    vtpr;
-    
+
     vtpr.val = VCPU(vcpu, tpr);
 
     if ( h_inservice == NMI_VECTOR ) {
@@ -467,7 +395,7 @@ static int irq_masked(VCPU *vcpu, int h_
 static int irq_masked(VCPU *vcpu, int h_pending, int h_inservice)
 {
     int mask;
-    
+
     mask = _xirq_masked(vcpu, h_pending, h_inservice);
     return mask;
 }
@@ -655,4 +583,213 @@ struct vcpu * vlsapic_lid_to_vcpu(struct
             return v;
     }
     return NULL;
-}                                     
+}
+
+
+/*
+ * To inject INIT to guest, we must set the PAL_INIT entry 
+ * and set psr to switch to physical mode
+ */
+#define PAL_INIT_ENTRY 0x80000000ffffffa0
+#define PSR_SET_BITS (IA64_PSR_DT | IA64_PSR_IT | IA64_PSR_RT | \
+                      IA64_PSR_IC | IA64_PSR_RI)
+
+static void vmx_inject_guest_pal_init(VCPU *vcpu)
+{
+    REGS *regs = vcpu_regs(vcpu);
+    uint64_t psr = vmx_vcpu_get_psr(vcpu);
+
+    regs->cr_iip = PAL_INIT_ENTRY;
+
+    psr = psr & ~PSR_SET_BITS;
+    vmx_vcpu_set_psr(vcpu, psr);
+}
+
+
+/*
+ * Deliver IPI message. (Only U-VP is supported now)
+ *  offset: address offset to IPI space.
+ *  value:  deliver value.
+ */
+static void vlsapic_deliver_ipi(VCPU *vcpu, uint64_t dm, uint64_t vector)
+{
+    IPI_DPRINTK("deliver_ipi %lx %lx\n", dm, vector);
+
+    switch (dm) {
+    case SAPIC_FIXED:     // INT
+        vmx_vcpu_pend_interrupt(vcpu, vector);
+        break;
+    case SAPIC_PMI:
+        // TODO -- inject guest PMI
+        panic_domain(NULL, "Inject guest PMI!\n");
+        break;
+    case SAPIC_NMI:
+        vmx_vcpu_pend_interrupt(vcpu, 2);
+        break;
+    case SAPIC_INIT:
+        vmx_inject_guest_pal_init(vcpu);
+        break;
+    case SAPIC_EXTINT:     // ExtINT
+        vmx_vcpu_pend_interrupt(vcpu, 0);
+        break;
+    default:
+        panic_domain(NULL, "Deliver reserved IPI!\n");
+        break;
+    }
+}
+
+/*
+ * TODO: Use hash table for the lookup.
+ */
+static inline VCPU *lid_to_vcpu(struct domain *d, uint8_t id, uint8_t eid)
+{
+    VCPU  *v;
+    LID   lid; 
+
+    for_each_vcpu(d, v) {
+        lid.val = VCPU_LID(v);
+        if (lid.id == id && lid.eid == eid)
+            return v;
+    }
+    return NULL;
+}
+
+
+/*
+ * execute write IPI op.
+ */
+static void vlsapic_write_ipi(VCPU *vcpu, uint64_t addr, uint64_t value)
+{
+    VCPU   *targ;
+    struct domain *d = vcpu->domain; 
+
+    targ = lid_to_vcpu(vcpu->domain, ((ipi_a_t)addr).id, ((ipi_a_t)addr).eid);
+    if (targ == NULL)
+        panic_domain(NULL, "Unknown IPI cpu\n");
+
+    if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
+        struct pt_regs *targ_regs = vcpu_regs(targ);
+        struct vcpu_guest_context c;
+
+        memset (&c, 0, sizeof(c));
+
+        if (arch_set_info_guest(targ, &c) != 0) {
+            printk("arch_boot_vcpu: failure\n");
+            return;
+        }
+        /* First or next rendez-vous: set registers. */
+        vcpu_init_regs(targ);
+        targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip;
+        targ_regs->r1 = d->arch.sal_data->boot_rdv_r1;
+
+        if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) {
+            vcpu_wake(targ);
+            printk("arch_boot_vcpu: vcpu %d awaken %016lx!\n",
+                   targ->vcpu_id, targ_regs->cr_iip);
+        } else {
+            printk("arch_boot_vcpu: huh, already awake!");
+        }
+    } else {
+        int running = test_bit(_VCPUF_running, &targ->vcpu_flags);
+        vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, 
+                            ((ipi_d_t)value).vector);
+        vcpu_unblock(targ);
+        if (running)
+            smp_send_event_check_cpu(targ->processor);
+    }
+    return;
+}
+
+
+unsigned long vlsapic_read(struct vcpu *v,
+                           unsigned long addr,
+                           unsigned long length)
+{
+    uint64_t result = 0;
+
+    addr &= (PIB_SIZE - 1);
+
+    switch (addr) {
+    case PIB_OFST_INTA:
+        if (length == 1) // 1 byte load
+            ; // There is no i8259, there is no INTA access
+        else
+            panic_domain(NULL,"Undefined read on PIB INTA\n");
+
+        break;
+    case PIB_OFST_XTP:
+        if (length == 1) {
+            result = VLSAPIC_XTP(v);
+            // printk("read xtp %lx\n", result);
+        } else {
+            panic_domain(NULL, "Undefined read on PIB XTP\n");
+        }
+        break;
+    default:
+        if (PIB_LOW_HALF(addr)) {  // lower half
+            if (length != 8 )
+                panic_domain(NULL, "Undefined IPI-LHF read!\n");
+            else
+                IPI_DPRINTK("IPI-LHF read %lx\n", pib_off);
+        } else {  // upper half
+            IPI_DPRINTK("IPI-UHF read %lx\n", addr);
+        }
+        break;
+    }
+    return result;
+}
+
+static void vlsapic_write_xtp(struct vcpu *v, uint8_t val)
+{
+    struct viosapic * viosapic;
+    struct vcpu *lvcpu, *vcpu;
+    viosapic = vcpu_viosapic(v); 
+    lvcpu = viosapic->lowest_vcpu;
+    VLSAPIC_XTP(v) = val;
+    
+    for_each_vcpu(v->domain, vcpu) {
+        if (VLSAPIC_XTP(lvcpu) > VLSAPIC_XTP(vcpu))
+            lvcpu = vcpu;
+    }
+        
+    if (VLSAPIC_XTP(lvcpu) & 0x80)  // Disabled
+        lvcpu = NULL;
+
+    viosapic->lowest_vcpu = lvcpu;
+}
+
+void vlsapic_write(struct vcpu *v,
+                      unsigned long addr,
+                      unsigned long length,
+                      unsigned long val)
+{
+    addr &= (PIB_SIZE - 1);
+
+    switch (addr) {
+    case PIB_OFST_INTA:
+        panic_domain(NULL, "Undefined write on PIB INTA\n");
+        break;
+    case PIB_OFST_XTP:
+        if (length == 1) {
+            // printk("write xtp %lx\n", val);
+            vlsapic_write_xtp(v, val);
+        } else {
+            panic_domain(NULL, "Undefined write on PIB XTP\n");
+        }
+        break;
+    default:
+        if (PIB_LOW_HALF(addr)) {   // lower half
+            if (length != 8)
+                panic_domain(NULL, "Undefined IPI-LHF write with size %ld!\n",
+                             length);
+            else
+                vlsapic_write_ipi(v, addr, val);
+        }
+        else {   // upper half
+            // printk("IPI-UHF write %lx\n",addr);
+            panic_domain(NULL, "No support for SM-VP yet\n");
+        }
+        break;
+    }
+}
+
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/include/asm-ia64/viosapic.h
--- a/xen/include/asm-ia64/viosapic.h   Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/include/asm-ia64/viosapic.h   Thu Dec 07 05:34:07 2006 -0700
@@ -78,6 +78,7 @@ struct viosapic {
     uint64_t isr;     /* This is used for level trigger */
     uint32_t ioregsel;
     spinlock_t lock;
+    struct vcpu * lowest_vcpu;
     uint64_t base_address;
     union viosapic_rte redirtbl[VIOSAPIC_NUM_PINS];
 };
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/include/asm-ia64/vlsapic.h
--- a/xen/include/asm-ia64/vlsapic.h    Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/include/asm-ia64/vlsapic.h    Thu Dec 07 05:34:07 2006 -0700
@@ -50,10 +50,19 @@
 #define SAPIC_LEVEL            1
 
 /*
+ * LSAPIC OFFSET
+ */
+#define PIB_LOW_HALF(ofst)     !(ofst & (1 << 20))
+#define PIB_OFST_INTA          0x1E0000
+#define PIB_OFST_XTP           0x1E0008
+
+/*
  *Mask bit
  */
 #define SAPIC_MASK_SHIFT       16
 #define SAPIC_MASK             (1 << SAPIC_MASK_SHIFT)
+
+#define VLSAPIC_XTP(_v)        VMX(_v, xtp)
 
 extern void vtm_init(struct vcpu *vcpu);
 extern void vtm_set_itc(struct  vcpu *vcpu, uint64_t new_itc);
@@ -63,5 +72,7 @@ extern void vhpi_detection(struct 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);
+extern uint64_t vlsapic_read(struct vcpu *v, uint64_t addr, uint64_t s);
+extern void vlsapic_write(struct vcpu *v, uint64_t addr, uint64_t s, uint64_t 
val);
 #define vlsapic_set_irq vmx_vcpu_pend_interrupt
 #endif
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h       Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/include/asm-ia64/vmx_platform.h       Thu Dec 07 05:34:07 2006 -0700
@@ -28,7 +28,6 @@ typedef struct virtual_platform_def {
     spinlock_t             buffered_io_lock;
     unsigned long       shared_page_va;
     unsigned long       pib_base;
-    unsigned char       xtp;
     unsigned long       params[HVM_NR_PARAMS];
     struct mmio_list    *mmio;
     /* One IOSAPIC now... */
diff -r 4f1a3ae07dbc -r 3bd97b4fe77d xen/include/asm-ia64/vmx_vpd.h
--- a/xen/include/asm-ia64/vmx_vpd.h    Thu Dec 07 04:15:54 2006 -0700
+++ b/xen/include/asm-ia64/vmx_vpd.h    Thu Dec 07 05:34:07 2006 -0700
@@ -96,9 +96,9 @@ struct arch_vmx_struct {
 //    unsigned long   rfi_iip;
 //    unsigned long   rfi_ipsr;
 //    unsigned long   rfi_ifs;
-//     unsigned long   in_service[4];  // vLsapic inservice IRQ bits
     unsigned long   flags;
     unsigned long   xen_port;
+    unsigned char   xtp;
 #ifdef VTI_DEBUG
     unsigned long  ivt_current;
     struct ivt_debug ivt_debug[IVT_DEBUG_MAX];

_______________________________________________
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®.