Execution and Security states

The current state of an Armv8-A processor is determined by the Exception level and two other important states. The current Execution state defines the standard width of the general-purpose register and the available instruction sets. 

Execution state also affects aspects of the memory models and how exceptions are managed.

The current Security state controls which Exception levels are currently valid, which areas of memory can currently be accessed, and how those accesses are represented on the system memory bus. 

This diagram shows the Exception levels and Security states, with different Execution states being used:

This diagram shows Exception levels and Security states in Armv8-A.

Execution states

Armv8-A has two available Execution states:

  • AArch32: The 32-bit Execution state. Operation in this state is compatible with Armv7-A. There are two available instruction sets: T32 and A32. The standard register width is 32 bits.
  • AArch64: The 64-bit Execution state. There is one available instruction set: A64. The standard register width is 64 bits.
Security state

The Armv8-A architecture allows for implementation of two Security states. This allows a further partitioning of software to isolate and compartmentalize trusted software.

The two Security states are:

  • Secure state: In this state, a Processing Element (PE) can access both the Secure and Non-secure physical address spaces. In this state, the PE can access Secure and Non-secure System registers. Software running in this state can only acknowledge Secure interrupts.
  • Non-secure state: In this state, a PE can only access the Non-secure physical address space. The PE can also only access System registers that allow non-secure accesses. Software running in this state can only acknowledge Non-secure interrupts.

The uses of these Security states will be described in more detail in our guide TrustZone for Armv8-A.

Changing Execution state

A PE can only change Execution state on reset or when the Exception level changes.

The Execution state on reset is determined by an IMPLEMENTATION DEFINED mechanism. Some implementations fix the Execution state at reset. For example, Cortex-A32 will always reset into AArch32 state. In most implementations of Armv8-A, the Executions state after reset is controlled by a signal that is sampled at reset. This allows the reset Execution state to be controlled at the system-on-chip level.

When the PE changes between Exception levels, it is also possible to change Execution state. Transitioning between AArch32 and AArch64 is only allowed subject to certain rules.

  • When moving from a lower Exception level to a higher level, the Execution state can stay the same or change to AArch64.
  • When moving from a higher Exception level to a lower level, the Execution state can stay the same or change to AArch32.

Putting these two rules together means that a 64-bit layer can host a 32-bit layer, but not the other way around. For example, a 64-bit OS kernel can host both 64-bit and 32-bit applications, while a 32-bit OS kernel could only host 32-bit applications. This is illustrated here:

 This diagram relates to Security states in Armv8-A. 

In this example we have used an OS and applications, but the same rules apply to all Exception levels. For example, a 32-bit hypervisor at EL2 could only host 32-bit virtual machines at EL1.

Changing Security state

EL3 is always considered to be executing in Secure state. Using SCR_EL3, EL3 code can change the Security state of all lower Exception levels. If software uses SCR_EL3 to change the Security state of the lower Exception levels, the PE will not change Security state until it changes to a lower Exception level. 

Changing Security state will be discussed in more detail in our guide TrustZone for Armv8-A.

Implemented Exception levels and Execution states

The Armv8-A architecture allows an implementation to choose whether all Exception levels are implemented, and to choose which Execution states are allowed for each implemented Exception level.

EL0 and EL1 are the only Exception levels that must be implemented. EL2 and EL3 are optional. Choosing not to implement EL3 or EL2 has important implications. 

EL3 is the only level that can change Security state. If an implementation chooses not to implement EL3, that PE would not have access to a single Security state. 

Similarly, EL2 contains much of the virtualization functionality. Implementations that do not have EL2 have access to these features. All current Arm implementations of the architecture implement all Exception levels, and it would be impossible to use most standard software without all Exception levels.

An implementation can also choose which Execution states are valid for each Exception level. If AArch32 is allowed at an Exception level, it must be allowed all lower Exception levels. For example, if EL3 allows AArch32, then it must be allowed at all lower Exception levels.

Many implementations allow all Executions states and all Exception levels, but there are existing implementations with limitations. For example, Cortex-A32 only allows AArch32 at any Exception level. 

Some modern implementations, such as Cortex-A55, implement all Exception levels but only allow AArch32 at EL0. The other exception levels, EL1, EL2, and EL3, must be AArch64.

Previous Next