diff --git a/paw/stos/arch/amd64/cpu/mp.c b/paw/stos/arch/amd64/cpu/mp.c new file mode 100644 index 0000000..7394830 --- /dev/null +++ b/paw/stos/arch/amd64/cpu/mp.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: MP bringup + * Author: Chloe M. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Limit used to prevent log spam */ +#define MP_LOG_CAP 4 +#define MP_DEBUG 1 + +#define DTRACE(Fmt, ...) \ + TRACE("[ MP ]: " Fmt, ##__VA_ARGS__) + +#if MP_DEBUG +#define MP_DTRACE(...) \ + if (ProcessorsUp < MP_LOG_CAP) { \ + DTRACE(__VA_ARGS__); \ + } +#else +#define MP_DTRACE(...) (VOID)0 +#endif /* MP_DEBUG */ + +static USIZE ProcessorsUp = 0; + +/* + * Bring up a single application processor + * + * @Lapic: Local APIC of processor to bring up + */ +static VOID +ApKick(ACPI_LOCAL_APIC *Lapic) +{ + UQUAD UsecCur, UsecGoal; + ULONG BspId; + + if (Lapic == NULL) { + return; + } + + /* Don't nuke ourselves */ + BspId = MdLapicId(); + if (Lapic->ApicId == BspId) { + return; + } + + /* Send an INIT IPI to the processor */ + MdLapicSendIpi( + 0, + Lapic->ApicId, + 0, + IPI_XND_NONE, + IPI_DELMOD_INIT + ); + + /* MP spec states to wait 10 usec */ + UsecCur = MdHpetTimeUsec(); + UsecGoal = UsecCur + (USEC_PER_MSEC * 10); + while (MdHpetTimeUsec() < UsecGoal) { + HalCpuSpinWait(); + } + + DTRACE("sent init to apic%d\n", Lapic->ApicId); + ++ProcessorsUp; +} + +VOID +HalMpBringUp(VOID) +{ + ACPI_LOCAL_APIC *LocalApic; + USIZE Idx; + + /* Bring up each AP */ + for (Idx = 0;; ++Idx) { + LocalApic = MdLapicByIndex(Idx); + if (LocalApic == NULL) { + break; + } + + ApKick(LocalApic); + } +} diff --git a/paw/stos/head/hal/mp.h b/paw/stos/head/hal/mp.h new file mode 100644 index 0000000..4a04c6f --- /dev/null +++ b/paw/stos/head/hal/mp.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: MP bringup HAL layer + * Author: Chloe M. + */ + +#ifndef _HAL_MP_H_ +#define _HAL_MP_H_ 1 + +#include + +/* + * Bring the application processors up + */ +VOID HalMpBringUp(VOID); + +#endif /* !_HAL_MP_H_ */ diff --git a/paw/stos/init/init.c b/paw/stos/init/init.c index bbd6430..737d833 100644 --- a/paw/stos/init/init.c +++ b/paw/stos/init/init.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -89,4 +90,7 @@ KiKernelEntry(VOID) /* Phase 3 initialization of the bootstrap core */ HalKpcrP3Init(&BootstrapCore); + + /* Bring up all other cores */ + HalMpBringUp(); } diff --git a/tools/qemu-x64.sh b/tools/qemu-x64.sh index e60def4..dbcca7f 100755 --- a/tools/qemu-x64.sh +++ b/tools/qemu-x64.sh @@ -14,4 +14,5 @@ qemu-system-x86_64 \ -serial stdio \ -device virtio-vga-gl \ -display sdl,gl=on \ + -smp 4 \ -cpu host