diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-03-09 09:13:39 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-03-09 09:13:39 +0000 |
commit | f14ad81eed531adc9b3ae2af76cd52cfad5c9ae5 (patch) | |
tree | 9efb85611f0055761be0ee8f791996cb409a87ce /hw/isa/piix4.c | |
parent | 9f0369efb0f2a200f18b1aacd2ef493e22da5351 (diff) | |
parent | bc401b97eb55d28b6002de48ff9f877abecb0dcd (diff) |
Merge remote-tracking branch 'remotes/philmd/tags/mips-20220308' into staging
MIPS patches queue
- Fix CP0 cycle counter timing
- Fix VMState of gt64120 IRQs
- Long due PIIX4 QOM cleanups
- ISA IRQ QOM'ification / cleanups
# gpg: Signature made Tue 08 Mar 2022 18:39:42 GMT
# gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE
* remotes/philmd/tags/mips-20220308:
tests/avocado/linux_ssh_mips_malta.py: add missing accel (tcg) tag
hw/isa: Inline and remove one-line isa_init_irq()
hw/isa: Drop unused attributes from ISADevice
hw/isa/isa-bus: Remove isabus_dev_print()
hw/input/pckbd: QOM'ify IRQ numbers
hw/rtc/m48t59-isa: QOM'ify IRQ number
hw/rtc/mc146818rtc: QOM'ify IRQ number
hw/mips/gt64xxx_pci: Resolve gt64120_register()
hw/isa/piix4: Replace some magic IRQ constants
hw/isa/piix4: Resolve global instance variable
hw/isa/piix4: Pass PIIX4State as opaque parameter for piix4_set_irq()
hw/isa/piix4: Resolve redundant i8259[] attribute
malta: Move PCI interrupt handling from gt64xxx_pci to piix4
hw/mips/gt64xxx_pci: Fix PCI IRQ levels to be preserved during migration
target/mips: Remove duplicated MIPSCPU::cp0_count_rate
target/mips: Fix cycle counter timing calculations
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/isa/piix4.c')
-rw-r--r-- | hw/isa/piix4.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 0fe7b69bc4..8607e0ac36 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -39,8 +39,6 @@ #include "sysemu/runstate.h" #include "qom/object.h" -PCIDevice *piix4_dev; - struct PIIX4State { PCIDevice dev; qemu_irq cpu_intr; @@ -54,6 +52,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; + PIIX4State *s = opaque; + PCIBus *bus = pci_get_bus(&s->dev); + + /* now we change the pic irq level according to the piix irq mappings */ + /* XXX: optimize */ + pic_irq = s->dev.config[PIIX_PIRQCA + irq_num]; + if (pic_irq < ISA_NUM_IRQS) { + /* The pic level is the logical OR of all the PCI irqs mapped to it. */ + pic_level = 0; + for (i = 0; i < PIIX_NUM_PIRQS; i++) { + if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) { + pic_level |= pci_bus_get_irq_level(bus, i); + } + } + qemu_set_irq(s->isa[pic_irq], pic_level); + } +} + static void piix4_isa_reset(DeviceState *dev) { PIIX4State *d = PIIX4_PCI_DEVICE(dev); @@ -197,9 +216,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp) if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) { return; } - isa_init_irq(ISA_DEVICE(&s->rtc), &s->rtc.irq, RTC_ISA_IRQ); - - piix4_dev = dev; + s->rtc.irq = isa_get_irq(ISA_DEVICE(&s->rtc), s->rtc.isairq); } static void piix4_init(Object *obj) @@ -248,8 +265,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 +300,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 +315,7 @@ 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, PIIX_NUM_PIRQS); + return dev; } |