Configure the vector table

When any exception is taken, the processor must handle the exception correctly. This means that the processor must detect the type of exception, then branch to an appropriate handler.

Let’s look at the code in vectors.s. Here we can see how a vector table is configured to branch fiqFirstLevelHandler when an FIQ event occurs:

   .section  VECTORS,"ax"
   .align 12

   .global vectors
 vectors:

   .global fiqHandler

 // ------------------------------------------------------------
 // Current EL with SP0
 // ------------------------------------------------------------

   .balign 128
 sync_current_el_sp0:
   B        .                    //        Synchronous

   .balign 128
 irq_current_el_sp0:
   B        .                    //        IRQ

   .balign 128
 fiq_current_el_sp0:
   B        fiqFirstLevelHandler //        FIQ

   .balign 128
 serror_current_el_sp0:
   B        .                    //        SError

   //
   // NB, CODE OMITTED!
   //

fiqFirstLevelHandler:
  STP      x29, x30, [sp, #-16]!
  STP      x18, x19, [sp, #-16]!
  STP      x16, x17, [sp, #-16]!
  STP      x14, x15, [sp, #-16]!
  STP      x12, x13, [sp, #-16]!
  STP      x10, x11, [sp, #-16]!
  STP      x8, x9, [sp, #-16]!
  STP      x6, x7, [sp, #-16]!
  STP      x4, x5, [sp, #-16]!
  STP      x2, x3, [sp, #-16]!
  STP      x0, x1, [sp, #-16]!

  BL       fiqHandler

  LDP      x0, x1, [sp], #16
  LDP      x2, x3, [sp], #16
  LDP      x4, x5, [sp], #16
  LDP      x6, x7, [sp], #16
  LDP      x8, x9, [sp], #16
  LDP      x10, x11, [sp], #16
  LDP      x12, x13, [sp], #16
  LDP      x14, x15, [sp], #16
  LDP      x16, x17, [sp], #16
  LDP      x18, x19, [sp], #16
  LDP      x29, x30, [sp], #16
  ERET

In this case, only an FIQ entry and handler have been defined. In fact, fiqFirstLevelHandler merely branches to fiqHandler, a procedure that we will define later in C. Here, we have used the BL instruction, or branch with link, which branches to the given label. The BL instruction saves the current value of the program counter plus four bytes, the next instruction address, to register x30.

Our C procedure ends with a return statement which compiles to a RET instruction. By default (that is, if no other register is specified) RET branches to the address stored in register x30.

The handler also saves and restores all the general-purpose registers. This is because these registers may be modified by the procedure call.

The remaining entries branch to self, because the handlers have not been written. When you create your own image, you will need to define and configure your vector table to handle all required event types.

 

Previous Next