|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 18 – Fault Dispatcher & Precise Exceptions > 18.7 PAL Mode Entry |
All exception and interrupt delivery paths converge on AlphaCPU::enterPalMode(), which performs the atomic transition from normal execution to PAL handler code:
void enterPalMode(PalEntryReason reason, quint64 vector, quint64 faultPC) {
// 1. Save complete context
m_iprGlobalMaster->saveContext();
// 2. Compute entry PC
quint64 entryPC;
if (reason == PalEntryReason::CALL_PAL_INSTRUCTION)
entryPC = m_iprGlobalMaster->computeCallPalEntry(vector);
else
entryPC = vector;
// 3. Set EXC_ADDR to faulting PC
m_iprGlobalMaster->h->exc_addr = faultPC;
// 4. Enter PAL mode: IPL = 7, CM = KERNEL
m_iprGlobalMaster->h->pc = entryPC | 0x1; // low bit = PAL mode
m_iprGlobalMaster->h->setIPL_Unsynced(7);
m_iprGlobalMaster->h->setCM(CM_KERNEL);
// 5. Activate shadow registers for CALL_PAL
if (reason == CALL_PAL_INSTRUCTION)
m_iprGlobalMaster->setShadowEnabled(true);
// 6. Flush pipeline
m_alphaPipeline->flush("enterPalMode");
}
The state changes are atomic with respect to the CPU: EXC_ADDR receives the faulting PC, EXC_SUM is updated for arithmetic exceptions, processor status is updated (mode → kernel, IPL → 7, interrupts masked), and the pipeline is flushed. The low bit of the entry PC (| 0x1) is the architectural PAL mode indicator checked by the execution engine on every instruction.
PalEntryReason determines how the PAL vector is computed and what additional state is saved:
Reason |
Behavior |
|---|---|
CALL_PAL_INSTRUCTION |
Explicit PAL call; vector from PAL_BASE + dispatch offset; shadow registers activated |
FAULT |
Synchronous fault (translation, alignment, access violation); vector from exception dispatch |
TRAP |
Synchronous trap (arithmetic, software); vector from exception dispatch |
INTERRUPT |
Asynchronous interrupt; vector from interrupt dispatch table |
Invariant: All exception delivery paths call enterPalMode() with the appropriate PalEntryReason and PalVectorId. All interrupt delivery calls PalService::deliverInterrupt(). No exception handler exists outside PAL code.
See Also: cpuCoreLib/AlphaCPU.h – enterPalMode(); 7.9 Exception Delivery and PAL Mode Entry; Chapter 8 - PAL and Privileged Boundary.