Undefined Instruction Error on ICC_HSRE Access in AArch32 EL2

The core issue revolves around an undefined instruction error when attempting to access the ICC_HSRE (Interrupt Controller Hyp System Register Enable) register in AArch32 EL2 mode on a Cortex-A53 processor with a GICv3 (Generic Interrupt Controller version 3) implementation. The specific instruction causing the error is:

mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE

This error suggests that the processor is unable to recognize or execute the instruction, which is typically indicative of one or more of the following scenarios:

  1. The register access is not enabled at the appropriate exception level.
  2. The processor is not configured correctly to support GICv3 system register accesses in AArch32 mode.
  3. The GICv3 system register interface is not initialized or "woken up" properly.
  4. The system is not in the correct architectural state (e.g., EL3 configuration is missing or incorrect).

The Cortex-A53 processor, when operating in AArch32 mode, relies on specific configurations to enable access to GICv3 system registers. These configurations are often tied to the state of higher exception levels (EL3) and the proper initialization of the GICv3 interface. Without these prerequisites, attempts to access registers like ICC_HSRE or ICC_MSRE will result in undefined instruction errors.


Missing ICC_MSRE.Enable or ICC_SRE_ELx Configuration

The root cause of the undefined instruction error is likely tied to the absence of proper configuration in the ICC_MSRE (Monitor System Register Enable) or ICC_SRE_ELx (System Register Enable at Exception Level x) registers. These registers control whether the processor can access GICv3 system registers at lower exception levels (e.g., EL2 or EL1).

ICC_MSRE and ICC_SRE_ELx Overview

  • ICC_MSRE: This register is accessible only in EL3 (Monitor Mode) and is used to enable or disable access to GICv3 system registers at lower exception levels. If the .Enable bit in ICC_MSRE is not set, attempts to access ICC_HSRE or other GICv3 system registers in EL2 or EL1 will result in undefined instruction errors.

  • ICC_SRE_EL2/EL3: These registers serve a similar purpose but are accessible in their respective exception levels. For example, ICC_SRE_EL2 must be configured to enable GICv3 system register access in EL2. If this configuration is missing, the processor will not recognize instructions like mrc p15, 4, r7, c12, c9, 5.

Key Observations from the Cortex-A53 and GICv3 Interaction

  1. EL3 Dependency: The Cortex-A53 processor requires EL3 to configure ICC_MSRE or ICC_SRE_EL3. Without this configuration, lower exception levels (EL2 and EL1) cannot access GICv3 system registers. This is a common source of confusion, as developers often assume that GICv3 registers are accessible directly in EL2 without prior EL3 configuration.

  2. AArch32 vs. AArch64 Differences: In AArch64 mode, the GICv3 system registers are accessed using different mnemonics (e.g., mrs x8, s3_4_c12_c9_5 for ICC_SRE_EL2). However, in AArch32 mode, the same functionality is provided through coprocessor instructions like mrc. If the system is not properly configured, these instructions will fail.

  3. GICR Interface Initialization: The GICv3 architecture includes a GICR (Redistributor) interface that must be initialized before accessing system registers. This involves writing to the GICR_WAKER register to ensure the redistributor is active. If this step is skipped, the GICv3 system registers may not be accessible.


Enabling GICv3 System Registers and Resolving Undefined Instruction Errors

To resolve the undefined instruction error when accessing ICC_HSRE in AArch32 EL2, follow these steps:

Step 1: Verify EL3 Configuration

Ensure the system is booting in EL3 and configure the ICC_MSRE or ICC_SRE_EL3 registers to enable GICv3 system register access at lower exception levels. The following steps outline the process:

  1. Boot into EL3: Confirm that the processor is starting in EL3. This can be verified by checking the current exception level using the CurrentEL system register.

  2. Set ICC_MSRE.Enable: If operating in AArch32 mode, write to the ICC_MSRE register to enable GICv3 system register access. The exact instruction sequence depends on the assembler and toolchain, but it typically involves a coprocessor write.

  3. Set ICC_SRE_EL3.Enable: If operating in AArch64 mode, use the msr instruction to set the .Enable bit in ICC_SRE_EL3. For example:

    msr ICC_SRE_EL3, #0xF
    

    This enables access to GICv3 system registers at EL2 and EL1.

Step 2: Initialize the GICR Interface

Before accessing GICv3 system registers, ensure the GICR interface is active. This involves writing to the GICR_WAKER register to wake up the redistributor. The following code demonstrates this process:

/* Wakeup GICR interface */
MOV32 x0, 0x38880000  @ Base address of GICR
mov w1, #0            @ Write 0 to GICR_WAKER
str w1, [x0, #0x14]   @ Offset 0x14 for GICR_WAKER

This step is critical for ensuring the GICv3 system registers are accessible.

Step 3: Configure ICC_SRE_EL2 in AArch64 Mode

If the system switches from AArch64 to AArch32, configure ICC_SRE_EL2 in AArch64 mode before the switch. This ensures that GICv3 system registers remain accessible in AArch32 EL2. Use the following instruction:

msr ICC_SRE_EL2, #0xF

This sets the .Enable bit in ICC_SRE_EL2, allowing access to ICC_HSRE and other GICv3 system registers in AArch32 EL2.

Step 4: Access ICC_HSRE in AArch32 EL2

Once the above configurations are complete, the mrc instruction to access ICC_HSRE should no longer result in an undefined instruction error. The following code demonstrates the correct usage:

mrc p15, 4, r7, c12, c9, 5 @ Read ICC_HSRE into r7

Step 5: Debugging and Validation

If the issue persists, perform the following debugging steps:

  1. Verify Exception Level: Use the CurrentEL register to confirm the current exception level. Ensure the system is in EL2 when accessing ICC_HSRE.

  2. Check GICv3 Support: Read the ID_PFR1 register to verify GICv3 support. The relevant fields should indicate GICv3 compatibility.

  3. Inspect GICR_WAKER: Ensure the GICR_WAKER register is properly initialized by reading its value after writing to it.

  4. Review EL3 Configuration: Double-check the ICC_MSRE or ICC_SRE_EL3 configuration to ensure the .Enable bit is set.


Summary of Key Fixes and Configurations

Step Description Register/Instruction
Boot into EL3 Ensure the system starts in EL3. CurrentEL
Set ICC_MSRE.Enable Enable GICv3 system register access in AArch32 EL3. mcr p15, 4, r7, c12, c9, 5
Set ICC_SRE_EL3.Enable Enable GICv3 system register access in AArch64 EL3. msr ICC_SRE_EL3, #0xF
Initialize GICR Interface Wake up the GICR redistributor by writing to GICR_WAKER. str w1, [x0, #0x14]
Configure ICC_SRE_EL2 Enable GICv3 system register access in AArch64 EL2 before switching to AArch32. msr ICC_SRE_EL2, #0xF
Access ICC_HSRE in AArch32 Read ICC_HSRE in AArch32 EL2 after proper configuration. mrc p15, 4, r7, c12, c9, 5

By following these steps, the undefined instruction error when accessing ICC_HSRE in AArch32 EL2 can be resolved. Proper configuration of the GICv3 system registers and initialization of the GICR interface are critical to ensuring reliable operation.

Similar Posts

Leave a Reply

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