|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 19 – Interrupt Architecture & IPI > 19.5 IPI Architecture |
EMulatR intentionally does not create a second interrupt system for IPIs. Instead, IPIs are injected into the same interrupt infrastructure as device and software interrupts. They use the same prioritization, masking, and PAL delivery rules. They differ only in source (another CPU) and payload (an IPICommand with encoded parameters). This avoids duplicated logic and preserves architectural clarity.
IPIManager (emulatrLib/IPIManager.h, ~192 lines) provides lock-free IPI message routing. Each CPU has an atomic IPI data slot (std::atomic<quint64>). The design uses latest-IPI-wins semantics, which matches Alpha hardware behavior — posting a new IPI overwrites any pending IPI that has not yet been read.
Key API:
postIPI(cpuId, ipiData) — stores atomically with memory_order_release. The source CPU writes the encoded IPI data into the target CPU's slot.
fetchIPI(cpuId) — atomically exchanges to zero with memory_order_acq_rel (read and clear). The target CPU reads and clears its IPI slot in a single atomic operation.
peekIPI(cpuId) — reads without clearing. Used for diagnostic inspection.
hasIPIPending(cpuId) — checks for non-zero data. Used by the CPU run loop to determine if IPI processing is needed.
IPI data is encoded as a quint64: the command byte occupies bits [63:56], and the parameter occupies bits [55:0]. The IPICommand enumeration (coreLib/IPI_core.h, ~245 lines) defines the complete command set:
Category |
Commands |
Range |
|---|---|---|
TLB Invalidation |
TLB_INVALIDATE_ALL (TBIA), TLB_INVALIDATE_ASN (TBIAP), TLB_INVALIDATE_VA_BOTH (TBIS), TLB_INVALIDATE_VA_ITB, TLB_INVALIDATE_VA_DTB |
0x01–0x07 |
Cache Coherency |
CACHE_INVALIDATE_LINE, CACHE_FLUSH_LINE, CACHE_EVICT_LINE, CACHE_INVALIDATE_ALL |
0x10–0x13 |
Memory Barriers |
MEMORY_BARRIER_FULL (MB), MEMORY_BARRIER_WRITE (WMB) |
0x20–0x22 |
Synchronization |
SYNC_REQUEST, SYNC_ACKNOWLEDGE |
0x30–0x31 |
System Control |
HALT_CPU, WAKE_CPU, CONTEXT_SWITCH |
0x40–0x42 |
Custom |
CUSTOM_BASE, CUSTOM |
0xF0–0xFF |
Helper functions encodeIPIData(), encodeIPIWithVA(), encodeIPIWithASN(), decodeIPICommand(), decodeIPIVA(), and decodeIPIASN() handle encoding and decoding of the 64-bit IPI data word.
When an IPI is delivered to the target CPU:
1. IRQPendingState signals the target CPU (IPI source asserted)
2. CPU enters PAL interrupt handler via checkInterrupts()
3. PAL calls handleTLBShootdownIPI(cpuId, ipiData)
4. decodeIPICommand(ipiData) extracts the command
5. Command-specific handler executes:
TLB_INVALIDATE_VA_ITB → m_tlb→invalidateTLBEntry(cpuId, Realm::I, va, asn)
TLB_INVALIDATE_VA_DTB → m_tlb→invalidateTLBEntry(cpuId, Realm::D, va, asn)
TLB_INVALIDATE_ALL → tbia(cpuId)
MEMORY_BARRIER_FULL → drain write buffer, acknowledge barrier
6. Optional acknowledgment sent to initiating CPU
7. HW_REI returns to normal execution
IPIs are never handled inline in normal execution. They always enter PAL mode for processing.
See Also: emulatrLib/IPIManager.h (~192 lines); coreLib/IPI_core.h (~245 lines); cpuCoreLib/AlphaCPU.h – handleTLBShootdownIPI(); 9.6 Inter-Processor Interrupts (IPIs).