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.

Reply via email to