Cortex-A55 AARCH32 State Configuration and Exception Handling at EL1
The ARM Cortex-A55 is a highly efficient mid-range processor core designed for a wide range of applications, from mobile devices to embedded systems. One of its key features is the ability to operate in both AARCH64 (64-bit) and AARCH32 (32-bit) execution states. However, transitioning the Cortex-A55 to AARCH32 state at EL1 (Exception Level 1) can be challenging, especially when bare-metal booting is involved. This issue often manifests as an exception being triggered during the transition, preventing the system from entering the desired execution state.
The core of the problem lies in the configuration of system registers and the sequence of operations required to switch from a higher exception level (EL2 or EL3) to EL1 in AARCH32 state. Misconfigurations in the HCR_EL2 (Hypervisor Configuration Register), SCTLR_EL1 (System Control Register for EL1), and SCR_EL3 (Secure Configuration Register) can lead to unexpected exceptions. Additionally, the state of the NS (Non-Secure) bit in SCR_EL3 plays a critical role in determining whether the system transitions to secure or non-secure EL1.
Understanding the interaction between these registers and the precise sequence of operations required to transition to AARCH32 state at EL1 is essential for resolving the issue. This guide will delve into the specifics of the Cortex-A55 architecture, the role of each register, and the steps necessary to ensure a successful transition.
Misconfigured HCR_EL2, SCTLR_EL1, and SCR_EL3 Registers
The HCR_EL2 register is responsible for configuring the behavior of the hypervisor and the execution state of EL1. Specifically, the RW (Register Width) bit (bit 31) in HCR_EL2 determines whether EL1 operates in AARCH64 (RW=1) or AARCH32 (RW=0) state. In the provided code snippet, the RW bit is cleared to configure EL1 for AARCH32 execution. However, this alone is not sufficient to ensure a successful transition.
The SCTLR_EL1 register controls the system configuration at EL1, including the MMU, caches, and alignment checks. Before entering EL1, SCTLR_EL1 must be initialized to a known state. In the provided code, SCTLR_EL1 is reset using the MSR SCTLR_EL1, XZR instruction, which sets all bits to zero. While this ensures a clean slate, it may not be appropriate for all use cases. For example, disabling the MMU or caches at this stage could lead to unexpected behavior if the system relies on these features.
The SCR_EL3 register is critical for configuring the security state of the system. The NS (Non-Secure) bit (bit 0) in SCR_EL3 determines whether the system operates in secure or non-secure state. If the NS bit is not set correctly, the system may fail to transition to the desired execution state. In the provided code, there is no explicit configuration of SCR_EL3, which could be a contributing factor to the exception.
Additionally, the SPSR_EL2 (Saved Program Status Register for EL2) and ELR_EL2 (Exception Link Register for EL2) must be configured correctly to ensure that the processor enters EL1 in the desired state. The SPSR_EL2 register defines the processor state (e.g., AARCH32 SVC mode) upon executing the ERET instruction, while ELR_EL2 specifies the address of the first instruction to execute at EL1. Any misconfiguration in these registers can lead to an exception during the transition.
Diagnosing and Resolving Cortex-A55 AARCH32 State Transition Exceptions
To diagnose and resolve the issue of exceptions during the transition to AARCH32 state at EL1, follow these detailed steps:
Step 1: Verify the Configuration of HCR_EL2
Ensure that the RW bit (bit 31) in HCR_EL2 is cleared to configure EL1 for AARCH32 execution. Additionally, check other bits in HCR_EL2 to ensure they are set appropriately for your use case. For example, the AMO, IMO, and FMO bits control the routing of asynchronous exceptions (e.g., interrupts) to EL2. If these bits are not set correctly, exceptions may be routed to the wrong exception level.
Step 2: Initialize SCTLR_EL1 Appropriately
Before entering EL1, initialize SCTLR_EL1 to a known state. While resetting SCTLR_EL1 to zero is a good starting point, consider enabling or disabling specific features based on your system requirements. For example, if your system relies on the MMU, ensure that the M (MMU enable) bit (bit 0) is set. Similarly, if your system uses caches, ensure that the I (Instruction cache enable) and C (Data cache enable) bits (bits 12 and 2, respectively) are set.
Step 3: Configure SCR_EL3 for the Desired Security State
Set the NS bit (bit 0) in SCR_EL3 to determine whether the system operates in secure or non-secure state. If your system is designed to operate in non-secure state, ensure that the NS bit is set. Additionally, configure other bits in SCR_EL3 as needed. For example, the IRQ and FIQ bits (bits 1 and 2, respectively) control the routing of interrupts to EL3. If these bits are not set correctly, interrupts may not be handled as expected.
Step 4: Set Up SPSR_EL2 and ELR_EL2 Correctly
Configure SPSR_EL2 to define the processor state upon executing the ERET instruction. For AARCH32 execution at EL1, set the M[4:0] field to 10011 (SVC mode). Additionally, ensure that the DAIF bits (bits 9-6) are set to mask interrupts during the transition. Set ELR_EL2 to the address of the first instruction to execute at EL1. This address should point to the entry point of your AARCH32 code.
Step 5: Analyze the Exception and ESR_ELx Value
If an exception occurs, analyze the exception to determine the cause. The exception syndrome register (ESR_ELx) provides detailed information about the exception, including the exception class, instruction-specific syndrome, and fault address. Use this information to identify the root cause of the exception. For example, if the exception class indicates an instruction abort, check the fault address to determine whether the issue is related to memory access or alignment.
Step 6: Implement Data Synchronization Barriers
Ensure that data synchronization barriers (DSB) and instruction synchronization barriers (ISB) are used appropriately to maintain the correct order of memory accesses and instruction execution. For example, insert a DSB instruction after configuring HCR_EL2 and before executing the ERET instruction to ensure that all previous memory accesses are complete. Similarly, insert an ISB instruction after configuring SCTLR_EL1 to ensure that the processor executes subsequent instructions with the new configuration.
Step 7: Validate the Transition with Debugging Tools
Use debugging tools (e.g., JTAG, trace, or simulation) to validate the transition to AARCH32 state at EL1. Set breakpoints at key points in the code (e.g., before and after the ERET instruction) to verify that the processor enters the desired state. Use trace tools to capture the sequence of instructions and exceptions, and analyze the trace to identify any discrepancies.
By following these steps, you can diagnose and resolve the issue of exceptions during the transition to AARCH32 state at EL1 on the Cortex-A55. Proper configuration of HCR_EL2, SCTLR_EL1, SCR_EL3, SPSR_EL2, and ELR_EL2, along with careful analysis of exceptions and the use of debugging tools, will ensure a successful transition and stable operation in AARCH32 state.