PIC32MZ Exception Entry Points

The Reset, Soft Reset, and NMI exceptions are always vectored to location 0xBFC00000 (uncached, start-up safe KSEG1 region).

Addresses for all other exceptions are a combination of a vector base address and a vector offset.

Exception Vector "Base" Addresses

In MIPS32® Release 2 and higher architectures, the software is allowed to specify the vector base address via the CP0 Ebase register for exceptions that occur when CP0 StatusBEV equals 0.


MIPS32 architectures provide a Bootstrap mode (referred to as Boot-Exception Vector (BEV) mode) whereby exception entry points are reallocated into the uncached, start-up-safe KSEG1 region.

The CP0 Status register flag StatusBEV controls the Bootstrap mode.

  • StatusBEV = 1: Exceptions vector to an uncached entry point in KSEG1: 0xBFC00xxx.
  • StatusBEV = 0: Exceptions vector to cached entry points in KSEG0: defined by CP0 Ebase register, plus some offset.

Note: StatusBEV = 1 at reset.

The following table gives the vector base address as a function of the exception and whether the BEV bit is set in the Status register:


MPLAB® XC32 start-up code initializes Ebase to the value defined by the symbol _ebase_address in the PIC32MZ device linker script (for PIC32MZ2048EFG100, _ebase_address = 0x9D000000).

If Ebase is to be changed, it must be done with StatusBEV = 1 (i.e. at system boot). The operation of the CPU is UNDEFINED if Ebase is written when StatusBEV = 0.

Vector "Offsets"

Next, we have fixed vector offsets which are added to the above exception base addresses as a function of the exception:



Setting the CP0 CauseIV bit to 1 causes Interrupt exceptions to use a dedicated exception vector offset (0x200), rather than having to use the general exception vector offset (0x180).

MPLAB XC32 start-up code initializes CauseIV to 1.

"Final" Entry Point Addresses

As seen in the above table, PIC32MZ Interrupt exception vector addresses have an additional variable offset component which is added to Ebase to form the final entry point:

  • Variable Offset = OFFx register value (initialized by the C-Run-time startup for each defined Interrupt Service Routine (ISR), starting at 0x200).

We can now list the complete vector addresses for the most common exceptions (not incl. EJTAG or TLB exceptions):



MPLAB XC32 start-up code initializes Ebase to the value defined by the symbol _ebase_address in the PIC32MZ device linker script (for PIC32MZ2048EFG100, _ebase_address = 0x9D000000).

Therefore, for normal interrupt operations on PIC32MZ,

  • The Interrupt Exception Vector Base Address = 0x9D000000.
  • The Interrupt Exception Vector Final Address = 0x9D000000 + <OFFx> register value.


  • The first ISR's <OFFx> value is set to 0x200, and
  • Subsequent ISR vector offsets (<OFFx> value) are set according to the size of the handler function(s).

For an illustration, see the multi-vector example below.


Exception Level: Set by the processor when any exception other than Reset, Soft Reset, NMI or Cache Error exception is taken:

  • StatusEXL = 0: Normal level.
  • StatusEXL = 1: Exception level; when EXL is set.
    • The processor is running in Kernel mode.
    • Hardware and Software Interrupts are disabled.
    • EPC, BD, and SRSCtl will not be updated if another exception is taken.

Note: StatusEXL must be cleared by the exception handler in order to re-enable interrupts. MIPS CPUs have an instruction, eret, that both clears StatusEXL and returns control to the address stored in EPC.

Interrupt Exception Vectors

As discussed above, PIC32MZ interrupt controllers operating in Multi-Vector mode implement a Variable Offset mode for calculating the final interrupt vector address:

  • Interrupt Exception Vector Final Address = Ebase + OFFx

MPLAB XC32 Compiler calculates & initializes the values of OFFx for each defined application interrupt service routine (see table 7.2 in the PIC32MZ datasheet for a listing of OFFx registers for each interrupt source).

The first handler is assigned 0x200 for it's OFFx register. Subsequent handler OFFx registers are initialized based upon the size of the handler functions.

Handler functions linked directly to the vector will be executed faster than those linked as the target of a dispatch function (as done on PIC32MX).

Multi-Vector Example Using Timer 2 and Timer 4 Interrupts

A small project using Timer 2 and Timer 4 to blink 2 different LEDs at different rates produced the following results for the final exception vector addresses:


  • 0x9D000000 (initialized by the C-Run-time startup)

Timer 2 Vector Offset Register (OFF009):

  • 0x200 (initialized by the C-Run-time startup)

Timer 2 Interrupt Exception Vector Final Address:

  • 0x9D000000 + 0x200 = 0x9D000200

Timer 4 Vector Offset Register (OFF019):

  • 0x274 (initialized by the C-Run-time startup)

Timer 4 Interrupt Exception Vector Final Address:

  • 0x9D000000 + 0x274 = 0x9D000274
© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.