ARM Cortex-A53 Execution State Control via AA64nAA32 Signal
The ARM Cortex-A53 processor, part of the ARMv8-A architecture, supports two execution states: AArch64 and AArch32. The initial execution state after reset is determined by the AA64nAA32 signal, which is a hardware input to the processor. This signal is sampled at reset and dictates whether the processor boots in AArch64 (64-bit) or AArch32 (32-bit) mode at Exception Level 3 (EL3). The AA64nAA32 signal is critical for systems requiring deterministic boot behavior, especially in bare-metal or low-level firmware implementations.
The AA64nAA32 signal is typically controlled by the SoC (System on Chip) design. In many cases, this signal is tied to a specific voltage level or configured via a pin multiplexing setting. If the signal is not directly accessible or configurable in software, the processor will default to the state determined by the hardware design. For developers working with custom or programmable SoCs, the AA64nAA32 signal can often be configured through board-level initialization code or hardware configuration files.
When the AA64nAA32 signal is set to 0, the Cortex-A53 boots in AArch32 mode at EL3. This is the desired configuration for systems requiring 32-bit execution. Conversely, when the signal is set to 1, the processor boots in AArch64 mode. It is important to note that the execution state at EL3 cannot be changed dynamically without a reset. However, lower exception levels (EL2, EL1, and EL0) can switch between AArch32 and AArch64 modes under software control.
Bare-Metal Boot Code for AArch32 Mode Configuration
For developers implementing bare-metal firmware, configuring the Cortex-A53 to boot in AArch32 mode requires careful handling of the AA64nAA32 signal and subsequent software initialization. If the signal is not directly accessible, the processor can be booted in AArch64 mode and then switched to AArch32 mode at a lower exception level. This approach involves writing to system control registers and executing an exception return (ERET) to transition to the desired execution state.
The following steps outline the process of switching from AArch64 to AArch32 mode in bare-metal code:
-
Initialize System Control Registers: Before switching to AArch32 mode, ensure that the system control registers for the target exception level are properly configured. For example, the SCTLR_EL2 register should be cleared to disable the MMU and caches, ensuring a clean state for the transition.
-
Configure Secure Configuration Register (SCR_EL3): The SCR_EL3 register controls various security and execution state settings. To enable AArch32 mode at EL2, set the NS (Non-Secure) bit and the HCE (Hypervisor Call Enable) bit. This allows the processor to handle hypervisor calls in AArch32 mode.
-
Set Exception Link Register (ELR_EL3): The ELR_EL3 register holds the address to which the processor will return after the exception return. Load this register with the address of the entry point for AArch32 execution at EL2.
-
Set Saved Program Status Register (SPSR_EL3): The SPSR_EL3 register defines the processor state after the exception return. Configure this register with the bit pattern corresponding to AArch32 Hyp mode (0x1A). This ensures that the processor transitions to the correct execution state.
-
Execute Exception Return (ERET): The ERET instruction triggers the transition to the new execution state. After executing this instruction, the processor will resume execution at the address specified in ELR_EL3, operating in AArch32 mode.
Here is an example of the assembly code to perform the transition:
MSR SCTLR_EL2, xzr ; Clear SCTLR_EL2 to disable MMU and caches
MOV w1, wzr ; Initialize w1 to zero
ORR w1, w1, #1 ; Set NS bit in SCR_EL3
ORR w1, w1, #(1 << 8) ; Set HCE bit in SCR_EL3
MSR SCR_EL3, x1 ; Write configuration to SCR_EL3
ADR x1, el2_entry_aarch32 ; Load address of AArch32 entry point
MSR ELR_EL3, x1 ; Set ELR_EL3 to AArch32 entry point
LDR x1, =0x1A ; Load bit pattern for AArch32 Hyp mode
MSR spsr_el3, x1 ; Set SPSR_EL3 for AArch32 mode
ERET ; Perform exception return to AArch32 mode
In this example, el2_entry_aarch32 is a label representing the entry point for AArch32 execution at EL2. The code clears the SCTLR_EL2 register, configures the SCR_EL3 register, sets the exception return address and processor state, and finally executes the ERET instruction to transition to AArch32 mode.
Verifying AArch32 Mode Execution
After configuring the Cortex-A53 to boot in AArch32 mode, it is essential to verify that the processor is operating in the correct execution state. This can be done by inspecting the Current Program Status Register (CPSR) or by executing specific instructions that behave differently in AArch32 and AArch64 modes.
-
Inspect CPSR: The CPSR contains bits that indicate the current execution state. In AArch32 mode, the T and J bits in the CPSR will reflect the instruction set being used. For example, if the T bit is set, the processor is executing Thumb instructions. If both T and J bits are clear, the processor is executing ARM instructions.
-
Execute Mode-Specific Instructions: Certain instructions are only available in AArch32 or AArch64 mode. For example, the
CPSinstruction, used to change processor state, is only available in AArch32 mode. Attempting to execute this instruction in AArch64 mode will result in an undefined instruction exception. -
Check Exception Level: The processor’s exception level can be determined by reading the CurrentEL register. In AArch32 mode, this register will reflect the current exception level (EL2, EL1, or EL0). This can be used to confirm that the processor has successfully transitioned to the desired execution state.
Here is an example of how to verify AArch32 mode execution using assembly code:
MRS x0, CurrentEL ; Read CurrentEL register
CMP x0, #0x8 ; Compare with EL2 (0x8)
BNE not_el2 ; Branch if not in EL2
MRS x0, CPSR ; Read CPSR
AND x0, x0, #0x20 ; Check T bit
CBNZ x0, thumb_mode ; Branch if in Thumb mode
B arm_mode ; Branch if in ARM mode
In this example, the code reads the CurrentEL register to confirm that the processor is in EL2. It then reads the CPSR and checks the T bit to determine whether the processor is executing Thumb or ARM instructions. This provides a clear indication of the current execution state.
By following these steps, developers can ensure that the Cortex-A53 processor is correctly configured to boot in AArch32 mode and verify its execution state. This is particularly important for systems requiring deterministic behavior and compatibility with legacy 32-bit software.