malta: Fix regression (i8259 interrupts did not work)
Commit 5632ae46d5
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>
This commit is contained in:
parent
a2e4d53ec5
commit
e9b40fd34c
@ -47,6 +47,7 @@
|
|||||||
#include "mc146818rtc.h"
|
#include "mc146818rtc.h"
|
||||||
#include "blockdev.h"
|
#include "blockdev.h"
|
||||||
#include "exec-memory.h"
|
#include "exec-memory.h"
|
||||||
|
#include "sysbus.h" /* SysBusDevice */
|
||||||
|
|
||||||
//#define DEBUG_BOARD_INIT
|
//#define DEBUG_BOARD_INIT
|
||||||
|
|
||||||
@ -72,6 +73,11 @@ typedef struct {
|
|||||||
SerialState *uart;
|
SerialState *uart;
|
||||||
} MaltaFPGAState;
|
} MaltaFPGAState;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SysBusDevice busdev;
|
||||||
|
qemu_irq *i8259;
|
||||||
|
} MaltaState;
|
||||||
|
|
||||||
static ISADevice *pit;
|
static ISADevice *pit;
|
||||||
|
|
||||||
static struct _loaderparams {
|
static struct _loaderparams {
|
||||||
@ -776,7 +782,7 @@ void mips_malta_init (ram_addr_t ram_size,
|
|||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
ISABus *isa_bus;
|
ISABus *isa_bus;
|
||||||
CPUState *env;
|
CPUState *env;
|
||||||
qemu_irq *i8259 = NULL, *isa_irq;
|
qemu_irq *isa_irq;
|
||||||
qemu_irq *cpu_exit_irq;
|
qemu_irq *cpu_exit_irq;
|
||||||
int piix4_devfn;
|
int piix4_devfn;
|
||||||
i2c_bus *smbus;
|
i2c_bus *smbus;
|
||||||
@ -788,6 +794,11 @@ void mips_malta_init (ram_addr_t ram_size,
|
|||||||
int fl_sectors = 0;
|
int fl_sectors = 0;
|
||||||
int be;
|
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. */
|
/* Make sure the first 3 serial ports are associated with a device. */
|
||||||
for(i = 0; i < 3; i++) {
|
for(i = 0; i < 3; i++) {
|
||||||
if (!serial_hds[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
|
* qemu_irq_proxy() adds an extra bit of indirection, allowing us
|
||||||
* to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
|
* 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 */
|
/* Northbridge */
|
||||||
pci_bus = gt64120_register(isa_irq);
|
pci_bus = gt64120_register(isa_irq);
|
||||||
@ -949,9 +960,9 @@ void mips_malta_init (ram_addr_t ram_size,
|
|||||||
|
|
||||||
/* Interrupt controller */
|
/* Interrupt controller */
|
||||||
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
|
/* 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);
|
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
|
||||||
usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
|
usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
|
||||||
smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
|
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 = {
|
static QEMUMachine mips_malta_machine = {
|
||||||
.name = "malta",
|
.name = "malta",
|
||||||
.desc = "MIPS Malta Core LV",
|
.desc = "MIPS Malta Core LV",
|
||||||
@ -1003,9 +1028,15 @@ static QEMUMachine mips_malta_machine = {
|
|||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void mips_malta_device_init(void)
|
||||||
|
{
|
||||||
|
sysbus_register_withprop(&mips_malta_device);
|
||||||
|
}
|
||||||
|
|
||||||
static void mips_malta_machine_init(void)
|
static void mips_malta_machine_init(void)
|
||||||
{
|
{
|
||||||
qemu_register_machine(&mips_malta_machine);
|
qemu_register_machine(&mips_malta_machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_init(mips_malta_device_init);
|
||||||
machine_init(mips_malta_machine_init);
|
machine_init(mips_malta_machine_init);
|
||||||
|
Loading…
Reference in New Issue
Block a user