mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services
Consume MP Initialize library to produce CPU MP Protocol services to simply the code. v4: 1. Update CpuDxe.c file header to mention it produces CPU Arch protocol. 2. Update BistData type from UINT32 to EFI_HEALTH_FLAG. 3. Move some header location from CpuMp.h to CpuDxe.h. v3: 1. Move the code Consume MpInitLib APIs to produce CPU MP Protocol from patch #40 to this patch. 2. Add DxeMpInitLib.inf in DSC file Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
89fa1bf218
commit
7fadaacd50
|
@ -1,5 +1,5 @@
|
||||||
/** @file
|
/** @file
|
||||||
CPU DXE Module.
|
CPU DXE Module to produce CPU ARCH Protocol.
|
||||||
|
|
||||||
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
CPU DXE Module.
|
CPU DXE Module to produce CPU ARCH Protocol and CPU MP Protocol.
|
||||||
|
|
||||||
Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -18,6 +18,10 @@
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
|
||||||
#include <Protocol/Cpu.h>
|
#include <Protocol/Cpu.h>
|
||||||
|
#include <Protocol/MpService.h>
|
||||||
|
|
||||||
|
#include <Ppi/SecPlatformInformation.h>
|
||||||
|
#include <Ppi/SecPlatformInformation2.h>
|
||||||
|
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
@ -33,6 +37,10 @@
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/CpuExceptionHandlerLib.h>
|
#include <Library/CpuExceptionHandlerLib.h>
|
||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
|
#include <Library/MpInitLib.h>
|
||||||
|
|
||||||
#include <Guid/IdleLoopEvent.h>
|
#include <Guid/IdleLoopEvent.h>
|
||||||
#include <Guid/VectorHandoffTable.h>
|
#include <Guid/VectorHandoffTable.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
## @file
|
## @file
|
||||||
# Simple CPU driver installs CPU Architecture Protocol.
|
# CPU driver installs CPU Architecture Protocol and CPU MP protocol.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
|
@ -41,10 +41,9 @@
|
||||||
UefiCpuLib
|
UefiCpuLib
|
||||||
UefiLib
|
UefiLib
|
||||||
CpuExceptionHandlerLib
|
CpuExceptionHandlerLib
|
||||||
TimerLib
|
|
||||||
SynchronizationLib
|
|
||||||
HobLib
|
HobLib
|
||||||
ReportStatusCodeLib
|
ReportStatusCodeLib
|
||||||
|
MpInitLib
|
||||||
|
|
||||||
[Sources]
|
[Sources]
|
||||||
ApStartup.c
|
ApStartup.c
|
||||||
|
@ -71,7 +70,7 @@
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiCpuArchProtocolGuid ## PRODUCES
|
gEfiCpuArchProtocolGuid ## PRODUCES
|
||||||
gEfiMpServiceProtocolGuid ## SOMETIMES_PRODUCES
|
gEfiMpServiceProtocolGuid ## PRODUCES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gIdleLoopEventGuid ## CONSUMES ## Event
|
gIdleLoopEventGuid ## CONSUMES ## Event
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// /** @file
|
// /** @file
|
||||||
// Simple CPU driver installs CPU Architecture Protocol.
|
// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.
|
||||||
//
|
//
|
||||||
// Simple CPU driver installs CPU Architecture Protocol.
|
// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.
|
||||||
//
|
//
|
||||||
// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
|
// Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
//
|
//
|
||||||
// This program and the accompanying materials
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
// **/
|
// **/
|
||||||
|
|
||||||
|
|
||||||
#string STR_MODULE_ABSTRACT #language en-US "Installs CPU Architecture Protocol"
|
#string STR_MODULE_ABSTRACT #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."
|
||||||
|
|
||||||
#string STR_MODULE_DESCRIPTION #language en-US "Simple CPU driver installs CPU Architecture Protocol."
|
#string STR_MODULE_DESCRIPTION #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// /** @file
|
// /** @file
|
||||||
// CpuDxe Localized Strings and Content
|
// CpuDxe Localized Strings and Content
|
||||||
//
|
//
|
||||||
// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
|
// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
//
|
//
|
||||||
// This program and the accompanying materials
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -15,6 +15,6 @@
|
||||||
|
|
||||||
#string STR_PROPERTIES_MODULE_NAME
|
#string STR_PROPERTIES_MODULE_NAME
|
||||||
#language en-US
|
#language en-US
|
||||||
"CPU Architectural DXE Driver"
|
"CPU Architectural and CPU Multi-processor DXE Driver"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
CPU DXE Module.
|
CPU DXE Module to produce CPU MP Protocol.
|
||||||
|
|
||||||
Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -21,6 +21,7 @@ UINTN gPollInterval = 100; // 100 microseconds
|
||||||
|
|
||||||
MP_SYSTEM_DATA mMpSystemData;
|
MP_SYSTEM_DATA mMpSystemData;
|
||||||
EFI_HANDLE mMpServiceHandle = NULL;
|
EFI_HANDLE mMpServiceHandle = NULL;
|
||||||
|
UINTN mNumberOfProcessors = 1;
|
||||||
EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL;
|
EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||||
|
|
||||||
VOID *mCommonStack = 0;
|
VOID *mCommonStack = 0;
|
||||||
|
@ -28,7 +29,6 @@ VOID *mTopOfApCommonStack = 0;
|
||||||
VOID *mApStackStart = 0;
|
VOID *mApStackStart = 0;
|
||||||
|
|
||||||
volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;
|
volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;
|
||||||
volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;
|
|
||||||
|
|
||||||
EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
|
EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
|
||||||
GetNumberOfProcessors,
|
GetNumberOfProcessors,
|
||||||
|
@ -102,6 +102,7 @@ IsBSP (
|
||||||
@retval CPU_STATE the AP status
|
@retval CPU_STATE the AP status
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
CPU_STATE
|
CPU_STATE
|
||||||
GetApState (
|
GetApState (
|
||||||
IN CPU_DATA_BLOCK *CpuData
|
IN CPU_DATA_BLOCK *CpuData
|
||||||
|
@ -123,6 +124,7 @@ GetApState (
|
||||||
@param State The AP status
|
@param State The AP status
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
SetApState (
|
SetApState (
|
||||||
IN CPU_DATA_BLOCK *CpuData,
|
IN CPU_DATA_BLOCK *CpuData,
|
||||||
|
@ -452,13 +454,10 @@ GetNumberOfProcessors (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsBSP ()) {
|
return MpInitLibGetNumberOfProcessors (
|
||||||
return EFI_DEVICE_ERROR;
|
NumberOfProcessors,
|
||||||
}
|
NumberOfEnabledProcessors
|
||||||
|
);
|
||||||
*NumberOfProcessors = mMpSystemData.NumberOfProcessors;
|
|
||||||
*NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -495,20 +494,7 @@ GetProcessorInfo (
|
||||||
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (ProcessorInfoBuffer == NULL) {
|
return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsBSP ()) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMem (ProcessorInfoBuffer, &mMpSystemData.CpuDatas[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -659,155 +645,14 @@ StartupAllAPs (
|
||||||
OUT UINTN **FailedCpuList OPTIONAL
|
OUT UINTN **FailedCpuList OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
return MpInitLibStartupAllAPs (
|
||||||
CPU_DATA_BLOCK *CpuData;
|
Procedure,
|
||||||
UINTN Number;
|
SingleThread,
|
||||||
CPU_STATE APInitialState;
|
WaitEvent,
|
||||||
CPU_STATE CpuState;
|
TimeoutInMicroseconds,
|
||||||
|
ProcedureArgument,
|
||||||
CpuData = NULL;
|
FailedCpuList
|
||||||
|
);
|
||||||
if (FailedCpuList != NULL) {
|
|
||||||
*FailedCpuList = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsBSP ()) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mMpSystemData.NumberOfProcessors == 1) {
|
|
||||||
return EFI_NOT_STARTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Procedure == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// temporarily stop checkAllAPsStatus for avoid resource dead-lock.
|
|
||||||
//
|
|
||||||
mStopCheckAllAPsStatus = TRUE;
|
|
||||||
|
|
||||||
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[Number];
|
|
||||||
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
|
|
||||||
//
|
|
||||||
// Skip BSP
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
|
|
||||||
//
|
|
||||||
// Skip Disabled processors
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuState = GetApState (CpuData);
|
|
||||||
if (CpuState != CpuStateIdle &&
|
|
||||||
CpuState != CpuStateSleeping) {
|
|
||||||
return EFI_NOT_READY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mMpSystemData.Procedure = Procedure;
|
|
||||||
mMpSystemData.ProcedureArgument = ProcedureArgument;
|
|
||||||
mMpSystemData.WaitEvent = WaitEvent;
|
|
||||||
mMpSystemData.Timeout = TimeoutInMicroseconds;
|
|
||||||
mMpSystemData.TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
|
|
||||||
mMpSystemData.FinishCount = 0;
|
|
||||||
mMpSystemData.StartCount = 0;
|
|
||||||
mMpSystemData.SingleThread = SingleThread;
|
|
||||||
mMpSystemData.FailedList = FailedCpuList;
|
|
||||||
mMpSystemData.FailedListIndex = 0;
|
|
||||||
APInitialState = CpuStateReady;
|
|
||||||
|
|
||||||
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[Number];
|
|
||||||
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
|
|
||||||
//
|
|
||||||
// Skip BSP
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
|
|
||||||
//
|
|
||||||
// Skip Disabled processors
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get APs prepared, and put failing APs into FailedCpuList
|
|
||||||
// if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready
|
|
||||||
// state 1 by 1, until the previous 1 finished its task
|
|
||||||
// if not "SingleThread", all APs are put to ready state from the beginning
|
|
||||||
//
|
|
||||||
CpuState = GetApState (CpuData);
|
|
||||||
if (CpuState == CpuStateIdle ||
|
|
||||||
CpuState == CpuStateSleeping) {
|
|
||||||
mMpSystemData.StartCount++;
|
|
||||||
|
|
||||||
SetApState (CpuData, APInitialState);
|
|
||||||
|
|
||||||
if (APInitialState == CpuStateReady) {
|
|
||||||
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
|
||||||
//
|
|
||||||
// If this AP previous state is Sleeping, we should
|
|
||||||
// wake up this AP by sent a SIPI. and avoid
|
|
||||||
// re-involve the sleeping state. we must call
|
|
||||||
// SetApProcedure() first.
|
|
||||||
//
|
|
||||||
if (CpuState == CpuStateSleeping) {
|
|
||||||
ResetProcessorToIdleState (CpuData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SingleThread) {
|
|
||||||
APInitialState = CpuStateBlocked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mStopCheckAllAPsStatus = FALSE;
|
|
||||||
|
|
||||||
if (WaitEvent != NULL) {
|
|
||||||
//
|
|
||||||
// non blocking
|
|
||||||
//
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Blocking temporarily stop CheckAllAPsStatus()
|
|
||||||
//
|
|
||||||
mStopCheckAllAPsStatus = TRUE;
|
|
||||||
|
|
||||||
while (TRUE) {
|
|
||||||
CheckAndUpdateAllAPsToIdleState ();
|
|
||||||
if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// task timeout
|
|
||||||
//
|
|
||||||
if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
|
|
||||||
ResetAllFailedAPs();
|
|
||||||
Status = EFI_TIMEOUT;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
MicroSecondDelay (gPollInterval);
|
|
||||||
mMpSystemData.Timeout -= gPollInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
Done:
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -908,90 +753,14 @@ StartupThisAP (
|
||||||
OUT BOOLEAN *Finished OPTIONAL
|
OUT BOOLEAN *Finished OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CPU_DATA_BLOCK *CpuData;
|
return MpInitLibStartupThisAP (
|
||||||
CPU_STATE CpuState;
|
Procedure,
|
||||||
|
ProcessorNumber,
|
||||||
CpuData = NULL;
|
WaitEvent,
|
||||||
|
TimeoutInMicroseconds,
|
||||||
if (Finished != NULL) {
|
ProcedureArgument,
|
||||||
*Finished = FALSE;
|
Finished
|
||||||
}
|
);
|
||||||
|
|
||||||
if (!IsBSP ()) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Procedure == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// temporarily stop checkAllAPsStatus for avoid resource dead-lock.
|
|
||||||
//
|
|
||||||
mStopCheckAllAPsStatus = TRUE;
|
|
||||||
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
|
|
||||||
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) ||
|
|
||||||
!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuState = GetApState (CpuData);
|
|
||||||
if (CpuState != CpuStateIdle &&
|
|
||||||
CpuState != CpuStateSleeping) {
|
|
||||||
return EFI_NOT_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetApState (CpuData, CpuStateReady);
|
|
||||||
|
|
||||||
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
|
||||||
//
|
|
||||||
// If this AP previous state is Sleeping, we should
|
|
||||||
// wake up this AP by sent a SIPI. and avoid
|
|
||||||
// re-involve the sleeping state. we must call
|
|
||||||
// SetApProcedure() first.
|
|
||||||
//
|
|
||||||
if (CpuState == CpuStateSleeping) {
|
|
||||||
ResetProcessorToIdleState (CpuData);
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuData->Timeout = TimeoutInMicroseconds;
|
|
||||||
CpuData->WaitEvent = WaitEvent;
|
|
||||||
CpuData->TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
|
|
||||||
CpuData->Finished = Finished;
|
|
||||||
|
|
||||||
mStopCheckAllAPsStatus = FALSE;
|
|
||||||
|
|
||||||
if (WaitEvent != NULL) {
|
|
||||||
//
|
|
||||||
// Non Blocking
|
|
||||||
//
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Blocking
|
|
||||||
//
|
|
||||||
while (TRUE) {
|
|
||||||
if (GetApState (CpuData) == CpuStateFinished) {
|
|
||||||
SetApState (CpuData, CpuStateIdle);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
|
|
||||||
ResetProcessorToIdleState (CpuData);
|
|
||||||
return EFI_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MicroSecondDelay (gPollInterval);
|
|
||||||
CpuData->Timeout -= gPollInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1037,10 +806,7 @@ SwitchBSP (
|
||||||
IN BOOLEAN EnableOldBSP
|
IN BOOLEAN EnableOldBSP
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
|
||||||
// Current always return unsupported.
|
|
||||||
//
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1093,62 +859,7 @@ EnableDisableAP (
|
||||||
IN UINT32 *HealthFlag OPTIONAL
|
IN UINT32 *HealthFlag OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CPU_DATA_BLOCK *CpuData;
|
return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
|
||||||
BOOLEAN TempStopCheckState;
|
|
||||||
CPU_STATE CpuState;
|
|
||||||
|
|
||||||
CpuData = NULL;
|
|
||||||
TempStopCheckState = FALSE;
|
|
||||||
|
|
||||||
if (!IsBSP ()) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// temporarily stop checkAllAPsStatus for initialize parameters.
|
|
||||||
//
|
|
||||||
if (!mStopCheckAllAPsStatus) {
|
|
||||||
mStopCheckAllAPsStatus = TRUE;
|
|
||||||
TempStopCheckState = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
|
|
||||||
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuState = GetApState (CpuData);
|
|
||||||
if (CpuState != CpuStateIdle &&
|
|
||||||
CpuState != CpuStateSleeping) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EnableAP) {
|
|
||||||
if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) {
|
|
||||||
mMpSystemData.NumberOfEnabledProcessors++;
|
|
||||||
}
|
|
||||||
CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT);
|
|
||||||
} else {
|
|
||||||
if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
|
|
||||||
mMpSystemData.NumberOfEnabledProcessors--;
|
|
||||||
}
|
|
||||||
CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HealthFlag != NULL) {
|
|
||||||
CpuStatusFlagAndNot (CpuData, (UINT32)~PROCESSOR_HEALTH_STATUS_BIT);
|
|
||||||
CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TempStopCheckState) {
|
|
||||||
mStopCheckAllAPsStatus = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1182,383 +893,7 @@ WhoAmI (
|
||||||
OUT UINTN *ProcessorNumber
|
OUT UINTN *ProcessorNumber
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
return MpInitLibWhoAmI (ProcessorNumber);;
|
||||||
UINT32 ProcessorId;
|
|
||||||
|
|
||||||
if (ProcessorNumber == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessorId = GetApicId ();
|
|
||||||
for (Index = 0; Index < mMpSystemData.NumberOfProcessors; Index++) {
|
|
||||||
if (mMpSystemData.CpuDatas[Index].Info.ProcessorId == ProcessorId) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ProcessorNumber = Index;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Terminate AP's task and set it to idle state.
|
|
||||||
|
|
||||||
This function terminates AP's task due to timeout by sending INIT-SIPI,
|
|
||||||
and sends it to idle state.
|
|
||||||
|
|
||||||
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
ResetProcessorToIdleState (
|
|
||||||
IN CPU_DATA_BLOCK *CpuData
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ResetApStackless ((UINT32)CpuData->Info.ProcessorId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Application Processors do loop routine
|
|
||||||
after switch to its own stack.
|
|
||||||
|
|
||||||
@param Context1 A pointer to the context to pass into the function.
|
|
||||||
@param Context2 A pointer to the context to pass into the function.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
ProcessorToIdleState (
|
|
||||||
IN VOID *Context1, OPTIONAL
|
|
||||||
IN VOID *Context2 OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN ProcessorNumber;
|
|
||||||
CPU_DATA_BLOCK *CpuData;
|
|
||||||
EFI_AP_PROCEDURE Procedure;
|
|
||||||
volatile VOID *ProcedureArgument;
|
|
||||||
|
|
||||||
AsmApDoneWithCommonStack ();
|
|
||||||
|
|
||||||
while (!mAPsAlreadyInitFinished) {
|
|
||||||
CpuPause ();
|
|
||||||
}
|
|
||||||
|
|
||||||
WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Avoid forcibly reset AP caused the AP got lock not release.
|
|
||||||
//
|
|
||||||
if (CpuData->LockSelf == (INTN) GetApicId ()) {
|
|
||||||
ReleaseSpinLock (&CpuData->CpuDataLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Avoid forcibly reset AP caused the timeout AP State is not
|
|
||||||
// updated.
|
|
||||||
//
|
|
||||||
GetMpSpinLock (CpuData);
|
|
||||||
if (CpuData->State == CpuStateBusy) {
|
|
||||||
CpuData->Procedure = NULL;
|
|
||||||
}
|
|
||||||
CpuData->State = CpuStateIdle;
|
|
||||||
ReleaseMpSpinLock (CpuData);
|
|
||||||
|
|
||||||
while (TRUE) {
|
|
||||||
GetMpSpinLock (CpuData);
|
|
||||||
ProcedureArgument = CpuData->Parameter;
|
|
||||||
Procedure = CpuData->Procedure;
|
|
||||||
ReleaseMpSpinLock (CpuData);
|
|
||||||
|
|
||||||
if (Procedure != NULL) {
|
|
||||||
SetApState (CpuData, CpuStateBusy);
|
|
||||||
|
|
||||||
Procedure ((VOID*) ProcedureArgument);
|
|
||||||
|
|
||||||
GetMpSpinLock (CpuData);
|
|
||||||
CpuData->Procedure = NULL;
|
|
||||||
CpuData->State = CpuStateFinished;
|
|
||||||
ReleaseMpSpinLock (CpuData);
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// if no procedure to execution, we simply put AP
|
|
||||||
// into sleeping state, and waiting BSP sent SIPI.
|
|
||||||
//
|
|
||||||
GetMpSpinLock (CpuData);
|
|
||||||
if (CpuData->State == CpuStateIdle) {
|
|
||||||
CpuData->State = CpuStateSleeping;
|
|
||||||
}
|
|
||||||
ReleaseMpSpinLock (CpuData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetApState (CpuData) == CpuStateSleeping) {
|
|
||||||
CpuSleep ();
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuPause ();
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuSleep ();
|
|
||||||
CpuDeadLoop ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks AP' status periodically.
|
|
||||||
|
|
||||||
This function is triggerred by timer perodically to check the
|
|
||||||
state of AP forStartupThisAP() executed in non-blocking mode.
|
|
||||||
|
|
||||||
@param Event Event triggered.
|
|
||||||
@param Context Parameter passed with the event.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
CheckThisAPStatus (
|
|
||||||
IN EFI_EVENT Event,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CPU_DATA_BLOCK *CpuData;
|
|
||||||
CPU_STATE CpuState;
|
|
||||||
|
|
||||||
CpuData = (CPU_DATA_BLOCK *) Context;
|
|
||||||
if (CpuData->TimeoutActive) {
|
|
||||||
CpuData->Timeout -= gPollInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
CpuState = GetApState (CpuData);
|
|
||||||
|
|
||||||
if (CpuState == CpuStateFinished) {
|
|
||||||
if (CpuData->Finished) {
|
|
||||||
*CpuData->Finished = TRUE;
|
|
||||||
}
|
|
||||||
SetApState (CpuData, CpuStateIdle);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
|
|
||||||
if (CpuState != CpuStateIdle &&
|
|
||||||
CpuData->Finished) {
|
|
||||||
*CpuData->Finished = FALSE;
|
|
||||||
}
|
|
||||||
ResetProcessorToIdleState (CpuData);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
out:
|
|
||||||
CpuData->TimeoutActive = FALSE;
|
|
||||||
gBS->SignalEvent (CpuData->WaitEvent);
|
|
||||||
CpuData->WaitEvent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks APs' status periodically.
|
|
||||||
|
|
||||||
This function is triggerred by timer perodically to check the
|
|
||||||
state of APs for StartupAllAPs() executed in non-blocking mode.
|
|
||||||
|
|
||||||
@param Event Event triggered.
|
|
||||||
@param Context Parameter passed with the event.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
CheckAllAPsStatus (
|
|
||||||
IN EFI_EVENT Event,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CPU_DATA_BLOCK *CpuData;
|
|
||||||
UINTN Number;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (mMpSystemData.TimeoutActive) {
|
|
||||||
mMpSystemData.Timeout -= gPollInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mStopCheckAllAPsStatus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// avoid next timer enter.
|
|
||||||
//
|
|
||||||
Status = gBS->SetTimer (
|
|
||||||
mMpSystemData.CheckAllAPsEvent,
|
|
||||||
TimerCancel,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
if (mMpSystemData.WaitEvent != NULL) {
|
|
||||||
CheckAndUpdateAllAPsToIdleState ();
|
|
||||||
//
|
|
||||||
// task timeout
|
|
||||||
//
|
|
||||||
if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
|
|
||||||
ResetAllFailedAPs();
|
|
||||||
//
|
|
||||||
// force exit
|
|
||||||
//
|
|
||||||
mMpSystemData.FinishCount = mMpSystemData.StartCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
|
|
||||||
goto EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMpSystemData.TimeoutActive = FALSE;
|
|
||||||
gBS->SignalEvent (mMpSystemData.WaitEvent);
|
|
||||||
mMpSystemData.WaitEvent = NULL;
|
|
||||||
mStopCheckAllAPsStatus = TRUE;
|
|
||||||
|
|
||||||
goto EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check each AP status for StartupThisAP
|
|
||||||
//
|
|
||||||
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[Number];
|
|
||||||
if (CpuData->WaitEvent) {
|
|
||||||
CheckThisAPStatus (NULL, (VOID *)CpuData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXIT:
|
|
||||||
Status = gBS->SetTimer (
|
|
||||||
mMpSystemData.CheckAllAPsEvent,
|
|
||||||
TimerPeriodic,
|
|
||||||
EFI_TIMER_PERIOD_MICROSECONDS (100)
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Application Processor C code entry point.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ApEntryPointInC (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
VOID* TopOfApStack;
|
|
||||||
UINTN ProcessorNumber;
|
|
||||||
|
|
||||||
if (!mAPsAlreadyInitFinished) {
|
|
||||||
FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
|
|
||||||
TopOfApStack = (UINT8*)mApStackStart + gApStackSize;
|
|
||||||
mApStackStart = TopOfApStack;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Store the Stack address, when reset the AP, We can found the original address.
|
|
||||||
//
|
|
||||||
mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack;
|
|
||||||
mMpSystemData.NumberOfProcessors++;
|
|
||||||
mMpSystemData.NumberOfEnabledProcessors++;
|
|
||||||
} else {
|
|
||||||
WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
|
|
||||||
//
|
|
||||||
// Get the original stack address.
|
|
||||||
//
|
|
||||||
TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitchStack (
|
|
||||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
TopOfApStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
This function is called by all processors (both BSP and AP) once and collects MP related data.
|
|
||||||
|
|
||||||
@param Bsp TRUE if the CPU is BSP
|
|
||||||
@param ProcessorNumber The specific processor number
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data for the processor collected and filled in
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
FillInProcessorInformation (
|
|
||||||
IN BOOLEAN Bsp,
|
|
||||||
IN UINTN ProcessorNumber
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CPU_DATA_BLOCK *CpuData;
|
|
||||||
UINT32 ProcessorId;
|
|
||||||
|
|
||||||
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
|
|
||||||
ProcessorId = GetApicId ();
|
|
||||||
CpuData->Info.ProcessorId = ProcessorId;
|
|
||||||
CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
|
|
||||||
if (Bsp) {
|
|
||||||
CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
|
|
||||||
}
|
|
||||||
CpuData->Info.Location.Package = ProcessorId;
|
|
||||||
CpuData->Info.Location.Core = 0;
|
|
||||||
CpuData->Info.Location.Thread = 0;
|
|
||||||
CpuData->State = Bsp ? CpuStateBusy : CpuStateIdle;
|
|
||||||
|
|
||||||
CpuData->Procedure = NULL;
|
|
||||||
CpuData->Parameter = NULL;
|
|
||||||
InitializeSpinLock (&CpuData->CpuDataLock);
|
|
||||||
CpuData->LockSelf = -1;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Prepare the System Data.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS the System Data finished initilization.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
InitMpSystemData (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));
|
|
||||||
|
|
||||||
mMpSystemData.NumberOfProcessors = 1;
|
|
||||||
mMpSystemData.NumberOfEnabledProcessors = 1;
|
|
||||||
|
|
||||||
mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber);
|
|
||||||
ASSERT(mMpSystemData.CpuDatas != NULL);
|
|
||||||
|
|
||||||
Status = gBS->CreateEvent (
|
|
||||||
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
|
||||||
TPL_CALLBACK,
|
|
||||||
CheckAllAPsStatus,
|
|
||||||
NULL,
|
|
||||||
&mMpSystemData.CheckAllAPsEvent
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set timer to check all APs status.
|
|
||||||
//
|
|
||||||
Status = gBS->SetTimer (
|
|
||||||
mMpSystemData.CheckAllAPsEvent,
|
|
||||||
TimerPeriodic,
|
|
||||||
EFI_TIMER_PERIOD_MICROSECONDS (100)
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// BSP
|
|
||||||
//
|
|
||||||
FillInProcessorInformation (TRUE, 0);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1580,8 +915,8 @@ CollectBistDataFromHob (
|
||||||
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
|
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
|
||||||
UINTN ProcessorNumber;
|
UINTN ProcessorNumber;
|
||||||
UINT32 InitialLocalApicId;
|
EFI_PROCESSOR_INFORMATION ProcessorInfo;
|
||||||
CPU_DATA_BLOCK *CpuData;
|
EFI_HEALTH_FLAGS BistData;
|
||||||
|
|
||||||
SecPlatformInformation2 = NULL;
|
SecPlatformInformation2 = NULL;
|
||||||
SecPlatformInformation = NULL;
|
SecPlatformInformation = NULL;
|
||||||
|
@ -1622,23 +957,22 @@ CollectBistDataFromHob (
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((NumberOfData--) > 0) {
|
while ((NumberOfData--) > 0) {
|
||||||
for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
|
for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) {
|
||||||
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
|
MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
|
||||||
InitialLocalApicId = (UINT32) CpuData->Info.ProcessorId;
|
if (ProcessorInfo.ProcessorId == CpuInstance[NumberOfData].CpuLocation) {
|
||||||
if (InitialLocalApicId == CpuInstance[NumberOfData].CpuLocation) {
|
|
||||||
//
|
//
|
||||||
// Update CPU health status for MP Services Protocol according to BIST data.
|
// Update CPU health status for MP Services Protocol according to BIST data.
|
||||||
//
|
//
|
||||||
if (CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags.Uint32 != 0) {
|
BistData = CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags;
|
||||||
CpuData->Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
|
}
|
||||||
//
|
if (BistData.Uint32 != 0) {
|
||||||
// Report Status Code that self test is failed
|
//
|
||||||
//
|
// Report Status Code that self test is failed
|
||||||
REPORT_STATUS_CODE (
|
//
|
||||||
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
|
REPORT_STATUS_CODE (
|
||||||
(EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
|
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
|
||||||
);
|
(EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1692,115 +1026,37 @@ InitializeMpSupport (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
MTRR_SETTINGS MtrrSettings;
|
UINTN NumberOfProcessors;
|
||||||
UINTN Timeout;
|
UINTN NumberOfEnabledProcessors;
|
||||||
|
|
||||||
gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
|
NumberOfProcessors = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
|
||||||
if (gMaxLogicalProcessorNumber < 1) {
|
if (NumberOfProcessors < 1) {
|
||||||
DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
|
DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
InitMpSystemData ();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
|
// Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
|
||||||
//
|
//
|
||||||
if (gMaxLogicalProcessorNumber > 1) {
|
if (NumberOfProcessors > 1) {
|
||||||
|
Status = MpInitLibInitialize ();
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
|
MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);
|
||||||
ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);
|
mNumberOfProcessors = NumberOfProcessors;
|
||||||
|
|
||||||
mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
|
|
||||||
ASSERT (mApStackStart != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// the first buffer of stack size used for common stack, when the amount of AP
|
|
||||||
// more than 1, we should never free the common stack which maybe used for AP reset.
|
|
||||||
//
|
|
||||||
mCommonStack = mApStackStart;
|
|
||||||
mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;
|
|
||||||
mApStackStart = mTopOfApCommonStack;
|
|
||||||
|
|
||||||
PrepareAPStartupCode ();
|
|
||||||
|
|
||||||
StartApsStackless ();
|
|
||||||
}
|
}
|
||||||
|
DEBUG ((EFI_D_ERROR, "Detect CPU count: %d\n", mNumberOfProcessors));
|
||||||
DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors));
|
|
||||||
if (mMpSystemData.NumberOfProcessors == 1) {
|
|
||||||
FreeApStartupCode ();
|
|
||||||
if (mCommonStack != NULL) {
|
|
||||||
FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mMpSystemData.CpuDatas = ReallocatePool (
|
|
||||||
sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber,
|
|
||||||
sizeof (CPU_DATA_BLOCK) * mMpSystemData.NumberOfProcessors,
|
|
||||||
mMpSystemData.CpuDatas);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Release all APs to complete initialization and enter idle loop
|
|
||||||
//
|
|
||||||
mAPsAlreadyInitFinished = TRUE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Wait for all APs to enter idle loop.
|
|
||||||
//
|
|
||||||
Timeout = 0;
|
|
||||||
do {
|
|
||||||
if (CheckAllAPsSleeping ()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MicroSecondDelay (gPollInterval);
|
|
||||||
Timeout += gPollInterval;
|
|
||||||
} while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
|
|
||||||
ASSERT (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update CPU healthy information from Guided HOB
|
// Update CPU healthy information from Guided HOB
|
||||||
//
|
//
|
||||||
CollectBistDataFromHob ();
|
CollectBistDataFromHob ();
|
||||||
|
|
||||||
//
|
|
||||||
// Synchronize MTRR settings to APs.
|
|
||||||
//
|
|
||||||
MtrrGetAllMtrrs (&MtrrSettings);
|
|
||||||
Status = mMpServicesTemplate.StartupAllAPs (
|
|
||||||
&mMpServicesTemplate, // This
|
|
||||||
SetMtrrsFromBuffer, // Procedure
|
|
||||||
TRUE, // SingleThread
|
|
||||||
NULL, // WaitEvent
|
|
||||||
0, // TimeoutInMicrosecsond
|
|
||||||
&MtrrSettings, // ProcedureArgument
|
|
||||||
NULL // FailedCpuList
|
|
||||||
);
|
|
||||||
ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_STARTED);
|
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&mMpServiceHandle,
|
&mMpServiceHandle,
|
||||||
&gEfiMpServiceProtocolGuid, &mMpServicesTemplate,
|
&gEfiMpServiceProtocolGuid, &mMpServicesTemplate,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
if (mMpSystemData.NumberOfProcessors > 1 && mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
|
|
||||||
if (mApStackStart != NULL) {
|
|
||||||
FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
|
|
||||||
(gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *
|
|
||||||
gApStackSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = gBS->CreateEvent (
|
|
||||||
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
|
||||||
TPL_CALLBACK,
|
|
||||||
ExitBootServicesCallback,
|
|
||||||
NULL,
|
|
||||||
&mExitBootServicesEvent
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#include <Ppi/SecPlatformInformation2.h>
|
#include <Ppi/SecPlatformInformation2.h>
|
||||||
#include <Protocol/MpService.h>
|
#include <Protocol/MpService.h>
|
||||||
#include <Library/SynchronizationLib.h>
|
#include <Library/SynchronizationLib.h>
|
||||||
#include <Library/HobLib.h>
|
|
||||||
#include <Library/ReportStatusCodeLib.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize Multi-processor support.
|
Initialize Multi-processor support.
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||||
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
|
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
|
||||||
|
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.DXE_SMM_DRIVER]
|
[LibraryClasses.common.DXE_SMM_DRIVER]
|
||||||
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
|
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
|
||||||
|
|
Loading…
Reference in New Issue