You copied the Doc URL to your clipboard.

Synchronous and asynchronous exceptions

In AArch64, exceptions can be either synchronous, or asynchronous.

  • An exception is described as synchronous if it is generated because of execution or attempted execution of the instruction stream, and where the return address provides details of the instruction that caused it.
  • Otherwise, an exception is described as asynchronous.

Sources of asynchronous exceptions are IRQ, FIQ, or SError (System Error). System errors have several possible causes, the most common being asynchronous Data Aborts (for example, an abort that is triggered by write-back of dirty data from a cache line to external memory).

Handling synchronous exceptions

The Exception Syndrome Register (ESR_ELn) and The Fault Address Register (FAR_ELn) are provided to supply information to exception handlers about the cause of a synchronous exception. The ESR_ELn gives information about the reasons for the exception, while the FAR_ELn holds the faulting virtual address for all synchronous instruction and Data Aborts and alignment faults. The Exception Link Register (ELR_ELn) also holds the address of the instruction that caused the aborting data access (for Data Aborts). These are updated after a memory fault, but are set in other circumstances, for example, by branching to a misaligned address.

If an exception is taken from an Exception level in AArch32 into an Exception level using AArch64, and the exception writes the Fault Address Register that is associated with the target Exception level, the top 32 bits of the FAR_ELn are all set to zero.

For systems which implement EL2 (Hypervisor) or EL3 (Secure Kernel), Synchronous exceptions are normally taken in the current or a higher Exception level. Asynchronous exceptions can (if necessary), be routed to a higher Exception level to be dealt with by a Hypervisor or Secure kernel. The SCR_EL3 register specifies which exceptions are routed to EL3 and similarly, HCR_EL2 specifies which exceptions are routed to EL2. There are separate bits that allow individual control over routing of IRQ, FIQ, and SError.

The Exception Syndrome Register

The Exception Syndrome Register, ESR_ELn, contains information that allows the exception handler to determine the reason for the exception. It is updated only for synchronous exceptions and SError. It is not updated for IRQ or FIQ as these interrupt handlers typically obtain status information from registers in the Generic Interrupt Controller (GIC).

The bit coding for the register is:

exception_syndrom_reg.png
  • Bits [31:26] (ESR_ELEC) indicate the exception class which enables the handler to distinguish between the various possible exception causes (such as unallocated instruction, exceptions from MCR or MRC to CP15, exception from FP operation, SVC, HVC or SMC executed, Data Aborts, and alignment exceptions). For example, EC = 101111 is an SError interrupt.
  • Bit [25] (ESR_ELn.IL) indicates the length of the trapped instruction (0 for a 16-bit instruction or 1 for a 32-bit instruction) and is set for certain exception classes.
  • Bits [24:0] (ESR_ELn.ISS) form the Instruction Specific Syndrome (ISS) field containing information specific to that exception type. For example, when a system call instruction (SVC, HVC or SMC) is executed, the field contains the immediate value that is associated with the opcode such as 0x123456 for SVC.

Unallocated instructions

Unallocated instructions cause a Synchronous Abort in AArch64. This exception type is generated when the processor executes one of the following:

  • An instruction opcode that is not allocated.
  • An instruction that requires a higher level of privilege than the current Exception level.
  • An instruction that has been disabled.
  • Any instruction when the PSTATE.IL field is set.

System calls

Some instructions or system functions can only be carried out at a specific Exception level. For example, if code running at a lower Exception level has to perform a privileged operation, such as when application code requests functionality from the kernel. One way to do this is by using the SVC instruction. This allows applications to generate an exception. Parameters can be passed in registers, or coded within the System call.

For example:

Application code at EL0 requests memory using malloc()

calls_using_malloc.png

System calls to EL2/EL3

SVC instructions can be used to call from user applications at EL0 to the kernel at EL1. The HVC and SMC system-call instructions move the processor in a similar fashion to EL2 and EL3. When the processor is executing at EL0 (Application), it cannot call directly into the hypervisor (EL2) or Secure monitor (EL3). This is only possible from EL1 and above. Applications must therefore use SVC to call into kernel and allow the kernel to call into higher Exception levels on their behalf.

From the OS kernel (EL1), software can call the hypervisor (EL2) with the HVC instruction, or call the Secure monitor (EL3) with the SMC instruction. If the processor is implemented with EL3, the ability to have EL2 trap SMC instructions from EL1 is provided. If there is no EL3, the SMC is unallocated and triggers at the current Exception level.

system_calls.png

Similarly, from hypervisor code (EL2), the program can call the Secure monitor (EL3) with the SMC instruction. If you make an SMC call when in EL2 or EL3, it still causes a synchronous exception at the same Exception level, and the handler for that Exception level can decide how to respond.

Was this page helpful? Yes No