[HALX86] Add support for parsing ACPI MADT tables

This commit is contained in:
Justin Miller 2022-03-26 12:39:28 -07:00 committed by Stanislav Motylkov
parent 5c79900519
commit eebe11ae0c
No known key found for this signature in database
GPG key ID: AFE513258CBA9E92
3 changed files with 62 additions and 6 deletions

View file

@ -19,6 +19,10 @@
PROCESSOR_IDENTITY HalpStaticProcessorIdentity[MAXIMUM_PROCESSORS] = {{0}}; PROCESSOR_IDENTITY HalpStaticProcessorIdentity[MAXIMUM_PROCESSORS] = {{0}};
PPROCESSOR_IDENTITY HalpProcessorIdentity = NULL; PPROCESSOR_IDENTITY HalpProcessorIdentity = NULL;
HALP_APIC_INFO_TABLE HalpApicInfoTable;
ACPI_TABLE_MADT *MadtTable;
ACPI_SUBTABLE_HEADER *AcpiHeader;
ACPI_MADT_LOCAL_APIC *LocalApic;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -26,7 +30,46 @@ VOID
HalpParseApicTables( HalpParseApicTables(
_In_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
UNIMPLEMENTED; ULONG_PTR TableEnd;
ULONG ValidProcessorCount;
/* We only support legacy APIC for now, this will be updated in the future */
HalpApicInfoTable.ApicMode = 0x10;
MadtTable = HalAcpiGetTable(LoaderBlock, 'CIPA');
AcpiHeader = (ACPI_SUBTABLE_HEADER*)MadtTable;
AcpiHeader->Length = sizeof(ACPI_TABLE_MADT);
TableEnd = (ULONG_PTR)MadtTable + MadtTable->Header.Length;
HalpApicInfoTable.ProcessorCount = 0;
HalpProcessorIdentity = HalpStaticProcessorIdentity;
AcpiHeader = (ACPI_SUBTABLE_HEADER*)MadtTable;
AcpiHeader->Length = sizeof(ACPI_TABLE_MADT);
TableEnd = (ULONG_PTR)MadtTable + MadtTable->Header.Length;
while ((ULONG_PTR)AcpiHeader <= TableEnd)
{
LocalApic = (ACPI_MADT_LOCAL_APIC*)AcpiHeader;
if (LocalApic->Header.Type == ACPI_MADT_TYPE_LOCAL_APIC &&
LocalApic->Header.Length == sizeof(ACPI_MADT_LOCAL_APIC))
{
ValidProcessorCount = HalpApicInfoTable.ProcessorCount;
HalpProcessorIdentity[ValidProcessorCount].LapicId = LocalApic->Id;
HalpProcessorIdentity[ValidProcessorCount].ProcessorId = LocalApic->ProcessorId;
HalpApicInfoTable.ProcessorCount++;
AcpiHeader = (ACPI_SUBTABLE_HEADER*)((ULONG_PTR)AcpiHeader + AcpiHeader->Length);
}
else
{
/* End the parsing early if we don't use the currently selected table */
AcpiHeader = (ACPI_SUBTABLE_HEADER*)((ULONG_PTR)AcpiHeader + 1);
}
}
} }
VOID VOID

View file

@ -25,13 +25,14 @@ HalpInitProcessor(
IN ULONG ProcessorNumber, IN ULONG ProcessorNumber,
IN PLOADER_PARAMETER_BLOCK LoaderBlock) IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
#ifdef CONFIG_SMP
if (ProcessorNumber == 0) if (ProcessorNumber == 0)
{ {
/* APIC tables should always be parsed once before touching APIC */ #endif
HalpParseApicTables(LoaderBlock); HalpParseApicTables(LoaderBlock);
#ifdef CONFIG_SMP
} }
#ifdef CONFIG_SMP
HalpSetupProcessorsTable(ProcessorNumber); HalpSetupProcessorsTable(ProcessorNumber);
#endif #endif
@ -52,6 +53,8 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
(HalpBuildType & PRCB_BUILD_UNIPROCESSOR) ? "UP" : "SMP", (HalpBuildType & PRCB_BUILD_UNIPROCESSOR) ? "UP" : "SMP",
(HalpBuildType & PRCB_BUILD_DEBUG) ? "DBG" : "REL"); (HalpBuildType & PRCB_BUILD_DEBUG) ? "DBG" : "REL");
HalpPrintApicTables();
/* Enable clock interrupt handler */ /* Enable clock interrupt handler */
HalpEnableInterruptHandler(IDT_INTERNAL, HalpEnableInterruptHandler(IDT_INTERNAL,
0, 0,
@ -59,9 +62,6 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
CLOCK2_LEVEL, CLOCK2_LEVEL,
HalpClockInterrupt, HalpClockInterrupt,
Latched); Latched);
#if DBG
HalpPrintApicTables();
#endif
} }
VOID VOID

View file

@ -18,6 +18,19 @@ typedef struct _PROCESSOR_IDENTITY
} PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY; } PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
/* This table is counter of the overall APIC constants acquired from madt */
typedef struct _HALP_APIC_INFO_TABLE
{
ULONG ApicMode;
ULONG ProcessorCount; /* Count of all physical cores, This includes BSP */
ULONG IOAPICCount;
ULONG LocalApicPA; // The 32-bit physical address at which each processor can access its local interrupt controller
ULONG IoApicVA[256];
ULONG IoApicPA[256];
ULONG IoApicIrqBase[256]; // Global system interrupt base
} HALP_APIC_INFO_TABLE, *PHALP_APIC_INFO_TABLE;
VOID VOID
HalpParseApicTables( HalpParseApicTables(
_In_ PLOADER_PARAMETER_BLOCK LoaderBlock); _In_ PLOADER_PARAMETER_BLOCK LoaderBlock);