[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 Reply Children
  • 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.