# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID cba947bc845063ed820142bb921121ab8ead6452
# Parent 9fbb26d47b8397681de6c910540f4ab0835ca787
[HVM] VIOAPIC and VPIC cleanups.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/ia64/vmx/vlsapic.c | 8
xen/arch/ia64/vmx/vmx_init.c | 2
xen/arch/x86/hvm/hvm.c | 12
xen/arch/x86/hvm/i8259.c | 154 +++---
xen/arch/x86/hvm/rtc.c | 22
xen/arch/x86/hvm/svm/intr.c | 2
xen/arch/x86/hvm/vioapic.c | 861 +++++++++++++++++-------------------
xen/arch/x86/hvm/vlapic.c | 4
xen/arch/x86/hvm/vmx/io.c | 2
xen/include/asm-ia64/vmx_platform.h | 2
xen/include/asm-x86/hvm/domain.h | 4
xen/include/asm-x86/hvm/vioapic.h | 111 ++--
xen/include/asm-x86/hvm/vpic.h | 32 -
13 files changed, 588 insertions(+), 628 deletions(-)
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/ia64/vmx/vlsapic.c Tue Nov 07 17:46:40 2006 +0000
@@ -324,7 +324,7 @@ void vtm_domain_in(VCPU *vcpu)
*/
#ifdef V_IOSAPIC_READY
-int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint16_t dest)
+int ioapic_match_logical_addr(struct vioapic *s, int number, uint16_t dest)
{
return (VLAPIC_ID(s->lapic_info[number]) == dest);
}
@@ -335,14 +335,14 @@ struct vlapic* apic_round_robin(struct d
uint32_t bitmap)
{
uint8_t bit;
- hvm_vioapic_t *s;
+ struct vioapic *s;
if (!bitmap) {
printk("<apic_round_robin> no bit on bitmap\n");
return NULL;
}
- s = &d->arch.vmx_platform.vioapic;
+ s = domain_vioapic(d);
for (bit = 0; bit < s->lapic_count; bit++) {
if (bitmap & (1 << bit))
return s->lapic_info[bit];
@@ -375,7 +375,7 @@ void vlsapic_reset(VCPU *vcpu)
#ifdef V_IOSAPIC_READY
vcpu->arch.arch_vmx.vlapic.vcpu = vcpu;
- hvm_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
+ vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
#endif
dprintk(XENLOG_INFO, "VLSAPIC inservice base=%p\n", &VLSAPIC_INSVC(vcpu,0)
);
}
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/ia64/vmx/vmx_init.c Tue Nov 07 17:46:40 2006 +0000
@@ -456,7 +456,7 @@ void vmx_setup_platform(struct domain *d
spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
/* Initialize iosapic model within hypervisor */
- hvm_vioapic_init(d);
+ vioapic_init(d);
}
void vmx_do_launch(struct vcpu *v)
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/hvm.c Tue Nov 07 17:46:40 2006 +0000
@@ -133,7 +133,7 @@ int hvm_domain_initialise(struct domain
pic_init(&platform->vpic, pic_irq_request, &platform->interrupt_request);
register_pic_io_hook(d);
- hvm_vioapic_init(d);
+ vioapic_init(d);
return 0;
}
@@ -219,15 +219,15 @@ int cpu_get_interrupt(struct vcpu *v, in
int cpu_get_interrupt(struct vcpu *v, int *type)
{
int intno;
- struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic;
+ struct vpic *vpic = domain_vpic(v->domain);
unsigned long flags;
if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) {
/* set irq request if a PIC irq is still pending */
/* XXX: improve that */
- spin_lock_irqsave(&s->lock, flags);
- pic_update_irq(s);
- spin_unlock_irqrestore(&s->lock, flags);
+ spin_lock_irqsave(&vpic->lock, flags);
+ pic_update_irq(vpic);
+ spin_unlock_irqrestore(&vpic->lock, flags);
return intno;
}
/* read the irq from the PIC */
@@ -674,7 +674,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
rc = -EINVAL;
if ( is_hvm_domain(d) )
{
- pic_set_irq(&d->arch.hvm_domain.vpic, op.irq, op.level);
+ pic_set_irq(domain_vpic(d), op.irq, op.level);
rc = 0;
}
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/i8259.c Tue Nov 07 17:46:40 2006 +0000
@@ -5,10 +5,10 @@
* Copyright (c) 2005 Intel Corperation
*
* 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
+ * 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
@@ -18,10 +18,11 @@
* 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.
+ * 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.
*/
+
#include <xen/config.h>
#include <xen/types.h>
#include <xen/mm.h>
@@ -33,6 +34,8 @@
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
#include <asm/current.h>
+
+#define hw_error(x) ((void)0)
/* set irq level. If an edge is detected, then the IRR is set to 1 */
static inline void pic_set_irq1(PicState *s, int irq, int level)
@@ -108,38 +111,38 @@ static int pic_get_irq(PicState *s)
/* raise irq to CPU if necessary. must be called every time the active
irq may change */
/* XXX: should not export it, but it is needed for an APIC kludge */
-void pic_update_irq(struct hvm_virpic *s)
+void pic_update_irq(struct vpic *vpic)
{
int irq2, irq;
- ASSERT(spin_is_locked(&s->lock));
+ ASSERT(spin_is_locked(&vpic->lock));
/* first look at slave pic */
- irq2 = pic_get_irq(&s->pics[1]);
+ irq2 = pic_get_irq(&vpic->pics[1]);
if (irq2 >= 0) {
/* if irq request by slave pic, signal master PIC */
- pic_set_irq1(&s->pics[0], 2, 1);
- pic_set_irq1(&s->pics[0], 2, 0);
+ pic_set_irq1(&vpic->pics[0], 2, 1);
+ pic_set_irq1(&vpic->pics[0], 2, 0);
}
/* look at requested irq */
- irq = pic_get_irq(&s->pics[0]);
+ irq = pic_get_irq(&vpic->pics[0]);
if (irq >= 0) {
- s->irq_request(s->irq_request_opaque, 1);
+ vpic->irq_request(vpic->irq_request_opaque, 1);
}
}
void pic_set_xen_irq(void *opaque, int irq, int level)
{
- struct hvm_virpic *s = opaque;
+ struct vpic *vpic = opaque;
unsigned long flags;
PicState *ps;
- spin_lock_irqsave(&s->lock, flags);
-
- hvm_vioapic_set_xen_irq(current->domain, irq, level);
+ spin_lock_irqsave(&vpic->lock, flags);
+
+ vioapic_set_xen_irq(current->domain, irq, level);
/* Set it on the 8259s */
- ps = &s->pics[irq >> 3];
+ ps = &vpic->pics[irq >> 3];
if (!(ps->elcr & (1 << (irq & 7))))
gdprintk(XENLOG_WARNING, "edge-triggered override IRQ?\n");
if (level) {
@@ -148,26 +151,25 @@ void pic_set_xen_irq(void *opaque, int i
ps->irr_xen &= ~(1 << (irq & 7));
}
- pic_update_irq(s);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-void pic_set_irq(struct hvm_virpic *s, int irq, int level)
+ pic_update_irq(vpic);
+ spin_unlock_irqrestore(&vpic->lock, flags);
+}
+
+void pic_set_irq(struct vpic *vpic, int irq, int level)
{
unsigned long flags;
if ( irq < 0 )
return;
- spin_lock_irqsave(&s->lock, flags);
- hvm_vioapic_set_irq(container_of(s, struct domain, arch.hvm_domain.vpic),
- irq, level);
+ spin_lock_irqsave(&vpic->lock, flags);
+ vioapic_set_irq(vpic_domain(vpic), irq, level);
if ( irq < 16 )
{
- pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
- pic_update_irq(s);
- }
- spin_unlock_irqrestore(&s->lock, flags);
+ pic_set_irq1(&vpic->pics[irq >> 3], irq & 7, level);
+ pic_update_irq(vpic);
+ }
+ spin_unlock_irqrestore(&vpic->lock, flags);
}
/* acknowledge interrupt 'irq' */
@@ -186,37 +188,37 @@ static inline void pic_intack(PicState *
s->irr &= ~(1 << irq);
}
-static int pic_read_irq(struct hvm_virpic *s)
+static int pic_read_irq(struct vpic *vpic)
{
int irq, irq2, intno;
unsigned long flags;
- spin_lock_irqsave(&s->lock, flags);
- irq = pic_get_irq(&s->pics[0]);
+ spin_lock_irqsave(&vpic->lock, flags);
+ irq = pic_get_irq(&vpic->pics[0]);
if (irq >= 0) {
- pic_intack(&s->pics[0], irq);
+ pic_intack(&vpic->pics[0], irq);
if (irq == 2) {
- irq2 = pic_get_irq(&s->pics[1]);
+ irq2 = pic_get_irq(&vpic->pics[1]);
if (irq2 >= 0) {
- pic_intack(&s->pics[1], irq2);
+ pic_intack(&vpic->pics[1], irq2);
} else {
/* spurious IRQ on slave controller */
gdprintk(XENLOG_WARNING, "Spurious irq on slave i8259.\n");
irq2 = 7;
}
- intno = s->pics[1].irq_base + irq2;
+ intno = vpic->pics[1].irq_base + irq2;
irq = irq2 + 8;
} else {
- intno = s->pics[0].irq_base + irq;
+ intno = vpic->pics[0].irq_base + irq;
}
} else {
/* spurious IRQ on host controller */
irq = 7;
- intno = s->pics[0].irq_base + irq;
+ intno = vpic->pics[0].irq_base + irq;
gdprintk(XENLOG_WARNING, "Spurious irq on master i8259.\n");
}
- pic_update_irq(s);
- spin_unlock_irqrestore(&s->lock, flags);
+ pic_update_irq(vpic);
+ spin_unlock_irqrestore(&vpic->lock, flags);
return intno;
}
@@ -414,28 +416,28 @@ static void pic_init1(int io_addr, int e
s->elcr = 0xff & s->elcr_mask;
}
-void pic_init(struct hvm_virpic *s, void (*irq_request)(void *, int),
+void pic_init(struct vpic *vpic, void (*irq_request)(void *, int),
void *irq_request_opaque)
{
unsigned long flags;
- memset(s, 0, sizeof(*s));
- spin_lock_init(&s->lock);
- s->pics[0].pics_state = s;
- s->pics[1].pics_state = s;
- s->pics[0].elcr_mask = 0xf8;
- s->pics[1].elcr_mask = 0xde;
- spin_lock_irqsave(&s->lock, flags);
- pic_init1(0x20, 0x4d0, &s->pics[0]);
- pic_init1(0xa0, 0x4d1, &s->pics[1]);
- spin_unlock_irqrestore(&s->lock, flags);
- s->irq_request = irq_request;
- s->irq_request_opaque = irq_request_opaque;
+ memset(vpic, 0, sizeof(*vpic));
+ spin_lock_init(&vpic->lock);
+ vpic->pics[0].pics_state = vpic;
+ vpic->pics[1].pics_state = vpic;
+ vpic->pics[0].elcr_mask = 0xf8;
+ vpic->pics[1].elcr_mask = 0xde;
+ spin_lock_irqsave(&vpic->lock, flags);
+ pic_init1(0x20, 0x4d0, &vpic->pics[0]);
+ pic_init1(0xa0, 0x4d1, &vpic->pics[1]);
+ spin_unlock_irqrestore(&vpic->lock, flags);
+ vpic->irq_request = irq_request;
+ vpic->irq_request_opaque = irq_request_opaque;
}
static int intercept_pic_io(ioreq_t *p)
{
- struct hvm_virpic *pic;
+ struct vpic *pic;
uint32_t data;
unsigned long flags;
@@ -444,7 +446,7 @@ static int intercept_pic_io(ioreq_t *p)
return 1;
}
- pic = ¤t->domain->arch.hvm_domain.vpic;
+ pic = domain_vpic(current->domain);
if ( p->dir == IOREQ_WRITE ) {
if ( p->data_is_ptr )
(void)hvm_copy_from_guest_phys(&data, p->data, p->size);
@@ -470,7 +472,7 @@ static int intercept_pic_io(ioreq_t *p)
static int intercept_elcr_io(ioreq_t *p)
{
- struct hvm_virpic *s;
+ struct vpic *vpic;
uint32_t data;
unsigned long flags;
@@ -479,20 +481,20 @@ static int intercept_elcr_io(ioreq_t *p)
return 1;
}
- s = ¤t->domain->arch.hvm_domain.vpic;
+ vpic = domain_vpic(current->domain);
if ( p->dir == IOREQ_WRITE ) {
if ( p->data_is_ptr )
(void)hvm_copy_from_guest_phys(&data, p->data, p->size);
else
data = p->data;
- spin_lock_irqsave(&s->lock, flags);
- elcr_ioport_write((void*)&s->pics[p->addr&1],
+ spin_lock_irqsave(&vpic->lock, flags);
+ elcr_ioport_write((void*)&vpic->pics[p->addr&1],
(uint32_t) p->addr, (uint32_t)( data & 0xff));
- spin_unlock_irqrestore(&s->lock, flags);
+ spin_unlock_irqrestore(&vpic->lock, flags);
}
else {
data = (u64) elcr_ioport_read(
- (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
+ (void*)&vpic->pics[p->addr&1], (uint32_t) p->addr);
if ( p->data_is_ptr )
(void)hvm_copy_to_guest_phys(p->data, &data, p->size);
else
@@ -514,7 +516,7 @@ int cpu_get_pic_interrupt(struct vcpu *v
int cpu_get_pic_interrupt(struct vcpu *v, int *type)
{
int intno;
- struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic;
+ struct vpic *vpic = domain_vpic(v->domain);
struct hvm_domain *plat = &v->domain->arch.hvm_domain;
if ( !vlapic_accept_pic_intr(v) )
@@ -524,7 +526,7 @@ int cpu_get_pic_interrupt(struct vcpu *v
return -1;
/* read the irq from the PIC */
- intno = pic_read_irq(s);
+ intno = pic_read_irq(vpic);
*type = APIC_DM_EXTINT;
return intno;
}
@@ -539,10 +541,9 @@ int is_periodic_irq(struct vcpu *v, int
if (pt->irq == 0) { /* Is it pit irq? */
if (type == APIC_DM_EXTINT)
- vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base;
- else
- vec =
- v->domain->arch.hvm_domain.vioapic.redirtbl[0].RedirForm.vector;
+ vec = domain_vpic(v->domain)->pics[0].irq_base;
+ else
+ vec = domain_vioapic(v->domain)->redirtbl[0].fields.vector;
if (irq == vec)
return 1;
@@ -550,10 +551,9 @@ int is_periodic_irq(struct vcpu *v, int
if (pt->irq == 8) { /* Or rtc irq? */
if (type == APIC_DM_EXTINT)
- vec = v->domain->arch.hvm_domain.vpic.pics[1].irq_base;
- else
- vec =
- v->domain->arch.hvm_domain.vioapic.redirtbl[8].RedirForm.vector;
+ vec = domain_vpic(v->domain)->pics[1].irq_base;
+ else
+ vec = domain_vioapic(v->domain)->redirtbl[8].fields.vector;
if (irq == vec)
return is_rtc_periodic_irq(vrtc);
@@ -564,10 +564,10 @@ int is_periodic_irq(struct vcpu *v, int
int is_irq_enabled(struct vcpu *v, int irq)
{
- struct hvm_vioapic *vioapic = &v->domain->arch.hvm_domain.vioapic;
- struct hvm_virpic *vpic=&v->domain->arch.hvm_domain.vpic;
-
- if (vioapic->redirtbl[irq].RedirForm.mask == 0)
+ struct vioapic *vioapic = domain_vioapic(v->domain);
+ struct vpic *vpic = domain_vpic(v->domain);
+
+ if (vioapic->redirtbl[irq].fields.mask == 0)
return 1;
if ( irq & 8 ) {
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/rtc.c Tue Nov 07 17:46:40 2006 +0000
@@ -4,10 +4,10 @@
* Copyright (c) 2003-2004 Fabrice Bellard
*
* 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
+ * 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
@@ -17,9 +17,9 @@
* 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.
+ * 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.
*/
#include <asm/mc146818rtc.h>
@@ -263,8 +263,8 @@ static void rtc_update_second2(void *opa
static void rtc_update_second2(void *opaque)
{
RTCState *s = opaque;
- struct hvm_domain *plat=&s->vcpu->domain->arch.hvm_domain;
- struct hvm_virpic *pic= &plat->vpic;
+ struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain;
+ struct vpic *pic = &plat->vpic;
if (!(s->cmos_data[RTC_REG_B] & RTC_SET)) {
rtc_copy_date(s);
@@ -302,8 +302,8 @@ static uint32_t rtc_ioport_read(void *op
static uint32_t rtc_ioport_read(void *opaque, uint32_t addr)
{
RTCState *s = opaque;
- struct hvm_domain *plat=&s->vcpu->domain->arch.hvm_domain;
- struct hvm_virpic *pic= &plat->vpic;
+ struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain;
+ struct vpic *pic = &plat->vpic;
int ret;
if ((addr & 1) == 0) {
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c Tue Nov 07 17:46:40 2006 +0000
@@ -65,7 +65,7 @@ asmlinkage void svm_intr_assist(void)
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
struct periodic_time *pt = &plat->pl_time.periodic_tm;
- struct hvm_virpic *pic= &plat->vpic;
+ struct vpic *pic= &plat->vpic;
int callback_irq;
int intr_type = APIC_DM_EXTINT;
int intr_vector = -1;
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/vioapic.c Tue Nov 07 17:46:40 2006 +0000
@@ -1,31 +1,29 @@
/*
-* 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.
-*/
+ * 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>
@@ -51,14 +49,6 @@ static int redir_warning_done = 0;
#define opt_hvm_debug_level opt_vmx_debug_level
#endif
-static void ioapic_enable(hvm_vioapic_t *s, uint8_t enable)
-{
- if (enable)
- s->flags |= IOAPIC_ENABLE_FLAG;
- else
- s->flags &= ~IOAPIC_ENABLE_FLAG;
-}
-
#ifdef HVM_DOMAIN_SAVE_RESTORE
void ioapic_save(QEMUFile* f, void* opaque)
{
@@ -72,234 +62,215 @@ int ioapic_load(QEMUFile* f, void* opaqu
}
#endif
-static unsigned long hvm_vioapic_read_indirect(struct hvm_vioapic *s,
- unsigned long addr,
- unsigned long length)
+static unsigned long vioapic_read_indirect(struct vioapic *vioapic,
+ unsigned long addr,
+ unsigned long length)
{
unsigned long result = 0;
- ASSERT(s);
-
- switch (s->ioregsel) {
- case IOAPIC_REG_VERSION:
- result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)
- | (IOAPIC_VERSION_ID & 0xff));
- break;
-
-#ifndef __ia64__
- case IOAPIC_REG_APIC_ID:
- result = ((s->id & 0xf) << 24);
- break;
-
- case IOAPIC_REG_ARB_ID:
- /* XXX how arb_id used on p4? */
- result = ((s->arb_id & 0xf) << 24);
- break;
-#endif
-
- default:
- {
- uint32_t redir_index = 0;
- uint64_t redir_content = 0;
-
- redir_index = (s->ioregsel - 0x10) >> 1;
-
- if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
- redir_content = s->redirtbl[redir_index].value;
-
- result = (s->ioregsel & 0x1)?
- (redir_content >> 32) & 0xffffffff :
- redir_content & 0xffffffff;
- } else {
- printk("apic_mem_readl:undefined ioregsel %x\n",
- s->ioregsel);
- domain_crash_synchronous();
+ switch ( vioapic->ioregsel )
+ {
+ case VIOAPIC_REG_VERSION:
+ result = ((((VIOAPIC_NUM_PINS-1) & 0xff) << 16)
+ | (VIOAPIC_VERSION_ID & 0xff));
+ break;
+
+#if !VIOAPIC_IS_IOSAPIC
+ case VIOAPIC_REG_APIC_ID:
+ case VIOAPIC_REG_ARB_ID:
+ result = ((vioapic->id & 0xf) << 24);
+ break;
+#endif
+
+ default:
+ {
+ uint32_t redir_index = (vioapic->ioregsel - 0x10) >> 1;
+ uint64_t redir_content;
+
+ if ( redir_index >= VIOAPIC_NUM_PINS )
+ {
+ gdprintk(XENLOG_WARNING, "apic_mem_readl:undefined ioregsel %x\n",
+ vioapic->ioregsel);
+ break;
+ }
+
+ redir_content = vioapic->redirtbl[redir_index].bits;
+ result = (vioapic->ioregsel & 0x1)?
+ (redir_content >> 32) & 0xffffffff :
+ redir_content & 0xffffffff;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static unsigned long vioapic_read(struct vcpu *v,
+ unsigned long addr,
+ unsigned long length)
+{
+ struct vioapic *vioapic = domain_vioapic(v->domain);
+ uint32_t result;
+
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_read addr %lx\n", addr);
+
+ addr &= 0xff;
+
+ switch ( addr )
+ {
+ case VIOAPIC_REG_SELECT:
+ result = vioapic->ioregsel;
+ break;
+
+ case VIOAPIC_REG_WINDOW:
+ result = vioapic_read_indirect(vioapic, addr, length);
+ break;
+
+ default:
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+static void vioapic_update_imr(struct vioapic *vioapic, int index)
+{
+ if ( vioapic->redirtbl[index].fields.mask )
+ set_bit(index, &vioapic->imr);
+ else
+ clear_bit(index, &vioapic->imr);
+}
+
+
+static void vioapic_write_indirect(struct vioapic *vioapic,
+ unsigned long addr,
+ unsigned long length,
+ unsigned long val)
+{
+ switch ( vioapic->ioregsel )
+ {
+ case VIOAPIC_REG_VERSION:
+ /* Writes are ignored. */
+ break;
+
+#if !VIOAPIC_IS_IOSAPIC
+ case VIOAPIC_REG_APIC_ID:
+ vioapic->id = (val >> 24) & 0xf;
+ break;
+
+ case VIOAPIC_REG_ARB_ID:
+ break;
+#endif
+
+ default:
+ {
+ uint32_t redir_index = (vioapic->ioregsel - 0x10) >> 1;
+ uint64_t redir_content;
+
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_write_indirect "
+ "change redir index %x val %lx\n",
+ redir_index, val);
+
+ if ( redir_index >= VIOAPIC_NUM_PINS )
+ {
+ gdprintk(XENLOG_WARNING, "vioapic_write_indirect "
+ "error register %x\n", vioapic->ioregsel);
+ break;
+ }
+
+ redir_content = vioapic->redirtbl[redir_index].bits;
+
+ if ( vioapic->ioregsel & 0x1 )
+ {
+#ifdef IRQ0_SPECIAL_ROUTING
+ if ( !redir_warning_done && (redir_index == 0) &&
+ ((val >> 24) != 0) )
+ {
+ /*
+ * Cannot yet handle delivering PIT interrupts to any VCPU !=
+ * 0. Needs proper fixing, but for now simply spit a warning
+ * that we're going to ignore the target in practice and always
+ * deliver to VCPU 0.
+ */
+ printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx "
+ "will be ignored.\n", val >> 24);
+ redir_warning_done = 1;
}
- break;
- }
+#endif
+ redir_content = (((uint64_t)val & 0xffffffff) << 32) |
+ (redir_content & 0xffffffff);
+ }
+ else
+ {
+ redir_content = ((redir_content >> 32) << 32) |
+ (val & 0xffffffff);
+ }
+ vioapic->redirtbl[redir_index].bits = redir_content;
+ vioapic_update_imr(vioapic, redir_index);
+ break;
+ }
} /* switch */
-
- return result;
-}
-
-static unsigned long hvm_vioapic_read(struct vcpu *v,
- unsigned long addr,
- unsigned long length)
-{
- struct hvm_vioapic *s = &(v->domain->arch.hvm_domain.vioapic);
- uint32_t result = 0;
-
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_read addr %lx\n", addr);
-
- ASSERT(s);
+}
+
+static void vioapic_write(struct vcpu *v,
+ unsigned long addr,
+ unsigned long length,
+ unsigned long val)
+{
+ struct vioapic *vioapic = domain_vioapic(v->domain);
addr &= 0xff;
- switch (addr) {
- case IOAPIC_REG_SELECT:
- result = s->ioregsel;
- break;
-
- case IOAPIC_REG_WINDOW:
- result = hvm_vioapic_read_indirect(s, addr, length);
- break;
-
- default:
- break;
- }
-
- return result;
-}
-
-static void hvm_vioapic_update_imr(struct hvm_vioapic *s, int index)
-{
- if (s->redirtbl[index].RedirForm.mask)
- set_bit(index, &s->imr);
- else
- clear_bit(index, &s->imr);
-}
-
-
-static void hvm_vioapic_write_indirect(struct hvm_vioapic *s,
- unsigned long addr,
- unsigned long length,
- unsigned long val)
-{
- switch (s->ioregsel) {
- case IOAPIC_REG_VERSION:
- printk("hvm_vioapic_write_indirect: version register read only\n");
- break;
-
-#ifndef __ia64__
- case IOAPIC_REG_APIC_ID:
- s->id = (val >> 24) & 0xf;
- break;
-
- case IOAPIC_REG_ARB_ID:
- s->arb_id = val;
- break;
-#endif
-
- default:
- {
- uint32_t redir_index = 0;
-
- redir_index = (s->ioregsel - 0x10) >> 1;
-
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_write_indirect "
- "change redir index %x val %lx\n",
- redir_index, val);
-
- if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
- uint64_t redir_content;
-
- redir_content = s->redirtbl[redir_index].value;
-
- if (s->ioregsel & 0x1) {
-#ifdef IRQ0_SPECIAL_ROUTING
- if ( !redir_warning_done && (redir_index == 0) &&
- ((val >> 24) != 0) ) {
- /*
- * Cannot yet handle delivering PIT interrupts to
- * any VCPU != 0. Needs proper fixing, but for now
- * simply spit a warning that we're going to ignore
- * the target in practice & always deliver to VCPU 0
- */
- printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx "
- "will be ignored.\n", val >> 24);
- redir_warning_done = 1;
- }
-#endif
- redir_content = (((uint64_t)val & 0xffffffff) << 32) |
- (redir_content & 0xffffffff);
- } else
- redir_content = ((redir_content >> 32) << 32) |
- (val & 0xffffffff);
- s->redirtbl[redir_index].value = redir_content;
- hvm_vioapic_update_imr(s, redir_index);
- } else {
- printk("hvm_vioapic_write_indirect "
- "error register %x\n", s->ioregsel);
- }
- break;
- }
- } /* switch */
-}
-
-static void hvm_vioapic_write(struct vcpu *v,
- unsigned long addr,
- unsigned long length,
- unsigned long val)
-{
- hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic);
-
- ASSERT(s);
-
- addr &= 0xff;
-
- switch (addr) {
- case IOAPIC_REG_SELECT:
- s->ioregsel = val;
- break;
-
- case IOAPIC_REG_WINDOW:
- hvm_vioapic_write_indirect(s, addr, length, val);
- break;
-
-#ifdef __ia64__
- case IOAPIC_REG_EOI:
- ioapic_update_EOI(v->domain, val);
- break;
-#endif
-
- default:
- break;
- }
-}
-
-static int hvm_vioapic_range(struct vcpu *v, unsigned long addr)
-{
- hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic);
-
- if ((s->flags & IOAPIC_ENABLE_FLAG) &&
- (addr >= s->base_address &&
- (addr < s->base_address + IOAPIC_MEM_LENGTH)))
- return 1;
- else
- return 0;
+ switch ( addr )
+ {
+ case VIOAPIC_REG_SELECT:
+ vioapic->ioregsel = val;
+ break;
+
+ case VIOAPIC_REG_WINDOW:
+ vioapic_write_indirect(vioapic, addr, length, val);
+ break;
+
+#if VIOAPIC_IS_IOSAPIC
+ case VIOAPIC_REG_EOI:
+ vioapic_update_EOI(v->domain, val);
+ break;
+#endif
+
+ default:
+ break;
+ }
+}
+
+static int vioapic_range(struct vcpu *v, unsigned long addr)
+{
+ struct vioapic *vioapic = domain_vioapic(v->domain);
+
+ return ((addr >= vioapic->base_address &&
+ (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH)));
}
struct hvm_mmio_handler vioapic_mmio_handler = {
- .check_handler = hvm_vioapic_range,
- .read_handler = hvm_vioapic_read,
- .write_handler = hvm_vioapic_write
+ .check_handler = vioapic_range,
+ .read_handler = vioapic_read,
+ .write_handler = vioapic_write
};
-static void hvm_vioapic_reset(hvm_vioapic_t *s)
+static void vioapic_reset(struct vioapic *vioapic)
{
int i;
- memset(s, 0, sizeof(hvm_vioapic_t));
-
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- s->redirtbl[i].RedirForm.mask = 0x1;
- hvm_vioapic_update_imr(s, i);
- }
-}
-
-static void ioapic_update_config(hvm_vioapic_t *s,
- unsigned long address,
- uint8_t enable)
-{
- ASSERT(s);
-
- ioapic_enable(s, enable);
-
- if (address != s->base_address)
- s->base_address = address;
-}
-
-static int ioapic_inj_irq(hvm_vioapic_t *s,
+ memset(vioapic, 0, sizeof(*vioapic));
+
+ for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
+ {
+ vioapic->redirtbl[i].fields.mask = 0x1;
+ vioapic_update_imr(vioapic, i);
+ }
+}
+
+static int ioapic_inj_irq(struct vioapic *vioapic,
struct vlapic * target,
uint8_t vector,
uint8_t trig_mode,
@@ -307,65 +278,64 @@ static int ioapic_inj_irq(hvm_vioapic_t
{
int result = 0;
- ASSERT(s && target);
-
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
- "irq %d trig %d delive mode %d\n",
- vector, trig_mode, delivery_mode);
-
- switch (delivery_mode) {
+ "irq %d trig %d delive mode %d\n",
+ vector, trig_mode, delivery_mode);
+
+ switch ( delivery_mode )
+ {
case dest_Fixed:
case dest_LowestPrio:
- if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1))
- printk("<ioapic_inj_irq> level interrupt happen before cleared\n");
+ if ( vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1) )
+ gdprintk(XENLOG_WARNING, "level interrupt before cleared\n");
result = 1;
break;
default:
- printk("<ioapic_inj_irq> error delivery mode %d\n",
- delivery_mode);
- break;
- }
-
- return result;
+ gdprintk(XENLOG_WARNING, "error delivery mode %d\n", delivery_mode);
+ break;
+ }
+
+ return result;
}
#ifndef __ia64__
-static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t
dest)
+static int ioapic_match_logical_addr(
+ struct vioapic *vioapic, int number, uint8_t dest)
{
int result = 0;
- uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR);
-
- ASSERT(s && s->lapic_info[number]);
+ uint32_t logical_dest;
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr "
- "number %i dest %x\n",
- number, dest);
-
- switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR))
+ "number %i dest %x\n",
+ number, dest);
+
+ logical_dest = vlapic_get_reg(vioapic->lapic_info[number], APIC_LDR);
+
+ switch ( vlapic_get_reg(vioapic->lapic_info[number], APIC_DFR) )
{
case APIC_DFR_FLAT:
- result =
- (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0;
+ result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0);
break;
case APIC_DFR_CLUSTER:
/* Should we support flat cluster mode ?*/
if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4
- == ((dest >> 0x4) & 0xf)) &&
+ == ((dest >> 0x4) & 0xf)) &&
(logical_dest & (dest & 0xf)) )
result = 1;
break;
default:
- printk("error DFR value for %x local apic\n", number);
+ gdprintk(XENLOG_WARNING, "error DFR value for %x lapic\n", number);
break;
}
return result;
}
#else
-extern int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t
dest);
-#endif
-
-static uint32_t ioapic_get_delivery_bitmask(hvm_vioapic_t *s,
+extern int ioapic_match_logical_addr(
+ struct vioapic *vioapic, int number, uint8_t dest);
+#endif
+
+static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic,
uint16_t dest,
uint8_t dest_mode,
uint8_t vector,
@@ -375,18 +345,16 @@ static uint32_t ioapic_get_delivery_bitm
int i;
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
- "dest %d dest_mode %d "
- "vector %d del_mode %d, lapic_count %d\n",
- dest, dest_mode, vector, delivery_mode, s->lapic_count);
-
- ASSERT(s);
+ "dest %d dest_mode %d "
+ "vector %d del_mode %d, lapic_count %d\n",
+ dest, dest_mode, vector, delivery_mode, vioapic->lapic_count);
if ( dest_mode == 0 )
{
/* Physical mode. */
- for ( i = 0; i < s->lapic_count; i++ )
- {
- if ( VLAPIC_ID(s->lapic_info[i]) == dest )
+ for ( i = 0; i < vioapic->lapic_count; i++ )
+ {
+ if ( VLAPIC_ID(vioapic->lapic_info[i]) == dest )
{
mask = 1 << i;
break;
@@ -396,7 +364,7 @@ static uint32_t ioapic_get_delivery_bitm
/* Broadcast. */
if ( dest == 0xFF )
{
- for ( i = 0; i < s->lapic_count; i++ )
+ for ( i = 0; i < vioapic->lapic_count; i++ )
mask |= ( 1 << i );
}
}
@@ -405,63 +373,67 @@ static uint32_t ioapic_get_delivery_bitm
/* Logical destination. Call match_logical_addr for each APIC. */
if ( dest != 0 )
{
- for ( i = 0; i < s->lapic_count; i++ )
+ for ( i = 0; i < vioapic->lapic_count; i++ )
{
- if ( s->lapic_info[i] &&
- ioapic_match_logical_addr(s, i, dest) )
+ if ( vioapic->lapic_info[i] &&
+ ioapic_match_logical_addr(vioapic, i, dest) )
mask |= (1<<i);
}
}
}
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
- "mask %x\n", mask);
+ "mask %x\n", mask);
return mask;
}
-static void ioapic_deliver(hvm_vioapic_t *s, int irqno)
-{
- uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id;
- uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
- uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
- uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
- uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
+static void ioapic_deliver(struct vioapic *vioapic, int irq)
+{
+ uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
+ uint8_t dest_mode = vioapic->redirtbl[irq].fields.dest_mode;
+ uint8_t delivery_mode = vioapic->redirtbl[irq].fields.delivery_mode;
+ uint8_t vector = vioapic->redirtbl[irq].fields.vector;
+ uint8_t trig_mode = vioapic->redirtbl[irq].fields.trig_mode;
uint32_t deliver_bitmask;
struct vlapic *target;
HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
- "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
- dest, dest_mode, delivery_mode, vector, trig_mode);
+ "dest %x dest_mode %x delivery_mode %x vector %x trig_mode
%x\n",
+ dest, dest_mode, delivery_mode, vector, trig_mode);
deliver_bitmask = ioapic_get_delivery_bitmask(
- s, dest, dest_mode, vector, delivery_mode);
-
- if (!deliver_bitmask) {
+ vioapic, dest, dest_mode, vector, delivery_mode);
+ if ( !deliver_bitmask )
+ {
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
- "no target on destination\n");
-
+ "no target on destination\n");
return;
}
- switch (delivery_mode) {
+ switch ( delivery_mode )
+ {
case dest_LowestPrio:
{
#ifdef IRQ0_SPECIAL_ROUTING
/* Force round-robin to pick VCPU 0 */
- if (irqno == 0)
- target = s->lapic_info[0];
+ if ( irq == 0 )
+ target = vioapic->lapic_info[0];
else
#endif
- target = apic_round_robin(s->domain, dest_mode,
+ target = apic_round_robin(vioapic_domain(vioapic), dest_mode,
vector, deliver_bitmask);
- if (target) {
- ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
+ if ( target != NULL )
+ {
+ ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode);
vcpu_kick(vlapic_vcpu(target));
- } else
+ }
+ else
+ {
HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
- "null round robin mask %x vector %x delivery_mode %x\n",
- deliver_bitmask, vector, dest_LowestPrio);
+ "null round robin mask %x vector %x delivery_mode
%x\n",
+ deliver_bitmask, vector, dest_LowestPrio);
+ }
break;
}
@@ -469,18 +441,21 @@ static void ioapic_deliver(hvm_vioapic_t
case dest_ExtINT:
{
uint8_t bit;
- for (bit = 0; bit < s->lapic_count; bit++) {
+ for ( bit = 0; bit < vioapic->lapic_count; bit++ )
+ {
if ( !(deliver_bitmask & (1 << bit)) )
continue;
#ifdef IRQ0_SPECIAL_ROUTING
/* Do not deliver timer interrupts to VCPU != 0 */
- if ( (irqno == 0) && (bit !=0 ) )
- target = s->lapic_info[0];
+ if ( (irq == 0) && (bit != 0) )
+ target = vioapic->lapic_info[0];
else
#endif
- target = s->lapic_info[bit];
- if (target) {
- ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
+ target = vioapic->lapic_info[bit];
+ if ( target != NULL )
+ {
+ ioapic_inj_irq(vioapic, target, vector,
+ trig_mode, delivery_mode);
vcpu_kick(vlapic_vcpu(target));
}
}
@@ -492,164 +467,160 @@ static void ioapic_deliver(hvm_vioapic_t
case dest_INIT:
case dest__reserved_2:
default:
- printk("Not support delivey mode %d\n", delivery_mode);
- break;
- }
-}
-
-static int ioapic_get_highest_irq(hvm_vioapic_t *s)
-{
- uint32_t irqs = (s->irr | s->irr_xen) & ~s->isr & ~s->imr;
+ gdprintk(XENLOG_WARNING, "Unsupported delivery mode %d\n",
+ delivery_mode);
+ break;
+ }
+}
+
+static int ioapic_get_highest_irq(struct vioapic *vioapic)
+{
+ uint32_t irqs = vioapic->irr | vioapic->irr_xen;
+ irqs &= ~vioapic->isr & ~vioapic->imr;
return fls(irqs) - 1;
}
-static void service_ioapic(hvm_vioapic_t *s)
-{
- int irqno;
-
- while ((irqno = ioapic_get_highest_irq(s)) != -1) {
-
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic "
- "highest irqno %x\n", irqno);
-
- if (!test_bit(irqno, &s->imr)) {
- ioapic_deliver(s, irqno);
- }
-
- if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
- s->isr |= (1 << irqno);
- }
-
- s->irr &= ~(1 << irqno);
- s->irr_xen &= ~(1 << irqno);
- }
-}
-
-void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level)
-{
- hvm_vioapic_t *s = &d->arch.hvm_domain.vioapic;
-
- if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
+static void service_ioapic(struct vioapic *vioapic)
+{
+ int irq;
+
+ while ( (irq = ioapic_get_highest_irq(vioapic)) != -1 )
+ {
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic highest irq %x\n", irq);
+
+ if ( !test_bit(irq, &vioapic->imr) )
+ ioapic_deliver(vioapic, irq);
+
+ if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_LEVEL_TRIG )
+ vioapic->isr |= (1 << irq);
+
+ vioapic->irr &= ~(1 << irq);
+ vioapic->irr_xen &= ~(1 << irq);
+ }
+}
+
+void vioapic_set_xen_irq(struct domain *d, int irq, int level)
+{
+ struct vioapic *vioapic = domain_vioapic(d);
+
+ if ( vioapic->redirtbl[irq].fields.mask )
return;
- if (s->redirtbl[irq].RedirForm.trigmod != IOAPIC_LEVEL_TRIGGER)
- gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq);
-
- if (level)
- s->irr_xen |= 1 << irq;
+ if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_EDGE_TRIG )
+ gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq);
+
+ if ( level )
+ vioapic->irr_xen |= 1 << irq;
else
- s->irr_xen &= ~(1 << irq);
-}
-
-void hvm_vioapic_set_irq(struct domain *d, int irq, int level)
-{
- hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic);
+ vioapic->irr_xen &= ~(1 << irq);
+}
+
+void vioapic_set_irq(struct domain *d, int irq, int level)
+{
+ struct vioapic *vioapic = domain_vioapic(d);
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
- "irq %x level %x\n", irq, level);
-
- if ( (irq < 0) || (irq >= IOAPIC_NUM_PINS) )
+ "irq %x level %x\n", irq, level);
+
+ if ( (irq < 0) || (irq >= VIOAPIC_NUM_PINS) )
return;
- if ( !IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask )
+ if ( vioapic->redirtbl[irq].fields.mask )
return;
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_set_irq entry %x "
- "vector %x deliver_mod %x destmode %x delivestatus %x "
- "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
- irq,
- s->redirtbl[irq].RedirForm.vector,
- s->redirtbl[irq].RedirForm.deliver_mode,
- s->redirtbl[irq].RedirForm.destmode,
- s->redirtbl[irq].RedirForm.delivestatus,
- s->redirtbl[irq].RedirForm.polarity,
- s->redirtbl[irq].RedirForm.remoteirr,
- s->redirtbl[irq].RedirForm.trigmod,
- s->redirtbl[irq].RedirForm.mask,
- s->redirtbl[irq].RedirForm.dest_id);
-
- if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_set_irq entry %x "
+ "vector %x delivery_mode %x dest_mode %x delivery_status %x "
+ "polarity %x remote_irr %x trig_mode %x mask %x dest_id %x\n",
+ irq,
+ vioapic->redirtbl[irq].fields.vector,
+ vioapic->redirtbl[irq].fields.delivery_mode,
+ vioapic->redirtbl[irq].fields.dest_mode,
+ vioapic->redirtbl[irq].fields.delivery_status,
+ vioapic->redirtbl[irq].fields.polarity,
+ vioapic->redirtbl[irq].fields.remote_irr,
+ vioapic->redirtbl[irq].fields.trig_mode,
+ vioapic->redirtbl[irq].fields.mask,
+ vioapic->redirtbl[irq].fields.dest_id);
+
+ if ( (irq >= 0) && (irq < VIOAPIC_NUM_PINS) )
+ {
uint32_t bit = 1 << irq;
- if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
- if (level)
- s->irr |= bit;
+ if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_LEVEL_TRIG )
+ {
+ if ( level )
+ vioapic->irr |= bit;
else
- s->irr &= ~bit;
- } else {
- if (level)
+ vioapic->irr &= ~bit;
+ }
+ else
+ {
+ if ( level )
/* XXX No irr clear for edge interrupt */
- s->irr |= bit;
- }
- }
-
- service_ioapic(s);
+ vioapic->irr |= bit;
+ }
+ }
+
+ service_ioapic(vioapic);
}
/* XXX If level interrupt, use vector->irq table for performance */
-static int get_redir_num(hvm_vioapic_t *s, int vector)
-{
- int i = 0;
-
- ASSERT(s);
-
- for(i = 0; i < IOAPIC_NUM_PINS; i++) {
- if (s->redirtbl[i].RedirForm.vector == vector)
+static int get_redir_num(struct vioapic *vioapic, int vector)
+{
+ int i;
+
+ for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
+ if ( vioapic->redirtbl[i].fields.vector == vector )
return i;
- }
return -1;
}
-void ioapic_update_EOI(struct domain *d, int vector)
-{
- hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic);
+void vioapic_update_EOI(struct domain *d, int vector)
+{
+ struct vioapic *vioapic = domain_vioapic(d);
int redir_num;
- if ((redir_num = get_redir_num(s, vector)) == -1) {
- printk("Can't find redir item for %d EOI \n", vector);
+ if ( (redir_num = get_redir_num(vioapic, vector)) == -1 )
+ {
+ gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector);
return;
}
- if (!test_and_clear_bit(redir_num, &s->isr)) {
- printk("redir %d not set for %d EOI\n", redir_num, vector);
+ if ( !test_and_clear_bit(redir_num, &vioapic->isr) )
+ {
+ gdprintk(XENLOG_WARNING, "redir %d not set for %d EOI\n",
+ redir_num, vector);
return;
}
}
-int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
-{
- hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic);
-
- if (v->vcpu_id != s->lapic_count) {
- printk("hvm_vioapic_add_lapic "
- "cpu_id not match vcpu_id %x lapic_count %x\n",
- v->vcpu_id, s->lapic_count);
+int vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
+{
+ struct vioapic *vioapic = domain_vioapic(v->domain);
+
+ if ( v->vcpu_id != vioapic->lapic_count )
+ {
+ gdprintk(XENLOG_ERR, "vioapic_add_lapic "
+ "cpu_id not match vcpu_id %x lapic_count %x\n",
+ v->vcpu_id, vioapic->lapic_count);
domain_crash_synchronous();
}
- /* update count later for race condition on interrupt */
- s->lapic_info[s->lapic_count] = vlapic;
- s->lapic_count ++;
-
- return s->lapic_count;
-}
-
-hvm_vioapic_t * hvm_vioapic_init(struct domain *d)
-{
- int i = 0;
- hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic);
-
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_init\n");
-
- hvm_vioapic_reset(s);
-
- s->domain = d;
-
- for (i = 0; i < MAX_LAPIC_NUM; i++)
- s->lapic_info[i] = NULL;
-
- /* Remove after GFW ready */
- ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1);
-
- return s;
-}
+ /* Update count later for race condition on interrupt. */
+ vioapic->lapic_info[vioapic->lapic_count] = vlapic;
+ wmb();
+ vioapic->lapic_count++;
+
+ return vioapic->lapic_count;
+}
+
+void vioapic_init(struct domain *d)
+{
+ struct vioapic *vioapic = domain_vioapic(d);
+
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_init\n");
+
+ vioapic_reset(vioapic);
+
+ vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
+}
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Tue Nov 07 17:46:40 2006 +0000
@@ -432,7 +432,7 @@ void vlapic_EOI_set(struct vlapic *vlapi
vlapic_clear_vector(vector, vlapic->regs + APIC_ISR);
if ( vlapic_test_and_clear_vector(vector, vlapic->regs + APIC_TMR) )
- ioapic_update_EOI(vlapic_domain(vlapic), vector);
+ vioapic_update_EOI(vlapic_domain(vlapic), vector);
}
static void vlapic_ipi(struct vlapic *vlapic)
@@ -1001,7 +1001,7 @@ int vlapic_init(struct vcpu *v)
if ( v->vcpu_id == 0 )
vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
- hvm_vioapic_add_lapic(vlapic, v);
+ vioapic_add_lapic(vlapic, v);
init_timer(&vlapic->vlapic_timer,
vlapic_timer_fn, vlapic, v->processor);
diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/io.c Tue Nov 07 17:46:40 2006 +0000
@@ -99,7 +99,7 @@ asmlinkage void vmx_intr_assist(void)
struct vlapic *vlapic = vcpu_vlapic(v);
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
struct periodic_time *pt = &plat->pl_time.periodic_tm;
- struct hvm_virpic *pic= &plat->vpic;
+ struct vpic *pic= &plat->vpic;
unsigned int idtv_info_field;
unsigned long inst_len;
int has_ext_irq;
diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/include/asm-ia64/vmx_platform.h Tue Nov 07 17:46:40 2006 +0000
@@ -32,7 +32,7 @@ typedef struct virtual_platform_def {
unsigned long params[HVM_NR_PARAMS];
struct mmio_list *mmio;
/* One IOSAPIC now... */
- struct hvm_vioapic vioapic;
+ struct vioapic vioapic;
} vir_plat_t;
static inline int __fls(uint32_t word)
diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/include/asm-x86/hvm/domain.h Tue Nov 07 17:46:40 2006 +0000
@@ -35,8 +35,8 @@ struct hvm_domain {
s64 tsc_frequency;
struct pl_time pl_time;
- struct hvm_virpic vpic;
- struct hvm_vioapic vioapic;
+ struct vpic vpic;
+ struct vioapic vioapic;
struct hvm_io_handler io_handler;
unsigned char round_info[256];
diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/vioapic.h
--- a/xen/include/asm-x86/hvm/vioapic.h Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/include/asm-x86/hvm/vioapic.h Tue Nov 07 17:46:40 2006 +0000
@@ -23,97 +23,90 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __ASM_X86_HVM_IOAPIC_H__
-#define __ASM_X86_HVM_IOAPIC_H__
+#ifndef __ASM_X86_HVM_VIOAPIC_H__
+#define __ASM_X86_HVM_VIOAPIC_H__
#include <xen/config.h>
#include <xen/types.h>
#include <xen/smp.h>
-#ifndef __ia64__
-#define IOAPIC_VERSION_ID 0x11
-#else
-#define IOAPIC_VERSION_ID 0x21
+#ifdef __ia64__
+#define VIOAPIC_IS_IOSAPIC 1
#endif
-#define IOAPIC_NUM_PINS 24
-#define MAX_LAPIC_NUM 32
-
-#define IOAPIC_LEVEL_TRIGGER 1
-
-#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000
-#define IOAPIC_MEM_LENGTH 0x100
-
-#define IOAPIC_ENABLE_MASK 0x0
-#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK)
-#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG)
-
-#define IOAPIC_REG_SELECT 0x0
-#define IOAPIC_REG_WINDOW 0x10
-
-#ifdef __ia64__
-#define IOAPIC_REG_ASSERTION 0x20
-#define IOAPIC_REG_EOI 0x40
+#if !VIOAPIC_IS_IOSAPIC
+#define VIOAPIC_VERSION_ID 0x11 /* IOAPIC version */
+#else
+#define VIOAPIC_VERSION_ID 0x21 /* IOSAPIC version */
#endif
-#ifndef __ia64__
-#define IOAPIC_REG_APIC_ID 0x0
-#define IOAPIC_REG_ARB_ID 0x2
-#endif
+#define VIOAPIC_NUM_PINS 24
-#define IOAPIC_REG_VERSION 0x1
+#define VIOAPIC_EDGE_TRIG 0
+#define VIOAPIC_LEVEL_TRIG 1
-typedef union RedirStatus
+#define VIOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000
+#define VIOAPIC_MEM_LENGTH 0x100
+
+/* Direct registers. */
+#define VIOAPIC_REG_SELECT 0x00
+#define VIOAPIC_REG_WINDOW 0x10
+#define VIOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */
+
+/* Indirect registers. */
+#define VIOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */
+#define VIOAPIC_REG_VERSION 0x01
+#define VIOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */
+
+#define domain_vioapic(d) (&(d)->arch.hvm_domain.vioapic)
+#define vioapic_domain(v) (container_of((v), struct domain, \
+ arch.hvm_domain.vioapic))
+
+union vioapic_redir_entry
{
- uint64_t value;
+ uint64_t bits;
struct {
uint8_t vector;
- uint8_t deliver_mode:3;
- uint8_t destmode:1;
- uint8_t delivestatus:1;
+ uint8_t delivery_mode:3;
+ uint8_t dest_mode:1;
+ uint8_t delivery_status:1;
uint8_t polarity:1;
- uint8_t remoteirr:1;
- uint8_t trigmod:1;
- uint8_t mask:1; /* interrupt mask*/
+ uint8_t remote_irr:1;
+ uint8_t trig_mode:1;
+ uint8_t mask:1;
uint8_t reserve:7;
-#ifndef __ia64__
+#if !VIOAPIC_IS_IOSAPIC
uint8_t reserved[4];
uint8_t dest_id;
#else
uint8_t reserved[3];
uint16_t dest_id;
#endif
- } RedirForm;
-} RedirStatus;
+ } fields;
+};
-typedef struct hvm_vioapic {
+struct vioapic {
uint32_t irr;
uint32_t irr_xen; /* interrupts forced on by the hypervisor. */
- uint32_t isr; /* This is used for level trigger */
+ uint32_t isr; /* This is used for level trigger */
uint32_t imr;
uint32_t ioregsel;
- uint32_t flags;
+ uint32_t id;
+ unsigned long base_address;
+ union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS];
+ struct vlapic *lapic_info[32];
uint32_t lapic_count;
- uint32_t id;
- uint32_t arb_id;
- unsigned long base_address;
- RedirStatus redirtbl[IOAPIC_NUM_PINS];
- struct vlapic *lapic_info[MAX_LAPIC_NUM];
- struct domain *domain;
-} hvm_vioapic_t;
+};
-hvm_vioapic_t *hvm_vioapic_init(struct domain *d);
-
-void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level);
-void hvm_vioapic_set_irq(struct domain *d, int irq, int level);
-
-int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
-
-void ioapic_update_EOI(struct domain *d, int vector);
+void vioapic_init(struct domain *d);
+void vioapic_set_xen_irq(struct domain *d, int irq, int level);
+void vioapic_set_irq(struct domain *d, int irq, int level);
+int vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
+void vioapic_update_EOI(struct domain *d, int vector);
#ifdef HVM_DOMAIN_SAVE_RESTORE
void ioapic_save(QEMUFile* f, void* opaque);
int ioapic_load(QEMUFile* f, void* opaque, int version_id);
#endif
-#endif /* __ASM_X86_HVM_IOAPIC_H__ */
+#endif /* __ASM_X86_HVM_VIOAPIC_H__ */
diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/vpic.h
--- a/xen/include/asm-x86/hvm/vpic.h Tue Nov 07 15:48:10 2006 +0000
+++ b/xen/include/asm-x86/hvm/vpic.h Tue Nov 07 17:46:40 2006 +0000
@@ -5,10 +5,10 @@
* Copyright (c) 2005 Intel Corp
*
* 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
+ * 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
@@ -18,19 +18,17 @@
* 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.
+ * 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.
*/
#ifndef __ASM_X86_HVM_VPIC_H__
#define __ASM_X86_HVM_VPIC_H__
-#define hw_error(x) do {} while (0);
+#define domain_vpic(d) (&(d)->arch.hvm_domain.vpic)
+#define vpic_domain(v) (container_of((v), struct domain, arch.hvm_domain.vpic))
-
-/* i8259.c */
-typedef struct IOAPICState IOAPICState;
typedef struct PicState {
uint8_t last_irr; /* edge detection */
uint8_t irr; /* interrupt request register */
@@ -50,12 +48,11 @@ typedef struct PicState {
uint8_t init4; /* true if 4 byte init */
uint8_t elcr; /* PIIX edge/trigger selection*/
uint8_t elcr_mask;
- struct hvm_virpic *pics_state;
+ struct vpic *pics_state;
} PicState;
-struct hvm_virpic {
+struct vpic {
/* 0 is master pic, 1 is slave pic */
- /* XXX: better separation between the two pics */
PicState pics[2];
void (*irq_request)(void *opaque, int level);
void *irq_request_opaque;
@@ -63,13 +60,12 @@ struct hvm_virpic {
spinlock_t lock;
};
-
void pic_set_xen_irq(void *opaque, int irq, int level);
-void pic_set_irq(struct hvm_virpic *s, int irq, int level);
-void pic_init(struct hvm_virpic *s,
+void pic_set_irq(struct vpic *vpic, int irq, int level);
+void pic_init(struct vpic *vpic,
void (*irq_request)(void *, int),
void *irq_request_opaque);
-void pic_update_irq(struct hvm_virpic *s); /* Caller must hold s->lock */
+void pic_update_irq(struct vpic *vpic); /* Caller must hold vpic->lock */
void register_pic_io_hook(struct domain *d);
int cpu_get_pic_interrupt(struct vcpu *v, int *type);
int is_periodic_irq(struct vcpu *v, int irq, int type);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|