diff options
author | Stefan Weil <sw@weilnetz.de> | 2011-11-29 06:34:48 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2012-01-07 18:16:24 +0100 |
commit | e9b40fd34ceb23461083d505a444a389c094455b (patch) | |
tree | 99916c8b2d39fbc89228ff27d3ebad3cb292699b | |
parent | a2e4d53ec5cc1983a615d87b251726f17358be9a (diff) |
malta: Fix regression (i8259 interrupts did not work)
Commit 5632ae46d5bda798e971dae48ebb318ac2c3686a passes the address
of i8259 to qemu_irq_proxy. i8259 is an auto variable with undefined
value outside of mips_malta_init.
This made the interrupt proxy unusable: either QEMU crashes, or
the interrupt handler was not called.
Ethernet for example no longer worked with MIPS Malta.
v2:
While v1 used a static variable for i8259, this patch introduces
a qdev for the malta machine. i8259 is now part of the device status.
This is a minimal qdev implementation to keep the patch small.
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r-- | hw/mips_malta.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 6b72cf2508..e625ec398f 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -47,6 +47,7 @@ #include "mc146818rtc.h" #include "blockdev.h" #include "exec-memory.h" +#include "sysbus.h" /* SysBusDevice */ //#define DEBUG_BOARD_INIT @@ -72,6 +73,11 @@ typedef struct { SerialState *uart; } MaltaFPGAState; +typedef struct { + SysBusDevice busdev; + qemu_irq *i8259; +} MaltaState; + static ISADevice *pit; static struct _loaderparams { @@ -776,7 +782,7 @@ void mips_malta_init (ram_addr_t ram_size, PCIBus *pci_bus; ISABus *isa_bus; CPUState *env; - qemu_irq *i8259 = NULL, *isa_irq; + qemu_irq *isa_irq; qemu_irq *cpu_exit_irq; int piix4_devfn; i2c_bus *smbus; @@ -788,6 +794,11 @@ void mips_malta_init (ram_addr_t ram_size, int fl_sectors = 0; int be; + DeviceState *dev = qdev_create(NULL, "mips-malta"); + MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev); + + qdev_init_nofail(dev); + /* Make sure the first 3 serial ports are associated with a device. */ for(i = 0; i < 3; i++) { if (!serial_hds[i]) { @@ -937,7 +948,7 @@ void mips_malta_init (ram_addr_t ram_size, * qemu_irq_proxy() adds an extra bit of indirection, allowing us * to resolve the isa_irq -> i8259 dependency after i8259 is initialized. */ - isa_irq = qemu_irq_proxy(&i8259, 16); + isa_irq = qemu_irq_proxy(&s->i8259, 16); /* Northbridge */ pci_bus = gt64120_register(isa_irq); @@ -949,9 +960,9 @@ void mips_malta_init (ram_addr_t ram_size, /* Interrupt controller */ /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ - i8259 = i8259_init(isa_bus, env->irq[2]); + s->i8259 = i8259_init(isa_bus, env->irq[2]); - isa_bus_irqs(isa_bus, i8259); + isa_bus_irqs(isa_bus, s->i8259); pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, @@ -995,6 +1006,20 @@ void mips_malta_init (ram_addr_t ram_size, } } +static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev) +{ + return 0; +} + +static SysBusDeviceInfo mips_malta_device = { + .init = mips_malta_sysbus_device_init, + .qdev.name = "mips-malta", + .qdev.size = sizeof(MaltaState), + .qdev.props = (Property[]) { + DEFINE_PROP_END_OF_LIST(), + } +}; + static QEMUMachine mips_malta_machine = { .name = "malta", .desc = "MIPS Malta Core LV", @@ -1003,9 +1028,15 @@ static QEMUMachine mips_malta_machine = { .is_default = 1, }; +static void mips_malta_device_init(void) +{ + sysbus_register_withprop(&mips_malta_device); +} + static void mips_malta_machine_init(void) { qemu_register_machine(&mips_malta_machine); } +device_init(mips_malta_device_init); machine_init(mips_malta_machine_init); |