* [RFC PATCH 0/3] Decouple INTx-to-LNKx routing from south bridges
@ 2022-11-16 18:54 Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 1/3] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific Bernhard Beschow
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Bernhard Beschow @ 2022-11-16 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: Eduardo Habkost, Paolo Bonzini, Huacai Chen, Marcel Apfelbaum,
Richard Henderson, Jiaxun Yang, Michael S. Tsirkin,
Hervé Poussineau, Philippe Mathieu-Daudé,
Aurelien Jarno, Bernhard Beschow
During my PIIX consolidation work [1] I've noticed that both PIIX models have
quite different pci_slot_get_pirq() implementations. These functions seem to
map PCI INTx pins to input pins of a programmable interrupt router which is
AFAIU board-specific. IOW, board-specific assumptions are baked into the device
models which prevent e.g. the whole PIIX4 south bridge to be reusable in the PC
machine.
In this series, I've moved the pci_slot_get_pirq() implementations into their
respective boards. This required a hack, however, thus this RFC. The issue is
that pci_slot_get_pirq() can only be assigned using pci_bus_irqs() which also
wants a pci_set_irq_fn. That function is in turn device-specific.
Futhermore, the issue does not only affect PIIX but also the VIA south bridges
as demonstrated in the last patch. Any advice for an upstreamable solution would
be highly appreciated.
Testing done:
* `make check`
* `make check-avocado`
* `qemu-system-ppc -machine pegasos2 -rtc base=localtime -device ati-vga,guest_hwcursor=true,romfile="" -cdrom morphos-3.17.iso -kernel morphos-3.17/boot.img -serial stdio`
* `qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=ttyS0"`
* `qemu-system-x86_64 -M pc -m 2G -cdrom manjaro-kde-21.3.2-220704-linux515.iso`
Thanks,
Bernhard
[1] https://lists.nongnu.org/archive/html/qemu-devel/2022-10/msg03941.html
Bernhard Beschow (3):
hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific
hw/isa/piix4: Decouple INTx-to-LNKx routing which is board-specific
hw/isa/vt82c686: Implement PIRQ routing
hw/i386/pc_piix.c | 17 +++++++++++++++++
hw/isa/piix3.c | 16 +++-------------
hw/isa/piix4.c | 28 ++--------------------------
hw/isa/vt82c686.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
hw/mips/malta.c | 29 +++++++++++++++++++++++++++++
5 files changed, 97 insertions(+), 39 deletions(-)
--
2.38.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [RFC PATCH 1/3] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific
2022-11-16 18:54 [RFC PATCH 0/3] Decouple INTx-to-LNKx routing from south bridges Bernhard Beschow
@ 2022-11-16 18:54 ` Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 2/3] hw/isa/piix4: " Bernhard Beschow
2022-11-16 18:55 ` [RFC PATCH 3/3] hw/isa/vt82c686: Implement PIRQ routing Bernhard Beschow
2 siblings, 0 replies; 4+ messages in thread
From: Bernhard Beschow @ 2022-11-16 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: Eduardo Habkost, Paolo Bonzini, Huacai Chen, Marcel Apfelbaum,
Richard Henderson, Jiaxun Yang, Michael S. Tsirkin,
Hervé Poussineau, Philippe Mathieu-Daudé,
Aurelien Jarno, Bernhard Beschow
pci_map_irq_fn's in general seem to be board-specific. So move PIIX3's
pci_slot_get_pirq() to board code to not have PIIX3 make assuptions
about its board.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
hw/i386/pc_piix.c | 17 +++++++++++++++++
hw/isa/piix3.c | 16 +++-------------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0ad0ed1603..07aa38081a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -47,6 +47,7 @@
#include "hw/sysbus.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/xen/xen-x86.h"
+#include "hw/xen/xen.h"
#include "exec/memory.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/piix4.h"
@@ -73,6 +74,17 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
#endif
+/*
+ * Return the global irq number corresponding to a given device irq
+ * pin. We could also use the bus number to have a more precise mapping.
+ */
+static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
+{
+ int slot_addend;
+ slot_addend = PCI_SLOT(pci_dev->devfn) - 1;
+ return (pci_intx + slot_addend) & 3;
+}
+
/* PC hardware initialisation */
static void pc_init1(MachineState *machine,
const char *host_type, const char *pci_type)
@@ -223,6 +235,11 @@ static void pc_init1(MachineState *machine,
piix3->pic = x86ms->gsi;
piix3_devfn = piix3->dev.devfn;
isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
+
+ pci_bus_irqs(pci_bus, pci_bus->set_irq,
+ xen_enabled() ? xen_pci_slot_get_pirq
+ : pci_slot_get_pirq,
+ pci_dev, pci_bus->nirq);
} else {
pci_bus = NULL;
isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index f9b4af5c05..83a6e3be72 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -29,6 +29,7 @@
#include "hw/southbridge/piix.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
+#include "hw/pci/pci_bus.h"
#include "hw/xen/xen.h"
#include "sysemu/runstate.h"
#include "migration/vmstate.h"
@@ -79,17 +80,6 @@ static void piix3_set_irq(void *opaque, int pirq, int level)
piix3_set_irq_level(piix3, pirq, level);
}
-/*
- * Return the global irq number corresponding to a given device irq
- * pin. We could also use the bus number to have a more precise mapping.
- */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
-{
- int slot_addend;
- slot_addend = PCI_SLOT(pci_dev->devfn) - 1;
- return (pci_intx + slot_addend) & 3;
-}
-
static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
{
PIIX3State *piix3 = opaque;
@@ -388,7 +378,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
return;
}
- pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
+ pci_bus_irqs(pci_bus, piix3_set_irq, pci_bus->map_irq,
piix3, PIIX_NUM_PIRQS);
pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
}
@@ -424,7 +414,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
* connected to the IOAPIC directly.
* These additional routes can be discovered through ACPI.
*/
- pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+ pci_bus_irqs(pci_bus, xen_piix3_set_irq, pci_bus->map_irq,
piix3, XEN_PIIX_NUM_PIRQS);
}
--
2.38.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC PATCH 2/3] hw/isa/piix4: Decouple INTx-to-LNKx routing which is board-specific
2022-11-16 18:54 [RFC PATCH 0/3] Decouple INTx-to-LNKx routing from south bridges Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 1/3] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific Bernhard Beschow
@ 2022-11-16 18:54 ` Bernhard Beschow
2022-11-16 18:55 ` [RFC PATCH 3/3] hw/isa/vt82c686: Implement PIRQ routing Bernhard Beschow
2 siblings, 0 replies; 4+ messages in thread
From: Bernhard Beschow @ 2022-11-16 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: Eduardo Habkost, Paolo Bonzini, Huacai Chen, Marcel Apfelbaum,
Richard Henderson, Jiaxun Yang, Michael S. Tsirkin,
Hervé Poussineau, Philippe Mathieu-Daudé,
Aurelien Jarno, Bernhard Beschow
pci_map_irq_fn's in general seem to be board-specific, and PIIX4's
pci_slot_get_pirq() in particular seems very Malta-specific. So move the
latter to malta.c to 1/ keep the board logic in one place and 2/ avoid
PIIX4 to make assumptions about its board.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
hw/isa/piix4.c | 28 ++--------------------------
hw/mips/malta.c | 29 +++++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 8fc1db6dc9..709dd901c2 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -28,6 +28,7 @@
#include "hw/irq.h"
#include "hw/southbridge/piix.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/ide/piix.h"
#include "hw/isa/isa.h"
#include "hw/intc/i8259.h"
@@ -79,31 +80,6 @@ static void piix4_set_irq(void *opaque, int irq_num, int level)
}
}
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-{
- int slot;
-
- slot = PCI_SLOT(pci_dev->devfn);
-
- switch (slot) {
- /* PIIX4 USB */
- case 10:
- return 3;
- /* AMD 79C973 Ethernet */
- case 11:
- return 1;
- /* Crystal 4281 Sound */
- case 12:
- return 2;
- /* PCI slot 1 to 4 */
- case 18 ... 21:
- return ((slot - 18) + irq_num) & 0x03;
- /* Unknown device, don't do any translation */
- default:
- return irq_num;
- }
-}
-
static void piix4_isa_reset(DeviceState *dev)
{
PIIX4State *d = PIIX4_PCI_DEVICE(dev);
@@ -271,7 +247,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
}
qdev_connect_gpio_out(DEVICE(&s->pm), 0, s->isa[9]);
- pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
+ pci_bus_irqs(pci_bus, piix4_set_irq, pci_bus->map_irq, s, PIIX_NUM_PIRQS);
}
static void piix4_init(Object *obj)
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index c0a2e0ab04..8a6b66e759 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -39,6 +39,7 @@
#include "hw/mips/bootloader.h"
#include "hw/mips/cpudevs.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "qemu/log.h"
#include "hw/mips/bios.h"
#include "hw/ide/pci.h"
@@ -1140,6 +1141,31 @@ static void malta_mips_config(MIPSCPU *cpu)
}
}
+static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+ int slot;
+
+ slot = PCI_SLOT(pci_dev->devfn);
+
+ switch (slot) {
+ /* PIIX4 USB */
+ case 10:
+ return 3;
+ /* AMD 79C973 Ethernet */
+ case 11:
+ return 1;
+ /* Crystal 4281 Sound */
+ case 12:
+ return 2;
+ /* PCI slot 1 to 4 */
+ case 18 ... 21:
+ return ((slot - 18) + irq_num) & 0x03;
+ /* Unknown device, don't do any translation */
+ default:
+ return irq_num;
+ }
+}
+
static void main_cpu_reset(void *opaque)
{
MIPSCPU *cpu = opaque;
@@ -1411,6 +1437,9 @@ void mips_malta_init(MachineState *machine)
/* Interrupt controller */
qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
+ pci_bus_irqs(pci_bus, pci_bus->set_irq, pci_slot_get_pirq,
+ piix4, pci_bus->nirq);
+
/* generate SPD EEPROM data */
dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
--
2.38.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC PATCH 3/3] hw/isa/vt82c686: Implement PIRQ routing
2022-11-16 18:54 [RFC PATCH 0/3] Decouple INTx-to-LNKx routing from south bridges Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 1/3] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 2/3] hw/isa/piix4: " Bernhard Beschow
@ 2022-11-16 18:55 ` Bernhard Beschow
2 siblings, 0 replies; 4+ messages in thread
From: Bernhard Beschow @ 2022-11-16 18:55 UTC (permalink / raw)
To: qemu-devel
Cc: Eduardo Habkost, Paolo Bonzini, Huacai Chen, Marcel Apfelbaum,
Richard Henderson, Jiaxun Yang, Michael S. Tsirkin,
Hervé Poussineau, Philippe Mathieu-Daudé,
Aurelien Jarno, Bernhard Beschow
Both VIA south bridges allow system software to configure the routing of
PCI interrupts to ISA interrupts. Implement this to model the real
hardware more closely.
The implementation is based on hw/isa/piix4.c.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
hw/isa/vt82c686.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 3f9bd0c04d..21157c669b 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -16,6 +16,7 @@
#include "qemu/osdep.h"
#include "hw/isa/vt82c686.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/qdev-properties.h"
#include "hw/ide/pci.h"
#include "hw/isa/isa.h"
@@ -604,6 +605,48 @@ static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
qemu_set_irq(s->cpu_intr, level);
}
+static int via_isa_get_pic_irq(const ViaISAState *s, int irq_num)
+{
+ switch (irq_num) {
+ case 0:
+ return s->dev.config[0x55] >> 4;
+
+ case 1:
+ return s->dev.config[0x56] & 0xf;
+
+ case 2:
+ return s->dev.config[0x56] >> 4;
+
+ case 3:
+ return s->dev.config[0x57] >> 4;
+ }
+
+ return 0;
+}
+
+static void via_isa_set_pic_irq(void *opaque, int irq_num, int level)
+{
+ ViaISAState *s = opaque;
+ PCIBus *bus = pci_get_bus(&s->dev);
+ int pic_irq;
+
+ /* now we change the pic irq level according to the via irq mappings */
+ /* XXX: optimize */
+ pic_irq = via_isa_get_pic_irq(s, irq_num);
+ if (pic_irq < ISA_NUM_IRQS) {
+ int i, pic_level;
+
+ /* The pic level is the logical OR of all the PCI irqs mapped to it. */
+ pic_level = 0;
+ for (i = 0; i < PCI_NUM_PINS; i++) {
+ if (pic_irq == via_isa_get_pic_irq(s, i)) {
+ pic_level |= pci_bus_get_irq_level(bus, i);
+ }
+ }
+ qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+ }
+}
+
static void via_isa_realize(PCIDevice *d, Error **errp)
{
ViaISAState *s = VIA_ISA(d);
@@ -676,6 +719,9 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
if (!qdev_realize(DEVICE(&s->mc97), BUS(pci_bus), errp)) {
return;
}
+
+ pci_bus_irqs(pci_bus, via_isa_set_pic_irq, pci_bus->map_irq,
+ s, ISA_NUM_IRQS);
}
/* TYPE_VT82C686B_ISA */
--
2.38.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-11-16 18:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-16 18:54 [RFC PATCH 0/3] Decouple INTx-to-LNKx routing from south bridges Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 1/3] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific Bernhard Beschow
2022-11-16 18:54 ` [RFC PATCH 2/3] hw/isa/piix4: " Bernhard Beschow
2022-11-16 18:55 ` [RFC PATCH 3/3] hw/isa/vt82c686: Implement PIRQ routing Bernhard Beschow
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).