TrustZone in the processor

In this topic, we discuss support for TrustZone within the processor. Other sections cover support in the memory system and the software story that is built on the processor and memory system support.

Security states

In the Arm architecture, there are two Security states: Secure and Non-secure. These Security states map onto the Trusted and Normal worlds that we referred to in What is TrustZone?

At EL0, EL1, and EL2 the processor can be in either Secure state or Non-secure state, which is controlled by the SCR_EL3.NS bit. You often see this written as:

  • NS.EL1: Non-secure state, Exception level 1
  • S.EL1: Secure state, Exception level 1

EL3 is always in Secure state, regardless of the value of the SCR_EL3.NS bit. The arrangement of Security states and Exception levels is shown here:

Note: Support for Secure EL2 was first introduced in Armv8.4-A and support remains optional in Armv8-A.

Switching between security states

If the processor is in NS.EL1 and software wants to move into S.EL1, how does it do this?

To change Security state, in either direction, execution must pass through EL3, as shown in the following diagram:

The preceding diagram shows an example sequence of the steps involved in moving between Security states. Taking these one step at a time:

  1. Entering a higher Exception level requires an exception. Typically, this exception would be an FIQ or an SMC (Secure Monitor Call) exception. We look at interrupt handling and SMCs in more detail later.
  2. EL3 is entered at the appropriate exception vector. Software that is running in EL3 toggles the SCR_EL3.NS bit.
  3. An exception return then takes the processor from EL3 to S.EL1.

There is more to changing Security state than just moving between the Exception levels and changing the SCR_EL3.NS bit. We also must consider processor state.

There is only one copy of the vector registers, the general-purpose registers, and most System registers. When moving between Security states it is the responsibility of software, not hardware, to save and restore register state. By convention, the piece of software that does this is called the Secure Monitor. This makes our earlier example look more like what you can see in the following diagram:

Trusted Firmware, an open-source project that Arm sponsors, provides a reference implementation of a Secure Monitor. We will discuss Trusted Firmware later in the guide.

A small number of registers are banked by Security state. This means that there are two copies of the register, and the core automatically uses the copy that belongs to the current Security state. These registers are limited to the ones for which the processor needs to know both settings at all times. An example is ICC_BPR1_EL1, a GIC register that is used to control interrupt preemption. Banking is the exception, not the rule, and will be explicitly called out in the Architecture Reference Manual for your processor.

When a System register is banked, we use (S) and (NS) to identify which copy we are referring to. For example, ICC_BPR1_EL1(S) and ICC_BPR1_EL1(NS).

Note: In Armv6 and Armv7-A most System registers are banked by Security state, but general-purpose registers and vector registers are still common.

Virtual address space

The memory management guide in this series introduced the idea of multiple virtual address spaces, or translation regimes. For example, there is a translation regime for EL0/1 and a separate translation regime for EL2, shown here:

There are also separate translation regimes for the Secure and Non-secure states. For example, there is a Secure EL0/1 translation regime and Non-secure EL0/1 translation regime, which is shown here:

When writing addresses, it is convention to use prefixes to identify which translation regime is being referred to:

  • NS.EL1:0x8000 - Virtual address 0x8000 in the Non-secure EL0/1 translation regime
  • S.EL1:0x8000 - Virtual address 0x8000 in the Secure EL0/1 translation regime

It is important to note that S.EL1:0x8000 and NS.EL1:0x8000 are two different and independent virtual addresses. The processor does not use a NS.EL1 translation while in Secure state, or a S.EL1 translation while in Non-secure state.

Physical address spaces

In addition to two Security states, the architecture provides two physical address spaces: Secure and Non-secure.

While in Non-secure state, virtual addresses always translate to Non-secure physical addresses. This means that software in Non-secure state can only see Non-secure resources, but can never see Secure resources.  This is illustrated here:

While in Secure state, software can access both the Secure and Non-secure physical address spaces. The NS bit in the translation table entries controls which physical address space a block or page of virtual memory translates to, as shown in the following diagram:

Note: In Secure state, when the Stage 1 MMU is disabled all addresses are treated as Secure.

Like with virtual addresses, typically prefixes are used to identify which address space is being referred to. For physical addresses, these prefixes are NP: and SP:. For example:

  • NP:0x8000 – Address 0x8000 in the Non-secure physical address space
  • SP:0x8000 – Address 0x8000 in the Secure physical address space

It is important to remember that Secure and Non-secure are different address spaces, not just an attribute like readable or writable. This means that NP:0x8000 and SP:0x8000 in the preceding example are different memory locations and are treated as different memory locations by the processor.

Note: It can helpful to think of the address space as an extra address bit on the bus.

Data, instruction, and unified caches

In the Arm architecture, data caches are physically tagged. The physical address includes which address space the line is from, shown here:

A cache lookup on NP:0x800000 never hits on a cache line that is tagged with SP:0x800000. This is because NP:0x800000 and SP:0x800000 are different addresses.

