December 23, 2025

RK3399 - Linux, EL1, and GICv3

The following document is fascinating and useful: A section that I find especially interesting is:
For systems with a GICv3 interrupt controller to be used in v3 mode:
  - If EL3 is present:
    ICC_SRE_EL3.Enable (bit 3) must be initialiased to 0b1.
    ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b1.
  - If the kernel is entered at EL1:
    ICC.SRE_EL2.Enable (bit 3) must be initialised to 0b1
    ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b1.
  - The DT or ACPI tables must describe a GICv3 interrupt controller.

  For systems with a GICv3 interrupt controller to be used in
  compatibility (v2) mode:
  - If EL3 is present:
    ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b0.
  - If the kernel is entered at EL1:
    ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b0.
  - The DT or ACPI tables must describe a GICv2 interrupt controller.

  For CPUs with pointer authentication functionality:
  - If EL3 is present:
    SCR_EL3.APK (bit 16) must be initialised to 0b1
    SCR_EL3.API (bit 17) must be initialised to 0b1
  - If the kernel is entered at EL1:
    HCR_EL2.APK (bit 40) must be initialised to 0b1
    HCR_EL2.API (bit 41) must be initialised to 0b1
Take note of at least 2 things here:

Uboot switch to EL1

Doing this via an ERET is what I would expect, but I now read that an SMC call can be used to do the switch. This of course is effectively a "system call" but to the secure monitor (BL31 from ATF) running at EL3. Something to search for in the U-boot sources. Searches expose a LOT of stuff involving SMC and ARM_SMCCC and so on.
Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org