ARM Cortex-A72 Exception Handling During ICC_IAR1_EL1 Access at EL1
The ARM Cortex-A72 processor, part of the ARMv8-A architecture, provides a sophisticated interrupt handling mechanism through the Generic Interrupt Controller (GIC). One of the critical registers in this context is the ICC_IAR1_EL1 (Interrupt Controller Interrupt Acknowledge Register 1), which is used to acknowledge and retrieve the highest priority pending interrupt at EL1 (Exception Level 1). However, accessing this register can lead to unexpected exceptions if the system is not configured correctly, particularly when transitioning between secure and non-secure states or when register access permissions are misconfigured.
In this scenario, the Cortex-A72 processor raises an exception when attempting to access ICC_IAR1_EL1 at EL1, even though the same access succeeds at EL3. The exception is characterized by an MSR/MRS instruction trap with an exception class of 0x18, indicating a system register access violation. This behavior is tied to the configuration of several key registers, including ICC_SRE_EL1 (System Register Enable Register), SCR_EL3 (Secure Configuration Register), and HCR_EL2 (Hypervisor Configuration Register). The root cause lies in the interaction between these registers and the security state of the processor.
The ICC_SRE_EL1 register controls whether system register access to the GIC is enabled at EL1. If the SRE (System Register Enable) bit is cleared, any attempt to access ICC_IAR1_EL1 will trigger a trap. Additionally, the SCR_EL3.IRQ bit determines whether IRQ handling is routed to EL3 or EL1, and the SCR_EL3.NS bit controls whether the processor is in secure or non-secure state. Misconfiguration of these bits can lead to unexpected behavior, such as trapping to EL3 instead of EL1 or causing an undefined instruction exception.
ICC_SRE_EL1 Configuration and Security State Mismatch
The primary cause of the exception is a mismatch between the security state of the processor and the configuration of the ICC_SRE_EL1 register. The ICC_SRE_EL1 register is banked, meaning there are separate copies for secure and non-secure states. The active copy is determined by the SCR_EL3.NS bit. If the processor transitions from EL3 to EL1 without ensuring that the correct copy of ICC_SRE_EL1 is configured, the access to ICC_IAR1_EL1 will fail.
For example, if ICC_SRE_EL1.SRE is set to 1 in the secure state (SCR_EL3.NS = 0) but not in the non-secure state (SCR_EL3.NS = 1), accessing ICC_IAR1_EL1 at EL1 in the non-secure state will trigger a trap. This is because the non-secure copy of ICC_SRE_EL1 has not been properly initialized. Similarly, if SCR_EL3.IRQ is set to 1, the processor may route the access to EL3 instead of EL1, leading to an unexpected exception.
Another potential cause is the configuration of HCR_EL2 and ICH_HCR_EL2 when the processor is operating in a virtualized environment. If HCR_EL2.IMO (Immediate Maintenance Interrupt) is set to 1, the processor will use the virtualized interrupt controller registers (ICV_IAR1_EL1) instead of the physical registers (ICC_IAR1_EL1). If ICH_HCR_EL2.TALL1 (Trap All EL1 Accesses) is set to 1, all accesses to ICC_IAR1_EL1 at EL1 will be trapped to EL2. These configurations must be carefully reviewed to ensure that the processor is accessing the correct set of registers.
Resolving ICC_IAR1_EL1 Access Exceptions Through Proper Register Initialization and Synchronization
To resolve the exception and ensure proper access to ICC_IAR1_EL1 at EL1, the following steps should be taken:
-
Initialize Both Secure and Non-Secure Copies of ICC_SRE_EL1: Before transitioning from EL3 to EL1, ensure that both the secure and non-secure copies of ICC_SRE_EL1 are initialized with the SRE bit set to 1. This can be done by toggling the SCR_EL3.NS bit and writing to ICC_SRE_EL1 in both states. For example:
MSR SCR_EL3, #0xC0E // Set SCR_EL3.NS = 0 (secure state) MSR ICC_SRE_EL1, #0x7 // Set SRE = 1 in secure copy MSR SCR_EL3, #0xC0F // Set SCR_EL3.NS = 1 (non-secure state) MSR ICC_SRE_EL1, #0x7 // Set SRE = 1 in non-secure copy
-
Configure SCR_EL3.IRQ and SCR_EL3.NS: Ensure that the SCR_EL3.IRQ bit is set to 0 if IRQ handling should be routed to EL1. Additionally, verify that the SCR_EL3.NS bit matches the intended security state when accessing ICC_IAR1_EL1. For example:
MSR SCR_EL3, #0xC0D // Set SCR_EL3.IRQ = 0 and SCR_EL3.NS = 1
-
Insert ISB (Instruction Synchronization Barrier) After Register Writes: After modifying SCR_EL3 or ICC_SRE_EL1, insert an ISB instruction to ensure that the changes take effect before proceeding. For example:
MSR SCR_EL3, #0xC0F ISB MSR ICC_SRE_EL1, #0x7 ISB
-
Check HCR_EL2 and ICH_HCR_EL2 in Virtualized Environments: If the processor is operating in a virtualized environment, ensure that HCR_EL2.IMO and ICH_HCR_EL2.TALL1 are configured correctly. For example:
MRS X0, HCR_EL2 AND X0, X0, #0xFFFFFFF7 // Clear HCR_EL2.IMO MSR HCR_EL2, X0 MRS X0, ICH_HCR_EL2 AND X0, X0, #0xFFFFFFFE // Clear ICH_HCR_EL2.TALL1 MSR ICH_HCR_EL2, X0
-
Verify Exception Handling Logic: If the processor traps to EL3 instead of EL1, ensure that the exception handler at EL3 correctly handles the access and either re-executes the trapped instruction or emulates the access. For example:
EL3_Exception_Handler: MRS X0, ESR_EL3 AND X0, X0, #0x3F // Extract EC field CMP X0, #0x18 // Check for MSR/MRS trap B.EQ Handle_ICC_IAR1_EL1_Access
By following these steps, the processor can be configured to allow seamless access to ICC_IAR1_EL1 at EL1, avoiding unnecessary exceptions and ensuring reliable interrupt handling. Proper initialization and synchronization of system registers are critical to achieving this goal, particularly in systems that transition between secure and non-secure states or operate in virtualized environments.
Summary of Key Registers and Their Roles
Register | Bit/Field | Description |
---|---|---|
ICC_SRE_EL1 | SRE (Bit 0) | Enables system register access to GIC at EL1. |
SCR_EL3 | NS (Bit 0) | Controls secure (0) or non-secure (1) state. |
SCR_EL3 | IRQ (Bit 1) | Routes IRQ handling to EL3 (1) or EL1 (0). |
HCR_EL2 | IMO (Bit 3) | Routes physical interrupts to virtualized registers (1) or physical (0). |
ICH_HCR_EL2 | TALL1 (Bit 0) | Traps all EL1 accesses to EL2 (1) or allows direct access (0). |
This table provides a quick reference to the key registers and their roles in configuring ICC_IAR1_EL1 access. Proper understanding and configuration of these registers are essential for avoiding exceptions and ensuring correct interrupt handling in ARM Cortex-A72 systems.