FABRIC-3.10.8 MC-3b: waking a worker core

Each worker core sets up its own IPI receiver before going online (amd64
LAPIC + vector 0x22 with its own stub, aarch64 banked GIC SGI 0, riscv64
sie.SSIE); core 0 sends by ICR / GICD_SGIR / SBI IPI. Park lets exactly
one interrupt in without a lost-wake window. Boot self-test: IPI round
trips 3/3 and 'woke x3, IPIs x3' on all three ISAs; worker vCPU threads
0.0% on the host. 3-ISA acceptance clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-26 16:31:01 -04:00
co-authored by Claude Opus 5.5
parent d7745b49be
commit 71e0be96b0
24 changed files with 46016 additions and 8 deletions
+33
View File
@@ -380,6 +380,39 @@ void apic_eoi_intid(uint32_t intid)
mmio_write32(s_gicc_base, GICC_EOIR, intid);
}
/* FABRIC-3.10.8 MC-3b: the wake SGI. */
#define GICD_SGIR 0xF00
#define GIC_WAKE_SGI 0u
/**
* @brief On a secondary core: its banked GIC state, for the wake SGI only.
*
* SGI/PPI enables and priorities (GICD_ISENABLER0, GICD_IPRIORITYR 0-31)
* and the whole CPU interface are banked per core, so each core sets its
* own; the distributor itself is already enabled by core 0's apic_init().
* Its timer PPI stays disabled.
*
* @return This core's CPU-interface target mask, read from its own banked
* GICD_ITARGETSR0 (byte 0 names the reading core).
*/
uint32_t apic_secondary_init_gic(void)
{
uint32_t val = mmio_read32(s_gicd_base, GICD_IPRIORITYR); /* SGIs 0-3 */
val = (val & ~0xFFu) | TIMER_PRIORITY; /* SGI 0 */
mmio_write32(s_gicd_base, GICD_IPRIORITYR, val);
mmio_write32(s_gicd_base, GICD_ISENABLER0, 1u << GIC_WAKE_SGI);
mmio_write32(s_gicc_base, GICC_PMR, PMR_ALLOW_ALL);
mmio_write32(s_gicc_base, GICC_CTLR, GICC_CTLR_ENABLE_GRP0);
return mmio_read32(s_gicd_base, GICD_ITARGETSR) & 0xFFu;
}
/** @brief Send the wake SGI to the cores in @p target_mask. */
void apic_send_wake_sgi(uint32_t target_mask)
{
__asm__ volatile ("dsb ishst" ::: "memory");
mmio_write32(s_gicd_base, GICD_SGIR, ((target_mask & 0xFFu) << 16) | GIC_WAKE_SGI);
}
/**
* @brief Signal End of Interrupt (common cross-ISA signature — see below).
*