https://git.reactos.org/?p=reactos.git;a=commitdiff;h=eebe11ae0cc923d9cd904…
commit eebe11ae0cc923d9cd9047b3394ea5c3e9d37c60
Author: Justin Miller <justinmiller100(a)gmail.com>
AuthorDate: Sat Mar 26 12:39:28 2022 -0700
Commit: Stanislav Motylkov <x86corez(a)gmail.com>
CommitDate: Thu Apr 7 22:54:32 2022 +0300
[HALX86] Add support for parsing ACPI MADT tables
---
hal/halx86/acpi/madt.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
hal/halx86/apic/halinit.c | 10 +++++-----
hal/halx86/include/smp.h | 13 +++++++++++++
3 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/hal/halx86/acpi/madt.c b/hal/halx86/acpi/madt.c
index 183eaefcb04..cd26be67b21 100644
--- a/hal/halx86/acpi/madt.c
+++ b/hal/halx86/acpi/madt.c
@@ -19,6 +19,10 @@
PROCESSOR_IDENTITY HalpStaticProcessorIdentity[MAXIMUM_PROCESSORS] = {{0}};
PPROCESSOR_IDENTITY HalpProcessorIdentity = NULL;
+HALP_APIC_INFO_TABLE HalpApicInfoTable;
+ACPI_TABLE_MADT *MadtTable;
+ACPI_SUBTABLE_HEADER *AcpiHeader;
+ACPI_MADT_LOCAL_APIC *LocalApic;
/* FUNCTIONS ******************************************************************/
@@ -26,7 +30,46 @@ VOID
HalpParseApicTables(
_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
diff --git a/hal/halx86/apic/halinit.c b/hal/halx86/apic/halinit.c
index cb0c5af7b77..907f0cfd28f 100644
--- a/hal/halx86/apic/halinit.c
+++ b/hal/halx86/apic/halinit.c
@@ -25,13 +25,14 @@ HalpInitProcessor(
IN ULONG ProcessorNumber,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
+#ifdef CONFIG_SMP
if (ProcessorNumber == 0)
{
- /* APIC tables should always be parsed once before touching APIC */
+#endif
HalpParseApicTables(LoaderBlock);
+#ifdef CONFIG_SMP
}
-#ifdef CONFIG_SMP
HalpSetupProcessorsTable(ProcessorNumber);
#endif
@@ -52,6 +53,8 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
(HalpBuildType & PRCB_BUILD_UNIPROCESSOR) ? "UP" :
"SMP",
(HalpBuildType & PRCB_BUILD_DEBUG) ? "DBG" : "REL");
+ HalpPrintApicTables();
+
/* Enable clock interrupt handler */
HalpEnableInterruptHandler(IDT_INTERNAL,
0,
@@ -59,9 +62,6 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
CLOCK2_LEVEL,
HalpClockInterrupt,
Latched);
-#if DBG
- HalpPrintApicTables();
-#endif
}
VOID
diff --git a/hal/halx86/include/smp.h b/hal/halx86/include/smp.h
index cac946310f2..06ec42ec6db 100644
--- a/hal/halx86/include/smp.h
+++ b/hal/halx86/include/smp.h
@@ -18,6 +18,19 @@ typedef struct _PROCESSOR_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
HalpParseApicTables(
_In_ PLOADER_PARAMETER_BLOCK LoaderBlock);