aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-06 23:51:08 +0000
committerLaurent Vivier <laurent@vivier.eu>2020-12-12 18:05:30 +0100
commit9526486164818f1c59a142dec8a1f09fbf77669c (patch)
tree7785400e4e3ba3fdfa1bed3e149ea6e8eefb82c9
parentad717e6da3852b5729217d7938eecdb81c546114 (diff)
downloadqemu-9526486164818f1c59a142dec8a1f09fbf77669c.zip
qemu-9526486164818f1c59a142dec8a1f09fbf77669c.tar.gz
qemu-9526486164818f1c59a142dec8a1f09fbf77669c.tar.bz2
hw/m68k/q800: Don't connect two qemu_irqs directly to the same input
The q800 board code connects both of the IRQ outputs of the ESCC to the same pic[3] qemu_irq. Connecting two qemu_irqs outputs directly to the same input is not valid as it produces subtly wrong behaviour (for instance if both the IRQ lines are high, and then one goes low, the PIC input will see this as a high-to-low transition even though the second IRQ line should still be holding it high). This kind of wiring needs an explicitly created OR gate; add one. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20201106235109.7066-2-peter.maydell@linaro.org> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
-rw-r--r--hw/m68k/Kconfig1
-rw-r--r--hw/m68k/q800.c12
2 files changed, 11 insertions, 2 deletions
diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index c757e7d..60d7bcf 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -22,3 +22,4 @@ config Q800
select ESCC
select ESP
select DP8393X
+ select OR_IRQ
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 4db2b9b..f9a2be7 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -29,6 +29,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/irq.h"
+#include "hw/or-irq.h"
#include "elf.h"
#include "hw/loader.h"
#include "ui/console.h"
@@ -173,6 +174,7 @@ static void q800_init(MachineState *machine)
CPUState *cs;
DeviceState *dev;
DeviceState *via_dev;
+ DeviceState *escc_orgate;
SysBusESPState *sysbus_esp;
ESPState *esp;
SysBusDevice *sysbus;
@@ -285,8 +287,14 @@ static void q800_init(MachineState *machine)
qdev_prop_set_uint32(dev, "chnAtype", 0);
sysbus = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
- sysbus_connect_irq(sysbus, 0, pic[3]);
- sysbus_connect_irq(sysbus, 1, pic[3]);
+
+ /* Logically OR both its IRQs together */
+ escc_orgate = DEVICE(object_new(TYPE_OR_IRQ));
+ object_property_set_int(OBJECT(escc_orgate), "num-lines", 2, &error_fatal);
+ qdev_realize_and_unref(escc_orgate, NULL, &error_fatal);
+ sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
+ sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
+ qdev_connect_gpio_out(DEVICE(escc_orgate), 0, pic[3]);
sysbus_mmio_map(sysbus, 0, SCC_BASE);
/* SCSI */