This also affects cache maintenance operations. Consider the example data cache in the preceding diagram. If the virtual address va1 maps to physical address 0x800000, what happens when software issues DC IVAC, va1 (Data or unified Cache line Invalidate by Virtual Address) from Non-secure state?

The answer is that in Non-secure state, all virtual addresses translate to Non-secure physical addresses. Therefore, va1 maps to NP:0x800000. The cache only operates on the line containing the specified address, in this case NP:0x800000. The line containing SP:0x800000 is unaffected.

Check your knowledge

For set/way operations, for example DC ISW, Xt, operations that are issued in Non-secure state will only affect lines containing Non-secure addresses. From Secure state set/way operations affect lines containing both Secure and Non-secure addresses.

This means that software can completely invalidate or clean the entire cache only in Secure state. From Non-secure state, software can only clean or invalidate Non-secure data.

Translation Look aside Buffer

Translation Look aside Buffer (TLBs) cache recently used translations. The processor has multiple independent translation regimes. The TLB records which translation regime, including the Security state, an entry represents. While the structure of TLBs is implementation defined, the following diagram shows an example:

When software issues a TLB invalidate operation (TLBI instruction) at EL1 or EL2, the software targets the current Security state. Therefore, TLBI ALLE1 from Secure state invalidates all cached entries for the S.EL0/1 translation regime.

EL3 is a special case. As covered earlier in Security states, when in EL0/1/2 the SCR_EL3.NS bit controls which Security state the processor is in. However, EL3 is always in Secure state, regardless of the SCR_EL3.NS bit. When in EL3, SCR_EL3.NS lets software control which Security state TLBIs operate on.

For example, executing TBLI ALLE1 at EL3 with:

  • SCR_EL3.NS==0: Affects Secure EL0/1 translation regime
  • SCR_EL3.NS==1: Affects Non-secure EL0/1 translation regime

SMC exceptions

As part of the support for two Security states, the architecture includes the Secure Monitor Call (SMC) instruction. Executing SMC causes a Secure Monitor Call exception, which targets EL3.

SMC's are normally used to request services, either from firmware resident in EL3 or from a service that is hosted by the Trusted Execution Environment. The SMC is initially taken to EL3, where an SMC dispatcher determines which entity the call will be handled by. This is shown in the following diagram:


In a bid to standardize interfaces, Arm provides the SMC Calling Convention (DEN0028) and Power State Coordination Interface Platform Design Document (DEN0022). These specifications lay out how SMCs are used to request services.

Execution of an SMC at EL1 can be trapped to EL2. This is useful for hypervisors, because hypervisors might want to emulate the firmware interface that is seen by a virtual machine.

Note: The SMC instruction is not available at EL0 in either Security state.

We discuss exceptions later in System architecture when we look at the interrupt controller.

Secure virtualization

When virtualization was first introduced in Armv7-A, it was only added in the Non-secure state. Until Armv8.3, the same was true for Armv8 as illustrated in the following diagram:

As previously described in TrustZone in the processor, EL3 is used to host firmware and the Secure Monitor. Secure EL0/1 host the Trusted Execution Environment (TEE), which is made up of the Trusted services and kernel.

There was no perceived need for multiple virtual machines in Secure state. This means that support for virtualization was not necessary. As TrustZone adoption increased, several requirements became apparent:

  • Some trusted services were tied to specific trusted kernels. For a device to support multiple services, it might need to run multiple trusted kernels.
  • Following the principle of running with least privilege, moving some of the firmware functionality out of EL3 was required.

The solution was to introduce support for EL2 in Secure state, which came with Armv8.4-A, as you can see in this diagram:

Rather than a full hypervisor, S.EL2 typically hosts a Secure Partition Manager (SPM). An SPM allows the creation of the isolated partitions, which are unable to see the resources of other partitions. A system could have multiple partitions containing Trusted kernels and their Trusted services.

A partition can also be created to house platform firmware, removing the need to have that code that is run at EL3.

  • Enabling Secure EL2
    When S.EL2 is supported, it can be enabled or disabled. Whether S.EL2 is enabled is controlled by the SCR_EL3.EEL2 bit:
    • 0: S.EL2 disabled, behavior is as on a processor not supporting S.EL2
    • 1: S.EL2 enabled

  • Stage 2 translation in Secure state
    In Secure state, the Stage 1 translation of the Virtual Machine (VM) can output both Secure and Non-secure addresses and is controlled by the NS bit in the translation table descriptors. This results in two IPA spaces, Secure and Non-secure, each with its own set of Stage 2 translation tables as you can see in the following diagram:

    Unlike the Stage 1 tables, there is no NS bit in the Stage 2 table entries. For a given IPA space, all the translations either result in a Secure or Non-secure physical address, which is controlled by a register bit. Typically, the Non-secure IPAs translate to Non-secure PAs and the Secure IPAs translate to Secure PAs.
Previous Next