* [PATCH] irq assignment
@ 2008-06-18 6:38 Xu, Anthony
2008-06-25 11:53 ` Avi Kivity
0 siblings, 1 reply; 2+ messages in thread
From: Xu, Anthony @ 2008-06-18 6:38 UTC (permalink / raw)
To: kvm, kvm-ia64
[-- Attachment #1: Type: text/plain, Size: 6644 bytes --]
>From 67806cc642cb666fb59fec60115fee37b80ecb3a Mon Sep 17 00:00:00 2001
From: Anthony Xu <anthony.xu@intel.com>
Date: Wed, 18 Jun 2008 14:32:46 -0400
Subject: [PATCH] Irq assignment
1. use bimodal _PRT
2. pci device can use irq > 15, reduce interrupt sharing
3. test by running linux guest in kvm-ia64, kvm-i32(w/ wo/ -no-kvm)
signed-off-by: Anthony Xu <anthony.xu@intel.com>
---
bios/acpi-dsdt.dsl | 59
+++++++++++++++++++++++++++++++++++++++++++++++++++-
qemu/hw/apic.c | 22 ++++++++++++++++++-
qemu/hw/ipf.c | 24 +++++++++++++++++++++
qemu/hw/pc.c | 2 +-
qemu/hw/pc.h | 4 +++
qemu/hw/pci.c | 8 +++++++
6 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index d1bfa2c..62dd612 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -89,6 +89,12 @@ DefinitionBlock (
}
}
+ Name (PICD, 0)
+
+ Method(_PIC, 1)
+ {
+ Store(Arg0, PICD)
+ }
/* PCI Bus definition */
Scope(\_SB) {
@@ -96,7 +102,15 @@ DefinitionBlock (
Name (_HID, EisaId ("PNP0A03"))
Name (_ADR, 0x00)
Name (_UID, 1)
- Name(_PRT, Package() {
+
+ Method (_PRT,0) {
+ If (PICD) {
+ Return (PRTA)
+ }
+ Return (PRTP)
+ }
+
+ Name (PRTP, Package() {
/* PCI IRQ routing table, example from ACPI 2.0a
specification,
section 6.2.8.1 */
/* Note: we provide the same info as the PCI routing
@@ -147,6 +161,49 @@ DefinitionBlock (
prt_slot3(0x001f),
})
+ Name (PRTA, Package() {
+ /* IOAPIC use fixed connection */
+
+#define aprt_slot(nr, irq) \
+ Package() { nr##ffff, 0, 0, irq }, \
+ Package() { nr##ffff, 1, 0, irq }, \
+ Package() { nr##ffff, 2, 0, irq }, \
+ Package() { nr##ffff, 3, 0, irq }
+
+ aprt_slot(0x0000, 16),
+ aprt_slot(0x0001, 17),
+ aprt_slot(0x0002, 18),
+ aprt_slot(0x0003, 19),
+ aprt_slot(0x0004, 20),
+ aprt_slot(0x0005, 21),
+ aprt_slot(0x0006, 22),
+ aprt_slot(0x0007, 23),
+ aprt_slot(0x0008, 16),
+ aprt_slot(0x0009, 17),
+ aprt_slot(0x000a, 18),
+ aprt_slot(0x000b, 19),
+ aprt_slot(0x000c, 20),
+ aprt_slot(0x000d, 21),
+ aprt_slot(0x000e, 22),
+ aprt_slot(0x000f, 23),
+ aprt_slot(0x0010, 16),
+ aprt_slot(0x0011, 17),
+ aprt_slot(0x0012, 18),
+ aprt_slot(0x0013, 19),
+ aprt_slot(0x0014, 20),
+ aprt_slot(0x0015, 21),
+ aprt_slot(0x0016, 22),
+ aprt_slot(0x0017, 23),
+ aprt_slot(0x0018, 16),
+ aprt_slot(0x0019, 17),
+ aprt_slot(0x001a, 18),
+ aprt_slot(0x001b, 19),
+ aprt_slot(0x001c, 20),
+ aprt_slot(0x001d, 21),
+ aprt_slot(0x001e, 22),
+ aprt_slot(0x001f, 23),
+ })
+
OperationRegion(PCST, SystemIO, 0xae00, 0x08)
Field (PCST, DWordAcc, NoLock, WriteAsZeros)
{
diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c
index 4ebf1ff..98bf3ad 100644
--- a/qemu/hw/apic.c
+++ b/qemu/hw/apic.c
@@ -1053,10 +1053,30 @@ static void ioapic_service(IOAPICState *s)
}
}
+int ioapic_map_irq(int devfn, int irq_num)
+{
+ int irq;
+ irq = ((devfn >> 3) & 7) + 16;
+ return irq;
+}
+
+static int ioapic_irq_count[IOAPIC_NUM_PINS];
+
void ioapic_set_irq(void *opaque, int vector, int level)
{
IOAPICState *s = opaque;
-
+ if( vector >= 16 ){
+ if( level )
+ ioapic_irq_count[vector] += 1;
+ else
+ ioapic_irq_count[vector] -= 1;
+ level = (ioapic_irq_count[vector] != 0);
+ }
+#ifdef KVM_CAP_IRQCHIP
+ if (kvm_enabled())
+ if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0))
+ return;
+#endif
if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
uint32_t mask = 1 << vector;
uint64_t entry = s->ioredtbl[vector];
diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index b11e328..dabd7cc 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -672,3 +672,27 @@ QEMUMachine ipf_machine = {
ipf_init_pci,
VGA_RAM_SIZE + VGA_RAM_SIZE,
};
+
+#define IOAPIC_NUM_PINS 48
+static int ioapic_irq_count[IOAPIC_NUM_PINS];
+
+int ioapic_map_irq(int devfn, int irq_num)
+{
+ int irq, dev;
+ dev = devfn >> 3;
+ irq = ((((dev << 2) + (dev >> 3) + irq_num) & 31) + 16);
+ return irq;
+}
+
+void ioapic_set_irq(void *opaque, int vector, int level)
+{
+ if( level )
+ ioapic_irq_count[vector] += 1;
+ else
+ ioapic_irq_count[vector] -= 1;
+
+ if (kvm_enabled())
+ if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0))
+ return;
+}
+
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 42c2687..bf49689 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -53,8 +53,8 @@
static fdctrl_t *floppy_controller;
static RTCState *rtc_state;
static PITState *pit;
-static IOAPICState *ioapic;
static PCIDevice *i440fx_state;
+IOAPICState *ioapic;
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
{
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index c284bf1..379b386 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -47,6 +47,7 @@ int apic_accept_pic_intr(CPUState *env);
void apic_local_deliver(CPUState *env, int vector);
int apic_get_interrupt(CPUState *env);
IOAPICState *ioapic_init(void);
+int ioapic_map_irq(int devfn, int irq_num);
void ioapic_set_irq(void *opaque, int vector, int level);
/* i8254.c */
@@ -95,6 +96,9 @@ void ioport_set_a20(int enable);
int ioport_get_a20(void);
CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled);
+/* pc.c */
+extern IOAPICState *ioapic;
+
/* acpi.c */
extern int acpi_enabled;
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 92683d1..c1a0361 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -538,12 +538,20 @@ static void pci_set_irq(void *opaque, int irq_num,
int level)
PCIDevice *pci_dev = (PCIDevice *)opaque;
PCIBus *bus;
int change;
+ int irq;
change = level - pci_dev->irq_state[irq_num];
if (!change)
return;
pci_dev->irq_state[irq_num] = level;
+
+ irq = ioapic_map_irq(pci_dev->devfn, irq_num);
+#if defined(TARGET_IA64)
+ ioapic_set_irq(NULL, irq, level);
+#else
+ ioapic_set_irq(ioapic, irq, level);
+#endif
for (;;) {
bus = pci_dev->bus;
irq_num = bus->map_irq(pci_dev, irq_num);
--
1.5.5
[-- Attachment #2: 0002-Irq-assignment.patch --]
[-- Type: application/octet-stream, Size: 6407 bytes --]
From 67806cc642cb666fb59fec60115fee37b80ecb3a Mon Sep 17 00:00:00 2001
From: Anthony Xu <anthony.xu@intel.com>
Date: Wed, 18 Jun 2008 14:32:46 -0400
Subject: [PATCH] Irq assignment
1. use bimodal _PRT
2. pci device can use irq > 15, reduce interrupt sharing
3. test by running linux guest in kvm-ia64, kvm-i32(w/ wo/ -no-kvm)
signed-off-by: Anthony Xu <anthony.xu@intel.com>
---
bios/acpi-dsdt.dsl | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
qemu/hw/apic.c | 22 ++++++++++++++++++-
qemu/hw/ipf.c | 24 +++++++++++++++++++++
qemu/hw/pc.c | 2 +-
qemu/hw/pc.h | 4 +++
qemu/hw/pci.c | 8 +++++++
6 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index d1bfa2c..62dd612 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -89,6 +89,12 @@ DefinitionBlock (
}
}
+ Name (PICD, 0)
+
+ Method(_PIC, 1)
+ {
+ Store(Arg0, PICD)
+ }
/* PCI Bus definition */
Scope(\_SB) {
@@ -96,7 +102,15 @@ DefinitionBlock (
Name (_HID, EisaId ("PNP0A03"))
Name (_ADR, 0x00)
Name (_UID, 1)
- Name(_PRT, Package() {
+
+ Method (_PRT,0) {
+ If (PICD) {
+ Return (PRTA)
+ }
+ Return (PRTP)
+ }
+
+ Name (PRTP, Package() {
/* PCI IRQ routing table, example from ACPI 2.0a specification,
section 6.2.8.1 */
/* Note: we provide the same info as the PCI routing
@@ -147,6 +161,49 @@ DefinitionBlock (
prt_slot3(0x001f),
})
+ Name (PRTA, Package() {
+ /* IOAPIC use fixed connection */
+
+#define aprt_slot(nr, irq) \
+ Package() { nr##ffff, 0, 0, irq }, \
+ Package() { nr##ffff, 1, 0, irq }, \
+ Package() { nr##ffff, 2, 0, irq }, \
+ Package() { nr##ffff, 3, 0, irq }
+
+ aprt_slot(0x0000, 16),
+ aprt_slot(0x0001, 17),
+ aprt_slot(0x0002, 18),
+ aprt_slot(0x0003, 19),
+ aprt_slot(0x0004, 20),
+ aprt_slot(0x0005, 21),
+ aprt_slot(0x0006, 22),
+ aprt_slot(0x0007, 23),
+ aprt_slot(0x0008, 16),
+ aprt_slot(0x0009, 17),
+ aprt_slot(0x000a, 18),
+ aprt_slot(0x000b, 19),
+ aprt_slot(0x000c, 20),
+ aprt_slot(0x000d, 21),
+ aprt_slot(0x000e, 22),
+ aprt_slot(0x000f, 23),
+ aprt_slot(0x0010, 16),
+ aprt_slot(0x0011, 17),
+ aprt_slot(0x0012, 18),
+ aprt_slot(0x0013, 19),
+ aprt_slot(0x0014, 20),
+ aprt_slot(0x0015, 21),
+ aprt_slot(0x0016, 22),
+ aprt_slot(0x0017, 23),
+ aprt_slot(0x0018, 16),
+ aprt_slot(0x0019, 17),
+ aprt_slot(0x001a, 18),
+ aprt_slot(0x001b, 19),
+ aprt_slot(0x001c, 20),
+ aprt_slot(0x001d, 21),
+ aprt_slot(0x001e, 22),
+ aprt_slot(0x001f, 23),
+ })
+
OperationRegion(PCST, SystemIO, 0xae00, 0x08)
Field (PCST, DWordAcc, NoLock, WriteAsZeros)
{
diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c
index 4ebf1ff..98bf3ad 100644
--- a/qemu/hw/apic.c
+++ b/qemu/hw/apic.c
@@ -1053,10 +1053,30 @@ static void ioapic_service(IOAPICState *s)
}
}
+int ioapic_map_irq(int devfn, int irq_num)
+{
+ int irq;
+ irq = ((devfn >> 3) & 7) + 16;
+ return irq;
+}
+
+static int ioapic_irq_count[IOAPIC_NUM_PINS];
+
void ioapic_set_irq(void *opaque, int vector, int level)
{
IOAPICState *s = opaque;
-
+ if( vector >= 16 ){
+ if( level )
+ ioapic_irq_count[vector] += 1;
+ else
+ ioapic_irq_count[vector] -= 1;
+ level = (ioapic_irq_count[vector] != 0);
+ }
+#ifdef KVM_CAP_IRQCHIP
+ if (kvm_enabled())
+ if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0))
+ return;
+#endif
if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
uint32_t mask = 1 << vector;
uint64_t entry = s->ioredtbl[vector];
diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index b11e328..dabd7cc 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -672,3 +672,27 @@ QEMUMachine ipf_machine = {
ipf_init_pci,
VGA_RAM_SIZE + VGA_RAM_SIZE,
};
+
+#define IOAPIC_NUM_PINS 48
+static int ioapic_irq_count[IOAPIC_NUM_PINS];
+
+int ioapic_map_irq(int devfn, int irq_num)
+{
+ int irq, dev;
+ dev = devfn >> 3;
+ irq = ((((dev << 2) + (dev >> 3) + irq_num) & 31) + 16);
+ return irq;
+}
+
+void ioapic_set_irq(void *opaque, int vector, int level)
+{
+ if( level )
+ ioapic_irq_count[vector] += 1;
+ else
+ ioapic_irq_count[vector] -= 1;
+
+ if (kvm_enabled())
+ if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0))
+ return;
+}
+
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 42c2687..bf49689 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -53,8 +53,8 @@
static fdctrl_t *floppy_controller;
static RTCState *rtc_state;
static PITState *pit;
-static IOAPICState *ioapic;
static PCIDevice *i440fx_state;
+IOAPICState *ioapic;
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
{
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index c284bf1..379b386 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -47,6 +47,7 @@ int apic_accept_pic_intr(CPUState *env);
void apic_local_deliver(CPUState *env, int vector);
int apic_get_interrupt(CPUState *env);
IOAPICState *ioapic_init(void);
+int ioapic_map_irq(int devfn, int irq_num);
void ioapic_set_irq(void *opaque, int vector, int level);
/* i8254.c */
@@ -95,6 +96,9 @@ void ioport_set_a20(int enable);
int ioport_get_a20(void);
CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled);
+/* pc.c */
+extern IOAPICState *ioapic;
+
/* acpi.c */
extern int acpi_enabled;
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 92683d1..c1a0361 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -538,12 +538,20 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
PCIDevice *pci_dev = (PCIDevice *)opaque;
PCIBus *bus;
int change;
+ int irq;
change = level - pci_dev->irq_state[irq_num];
if (!change)
return;
pci_dev->irq_state[irq_num] = level;
+
+ irq = ioapic_map_irq(pci_dev->devfn, irq_num);
+#if defined(TARGET_IA64)
+ ioapic_set_irq(NULL, irq, level);
+#else
+ ioapic_set_irq(ioapic, irq, level);
+#endif
for (;;) {
bus = pci_dev->bus;
irq_num = bus->map_irq(pci_dev, irq_num);
--
1.5.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] irq assignment
2008-06-18 6:38 [PATCH] irq assignment Xu, Anthony
@ 2008-06-25 11:53 ` Avi Kivity
0 siblings, 0 replies; 2+ messages in thread
From: Avi Kivity @ 2008-06-25 11:53 UTC (permalink / raw)
To: Xu, Anthony; +Cc: kvm, kvm-ia64, qemu-devel
(copying qemu-devel)
Xu, Anthony wrote:
> Subject: [PATCH] Irq assignment
>
> 1. use bimodal _PRT
> 2. pci device can use irq > 15, reduce interrupt sharing
> 3. test by running linux guest in kvm-ia64, kvm-i32(w/ wo/ -no-kvm)
>
>
> +
> +static int ioapic_irq_count[IOAPIC_NUM_PINS];
> +
> void ioapic_set_irq(void *opaque, int vector, int level)
> {
> IOAPICState *s = opaque;
> -
> + if( vector >= 16 ){
> + if( level )
> + ioapic_irq_count[vector] += 1;
> + else
> + ioapic_irq_count[vector] -= 1;
> + level = (ioapic_irq_count[vector] != 0);
> + }
> +#ifdef KVM_CAP_IRQCHIP
> + if (kvm_enabled())
> + if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0))
> + return;
> +#endif
>
It's legal to call ioapic_set_irq(vector, 1) twice, which will screw up
the level calculation.
We need qemu_irq_or(), similar to qemu_irq_invert():
qemu_irq qemu_irq_or(qemu_irq irqs[], int nr);
Also, this is not the place for doing the or. The ioapic does not know
which interrupts are level connected and which are not. This belongs on
the pci level (or the mainboard level).
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-06-25 11:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-18 6:38 [PATCH] irq assignment Xu, Anthony
2008-06-25 11:53 ` Avi Kivity
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox