|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 9 - SMP Architecture > 9.6 Inter-Processor Interrupts (IPIs) |
IPIs are the primary SMP coordination mechanism. They are used for TLB shootdowns, cache invalidation coordination, memory barrier completion signaling, CPU halt/wake, context switch requests, and cross-CPU synchronization.
IPI commands are defined by IPICommand (IPI_core.h, 245 lines). The full command set is organized by function:
enum class IPICommand : quint8 {
INVALID = 0x00,
// TLB Invalidation (0x01–0x07)
TLB_INVALIDATE_ALL = 0x01, // TBIA: all TLBs, all ASNs
TLB_INVALIDATE_ASN = 0x02, // TBIAP: by ASN (ITB+DTB)
TLB_INVALIDATE_VA_BOTH = 0x03, // TBIS: single VA (ITB+DTB)
TLB_INVALIDATE_VA_ITB = 0x04, // TBISI: single VA (ITB only)
TLB_INVALIDATE_VA_DTB = 0x05, // TBISD: single VA (DTB only)
TLB_INVALIDATE_GLOBAL = 0x06, // Reserved: global entries
TLB_INVALIDATE_RANGE = 0x07, // Reserved: VA range
// Cache Coherency (0x10–0x13)
CACHE_INVALIDATE_LINE = 0x10, // Invalidate cache line at PA
CACHE_FLUSH_LINE = 0x11, // Write-back + invalidate
CACHE_EVICT_LINE = 0x12, // ECB instruction
CACHE_INVALIDATE_ALL = 0x13, // Invalidate all caches
// Memory Barriers (0x20–0x22)
MEMORY_BARRIER_FULL = 0x20, // MB: full memory barrier
MEMORY_BARRIER_WRITE = 0x21, // WMB: write memory barrier
MEMORY_BARRIER_READ = 0x22, // Reserved: read barrier
// Synchronization (0x30–0x31)
SYNC_REQUEST = 0x30, // Request sync point
SYNC_ACKNOWLEDGE = 0x31, // Acknowledge sync
// System Control (0x40–0x42)
HALT_CPU = 0x40, // Halt target CPU
WAKE_CPU = 0x41, // Wake from halt
CONTEXT_SWITCH = 0x42, // Remote context switch
// Custom (0xF0–0xFF)
CUSTOM_BASE = 0xF0, // Custom command base
CUSTOM = 0xFF // Generic custom IPI
};
IPI data is encoded as a quint64: command byte in bits [63:56], parameter in bits [55:0]. Helper functions encodeIPIData(), encodeIPIWithVA(), encodeIPIWithASN(), decodeIPICommand(), decodeIPIVA(), and decodeIPIASN() handle encoding and decoding.
IPIManager (IPIManager.h, 192 lines) provides lock-free IPI message routing. Each CPU has an atomic IPI data slot (std::atomic<quint64>). Latest-IPI-wins semantics (Alpha behavior — posting overwrites any pending IPI).
Key API: postIPI(cpuId, ipiData) stores atomically with memory_order_release; fetchIPI(cpuId) atomically exchanges to zero with memory_order_acq_rel (read and clear); peekIPI(cpuId) reads without clearing; hasIPIPending(cpuId) checks for non-zero data.
IPIs are generated by one CPU (via MTPR_IPIR or WRIPIR PAL instructions), routed via IPIManager (lock-free atomic slots), delivered to the target CPU as interrupts (sampled by checkInterrupts()), and handled in PAL mode on the target CPU. IPIs follow the same delivery rules as other interrupts — masked by IPL, delivered at instruction boundaries.
See Also: coreLib/IPI_core.h; emulatrLib/IPIManager.h.