aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Beschow <shentey@gmail.com>2022-02-17 11:19:19 +0100
committerPhilippe Mathieu-Daudé <f4bug@amsat.org>2022-03-08 19:17:04 +0100
commita7fc9880514fcbc96c9825f040296fa59d7b3ccc (patch)
tree8e89e1720a9b8a04398edc7563da811ea5dc5fa2
parentc291635867a03c9217bd9610fe2a16d997932ec0 (diff)
downloadqemu-a7fc9880514fcbc96c9825f040296fa59d7b3ccc.zip
qemu-a7fc9880514fcbc96c9825f040296fa59d7b3ccc.tar.gz
qemu-a7fc9880514fcbc96c9825f040296fa59d7b3ccc.tar.bz2
malta: Move PCI interrupt handling from gt64xxx_pci to piix4
Handling PCI interrupts in piix4 increases cohesion and reduces differences between piix4 and piix3. Signed-off-by: Bernhard Beschow <shentey@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20220217101924.15347-3-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
-rw-r--r--hw/isa/piix4.c55
-rw-r--r--hw/mips/gt64xxx_pci.c60
-rw-r--r--hw/mips/malta.c6
-rw-r--r--include/hw/mips/mips.h2
4 files changed, 62 insertions, 61 deletions
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 0fe7b69..196b56e 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -45,6 +45,7 @@ struct PIIX4State {
PCIDevice dev;
qemu_irq cpu_intr;
qemu_irq *isa;
+ qemu_irq i8259[ISA_NUM_IRQS];
RTCState rtc;
/* Reset Control Register */
@@ -54,6 +55,27 @@ struct PIIX4State {
OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
+static void piix4_set_irq(void *opaque, int irq_num, int level)
+{
+ int i, pic_irq, pic_level;
+ qemu_irq *pic = opaque;
+ PCIBus *bus = pci_get_bus(piix4_dev);
+
+ /* now we change the pic irq level according to the piix irq mappings */
+ /* XXX: optimize */
+ pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
+ if (pic_irq < 16) {
+ /* The pic level is the logical OR of all the PCI irqs mapped to it. */
+ pic_level = 0;
+ for (i = 0; i < 4; i++) {
+ if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
+ pic_level |= pci_bus_get_irq_level(bus, i);
+ }
+ }
+ qemu_set_irq(pic[pic_irq], pic_level);
+ }
+}
+
static void piix4_isa_reset(DeviceState *dev)
{
PIIX4State *d = PIIX4_PCI_DEVICE(dev);
@@ -248,8 +270,34 @@ static void piix4_register_types(void)
type_init(piix4_register_types)
+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;
+ }
+}
+
DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
{
+ PIIX4State *s;
PCIDevice *pci;
DeviceState *dev;
int devfn = PCI_DEVFN(10, 0);
@@ -257,6 +305,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
pci = pci_create_simple_multifunction(pci_bus, devfn, true,
TYPE_PIIX4_PCI_DEVICE);
dev = DEVICE(pci);
+ s = PIIX4_PCI_DEVICE(pci);
if (isa_bus) {
*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
}
@@ -271,5 +320,11 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
NULL, 0, NULL);
}
+ pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s->i8259, 4);
+
+ for (int i = 0; i < ISA_NUM_IRQS; i++) {
+ s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
+ }
+
return dev;
}
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 4cbd091..eb205d6 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -29,7 +29,6 @@
#include "hw/mips/mips.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
-#include "hw/southbridge/piix.h"
#include "migration/vmstate.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
@@ -981,53 +980,6 @@ static const MemoryRegionOps isd_mem_ops = {
},
};
-static int gt64120_pci_map_irq(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 gt64120_pci_set_irq(void *opaque, int irq_num, int level)
-{
- int i, pic_irq, pic_level;
- qemu_irq *pic = opaque;
- PCIBus *bus = pci_get_bus(piix4_dev);
-
- /* now we change the pic irq level according to the piix irq mappings */
- /* XXX: optimize */
- pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
- if (pic_irq < 16) {
- /* The pic level is the logical OR of all the PCI irqs mapped to it. */
- pic_level = 0;
- for (i = 0; i < 4; i++) {
- if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
- pic_level |= pci_bus_get_irq_level(bus, i);
- }
- }
- qemu_set_irq(pic[pic_irq], pic_level);
- }
-}
-
-
static void gt64120_reset(DeviceState *dev)
{
GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
@@ -1204,7 +1156,7 @@ static void gt64120_realize(DeviceState *dev, Error **errp)
"gt64120-isd", 0x1000);
}
-PCIBus *gt64120_register(qemu_irq *pic)
+PCIBus *gt64120_register(void)
{
GT64120State *d;
PCIHostState *phb;
@@ -1215,12 +1167,10 @@ PCIBus *gt64120_register(qemu_irq *pic)
phb = PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", 4 * GiB);
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
- phb->bus = pci_register_root_bus(dev, "pci",
- gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic,
- &d->pci0_mem,
- get_system_io(),
- PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
+ phb->bus = pci_root_bus_new(dev, "pci",
+ &d->pci0_mem,
+ get_system_io(),
+ PCI_DEVFN(18, 0), TYPE_PCI_BUS);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index b770b8d..13254db 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -97,7 +97,6 @@ struct MaltaState {
Clock *cpuclk;
MIPSCPSState cps;
- qemu_irq i8259[ISA_NUM_IRQS];
};
static struct _loaderparams {
@@ -1391,7 +1390,7 @@ void mips_malta_init(MachineState *machine)
stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
/* Northbridge */
- pci_bus = gt64120_register(s->i8259);
+ pci_bus = gt64120_register();
/*
* The whole address space decoded by the GT-64120A doesn't generate
* exception when accessing invalid memory. Create an empty slot to
@@ -1404,9 +1403,6 @@ void mips_malta_init(MachineState *machine)
/* Interrupt controller */
qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
- for (int i = 0; i < ISA_NUM_IRQS; i++) {
- s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
- }
/* generate SPD EEPROM data */
generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 6c9c880..ff88942 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -10,7 +10,7 @@
#include "exec/memory.h"
/* gt64xxx.c */
-PCIBus *gt64120_register(qemu_irq *pic);
+PCIBus *gt64120_register(void);
/* bonito.c */
PCIBus *bonito_init(qemu_irq *pic);