ARM Cortex-A53 Execution State Limitations and Use Cases

The ARM Cortex-A53 processor, part of the ARMv8-A architecture, supports both 32-bit (AArch32) and 64-bit (AArch64) execution states. However, transitioning between these states is not as straightforward as flipping a switch, especially when operating at Exception Level 1 (EL1), which is typically used for operating systems and applications. The Cortex-A53 processor can operate in either AArch32 or AArch64 at EL1, but the execution state is determined at reset and cannot be dynamically switched during runtime without significant architectural constraints.

In AArch64 mode, the processor can execute both 64-bit and 32-bit applications (EL0), but in AArch32 mode, the processor is restricted to 32-bit execution at all exception levels. This limitation becomes critical when attempting to execute a 64-bit instruction or access a 64-bit address range while running in AArch32 mode. The inability to dynamically switch execution states at EL1 is a fundamental architectural constraint, not a software or configuration issue.

The primary use case for needing such a transition often involves accessing memory-mapped registers or peripherals located in the 64-bit address space. For example, a 32-bit application running at EL1 might need to read or write to a 64-bit address range for hardware interaction. Since direct access is impossible in AArch32 mode, alternative mechanisms must be employed to achieve this functionality.


Root Cause: Execution State Lock at EL1 and Missing Monitor Mode Implementation

The root cause of the inability to switch between 32-bit and 64-bit modes dynamically lies in the ARMv8-A architecture’s design. When the Cortex-A53 processor is configured to run in AArch32 mode at EL1, it cannot transition to AArch64 mode without a reset or an exception level change. This is because the execution state is tied to the exception level and the processor’s configuration at boot time.

Additionally, the absence of a properly implemented monitor mode (EL3) exacerbates the problem. In ARMv8-A, EL3 is the highest privilege level and is responsible for switching between secure and non-secure states. It can also facilitate transitions between AArch32 and AArch64 execution states. However, if EL3 is not implemented or configured correctly, the processor loses the ability to mediate such transitions, leaving the system locked in its current execution state.

In the provided scenario, the user attempts to execute a 64-bit instruction or access a 64-bit address range while running in AArch32 mode at EL1. This is inherently impossible due to the architectural constraints. The suggested workaround involves leveraging the Secure Monitor Call (SMC) instruction to delegate the operation to EL3, where the processor can execute in AArch64 mode. However, this requires a properly configured EL3 environment and a corresponding handler to perform the requested operation.


Implementing Secure Monitor Calls for 64-bit Operations in AArch32 Mode

To address the limitation of executing 64-bit operations in AArch32 mode, the Secure Monitor Call (SMC) instruction can be used to delegate the operation to EL3, where the processor can execute in AArch64 mode. This approach involves the following steps:

Step 1: Define the SMC Handler in EL3

The SMC handler at EL3 must be capable of interpreting the request from EL1, performing the required 64-bit operation, and returning the result. The handler should be written in AArch64 assembly or C code, depending on the complexity of the operation.

// Example SMC handler in EL3 (AArch64)
void smc_handler(uint64_t command, uint64_t address_upper, uint64_t address_lower, uint64_t *result) {
    switch (command) {
        case SMC_LONG_ADDRESS_READ_SINGLE:
            *result = read_64bit_memory(address_upper << 32 | address_lower);
            break;
        case SMC_LONG_ADDRESS_WRITE_SINGLE:
            write_64bit_memory(address_upper << 32 | address_lower, *result);
            break;
        default:
            // Handle unknown command
            break;
    }
}

Step 2: Implement the SMC Call in AArch32 Mode

The AArch32 code at EL1 must prepare the necessary parameters and issue the SMC instruction. The parameters include the command (e.g., read or write), the upper and lower 32 bits of the 64-bit address, and a placeholder for the result.

// Example SMC call in AArch32 mode
FAST_PATH_CODE static inline uint32_t read_from_64bit_address(uint64_t address) {
    uint32_t address_upper = (uint32_t)(address >> 32);
    uint32_t address_lower = (uint32_t)(address);
    register uint32_t result asm("r0");
    asm volatile (
        "mov r0, %[command]\n"
        "mov r1, %[addr_upper]\n"
        "mov r2, %[addr_lower]\n"
        "smc #0\n"
        : "=r" (result)
        : [addr_upper] "r" (address_upper), [addr_lower] "r" (address_lower), [command] "r" (SMC_LONG_ADDRESS_READ_SINGLE)
        : "r1", "r2"
    );
    return result;
}

Step 3: Configure EL3 Environment

Ensure that the EL3 environment is properly configured to handle SMC calls. This includes setting up the exception vector table, enabling the appropriate security features, and initializing the SMC handler.

Step 4: Validate the Implementation

Test the implementation by performing read and write operations to 64-bit addresses from AArch32 mode. Verify that the results are correct and that the system remains stable.

Step 5: Optimize for Performance

If the SMC calls are frequent, consider optimizing the handler and the communication mechanism between EL1 and EL3. Techniques such as batching multiple operations into a single SMC call or using shared memory for data transfer can reduce overhead.


Summary of Key Considerations

Aspect Details
Execution State Lock AArch32 at EL1 cannot switch to AArch64 without reset or EL3 intervention.
SMC Instruction Used to delegate 64-bit operations to EL3.
EL3 Handler Must be implemented in AArch64 to perform 64-bit operations.
Parameter Passing Upper and lower 32 bits of the 64-bit address are passed separately.
Performance Optimization Minimize SMC call overhead through batching or shared memory.

By following these steps, it is possible to perform 64-bit operations while running in AArch32 mode at EL1, leveraging the capabilities of EL3 to bridge the gap between the two execution states. This approach ensures compatibility with existing 32-bit software while enabling access to 64-bit resources when needed.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *