MicrocodeDetect function will run by every threads, and it will
use PcdGet to get PcdCpuMicrocodePatchAddress and
PcdCpuMicrocodePatchRegionSize, if change both PCD default to dynamic,
system will in non-deterministic behavior.
By design, UEFI/PI services are single threaded and not re-entrant
so Multi processor code should not use UEFI/PI services. Here, Pcd
protocol/PPI is used to access dynamic PCDs so it would result in
non-deterministic behavior.
This code get PCD value in BSP and save them in CPU_MP_DATA for Ap.
https://bugzilla.tianocore.org/show_bug.cgi?id=726
Cc: Crystal Lee <CrystalLee@ami.com.tw>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
/** @file\r
Implementation of loading microcode on processors.\r
\r
/** @file\r
Implementation of loading microcode on processors.\r
\r
- Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- UINT64 MicrocodePatchAddress;\r
- UINT64 MicrocodePatchRegionSize;\r
UINT32 ExtendedTableLength;\r
UINT32 ExtendedTableCount;\r
CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;\r
UINT32 ExtendedTableLength;\r
UINT32 ExtendedTableCount;\r
CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;\r
VOID *MicrocodeData;\r
MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
\r
VOID *MicrocodeData;\r
MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
\r
- MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);\r
- MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);\r
- if (MicrocodePatchRegionSize == 0) {\r
+ if (CpuMpData->MicrocodePatchRegionSize == 0) {\r
//\r
// There is no microcode patches\r
//\r
//\r
// There is no microcode patches\r
//\r
\r
LatestRevision = 0;\r
MicrocodeData = NULL;\r
\r
LatestRevision = 0;\r
MicrocodeData = NULL;\r
- MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);\r
- MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;\r
+ MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize);\r
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->MicrocodePatchAddress;\r
do {\r
//\r
// Check if the microcode is for the Cpu and the version is newer\r
do {\r
//\r
// Check if the microcode is for the Cpu and the version is newer\r
CpuMpData->SwitchBspFlag = FALSE;\r
CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);\r
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
CpuMpData->SwitchBspFlag = FALSE;\r
CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);\r
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
+ CpuMpData->MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);\r
+ CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);\r
InitializeSpinLock(&CpuMpData->MpLock);\r
//\r
// Save BSP's Control registers to APs\r
InitializeSpinLock(&CpuMpData->MpLock);\r
//\r
// Save BSP's Control registers to APs\r
UINT8 Vector;\r
BOOLEAN PeriodicMode;\r
BOOLEAN TimerInterruptState;\r
UINT8 Vector;\r
BOOLEAN PeriodicMode;\r
BOOLEAN TimerInterruptState;\r
+ UINT64 MicrocodePatchAddress;\r
+ UINT64 MicrocodePatchRegionSize;\r
};\r
\r
extern EFI_GUID mCpuInitMpLibHobGuid;\r
};\r
\r
extern EFI_GUID mCpuInitMpLibHobGuid;\r