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:
co-authored by
Claude Opus 5.5
parent
d7745b49be
commit
71e0be96b0
@@ -366,6 +366,12 @@ int apic_send_ipi(uint8_t dest_apic_id, uint32_t icr_low)
|
||||
return -1; /* still pending: reported by the caller */
|
||||
}
|
||||
|
||||
void apic_secondary_enable(void)
|
||||
{
|
||||
lapic_write(APIC_REG_TPR, 0);
|
||||
lapic_write(APIC_REG_SIVR, 0x100u | APIC_SPURIOUS_VECTOR); /* bit 8: APIC enable */
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* APIC Timer
|
||||
* ============================================================================ */
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "apic.h"
|
||||
#include "timer.h"
|
||||
#include "starkernel/i8042.h"
|
||||
#include "starkernel/smp.h" /* FABRIC-3.10.8 MC-3b -- sk_smp_ipi_received() */
|
||||
|
||||
/* Set by the FORTH dispatcher just before calling entry->func(vm).
|
||||
* Printed on fault to identify which word was executing. */
|
||||
@@ -346,6 +347,14 @@ void isr_common_handler(uint64_t vector,
|
||||
return;
|
||||
}
|
||||
|
||||
/* FABRIC-3.10.8 MC-3b: the wake IPI -- counted on the receiving core;
|
||||
* the wake itself is the return from its halt. */
|
||||
if (vector == SK_IPI_VECTOR) {
|
||||
sk_smp_ipi_received();
|
||||
apic_eoi();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Handle i8042 keyboard interrupt (item 4.3.5) */
|
||||
if (vector == I8042_KEYBOARD_VECTOR) {
|
||||
i8042_handle_irq();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
.hidden isr_stub0
|
||||
.hidden isr_stub32
|
||||
.hidden isr_stub33
|
||||
.hidden isr_stub34
|
||||
.hidden isr_stub_default
|
||||
.hidden isr_common_entry
|
||||
|
||||
@@ -197,7 +198,15 @@ isr_stub33:
|
||||
push 33
|
||||
jmp isr_common_entry
|
||||
|
||||
/* Default stub for other vectors (34-255) */
|
||||
/* Stub for the inter-processor wake IPI, vector 0x22 = 34 (FABRIC-3.10.8
|
||||
* MC-3b, SK_IPI_VECTOR) -- its own stub for the reason stub 33 has one. */
|
||||
.global isr_stub34
|
||||
isr_stub34:
|
||||
push 0
|
||||
push 34
|
||||
jmp isr_common_entry
|
||||
|
||||
/* Default stub for other vectors (35-255) */
|
||||
.global isr_stub_default
|
||||
isr_stub_default:
|
||||
push 0 /* fake error */
|
||||
@@ -221,7 +230,9 @@ isr_stub_table:
|
||||
.quad isr_stub32
|
||||
/* Vector 33 = i8042 keyboard IRQ1 (item 4.3.5) */
|
||||
.quad isr_stub33
|
||||
/* Vectors 34-255 default to unknown stub */
|
||||
.rept 222
|
||||
/* Vector 34 = the wake IPI (MC-3b) */
|
||||
.quad isr_stub34
|
||||
/* Vectors 35-255 default to unknown stub */
|
||||
.rept 221
|
||||
.quad isr_stub_default
|
||||
.endr
|
||||
|
||||
@@ -102,9 +102,22 @@ uint32_t arch_smp_enumerate(BootInfo *boot_info, uint64_t *hw_ids, uint32_t cap)
|
||||
|
||||
uint64_t arch_smp_boot_hw_id(void) { return apic_id(); }
|
||||
|
||||
/* MC-3b: exactly one interrupt may end the halt -- `sti`'s one-instruction
|
||||
* shadow covers the `hlt`, so a wake IPI can't slip in between and be lost. */
|
||||
void arch_smp_park_once(void)
|
||||
{
|
||||
__asm__ volatile ("cli; hlt" ::: "memory");
|
||||
__asm__ volatile ("sti; hlt; cli" ::: "memory");
|
||||
}
|
||||
|
||||
void arch_smp_secondary_init(sk_percpu_t *pc)
|
||||
{
|
||||
apic_secondary_enable();
|
||||
pc->ipi_target = pc->hw_id; /* the APIC id */
|
||||
}
|
||||
|
||||
void arch_smp_send_ipi(const sk_percpu_t *target)
|
||||
{
|
||||
(void)apic_send_ipi((uint8_t)target->ipi_target, 0x00004000u | SK_IPI_VECTOR); /* fixed, assert */
|
||||
}
|
||||
|
||||
const char *arch_smp_arrival(const sk_percpu_t *pc)
|
||||
|
||||
Reference in New Issue
Block a user