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:
- 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
MRCto CP15, exception from FP operation,
SMCexecuted, Data Aborts, and alignment exceptions). For example, EC =
101111is an SError interrupt.
- Bit  (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 (
SMC) is executed, the field contains the immediate value that is associated with the opcode such as
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.
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
instruction. This allows applications to generate an exception. Parameters can be passed
in registers, or coded within the System call.
at EL0 requests memory using
System calls to EL2/EL3
SVC instructions can be used to call from user applications
at EL0 to the kernel at EL1. The
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
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.
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.