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);