<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE register_page SYSTEM "registers.dtd">
<!-- Copyright (c) 2010-2026 Arm Limited or its affiliates. All rights reserved. -->
<!-- This document is Non-Confidential. This document may only be used and distributed in accordance with the terms of the agreement entered into by Arm and the party that Arm delivered this document to. -->
<!--The data contained in this document is preliminary and subject to change or correction following further review. -->
<?xml-stylesheet href="one_register.xsl" type="text/xsl" ?>







<register_page>
  <registers>
  
    <register execution_state="AArch64" is_register="True" is_internal="True" is_stub_entry="False">
      <reg_short_name>ELR_EL2</reg_short_name>
        
        <reg_long_name>Exception Link Register (EL2)</reg_long_name>



      
            <reg_condition otherwise="UNDEFINED">when FEAT_AA64 is implemented</reg_condition>
      




          <reg_reset_value></reg_reset_value>

      <reg_mappings>
        



    
      
      <reg_mapping>
        
  

    

  

    <mapped_name filename="AArch32-elr_hyp.xml">ELR_hyp</mapped_name>
  <mapped_type>Architectural</mapped_type>
      <mapped_execution_state>AArch32</mapped_execution_state>
    <mapped_from_startbit>31</mapped_from_startbit>
    <mapped_from_endbit>0</mapped_from_endbit>
    <mapped_to_startbit>31</mapped_to_startbit>
    <mapped_to_endbit>0</mapped_to_endbit>
    <mapped_from_rangeset output="31:0">
      <range>
        <msb>31</msb>
        <lsb>0</lsb>
      </range>
    </mapped_from_rangeset>
    <mapped_to_rangeset output="31:0">
      <range>
        <msb>31</msb>
        <lsb>0</lsb>
      </range>
    </mapped_to_rangeset>

      </reg_mapping>

      </reg_mappings>

        <reg_purpose>
          
    
      <purpose_text>
        <para>When taking an exception to EL2, holds the address to return to.</para>
      </purpose_text>

        </reg_purpose>

      <reg_groups>
          <reg_group>Special</reg_group>
      </reg_groups>
      <reg_configuration>
        
    
      <configuration_text>
        <para>This register has no effect if EL2 is not enabled in the current Security state.</para>
      </configuration_text>

      </reg_configuration>
      
      
        
      <reg_attributes>
          
    
      <attributes_text>
        <para>ELR_EL2 is a 64-bit register.</para>
      </attributes_text>

      </reg_attributes>
      <reg_fieldsets>
        






<fields id="fieldset_0" length="64">
  <text_before_fields/>
  <field id="fieldset_0-63_0" has_partial_fieldset="False" is_linked_to_partial_fieldset="False" is_access_restriction_possible="False" is_variable_length="False" is_constant_value="False" is_partial_field="False" is_conditional_field_name="False">
    <field_name>ADDR</field_name>
    <field_shortdesc>Return address</field_shortdesc>
    <field_msb>63</field_msb>
    <field_lsb>0</field_lsb>
    <rel_range>63:0</rel_range>
    <field_description order="before"><para>Return address.</para>
<para>An exception return from EL2 using AArch64 makes ELR_EL2 become <arm-defined-word>UNKNOWN</arm-defined-word>.</para>
<para>When EL2 is in AArch32 Execution state and an exception is taken from EL0, EL1, or EL2 to EL3 and AArch64 execution, the upper 32-bits of ELR_EL2 are either set to 0 or hold the same value that they did before AArch32 execution. Which option is adopted is determined by an implementation, and might vary dynamically within an implementation. Correspondingly software must regard the value as being an <arm-defined-word>UNKNOWN</arm-defined-word> choice between the two values.</para></field_description>
    <field_resets>
      <field_reset reset_type="Warm">
        <field_reset_standard_text>AU</field_reset_standard_text>
      </field_reset>
    </field_resets>
  </field>
  <text_after_fields/>
</fields>




