Following the same method as before, we incorporate code from Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuMpDxe that sets "mCpuConfigConextBuffer.NumberOfProcessors" on the entry point's call stack, and ultimately stores it into ACPI_CPU_DATA.NumberOfCpus on SmmConfigurationEventNotify()'s call stack.
The CheckApicId() function is scavenged from Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuMpDxe because it contains useful checks, and the SortApicId() function is taken (and completely rewritten) because that's the one that sets "mCpuConfigConextBuffer.NumberOfProcessors". Unlike in Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuMpDxe, which implements the CPU MP Services itself, in SortApicId() we retrieve the number of processors from the same protocol provided by UefiCpuPkg/CpuDxe. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf | 5 +- OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.h | 69 +++++++++++++++ OvmfPkg/QuarkPort/CpuS3DataDxe/MpCommon.h | 3 + OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.c | 93 ++++++++++++++++++++ OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c | 21 +++++ 5 files changed, 190 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf b/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf index e67e256..7c8c90b 100644 --- a/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf +++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf @@ -54,6 +54,8 @@ [Sources] MpCommon.h MpCommon.c Cpu.h + MpApic.c + MpApic.h [Sources.Ia32] IA32/CpuAsm.asm @@ -80,6 +82,7 @@ [LibraryClasses] [Guids] [Protocols] + gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiLegacyBiosProtocolGuid ## SOMETIMES_CONSUMES gEfiSmmConfigurationProtocolGuid # PROTOCOL ALWAYS_CONSUMED @@ -94,4 +97,4 @@ [Pcd] gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize [Depex] - TRUE + gEfiMpServiceProtocolGuid diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.h b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.h new file mode 100644 index 0000000..7a6e93d --- /dev/null +++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.h @@ -0,0 +1,69 @@ +/** @file + + Include file for APIC feature. + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2013-2015 Intel Corporation. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Module Name: MpApic.h + +**/ + +#ifndef _CPU_MP_APIC_H_ +#define _CPU_MP_APIC_H_ + +#include "Cpu.h" + +/** + Sort the APIC ID of all processors. + + This function sorts the APIC ID of all processors so that processor number is + assigned in the ascending order of APIC ID which eases MP debugging. SMBIOS + logic also depends on this assumption. + +**/ +VOID +SortApicId ( + VOID + ); + +/** + Check if there is legacy APIC ID conflict among all processors. + + @retval EFI_SUCCESS No coflict or conflict was resoved by force x2APIC + mode + @retval EFI_UNSUPPORTED There is legacy APIC ID conflict and can't be + rsolved in xAPIC mode +**/ +EFI_STATUS +CheckApicId ( + VOID + ); + +#endif diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/MpCommon.h b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpCommon.h index 8f47da2..396bdcc 100644 --- a/OvmfPkg/QuarkPort/CpuS3DataDxe/MpCommon.h +++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpCommon.h @@ -43,6 +43,7 @@ #include "ArchSpecificDef.h" #include <AcpiCpuData.h> +#include <Protocol/MpService.h> #include <Protocol/LegacyBios.h> #include <Protocol/SmmConfiguration.h> @@ -51,6 +52,7 @@ #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/CpuConfigLib.h> #define INTERRUPT_HANDLER_MACHINE_CHECK 0x12 @@ -74,6 +76,7 @@ typedef struct { } MP_CPU_EXCHANGE_INFO; extern MP_CPU_EXCHANGE_INFO *mExchangeInfo; +extern CPU_CONFIG_CONTEXT_BUFFER mCpuConfigConextBuffer; extern EFI_PHYSICAL_ADDRESS mApMachineCheckHandlerBase; extern UINT32 mApMachineCheckHandlerSize; diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.c b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.c new file mode 100644 index 0000000..012582a --- /dev/null +++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/MpApic.c @@ -0,0 +1,93 @@ +/** @file + + Code for APIC feature. + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2013-2015 Intel Corporation. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Module Name: MpApic.c + +**/ + +#include "MpApic.h" + +/** + Sort the APIC ID of all processors. + + This function sorts the APIC ID of all processors so that processor number is + assigned in the ascending order of APIC ID which eases MP debugging. SMBIOS + logic also depends on this assumption. + +**/ +VOID +SortApicId ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + + Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, + (VOID **)&MpServices); + ASSERT_EFI_ERROR (Status); + + Status = MpServices->GetNumberOfProcessors ( + MpServices, + &NumberOfProcessors, + &NumberOfEnabledProcessors + ); + ASSERT_EFI_ERROR (Status); + + mCpuConfigConextBuffer.NumberOfProcessors = NumberOfProcessors; +} + +/** + Check if there is legacy APIC ID conflict among all processors. + + @retval EFI_SUCCESS No coflict + @retval EFI_UNSUPPORTED There is legacy APIC ID conflict and can't be + rsolved in xAPIC mode +**/ +EFI_STATUS +CheckApicId ( + VOID + ) +{ + ASSERT (mCpuConfigConextBuffer.NumberOfProcessors <= + FixedPcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + + if (mCpuConfigConextBuffer.NumberOfProcessors > 255) { + DEBUG ((EFI_D_ERROR, "Number of processors > 255!\n")); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c b/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c index 3498230..a69c58c 100644 --- a/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c +++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c @@ -36,7 +36,9 @@ #include "MpService.h" #include "Cpu.h" +#include "MpApic.h" +CPU_CONFIG_CONTEXT_BUFFER mCpuConfigConextBuffer; EFI_PHYSICAL_ADDRESS mStartupVector; ACPI_CPU_DATA *mAcpiCpuData; EFI_EVENT mSmmConfigurationNotificationEvent; @@ -123,18 +125,34 @@ ProcessorConfiguration ( VOID ) { + EFI_STATUS Status; + // // Wakeup APs for the first time, BSP stalls for arbitrary // time for APs' completion. BSP then collects the number // and BIST information of APs. // WakeupAPAndCollectBist (); + // + // Sort APIC ID of all processors in asending order. Processor number + // is assigned in this order to ease MP debug. SMBIOS logic also depends on + // it. + // + SortApicId (); // // Prepare data in memory for processor configuration // PrepareMemoryForConfiguration (); + // + // Check if there is legacy APIC ID conflict among all processors. + // + Status = CheckApicId (); + if (EFI_ERROR (Status)) { + return Status; + } + return EFI_SUCCESS; } @@ -246,6 +264,9 @@ SaveCpuS3Data ( CopyMem ((VOID *) (UINTN) mAcpiCpuData->IdtrProfile, (VOID *) (UINTN) &mExchangeInfo->IdtrProfile, sizeof (IA32_DESCRIPTOR)); + mAcpiCpuData->NumberOfCpus = + (UINT32) mCpuConfigConextBuffer.NumberOfProcessors; + // // Set the base address of CPU S3 data to PcdCpuS3DataAddress // -- 1.8.3.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel