Skip to content

Commit

Permalink
[HALX86] Fix AP startup by properly avoiding the BSP
Browse files Browse the repository at this point in the history
[HALX86] Clean up and move MADT code further
  • Loading branch information
DarkFire01 committed Nov 1, 2024
1 parent 36a8f3e commit 549d3cc
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 90 deletions.
115 changes: 37 additions & 78 deletions hal/halx86/acpi/madt.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,6 @@
#define NDEBUG
#include <debug.h>

// See HalpParseApicTables(). Only enable this to local-debug it.
// That needs, for example, to test-call the function later or to use the "FrLdrDbgPrint" hack.
#if DBG && 0
#define DPRINT01 DPRINT1
#define DPRINT00 DPRINT
#else
#if defined(_MSC_VER)
#define DPRINT01 __noop
#define DPRINT00 __noop
#else
#define DPRINT01(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT00(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif // _MSC_VER
#endif // DBG && 0

/* GLOBALS ********************************************************************/

HALP_APIC_INFO_TABLE HalpApicInfoTable;
Expand All @@ -41,12 +26,12 @@ HALP_APIC_INFO_TABLE HalpApicInfoTable;
#define LAPIC_FLAG_ONLINE_CAPABLE 0x00000002
// Bits 2-31 are reserved.

static PROCESSOR_IDENTITY HalpStaticProcessorIdentity[MAXIMUM_PROCESSORS];
const PPROCESSOR_IDENTITY HalpProcessorIdentity = HalpStaticProcessorIdentity;
PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS];

#if 0
extern ULONG HalpPicVectorRedirect[16];
#endif

ULONG
HalpGetCurrentProcessorHwID(VOID);

/* FUNCTIONS ******************************************************************/