<reg_fieldset length="64">
  <fieldat id="fieldset_0-63_0" msb="63" lsb="0"/>
</reg_fieldset>


      </reg_fieldsets>

      <access_mechanisms>
          


  
    
      <access_permission_text>
        <para>When the Effective value of <register_link state="AArch64" id="AArch64-hcr_el2.xml">HCR_EL2</register_link>.E2H is 1, without explicit synchronization, accesses from EL2 using the accessor name <value>ELR_EL2</value> or <value>ELR_EL1</value> are not guaranteed to be ordered with respect to accesses using the other accessor name.</para>
      </access_permission_text>





    
        
        <access_mechanism accessor="MRS ELR_EL2" type="SystemAccessor">
            <encoding>
            <access_instruction>MRS &lt;Xt&gt;, ELR_EL2</access_instruction>
                
                <enc n="op0" v="0b11"/>
                
                <enc n="op1" v="0b100"/>
                
                <enc n="CRn" v="0b0100"/>
                
                <enc n="CRm" v="0b0000"/>
                
                <enc n="op2" v="0b001"/>
            </encoding>
            <access_permission>
                <ps name="MRS" sections="1" secttype="access_permission">
                <pstext>
if !IsFeatureImplemented(FEAT_AA64) then
    Undefined();
elsif PSTATE.EL == EL0 then
    Undefined();
elsif PSTATE.EL == EL1 then
    if EffectiveHCR_EL2_NVx() IN {'1x1'} then
        X{64}(t) = ELR_EL1();
    elsif EffectiveHCR_EL2_NVx() IN {'xx1'} then
        AArch64_SystemAccessTrap(EL2, 0x18);
    else
        Undefined();
    end;
elsif PSTATE.EL == EL2 then
    X{64}(t) = ELR_EL2();
elsif PSTATE.EL == EL3 then
    X{64}(t) = ELR_EL2();
end;
                </pstext>
                </ps>
            </access_permission>
        </access_mechanism>
    
        
        <access_mechanism accessor="MSRregister ELR_EL2" type="SystemAccessor">
            <encoding>
            <access_instruction>MSR ELR_EL2, &lt;Xt&gt;</access_instruction>
                
                <enc n="op0" v="0b11"/>
                
                <enc n="op1" v="0b100"/>
                
                <enc n="CRn" v="0b0100"/>
                
                <enc n="CRm" v="0b0000"/>
                
                <enc n="op2" v="0b001"/>
            </encoding>
            <access_permission>
                <ps name="MSRregister" sections="1" secttype="access_permission">
                <pstext>
if !IsFeatureImplemented(FEAT_AA64) then
    Undefined();
elsif PSTATE.EL == EL0 then
    Undefined();
elsif PSTATE.EL == EL1 then
    if IsFeatureImplemented(FEAT_GCS) &amp;&amp; GetCurrentEXLOCKEN() &amp;&amp; !Halted() &amp;&amp; PSTATE.EXLOCK == '1' &amp;&amp; EffectiveHCR_EL2_NVx() IN {'xx1'} then
        EXLOCKException();
    elsif EffectiveHCR_EL2_NVx() IN {'1x1'} then
        ELR_EL1() = X{64}(t);
    elsif EffectiveHCR_EL2_NVx() IN {'xx1'} then
        AArch64_SystemAccessTrap(EL2, 0x18);
    else
        Undefined();
    end;
elsif PSTATE.EL == EL2 then
    if IsFeatureImplemented(FEAT_GCS) &amp;&amp; GetCurrentEXLOCKEN() &amp;&amp; !Halted() &amp;&amp; PSTATE.EXLOCK == '1' then
        EXLOCKException();
    else
        ELR_EL2() = X{64}(t);
    end;
elsif PSTATE.EL == EL3 then
    ELR_EL2() = X{64}(t);
