You copied the Doc URL to your clipboard.

AArch64 exception vector table

When an exception occurs, the processor must execute handler code that corresponds to the exception. The location in memory where the handler is stored is called the exception vector. In the ARM architecture, exception vectors are stored in a table, called the exception vector table.

Each Exception level has its own vector table, that is, there is one for each of EL3, EL2, and EL1. The table contains instructions to be executed, rather than a set of addresses. These would normally be branch instructions that direct the core to the full exception handler.

The exception vector table for EL1, for example, holds instructions for handling all types of exception that can occur at EL1, Vectors for individual exceptions are at fixed offsets from the beginning of the table. The virtual address of each table base is set by the Vector Based Address Registers: VBAR_EL3, VBAR_EL2 and VBAR_EL1.

Each entry in the vector table is 16 instructions long (in ARMv7-A and AArch32, each entry is only 4 bytes). This means that in AArch64 the top-level handler can be written directly in the vector table.

The base address is given by VBAR_ELn and each entry has a defined offset from this base address. Each table has 16 entries, with each entry being 128 bytes (32 instructions) in size. The table effectively consists of 4 sets of 4 entries. Which entry is used depends on several factors:

  • The type of exception (SError, FIQ, IRQ, or Synchronous)
  • If the exception is being taken at the same Exception level, the stack pointer to be used (SP0 or SPn)
  • If the exception is being taken at a lower Exception level, the Execution state of the next lower level (AArch64 or AArch32).

A typical vector table is shown below.

Address

Exception type

Description

VBAR_ELn + 0x000

Synchronous

Current EL with SP0

+ 0x080

IRQ/vIRQ

+ 0x100

FIQ/vFIQ

+ 0x180

SError/vSError

+ 0x200

Synchronous

Current EL with SPx

+ 0x280

IRQ/vIRQ

+ 0x300

FIQ/vFIQ

+ 0x380

SError/vSError

+ 0x400

Synchronous

Lower EL using AArch64

+ 0x480

IRQ/vIRQ

+ 0x500

FIQ/vFIQ

+ 0x580

SError/vSError

+ 0x600

Synchronous

Lower EL using AArch32

+ 0x680

IRQ/vIRQ

+ 0x700

FIQ/vFIQ

+ 0x780

SError/vSError

Considering an example might make this easier to understand.

If kernel code is executing at EL1 and an IRQ interrupt is signaled, an IRQ exception occurs. This particular interrupt is not associated with the hypervisor or secure environment and is also handled within the kernel, and the SPSel bit is set, so SP_EL1 is used.

Execution takes place, therefore, from address VBAR_EL1 + 0x280.

In the absence of LDR PC, [PC, #offset] in the ARMv8-A architecture, more instructions must be used for the destination to be read from a table of registers. The spacing of the vectors is designed to avoid cache pollution for typical sized instruction cache lines from vectors that are not being used. The Reset Address is a completely separate address, which is IMPLEMENTATION DEFINED, and is typically set by hardwired configuration within the core. This address is visible in the RVBAR_EL1/2/3 register.

Having a separate exception vector for each exception gives the flexibility for the OS or hypervisor to determine the AArch64 and AArch32 state of the lower Exception levels. The SP_ELn is used for exceptions generated from lower levels. However, the software can switch to use SP_EL0 inside the handler. When this mechanism is used, it facilitates access to the values from the thread in the handler.

The following code is for a typical vector table for EL3 vectors for exceptions in AArch64.

// Typical exception vector table code.
.balign 0x800
Vector_table_el3:
curr_el_sp0_sync:        // The exception handler for a synchronous 
                         // exception from the current EL using SP0.
.balign 0x80
curr_el_sp0_irq:         // The exception handler for an IRQ exception
                         // from the current EL using SP0.
.balign 0x80
curr_el_sp0_fiq:         // The exception handler for an FIQ exception
                         // from the current EL using SP0.
.balign 0x80
curr_el_sp0_serror:      // The exception handler for a System Error 
                         // exception from the current EL using SP0.
.balign 0x80
curr_el_spx_sync:        // The exception handler for a synchrous 
                         // exception from the current EL using the
                         // current SP.
.balign 0x80
curr_el_spx_irq:         // The exception handler for an IRQ exception from 
                         // the current EL using the current SP.

.balign 0x80
curr_el_spx_fiq:         // The exception handler for an FIQ from 
                         // the current EL using the current SP.

.balign 0x80
curr_el_spx_serror:      // The exception handler for a System Error 
                         // exception from the current EL using the
                         // current SP.

 .balign 0x80
lower_el_aarch64_sync:   // The exception handler for a synchronous 
                         // exception from a lower EL (AArch64).

.balign 0x80
lower_el_aarch64_irq:    // The exception handler for an IRQ from a lower EL
                         // (AArch64).

.balign 0x80
lower_el_aarch64_fiq:    // The exception handler for an FIQ from a lower EL
                         // (AArch64).

.balign 0x80
lower_el_aarch64_serror: // The exception handler for a System Error 
                         // exception from a lower EL(AArch64).

.balign 0x80
lower_el_aarch32_sync:   // The exception handler for a synchronous 
                         // exception from a lower EL(AArch32).
.balign 0x80
lower_el_aarch32_irq:    // The exception handler for an IRQ exception 
                         // from a lower EL (AArch32).
.balign 0x80
lower_el_aarch32_fiq:    // The exception handler for an FIQ exception from 
                         // a lower EL (AArch32).
.balign 0x80
lower_el_aarch32_serror: // The exception handler for a System Error
                         // exception from a lower EL(AArch32).
Was this page helpful? Yes No