On 01/03/2020 11:35, Mark Cave-Ayland wrote: > On 29/02/2020 23:02, BALATON Zoltan wrote: > >> Some machines operate in "non 100% native mode" where interrupts are >> fixed at legacy IDE interrupts and some guests expect this behaviour >> without checking based on knowledge about hardware. Even Linux has >> arch specific workarounds for this that are activated on such boards >> so this needs to be emulated as well. >> >> Signed-off-by: BALATON Zoltan <bala...@eik.bme.hu> >> --- >> hw/ide/via.c | 60 +++++++++++++++++++++++++++++++++++------ >> hw/mips/mips_fulong2e.c | 2 +- >> include/hw/ide.h | 3 ++- >> 3 files changed, 55 insertions(+), 10 deletions(-) >> >> diff --git a/hw/ide/via.c b/hw/ide/via.c >> index 096de8dba0..17418c5822 100644 >> --- a/hw/ide/via.c >> +++ b/hw/ide/via.c >> @@ -1,9 +1,10 @@ >> /* >> - * QEMU IDE Emulation: PCI VIA82C686B support. >> + * QEMU VIA southbridge IDE emulation (VT82C686B, VT8231) >> * >> * Copyright (c) 2003 Fabrice Bellard >> * Copyright (c) 2006 Openedhand Ltd. >> * Copyright (c) 2010 Huacai Chen <zltjiang...@gmail.com> >> + * Copyright (c) 2019-2020 BALATON Zoltan >> * >> * Permission is hereby granted, free of charge, to any person obtaining a >> copy >> * of this software and associated documentation files (the "Software"), to >> deal >> @@ -25,6 +26,8 @@ >> */ >> >> #include "qemu/osdep.h" >> +#include "qemu/range.h" >> +#include "hw/qdev-properties.h" >> #include "hw/pci/pci.h" >> #include "migration/vmstate.h" >> #include "qemu/module.h" >> @@ -111,14 +114,43 @@ static void via_ide_set_irq(void *opaque, int n, int >> level) >> } else { >> d->config[0x70 + n * 8] &= ~0x80; >> } >> - >> level = (d->config[0x70] & 0x80) || (d->config[0x78] & 0x80); >> - n = pci_get_byte(d->config + PCI_INTERRUPT_LINE); >> - if (n) { >> - qemu_set_irq(isa_get_irq(NULL, n), level); >> + >> + /* >> + * Some machines operate in "non 100% native mode" where >> PCI_INTERRUPT_LINE >> + * is not used but IDE always uses ISA IRQ 14 and 15 even in native >> mode. >> + * Some guest drivers expect this, often without checking. >> + */ >> + if (!(pci_get_byte(d->config + PCI_CLASS_PROG) & (n ? 4 : 1)) || >> + PCI_IDE(d)->flags & BIT(PCI_IDE_LEGACY_IRQ)) { >> + qemu_set_irq(isa_get_irq(NULL, (n ? 15 : 14)), level); >> + } else { >> + n = pci_get_byte(d->config + PCI_INTERRUPT_LINE); >> + if (n) { >> + qemu_set_irq(isa_get_irq(NULL, n), level); >> + } >> } >> }
The other part I'm not sure about is that I can't see how via_ide_set_irq() can ever raise a native PCI IRQ - comparing with my experience on cmd646, should there not be a pci_set_irq(d, level) at the end? ATB, Mark.