end;
                </pstext>
                </ps>
            </access_permission>
        </access_mechanism>
    
        
        <access_mechanism accessor="MRS ELR_EL1" type="SystemAccessor">
            <encoding>
            <access_instruction>MRS &lt;Xt&gt;, ELR_EL1</access_instruction>
                
                <enc n="op0" v="0b11"/>
                
                <enc n="op1" v="0b000"/>
                
                <enc n="CRn" v="0b0100"/>
                
                <enc n="CRm" v="0b0000"/>
                
                <enc n="op2" v="0b001"/>
            </encoding>
            <access_condition>
When FEAT_VHE is implemented
            </access_condition>
            <access_permission>
                <ps name="MRS" sections="1" secttype="access_permission">
                <pstext>
if !IsFeatureImplemented(FEAT_AA64) then
    Undefined();
elsif PSTATE.EL == EL0 then
    Undefined();
elsif PSTATE.EL == EL1 then
    if EffectiveHCR_EL2_NVx() == '011' then
        AArch64_SystemAccessTrap(EL2, 0x18);
    elsif EffectiveHCR_EL2_NVx() IN {'111'} then
        X{64}(t) = NVMem(0x230);
    else
        X{64}(t) = ELR_EL1();
    end;
elsif PSTATE.EL == EL2 then
    if ELIsInHost(EL2) then
        X{64}(t) = ELR_EL2();
    else
        X{64}(t) = ELR_EL1();
    end;
elsif PSTATE.EL == EL3 then
    X{64}(t) = ELR_EL1();
end;
                </pstext>
                </ps>
            </access_permission>
        </access_mechanism>
    
        
        <access_mechanism accessor="MSRregister ELR_EL1" type="SystemAccessor">
            <encoding>
            <access_instruction>MSR ELR_EL1, &lt;Xt&gt;</access_instruction>
                
                <enc n="op0" v="0b11"/>
                
                <enc n="op1" v="0b000"/>
                
                <enc n="CRn" v="0b0100"/>
                
                <enc n="CRm" v="0b0000"/>
                
                <enc n="op2" v="0b001"/>
            </encoding>
            <access_condition>
When FEAT_VHE is implemented
            </access_condition>
            <access_permission>
                <ps name="MSRregister" sections="1" secttype="access_permission">
                <pstext>
if !IsFeatureImplemented(FEAT_AA64) then
    Undefined();
elsif PSTATE.EL == EL0 then
    Undefined();
elsif PSTATE.EL == EL1 then
    if IsFeatureImplemented(FEAT_GCS) &amp;&amp; GetCurrentEXLOCKEN() &amp;&amp; !Halted() &amp;&amp; PSTATE.EXLOCK == '1' &amp;&amp; !(EffectiveHCR_EL2_NVx() IN {'x11'}) then
        EXLOCKException();
    elsif EffectiveHCR_EL2_NVx() == '011' then
        AArch64_SystemAccessTrap(EL2, 0x18);
    elsif EffectiveHCR_EL2_NVx() IN {'111'} then
        NVMem(0x230) = X{64}(t);
    else
        ELR_EL1() = X{64}(t);
    end;
elsif PSTATE.EL == EL2 then
    if IsFeatureImplemented(FEAT_GCS) &amp;&amp; GetCurrentEXLOCKEN() &amp;&amp; !Halted() &amp;&amp; PSTATE.EXLOCK == '1' &amp;&amp; ELIsInHost(EL2) then
        EXLOCKException();
    elsif ELIsInHost(EL2) then
        ELR_EL2() = X{64}(t);
    else
        ELR_EL1() = X{64}(t);
    end;
elsif PSTATE.EL == EL3 then
    ELR_EL1() = X{64}(t);
end;
                </pstext>
                </ps>
            </access_permission>
        </access_mechanism>

      </access_mechanisms>

      <arch_variants>
      </arch_variants>
  </register>
</registers>
<timestamp>2026-03-26 20:27:25</timestamp>
<commit_id>2026-03_rel</commit_id>
</register_page>