18.4 FaultDispatcher Implementation

<< Click to Display Table of Contents >>

Navigation:  ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 18 – Fault Dispatcher & Precise Exceptions >

18.4 FaultDispatcher Implementation

18.4.1 Per-CPU Authority

 

There is one FaultDispatcher per CPU, accessed via globalFaultDispatcher(cpuId). The FaultDispatcher is the central authority for managing exceptional events on its CPU. It decouples detection from delivery: faults are queued when detected (in EX stage) and delivered when the pipeline reaches a safe state (in WB stage). No other component may deliver exceptions or modify event state.

 


 

18.4.2 Pending Flags (Hot Path)

 

The FaultDispatcher's eventPending() method is the hottest path in the emulator — it is called every cycle by the CPU run loop. The implementation uses a simple bitfield check with no atomics (the FaultDispatcher is per-CPU and only accessed by its owning CPU thread):

 

bool eventPending() const noexcept {

 return m_pendingFlags != 0; // ~1 cycle, no atomic

}

 

The pending flags are a bitmask tracking event categories:

 

FLAG_NONE = 0x00

FLAG_EXCEPTION = 0x01 // Generic exception

FLAG_ARITHMETIC_TRAP = 0x02 // Arithmetic trap (for TRAPB)

FLAG_DTB_MISS = 0x04 // Data TLB miss

FLAG_ITB_MISS = 0x08 // Instruction TLB miss

FLAG_INTERRUPT = 0x10 // Interrupt pending

FLAG_MACHINE_CHECK = 0x20 // Machine check (highest)

 

Specialized query methods test individual flags: hasPendingArithmeticTraps() (FLAG_ARITHMETIC_TRAP, used by TRAPB), hasPendingTLBFaults() (DTB/ITB), hasPendingInterrupt(), hasPendingMachineCheck(). These provide zero-cost queries for barrier release decisions without examining the full PendingEvent structure.

 


 

18.4.3 Event Queueing and Clearing

 

setPendingEvent(event) stores the PendingEvent and sets the appropriate flag bits. If a higher-priority event is already pending, the lower-priority event is held until the higher-priority event clears. clearPendingEvents() resets both the PendingEvent structure and the flag bitmask to zero. clearArithmeticTrap() selectively clears only the arithmetic trap flag and, if the pending event is of Arithmetic class, clears the event as well — this allows TRAPB to drain arithmetic traps while leaving other events pending.

 


 

18.4.4 Delivery Preparation

 

When the pipeline is ready to deliver an event (faulting instruction at WB stage, or interrupt sampling point), the FaultDispatcher performs delivery preparation:

 

// 1. Map ExceptionClass → PalVectorId

ev.palVectorId = ExceptionMapping_inl::mapClassToPalVector(ev);

 

// 2. Validate mapping

if (ev.palVectorId == PalVectorId::INVALID) → internal error

 

// 3. Look up PAL vector entry

const PalVectorEntry* entry = globalPALVectorTable().lookup(ev.palVectorId);

 

// 4. Enter PAL mode with resolved vector

enterPalMode(reason, entry->entryPC, ev.faultPC);

 

The vector resolution is a two-step lookup: ExceptionMapping_inl::mapClassToPalVector() maps the ExceptionClass_EV6 to a PalVectorId_EV6, and PalVectorTable::lookup() returns the PalVectorEntry containing the entry PC, target IPL, and entry conditions. This two-step design allows the classification and vector table to evolve independently.

 

See Also: faultLib/FaultDispatcher.h (~449 lines); exceptionLib/ExceptionMapping_inl.h – mapClassToPalVector(); palLib_EV6/PalVectorId_refined.h – PalVectorId enumeration; palLib_EV6/PalVectorTable_final.h – PAL vector table.