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

Notes:
    v2:
    - in v2, this is the patch where CpuS3DataDxe starts depending on
      OvmfPkg/OvmfPkg.dec

 OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf  |  6 +-
 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, 191 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf 
b/OvmfPkg/QuarkPort/CpuS3DataDxe/CpuS3DataDxe.inf
index 4ade193..249408b 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
@@ -66,6 +68,7 @@ [Packages]
   IntelFrameworkPkg/IntelFrameworkPkg.dec
   IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   UefiBootServicesTableLib
@@ -79,6 +82,7 @@ [LibraryClasses]
 [Guids]
 
 [Protocols]
+  gEfiMpServiceProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
   gEfiLegacyBiosProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiSmmConfigurationProtocolGuid              # PROTOCOL ALWAYS_CONSUMED
 
@@ -93,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

Reply via email to