First Part - EL3 Group1 SGI issue
I successfully developed a validation test, which makes A72 trigger and handle non-secure group1 SGI number 0~15 at EL3.
But I have some problem. At EL3.
Why SGI0~15 are generated by same register, but can be handled only when assigned to different group?
When I generate SGI by writing ICC_SGI1R_EL1 and ICC_ASGI1R_EL1 at EL3, how should I correctly group them?
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Second Part - Group1 SGI from EL3 to EL1
Now, ignoring this question, I want to let A72 trigger and handle Non-secure group1 SGI test at EL1 Non-secure state.
But I after I configure register at EL3 as showed below, and change El3 to EL1, interrupt can't be handled. What step I still miss?
uint32_t reg; reg = get_SCR_EL3(); reg &= ~(1<<2);//clear fiq reg &= ~(1<<1);//clear irq set_SCR_EL3(reg); reg = get_HCR_EL2(); reg &= ~(1<<4);//clear FMO reg &= ~(1<<3);//clear IMO set_HCR_EL2(reg); el3_config_to_non_secure(); transition_to_lower_el(EL3, EL2); transition_to_lower_el(EL2, EL1);
Dealing with the SGI question first.
When we're talking about SGIs, you need to consider two things:
There's a table (plus explanation) on this page: https://developer.arm.com/documentation/198123/0302/Sending-and-receiving-Software-Generated-Interrupts
But in summary - the Sender and Receiver need to agree, otherwise the interrupt is dropped.
For example:
If SW at EL3 send INTID 0 using ICC_SGI0R_EL1, it's sending the SGI as G0. If the receiver has INTID 0 configured as NSG1 or SG0, the interrupt will be dropped because of the mismatch between the sender and receiver.
The most likely explanation for what you're seeing is that you have different values programmed for GICR_IGRPUPR0 and GICR_IGRPMODR0 for INTIDs 0:14 compared to INTID 15.
There's unfortunately not enough information in code snippet you shared to answer. Here are some things that I would check:
Assuming all of that checks out, when you think you should be getting an interrupt:
Also... you probably don't want SCR_EL3.FIQ cleared while in Non-secure state. In GICv3, FIQ is used for G0 interrupts and interrupts for the "other" Security state. Meaning in NS state, FIQs will either be G0 interrupts or SG1 interrupts - neither of which you can really manage in Non-secure state.
Hi Martin,
Glad to have your feedback again. Much appreciated for your always great help!!
I pretty sure that SGI 0~15 have the same sender set up, I will have a check about the receiver set up.
BTW, I have a few more question about ICC_SGIxR_EL1/ICC_ASGI1_EL1 and GICD_SGIR. Could you kindly help to explain more? thanks in advance.
First one.
Second one.
Thanks for your so detail explanation about the second question, I will check them one by one, and feedback to you.
Kael Hong said:I see SGI can be generated by either ICC_SGIxR_EL1/ICC_ASGI1_EL1 or GICD_SGIR. What's difference between the SGI that generated by different register?
GICD_SGIR is used in legacy operation only (when GICD_CTLR.ARE=0 and ICC_SRE_ELx.SRE=0).
ICC_SGI0/ICC_SGR1/ICC_SSG1 let you control what you send:
I say "typically" in the examples because they are just examples. You can use them for whatever you want within the architecture rules.
Kael Hong said:Are they distributed by different SS? distributor and redistributor? Are they generated and handled at different EL?
The register used matters to decide if the interrupt will be set pending or not. That's what I wrote before about comparing what the Sender sent to how the target CPU has the interrupt configured. Beyond deciding whether interrupt is set pending or not, the register used for the SGI does not matter.
Kael Hong said:I thought that before, NS/S Group1 SGI is not allowed to be handled at EL3, and is expected to be handled at other EL. But seems this not the truth. right? It's better to not have them being handled at EL3, but actually they can be. right?
That's right.
What the manual is describing is the common/typical usage. If you want to handle everything at EL3 you can - and in test or bring up software that might be useful.
thanks for that. understood.
Additionally, can I understand it that way?
SGI generated by CPU interface is distributed by redistributor, and SGI generated by distributor is distributed by distributor?
Kael Hong said:SGI generated by CPU interface is distributed by redistributor, and SGI generated by distributor is distributed by distributor?
The architecture doesn't specify how a GIC is built, only how it behaves/functions. And I don't know the GIC-500 well enough to comment on how precisely it works.
But from a pure architecture perspective: A Redistributor only talks to a single CPU interface. It's the Distributor which links all the Redistributors together. Therefore, the notional path for an SGI in GICv3 is:
Source CPUIF --> Source Redistributor --> Distributor --> Target Redistributor(s) --> Target CPU interface(s)
In GICv1/2 it was:
Distributor --> [GICv3 legacy only -Target Redistributor(s)] --> Target CPU interface(s)
But, that's a little misleading. In GICv3, SW writes to a local system register. In GICv1/2 (or GICv3 legacy), GICD_SGIR is an MMIO register. Therefore, although the distribution path in the GIC looks smaller in GICv1/2, i'd expect the GICv3 approach to better in most cases. As MMIO is typically slow.
understood. it's very clear to me. thank you so so much!