5e99093e9f
Signed-off-by: Chloe M. <chloe@mensia.org>
104 lines
2.0 KiB
C
104 lines
2.0 KiB
C
/*
|
|
* Copyright (c) 2026, Chloe M.
|
|
* Provided under the BSD-3 clause.
|
|
*
|
|
* Description: MP bringup
|
|
* Author: Chloe M.
|
|
*/
|
|
|
|
#include <stdef.h>
|
|
#include <hal/mp.h>
|
|
#include <hal/prim.h>
|
|
#include <ex/trace.h>
|
|
#include <machine/irqchip.h>
|
|
#include <machine/hpet.h>
|
|
#include <machine/lapic.h>
|
|
#include <units.h>
|
|
|
|
/* Limit used to prevent log spam */
|
|
#define MP_LOG_CAP 4
|
|
#define MP_DEBUG 1
|
|
|
|
/* Local APIC flags */
|
|
#define LAPIC_ONLINE_CAPABLE BIT(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;
|
|
}
|
|
|
|
/*
|
|
* Some processor entries may not be "online capable", if we
|
|
* encounter such entries, ignore it.
|
|
*/
|
|
if (!ISSET(Lapic->Flags, LAPIC_ONLINE_CAPABLE)) {
|
|
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);
|
|
}
|
|
}
|