I am trying to work out a loop SGI0 ~ SGI15 triggering and handling test.
I made it work for only one round. A72 can trigger SGI0~SGI15 and handle it.
But when I try to trigger any SGI again, it will not enter pending state, and be distributed to A72 again.
my first round code is like
init a53/a72/GIC
use a53 to kick off a72
use a72 to read out MPIDR_EL1
use a72 to configure affinity and set ICC_SGI0R_EL1 (SGI0 from A53 to A72)
use a72 to check redistributor GIR_ISPENDER (make sure SGI enter is generated and enter pending state)
use a72 to install interrupt handler (read out IAR0 and set EOIR0)
use a72 to enable interrupt (GICR_WAKER / GIC_PRIORITY / GICR_CFG / GICR_GROUP/ GICR_ISENABLER )
SGI0 ~ SGI15 can be triggered and handled without error. but when I set ICC_SGI0R_EL1 again to trigger anyone of SGI. GIR_ISPENDER is always 0x40000000, seems SGI can't enter pending state again?
why's that? thanks in advance.
Hi Martin,
much appreciated for your help!
Martin Weidmann said:Do you mean that you successfully trigger all the SGI IDs? (That is, within the test you trigger 16 interrupts). Or, do you mean that you trigger one interrupt, but it can be any of the SGI IDs?
I triggered all 16 SGI interrupts one by one, and all of them can be handled successfully.
but after A72 handle and end all 16 interrupts, no matter which interrupt I trigger again, A72 doesn't received any interrupt.
Martin Weidmann said:Was it ICC_SGI0R_EL1 you used for the previous past of the test? Has anything changed in the PE? For example, are you at a different Exception level (EL) or in a different Security state? Have you tried adding a "DSB SY" between the write to ICC_SGI0R_EL1 and the read of GICR_IPENDR0?
Was it ICC_SGI0R_EL1 you used for the previous past of the test?
Has anything changed in the PE? For example, are you at a different Exception level (EL) or in a different Security state?
Have you tried adding a "DSB SY" between the write to ICC_SGI0R_EL1 and the read of GICR_IPENDR0?
yes, I try to set same ICC_SGI0R_EL1 again to trigger interrupt again.
I think I don't change any set up of PE, EL is always 3.
No, I don't add "DSB SY" between write to ICC_SGI and read of GICR_PENDR0.
Do I need to add "DSB SY" into every read/write to GIC register?
Martin Weidmann said:What value did you write in into GICR_IGROUPR0? Are you also programming GICR_IGRPMODR0?
I only write GICR_IGROUPR0, don't program the GICR_IGRPMODR0.
Value I write to GICR_IGROUPR0 is "(1 << (src_int_num ))"
Ok, a potential explanation if I understood the order of the steps correctly.
There are three registers for generating SGIs:
Which register you write sets the Group the sender wants to send. The GIC compares what the sender sent against how the receiver configured the interrupt. For example, if the sender sends G1 (ICC_SGI1R_EL1) but the receiver has configured the interrupt as G0 (in GICR_IGROUPR0/GICR_IGRPMODR0), then the request is dropped. The GIC guide has a handy table on the result of differences in the sending and receiving Group:
Learn the architecture - Generic Interrupt Controller v3 and v4, Overview (arm.com)
In you original post I think you generate the SGIs first (write ICC_SGI0R_EL1), then later configure the SGIs (GICR_IGROUPR0) later. Is that correct?
If so, that could be the problem.
You're writing ICC_SGI0R_EL1, which is setting the sending Group as 0. At reset, all SGIs are assigned to G0, so the sending/receiving Group are the same.
Later you're write 1s to GICR_IGROUPR0, which is allocating the SGIs to NS.G1. So when you write ICC_SGI0R_EL1 for a second time the sending and receiving Group no longer match.
To fix you either to leave the SGIs as G0 (remove the writes to GICR_IGROUPR0), or change which register you write to when you generate the second set of SGIs.
Much appreciated for your help!!!!! I made it after delete the GICR_IGROUPR0 register access!!!
I wondered why I need to access IGROUP0 after access IENABLER, but I didn't pay more attention on it. (Legacy code issue from colleague I suppose)
And I found that my access to EOIR is also wrong. After I correct them all. Looping SGI triggering and handling test can be run and pass.
Thanks very much again. And have a wonderful day!