On 14/10/2021 11:47, Christophe Leroy wrote:
Le 14/10/2021 à 12:34, Christophe Leroy a écrit :
Le 14/10/2021 à 11:31, Thomas Huth a écrit :
Hi,
I tried to build a current Linux kernel for the "bamboo" board and use it in QEMU,
but QEMU then quickly aborts with:
pci.c:262: pci_bus_change_irq_level: Assertion `irq_num >= 0' failed.
(or with a "DCR write error" if I try to use the cuImage instead).
I googled a little bit and found this discussion:
https://qemu-devel.nongnu.narkive.com/vYHona3u/emulating-powerpc-440ep-with-qemu-system-ppcemb#post2
Seems like this board was used for KVM on the PPC440 only, and has never been
enabled with the TCG emulation?
Well, KVM support on the 440 has been removed years ago already:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b2677b8dd8de0dc1496ede4da09b9dfd59f15cea
So is this "bamboo" board dead code in QEMU now? Or does anybody still have a
kernel binary which could be used for testing it? Note: This board does not
support "-bios", so u-boot or other firmwares are certainly also not an option
here...
Should we mark "bamboo" as deprecated nowadays?
I have the following change in QEMU to be able to run the bamboo, found it some
time ago via google (can't remember where):
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 8147ba6f94..600e89e791 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -246,7 +246,7 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int
irq_num)
trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot);
- return slot - 1;
+ return slot ? slot - 1 : slot;
}
static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
---
It's probably no the final change, but at least it allows booting bamboo on qemu
again.
Found the source :
https://www.mail-archive.com/qemu-devel@nongnu.org/msg769121.html
Ah yes, that thread rings a bell. I think the important part was in my initial reply
at https://www.mail-archive.com/qemu-devel@nongnu.org/msg769115.html: in other words
ppc4xx_pci_map_irq() function expects the IRQ number to range from 1 to 4.
When I looked at this the issue was caused by the guest writing to PCI configuration
space to disable PCI interrupts: this ends up calling pci_update_irq_disabled() as below:
/* Called after interrupt disabled field update in config space,
* assert/deassert interrupts if necessary.
* Gets original interrupt disable bit value (before update). */
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
{
int i, disabled = pci_irq_disabled(d);
if (disabled == was_irq_disabled)
return;
for (i = 0; i < PCI_NUM_PINS; ++i) {
int state = pci_irq_state(d, i);
pci_change_irq_level(d, i, disabled ? -state : state);
}
}
Since the IRQ is disabled pci_change_irq_level() ends up being called with -1 which
triggers the assert().
My feeling is that the existing assert() is correct, since from what I can see
without it there would be an IRQ array underflow, however I wasn't sure whether
passing a negative number to pci_change_irq_level() is supposed to be valid?
ATB,
Mark.