Expand All @@ -62,59 +47,35 @@ HalpParseApicTables(
MadtTable = HalAcpiGetTable(LoaderBlock, APIC_SIGNATURE);
if (!MadtTable)
{
DPRINT01("MADT table not found\n");
DPRINT1("MADT table not found\n");
return;
}

if (MadtTable->Header.Length < sizeof(*MadtTable))
{
DPRINT01("Length is too short: %p, %u\n", MadtTable, MadtTable->Header.Length);
DPRINT1("Length is too short: %p, %u\n", MadtTable, MadtTable->Header.Length);
return;
}

DPRINT00("MADT table: Address %08X, Flags %08X\n", MadtTable->Address, MadtTable->Flags);

#if 1
DPRINT("MADT table: Address %08X, Flags %08X\n", MadtTable->Address, MadtTable->Flags);

// TODO: We support only legacy APIC for now
HalpApicInfoTable.ApicMode = HALP_APIC_MODE_LEGACY;
// TODO: What about 'MadtTable->Flags & ACPI_MADT_PCAT_COMPAT'?

#else // TODO: Is that correct?

if ((MadtTable->Flags & ACPI_MADT_PCAT_COMPAT) == ACPI_MADT_DUAL_PIC)
{
HalpApicInfoTable.ApicMode = HALP_APIC_MODE_LEGACY;
}
else // if ((MadtTable->Flags & ACPI_MADT_PCAT_COMPAT) == ACPI_MADT_MULTIPLE_APIC)
{
#if 1
DPRINT01("ACPI_MADT_MULTIPLE_APIC support is UNIMPLEMENTED\n");
return;
#else
HalpApicInfoTable.ApicMode = HALP_APIC_MODE_xyz;
#endif
}

#endif

HalpApicInfoTable.LocalApicPA = MadtTable->Address;

AcpiHeader = (ACPI_SUBTABLE_HEADER *)((ULONG_PTR)MadtTable + sizeof(*MadtTable));
TableEnd = (ULONG_PTR)MadtTable + MadtTable->Header.Length;
DPRINT00(" MadtTable %p, subtables %p - %p\n", MadtTable, AcpiHeader, (PVOID)TableEnd);
DPRINT(" MadtTable %p, subtables %p - %p\n", MadtTable, AcpiHeader, (PVOID)TableEnd);

while ((ULONG_PTR)(AcpiHeader + 1) <= TableEnd)
{
if (AcpiHeader->Length < sizeof(*AcpiHeader))
{
DPRINT01("Length is too short: %p, %u\n", AcpiHeader, AcpiHeader->Length);
DPRINT1("Length is too short: %p, %u\n", AcpiHeader, AcpiHeader->Length);
return;
}

if ((ULONG_PTR)AcpiHeader + AcpiHeader->Length > TableEnd)
{
DPRINT01("Length mismatch: %p, %u, %p\n",
DPRINT1("Length mismatch: %p, %u, %p\n",
AcpiHeader, AcpiHeader->Length, (PVOID)TableEnd);
return;
}
Expand All @@ -127,23 +88,23 @@ HalpParseApicTables(

if (AcpiHeader->Length != sizeof(*LocalApic))
{
DPRINT01("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
DPRINT1("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
return;
}

DPRINT00(" Local Apic, Processor %lu: ProcessorId %u, Id %u, LapicFlags %08X\n",
DPRINT(" Local Apic, Processor %lu: ProcessorId %u, Id %u, LapicFlags %08X\n",
HalpApicInfoTable.ProcessorCount,
LocalApic->ProcessorId, LocalApic->Id, LocalApic->LapicFlags);

if (!(LocalApic->LapicFlags & (LAPIC_FLAG_ONLINE_CAPABLE | LAPIC_FLAG_ENABLED)))
{
DPRINT00(" Ignored: unusable\n");
DPRINT(" Ignored: unusable\n");
break;
}

if (HalpApicInfoTable.ProcessorCount == _countof(HalpStaticProcessorIdentity))
if (HalpApicInfoTable.ProcessorCount == MAXIMUM_PROCESSORS)
{
DPRINT00(" Skipped: array is full\n");
DPRINT1(" Skipped: array is full\n");
// We assume ignoring this processor is acceptable, until proven otherwise.
break;
}
Expand All @@ -153,6 +114,13 @@ HalpParseApicTables(
LocalApic->ProcessorId;
HalpProcessorIdentity[HalpApicInfoTable.ProcessorCount].LapicId = LocalApic->Id;

/* Check against the processor running this code, which is only the BSP. */
if (LocalApic->Id == HalpGetCurrentProcessorHwID())
{
HalpProcessorIdentity[HalpApicInfoTable.ProcessorCount].BSPCheck = TRUE;
HalpProcessorIdentity[HalpApicInfoTable.ProcessorCount].ProcessorStarted = TRUE;
}

HalpApicInfoTable.ProcessorCount++;

break;
Expand All @@ -163,17 +131,17 @@ HalpParseApicTables(

if (AcpiHeader->Length != sizeof(*IoApic))
{
DPRINT01("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
DPRINT1("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
return;
}

DPRINT00(" Io Apic: Id %u, Address %08X, GlobalIrqBase %08X\n",
DPRINT(" IoApic: Id %u, Address %08X, GlobalIrqBase %08X\n",
IoApic->Id, IoApic->Address, IoApic->GlobalIrqBase);

// Ensure HalpApicInfoTable.IOAPICCount consistency.
if (HalpApicInfoTable.IoApicPA[IoApic->Id] != 0)
{
DPRINT01("Id duplication: %p, %u\n", IoApic, IoApic->Id);
DPRINT1("Id duplication: %p, %u\n", IoApic, IoApic->Id);
return;
}

Expand All @@ -192,41 +160,30 @@ HalpParseApicTables(

if (AcpiHeader->Length != sizeof(*InterruptOverride))
{
DPRINT01("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
DPRINT1("Type/Length mismatch: %p, %u\n", AcpiHeader, AcpiHeader->Length);
return;
}

DPRINT00(" Interrupt Override: Bus %u, SourceIrq %u, GlobalIrq %08X, IntiFlags %04X / UNIMPLEMENTED\n",
/*
* We use this information to make sure IOAPIC knows the difference between the
* legacy PIC IRQs and the associated GSI with them.
*/
DPRINT1(" Interrupt Override: Bus %u, SourceIrq %u, GlobalIrq %08X, IntiFlags %04X / UNIMPLEMENTED\n",
InterruptOverride->Bus, InterruptOverride->SourceIrq,
InterruptOverride->GlobalIrq, InterruptOverride->IntiFlags);

if (InterruptOverride->Bus != 0) // 0 = ISA
{
DPRINT01("Invalid Bus: %p, %u\n", InterruptOverride, InterruptOverride->Bus);
return;
}

#if 1
// TODO: Implement it.
#else // TODO: Is that correct?
if (InterruptOverride->SourceIrq > _countof(HalpPicVectorRedirect))
{
DPRINT01("Invalid SourceIrq: %p, %u\n",
InterruptOverride, InterruptOverride->SourceIrq);
DPRINT1("Invalid Bus: %p, %u\n", InterruptOverride, InterruptOverride->Bus);
return;
}

// Note: GlobalIrq is not validated in any way (yet).
HalpPicVectorRedirect[InterruptOverride->SourceIrq] = InterruptOverride->GlobalIrq;
// TODO: What about 'InterruptOverride->IntiFlags'?
#endif

break;
}
default:
{
DPRINT01(" UNIMPLEMENTED: Type %u, Length %u\n",
AcpiHeader->Type, AcpiHeader->Length);
DPRINT1(" UNIMPLEMENTED: Type %u, Length %u\n",
AcpiHeader->Type, AcpiHeader->Length);
return;
}
}
Expand All @@ -236,9 +193,11 @@ HalpParseApicTables(

if ((ULONG_PTR)AcpiHeader != TableEnd)
{
DPRINT01("Length mismatch: %p, %p, %p\n", MadtTable, AcpiHeader, (PVOID)TableEnd);
DPRINT("Length mismatch: %p, %p, %p\n", MadtTable, AcpiHeader, (PVOID)TableEnd);
return;
}

HalpPrintApicTables();
}

VOID
Expand Down
6 changes: 6 additions & 0 deletions hal/halx86/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
ULONG ApicVersion;
UCHAR HalpVectorToIndex[256];

ULONG
HalpGetCurrentProcessorHwID(VOID)
{
return ApicRead(APIC_ID);
}

#ifndef _M_AMD64
const UCHAR
HalpIRQLtoTPR[32] =
Expand Down
2 changes: 1 addition & 1 deletion hal/halx86/apic/apicsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <debug.h>


extern PPROCESSOR_IDENTITY HalpProcessorIdentity;
extern PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS];

/* INTERNAL FUNCTIONS *********************************************************/

Expand Down
8 changes: 2 additions & 6 deletions hal/halx86/apic/halinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ HalpInitProcessor(
IN ULONG ProcessorNumber,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
if (ProcessorNumber == 0)
{
HalpParseApicTables(LoaderBlock);
}

HalpSetupProcessorsTable(ProcessorNumber);

/* Initialize the local APIC for this cpu */
Expand All @@ -49,7 +44,8 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
(HalpBuildType & PRCB_BUILD_UNIPROCESSOR) ? "UP" : "SMP",
(HalpBuildType & PRCB_BUILD_DEBUG) ? "DBG" : "REL");

HalpPrintApicTables();
/* This works because InitPhase0 happens before secondary processors are spun-up */
HalpParseApicTables(LoaderBlock);

/* Enable clock interrupt handler */
HalpEnableInterruptHandler(IDT_INTERNAL,
Expand Down
6 changes: 6 additions & 0 deletions hal/halx86/pic/pic.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ NTAPI
HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
IN PKTRAP_FRAME TrapFrame);

ULONG
HalpGetCurrentProcessorHwID(VOID)
{
return 0;
}

/* GLOBALS ********************************************************************/

#ifndef _MINIHAL_
Expand Down
10 changes: 8 additions & 2 deletions hal/halx86/smp/i386/spinup.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

/* GLOBALS *******************************************************************/

extern PPROCESSOR_IDENTITY HalpProcessorIdentity;
extern PHYSICAL_ADDRESS HalpLowStubPhysicalAddress;
extern PVOID HalpLowStub;

Expand All @@ -26,8 +25,9 @@ extern PVOID HalpAPEntryData;
extern PVOID HalpAPEntry32;
extern PVOID HalpAPEntry16End;
extern HALP_APIC_INFO_TABLE HalpApicInfoTable;
extern PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS];

ULONG HalpStartedProcessorCount = 1;
ULONG HalpStartedProcessorCount = 0;

#ifndef Add2Ptr
#define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I)))
Expand Down Expand Up @@ -91,6 +91,12 @@ HalStartNextProcessor(
if (HalpStartedProcessorCount == HalpApicInfoTable.ProcessorCount)
return FALSE;

if (HalpProcessorIdentity[HalpStartedProcessorCount].BSPCheck == TRUE)
{
// SKIP the BSP
HalpStartedProcessorCount++;
}

// Initalize the temporary page table
// TODO: clean it up after an AP boots successfully
ULONG initialCr3 = HalpSetupTemporaryMappings(ProcessorState);
Expand Down
3 changes: 1 addition & 2 deletions hal/halx86/smp/mps/mps.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
static // TODO: While HalpParseApicTables() is UNIMPLEMENTED.
ULONG PhysicalProcessorCount;

static PROCESSOR_IDENTITY HalpStaticProcessorIdentity[MAXIMUM_PROCESSORS];
const PPROCESSOR_IDENTITY HalpProcessorIdentity = HalpStaticProcessorIdentity;
PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS];

/* FUNCTIONS ******************************************************************/

Expand Down
2 changes: 1 addition & 1 deletion hal/halx86/smp/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/* GLOBALS *******************************************************************/

extern PPROCESSOR_IDENTITY HalpProcessorIdentity;
extern PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS];

/* FUNCTIONS *****************************************************************/

Expand Down

0 comments on commit 549d3cc

Please sign in to comment.