On Thu, 27 Feb 2025 at 09:15, Sourojeet Adhikari <s23ad...@csclub.uwaterloo.ca> wrote: > > The systmr INTERRUPT_TIMER0..3 sysbus IRQ outputs are already > > being wired up in the function bcm_soc_peripherals_common_realize() > > in hw/arm/bcm2835_peripherals.c (to the TYPE_BCM2835_IC > > interrupt controller), and it isn't valid to wire one input > > directly to multiple outputs. > > > > In fact it looks like we are currently getting this wrong for > > all of the interrupts that need to be wired to both the > > "legacy interrupt controller" and the GIC. I think at the moment > > what happens is that the wiring to the GIC will happen last > > and this overrides the earlier wiring to the legacy interrupt > > controller, so code using the latter won't work correctly.
> I'll try reading through the relevant sections and send an > updated patch later next week. From what I can tell it falls > under the bcm2835_pheripherals.c file, right? Yes. To expand a bit, QEMU's qemu_irq abstraction must always be wired exactly 1-to-1, from a single output to a single input. Wiring either one input to multiple outputs or one output to multiple inputs will not behave correctly (and unfortunately we don't have an easy way to assert() if code in QEMU gets this wrong). So for cases where you want the one-to-many behaviour you need to create an object of TYPE_SPLIT_IRQ. This has one input and multiple outputs, so you can connect your wire from device A's output to the splitter's input, and then connect outputs from the splitter to devices B, C, etc. (In this case A would be the timer, and B, C the two interrupt controllers.) Searching the source code for TYPE_SPLIT_IRQ will give some places where it's used. (Ignore the qdev_new(TYPE_SPLIT_IRQ) ones, those are a code pattern we use in board models, not in SoC device models.) In this specific bcm2838 case, it's a little more awkward, because one of the two interrupt controllers is created inside bcm2835_peripherals.c and one of them is created outside it. Since bcm2838 is already reaching inside the bcm2835_peripherals object I guess the simplest thing is: * create a splitter object in bcm2835_peripherals.c for every IRQ line that needs to be connected to both interrupt controllers (probably easiest to have an array of splitter objects, irq_splitter[]) * in bcm2835_peripherals.c, connect the device's outbound IRQ to the input of the appropriate splitter, and connect output 0 of that splitter to the BCM2835_IC correct interrupt controller input * in bcm2838.c, connect output 0 of ps_base->irq_splitter[n] to the correct GIC input (This is kind of breaking the abstraction layer that ideally exists where the code that creates and uses a device doesn't try to look "inside" it at any subparts it might have. We could, for instance, instead make the bcm2835_peripherals object expose its own qemu_irq outputs which were the second outputs of the splitters, so that the bcm2838.c code wasn't looking inside and finding the splitters directly. But I think that's more awkward than it's worth. It's also possible that we have the split between the main SoC and the peripheral object wrong and either both interrupt controllers or neither should be inside the peripheral object; but reshuffling things like that would be a lot of work too.) (PS: for the other "not 1:1" case, where you want to connect many qemu_irqs outputs together into one input, the usual semantics you want is to logically-OR the interrupt lines together, and so you use TYPE_OR_IRQ for that.) thanks -- PMM