# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 0705db48d23cca452e33f7ab2bc01b0da27e759d
# Parent 76d379e3f1d786858e4b8d34175f95e55ab1d8fa
[IA64] Change to new interrupt deliver mechanism.
Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c | 13 ++
tools/ioemu/Makefile.target | 4
xen/arch/ia64/vmx/viosapic.c | 71 +++++-----------
xen/arch/ia64/vmx/vmx_hypercall.c | 97 +++++++++++++++++-----
xen/include/asm-ia64/viosapic.h | 12 +-
5 files changed, 117 insertions(+), 80 deletions(-)
diff -r 76d379e3f1d7 -r 0705db48d23c
linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Fri Dec 01 11:12:00
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Fri Dec 01 11:40:57
2006 -0700
@@ -579,9 +579,16 @@ xencomm_privcmd_hvm_op(privcmd_hypercall
case HVMOP_set_param:
argsize = sizeof(xen_hvm_param_t);
break;
- case HVMOP_set_irq_level:
- argsize = sizeof(xen_hvm_set_irq_level_t);
- break;
+ case HVMOP_set_pci_intx_level:
+ argsize = sizeof(xen_hvm_set_pci_intx_level_t);
+ break;
+ case HVMOP_set_isa_irq_level:
+ argsize = sizeof(xen_hvm_set_isa_irq_level_t);
+ break;
+ case HVMOP_set_pci_link_route:
+ argsize = sizeof(xen_hvm_set_pci_link_route_t);
+ break;
+
default:
printk("%s: unknown HVMOP %d\n", __func__, cmd);
return -EINVAL;
diff -r 76d379e3f1d7 -r 0705db48d23c tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target Fri Dec 01 11:12:00 2006 -0700
+++ b/tools/ioemu/Makefile.target Fri Dec 01 11:40:57 2006 -0700
@@ -296,7 +296,7 @@ endif
# qemu-dm objects
ifeq ($(ARCH),ia64)
-LIBOBJS=helper2.o exec-dm.o i8259-dm.o
+LIBOBJS=helper2.o exec-dm.o i8259-dm.o piix_pci-dm.o
else
LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
endif
@@ -360,7 +360,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
# Hardware support
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
ifeq ($(ARCH),ia64)
-VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o
+VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
else
VL_OBJS+= fdc.o serial.o pc.o
endif
diff -r 76d379e3f1d7 -r 0705db48d23c xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c Fri Dec 01 11:12:00 2006 -0700
+++ b/xen/arch/ia64/vmx/viosapic.c Fri Dec 01 11:40:57 2006 -0700
@@ -70,9 +70,12 @@ static void viosapic_deliver(struct vios
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;
+ uint64_t irqs = viosapic->irr & ~viosapic->isr ;
+
+ if (irqs >> 32)
+ return (fls(irqs >> 32) - 1 + 32);
+ else
+ return fls(irqs) - 1;
}
@@ -95,14 +98,12 @@ static void service_iosapic(struct viosa
while ( (irq = iosapic_get_highest_irq(viosapic)) != -1 )
{
- if ( !test_bit(irq, &viosapic->imr) )
- viosapic_deliver(viosapic, irq);
+ 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);
+ viosapic->isr |= (1UL << irq);
+
+ viosapic->irr &= ~(1UL << irq);
}
}
@@ -192,15 +193,6 @@ unsigned long viosapic_read(struct vcpu
}
-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,
@@ -237,7 +229,6 @@ static void viosapic_write_indirect(stru
(val & 0xffffffff);
}
viosapic->redirtbl[redir_index].bits = redir_content;
- viosapic_update_imr(viosapic, redir_index);
break;
}
} /* switch */
@@ -282,39 +273,14 @@ static void viosapic_reset(struct viosap
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)
+void viosapic_set_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;
+ uint64_t bit;
spin_lock(&viosapic->lock);
if ( (irq < 0) || (irq >= VIOSAPIC_NUM_PINS) )
@@ -323,7 +289,7 @@ void viosapic_set_irq(struct domain *d,
if ( viosapic->redirtbl[irq].mask )
goto out;
- bit = 1 << irq;
+ bit = 1UL << irq;
if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL )
{
if ( level )
@@ -343,6 +309,17 @@ out:
spin_unlock(&viosapic->lock);
}
+#define hvm_pci_intx_gsi(dev, intx) \
+ (((((dev) << 2) + ((dev) >> 3) + (intx)) & 31) + 16)
+
+
+void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level)
+{
+ int irq;
+ irq = hvm_pci_intx_gsi(device, intx);
+
+ viosapic_set_irq(d, irq, level);
+}
void viosapic_init(struct domain *d)
{
diff -r 76d379e3f1d7 -r 0705db48d23c xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec 01 11:12:00 2006 -0700
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec 01 11:40:57 2006 -0700
@@ -36,6 +36,72 @@
#include <xen/domain.h>
#include <asm/vmx.h>
#include <asm/viosapic.h>
+
+static int hvmop_set_isa_irq_level(
+ XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t) uop)
+{
+ struct xen_hvm_set_isa_irq_level op;
+ struct domain *d;
+ int rc;
+
+ if ( copy_from_guest(&op, uop, 1) )
+ return -EFAULT;
+
+ if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+
+ if ( op.isa_irq > 15 )
+ return -EINVAL;
+
+ d = find_domain_by_id(op.domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ rc = -EINVAL;
+ if ( !is_hvm_domain(d) )
+ goto out;
+
+ rc = 0;
+ viosapic_set_irq(d, op.isa_irq, op.level);
+
+ out:
+ put_domain(d);
+ return rc;
+}
+
+static int hvmop_set_pci_intx_level(
+ XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t) uop)
+{
+ struct xen_hvm_set_pci_intx_level op;
+ struct domain *d;
+ int rc;
+
+ if ( copy_from_guest(&op, uop, 1) )
+ return -EFAULT;
+
+ if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+
+ if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
+ return -EINVAL;
+
+ d = find_domain_by_id(op.domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ rc = -EINVAL;
+ if ( !is_hvm_domain(d) )
+ goto out;
+
+ rc = 0;
+ viosapic_set_pci_irq(d, op.device, op.intx, op.level);
+
+ out:
+ put_domain(d);
+ return rc;
+}
+
+
long
do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
@@ -80,30 +146,19 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
break;
}
- case HVMOP_set_irq_level:
- {
- struct xen_hvm_set_irq_level op;
- struct domain *d;
+ case HVMOP_set_pci_intx_level:
+ rc = hvmop_set_pci_intx_level(
+ guest_handle_cast(arg, xen_hvm_set_pci_intx_level_t));
+ break;
- if (copy_from_guest(&op, arg, 1))
- return -EFAULT;
+ case HVMOP_set_isa_irq_level:
+ rc = hvmop_set_isa_irq_level(
+ guest_handle_cast(arg, xen_hvm_set_isa_irq_level_t));
+ break;
- if (!IS_PRIV(current->domain))
- return -EPERM;
-
- d = find_domain_by_id(op.domid);
- if (d == NULL)
- return -ESRCH;
-
- rc = -EINVAL;
- if (is_hvm_domain(d)) {
- viosapic_set_irq(d, op.irq, op.level);
- rc = 0;
- }
-
- put_domain(d);
+ case HVMOP_set_pci_link_route:
+ rc = 0;
break;
- }
default:
gdprintk(XENLOG_INFO, "Bad HVM op %ld.\n", op);
diff -r 76d379e3f1d7 -r 0705db48d23c xen/include/asm-ia64/viosapic.h
--- a/xen/include/asm-ia64/viosapic.h Fri Dec 01 11:12:00 2006 -0700
+++ b/xen/include/asm-ia64/viosapic.h Fri Dec 01 11:40:57 2006 -0700
@@ -42,7 +42,7 @@
#define VIOSAPIC_VERSION_ID 0x21 /* IOSAPIC version */
-#define VIOSAPIC_NUM_PINS 24
+#define VIOSAPIC_NUM_PINS 48
#define VIOSAPIC_DEFAULT_BASE_ADDRESS 0xfec00000
#define VIOSAPIC_MEM_LENGTH 0x100
@@ -74,19 +74,17 @@ union viosapic_rte
};
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;
+ uint64_t irr;
+ uint64_t isr; /* This is used for level trigger */
uint32_t ioregsel;
spinlock_t lock;
- unsigned long base_address;
+ uint64_t 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_set_pci_irq(struct domain *d, int device, int intx, int level);
void viosapic_write(struct vcpu *v, unsigned long addr,
unsigned long length, unsigned long val);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|