---
hw/isa/piix4.c | 58 +++++++++++++++++++++++++++++++++++++++
hw/mips/gt64xxx_pci.c | 62 ++++--------------------------------------
hw/mips/malta.c | 6 +---
include/hw/mips/mips.h | 2 +-
4 files changed, 65 insertions(+), 63 deletions(-)
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 0fe7b69bc4..5a86308689 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,30 @@ struct PIIX4State {
OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
+static int pci_irq_levels[4];
+
+static void piix4_set_irq(void *opaque, int irq_num, int level)
+{
+ int i, pic_irq, pic_level;
+ qemu_irq *pic = opaque;
+
+ pci_irq_levels[irq_num] = level;
+
+ /* 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_irq_levels[i];
+ }
+ }
+ qemu_set_irq(pic[pic_irq], pic_level);
+ }
+}
+
static void piix4_isa_reset(DeviceState *dev)
{
PIIX4State *d = PIIX4_PCI_DEVICE(dev);
@@ -248,8 +273,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 +308,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 +323,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++) {