Hello Michael,
On Thu, Aug 22, 2024 at 12:52:29PM +0200, Michael Grunditz wrote:
Many thanks for the long answer!
On Thu, 22 Aug 2024 at 09:51, Stefan Kalkowski stefan.kalkowski@genode-labs.com wrote:
Hello Michael,
On Wed, Aug 21, 2024 at 05:47:37PM +0200, Michael Grunditz wrote:
Time for next problem, interrupts. No interrupts are firing including timer. This is my GIC mem layout:
IRQ_CONTROLLER_DISTR_BASE = 0xfee00000, IRQ_CONTROLLER_DISTR_SIZE = 0x100000, IRQ_CONTROLLER_REDIST_BASE = 0xfef00000, IRQ_CONTROLLER_REDIST_SIZE = 0x100000,
The addresses are what RISC OS uses on rk3399. If this is correct, what can stop interrupts.. can they be turned off? I probably need to toggle because I think that they are on from uboot. I can fix in uboot, but it would be nice if it can be done in kernel.
Well, reasons for getting no interrupt can be versatile. First and foremost, it might wait for the wrong interrupt number. The GIC registers might be wrong. Also interrupts can be turned off globally via the CPU (pstate) register (typically this is normal state inside our kernel). Finally, interrupts are TrustZone-sensitive and can be routed either to secure or normal world.
I have checked bits and pieces. I believe that irq 30 is the timer according to the manual. The gic should work , it did on RK3588. Not sure if they are critical , but both is 0x1. ICC_IGRPEN0_EL1 ICC_IGRPEN1_EL1
Just a shot in the dark: you told us that you stepped from EL3 to EL2 in u-boot?! Maybe you just switched the exception-level without further preparation of additional peripherals (like GIC) normally done by the TrustZone firmware? I assume that the GIC's default register values are initialized in a way that interrupts are marked "secure", and thereby cannot be enabled by the normal world resp. the hw kernel then. One way to proof this would be to lookup the Igroup registers of the GIC's redistributor interface while the CPU is still in EL3 (shortly before switching to EL2).
Do you refer to the above regs? If I need to access GIC memory mapped I need somes extra code.
No, the ICC_IGREN* register belong to the cpu local interface of the GIC. What I meant are global ones that belong to the GIC's redistributor interface. In general the GIC's memory mapped I/O registers are accessed already within the Hw::Pic constructor within `repos/base-hw/src/bootstrap/spec/arm/gicv3.cc`. The constructor is used explicitly within the EL2 codepath of the `Bootstrap::Platform::enable_mmu()` for Cortex A53. If you really start in EL3, at least part of that code should be executed in EL3. In that case, you could duplicate the Pic initialization before entering `prepare_non_secure_world` as a first try.
Apart from this first guess, I think you need to check the state systematically. There is no way to simply fix things in u-boot anyway, because the kernel initializes the GIC by itself, thereby overwriting any settings done before (except secure TrustZone configuration, if started below EL3).
Today something strange happened! I removed the el2 switch from u-boot and it was in el2 without it. No idea why!
Well, you first should find out whether you originally really started in EL3, or whether you now have some outdated u-boot binary or build relict which boots. Otherwise, we fish in murky waters, and the whole interpretation will lead to wrong assumptions.
If my above assumption is a dead end, you might start with printing the GIC's state, after interrupts got turned on or off. A simple print of the register addresses and values, and of course the interrupt number, whenever an interrupt got enabled or disabled, could help already.
Yes , that was the first thing I did. It unmasks the timer at start, but nothing gets masked. Sorry for being uneducated, but do the handlers mask the interrupt while running? I expect that, and that my logs would be flooded by printouts :)
At the very beginning within the constructor all interrupts are masked. If you enable an interrupt, it gets unmasked (like the timer you described above). It will get masked within the low-level interrupt kernel routine, after it occurred. And it gets unmasked again, when the device-specific interrupt routine signaled an EOI (end of interrupt).
So what you describe shows there is an unmask, but no mask?! That would mean no interrupt was received by the kernel.
Regards Stefan
to be continued ...
/Michael _______________________________________________ users mailing list -- users@lists.genode.org To unsubscribe send an email to users-leave@lists.genode.org Archived at https://lists.genode.org/mailman3/hyperkitty/list/users@lists.genode.org/mes...
-- Stefan Kalkowski Genode labs