[GIC500v3][ARMv8][A72] Interrupt is not handled correctly after A72 change from EL3 to EL1

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. 

  • When SGI0~15 are generated by ICC_SGI1R_EL1, and be grouped as Secure Group1, only SGI15 can be handled
  • When SGI0~15 are generated by ICC_SGI1R_EL1, and be grouped as Non Secure Group1, only SGI0~14 can be handled
  • When SGI0~15 are generated by ICC_ASGI1R_EL1, and be grouped as Secure Group1, only SGI0~14 can be handled
  • When SGI0~15 are generated by ICC_ASGI1R_EL1, and be grouped as Non Secure Group1, only SGI15 can be handled

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);

Parents
    • 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:

    • ICC_SGIR0 - Send a G0
      • Typically used either for IPIs within the EL3 firmware, or to request EL3 firmware does something.
    • ICC_SGIR1 - Send G1 for current Security state
      • Typically used as IPIs within the host OS/hypervisor.
    • ICC_ASGI1 - Send G1 for the other/non-current Security state
      • Typically used as part of a calling convention between Secure and Non-secure worlds.

    I say "typically" in the examples because they are just examples.  You can use them for whatever you want within the architecture rules.

    • 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.

    • 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. 

Reply
    • 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:

    • ICC_SGIR0 - Send a G0
      • Typically used either for IPIs within the EL3 firmware, or to request EL3 firmware does something.
    • ICC_SGIR1 - Send G1 for current Security state
      • Typically used as IPIs within the host OS/hypervisor.
    • ICC_ASGI1 - Send G1 for the other/non-current Security state
      • Typically used as part of a calling convention between Secure and Non-secure worlds.

    I say "typically" in the examples because they are just examples.  You can use them for whatever you want within the architecture rules.

    • 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.

    • 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. 

Children