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