aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/i8259.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2023-03-02 10:06:26 +0100
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2023-03-08 00:37:48 +0100
commitecb0e98b4f24495dd4febab7d69579d62773bdc4 (patch)
tree26d5b56defe053ab32f89e7ec80c2e06f6d5f1cc /hw/intc/i8259.c
parent4e0210525752511646c737f89ea2f2e7c7ca85de (diff)
hw/intc/i8259: Implement legacy LTIM Edge/Level Bank Select
Back in the mists of time, before EISA came along and required per-pin level control in the ELCR register, the i8259 had a single chip-wide level-mode control in bit 3 of ICW1. Even in the PIIX3 datasheet from 1996 this is documented as 'This bit is disabled', but apparently MorphOS is using it in the version of the i8259 which is in the Pegasos2 board as part of the VT8231 chipset. It's easy enough to implement, and I think it's harmless enough to do so unconditionally. Signed-off-by: David Woodhouse <dwmw2@infradead.org> [balaton: updated commit message as asked by author] Tested-by: BALATON Zoltan <balaton@eik.bme.hu> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <3f09b2dd109d19851d786047ad5c2ff459c90cd7.1678188711.git.balaton@eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'hw/intc/i8259.c')
-rw-r--r--hw/intc/i8259.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index 17910f3bcb..bbae2d87f4 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -133,7 +133,7 @@ static void pic_set_irq(void *opaque, int irq, int level)
}
#endif
- if (s->elcr & mask) {
+ if (s->ltim || (s->elcr & mask)) {
/* level triggered */
if (level) {
s->irr |= mask;
@@ -167,7 +167,7 @@ static void pic_intack(PICCommonState *s, int irq)
s->isr |= (1 << irq);
}
/* We don't clear a level sensitive interrupt here */
- if (!(s->elcr & (1 << irq))) {
+ if (!s->ltim && !(s->elcr & (1 << irq))) {
s->irr &= ~(1 << irq);
}
pic_update_irq(s);
@@ -224,6 +224,7 @@ static void pic_reset(DeviceState *dev)
PICCommonState *s = PIC_COMMON(dev);
s->elcr = 0;
+ s->ltim = 0;
pic_init_reset(s);
}
@@ -243,10 +244,7 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
s->init_state = 1;
s->init4 = val & 1;
s->single_mode = val & 2;
- if (val & 0x08) {
- qemu_log_mask(LOG_UNIMP,
- "i8259: level sensitive irq not supported\n");
- }
+ s->ltim = val & 8;
} else if (val & 0x08) {
if (val & 0x04) {
s->poll = 1;