Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan <[email protected]>
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 113 +++++++++++++++++++++++++++++++++++++++++++++-
 UefiCpuPkg/CpuDxe/CpuMp.h |  28 ++++++++++++
 2 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 398426d..fce015c 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -16,6 +16,7 @@
 #include "CpuMp.h"
 
 EFI_HANDLE mMpServiceHandle = NULL;
+MP_SYSTEM_DATA mMpSystemData;
 
 VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
@@ -27,9 +28,87 @@ UINTN mNumberOfProcessors;
 BOOLEAN mAllApsInitFinished = FALSE;
 UINTN mApDoneCount = 0;
 
+BOOLEAN
+IsBSP (
+  VOID
+  )
+{
+  UINTN ProcessorId;
+  UINTN CpuIndex;
+  CPU_DATA_BLOCK  *CpuData = NULL;
+
+  ProcessorId = GetApicId ();
+  for (CpuIndex = 0; CpuIndex < mMpSystemData.NumberOfProcessors; CpuIndex++) {
+    if (mMpSystemData.CpuDatas[CpuIndex].Info.ProcessorId == ProcessorId) {
+      CpuData = &mMpSystemData.CpuDatas[CpuIndex];
+      break;
+    }
+  }
+
+  return (CpuData) && (CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) ? TRUE 
: FALSE;
+}
+
+
+/**
+  This service retrieves the number of logical processor in the platform
+  and the number of those logical processors that are enabled on this boot.
+  This service may only be called from the BSP.
+
+  This function is used to retrieve the following information:
+    - The number of logical processors that are present in the system.
+    - The number of enabled logical processors in the system at the instant
+      this call is made.
+
+  Because MP Service Protocol provides services to enable and disable 
processors
+  dynamically, the number of enabled logical processors may vary during the
+  course of a boot session.
+
+  If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+  If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+  EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+  is returned in NumberOfProcessors, the number of currently enabled processor
+  is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+  @param[in]  This                        A pointer to the 
EFI_MP_SERVICES_PROTOCOL
+                                          instance.
+  @param[out] NumberOfProcessors          Pointer to the total number of 
logical
+                                          processors in the system, including 
the BSP
+                                          and disabled APs.
+  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled 
logical
+                                          processors that exist in system, 
including
+                                          the BSP.
+
+  @retval EFI_SUCCESS             The number of logical processors and enabled
+                                  logical processors was retrieved.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
+  @retval EFI_INVALID_PARAMETER   NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetNumberOfProcessors (
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,
+  OUT UINTN                     *NumberOfProcessors,
+  OUT UINTN                     *NumberOfEnabledProcessors
+  )
+{
+  if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!IsBSP ()) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  *NumberOfProcessors        = mMpSystemData.NumberOfProcessors;
+  *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;
+  return EFI_SUCCESS;
+}
+
 
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
-  NULL, // GetNumberOfProcessors,
+  GetNumberOfProcessors,
   NULL, // GetProcessorInfo,
   NULL, // StartupAllAps,
   NULL, // StartupThisAP,
@@ -44,8 +123,12 @@ ProcessorToIdleState (
   IN VOID *context2 OPTIONAL
   )
 {
+  CPU_DATA_BLOCK *CpuData;
+
   DEBUG ((DEBUG_INFO, "detect Apic id: %d\n",
                       GetApicId()));
+  CpuData = &mMpSystemData.CpuDatas[mIndexOfProcessors];
+  CpuData->Info.ProcessorId = GetApicId ();
 
   mIndexOfProcessors++;
   mApDoneCount++;
@@ -79,6 +162,26 @@ ApEntryPointInC (
   CpuDeadLoop ();
 }
 
+EFI_STATUS
+InitMpSystemData (
+  VOID
+  )
+{
+  UINTN CpuIndex;
+  CPU_DATA_BLOCK *CpuData;
+
+
+  for (CpuIndex = 0; CpuIndex < mMpSystemData.NumberOfProcessors; CpuIndex++) {
+    CpuData = &mMpSystemData.CpuDatas[CpuIndex];
+    CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | 
PROCESSOR_HEALTH_STATUS_BIT;
+    if (CpuIndex == 0) {
+      CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
+      CpuData->Info.ProcessorId = GetApicId ();
+    }
+  }
+
+  return EFI_SUCCESS;
+}
 
 VOID
 InitializeMpSupport (
@@ -104,6 +207,12 @@ InitializeMpSupport (
     goto EXIT;
   }
 
+  mMpSystemData.NumberOfProcessors = mNumberOfProcessors;
+  mMpSystemData.NumberOfEnabledProcessors = mNumberOfProcessors;
+
+  mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * 
mNumberOfProcessors);
+  ASSERT(mMpSystemData.CpuDatas != NULL);
+
   DEBUG ((DEBUG_ERROR, "Detect CPU count: %d\n", mNumberOfProcessors));
   mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES ((mNumberOfProcessors - 1) 
* AP_STACK_SIZE));
   mApStackSize = AP_STACK_SIZE;
@@ -112,6 +221,8 @@ InitializeMpSupport (
 
   while (mApDoneCount != (mNumberOfProcessors - 1));
 
+  InitMpSystemData ();
+
   Status = gBS->InstallMultipleProtocolInterfaces (
                   &mMpServiceHandle,
                   &gEfiMpServiceProtocolGuid,  &mMpServicesTemplate,
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 889b10a..03cc438 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -16,6 +16,7 @@
 #define _CPU_MP_H_
 
 #include <Protocol/MpService.h>
+#include <Library/SynchronizationLib.h>
 
 #define AP_STACK_SIZE      SIZE_64KB
 #define STALL_100_MILLI_SECOND (1000 * 100)
@@ -68,5 +69,32 @@ AsmApReleaseLock (
   VOID
   );
 
+typedef enum {
+  CPU_STATE_IDLE,
+  CPU_STATE_BLOCKED,
+  CPU_STATE_READY,
+  CPU_STATE_BUSY,
+  CPU_STATE_FINISHED
+} CPU_STATE;
+
+//
+// Define Individual Processor Data block.
+//
+typedef struct {
+  EFI_PROCESSOR_INFORMATION      Info;
+  SPIN_LOCK                      CpuDataLock;
+  CPU_STATE volatile             State;
+} CPU_DATA_BLOCK;
+
+//
+// Define MP data block which consumes individual processor block.
+//
+typedef struct {
+  CPU_DATA_BLOCK              *CpuDatas;
+  UINTN                       NumberOfProcessors;
+  UINTN                       NumberOfEnabledProcessors;
+} MP_SYSTEM_DATA;
+
+
 #endif // _CPU_MP_H_
 
-- 
1.9.3


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to