summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/Library
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 13:33:16 +0800
committerGuo Mang <mang.guo@intel.com>2017-05-09 13:02:58 +0800
commite7b8e072fd6da92d7820b0a18c30bd3eea6ffc44 (patch)
tree99cae09b138c37a958c7e4e80e318ad20dab553f /Platform/BroxtonPlatformPkg/Common/Library
parent54901c47dd992753dfce0a234c8cd53492e70d1a (diff)
downloadedk2-platforms-e7b8e072fd6da92d7820b0a18c30bd3eea6ffc44.tar.xz
BroxtonPlatformPkg: Add package Include and Library
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common/Library')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.c757
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.h47
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.inf37
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.c269
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.inf42
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/PlatformStatusCodesInternal.h343
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/BasePostCodeLibPort80Ex.inf44
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/PostCode.c133
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.c498
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.c392
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.c74
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.inf38
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.c326
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.inf48
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/CpuIA32Lib.inf39
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/EfiCpuVersion.c68
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.S213
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.asm194
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.c174
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.S204
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.asm210
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.c1265
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.inf70
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/DxeLogoLib.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/Logo.c856
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf48
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c101
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h40
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.c492
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.h51
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.inf55
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.c269
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.inf40
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c578
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf34
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.c255
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.inf50
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/DebugLib.c265
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/PeiDebugLib.inf52
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.c434
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.inf58
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c127
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h162
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf99
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLibPreMem.c105
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c283
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspScPolicyInitLib.c625
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c54
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.c198
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.inf56
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.c96
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h60
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.c46
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.h27
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf55
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c39
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.c57
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.h58
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.c60
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.h47
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.c175
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.h30
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c232
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h53
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c36
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf93
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c254
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h43
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.c773
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.h41
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c65
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h26
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.c240
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.h46
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.inf48
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c2401
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h465
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c586
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h330
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm54
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S42
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm49
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S41
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h168
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c247
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf142
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c242
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.c120
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.inf37
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset.inc107
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset_S.inc109
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32.inc167
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32_S.inc164
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform.inc99
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform_S.inc92
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore.inc37
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore_S.inc37
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.S570
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.asm536
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.c124
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.h36
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Vtf0PlatformSecLib.inf85
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.c952
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.inf69
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.c47
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.c105
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.inf66
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.c79
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibInternal.h58
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibShare.c283
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.c150
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.inf53
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/CommonHeader.h29
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.c565
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.inf48
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.c1089
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.inf62
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmm.c90
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmmLib.inf47
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.c84
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.inf43
125 files changed, 24888 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.c b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.c
new file mode 100644
index 0000000000..1746036303
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.c
@@ -0,0 +1,757 @@
+/** @file
+ CMOS access library instance.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BaseCmosAccessLib.h"
+
+
+/**
+ Writes an 8-bit to I/O port.
+
+ Writes the 8-bit to I/O port specified by PortAdd with the value specified by Value
+ and returns Value.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param[in] PortAdd The I/O port to write.
+ @param[in] Value The value to write to the I/O port.
+
+ @retval Value The value written to the I/O port.
+
+**/
+UINT8
+WriteIoPort (
+ IN UINT8 PortAdd,
+ IN UINT8 Value
+ )
+{
+ return IoWrite8 (PortAdd, Value);
+}
+
+
+/**
+ Reads an 8-bit from I/O port.
+
+ Reads the 8-bit from I/O port specified by PortAdd and returns value.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param[in] PortAdd The I/O port to read.
+
+ @retval Value The value read from the I/O port.
+
+**/
+UINT8
+ReadIoPort (
+ IN UINT8 PortAdd
+ )
+{
+ return IoRead8 (PortAdd);
+}
+
+
+/**
+ Check if the CMOS location has to be included for the Checksum calculation.
+
+ @param[in] CmosAddCnt Cmos address to be checked
+
+ @retval TRUE CMOS location need to be skipped for Checksum calculation.
+ @retval FALSE CMOS location need to be included for Checksum calculation.
+
+**/
+BOOLEAN
+CheckIfSkipChkSum (
+ IN UINT8 CmosAddCnt
+ )
+{
+ UINTN TabLen;
+ UINT16 Count;
+ CMOS_ENTRY *TabPtr;
+ EFI_STATUS Status;
+
+ Status = GetPlatformCmosEntry (&TabPtr, &TabLen);
+ if (EFI_ERROR (Status)) {
+ return TRUE;
+ }
+
+ for (Count = 0; Count < TabLen; Count++) {
+ if (TabPtr[Count].CmosAddress == CmosAddCnt) {
+ if (TabPtr[Count].Attribute & CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Check if the CMOS location has to be included for filling default data.
+
+ @param[in] CmosAddCnt Cmos address to be checked
+
+ @retval TRUE CMOS location need to be skipped for filling default data.
+ @retval FALSE CMOS location need to be included for filling default data.
+
+**/
+BOOLEAN
+CheckIfSkipFillData (
+ IN UINT8 CmosAddCnt
+ )
+{
+ UINTN TabLen;
+ UINT16 Count;
+ CMOS_ENTRY *TabPtr;
+ EFI_STATUS Status;
+
+ Status = GetPlatformCmosEntry (&TabPtr, &TabLen);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ for (Count = 0; Count < TabLen; Count++) {
+ if (TabPtr[Count].CmosAddress == CmosAddCnt) {
+ if (TabPtr[Count].Attribute & CMOS_ATTRIBUTE_EXCLUDE_FROM_INIT_DATA) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Performs the calculation of Checksum.
+
+ @retval ChkSumVal calculated CheckSum value
+
+**/
+UINT16
+CalculateCmosCheckSum (
+ VOID
+ )
+{
+ UINT16 ChkSumVal;
+ UINT16 CmosReg;
+ UINT8 Data;
+ BOOLEAN NeedSkip;
+
+ ChkSumVal = 0;
+ Data = 0;
+
+ for (CmosReg = CMOS_START_ADDR; CmosReg <= CMOS_END_ADDR; CmosReg ++) {
+ NeedSkip = CheckIfSkipChkSum ((UINT8) CmosReg);
+
+ //
+ // Skip these during checksum calculation.
+ // If the CMOS table Attribute is 1 and
+ // If the place of saving checksum
+ //
+ if (NeedSkip || (CmosReg == CMOS_CHECKSUM_ADDR_LOW) || (CmosReg == CMOS_CHECKSUM_ADDR_HIGH)) {
+ continue;
+ }
+
+ ReadCmos ((UINT8) CmosReg, &Data);
+ ChkSumVal = ChkSumVal + Data;
+ }
+
+ return ChkSumVal;
+}
+
+
+/**
+ Reads from the checksum address.
+
+ Reads the 8-bit checksum from specified CheckSum address. The 8-bit read value is returned.
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @retval ChkSumVal The value read.
+
+**/
+UINT16
+ReadCheckSum (
+ VOID
+ )
+{
+ UINT16 ChkSumVal;
+ UINT8 LVal;
+ UINT8 HVal;
+ UINT8 APort;
+ UINT8 DPort;
+ UINT8 TCmosAddress;
+
+ //
+ // Check if Check sum address lies in the CMOS Lower memory or CMOS upper memory
+ //
+ if ((CMOS_CHECKSUM_ADDR_LOW >= CMOS_LOW_MEM_ST) && (CMOS_CHECKSUM_ADDR_LOW < CMOS_LOW_MEM_END)) {
+ APort = PORT_70;
+ DPort = PORT_71;
+ } else {
+ APort = PORT_72;
+ DPort = PORT_73;
+ }
+
+ TCmosAddress = CMOS_CHECKSUM_ADDR_HIGH;
+ WriteIoPort (APort, TCmosAddress);
+ HVal = ReadIoPort (DPort);
+
+ TCmosAddress = CMOS_CHECKSUM_ADDR_LOW;
+ WriteIoPort (APort, TCmosAddress);
+ LVal = ReadIoPort (DPort);
+
+ ChkSumVal = HVal;
+ ChkSumVal = ChkSumVal << 8;
+ ChkSumVal = ChkSumVal + LVal;
+
+ return ChkSumVal;
+}
+
+
+/**
+ Write the Checksum to appropriate address.
+
+ Write the 8-bit checksum to specified CheckSum address.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param[in] ChecksumValue
+
+**/
+VOID
+WriteCheckSum (
+ IN UINT16 ChecksumValue
+ )
+{
+ UINT8 LVal;
+ UINT8 HVal;
+ UINT8 APort;
+ UINT8 DPort;
+ UINT8 TCmosAddress;
+
+ //
+ // spliting the 16 bit checksum
+ //
+ LVal = (UINT8) (ChecksumValue & 0x00FF);
+ HVal = (UINT8) ((ChecksumValue >> 8) & 0x00FF);
+
+ //
+ // Check if Check sum address lies in the CMOS Lower memory or CMOS upper memory
+ //
+ if ((CMOS_CHECKSUM_ADDR_LOW >= CMOS_LOW_MEM_ST) && (CMOS_CHECKSUM_ADDR_LOW < CMOS_LOW_MEM_END)) {
+ APort = PORT_70;
+ DPort = PORT_71;
+ } else {
+ APort = PORT_72;
+ DPort = PORT_73;
+ }
+
+ TCmosAddress = CMOS_CHECKSUM_ADDR_LOW ;
+ WriteIoPort (APort, TCmosAddress);
+ WriteIoPort (DPort, LVal);
+
+ TCmosAddress = CMOS_CHECKSUM_ADDR_HIGH ;
+ WriteIoPort (APort, TCmosAddress);
+ WriteIoPort (DPort, HVal);
+
+ return ;
+}
+
+
+/**
+ Calculates and update the Checksum to appropriate address.
+
+ Write the 8-bit checksum to specified CheckSum address.
+
+**/
+VOID
+UpdateCheckSum (
+ VOID
+ )
+{
+ UINT16 NewChkSum;
+
+ //
+ // Calculate the new checksum
+ //
+ NewChkSum = CalculateCmosCheckSum ();
+
+ //
+ // Write the New checksum to the Checksum field
+ //
+ WriteCheckSum (NewChkSum);
+
+ return;
+}
+
+
+/**
+ Check if the CMOS is corrupted by verifing the Checksum value.
+
+ @retval TRUE CMOS checksum is correct
+ @retval FALSE CMOS checksum is wrong
+
+**/
+BOOLEAN
+VerifyCmosCheckSum (
+ VOID
+ )
+{
+ UINT16 StoredChkSum;
+ UINT16 CurrentChkSum;
+
+ StoredChkSum = (UINT16) ReadCheckSum ();
+ CurrentChkSum = (UINT16) CalculateCmosCheckSum ();
+
+ if (CurrentChkSum == StoredChkSum) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/**
+ Fill CMOS registers with the default values.
+
+**/
+VOID
+CmosFillDefaults (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT16 CmosAddress;
+ UINT16 Count;
+ UINTN TabLen;
+ UINT8 DefVal;
+ CMOS_ENTRY *TabPtr;
+
+ Status = GetPlatformCmosEntry (&TabPtr, &TabLen);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ //
+ // Traverse thro entire CMOS location and fill it with zero
+ //
+ for (CmosAddress = CMOS_START_ADDR ; CmosAddress <= CMOS_END_ADDR; CmosAddress++) {
+ DefVal = 0;
+ if (!CheckIfSkipFillData ((UINT8) CmosAddress)) {
+ WriteCmos ((UINT8) CmosAddress, &DefVal);
+ }
+ }
+
+ //
+ // Now fill only the CMOS location specified in the table
+ // with default value from the table
+ //
+ for (Count = 0; Count < TabLen; Count++) {
+ CmosAddress = (UINT8) (TabPtr[Count].CmosAddress);
+ DefVal = TabPtr[Count].DefaultValue;
+ if (!CheckIfSkipFillData ((UINT8) CmosAddress)) {
+ WriteCmos ((UINT8) CmosAddress, &DefVal);
+ }
+ }
+
+ //
+ // Calculate and update the new checksum
+ //
+ UpdateCheckSum ();
+ return ;
+}
+
+
+/**
+ Returns the value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to read from CMOS
+ @param[out] Data Contains the value read from the CMOS
+
+ @retval RETURN_SUCCESS
+ @retval RETURN_NOT_FOUND
+
+**/
+RETURN_STATUS
+EFIAPI
+ReadCmos (
+ IN UINT8 CmosAddress,
+ OUT UINT8 *Data
+ )
+{
+ //
+ // Initial validation of the CMOS address
+ //
+ if ((CmosAddress < CMOS_START_ADDR) || (CmosAddress > CMOS_END_ADDR) ||
+ (CmosAddress == CMOS_CHECKSUM_ADDR_LOW) || (CmosAddress == CMOS_CHECKSUM_ADDR_HIGH)) {
+ return RETURN_NOT_FOUND;
+ }
+
+ if (CmosAddress <= CMOS_LOW_MEM_END) {
+ WriteIoPort (PORT_70, CmosAddress);
+ *Data = (UINT8) ReadIoPort (PORT_71);
+ } else {
+ WriteIoPort (PORT_72, CmosAddress);
+ *Data= (UINT8) ReadIoPort (PORT_73);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Write the value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to write to CMOS
+ @param[in] Data Value to be written to the CMOS
+
+ @retval RETURN_SUCCESS
+ @retval RETURN_NOT_FOUND
+ @retval Status
+
+**/
+RETURN_STATUS
+EFIAPI
+WriteCmos (
+ IN UINT8 CmosAddress,
+ IN UINT8 *Data
+ )
+{
+ RETURN_STATUS Status;
+ UINT16 OldChkSum;
+ UINT16 NewChkSum;
+ UINT8 OldCmosVal;
+ BOOLEAN NeedSkip;
+
+ OldCmosVal = 0;
+
+ if ((CmosAddress < CMOS_START_ADDR) || (CmosAddress > CMOS_END_ADDR) ||
+ (CmosAddress == CMOS_CHECKSUM_ADDR_LOW) || (CmosAddress == CMOS_CHECKSUM_ADDR_HIGH)) {
+ return RETURN_NOT_FOUND;
+ }
+
+ //
+ // Read the actual value in the CMOS location to Write
+ //
+ NeedSkip = CheckIfSkipChkSum (CmosAddress);
+ if (!NeedSkip) {
+ Status = ReadCmos (CmosAddress, &OldCmosVal);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Write data to CMOS address given
+ //
+ if (CmosAddress <= CMOS_LOW_MEM_END) {
+ WriteIoPort (PORT_70, CmosAddress);
+ WriteIoPort (PORT_71, *Data);
+ } else {
+ WriteIoPort (PORT_72, CmosAddress);
+ WriteIoPort (PORT_73, *Data);
+ }
+
+ //
+ // Update the checksum optimization
+ //
+ if (!NeedSkip) {
+ OldChkSum = ReadCheckSum ();
+ NewChkSum = (OldChkSum - (UINT16) OldCmosVal + (UINT16) (*Data));
+ WriteCheckSum (NewChkSum);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Returns the 16bit value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to read from CMOS
+ @param[out] Data The Value read from CMOS location
+
+ @retval RETURN_SUCCESS
+ @retval Status
+
+**/
+RETURN_STATUS
+InternalReadCmosN (
+ IN UINT8 CmosAddress,
+ OUT UINTN *Data,
+ IN UINTN ByteCount
+ )
+{
+ RETURN_STATUS Status;
+ UINT8 Index;
+ UINT8 *Value;
+
+ Value = (UINT8 *) Data;
+
+ for (Index = 0; Index < ByteCount; Index++) {
+ Status = ReadCmos (CmosAddress + Index, Value);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+ Value++;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Write the 16bit value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to write to CMOS
+ @param[in] Data Value to be written to the CMOS
+
+ @retval RETURN_SUCCESS
+ @retval Status
+
+**/
+RETURN_STATUS
+InternalWriteCmosN (
+ IN UINT8 CmosAddress,
+ IN UINTN *Data,
+ IN UINTN ByteCount
+ )
+{
+ RETURN_STATUS Status;
+ UINT8 Index;
+ UINT8 *Value;
+
+ Value = (UINT8 *) Data;
+
+ for (Index = 0; Index < ByteCount; Index++) {
+ Status = WriteCmos (CmosAddress + Index, Value);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+ Value++;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Returns the 1 Byte value from a CMOS location.
+
+ If the passed address is beyond the max address return 0.
+
+ @param[in] CmosAddress Location to read from CMOS
+
+ @retval Data The Value read from CMOS location
+
+**/
+UINT8
+EFIAPI
+ReadCmos8 (
+ IN UINT8 CmosAddress
+ )
+{
+ UINT8 Data;
+
+ Data = 0;
+ InternalReadCmosN (CmosAddress, (UINTN *) &Data, 1);
+ return Data;
+}
+
+
+/**
+ Write the 1 Byte value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to write to CMOS
+ @param[in] Data Value to be written to the CMOS
+
+ @retval Status
+
+**/
+RETURN_STATUS
+EFIAPI
+WriteCmos8 (
+ IN UINT8 CmosAddress,
+ IN UINT8 Data
+ )
+{
+ return InternalWriteCmosN (CmosAddress, (UINTN *) &Data, 1);
+}
+
+
+/**
+ Returns the 2 Bytes value from a CMOS location.
+
+ If the passed address is beyond the max address return 0.
+
+ @param[in] CmosAddress Location to read from CMOS
+
+ @retval Data The Value read from CMOS location
+
+**/
+UINT16
+EFIAPI
+ReadCmos16 (
+ IN UINT8 CmosAddress
+ )
+{
+ UINT16 Data;
+
+ Data = 0;
+ InternalReadCmosN (CmosAddress, (UINTN *) &Data, 2);
+ return Data;
+}
+
+
+/**
+ Write the 2 Bytes value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to write to CMOS
+ @param[in] Data Value to be written to the CMOS
+
+ @retval Status
+
+**/
+RETURN_STATUS
+EFIAPI
+WriteCmos16 (
+ IN UINT8 CmosAddress,
+ IN UINT16 Data
+ )
+{
+ return InternalWriteCmosN (CmosAddress, (UINTN *) &Data, 2);
+}
+
+
+/**
+ Returns the 4 Bytes value from a CMOS location.
+
+ If the passed address is beyond the max address return 0.
+
+ @param[in] CmosAddress Location to read from CMOS
+
+ @retval Data The Value read from CMOS location
+
+**/
+UINT32
+EFIAPI
+ReadCmos32 (
+ IN UINT8 CmosAddress
+ )
+{
+ UINT32 Data;
+
+ Data = 0;
+ InternalReadCmosN (CmosAddress, (UINTN *) &Data, 4);
+ return Data;
+}
+
+
+/**
+ Write the 4 Bytes value from a CMOS location.
+
+ If the passed address is beyond the max address return RETURN_NOT_FOUND.
+ If the function completed successfully return RETURN_SUCCESS
+
+ @param[in] CmosAddress Location to write to CMOS
+ @param[in] Data Value to be written to the CMOS
+
+ @retval Status
+
+**/
+RETURN_STATUS
+EFIAPI
+WriteCmos32 (
+ IN UINT8 CmosAddress,
+ IN UINT32 Data
+ )
+{
+ return InternalWriteCmosN (CmosAddress, (UINTN *) &Data, 4);
+}
+
+
+/**
+ Funtion to Initialize the CMOS.
+
+ Checks the presence of CMOS battery, else it initialize CMOS to default.
+ Perform a checksum computation and verify if the checksum is correct.
+ If the input parameter ForceInit is TRUE, initialize all the CMOS
+ location to their default values
+
+ @param[in] ForceInit A boolean variable to initialize the CMOS to its default
+ without checking the RTC_PWR_STS or verifying the checksum.
+ @param[out] DefaultsRestored A boolean variable to indicate if the defaults were restored
+
+ @retval RETURN_SUCCESS
+
+**/
+RETURN_STATUS
+EFIAPI
+InitCmos (
+ IN BOOLEAN ForceInit,
+ OUT BOOLEAN *DefaultsRestored
+ )
+{
+ //
+ // Check if the CMOS battery is present
+ //
+ if (!CheckCmosBatteryStatus ()) {
+ ForceInit = TRUE;
+ }
+
+ //
+ // Check if the ForceInit is True
+ //
+ if (ForceInit) {
+ CmosFillDefaults ();
+ *DefaultsRestored = TRUE;
+ return RETURN_SUCCESS;
+ }
+
+ //
+ // Check if CMOS is BAD
+ //
+ if (!VerifyCmosCheckSum ()) {
+ CmosFillDefaults ();
+ *DefaultsRestored = TRUE;
+ return RETURN_SUCCESS;
+ }
+
+ *DefaultsRestored = FALSE;
+ return RETURN_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.h b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.h
new file mode 100644
index 0000000000..b40e491418
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.h
@@ -0,0 +1,47 @@
+/** @file
+ Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _CMOS_ACCESS_LIB_
+#define _CMOS_ACCESS_LIB_
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/CmosAccessLib.h>
+#include <Library/BasePlatformCmosLib.h>
+
+//
+// CMOS access Port address
+//
+#define PORT_70 0x70
+#define PORT_71 0x71
+#define PORT_72 0x72
+#define PORT_73 0x73
+
+#define CMOS_LOW_MEM_ST 0
+#define CMOS_LOW_MEM_END 127
+
+#define CMOS_HIGH_MEM_ST 128
+#define CMOS_HIGH_MEM_END 255
+
+#define CMOS_START_ADDR 40
+#define CMOS_END_ADDR 255
+
+//
+// Don't set this value more than 254 and equal to 127
+//
+#define CMOS_CHECKSUM_ADDR_LOW 254
+#define CMOS_CHECKSUM_ADDR_HIGH (CMOS_CHECKSUM_ADDR_LOW + 1)
+
+#endif // _CMOS_ACCESS_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.inf
new file mode 100644
index 0000000000..9472d9e387
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseCmosAccessLib/BaseCmosAccessLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Library producing CMOS access functionality.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseCmosAccessLib
+ FILE_GUID = B7F6BC23-C59F-4e06-9F60-85356D88B404
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = CmosAccessLib
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+ DebugLib
+ BasePlatformCmosLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ BaseCmosAccessLib.c
+ BaseCmosAccessLib.h
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.c b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.c
new file mode 100644
index 0000000000..9e6705578f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.c
@@ -0,0 +1,269 @@
+/** @file
+ Platform Info driver to public platform related HOB data.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include "PlatformStatusCodesInternal.h"
+
+STATUS_CODE_TO_DATA_MAP mPostCodeProgressMap[] = {
+ //
+ // PEI
+ //
+ // Regular boot
+ //
+ { PEI_CORE_STARTED, 0x10 },
+ { PEI_CAR_CPU_INIT, 0x11 },
+
+ //
+ // reserved for CPU 0x12 - 0x14
+ // reserved for NB 0x16 - 0x18
+ // reserved for SB 0x1A - 0x1C
+ //
+ { PEI_MEMORY_SPD_READ, 0x1D },
+ { PEI_MEMORY_PRESENCE_DETECT, 0x1E },
+ { PEI_MEMORY_TIMING, 0x1F},
+ { PEI_MEMORY_CONFIGURING, 0x20 },
+ { PEI_MEMORY_INIT, 0x21 },
+
+ //
+ // reserved for OEM use: 0x22 - 0x2F
+ // reserved for AML use: 0x30
+ //
+ { PEI_MEMORY_INSTALLED, 0x31 },
+ { PEI_CPU_INIT, 0x32 },
+ { PEI_CPU_CACHE_INIT, 0x33 },
+ { PEI_CPU_BSP_SELECT, 0x34 },
+ { PEI_CPU_AP_INIT, 0x35 },
+ { PEI_CPU_SMM_INIT, 0x36 },
+ { PEI_MEM_NB_INIT, 0x37 },
+
+ //
+ // reserved for NB 0x38 - 0x3A
+ //
+ { PEI_MEM_SB_INIT, 0x3B },
+
+ //
+ // reserved for SB 0x3C - 0x3E
+ // reserved for OEM use: 0x3F - 0x4E
+ //
+ { PEI_DXE_IPL_STARTED, 0x4F },
+
+ //
+ // Recovery
+ //
+ { PEI_RECOVERY_AUTO, 0xF0 },
+ { PEI_RECOVERY_USER, 0xF1 },
+ { PEI_RECOVERY_STARTED, 0xF2 },
+ { PEI_RECOVERY_CAPSULE_FOUND, 0xF3 },
+ { PEI_RECOVERY_CAPSULE_LOADED, 0xF4 },
+
+ //
+ // S3
+ //
+ { PEI_S3_BOOT_SCRIPT, 0xE1 },
+ { PEI_S3_OS_WAKE, 0xE3 },
+
+ //
+ // DXE
+ //
+ { DXE_CORE_STARTED, 0x60 },
+ { DXE_SBRUN_INIT, 0x62 },
+
+ //
+ // reserved for CPU 0x64 - 0x67
+ //
+ { DXE_NB_HB_INIT, 0x68 },
+ { DXE_NB_INIT, 0x69 },
+ { DXE_NB_SMM_INIT, 0x6A },
+
+ //
+ // reserved for NB 0x6B - 0x6F
+ //
+ { DXE_SB_INIT, 0x70 },
+ { DXE_SB_SMM_INIT, 0x71 },
+ { DXE_SB_DEVICES_INIT, 0x72 },
+
+ //
+ // reserved for SB 0x73 - 0x77
+ // reserved for IBV use: 0x7A - 0x7F
+ // reserved fpr OEM use: 0x80 - 0x8F
+ //
+ { DXE_BDS_STARTED, 0x90 },
+ { DXE_PCI_BUS_BEGIN, 0x92 },
+ { DXE_PCI_BUS_HPC_INIT, 0x93 },
+ { DXE_PCI_BUS_ENUM, 0x94 },
+ { DXE_PCI_BUS_REQUEST_RESOURCES, 0x95 },
+ { DXE_PCI_BUS_ASSIGN_RESOURCES, 0x96 },
+ { DXE_CON_OUT_CONNECT, 0x97 },
+ { DXE_CON_IN_CONNECT, 0x98 },
+ { DXE_SIO_INIT, 0x99 },
+ { DXE_USB_BEGIN, 0x9A },
+ { DXE_USB_RESET, 0x9B },
+ { DXE_USB_DETECT, 0x9C },
+ { DXE_USB_ENABLE, 0x9D },
+
+ //
+ // reserved for IBV use: 0x9E - 0x9F
+ // reserved for AML use: 0xA0
+ //
+ { DXE_IDE_BEGIN, 0xA1 },
+ { DXE_IDE_RESET, 0xA2 },
+ { DXE_IDE_DETECT, 0xA3 },
+ { DXE_IDE_ENABLE, 0xA4 },
+ { DXE_SCSI_BEGIN, 0xA5 },
+ { DXE_SCSI_RESET, 0xA6 },
+ { DXE_SCSI_DETECT, 0xA7 },
+ { DXE_SCSI_ENABLE, 0xA8 },
+
+ //
+ // reserved for AML use: 0xAA
+ //
+ { DXE_SETUP_START, 0xAB },
+ { DXE_SETUP_INPUT_WAIT, 0xAC },
+ { DXE_READY_TO_BOOT, 0xAD },
+ { DXE_LEGACY_BOOT, 0xAE },
+ { DXE_EXIT_BOOT_SERVICES, 0xAF },
+ { RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN, 0xB0 },
+ { RT_SET_VIRTUAL_ADDRESS_MAP_END, 0xB1 },
+ { DXE_LEGACY_OPROM_INIT, 0xB2 },
+ { DXE_RESET_SYSTEM, 0xB3 },
+ { DXE_USB_HOTPLUG, 0xB4 },
+ { DXE_PCI_BUS_HOTPLUG, 0xB5 },
+
+ //
+ // reserved for IBV use: 0xB8 - 0xBF
+ // reserved for OEM use: 0xC0 - 0xCF
+ //
+ {0,0}
+};
+
+STATUS_CODE_TO_DATA_MAP mPostCodeErrorMap[] = {
+ //
+ // PEI
+ // Regular boot
+ //
+ { PEI_MEMORY_INVALID_TYPE, 0x50 },
+ { PEI_MEMORY_INVALID_SPEED, 0x50 },
+ { PEI_MEMORY_SPD_FAIL, 0x51 },
+ { PEI_MEMORY_INVALID_SIZE, 0x52 },
+ { PEI_MEMORY_MISMATCH, 0x52 },
+ { PEI_MEMORY_NOT_DETECTED, 0x53 },
+ { PEI_MEMORY_NONE_USEFUL, 0x53 },
+ { PEI_MEMORY_ERROR, 0x54 },
+ { PEI_MEMORY_NOT_INSTALLED, 0x55 },
+ { PEI_CPU_INVALID_TYPE, 0x56 },
+ { PEI_CPU_INVALID_SPEED, 0x56 },
+ { PEI_CPU_MISMATCH, 0x57 },
+ { PEI_CPU_SELF_TEST_FAILED, 0x58 },
+ { PEI_CPU_CACHE_ERROR, 0x58 },
+ { PEI_CPU_MICROCODE_UPDATE_FAILED, 0x59 },
+ { PEI_CPU_NO_MICROCODE, 0x59 },
+ { PEI_CPU_INTERNAL_ERROR, 0x5A },
+ { PEI_CPU_ERROR, 0x5A },
+ { PEI_RESET_NOT_AVAILABLE,0x5B },
+
+ //
+ // reserved for IBV use: 0x5C - 0x5F
+ // Recovery
+ //
+ { PEI_RECOVERY_PPI_NOT_FOUND, 0xF8 },
+ { PEI_RECOVERY_NO_CAPSULE, 0xF9 },
+ { PEI_RECOVERY_INVALID_CAPSULE, 0xFA },
+
+ //
+ // reserved for IBV use: 0xFB - 0xFF
+ // S3 Resume
+ //
+ { PEI_MEMORY_S3_RESUME_FAILED, 0xE8 },
+ { PEI_S3_RESUME_PPI_NOT_FOUND, 0xE9 },
+ { PEI_S3_BOOT_SCRIPT_ERROR, 0xEA },
+ { PEI_S3_OS_WAKE_ERROR, 0xEB },
+
+ //
+ // reserved for IBV use: 0xEC - 0xEF
+ // DXE
+ //
+ { DXE_CPU_SELF_TEST_FAILED, 0x58 },
+ { DXE_NB_ERROR, 0xD1 },
+ { DXE_SB_ERROR, 0xD2 },
+ { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 0xD3 },
+ { DXE_PCI_BUS_OUT_OF_RESOURCES, 0xD4 },
+ { DXE_LEGACY_OPROM_NO_SPACE, 0xD5 },
+ { DXE_NO_CON_OUT, 0xD6 },
+ { DXE_NO_CON_IN, 0xD7 },
+ { DXE_INVALID_PASSWORD, 0xD8 },
+ { DXE_BOOT_OPTION_LOAD_ERROR, 0xD9 },
+ { DXE_BOOT_OPTION_FAILED, 0xDA },
+ { DXE_FLASH_UPDATE_FAILED, 0xDB },
+ { DXE_RESET_NOT_AVAILABLE, 0xDC },
+
+ //
+ // reserved for IBV use: 0xDE - 0xDF
+ //
+ {0,0}
+};
+
+STATUS_CODE_TO_DATA_MAP *mPostCodeStatusCodesMap[] = {
+ mPostCodeProgressMap,
+ mPostCodeErrorMap
+};
+
+UINT32
+FindPostCodeData (
+ IN STATUS_CODE_TO_DATA_MAP *Map,
+ IN EFI_STATUS_CODE_VALUE Value
+ )
+{
+ while (Map->Value != 0) {
+ if (Map->Value == Value) {
+ return Map->Data;
+ }
+ Map++;
+ }
+ return 0;
+}
+
+
+/**
+ Get PostCode from status code type and value.
+
+ @param[in] CodeType Indicates the type of status code being reported.
+ @param[in] Value Describes the current status of a hardware or
+ software entity. This includes information about the class and
+ subclass that is used to classify the entity as well as an operation.
+ For progress codes, the operation is the current activity.
+ For error codes, it is the exception.For debug codes,it is not defined at this time.
+
+ @return PostCode
+
+**/
+UINT32
+EFIAPI
+GetPostCodeFromStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value
+ )
+{
+ UINT32 CodeTypeIndex;
+
+ CodeTypeIndex = STATUS_CODE_TYPE (CodeType) - 1;
+
+ if (CodeTypeIndex >= sizeof (mPostCodeStatusCodesMap) / sizeof (mPostCodeStatusCodesMap[0])) {
+ return 0;
+ }
+
+ return FindPostCodeData (mPostCodeStatusCodesMap[CodeTypeIndex], Value);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.inf
new file mode 100644
index 0000000000..3dea66e12c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/BasePlatformPostCodeMapLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Instance of Platform Post Code Map Library.
+#
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BasePlatformPostCodeMapLib
+ FILE_GUID = A08629F3-13C3-4bf6-A7AA-C119648D5267
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = PlatformPostCodeMapLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ IoLib
+ PcdLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask
+
+[Sources]
+ BasePlatformPostCodeMapLib.c
+ PlatformStatusCodesInternal.h
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/PlatformStatusCodesInternal.h b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/PlatformStatusCodesInternal.h
new file mode 100644
index 0000000000..e7d054d41e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BasePlatformPostCodeMapLib/PlatformStatusCodesInternal.h
@@ -0,0 +1,343 @@
+/** @file
+ PostCode status code definition.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PLATFORM_STATUS_CODES_INTERNAL_H__
+#define __PLATFORM_STATUS_CODES_INTERNAL_H__
+
+#include <Pi/PiStatusCode.h>
+
+typedef struct{
+ EFI_STATUS_CODE_VALUE Value;
+ UINT32 Data;
+} STATUS_CODE_TO_DATA_MAP;
+
+//
+// Enable PEI/DXE status code
+//
+#define PEI_STATUS_CODE 1
+#define DXE_STATUS_CODE 1
+
+#define STATUS_CODE_TYPE(Type) ((Type)&EFI_STATUS_CODE_TYPE_MASK)
+#define STATUS_CODE_CLASS(Value) ((Value)&EFI_STATUS_CODE_CLASS_MASK)
+
+//
+// Progress/Error codes
+//
+#define PEI_CORE_STARTED (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_ENTRY_POINT)
+#define PEI_RESET_NOT_AVAILABLE (EFI_SOFTWARE_PEI_CORE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE)
+#define PEI_DXEIPL_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND)
+#define PEI_DXE_CORE_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT)
+#define PEI_S3_RESUME_ERROR (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
+#define PEI_RECOVERY_FAILED (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_EC_RECOVERY_FAILED)
+#define DXE_CORE_STARTED (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT)
+#define DXE_EXIT_BOOT_SERVICES_END (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)
+
+//
+// Reported by CPU PEIM
+//
+#define PEI_CAR_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT)
+
+//
+// Reported by Memory Detection PEIM
+//
+#define PEI_MEMORY_SPD_READ (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_SPD_READ)
+#define PEI_MEMORY_PRESENCE_DETECT (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PRESENCE_DETECT)
+#define PEI_MEMORY_TIMING (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TIMING)
+#define PEI_MEMORY_CONFIGURING (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_CONFIGURING)
+#define PEI_MEMORY_OPTIMIZING (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_OPTIMIZING)
+#define PEI_MEMORY_INIT (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_INIT)
+#define PEI_MEMORY_TEST (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TEST)
+#define PEI_MEMORY_INVALID_TYPE (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_TYPE)
+#define PEI_MEMORY_INVALID_SPEED (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SPEED)
+#define PEI_MEMORY_SPD_FAIL (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_SPD_FAIL)
+#define PEI_MEMORY_INVALID_SIZE (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SIZE)
+#define PEI_MEMORY_MISMATCH (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH)
+#define PEI_MEMORY_S3_RESUME_FAILED (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_S3_RESUME_FAIL)
+#define PEI_MEMORY_NOT_DETECTED (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED)
+#define PEI_MEMORY_NONE_USEFUL (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL)
+#define PEI_MEMORY_ERROR (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_EC_NON_SPECIFIC)
+#define PEI_MEMORY_INSTALLED (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_INSTALL_PEI_MEMORY)
+#define PEI_MEMORY_NOT_INSTALLED (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED)
+#define PEI_MEMORY_INSTALLED_TWICE (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE)
+
+//
+// Reported by CPU PEIM
+//
+#define PEI_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_PC_INIT_BEGIN)
+#define PEI_CPU_CACHE_INIT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT)
+#define PEI_CPU_BSP_SELECT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT)
+#define PEI_CPU_AP_INIT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT)
+#define PEI_CPU_SMM_INIT (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT)
+#define PEI_CPU_INVALID_TYPE (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_TYPE)
+#define PEI_CPU_INVALID_SPEED (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_SPEED)
+#define PEI_CPU_MISMATCH (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MISMATCH)
+#define PEI_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
+#define PEI_CPU_CACHE_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CACHE)
+#define PEI_CPU_MICROCODE_UPDATE_FAILED (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MICROCODE_UPDATE)
+#define PEI_CPU_NO_MICROCODE (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_NO_MICROCODE_UPDATE)
+//
+// If non of the errors above apply use this one
+//
+#define PEI_CPU_INTERNAL_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INTERNAL)
+
+//
+// Generic CPU error. It should only be used if non of the errors above apply
+//
+#define PEI_CPU_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_NON_SPECIFIC)
+
+//
+// Reported by NB PEIM
+//
+#define PEI_MEM_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_MEM_NB_INIT)
+
+//
+// Reported by SB PEIM
+//
+#define PEI_MEM_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_MEM_SB_INIT)
+
+//
+// Reported by PEIM which detected forced or auto recovery condition
+//
+#define PEI_RECOVERY_AUTO (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_AUTO)
+#define PEI_RECOVERY_USER (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_USER)
+
+//
+// Reported by DXE IPL
+//
+#define PEI_RECOVERY_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
+#define PEI_S3_RESUME_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
+#define PEI_S3_RESUME_FAILED (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
+
+//
+// Reported by Recovery PEIM
+//
+#define PEI_RECOVERY_STARTED (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN)
+#define PEI_RECOVERY_CAPSULE_FOUND (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD)
+#define PEI_RECOVERY_NO_CAPSULE (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
+#define PEI_RECOVERY_CAPSULE_LOADED (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START)
+#define PEI_RECOVERY_INVALID_CAPSULE (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR)
+
+//
+// Reported by S3 Resume PEIM
+//
+#define PEI_S3_BOOT_SCRIPT (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT)
+#define PEI_S3_OS_WAKE (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE)
+#define PEI_S3_BOOT_SCRIPT_ERROR (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR)
+#define PEI_S3_OS_WAKE_ERROR (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)
+
+#define PEI_PEIM_STARTED (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN)
+#define PEI_PEIM_ENDED (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END)
+
+//
+// Reported by DXE IPL
+//
+#define PEI_DXE_IPL_STARTED (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)
+
+//
+// Reported by PEIM which installs Reset PPI
+//
+#define PEI_RESET_SYSTEM (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_RESET_SYSTEM)
+
+//
+// Reported by the PEIM or DXE driver which detected the error
+//
+#define GENERIC_MEMORY_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_CORRECTABLE)
+#define GENERIC_MEMORY_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UNCORRECTABLE)
+
+//
+// Reported by Flash Update DXE driver
+//
+#define DXE_FLASH_UPDATE_FAILED (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UPDATE_FAIL)
+
+//
+// Reported by the PEIM or DXE driver which detected the error
+//
+#define GENERIC_CPU_THERMAL_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_THERMAL)
+#define GENERIC_CPU_LOW_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_LOW_VOLTAGE)
+#define GENERIC_CPU_HIGH_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_HIGH_VOLTAGE)
+#define GENERIC_CPU_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CORRECTABLE)
+#define GENERIC_CPU_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_UNCORRECTABLE)
+#define GENERIC_BAD_DATE_TIME_ERROR (EFI_SOFTWARE_UNSPECIFIED | EFI_SW_EC_BAD_DATE_TIME)
+#define GENERIC_MEMORY_SIZE_DECREASE (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH)
+
+//
+// Reported by DXE Core
+//
+#define DXE_DRIVER_STARTED (EFI_SOFTWARE_EFI_DXE_SERVICE | EFI_SW_PC_INIT_BEGIN)
+#define DXE_DRIVER_ENED (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END)
+#define DXE_ARCH_PROTOCOLS_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ARCH_READY)
+#define DXE_DRIVER_CONNECTED (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_START_DRIVER)
+#define DXE_ARCH_PROTOCOL_NOT_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH)
+
+//
+// Reported by DXE CPU driver
+//
+#define DXE_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
+
+//
+// Reported by PCI Host Bridge driver
+//
+#define DXE_NB_HB_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_HB_INIT )
+
+//
+// Reported by NB Driver
+//
+#define DXE_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_NB_INIT )
+#define DXE_NB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_NB_SMM_INIT )
+#define DXE_NB_ERROR (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_DXE_NB_ERROR )
+
+//
+// Reported by SB Driver(s)
+//
+#define DXE_SBRUN_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_RT_INIT )
+#define DXE_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_INIT )
+#define DXE_SB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_SMM_INIT )
+#define DXE_SB_DEVICES_INIT (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT )
+#define DXE_SB_BAD_BATTERY (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_BAD_BATTERY)
+#define DXE_SB_ERROR (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_DXE_SB_ERROR )
+
+//
+// Reported by DXE Core
+//
+#define DXE_BDS_STARTED (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)
+
+//
+// Reported by Boot Manager
+//
+#define DXE_READY_TO_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)
+
+//
+// Reported by DXE Core
+//
+#define DXE_EXIT_BOOT_SERVICES (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)
+#define DXE_EXIT_BOOT_SERVICES_EVENT (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT)
+
+//
+// Reported by driver that installs Runtime AP
+//
+#define RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)
+#define RT_SET_VIRTUAL_ADDRESS_MAP_END (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT)
+
+//
+// Reported by CSM
+//
+#define DXE_LEGACY_OPROM_INIT (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT)
+#define DXE_LEGACY_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)
+#define DXE_LEGACY_OPROM_NO_SPACE (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)
+
+//
+// Reported by SETUP
+//
+#define DXE_SETUP_START (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
+#define DXE_SETUP_INPUT_WAIT (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
+#define DXE_INVALID_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_PASSWORD)
+#define DXE_INVALID_IDE_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD)
+#define DXE_BOOT_OPTION_LOAD_ERROR (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
+#define DXE_BOOT_OPTION_FAILED (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
+
+//
+// Reported by a Driver that installs Reset AP
+//
+#define DXE_RESET_SYSTEM (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM)
+#define DXE_RESET_NOT_AVAILABLE (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE)
+
+//
+// Reported by PCI bus driver
+//
+#define DXE_PCI_BUS_BEGIN (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT)
+#define DXE_PCI_BUS_ENUM (EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM)
+#define DXE_PCI_BUS_HPC_INIT (EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT)
+#define DXE_PCI_BUS_REQUEST_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC)
+#define DXE_PCI_BUS_ASSIGN_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PC_ENABLE)
+#define DXE_PCI_BUS_HOTPLUG (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG)
+#define DXE_PCI_BUS_OUT_OF_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT)
+
+//
+// Reported by USB bus driver
+//
+#define DXE_USB_BEGIN (EFI_IO_BUS_USB | EFI_IOB_PC_INIT)
+#define DXE_USB_RESET (EFI_IO_BUS_USB | EFI_IOB_PC_RESET)
+#define DXE_USB_DETECT (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT)
+#define DXE_USB_ENABLE (EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE)
+#define DXE_USB_HOTPLUG (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG)
+
+//
+// Reported by IDE bus driver
+//
+#define DXE_IDE_BEGIN (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_INIT)
+#define DXE_IDE_RESET (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET)
+#define DXE_IDE_DETECT (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_DETECT)
+#define DXE_IDE_ENABLE (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_ENABLE)
+#define DXE_IDE_SMART_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
+#define DXE_IDE_CONTROLLER_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR)
+#define DXE_IDE_DEVICE_FAILURE (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_INTERFACE_ERROR)
+
+//
+// Reported by SCSI bus driver
+//
+#define DXE_SCSI_BEGIN (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT)
+#define DXE_SCSI_RESET (EFI_IO_BUS_SCSI | EFI_IOB_PC_RESET)
+#define DXE_SCSI_DETECT (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT)
+#define DXE_SCSI_ENABLE (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE)
+
+//
+// Reported by Super I/O driver
+//
+#define DXE_SIO_INIT (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT)
+
+//
+// Reported by Keyboard driver
+//
+#define DXE_KEYBOARD_INIT (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT)
+#define DXE_KEYBOARD_RESET (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET)
+#define DXE_KEYBOARD_DISABLE (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE)
+#define DXE_KEYBOARD_DETECT (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_KEYBOARD_ENABLE (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE)
+#define DXE_KEYBOARD_CLEAR_BUFFER (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER)
+#define DXE_KEYBOARD_SELF_TEST (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST)
+
+//
+// Reported by Mouse driver
+//
+#define DXE_MOUSE_INIT (EFI_PERIPHERAL_MOUSE | EFI_P_PC_INIT)
+#define DXE_MOUSE_RESET (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET)
+#define DXE_MOUSE_DISABLE (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE)
+#define DXE_MOUSE_DETECT (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_MOUSE_ENABLE (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE)
+
+//
+// Reported by Mass Storage drivers
+//
+#define DXE_FIXED_MEDIA_INIT (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_INIT)
+#define DXE_FIXED_MEDIA_RESET (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_RESET)
+#define DXE_FIXED_MEDIA_DISABLE (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_DISABLE)
+#define DXE_FIXED_MEDIA_DETECT (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_FIXED_MEDIA_ENABLE (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE)
+#define DXE_REMOVABLE_MEDIA_INIT (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_INIT)
+#define DXE_REMOVABLE_MEDIA_RESET (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)
+#define DXE_REMOVABLE_MEDIA_DISABLE (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)
+#define DXE_REMOVABLE_MEDIA_DETECT (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_REMOVABLE_MEDIA_ENABLE (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)
+
+//
+// Reported by BDS
+//
+#define DXE_CON_OUT_CONNECT (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_INIT)
+#define DXE_CON_IN_CONNECT (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT)
+#define DXE_NO_CON_OUT (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED)
+#define DXE_NO_CON_IN (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED)
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/BasePostCodeLibPort80Ex.inf b/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/BasePostCodeLibPort80Ex.inf
new file mode 100644
index 0000000000..84c3d73ff1
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/BasePostCodeLibPort80Ex.inf
@@ -0,0 +1,44 @@
+## @file
+# Instance of Post Code Library using I/O port 0x80.
+# Post Code Library that writes post code values to I/O port 0x80.
+#
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BasePostCodeLibPort80Ex
+ FILE_GUID = 445E7394-53E8-40c1-8461-5242EF9AE7F7
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = PostCodeLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ IoLib
+ PcdLib
+ DebugLib
+ BaseLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask
+
+[Sources]
+ PostCode.c
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/PostCode.c b/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/PostCode.c
new file mode 100644
index 0000000000..b266c84495
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BasePostCodeLibPort80Ex/PostCode.c
@@ -0,0 +1,133 @@
+/** @file
+ Post Code Library instance that writes post code values to I/O port 0x80.
+
+ Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+
+
+/**
+ Sends an 32-bit value to a POST card.
+
+ Sends the 32-bit value specified by Value to a POST card, and returns Value.
+ Some implementations of this library function may perform I/O operations
+ directly to a POST card device. Other implementations may send Value to
+ ReportStatusCode(), and the status code reporting mechanism will eventually
+ display the 32-bit value on the status reporting device.
+
+ PostCode() must actively prevent recursion. If PostCode() is called while
+ processing another any other Post Code Library function, then
+ PostCode() must return Value immediately.
+
+ @param[in] Value The 32-bit value to write to the POST card.
+
+ @retval Value The 32-bit value to write to the POST card.
+
+**/
+UINT32
+EFIAPI
+PostCode (
+ IN UINT32 Value
+ )
+{
+ IoWrite32 (0x80, Value);
+ DEBUG ((DEBUG_INFO, "POSTCODE=<%08x>\n", Value));
+
+ return Value;
+}
+
+
+/**
+ Sends an 32-bit value to a POST and associated ASCII string.
+
+ Sends the 32-bit value specified by Value to a POST card, and returns Value.
+ If Description is not NULL, then the ASCII string specified by Description is
+ also passed to the handler that displays the POST card value. Some
+ implementations of this library function may perform I/O operations directly
+ to a POST card device. Other implementations may send Value to ReportStatusCode(),
+ and the status code reporting mechanism will eventually display the 32-bit
+ value on the status reporting device.
+
+ PostCodeWithDescription()must actively prevent recursion. If
+ PostCodeWithDescription() is called while processing another any other Post
+ Code Library function, then PostCodeWithDescription() must return Value
+ immediately.
+
+ @param[in] Value The 32-bit value to write to the POST card.
+ @param[in] Description The pointer to an ASCII string that is a description of the
+ POST code value. This is an optional parameter that may
+ be NULL.
+
+ @retval Value The 32-bit value to write to the POST card.
+
+**/
+UINT32
+EFIAPI
+PostCodeWithDescription (
+ IN UINT32 Value,
+ IN CONST CHAR8 *Description OPTIONAL
+ )
+{
+ PostCode (Value);
+ return Value;
+}
+
+
+/**
+ Returns TRUE if POST Codes are enabled.
+
+ This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_ENABLED
+ bit of PcdPostCodePropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of
+ PcdPostCodeProperyMask is set.
+ @retval FALSE The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of
+ PcdPostCodeProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+PostCodeEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if POST code descriptions are enabled.
+
+ This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED
+ bit of PcdPostCodePropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of
+ PcdPostCodeProperyMask is set.
+ @retval FALSE The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of
+ PcdPostCodeProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+PostCodeDescriptionEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.c b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.c
new file mode 100644
index 0000000000..5fc9d8c71f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.c
@@ -0,0 +1,498 @@
+/** @file
+ Serial I/O Port library functions with no library constructor/destructor.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/SerialPortParameterLib.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/CmosAccessLib.h>
+#include <Library/ScSerialIoUartLib.h>
+
+#ifdef TRACE_HUB_DEBUGLIB_USAGE
+#include <Library/TraceHubDebugLib.h>
+#endif
+
+//
+// UART register offsets and bitfields
+//
+#define RXBUF_OFFSET 0x00
+#define TXBUF_OFFSET 0x00
+#define BAUD_LOW_OFFSET 0x00
+#define BAUD_HIGH_OFFSET 0x01
+#define IER_OFFSET 0x01
+#define LCR_SHADOW_OFFSET 0x01
+#define FCR_SHADOW_OFFSET 0x02
+#define IR_CONTROL_OFFSET 0x02
+#define FCR_OFFSET 0x02
+#define EIR_OFFSET 0x02
+#define BSR_OFFSET 0x03
+#define LCR_OFFSET 0x03
+#define MCR_OFFSET 0x04
+#define LSR_OFFSET 0x05
+#define MSR_OFFSET 0x06
+
+//
+// UART Register Bit Defines
+//
+#define FCR_FIFOE BIT0
+#define FCR_FIFO64 BIT5
+#define LSR_TXRDY 0x20
+#define LSR_RXDA 0x01
+#define DLAB BIT7
+#define MCR_RTS BIT1
+#define MSR_CTS BIT4
+#define MSR_DSR BIT5
+
+#define MAX_BAUD_RATE 115200
+
+UINT8
+SerialPortReadRegister (
+ UINTN Offset
+ )
+{
+ return IoRead8 ((UINTN) PcdGet64 (PcdSerialRegisterBase) + Offset);
+}
+
+UINT8
+SerialPortWriteRegister (
+ UINTN Offset,
+ UINT8 Value
+ )
+{
+ return IoWrite8 ((UINTN) PcdGet64 (PcdSerialRegisterBase) + Offset, Value);
+}
+
+RETURN_STATUS
+EFIAPI
+UARTInitialize (
+ VOID
+ )
+
+/**
+ Initialize Serial Port.
+
+ The Baud Rate Divisor registers are programmed and the LCR
+ is used to configure the communications format. Hard coded
+ UART config comes from globals in DebugSerialPlatform lib.
+
+ @param None
+
+ @retval None
+
+**/
+{
+ UINTN Divisor;
+ UINTN TempDivisor;
+ UINT32 BaudRate;
+ BOOLEAN Initialized;
+
+ //
+ // Calculate divisor for baud generator
+ //
+ BaudRate = GetSerialPortBaudRate ();
+ if ((BaudRate == 0) || ((BaudRate % 9600) != 0)) {
+ //
+ // If Serail Baud Rate is not valid, set it to the default value
+ //
+ BaudRate = PcdGet32 (PcdSerialBaudRate);
+ SetSerialPortBaudRate (BaudRate);
+ }
+ Divisor = MAX_BAUD_RATE / BaudRate;
+
+ //
+ // See if the serial port is already initialized
+ //
+ Initialized = TRUE;
+ if ((SerialPortReadRegister (FCR_OFFSET) & (FCR_FIFOE | FCR_FIFO64)) !=
+ (PcdGet8 (PcdSerialFifoControl) & (FCR_FIFOE | FCR_FIFO64))) {
+ Initialized = FALSE;
+ }
+ if ((SerialPortReadRegister (LCR_OFFSET) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
+ Initialized = FALSE;
+ }
+ SerialPortWriteRegister (LCR_OFFSET, (UINT8) (SerialPortReadRegister (LCR_OFFSET) | DLAB));
+ TempDivisor = (UINTN) SerialPortReadRegister (BAUD_HIGH_OFFSET);
+ TempDivisor = TempDivisor << 8;
+ TempDivisor |= (UINTN) SerialPortReadRegister (BAUD_LOW_OFFSET);
+ SerialPortWriteRegister (LCR_OFFSET, (UINT8) (SerialPortReadRegister (LCR_OFFSET) & ~DLAB));
+ if (TempDivisor != Divisor) {
+ Initialized = FALSE;
+ }
+ if (Initialized) {
+ return RETURN_SUCCESS;
+ }
+
+ //
+ // Set communications format
+ //
+ SerialPortWriteRegister (LCR_OFFSET, DLAB);
+
+ //
+ // Configure baud rate
+ //
+ SerialPortWriteRegister (BAUD_HIGH_OFFSET, (UINT8) (Divisor >> 8));
+ SerialPortWriteRegister (BAUD_LOW_OFFSET, (UINT8) (Divisor & 0xff));
+
+ //
+ // Switch back to bank 0
+ //
+ SerialPortWriteRegister (LCR_OFFSET, (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3F));
+
+ //
+ // Enable and reset FIFOs
+ // Strip reserved bits from PcdSerialFifoControl
+ //
+ SerialPortWriteRegister (FCR_OFFSET, (UINT8) (PcdGet8 (PcdSerialFifoControl) & 0x27));
+
+ //
+ // Put Modem Control Register(MCR) into its reset state of 0x00.
+ //
+ SerialPortWriteRegister (MCR_OFFSET, 0x00);
+
+ return RETURN_SUCCESS;
+}
+
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+ CmosStatusCodeFlags = STATUS_CODE_USE_SERIALIO | STATUS_CODE_CMOS_VALID;
+ SetDebugInterface (CmosStatusCodeFlags);
+ }
+ //
+ // no init for MEM
+ //
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ PchSerialIoUartInit (PcdGet8 (PcdSerialIoUartNumber), TRUE, 115200, 3, FALSE);
+ }
+ //
+ // no init for TRACEHUB
+ //
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Write data to serial device.
+
+ If the buffer is NULL, then return 0;
+ if NumberOfBytes is zero, then return 0.
+
+ @param[in] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Write data failed.
+ @retval !0 Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgOut (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINTN Result;
+ UINTN FifoSize;
+ UINTN Index;
+
+ if (NULL == Buffer) {
+ return 0;
+ }
+
+ //
+ // Compute the maximum size of the Tx FIFO
+ //
+ FifoSize = 1;
+ if ((PcdGet8 (PcdSerialFifoControl) & FCR_FIFOE) != 0) {
+ if ((PcdGet8 (PcdSerialFifoControl) & FCR_FIFO64) == 0) {
+ FifoSize = 16;
+ } else {
+ FifoSize = 64;
+ }
+ }
+
+ Result = NumberOfBytes;
+
+ while (NumberOfBytes != 0) {
+ //
+ // Wait for the serial port to be ready, to make sure both the transmit FIFO
+ // and shift register empty.
+ //
+ while ((SerialPortReadRegister (LSR_OFFSET) & LSR_TXRDY) == 0);
+
+ //
+ // Fill then entire Tx FIFO
+ //
+ for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ if (PcdGetBool (PcdSerialDetectCable)) {
+ //
+ // Wait for both DSR and CTS to be set
+ // DSR is set if a cable is connected.
+ // CTS is set if it is ok to transmit data
+ //
+ // DSR CTS Description Action
+ // === === ======================================== ========
+ // 0 0 No cable connected. Wait
+ // 0 1 No cable connected. Wait
+ // 1 0 Cable connected, but not clear to send. Wait
+ // 1 1 Cable connected, and clear to send. Transmit
+ //
+ while ((SerialPortReadRegister (MSR_OFFSET) & (MSR_DSR | MSR_CTS)) != (MSR_DSR | MSR_CTS));
+ } else {
+ //
+ // Wait for both DSR and CTS to be set OR for DSR to be clear.
+ // DSR is set if a cable is connected.
+ // CTS is set if it is ok to transmit data
+ //
+ // DSR CTS Description Action
+ // === === ======================================== ========
+ // 0 0 No cable connected. Transmit
+ // 0 1 No cable connected. Transmit
+ // 1 0 Cable connected, but not clear to send. Wait
+ // 1 1 Cable connected, and clar to send. Transmit
+ //
+ while ((SerialPortReadRegister (MSR_OFFSET) & (MSR_DSR | MSR_CTS)) == (MSR_DSR));
+ }
+ }
+
+ //
+ // Write byte to the transmit buffer.
+ //
+ SerialPortWriteRegister (TXBUF_OFFSET, *Buffer);
+ }
+ }
+
+ return Result;
+}
+
+
+/**
+ Common function to write trace data to a chosen debug interface like
+ UART Serial device, USB Serial device or Trace Hub device
+
+ @param[in] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return RETURN_NOT_READY;
+ }
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ PchSerialIoUartOut (PcdGet8 (PcdSerialIoUartNumber), Buffer, NumberOfBytes);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Read data from serial device and save the datas in buffer.
+
+ If the buffer is NULL, then return 0;
+ if NumberOfBytes is zero, then return 0.
+
+ @param[out] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Read data failed.
+ @retval !0 Actual number of bytes raed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgIn (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINTN Result;
+ UINT8 Mcr;
+
+ if (NULL == Buffer) {
+ return 0;
+ }
+
+ Result = NumberOfBytes;
+
+ Mcr = (UINT8) (SerialPortReadRegister (MCR_OFFSET) & ~MCR_RTS);
+
+ for (Result = 0; NumberOfBytes-- != 0; Result ++, Buffer ++) {
+ //
+ // Wait for the serial port to have some data.
+ //
+ while ((SerialPortReadRegister (LSR_OFFSET) & LSR_RXDA) == 0) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Set RTS to let the peer send some data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (Mcr | MCR_RTS));
+ }
+ }
+
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Clear RTS to prevent peer from sending data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, Mcr);
+ }
+
+ //
+ // Read byte from the receive buffer.
+ //
+ *Buffer = SerialPortReadRegister (RXBUF_OFFSET);
+ }
+
+ return Result;
+}
+
+
+/**
+ Common function to Read data from UART serial device, USB serial device and save the datas in buffer.
+
+ @param[in] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return RETURN_NOT_READY;
+ }
+
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ PchSerialIoUartIn (PcdGet8 (PcdSerialIoUartNumber), Buffer, NumberOfBytes, FALSE);
+ }
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Polls a serial device to see if there is any data waiting to be read.
+
+ Polls a serial device to see if there is any data waiting to be read.
+ If there is data waiting to be read from the serial device, then TRUE is returned.
+ If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+ @retval TRUE Data is waiting to be read from the serial device.
+ @retval FALSE There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+UARTDbgPoll (
+ VOID
+ )
+{
+ //
+ // Read the serial port status
+ //
+ if ((SerialPortReadRegister (LSR_OFFSET) & LSR_RXDA) != 0) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Clear RTS to prevent peer from sending data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (SerialPortReadRegister (MCR_OFFSET) & ~ MCR_RTS));
+ }
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Set RTS to let the peer send some data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (SerialPortReadRegister (MCR_OFFSET) | MCR_RTS));
+ }
+ return FALSE;
+}
+
+
+/**
+ Polls a serial device to see if there is any data waiting to be read.
+
+ Polls a serial device to see if there is any data waiting to be read.
+ If there is data waiting to be read from the serial device, then TRUE is returned.
+ If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+ @retval TRUE Data is waiting to be read from the serial device.
+ @retval FALSE There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+ VOID
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+ BOOLEAN Status;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return FALSE;
+ }
+
+ Status = FALSE;
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ Status |= PchSerialIoUartPoll (PcdGet8 (PcdSerialIoUartNumber));
+ }
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.inf
new file mode 100644
index 0000000000..0e78ab2887
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Serial I/O Port library functions.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseSerialPortLib
+ FILE_GUID = 15B26F43-A389-4bae-BDE3-4BB0719B7D4F
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = BaseSerialPortLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ IoLib
+ PciLib
+ TimerLib
+ SerialPortParameterLib
+ PchSerialIoUartLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[FeaturePcd]
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+ gClientCommonModuleTokenSpaceGuid.PcdStatusCodeFlagsCmosIndex
+ gBxtRefCodePkgTokenSpaceGuid.PcdSerialIoUartNumber
+
+[Sources]
+ BaseSerialPortLib.c
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.c b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.c
new file mode 100644
index 0000000000..e7e8179d1c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.c
@@ -0,0 +1,392 @@
+/** @file
+ Serial I/O Port library functions with no library constructor/destructor.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/SerialPortParameterLib.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/CmosAccessLib.h>
+#include <Library/ScSerialIoUartLib.h>
+
+#ifdef TRACE_HUB_DEBUGLIB_USAGE
+#include <Library/TraceHubDebugLib.h>
+#endif
+
+//
+// UART register offsets and bitfields
+//
+#define RXBUF_OFFSET 0x00
+#define TXBUF_OFFSET 0x00
+#define BAUD_LOW_OFFSET 0x00
+#define BAUD_HIGH_OFFSET 0x01
+#define IER_OFFSET 0x01
+#define LCR_SHADOW_OFFSET 0x01
+#define FCR_SHADOW_OFFSET 0x02
+#define IR_CONTROL_OFFSET 0x02
+#define FCR_OFFSET 0x02
+#define EIR_OFFSET 0x02
+#define BSR_OFFSET 0x03
+#define LCR_OFFSET 0x03
+#define MCR_OFFSET 0x04
+#define LSR_OFFSET 0x05
+#define MSR_OFFSET 0x06
+
+//
+// UART Register Bit Defines
+//
+#define FCR_FIFOE BIT0
+#define FCR_FIFO64 BIT5
+#define LSR_TXRDY 0x20
+#define LSR_RXDA 0x01
+#define DLAB BIT7
+#define MCR_RTS BIT1
+#define MSR_CTS BIT4
+#define MSR_DSR BIT5
+
+#define MAX_BAUD_RATE 115200
+
+UINT8
+SerialPortReadRegister (
+ UINTN Offset
+ )
+{
+ return IoRead8 ((UINTN) PcdGet64 (PcdSerialRegisterBase) + Offset);
+}
+
+UINT8
+SerialPortWriteRegister (
+ UINTN Offset,
+ UINT8 Value
+ )
+{
+ return IoWrite8 ((UINTN) PcdGet64 (PcdSerialRegisterBase) + Offset, Value);
+}
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Write data to serial device.
+
+ If the buffer is NULL, then return 0;
+ if NumberOfBytes is zero, then return 0.
+
+ @param[in] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Write data failed.
+ @retval !0 Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgOut (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN Result;
+ UINTN FifoSize;
+ UINTN Index;
+
+ if (NULL == Buffer) {
+ return 0;
+ }
+
+ //
+ // Compute the maximum size of the Tx FIFO
+ //
+ FifoSize = 1;
+ if ((PcdGet8 (PcdSerialFifoControl) & FCR_FIFOE) != 0) {
+ if ((PcdGet8 (PcdSerialFifoControl) & FCR_FIFO64) == 0) {
+ FifoSize = 16;
+ } else {
+ FifoSize = 64;
+ }
+ }
+
+ Result = NumberOfBytes;
+
+ while (NumberOfBytes != 0) {
+ //
+ // Wait for the serial port to be ready, to make sure both the transmit FIFO
+ // and shift register empty.
+ //
+ while ((SerialPortReadRegister (LSR_OFFSET) & LSR_TXRDY) == 0);
+
+ //
+ // Fill then entire Tx FIFO
+ //
+ for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ if (PcdGetBool (PcdSerialDetectCable)) {
+ //
+ // Wait for both DSR and CTS to be set
+ // DSR is set if a cable is connected.
+ // CTS is set if it is ok to transmit data
+ //
+ // DSR CTS Description Action
+ // === === ======================================== ========
+ // 0 0 No cable connected. Wait
+ // 0 1 No cable connected. Wait
+ // 1 0 Cable connected, but not clear to send. Wait
+ // 1 1 Cable connected, and clear to send. Transmit
+ //
+ while ((SerialPortReadRegister (MSR_OFFSET) & (MSR_DSR | MSR_CTS)) != (MSR_DSR | MSR_CTS));
+ } else {
+ //
+ // Wait for both DSR and CTS to be set OR for DSR to be clear.
+ // DSR is set if a cable is connected.
+ // CTS is set if it is ok to transmit data
+ //
+ // DSR CTS Description Action
+ // === === ======================================== ========
+ // 0 0 No cable connected. Transmit
+ // 0 1 No cable connected. Transmit
+ // 1 0 Cable connected, but not clear to send. Wait
+ // 1 1 Cable connected, and clar to send. Transmit
+ //
+ while ((SerialPortReadRegister (MSR_OFFSET) & (MSR_DSR | MSR_CTS)) == (MSR_DSR));
+ }
+ }
+
+ //
+ // Write byte to the transmit buffer.
+ //
+ SerialPortWriteRegister (TXBUF_OFFSET, *Buffer);
+ }
+ }
+
+ return Result;
+}
+
+
+/**
+ Common function to write trace data to a chosen debug interface like
+ UART Serial device, USB Serial device or Trace Hub device
+
+ @param[in] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return RETURN_NOT_READY;
+ }
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ PchSerialIoUartOut (PcdGet8 (PcdSerialIoUartNumber), Buffer, NumberOfBytes);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Read data from serial device and save the datas in buffer.
+
+ If the buffer is NULL, then return 0;
+ if NumberOfBytes is zero, then return 0.
+
+ @param[out] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Read data failed.
+ @retval !0 Actual number of bytes raed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgIn (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINTN Result;
+ UINT8 Mcr;
+
+ if (NULL == Buffer) {
+ return 0;
+ }
+
+ Result = NumberOfBytes;
+
+ Mcr = (UINT8) (SerialPortReadRegister (MCR_OFFSET) & ~ MCR_RTS);
+
+ for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) {
+ //
+ // Wait for the serial port to have some data.
+ //
+ while ((SerialPortReadRegister (LSR_OFFSET) & LSR_RXDA) == 0) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Set RTS to let the peer send some data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (Mcr | MCR_RTS));
+ }
+ }
+
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Clear RTS to prevent peer from sending data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, Mcr);
+ }
+
+ //
+ // Read byte from the receive buffer.
+ //
+ *Buffer = SerialPortReadRegister (RXBUF_OFFSET);
+ }
+
+ return Result;
+}
+
+
+/**
+ Common function to Read data from UART serial device, USB serial device and save the datas in buffer.
+
+ @param[out] Buffer Point of data buffer which need to be writed.
+ @param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return RETURN_NOT_READY;
+ }
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ PchSerialIoUartIn (PcdGet8 (PcdSerialIoUartNumber), Buffer, NumberOfBytes, FALSE);
+ }
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Polls a serial device to see if there is any data waiting to be read.
+
+ Polls a serial device to see if there is any data waiting to be read.
+ If there is data waiting to be read from the serial device, then TRUE is returned.
+ If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+ @retval TRUE Data is waiting to be read from the serial device.
+ @retval FALSE There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+UARTDbgPoll (
+ VOID
+ )
+{
+ //
+ // Read the serial port status
+ //
+ if ((SerialPortReadRegister (LSR_OFFSET) & LSR_RXDA) != 0) {
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Clear RTS to prevent peer from sending data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (SerialPortReadRegister (MCR_OFFSET) & ~MCR_RTS));
+ }
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+ //
+ // Set RTS to let the peer send some data
+ //
+ SerialPortWriteRegister (MCR_OFFSET, (UINT8) (SerialPortReadRegister (MCR_OFFSET) | MCR_RTS));
+ }
+ return FALSE;
+}
+
+
+/**
+ Polls a serial device to see if there is any data waiting to be read.
+
+ Polls a serial device to see if there is any data waiting to be read.
+ If there is data waiting to be read from the serial device, then TRUE is returned.
+ If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+ @retval TRUE Data is waiting to be read from the serial device.
+ @retval FALSE There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+ VOID
+ )
+{
+ UINT8 CmosStatusCodeFlags;
+ BOOLEAN Status;
+
+ CmosStatusCodeFlags = GetDebugInterface ();
+ if ((!(CmosStatusCodeFlags & STATUS_CODE_CMOS_VALID)) || (CmosStatusCodeFlags & STATUS_CODE_CMOS_INVALID)) {
+
+ //
+ // invalid cmos value, it means action was attempted before Init
+ //
+ return FALSE;
+ }
+
+ Status = FALSE;
+
+ if (CmosStatusCodeFlags & STATUS_CODE_USE_SERIALIO) {
+ Status |= PchSerialIoUartPoll (PcdGet8 (PcdSerialIoUartNumber));
+ }
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.inf b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.inf
new file mode 100644
index 0000000000..8120ff26dd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortLib/BaseSerialPortLibNoInit.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Serial I/O Port library functions.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseSerialPortLibNoInit
+ FILE_GUID = 9029CFFA-E9A5-4B10-93B1-0031B5F1FD8A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = BaseSerialPortLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ IoLib
+ PciLib
+ TimerLib
+ SerialPortParameterLib
+ PchSerialIoUartLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[FeaturePcd]
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial
+ gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+ gClientCommonModuleTokenSpaceGuid.PcdStatusCodeFlagsCmosIndex
+ gBxtRefCodePkgTokenSpaceGuid.PcdSerialIoUartNumber
+
+[Sources]
+ BaseSerialPortLibNoInit.c
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.c b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.c
new file mode 100644
index 0000000000..97e56daa2b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.c
@@ -0,0 +1,74 @@
+/** @file
+ DebugPrintErrorLevel access library instance.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <Library/CmosAccessLib.h>
+
+
+/**
+ Returns the serial port baud rate.
+
+ @return Baud rate of serial port.
+
+**/
+UINT32
+EFIAPI
+GetSerialPortBaudRate (
+ VOID
+ )
+{
+ return ReadCmos32 (PcdGet8 (PcdSerialBaudRateCmosIndex));
+}
+
+
+/**
+ Sets the serial port baud rate value.
+
+ @param[in] Baud rate value to be set.
+
+ @retval TRUE The baud rate of serial port was sucessfully set.
+ @retval FALSE The baud rate of serial port could not be set.
+
+**/
+BOOLEAN
+EFIAPI
+SetSerialPortBaudRate (
+ UINT32 BaudRate
+ )
+{
+ RETURN_STATUS Status;
+
+ Status = WriteCmos32 (PcdGet8 (PcdSerialBaudRateCmosIndex), BaudRate);
+ return (BOOLEAN) (Status == RETURN_SUCCESS);
+}
+
+
+UINT8
+GetDebugInterface (
+ )
+{
+ return ReadCmos8 (PcdGet8 (PcdStatusCodeFlagsCmosIndex));
+}
+
+
+VOID
+SetDebugInterface (
+ UINT8 DebugInterface
+ )
+{
+ WriteCmos8 (PcdGet8 (PcdStatusCodeFlagsCmosIndex), DebugInterface);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.inf b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.inf
new file mode 100644
index 0000000000..8d29686193
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BaseSerialPortParameterLibCmos/BaseSerialPortParameterLibCmos.inf
@@ -0,0 +1,38 @@
+## @file
+# Get and/or set serial Port baud rate.
+#
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseSerialPortParameterLibCmos
+ FILE_GUID = D9C952F8-87FD-4e0b-ADC7-95AD85B9B795
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = SerialPortParameterLib
+
+[LibraryClasses]
+ BaseLib
+ CmosAccessLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gClientCommonModuleTokenSpaceGuid.PcdSerialBaudRateCmosIndex
+ gClientCommonModuleTokenSpaceGuid.PcdStatusCodeFlagsCmosIndex
+
+[Sources]
+ BaseSerialPortParameterLibCmos.c
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.c b/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.c
new file mode 100644
index 0000000000..6eee7f3adf
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.c
@@ -0,0 +1,326 @@
+/** @file
+ Boot service DXE BIOS ID library implementation.
+ These functions in this file can be called during DXE and cannot be called during runtime
+ or in SMM which should use a RT or SMM library.
+
+ Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BiosIdLib.h>
+#include <Guid/BiosId.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadedImage.h>
+
+
+EFI_STATUS
+GetImageFromFv (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+ IN EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 AuthenticationStatus;
+
+ //
+ // Read desired section content in NameGuid file
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ SectionType,
+ 0,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
+ //
+ // Try reading PE32 section, since the TE section does not exist
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_PE32,
+ 0,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+ }
+
+ if (EFI_ERROR (Status) &&
+ ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {
+ //
+ // Try reading raw file, since the desired section does not exist
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadFile (
+ Fv,
+ NameGuid,
+ Buffer,
+ Size,
+ &FileType,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+GetImageEx (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT VOID **Buffer,
+ OUT UINTN *Size,
+ BOOLEAN WithinImageFv
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+ if (ImageHandle == NULL && WithinImageFv) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_NOT_FOUND;
+ ImageFv = NULL;
+ if (ImageHandle != NULL) {
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = gBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &ImageFv
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
+ }
+ }
+
+ if (Status == EFI_SUCCESS || WithinImageFv) {
+ return Status;
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find desired image in all Fvs
+ //
+ for (Index = 0; Index < HandleCount; ++Index) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (HandleBuffer);
+ return Status;
+ }
+
+ if (ImageFv != NULL && Fv == ImageFv) {
+ continue;
+ }
+
+ Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
+
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ gBS->FreePool (HandleBuffer);
+
+ //
+ // Not found image
+ //
+ if (Index == HandleCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function returns BIOS ID by searching HOB or FV.
+
+ @param[out] BiosIdImage The BIOS ID got from HOB or FV
+
+ @retval EFI_SUCCESS All parameters were valid and BIOS ID has been got.
+ @retval EFI_NOT_FOUND BiosId image is not found, and no parameter will be modified.
+ @retval EFI_INVALID_PARAMETER The parameter is NULL
+
+**/
+EFI_STATUS
+GetBiosId (
+ OUT BIOS_ID_IMAGE *BiosIdImage
+ )
+{
+ EFI_STATUS Status;
+ VOID *Address = NULL;
+ UINTN Size = 0;
+
+ DEBUG ((EFI_D_INFO, "Get BIOS ID from FV\n"));
+
+ Status = GetImageEx (
+ NULL,
+ &gEfiBiosIdGuid,
+ EFI_SECTION_RAW,
+ &Address,
+ &Size,
+ FALSE
+ );
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // BiosId image is present in FV
+ //
+ if (Address != NULL) {
+ Size = sizeof (BIOS_ID_IMAGE);
+ gBS->CopyMem ((VOID *) BiosIdImage, Address, Size);
+ //
+ // GetImage () allocated buffer for Address, now clear it
+ //
+ gBS->FreePool (Address);
+
+ DEBUG ((EFI_D_INFO, "Get BIOS ID from FV successfully\n"));
+ DEBUG ((EFI_D_INFO, "BIOS ID: %s\n", (CHAR16 *) (&(BiosIdImage->BiosIdString))));
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ This function returns the Version & Release Date and Time by getting and converting
+ BIOS ID.
+
+ @param[out] BiosVersion The Bios Version out of the conversion
+ @param[out] BiosReleaseDate The Bios Release Date out of the conversion
+ @param[out] BiosReleaseTime The Bios Release Time out of the conversion
+
+ @retval EFI_SUCCESS BIOS Version & Release Date and Time have been got successfully.
+ @retval EFI_NOT_FOUND BiosId image is not found, and no parameter will be modified.
+ @retval EFI_INVALID_PARAMETER All the parameters are NULL.
+
+**/
+EFI_STATUS
+GetBiosVersionDateTime (
+ OUT CHAR16 *BiosVersion, OPTIONAL
+ OUT CHAR16 *BiosReleaseDate, OPTIONAL
+ OUT CHAR16 *BiosReleaseTime OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ BIOS_ID_IMAGE BiosIdImage;
+
+ if ((BiosVersion == NULL) && (BiosReleaseDate == NULL) && (BiosReleaseTime == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetBiosId (&BiosIdImage);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (BiosVersion != NULL) {
+ //
+ // Fill the BiosVersion data from the BIOS ID.
+ //
+ StrCpyS (BiosVersion, sizeof (BIOS_ID_STRING) / sizeof (CHAR16), (CHAR16 *) (&(BiosIdImage.BiosIdString)));
+ }
+
+ if (BiosReleaseDate != NULL) {
+ //
+ // Fill the build timestamp date from the BIOS ID in the "MM/DD/YY" format.
+ //
+ BiosReleaseDate[0] = BiosIdImage.BiosIdString.TimeStamp[2];
+ BiosReleaseDate[1] = BiosIdImage.BiosIdString.TimeStamp[3];
+ BiosReleaseDate[2] = (CHAR16) ((UINT8) ('/'));
+
+ BiosReleaseDate[3] = BiosIdImage.BiosIdString.TimeStamp[4];
+ BiosReleaseDate[4] = BiosIdImage.BiosIdString.TimeStamp[5];
+ BiosReleaseDate[5] = (CHAR16) ((UINT8) ('/'));
+
+ //
+ // Add 20 for SMBIOS table
+ // Current Linux kernel will misjudge 09 as year 0, so using 2009 for SMBIOS table
+ //
+ BiosReleaseDate[6] = '2';
+ BiosReleaseDate[7] = '0';
+ BiosReleaseDate[8] = BiosIdImage.BiosIdString.TimeStamp[0];
+ BiosReleaseDate[9] = BiosIdImage.BiosIdString.TimeStamp[1];
+
+ BiosReleaseDate[10] = (CHAR16) ((UINT8) ('\0'));
+ }
+
+ if (BiosReleaseTime != NULL) {
+ //
+ // Fill the build timestamp time from the BIOS ID in the "HH:MM" format.
+ //
+ BiosReleaseTime[0] = BiosIdImage.BiosIdString.TimeStamp[6];
+ BiosReleaseTime[1] = BiosIdImage.BiosIdString.TimeStamp[7];
+ BiosReleaseTime[2] = (CHAR16) ((UINT8) (':'));
+
+ BiosReleaseTime[3] = BiosIdImage.BiosIdString.TimeStamp[8];
+ BiosReleaseTime[4] = BiosIdImage.BiosIdString.TimeStamp[9];
+
+ BiosReleaseTime[5] = (CHAR16) ((UINT8) ('\0'));
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.inf
new file mode 100644
index 0000000000..75b7b5db38
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/BiosIdLib/BiosIdLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for BIOS ID library.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BiosIdLib
+ FILE_GUID = 98546145-64F1-4d2e-814F-6BF963DB7930
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BiosIdLib
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+[Sources]
+ BiosIdLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+ HobLib
+
+[Guids]
+ gEfiBiosIdGuid
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid
+
+[Depex]
+ gEfiLoadedImageProtocolGuid AND
+ gEfiFirmwareVolume2ProtocolGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/CpuIA32Lib.inf b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/CpuIA32Lib.inf
new file mode 100644
index 0000000000..bcb9de1076
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/CpuIA32Lib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for the Cpu IA32 library.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CpuIA32Lib
+ FILE_GUID = 98546178-64F1-4d2e-814F-6BF963DB7930
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CpuIA32Lib
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+[Sources]
+ EfiCpuVersion.c
+
+[Sources.IA32]
+ IA32/CpuIA32.c
+ IA32/CpuIA32.S
+
+[Sources.X64]
+ X64/Cpu.asm
+ X64/Cpu.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/EfiCpuVersion.c b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/EfiCpuVersion.c
new file mode 100644
index 0000000000..e9b1a8607b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/EfiCpuVersion.c
@@ -0,0 +1,68 @@
+/** @file
+ Provide Cpu version extract considering extended family & model ID.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/CpuIA32.h>
+
+
+/**
+ Extract CPU detail version infomation
+
+ @param[in, out] FamilyId FamilyId, including ExtendedFamilyId
+ @param[in, out] Model Model, including ExtendedModel
+ @param[in, out] SteppingId SteppingId
+ @param[in, out] Processor Processor
+
+**/
+VOID
+EFIAPI
+EfiCpuVersion (
+ IN OUT UINT16 *FamilyId, OPTIONAL
+ IN OUT UINT8 *Model, OPTIONAL
+ IN OUT UINT8 *SteppingId, OPTIONAL
+ IN OUT UINT8 *Processor OPTIONAL
+ )
+{
+ EFI_CPUID_REGISTER Register;
+ UINT8 TempFamilyId;
+
+ EfiCpuid (EFI_CPUID_VERSION_INFO, &Register);
+
+ if (SteppingId != NULL) {
+ *SteppingId = (UINT8) (Register.RegEax & 0xF);
+ }
+
+ if (Processor != NULL) {
+ *Processor = (UINT8) ((Register.RegEax >> 12) & 0x3);
+ }
+
+ if (Model != NULL || FamilyId != NULL) {
+ TempFamilyId = (UINT8) ((Register.RegEax >> 8) & 0xF);
+
+ if (Model != NULL) {
+ *Model = (UINT8) ((Register.RegEax >> 4) & 0xF);
+ if (TempFamilyId == 0x6 || TempFamilyId == 0xF) {
+ *Model = (UINT8) (*Model | ((Register.RegEax >> 12) & 0xF0));
+ }
+ }
+
+ if (FamilyId != NULL) {
+ *FamilyId = TempFamilyId;
+ if (TempFamilyId == 0xF) {
+ *FamilyId = (UINT8 ) (*FamilyId + (UINT16) ((Register.RegEax >> 20) & 0xFF));
+ }
+ }
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.S b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.S
new file mode 100644
index 0000000000..2c9a27cffb
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.S
@@ -0,0 +1,213 @@
+## @file
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+#---------------------------------------------------------------------------
+ .586p:
+ #.MODEL flat,C
+ .code:
+
+#---------------------------------------------------------------------------
+
+.globl ASM_PFX(EfiHalt)
+.globl ASM_PFX(EfiWbinvd)
+.globl ASM_PFX(EfiInvd)
+.globl ASM_PFX(EfiCpuid)
+.globl ASM_PFX(EfiReadMsr)
+.globl ASM_PFX(EfiWriteMsr)
+.globl ASM_PFX(EfiReadTsc)
+.globl ASM_PFX(EfiDisableCache)
+.globl ASM_PFX(EfiEnableCache)
+.globl ASM_PFX(EfiGetEflags)
+.globl ASM_PFX(EfiDisableInterrupts)
+.globl ASM_PFX(EfiEnableInterrupts)
+.globl ASM_PFX(EfiCpuidExt)
+
+
+#VOID
+#EfiHalt (
+# VOID
+#)
+ASM_PFX(EfiHalt):
+ hlt
+ ret
+#EfiHalt ENDP
+
+#VOID
+#EfiWbinvd (
+# VOID
+#)
+ASM_PFX(EfiWbinvd):
+ wbinvd
+ ret
+#EfiWbinvd ENDP
+
+#VOID
+#EfiInvd (
+# VOID
+#)
+ASM_PFX(EfiInvd):
+ invd
+ ret
+#EfiInvd ENDP
+
+#VOID
+#EfiCpuid (IN UINT32 RegisterInEax,
+# OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+ASM_PFX(EfiCpuid):
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ pushal
+
+ movl 8(%ebp), %eax #RegisterInEax
+ cpuid
+ cmpl $0, 0xC(%ebp) # Reg
+ je L1
+ movl 0xC(%ebp), %edi # Reg
+
+ movl %eax, (%edi) # Reg->RegEax
+ movl %ebx, 4(%edi) # Reg->RegEbx
+ movl %ecx, 8(%edi) # Reg->RegEcx
+ movl %edx, 0xC(%edi) # Reg->RegEdx
+
+L1:
+ popal
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+
+ ret
+#EfiCpuid ENDP
+
+
+#UINT64
+#EfiReadMsr (
+# IN UINT32 Index
+# );
+ASM_PFX(EfiReadMsr):
+ movl 4(%esp), %ecx # Index
+ rdmsr
+ ret
+#EfiReadMsr ENDP
+
+#VOID
+#EfiWriteMsr (
+# IN UINT32 Index,
+# IN UINT64 Value
+# );
+ASM_PFX(EfiWriteMsr):
+ movl 4(%esp), %ecx # Index
+ movl 8(%esp), %eax # DWORD PTR Value[0]
+ movl 0xC(%esp), %edx # DWORD PTR Value[4]
+ wrmsr
+ ret
+#EfiWriteMsr ENDP
+
+#UINT64
+#EfiReadTsc (
+# VOID
+# )
+ASM_PFX(EfiReadTsc):
+ rdtsc
+ ret
+#EfiReadTsc ENDP
+
+#VOID
+#EfiDisableCache (
+# VOID
+#)
+ASM_PFX(EfiDisableCache):
+ movl %cr0, %eax
+ bswapl %eax
+ andb $0x60, %al
+ cmpb $0x60, %al
+ je L2
+ movl %cr0, %eax
+ orl $0x60000000, %eax
+ movl %eax, %cr0
+ wbinvd
+L2:
+ ret
+#EfiDisableCache ENDP
+
+#VOID
+#EfiEnableCache (
+# VOID
+# )
+ASM_PFX(EfiEnableCache):
+ wbinvd
+ movl %cr0, %eax
+ andl $0x9fffffff, %eax
+ movl %eax, %cr0
+ ret
+#EfiEnableCache ENDP
+
+#UINT32
+#EfiGetEflags (
+# VOID
+# )
+ASM_PFX(EfiGetEflags):
+ pushfl
+ popl %eax
+ ret
+#EfiGetEflags ENDP
+
+#VOID
+#EfiDisableInterrupts (
+# VOID
+# )
+ASM_PFX(EfiDisableInterrupts):
+ cli
+ ret
+#EfiDisableInterrupts ENDP
+
+#VOID
+#EfiEnableInterrupts (
+# VOID
+# )
+ASM_PFX(EfiEnableInterrupts):
+ sti
+ ret
+#EfiEnableInterrupts ENDP
+
+#VOID
+#EfiCpuidExt (
+# IN UINT32 RegisterInEax,
+# IN UINT32 CacheLevel,
+# OUT EFI_CPUID_REGISTER *Regs
+# )
+ASM_PFX(EfiCpuidExt):
+ push %ebx
+ push %edi
+ push %esi
+ pushal
+
+ movl 0x30(%esp), %eax # RegisterInEax
+ movl 0x34(%esp), %ecx # CacheLevel
+ cpuid
+ movl 0x38(%esp), %edi # DWORD PTR Regs
+
+ movl %eax, (%edi) # Reg->RegEax
+ movl %ebx, 4(%edi) # Reg->RegEbx
+ movl %ecx, 8(%edi) # Reg->RegEcx
+ movl %edx, 0xC(%edi) # Reg->RegEdx
+
+ popal
+ pop %esi
+ pop %edi
+ pop %ebx
+ ret
+#EfiCpuidExt ENDP
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.asm b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.asm
new file mode 100644
index 0000000000..cb627d0cb0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.asm
@@ -0,0 +1,194 @@
+;; @file
+; Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+;---------------------------------------------------------------------------
+ .586p
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+;VOID
+;EfiHalt (
+; VOID
+;)
+EfiHalt PROC C PUBLIC
+ hlt
+ ret
+EfiHalt ENDP
+
+;VOID
+;EfiWbinvd (
+; VOID
+;)
+EfiWbinvd PROC C PUBLIC
+ wbinvd
+ ret
+EfiWbinvd ENDP
+
+;VOID
+;EfiInvd (
+; VOID
+;)
+EfiInvd PROC C PUBLIC
+ invd
+ ret
+EfiInvd ENDP
+
+;VOID
+;EfiCpuid (IN UINT32 RegisterInEax,
+; OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+EfiCpuid PROC C PUBLIC
+ push ebp
+ mov ebp, esp
+ push ebx
+ push esi
+ push edi
+ pushad
+
+ mov eax, dword ptr[ebp + 8] ;egisterInEax
+ cpuid
+ cmp dword ptr[ebp + 0Ch], 0 ; Reg
+ je @F
+ mov edi,dword ptr [ebp+0Ch] ; Reg
+
+ mov dword ptr [edi],eax ; Reg->RegEax
+ mov dword ptr [edi+4],ebx ; Reg->RegEbx
+ mov dword ptr [edi+8],ecx ; Reg->RegEcx
+ mov dword ptr [edi+0Ch],edx ; Reg->RegEdx
+
+@@:
+ popad
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+
+ ret
+EfiCpuid ENDP
+
+
+;UINT64
+;EfiReadMsr (
+; IN UINT32 Index
+; );
+EfiReadMsr PROC C PUBLIC
+ mov ecx, dword ptr [esp + 4]; Index
+ rdmsr
+ ret
+EfiReadMsr ENDP
+
+;VOID
+;EfiWriteMsr (
+; IN UINT32 Index,
+; IN UINT64 Value
+; );
+EfiWriteMsr PROC C PUBLIC
+ mov ecx, dword ptr [esp+4]; Index
+ mov eax, dword ptr [esp+8]; DWORD PTR Value[0]
+ mov edx, dword ptr [esp+0Ch]; DWORD PTR Value[4]
+ wrmsr
+ ret
+EfiWriteMsr ENDP
+
+;UINT64
+;EfiReadTsc (
+; VOID
+; )
+EfiReadTsc PROC C PUBLIC
+ rdtsc
+ ret
+EfiReadTsc ENDP
+
+;VOID
+;EfiDisableCache (
+; VOID
+;)
+EfiDisableCache PROC C PUBLIC
+ mov eax, cr0
+ bswap eax
+ and al, 60h
+ cmp al, 60h
+ je @F
+ mov eax, cr0
+ or eax, 060000000h
+ mov cr0, eax
+ wbinvd
+@@:
+ ret
+EfiDisableCache ENDP
+
+;VOID
+;EfiEnableCache (
+; VOID
+; )
+EfiEnableCache PROC C PUBLIC
+ wbinvd
+ mov eax, cr0
+ and eax, 09fffffffh
+ mov cr0, eax
+ ret
+EfiEnableCache ENDP
+
+;UINT32
+;EfiGetEflags (
+; VOID
+; )
+EfiGetEflags PROC C PUBLIC
+ pushfd
+ pop eax
+ ret
+EfiGetEflags ENDP
+
+;VOID
+;EfiDisableInterrupts (
+; VOID
+; )
+EfiDisableInterrupts PROC C PUBLIC
+ cli
+ ret
+EfiDisableInterrupts ENDP
+
+;VOID
+;EfiEnableInterrupts (
+; VOID
+; )
+EfiEnableInterrupts PROC C PUBLIC
+ sti
+ ret
+EfiEnableInterrupts ENDP
+
+;VOID
+;EfiCpuidExt (
+; IN UINT32 RegisterInEax,
+; IN UINT32 CacheLevel,
+; OUT EFI_CPUID_REGISTER *Regs
+; )
+EfiCpuidExt PROC C PUBLIC USES ebx edi esi
+ pushad
+
+ mov eax, dword ptr [esp + 30h] ; RegisterInEax
+ mov ecx, dword ptr [esp + 34h] ; CacheLevel
+ cpuid
+ mov edi, dword ptr [esp + 38h] ; DWORD PTR Regs
+
+ mov dword ptr [edi], eax ; Reg->RegEax
+ mov dword ptr [edi + 4], ebx ; Reg->RegEbx
+ mov dword ptr [edi + 8], ecx ; Reg->RegEcx
+ mov dword ptr [edi + 0Ch], edx ; Reg->RegEdx
+
+ popad
+ ret
+EfiCpuidExt ENDP
+
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.c b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.c
new file mode 100644
index 0000000000..479d16f867
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/IA32/CpuIA32.c
@@ -0,0 +1,174 @@
+/** @file
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/CpuIA32.h>
+
+VOID
+EfiHalt (VOID)
+{
+ __asm {
+ hlt
+ }
+}
+
+VOID
+EfiWbinvd (VOID)
+{
+ __asm {
+ wbinvd
+ }
+}
+
+VOID
+EfiInvd (VOID)
+{
+ __asm {
+ invd
+ }
+}
+
+VOID
+EfiCpuid (IN UINT32 RegisterInEax,
+ OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+{
+ __asm {
+ pushad
+
+ mov eax, RegisterInEax
+ cpuid
+ cmp Reg, 0
+ je _Exit
+ mov edi, DWORD PTR Reg
+
+ mov DWORD PTR [edi].RegEax, eax ; Reg->RegEax
+ mov DWORD PTR [edi].RegEbx, ebx ; Reg->RegEbx
+ mov DWORD PTR [edi].RegEcx, ecx ; Reg->RegEcx
+ mov DWORD PTR [edi].RegEdx, edx ; Reg->RegEdx
+
+_Exit:
+ popad
+ }
+}
+
+UINT64
+EfiReadMsr (IN UINT32 Index)
+{
+ __asm {
+ mov ecx, Index
+ rdmsr
+ }
+}
+
+VOID
+EfiWriteMsr (
+ IN UINT32 Index,
+ IN UINT64 Value
+ )
+{
+ __asm {
+ mov ecx, Index
+ mov eax, DWORD PTR Value[0]
+ mov edx, DWORD PTR Value[4]
+ wrmsr
+ }
+}
+
+UINT64
+EfiReadTsc (VOID)
+{
+ __asm {
+ rdtsc
+ }
+}
+
+VOID
+EfiDisableCache (VOID)
+{
+ __asm {
+ mov eax, cr0
+ bswap eax
+ and al, 60h
+ cmp al, 60h
+ je Exit
+ mov eax, cr0
+ or eax, 060000000h
+ mov cr0, eax
+ wbinvd
+Exit:
+ }
+}
+
+VOID
+EfiEnableCache (VOID)
+{
+ __asm {
+ wbinvd
+ mov eax, cr0
+ and eax, 09fffffffh
+ mov cr0, eax
+ }
+}
+
+UINT32
+EfiGetEflags (
+ VOID
+ )
+{
+ __asm {
+ pushfd
+ pop eax
+ }
+}
+
+VOID
+EfiDisableInterrupts (VOID)
+{
+ __asm {
+ cli
+ }
+}
+
+VOID
+EfiEnableInterrupts (
+ VOID
+ )
+{
+ __asm {
+ sti
+ }
+}
+
+VOID
+EfiCpuidExt (
+ IN UINT32 RegisterInEax,
+ IN UINT32 CacheLevel,
+ OUT EFI_CPUID_REGISTER *Regs
+ )
+{
+ __asm {
+ pushad
+
+ mov eax, RegisterInEax
+ mov ecx, CacheLevel
+ cpuid
+ mov edi, DWORD PTR Regs
+
+ mov DWORD PTR [edi].RegEax, eax ; Reg->RegEax
+ mov DWORD PTR [edi].RegEbx, ebx ; Reg->RegEbx
+ mov DWORD PTR [edi].RegEcx, ecx ; Reg->RegEcx
+ mov DWORD PTR [edi].RegEdx, edx ; Reg->RegEdx
+
+ popad
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.S b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.S
new file mode 100644
index 0000000000..d43eed8f44
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.S
@@ -0,0 +1,204 @@
+## @file
+# Assembly code for the x64 resources.
+#
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+.globl ASM_PFX(EfiHalt)
+.globl ASM_PFX(EfiWbinvd)
+.globl ASM_PFX(EfiInvd)
+.globl ASM_PFX(EfiCpuid)
+.globl ASM_PFX(EfiReadTsc)
+.globl ASM_PFX(EfiDisableCache)
+.globl ASM_PFX(EfiEnableCache)
+.globl ASM_PFX(EfiReadMsr)
+.globl ASM_PFX(EfiWriteMsr)
+.globl ASM_PFX(EfiGetEflags)
+.globl ASM_PFX(EfiDisableInterrupts)
+.globl ASM_PFX(EfiEnableInterrupts)
+.globl ASM_PFX(EfiCpuidExt)
+
+.text
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiHalt (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiHalt):
+ hlt
+ retq
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiWbinvd (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiWbinvd):
+ wbinvd
+ retq
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiInvd (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiInvd):
+ invd
+ retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiCpuid (
+# IN UINT32 RegisterInEax, // rcx
+# OUT EFI_CPUID_REGISTER *Reg OPTIONAL // rdx
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiCpuid):
+ push %rbx
+ mov %rdx,%r8
+ mov %rcx,%rax
+ cpuid
+ cmp $0x0,%r8
+ je _Exit
+ mov %eax,(%r8)
+ mov %ebx,0x4(%r8)
+ mov %ecx,0x8(%r8)
+ mov %edx,0xc(%r8)
+_Exit:
+ pop %rbx
+ retq
+
+#------------------------------------------------------------------------------
+# UINT64
+# EfiReadMsr (
+# IN UINT32 Index, // rcx
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiReadMsr):
+ rdmsr
+ shl $0x20,%rdx
+ or %rdx,%rax
+ retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiWriteMsr (
+# IN UINT32 Index, // rcx
+# IN UINT64 Value // rdx
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiWriteMsr):
+ mov %rdx,%rax
+ sar $0x20,%rdx
+ wrmsr
+ retq
+
+#------------------------------------------------------------------------------
+# UINT64
+# EfiReadTsc (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiReadTsc):
+ rdtsc
+ shl $0x20,%rax
+ shrd $0x20,%rdx,%rax
+ retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiDisableCache (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiDisableCache):
+# added a check to see if cache is already disabled. If it is, then skip.
+ mov %cr0,%rax
+ and $0x60000000,%rax
+ cmp $0x0,%rax
+ jne 1f
+ mov %cr0,%rax
+ or $0x60000000,%rax
+ mov %rax,%cr0
+ wbinvd
+1:
+ retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiEnableCache (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiEnableCache):
+ wbinvd
+ mov %cr0,%rax
+ and $0xffffffff9fffffff,%rax
+ mov %rax,%cr0
+ retq
+
+#------------------------------------------------------------------------------
+# UINTN
+# EfiGetEflags (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiGetEflags):
+ pushfq
+ pop %rax
+ retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiDisableInterrupts (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiDisableInterrupts):
+ cli
+ ret
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiEnableInterrupts (
+# VOID
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiEnableInterrupts):
+ sti
+ ret
+#------------------------------------------------------------------------------
+# VOID
+# EfiCpuidExt (
+# IN UINT32 RegisterInEax,
+# IN UINT32 CacheLevel,
+# OUT EFI_CPUID_REGISTER *Regs
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiCpuidExt):
+ push %rbx
+ mov %rcx,%rax
+ mov %rdx,%rcx
+ cpuid
+ mov %eax,(%r8)
+ mov %ebx,0x4(%r8)
+ mov %ecx,0x8(%r8)
+ mov %edx,0xc(%r8)
+ pop %rbx
+ retq
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.asm b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.asm
new file mode 100644
index 0000000000..d123660a3a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/CpuIA32Lib/X64/Cpu.asm
@@ -0,0 +1,210 @@
+;; @file
+; Assembly code for the x64 resources
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+text SEGMENT
+
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiHalt (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EfiHalt PROC PUBLIC
+ hlt
+ ret
+EfiHalt ENDP
+
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiWbinvd (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EfiWbinvd PROC PUBLIC
+ wbinvd
+ ret
+EfiWbinvd ENDP
+
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiInvd (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EfiInvd PROC PUBLIC
+ invd
+ ret
+EfiInvd ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiCpuid (
+; IN UINT32 RegisterInEax, // rcx
+; OUT EFI_CPUID_REGISTER *Reg OPTIONAL // rdx
+; )
+;------------------------------------------------------------------------------
+EfiCpuid PROC PUBLIC
+ push rbx
+
+ mov r8, rdx ; r8 = *Reg
+ mov rax, rcx ; RegisterInEax
+ cpuid
+ cmp r8, 0
+ je _Exit
+ mov [r8 + 0], eax ; Reg->RegEax
+ mov [r8 + 4], ebx ; Reg->RegEbx
+ mov [r8 + 8], ecx ; Reg->RegEcx
+ mov [r8 + 12], edx ; Reg->RegEdx
+
+_Exit:
+ pop rbx
+ ret
+EfiCpuid ENDP
+
+;------------------------------------------------------------------------------
+; UINT64
+; EfiReadMsr (
+; IN UINT32 Index, // rcx
+; )
+;------------------------------------------------------------------------------
+EfiReadMsr PROC PUBLIC
+ rdmsr
+ sal rdx, 32 ; edx:eax -> rax
+ or rax, rdx ; rax = edx:eax
+ ret
+EfiReadMsr ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiWriteMsr (
+; IN UINT32 Index, // rcx
+; IN UINT64 Value // rdx
+; )
+;------------------------------------------------------------------------------
+EfiWriteMsr PROC PUBLIC
+ mov rax, rdx ; rdx = Value
+ sar rdx, 32 ; convert rdx to edx upper 32-bits
+ wrmsr ; wrmsr[ecx] result = edx:eax
+ ret
+EfiWriteMsr ENDP
+
+
+;------------------------------------------------------------------------------
+; UINT64
+; EfiReadTsc (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiReadTsc PROC PUBLIC
+ rdtsc
+ shl rax, 32
+ shrd rax, rdx, 32
+ ret
+EfiReadTsc ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiDisableCache (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiDisableCache PROC PUBLIC
+; added a check to see if cache is already disabled. If it is, then skip.
+ mov rax, cr0
+ and rax, 060000000h
+ cmp rax, 0
+ jne @f
+ mov rax, cr0
+ or rax, 060000000h
+ mov cr0, rax
+ wbinvd
+@@:
+ ret
+EfiDisableCache ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiEnableCache (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiEnableCache PROC PUBLIC
+ wbinvd
+ mov rax, cr0
+ and rax, 09fffffffh
+ mov cr0, rax
+ ret
+EfiEnableCache ENDP
+
+;------------------------------------------------------------------------------
+; UINTN
+; EfiGetEflags (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiGetEflags PROC PUBLIC
+ pushfq
+ pop rax
+ ret
+EfiGetEflags ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiDisableInterrupts (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiDisableInterrupts PROC PUBLIC
+ cli
+ ret
+EfiDisableInterrupts ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiEnableInterrupts (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiEnableInterrupts PROC PUBLIC
+ sti
+ ret
+EfiEnableInterrupts ENDP
+;------------------------------------------------------------------------------
+; VOID
+; EfiCpuidExt (
+; IN UINT32 RegisterInEax,
+; IN UINT32 CacheLevel,
+; OUT EFI_CPUID_REGISTER *Regs
+; )
+;------------------------------------------------------------------------------
+EfiCpuidExt PROC PUBLIC
+ push rbx
+ mov rax, rcx ; rax = RegisterInEax
+ mov rcx, rdx ; rcx = CacheLevel
+
+ cpuid
+ mov [r8 + 0 ], eax ; Reg->RegEax
+ mov [r8 + 4 ], ebx ; Reg->RegEbx
+ mov [r8 + 8 ], ecx ; Reg->RegEcx
+ mov [r8 + 12], edx ; Reg->RegEdx
+
+ pop rbx
+ ret
+EfiCpuidExt ENDP
+END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.c b/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.c
new file mode 100644
index 0000000000..b09bc988be
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.c
@@ -0,0 +1,1265 @@
+/** @file
+ Performance library instance mainly used by DxeCore.
+
+ This library provides the performance measurement interfaces and initializes performance
+ logging for DXE phase. It first initializes its private global data structure for
+ performance logging and saves the performance GUIDed HOB passed from PEI phase.
+ It initializes DXE phase performance logging by publishing the PerformanceEx Protocol,
+ which are consumed by DxePerformanceLib to logging performance data in DXE phase.
+
+ This library is mainly used by DxeCore to start performance logging to ensure that
+ PerformanceEx Protocol is installed at the very beginning of DXE phase.
+
+ This library also converts performance log to FPDT record, and report them to boot FPDT table.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Guid/Performance.h>
+#include <Guid/FirmwarePerformance.h>
+#include <PeiFirmwarePerformance.h>
+#include <Guid/ZeroGuid.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/DevicePathToText.h>
+#include <Library/PerformanceLib.h>
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/DxeServicesLib.h>
+#include <ExtendedFirmwarePerformanceData.h>
+
+//
+// Data buffer for FPDT performance records.
+//
+#define FIRMWARE_RECORD_BUFFER 0x10000
+UINT8 *mPerformancePointer = NULL;
+UINTN mPerformanceLength = 0;
+UINTN mMaxPerformanceLength = 0;
+UINT16 mBdsAttemptNumber = 0;
+BOOLEAN mFpdtDataIsReport = FALSE;
+EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathToText = NULL;
+CHAR8 *mPlatformLanguage = NULL;
+
+/**
+ Get a human readable module name and module guid for the given image handle.
+ If module name can't be found, "" string will return.
+ If module guid can't be found, Zero Guid will return.
+
+ @param[in] Handle Image handle or Controller handle.
+ @param[out] NameString The ascii string will be filled into it. If not found, null string will return.
+ @param[in] BufferSize Size of the input NameString buffer.
+ @param[out] ModuleGuid Point to the guid buffer to store the got module guid value.
+
+ @retval EFI_SUCCESS Successfully get module name and guid.
+ @retval EFI_INVALID_PARAMETER The input parameter NameString is NULL.
+ @retval Other value Module Name can't be got.
+
+**/
+EFI_STATUS
+EFIAPI
+GetModuleInfoFromHandle (
+ IN EFI_HANDLE Handle,
+ OUT CHAR8 *NameString,
+ IN UINTN BufferSize,
+ OUT EFI_GUID *ModuleGuid OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+ CHAR8 *PdbFileName;
+ EFI_GUID *TempGuid;
+ UINTN StartIndex;
+ UINTN Index;
+ BOOLEAN ModuleGuidIsGet;
+ UINTN StringSize;
+ CHAR16 *StringPtr;
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
+
+ if (NameString == NULL || BufferSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_INVALID_PARAMETER;
+ LoadedImage = NULL;
+ ModuleGuidIsGet = FALSE;
+
+ //
+ // Initialize GUID as zero value.
+ //
+ TempGuid = &gZeroGuid;
+
+ //
+ // Initialize it as "" string.
+ //
+ NameString[0] = 0;
+
+ if (Handle != NULL) {
+ //
+ // Try Handle as ImageHandle.
+ //
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Try Handle as Controller Handle
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiDriverBindingProtocolGuid,
+ (VOID **) &DriverBinding,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get Image protocol from ImageHandle
+ //
+ Status = gBS->HandleProtocol (
+ DriverBinding->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ }
+ }
+ }
+
+ if (!EFI_ERROR (Status) && LoadedImage != NULL) {
+ //
+ // Get Module Guid from DevicePath.
+ //
+ if (LoadedImage->FilePath != NULL &&
+ LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH &&
+ LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP
+ ) {
+ //
+ // Determine GUID associated with module logging performance
+ //
+ ModuleGuidIsGet = TRUE;
+ FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LoadedImage->FilePath;
+ TempGuid = &FvFilePath->FvFileName;
+ }
+
+ //
+ // Method 1 Get Module Name from PDB string.
+ //
+ PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
+ if (PdbFileName != NULL && BufferSize > 0) {
+ StartIndex = 0;
+ for (Index = 0; PdbFileName[Index] != 0; Index++) {
+ if ((PdbFileName[Index] == '\\') || (PdbFileName[Index] == '/')) {
+ StartIndex = Index + 1;
+ }
+ }
+
+ //
+ // Copy the PDB file name to our temporary string.
+ // If the length is bigger than BufferSize, trim the redudant characters to avoid overflow in array boundary.
+ //
+ for (Index = 0; Index < BufferSize - 1; Index++) {
+ NameString[Index] = PdbFileName[Index + StartIndex];
+ if (NameString[Index] == 0 || NameString[Index] == '.') {
+ NameString[Index] = 0;
+ break;
+ }
+ }
+
+ if (Index == BufferSize - 1) {
+ NameString[Index] = 0;
+ }
+ //
+ // Module Name is got.
+ //
+ goto Done;
+ }
+ }
+
+ //
+ // Method 2: Get the name string from ComponentName2 protocol
+ //
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiComponentName2ProtocolGuid,
+ (VOID **) &ComponentName2
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get the current platform language setting
+ //
+ if (mPlatformLanguage == NULL) {
+ mPlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");
+ }
+ if (mPlatformLanguage != NULL) {
+ Status = ComponentName2->GetDriverName (
+ ComponentName2,
+ mPlatformLanguage != NULL ? mPlatformLanguage : "en-US",
+ &StringPtr
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < BufferSize - 1 && StringPtr[Index] != 0; Index++) {
+ NameString[Index] = (CHAR8) StringPtr[Index];
+ }
+ NameString[Index] = 0;
+ //
+ // Module Name is got.
+ //
+ goto Done;
+ }
+ }
+ }
+
+ if (ModuleGuidIsGet) {
+ //
+ // Method 3 Try to get the image's FFS UI section by image GUID
+ //
+ StringPtr = NULL;
+ StringSize = 0;
+ Status = GetSectionFromAnyFv (
+ TempGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **) &StringPtr,
+ &StringSize
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Method 3. Get the name string from FFS UI section
+ //
+ for (Index = 0; Index < BufferSize - 1 && StringPtr[Index] != 0; Index++) {
+ NameString[Index] = (CHAR8) StringPtr[Index];
+ }
+ NameString[Index] = 0;
+ FreePool (StringPtr);
+ }
+ }
+
+Done:
+ //
+ // Copy Module Guid
+ //
+ if (ModuleGuid != NULL) {
+ CopyGuid (ModuleGuid, TempGuid);
+ if (CompareGuid (TempGuid, &gZeroGuid) && (Handle != NULL) && !ModuleGuidIsGet) {
+ //
+ // Handle is GUID
+ //
+ CopyGuid (ModuleGuid, (EFI_GUID *) Handle);
+ }
+ }
+
+ return Status;
+}
+
+
+/**
+ Convert performance token to FPDT record.
+
+ @param[in] IsStart TRUE if the performance log is start log.
+ @param[in] Token Pointer to environment specific context used
+ to identify the component being measured.
+ @param[out] RecordType Type of FPDT record
+ @param[out] Identifier Identifier for FPDT records
+
+ @retval EFI_SUCCESS The data was converted correctly.
+ @retval EFI_NOT_FOUND No matched FPDT record is for the input Token.
+ @retval EFI_INVALID_PARAMETER Input Pointer is NULL.
+
+**/
+EFI_STATUS
+ConvertTokenToType (
+ IN BOOLEAN IsStart,
+ IN CONST CHAR8 *Token,
+ OUT UINTN *FpdtRecType,
+ OUT UINT32 *Identifier
+ )
+{
+ UINTN RecordType;
+
+ if (Token == NULL || FpdtRecType == NULL || Identifier == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RecordType = STRING_EVENT_TYPE;
+
+ //
+ // Token to Type and Id.
+ //
+ if (AsciiStrCmp (Token, START_IMAGE_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = MODULE_START_ID;
+ } else {
+ *Identifier = MODULE_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = MODULE_LOADIMAGE_START_ID;
+ } else {
+ *Identifier = MODULE_LOADIMAGE_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, DRIVERBINDING_START_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = MODULE_DRIVERBINDING_START_ID;
+ } else {
+ *Identifier = MODULE_DRIVERBINDING_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, DXE_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = DXE_START_ID;
+ } else {
+ *Identifier = DXE_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, DXE_CORE_DISP_INIT_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = DXE_CORE_DISP_START_ID;
+ } else {
+ *Identifier = DXE_CORE_DISP_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, COREDISPATCHER_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = COREDISPATCHER_START_ID;
+ } else {
+ *Identifier = COREDISPATCHER_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, BDS_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = BDS_START_ID;
+ } else {
+ *Identifier = BDS_END_ID;
+ }
+ } else if (IsStart && AsciiStrCmp (Token, BDS_ATTEMPT_TOK) == 0) {
+ RecordType = BDS_ATTEMPT_EVENT_TYPE;
+ } else if (IsStart && AsciiStrCmp (Token, SMM_MODULE_TOK) == 0) {
+ RecordType = RUNTIME_MODULE_TABLE_PTR_TYPE;
+ } else if (IsStart && AsciiStrCmp (Token, BOOT_MODULE_TOK) == 0) {
+ RecordType = BOOT_MODULE_TABLE_PTR_TYPE;
+ } else if (AsciiStrCmp (Token, EVENT_REC_TOK) == 0) {
+ RecordType = STRING_EVENT_TYPE;
+ } else if (IsStart && AsciiStrCmp (Token, PLATFORM_BOOT_TOK) == 0) {
+ RecordType = PLATFORM_BOOT_TABLE_PTR_TYPE;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ *FpdtRecType = RecordType;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Add performance log to FPDT boot record table.
+
+ @param[in] IsStart TRUE if the performance log is start log.
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] Ticker 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS Add FPDT boot record.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+ @retval EFI_ABORTED No matched FPDT record.
+
+**/
+EFI_STATUS
+InsertFpdtMeasurement (
+ IN BOOLEAN IsStart,
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 Ticker,
+ IN UINT32 Identifier
+ )
+{
+ EFI_GUID ModuleGuid;
+ CHAR8 ModuleName[STRING_EVENT_RECORD_NAME_LENGTH];
+ UINTN FpdtRecType;
+ EFI_STATUS Status;
+ FPDT_RECORD_PTR FpdtRecordPtr;
+ FPDT_RECORD FpdtRecord;
+ CHAR16 BootOptionStr[0x10];
+ UINT8 *BootOption;
+ EFI_DEVICE_PATH_PROTOCOL *BootDevice;
+ CHAR16 *BootString;
+ UINTN Length;
+ BDS_ATTEMPT_RECORD *BdsAttempRecordPtr;
+
+ //
+ // Convert performance log to FPDT record.
+ //
+ Status = ConvertTokenToType (IsStart, Token, &FpdtRecType, &Identifier);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mFpdtDataIsReport) {
+ //
+ // Cached FPDT data has been reported. Now, report FPDT record one by one.
+ //
+ FpdtRecordPtr.RecordHeader = &FpdtRecord.RecordHeader;
+ } else {
+ //
+ // Check if pre-allocated buffer is full
+ //
+ if (mPerformanceLength + sizeof (FPDT_RECORD) > mMaxPerformanceLength) {
+ mPerformancePointer = ReallocatePool (
+ mPerformanceLength,
+ mPerformanceLength + sizeof (FPDT_RECORD) + FIRMWARE_RECORD_BUFFER,
+ mPerformancePointer
+ );
+
+ ASSERT (mPerformancePointer != NULL);
+ mMaxPerformanceLength = mPerformanceLength + sizeof (FPDT_RECORD) + FIRMWARE_RECORD_BUFFER;
+ }
+
+ //
+ // Covert buffer to FPDT Ptr Union type.
+ //
+ FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *) (mPerformancePointer + mPerformanceLength);
+ }
+ FpdtRecordPtr.RecordHeader->Length = 0;
+
+ switch (FpdtRecType) {
+ case GUID_EVENT_TYPE:
+ case STRING_EVENT_TYPE:
+ //
+ // Get real ticker
+ //
+ if (Ticker == 0) {
+ Ticker = GetPerformanceCounter ();
+ }
+
+ //
+ // Get Module Guid and Name based on ImageHandle
+ //
+ GetModuleInfoFromHandle ((EFI_HANDLE) Handle, ModuleName, sizeof (ModuleName), &ModuleGuid);
+ if ((AsciiStrLen (ModuleName) != 0) || (Module != NULL && AsciiStrLen (Module) != 0)) {
+ //
+ // String Event Record
+ //
+ FpdtRecordPtr.StringEvent->Header.Type = STRING_EVENT_TYPE;
+ FpdtRecordPtr.StringEvent->Header.Length = sizeof (STRING_EVENT_RECORD);
+ FpdtRecordPtr.StringEvent->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.StringEvent->ProgressID = (UINT16) Identifier;
+ FpdtRecordPtr.StringEvent->ApicID = GetApicId ();
+ FpdtRecordPtr.StringEvent->Timestamp = GetTimeInNanoSecond (Ticker);
+ CopyMem (&FpdtRecordPtr.StringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.StringEvent->Guid));
+ if (AsciiStrLen (ModuleName) != 0) {
+ AsciiStrnCpyS (FpdtRecordPtr.StringEvent->NameString, sizeof (FpdtRecordPtr.StringEvent->NameString), ModuleName, AsciiStrLen (ModuleName));
+ } else {
+ AsciiStrnCpyS (FpdtRecordPtr.StringEvent->NameString, sizeof (FpdtRecordPtr.StringEvent->NameString), Module, AsciiStrLen (Module));
+ }
+ } else {
+ //
+ // GUID Event Record
+ //
+ FpdtRecordPtr.GuidEvent->Header.Type = GUID_EVENT_TYPE;
+ FpdtRecordPtr.GuidEvent->Header.Length = sizeof (GUID_EVENT_RECORD);
+ FpdtRecordPtr.GuidEvent->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.GuidEvent->ProgressID = (UINT16) Identifier;
+ FpdtRecordPtr.GuidEvent->ApicID = GetApicId ();
+ FpdtRecordPtr.GuidEvent->Timestamp = GetTimeInNanoSecond (Ticker);
+ CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid));
+ }
+ break;
+
+ case BDS_ATTEMPT_EVENT_TYPE:
+ //
+ // Identifier should be less than 0xFFFF, it will be recorded in "Boot####".
+ //
+ if (Identifier >= 0x10000) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get real ticker
+ //
+ if (Ticker == 0) {
+ Ticker = GetPerformanceCounter ();
+ }
+
+ //
+ // BDS Boot Attempt Record
+ //
+ FpdtRecordPtr.BdsAttempt->Header.Type = BDS_ATTEMPT_EVENT_TYPE;
+ FpdtRecordPtr.BdsAttempt->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.BdsAttempt->ApicID = GetApicId ();
+ FpdtRecordPtr.BdsAttempt->BdsAttemptNo = ++ mBdsAttemptNumber;
+ FpdtRecordPtr.BdsAttempt->Timestamp = GetTimeInNanoSecond (Ticker);
+ UnicodeSPrint (BootOptionStr, sizeof (BootOptionStr), L"Boot%04X", (UINT16) Identifier);
+ UnicodeStrToAsciiStr (BootOptionStr, (CHAR8 *) &FpdtRecordPtr.BdsAttempt->UEFIBootVar);
+ FpdtRecordPtr.BdsAttempt->DevicePathString[0] = 0;
+ FpdtRecordPtr.BdsAttempt->DevicePathString[1] = 0;
+ FpdtRecordPtr.BdsAttempt->Header.Length = sizeof (BDS_ATTEMPT_RECORD);
+
+ //
+ // DevicePath matches to Boot variable "Boot%04X"
+ // Get DevicePath, and convert it to text string by DevicePathToText protocol.
+ //
+
+ //
+ // Get DevicePathToText protocol first.
+ //
+ Status = EFI_SUCCESS;
+ if (mDevicePathToText == NULL) {
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathToTextProtocolGuid,
+ NULL,
+ (VOID **) &mDevicePathToText
+ );
+ }
+
+ //
+ // Get DevicePath that matches to Boot variable "Boot%04X"
+ //
+ if (!EFI_ERROR (Status) && mDevicePathToText != NULL) {
+ BootOption = GetEfiGlobalVariable (BootOptionStr);
+ if (BootOption != NULL) {
+ //
+ // Get BootDevice from LoadOption.
+ //
+ BootString = (CHAR16 *) (BootOption + sizeof (UINT32) + sizeof (UINT16));
+ BootDevice = (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) BootString + StrSize (BootString));
+ //
+ // Convert DevicePath to Text string.
+ //
+ BootString = mDevicePathToText->ConvertDevicePathToText (BootDevice, TRUE, FALSE);
+ FreePool (BootOption);
+ if (BootString != NULL) {
+ //
+ // Make Length is 4 byte alignment and less than 0x100
+ //
+ Length = (StrLen (BootString) + sizeof (BDS_ATTEMPT_RECORD) + 3) & ~3;
+ if (Length >= 0x100) {
+ Length = 0x100 - 4;
+ BootString[Length - sizeof (BDS_ATTEMPT_RECORD) + 1] = 0;
+ }
+
+ //
+ // Allocate BdsAttempRecord buffer.
+ //
+ BdsAttempRecordPtr = (BDS_ATTEMPT_RECORD *) AllocateZeroPool (Length);
+ ASSERT (BdsAttempRecordPtr != NULL);
+ CopyMem (BdsAttempRecordPtr, FpdtRecordPtr.BdsAttempt, sizeof (BDS_ATTEMPT_RECORD));
+
+ //
+ // Copy DevicePath string as ascii string into BdsAttempt record.
+ //
+ BdsAttempRecordPtr->Header.Length = (UINT8) Length;
+ UnicodeStrToAsciiStr (BootString, BdsAttempRecordPtr->DevicePathString);
+ FreePool (BootString);
+
+ //
+ // Report allocated BdsAttempt record
+ //
+ REPORT_STATUS_CODE_EX (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_DXE_BS_DRIVER,
+ 0,
+ NULL,
+ &gEfiFirmwarePerformanceGuid,
+ BdsAttempRecordPtr,
+ BdsAttempRecordPtr->Header.Length
+ );
+
+ //
+ // Free allocated memory.
+ //
+ FreePool (BdsAttempRecordPtr);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ break;
+
+ case BOOT_MODULE_TABLE_PTR_TYPE:
+ //
+ // Get Module Guid and Name based on ImageHandle
+ // Ticker is the table address of boot module pointer table.
+ //
+ GetModuleInfoFromHandle ((EFI_HANDLE) Handle, ModuleName, sizeof (ModuleName), &ModuleGuid);
+ FpdtRecordPtr.BootTablePtr->Header.Type = BOOT_MODULE_TABLE_PTR_TYPE;
+ FpdtRecordPtr.BootTablePtr->Header.Length = sizeof (BOOT_MODULE_PERFORMANCE_TABLE_POINTER_RECORD);
+ FpdtRecordPtr.BootTablePtr->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.BootTablePtr->PerformanceTablePointer = Ticker;
+ CopyGuid (&FpdtRecordPtr.BootTablePtr->Guid, &ModuleGuid);
+ break;
+
+ case PLATFORM_BOOT_TABLE_PTR_TYPE:
+ //
+ // Ticker is the table address of platform boot pointer table.
+ //
+ FpdtRecordPtr.PlatformBootTablePtr->Header.Type = PLATFORM_BOOT_TABLE_PTR_TYPE;
+ FpdtRecordPtr.PlatformBootTablePtr->Header.Length = sizeof (PLATFORM_BOOT_PERFORMANCE_TABLE_POINTER_RECORD);
+ FpdtRecordPtr.PlatformBootTablePtr->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.PlatformBootTablePtr->PerformanceTablePointer = Ticker;
+ break;
+
+ case RUNTIME_MODULE_TABLE_PTR_TYPE:
+ //
+ // Get Module Guid and Name based on ImageHandle
+ // Ticker is the table address of runtime module table.
+ //
+ GetModuleInfoFromHandle ((EFI_HANDLE) Handle, ModuleName, sizeof (ModuleName), &ModuleGuid);
+ FpdtRecordPtr.RuntimeTablePtr->Header.Type = RUNTIME_MODULE_TABLE_PTR_TYPE;
+ FpdtRecordPtr.RuntimeTablePtr->Header.Length = sizeof (RUNTIME_MODULE_PERFORMANCE_TABLE_POINTER_RECORD);
+ FpdtRecordPtr.RuntimeTablePtr->Header.Revision = RECORD_REVISION_1;
+ FpdtRecordPtr.RuntimeTablePtr->PerformanceTablePointer = Ticker;
+ CopyGuid (&FpdtRecordPtr.RuntimeTablePtr->Guid, &ModuleGuid);
+ break;
+
+ default:
+ //
+ // Record is undefined, return EFI_ABORTED
+ //
+ return EFI_ABORTED;
+ break;
+ }
+
+ //
+ // Report record one by one after records have been reported together.
+ //
+ if (mFpdtDataIsReport) {
+ REPORT_STATUS_CODE_EX (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_DXE_BS_DRIVER,
+ 0,
+ NULL,
+ &gEfiFirmwarePerformanceGuid,
+ FpdtRecordPtr.RecordHeader,
+ FpdtRecordPtr.RecordHeader->Length
+ );
+ } else {
+ //
+ // Update the cached FPDT record buffer.
+ //
+ mPerformanceLength += FpdtRecordPtr.RecordHeader->Length;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Dumps all the PEI performance .
+
+ This internal function dumps all the PEI performance log to the DXE performance gauge array.
+ It retrieves the optional GUID HOB for PEI performance and then saves the performance data
+ to DXE performance data structures.
+
+**/
+VOID
+InternalGetPeiPerformance (
+ VOID
+ )
+{
+ UINT32 Index;
+ PEI_FIRMWARE_PERFORMANCE_HOB *FirmwarePerformanceHob;
+ PEI_GUID_EVENT_RECORD *PeiGuidRec;
+ GUID_EVENT_RECORD *GuidEventRec;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gPeiFirmwarePerformanceGuid);
+ if (GuidHob != NULL) {
+ FirmwarePerformanceHob = GET_GUID_HOB_DATA (GuidHob);
+ if (mPerformanceLength + sizeof (GUID_EVENT_RECORD) * FirmwarePerformanceHob->NumberOfEntries > mMaxPerformanceLength) {
+ mPerformancePointer = ReallocatePool (
+ mPerformanceLength,
+ mPerformanceLength +
+ sizeof (GUID_EVENT_RECORD) * FirmwarePerformanceHob->NumberOfEntries +
+ FIRMWARE_RECORD_BUFFER,
+ mPerformancePointer
+ );
+
+ ASSERT (mPerformancePointer != NULL);
+ mMaxPerformanceLength = mPerformanceLength +
+ sizeof (GUID_EVENT_RECORD) * FirmwarePerformanceHob->NumberOfEntries +
+ FIRMWARE_RECORD_BUFFER;
+ }
+
+ GuidEventRec = (GUID_EVENT_RECORD *) (mPerformancePointer + mPerformanceLength);
+ for (Index = 0; Index < FirmwarePerformanceHob->NumberOfEntries; Index ++, GuidEventRec ++) {
+ PeiGuidRec = &(FirmwarePerformanceHob->GuidEventRecord[Index]);
+
+ //
+ // GUID Event Records from PEI phase
+ //
+ GuidEventRec->Header.Type = GUID_EVENT_TYPE;
+ GuidEventRec->Header.Length = sizeof (GUID_EVENT_RECORD);
+ GuidEventRec->Header.Revision = RECORD_REVISION_1;
+ GuidEventRec->ProgressID = PeiGuidRec->ProgressID;
+ GuidEventRec->ApicID = PeiGuidRec->ApicID;
+ GuidEventRec->Timestamp = PeiGuidRec->Timestamp;
+ GuidEventRec->Guid = PeiGuidRec->Guid;
+ }
+ //
+ // Update the used buffer size.
+ //
+ mPerformanceLength += sizeof (GUID_EVENT_RECORD) * FirmwarePerformanceHob->NumberOfEntries;
+ DEBUG ((DEBUG_INFO, "FPDT: Performance PEI Boot Performance Record Number is 0x%x\n", FirmwarePerformanceHob->NumberOfEntries));
+ }
+}
+
+
+/**
+ Report all FPDT record as report status code.
+
+ @param[in] Event The event of notify protocol.
+ @param[in] Context Notify event context.
+
+**/
+VOID
+EFIAPI
+ReportFpdtRecordData (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT8 *PerfBuffer;
+ UINTN MaxUint16;
+
+ PerfBuffer = mPerformancePointer;
+ MaxUint16 = 0xFFFF;
+
+ while (mPerformanceLength > MaxUint16) {
+ //
+ // Report extension data size is UINT16. So, the size of report data can't exceed 0xFFFF.
+ //
+ REPORT_STATUS_CODE_EX (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_DXE_BS_DRIVER,
+ 0,
+ NULL,
+ &gEfiFirmwarePerformanceGuid,
+ PerfBuffer,
+ MaxUint16
+ );
+ mPerformanceLength = mPerformanceLength - MaxUint16;
+ PerfBuffer = PerfBuffer + MaxUint16;
+ }
+
+ REPORT_STATUS_CODE_EX (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_DXE_BS_DRIVER,
+ 0,
+ NULL,
+ &gEfiFirmwarePerformanceGuid,
+ PerfBuffer,
+ mPerformanceLength
+ );
+
+ //
+ // Free Cached FPDT record Buffer
+ //
+ FreePool (mPerformancePointer);
+ mPerformanceLength = 0;
+ mMaxPerformanceLength = 0;
+
+ //
+ // Set FPDT report state to TRUE.
+ //
+ mFpdtDataIsReport = TRUE;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, Module and Identifier.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+EFI_STATUS
+EFIAPI
+StartGaugeEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
+ If the record can not be found then return EFI_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the found record
+ is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS The end of the measurement was recorded.
+ @retval EFI_NOT_FOUND The specified measurement record could not be found.
+
+**/
+EFI_STATUS
+EFIAPI
+EndGaugeEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Retrieves a previously logged performance measurement.
+ It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
+ and then assign the Identifier with 0.
+
+ Retrieves the performance log entry from the performance log specified by LogEntryKey.
+ If it stands for a valid entry, then EFI_SUCCESS is returned and
+ GaugeDataEntryEx stores the pointer to that entry.
+
+ @param[in] LogEntryKey The key for the previous performance measurement log entry.
+ If 0, then the first performance measurement log entry is retrieved.
+ @param[out] GaugeDataEntryEx The indirect pointer to the extended gauge data entry specified by LogEntryKey
+ if the retrieval is successful.
+
+ @retval EFI_SUCCESS The GuageDataEntryEx is successfully found based on LogEntryKey.
+ @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).
+ @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).
+ @retval EFI_INVALIDE_PARAMETER GaugeDataEntryEx is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetGaugeEx (
+ IN UINTN LogEntryKey,
+ OUT GAUGE_DATA_ENTRY_EX **GaugeDataEntryEx
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//
+// Interfaces for PerformanceEx Protocol.
+//
+PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {
+ StartGaugeEx,
+ EndGaugeEx,
+ GetGaugeEx
+ };
+
+
+/**
+ The constructor function initializes Performance infrastructure for DXE phase.
+
+ The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance
+ and merges PEI performance data to DXE performance log.
+ It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeCoreFpdtPerformanceLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_EVENT EndOfDxeEvent;
+
+ if (!PerformanceMeasurementEnabled ()) {
+ //
+ // Do not initialize performance infrastructure if not required.
+ //
+ return EFI_SUCCESS;
+ }
+
+ InternalGetPeiPerformance ();
+
+ //
+ // Install the protocol interfaces for DXE performance library instance.
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gPerformanceExProtocolGuid,
+ &mPerformanceExInterface,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register End of DXE event to report StatusCode data
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ ReportFpdtRecordData,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, Module and Identifier.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return (RETURN_STATUS) InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the found record
+ is same as the one found by EndPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return (RETURN_STATUS) InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
+ and then assign the Identifier with 0.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+ If Identifier is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance log entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+ @param[out] Identifier Pointer to the 32-bit identifier that was recorded when the measurement
+ was ended.
+
+ @return The key for the next performance log entry
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurementEx (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp,
+ OUT UINT32 *Identifier
+ )
+{
+ return 0;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, and Module.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return (RETURN_STATUS) InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, and Module and has an end time value of zero.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return (RETURN_STATUS) InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
+ and then eliminate the Identifier.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance log entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+
+ @return The key for the next performance log entry
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurement (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp
+ )
+{
+ return 0;
+}
+
+
+/**
+ Returns TRUE if the performance measurement macros are enabled.
+
+ This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set.
+ @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+PerformanceMeasurementEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.inf
new file mode 100644
index 0000000000..229c78de61
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeCoreFpdtPerformanceLib/DxeCoreFpdtPerformanceLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Performance library instance mainly for DxeCore usage.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxeCoreFpdtPerformanceLib
+ FILE_GUID = F7D43893-7E45-4F6A-8D09-D8071F3CC4BC
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_CORE
+ LIBRARY_CLASS = PerformanceLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = DxeCoreFpdtPerformanceLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PcdLib
+ TimerLib
+ HobLib
+ PrintLib
+ ReportStatusCodeLib
+ LocalApicLib
+ UefiLib
+ DxeServicesLib
+ PeCoffGetEntryPointLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask ## CONSUMES
+
+[Sources]
+ DxeCoreFpdtPerformanceLib.c
+
+[Protocols]
+ gEfiDevicePathToTextProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiFirmwarePerformanceGuid ## SOMETIMES_PRODUCES # StatusCode Data
+ gPeiFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## HOB
+ gPerformanceExProtocolGuid ## SOMETIMES_PRODUCES # Install Protocol Interfaces
+ gZeroGuid ## SOMETIMES_CONSUMES ## GUID
+ gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/DxeLogoLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/DxeLogoLib.inf
new file mode 100644
index 0000000000..6a2a7f9b0a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/DxeLogoLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Module that show progress bar and title above it.
+#
+# General BDS defines and produce general interfaces for platform BDS driver including:
+# 1) BDS boot policy interface;
+# 2) BDS boot device connect interface;
+# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxeLogoLib
+ FILE_GUID = F5AE5B5C-42E8-4A9B-829D-5B631CD5367A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = LogoLib|DXE_DRIVER UEFI_APPLICATION
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ UefiLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ PcdLib
+ DxeServicesLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[FeaturePcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
+
+[Sources]
+ Logo.c
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUserManagerProtocolGuid ## CONSUMES
+ gEfiOEMBadgingProtocolGuid ## CONSUMES
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/Logo.c b/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/Logo.c
new file mode 100644
index 0000000000..f8f7de3819
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeLogoLib/Logo.c
@@ -0,0 +1,856 @@
+/** @file
+ BDS Lib functions which contain all the code to connect console device.
+
+ Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/OEMBadging.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/BootLogo.h>
+
+
+/**
+ Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+ is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+ buffer is passed in it will be used if it is big enough.
+
+ @param[in] BmpImage Pointer to BMP file
+ @param[in] BmpImageSize Number of bytes in BmpImage
+ @param[in, out] GopBlt Buffer containing GOP version of BmpImage.
+ @param[in, out] GopBltSize Size of GopBlt in bytes.
+ @param[out] PixelHeight Height of GopBlt/BmpImage in pixels
+ @param[out] PixelWidth Width of GopBlt/BmpImage in pixels
+
+ @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
+ @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
+ @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
+ GopBltSize will contain the required size.
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
+
+**/
+EFI_STATUS
+ConvertBmpToGopBlt (
+ IN VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ IN OUT VOID **GopBlt,
+ IN OUT UINTN *GopBltSize,
+ OUT UINTN *PixelHeight,
+ OUT UINTN *PixelWidth
+ )
+{
+ UINT8 *Image;
+ UINT8 *ImageHeader;
+ BMP_IMAGE_HEADER *BmpHeader;
+ BMP_COLOR_MAP *BmpColorMap;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT64 BltBufferSize;
+ UINTN Index;
+ UINTN Height;
+ UINTN Width;
+ UINTN ImageIndex;
+ UINT32 DataSizePerLine;
+ BOOLEAN IsAllocated;
+ UINT32 ColorMapNum;
+
+ if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Doesn't support compress.
+ //
+ if (BmpHeader->CompressionType != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Only support BITMAPINFOHEADER format.
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+ //
+ if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // The data size in each line must be 4 byte alignment.
+ //
+ DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+ BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+ if (BltBufferSize > (UINT32) ~0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BmpHeader->Size != BmpImageSize) ||
+ (BmpHeader->Size < BmpHeader->ImageOffset) ||
+ (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate Color Map offset in the image.
+ //
+ Image = BmpImage;
+ BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+ if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ ColorMapNum = 2;
+ break;
+ case 4:
+ ColorMapNum = 16;
+ break;
+ case 8:
+ ColorMapNum = 256;
+ break;
+ default:
+ ColorMapNum = 0;
+ break;
+ }
+ //
+ // BMP file may has padding data between the bmp header section and the bmp data section.
+ //
+ if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Calculate graphics image data address in the image
+ //
+ Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+ ImageHeader = Image;
+
+ //
+ // Calculate the BltBuffer needed size.
+ //
+ BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+
+ //
+ // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+ BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ IsAllocated = FALSE;
+ if (*GopBlt == NULL) {
+ //
+ // GopBlt is not allocated by caller.
+ //
+ *GopBltSize = (UINTN) BltBufferSize;
+ *GopBlt = AllocatePool (*GopBltSize);
+ IsAllocated = TRUE;
+ if (*GopBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // GopBlt has been allocated by caller.
+ //
+ if (*GopBltSize < (UINTN) BltBufferSize) {
+ *GopBltSize = (UINTN) BltBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+
+ *PixelWidth = BmpHeader->PixelWidth;
+ *PixelHeight = BmpHeader->PixelHeight;
+
+ //
+ // Convert image from BMP to Blt buffer format
+ //
+ BltBuffer = *GopBlt;
+ for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+ Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+ for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ //
+ // Convert 1-bit (2 colors) BMP to 24-bit color
+ //
+ for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+ Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+ Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+ Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+ Blt++;
+ Width++;
+ }
+
+ Blt--;
+ Width--;
+ break;
+
+ case 4:
+ //
+ // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+ //
+ Index = (*Image) >> 4;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ if (Width < (BmpHeader->PixelWidth - 1)) {
+ Blt++;
+ Width++;
+ Index = (*Image) & 0x0f;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ }
+ break;
+
+ case 8:
+ //
+ // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+ //
+ Blt->Red = BmpColorMap[*Image].Red;
+ Blt->Green = BmpColorMap[*Image].Green;
+ Blt->Blue = BmpColorMap[*Image].Blue;
+ break;
+
+ case 24:
+ //
+ // It is 24-bit BMP.
+ //
+ Blt->Blue = *Image++;
+ Blt->Green = *Image++;
+ Blt->Red = *Image;
+ break;
+
+ default:
+ //
+ // Other bit format BMP is not supported.
+ //
+ if (IsAllocated) {
+ FreePool (*GopBlt);
+ *GopBlt = NULL;
+ }
+ return EFI_UNSUPPORTED;
+ break;
+ };
+
+ }
+
+ ImageIndex = (UINTN) (Image - ImageHeader);
+ if ((ImageIndex % 4) != 0) {
+ //
+ // Bmp Image starts each row on a 32-bit boundary!
+ //
+ Image = Image + (4 - (ImageIndex % 4));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Use SystemTable Conout to stop video based Simple Text Out consoles from going
+ to the video device. Put up LogoFile on every video device that is a console.
+
+ @param[in] LogoFile File name of logo to display on the center of the screen.
+
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
+ @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+EFIAPI
+EnableQuietBoot (
+ IN EFI_GUID *LogoFile
+ )
+{
+ EFI_STATUS Status;
+ EFI_OEM_BADGING_PROTOCOL *Badging;
+ UINT32 SizeOfX;
+ UINT32 SizeOfY;
+ INTN DestX;
+ INTN DestY;
+ UINT8 *ImageData;
+ UINTN ImageSize;
+ UINTN BltSize;
+ UINT32 Instance;
+ EFI_BADGING_FORMAT Format;
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+ UINTN CoordinateX;
+ UINTN CoordinateY;
+ UINTN Height;
+ UINTN Width;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_BOOT_LOGO_PROTOCOL *BootLogo;
+ UINTN NumberOfLogos;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
+ UINTN LogoDestX;
+ UINTN LogoDestY;
+ UINTN LogoHeight;
+ UINTN LogoWidth;
+ UINTN NewDestX;
+ UINTN NewDestY;
+ UINTN NewHeight;
+ UINTN NewWidth;
+ UINT64 BufferSize;
+
+ UgaDraw = NULL;
+ //
+ // Try to open GOP first
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ GraphicsOutput = NULL;
+ //
+ // Open GOP failed, try to open UGA
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
+ }
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Try to open Boot Logo Protocol.
+ //
+ BootLogo = NULL;
+ gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+
+ //
+ // Erase Cursor from screen
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+ Badging = NULL;
+ Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
+
+ if (GraphicsOutput != NULL) {
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ Blt = NULL;
+ NumberOfLogos = 0;
+ LogoDestX = 0;
+ LogoDestY = 0;
+ LogoHeight = 0;
+ LogoWidth = 0;
+ NewDestX = 0;
+ NewDestY = 0;
+ NewHeight = 0;
+ NewWidth = 0;
+ Instance = 0;
+ while (1) {
+ ImageData = NULL;
+ ImageSize = 0;
+
+ if (Badging != NULL) {
+ //
+ // Get image from OEMBadging protocol.
+ //
+ Status = Badging->GetImage (
+ Badging,
+ &Instance,
+ &Format,
+ &ImageData,
+ &ImageSize,
+ &Attribute,
+ &CoordinateX,
+ &CoordinateY
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ } else {
+ //
+ // Get the specified image from FV.
+ //
+ Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CoordinateX = 0;
+ CoordinateY = 0;
+ Attribute = EfiBadgingDisplayAttributeCenter;
+ }
+
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Try BMP decoder
+ //
+ Blt = NULL;
+ Status = ConvertBmpToGopBlt (
+ ImageData,
+ ImageSize,
+ (VOID **) &Blt,
+ &BltSize,
+ &Height,
+ &Width
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ return Status;
+ } else {
+ continue;
+ }
+ }
+
+ //
+ // Calculate the display position according to Attribute.
+ //
+ switch (Attribute) {
+ case EfiBadgingDisplayAttributeLeftTop:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterTop:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeRightTop:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = CoordinateY;;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterRight:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeRightBottom:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterBottom:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeLeftBottom:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterLeft:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeCenter:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ default:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+ }
+
+ if ((DestX >= 0) && (DestY >= 0)) {
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ Blt,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) Blt,
+ EfiUgaBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ //
+ // Report displayed Logo information.
+ //
+ if (!EFI_ERROR (Status)) {
+ NumberOfLogos++;
+
+ if (LogoWidth == 0) {
+ //
+ // The first Logo.
+ //
+ LogoDestX = (UINTN) DestX;
+ LogoDestY = (UINTN) DestY;
+ LogoWidth = Width;
+ LogoHeight = Height;
+ } else {
+ //
+ // Merge new logo with old one.
+ //
+ NewDestX = MIN ((UINTN) DestX, LogoDestX);
+ NewDestY = MIN ((UINTN) DestY, LogoDestY);
+ NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
+ NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;
+
+ LogoDestX = NewDestX;
+ LogoDestY = NewDestY;
+ LogoWidth = NewWidth;
+ LogoHeight = NewHeight;
+ }
+ }
+ }
+
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ break;
+ }
+ }
+
+Done:
+ if (BootLogo == NULL || NumberOfLogos == 0) {
+ //
+ // No logo displayed.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ return Status;
+ }
+
+ //
+ // Advertise displayed Logo information.
+ //
+ if (NumberOfLogos == 1) {
+ //
+ // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
+ //
+ LogoBlt = Blt;
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Ensure the LogoHeight * LogoWidth doesn't overflow
+ //
+ if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
+ return EFI_UNSUPPORTED;
+ }
+ BufferSize = MultU64x64 (LogoWidth, LogoHeight);
+
+ //
+ // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ LogoBlt = AllocateZeroPool ((UINTN) BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (LogoBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ LogoBlt,
+ EfiBltVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) LogoBlt,
+ EfiUgaVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
+ }
+ FreePool (LogoBlt);
+
+ return Status;
+}
+
+
+/**
+ Use SystemTable Conout to turn on video based Simple Text Out consoles. The
+ Simple Text Out screens will now be synced up with all non video output devices
+
+ @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableQuietBoot (
+ VOID
+ )
+{
+ //
+ // Enable Cursor on Screen
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Show progress bar with title above it. It only works in Graphics mode.
+
+ @param[in] TitleForeground Foreground color for Title.
+ @param[in] TitleBackground Background color for Title.
+ @param[in] Title Title above progress bar.
+ @param[in] ProgressColor Progress bar color.
+ @param[in] Progress Progress (0-100)
+ @param[in] PreviousValue The previous value of the progress.
+
+ @retval EFI_STATUS Success update the progress bar
+
+**/
+EFI_STATUS
+EFIAPI
+ShowProgress (
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+ IN CHAR16 *Title,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+ IN UINTN Progress,
+ IN UINTN PreviousValue
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ UINT32 SizeOfX;
+ UINT32 SizeOfY;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
+ UINTN BlockHeight;
+ UINTN BlockWidth;
+ UINTN BlockNum;
+ UINTN PosX;
+ UINTN PosY;
+ UINTN Index;
+
+ if (Progress > 100) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UgaDraw = NULL;
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **) &GraphicsOutput
+ );
+
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ GraphicsOutput = NULL;
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiUgaDrawProtocolGuid,
+ (VOID **) &UgaDraw
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SizeOfX = 0;
+ SizeOfY = 0;
+ if (GraphicsOutput != NULL) {
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+ } else if (UgaDraw != NULL) {
+ Status = UgaDraw->GetMode (
+ UgaDraw,
+ &SizeOfX,
+ &SizeOfY,
+ &ColorDepth,
+ &RefreshRate
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ BlockWidth = SizeOfX / 100;
+ BlockHeight = SizeOfY / 50;
+
+ BlockNum = Progress;
+
+ PosX = 0;
+ PosY = SizeOfY * 48 / 50;
+
+ if (BlockNum == 0) {
+ //
+ // Clear progress area
+ //
+ SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ &Color,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ 0,
+ PosY - EFI_GLYPH_HEIGHT - 1,
+ SizeOfX,
+ SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
+ SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+
+ } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) &Color,
+ EfiUgaVideoFill,
+ 0,
+ 0,
+ 0,
+ PosY - EFI_GLYPH_HEIGHT - 1,
+ SizeOfX,
+ SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
+ SizeOfX * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ //
+ // Show progress by drawing blocks
+ //
+ for (Index = PreviousValue; Index < BlockNum; Index++) {
+ PosX = Index * BlockWidth;
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ &ProgressColor,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ PosX,
+ PosY,
+ BlockWidth - 1,
+ BlockHeight,
+ (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+
+ } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) &ProgressColor,
+ EfiUgaVideoFill,
+ 0,
+ 0,
+ PosX,
+ PosY,
+ BlockWidth - 1,
+ BlockHeight,
+ (BlockWidth) * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ PrintXY (
+ (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
+ PosY - EFI_GLYPH_HEIGHT - 1,
+ &TitleForeground,
+ &TitleBackground,
+ Title
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
new file mode 100644
index 0000000000..8002c068bc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Module Infomation file for DxePolicyUpdateLib Library.
+#
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxePolicyUpdateLib
+ FILE_GUID = D8E9897A-5B25-4f90-A8FA-93131D2FA6A1
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = DxePolicyUpdateLib
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+ ConfigBlockLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Sources]
+ DxeSaPolicyUpdate.c
+
+[Protocols]
+ gPlatformGOPPolicyGuid
+ gIgdPanelConfigGuid
+ gSaDxeMiscConfigGuid
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiNormalSetupGuid
+ gVbtInfoGuid
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
new file mode 100644
index 0000000000..4fa42747ea
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
@@ -0,0 +1,101 @@
+/** @file
+ This file is the library for SA DXE Policy initialzation.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <DxeSaPolicyUpdate.h>
+
+
+/**
+ Get data for platform policy from setup options.
+
+ @param[in] DxeSaPolicy The pointer to get SA Policy protocol instance
+ @param[in] SystemConfiguration The pointer to get System Setup
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+ IN OUT SA_POLICY_PROTOCOL *SaPolicy,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+#if defined (ENBDT_PF_ENABLE) && (ENBDT_PF_ENABLE == 1) // For ApolloLake
+ PLATFORM_GOP_POLICY_PROTOCOL *GopPolicy;
+ VBT_INFO *VbtInfo = NULL;
+ EFI_PHYSICAL_ADDRESS VbtAddress;
+ UINT32 Size;
+ EFI_PEI_HOB_POINTERS GuidHob;
+#endif
+ EFI_STATUS Status;
+ SA_DXE_MISC_CONFIG *SaDxeMiscConfig = NULL;
+ IGD_PANEL_CONFIG *IgdPanelConfig = NULL;
+
+ DEBUG ((DEBUG_INFO, "UpdateDxeSaPolicy\n"));
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SaPolicy, &gIgdPanelConfigGuid, (VOID *) &IgdPanelConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SaPolicy, &gSaDxeMiscConfigGuid, (VOID *) &SaDxeMiscConfig);
+ ASSERT_EFI_ERROR (Status);
+#if defined (ENBDT_PF_ENABLE) && (ENBDT_PF_ENABLE == 1) // For ApolloLake
+ DEBUG ((DEBUG_INFO, "Locate GopPolicy and GetVbtData\n"));
+
+ //
+ // Locate the GOP Policy Protocol.
+ //
+ GopPolicy = NULL;
+ Status = gBS->LocateProtocol (
+ &gPlatformGOPPolicyGuid,
+ NULL,
+ &GopPolicy
+ );
+
+ if (EFI_ERROR (Status) || (GopPolicy == NULL)) {
+ return Status;
+ }
+
+ //
+ // Get VBT data
+ //
+ VbtAddress = 0;
+ Size = 0;
+ DEBUG ((DEBUG_INFO, "GetVbtData\n"));
+ Status = GopPolicy->GetVbtData (&VbtAddress, &Size);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GuidHob.Raw = GetHobList ();
+ if (GuidHob.Raw != NULL) {
+ if ((GuidHob.Raw = GetNextGuidHob (&gVbtInfoGuid, GuidHob.Raw)) != NULL) {
+ VbtInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
+ VbtInfo->VbtAddress = VbtAddress;
+ VbtInfo->VbtSize = Size;
+ Status = EFI_SUCCESS;
+ }
+ } else {
+ Status = EFI_NOT_FOUND;
+ return Status;
+ }
+#endif
+
+ IgdPanelConfig->PFITStatus = SystemConfiguration->PanelScaling;
+ SaDxeMiscConfig->S0ixSupported = SystemConfiguration->LowPowerS0Idle;
+ IgdPanelConfig->PanelSelect = SystemConfiguration->VbtSelect;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
new file mode 100644
index 0000000000..d83df4aef9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
@@ -0,0 +1,40 @@
+/** @file
+ Header file for SA DXE Policy initialzation.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_H_
+#define _DXE_SA_POLICY_UPDATE_H_
+
+#include <PiDxe.h>
+#include <CpuRegs.h>
+#include <Guid/SaDataHob.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/MmPciLib.h>
+
+#if defined (ENBDT_PF_ENABLE) && (ENBDT_PF_ENABLE == 1) // For ApolloLake
+#include <Protocol/PlatformGopPolicy.h>
+#endif
+
+#include <Library/ConfigBlockLib.h>
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.c b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.c
new file mode 100644
index 0000000000..f182c8d90e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.c
@@ -0,0 +1,492 @@
+/** @file
+ Smbios Processor Information Driver which produces Smbios type 4 and 7 tables.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <SmbiosCacheInfoHob.h>
+#include <SmbiosProcessorInfoHob.h>
+#include <DxeSmbiosProcessorLib.h>
+
+#define MAX_PROCESSOR_SOCKET_SUPPORTED 8
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMBIOS_HANDLE mSmbiosHandleArray[MAX_PROCESSOR_SOCKET_SUPPORTED][3];
+
+//
+// Cache Information (Type 7)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SMBIOS_TABLE_TYPE7 SmbiosTableType7Data = {
+ { EFI_SMBIOS_TYPE_CACHE_INFORMATION, sizeof (SMBIOS_TABLE_TYPE7), 0 },
+ TO_BE_FILLED, ///< SocketDesignation
+ TO_BE_FILLED, ///< CacheConfiguration
+ TO_BE_FILLED, ///< MaximumCacheSize
+ TO_BE_FILLED, ///< InstalledSize
+ { ///< SupportedSRAMType
+ TO_BE_FILLED, ///< Other :1;
+ TO_BE_FILLED, ///< Unknown :1;
+ TO_BE_FILLED, ///< NonBurst :1;
+ TO_BE_FILLED, ///< Burst :1;
+ TO_BE_FILLED, ///< PipelineBurst :1;
+ TO_BE_FILLED, ///< Synchronous :1;
+ TO_BE_FILLED, ///< Asynchronous :1;
+ TO_BE_FILLED, ///< Reserved :9;
+ },
+ { ///< CurrentSRAMType
+ TO_BE_FILLED, ///< Other :1;
+ TO_BE_FILLED, ///< Unknown :1;
+ TO_BE_FILLED, ///< NonBurst :1;
+ TO_BE_FILLED, ///< Burst :1;
+ TO_BE_FILLED, ///< PipelineBurst :1;
+ TO_BE_FILLED, ///< Synchronous :1;
+ TO_BE_FILLED, ///< Asynchronous :1;
+ TO_BE_FILLED, ///< Reserved :9;
+ },
+ TO_BE_FILLED, ///< CacheSpeed
+ TO_BE_FILLED, ///< ErrorCorrectionType
+ TO_BE_FILLED, ///< SystemCacheType
+ TO_BE_FILLED, ///< Associativity
+};
+
+//
+// Processor Information (Type 4)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SMBIOS_TABLE_TYPE4 SmbiosTableType4Data = {
+ { EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE4), 0 },
+ TO_BE_FILLED, ///< Socket
+ TO_BE_FILLED, ///< ProcessorType
+ TO_BE_FILLED, ///< ProcessorFamily
+ TO_BE_FILLED, ///< ProcessorManufacture
+ { ///< ProcessorId
+ { TO_BE_FILLED },
+ { TO_BE_FILLED }
+ },
+ TO_BE_FILLED, ///< ProcessorVersion
+ { TO_BE_FILLED }, ///< Voltage
+ TO_BE_FILLED, ///< ExternalClock
+ TO_BE_FILLED, ///< MaxSpeed
+ TO_BE_FILLED, ///< CurrentSpeed
+ TO_BE_FILLED, ///< Status
+ TO_BE_FILLED, ///< ProcessorUpgrade
+ TO_BE_FILLED, ///< L1CacheHandle
+ TO_BE_FILLED, ///< L2CacheHandle
+ TO_BE_FILLED, ///< L3CacheHandle
+ TO_BE_FILLED, ///< SerialNumber
+ TO_BE_FILLED, ///< AssetTag
+ TO_BE_FILLED, ///< PartNumber
+ TO_BE_FILLED, ///< CoreCount
+ TO_BE_FILLED, ///< EnabledCoreCount
+ TO_BE_FILLED, ///< ThreadCount
+ TO_BE_FILLED, ///< ProcessorCharacteristics
+ TO_BE_FILLED, ///< ProcessorFamily2
+ TO_BE_FILLED, ///< CoreCount2
+ TO_BE_FILLED, ///< EnabledCoreCount2
+ TO_BE_FILLED, ///< ThreadCount2
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED SMBIOS_TYPE4_STRING_ARRAY SmbiosTableType4Strings = {
+ TO_BE_FILLED_STRING, ///< Socket
+ TO_BE_FILLED_STRING, ///< ProcessorManufacture
+ TO_BE_FILLED_STRING, ///< ProcessorVersion
+ TO_BE_FILLED_STRING, ///< SerialNumber
+ TO_BE_FILLED_STRING, ///< AssetTag
+ TO_BE_FILLED_STRING, ///< PartNumber
+};
+
+/**
+ Assigns the next string number in sequence, or 0 if string is null or empty.
+
+ @param[in] String The string pointer.
+ @param[in, out] StringNumber Pointer to the prior string number in sequence.
+
+ @retval StringNumber The next string number in sequence, or 0 if string is null or empty.
+
+**/
+UINT8
+AssignStringNumber (
+ IN CHAR8 *String,
+ IN OUT UINT8 *StringNumber
+ )
+{
+ if ((String == NULL) || (*String == '\0')) {
+ return NO_STRING_AVAILABLE;
+ } else {
+ *StringNumber = *StringNumber + 1;
+ return *StringNumber;
+ }
+}
+
+
+/**
+ Add an SMBIOS table entry using EFI_SMBIOS_PROTOCOL.
+ Create the full table record using the formatted section plus each non-null string, plus the terminating (double) null.
+
+ @param[in] Entry The data for the fixed portion of the SMBIOS entry.
+ The format of the data is determined by EFI_SMBIOS_TABLE_HEADER.
+ Type. The size of the formatted area is defined by
+ EFI_SMBIOS_TABLE_HEADER. Length and either followed by a
+ double-null (0x0000) or a set of null terminated strings and a null.
+ @param[in] TableStrings Set of string pointers to append onto the full record.
+ If TableStrings is null, no strings are appended. Null strings
+ are skipped.
+ @param[in] NumberOfStrings Number of TableStrings to append, null strings are skipped.
+ @param[in] SmbiosProtocol Instance of Smbios Protocol
+ @param[out] SmbiosHandle A unique handle will be assigned to the SMBIOS record.
+
+ @retval EFI_SUCCESS Table was added.
+ @retval EFI_OUT_OF_RESOURCES Table was not added due to lack of system resources.
+**/
+EFI_STATUS
+AddSmbiosTableEntry (
+ IN EFI_SMBIOS_TABLE_HEADER *Entry,
+ IN CHAR8 **TableStrings,
+ IN UINT8 NumberOfStrings,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ OUT EFI_SMBIOS_HANDLE *SmbiosHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_TABLE_HEADER *Record;
+ CHAR8 *StringPtr;
+ UINTN Size;
+ UINTN Index;
+
+ //
+ // Calculate the total size of the full record
+ //
+ Size = Entry->Length;
+
+ //
+ // Add the size of each non-null string
+ //
+ if (TableStrings != NULL) {
+ for (Index = 0; Index < NumberOfStrings; Index++) {
+ if ((TableStrings[Index] != NULL) && (*TableStrings[Index] != '\0')) {
+ Size += AsciiStrSize (TableStrings[Index]);
+ }
+ }
+ }
+
+ //
+ // Add the size of the terminating double null
+ // If there were any strings added, just add the second null
+ //
+ if (Size == Entry->Length) {
+ Size += 2;
+ } else {
+ Size += 1;
+ }
+
+ //
+ // Initialize the full record
+ //
+ Record = (EFI_SMBIOS_TABLE_HEADER *) AllocateZeroPool(Size);
+ if (Record == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (Record, Entry, Entry->Length);
+
+ //
+ // Copy the strings to the end of the record
+ //
+ StringPtr = ((CHAR8 *) Record) + Entry->Length;
+ if (TableStrings != NULL) {
+ for (Index = 0; Index < NumberOfStrings; Index++) {
+ if ((TableStrings[Index] != NULL) && (*TableStrings[Index] != '\0')) {
+ AsciiStrCpyS (StringPtr, Size - Entry->Length - 1, TableStrings[Index]);
+ StringPtr += AsciiStrSize (TableStrings[Index]);
+ Size -= AsciiStrSize (TableStrings[Index]);
+ }
+ }
+ }
+
+ *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = SmbiosProtocol->Add (SmbiosProtocol, NULL, SmbiosHandle, Record);
+
+ FreePool (Record);
+ return Status;
+}
+
+
+/**
+ Installs the SMBIOS Cache Information type SMBIOS table based on the SMBIOS_CACHE_INFO
+
+ @retval EFI_UNSUPPORTED Could not locate SMBIOS protocol
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for SMBIOS Cache Information type.
+ @retval EFI_SUCCESS Successfully installed SMBIOS Cache Information type.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallSmbiosCacheInfo (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_PEI_HOB_POINTERS Hob;
+ SMBIOS_CACHE_INFO *CacheInfo;
+ UINT8 *HobStringBufferPtr;
+ UINTN StringBufferLength;
+ SMBIOS_TABLE_TYPE7 *SmbiosType7Record;
+ UINT8 *SmbiosStringBufferPtr;
+ UINT8 CacheLevel;
+
+ DEBUG ((DEBUG_INFO, "InstallSmbiosProcessorInfo(): Install SMBIOS Cache Information Type.\n"));
+
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &SmbiosProtocol);
+ if (SmbiosProtocol == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get Cache Information HOB
+ //
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_GUID_EXTENSION) && (CompareGuid (&Hob.Guid->Name, &gSmbiosCacheInfoHobGuid))) {
+
+ CacheInfo = (SMBIOS_CACHE_INFO *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
+ HobStringBufferPtr = Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID) + sizeof (SMBIOS_CACHE_INFO);
+ StringBufferLength = Hob.Header->HobLength - (sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID) + sizeof (SMBIOS_CACHE_INFO));
+
+ if (CacheInfo->ProcessorSocketNumber >= MAX_PROCESSOR_SOCKET_SUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "Error creating SMBIOS table Type 7. Socket number exceed limit\n"));
+ continue;
+ }
+
+ //
+ // Allocate full record, including fixed data region, and string buffer region.
+ //
+ SmbiosType7Record = (SMBIOS_TABLE_TYPE7 *) AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE7) + StringBufferLength);
+ SmbiosStringBufferPtr = ((UINT8 *) SmbiosType7Record) + sizeof (SMBIOS_TABLE_TYPE7);
+
+ //
+ // Initialize the Header
+ //
+ SmbiosType7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+ SmbiosType7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
+ SmbiosType7Record->Hdr.Handle = 0;
+
+ //
+ // Initialize fixed data region from HOB
+ //
+ SmbiosType7Record->SocketDesignation = CacheInfo->SocketDesignationStrIndex;
+ SmbiosType7Record->CacheConfiguration = CacheInfo->CacheConfiguration;
+ SmbiosType7Record->MaximumCacheSize = CacheInfo->MaxCacheSize;
+ SmbiosType7Record->InstalledSize = CacheInfo->InstalledSize;
+ *(UINT16 *) &SmbiosType7Record->SupportedSRAMType = CacheInfo->SupportedSramType;
+ *(UINT16 *) &SmbiosType7Record->CurrentSRAMType = CacheInfo->CurrentSramType;
+ SmbiosType7Record->CacheSpeed = CacheInfo->CacheSpeed;
+ SmbiosType7Record->ErrorCorrectionType = CacheInfo->ErrorCorrectionType;
+ SmbiosType7Record->SystemCacheType = CacheInfo->SystemCacheType;
+ SmbiosType7Record->Associativity = CacheInfo->Associativity;
+
+ //
+ // Initialize string buffer region
+ //
+ CopyMem (SmbiosStringBufferPtr, HobStringBufferPtr, StringBufferLength);
+
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = SmbiosProtocol->Add (SmbiosProtocol, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosType7Record);
+
+ FreePool (SmbiosType7Record);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error adding SMBIOS table Type 7. Status = %r\n", Status));
+ return Status;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Adding SMBIOS table Type 7 successfully.\n"));
+ }
+
+ CacheLevel = (UINT8) (CacheInfo->CacheConfiguration & 0x7);
+ mSmbiosHandleArray[CacheInfo->ProcessorSocketNumber][CacheLevel] = SmbiosHandle;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Installs the SMBIOS Processor Information type SMBIOS table based on the SMBIOS_PROCESSOR_INFO
+
+ @retval EFI_UNSUPPORTED Could not locate SMBIOS protocol
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for SMBIOS Processor Information type.
+ @retval EFI_SUCCESS Successfully installed SMBIOS Processor Information type.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallSmbiosProcessorInfo (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+ EFI_STATUS Status;
+ SMBIOS_PROCESSOR_INFO *ProcessorInfo;
+ UINT8 StringNumber;
+ UINTN String1Size;
+
+ Status = EFI_SUCCESS;
+ StringNumber = 0;
+
+ DEBUG ((DEBUG_INFO, "InstallSmbiosProcessorInfo(): Install SMBIOS Processor Information Type.\n"));
+
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &SmbiosProtocol);
+ if (SmbiosProtocol == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get Processor Information HOB
+ //
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_GUID_EXTENSION) && (CompareGuid (&Hob.Guid->Name, &gSmbiosProcessorInfoHobGuid))) {
+
+ ProcessorInfo = (SMBIOS_PROCESSOR_INFO *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
+
+ if (ProcessorInfo->CurrentSocketNumber >= MAX_PROCESSOR_SOCKET_SUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "Error creating SMBIOS table Type 4. Socket number exceed limit\n"));
+ continue;
+ }
+
+ SmbiosTableType4Strings.Socket = (CHAR8 *) PcdGetPtr (PcdSmbiosDefaultSocketDesignation);
+ SmbiosTableType4Data.Socket = AssignStringNumber (SmbiosTableType4Strings.Socket, &StringNumber);
+
+ SmbiosTableType4Data.ProcessorType = ProcessorInfo->ProcessorType;
+ //
+ // Fix this to use correct algorithm
+ //
+ SmbiosTableType4Data.ProcessorFamily = (UINT8) ProcessorInfo->ProcessorFamily;
+
+ if (ProcessorInfo->ProcessorManufacturerStrIndex == 1) {
+ SmbiosTableType4Strings.ProcessorManufacture = (CHAR8 *) (ProcessorInfo + 1);
+ SmbiosTableType4Data.ProcessorManufacture = AssignStringNumber (SmbiosTableType4Strings.ProcessorManufacture, &StringNumber);
+
+ String1Size = AsciiStrSize ((CHAR8 *) (ProcessorInfo + 1)); // Size includes the trailing /0
+ SmbiosTableType4Strings.ProcessorVersion = (CHAR8 *) (SmbiosTableType4Strings.ProcessorManufacture + String1Size);
+ SmbiosTableType4Data.ProcessorVersion = AssignStringNumber (SmbiosTableType4Strings.ProcessorVersion, &StringNumber);
+ } else if (ProcessorInfo->ProcessorVersionStrIndex == 1) {
+ SmbiosTableType4Strings.ProcessorVersion = (CHAR8 *) (ProcessorInfo + 1);
+ SmbiosTableType4Data.ProcessorVersion = AssignStringNumber (SmbiosTableType4Strings.ProcessorVersion, &StringNumber);
+
+ String1Size = AsciiStrSize ((CHAR8 *) (ProcessorInfo + 1)); // Size includes the trailing /0
+ SmbiosTableType4Strings.ProcessorManufacture = (CHAR8 *) (SmbiosTableType4Strings.ProcessorVersion + String1Size);
+ SmbiosTableType4Data.ProcessorManufacture = AssignStringNumber (SmbiosTableType4Strings.ProcessorManufacture, &StringNumber);
+ } else {
+ SmbiosTableType4Strings.ProcessorManufacture = NULL;
+ SmbiosTableType4Data.ProcessorManufacture = 0;
+ SmbiosTableType4Strings.ProcessorVersion = NULL;
+ SmbiosTableType4Data.ProcessorVersion = 0;
+ }
+
+ *(UINT64 *) &SmbiosTableType4Data.ProcessorId = ProcessorInfo->ProcessorId;
+
+ *(UINT8 *) &SmbiosTableType4Data.Voltage = ProcessorInfo->Voltage;
+
+ SmbiosTableType4Data.ExternalClock = ProcessorInfo->ExternalClockInMHz;
+
+ SmbiosTableType4Data.MaxSpeed = PcdGet16 (PcdSmbiosDefaultMaxSpeed);
+
+ SmbiosTableType4Data.CurrentSpeed = ProcessorInfo->CurrentSpeedInMHz;
+
+ SmbiosTableType4Data.Status = ProcessorInfo->Status;
+
+ SmbiosTableType4Data.ProcessorUpgrade = ProcessorInfo->ProcessorUpgrade;
+
+ SmbiosTableType4Data.L1CacheHandle = mSmbiosHandleArray[ProcessorInfo->CurrentSocketNumber][0];
+ SmbiosTableType4Data.L2CacheHandle = mSmbiosHandleArray[ProcessorInfo->CurrentSocketNumber][1];
+ SmbiosTableType4Data.L3CacheHandle = mSmbiosHandleArray[ProcessorInfo->CurrentSocketNumber][2];
+
+ SmbiosTableType4Strings.SerialNumber = (CHAR8 *) PcdGetPtr (PcdSmbiosDefaultSerialNumber);
+ SmbiosTableType4Data.SerialNumber = AssignStringNumber (SmbiosTableType4Strings.SerialNumber, &StringNumber);
+ SmbiosTableType4Strings.AssetTag = (CHAR8 *) PcdGetPtr (PcdSmbiosDefaultAssetTag);
+ SmbiosTableType4Data.AssetTag = AssignStringNumber (SmbiosTableType4Strings.AssetTag, &StringNumber);
+ SmbiosTableType4Strings.PartNumber = (CHAR8 *) PcdGetPtr (PcdSmbiosDefaultPartNumber);
+ SmbiosTableType4Data.PartNumber = AssignStringNumber (SmbiosTableType4Strings.PartNumber, &StringNumber);
+
+ //
+ // Fix this to use correct algorithm
+ //
+ SmbiosTableType4Data.CoreCount = (UINT8) ProcessorInfo->CoreCount;
+ SmbiosTableType4Data.EnabledCoreCount = (UINT8) ProcessorInfo->EnabledCoreCount;
+ SmbiosTableType4Data.ThreadCount = (UINT8) ProcessorInfo->ThreadCount;
+
+ SmbiosTableType4Data.ProcessorCharacteristics = ProcessorInfo->ProcessorCharacteristics;
+
+ SmbiosTableType4Data.ProcessorFamily2 = ProcessorInfo->ProcessorFamily;
+ SmbiosTableType4Data.CoreCount2 = ProcessorInfo->CoreCount;
+ SmbiosTableType4Data.EnabledCoreCount2 = ProcessorInfo->EnabledCoreCount;
+ SmbiosTableType4Data.ThreadCount2 = ProcessorInfo->ThreadCount;
+
+ Status = AddSmbiosTableEntry (
+ (EFI_SMBIOS_TABLE_HEADER *) &SmbiosTableType4Data,
+ (CHAR8 **) &SmbiosTableType4Strings,
+ SMBIOS_TYPE4_NUMBER_OF_STRINGS,
+ SmbiosProtocol,
+ &SmbiosHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error adding SMBIOS table Type 4. Status = %r\n", Status));
+ } else {
+ DEBUG ((DEBUG_ERROR, "Adding SMBIOS table Type 4 successfully.\n"));
+ }
+
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Add Smbios Cache information (type 7) table and Processor information (type 4) table
+ using the HOB info from Silicon.
+
+ It installs Smbios type 4 and type 7 tables.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+AddSmbiosProcessorAndCacheTables (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Index1, Index2;
+
+ for (Index1 = 0; Index1 < MAX_PROCESSOR_SOCKET_SUPPORTED; Index1++) {
+ for (Index2 = 0; Index2 < 3; Index2++) {
+ mSmbiosHandleArray[Index1][Index2] = 0;
+ }
+ }
+
+ Status = InstallSmbiosCacheInfo ();
+
+ Status = InstallSmbiosProcessorInfo ();
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.h b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.h
new file mode 100644
index 0000000000..a334d56c1f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.h
@@ -0,0 +1,51 @@
+/** @file
+ Header file for SMBIOS related functions.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DXE_SMBIOS_PROCESSOR_LIB_H_
+#define _DXE_SMBIOS_PROCESSOR_LIB_H_
+
+//
+// Non-static SMBIOS table data to be filled later with a dynamically generated value
+//
+#define TO_BE_FILLED 0
+#define TO_BE_FILLED_STRING " " ///< Initial value should not be NULL
+
+//
+// String references in SMBIOS tables. This eliminates the need for pointers. See spec for details.
+//
+#define NO_STRING_AVAILABLE 0
+#define STRING_1 1
+#define STRING_2 2
+#define STRING_3 3
+#define STRING_4 4
+#define STRING_5 5
+#define STRING_6 6
+#define STRING_7 7
+
+#pragma pack(1)
+typedef struct {
+ CHAR8 *Socket;
+ CHAR8 *ProcessorManufacture;
+ CHAR8 *ProcessorVersion;
+ CHAR8 *SerialNumber;
+ CHAR8 *AssetTag;
+ CHAR8 *PartNumber;
+} SMBIOS_TYPE4_STRING_ARRAY;
+
+#define SMBIOS_TYPE4_NUMBER_OF_STRINGS 6
+#pragma pack()
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.inf
new file mode 100644
index 0000000000..a387018a9f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/DxeSmbiosProcessorLib/DxeSmbiosProcessorLib.inf
@@ -0,0 +1,55 @@
+## @file
+# Smbios Processor Information Driver which produces Smbios type 4 and 7 tables.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxeSmbiosProcessorLib
+ FILE_GUID = 5F59B483-73A4-4507-AC11-A1D26EFA187B
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = DxeSmbiosProcessorLib
+
+[LibraryClasses]
+ DebugLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ BaseLib
+ HobLib
+ UefiLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ DxeSmbiosProcessorLib.c
+
+[Guids]
+ gSmbiosProcessorInfoHobGuid ## CONSUMES
+ gSmbiosCacheInfoHobGuid ## CONSUMES
+
+[Protocols]
+ gEfiSmbiosProtocolGuid ## CONSUMES
+
+[Pcd]
+ gClientCommonModuleTokenSpaceGuid.PcdSmbiosDefaultMaxSpeed
+ gClientCommonModuleTokenSpaceGuid.PcdSmbiosDefaultSocketDesignation
+ gClientCommonModuleTokenSpaceGuid.PcdSmbiosDefaultSerialNumber
+ gClientCommonModuleTokenSpaceGuid.PcdSmbiosDefaultAssetTag
+ gClientCommonModuleTokenSpaceGuid.PcdSmbiosDefaultPartNumber
+
+[Depex]
+ gEfiSmbiosProtocolGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.c b/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.c
new file mode 100644
index 0000000000..1d312e2c8c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.c
@@ -0,0 +1,269 @@
+/** @file
+ Lib function for table driven register initialization.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/EfiRegTableLib.h>
+#include <Library/S3BootScriptLib.h>
+
+
+/**
+ Local worker function to process PCI_WRITE table entries. Performs write and
+ may also call BootScriptSave protocol if indicated in the Entry flags
+
+ @param[in] Entry A pointer to the PCI_WRITE entry to process
+ @param[in] PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+ @retval Nothing.
+
+**/
+STATIC
+VOID
+PciWrite (
+ EFI_REG_TABLE_PCI_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &Entry->Data
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = S3BootScriptSavePciCfgWrite (
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &Entry->Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+
+/**
+ Local worker function to process PCI_READ_MODIFY_WRITE table entries.
+ Performs RMW write and may also call BootScriptSave protocol if indicated in
+ the Entry flags.
+
+ @param[in] Entry A pointer to the PCI_READ_MODIFY_WRITE entry to process.
+
+ @param[in] PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+ @retval Nothing.
+
+**/
+STATIC
+VOID
+PciReadModifyWrite (
+ EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TempData;
+
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Entry->OrMask &= Entry->AndMask;
+ TempData &= ~Entry->AndMask;
+ TempData |= Entry->OrMask;
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = S3BootScriptSavePciCfgReadWrite (
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ &Entry->OrMask,
+ &Entry->AndMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+
+/**
+ Local worker function to process MEM_READ_MODIFY_WRITE table entries.
+ Performs RMW write and may also call BootScriptSave protocol if indicated in
+ the Entry flags.
+
+ @param[in] Entry A pointer to the MEM_READ_MODIFY_WRITE entry to process.
+ @param[in] PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+ @retval Nothing.
+
+**/
+STATIC
+VOID
+MemReadModifyWrite (
+ EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TempData;
+
+ Status = PciRootBridgeIo->Mem.Read (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->MemAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Entry->OrMask &= Entry->AndMask;
+ TempData &= ~Entry->AndMask;
+ TempData |= Entry->OrMask;
+
+ Status = PciRootBridgeIo->Mem.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->MemAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = S3BootScriptSaveMemReadWrite (
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ Entry->MemAddress,
+ &Entry->OrMask,
+ &Entry->AndMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+
+/**
+ Processes register table assuming which may contain PCI, IO, MEM, and STALL
+ entries.
+
+ No parameter checking is done so the caller must be careful about omitting
+ values for PciRootBridgeIo or CpuIo parameters. If the regtable does
+ not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
+ NULL). If the regtable does not contain any IO or Mem entries, it is safe to
+ omit the CpuIo (supply NULL).
+
+ The RegTableEntry parameter is not checked, but is required.
+
+ gBS is assumed to have been defined and is used when processing stalls.
+
+ The function processes each entry sequentially until an OP_TERMINATE_TABLE
+ entry is encountered.
+
+ @param[in] RegTableEntry A pointer to the register table to process
+ @param[in] PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
+ when processing PCI table entries
+ @param[in] CpuIo A pointer to the instance of CpuIo that is used when processing IO and
+ MEM table entries
+
+ @retval Nothing.
+
+**/
+VOID
+ProcessRegTablePci (
+ EFI_REG_TABLE *RegTableEntry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ EFI_CPU_IO2_PROTOCOL *CpuIo
+ )
+{
+ while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+ switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+ case OP_PCI_WRITE:
+ PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ case OP_PCI_READ_MODIFY_WRITE:
+ PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ case OP_MEM_READ_MODIFY_WRITE:
+ MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+ ASSERT (0);
+ break;
+ }
+
+ RegTableEntry ++;
+ }
+}
+
+
+/**
+ Processes register table assuming which may contain IO, MEM, and STALL
+ entries, but must NOT contain any PCI entries. Any PCI entries cause an
+ ASSERT in a DEBUG build and are skipped in a free build.
+
+ No parameter checking is done. Both RegTableEntry and CpuIo parameters are
+ required.
+
+ gBS is assumed to have been defined and is used when processing stalls.
+
+ The function processes each entry sequentially until an OP_TERMINATE_TABLE
+ entry is encountered.
+
+ @param[in] RegTableEntry A pointer to the register table to process
+ @param[in] CpuIo A pointer to the instance of CpuIo that is used when processing IO and
+ MEM table entries
+
+ @retval Nothing.
+
+**/
+VOID
+ProcessRegTableCpu (
+ EFI_REG_TABLE *RegTableEntry,
+ EFI_CPU_IO2_PROTOCOL *CpuIo
+ )
+{
+ while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+ switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+ default:
+ DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+ ASSERT (0);
+ break;
+ }
+
+ RegTableEntry ++;
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.inf
new file mode 100644
index 0000000000..ad21c8719c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/EfiRegTableLib/EfiRegTableLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file.
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EfiRegTableLib
+ FILE_GUID = 98546145-64F1-4d2e-814F-6BF963DB7930
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EfiRegTableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ EfiRegTableLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c
new file mode 100644
index 0000000000..2a558566e5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c
@@ -0,0 +1,578 @@
+/** @file
+ FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+
+ Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/GraphicsOutput.h>
+
+#if 0
+#define VDEBUG DEBUG
+#else
+#define VDEBUG(x)
+#endif
+
+#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+
+UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];
+EFI_PIXEL_BITMASK mBltLibRgbPixelMasks = {0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000};
+EFI_PIXEL_BITMASK mBltLibBgrPixelMasks = {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};
+
+EFI_STATUS
+BltLibParsePixelFormat (
+ IN EFI_GRAPHICS_PIXEL_FORMAT PixelFormat,
+ IN EFI_PIXEL_BITMASK *PixelInformation,
+ OUT UINT8 *PixelShl,
+ OUT UINT8 *PixelShr,
+ OUT UINT32 *PixelMask,
+ OUT UINT8 *BytesPerPixel
+ )
+{
+ UINTN Index;
+ UINT32 MergedMasks;
+ UINT32 *Mask;
+
+ switch (PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ return BltLibParsePixelFormat (PixelBitMask, &mBltLibRgbPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel);
+
+ case PixelBlueGreenRedReserved8BitPerColor:
+ return BltLibParsePixelFormat (PixelBitMask, &mBltLibBgrPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel);
+
+ case PixelBitMask:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MergedMasks = 0;
+ Mask = (UINT32 *) PixelInformation;
+ for (Index = 0; Index < 4; Index++) {
+ //
+ // Only ReservedMask can be 0
+ //
+ if (Index != 3 && Mask[Index] == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // The Mask of each color shouldn't overlap
+ //
+ if ((MergedMasks & Mask[Index]) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MergedMasks |= Mask[Index];
+
+ if (PixelShl != NULL && PixelShr != NULL) {
+ PixelShl[Index] = (UINT8) (HighBitSet32 (Mask[Index]) - 23 + (Index * 8));
+ PixelShl[Index] %= 32;
+ if ((INT8) PixelShl[Index] < 0) {
+ PixelShr[Index] = -PixelShl[Index];
+ PixelShl[Index] = 0;
+ } else {
+ PixelShr[Index] = 0;
+ }
+ VDEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Index, PixelShl[Index], PixelShr[Index], Mask[Index]));
+ }
+ }
+ if (PixelMask != NULL) {
+ CopyMem (PixelMask, PixelInformation, sizeof (EFI_PIXEL_BITMASK));
+ }
+
+ if (BytesPerPixel != NULL) {
+ *BytesPerPixel = (UINT8) ((HighBitSet32 (MergedMasks) + 7) / 8);
+ VDEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BltLibVerifyLocation (
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN UINTN X,
+ IN UINTN Y,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ if ((X >= FrameBufferInfo->HorizontalResolution) ||
+ (Width > FrameBufferInfo->HorizontalResolution - X)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Y >= FrameBufferInfo->VerticalResolution) ||
+ (Height > FrameBufferInfo->VerticalResolution - Y)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] Color Color to fill the region with
+ @param[in] DestinationX X location to start fill operation
+ @param[in] DestinationY Y location to start fill operation
+ @param[in] Width Width (in pixels) to fill
+ @param[in] Height Height to fill
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoFill (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ EFI_STATUS Status;
+ UINTN Y;
+ UINT8 *Destination;
+ UINTN X;
+ UINT8 Uint8;
+ UINT32 Uint32;
+ UINT64 WideFill;
+ BOOLEAN UseWideFill;
+ BOOLEAN LineBufferReady;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINTN SizeInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShr, PixelShl, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ Uint32 = *(UINT32 *) Color;
+ WideFill = (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) |
+ (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) |
+ (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) |
+ (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]);
+ VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));
+
+ //
+ // If the size of the pixel data evenly divides the sizeof
+ // WideFill, then a wide fill operation can be used
+ //
+ UseWideFill = TRUE;
+ if (sizeof (WideFill) % BytesPerPixel == 0) {
+ for (X = BytesPerPixel; X < sizeof (WideFill); X++) {
+ ((UINT8 *) &WideFill)[X] = ((UINT8 *) &WideFill)[X % BytesPerPixel];
+ }
+ } else {
+ //
+ // If all the bytes in the pixel are the same value, then use
+ // a wide fill operation.
+ //
+ for (X = 1, Uint8 = ((UINT8 *) &WideFill)[0]; X < BytesPerPixel; X++) {
+ if (Uint8 != ((UINT8 *) &WideFill)[X]) {
+ UseWideFill = FALSE;
+ break;
+ }
+ }
+ if (UseWideFill) {
+ SetMem (&WideFill, sizeof (WideFill), Uint8);
+ }
+ }
+
+ if (UseWideFill && (DestinationX == 0) && (Width == FrameBufferInfo->HorizontalResolution)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));
+ Offset = DestinationY * FrameBufferInfo->PixelsPerScanLine * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+ SizeInBytes = WidthInBytes * Height;
+ if (SizeInBytes >= 8) {
+ SetMem64 (Destination, SizeInBytes & ~7, WideFill);
+ Destination += (SizeInBytes & ~7);
+ SizeInBytes &= 7;
+ }
+ if (SizeInBytes > 0) {
+ CopyMem (Destination, &WideFill, SizeInBytes);
+ }
+ } else {
+ LineBufferReady = FALSE;
+ for (Y = DestinationY; Y < (Height + DestinationY); Y++) {
+ Offset = ((Y * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ if (UseWideFill && (((UINTN) Destination & 7) == 0)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));
+ SizeInBytes = WidthInBytes;
+ if (SizeInBytes >= 8) {
+ SetMem64 (Destination, SizeInBytes & ~7, WideFill);
+ Destination += (SizeInBytes & ~7);
+ SizeInBytes &= 7;
+ }
+ if (SizeInBytes > 0) {
+ CopyMem (Destination, &WideFill, SizeInBytes);
+ }
+ } else {
+ VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));
+ if (!LineBufferReady) {
+ CopyMem (mBltLibLineBuffer, &WideFill, BytesPerPixel);
+ for (X = 1; X < Width; ) {
+ CopyMem (
+ (mBltLibLineBuffer + (X * BytesPerPixel)),
+ mBltLibLineBuffer,
+ MIN (X, Width - X) * BytesPerPixel
+ );
+ X += MIN (X, Width - X);
+ }
+ LineBufferReady = TRUE;
+ }
+ CopyMem (Destination, mBltLibLineBuffer, WidthInBytes);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[out] BltBuffer Output buffer for pixel color data
+ @param[in] SourceX X location within video
+ @param[in] SourceY Y location within video
+ @param[in] DestinationX X location within BltBuffer
+ @param[in] DestinationY Y location within BltBuffer
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+ @param[in] Delta Number of bytes in a row of BltBuffer
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoToBuffer (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+{
+ EFI_STATUS Status;
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN X;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShl, PixelShr, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ for (SrcY = SourceY, DstY = DestinationY; DstY < (DestinationY + Height); SrcY++, DstY++) {
+
+ Offset = ((SrcY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel;
+ Source = (UINT8 *) FrameBuffer + Offset;
+
+ if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ } else {
+ Destination = mBltLibLineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+
+ if (FrameBufferInfo->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
+ for (X = 0; X < Width; X++) {
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ Uint32 = *(UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel));
+ *(UINT32 *) Blt = (((Uint32 & PixelMask[0]) >> PixelShl[0]) << PixelShr[0]) |
+ (((Uint32 & PixelMask[1]) >> PixelShl[1]) << PixelShr[1]) |
+ (((Uint32 & PixelMask[2]) >> PixelShl[2]) << PixelShr[2]) |
+ (((Uint32 & PixelMask[3]) >> PixelShl[3]) << PixelShr[3]);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] BltBuffer Output buffer for pixel color data
+ @param[in] SourceX X location within BltBuffer
+ @param[in] SourceY Y location within BltBuffer
+ @param[in] DestinationX X location within video
+ @param[in] DestinationY Y location within video
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+ @param[in] Delta Number of bytes in a row of BltBuffer
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltBufferToVideo (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+{
+ EFI_STATUS Status;
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN X;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShl, PixelShr, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+
+ Offset = ((DstY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Source = (UINT8 *) BltBuffer + (SrcY * Delta);
+ } else {
+ for (X = 0; X < Width; X++) {
+ Blt =
+ (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
+ (UINT8 *) BltBuffer +
+ (SrcY * Delta) +
+ ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+ );
+ Uint32 = *(UINT32 *) Blt;
+ *(UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel)) =
+ (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) |
+ (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) |
+ (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) |
+ (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]);
+ }
+ Source = mBltLibLineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Video operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] SourceX X location within video
+ @param[in] SourceY Y location within video
+ @param[in] DestinationX X location within video
+ @param[in] DestinationY Y location within video
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoToVideo (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ INTN LineStride;
+ UINT8 BytesPerPixel;
+
+ //
+ // Video to Video: Source is Video, destination is Video
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ NULL, NULL, NULL, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ Offset = ((SourceY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel;
+ Source = (UINT8 *) FrameBuffer + Offset;
+
+ Offset = ((DestinationY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ LineStride = FrameBufferInfo->PixelsPerScanLine * BytesPerPixel;
+ if (Destination > Source) {
+ //
+ // Copy from last line to avoid source is corrupted by copying
+ //
+ Source += Height * LineStride;
+ Destination += Height * LineStride;
+ LineStride = -LineStride;
+ }
+
+ while (Height-- > 0) {
+ CopyMem (Destination, Source, WidthInBytes);
+
+ Source += LineStride;
+ Destination += LineStride;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf
new file mode 100644
index 0000000000..850551d2ea
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@@ -0,0 +1,34 @@
+## @file
+# FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+#
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FrameBufferBltLib
+ FILE_GUID = 2a40f516-c852-4baa-b7a8-0e9ea090d659
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BltLib
+
+[Sources.common]
+ FrameBufferBltLib.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.c b/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.c
new file mode 100644
index 0000000000..4a5dee5ebd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.c
@@ -0,0 +1,255 @@
+/** @file
+ ICH9 ACPI Timer implements one instance of Timer Library.
+
+ Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <ScAccess.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+
+
+/**
+ The constructor function enables ACPI IO space.
+
+ If ACPI I/O space not enabled, this function will enable it.
+ It will always return RETURN_SUCCESS.
+
+ @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+IntelScAcpiTimerLibConstructor (
+ VOID
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Internal function to read the current tick counter of ACPI.
+
+ @return The tick counter read.
+
+**/
+STATIC
+UINT32
+InternalAcpiGetTimerTick (
+ VOID
+ )
+{
+ return IoRead32 (PcdGet16 (PcdScAcpiIoPortBaseAddress) + R_ACPI_PM1_TMR);
+}
+
+
+/**
+ Stalls the CPU for at least the given number of ticks.
+
+ Stalls the CPU for at least the given number of ticks. It's invoked by
+ MicroSecondDelay() and NanoSecondDelay().
+
+ @param[in] Delay A period of time to delay in ticks.
+
+**/
+STATIC
+VOID
+InternalAcpiDelay (
+ IN UINT32 Delay
+ )
+{
+ UINT32 Ticks;
+ UINT32 Times;
+
+ Times = Delay >> 22;
+ Delay &= BIT22 - 1;
+ do {
+ //
+ // The target timer count is calculated here
+ //
+ Ticks = InternalAcpiGetTimerTick () + Delay;
+ Delay = BIT22;
+
+ //
+ // Wait until time out
+ // Delay >= 2^23 could not be handled by this function
+ // Timer wrap-arounds are handled correctly by this function
+ //
+ while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
+ CpuPause ();
+ }
+ } while (Times-- > 0);
+}
+
+
+/**
+ Stalls the CPU for at least the given number of microseconds.
+ Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+ @param[in] MicroSeconds The minimum number of microseconds to delay.
+
+ @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ MicroSeconds = (UINTN) DivU64x32 (
+ MultU64x32 (
+ MicroSeconds,
+ V_ACPI_PM1_TMR_FREQUENCY
+ ),
+ 1000000u
+ );
+
+ InternalAcpiDelay (
+ (UINT32) MicroSeconds
+ );
+
+ return MicroSeconds;
+}
+
+
+/**
+ Stalls the CPU for at least the given number of nanoseconds.
+ Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+ @param[in] NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ NanoSeconds = (UINTN) DivU64x32 (
+ MultU64x32 (
+ NanoSeconds,
+ V_ACPI_PM1_TMR_FREQUENCY
+ ),
+ 1000000000u
+ );
+
+ InternalAcpiDelay (
+ (UINT32) NanoSeconds
+ );
+ return NanoSeconds;
+}
+
+
+/**
+ Retrieves the current value of a 64-bit free running performance counter.
+
+ Retrieves the current value of a 64-bit free running performance counter. The
+ counter can either count up by 1 or count down by 1. If the physical
+ performance counter counts by a larger increment, then the counter values
+ must be translated. The properties of the counter can be retrieved from
+ GetPerformanceCounterProperties().
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ return (UINT64) InternalAcpiGetTimerTick ();
+}
+
+
+/**
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with immediately after is it rolls over is returned in StartValue. If
+ EndValue is not NULL, then the value that the performance counter end with
+ immediately before it rolls over is returned in EndValue. The 64-bit
+ frequency of the performance counter in Hz is always returned. If StartValue
+ is less than EndValue, then the performance counter counts up. If StartValue
+ is greater than EndValue, then the performance counter counts down. For
+ example, a 64-bit free running counter that counts up would have a StartValue
+ of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+ that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+ @param[out] StartValue The value the performance counter starts with when it
+ rolls over.
+ @param[out] EndValue The value that the performance counter ends with before
+ it rolls over.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+ if (StartValue != NULL) {
+ *StartValue = 0;
+ }
+
+ if (EndValue != NULL) {
+ *EndValue = V_ACPI_PM1_TMR_MAX_VAL - 1;
+ }
+
+ return V_ACPI_PM1_TMR_FREQUENCY;
+}
+
+
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+ IN UINT64 Ticks
+ )
+{
+ UINT64 Frequency;
+ UINT64 NanoSeconds;
+ UINT64 Remainder;
+ INTN Shift;
+
+ Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+ //
+ // Ticks
+ // Time = --------- x 1,000,000,000
+ // Frequency
+ //
+ NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+ //
+ // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+ // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+ // i.e. highest bit set in Remainder should <= 33.
+ //
+ Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+ Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+ Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+ NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+ return NanoSeconds;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.inf
new file mode 100644
index 0000000000..2ef10be065
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/IntelScAcpiTimerLib/IntelScAcpiTimerLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Intel ICH9 Acpi Timer Instance.
+# ICH9 Acpi timer implements one instance of Timer Library. Acpi timer cannot be programmed,
+# so it could be used by any types of drivers, including SMM drivers and Runtime drivers.
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IntelScAcpiTimerLib
+ FILE_GUID = 0C0AC8C1-E368-4d20-85FE-23EFB3DB094E
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+ CONSTRUCTOR = IntelScAcpiTimerLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ IntelScAcpiTimerLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ PciLib
+ IoLib
+ BaseLib
+
+[Pcd.common]
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/DebugLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/DebugLib.c
new file mode 100644
index 0000000000..40ec5d305c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/DebugLib.c
@@ -0,0 +1,265 @@
+/** @file
+ Debug Library based on Debug Service.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <Ppi/DebugService.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseDebugPrintErrorLevelLib.h>
+
+
+/**
+ Prints a debug message to the debug output device if the specified error level is enabled.
+
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
+ GetDebugPrintErrorLevel (), then print the message specified by Format and the
+ associated variable argument list to the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ If the length of the message string specified by Format is larger than the maximum allowable
+ record length, then directly return and not print it.
+
+ @param[in] ErrorLevel The error level of the debug message.
+ @param[in] Format Format string for the debug message to print.
+ @param ... Variable argument list whose contents are accessed
+ based on the format string specified by Format.
+
+**/
+
+
+VOID
+EFIAPI
+DebugPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+{
+ DEBUG_SERVICE_PPI *DebugServiceData;
+ CONST EFI_PEI_SERVICES **PeiServices;
+ IA32_DESCRIPTOR Idtr;
+ VA_LIST Marker;
+ EFI_STATUS Status;
+
+ //
+ // If Format is NULL, then ASSERT().
+ //
+ ASSERT (Format != NULL);
+
+ //
+ // Check driver Debug Level value and global debug level
+ //
+ if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
+ return;
+ }
+
+ AsmReadIdtr (&Idtr);
+ PeiServices = (CONST EFI_PEI_SERVICES **) (*(UINTN *) (Idtr.Base - sizeof (UINTN)));
+
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gDebugServicePpiGuid, 0, NULL, (VOID **) &DebugServiceData);
+
+ if (Status == EFI_SUCCESS) {
+ VA_START (Marker, Format);
+ DebugServiceData->DebugPrint (ErrorLevel, Format, Marker);
+ VA_END (Marker);
+ }
+
+}
+
+
+/**
+ Prints an assert message containing a filename, line number, and description.
+ This may be followed by a breakpoint or a dead loop.
+
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ CpuDeadLoop() is called. If neither of these bits are set, then this function
+ returns immediately after the message is printed to the debug output device.
+ DebugAssert() must actively prevent recursion. If DebugAssert() is called while
+ processing another DebugAssert(), then DebugAssert() must return immediately.
+
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+ @param[in] FileName Pointer to the name of the source file that generated the assert condition.
+ @param[in] LineNumber The line number in the source file that generated the assert condition
+ @param[in] Description Pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+DebugAssert (
+ IN CONST CHAR8 *FileName,
+ IN UINTN LineNumber,
+ IN CONST CHAR8 *Description
+ )
+{
+ DEBUG_SERVICE_PPI *DebugServiceData;
+ CONST EFI_PEI_SERVICES **PeiServices;
+ IA32_DESCRIPTOR Idtr;
+ EFI_STATUS Status;
+
+ AsmReadIdtr (&Idtr);
+ PeiServices = (CONST EFI_PEI_SERVICES **) (*(UINTN *) (Idtr.Base - sizeof (UINTN)));
+
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gDebugServicePpiGuid, 0, NULL, (VOID **) &DebugServiceData);
+
+ if (Status == EFI_SUCCESS) {
+ DebugServiceData->DebugAssert (FileName, LineNumber, Description, PcdGet8 (PcdDebugPropertyMask));
+ } else {
+ //
+ // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
+ //
+ if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
+ CpuBreakpoint ();
+ } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
+ CpuDeadLoop ();
+ }
+ }
+}
+
+
+/**
+ Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the value specified by
+ PcdDebugClearMemoryValue, and returns Buffer.
+
+ If Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param[out] Buffer Pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
+ @param[in] Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
+
+ @retval Buffer Pointer to the target buffer filled with PcdDebugClearMemoryValue.
+
+**/
+VOID *
+EFIAPI
+DebugClearMemory (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue));
+}
+
+
+/**
+ Returns TRUE if ASSERT() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugAssertEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if DEBUG() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if DEBUG_CODE() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugCodeEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugClearMemoryEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
+}
+
+/**
+ Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+ This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+ @retval TRUE Current ErrorLevel is supported.
+ @retval FALSE Current ErrorLevel is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintLevelEnabled (
+ IN CONST UINTN ErrorLevel
+ )
+{
+ return (BOOLEAN) ((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/PeiDebugLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/PeiDebugLib.inf
new file mode 100644
index 0000000000..3f6d2b5de3
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiDebugLib/PeiDebugLib.inf
@@ -0,0 +1,52 @@
+## @file
+# Copyright (c) 2003 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DebugLib
+ FILE_GUID = bda39d3a-451b-4350-8266-81ab10fa0525
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = DebugLib|PEIM PEI_CORE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ PcdLib
+ ReportStatusCodeLib
+ BaseMemoryLib
+ DebugPrintErrorLevelLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES
+
+[Sources]
+ DebugLib.c
+
+[Ppis]
+ gDebugServicePpiGuid
+
+[Depex.common.PEIM]
+ gDebugServicePpiGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.c
new file mode 100644
index 0000000000..7e6dfa671c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.c
@@ -0,0 +1,434 @@
+/** @file
+ Performance library instance used in PEI phase.
+
+ This file implements Performance Library class in MdePkg. It converts performance data
+ to PEI GUID event, and creates performance logging GUIDed HOB on the first performance
+ logging and then logs the performance data to the GUIDed HOB. Due to the limitation
+ of temporary RAM, the maximum number of performance logging entry is specified by PcdMaxPeiPerformanceLogEntries.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <PeiFirmwarePerformance.h>
+#include <Library/PerformanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/LocalApicLib.h>
+#include <ExtendedFirmwarePerformanceData.h>
+
+
+/**
+ Convert PEI performance log to FPDT GUID boot record.
+
+ @param[in] IsStart TRUE if the performance log is start log.
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] Ticker 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
+
+ @retval RETURN_SUCCESS Add FPDT boot record.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+ @retval RETURN_UNSUPPORTED No matched FPDT record.
+
+**/
+RETURN_STATUS
+InsertPeiFpdtMeasurement (
+ IN BOOLEAN IsStart,
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 Ticker,
+ IN UINT32 Identifier
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINTN PeiPerformanceSize;
+ PEI_FIRMWARE_PERFORMANCE_HOB *PeiFirmwarePerformance;
+ PEI_GUID_EVENT_RECORD *PeiGuidEvent;
+ UINT16 ProgressId;
+
+ //
+ // Create GUID HOB Data.
+ //
+ GuidHob = GetFirstGuidHob (&gPeiFirmwarePerformanceGuid);
+ if (GuidHob != NULL) {
+ //
+ // PEI Performance HOB was found, then return the existing one.
+ //
+ PeiFirmwarePerformance = GET_GUID_HOB_DATA (GuidHob);
+ } else {
+ //
+ // PEI Performance HOB was not found, then build one.
+ //
+ PeiPerformanceSize = sizeof (PEI_FIRMWARE_PERFORMANCE_HOB) +
+ sizeof (PEI_GUID_EVENT_RECORD) * (PcdGet8 (PcdMaxPeiPerformanceLogEntries) - 1);
+ PeiFirmwarePerformance = BuildGuidHob (&gPeiFirmwarePerformanceGuid, PeiPerformanceSize);
+ ASSERT (PeiFirmwarePerformance != NULL);
+ ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
+ }
+
+ //
+ // Check whether GUID Data is enough to store new PEI GUID Event Perf Data.
+ //
+ if (PeiFirmwarePerformance->NumberOfEntries >= PcdGet8 (PcdMaxPeiPerformanceLogEntries)) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ PeiGuidEvent = &PeiFirmwarePerformance->GuidEventRecord[PeiFirmwarePerformance->NumberOfEntries];
+
+ //
+ // Covert Performance token to ProgressId.
+ //
+ if (Identifier != 0) {
+ ProgressId = (UINT16) Identifier;
+ } else if (Token == NULL) {
+ return RETURN_UNSUPPORTED;
+ } else if (AsciiStrCmp (Token, PEIM_TOK) == 0) {
+ if (IsStart) {
+ ProgressId = MODULE_START_ID;
+ } else {
+ ProgressId = MODULE_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, PREMEM_TOK) == 0) {
+ if (IsStart) {
+ ProgressId = PREMEM_START_ID;
+ } else {
+ ProgressId = PREMEM_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, POSTMEM_TOK) == 0) {
+ if (IsStart) {
+ ProgressId = POSTMEM_START_ID;
+ } else {
+ ProgressId = POSTMEM_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, DISMEM_TOK) == 0) {
+ if (IsStart) {
+ ProgressId = DISMEM_START_ID;
+ } else {
+ ProgressId = DISMEM_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, SCRIPT_EXEC_TOK) == 0) {
+ if (IsStart) {
+ ProgressId = SCRIPT_EXEC_START_ID;
+ } else {
+ ProgressId = SCRIPT_EXEC_END_ID;
+ }
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Fill PEI GUID Event Data.
+ //
+ if (Handle != NULL) {
+ CopyGuid (&PeiGuidEvent->Guid, Handle);
+ } else {
+ CopyGuid (&PeiGuidEvent->Guid, &gEfiCallerIdGuid);
+ }
+ PeiGuidEvent->ProgressID = ProgressId;
+ PeiGuidEvent->ApicID = GetApicId ();
+ //
+ // Get ticker value.
+ //
+ if (Ticker == 0) {
+ Ticker = GetPerformanceCounter ();
+ }
+ PeiGuidEvent->Timestamp = GetTimeInNanoSecond (Ticker);
+ PeiFirmwarePerformance->NumberOfEntries ++;
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Creates a record for the beginning of a performance measurement.
+
+ Creates a record that contains the Handle, Token, Module and Identifier.
+ If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
+ If TimeStamp is zero, then this function reads the current time stamp
+ and adds that time stamp value to the record as the start time.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return InsertPeiFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Fills in the end time of a performance measurement.
+
+ Looks up the record that matches Handle, Token, Module and Identifier.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then TimeStamp is added to the record as the end time.
+ If the record is found and TimeStamp is zero, then this function reads
+ the current time stamp and adds that time stamp value to the record as the end time.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the found record
+ is same as the one found by EndPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return InsertPeiFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
+ and then assign the Identifier with 0.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+ If Identifier is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance of entry entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+ @param[out] Identifier Pointer to the 32-bit identifier that was recorded.
+
+ @retval The key for the next performance log entry (in general case).
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurementEx (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp,
+ OUT UINT32 *Identifier
+ )
+{
+ return 0;
+}
+
+
+/**
+ Creates a record for the beginning of a performance measurement.
+
+ Creates a record that contains the Handle, Token, and Module.
+ If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
+ If TimeStamp is zero, then this function reads the current time stamp
+ and adds that time stamp value to the record as the start time.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return InsertPeiFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Fills in the end time of a performance measurement.
+
+ Looks up the record that matches Handle, Token, and Module.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then TimeStamp is added to the record as the end time.
+ If the record is found and TimeStamp is zero, then this function reads
+ the current time stamp and adds that time stamp value to the record as the end time.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return InsertPeiFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
+ and then eliminate the Identifier.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance of entry entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+
+ @retval The key for the next performance log entry (in general case).
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurement (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp
+ )
+{
+ return 0;
+}
+
+
+/**
+ Returns TRUE if the performance measurement macros are enabled.
+
+ This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set.
+ @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+PerformanceMeasurementEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.inf
new file mode 100644
index 0000000000..e28ec34b1d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFpdtPerformanceLib/PeiFpdtPerformanceLib.inf
@@ -0,0 +1,58 @@
+## @file
+# Performance library instance used in PEI phase.
+#
+# This library provides the performance measurement interfaces in PEI
+# phase, it converts performance data to PEI GUID event, and created
+# GUIDed HOB for GUID event logging. The GUIDed HOB is passed to DXE
+# phase so that it can be taken over by DxeCorePerformanceLib.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiFpdtPerformanceLib
+ FILE_GUID = EB9433F6-91E4-45c6-B937-BAE819DA4106
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PerformanceLib|PEIM PEI_CORE SEC
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseMemoryLib
+ PcdLib
+ TimerLib
+ BaseLib
+ HobLib
+ DebugLib
+ LocalApicLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask
+
+[Sources]
+ PeiFpdtPerformanceLib.c
+
+[Guids]
+ gPeiFirmwarePerformanceGuid ## PRODUCES ## HOB
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
new file mode 100644
index 0000000000..4af0dc2017
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
@@ -0,0 +1,127 @@
+/** @file
+ Implementation of Fsp PCH Policy Initialization.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/CpuPolicy.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/CpuPolicyLib.h>
+
+
+/**
+ Performs FSP CPU PEI Policy initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ )
+{
+ EFI_STATUS Status;
+ SI_CPU_POLICY_PPI *SiCpuPolicyPpi;
+
+ //
+ // Locate SiCpuPolicyPpi
+ //
+ SiCpuPolicyPpi = NULL;
+ Status = PeiServicesLocatePpi (
+ &gSiCpuPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SiCpuPolicyPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs FSP CPU PEI Policy post memory initialization.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ )
+{
+ SYSTEM_CONFIGURATION *SystemConfiguration;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINTN VariableSize = 0;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "Update FspsUpd from setup option...\n"));
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ SystemConfiguration = AllocateZeroPool (VariableSize);
+
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ SystemConfiguration
+ );
+
+ if (Status == EFI_SUCCESS) {
+ FspsUpd->FspsConfig.ActiveProcessorCores = SystemConfiguration->ActiveProcessorCores;
+ FspsUpd->FspsConfig.DisableCore1 = SystemConfiguration->Core1;
+ FspsUpd->FspsConfig.DisableCore2 = SystemConfiguration->Core2;
+ FspsUpd->FspsConfig.DisableCore3 = SystemConfiguration->Core3;
+ FspsUpd->FspsConfig.VmxEnable = SystemConfiguration->ProcessorVmxEnable;
+ FspsUpd->FspsConfig.ProcTraceMemSize = SystemConfiguration->ProcTraceMemSize;
+ FspsUpd->FspsConfig.ProcTraceEnable = SystemConfiguration->ProcTraceEnable;
+ FspsUpd->FspsConfig.Eist = SystemConfiguration->EnableGv;
+ FspsUpd->FspsConfig.BootPState = SystemConfiguration->BootPState;
+ FspsUpd->FspsConfig.EnableCx = SystemConfiguration->EnableCx;
+ FspsUpd->FspsConfig.C1e = SystemConfiguration->EnableCxe;
+ FspsUpd->FspsConfig.BiProcHot = SystemConfiguration->EnableProcHot;
+ FspsUpd->FspsConfig.PkgCStateLimit = (MAX_PKG_C_STATE) SystemConfiguration->MaxPkgCState;
+ FspsUpd->FspsConfig.EnableCx = SystemConfiguration->EnableCx;
+ FspsUpd->FspsConfig.CStateAutoDemotion = SystemConfiguration->CStateAutoDemotion;
+ FspsUpd->FspsConfig.CStateUnDemotion = SystemConfiguration->CStateUnDemotion;
+ FspsUpd->FspsConfig.MaxCoreCState = SystemConfiguration->MaxCoreCState;
+ FspsUpd->FspsConfig.PkgCStateDemotion = SystemConfiguration->PkgCStateDemotion;
+ FspsUpd->FspsConfig.PkgCStateUnDemotion = SystemConfiguration->PkgCStateUnDemotion;
+ FspsUpd->FspsConfig.TurboMode = SystemConfiguration->TurboModeEnable;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
new file mode 100644
index 0000000000..e9eaa9611b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
@@ -0,0 +1,162 @@
+/** @file
+ Internal header file for Fsp Policy Initialization Library.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_FSP_POLICY_INIT_LIB_H_
+#define _PEI_FSP_POLICY_INIT_LIB_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiScPolicyLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Guid/SetupVariable.h>
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+
+/**
+ Performs FSP SI PEI Policy initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ );
+
+/**
+ Performs FSP PCH PEI Policy pre mem initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspScPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ );
+
+/**
+ Performs FSP PCH PEI Policy initialization.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspScPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ );
+
+/**
+ Performs FSP CPU PEI Policy initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ );
+
+/**
+ Performs FSP SA PEI Policy initialization in pre-memory.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ );
+
+/**
+ Performs FSP SA PEI Policy initialization.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ );
+
+/**
+ Performs FSP CPU PEI Policy post memory initialization.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ );
+
+/**
+ PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+ @param[in] NameGuid File GUID
+ @param[out] Address Pointer to the File Address
+ @param[out] Size Pointer to File Size
+
+ @retval EFI_SUCCESS Successfull in reading the section from FV
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ );
+
+#endif // _PEI_FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
new file mode 100644
index 0000000000..856d173322
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
@@ -0,0 +1,99 @@
+## @file
+# Library functions for Fsp Policy Initialization Library.
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiFspPolicyInitLib
+ FILE_GUID = 2CB87D67-D1A4-4CD3-8CD7-91A1FA1DF6E0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspPolicyInitLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ PeiFspPolicyInitLibPreMem.c
+ PeiFspSiPolicyInitLib.c
+ PeiFspScPolicyInitLib.c
+ PeiFspCpuPolicyInitLib.c
+ PeiFspSaPolicyInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ PeiServicesLib
+ SmbusLib
+ MmPciLib
+ ConfigBlockLib
+ PeiPolicyInitLib
+ ScPlatformLib
+
+[Pcd]
+
+[Guids]
+ gEfiSetupVariableGuid
+ gPeiDefaultVbtGuid
+ gVbtMipiAuoGuid
+ gVbtMipiSharpGuid
+ gVbtMipiJdiGuid
+ gVbtEdpTypeCGuid
+ gEfiPlatformInfoGuid
+ gPeiLogoGuid
+
+[Pcd.common]
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+
+[Ppis]
+ gSiPolicyPpiGuid ## CONSUMES
+ gScPolicyPpiGuid
+ gSiCpuPolicyPpiGuid ## CONSUMES
+ gSiSaPolicyPpiGuid ## CONSUMES
+ gSaMiscConfigGuid
+ gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gMemoryConfigGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLibPreMem.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLibPreMem.c
new file mode 100644
index 0000000000..788cebf03b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLibPreMem.c
@@ -0,0 +1,105 @@
+/** @file
+ Instance of Fsp Policy Initialization Library.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+/**
+ Performs FSP PEI Policy Pre-memory initialization.
+
+ @param[in] FspHeader Pointer to FSP infomation header.
+ @param[in] FspInitParam Pointer to FSP initialization parameters.
+
+**/
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // SI Pei Fsp Policy Initialization
+ //
+ Status = PeiFspSiPolicyInitPreMem (FspmUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+ }
+
+ //
+ // SC Pei Fsp Policy Initialization
+ //
+ Status = PeiFspScPolicyInitPreMem (FspmUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - SC Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+ }
+
+ //
+ // Cpu Pei Fsp Policy Initialization
+ //
+ Status = PeiFspCpuPolicyInitPreMem (FspmUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+ }
+
+ //
+ // SystemAgent Pei Fsp Policy Initialization
+ //
+ Status = PeiFspSaPolicyInitPreMem (FspmUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+ }
+
+}
+
+/**
+ Performs FSP PEI Policy initialization.
+
+ @param[in, out] FspsUpd Pointer UPD data region
+
+**/
+VOID
+EFIAPI
+FspPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // SC Pei Fsp Policy Initialization
+ //
+ Status = PeiFspScPolicyInit (FspsUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - SC Pei Fsp Policy iInitialization fail, Status = %r\n", Status));
+ }
+
+ //
+ // SystemAgent Pei Fsp Policy Initialization
+ //
+ Status = PeiFspSaPolicyInit (FspsUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+ }
+
+ //
+ // Cpu Pei Fsp Policy Initialization
+ //
+ Status = PeiFspCpuPolicyInit (FspsUpd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
new file mode 100644
index 0000000000..04167c59cb
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
@@ -0,0 +1,283 @@
+/** @file
+ Implementation of Fsp SA Policy Initialization.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/SaPolicy.h>
+#include <Ppi/SaMiscConfig.h>
+#include <Ppi/MemoryConfig.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Ppi/DramPolicyPpi.h>
+#include <ScAccess.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+
+
+/**
+ PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+ @param[in] NameGuid File GUID
+ @param[out] Address Pointer to the File Address
+ @param[out] Size Pointer to File Size
+
+ @retval EFI_SUCCESS Successfull in reading the section from FV
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+ EFI_FV_FILE_INFO FvFileInfo;
+ PEI_CORE_INSTANCE *PrivateData;
+ UINTN CurrentFv;
+ PEI_CORE_FV_HANDLE *CoreFvHandle;
+ EFI_PEI_FILE_HANDLE VbtFileHandle;
+ EFI_GUID *VbtGuid;
+ EFI_COMMON_SECTION_HEADER *Section;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiFirmwareFileSystem2Guid,
+ 0,
+ NULL,
+ (VOID **) &FvPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CurrentFv = PrivateData->CurrentPeimFvCount;
+ CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+ Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+ if (!EFI_ERROR (Status) && VbtFileHandle != NULL) {
+
+ DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
+
+ Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
+ Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
+ Section = (EFI_COMMON_SECTION_HEADER *) FvFileInfo.Buffer;
+ if (IS_SECTION2 (Section)) {
+ ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+ *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs FSP SA PEI Policy initialization in pre-memory.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ )
+{
+ SYSTEM_CONFIGURATION *SystemConfiguration;
+ UINTN VariableSize = 0;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "Wrapper-PeiFspSaPolicyInitPreMem - Start\n"));
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ SystemConfiguration = AllocateZeroPool (VariableSize);
+
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ SystemConfiguration
+ );
+
+ if (Status == EFI_SUCCESS) {
+ FspmUpd->FspmConfig.IgdDvmt50PreAlloc = SystemConfiguration->IgdDvmt50PreAlloc;
+ FspmUpd->FspmConfig.IgdApertureSize = SystemConfiguration->IgdApertureSize;
+ FspmUpd->FspmConfig.GttSize = SystemConfiguration->GTTSize;
+ FspmUpd->FspmConfig.Igd = SystemConfiguration->Igd;
+ FspmUpd->FspmConfig.PrimaryVideoAdaptor = SystemConfiguration->PrimaryVideoAdaptor;
+
+ FspmUpd->FspmConfig.FwTraceEn = 1;
+ FspmUpd->FspmConfig.FwTraceDestination = 4;
+ FspmUpd->FspmConfig.RecoverDump = 0;
+ FspmUpd->FspmConfig.Msc0Size = 0;
+ FspmUpd->FspmConfig.Msc0Wrap = 1;
+ FspmUpd->FspmConfig.Msc1Size = 0;
+ FspmUpd->FspmConfig.Msc1Wrap = 1;
+ FspmUpd->FspmConfig.PtiMode = 1;
+ FspmUpd->FspmConfig.PtiTraining = 0;
+ FspmUpd->FspmConfig.PtiSpeed = 2;
+ FspmUpd->FspmConfig.PunitMlvl = 1;
+ FspmUpd->FspmConfig.PmcMlvl = 1;
+ FspmUpd->FspmConfig.SwTraceEn = 0;
+ }
+
+ DEBUG ((DEBUG_INFO, "Wrapper-PeiFspSaPolicyInitPreMem - End\n"));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs FSP SA PEI Policy initialization.
+
+ @param[in, out] FspsUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ )
+{
+ EFI_STATUS Status;
+ SA_MISC_CONFIG *MiscConfig;
+ SI_SA_POLICY_PPI *SiSaPolicyPpi;
+ VOID *Buffer;
+ UINT32 Size;
+ EFI_GUID PeiLogoGuid = gPeiLogoGuid;
+ EFI_GUID PeiVbtGuid;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION *SystemConfiguration;
+ UINTN VariableSize = 0;
+ EFI_BOOT_MODE BootMode;
+
+ //
+ // Locate SiSaPolicyPpi
+ //
+ SiSaPolicyPpi = NULL;
+ MiscConfig = NULL;
+ Status = PeiServicesLocatePpi(
+ &gSiSaPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SiSaPolicyPpi
+ );
+ if (EFI_ERROR (Status) == FALSE) {
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gSaMiscConfigGuid, (VOID *) &MiscConfig);
+ }
+
+ Status = PeiServicesGetBootMode (&BootMode);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "Update North Cluster FspsUpd from setup option...\n"));
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ SystemConfiguration = AllocateZeroPool (VariableSize);
+
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ SystemConfiguration
+ );
+
+ if (Status == EFI_SUCCESS) {
+ FspsUpd->FspsConfig.PmSupport = SystemConfiguration->PmSupport;
+ FspsUpd->FspsConfig.EnableRenderStandby = SystemConfiguration->EnableRenderStandby;
+ FspsUpd->FspsConfig.CdClock = SystemConfiguration->CdClock;
+ FspsUpd->FspsConfig.PavpEnable = SystemConfiguration->PavpEnable;
+ FspsUpd->FspsConfig.PeiGraphicsPeimInit = SystemConfiguration->PeiGraphicsPeimInit;
+ FspsUpd->FspsConfig.IpuEn = SystemConfiguration->IpuEn;
+ FspsUpd->FspsConfig.IpuAcpiMode = SystemConfiguration->IpuAcpiMode;
+ }
+
+ //
+ // Update VbtGuid based on VbtSelect opion from setup
+ //
+ PeiVbtGuid = gPeiDefaultVbtGuid;
+
+ //
+ // Update UPD:LogoPtr
+ //
+ PeiGetSectionFromFv (PeiVbtGuid, &Buffer, &Size);
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not locate VBT"));
+ }
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) NULL;
+ } else {
+ FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) Buffer;
+ }
+ DEBUG ((DEBUG_INFO, "VbtPtr from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
+ DEBUG ((DEBUG_INFO, "VbtSize from PeiGetSectionFromFv is 0x%x\n", Size));
+
+ PeiGetSectionFromFv (PeiLogoGuid, &Buffer, &Size);
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not locate Logo"));
+ }
+ FspsUpd->FspsConfig.LogoPtr = (UINT32) Buffer;
+ FspsUpd->FspsConfig.LogoSize = Size;
+ DEBUG ((DEBUG_INFO, "LogoPtr from PeiFspSaPolicyInit PeiGetSectionFromFv is 0x%x\n", Buffer));
+ DEBUG ((DEBUG_INFO, "LogoSize from PeiFspSaPolicyInit PeiGetSectionFromFv is 0x%x\n", Size));
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspScPolicyInitLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspScPolicyInitLib.c
new file mode 100644
index 0000000000..47ec706006
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspScPolicyInitLib.c
@@ -0,0 +1,625 @@
+/** @file
+ Implementation of Fsp SC Policy Initialization.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/ScPolicy.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/PeiScPolicyLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SteppingLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/ScPlatformLib.h>
+
+extern EFI_GUID gEfiBootMediaHobGuid;
+//
+// Generic definitions for device Auto/enabling/disabling used by platform
+//
+#define DEVICE_AUTO 2
+#define DEVICE_ENABLE 1
+#define DEVICE_DISABLE 0
+
+/**
+ Check it's eMMC boot path or not.
+
+ @retval TRUE eMMC Boot path
+ @retval FALSE Not eMMC boot path
+
+**/
+BOOLEAN
+IseMMCBoot(
+ VOID
+ )
+{
+ VOID *HobList;
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData;
+
+ DEBUG ((EFI_D_INFO, "IseMMCBoot Start!\n"));
+ HobList = GetFirstGuidHob (&gEfiBootMediaHobGuid);
+ if (HobList != NULL) {
+ DEBUG ((EFI_D_INFO, "IseMMCBoot HobList != NULL\n"));
+ BootMediaData = GET_GUID_HOB_DATA (HobList);
+ if (BootMediaData->PhysicalData == BOOT_FROM_EMMC) {
+ DEBUG ((EFI_D_INFO, "BootMediaData->PhysicalData == IseMMCBoot\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Not boot from eMMC\n"));
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ Check it's SPI boot path or not.
+
+ @retval TRUE SPI Boot path
+ @retval FALSE Not SPI boot path
+
+**/
+BOOLEAN
+IsSpiBoot(
+ VOID
+ )
+{
+ VOID *HobList;
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData;
+
+ DEBUG ((EFI_D_INFO, "IsSpiBoot Start!\n"));
+ HobList = GetFirstGuidHob (&gEfiBootMediaHobGuid);
+ if (HobList != NULL) {
+ DEBUG ((EFI_D_INFO, "IsSpiBoot HobList != NULL\n"));
+ BootMediaData = GET_GUID_HOB_DATA (HobList);
+ if (BootMediaData->PhysicalData == BOOT_FROM_SPI) {
+ DEBUG ((EFI_D_INFO, "BootMediaData->PhysicalData == IsSpiBoot\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Not boot from SPI\n"));
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ Performs FSP SC PEI Policy pre mem initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspScPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ )
+{
+ DEBUG ((DEBUG_INFO, "Wrapper-PeiFspScPolicyInitPreMem - Start\n"));
+ DEBUG ((DEBUG_INFO, "Wrapper-PeiFspScPolicyInitPreMem - End\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs FSP SC PEI Policy initialization.
+
+ @param[in, out] UpdDataRgnPtr Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspScPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ UINTN VariableSize;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION *SystemConfiguration = NULL;
+ UINT8 Index;
+ UINT8 PortIndex;
+ UINT32 SpiHsfsReg;
+ UINT32 SpiFdodReg;
+ UINT8 DevIndex;
+ UINT8 HdaIndex;
+ BOOLEAN FlashProtectionEnabled;
+ SC_POLICY_PPI *ScPolicy;
+ SC_FLASH_PROTECTION_CONFIG *FlashProtectionConfig;
+ SC_HDAUDIO_CONFIG *HdaConfig;
+ UINTN HeciBaseAddress;
+ UINT32 SecMode;
+
+ ScPolicy = NULL;
+
+ DEBUG ((DEBUG_INFO, "PeiFspScPolicyInit - Start\n"));
+
+ //
+ // Locate ScPolicyPpi
+ //
+ Status = PeiServicesLocatePpi (
+ &gScPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &ScPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "PeiFspScPolicyInit - Start\n"));
+
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ SystemConfiguration = AllocateZeroPool (VariableSize);
+
+ ASSERT (SystemConfiguration != NULL);
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ SystemConfiguration
+ );
+
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Pass setup option to FspsUpd...\n"));
+
+ SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_SPI_HSFS);
+ if ((SpiHsfsReg & B_SPI_HSFS_FDV) == B_SPI_HSFS_FDV) {
+ MmioWrite32 (SPI_BASE_ADDRESS + R_SPI_FDOC, V_SPI_FDOC_FDSS_FSDM);
+ SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_SPI_FDOD);
+ if (SpiFdodReg == V_SPI_FDBAR_FLVALSIG) {
+ }
+ }
+
+ //
+ // Set ACPI and P2SB Base Addresses
+ //
+ FspsUpd->FspsConfig.ResetSelect = SystemConfiguration->ResetSelect;
+ FspsUpd->FspsConfig.CRIDSettings = SystemConfiguration->CRIDSettings;
+
+ //
+ // Set HPET configurations
+ //
+ FspsUpd->FspsConfig.Hpet = SystemConfiguration->Hpet;
+ FspsUpd->FspsConfig.HpetBdfValid = 0x01;
+ FspsUpd->FspsConfig.HpetBusNumber = 0xFA;
+ FspsUpd->FspsConfig.HpetDeviceNumber = 0x0F;
+ FspsUpd->FspsConfig.HpetFunctionNumber = 0;
+
+ //
+ // Set IOAPIC configurations
+ //
+ FspsUpd->FspsConfig.IoApicId = 0x01;
+ FspsUpd->FspsConfig.IoApicBdfValid = 1;
+ FspsUpd->FspsConfig.IoApicBusNumber = 0xFA;
+ FspsUpd->FspsConfig.IoApicDeviceNumber = 0x1F;
+ FspsUpd->FspsConfig.IoApicFunctionNumber = 0;
+
+ //
+ // Set PCI express configuration according to setup value
+ //
+ FspsUpd->FspsConfig.PcieClockGatingDisabled = SystemConfiguration->PcieClockGatingDisabled;
+ FspsUpd->FspsConfig.PcieRootPort8xhDecode = SystemConfiguration->PcieRootPort8xhDecode;
+ FspsUpd->FspsConfig.Pcie8xhDecodePortIndex = SystemConfiguration->Pcie8xhDecodePortIndex;
+ FspsUpd->FspsConfig.PcieRootPortPeerMemoryWriteEnable = SystemConfiguration->PcieRootPortPeerMemoryWriteEnable;
+
+ for (PortIndex = 0; PortIndex < SC_MAX_PCIE_ROOT_PORTS; PortIndex++) {
+ FspsUpd->FspsConfig.PcieRootPortEn[PortIndex] = SystemConfiguration->PcieRootPortEn[PortIndex];
+ FspsUpd->FspsConfig.PcieRpSlotImplemented[PortIndex] = TRUE;
+ FspsUpd->FspsConfig.PhysicalSlotNumber[PortIndex] = (UINT8) PortIndex;
+ FspsUpd->FspsConfig.PcieRpAspm[PortIndex] = SystemConfiguration->PcieRootPortAspm[PortIndex];
+ FspsUpd->FspsConfig.PcieRpL1Substates[PortIndex] = SystemConfiguration->PcieRootPortL1SubStates[PortIndex];
+ FspsUpd->FspsConfig.PcieRpAcsEnabled[PortIndex] = SystemConfiguration->PcieRootPortACS[PortIndex];
+ FspsUpd->FspsConfig.PcieRpPmSci[PortIndex] = SystemConfiguration->PcieRootPortPMCE[PortIndex];
+ FspsUpd->FspsConfig.PcieRpHotPlug[PortIndex] = SystemConfiguration->PcieRootPortHPE[PortIndex];
+ FspsUpd->FspsConfig.AdvancedErrorReporting[PortIndex] = FALSE;
+ FspsUpd->FspsConfig.UnsupportedRequestReport[PortIndex] = SystemConfiguration->PcieRootPortURE[PortIndex];
+ FspsUpd->FspsConfig.FatalErrorReport[PortIndex] = SystemConfiguration->PcieRootPortFEE[PortIndex];
+ FspsUpd->FspsConfig.NoFatalErrorReport[PortIndex] = SystemConfiguration->PcieRootPortNFE[PortIndex];
+ FspsUpd->FspsConfig.CorrectableErrorReport[PortIndex] = SystemConfiguration->PcieRootPortCEE[PortIndex];
+ FspsUpd->FspsConfig.PmeInterrupt[PortIndex] = 0;
+ FspsUpd->FspsConfig.SystemErrorOnFatalError[PortIndex] = SystemConfiguration->PcieRootPortSFE[PortIndex];
+ FspsUpd->FspsConfig.SystemErrorOnNonFatalError[PortIndex] = SystemConfiguration->PcieRootPortSNE[PortIndex];
+ FspsUpd->FspsConfig.SystemErrorOnCorrectableError[PortIndex] = SystemConfiguration->PcieRootPortSCE[PortIndex];
+ FspsUpd->FspsConfig.PcieRpTransmitterHalfSwing[PortIndex] = SystemConfiguration->PcieRootPortTHS[PortIndex];
+ FspsUpd->FspsConfig.PcieRpCompletionTimeout[PortIndex] = ScPcieCompletionTO_Default;
+ FspsUpd->FspsConfig.PcieRpSpeed[PortIndex] = SystemConfiguration->PcieRootPortSpeed[PortIndex];
+ FspsUpd->FspsConfig.PcieRpSelectableDeemphasis[PortIndex] = SystemConfiguration->PcieRootPortSelectableDeemphasis[PortIndex];
+
+ //
+ // LTR settings
+ //
+ FspsUpd->FspsConfig.PcieRpLtrEnable[PortIndex] = SystemConfiguration->PchPcieLtrEnable[PortIndex];
+ FspsUpd->FspsConfig.PcieRpLtrConfigLock[PortIndex] = SystemConfiguration->PchPcieLtrConfigLock[PortIndex];
+ FspsUpd->FspsConfig.PcieRpLtrMaxSnoopLatency[PortIndex] = SystemConfiguration->PcieLtrMaxSnoopLatency[PortIndex];
+ FspsUpd->FspsConfig.PcieRpLtrMaxNonSnoopLatency[PortIndex] = SystemConfiguration->PcieLtrMaxNoSnoopLatency[PortIndex];
+ FspsUpd->FspsConfig.PcieRpSnoopLatencyOverrideMode[PortIndex] = SystemConfiguration->PchPcieSnoopLatencyOverrideMode[PortIndex];
+ FspsUpd->FspsConfig.PcieRpSnoopLatencyOverrideMultiplier[PortIndex] = SystemConfiguration->PchPcieSnoopLatencyOverrideMultiplier[PortIndex];
+ FspsUpd->FspsConfig.PcieRpSnoopLatencyOverrideValue[PortIndex] = SystemConfiguration->PchPcieSnoopLatencyOverrideValue[PortIndex];
+ FspsUpd->FspsConfig.PcieRpNonSnoopLatencyOverrideMode[PortIndex] = SystemConfiguration->PchPcieNonSnoopLatencyOverrideMode[PortIndex];
+ FspsUpd->FspsConfig.PcieRpNonSnoopLatencyOverrideMultiplier[PortIndex] = SystemConfiguration->PchPcieNonSnoopLatencyOverrideMultiplier[PortIndex];
+ FspsUpd->FspsConfig.PcieRpNonSnoopLatencyOverrideValue[PortIndex] = SystemConfiguration->PchPcieNonSnoopLatencyOverrideValue[PortIndex];
+ FspsUpd->FspsConfig.PtmEnable[PortIndex] = TRUE;
+ }
+#if (ENBDT_PF_ENABLE == 1)
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[0] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [0] = 2;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[1] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [1] = 3;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[2] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [2] = 0;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[3] = FALSE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [3] = 0xF;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[4] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [4] = 0x1;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[5] = FALSE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [5] = 0xF;
+#endif
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[0] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [0] = 2;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[1] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [1] = 3;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[2] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [2] = 1;
+ FspsUpd->FspsConfig.PcieRpClkReqSupported[4] = TRUE;
+ FspsUpd->FspsConfig.PcieRpClkReqNumber [4] = 0;
+
+ //
+ // Set SATA configuration according to setup value
+ //
+ FspsUpd->FspsConfig.EnableSata = SystemConfiguration->Sata;
+ FspsUpd->FspsConfig.SataMode = SystemConfiguration->SataInterfaceMode;
+ FspsUpd->FspsConfig.SataSalpSupport = SystemConfiguration->SataSalp;
+ for (PortIndex = 0; PortIndex < SC_MAX_SATA_PORTS; PortIndex++) {
+ FspsUpd->FspsConfig.SataPortsEnable[PortIndex] = SystemConfiguration->SataPort[PortIndex];
+ FspsUpd->FspsConfig.SataPortsHotPlug[PortIndex] = SystemConfiguration->SataHotPlug[PortIndex];
+ FspsUpd->FspsConfig.SataPortsSpinUp[PortIndex] = SystemConfiguration->SataSpinUp[PortIndex];
+ FspsUpd->FspsConfig.SataPortsExternal[PortIndex] = FALSE;
+ FspsUpd->FspsConfig.SataPortsDevSlp[PortIndex] = SystemConfiguration->PxDevSlp[PortIndex];
+ FspsUpd->FspsConfig.SataPortsEnableDitoConfig[PortIndex] = SystemConfiguration->EnableDitoConfig[PortIndex];
+ FspsUpd->FspsConfig.SataPortsDmVal[PortIndex] = SystemConfiguration->DmVal[PortIndex];
+ FspsUpd->FspsConfig.SataPortsDitoVal[PortIndex] = SystemConfiguration->DitoVal[PortIndex];
+ FspsUpd->FspsConfig.SataPortsSolidStateDrive[PortIndex] = SystemConfiguration->SataType[PortIndex];
+ }
+ FspsUpd->FspsConfig.SataTestMode = SystemConfiguration->SataTestMode;
+
+ //
+ // Flash Security Recommendation,
+ // Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit
+ // will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+ // BIOS lock down bit is enabled by default as per Platform policy, except that when system is in recovery mode or FDO is enabled. In this case this will be disabled as part of Firmware Update / Recovery update
+ //
+
+ HeciBaseAddress = MmPciBase (
+ SEC_BUS,
+ SEC_DEVICE_NUMBER,
+ HECI_FUNCTION_NUMBER
+ );
+ SecMode = MmioRead32 (HeciBaseAddress + R_SEC_FW_STS0);
+ DEBUG ((DEBUG_INFO, " BIOS lock -CSE Status :%x in Register Value :0x%08X and 0x%08X \n", (SecMode & 0xF0000), SecMode, HeciBaseAddress));
+
+ if ((GetBxtSeries() == BxtP)&& ((SEC_MODE_NORMAL == (SecMode & 0xF0000)))) {
+ FspsUpd->FspsConfig.BiosInterface = TRUE;
+ FspsUpd->FspsConfig.BiosLock = SystemConfiguration->ScBiosLock;
+ DEBUG ((DEBUG_INFO, "ScBiosLock = %d\n", SystemConfiguration->ScBiosLock));
+ if (SystemConfiguration->ScBiosLock) {
+ FspsUpd->FspsConfig.SpiEiss = TRUE;
+ } else {
+ FspsUpd->FspsConfig.SpiEiss = FALSE;
+ }
+ } else {
+ FspsUpd->FspsConfig.BiosInterface = FALSE;
+ FspsUpd->FspsConfig.BiosLock = FALSE;
+ FspsUpd->FspsConfig.SpiEiss = FALSE;
+ }
+ FspsUpd->FspsConfig.RtcLock = SystemConfiguration->RtcLock;
+ //
+ // Set HDA configuration according to setup value
+ //
+ FspsUpd->FspsConfig.HdaEnable = SystemConfiguration->ScHdAudio;
+ FspsUpd->FspsConfig.DspEnable = SystemConfiguration->ScHdAudioDsp;
+ FspsUpd->FspsConfig.Mmt = SystemConfiguration->ScHdAudioMmt;
+ FspsUpd->FspsConfig.Hmt = SystemConfiguration->ScHdAudioHmt;
+ FspsUpd->FspsConfig.HdAudioIoBufferOwnership = SystemConfiguration->ScHdAudioIoBufferOwnership;
+
+ Status = GetConfigBlock ((VOID *) ScPolicy, &gHdAudioConfigGuid, (VOID *) &HdaConfig);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ FspsUpd->FspsConfig.HdaVerbTableEntryNum = HdaConfig->VerbTableEntryNum;
+ FspsUpd->FspsConfig.HdaVerbTablePtr = HdaConfig->VerbTablePtr;
+ }
+ FspsUpd->FspsConfig.BiosCfgLockDown = SystemConfiguration->ScHdAudioBiosCfgLockDown;
+ FspsUpd->FspsConfig.HDAudioPwrGate = SystemConfiguration->ScHdAudioPwrGate;
+ FspsUpd->FspsConfig.HDAudioClkGate = SystemConfiguration->ScHdAudioClkGate;
+ FspsUpd->FspsConfig.Pme = SystemConfiguration->ScHdAudioPme;
+ FspsUpd->FspsConfig.DspEndpointDmic = SystemConfiguration->ScHdAudioNhltEndpointDmic;
+ FspsUpd->FspsConfig.DspEndpointBluetooth = SystemConfiguration->ScHdAudioNhltEndpointBt;
+
+ if (FspsUpd->FspsConfig.HdAudioIoBufferOwnership == ScHdaIoBufOwnerHdaLink) {
+ FspsUpd->FspsConfig.DspEndpointI2sSkp = FALSE;
+ FspsUpd->FspsConfig.DspEndpointI2sHp = FALSE;
+ } else {
+ FspsUpd->FspsConfig.DspEndpointI2sSkp = SystemConfiguration->ScHdAudioNhltEndpointI2sSKP;
+ FspsUpd->FspsConfig.DspEndpointI2sHp = SystemConfiguration->ScHdAudioNhltEndpointI2sHP;
+ }
+ FspsUpd->FspsConfig.HdAudioVcType = SystemConfiguration->SvHdaVcType;
+ FspsUpd->FspsConfig.HdAudioLinkFrequency = SystemConfiguration->HdAudioLinkFrequency;
+ FspsUpd->FspsConfig.HdAudioIDispLinkFrequency = SystemConfiguration->IDispLinkFrequency;
+ FspsUpd->FspsConfig.HdAudioIDispLinkTmode = SystemConfiguration->IDispLinkTmode;
+ for (HdaIndex = 0; HdaIndex < HDAUDIO_FEATURES; HdaIndex++) {
+ FspsUpd->FspsConfig.DspFeatureMask |= (UINT32) (SystemConfiguration->ScHdAudioFeature[HdaIndex] ? (1 << HdaIndex) : 0);
+ }
+ for(HdaIndex = 0; HdaIndex < HDAUDIO_PP_MODULES; HdaIndex++) {
+ FspsUpd->FspsConfig.DspPpModuleMask |= (UINT32) (SystemConfiguration->ScHdAudioPostProcessingMod[HdaIndex] ? (1 << HdaIndex) : 0);
+ }
+ FspsUpd->FspsConfig.ResetWaitTimer = 300;
+
+ //
+ // Set GMM configuration according to setup value
+ //
+ FspsUpd->FspsConfig.Gmm = SystemConfiguration->Gmm;
+ FspsUpd->FspsConfig.ClkGatingPgcbClkTrunk = SystemConfiguration->GmmCgPGCBEnabled;
+ FspsUpd->FspsConfig.ClkGatingSb = SystemConfiguration->GmmCgSBDEnabled;
+ FspsUpd->FspsConfig.ClkGatingSbClkTrunk = SystemConfiguration->GmmCgSBTEnabled;
+ FspsUpd->FspsConfig.ClkGatingSbClkPartition = SystemConfiguration->GmmCgSBPEnabled;
+ FspsUpd->FspsConfig.ClkGatingCore = SystemConfiguration->GmmCgCoreEnabled;
+ FspsUpd->FspsConfig.ClkGatingDma = SystemConfiguration->GmmCgDmaEnabled;
+ FspsUpd->FspsConfig.ClkGatingRegAccess = SystemConfiguration->GmmCgRAEnabled;
+ FspsUpd->FspsConfig.ClkGatingHost = SystemConfiguration->GmmCgHostEnabled;
+ FspsUpd->FspsConfig.ClkGatingPartition = SystemConfiguration->GmmCgPEnabled;
+ FspsUpd->FspsConfig.ClkGatingTrunk = SystemConfiguration->GmmCgTEnabled;
+
+ //
+ // Set ISH configuration according to setup value.
+ //
+ FspsUpd->FspsConfig.IshEnable = SystemConfiguration->ScIshEnabled;
+
+ //
+ // Set USB Device 21 configuration according to setup value
+ //
+ FspsUpd->FspsConfig.DisableComplianceMode = SystemConfiguration->DisableComplianceMode;
+
+ //
+ // Set xHCI (USB 3.0) configuration according to setup value
+ //
+ FspsUpd->FspsConfig.Usb30Mode = SystemConfiguration->ScUsb30Mode;
+ FspsUpd->FspsConfig.SsicPortEnable[0] = SystemConfiguration->Ssic1Support;
+ FspsUpd->FspsConfig.SsicPortEnable[1] = SystemConfiguration->Ssic2Support;
+ FspsUpd->FspsConfig.SsicRate[0] = SystemConfiguration->Ssic1Rate;
+ FspsUpd->FspsConfig.SsicRate[1] = SystemConfiguration->Ssic2Rate;
+ FspsUpd->FspsConfig.DlanePwrGating = SystemConfiguration->SsicDlanePg;
+ FspsUpd->FspsConfig.UsbOtg = SystemConfiguration->ScUsbOtg;
+
+ //
+ // Overcurrent applies to walk-up xHCI ports only - not SSIC or HSIC
+ //
+ // OC0: Used for the OTG port (port 0)
+ // OC1: Used for the 2 host walk-up ports
+ //
+#if (ENBDT_PF_ENABLE == 1)
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[0] = ScUsbOverCurrentPin0;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[1] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[2] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[3] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[4] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[5] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[6] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[7] = ScUsbOverCurrentPinSkip;
+
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[0] = ScUsbOverCurrentPin0;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[1] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[2] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[3] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[4] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[5] = ScUsbOverCurrentPin1;
+
+ for (DevIndex = 0; DevIndex < GetScXhciMaxUsb2PortNum (); DevIndex++) {
+ FspsUpd->FspsConfig.PortUsb20Enable[DevIndex]= SystemConfiguration->PortUsb20[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < GetScXhciMaxUsb3PortNum (); DevIndex++) {
+ FspsUpd->FspsConfig.PortUsb30Enable[DevIndex]= SystemConfiguration->PortUsb30[DevIndex];
+ }
+#else
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[0] = ScUsbOverCurrentPin0;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[1] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[2] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[3] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[4] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[5] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[6] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs20bOverCurrentPin[7] = ScUsbOverCurrentPinSkip;
+
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[0] = ScUsbOverCurrentPin0;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[1] = ScUsbOverCurrentPin1;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[2] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[3] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[4] = ScUsbOverCurrentPinSkip;
+ FspsUpd->FspsConfig.PortUs30bOverCurrentPin[5] = ScUsbOverCurrentPinSkip;
+
+ FspsUpd->FspsConfig.PortUsb20Enable[0] = TRUE;
+ FspsUpd->FspsConfig.PortUsb20Enable[1] = TRUE;
+ FspsUpd->FspsConfig.PortUsb20Enable[2] = TRUE;
+ FspsUpd->FspsConfig.PortUsb20Enable[3] = FALSE;
+ FspsUpd->FspsConfig.PortUsb20Enable[4] = FALSE;
+ FspsUpd->FspsConfig.PortUsb20Enable[5] = FALSE;
+ FspsUpd->FspsConfig.PortUsb20Enable[6] = FALSE;
+ FspsUpd->FspsConfig.PortUsb20Enable[7] = FALSE;
+
+ FspsUpd->FspsConfig.PortUsb30Enable[0] = TRUE;
+ FspsUpd->FspsConfig.PortUsb30Enable[1] = TRUE;
+ FspsUpd->FspsConfig.PortUsb30Enable[2] = FALSE;
+ FspsUpd->FspsConfig.PortUsb30Enable[3] = FALSE;
+ FspsUpd->FspsConfig.PortUsb30Enable[4] = FALSE;
+ FspsUpd->FspsConfig.PortUsb30Enable[5] = FALSE;
+#endif
+
+ //
+ // Set LPSS configuration according to setup value.
+ //
+ FspsUpd->FspsConfig.I2c0Enable = SystemConfiguration->LpssI2C0Enabled;
+ FspsUpd->FspsConfig.I2c1Enable = SystemConfiguration->LpssI2C1Enabled;
+ FspsUpd->FspsConfig.I2c2Enable = SystemConfiguration->LpssI2C2Enabled;
+ FspsUpd->FspsConfig.I2c3Enable = SystemConfiguration->LpssI2C3Enabled;
+ FspsUpd->FspsConfig.I2c4Enable = SystemConfiguration->LpssI2C4Enabled;
+ FspsUpd->FspsConfig.I2c5Enable = SystemConfiguration->LpssI2C5Enabled;
+ FspsUpd->FspsConfig.I2c6Enable = SystemConfiguration->LpssI2C6Enabled;
+ FspsUpd->FspsConfig.I2c7Enable = SystemConfiguration->LpssI2C7Enabled;
+ FspsUpd->FspsConfig.Hsuart0Enable = SystemConfiguration->LpssHsuart0Enabled;
+ FspsUpd->FspsConfig.Hsuart1Enable = SystemConfiguration->LpssHsuart1Enabled;
+ FspsUpd->FspsConfig.Hsuart2Enable = SystemConfiguration->LpssHsuart2Enabled;
+ FspsUpd->FspsConfig.Hsuart3Enable = SystemConfiguration->LpssHsuart3Enabled;
+ FspsUpd->FspsConfig.Spi0Enable = SystemConfiguration->LpssSpi0Enabled;
+ FspsUpd->FspsConfig.Spi1Enable = SystemConfiguration->LpssSpi1Enabled;
+ FspsUpd->FspsConfig.Spi2Enable = SystemConfiguration->LpssSpi2Enabled;
+ FspsUpd->FspsConfig.Uart2KernelDebugBaseAddress = SystemConfiguration->Uart2KernelDebugBaseAddress;
+ for (DevIndex = 0; DevIndex < LPSS_I2C_DEVICE_NUM; DevIndex++) {
+ FspsUpd->FspsConfig.I2cClkGateCfg[DevIndex] = SystemConfiguration->LpssI2cClkGateCfg[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < LPSS_HSUART_DEVICE_NUM; DevIndex++) {
+ FspsUpd->FspsConfig.HsuartClkGateCfg[DevIndex] = SystemConfiguration->LpssHsuartClkGateCfg[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < LPSS_SPI_DEVICE_NUM; DevIndex++) {
+ FspsUpd->FspsConfig.SpiClkGateCfg[DevIndex] = SystemConfiguration->LpssSpiClkGateCfg[DevIndex];
+ }
+ //
+ // Kernel Debugger (e.g. WinDBG) Enable
+ //
+ FspsUpd->FspsConfig.OsDbgEnable = (BOOLEAN) SystemConfiguration->OsDbgEnable;
+ FspsUpd->FspsConfig.LPSS_S0ixEnable = (BOOLEAN) SystemConfiguration->LowPowerS0Idle;
+
+ FspsUpd->FspsConfig.DciEn = SystemConfiguration->DciEn;
+ FspsUpd->FspsConfig.DciAutoDetect = SystemConfiguration->DciAutoDetect;
+
+ //
+ // Set SCS configuration according to setup value.
+ //
+ FspsUpd->FspsConfig.SdcardEnabled = SystemConfiguration->SccSdcardEnabled;
+ FspsUpd->FspsConfig.UfsEnabled = 0;
+ FspsUpd->FspsConfig.eMMCEnabled = SystemConfiguration->ScceMMCEnabled;
+ FspsUpd->FspsConfig.SdioEnabled = SystemConfiguration->SccSdioEnabled;
+ FspsUpd->FspsConfig.eMMCHostMaxSpeed = SystemConfiguration->ScceMMCHostMaxSpeed;
+ FspsUpd->FspsConfig.GppLock = SystemConfiguration->GPPLock;
+ FspsUpd->FspsConfig.SdioTxCmdCntl = 0x505;
+ FspsUpd->FspsConfig.SdioTxDataCntl1 = 0xE;
+ FspsUpd->FspsConfig.SdioTxDataCntl2 = 0x22272828;
+ FspsUpd->FspsConfig.SdioRxCmdDataCntl1 = 0x16161616;
+ FspsUpd->FspsConfig.SdioRxCmdDataCntl2 = 0x10000;
+ FspsUpd->FspsConfig.SdcardTxCmdCntl = 0x505;
+ FspsUpd->FspsConfig.SdcardTxDataCntl1 = 0xA13;
+ FspsUpd->FspsConfig.SdcardTxDataCntl2 = 0x24242828;
+ FspsUpd->FspsConfig.SdcardRxCmdDataCntl1 = 0x73A3637;
+ FspsUpd->FspsConfig.SdcardRxStrobeCntl = 0x0;
+ FspsUpd->FspsConfig.SdcardRxCmdDataCntl2 = 0x10000;
+ FspsUpd->FspsConfig.EmmcTxCmdCntl = 0x505;
+ FspsUpd->FspsConfig.EmmcTxDataCntl1 = 0xC11;
+ FspsUpd->FspsConfig.EmmcTxDataCntl2 = 0x1C2A2927;
+ FspsUpd->FspsConfig.EmmcRxCmdDataCntl1 = 0x000D162F;
+ FspsUpd->FspsConfig.EmmcRxStrobeCntl = 0x0a0a;
+ FspsUpd->FspsConfig.EmmcRxCmdDataCntl2 = 0x1003b;
+ FspsUpd->FspsConfig.EmmcMasterSwCntl = 0x001;
+
+ if (SystemConfiguration->ScceMMCEnabled == DEVICE_AUTO) {
+ if (IseMMCBoot ()) {
+ FspsUpd->FspsConfig.eMMCEnabled = DEVICE_ENABLE;
+ } else {
+ FspsUpd->FspsConfig.eMMCEnabled = DEVICE_DISABLE;
+ }
+ }
+
+ //
+ //Update P2sbUnhide Policy
+ //
+ FspsUpd->FspsConfig.P2sbUnhide = 1;
+ FspsUpd->FspsConfig.VtdEnable = SystemConfiguration->VTdEnable;
+
+ //
+ // Power management Configuration
+ //
+ if (SystemConfiguration->Cg8254 == 0) {
+ FspsUpd->FspsConfig.Timer8254ClkSetting = FALSE;
+ }
+ FspsUpd->FspsConfig.PowerButterDebounceMode = SystemConfiguration->PowerButterDebounceMode;
+ //
+ // Set Flash Protection configuration according to setup data
+ //
+ if ((GetBxtSeries() == BxtP) && (IsSpiBoot ())) {
+ //
+ // Configure Flash Protection Range Registers
+ //
+ FlashProtectionEnabled = SystemConfiguration->FprrEnable == TRUE ? TRUE : FALSE;
+
+ //
+ // Enabling Flash Protection Range Registers
+ // Enable FPRR policy and set up ranges on non-Capsule Update flow with Flash Wear-Out Protection enabled
+ // PrintFlashProtectionConfig() dumps FPRR information during ScPrintPolicyPpi()
+ // Enable the FPRR Bit is enabled by default as per Platform policy, except that when system is in recovery mode or FDO is enabled. In this case this will be disabled as part of Firmware Update / Recovery update
+ //
+ if (FlashProtectionEnabled && (SEC_MODE_NORMAL == (SecMode & 0xF0000))) {
+ //
+ // Flash Protection Range Register initialization
+ //
+ for (Index = 0; Index < SC_FLASH_PROTECTED_RANGES; Index++) {
+ FspsUpd->FspsConfig.WriteProtectionEnable[Index] = TRUE;
+ FspsUpd->FspsConfig.ReadProtectionEnable[Index] = FALSE;
+ }
+
+ //
+ // Assign FPRR ranges
+ //
+ Status = GetConfigBlock ((VOID *) ScPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ FspsUpd->FspsConfig.ProtectedRangeBase[0] = FlashProtectionConfig->ProtectRange[0].ProtectedRangeBase;
+ FspsUpd->FspsConfig.ProtectedRangeLimit[0] = FlashProtectionConfig->ProtectRange[0].ProtectedRangeLimit;
+ FspsUpd->FspsConfig.ProtectedRangeBase[1] = FlashProtectionConfig->ProtectRange[1].ProtectedRangeBase;
+ FspsUpd->FspsConfig.ProtectedRangeLimit[1] = FlashProtectionConfig->ProtectRange[1].ProtectedRangeLimit;
+ }
+ } // if (FlashProtectionEnabled)
+ } // if ((GetBxtSeries() == BxtP) && (IsSpiBoot ()))
+ } // if (Status == EFI_SUCCESS)
+ DEBUG ((DEBUG_INFO, "PeiFspScPolicyInit - End\n"));
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
new file mode 100644
index 0000000000..37e5cb7ff4
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
@@ -0,0 +1,54 @@
+/** @file
+ Implementation of Fsp SI Policy Initialization.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/SiPolicyPpi.h>
+
+/**
+ Performs FSP SI PEI Policy initialization.
+
+ @param[in, out] FspmUpd Pointer to FSP UPD Data.
+
+ @retval EFI_SUCCESS FSP UPD Data is updated.
+ @retval EFI_NOT_FOUND Fail to locate required PPI.
+ @retval Other FSP UPD Data update process fail.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ )
+{
+ EFI_STATUS Status;
+ SI_POLICY_PPI *SiPolicyPpi;
+
+ //
+ // Locate SiPolicyPpi
+ //
+ SiPolicyPpi = NULL;
+ Status = PeiServicesLocatePpi (
+ &gSiPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SiPolicyPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.c
new file mode 100644
index 0000000000..f56097f3a7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.c
@@ -0,0 +1,198 @@
+/** @file
+ Platform Configuration Update library implementation file.
+ This library updates the setup data with platform overrides.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Guid/PlatformInfo.h>
+#include <Guid/TpmInstance.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiPlatformConfigUpdateLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/SteppingLib.h>
+#include <Ppi/DramPolicyPpi.h>
+
+#define SETUP_NFC_Disabled 0
+#define SETUP_NFC_IPT 1
+#define SETUP_NFC 2
+
+EFI_STATUS
+TpmSetupPolicyInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+#if FTPM_SUPPORT
+ EFI_STATUS Status;
+ BOOLEAN PttEnabledState = FALSE;
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+
+ if (SystemConfiguration->TpmDetection == 0) {
+ Status = PttHeciGetState (&PttEnabledState);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Get PTT enabled state failed.\n"));
+ }
+
+ if (PttEnabledState && (FdoEnabledGuidHob == NULL)) {
+ SystemConfiguration->TPM = TPM_PTT;
+ } else {
+ DEBUG ((EFI_D_INFO, "TpmPolicyInit-TPM and TpmDetection is disabled because of FDO \n\r"));
+ SystemConfiguration->TPM = TPM_DISABLE;
+ }
+ SystemConfiguration->TpmDetection = 1;
+ }
+
+#endif
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetSecureNfcInfo (
+ SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS GuidHob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo = NULL;
+ MEFWCAPS_SKU CurrentFeatures;
+ UINT32 EnableBitmap = 0;
+ UINT32 DisableBitmap = 0;
+ BOOLEAN Cse_Nfc_Strap = FALSE;
+ BOOLEAN SecureNfcInSetup = FALSE;
+ BOOLEAN Fab_B_C = FALSE;
+
+ DEBUG ((EFI_D_INFO, "GetSecureNfcInfo ++ \n"));
+
+ if (SystemConfiguration->NfcSelect == SETUP_NFC_IPT) {
+ SecureNfcInSetup = TRUE;
+ }
+
+ DEBUG ((EFI_D_INFO, "Old NfcSelect: %d\n", SystemConfiguration->NfcSelect));
+
+ Status = HeciGetFwFeatureStateMsgII (&CurrentFeatures);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if (CurrentFeatures.Fields.NFC == 1) {
+ Cse_Nfc_Strap = TRUE;
+ }
+
+ DEBUG ((EFI_D_INFO, "HeciGetFwFeatureStateMsgII CurrentFeatures.Fields.NFC: %d\n", CurrentFeatures.Fields.NFC));
+
+ //
+ // Get the HOB list. If it is not present, then ASSERT.
+ //
+ GuidHob.Raw = GetHobList ();
+ if (GuidHob.Raw != NULL) {
+ if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
+ PlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
+ }
+ }
+
+ if (PlatformInfo == NULL) {
+ ASSERT (PlatformInfo != NULL);
+ return EFI_NOT_FOUND;
+ }
+
+ if ((!Cse_Nfc_Strap) && SecureNfcInSetup && (!Fab_B_C)){
+ //
+ // Enable secure NFC
+ //
+ DEBUG ((EFI_D_INFO, "Enable NFC\n"));
+ EnableBitmap = NFC_BITMASK;
+ DisableBitmap = CLEAR_FEATURE_BIT;
+ } else if ( (SecureNfcInSetup && Fab_B_C) ||\
+ (Cse_Nfc_Strap && (!SecureNfcInSetup)) \
+ ) {
+ //
+ // Disable secure NFC
+ //
+ DEBUG ((EFI_D_INFO, "Disable NFC\n"));
+ EnableBitmap = CLEAR_FEATURE_BIT;
+ DisableBitmap = NFC_BITMASK;
+ SystemConfiguration->NfcSelect = SETUP_NFC;
+ }
+
+ Status = HeciFwFeatureStateOverride (EnableBitmap, DisableBitmap);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "NfcSelect: %d\n", SystemConfiguration->NfcSelect));
+
+ return Status;
+}
+
+
+/**
+ Updates Setup values from PlatformInfoHob and platform policies.
+
+ @param PreDefaultSetupData A pointer to the setup data prior to being
+ placed in the default data HOB.
+
+ @retval EFI_SUCCESS The Setup data was updated successfully.
+
+**/
+EFI_STATUS
+UpdateSetupDataValues (
+ SYSTEM_CONFIGURATION *PreDefaultSetupData
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+ DRAM_POLICY_PPI *DramPolicyPpi;
+
+ Status = PeiServicesLocatePpi (
+ &gDramPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &DramPolicyPpi
+ );
+
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "Couldn't find DRAM policy PPI: %g, Status: %r.\n", &gDramPolicyPpiGuid, Status));
+ } else {
+ DEBUG ((EFI_D_INFO, "Overriding Memory System Config Data using DRAM Policy.\n"));
+ PreDefaultSetupData->ChannelHashMask = DramPolicyPpi->ChannelHashMask;
+ PreDefaultSetupData->SliceHashMask = DramPolicyPpi->SliceHashMask;
+ PreDefaultSetupData->ChannelsSlicesEnabled = DramPolicyPpi->ChannelsSlicesEnabled;
+ PreDefaultSetupData->ScramblerSupport = DramPolicyPpi->ScramblerSupport;
+ PreDefaultSetupData->InterleavedMode = DramPolicyPpi->InterleavedMode;
+ PreDefaultSetupData->MinRefRate2xEnabled = DramPolicyPpi->MinRefRate2xEnabled;
+ PreDefaultSetupData->DualRankSupportEnabled = DramPolicyPpi->DualRankSupportEnabled;
+ }
+
+ if (FdoEnabledGuidHob != NULL) {
+ PreDefaultSetupData->SecureBoot = FALSE;
+ PreDefaultSetupData->FprrEnable = FALSE;
+ PreDefaultSetupData->ScBiosLock = FALSE;
+ DEBUG ((EFI_D_INFO, "SPI FDO mode is enabled. Disabling SecureBoot, FprrEnable, and ScBiosLock.\n"));
+ }
+
+ Status = GetSecureNfcInfo (PreDefaultSetupData);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = TpmSetupPolicyInit (PreDefaultSetupData);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.inf
new file mode 100644
index 0000000000..3e354bb230
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPlatformConfigUpdateLib/PeiPlatformConfigUpdateLib.inf
@@ -0,0 +1,56 @@
+## @file
+# Platform configuration update library.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiPlatformConfigUpdateLib
+ FILE_GUID = 7677AA3B-A9B4-402C-A8D2-03CE02D6DC2E
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiPlatformConfigUpdateLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+ DebugLib
+ HeciMsgLib
+ HobLib
+ PcdLib
+ PeiServicesLib
+ SteppingLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ SecurityPkg/SecurityPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Sources]
+ PeiPlatformConfigUpdateLib.c
+
+[Ppis]
+ gSeCfTPMPolicyPpiGuid
+
+[Guids]
+ gEfiPlatformInfoGuid
+ gFdoModeEnabledHobGuid
+ gEfiTpmDeviceSelectedGuid
+ gEfiTpmDeviceInstanceNoneGuid
+ gEfiTpmDeviceInstanceTpm12Guid
+ gEfiTpmDeviceInstanceTpm20DtpmGuid
+ gTpmDeviceInstanceTpm20PttPtpGuid
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.c
new file mode 100644
index 0000000000..4d8336b7f3
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.c
@@ -0,0 +1,96 @@
+/** @file
+ This file is SampleCode for Intel CPU PEI Policy initialzation.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiCpuPolicyInit.h"
+
+/**
+ This function performs CPU PEI Policy initialization in Pre-Memory.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES No enough resoruces (such as out of memory).
+
+**/
+EFI_STATUS
+EFIAPI
+PeiCpuPolicyInitPreMem (
+ )
+{
+ EFI_STATUS Status;
+ SI_CPU_POLICY_PPI *SiCpuPolicyPpi;
+
+ //
+ // Call CpuCreatePolicyDefaults to initialize platform policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = CreateCpuConfigBlocks (&SiCpuPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update Pre-Mem Policy related policies.
+ //
+ UpdatePeiCpuPolicyPreMem (SiCpuPolicyPpi);
+
+ //
+ // Install SiCpuPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = CpuInstallPolicyPpi (SiCpuPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ This function performs CPU PEI Policy initialization in Post-Memory.
+
+ @param[in] SystemConfiguration The pointer to get System Setup
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES No enough resoruces (such as out of memory).
+
+**/
+EFI_STATUS
+EFIAPI
+PeiCpuPolicyInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ SI_CPU_POLICY_PPI *SiCpuPolicyPpi;
+
+ //
+ // Call CreateCpuConfigBlocks to initialize platform policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = CreateCpuConfigBlocks (&SiCpuPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ UpdatePeiCpuPolicy (SiCpuPolicyPpi, SystemConfiguration);
+
+ //
+ // Install SiCpuPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = CpuInstallPolicyPpi (SiCpuPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
new file mode 100644
index 0000000000..98cc506dfb
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
@@ -0,0 +1,60 @@
+/** @file
+ Header file for the PeiCpuPolicyInit.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_CPU_POLICY_INIT_H_
+#define _PEI_CPU_POLICY_INIT_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Guid/SetupVariable.h>
+#include <Library/PeiCpuPolicyUpdateLib.h>
+
+//
+// Function prototypes
+//
+/**
+ This function performs CPU PEI Policy initialization in Pre-Memory.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES No enough resoruces (such as out of memory).
+
+**/
+EFI_STATUS
+EFIAPI
+PeiCpuPolicyInitPreMem (
+ );
+
+/**
+ This function performs CPU PEI Policy initialization in Post-Memory.
+
+ @param[in] SystemConfiguration The pointer to get System Setup
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES No enough resoruces (such as out of memory).
+
+**/
+EFI_STATUS
+EFIAPI
+PeiCpuPolicyInit (
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ );
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.c
new file mode 100644
index 0000000000..eab67edb0b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.c
@@ -0,0 +1,46 @@
+/** @file
+ This file is SampleCode for Intel PEI Platform Policy initialzation.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+ Initialize Intel PEI Platform Policy
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' varaible.
+
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "PeiPolicyInit - Start\n"));
+
+ //
+ // CPU PEI Policy Initialization
+ //
+ Status = PeiCpuPolicyInit (SystemConfiguration);
+ DEBUG ((DEBUG_INFO, "CPU PEI Policy Initialization Done in Post-Memory\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "PeiPolicyInit - End\n"));
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.h
new file mode 100644
index 0000000000..1e23002370
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInit.h
@@ -0,0 +1,27 @@
+/** @file
+ Header file for the PolicyInitPei PEIM.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_POLICY_INIT_H_
+#define _PEI_POLICY_INIT_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "PeiSaPolicyInit.h"
+#include "PeiSiPolicyInit.h"
+#include "PeiCpuPolicyInit.h"
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
new file mode 100644
index 0000000000..db70e74c83
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
@@ -0,0 +1,55 @@
+## @file
+# Component description file for PeiPolicyInit library.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiPolicyInit
+ FILE_GUID = BB1CBA6F-ABB3-445d-801F-2C584C1197D3
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiPolicyInitLib
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ DebugPrintErrorLevelLib
+ HobLib
+ PeiServicesLib
+ PeiPolicyUpdateLib
+ PeiSaPolicyLib
+ ConfigBlockLib
+ SteppingLib
+ CpuPolicyLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ PeiPolicyInitPreMem.c
+ PeiPolicyInit.c
+ PeiPolicyInit.h
+ PeiCpuPolicyInit.c
+ PeiCpuPolicyInit.h
+ PeiSaPolicyInit.c
+ PeiSaPolicyInit.h
+ PeiSiPolicyInit.c
+ PeiSiPolicyInit.h
+
+[Ppis]
+ gSiSaPolicyPpiGuid
+ gScPcieDeviceTablePpiGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
new file mode 100644
index 0000000000..3988218bcd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
@@ -0,0 +1,39 @@
+/** @file
+ This file is SampleCode for Intel PEI Platform Policy initialization.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+ Initialize Intel PEI Platform Policy
+
+**/
+EFI_STATUS
+EFIAPI
+PeiPolicyInitPreMem (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // CPU PEI Policy Initialization
+ //
+ Status = PeiCpuPolicyInitPreMem ();
+ DEBUG ((DEBUG_INFO, "CPU PEI Policy Initialization Done in Pre-Memory\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
new file mode 100644
index 0000000000..5f0300ec59
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
@@ -0,0 +1,57 @@
+/** @file
+ This file is SampleCode for Intel SA PEI Policy initialization.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiSaPolicyInit.h"
+
+/**
+ This PEIM performs SA PEI Policy initialzation.
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' varaible.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the PPI.
+ @retval EFI ERRORS The PPI is not successfully installed.
+
+**/
+EFI_STATUS
+PeiSaPolicyInit (
+ IN UINT8 FirmwareConfiguration
+ )
+{
+ EFI_STATUS Status;
+ SI_SA_POLICY_PPI *SiSaPolicyPpi;
+
+ //
+ // Call SaCreatePolicyDefaults to initialize platform policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = CreateConfigBlocks (&SiSaPolicyPpi);
+ DEBUG ((DEBUG_INFO, "SiSaPolicyPpi->TableHeader.NumberOfBlocks = 0x%x\n ", SiSaPolicyPpi->TableHeader.NumberOfBlocks));
+ ASSERT_EFI_ERROR (Status);
+
+ UpdatePeiSaPolicy (SiSaPolicyPpi);
+
+ //
+ // Install SiSaPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = SiSaInstallPolicyPpi (SiSaPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
new file mode 100644
index 0000000000..d1ce77b794
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
@@ -0,0 +1,58 @@
+/** @file
+ Header file for the SaPolicyInitPei PEIM.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SA_POLICY_INIT_PEI_H_
+#define _SA_POLICY_INIT_PEI_H_
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Ppi/SaPolicy.h>
+#include <Library/PeiSaPolicyUpdateLib.h>
+
+//
+// Functions
+//
+/**
+ <b>This PEIM performs SA PEI Policy initialzation</b> \n
+ - <b>Introduction</b> \n
+ System Agent PEIM behavior can be controlled by platform policy without modifying reference code directly.
+ Platform policy PPI is initialized with default settings in this funciton.
+ Some MRC functions will be initialized in this PEIM to provide the capability for customization.
+ This policy PPI has to be initialized prior to System Agent initialization PEIM and MRC execution.
+
+ - @pre
+ - PEI_READ_ONLY_VARIABLE_PPI
+
+ - @result
+ SI_SA_POLICY_PPI will be installed successfully and ready for System Agent reference code use.
+
+ - <b>Porting Recommendations</b> \n
+ Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' varaible.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the PPI.
+ @retval EFI ERRORS The PPI is not successfully installed.
+
+**/
+EFI_STATUS
+PeiSaPolicyInit (
+ IN UINT8 FirmwareConfiguration
+ );
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.c
new file mode 100644
index 0000000000..dac17f1280
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.c
@@ -0,0 +1,60 @@
+/** @file
+ This file is SampleCode for Intel Silicon PEI Policy initialzation.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiSiPolicyInit.h"
+
+/**
+ This function performs Silicon Policy initialzation.
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' varaible.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+PeiSiPolicyInit (
+ IN UINT8 FirmwareConfiguration
+ )
+{
+ EFI_STATUS Status;
+ SI_POLICY_PPI *SiPolicyPpi;
+
+ //
+ // Call SiCreatePolicyDefaults to initialize Silicon Policy structure
+ // and get all Intel default policy settings.
+ //
+ Status = SiCreatePolicyDefaults (&SiPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update and override all platform related and customized settings below.
+ //
+ UpdatePeiSiPolicy (SiPolicyPpi);
+
+ //
+ // Install SiPolicyPpi.
+ // While installed, RC assumes the Policy is ready and finalized. So please
+ // update and override any setting before calling this function.
+ //
+ Status = SiInstallPolicyPpi (SiPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
new file mode 100644
index 0000000000..783421fe8a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
@@ -0,0 +1,47 @@
+/** @file
+ Header file for the PeiSiPolicyInit.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SI_POLICY_INIT_PEI_H_
+#define _SI_POLICY_INIT_PEI_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+
+//
+// Functions
+//
+/**
+ This function performs Silicon Policy initialzation.
+
+ @param[in] FirmwareConfiguration It uses to skip specific policy init that depends
+ on the 'FirmwareConfiguration' varaible.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiSiPolicyInit (
+ IN UINT8 FirmwareConfiguration
+ );
+
+#endif // _SI_POLICY_INIT_PEI_H_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.c
new file mode 100644
index 0000000000..6cd068e418
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.c
@@ -0,0 +1,175 @@
+/** @file
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HdaVerbTables.h"
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc662 = {
+ //
+ // VerbTable: (Realtek ALC662)
+ // Revision ID = 0xff
+ // Codec Verb Table for IOTG CRB boards
+ // Codec Address: CAd value (0/1/2)
+ // Codec Vendor: 0x10EC0662
+ //
+ {
+ 0x10EC0662, // Vendor ID / Device ID
+ 0xFF, // Revision ID
+ 0xFF, // SDI number, 0xFF matches any SDI.
+ 15 * 4 // Number of data DWORDs following the header.
+ },
+ {
+ //
+ // Realtek Semiconductor Corp.
+ //
+ // Realtek High Definition Audio Configuration - Version : 5.0.2.6
+ // Realtek HD Audio Codec : ALC662-VD
+ // PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+ // HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0662&SUBSYS_80860000
+ // The number of verb command block : 15
+ //
+ // NID 0x12 : 0x40130000
+ // NID 0x14 : 0x01014010
+ // NID 0x15 : 0x01011012
+ // NID 0x16 : 0x01016011
+ // NID 0x18 : 0x01A19030
+ // NID 0x19 : 0x02A19040
+ // NID 0x1A : 0x0181303F
+ // NID 0x1B : 0x0221401F
+ // NID 0x1C : 0x411111F0
+ // NID 0x1D : 0x4045E601
+ // NID 0x1E : 0x01441120
+ //
+ //
+ // HDA Codec Subsystem ID Verb-table
+ // HDA Codec Subsystem ID : 0x80860000
+ //
+ 0x00172000,
+ 0x00172100,
+ 0x00172286,
+ 0x00172380,
+
+ //
+ // Pin Widget Verb-table
+ // Widget node 0x01 :
+ //
+ 0x0017FF00,
+ 0x0017FF00,
+ 0x0017FF00,
+ 0x0017FF00,
+
+ //
+ // Pin widget 0x12 - DMIC
+ //
+ 0x01271C00,
+ 0x01271D00,
+ 0x01271E13,
+ 0x01271F40,
+
+ //
+ // Pin widget 0x14 - FRONT (Port-D)
+ //
+ 0x01471C10,
+ 0x01471D40,
+ 0x01471E01,
+ 0x01471F01,
+
+ //
+ // Pin widget 0x15 - SURR (Port-A)
+ //
+ 0x01571C12,
+ 0x01571D10,
+ 0x01571E01,
+ 0x01571F01,
+
+ //
+ // Pin widget 0x16 - CEN/LFE (Port-G)
+ //
+ 0x01671C11,
+ 0x01671D60,
+ 0x01671E01,
+ 0x01671F01,
+
+ //
+ // Pin widget 0x18 - MIC1 (Port-B)
+ //
+ 0x01871C30,
+ 0x01871D90,
+ 0x01871EA1,
+ 0x01871F01,
+
+ //
+ // Pin widget 0x19 - MIC2 (Port-F)
+ //
+ 0x01971C40,
+ 0x01971D90,
+ 0x01971EA1,
+ 0x01971F02,
+
+ //
+ // Pin widget 0x1A - LINE1 (Port-C)
+ //
+ 0x01A71C3F,
+ 0x01A71D30,
+ 0x01A71E81,
+ 0x01A71F01,
+
+ //
+ // Pin widget 0x1B - LINE2 (Port-E)
+ //
+ 0x01B71C1F,
+ 0x01B71D40,
+ 0x01B71E21,
+ 0x01B71F02,
+
+ //
+ // Pin widget 0x1C - CD-IN
+ //
+ 0x01C71CF0,
+ 0x01C71D11,
+ 0x01C71E11,
+ 0x01C71F41,
+
+ //
+ // Pin widget 0x1D - BEEP-IN
+ //
+ 0x01D71C01,
+ 0x01D71DE6,
+ 0x01D71E45,
+ 0x01D71F40,
+
+ //
+ // Pin widget 0x1E - S/PDIF-OUT
+ //
+ 0x01E71C20,
+ 0x01E71D11,
+ 0x01E71E44,
+ 0x01E71F01,
+
+ //
+ // Widget node 0x20 :
+ //
+ 0x02050004,
+ 0x02040001,
+ 0x02050004,
+ 0x02040001,
+
+ //
+ // Widget node 0x20 - 1 :
+ //
+ 0x02050005,
+ 0x02040080,
+ 0x02050001,
+ 0x0204A9B8
+ }
+};
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.h
new file mode 100644
index 0000000000..64a42bc2cb
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/HdaVerbTables.h
@@ -0,0 +1,30 @@
+/** @file
+ Header file for HDA Verb Tables.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HDA_VERBTABLES_H_
+#define _HDA_VERBTABLES_H_
+
+#include <Ppi/ScPolicy.h>
+
+enum HDAUDIO_CODEC_SELECT {
+ HdaCodecPlatformOnboard = 0,
+ HdaCodecExternalKit = 1
+};
+
+extern HDAUDIO_VERB_TABLE HdaVerbTableAlc298;
+extern HDAUDIO_VERB_TABLE HdaVerbTableAlc662;
+
+#endif // _HDA_VERBTABLES_H_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
new file mode 100644
index 0000000000..dbb2bc53d5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
@@ -0,0 +1,232 @@
+/** @file
+ This file is SampleCode of the library for Intel CPU PEI Policy Update initialization.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiCpuPolicyUpdate.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/SteppingLib.h>
+#include <Library/HobLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Platform.h>
+
+
+/**
+ This function performs CPU PEI Policy initialization.
+
+ @param[in] SiCpuPolicyPpi The Cpu Policy PPI instance
+ @param[in] SystemConfiguration The pointer to get System Setup
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+ IN OUT SI_CPU_POLICY_PPI *SiCpuPolicyPpi,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ CPU_CONFIG *CpuConfig;
+ POWER_MGMT_CONFIG *PowerMgmtConfig;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, " Get config block for CpuConfig \n"));
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gPowerMgmtConfigGuid, (VOID *) &PowerMgmtConfig);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, " Get config block for PowerMgmtConfig \n"));
+
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+ CpuConfig->ActiveProcessorCores = SystemConfiguration->ActiveProcessorCores;
+ CpuConfig->DisableCore1 = SystemConfiguration->Core1;
+ CpuConfig->DisableCore2 = SystemConfiguration->Core2;
+ CpuConfig->DisableCore3 = SystemConfiguration->Core3;
+ CpuConfig->VmxEnable = SystemConfiguration->ProcessorVmxEnable;
+ CpuConfig->ProcTraceMemSize = SystemConfiguration->ProcTraceMemSize;
+ CpuConfig->ProcTraceEnable = SystemConfiguration->ProcTraceEnable;
+ CpuConfig->EnableDts = SystemConfiguration->EnableDigitalThermalSensor;
+ PowerMgmtConfig->Eist = SystemConfiguration->EnableGv;
+ PowerMgmtConfig->BootPState = SystemConfiguration->BootPState;
+ PowerMgmtConfig->Cx = SystemConfiguration->EnableCx;
+ PowerMgmtConfig->C1e = SystemConfiguration->EnableCxe;
+ PowerMgmtConfig->BiProcHot = SystemConfiguration->EnableProcHot;
+ PowerMgmtConfig->PkgCStateLimit = (MAX_PKG_C_STATE) SystemConfiguration->MaxPkgCState;
+ PowerMgmtConfig->AutoThermalReporting = SystemConfiguration->AutoThermalReporting;
+
+ if (BxtStepping () >= BxtPB1) {
+ PowerMgmtConfig->PmgCstCfgCtrIoMwaitRedirection = SOC_DEVICE_ENABLE;
+ } else {
+ PowerMgmtConfig->PmgCstCfgCtrIoMwaitRedirection = SOC_DEVICE_DISABLE;
+ }
+
+ //
+ //If Auto is selected, disable Monitor Mwait for B1 and enable for other stepping
+ //
+ if (SystemConfiguration->MonitorMwaitEnable == 2) {
+ if (BxtStepping () >= BxtPB1) {
+ CpuConfig->MonitorMwaitEnable = SOC_DEVICE_DISABLE;
+ } else {
+ CpuConfig->MonitorMwaitEnable = SOC_DEVICE_ENABLE;
+ }
+ } else {
+ CpuConfig->MonitorMwaitEnable = SystemConfiguration->MonitorMwaitEnable;
+ }
+
+
+ if (SystemConfiguration->EnableCx) {
+ //
+ // Clear C1 & C3 Auto demotion policy
+ //
+ PowerMgmtConfig->C1AutoDemotion = SOC_DEVICE_DISABLE;
+ PowerMgmtConfig->C3AutoDemotion = SOC_DEVICE_DISABLE;
+
+ switch (SystemConfiguration->CStateAutoDemotion) {
+ case 0:
+ //
+ // Disable C1 and C3 Auto-demotion
+ //
+ break;
+
+ case 1:
+ //
+ // Enable C3/C6/C7 Auto-demotion to C1
+ //
+ PowerMgmtConfig->C1AutoDemotion = SOC_DEVICE_ENABLE;
+ break;
+
+ case 2:
+ //
+ // Enable C6/C7 Auto-demotion to C3
+ //
+ PowerMgmtConfig->C3AutoDemotion = SOC_DEVICE_ENABLE;
+ break;
+
+ default:
+ case 3:
+ //
+ // Enable C6/C7 Auto-demotion to C1 and C3
+ //
+ PowerMgmtConfig->C1AutoDemotion = SOC_DEVICE_ENABLE;
+ PowerMgmtConfig->C3AutoDemotion = SOC_DEVICE_ENABLE;
+ break;
+ }
+ //
+ // Configure Un-demotion.
+ //
+ PowerMgmtConfig->C1UnDemotion = SOC_DEVICE_DISABLE;
+ PowerMgmtConfig->C3UnDemotion = SOC_DEVICE_DISABLE;
+
+ switch (SystemConfiguration->CStateUnDemotion) {
+ case 0:
+ //
+ // Disable C1 and C3 Un-demotion
+ //
+ break;
+
+ case 1:
+ //
+ // Enable C1 Un-demotion
+ //
+ PowerMgmtConfig->C1UnDemotion = SOC_DEVICE_ENABLE;
+ break;
+
+ case 2:
+ //
+ // Enable C3 Un-demotion
+ //
+ PowerMgmtConfig->C3UnDemotion = SOC_DEVICE_ENABLE;
+ break;
+
+ case 3:
+ //
+ // Enable C1 and C3 Un-demotion
+ //
+ PowerMgmtConfig->C1UnDemotion = SOC_DEVICE_ENABLE;
+ PowerMgmtConfig->C3UnDemotion = SOC_DEVICE_ENABLE;
+ break;
+
+ default:
+ break;
+ }
+ switch (SystemConfiguration->MaxCoreCState) {
+ case 0:
+ PowerMgmtConfig->UnlimitedCstate = SOC_DEVICE_ENABLE;
+ break;
+
+ case 1:
+ PowerMgmtConfig->EnableC1 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 2:
+ PowerMgmtConfig->EnableC3 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 3:
+ PowerMgmtConfig->EnableC6 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 4:
+ PowerMgmtConfig->EnableC7 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 5:
+ PowerMgmtConfig->EnableC8 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 6:
+ PowerMgmtConfig->EnableC9 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 7:
+ PowerMgmtConfig->EnableC10 = SOC_DEVICE_ENABLE;
+ break;
+
+ case 8:
+ PowerMgmtConfig->EnableCCx = SOC_DEVICE_ENABLE;
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // Pkg C-state Demotion/Un Demotion
+ //
+ PowerMgmtConfig->PkgCStateDemotion = SystemConfiguration->PkgCStateDemotion;
+ PowerMgmtConfig->PkgCStateUnDemotion = SystemConfiguration->PkgCStateUnDemotion;
+ }
+
+ if (BxtStepping() == BxtA0) {
+ PowerMgmtConfig->TurboMode = SOC_DEVICE_DISABLE;
+ } else {
+ PowerMgmtConfig->TurboMode = SystemConfiguration->TurboModeEnable;
+ }
+
+ PowerMgmtConfig->PowerLimit1Enable = SystemConfiguration->PowerLimit1Enable;
+ PowerMgmtConfig->PowerLimit1ClampEnable = SystemConfiguration->PowerLimit1Clamp;
+ PowerMgmtConfig->CustomPowerLimit1Time = SystemConfiguration->PowerLimit1Time;
+ PowerMgmtConfig->CustomPowerLimit1 = SystemConfiguration->PowerLimit1;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
new file mode 100644
index 0000000000..4c5d6e5bfa
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
@@ -0,0 +1,53 @@
+/** @file
+ Header file for PEI CpuPolicyUpdate.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_CPU_POLICY_UPDATE_H_
+#define _PEI_CPU_POLICY_UPDATE_H_
+
+#include <PiPei.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <CpuAccess.h>
+#include <Ppi/CpuPolicy.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/MmPciLib.h>
+
+
+/**
+ This function performs CPU PEI Policy initialization.
+
+ @param[in] SiCpuPolicyPpi The Cpu Policy PPI instance
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+ IN OUT SI_CPU_POLICY_PPI *SiCpuPolicyPpi,
+ IN SYSTEM_CONFIGURATION *SystemConfiguration
+ );
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..c507dba555
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ This file is SampleCode of the library for Intel CPU PEI Policy initialization.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiCpuPolicyUpdate.h>
+
+/**
+ This function performs CPU PEI Policy initialization in Pre-memory.
+
+ @param[in] SiCpuPolicyPpi The Cpu Policy PPI instance
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyPreMem (
+ IN OUT SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ )
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
new file mode 100644
index 0000000000..1f61f948cd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
@@ -0,0 +1,93 @@
+## @file
+# Module Infomation file for PEI PeiPolicyUpdateLib Library.
+#
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiPolicyUpdateLib
+ FILE_GUID = D8E9897A-5B25-4f90-A8FA-93131D2FA6A1
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiPolicyUpdateLib|PEIM PEI_CORE SEC
+
+[Sources]
+ PeiScPolicyUpdate.c
+ PeiCpuPolicyUpdatePreMem.c
+ PeiCpuPolicyUpdate.c
+ PeiSiPolicyUpdate.c
+ HdaVerbTables.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ ConfigBlockLib
+ PcdLib
+ PeiScPolicyLib
+ PeiServicesLib
+ SteppingLib
+ ScPlatformLib
+ MmPciLib
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gScPolicyPpiGuid
+ gSaMiscConfigGuid
+ gGraphicsConfigGuid
+ gIpuConfigGuid
+ gScSpiPpiGuid
+
+[Guids]
+ gEfiSetupVariableGuid
+ gEfiPlatformInfoGuid
+ gPlatformEmmcHs400TuningInfoGuid
+ gVbtInfoGuid
+ gEfiBootMediaHobGuid
+ gScGeneralConfigGuid
+ gPcieRpConfigGuid
+ gSataConfigGuid
+ gHpetConfigGuid
+ gUsbConfigGuid
+ gIoApicConfigGuid
+ gHdAudioConfigGuid
+ gPmConfigGuid
+ gLockDownConfigGuid
+ gLpssConfigGuid
+ gFdoModeEnabledHobGuid
+ gScsConfigGuid
+ gVtdConfigGuid
+ gIshConfigGuid
+ gFlashProtectionConfigGuid
+ gDciConfigGuid
+ gInterruptConfigGuid
+
+[Pcd.common]
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+
+[FixedPcd]
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashIbbRegionMappedBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashIbbRegionSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashObbRegionMappedBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashObbRegionSize
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
new file mode 100644
index 0000000000..4787f1fe6c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
@@ -0,0 +1,254 @@
+/** @file
+ Do Platform Stage System Agent initialization.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PeiSaPolicyUpdate.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+#include <Library/SteppingLib.h>
+
+
+/**
+ UpdatePeiSaPolicy performs SA PEI Policy initialzation
+
+ @param[in, out] SiSaPolicyPpi SI_SA_POLICY PPI
+
+ @retval EFI_SUCCESS The policy is installed and initialized.
+
+**/
+EFI_STATUS
+UpdatePeiSaPolicy (
+ IN OUT SI_SA_POLICY_PPI *SiSaPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VariableSize;
+ SA_MISC_CONFIG *MiscConfig = NULL;
+ GRAPHICS_CONFIG *GtConfig = NULL;
+ IPU_CONFIG *IpuPolicy = NULL;
+ VOID* Buffer;
+ UINT32 Size;
+ EFI_GUID PeiLogoGuid = { 0x7BB28B99, 0x61BB, 0x11D5, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D };
+ EFI_GUID TianmaVbtGuid = { 0xE08CA6D5, 0x8D02, 0x43ae, 0xAB, 0xB1, 0x95, 0x2C, 0xC7, 0x87, 0xC9, 0x33 };
+ EFI_GUID TrulyFabBVbtTypeCGuid = { 0xDBADD769, 0xE86A, 0x4819, 0x81, 0x20, 0xE9, 0x91, 0x79, 0x2C, 0x0B, 0xC1 };
+ EFI_GUID TrulyFabBVbtGuid = { 0x1a03cf12, 0xf54b, 0x4227, 0xa7, 0xa4, 0x6c, 0x97, 0x11, 0x3f, 0xac, 0x71 };
+ EFI_GUID TrulyFabBCMVbtGuid = { 0x1fc29068, 0x17cf, 0x4613, 0x98, 0xd, 0x17, 0x2f, 0x97, 0xe7, 0xfa, 0xe5 };
+ EFI_GUID TrulyFabBCMTypeCVbtGuid = { 0x2246d69f, 0xd9a6, 0x4f80, 0x90, 0x38, 0x78, 0xc5, 0xcc, 0x74, 0x1d, 0xdf };
+ EFI_GUID TrulyFabBPr1TypeCVbtGuid = { 0x190c66ce, 0x475e, 0x4c5e, 0xb7, 0xd0, 0x2f, 0x67, 0x72, 0xba, 0x71, 0x70 };
+ EFI_GUID TrulyFabBPr1CMTypeCVbtGuid = { 0xc1b31ace, 0x65db, 0x46d6, 0x9c, 0x7e, 0xa8, 0x2c, 0xce, 0x78, 0x45, 0x38 };
+ VBT_INFO VbtInfo;
+ SC_POLICY_PPI *ScPolicyPpi;
+ SC_VTD_CONFIG *VtdConfig;
+ BXT_SERIES SocSeries;
+ BXT_STEPPING SocStepping;
+
+ DEBUG ((DEBUG_INFO, "Entering Get Config Block function call from UpdatePeiSaPolicy\n"));
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gSaMiscConfigGuid , (VOID *) &MiscConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gGraphicsConfigGuid, (VOID *) &GtConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gIpuConfigGuid, (VOID *) &IpuPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Locate system configuration variable
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **) &VariableServices // PPI
+ );
+ ASSERT_EFI_ERROR ( Status);
+
+ //
+ // Locate SC Policy
+ //
+ Status = PeiServicesLocatePpi (
+ &gScPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &ScPolicyPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gVtdConfigGuid, (VOID *) &VtdConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get System configuration variables
+ //
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get the Platform Configuration from SetupData
+ //
+ GtConfig->GttMmAdr = GTTMM_BASE_ADDRESS;
+ GtConfig->GmAdr = GMADR_BASE_ADDRESS;
+ GtConfig->PeiGraphicsPeimInit = SystemConfiguration.PeiGraphicsPeimInit;
+ GtConfig->PmSupport = SystemConfiguration.PmSupport;
+ GtConfig->EnableRenderStandby = SystemConfiguration.EnableRenderStandby;
+ GtConfig->CdClock = SystemConfiguration.CdClock;
+ GtConfig->PavpEnable = SystemConfiguration.PavpEnable;
+
+ GtConfig->ForceWake = 0;
+ GtConfig->PavpLock = 1;
+ GtConfig->GraphicsFreqModify = 0;
+ GtConfig->GraphicsFreqReq = 0;
+ GtConfig->GraphicsVideoFreq = 0;
+ GtConfig->PmLock = 1;
+ GtConfig->DopClockGating = 1;
+ GtConfig->UnsolicitedAttackOverride = 0;
+ GtConfig->WOPCMSupport = 1;
+ GtConfig->WOPCMSize = 0;
+ GtConfig->PowerGating = 0;
+ GtConfig->UnitLevelClockGating = 1;
+
+ MiscConfig->FastBoot = 1;
+ MiscConfig->DynSR = 1;
+
+ IpuPolicy->SaIpuEnable = SystemConfiguration.IpuEn;
+
+ SocSeries = GetBxtSeries ();
+ SocStepping = BxtStepping ();
+ if ((SocSeries == BxtP && SocStepping <= BxtPB2) || (SocSeries != BxtP && SocStepping < BxtC0)) {
+ if (IpuPolicy->SaIpuEnble == 1) {
+ VtdConfig->VtdEnable = 0;
+ }
+ }
+
+ IpuPolicy->IpuAcpiMode = SystemConfiguration.IpuAcpiMode;
+ IpuPolicy->IpuMmAdr = IPUMM_BASE_ADDRESS;
+ }
+
+ PeiGetSectionFromFv (PeiLogoGuid, &Buffer, &Size);
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not locate Pei Logo"));
+ }
+ GtConfig->LogoPtr = Buffer;
+ GtConfig->LogoSize = Size;
+ DEBUG ((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", Buffer));
+ DEBUG ((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", Size));
+
+ //
+ // VBT selection may depend on SystemConfiguration->PanelSel value
+ //
+ PeiGetSectionFromFv (TianmaVbtGuid, &Buffer, &Size);
+
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not locate VBT"));
+ }
+ GtConfig->GraphicsConfigPtr = Buffer;
+
+ //
+ // Build the VBT data into HOB for DXE GOP
+ //
+ VbtInfo.VbtAddress = (EFI_PHYSICAL_ADDRESS) Buffer;
+ VbtInfo.VbtSize = Size;
+ DEBUG ((DEBUG_INFO, "VbtInfo VbtAddress is 0x%x\n", Buffer));
+ DEBUG ((DEBUG_INFO, "VbtInfo VbtSize is 0x%x\n", Size));
+
+ BuildGuidDataHob (
+ &gVbtInfoGuid,
+ &VbtInfo,
+ sizeof (VbtInfo)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+ @param[in] NameGuid File GUID
+ @param[out] Address Pointer to the File Address
+ @param[out] Size Pointer to File Size
+
+ @retval EFI_SUCCESS Successfull in reading the section from FV
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+ EFI_FV_FILE_INFO FvFileInfo;
+ PEI_CORE_INSTANCE *PrivateData;
+ UINTN CurrentFv;
+ PEI_CORE_FV_HANDLE *CoreFvHandle;
+ EFI_PEI_FILE_HANDLE VbtFileHandle;
+ EFI_GUID *VbtGuid;
+ EFI_COMMON_SECTION_HEADER *Section;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiFirmwareFileSystem2Guid,
+ 0,
+ NULL,
+ (VOID **) &FvPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CurrentFv = PrivateData->CurrentPeimFvCount;
+ CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+ Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+ if (!EFI_ERROR (Status) && VbtFileHandle != NULL) {
+ DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
+ Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
+ Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
+ Section = (EFI_COMMON_SECTION_HEADER *) FvFileInfo.Buffer;
+ if (IS_SECTION2 (Section)) {
+ ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+ *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+ *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..ae1fd09602
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
@@ -0,0 +1,43 @@
+/** @file
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Guid/SetupVariable.h>
+#include <SaAccess.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/SaPolicy.h>
+#include <Library/PeiServicesLib.h>
+
+extern EFI_GUID gVbtInfoGuid;
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS VbtAddress;
+ UINT32 VbtSize;
+} VBT_INFO;
+
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+ IN CONST EFI_GUID NameGuid,
+ OUT VOID **Address,
+ OUT UINT32 *Size
+ );
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.c
new file mode 100644
index 0000000000..6d9fc52de5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.c
@@ -0,0 +1,773 @@
+/** @file
+ This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiScPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include "HdaVerbTables.h"
+#include <Guid/PlatformInfo.h>
+#include <Library/PeiScPolicyLib.h>
+#include <Library/HeciMsgLib.h>
+#include <SeCAccess.h>
+#include <SeCChipset.h>
+#include <Library/ConfigBlockLib.h>
+#include <SeCState.h>
+#include <Library/MmPciLib.h>
+
+extern EFI_GUID gEfiBootMediaHobGuid;
+
+typedef struct {
+ UINT32 IbbOffset;
+ UINT32 IbbSize;
+ UINT32 ObbOffset;
+ UINT32 ObbSize;
+} IBB_OBB_INFORMATION;
+
+/**
+ Add verb table helper function.
+ This function calculates verb table number and shows verb table information.
+
+ @param[in, out] VerbTableEntryNum Input current VerbTable number and output the number after adding new table
+ @param[in, out] VerbTableArray Pointer to array of VerbTable
+ @param[in] VerbTable VerbTable which is going to add into array
+
+**/
+STATIC
+VOID
+InternalAddVerbTable (
+ IN OUT UINT8 *VerbTableEntryNum,
+ IN OUT UINT32 *VerbTableArray,
+ IN HDAUDIO_VERB_TABLE *VerbTable
+ )
+{
+ if (VerbTable == NULL) {
+ DEBUG ((DEBUG_INFO, "InternalAddVerbTable wrong input: VerbTable == NULL\n"));
+ return;
+ }
+
+ VerbTableArray[*VerbTableEntryNum] = (UINT32) VerbTable;
+ *VerbTableEntryNum += 1;
+
+ DEBUG ((DEBUG_INFO,
+ "Add verb table for VendorDeviceId = 0x%08X (size = %d DWords)\n",
+ VerbTable->VerbTableHeader.VendorDeviceId,
+ VerbTable->VerbTableHeader.DataDwords)
+ );
+ return;
+}
+
+
+STATIC
+VOID
+InstallPlatformVerbTables (
+ IN SC_HDAUDIO_CONFIG *HdaConfig,
+ IN UINT16 BoardId,
+ IN UINTN CodecType
+ )
+{
+ UINT8 VerbTableEntryNum;
+ UINT32 VerbTableArray[32];
+ UINT32 *VerbTablePtr;
+
+ VerbTableEntryNum = 0;
+
+ //
+ // left switch cases defined which can be PlatformInfo or stepping
+ //
+ if (CodecType == HdaCodecPlatformOnboard) {
+ //
+ // Add onboard verb table. If we use a board that uses a different one, we need to split this code to board specific
+ // location.
+ //
+ InternalAddVerbTable (&VerbTableEntryNum, VerbTableArray, &HdaVerbTableAlc662);
+ } else {
+ DEBUG ((DEBUG_INFO, "HD-Audio Warning: External codec kit selected or platform verb table not found, installing all!\n"));
+ }
+
+ HdaConfig->VerbTableEntryNum = VerbTableEntryNum;
+
+ VerbTablePtr = (UINT32 *) AllocateZeroPool (sizeof (UINT32) *VerbTableEntryNum);
+ CopyMem (VerbTablePtr, VerbTableArray, sizeof (UINT32) *VerbTableEntryNum);
+ HdaConfig->VerbTablePtr = (UINT32) VerbTablePtr;
+
+ return;
+}
+
+
+/**
+ Check it's eMMC boot path or not.
+
+ @retval TRUE eMMC Boot path
+ @retval FALSE Not eMMC boot path
+
+**/
+BOOLEAN
+IseMMCBoot (
+ VOID
+ )
+{
+ VOID *HobList;
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData;
+
+ DEBUG ((EFI_D_INFO, "IseMMCBoot Start!\n"));
+ HobList = GetFirstGuidHob (&gEfiBootMediaHobGuid);
+ if (HobList != NULL) {
+ DEBUG ((EFI_D_INFO, "IseMMCBoot HobList != NULL\n"));
+ BootMediaData = GET_GUID_HOB_DATA (HobList);
+ if (BootMediaData->PhysicalData == BOOT_FROM_EMMC) {
+ DEBUG ((EFI_D_INFO, "BootMediaData->PhysicalData == IseMMCBoot\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Not boot from eMMC\n"));
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ Check it's SPI boot path or not.
+
+ @retval TRUE SPI Boot path
+ @retval FALSE Not SPI boot path
+
+**/
+BOOLEAN
+IsSpiBoot (
+ VOID
+ )
+{
+ VOID *HobList;
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData;
+
+ DEBUG ((EFI_D_INFO, "IsSpiBoot Start!\n"));
+ HobList = GetFirstGuidHob (&gEfiBootMediaHobGuid);
+ if (HobList != NULL) {
+ DEBUG ((EFI_D_INFO, "IsSpiBoot HobList != NULL\n"));
+ BootMediaData = GET_GUID_HOB_DATA (HobList);
+ if (BootMediaData->PhysicalData == BOOT_FROM_SPI) {
+ DEBUG ((EFI_D_INFO, "BootMediaData->PhysicalData == IsSpiBoot\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Not boot from SPI\n"));
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Calculate the Address of Boot Partition 1.
+
+ @param[out] Address The address
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+FindBootPartition1 (
+ OUT UINT32 *Address
+ )
+{
+ UINT32 SecondBPFlashLinearAddress;
+ UINT32 BiosAddr;
+
+ //
+ //Compute Second BP FlashLinearAddress
+ //
+ SecondBPFlashLinearAddress = 0x1000;
+
+ DEBUG ((DEBUG_INFO, "SecondBPFlashLinearAddress = %X\n", SecondBPFlashLinearAddress));
+ //
+ // Calculate Boot partition #2 physical address
+ // FLA[26:0] <= (Flash_Regionn_Limit) - (FFFF_FFFCh - bios_address)
+ //
+ BiosAddr = GetSpiFlashRegionLimit (BIOS) + 0xFFC - SecondBPFlashLinearAddress;
+ *Address = 0xFFFFFFFC - BiosAddr;
+
+ DEBUG ((DEBUG_INFO, "system BP1 Address = %X\n", *Address));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Calculate the Address of Boot Partition 2.
+
+ @param[out] Address The address
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+FindBootPartition2 (
+ OUT UINT32 *Address
+ )
+{
+ UINT32 SecondBPFlashLinearAddress;
+ UINT32 BiosAddr;
+
+ //
+ // Compute Second BP FlashLinearAddress
+ //
+ if (HeciPciRead16 (R_SEC_DevID_VID) != 0xFFFF) {
+ //
+ // BP2 linear address is the midpoint between BIOS base and expansion data base
+ //
+ SecondBPFlashLinearAddress = (GetSpiFlashRegionBase (BIOS) + GetSpiFlashRegionBase (DeviceExpansion1)) / 2;
+ } else {
+ //
+ // W/A for non-secure boot
+ //
+ SecondBPFlashLinearAddress = FixedPcdGet32 (PcdFlashAreaSize) >> 1;
+ }
+
+ DEBUG ((DEBUG_INFO, "SecondBPFlashLinearAddress = %X\n", SecondBPFlashLinearAddress));
+ //
+ // Calculate Boot partition #2 physical address
+ // FLA[26:0] <= (Flash_Regionn_Limit) - (FFFF_FFFCh - bios_address)
+ //
+ BiosAddr = GetSpiFlashRegionLimit (BIOS) + 0xFFC - SecondBPFlashLinearAddress;
+ *Address = 0xFFFFFFFC - BiosAddr;
+
+ DEBUG ((DEBUG_INFO, "FlashRegionLimit = %X\n", *Address));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function performs PCH PEI Policy initialization.
+
+ @param[in, out] ScPolicy The PCH Policy PPI instance
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiScPolicy (
+ IN OUT SC_POLICY_PPI *ScPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINT16 BoardId;
+ UINTN VariableSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINT8 Index;
+ UINT8 PortIndex;
+ UINT32 SpiHsfsReg;
+ UINT32 SpiFdodReg;
+ UINT8 DevIndex;
+ UINT8 HdaIndex;
+ BOOLEAN FlashProtectionEnabled;
+ SC_GENERAL_CONFIG *GeneralConfig;
+ SC_SATA_CONFIG *SataConfig;
+ SC_PCIE_CONFIG *PcieConfig;
+ SC_USB_CONFIG *UsbConfig;
+ SC_HPET_CONFIG *HpetConfig;
+ SC_IOAPIC_CONFIG *IoApicConfig;
+ SC_HDAUDIO_CONFIG *HdaConfig;
+ SC_GMM_CONFIG *GmmConfig;
+ SC_PM_CONFIG *PmConfig;
+ SC_LOCK_DOWN_CONFIG *LockDownConfig;
+ SC_LPSS_CONFIG *LpssConfig;
+ SC_SCS_CONFIG *ScsConfig;
+ SC_VTD_CONFIG *VtdConfig;
+ SC_ISH_CONFIG *IshConfig;
+ SC_FLASH_PROTECTION_CONFIG *FlashProtectionConfig;
+ SC_DCI_CONFIG *DciConfig;
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+ SC_INTERRUPT_CONFIG *InterruptConfig;
+
+ //
+ // The PlatformInfoHob is default at this point, which is initialized after memory installed in PlatformInit.c
+ //
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+ ASSERT (Hob.Raw != NULL);
+ PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw);
+
+ BoardId = PlatformInfo->BoardId;
+
+ //
+ // Retrieve Setup variable
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install SC Policy PPI. As we depend on SC Init PPI so we are executed after
+ // ScInit PEIM. Thus we can insure SC Initialization is performed when we install the SC Policy PPI,
+ // as ScInit PEIM registered a notification function on our policy PPI.
+ //
+ // For better code structure / modularity, we should use a notification function on SC Init PPI to perform
+ // actions that depend on ScInit PEIM's initialization.
+ //
+ DEBUG ((DEBUG_INFO, "UpdatePeiScPolicy() - Start\n"));
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gScGeneralConfigGuid, (VOID *) &GeneralConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gSataConfigGuid, (VOID *) &SataConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gPcieRpConfigGuid, (VOID *) &PcieConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gUsbConfigGuid, (VOID *) &UsbConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gHpetConfigGuid, (VOID *) &HpetConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gHdAudioConfigGuid, (VOID *) &HdaConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gGmmConfigGuid, (VOID *) &GmmConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gPmConfigGuid, (VOID *) &PmConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gLpssConfigGuid, (VOID *) &LpssConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gScsConfigGuid, (VOID *) &ScsConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gVtdConfigGuid, (VOID *) &VtdConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gIshConfigGuid, (VOID *) &IshConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gDciConfigGuid, (VOID *) &DciConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) ScPolicyPpi, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Read ACPI and P2SB Base Addresses
+ //
+ GeneralConfig->PmcBase = (UINT32) PcdGet32 (PcdPmcGcrBaseAddress);
+ GeneralConfig->AcpiBase = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+ GeneralConfig->P2sbBase = (UINT32) PcdGet32 (PcdP2SBBaseAddress);
+ GeneralConfig->Crid = SystemConfiguration.CRIDSettings;
+ GeneralConfig->ResetSelect = SystemConfiguration.ResetSelect;
+
+ HpetConfig->Enable = SystemConfiguration.Hpet;
+ HpetConfig->Base = HPET_BASE_ADDRESS;
+ HpetConfig->BdfValid = 0x01;
+ HpetConfig->BusNumber = 0xFA;
+ HpetConfig->DeviceNumber = 0x0F;
+ HpetConfig->FunctionNumber = 0;
+ IoApicConfig->IoApicId = 0x01;
+ IoApicConfig->BdfValid = 1;
+ IoApicConfig->BusNumber = 0xFA;
+ IoApicConfig->DeviceNumber = 0x1F;
+ IoApicConfig->FunctionNumber = 0;
+
+ SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_SPI_HSFS);
+ if ((SpiHsfsReg & B_SPI_HSFS_FDV) == B_SPI_HSFS_FDV) {
+ MmioWrite32 (SPI_BASE_ADDRESS + R_SPI_FDOC, V_SPI_FDOC_FDSS_FSDM);
+ SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_SPI_FDOD);
+ if (SpiFdodReg == V_SPI_FDBAR_FLVALSIG) {
+ }
+ }
+
+ //
+ // Update PCIe config
+ //
+ PcieConfig->DisableRootPortClockGating = SystemConfiguration.PcieClockGatingDisabled;
+ PcieConfig->EnablePort8xhDecode = SystemConfiguration.PcieRootPort8xhDecode;
+ PcieConfig->ScPciePort8xhDecodePortIndex = SystemConfiguration.Pcie8xhDecodePortIndex;
+ PcieConfig->EnablePeerMemoryWrite = SystemConfiguration.PcieRootPortPeerMemoryWriteEnable;
+ PcieConfig->ComplianceTestMode = SystemConfiguration.PcieComplianceMode;
+ for (PortIndex = 0; PortIndex < SC_MAX_PCIE_ROOT_PORTS; PortIndex++) {
+ PcieConfig->RootPort[PortIndex].Enable = SystemConfiguration.PcieRootPortEn[PortIndex];
+ PcieConfig->RootPort[PortIndex].SlotImplemented = TRUE;
+ PcieConfig->RootPort[PortIndex].PhysicalSlotNumber = (UINT8) PortIndex;
+ PcieConfig->RootPort[PortIndex].Aspm = SystemConfiguration.PcieRootPortAspm[PortIndex];
+ PcieConfig->RootPort[PortIndex].L1Substates = SystemConfiguration.PcieRootPortL1SubStates[PortIndex];
+ PcieConfig->RootPort[PortIndex].AcsEnabled = SystemConfiguration.PcieRootPortACS[PortIndex];
+ PcieConfig->RootPort[PortIndex].PmSci = SystemConfiguration.PcieRootPortPMCE[PortIndex];
+ PcieConfig->RootPort[PortIndex].HotPlug = SystemConfiguration.PcieRootPortHPE[PortIndex];
+ PcieConfig->RootPort[PortIndex].AdvancedErrorReporting = FALSE;
+ PcieConfig->RootPort[PortIndex].UnsupportedRequestReport = SystemConfiguration.PcieRootPortURE[PortIndex];
+ PcieConfig->RootPort[PortIndex].FatalErrorReport = SystemConfiguration.PcieRootPortFEE[PortIndex];
+ PcieConfig->RootPort[PortIndex].NoFatalErrorReport = SystemConfiguration.PcieRootPortNFE[PortIndex];
+ PcieConfig->RootPort[PortIndex].CorrectableErrorReport = SystemConfiguration.PcieRootPortCEE[PortIndex];
+ PcieConfig->RootPort[PortIndex].PmeInterrupt = 0;
+ PcieConfig->RootPort[PortIndex].SystemErrorOnFatalError = SystemConfiguration.PcieRootPortSFE[PortIndex];
+ PcieConfig->RootPort[PortIndex].SystemErrorOnNonFatalError = SystemConfiguration.PcieRootPortSNE[PortIndex];
+ PcieConfig->RootPort[PortIndex].SystemErrorOnCorrectableError = SystemConfiguration.PcieRootPortSCE[PortIndex];
+ PcieConfig->RootPort[PortIndex].TransmitterHalfSwing = SystemConfiguration.PcieRootPortTHS[PortIndex];
+ PcieConfig->RootPort[PortIndex].CompletionTimeout = ScPcieCompletionTO_Default;
+ PcieConfig->RootPort[PortIndex].PcieSpeed = SystemConfiguration.PcieRootPortSpeed[PortIndex];
+ PcieConfig->RootPort[PortIndex].SelectableDeemphasis = SystemConfiguration.PcieRootPortSelectableDeemphasis[PortIndex];
+ // LTR settings
+ PcieConfig->RootPort[PortIndex].LtrEnable = SystemConfiguration.PchPcieLtrEnable[PortIndex];
+ PcieConfig->RootPort[PortIndex].LtrConfigLock = SystemConfiguration.PchPcieLtrConfigLock[PortIndex];
+ PcieConfig->RootPort[PortIndex].LtrMaxSnoopLatency = SystemConfiguration.PcieLtrMaxSnoopLatency[PortIndex];
+ PcieConfig->RootPort[PortIndex].LtrMaxNoSnoopLatency = SystemConfiguration.PcieLtrMaxNoSnoopLatency[PortIndex];
+ PcieConfig->RootPort[PortIndex].SnoopLatencyOverrideMode = SystemConfiguration.PchPcieSnoopLatencyOverrideMode[PortIndex];
+ PcieConfig->RootPort[PortIndex].SnoopLatencyOverrideMultiplier = SystemConfiguration.PchPcieSnoopLatencyOverrideMultiplier[PortIndex];
+ PcieConfig->RootPort[PortIndex].SnoopLatencyOverrideValue = SystemConfiguration.PchPcieSnoopLatencyOverrideValue[PortIndex];
+ PcieConfig->RootPort[PortIndex].NonSnoopLatencyOverrideMode = SystemConfiguration.PchPcieNonSnoopLatencyOverrideMode[PortIndex];
+ PcieConfig->RootPort[PortIndex].NonSnoopLatencyOverrideMultiplier = SystemConfiguration.PchPcieNonSnoopLatencyOverrideMultiplier[PortIndex];
+ PcieConfig->RootPort[PortIndex].NonSnoopLatencyOverrideValue = SystemConfiguration.PchPcieNonSnoopLatencyOverrideValue[PortIndex];
+ PcieConfig->RootPort[PortIndex].PtmEnable = TRUE;
+ }
+#if (ENBDT_PF_ENABLE == 1)
+ PcieConfig->RootPort[0].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[0].ClkReqNumber = 2;
+ PcieConfig->RootPort[1].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[1].ClkReqNumber = 3;
+ PcieConfig->RootPort[2].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[2].ClkReqNumber = 0;
+ PcieConfig->RootPort[3].ClkReqSupported = FALSE;
+ PcieConfig->RootPort[3].ClkReqNumber = 0xF;
+ PcieConfig->RootPort[4].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[4].ClkReqNumber = 0x1;
+ PcieConfig->RootPort[5].ClkReqSupported = FALSE;
+ PcieConfig->RootPort[5].ClkReqNumber = 0xF;
+#endif
+
+ PcieConfig->RootPort[0].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[0].ClkReqNumber = 2;
+ PcieConfig->RootPort[1].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[1].ClkReqNumber = 3;
+ PcieConfig->RootPort[2].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[2].ClkReqNumber = 1;
+ PcieConfig->RootPort[4].ClkReqSupported = TRUE;
+ PcieConfig->RootPort[4].ClkReqNumber = 0;
+
+ //
+ // Update SATA config
+ //
+ SataConfig->Enable = SystemConfiguration.Sata;
+ SataConfig->SataMode = SystemConfiguration.SataInterfaceMode;
+ for (PortIndex = 0; PortIndex < SC_MAX_SATA_PORTS; PortIndex++) {
+ if (SystemConfiguration.SataTestMode == TRUE) {
+ SataConfig->PortSettings[PortIndex].Enable = TRUE;
+ } else {
+ SataConfig->PortSettings[PortIndex].Enable = SystemConfiguration.SataPort[PortIndex];
+ }
+ SataConfig->PortSettings[PortIndex].HotPlug = SystemConfiguration.SataHotPlug[PortIndex];
+ SataConfig->PortSettings[PortIndex].SpinUp = SystemConfiguration.SataSpinUp[PortIndex];
+ SataConfig->PortSettings[PortIndex].External = FALSE;
+ SataConfig->PortSettings[PortIndex].DevSlp = SystemConfiguration.PxDevSlp[PortIndex];
+ SataConfig->PortSettings[PortIndex].EnableDitoConfig = SystemConfiguration.EnableDitoConfig[PortIndex];
+ SataConfig->PortSettings[PortIndex].DmVal = SystemConfiguration.DmVal[PortIndex];
+ SataConfig->PortSettings[PortIndex].DitoVal = SystemConfiguration.DitoVal[PortIndex];
+ SataConfig->PortSettings[PortIndex].SolidStateDrive = SystemConfiguration.SataType[PortIndex];
+ }
+ SataConfig->SalpSupport = SystemConfiguration.SataSalp;
+ SataConfig->TestMode = SystemConfiguration.SataTestMode;
+
+ //
+ // Flash Security Recommendation,
+ // Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit
+ // will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+ // BIOS lock down bit is enabled by default as per Platform policy, except that when system is in recovery mode or FDO is enabled. In this case this will be disabled as part of Firmware Update / Recovery update
+ //
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+
+ if ((GetBxtSeries() == BxtP) && (FdoEnabledGuidHob == NULL)) {
+ LockDownConfig->BiosInterface = TRUE;
+ LockDownConfig->BiosLock = SystemConfiguration.ScBiosLock;
+ if (SystemConfiguration.ScBiosLock) {
+ LockDownConfig->SpiEiss = TRUE;
+ } else {
+ LockDownConfig->SpiEiss = FALSE;
+ }
+ } else {
+ DEBUG ((DEBUG_INFO, " BIOS lock is not done -CSE Status -FDO ASSERTED\n"));
+ LockDownConfig->BiosInterface = FALSE;
+ LockDownConfig->BiosLock = FALSE;
+ LockDownConfig->SpiEiss = FALSE;
+ }
+ LockDownConfig->RtcLock = SystemConfiguration.RtcLock;
+ LockDownConfig->TcoLock = SystemConfiguration.TcoLock;
+
+ HdaConfig->Enable = SystemConfiguration.ScHdAudio;
+ HdaConfig->DspEnable = SystemConfiguration.ScHdAudioDsp;
+ HdaConfig->Mmt = SystemConfiguration.ScHdAudioMmt;
+ HdaConfig->Hmt = SystemConfiguration.ScHdAudioHmt;
+ HdaConfig->IoBufferOwnership = SystemConfiguration.ScHdAudioIoBufferOwnership;
+ HdaConfig->BiosCfgLockDown = SystemConfiguration.ScHdAudioBiosCfgLockDown;
+ HdaConfig->PwrGate = SystemConfiguration.ScHdAudioPwrGate;
+ HdaConfig->ClkGate = SystemConfiguration.ScHdAudioClkGate;
+ HdaConfig->Pme = SystemConfiguration.ScHdAudioPme;
+ HdaConfig->DspEndpointDmic = SystemConfiguration.ScHdAudioNhltEndpointDmic;
+ HdaConfig->DspEndpointBluetooth = SystemConfiguration.ScHdAudioNhltEndpointBt;
+ if (HdaConfig->IoBufferOwnership == ScHdaIoBufOwnerHdaLink) {
+ HdaConfig->DspEndpointI2sSkp = FALSE;
+ HdaConfig->DspEndpointI2sHp = FALSE;
+ } else {
+ HdaConfig->DspEndpointI2sSkp = SystemConfiguration.ScHdAudioNhltEndpointI2sSKP;
+ HdaConfig->DspEndpointI2sHp = SystemConfiguration.ScHdAudioNhltEndpointI2sHP;
+ }
+ HdaConfig->RsvdBits3 = SystemConfiguration.ScHdAduioRsvd1;
+ HdaConfig->VcType = SystemConfiguration.SvHdaVcType;
+ HdaConfig->HdAudioLinkFrequency = SystemConfiguration.HdAudioLinkFrequency;
+ HdaConfig->IDispLinkFrequency = SystemConfiguration.IDispLinkFrequency;
+ HdaConfig->IDispLinkTmode = SystemConfiguration.IDispLinkTmode;
+ for(HdaIndex = 0; HdaIndex < HDAUDIO_FEATURES; HdaIndex++) {
+ HdaConfig->DspFeatureMask |= (UINT32) (SystemConfiguration.ScHdAudioFeature[HdaIndex] ? (1 << HdaIndex) : 0);
+ }
+ for(HdaIndex = 0; HdaIndex < HDAUDIO_PP_MODULES; HdaIndex++) {
+ HdaConfig->DspPpModuleMask |= (UINT32) (SystemConfiguration.ScHdAudioPostProcessingMod[HdaIndex] ? (1 << HdaIndex) : 0);
+ }
+ HdaConfig->ResetWaitTimer = 300;
+
+ //
+ // Install Verb Table
+ //
+ if (SystemConfiguration.ScHdAudio) {
+ //
+ // set default to on board
+ //
+ InstallPlatformVerbTables (HdaConfig, BoardId, HdaCodecPlatformOnboard);
+ }
+
+ //
+ // Update GMM config
+ //
+ GmmConfig->Enable = SystemConfiguration.Gmm;
+ GmmConfig->ClkGatingPgcbClkTrunk = SystemConfiguration.GmmCgPGCBEnabled;
+ GmmConfig->ClkGatingSb = SystemConfiguration.GmmCgSBDEnabled;
+ GmmConfig->ClkGatingSbClkTrunk = SystemConfiguration.GmmCgSBTEnabled;
+ GmmConfig->ClkGatingSbClkPartition = SystemConfiguration.GmmCgSBPEnabled;
+ GmmConfig->ClkGatingCore = SystemConfiguration.GmmCgCoreEnabled;
+ GmmConfig->ClkGatingDma = SystemConfiguration.GmmCgDmaEnabled;
+ GmmConfig->ClkGatingRegAccess = SystemConfiguration.GmmCgRAEnabled;
+ GmmConfig->ClkGatingHost = SystemConfiguration.GmmCgHostEnabled;
+ GmmConfig->ClkGatingPartition = SystemConfiguration.GmmCgPEnabled;
+ GmmConfig->ClkGatingTrunk = SystemConfiguration.GmmCgTEnabled;
+ if (SystemConfiguration.GmmPgHwAutoEnabled) {
+ GmmConfig->SvPwrGatingHwAutoEnable = TRUE;
+ GmmConfig->SvPwrGatingD3HotEnable = FALSE;
+ GmmConfig->SvPwrGatingI3Enable = FALSE;
+ GmmConfig->SvPwrGatingPmcReqEnable = FALSE;
+ } else {
+ GmmConfig->SvPwrGatingHwAutoEnable = FALSE;
+ GmmConfig->SvPwrGatingD3HotEnable = SystemConfiguration.GmmPgD3HotEnabled;
+ GmmConfig->SvPwrGatingI3Enable = SystemConfiguration.GmmPgI3Enabled;
+ GmmConfig->SvPwrGatingPmcReqEnable = SystemConfiguration.GmmPgPMCREnabled;
+ }
+ //
+ // Set ISH configuration according to setup value.
+ //
+ IshConfig->Enable = SystemConfiguration.ScIshEnabled;
+
+ //
+ // USB Device 21 configuration
+ //
+ UsbConfig->DisableComplianceMode = SystemConfiguration.DisableComplianceMode;
+
+ //
+ // xHCI (USB 3.0) related settings from setup variable
+ //
+ UsbConfig->Usb30Settings.Mode = SystemConfiguration.ScUsb30Mode;
+
+ UsbConfig->SsicConfig.SsicPort[0].Enable = SystemConfiguration.Ssic1Support;
+ UsbConfig->SsicConfig.SsicPort[1].Enable = SystemConfiguration.Ssic2Support;
+ UsbConfig->SsicConfig.SsicPort[0].Rate = SystemConfiguration.Ssic1Rate;
+ UsbConfig->SsicConfig.SsicPort[1].Rate = SystemConfiguration.Ssic2Rate;
+ UsbConfig->SsicConfig.DlanePwrGating = SystemConfiguration.SsicDlanePg;
+ UsbConfig->XdciConfig.Enable = SystemConfiguration.ScUsbOtg;
+ //
+ // Overcurrent applies to walk-up xHCI ports only - not SSIC or HSIC
+ //
+ // OC0: Used for the OTG port (port 0)
+ // OC1: Used for the 2 host walk-up ports
+ //
+#if (ENBDT_PF_ENABLE == 1)
+ UsbConfig->PortUsb20[0].OverCurrentPin = ScUsbOverCurrentPin0;
+ UsbConfig->PortUsb20[1].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[2].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[3].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[4].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[5].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[6].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[7].OverCurrentPin = ScUsbOverCurrentPinSkip;
+
+ UsbConfig->PortUsb30[0].OverCurrentPin = ScUsbOverCurrentPin0;
+ UsbConfig->PortUsb30[1].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb30[2].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb30[3].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb30[4].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb30[5].OverCurrentPin = ScUsbOverCurrentPin1;
+
+ for (DevIndex = 0; DevIndex < GetScXhciMaxUsb2PortNum (); DevIndex++) {
+ UsbConfig->PortUsb20[DevIndex].Enable = SystemConfiguration.PortUsb20[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < GetScXhciMaxUsb3PortNum (); DevIndex++) {
+ UsbConfig->PortUsb30[DevIndex].Enable = SystemConfiguration.PortUsb30[DevIndex];
+ }
+#else
+ UsbConfig->PortUsb20[0].OverCurrentPin = ScUsbOverCurrentPin0;
+ UsbConfig->PortUsb20[1].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[2].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb20[3].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[4].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[5].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[6].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[7].OverCurrentPin = ScUsbOverCurrentPinSkip;
+
+ UsbConfig->PortUsb30[0].OverCurrentPin = ScUsbOverCurrentPin0;
+ UsbConfig->PortUsb30[1].OverCurrentPin = ScUsbOverCurrentPin1;
+ UsbConfig->PortUsb30[2].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb30[3].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb30[4].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb30[5].OverCurrentPin = ScUsbOverCurrentPinSkip;
+ UsbConfig->PortUsb20[0].Enable = TRUE;
+ UsbConfig->PortUsb20[1].Enable = TRUE;
+ UsbConfig->PortUsb20[2].Enable = TRUE;
+ UsbConfig->PortUsb20[3].Enable = FALSE;
+ UsbConfig->PortUsb20[4].Enable = FALSE;
+ UsbConfig->PortUsb20[5].Enable = FALSE;
+ UsbConfig->PortUsb20[6].Enable = FALSE;
+ UsbConfig->PortUsb20[7].Enable = FALSE;
+
+ UsbConfig->PortUsb30[0].Enable = TRUE;
+ UsbConfig->PortUsb30[1].Enable = TRUE;
+ UsbConfig->PortUsb30[2].Enable = FALSE;
+ UsbConfig->PortUsb30[3].Enable = FALSE;
+ UsbConfig->PortUsb30[4].Enable = FALSE;
+ UsbConfig->PortUsb30[5].Enable = FALSE;
+#endif
+ //
+ // Set LPSS configuration according to setup value.
+ //
+ LpssConfig->I2c0Enable = SystemConfiguration.LpssI2C0Enabled;
+ LpssConfig->I2c1Enable = SystemConfiguration.LpssI2C1Enabled;
+ LpssConfig->I2c2Enable = SystemConfiguration.LpssI2C2Enabled;
+ LpssConfig->I2c3Enable = SystemConfiguration.LpssI2C3Enabled;
+ LpssConfig->I2c4Enable = SystemConfiguration.LpssI2C4Enabled;
+ LpssConfig->I2c5Enable = SystemConfiguration.LpssI2C5Enabled;
+ LpssConfig->I2c6Enable = SystemConfiguration.LpssI2C6Enabled;
+ LpssConfig->I2c7Enable = SystemConfiguration.LpssI2C7Enabled;
+ LpssConfig->Hsuart0Enable = SystemConfiguration.LpssHsuart0Enabled;
+ LpssConfig->Hsuart1Enable = SystemConfiguration.LpssHsuart1Enabled;
+ LpssConfig->Hsuart2Enable = SystemConfiguration.LpssHsuart2Enabled;
+ LpssConfig->Hsuart3Enable = SystemConfiguration.LpssHsuart3Enabled;
+ LpssConfig->Spi0Enable = SystemConfiguration.LpssSpi0Enabled;
+ LpssConfig->Spi1Enable = SystemConfiguration.LpssSpi1Enabled;
+ LpssConfig->Spi2Enable = SystemConfiguration.LpssSpi2Enabled;
+ LpssConfig->Uart2KernelDebugBaseAddress = SystemConfiguration.Uart2KernelDebugBaseAddress;
+ for (DevIndex = 0; DevIndex < LPSS_I2C_DEVICE_NUM; DevIndex ++) {
+ LpssConfig->I2cClkGateCfg[DevIndex] = SystemConfiguration.LpssI2cClkGateCfg[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < LPSS_HSUART_DEVICE_NUM; DevIndex ++) {
+ LpssConfig->HsuartClkGateCfg[DevIndex] = SystemConfiguration.LpssHsuartClkGateCfg[DevIndex];
+ }
+ for (DevIndex = 0; DevIndex < LPSS_SPI_DEVICE_NUM; DevIndex ++) {
+ LpssConfig->SpiClkGateCfg[DevIndex] = SystemConfiguration.LpssSpiClkGateCfg[DevIndex];
+ }
+ //
+ // Kernel Debugger (e.g. WinDBG) Enable
+ //
+ LpssConfig->OsDbgEnable = (BOOLEAN) SystemConfiguration.OsDbgEnable;
+ LpssConfig->S0ixEnable = (BOOLEAN) SystemConfiguration.LowPowerS0Idle;
+ //
+ // Set SCS configuration according to setup value.
+ //
+ ScsConfig->SdcardEnable = SystemConfiguration.SccSdcardEnabled;
+ ScsConfig->UfsEnable = 0;
+ ScsConfig->EmmcEnable = SystemConfiguration.ScceMMCEnabled;
+ ScsConfig->SdioEnable = SystemConfiguration.SccSdioEnabled;
+ ScsConfig->EmmcHostMaxSpeed = SystemConfiguration.ScceMMCHostMaxSpeed;
+ ScsConfig->GppLock = SystemConfiguration.GPPLock;
+ ScsConfig->SccEmmcTraceLength = SCC_EMMC_LONG_TRACE_LEN;
+
+ if (SystemConfiguration.ScceMMCEnabled == DEVICE_AUTO) {
+ if (IseMMCBoot ()) {
+ ScsConfig->EmmcEnable = DEVICE_ENABLE;
+ } else {
+ ScsConfig->EmmcEnable = DEVICE_DISABLE;
+ }
+ }
+
+ VtdConfig->VtdEnable = SystemConfiguration.VTdEnable;
+ //
+ // Power management Configuration
+ //
+ if (SystemConfiguration.Cg8254 == 0) {
+ PmConfig->Timer8254ClkGateEn = FALSE;
+ }
+ PmConfig->PowerButterDebounceMode = SystemConfiguration.PowerButterDebounceMode;
+
+ if ((GetBxtSeries() == BxtP) && (IsSpiBoot ())) {
+ //
+ // Configure Flash Protection Range Registers
+ //
+ FlashProtectionEnabled = SystemConfiguration.FprrEnable == TRUE ? TRUE : FALSE;
+
+ //
+ // Enabling Flash Protection Range Registers
+ // Enable FPRR policy and set up ranges on non-Capsule Update flow with Flash Wear-Out Protection enabled
+ // PrintFlashProtectionConfig() dumps FPRR information during ScPrintPolicyPpi()
+ // FPRR bit is enabled by default as per Platform policy, except that when system is in recovery mode or FDO is enabled. In this case this will be disabled as part of Firmware Update / Recovery update
+ //
+ if (FlashProtectionEnabled && (FdoEnabledGuidHob == NULL)) {
+ //
+ // Flash Protection Range Register initialization
+ //
+ for (Index = 0; Index < SC_FLASH_PROTECTED_RANGES; Index++) {
+ FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable = TRUE;
+ FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable = FALSE;
+ }
+
+ DEBUG ((EFI_D_INFO, "IbbOffset = %x , IbbSize = %x\n", FixedPcdGet32 (PcdFlashIbbRegionMappedBase), FixedPcdGet32 (PcdFlashIbbRegionSize)));
+ DEBUG ((EFI_D_INFO, "ObbOffset = %x , ObbSize = %x\n", FixedPcdGet32 (PcdFlashObbRegionMappedBase), FixedPcdGet32 (PcdFlashObbRegionSize)));
+
+ //
+ // Assign FPRR ranges
+ //
+ FlashProtectionConfig->ProtectRange[0].ProtectedRangeBase = (UINT16) ((FixedPcdGet32 (PcdFlashIbbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress)) >> 12);
+ FlashProtectionConfig->ProtectRange[0].ProtectedRangeLimit = (UINT16) ((FixedPcdGet32 (PcdFlashIbbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress) + FixedPcdGet32 (PcdFlashIbbRegionSize) - 1) >> 12);
+ FlashProtectionConfig->ProtectRange[1].ProtectedRangeBase = (UINT16) ((FixedPcdGet32 (PcdFlashObbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress)) >> 12);
+ FlashProtectionConfig->ProtectRange[1].ProtectedRangeLimit = (UINT16) ((FixedPcdGet32 (PcdFlashObbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress) + FixedPcdGet32 (PcdFlashObbRegionSize) - 1) >> 12);
+ } else {
+ DEBUG ((DEBUG_INFO, " BIOS FPRR is not done -FDO ASSERT Status "));
+ }
+ }
+
+ DciConfig->DciEn = SystemConfiguration.DciEn;
+ DciConfig->DciAutoDetect = SystemConfiguration.DciAutoDetect;
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.h
new file mode 100644
index 0000000000..ee360ccd1f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiScPolicyUpdate.h
@@ -0,0 +1,41 @@
+/** @file
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_SC_POLICY_UPDATE_H_
+#define _PEI_SC_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiPei.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SteppingLib.h>
+#include <ScAccess.h>
+#include <Library/ScPlatformLib.h>
+
+//
+// Generic definitions for device Auto/enabling/disabling used by platform
+//
+#define DEVICE_AUTO 2
+#define DEVICE_ENABLE 1
+#define DEVICE_DISABLE 0
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
new file mode 100644
index 0000000000..4fc9434988
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
@@ -0,0 +1,65 @@
+/** @file
+ This file is SampleCode of the library for Intel Silicon PEI
+ Platform Policy initialzation.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiSiPolicyUpdate.h"
+#include <Library/PeiServicesLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+/**
+ This function performs Silicon PEI Policy initialzation.
+
+ @param[in] SiPolicy The Silicon Policy PPI instance
+
+ @retval EFI_SUCCESS The function completed successfully
+
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+ IN OUT SI_POLICY_PPI *SiPolicy
+ )
+{
+ UINTN VariableSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ EFI_STATUS Status;
+
+ //
+ // Update Silicon Policy Config
+ //
+ //
+ // Retrieve Setup variable
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ PLATFORM_SETUP_VARIABLE_NAME,
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VariableSize,
+ &SystemConfiguration
+ );
+ SiPolicy->OsSelection = 3;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
new file mode 100644
index 0000000000..711a5b4818
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
@@ -0,0 +1,26 @@
+/** @file
+ Header file for PEI SiPolicyUpdate.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_H_
+#define _PEI_SI_POLICY_UPDATE_H_
+
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Ppi/SiPolicyPpi.h>
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.c
new file mode 100644
index 0000000000..9d3b8056b2
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.c
@@ -0,0 +1,240 @@
+/** @file
+ Variable Cache Library implementation file.
+ This library builds a variable cache HOB consumed by the variable driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <VariableNvmStorageFormat.h>
+#include <Library/VariableNvmStorageLib.h>
+#include <Library/PeiVariableCacheLib.h>
+
+EFI_STATUS
+EFIAPI
+InitializeVariableCacheStore (
+ IN VARIABLE_STORE_HEADER *VariableCacheStore
+ )
+{
+ if (VariableCacheStore == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the variable store
+ //
+ CopyMem (&VariableCacheStore->Signature, &gEfiVariableGuid, sizeof (EFI_GUID));
+
+ VariableCacheStore->Format = VARIABLE_STORE_FORMATTED;
+ VariableCacheStore->State = VAR_IN_DELETED_TRANSITION;
+ VariableCacheStore->Size = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+//
+// Copy the NVM variable to a new variable in the cache store
+//
+EFI_STATUS
+EFIAPI
+CopyNvmVariablesToCacheStore (
+ IN VARIABLE_STORE_HEADER *VariableStoreHeader,
+ IN VARIABLE_NVM_STORE_INFO *VariableNvmStoreInfo
+ )
+{
+ VARIABLE_HEADER *VariableHeader = NULL;
+ VARIABLE_NVM_HEADER *VariableNvmHeader = NULL;
+ CHAR16 *VariableNamePtr = NULL;
+ UINT8 *VariableDataPtr = NULL;
+ UINTN *MrcDataPtr = NULL;
+
+ VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader + 1);
+ VariableNvmHeader = GetStartPointer (VariableNvmStoreInfo->VariableStoreHeader);
+
+ DEBUG ((EFI_D_INFO, "++> Copying variables from the pre-memory location to the cache HOB...\n"));
+ DEBUG ((EFI_D_INFO, " Starting pointers: VariableHeader at %p. VariableNvmHeader at %p.\n", VariableHeader, VariableNvmHeader));
+
+ while (IsValidVariableHeader (VariableNvmHeader, GetEndPointer (VariableNvmStoreInfo->VariableStoreHeader))) {
+
+ VariableHeader->StartId = VARIABLE_DATA;
+ VariableHeader->State = VAR_ADDED;
+ VariableHeader->Attributes = VariableNvmHeader->Attributes;
+ VariableHeader->NameSize = VariableNvmHeader->NameSize;
+ VariableHeader->DataSize = VariableNvmHeader->DataSize;
+
+ VariableNamePtr = (CHAR16 *) ((UINTN) VariableHeader + ((VariableNvmStoreInfo->AuthFlag) ? sizeof (AUTHENTICATED_VARIABLE_HEADER) : sizeof (VARIABLE_HEADER)));
+ VariableDataPtr = (UINT8 *) ((UINTN) VariableNamePtr + VariableHeader->NameSize + GET_PAD_SIZE (VariableHeader->NameSize));
+
+ DEBUG ((EFI_D_INFO, " VariableNamePtr is %p. VariableDataPtr is %p.\n", VariableNamePtr, VariableDataPtr));
+
+ //
+ // Capture the MRC configuration data address
+ //
+ if ((StrCmp (GetVariableNamePtr (VariableNvmHeader, VariableNvmStoreInfo->AuthFlag), L"MemoryConfig") == 0
+ || StrCmp (GetVariableNamePtr (VariableNvmHeader, VariableNvmStoreInfo->AuthFlag), L"MemoryBootData") == 0)
+ && CompareGuid (&VariableNvmHeader->VendorGuid, &gEfiMemoryConfigVariableGuid)) {
+
+ VariableHeader->DataSize = sizeof (UINTN);
+ MrcDataPtr = (UINTN *) VariableDataPtr;
+ *MrcDataPtr = (UINTN) ((UINTN) VariableNvmStoreInfo->VariableStoreHeader + GetVariableDataPtr (VariableNvmHeader, VariableNvmStoreInfo));
+
+ DEBUG ((EFI_D_INFO, " Found memory config data in variable store (in SRAM) at address 0x%x. Storing address in cache store...\n", *MrcDataPtr));
+ } else {
+ DEBUG ((EFI_D_INFO, " Variable data pointer = 0x%x.\n", ((UINTN) VariableNvmStoreInfo->VariableStoreHeader + GetVariableDataPtr (VariableNvmHeader, VariableNvmStoreInfo))));
+ CopyMem (VariableDataPtr,
+ (UINT8 *) ((UINTN) VariableNvmStoreInfo->VariableStoreHeader + GetVariableDataPtr (VariableNvmHeader, VariableNvmStoreInfo)),
+ VariableNvmHeader->DataSize
+ );
+ }
+
+ //
+ // Copy the variable GUID and name
+ //
+ CopyMem (&VariableHeader->VendorGuid, &VariableNvmHeader->VendorGuid, sizeof (EFI_GUID));
+ CopyMem (VariableNamePtr, GetVariableNamePtr (VariableNvmHeader, VariableNvmStoreInfo->AuthFlag), VariableNvmHeader->NameSize);
+
+ DEBUG ((EFI_D_INFO, " Variable name is %s and variable GUID is %g.\n", VariableNamePtr, &VariableHeader->VendorGuid));
+
+ //
+ // Output debug data for the variable just copied
+ //
+ DEBUG ((EFI_D_INFO, " Variable name is %d bytes.\n", VariableHeader->NameSize));
+ DEBUG ((EFI_D_INFO, " Variable data is %d bytes.\n", VariableHeader->DataSize));
+
+ VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VariableDataPtr + VariableHeader->DataSize + GET_PAD_SIZE (VariableHeader->DataSize));
+ VariableNvmHeader = GetNextVariablePtr (VariableNvmStoreInfo, VariableNvmHeader);
+ }
+
+ ASSERT ((UINTN) VariableHeader > (UINTN) VariableStoreHeader);
+ VariableStoreHeader->Size = (UINT32) ((UINTN) VariableHeader - (UINTN) VariableStoreHeader);
+
+ DEBUG ((EFI_D_INFO, " Final VariableStoreHeader size = %d bytes.\n", VariableStoreHeader->Size));
+ return EFI_SUCCESS;
+}
+
+
+UINT32
+EFIAPI
+GetNewVariableStoreSize (
+ IN VARIABLE_NVM_STORE_INFO *VariableNvmStoreInfo
+ )
+{
+ UINT32 VariableStoreSize = 0;
+ VARIABLE_NVM_HEADER *VariableNvmHeader = GetStartPointer (VariableNvmStoreInfo->VariableStoreHeader);
+
+ DEBUG ((EFI_D_INFO, "Start pointer = %p\n", VariableNvmHeader));
+
+ VariableStoreSize = VariableNvmStoreInfo->VariableStoreHeader->Size;
+ while (IsValidVariableHeader (VariableNvmHeader, GetEndPointer (VariableNvmStoreInfo->VariableStoreHeader))) {
+ if ((StrCmp (GetVariableNamePtr (VariableNvmHeader, VariableNvmStoreInfo->AuthFlag), L"MemoryConfig") == 0
+ || StrCmp (GetVariableNamePtr (VariableNvmHeader, VariableNvmStoreInfo->AuthFlag), L"MemoryBootData") == 0)
+ && CompareGuid (&VariableNvmHeader->VendorGuid, &gEfiMemoryConfigVariableGuid)) {
+ VariableStoreSize -= VariableNvmHeader->DataSize;
+ VariableStoreSize += sizeof (UINTN);
+ break;
+ }
+ VariableNvmHeader = GetNextVariablePtr (VariableNvmStoreInfo, VariableNvmHeader);
+ }
+
+ return VariableStoreSize;
+}
+
+
+/**
+ Creates the PEI variable cache HOB.
+
+ @param[out] MemoryConfigData A pointer to the memory training data.
+ This function will modify the pointer to point to the training data.
+
+ @retval EFI_SUCCESS The PEI variable cache was successfully created.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateVariableCacheHob (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_NVM_STORE_INFO VariableNvmStoreInfo;
+ UINT32 TotalVariableFileSize = 0;
+ EFI_HOB_GUID_TYPE *PreMemoryVariableLocationGuidHob = NULL;
+ PRE_MEMORY_VARIABLE_LOCATION_HOB *PreMemoryLocationHob = NULL;
+
+ if (GetFirstGuidHob (&gPeiVariableCacheHobGuid) != NULL) {
+ //
+ // Variable cache HOB already created
+ //
+ return EFI_SUCCESS;
+ }
+
+ // The variable store (at a memory address) to cache is passed via PreMemoryVariableLocationHob.
+ //
+ PreMemoryVariableLocationGuidHob = GetFirstGuidHob (&gPreMemoryVariableLocationHobGuid);
+
+ if (PreMemoryVariableLocationGuidHob == NULL) {
+ DEBUG ((EFI_D_ERROR, "Pre-memory variable location HOB not found. Could not build the variable cache.\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ PreMemoryLocationHob = (PRE_MEMORY_VARIABLE_LOCATION_HOB *) (VOID *) GET_GUID_HOB_DATA (PreMemoryVariableLocationGuidHob);
+
+ if (PreMemoryLocationHob == NULL) {
+ DEBUG ((EFI_D_ERROR, "Pre-memory variable data could be not found. Could not build the variable cache.\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ VariableNvmStoreInfo.VariableStoreHeader = PreMemoryLocationHob->VariableDataPtr;
+ Status = IsAuthenticatedVariableStore (PreMemoryLocationHob->VariableDataPtr, &VariableNvmStoreInfo.AuthFlag);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TotalVariableFileSize = GetNewVariableStoreSize (&VariableNvmStoreInfo);
+ DEBUG ((EFI_D_INFO, "Total variable store size in pre-memory file = %d bytes.\n", TotalVariableFileSize));
+
+ //
+ // Ensure the PEI variable cache size does not exceed the platform defined limit
+ //
+ if (TotalVariableFileSize > PcdGet32 (PcdVariableCacheMaximumSize)) {
+ DEBUG ((EFI_D_ERROR, "The space required for the variable cache exceeds the maximum cache size specified. Actual = 0x%x Maximum = 0x%x\n",
+ TotalVariableFileSize,
+ PcdGet32 (PcdVariableCacheMaximumSize)));
+
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Create the variable cache HOB
+ //
+ VariableStoreHeader = BuildGuidHob (&gPeiVariableCacheHobGuid, TotalVariableFileSize);
+ if (VariableStoreHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (VariableStoreHeader, TotalVariableFileSize);
+
+ DEBUG ((EFI_D_INFO, "VariableCacheStore HOB is allocated at 0x%x\n", VariableStoreHeader));
+
+ InitializeVariableCacheStore (VariableStoreHeader);
+
+ Status = CopyNvmVariablesToCacheStore (VariableStoreHeader, &VariableNvmStoreInfo);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Variable cache created successfully\n"));
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.h b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.h
new file mode 100644
index 0000000000..7a7352a410
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.h
@@ -0,0 +1,46 @@
+/** @file
+ Header file for the Variable Cache Library.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_VARIABLE_CACHE_LIB_H_
+#define _PEI_VARIABLE_CACHE_LIB_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/PeiVariableCacheHobGuid.h>
+#include <Guid/PreMemoryVariableLocationHobGuid.h>
+#include <Guid/VariableFormat.h>
+
+
+/**
+ Creates the variable cache HOB which holds variables in memory decided
+ by the platform.
+
+ @param VOID
+
+ @retval EFI_SUCCESS The PEI variable cache was successfully created
+
+**/
+EFI_STATUS
+EFIAPI
+CreateVariableCacheHob (
+ VOID
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.inf
new file mode 100644
index 0000000000..bf382ed927
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PeiVariableCacheLib/PeiVariableCacheLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Variable Cache Library information file.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiVariableCacheLib
+ FILE_GUID = 76AE6165-CBFD-4BEC-B364-5D09E720CDA6
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiVariableCacheLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ PcdLib
+ VariableNvmStorageLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ PeiVariableCacheLib.c
+
+[Guids]
+ gEfiMemoryConfigVariableGuid
+ gEfiVariableGuid
+ gPeiVariableCacheHobGuid
+ gPreMemoryVariableLocationHobGuid
+
+[Pcd]
+ gSiPkgTokenSpaceGuid.PcdVariableCacheMaximumSize
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c
new file mode 100644
index 0000000000..af887e4cc9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c
@@ -0,0 +1,2401 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BdsPlatform.h"
+#include "SetupMode.h"
+#include <Guid/SetupVariable.h>
+#include <Guid/EventGroup.h>
+#include <Library/TcgPhysicalPresenceLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Guid/TpmInstance.h>
+#include <Guid/PttPTPInstanceGuid.h>
+#include <Library/IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/ExitPmAuth.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/CustomizedDisplayLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/TimerLib.h>
+#include "Guid/Tcg2PhysicalPresenceData.h"
+#include "Guid/PhysicalPresenceData.h"
+
+extern EFI_GUID gUndiDriverImageGuid;
+
+EFI_GUID gUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 };
+
+EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;
+EFI_EVENT mHotKeyTimerEvent = NULL;
+EFI_EVENT mHitHotkeyEvent = NULL;
+BOOLEAN mHotKeyPressed = FALSE;
+VOID *mHitHotkeyRegistration;
+
+#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
+
+extern EFI_STATUS
+IFWIUpdateHack (
+ );
+
+EFI_STATUS
+PlatformBdsConnectSimpleConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+VOID
+EFIAPI
+PlatformBdsInitHotKeyEvent (
+ VOID
+ );
+
+VOID
+EFIAPI
+UnloadNetworkDriver (
+ VOID
+ );
+
+
+/**
+ An empty function to pass error checking of CreateEventEx ().
+
+ This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
+ checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+
+VOID
+InstallReadyToLock (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+ EFI_EVENT EndOfDxeEvent;
+ UINTN VarSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ //
+ // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter
+ // NOTE: We can NOT put it to PlatformBdsInit, because many boot script touch PCI BAR. :-(
+ // We have to connect PCI root bridge, allocate resource, then ExitPmAuth().
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gExitPmAuthProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InternalBdsEmptyCallbackFuntion,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ gBS->SignalEvent (EndOfDxeEvent);
+ gBS->CloseEvent (EndOfDxeEvent);
+ DEBUG ((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+ //
+ // Install DxeSmmReadyToLock protocol prior to the processing of boot options
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **) &SmmAccess);
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);
+ if (!EFI_ERROR (Status)) {
+ AcpiS3Save->S3Save (AcpiS3Save, NULL);
+ }
+
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return;
+}
+
+
+//
+// BDS Platform Functions
+//
+/**
+ Recursively connect all child devices to the handle that matches a given Device Path
+
+ @param[in] DevicePathToConnect The device path which will be connected
+
+ @retval EFI_SUCCESS All child handles have been created
+ @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
+ @retval EFI_NOT_FOUND Creating the child handles failed
+
+**/
+EFI_STATUS
+EFIAPI
+ConnectDevicePathRecursive (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
+ EFI_HANDLE Handle;
+
+ if (DevicePathToConnect == NULL) {
+ return EFI_SUCCESS;
+ }
+ DevicePath = DuplicateDevicePath (DevicePathToConnect);
+ if (DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyOfDevicePath = DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Handle);
+ if (!EFI_ERROR (Status)) {
+ gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ }
+
+ if (CopyOfDevicePath != NULL) {
+ FreePool (CopyOfDevicePath);
+ }
+ return Status;
+}
+
+
+/**
+ When FastBoot is enabled, all input devices may not be connected by default.
+ Hence, when entering into Setup menu, connecting all input consoles are required.
+
+ @param[in] Event The Event this notify function registered to.
+ @param[in] Context Pointer to the context data registerd to the
+ Event.
+
+ @return None.
+
+**/
+VOID
+ConnectAllConsolesForSetupMenu (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Protocol;
+
+ Status = gBS->LocateProtocol(
+ &gSetupEnterGuid,
+ NULL,
+ &Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+
+ //
+ // Connect PS2 and USB KB if boot to SETUP menu
+ //
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimpleUsbConInConsole[0].DevicePath, NULL);
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimplePs2ConInConsole[0].DevicePath, NULL);
+ BdsLibConnectAll ();
+}
+
+
+/**
+ Check if current BootCurrent variable is internal shell boot option.
+
+ @retval TRUE BootCurrent is internal shell.
+ @retval FALSE BootCurrent is not internal shell.
+
+**/
+BOOLEAN
+BootCurrentIsInternalShell (
+ VOID
+ )
+{
+ UINTN VarSize;
+ UINT16 BootCurrent;
+ CHAR16 BootOptionName[16];
+ UINT8 *BootOption;
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *BootDevicePath;
+ BOOLEAN Result;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
+ EFI_GUID *GuidPoint;
+
+ BootOption = NULL;
+ BootDevicePath = NULL;
+ Result = FALSE;
+
+ //
+ // Get BootCurrent variable
+ //
+ VarSize = sizeof (UINT16);
+ Status = gRT->GetVariable (
+ L"BootCurrent",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &VarSize,
+ &BootCurrent
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // Create boot option Bootxxxx from BootCurrent
+ //
+ UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04X", BootCurrent);
+
+ GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
+ if (BootOption == NULL || VarSize == 0) {
+ return FALSE;
+ }
+
+ Ptr = BootOption;
+ Ptr += sizeof (UINT32);
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((CHAR16 *) Ptr);
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ LastDeviceNode = TempDevicePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ LastDeviceNode = TempDevicePath;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+ GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+ (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+ );
+ if ((GuidPoint != NULL) &&
+ ((CompareGuid (GuidPoint, PcdGetPtr(PcdShellFile))) ||
+ (CompareGuid (GuidPoint, &gUefiShellFileGuid)))
+ ) {
+ //
+ // if this option is internal shell, return TRUE
+ //
+ Result = TRUE;
+ }
+
+ if (BootOption != NULL) {
+ FreePool (BootOption);
+ BootOption = NULL;
+ }
+
+ return Result;
+}
+
+
+/**
+ ReadyToBoot callback to set video and text mode for internal shell boot.
+
+ When FastBoot is enabled, input devices will not be connected
+ by default. Hence, when booting to EFI shell, connecting input consoles are required.
+
+ @param[in] Event Pointer to this event
+ @param[in] Context Event hanlder private data
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+FastBootOnReadyToBootCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Connect PS2 and USB KB if boot to shell
+ //
+ if (BootCurrentIsInternalShell ()) {
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimpleUsbConInConsole[0].DevicePath, NULL);
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimplePs2ConInConsole[0].DevicePath, NULL);
+ BdsLibConnectAll ();
+ }
+}
+
+
+/**
+ Update ConIn by corresponding console input behavior.
+
+ @param none
+
+ @retval none
+
+**/
+VOID
+FastBootUpdateConInVarByConInBehavior (
+ IN SYSTEM_CONFIGURATION SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ VOID *SetupRegistration;
+ EFI_EVENT Event;
+
+ DEBUG ((EFI_D_INFO,"ConInBehavior is %x\n", SystemConfiguration.ConInBehavior));
+ switch (SystemConfiguration.ConInBehavior) {
+ case PS2_CONSOLE:
+ //
+ // Remove all device path from ConIn first.
+ // Then create ConIn for PS2 or USB base on PS2 KB connected or not.
+ //
+ Status = gRT->SetVariable (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+
+ PlatformBdsConnectSimpleConsole (gPlatformSimpleUsbConInConsole);
+ break;
+
+ case RECONNECT_LAST_GOOD_INPUT_CONSOLE:
+ PlatformBdsConnectConsole (gPlatformConsole);
+ break;
+
+ case WINDOWS_CONSOLE:
+ //
+ // Remove all device path from ConIn.
+ // BIOS should not enumerate any input devices when Windows Console behavior is used
+ //
+ Status = gRT->SetVariable (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // Create event to connect ConIn device for internal shell.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ FastBootOnReadyToBootCallBack,
+ NULL,
+ &Event
+ );
+
+ //
+ // Register notification event for enter setup event
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gSetupEnterGuid,
+ TPL_CALLBACK,
+ ConnectAllConsolesForSetupMenu,
+ NULL,
+ &SetupRegistration
+ );
+
+}
+
+
+/**
+ Platform Bds init. Include the platform firmware vendor, revision
+ and so crc check.
+
+ @param None
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsInit (
+ VOID
+ )
+{
+ //
+ // Before user authentication, the user identification devices need be connected
+ // from the platform customized device paths
+ //
+ PlatformBdsConnectAuthDevice ();
+
+ //
+ // As console is not ready, the auto logon user will be identified.
+ //
+ BdsLibUserIdentify (&mCurrentUser);
+}
+
+
+EFI_STATUS
+GetGopDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
+ OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_HANDLE PciDeviceHandle;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
+ UINTN GopHandleCount;
+ EFI_HANDLE *GopHandleBuffer;
+ UINTN VarSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ if (PciDevicePath == NULL || GopDevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the GopDevicePath to be PciDevicePath
+ //
+ *GopDevicePath = PciDevicePath;
+ TempPciDevicePath = PciDevicePath;
+
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TempPciDevicePath,
+ &PciDeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Try to connect this handle, so that GOP driver could start on this
+ // device and create child handles with GraphicsOutput Protocol installed
+ // on them, then we get device paths of these child handles and select
+ // them as possible console device.
+ //
+
+ //
+ // Select display devices
+ //
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ if (SystemConfiguration.BootDisplayDevice != 0x0) {
+ ACPI_ADR_DEVICE_PATH AcpiAdr;
+ EFI_DEVICE_PATH_PROTOCOL *MyDevicePath = NULL;
+
+ AcpiAdr.Header.Type = ACPI_DEVICE_PATH;
+ AcpiAdr.Header.SubType = ACPI_ADR_DP;
+
+ switch (SystemConfiguration.BootDisplayDevice) {
+ case 1:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0); //CRT Device
+ break;
+ case 2:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0); //HDMI Device Port B
+ break;
+ case 3:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0); //DP PortB
+ break;
+ case 4:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0); //DP PortC
+ break;
+ case 5:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0); //eDP Port C
+ break;
+ case 6:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0); //DSI Port A
+ break;
+ case 7:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0); //DSI Port C
+ break;
+ default:
+ AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
+ break;
+ }
+
+ SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+ MyDevicePath = AppendDevicePathNode (MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &AcpiAdr);
+
+ gBS->ConnectController (PciDeviceHandle, NULL, MyDevicePath, FALSE);
+
+ FreePool(MyDevicePath);
+ } else {
+ gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiGraphicsOutputProtocolGuid,
+ NULL,
+ &GopHandleCount,
+ &GopHandleBuffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Add all the child handles as possible Console Device
+ //
+ for (Index = 0; Index < GopHandleCount; Index++) {
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &TempDevicePath);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ if (CompareMem (
+ PciDevicePath,
+ TempDevicePath,
+ GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
+ ) == 0) {
+ //
+ // In current implementation, we only enable one of the child handles
+ // as console device, i.e. store one of the child handle's device
+ // path to variable "ConOut"
+ // In future, we could select all child handles to be console device
+ //
+
+ *GopDevicePath = TempDevicePath;
+ }
+ }
+ gBS->FreePool (GopHandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Search out all the platform pci or agp video device. The function may will
+ find multiple video device, and return all enabled device path.
+
+ @param[in, out] PlugInPciVgaDevicePath Return the platform plug in pci video device
+ path if the system have plug in pci video device
+ @param[in, out] OnboardPciVgaDevicePath Return the platform active agp video device path
+ if the system have plug in agp video device or on
+ chip agp device
+
+ @retval EFI_SUCCSS Get all platform active video device path
+ @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
+ gBS->ConnectController ()
+ and gBS->LocateHandleBuffer ()
+
+**/
+EFI_STATUS
+GetPlugInPciVgaDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **PlugInPciVgaDevicePath,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **OnboardPciVgaDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE RootHandle;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ UINTN Index1;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ BOOLEAN PlugInPciVga;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ DevicePath = NULL;
+ PlugInPciVga = TRUE;
+ HandleCount = 0;
+ HandleBuffer = NULL;
+
+ //
+ // Make all the PCI_IO protocols on PCI Seg 0 show up
+ //
+ BdsLibConnectDevicePath (gPlatformRootBridges[0]);
+
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &gPlatformRootBridges[0],
+ &RootHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Start to check all the pci io to find all possible VGA device
+ //
+ HandleCount = 0;
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Check for all VGA device
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Here we decide which VGA device to enable in PCI bus
+ //
+ // The first plugin PCI VGA card device will be present as PCI VGA
+ // The onchip AGP or AGP card will be present as AGP VGA
+ //
+ if (!IS_PCI_VGA (&Pci)) {
+ continue;
+ }
+
+ //
+ // Set the device as the possible console out device,
+ //
+ // Below code will make every VGA device to be one
+ // of the possible console out device
+ //
+ PlugInPciVga = TRUE;
+ gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath
+ );
+
+ Index1 = 0;
+
+ while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
+ if (CompareMem (
+ DevicePath,
+ gPlatformAllPossiblePciVgaConsole[Index1],
+ GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
+ ) == 0) {
+
+ //
+ // This device is an AGP device
+ //
+ *OnboardPciVgaDevicePath = DevicePath;
+ PlugInPciVga = FALSE;
+ break;
+ }
+
+ Index1 ++;
+ }
+
+ if (PlugInPciVga) {
+ *PlugInPciVgaDevicePath = DevicePath;
+ }
+ }
+ }
+
+ FreePool (HandleBuffer);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Find the platform active vga, and base on the policy to enable the vga as
+ the console out device. The policy is driven by one setup variable "VBIOS".
+
+ @param None.
+
+ @retval EFI_UNSUPPORTED There is no active vga device
+ @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
+
+**/
+EFI_STATUS
+PlatformBdsForceActiveVga (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *PlugInPciVgaDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *OnboardPciVgaDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathFirst;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathSecond;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+ UINTN VarSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ Status = EFI_SUCCESS;
+ GopDevicePath = NULL;
+ PlugInPciVgaDevicePath = NULL;
+ OnboardPciVgaDevicePath = NULL;
+
+ //
+ // Check the policy which is the first enabled VGA
+ //
+ GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
+
+ DEBUG ((EFI_D_INFO,"PlugInPciVgaDevicePath: 0x%x OnboardPciVgaDevicePath: 0x%x\n", PlugInPciVgaDevicePath, OnboardPciVgaDevicePath));
+
+ if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL)) {
+ DEBUG ((EFI_D_INFO, "Update onboard PCI VGA ...\n"));
+ DevicePathFirst = OnboardPciVgaDevicePath;
+ DevicePathSecond = PlugInPciVgaDevicePath;
+ goto UpdateConOut;
+ }
+ if (OnboardPciVgaDevicePath != NULL && SystemConfiguration.PrimaryVideoAdaptor == 0) {
+ DEBUG ((EFI_D_ERROR, "Update onboard PCI VGA When set primary!!!...\n"));
+ DevicePathFirst = OnboardPciVgaDevicePath;
+ DevicePathSecond = PlugInPciVgaDevicePath;
+ goto UpdateConOut;
+ }
+ DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
+ DevicePathFirst = PlugInPciVgaDevicePath;
+ DevicePathSecond = OnboardPciVgaDevicePath;
+
+UpdateConOut:
+ GetGopDevicePath (DevicePathFirst, &GopDevicePath);
+ DevicePathFirst = GopDevicePath;
+
+ Status = BdsLibUpdateConsoleVariable (
+ L"ConOut",
+ DevicePathFirst,
+ DevicePathSecond
+ );
+
+ return Status;
+}
+
+
+/**
+ Connect the predefined platform default console device. Always try to find
+ and enable the vga device if have.
+
+ @param[in] PlatformConsole Predefined platform default console device array.
+
+ @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
+ device, there must have one ConOut device is
+ active vga device.
+
+ @retval EFI_STATUS Return the status of
+ BdsLibConnectAllDefaultConsoles ()
+
+**/
+EFI_STATUS
+PlatformBdsConnectConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *VarConout;
+ EFI_DEVICE_PATH_PROTOCOL *VarConin;
+ UINTN DevicePathSize;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+ DevicePathSize = 0;
+ VarConout = BdsLibGetVariableAndSize (
+ L"ConOut",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+
+ VarConin = BdsLibGetVariableAndSize (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+
+ DEBUG ((EFI_D_INFO, "Enter PlatformBdsConnectConsole()\n"));
+ if (VarConout == NULL || VarConin == NULL) {
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimue device group
+ // the platform should support
+ //
+ while (PlatformConsole[Index].DevicePath != NULL) {
+
+ //
+ // Update the console variable with the connect type
+ //
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ Index ++;
+ }
+ }
+
+ //
+ // Connect to serial device. Needed by GOP driver, hence before BdsLibConnectAllDefaultConsoles().
+ //
+ BdsLibConnectDevicePath (gSerialIoConnect[0]);
+
+ //
+ // Make sure we have at least one active VGA, and have the right
+ // active VGA in console variable
+ //
+ Status = PlatformBdsForceActiveVga ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Connect the all the default console with current console variable
+ //
+ Status = BdsLibConnectAllDefaultConsoles ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+{
+ UINTN Index;
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform connect sequence
+ // Notes: we can connect with new variable which record the
+ // last time boots connect device path sequence
+ //
+ while (gPlatformConnectSequence[Index] != NULL) {
+
+ //
+ // Build the platform boot option
+ //
+ BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
+ Index ++;
+ }
+
+ //
+ // Just use the simple policy to connect all devices
+ // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
+ //
+ // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
+ // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
+ //
+ // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
+ // We may also consider to connect SataController only later if needed.
+ //
+ BdsLibConnectAll ();
+}
+
+
+/**
+ Load the predefined driver option, OEM/IBV can customize this
+ to load their own drivers
+
+ @param[in, out] BdsDriverLists The header of the driver option link list.
+
+ @retval None.
+
+**/
+VOID
+PlatformBdsGetDriverOption (
+ IN OUT LIST_ENTRY *BdsDriverLists
+ )
+{
+ UINTN Index;
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform driver option
+ //
+ while (gPlatformDriverOption[Index] != NULL) {
+
+ //
+ // Build the platform boot option
+ //
+ BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
+ Index ++;
+ }
+
+}
+
+
+/**
+ This function is used for some critical time if the the system
+ have no any boot option, and there is no time out for user to add
+ the new boot option. This can also treat as the platform default
+ boot option.
+
+ @param[in, out] BdsBootOptionList The header of the boot option link list.
+
+ @retval None.
+
+**/
+VOID
+PlatformBdsPredictBootOption (
+ IN OUT LIST_ENTRY *BdsBootOptionList
+ )
+{
+ UINTN Index;
+
+ Index = 0;
+
+ //
+ // Here give chance to get platform boot option data
+ //
+ while (gPlatformBootOption[Index] != NULL) {
+
+ //
+ // Build the platform boot option
+ //
+ BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");
+ Index ++;
+ }
+}
+
+
+/**
+ Perform the platform diagnostic, such like test memory. OEM/IBV also
+ can customize this fuction to support specific platform diagnostic.
+
+ @param[in] MemoryTestLevel The memory test intensive level
+ @param[in] QuietBoot Indicate if need to enable the quiet boot
+ @param[in] BaseMemoryTest A pointer to BdsMemoryTest()
+
+ @retval None.
+
+**/
+VOID
+PlatformBdsDiagnostics (
+ IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
+ IN BOOLEAN QuietBoot,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Here we can decide if we need to show
+ // the diagnostics screen
+ // Notes: this quiet boot code should be remove
+ // from the graphic lib
+ //
+ if (QuietBoot) {
+ EnableQuietBoot (PcdGetPtr (PcdLogoFile));
+
+ //
+ // Perform system diagnostic
+ //
+ Status = BaseMemoryTest (MemoryTestLevel);
+ if (EFI_ERROR (Status)) {
+ DisableQuietBoot ();
+ }
+
+ return;
+ }
+
+ //
+ // Perform system diagnostic
+ //
+ Status = BaseMemoryTest (MemoryTestLevel);
+}
+
+
+/**
+ The function will execute with as the platform policy, current policy
+ is driven by boot mode. IBV/OEM can customize this code for their specific
+ policy action.
+
+ @param[in] DriverOptionList The header of the driver option link list
+ @param[in] BootOptionList The header of the boot option link list
+ @param[in] ProcessCapsules A pointer to ProcessCapsules()
+ @param[in] BaseMemoryTest A pointer to BaseMemoryTest()
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+ IN OUT LIST_ENTRY *DriverOptionList,
+ IN OUT LIST_ENTRY *BootOptionList,
+ IN PROCESS_CAPSULES ProcessCapsules,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Timeout;
+ EFI_BOOT_MODE BootMode;
+ BOOLEAN DeferredImageExist;
+ UINTN Index;
+ CHAR16 CapsuleVarName[30];
+ CHAR16 *TempVarName;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VarSize;
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ UINT32 UcodeRevision;
+ EFI_INPUT_KEY Key;
+ CHAR16 *ErrorInfo = L"uCode/Punit patch is not being loaded.";
+ CHAR16 *PressKey = L"Press any key to continue...";
+ UINTN Tcg2PpDataSize;
+ EFI_TCG2_PHYSICAL_PRESENCE Tcg2PpData;
+ EFI_PHYSICAL_PRESENCE TcgPpData;
+ UINTN TcgPpDataSize;
+
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Load the driver option as the driver option list
+ //
+ PlatformBdsGetDriverOption (DriverOptionList);
+
+ //
+ // Get current Boot Mode
+ //
+ BootMode = GetBootModeHob ();
+
+ //
+ // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
+ // as early as possible which will avoid the next time boot after the capsule update
+ // will still into the capsule loop
+ //
+ StrCpyS (CapsuleVarName, sizeof (CapsuleVarName) / sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
+ TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
+ Index = 0;
+ while (TRUE) {
+ if (Index > 0) {
+ UnicodeValueToString (TempVarName, 0, Index, 0);
+ }
+ Status = gRT->SetVariable (
+ CapsuleVarName,
+ &gEfiCapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ (VOID *) NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // There is no capsule variables, quit
+ //
+ break;
+ }
+ Index ++;
+ }
+
+ //
+ // No deferred images exist by default
+ //
+ DeferredImageExist = FALSE;
+
+ if (SystemConfiguration.FastBoot == 1) {
+ BootOrder = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderSize
+ );
+
+ if (BootOrder != NULL) {
+ //
+ // BootOrder exist, it means system has boot before. We can do fast boot.
+ //
+ BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+ }
+ FastBootUpdateConInVarByConInBehavior (SystemConfiguration);
+ }
+
+ //
+ // Unload EFI network driver if it is disabled in setup
+ //
+ if ((!SystemConfiguration.EfiNetworkSupport) || (SystemConfiguration.FastBoot == 1)) {
+ UnloadNetworkDriver ();
+ }
+ //
+ // Display message to indicate Ucode patch fails.
+ //
+ UcodeRevision = GetCpuUcodeRevision ();
+ if ((UcodeRevision == 0 )){
+ PlatformBdsConnectConsole (gPlatformConsole);
+ CreateDialog (&Key, ErrorInfo, PressKey, NULL);
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ gST->ConOut->ClearScreen (gST->ConOut);
+ }
+
+ //
+ // This will lock physical presence flag, therefore, need to do this before signal EndOfDxe
+ //
+ if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) &&
+ (BootMode != BOOT_ASSUMING_NO_CONFIGURATION_CHANGES) &&
+ (BootMode != BOOT_ON_FLASH_UPDATE) &&
+ (BootMode != BOOT_IN_RECOVERY_MODE)) {
+
+ //
+ // Initialize physical presence variable.
+ //
+ if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+ CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+ Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &Tcg2PpDataSize,
+ &Tcg2PpData
+ );
+
+ if (EFI_ERROR (Status)) {
+ ZeroMem ((VOID *) &Tcg2PpData, sizeof (Tcg2PpData));
+ Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Tcg2PpDataSize,
+ &Tcg2PpData
+ );
+ }
+ } else if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+ TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ NULL,
+ &TcgPpDataSize,
+ &TcgPpData
+ );
+
+ if (EFI_ERROR (Status)) {
+ ZeroMem ((VOID *) &TcgPpData, sizeof (TcgPpData));
+ TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ TcgPpDataSize,
+ &TcgPpData
+ );
+ }
+ }
+
+ if (!EFI_ERROR (Status) && ((Tcg2PpData.PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) || (TcgPpData.PPRequest != TCG_PHYSICAL_PRESENCE_NO_ACTION))) {
+ //
+ // If it requests any action on TCG, need to connect console to display information.
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ }
+
+ if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+ CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+ Tcg2PhysicalPresenceLibProcessRequest (NULL);
+ } else if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+ TcgPhysicalPresenceLibProcessRequest ();
+ }
+ }
+
+ //
+ // Close boot script and install ready to lock.
+ // This needs to be done before option rom dispatched.
+ //
+ InstallReadyToLock ();
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior()__BootMode = %d\n", BootMode));
+ switch (BootMode) {
+ case BOOT_WITH_MINIMAL_CONFIGURATION:
+ PlatformBdsConnectSimpleConsole (gPlatformSimpleOnChipPciVgaConOutConsole);
+ //
+ // Connect boot device here to give time to read keyboard.
+ //
+ Index = 0;
+ while (gPlatformSimpleBootOption[Index] != NULL) {
+ BdsLibConnectDevicePath (gPlatformSimpleBootOption[Index]);
+ ConnectDevicePathRecursive (gPlatformSimpleBootOption[Index]);
+ Index ++;
+ }
+ break;
+
+ case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+ //
+ // In no-configuration boot mode, we can connect the
+ // console directly.
+ //
+ BdsLibConnectAllDefaultConsoles ();
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ //
+ // As console is ready, perform user identification again.
+ //
+ if (mCurrentUser == NULL) {
+ PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+ if (DeferredImageExist) {
+ //
+ // After user authentication, the deferred drivers was loaded again.
+ // Here, need to ensure the deferred images are connected.
+ //
+ BdsLibConnectAllDefaultConsoles ();
+ PlatformBdsConnectSequence ();
+ }
+ }
+
+ //
+ // Notes: current time out = 0 can not enter the
+ // front page
+ //
+ PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+
+ //
+ // Check the boot option with the boot option list
+ //
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+ break;
+
+ case BOOT_ON_FLASH_UPDATE:
+ //
+ // Boot with the specific configuration
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
+ BdsLibConnectAll ();
+
+ //
+ // Perform user identification
+ //
+ if (mCurrentUser == NULL) {
+ PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+ if (DeferredImageExist) {
+ //
+ // After user authentication, the deferred drivers was loaded again.
+ // Here, need to ensure the deferred images are connected.
+ //
+ BdsLibConnectAll ();
+ }
+ }
+
+ ProcessCapsules (BOOT_ON_FLASH_UPDATE);
+ break;
+
+ case BOOT_IN_RECOVERY_MODE:
+ //
+ // In recovery mode, just connect platform console
+ // and show up the front page
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
+ BdsLibConnectAll ();
+
+ //
+ // Perform user identification
+ //
+ if (mCurrentUser == NULL) {
+ PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+ if (DeferredImageExist) {
+ //
+ // After user authentication, the deferred drivers was loaded again.
+ // Here, need to ensure the deferred drivers are connected.
+ //
+ BdsLibConnectAll ();
+ }
+ }
+
+ //
+ // In recovery boot mode, we still enter to the
+ // frong page now
+ //
+ PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+ break;
+
+ case BOOT_WITH_FULL_CONFIGURATION:
+ case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+ case BOOT_WITH_DEFAULT_SETTINGS:
+ default:
+ //
+ // Connect platform console
+ //
+ Status = PlatformBdsConnectConsole (gPlatformConsole);
+ if (EFI_ERROR (Status)) {
+ //
+ // Here OEM/IBV can customize with defined action
+ //
+ PlatformBdsNoConsoleAction ();
+ }
+
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ //
+ // Perform memory test as appropriate in order to promote any untested memory
+ //
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+
+ //
+ // Do a pre-delay so Hard Disk can spin up and see more logo.
+ //
+ gBS->Stall (SystemConfiguration.HddPredelay * 1000000);
+
+ //
+ // Perform user identification
+ //
+ if (mCurrentUser == NULL) {
+ PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+ if (DeferredImageExist) {
+ //
+ // After user authentication, the deferred drivers was loaded again.
+ // Here, need to ensure the deferred drivers are connected.
+ //
+ Status = PlatformBdsConnectConsole (gPlatformConsole);
+ if (EFI_ERROR (Status)) {
+ PlatformBdsNoConsoleAction ();
+ }
+ PlatformBdsConnectSequence ();
+ }
+ }
+
+ //
+ // Give one chance to enter the setup if we
+ // have the time out
+ //
+ PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+
+ //
+ // In default boot mode, always find all boot
+ // option and do enumerate all the default boot option
+ //
+ if (Timeout == 0) {
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+ if (IsListEmpty(BootOptionList)) {
+ PlatformBdsPredictBootOption (BootOptionList);
+ }
+
+ return;
+ }
+
+ //
+ // Here we have enough time to do the enumeration of boot device
+ //
+ BdsLibEnumerateAllBootOption (BootOptionList);
+ break;
+ }
+ return;
+}
+
+
+/**
+ Hook point after a boot attempt succeeds. We don't expect a boot option to
+ return, so the UEFI 2.0 specification defines that you will default to an
+ interactive mode and stop processing the BootOrder list in this case. This
+ is also a platform implementation and can be customized by IBV/OEM.
+
+ @param[in] Option Pointer to Boot Option that succeeded to boot.
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootSuccess (
+ IN BDS_COMMON_OPTION *Option
+ )
+{
+ CHAR16 *TmpStr;
+
+ //
+ // If Boot returned with EFI_SUCCESS and there is not in the boot device
+ // select loop then we need to pop up a UI and wait for user input.
+ //
+ TmpStr = Option->StatusString;
+ if (TmpStr != NULL) {
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+ FreePool(TmpStr);
+ }
+}
+
+
+/**
+ Hook point after a boot attempt fails.
+
+ @param[in] Option Pointer to Boot Option that failed to boot.
+ @param[in] Status Status returned from failed boot.
+ @param[in] ExitData Exit data returned from failed boot.
+ @param[in] ExitDataSize Exit data size returned from failed boot.
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootFail (
+ IN BDS_COMMON_OPTION *Option,
+ IN EFI_STATUS Status,
+ IN CHAR16 *ExitData,
+ IN UINTN ExitDataSize
+ )
+{
+ CHAR16 *TmpStr;
+
+ //
+ // If Boot returned with failed status then we need to pop up a UI and wait
+ // for user input.
+ //
+ TmpStr = Option->StatusString;
+ if (TmpStr != NULL) {
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+ FreePool (TmpStr);
+ }
+}
+
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function locks the block.
+
+ @param[in] Base The base address flash region to be locked.
+
+**/
+VOID
+BdsLockFv (
+ IN EFI_PHYSICAL_ADDRESS Base
+ )
+{
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT8 Data;
+ UINT32 BlockLength;
+ UINTN Index;
+
+ BaseAddress = Base - 0x400000 + 2;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
+ BlockMap = &(FvHeader->BlockMap[0]);
+
+ while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
+ BlockLength = BlockMap->Length;
+ for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
+ Data = MmioOr8 ((UINTN) BaseAddress, 0x03);
+ BaseAddress += BlockLength;
+ }
+ BlockMap++;
+ }
+}
+
+
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+ VOID
+ )
+{
+ EFI_PHYSICAL_ADDRESS Base;
+
+ Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvOBBBase);
+ if (Base > 0) {
+ BdsLockFv (Base);
+ }
+
+ Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvIBBMBase);
+ if (Base > 0) {
+ BdsLockFv (Base);
+ }
+}
+
+
+/**
+ Lock the ConsoleIn device in system table. All key
+ presses will be ignored until the Password is typed in. The only way to
+ disable the password is to type it in to a ConIn device.
+
+ @param[in] Password Password used to lock ConIn device.
+
+ @retval EFI_SUCCESS Lock the Console In Splitter virtual handle successfully.
+ @retval EFI_UNSUPPORTED Password not found.
+
+**/
+EFI_STATUS
+EFIAPI
+LockKeyboards (
+ IN CHAR16 *Password
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Connect the predefined platform default authentication devices.
+
+ This function connects the predefined device path for authentication device,
+ and if the predefined device path has child device path, the child handle will
+ be connected too. But the child handle of the child will not be connected.
+
+**/
+VOID
+EFIAPI
+PlatformBdsConnectAuthDevice (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN HandleIndex;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
+ EFI_USER_MANAGER_PROTOCOL *Manager;
+
+ Status = gBS->LocateProtocol (
+ &gEfiUserManagerProtocolGuid,
+ NULL,
+ (VOID **) &Manager
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // As user manager protocol is not installed, the authentication devices
+ // should not be connected.
+ //
+ return ;
+ }
+
+ Index = 0;
+ while (gUserAuthenticationDevice[Index] != NULL) {
+ //
+ // Connect the platform customized device paths
+ //
+ BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
+ Index++;
+ }
+
+ //
+ // Find and connect the child device paths of the platform customized device paths
+ //
+ HandleBuffer = NULL;
+ for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
+ HandleCount = 0;
+ Status = gBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ ASSERT (!EFI_ERROR (Status));
+
+ //
+ // Find and connect the child device paths of gUserIdentificationDevice[Index]
+ //
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ ChildDevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ChildDevicePath
+ );
+ if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
+ continue;
+ }
+
+ if (CompareMem (
+ ChildDevicePath,
+ gUserAuthenticationDevice[Index],
+ (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
+ ) != 0) {
+ continue;
+ }
+ gBS->ConnectController (HandleBuffer[HandleIndex], NULL, NULL, TRUE);
+ }
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+}
+
+
+/**
+ This function is to identify a user, and return whether deferred images exist.
+
+ @param[out] User Point to user profile handle.
+ @param[out] DeferredImageExist On return, points to TRUE if the deferred image
+ exist or FALSE if it did not exist.
+
+**/
+VOID
+EFIAPI
+PlatformBdsUserIdentify (
+ OUT EFI_USER_PROFILE_HANDLE *User,
+ OUT BOOLEAN *DeferredImageExist
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuf;
+ UINTN Index;
+ UINTN DriverIndex;
+ EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
+ VOID *DriverImage;
+ UINTN ImageSize;
+ BOOLEAN BootOption;
+
+ //
+ // Perform user identification
+ //
+ do {
+ Status = BdsLibUserIdentify (User);
+ } while (EFI_ERROR (Status));
+
+ //
+ // After user authentication now, try to find whether deferred image exists
+ //
+ HandleCount = 0;
+ HandleBuf = NULL;
+ *DeferredImageExist = FALSE;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDeferredImageLoadProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuf
+ );
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuf[Index],
+ &gEfiDeferredImageLoadProtocolGuid,
+ (VOID **) &DeferredImage
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Find whether deferred image exists in this instance.
+ //
+ DriverIndex = 0;
+ Status = DeferredImage->GetImageInfo(
+ DeferredImage,
+ DriverIndex,
+ &ImageDevicePath,
+ (VOID **) &DriverImage,
+ &ImageSize,
+ &BootOption
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // The deferred image is found.
+ //
+ FreePool (HandleBuf);
+ *DeferredImageExist = TRUE;
+ return ;
+ }
+ }
+ }
+
+ FreePool (HandleBuf);
+}
+
+UINTN gHotKey = 0;
+
+
+EFI_STATUS
+ShowProgressHotKey (
+ IN UINT16 TimeoutDefault
+ )
+{
+ CHAR16 *TmpStr;
+ UINT16 TimeoutRemain;
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
+
+ if (TimeoutDefault == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
+
+ SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+ SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+ SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+
+ //
+ // Clear the progress status bar first
+ //
+ TmpStr = L"Start boot option";
+ PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
+
+ //
+ // TimeoutDefault is determined by PcdPlatformBootTimeOut in PcdsDynamicHii.Default.dsc
+ //
+ TimeoutRemain = TimeoutDefault;
+
+ while (TimeoutRemain != 0) {
+ DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
+
+ Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
+ if (Status != EFI_TIMEOUT) {
+ break;
+ }
+ TimeoutRemain--;
+
+ //
+ // Show progress
+ //
+ if (TmpStr != NULL) {
+ PlatformBdsShowProgress (
+ Foreground,
+ Background,
+ TmpStr,
+ Color,
+ ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
+ 0
+ );
+ }
+ }
+
+ //
+ // Timeout expired
+ //
+ if (TimeoutRemain == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // User pressed some key
+ //
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ //
+ // User pressed enter, equivalent to select "continue"
+ //
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // F2 -- Front Page
+ // F5 -- Device Manager
+ // F7 -- Boot Manager
+ // do not use F8. generally people assume it is windows safe mode key.
+ // F9 -- Boot order
+ //
+ DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
+ switch (Key.ScanCode) {
+ case SCAN_F2:
+ gHotKey = 0;
+ break;
+
+ case SCAN_F5:
+ gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
+ break;
+
+ case SCAN_F7:
+ gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
+ break;
+
+ case SCAN_F9:
+ gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
+ break;
+
+ default:
+ //
+ //set gHotKey to continue so that flow will not go into CallFrontPage
+ //
+ gHotKey = FRONT_PAGE_KEY_CONTINUE;
+ return EFI_TIMEOUT;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function is the main entry of the platform setup entry.
+ The function will present the main menu of the system setup,
+ this is the platform reference part and can be customize.
+
+
+ @param[in] TimeoutDefault The fault time out value before the system
+ continue to boot.
+ @param[in] ConnectAllHappened The indicator to check if the connect all have
+ already happened.
+
+**/
+VOID
+PlatformBdsEnterFrontPageWithHotKey (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
+ UINTN BootTextColumn;
+ UINTN BootTextRow;
+
+ GraphicsOutput = NULL;
+ SimpleTextOut = NULL;
+
+ PERF_START (NULL, "BdsTimeOut", "BDS", 0);
+ //
+ // Indicate if we need connect all in the platform setup
+ //
+ if (ConnectAllHappened) {
+ gConnectAllHappened = TRUE;
+ }
+
+ if (!mModeInitialized) {
+ //
+ // After the console is ready, get current video resolution
+ // and text mode before launching setup at first time.
+ //
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **) &GraphicsOutput
+ );
+ if (EFI_ERROR (Status)) {
+ GraphicsOutput = NULL;
+ }
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID **) &SimpleTextOut
+ );
+ if (EFI_ERROR (Status)) {
+ SimpleTextOut = NULL;
+ }
+
+ if (GraphicsOutput != NULL) {
+ //
+ // Get current video resolution and text mode.
+ //
+ mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
+ mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
+ }
+
+ if (SimpleTextOut != NULL) {
+ Status = SimpleTextOut->QueryMode (
+ SimpleTextOut,
+ SimpleTextOut->Mode->Mode,
+ &BootTextColumn,
+ &BootTextRow
+ );
+ mBootTextModeColumn = (UINT32) BootTextColumn;
+ mBootTextModeRow = (UINT32) BootTextRow;
+ }
+
+ //
+ // Get user defined text mode for setup.
+ //
+ mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+ mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
+ mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
+ mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
+
+ mModeInitialized = TRUE;
+ }
+
+ if (TimeoutDefault != 0xffff) {
+ Status = ShowProgressHotKey (TimeoutDefault);
+
+ //
+ // Ensure screen is clear when switch Console from Graphics mode to Text mode
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+ gST->ConOut->ClearScreen (gST->ConOut);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Timeout or user press enter to continue
+ //
+ goto Exit;
+ }
+ }
+ InitBMPackage ();
+ do {
+ BdsSetConsoleMode (TRUE);
+ InitializeFrontPage (FALSE);
+
+ //
+ // Update Front Page strings
+ //
+ UpdateFrontPageStrings ();
+
+ Status = EFI_SUCCESS;
+ gCallbackKey = 0;
+
+ if (gHotKey == 0) {
+ Status = CallFrontPage ();
+ } else {
+ gCallbackKey = gHotKey;
+ gHotKey = 0;
+ }
+
+ //
+ // If gCallbackKey is greater than 1 and less or equal to 5,
+ // it will launch configuration utilities.
+ // 2 = set language
+ // 3 = boot manager
+ // 4 = device manager
+ // 5 = boot maintenance manager
+ //
+ if (gCallbackKey != 0) {
+ REPORT_STATUS_CODE (
+ EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
+ );
+ }
+
+ //
+ // Based on the key that was set, we can determine what to do
+ //
+ switch (gCallbackKey) {
+ //
+ // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
+ // describe to their customers in documentation how to find their setup information (namely
+ // under the device manager and specific buckets)
+ //
+ // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
+ //
+ case FRONT_PAGE_KEY_CONTINUE:
+ //
+ // User hit continue
+ //
+ break;
+
+ case FRONT_PAGE_KEY_LANGUAGE:
+ //
+ // User made a language setting change - display front page again
+ //
+ break;
+
+ case FRONT_PAGE_KEY_BOOT_MANAGER:
+ FreeBMPackage ();
+ //
+ // User chose to run the Boot Manager
+ //
+ CallBootManager ();
+ InitBMPackage ();
+ break;
+
+ case FRONT_PAGE_KEY_DEVICE_MANAGER:
+ //
+ // Display the Device Manager
+ //
+ do {
+ CallDeviceManager ();
+ } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
+ break;
+
+ case FRONT_PAGE_KEY_BOOT_MAINTAIN:
+ //
+ // Display the Boot Maintenance Manager
+ //
+ BdsStartBootMaint ();
+ break;
+ }
+
+ } while (((UINTN) gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
+
+ //
+ // Will leave browser, check any reset required change is applied? if yes, reset system
+ //
+ SetupResetReminder ();
+ FreeBMPackage ();
+Exit:
+ //
+ // Automatically load current entry
+ // Note: The following lines of code only execute when Auto boot
+ // takes affect
+ //
+ PERF_END (NULL, "BdsTimeOut", "BDS", 0);
+}
+
+
+EFI_STATUS
+PlatformBdsConnectSimpleConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *VarConout;
+ EFI_DEVICE_PATH_PROTOCOL *VarConin;
+ UINTN DevicePathSize;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+ DevicePathSize = 0;
+ VarConout = BdsLibGetVariableAndSize (
+ L"ConOut",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+ VarConin = BdsLibGetVariableAndSize (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+ DEBUG ((EFI_D_INFO, "Enter PlatformBdsConnectSimpleConsole()\n"));
+ if (VarConout == NULL || VarConin == NULL) {
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimum device group
+ // the platform should support
+ //
+ while (PlatformConsole[Index].DevicePath != NULL) {
+
+ //
+ // Update the console variable with the connect type
+ //
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
+ //
+ // Make sure we have at least one active VGA, and have the right
+ // active VGA in console variable
+ //
+ Status = PlatformBdsForceActiveVga ();
+ }
+
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ Index ++;
+ }
+ }
+
+ //
+ // Connect ConIn first to give keyboard time to parse hot key event.
+ //
+ Status = BdsLibConnectConsoleVariable (L"ConIn");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // It seems impossible not to have any ConOut device on platform,
+ // so we check the status here.
+ //
+ Status = BdsLibConnectConsoleVariable (L"ConOut");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Timer handler to convert the key from USB.
+
+ @param[in] Event Indicates the event that invoke this function.
+ @param[in] Context Indicates the calling context.
+
+**/
+VOID
+EFIAPI
+HotKeyTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ switch (Key.ScanCode) {
+ case SCAN_F2:
+ gHotKey = 0;
+ mHotKeyPressed = TRUE;
+ break;
+
+ case SCAN_F5:
+ gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
+ mHotKeyPressed = TRUE;
+ break;
+
+ case SCAN_F7:
+ gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
+ mHotKeyPressed = TRUE;
+ break;
+
+ case SCAN_F9:
+ gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
+ mHotKeyPressed = TRUE;
+ break;
+ }
+
+ if (mHotKeyPressed) {
+ gBS->SetTimer (mHotKeyTimerEvent, TimerCancel, 0);
+ gBS->CloseEvent (mHotKeyTimerEvent);
+ mHotKeyTimerEvent = NULL;
+ }
+
+ return;
+}
+
+
+/**
+ Callback function for SimpleTextInEx protocol install events.
+
+ @param[in] Event The event that is signalled.
+ @param[in] Context Not used here.
+
+**/
+VOID
+EFIAPI
+HitHotkeyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HotKeyTimerHandler,
+ NULL,
+ &mHotKeyTimerEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ Status = gBS->SetTimer (
+ mHotKeyTimerEvent,
+ TimerPeriodic,
+ KEYBOARD_TIMER_INTERVAL
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ return;
+}
+
+
+VOID
+EFIAPI
+PlatformBdsInitHotKeyEvent (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Register Protocol notify for Hotkey service
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ HitHotkeyEvent,
+ NULL,
+ &mHitHotkeyEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for protocol notifications on this event
+ //
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiSimpleTextInputExProtocolGuid,
+ mHitHotkeyEvent,
+ &mHitHotkeyRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+EFIAPI
+UnloadNetworkDriver (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN DriverImageHandleCount;
+ EFI_HANDLE *DriverImageHandleBuffer;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_GUID *NameGuid;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
+
+ DriverImageHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ &DriverImageHandleCount,
+ &DriverImageHandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ for (Index = 0; Index < DriverImageHandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ DriverImageHandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ if (LoadedImage->FilePath == NULL) {
+ continue;
+ }
+
+ TempDevicePath = LoadedImage->FilePath;
+ LastDeviceNode = TempDevicePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ LastDeviceNode = TempDevicePath;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+ NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (
+ (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+ );
+ if ((NameGuid != NULL) && (CompareGuid (NameGuid, &gUndiDriverImageGuid))) {
+ Status = gBS->UnloadImage (DriverImageHandleBuffer[Index]);
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h
new file mode 100644
index 0000000000..18c5f88779
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h
@@ -0,0 +1,465 @@
+/** @file
+ Header file for BDS Platform specific code.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <FrameworkDxe.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/UserManager.h>
+#include <Protocol/DeferredImageLoad.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/LoadedImage.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/PlatformBdsLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <IndustryStandard/Pci.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformAllPossiblePciVgaConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformBootOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gUserAuthenticationDevice[];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleOnChipPciVgaConOutConsole [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleUsbConInConsole [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimplePs2ConInConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformSimpleBootOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gSerialIoConnect[];
+
+//
+// the short form device path for Usb keyboard
+//
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_KEYBOARD 1
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+ { \
+ HARDWARE_DEVICE_PATH, \
+ HW_PCI_DP, \
+ { \
+ (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+ }, \
+ (Func), \
+ (Dev) \
+ }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ EISA_PNP_ID((PnpId)), \
+ 0 \
+ }
+
+#define gUart(BaudRate, DataBits, Parity, StopBits) \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_UART_DP, \
+ { \
+ (UINT8) (sizeof (UART_DEVICE_PATH)), \
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ 0, \
+ (BaudRate), \
+ (DataBits), \
+ (Parity), \
+ (StopBits) \
+ }
+
+#define gPcAnsiTerminal \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_VENDOR_DP, \
+ { \
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ DEVICE_PATH_MESSAGING_PC_ANSI \
+ }
+
+#define gUsbKeyboardMouse \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_USB_CLASS_DP, \
+ (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), \
+ (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) \
+ }, \
+ 0xffff, \
+ 0xffff, \
+ CLASS_HID, \
+ SUBCLASS_BOOT, \
+ PROTOCOL_KEYBOARD \
+ }
+
+#define gEndEntire \
+ { \
+ END_DEVICE_PATH_TYPE, \
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+ { \
+ END_DEVICE_PATH_LENGTH, \
+ 0 \
+ } \
+ }
+
+#define gPciRootBridge \
+ PNPID_DEVICE_PATH_NODE(0x0A03)
+
+#define gPnpPs2Keyboard \
+ PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+ PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gPciIsaBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+#define gPciSpiBridge \
+ PCI_DEVICE_PATH_NODE(1, 0x19)
+
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH Keyboard;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ISA_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+ USB_CLASS_DEVICE_PATH UsbClass;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH OnboardVga;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ONBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH AgpBridge;
+ PCI_DEVICE_PATH AgpDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_OFFBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH IsaSerial;
+ UART_DEVICE_PATH Uart;
+ VENDOR_DEVICE_PATH TerminalType;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ISA_SERIAL_DEVICE_PATH;
+
+//
+// Below is the boot option device path
+//
+typedef struct {
+ BBS_BBS_DEVICE_PATH LegacyHD;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} LEGACY_HD_DEVICE_PATH;
+
+//
+// Below is the platform IDE device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ATAPI_DEVICE_PATH Ide;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_IDE_DEVICE_PATH;
+
+//
+// Floppy device path definition
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH Floppy;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_FLOPPY_DEVICE_PATH;
+
+//
+// Below is the platform USB controller device path for
+// USB disk as user authentication device.
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_USB_DEVICE_PATH;
+
+//
+// Below is the platform PCI device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_PCI_DEVICE_PATH;
+
+//
+// Platform BDS Functions
+//
+VOID
+PlatformBdsGetDriverOption (
+ IN LIST_ENTRY *BdsDriverLists
+ );
+
+VOID
+PlatformBdsPredictBootOption (
+ IN LIST_ENTRY *BdsBootOptionList
+ );
+
+EFI_STATUS
+PlatformBdsShowProgress (
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+ CHAR16 *Title,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+ UINTN Progress,
+ UINTN PreviousValue
+ );
+
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ );
+
+EFI_STATUS
+PlatformBdsConnectConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ );
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+VOID
+EFIAPI
+PlatformBdsUserIdentify (
+ OUT EFI_USER_PROFILE_HANDLE *User,
+ OUT BOOLEAN *DeferredImage
+ );
+
+VOID
+EFIAPI
+PlatformBdsConnectAuthDevice (
+ VOID
+ );
+
+VOID
+PlatformBdsEnterFrontPageWithHotKey (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+EFI_STATUS
+ShowProgress (
+ IN UINT16 TimeoutDefault
+ );
+
+EFI_STATUS
+InitializeFrontPage (
+ IN BOOLEAN InitializeHiiData
+ );
+
+VOID
+UpdateFrontPageStrings (
+ VOID
+ );
+
+EFI_STATUS
+CallFrontPage (
+ VOID
+ );
+
+VOID
+CallBootManager (
+ VOID
+ );
+
+VOID
+CallDeviceManager (
+ VOID
+ );
+
+CHAR16 *
+GetStringById (
+ IN EFI_STRING_ID Id
+ );
+
+EFI_STATUS
+WaitForSingleEvent (
+ IN EFI_EVENT Event,
+ IN UINT64 Timeout OPTIONAL
+ );
+
+EFI_STATUS
+BdsBootAndroidFromUsb (
+ VOID
+ );
+
+EFI_STATUS
+BdsBootAndroidFromEmmc (
+ VOID
+ );
+
+EFI_STATUS
+BdsBootAndroid (
+ VOID
+ );
+
+EFI_STATUS
+InitBMPackage (
+ VOID
+ );
+
+/**
+ Remvoe the intalled BootMaint and FileExplorer HiiPackages.
+
+**/
+VOID
+FreeBMPackage (
+ VOID
+ );
+
+/**
+ Start boot maintenance manager
+
+ @retval EFI_SUCCESS If BMM is invoked successfully.
+ @return Other value If BMM return unsuccessfully.
+
+**/
+EFI_STATUS
+BdsStartBootMaint (
+ VOID
+ );
+
+#define ONE_SECOND 10000000
+#define FRONT_PAGE_KEY_CONTINUE 0x1000
+#define FRONT_PAGE_KEY_LANGUAGE 0x1234
+#define FRONT_PAGE_KEY_BOOT_MANAGER 0x1064
+#define FRONT_PAGE_KEY_DEVICE_MANAGER 0x8567
+#define FRONT_PAGE_KEY_BOOT_MAINTAIN 0x9876
+
+#define PORT_A_DVO 0 // DVO A
+#define PORT_B_DVO 1 // DVO B
+#define PORT_C_DVO 2 // DVO C
+#define PORT_D_DVO 3 // DVO D
+#define PORT_LVDS 4 // Integrated LVDS port
+#define PORT_ANALOG_TV 5 // Integrated TV port
+#define PORT_CRT 6 // integrated Analog port
+#define PORT_B_DP 7 // DisplayPort B
+#define PORT_C_DP 8 // DisplayPort C
+#define PORT_D_DP 9 // DisplayPort D
+#define PORT_A_DP 10 // DisplayPort A (for eDP on ILK)
+#define PORT_B_HDMI 11 // HDMI B
+#define PORT_C_HDMI 12 // HDMI C
+#define PORT_D_HDMI 13 // HDMI D
+#define PORT_B_DVI 14 // DVI B
+#define PORT_C_DVI 15 // DVI C
+#define PORT_D_DVI 16 // DVI D
+#define PORT_MIPI_A 21 // MIPI
+#define PORT_MIPI_B 22
+#define PORT_MIPI_C 23
+
+extern BOOLEAN gConnectAllHappened;
+extern UINTN gCallbackKey;
+
+VOID
+BdsBootDeviceSelect (
+ VOID
+ );
+
+VOID FastBoot(VOID);
+
+extern BOOLEAN mModeInitialized;
+
+//
+// Boot video resolution and text mode.
+//
+extern UINT32 mBootHorizontalResolution ;
+extern UINT32 mBootVerticalResolution ;
+extern UINT32 mBootTextModeColumn ;
+extern UINT32 mBootTextModeRow ;
+//
+// BIOS setup video resolution and text mode.
+//
+extern UINT32 mSetupTextModeColumn ;
+extern UINT32 mSetupTextModeRow ;
+extern UINT32 mSetupHorizontalResolution ;
+extern UINT32 mSetupVerticalResolution ;
+
+extern EFI_STATUS BdsSetConsoleMode (BOOLEAN);
+#endif // _BDS_PLATFORM_H
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c
new file mode 100644
index 0000000000..4b99d0014f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c
@@ -0,0 +1,586 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "EfiBootStub.h"
+#include "OsipPrivate.h"
+#include <Library/DxeServicesLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Global descriptor table (GDT) Template
+//
+STATIC GDT_ENTRIES GdtTemplate = {
+ //
+ // NULL_SEL
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+
+ //
+ // NULL_SEL2
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+
+ //
+ // SYS_CODE_SEL
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x09B, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+
+ //
+ // SYS_DATA_SEL
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x093, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ }
+};
+
+VOID
+AsmStartLinuxKernel (
+ UINT32 KernelEntry
+ );
+
+EFI_STATUS
+IsFileExistent (
+ IN EFI_HANDLE Device,
+ IN CONST CHAR16 *FileName
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
+ EFI_FILE_HANDLE Root;
+ EFI_FILE_HANDLE ThisFile;
+
+ Root = NULL;
+ ThisFile = NULL;
+ //
+ // Handle the file system interface to the device
+ //
+ Status = gBS->HandleProtocol (
+ Device,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **) &Volume
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = Volume->OpenVolume (
+ Volume,
+ &Root
+ );
+ if (EFI_ERROR (Status)) {
+ Root = NULL;
+ goto Done;
+ }
+ ASSERT (Root != NULL);
+ Status = Root->Open (Root, &ThisFile, (CHAR16 *) FileName, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (ThisFile != NULL);
+
+Done:
+ if (ThisFile != NULL) {
+ ThisFile->Close (ThisFile);
+ }
+ if (Root != NULL) {
+ Root->Close (Root);
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+LoadFileFromFileSystem (
+ IN CONST CHAR16 *FileName,
+ OUT VOID **FileBuffer,
+ OUT UINTN *FileSize
+ )
+{
+ EFI_HANDLE *FileSystemHandles;
+ UINTN NumberFileSystemHandles;
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ UINT32 AuthenticationStatus;
+
+ *FileBuffer = NULL;
+ *FileSize = 0;
+ //
+ // If there is simple file protocol which does not consume block Io protocol,
+ // create a boot option for it here.
+ //
+ FileSystemHandles = NULL;
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &NumberFileSystemHandles,
+ &FileSystemHandles
+ );
+
+ for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+ Status = IsFileExistent (FileSystemHandles[Index], FileName);
+ if (!EFI_ERROR (Status)) {
+ FilePath = FileDevicePath (FileSystemHandles[Index], FileName);
+ *FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize,&AuthenticationStatus);
+ FreePool (FilePath);
+
+ if (*FileBuffer != NULL)
+ break;
+ }
+ }
+
+ if (FileSystemHandles) {
+ FreePool (FileSystemHandles);
+ }
+
+ if (*FileBuffer == NULL)
+ return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+setup_boot_params (
+ IN struct boot_params *bp,
+ struct setup_header *sh,
+ IN VOID *CmdLine,
+ IN VOID *InitrdPtr,
+ IN UINTN InitrdSize
+ )
+{
+ UINT8 Index;
+
+ ZeroMem (bp, sizeof (struct boot_params));
+ bp->screen_info.orig_video_mode = 0;
+ bp->screen_info.orig_video_lines = 0;
+ bp->screen_info.orig_video_cols = 0;
+ bp->alt_mem_k = 128 * 1024; // hard coded 128M mem here, since SFI will override it
+ CopyMem (&bp->hdr, sh, sizeof (struct setup_header));
+ bp->hdr.cmd_line_ptr = (UINT32) (UINTN) CmdLine;
+ bp->hdr.cmdline_size = (UINT32) (AsciiStrLen ((CONST CHAR8 *) (UINTN) CmdLine));
+ bp->hdr.type_of_loader = 0xff; //bootstub is unknown bootloader for kernel :)
+ bp->hdr.ramdisk_size = (UINT32) InitrdSize;
+ bp->hdr.ramdisk_image = (bp->alt_mem_k * 1024 - bp->hdr.ramdisk_size) & 0xFFFFF000;
+ bp->hdr.hardware_subarch = X86_SUBARCH_MRST;
+
+ DEBUG ((EFI_D_INFO, "Relocating initramfs to high memory ...\n"));
+ CopyMem ((UINT8 *) (UINTN) bp->hdr.ramdisk_image, (UINT8 *) InitrdPtr, (UINTN) bp->hdr.ramdisk_size);
+
+ //
+ // Prepare the e820 , hard code now
+ //
+ Index = 0;
+ bp->e820_map[Index].addr = 0x00000;
+ bp->e820_map[Index].size = 0x8f000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x8f000;
+ bp->e820_map[Index].size = 0x90000 - 0x8f000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_map[Index].addr = 0x90000;
+ bp->e820_map[Index].size = 0xa0000 - 0x90000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x100000;
+ bp->e820_map[Index].size = 0x3afcf000 - 0x100000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x3afcf000;
+ bp->e820_map[Index].size = 0x3b7ff000 - 0x3afcf000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_map[Index].addr = 0x3b7ff000;
+ bp->e820_map[Index].size = 0x3b800000 - 0x3b7ff000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_entries = Index;
+
+}
+
+
+UINT32
+get_32bit_entry (
+ unsigned char *ptr
+ )
+{
+ while (1){
+ if (*(UINT32 *) ptr == SETUP_SIGNATURE && *(UINT32 *) (ptr+4) == 0)
+ break;
+ ptr++;
+ }
+ ptr+=4;
+ return (UINT32) (((UINTN) ptr + 511) / 512) * 512;
+}
+
+
+EFI_STATUS
+EfiBootStub (
+ IN VOID *CmdLine,
+ IN VOID *KernelPtr,
+ IN UINTN KernelSize,
+ IN VOID *InitrdPtr,
+ IN UINTN InitrdSize
+ )
+{
+ GDT_ENTRIES *gdt;
+ IA32_DESCRIPTOR gdtPtr;
+ IA32_DESCRIPTOR idtPtr = {0, 0};
+ UINT32 KernelEntry;
+
+ setup_boot_params (
+ (struct boot_params *) (UINTN) BOOT_PARAMS_OFFSET,
+ (struct setup_header *) (UINTN) SETUP_HEADER_OFFSET,
+ CmdLine,
+ InitrdPtr,
+ InitrdSize
+ );
+
+ SetInterruptState (FALSE);
+
+ //
+ // Load idt and gdt
+ //
+ AsmWriteIdtr (&idtPtr);
+
+ gdt = (GDT_ENTRIES *) (UINTN) ((UINTN) CmdLine - 0x1000);
+ CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));
+
+ //
+ // Write GDT register
+ //
+ gdtPtr.Base = (UINT32) (UINTN) (VOID *) gdt;
+ gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
+ AsmWriteGdtr (&gdtPtr);
+
+ //
+ // Jmp to the kernel entry
+ //
+#if X64_BUILD_ENABLE
+ //
+ //put X64 jump here...
+ //
+ KernelEntry = 0;
+#else
+ KernelEntry = get_32bit_entry ((unsigned char *) (UINTN) BZIMAGE_OFFSET);
+ AsmStartLinuxKernel (KernelEntry);
+#endif
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+BdsBootAndroidFromUsb (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *KernelFileBuffer;
+ UINTN KernelFileSize;
+ VOID *InitrdFileBuffer;
+ UINTN InitrdFileSize;
+ UINT8 *CmdPtr;
+ CHAR8 DefaultCmdLine [] = "console=ttyS0,115200 console=logk0 earlyprintk=nologger loglevel=8 kmemleak=off androidboot.bootmedia=sdcard androidboot.hardware=baylake emmc_ipanic.ipanic_part_number=1 vga=current i915.modeset=1 drm.vblankoffdelay=1 acpi_backlight=vendor";
+ CHAR8 MainBootMode [] = "androidboot.wakesrc=00 androidboot.mode=main";
+
+ //
+ // Load the kernel image
+ //
+ KernelFileBuffer = NULL;
+ KernelFileSize = 0;
+ Status = LoadFileFromFileSystem (L"\\kernel.img", &KernelFileBuffer, &KernelFileSize);
+ if (EFI_ERROR (Status))
+ return EFI_NOT_FOUND;
+
+ //
+ // Load the initrd image
+ //
+ InitrdFileBuffer = NULL;
+ InitrdFileSize = 0;
+ Status = LoadFileFromFileSystem (L"\\initrd.img", &InitrdFileBuffer, &InitrdFileSize);
+ if (EFI_ERROR (Status))
+ return EFI_NOT_FOUND;
+
+ //
+ // Prepare the cmd line at 0x1100000
+ //
+ CmdPtr = (UINT8 *) (UINTN) CMDLINE_OFFSET;
+ ZeroMem (CmdPtr, 0x200);
+ CopyMem (CmdPtr, DefaultCmdLine, sizeof (DefaultCmdLine));
+ CmdPtr += (sizeof (DefaultCmdLine) - 1);
+ *CmdPtr = 0x20;
+ CmdPtr += 1;
+ CopyMem (CmdPtr, MainBootMode, sizeof (MainBootMode));
+ CmdPtr += (sizeof (MainBootMode) - 1);
+ *CmdPtr = 0x0A;
+
+ //
+ // Copy the kernel image to 0x1102000
+ //
+ CmdPtr = (UINT8 *) (UINTN) BZIMAGE_OFFSET;
+ CopyMem (CmdPtr, KernelFileBuffer, KernelFileSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelFileSize, InitrdFileBuffer, InitrdFileSize);
+
+ FreePool (KernelFileBuffer);
+ FreePool (InitrdFileBuffer);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+LoadOsipImageFromBlockDevices (
+ IN UINTN ImageIndex,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *BlockIoHandles;
+ UINTN NumberBlockIoHandles;
+ UINTN Index;
+ EFI_BLOCK_IO_PROTOCOL *TestBlockIo;
+ EFI_BLOCK_IO_PROTOCOL *EmmcBlockIo;
+ VOID *OsipBuffer;
+ OSIP_HEADER *pOSIP;
+ UINTN FirstBlock;
+ UINTN NumberBlocks;
+ VOID *pLoadAddress;
+ UINTN OSSize;
+ UINTN VrlSize;
+ BOOLEAN SignedOs;
+
+ EmmcBlockIo = NULL;
+ pOSIP = NULL;
+
+ OsipBuffer = NULL;
+ OsipBuffer = AllocatePages (OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ if (!OsipBuffer)
+ return EFI_OUT_OF_RESOURCES;
+
+ BlockIoHandles = NULL;
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ &NumberBlockIoHandles,
+ &BlockIoHandles
+ );
+
+ for (Index = 0; Index < NumberBlockIoHandles; Index++) {
+ TestBlockIo = NULL;
+ Status = gBS->HandleProtocol(
+ BlockIoHandles[Index],
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &TestBlockIo
+ );
+ if ((EFI_ERROR (Status)) || (TestBlockIo == NULL)) {
+ continue;
+ }
+
+ //
+ // Read OSIP block from the block devices
+ //
+ ZeroMem (OsipBuffer, OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE);
+ Status = TestBlockIo->ReadBlocks(
+ TestBlockIo,
+ TestBlockIo->Media->MediaId,
+ (EFI_LBA) 0, // OSIP hard coded to start at LBA 0
+ OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE,
+ (VOID *) (UINTN) OsipBuffer);
+ if (EFI_ERROR (Status))
+ continue;
+
+ pOSIP = (OSIP_HEADER *) (UINTN) OsipBuffer;
+ if (pOSIP->Signature == OSIP_HEADER_SIGNATURE) {
+ EmmcBlockIo = TestBlockIo;
+ ValidateOsip(pOSIP, 1);
+ break;
+ }
+
+ pOSIP = NULL;
+ }
+
+ if (BlockIoHandles) {
+ FreePool (BlockIoHandles);
+ }
+
+ if ((!EmmcBlockIo) || (!pOSIP)) {
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES(OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Parse OSII entry and find OS Image size in bytes
+ //
+ FirstBlock = pOSIP->Osii[ImageIndex].FirstBlock;
+ NumberBlocks = pOSIP->Osii[ImageIndex].BlockCount;
+ pLoadAddress = (VOID *) (UINTN)(pOSIP->Osii[ImageIndex].LoadAddress);
+ OSSize = NumberBlocks * OSP_BLOCK_SIZE;
+
+ //
+ // Load OS image to the address required
+ //
+ Status = EmmcBlockIo->ReadBlocks(
+ EmmcBlockIo,
+ EmmcBlockIo->Media->MediaId,
+ FirstBlock,
+ OSSize,
+ (VOID *) (UINTN) pLoadAddress);
+ if (EFI_ERROR(Status)) {
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ SignedOs = ((pOSIP->Osii[ImageIndex].Attributes & 1) == 0) ? TRUE : FALSE;
+ if (SignedOs) {
+ VrlSize = 0x1e0;
+ } else {
+ VrlSize = 0;
+ }
+
+ OSSize -= VrlSize;
+
+ if (ImageBase)
+ *ImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN)pLoadAddress;
+
+ if (ImageSize)
+ *ImageSize = OSSize;
+
+ if (EntryPoint)
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) pOSIP->Osii[ImageIndex].EntryPoint;
+
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BdsBootAndroidFromEmmc (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN KernelSize;
+ VOID *InitrdBuffer;
+ UINTN InitrdSize;
+ UINT8 *CmdPtr;
+ CHAR8 DefaultCmdLine [] = "console=ttyS0,115200 console=logk0 earlyprintk=nologger loglevel=8 kmemleak=off androidboot.bootmedia=sdcard androidboot.hardware=baylake emmc_ipanic.ipanic_part_number=1 vga=current i915.modeset=1 drm.vblankoffdelay=1 acpi_backlight=vendor";
+ CHAR8 MainBootMode [] = "androidboot.wakesrc=00 androidboot.mode=main";
+
+ Status = LoadOsipImageFromBlockDevices (0, NULL, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to find OSIP Structure in any block devices \n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Prepare the cmd line at 0x1100000
+ //
+ CmdPtr = (UINT8 *) (UINTN) CMDLINE_OFFSET;
+ ZeroMem (CmdPtr, 0x200);
+ CopyMem (CmdPtr, DefaultCmdLine, sizeof (DefaultCmdLine));
+ CmdPtr += (sizeof (DefaultCmdLine) - 1);
+ *CmdPtr = 0x20;
+ CmdPtr += 1;
+ CopyMem (CmdPtr, MainBootMode, sizeof (MainBootMode));
+ CmdPtr += (sizeof (MainBootMode) - 1);
+ *CmdPtr = 0x0A;
+
+ //
+ // Get the kernel and initrd information
+ //
+ KernelSize = *((UINT32 *) (UINTN) BZIMAGE_SIZE_OFFSET);
+ InitrdSize = *((UINT32 *) (UINTN) INITRD_SIZE_OFFSET);
+ InitrdBuffer = (VOID *) (UINTN) (BZIMAGE_OFFSET + KernelSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelSize, InitrdBuffer, InitrdSize);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+BdsBootAndroid (
+ VOID
+ )
+{
+ UINTN KernelSize;
+ VOID *InitrdBuffer;
+ UINTN InitrdSize;
+
+ //
+ // Get the kernel and initrd information
+ //
+ KernelSize = *((UINT32 *) (UINTN) BZIMAGE_SIZE_OFFSET);
+ InitrdSize = *((UINT32 *) (UINTN) INITRD_SIZE_OFFSET);
+ InitrdBuffer = (VOID *) (UINTN) (BZIMAGE_OFFSET + KernelSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelSize, InitrdBuffer, InitrdSize);
+
+ return EFI_DEVICE_ERROR;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h
new file mode 100644
index 0000000000..71a9048a24
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h
@@ -0,0 +1,330 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DevicePathLib.h>
+#include "BdsPlatform.h"
+
+#pragma pack(1)
+
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
+
+#define EDD_MBR_SIG_MAX 16
+#define E820MAX 128
+#define EDDMAXNR 6
+
+struct screen_info {
+ __u8 orig_x;
+ __u8 orig_y;
+ __u16 ext_mem_k;
+ __u16 orig_video_page;
+ __u8 orig_video_mode;
+ __u8 orig_video_cols;
+ __u16 unused2;
+ __u16 orig_video_ega_bx;
+ __u16 unused3;
+ __u8 orig_video_lines;
+ __u8 orig_video_isVGA;
+ __u16 orig_video_points;
+
+ //
+ // VESA graphic mode -- linear frame buffer
+ //
+ __u16 lfb_width;
+ __u16 lfb_height;
+ __u16 lfb_depth;
+ __u32 lfb_base;
+ __u32 lfb_size;
+ __u16 cl_magic, cl_offset;
+ __u16 lfb_linelength;
+ __u8 red_size;
+ __u8 red_pos;
+ __u8 green_size;
+ __u8 green_pos;
+ __u8 blue_size;
+ __u8 blue_pos;
+ __u8 rsvd_size;
+ __u8 rsvd_pos;
+ __u16 vesapm_seg;
+ __u16 vesapm_off;
+ __u16 pages;
+ __u16 vesa_attributes;
+ __u32 capabilities;
+ __u8 _reserved[6];
+};
+
+
+struct apm_bios_info {
+ __u16 version;
+ __u16 cseg;
+ __u32 offset;
+ __u16 cseg_16;
+ __u16 dseg;
+ __u16 flags;
+ __u16 cseg_len;
+ __u16 cseg_16_len;
+ __u16 dseg_len;
+};
+
+struct ist_info {
+ __u32 signature;
+ __u32 command;
+ __u32 event;
+ __u32 perf_level;
+};
+
+struct sys_desc_table {
+ __u16 length;
+ __u8 table[14];
+};
+
+struct efi_info {
+ __u32 efi_loader_signature;
+ __u32 efi_systab;
+ __u32 efi_memdesc_size;
+ __u32 efi_memdesc_version;
+ __u32 efi_memmap;
+ __u32 efi_memmap_size;
+ __u32 efi_systab_hi;
+ __u32 efi_memmap_hi;
+};
+
+struct setup_header {
+ __u8 setup_sects;
+ __u16 root_flags;
+ __u32 syssize;
+ __u16 ram_size;
+ __u16 vid_mode;
+ __u16 root_dev;
+ __u16 boot_flag;
+ __u16 jump;
+ __u32 header;
+ __u16 version;
+ __u32 realmode_swtch;
+ __u16 start_sys;
+ __u16 kernel_version;
+ __u8 type_of_loader;
+ __u8 loadflags;
+ __u16 setup_move_size;
+ __u32 code32_start;
+ __u32 ramdisk_image;
+ __u32 ramdisk_size;
+ __u32 bootsect_kludge;
+ __u16 heap_end_ptr;
+ __u16 _pad1;
+ __u32 cmd_line_ptr;
+ __u32 initrd_addr_max;
+ __u32 kernel_alignment;
+ __u8 relocatable_kernel;
+ __u8 _pad2[3];
+ __u32 cmdline_size;
+ __u32 hardware_subarch;
+ __u64 hardware_subarch_data;
+ __u32 payload_offset;
+ __u32 payload_length;
+ __u64 setup_data;
+};
+
+struct edid_info {
+ unsigned char dummy[128];
+};
+
+struct e820entry {
+ __u64 addr; ///< start of memory segment
+ __u64 size; ///< size of memory segment
+ __u32 type; ///< type of memory segment
+};
+
+struct edd_device_params {
+ __u16 length;
+ __u16 info_flags;
+ __u32 num_default_cylinders;
+ __u32 num_default_heads;
+ __u32 sectors_per_track;
+ __u64 number_of_sectors;
+ __u16 bytes_per_sector;
+ __u32 dpte_ptr; ///< 0xFFFFFFFF for our purposes
+ __u16 key; ///< = 0xBEDD
+ __u8 device_path_info_length; ///< = 44
+ __u8 reserved2;
+ __u16 reserved3;
+ __u8 host_bus_type[4];
+ __u8 interface_type[8];
+ union {
+ struct {
+ __u16 base_address;
+ __u16 reserved1;
+ __u32 reserved2;
+ } isa;
+ struct {
+ __u8 bus;
+ __u8 slot;
+ __u8 function;
+ __u8 channel;
+ __u32 reserved;
+ } pci;
+
+ //
+ // pcix is same as pci
+ //
+ struct {
+ __u64 reserved;
+ } ibnd;
+ struct {
+ __u64 reserved;
+ } xprs;
+ struct {
+ __u64 reserved;
+ } htpt;
+ struct {
+ __u64 reserved;
+ } unknown;
+ } interface_path;
+ union {
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } ata;
+ struct {
+ __u8 device;
+ __u8 lun;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } atapi;
+ struct {
+ __u16 id;
+ __u64 lun;
+ __u16 reserved1;
+ __u32 reserved2;
+ } scsi;
+ struct {
+ __u64 serial_number;
+ __u64 reserved;
+ } usb;
+ struct {
+ __u64 eui;
+ __u64 reserved;
+ } i1394;
+ struct {
+ __u64 wwid;
+ __u64 lun;
+ } fibre;
+ struct {
+ __u64 identity_tag;
+ __u64 reserved;
+ } i2o;
+ struct {
+ __u32 array_number;
+ __u32 reserved1;
+ __u64 reserved2;
+ } raid;
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } sata;
+ struct {
+ __u64 reserved1;
+ __u64 reserved2;
+ } unknown;
+ } device_path;
+ __u8 reserved4;
+ __u8 checksum;
+};
+
+struct edd_info {
+ __u8 device;
+ __u8 version;
+ __u16 interface_support;
+ __u16 legacy_max_cylinder;
+ __u8 legacy_max_head;
+ __u8 legacy_sectors_per_track;
+ struct edd_device_params params;
+};
+
+//
+// The so-called "zeropage"
+//
+struct boot_params {
+ struct screen_info screen_info;
+ struct apm_bios_info apm_bios_info;
+ __u8 _pad2[12];
+ struct ist_info ist_info;
+ __u8 _pad3[16];
+ __u8 hd0_info[16];
+ __u8 hd1_info[16];
+ struct sys_desc_table sys_desc_table;
+ __u8 _pad4[144];
+ struct edid_info edid_info;
+ struct efi_info efi_info;
+ __u32 alt_mem_k;
+ __u32 scratch;
+ __u8 e820_entries;
+ __u8 eddbuf_entries;
+ __u8 edd_mbr_sig_buf_entries;
+ __u8 _pad6[6];
+ struct setup_header hdr;
+ __u8 _pad7[0x290 - 0x1f1 - sizeof (struct setup_header)];
+ __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];
+ struct e820entry e820_map[E820MAX];
+ __u8 _pad8[48];
+ struct edd_info eddbuf[EDDMAXNR];
+ __u8 _pad9[276];
+} ;
+
+#define X86_SUBARCH_PC 0
+#define X86_SUBARCH_LGUEST 1
+#define X86_SUBARCH_XEN 2
+#define X86_SUBARCH_MRST 3
+
+typedef struct _GDT_ENTRY {
+ UINT16 Limit15_0;
+ UINT16 Base15_0;
+ UINT8 Base23_16;
+ UINT8 Type;
+ UINT8 Limit19_16_and_flags;
+ UINT8 Base31_24;
+} GDT_ENTRY;
+
+typedef struct _GDT_ENTRIES {
+ GDT_ENTRY Null;
+ GDT_ENTRY Null2;
+ GDT_ENTRY SysCode;
+ GDT_ENTRY SysData;
+} GDT_ENTRIES;
+
+#pragma pack()
+
+#define CMDLINE_OFFSET 0x1100000
+#define BZIMAGE_SIZE_OFFSET (CMDLINE_OFFSET + 0x400)
+#define INITRD_SIZE_OFFSET (BZIMAGE_SIZE_OFFSET + 4)
+#define STACK_OFFSET 0x1101000
+#define BZIMAGE_OFFSET 0x1102000
+
+#define SETUP_HEADER_OFFSET (BZIMAGE_OFFSET + 0x1F1)
+#define SETUP_HEADER_SIZE (0x0202 + *(unsigned char*)(0x0201+BZIMAGE_OFFSET))
+#define BOOT_PARAMS_OFFSET 0x8000
+
+#define SETUP_SIGNATURE 0x5a5aaa55
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm
new file mode 100644
index 0000000000..4cd4bfe001
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm
@@ -0,0 +1,54 @@
+;; @file
+; This is the ASM for Jump to a specific address.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+
+JumpToVector PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter - Parameter to pass in
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+JumpToVector PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD
+
+ push ebx
+
+ mov ebx, Parameter
+ mov ecx, EntryPoint
+ push ebx
+ push 0
+ jmp ecx
+
+ pop ebx
+ ret
+
+JumpToVector ENDP
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S
new file mode 100644
index 0000000000..657158ddd7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S
@@ -0,0 +1,42 @@
+## @file
+# This is the ASM for Jump to a specific address
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+#
+# Routine Description:
+# This allows the caller to switch the stack and goes to the new entry point
+#
+# Arguments:
+# EntryPoint - Pointer to the location to enter
+# Parameter - Parameter to pass in
+#
+# Returns:
+#
+# Nothing. Goes to the Entry Point passing in the new parameters
+#
+ASM_GLOBAL ASM_PFX(JumpToVector)
+ASM_PFX(JumpToVector):
+
+ push %ebx
+
+ mov 12(%esp), %ebx # ebx = Parameter
+ mov 8(%esp), %ecx # ecx = EntryPoint
+ push %ebx
+ push $0
+ jmp %ecx
+
+ pop %ebx
+ ret
+
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm
new file mode 100644
index 0000000000..87cc8c4467
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm
@@ -0,0 +1,49 @@
+;; @file
+; This is the ASM for starting a linux kernel.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+AsmStartLinuxKernel PROC near C PUBLIC
+ mov eax, [esp+4]
+ sub esp, 010h
+ lea ebx, NewSelectorJmp
+ mov [esp], ebx
+ mov ebx, 010h
+ mov [esp+4], ebx
+ jmp fword ptr [esp]
+
+NewSelectorJmp:
+ add esp, 010h
+
+ mov ebx, 018h
+ mov ds, ebx
+ mov es, ebx
+ mov fs, ebx
+ mov gs, ebx
+ mov ss, ebx
+
+ mov esi, 08000h
+ xor ebp, ebp
+ xor edi, edi
+ xor ebx, ebx
+ jmp eax
+ ret
+AsmStartLinuxKernel ENDP
+
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S
new file mode 100644
index 0000000000..847ae342d2
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S
@@ -0,0 +1,41 @@
+## @file
+# This is the ASM for starting a linux kernel.
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+ASM_GLOBAL ASM_PFX(AsmStartLinuxKernel)
+ASM_PFX(AsmStartLinuxKernel):
+ movl 4(%esp), %eax
+ subl $0x10, %esp
+ leal NewSelectorJmp, %ebx
+ movl %ebx, (%esp)
+ movl $0x10, %ebx
+ movl %ebx, 4(%esp)
+ jmpl (%esp)
+
+NewSelectorJmp:
+ addl $0x10, %esp
+
+ movl $0x18, %ebx
+ movl %ebx, %ds
+ movl %ebx, %es
+ movl %ebx, %fs
+ movl %ebx, %gs
+ movl %ebx, %ss
+
+ movl $0x8000, %esi
+ xorl %ebp, %ebp
+ xorl %edi, %edi
+ xorl %ebx, %ebx
+ jmpl %eax
+ ret
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h
new file mode 100644
index 0000000000..9567e42c90
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h
@@ -0,0 +1,168 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DevicePathLib.h>
+#include "BdsPlatform.h"
+
+#pragma pack(1)
+//
+// Forward declarations
+//
+typedef struct _OSIP_HEADER_V0100 OSIP_HEADER_V0100;
+typedef struct _OSII_ENTRY_V0100 OSII_ENTRY_V0100 ;
+
+//
+// Supported values for OSIP version 1.0 (PNW A0)
+//
+#define OSIP_HEADER_MAJOR_REVISION 1
+#define OSIP_HEADER_MINOR_REVISION 0
+#define OSIP_HEADER_SIGNATURE 0x24534F24
+#define OSIP_SIZE_IN_BLOCKS 1
+#define OSIP_HEADER OSIP_HEADER_V0100
+#define OSII_ENTRY OSII_ENTRY_V0100
+
+//
+// Module global definitions
+//
+#define OSP_BLOCK_SIZE 512
+#define OSP_BLOCKS_TO_PAGES(x) (EFI_SIZE_TO_PAGES(x * OSP_BLOCK_SIZE))
+#define MAX_OSII_ENTRIES ((OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE - sizeof (OSIP_HEADER)) / sizeof (OSII_ENTRY))
+#define VRL_SIZE_LOCATION 0x20
+
+//
+// Definitions for PNW A0...
+//
+typedef struct _SMIP_FHOB_DWORD0 {
+ UINT8 MsicModuleId : 2;
+ UINT8 Qualifier : 1;
+ UINT8 OSRCR : 1;
+ UINT8 EOSR : 1;
+ UINT8 SafeModeJumper : 1;
+ UINT8 MM : 1;
+ UINT8 NOREn : 1; ///< 8
+ UINT8 OSVEn : 1;
+ UINT8 OSDnX : 1;
+ UINT8 Reserved11to10 : 2;
+ UINT8 Reserved19to12 : 8; ///< 20
+ UINT8 Reserved25to20 : 6;
+ UINT8 MemoryChannels : 1;
+ UINT8 MemoryBurstLength : 1; ///< 28
+ UINT8 MemoryDeviceDensity : 2;
+ UINT8 MemoryRanks : 1;
+ UINT8 MemoryFrequencyRatio : 1; ///< 32
+} SMIP_FHOB_DWORD0 ;
+
+struct _OSII_ENTRY_V0100 {
+ UINT16 MinorRevision;
+ UINT16 MajorRevision;
+ UINT32 FirstBlock;
+ UINT32 LoadAddress;
+ UINT32 EntryPoint;
+ UINT32 BlockCount;
+ UINT8 Attributes;
+ UINT8 Reserved1[3];
+} ;
+
+struct _OSIP_HEADER_V0100 {
+ UINT32 Signature;
+ UINT8 Reserved1;
+ UINT8 MinorRevision;
+ UINT8 MajorRevision;
+ UINT8 Checksum;
+ UINT8 NumberOfPointers;
+ UINT8 NumberOfImages;
+ UINT16 HeaderSize;
+ UINT8 Reserved2[0x14];
+ OSII_ENTRY Osii[1];
+} ;
+
+#pragma pack()
+
+//
+// Global Variables
+//
+#include <Protocol/BlockIo.h>
+
+extern OSIP_HEADER *mOsip;
+extern OSIP_HEADER *mOsip;
+extern BOOLEAN mOsipFound;
+extern EFI_BLOCK_IO_PROTOCOL *mEmmcBlockIo;
+extern EFI_BLOCK_IO_PROTOCOL *mSdBlockIo;
+extern EFI_BLOCK_IO_PROTOCOL *mBootableBlockIo;
+
+//
+// Functions oustide of the main module
+//
+
+//
+// OspUtil.c
+//
+EFI_STATUS
+ValidateFvHeader (
+ IN VOID *Buffer,
+ IN UINTN Size
+ );
+
+EFI_STATUS
+ValidateOsip (
+ IN OSIP_HEADER *OsipHdr,
+ IN UINTN MaxBlocks
+ );
+
+EFI_STATUS
+ConnectSecondStageFvDevice (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect,
+ OUT EFI_HANDLE *MatchingHandle
+ );
+
+VOID
+RebaseImage (
+ IN EFI_PHYSICAL_ADDRESS DstBuffer,
+ IN EFI_PHYSICAL_ADDRESS SrcBuffer,
+ IN UINTN NumberOfBytes
+ );
+
+UINTN
+GetImageSizeByNumber (
+ IN UINTN ImageNumber
+ );
+
+EFI_STATUS
+LoadImageByNumber (
+ IN UINTN ImageNumber,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *NumberOfPages
+ );
+
+//
+// OsrIpc.c
+//
+EFI_STATUS
+OsrIpcGetDnx ();
+
+EFI_STATUS
+OsrIpcGetOsip (
+ IN EFI_PHYSICAL_ADDRESS osipBase
+ );
+
+EFI_STATUS
+OsrIpcGetOsImage (
+ IN OSII_ENTRY *osiiEntry,
+ OUT EFI_PHYSICAL_ADDRESS osBuffer
+ );
+
+EFI_STATUS
+OsrIpcEndOfUpdate ();
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c
new file mode 100644
index 0000000000..b277a3562f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c
@@ -0,0 +1,247 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include "OsipPrivate.h"
+#include "BdsPlatform.h"
+
+#define EFI_MAX_E820_ENTRY 100
+
+typedef enum {
+ EfiAcpiAddressRangeMemory = 1,
+ EfiAcpiAddressRangeReserved = 2,
+ EfiAcpiAddressRangeACPI = 3,
+ EfiAcpiAddressRangeNVS = 4
+} EFI_ACPI_MEMORY_TYPE;
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 BaseAddr;
+ UINT32 Length;
+ UINT32 Type;
+} EFI_E820_ENTRY;
+
+#pragma pack()
+
+EFI_STATUS
+ValidateFvHeader (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
+
+ FvHdr = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
+
+ if (FvHdr->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Error: Invalid FV signature\n"));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ if (FvHdr->FvLength > Size) {
+ DEBUG ((EFI_D_ERROR,
+ "Error: FV length (0x%x) is larger than data read (0x%x)\n",
+ FvHdr->FvLength,
+ Size));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ValidateOsip (
+ IN OSIP_HEADER *Osip,
+ IN UINTN MaxBlocks
+ )
+{
+ UINTN idx;
+ UINTN nextBlock = OSIP_SIZE_IN_BLOCKS;
+
+ DEBUG ((EFI_D_INFO, "Parsing OSIP Header...\n")) ;
+ DEBUG ((EFI_D_INFO, " Signature : %x\n", Osip->Signature));
+ DEBUG ((EFI_D_INFO, " MajorRevision : %x\n", Osip->MajorRevision));
+ DEBUG ((EFI_D_INFO, " MinorRevision : %x\n", Osip->MinorRevision));
+ DEBUG ((EFI_D_INFO, " NumberOfPointers : %x\n", Osip->NumberOfPointers));
+ DEBUG ((EFI_D_INFO, " NumberOfImages : %x\n", Osip->NumberOfImages));
+ DEBUG ((EFI_D_INFO, " Checksum : %x\n", Osip->Checksum));
+
+ if (Osip->Signature != OSIP_HEADER_SIGNATURE) return EFI_INVALID_PARAMETER;
+ if (Osip->MajorRevision != OSIP_HEADER_MAJOR_REVISION) return EFI_INVALID_PARAMETER;
+ if (Osip->MinorRevision != OSIP_HEADER_MINOR_REVISION) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfPointers == 0) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfPointers > MAX_OSII_ENTRIES) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfImages == 0) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfImages > Osip->NumberOfPointers) return EFI_INVALID_PARAMETER;
+
+ //
+ // TODO: Validate checksum, not sure what good that does though...
+ //
+ DEBUG ((EFI_D_INFO, "Parsing OSII Entries...\n"));
+
+ for (idx = 0; idx < Osip->NumberOfPointers; idx++) {
+ DEBUG((EFI_D_INFO, "Image %d\n", idx + 1));
+ DEBUG((EFI_D_INFO, " MajorRevision : %x\n", Osip->Osii[idx].MajorRevision));
+ DEBUG((EFI_D_INFO, " MinorRevision : %x\n", Osip->Osii[idx].MinorRevision));
+ DEBUG((EFI_D_INFO, " FirstBlock : %x\n", Osip->Osii[idx].FirstBlock));
+ DEBUG((EFI_D_INFO, " LoadAddress : %x\n", Osip->Osii[idx].LoadAddress));
+ DEBUG((EFI_D_INFO, " EntryPoint : %x\n", Osip->Osii[idx].EntryPoint));
+ DEBUG((EFI_D_INFO, " BlockCount : %x\n", Osip->Osii[idx].BlockCount));
+ DEBUG((EFI_D_INFO, " Attributes : %x\n", Osip->Osii[idx].Attributes));
+
+ //
+ // Enforce ordering, do not permit empty entries or holes
+ //
+ if (Osip->Osii[idx].FirstBlock != nextBlock) return EFI_INVALID_PARAMETER;
+ if (Osip->Osii[idx].BlockCount == 0) return EFI_INVALID_PARAMETER;
+ nextBlock += Osip->Osii[idx].BlockCount;
+
+ //
+ // TODO: More intensive OSII validation
+ //
+ }
+
+ //
+ // Make sure numBlocks is not pointing past the end of the device
+ //
+ if (nextBlock > MaxBlocks) return EFI_INVALID_PARAMETER;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+RebaseImage (
+ IN EFI_PHYSICAL_ADDRESS DstBuffer,
+ IN EFI_PHYSICAL_ADDRESS SrcBuffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 *sptr;
+ UINT8 *dptr;
+ UINTN idx;
+
+ sptr = (UINT8 *) (UINTN) SrcBuffer;
+ dptr = (UINT8 *) (UINTN) DstBuffer;
+
+ for (idx = 0; idx < NumberOfBytes; ++idx, ++dptr, ++sptr) {
+ *dptr = *sptr;
+ }
+
+ return;
+}
+
+
+UINTN
+GetImageSizeByNumber (
+ IN UINTN ImageNumber
+ )
+{
+ return mOsip->Osii[ImageNumber].BlockCount * OSP_BLOCK_SIZE;
+}
+
+
+EFI_STATUS
+LoadImageByNumber (
+ IN UINTN ImageNumber,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *NumberOfPages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS physAddr;
+ UINTN firstBlock;
+ UINTN numBlocks;
+ UINTN numPages;
+
+ //
+ // Parse OSII entry and find OS Image size in bytes
+ //
+ firstBlock = mOsip->Osii[ImageNumber].FirstBlock;
+ numBlocks = mOsip->Osii[ImageNumber].BlockCount;
+ numPages = OSP_BLOCKS_TO_PAGES (numBlocks);
+
+ //
+ // Allocate image buffer
+ //
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ numPages,
+ &physAddr);
+
+ if (EFI_ERROR (Status)) ASSERT_EFI_ERROR (Status);
+
+ //
+ // Copy OSII[ImageNumber] to buffer
+ //
+ Status = mBootableBlockIo->ReadBlocks (
+ mBootableBlockIo,
+ mBootableBlockIo->Media->MediaId,
+ firstBlock,
+ numBlocks * OSP_BLOCK_SIZE,
+ (VOID *) (UINTN) physAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (physAddr, numPages);
+ return EFI_DEVICE_ERROR;
+ }
+
+ *ImageBase = physAddr;
+ *NumberOfPages = numPages;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Convert EFI Memory Type to E820 Memory Type.
+
+ @param[in] Type EFI Memory Type
+
+ @retval ACPI Memory Type for EFI Memory Type
+
+**/
+EFI_ACPI_MEMORY_TYPE
+EfiMemoryTypeToE820Type (
+ IN UINT32 Type
+ )
+{
+ switch (Type) {
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ return EfiAcpiAddressRangeMemory;
+
+ case EfiACPIReclaimMemory:
+ return EfiAcpiAddressRangeACPI;
+
+ case EfiACPIMemoryNVS:
+ return EfiAcpiAddressRangeNVS;
+
+ default:
+ return EfiAcpiAddressRangeReserved;
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf
new file mode 100644
index 0000000000..777d5f97a8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -0,0 +1,142 @@
+## @file
+# Component name for module PlatformBdsLib.
+#
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformBdsLib
+ FILE_GUID = A6BC385D-59E5-4b77-87D7-200ABAA83C15
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x0002000A
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BdsPlatform.c
+ BdsPlatform.h
+ PlatformData.c
+ OsipUtil.c
+ EfiBootStub.c
+
+[Sources.IA32]
+ Ia32/JumpToVector.Asm
+ Ia32/JumpToVector.S
+ Ia32/StartKernel.Asm
+ Ia32/StartKernel.S
+
+[Packages]
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ CryptoPkg/CryptoPkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ GenericBdsLib
+ DevicePathLib
+ UefiLib
+ HobLib
+ PciLib
+ PrintLib
+ BaseCryptLib
+ FileHandleLib
+ DxeServicesLib
+ CpuPlatformLib
+ CustomizedDisplayLib
+ Tcg2PhysicalPresenceLib
+ TcgPhysicalPresenceLib
+ UefiBootManagerLib
+ TimerLib
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiSimpleNetworkProtocolGuid
+ gEfiLoadFileProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiSmmAccess2ProtocolGuid
+ gEfiDxeSmmReadyToLockProtocolGuid
+ gEfiUserManagerProtocolGuid
+ gEfiDeferredImageLoadProtocolGuid
+ gEfiAcpiS3SaveProtocolGuid
+ gEfiSeCOperationProtocolGuid ## PROTOCOL CONSUMES
+ gEfiSpiProtocolGuid ## PROTOCOL CONSUMES
+ gEfiBlockIoProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gExitPmAuthProtocolGuid
+ gEfiTdtOperationProtocolGuid
+ gEfiGlobalNvsAreaProtocolGuid
+ gEfiUsbKeyboardConnectGuid
+ gEfiMmioDeviceProtocolGuid
+ gEfiI2cMasterProtocolGuid
+ gEfiI2cHostProtocolGuid
+ gExitPmAuthProtocolGuid
+ gEfiDiskInfoProtocolGuid
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gEfiMemoryTypeInformationGuid
+ gEfiSetupVariableGuid
+ gEfiCapsuleVendorGuid
+ gEfiGlobalVariableGuid
+ gEfiNormalSetupGuid
+ gEfiPartTypeSystemPartGuid
+ gEfiAcpi20TableGuid
+ gEfiAcpi10TableGuid
+ gEfiTpmDeviceInstanceTpm12Guid
+ gEfiTpmDeviceInstanceTpm20DtpmGuid
+ gTpmDeviceInstanceTpm20PttPtpGuid
+ gUndiDriverImageGuid
+ gSetupEnterGuid
+ gEfiPhysicalPresenceGuid
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBRBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMBase
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+ gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+ gPlatformModuleTokenSpaceGuid.PcdConnectUSBKeyboardonWaitForKeyStroke
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c
new file mode 100644
index 0000000000..8f619da558
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c
@@ -0,0 +1,242 @@
+/** @file
+ Defined the platform specific device path which will be used by
+ platform Bbd to perform the platform policy connect.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BdsPlatform.h"
+
+//
+// Predefined platform default time out value
+//
+UINT16 gPlatformBootTimeOutDefault = 10;
+
+//
+// Predefined platform root bridge
+//
+PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
+ gPciRootBridge,
+ gEndEntire
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0,
+ NULL
+};
+
+//
+// Platform specific ISA keyboard device path
+//
+PLATFORM_ISA_KEYBOARD_DEVICE_PATH gIsaKeyboardDevicePath = {
+ gPciRootBridge,
+ gPciIsaBridge,
+ gPnpPs2Keyboard,
+ gEndEntire
+};
+
+//
+// Platform specific on chip PCI VGA device path
+//
+PLATFORM_ONBOARD_VGA_DEVICE_PATH gOnChipPciVgaDevicePath = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x2),
+ gEndEntire
+};
+
+//
+// Platform specific plug in PCI VGA device path
+//
+PLATFORM_OFFBOARD_VGA_DEVICE_PATH gPlugInPciVgaDevicePath = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x1),
+ PCI_DEVICE_PATH_NODE (0, 0x0),
+ gEndEntire
+};
+
+//
+// Platform specific ISA serial device path
+//
+PLATFORM_ISA_SERIAL_DEVICE_PATH gIsaSerialDevicePath = {
+ gPciRootBridge,
+ gPciIsaBridge,
+ gPnp16550ComPort,
+ gUart (115200, 8, 1, 1),
+ gPcAnsiTerminal,
+ gEndEntire
+};
+
+//
+// Platform specific SPI Uart device path
+//
+PLATFORM_ISA_SERIAL_DEVICE_PATH gSpiDevicePath = {
+ gPciRootBridge,
+ gPciSpiBridge,
+ gPnp16550ComPort,
+ gUart (115200, 8, 1, 1),
+ gPcAnsiTerminal,
+ gEndEntire
+};
+
+USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+ gUsbKeyboardMouse,
+ gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gSpiDevicePath, (CONSOLE_OUT | CONSOLE_IN)},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, (CONSOLE_OUT | CONSOLE_IN)},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaKeyboardDevicePath, CONSOLE_IN},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+//
+// All the possible platform PCI VGA device path
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformAllPossiblePciVgaConsole [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gOnChipPciVgaDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlugInPciVgaDevicePath,
+ NULL
+};
+
+//
+// Legacy hard disk boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyHd = {
+ {
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT8) (sizeof (BBS_BBS_DEVICE_PATH)),
+ (UINT8) ((sizeof (BBS_BBS_DEVICE_PATH)) >> 8),
+ BBS_TYPE_HARDDRIVE,
+ 0,
+ 0
+ },
+ gEndEntire
+};
+
+//
+// Legacy cdrom boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyCdrom = {
+ {
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT8) (sizeof (BBS_BBS_DEVICE_PATH)),
+ (UINT8) ((sizeof (BBS_BBS_DEVICE_PATH)) >> 8),
+ BBS_TYPE_CDROM,
+ 0,
+ 0
+ },
+ gEndEntire
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformBootOption [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gLegacyHd,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gLegacyCdrom,
+ NULL
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gSerialIoConnect[] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath,
+ NULL
+};
+
+//
+// Predefined platform specific driver option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformDriverOption [] = {
+ NULL
+};
+
+//
+// Platform specific SATA controller device path
+//
+PLATFORM_PCI_DEVICE_PATH gSataBootDevPath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0x00, 0x12),
+ gEndEntire
+};
+
+//
+// eMMC device at BDF(0x0, 0x1C, 0x0)
+//
+PLATFORM_PCI_DEVICE_PATH gEmmcBootDevPath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0x00, 0x1C),
+ gEndEntire
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformConnectSequence [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0, // Force PCI enumer before Legacy OpROM shadow
+ (EFI_DEVICE_PATH_PROTOCOL *) &gSataBootDevPath0,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gEmmcBootDevPath0,
+ NULL
+};
+
+//
+// Platform specific USB controller device path
+//
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x15),
+ gEndEntire
+};
+
+//
+// Predefined platform device path for user authtication
+//
+EFI_DEVICE_PATH_PROTOCOL* gUserAuthenticationDevice[] = {
+ //
+ // Predefined device path for secure card (USB disk).
+ //
+ (EFI_DEVICE_PATH_PROTOCOL *) &gUsbDevicePath0,
+ NULL
+};
+
+//
+// Predefined platform console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleOnChipPciVgaConOutConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gOnChipPciVgaDevicePath, CONSOLE_OUT},
+ {NULL, 0}
+};
+
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleUsbConInConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimplePs2ConInConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformSimpleBootOption [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gEmmcBootDevPath0,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gSataBootDevPath0,
+ NULL
+};
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.c
new file mode 100644
index 0000000000..2be72a22e9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.c
@@ -0,0 +1,120 @@
+/** @file
+ The Libary for Platform Cmos.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/PlatformCmosLib.h>
+#include "CmosMap.h"
+#include <ScAccess.h>
+#include "PlatformBaseAddresses.h"
+#include <Library/SteppingLib.h>
+
+#define DEFAULT_VALUE 0
+#define DEFAULT_ATTRIBUTES 0
+#define EXCLUDE_FROM_CHECKSUM CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM
+
+#define CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE 0x46 // EFI_D_WARN|EFI_D_INFO|EFI_D_LOAD
+#define CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE 0x80 // EFI_D_ERROR
+
+//
+// Add the CMOS entry below
+//
+CMOS_ENTRY mCmosTable[] = {
+{ CPU_HT_POLICY, CPU_HT_POLICY_ENABLED, EXCLUDE_FROM_CHECKSUM },
+{ TPM_POLICY, TPM_POLICY_ENABLED, DEFAULT_ATTRIBUTES },
+{ CMOS_LCDPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_LCDPANELSCALING_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_IGDBOOTTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_BACKLIGHT_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_LFP_PANEL_COLOR_DEPTH_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_EDP_ACTIVE_LFP_CONFIG_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_PRIMARY_DISPLAY_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_IGD_DISPLAY_PIPE_B_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_SDVOPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_PLATFORM_RESET_OS, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_CPU_BSP_SELECT, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_CPU_RATIO_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_ICH_PORT80_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_MAXRATIO_CONFIG_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ RTC_ADDRESS_CENTURY, RTC_ADDRESS_CENTURY_DEFAULT, CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_1_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_2_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_3_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_REG, CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_1_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_2_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_3_REG, CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+};
+
+
+/**
+ Funtion to return platform CMOS entry.
+
+ @param[out] CmosEntry Platform CMOS entry.
+ @param[out] CmosEntryCount Number of platform CMOS entry.
+
+ @return Status.
+
+**/
+RETURN_STATUS
+EFIAPI
+GetPlatformCmosEntry (
+ OUT CMOS_ENTRY **CmosEntry,
+ OUT UINTN *CmosEntryCount
+ )
+{
+ *CmosEntry = mCmosTable;
+ *CmosEntryCount = sizeof (mCmosTable) / sizeof (mCmosTable[0]);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Function to check if Battery lost or CMOS cleared.
+
+ @reval TRUE Battery is always present.
+ @reval FALSE CMOS is cleared.
+
+**/
+BOOLEAN
+EFIAPI
+CheckCmosBatteryStatus (
+ VOID
+ )
+{
+ UINT8 PmcPmcon1;
+
+ //
+ // Check if the CMOS battery is present
+ // Checks RTC_PWR_STS bit in the GEN_PMCON_1 register
+ //
+ if ((BxtStepping () <= BxtA1)) {
+ return TRUE;
+ }
+ PmcPmcon1 = MmioRead8 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1);
+
+ if (PmcPmcon1 != 0xFF) {
+ if ((PmcPmcon1 & B_PMC_GEN_PMCON_RTC_PWR_STS) == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ return TRUE;
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.inf
new file mode 100644
index 0000000000..ff714d6502
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformCmosLib/PlatformCmosLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformCmosLib
+ FILE_GUID = ECA883EF-0CBE-40b6-84BC-FA4A709782F7
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformCmosLib
+
+[Sources]
+ PlatformCmosLib.c
+
+[LibraryClasses]
+ IoLib
+ SteppingLib
+
+[Packages]
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Pcd]
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset.inc
new file mode 100644
index 0000000000..c6e6229811
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset.inc
@@ -0,0 +1,107 @@
+;; @file
+; Chipset constants and macros.
+;
+; Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+;
+; APIC register
+;
+APICID EQU 0FEE00020h
+
+;
+; base addresses and register definitions.
+;
+
+IPC1_BASE_ADDRESS EQU 0FE042000h
+GCR_BASE_ADDRESS EQU (IPC1_BASE_ADDRESS + 1000h)
+IPC1_BASE2_ADDRESS EQU 0FE044000h
+
+ACPI_BASE_ADDRESS EQU 0400h
+B_ACPI_BASE_EN EQU BIT1
+ R_ACPI_PM1_CNT EQU 004h
+ V_ACPI_PM1_CNT_S5 EQU 01C00h
+ R_ACPI_PM1_TMR EQU 008h
+ R_TCO_STS EQU 064h
+ B_TCO_STS_SECOND_TO EQU BIT17
+ R_TCO_CNT EQU 068h
+ B_TCO_CNT_TMR_HLT EQU BIT11
+SMBUS_BASE_ADDRESS EQU 0EFA0h
+ B_SMBUS_PCICMD_IOSE EQU BIT0
+ R_SMBUS_AUXC EQU 00Dh
+SPI_BASE_ADDRESS EQU 0FED01000h
+; B_LPC_SPI_BASE_EN EQU BIT1
+ R_SPI_BCR EQU 0DCh
+PMC_BASE_ADDRESS EQU GCR_BASE_ADDRESS
+ R_PMC_GEN_PMCON_1 EQU 020h
+ R_PMC_PMIR EQU 048h
+ B_PMC_PMIR_CF9GR EQU BIT20
+PUNIT_BASE_ADDRESS EQU 0FED06000h
+ B_LPC_PUNIT_BASE_EN EQU BIT1
+ILB_BASE_ADDRESS EQU 0FED08000h
+ B_LPC_ILB_BASE_EN EQU BIT1
+RCBA_BASE_ADDRESS EQU 0FED1C000h
+ B_LPC_RCBA_EN EQU BIT0
+IO_BASE_ADDRESS EQU 0FED80000h
+ B_LPC_IO_BASE_EN EQU BIT1
+MPHY_BASE_ADDRESS EQU 0FEA00000h
+ B_LPC_MPHY_BASE_EN EQU BIT1
+MCH_BASE_ADDRESS EQU 0FED10000h
+ B_MCH_BASE_ADDRESS_EN EQU BIT0
+
+;
+;B_Unit Registers
+;
+BUNIT_BMISC EQU 6800h
+ B_BMISC_RESDRAM EQU 01h ;Bit 0 - When this bit is set, reads targeting E-segment are routed to DRAM.
+ B_BMISC_RFSDRAM EQU 02h ;Bit 1 - When this bit is set, reads targeting F-segment are routed to DRAM.
+
+;
+; HPET compare register
+;
+HPET_COMP_1 EQU 0FED00108h
+HPET_COMP_2 EQU 0FED0010Ch
+HPET_COMP_3 EQU 0FED00128h
+HPET_COMP_4 EQU 0FED00148h
+HPTC_AE EQU BIT7
+;
+; MCH PCIe base address
+;
+CPU_HEC_BASE EQU 0E0000000h ; Must be X0000000
+CPU_HEC_SIZE EQU 000000000h ; 256M
+CPU_HEC_EN EQU 000000001h ; Enable
+
+;
+; PCI registers
+;
+R_MCH_BASE EQU ((0h * 8 + 00h) * 1000h + 0048h + CPU_HEC_BASE)
+R_P2SB_HPTC EQU ((0Dh * 8 + 00h) * 1000h + 0060h + CPU_HEC_BASE) ;HPTC config register. B0:D13:F0 0x60x
+R_PMC_PCI_CMD EQU ((0Dh * 8 + 01h) * 1000h + 0004h + CPU_HEC_BASE)
+R_PMC_ACPI_BASE EQU ((0Dh * 8 + 01h) * 1000h + 0020h + CPU_HEC_BASE) ;BAR2 IO config register. B0:D13:F1 0x20
+R_PMC_MMIO_BAR0 EQU ((0Dh * 8 + 01h) * 1000h + 0010h + CPU_HEC_BASE) ;BAR0 IO config register. B0:D13:F1 0x10
+R_PMC_MMIO_BAR1 EQU ((0Dh * 8 + 01h) * 1000h + 0018h + CPU_HEC_BASE) ;BAR1 IO config register. B0:D13:F1 0x18
+
+SYRE_CPURST EQU 14
+
+;
+; PCIEXBAR constants for enable in bit [0]
+;
+ENABLE EQU 1
+
+;
+; PCIEXBAR constants for size in bit [2:1]
+;
+PCIEXBAR_64MB EQU 010b
+PCIEXBAR_128MB EQU 001b
+PCIEXBAR_256MB EQU 000b
+
+MMCFG_BASE EQU CPU_HEC_BASE ; 4GB-128MB
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset_S.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset_S.inc
new file mode 100644
index 0000000000..067ddf6c55
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Chipset_S.inc
@@ -0,0 +1,109 @@
+;; @file
+; Chipset constants and macros.
+;
+; Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+#
+# APIC register
+#
+.equ APICID, 0xFEE00020
+
+#
+# Base addresses and register definitions.
+#
+
+.equ SC_ADDR_BASE, 0xFF040000
+.equ IPC1_BASE_ADDRESS, 0xFE042000
+.equ GCR_BASE_ADDRESS, (IPC1_BASE_ADDRESS + 0x1000)
+.equ SSRAM_BASE_ADDRESS, 0xFE044000
+
+.equ ACPI_BASE_ADDRESS, 0x0400
+.equ B_ACPI_BASE_EN, BIT1
+.equ R_ACPI_PM1_CNT, 0x04
+.equ V_ACPI_PM1_CNT_S5, 0x1C00
+.equ R_ACPI_PM1_TMR, 0x008
+.equ R_TCO_STS, 0x64
+.equ B_TCO_STS_SECOND_TO, BIT17
+.equ R_TCO_CNT, 0x68
+.equ B_TCO_CNT_TMR_HLT, BIT11
+.equ SMBUS_BASE_ADDRESS, 0xEFA0
+.equ B_SMBUS_PCICMD_IOSE, BIT0
+.equ R_SMBUS_AUXC, 0x0D
+.equ SPI_BASE_ADDRESS, 0xFED01000
+#.equ B_LPC_SPI_BASE_EN, BIT1
+.equ R_SPI_BCR, 0xDC
+.equ PMC_BASE_ADDRESS, GCR_BASE_ADDRESS
+.equ R_PMC_GEN_PMCON_1, 0x20
+.equ R_PMC_PMIR, 0x48
+.equ B_PMC_PMIR_CF9GR, BIT20
+.equ PUNIT_BASE_ADDRESS, 0xFED06000
+.equ B_LPC_PUNIT_BASE_EN, BIT1
+.equ ILB_BASE_ADDRESS, 0xFED08000
+.equ B_LPC_ILB_BASE_EN, BIT1
+.equ RCBA_BASE_ADDRESS, 0xFED1C000
+.equ B_LPC_RCBA_EN, BIT0
+.equ IO_BASE_ADDRESS, 0xFED80000
+.equ B_LPC_IO_BASE_EN, BIT1
+.equ MPHY_BASE_ADDRESS, 0xFEA00000
+.equ B_LPC_MPHY_BASE_EN, BIT1
+.equ MCH_BASE_ADDRESS, 0xFED10000
+.equ B_MCH_BASE_ADDRESS_EN, BIT0
+
+#
+# B_Unit Registers
+#
+.equ BUNIT_BMISC, 0x6800
+.equ B_BMISC_RESDRAM, 0x01 # Bit 0 - When this bit is set, reads targeting E-segment are routed to DRAM.
+.equ B_BMISC_RFSDRAM, 0x02 # Bit 1 - When this bit is set, reads targeting F-segment are routed to DRAM.
+
+#
+# HPET compare register
+#
+.equ HPET_COMP_1, 0xFED00108
+.equ HPET_COMP_2, 0xFED0010C
+.equ HPET_COMP_3, 0xFED00128
+.equ HPET_COMP_4, 0xFED00148
+.equ HPTC_AE, BIT7
+
+#
+# MCH PCIe base address
+#
+.equ CPU_HEC_BASE, 0xE0000000 # Must be X0000000
+.equ CPU_HEC_SIZE, 0x00000000 # 256M
+.equ CPU_HEC_EN, 0x00000001 # Enable
+
+#
+# PCI registers
+#
+.equ R_MCH_BASE, ((0x00 * 8 + 0x00) * 0x1000 + 0x0048 + CPU_HEC_BASE)
+.equ R_P2SB_HPTC, ((0x0D * 8 + 0x00) * 0x1000 + 0x0060 + CPU_HEC_BASE) #HPTC config register. B0:D13:F0 0x60x
+.equ R_PMC_PCI_CMD, ((0x0D * 8 + 0x01) * 0x1000 + 0x0004 + CPU_HEC_BASE)
+.equ R_PMC_ACPI_BASE, ((0x0D * 8 + 0x01) * 0x1000 + 0x0020 + CPU_HEC_BASE) #BAR2 IO config register. B0:D13:F1 0x20
+
+.equ R_PMC_MMIO_BAR0, ((0x0D * 8 + 0x01) * 0x1000 + 0x0010 + CPU_HEC_BASE) #BAR0 IO config register. B0:D13:F1 0x10
+.equ R_PMC_MMIO_BAR1, ((0x0D * 8 + 0x01) * 0x1000 + 0x0018 + CPU_HEC_BASE) #BAR1 IO config register. B0:D13:F1 0x18
+.equ SYRE_CPURST, 14
+
+#
+# PCIEXBAR constants for enable in bit [0]
+#
+.equ ENABLE, 1
+
+#
+# PCIEXBAR constants for size in bit [2:1]
+#
+.equ PCIEXBAR_64MB, 0x02
+.equ PCIEXBAR_128MB, 0x01
+.equ PCIEXBAR_256MB, 0x00
+
+.equ MMCFG_BASE, CPU_HEC_BASE # 4GB-128MB
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32.inc
new file mode 100644
index 0000000000..afa48239ed
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32.inc
@@ -0,0 +1,167 @@
+;; @file
+; IA32 architecture MSRs.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+IA32_MTRR_CAP EQU 0FEh
+MTRR_PHYS_BASE_0 EQU 0200h
+MTRR_PHYS_MASK_0 EQU 0201h
+MTRR_PHYS_BASE_1 EQU 0202h
+MTRR_PHYS_MASK_1 EQU 0203h
+MTRR_PHYS_BASE_2 EQU 0204h
+MTRR_PHYS_MASK_2 EQU 0205h
+MTRR_PHYS_BASE_3 EQU 0206h
+MTRR_PHYS_MASK_3 EQU 0207h
+MTRR_PHYS_BASE_4 EQU 0208h
+MTRR_PHYS_MASK_4 EQU 0209h
+MTRR_PHYS_BASE_5 EQU 020Ah
+MTRR_PHYS_MASK_5 EQU 020Bh
+MTRR_PHYS_BASE_6 EQU 020Ch
+MTRR_PHYS_MASK_6 EQU 020Dh
+MTRR_PHYS_BASE_7 EQU 020Eh
+MTRR_PHYS_MASK_7 EQU 020Fh
+MTRR_PHYS_BASE_8 EQU 0210h
+MTRR_PHYS_MASK_8 EQU 0211h
+MTRR_PHYS_BASE_9 EQU 0212h
+MTRR_PHYS_MASK_9 EQU 0213h
+MTRR_FIX_64K_00000 EQU 0250h
+MTRR_FIX_16K_80000 EQU 0258h
+MTRR_FIX_16K_A0000 EQU 0259h
+MTRR_FIX_4K_C0000 EQU 0268h
+MTRR_FIX_4K_C8000 EQU 0269h
+MTRR_FIX_4K_D0000 EQU 026Ah
+MTRR_FIX_4K_D8000 EQU 026Bh
+MTRR_FIX_4K_E0000 EQU 026Ch
+MTRR_FIX_4K_E8000 EQU 026Dh
+MTRR_FIX_4K_F0000 EQU 026Eh
+MTRR_FIX_4K_F8000 EQU 026Fh
+MTRR_DEF_TYPE EQU 02FFh
+
+MTRR_MEMORY_TYPE_UC EQU 00h
+MTRR_MEMORY_TYPE_WC EQU 01h
+MTRR_MEMORY_TYPE_WT EQU 04h
+MTRR_MEMORY_TYPE_WP EQU 05h
+MTRR_MEMORY_TYPE_WB EQU 06h
+
+MTRR_DEF_TYPE_E EQU 0800h
+MTRR_DEF_TYPE_FE EQU 0400h
+MTRR_PHYSMASK_VALID EQU 0800h
+
+;
+; Define the high 32 bits of MTRR masking
+; This should be read from CPUID EAX = 080000008h, EAX bits [7:0]
+; But for most platforms this will be a fixed supported size so it is
+; fixed to save space.
+;
+MTRR_PHYS_MASK_VALID EQU 0800h
+MTRR_PHYS_MASK_HIGH EQU 00000000Fh ; For 36 bit addressing
+;MTRR_PHYS_MASK_HIGH EQU 0000000FFh ; For 40 bit addressing
+
+IA32_MISC_ENABLE EQU 1A0h
+FAST_STRING_ENABLE_BIT EQU 01h
+
+CR0_CACHE_DISABLE EQU 040000000h
+CR0_NO_WRITE EQU 020000000h
+
+IA32_PLATFORM_ID EQU 017h
+IA32_BIOS_UPDT_TRIG EQU 079h
+IA32_BIOS_SIGN_ID EQU 08Bh
+PLATFORM_INFO EQU 0CEh
+NO_EVICT_MODE EQU 2E0h
+NO_EVICTION_ENABLE_BIT EQU 01h
+
+;
+; MSR definitions
+;
+MSR_IA32_PLATFORM_ID EQU 0017h
+MSR_APIC_BASE EQU 001Bh
+MSR_SOCKET_ID EQU 0039h
+MSR_IA32_FEATURE_CONTROL EQU 003Ah
+MSR_CLOCK_CST_CONFIG_CONTROL EQU 00E2h
+MSR_CLOCK_FLEX_MAX EQU 0194h
+MSR_IA32_PERF_STS EQU 0198h
+MSR_IA32_PERF_CTL EQU 0199h
+MSR_IA32_MISC_ENABLES EQU 01A0h
+MSR_IA32_MC8_MISC2 EQU 0288h
+MSR_IA32_MC7_CTL EQU 041Ch
+
+
+CSR_SVID_SDID EQU 02Ch ; D0:F0:R2Ch
+DEAFULT_SVID_SDID EQU 80868086h ; DWORD Access & Write Once ONLY
+
+;
+; Processor MSR definitions
+;
+MSR_BBL_CR_CTL3 EQU 011Eh ; L2 cache configuration MSR
+B_MSR_BBL_CR_CTL3_L2_NOT_PRESENT EQU 23 ; L2 not present
+B_MSR_BBL_CR_CTL3_L2_ENABLED EQU 8 ; L2 enabled
+B_MSR_BBL_CR_CTL3_L2_HARDWARE_ENABLED EQU 0 ; L2 hardware enabled
+
+
+;
+; Local APIC Register Equates
+;
+LOCAL_APIC_ID_REG EQU 0FEE00020h
+APIC_ICR_HI EQU 0FEE00310h
+APIC_ICR_LO EQU 0FEE00300h
+ANDICRMask EQU 0FFF32000h ; AND mask for ICR Saving reserved bits
+ORSelfINIT EQU 000004500h ; OR mask to send INIT IPI to itself
+ORAllButSelf EQU 0000C0000h ; OR mask to set dest field = "All But Self"
+
+;
+; Cache control macro
+;
+DISABLE_CACHE macro
+ mov eax, cr0
+ or eax, CR0_CACHE_DISABLE + CR0_NO_WRITE
+ wbinvd
+ mov cr0, eax
+endm
+
+ENABLE_CACHE macro
+ mov eax, cr0
+ and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE)
+ wbinvd
+ mov cr0, eax
+endm
+
+
+BLOCK_LENGTH_BYTES EQU 2048
+
+UpdateHeaderStruc STRUC
+ dHeaderVersion dd ? ; Header version#
+ dUpdateRevision dd ? ; Update revision#
+ dDate dd ? ; Date in binary (08/13/07 as 0x08132007)
+ dProcessorSignature dd ? ; CPU type, family, model, stepping
+ dChecksum dd ? ; Checksum
+ dLoaderRevision dd ? ; Update loader version#
+ dProcessorFlags dd ? ; Processor Flags
+ dDataSize dd ? ; Size of encrypted data
+ dTotalSize dd ? ; Total size of update in bytes
+ bReserved db 12 dup(?) ; 12 bytes reserved
+UpdateHeaderStruc ENDS
+
+HobStruc STRUC
+ Sign dd 1 ; Signiture#
+ CarBase dd 1 ; Cache As Ram Base Address
+ CarSize dd 1 ; Cache As Ram Size
+ IBBSource dd 1 ; IBBM Address in SRAM
+ IBBBase dd 1 ; IBBM Base in CAR.
+ IBBSize dd 1 ; IBBM Size
+ IBBLSource dd 1 ; IBBL Address in SRAM
+ IBBLBase dd 1 ; IBBL Base in CAR.
+ IBBLSize dd 1 ; IBBL Size
+ FITBase dd 1 ; FIT Base Address
+ StackHeapBase dd 1 ; STACK&HEAP Base .
+ StackHeapSize dd 1 ; STACK&HEAP Size
+HobStruc ENDS
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32_S.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32_S.inc
new file mode 100644
index 0000000000..3279f074af
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Ia32_S.inc
@@ -0,0 +1,164 @@
+;; @file
+; IA32 architecture MSRs.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+.equ IA32_MTRR_CAP, 0xFE
+.equ MTRR_PHYS_BASE_0, 0x200
+.equ MTRR_PHYS_MASK_0, 0x201
+.equ MTRR_PHYS_BASE_1, 0x202
+.equ MTRR_PHYS_MASK_1, 0x203
+.equ MTRR_PHYS_BASE_2, 0x204
+.equ MTRR_PHYS_MASK_2, 0x205
+.equ MTRR_PHYS_BASE_3, 0x206
+.equ MTRR_PHYS_MASK_3, 0x207
+.equ MTRR_PHYS_BASE_4, 0x208
+.equ MTRR_PHYS_MASK_4, 0x209
+.equ MTRR_PHYS_BASE_5, 0x20A
+.equ MTRR_PHYS_MASK_5, 0x20B
+.equ MTRR_PHYS_BASE_6, 0x20C
+.equ MTRR_PHYS_MASK_6, 0x20D
+.equ MTRR_PHYS_BASE_7, 0x20E
+.equ MTRR_PHYS_MASK_7, 0x20F
+.equ MTRR_PHYS_BASE_8, 0x210
+.equ MTRR_PHYS_MASK_8, 0x211
+.equ MTRR_PHYS_BASE_9, 0x212
+.equ MTRR_PHYS_MASK_9, 0x213
+.equ MTRR_FIX_64K_00000, 0x250
+.equ MTRR_FIX_16K_80000, 0x258
+.equ MTRR_FIX_16K_A0000, 0x259
+.equ MTRR_FIX_4K_C0000, 0x268
+.equ MTRR_FIX_4K_C8000, 0x269
+.equ MTRR_FIX_4K_D0000, 0x26A
+.equ MTRR_FIX_4K_D8000, 0x26B
+.equ MTRR_FIX_4K_E0000, 0x26C
+.equ MTRR_FIX_4K_E8000, 0x26D
+.equ MTRR_FIX_4K_F0000, 0x26E
+.equ MTRR_FIX_4K_F8000, 0x26F
+.equ MTRR_DEF_TYPE, 0x2FF
+
+.equ MTRR_MEMORY_TYPE_UC, 0x00
+.equ MTRR_MEMORY_TYPE_WC, 0x01
+.equ MTRR_MEMORY_TYPE_WT, 0x04
+.equ MTRR_MEMORY_TYPE_WP, 0x05
+.equ MTRR_MEMORY_TYPE_WB, 0x06
+
+.equ MTRR_DEF_TYPE_E, 0x0800
+.equ MTRR_DEF_TYPE_FE, 0x0400
+.equ MTRR_PHYSMASK_VALID, 0x0800
+
+#
+# Define the high 32 bits of MTRR masking
+# This should be read from CPUID EAX = 080000008h, EAX bits [7:0]
+# But for most platforms this will be a fixed supported size so it is
+# fixed to save space.
+#
+.equ MTRR_PHYS_MASK_VALID, 0x0800
+.equ MTRR_PHYS_MASK_HIGH, 0x0000000F # For 36 bit addressing
+
+.equ IA32_MISC_ENABLE, 0x1A0
+.equ FAST_STRING_ENABLE_BIT, 0x01
+
+.equ CR0_CACHE_DISABLE, 0x40000000
+.equ CR0_NO_WRITE, 0x20000000
+
+.equ IA32_PLATFORM_ID, 0x17
+.equ IA32_BIOS_UPDT_TRIG, 0x79
+.equ IA32_BIOS_SIGN_ID, 0x8B
+.equ PLATFORM_INFO, 0xCE
+.equ NO_EVICT_MODE, 0x2E0
+.equ NO_EVICTION_ENABLE_BIT, 0x01
+
+#
+# MSR definitions
+#
+.equ MSR_IA32_PLATFORM_ID, 0x017
+.equ MSR_APIC_BASE, 0x01B
+.equ MSR_SOCKET_ID, 0x039
+.equ MSR_IA32_FEATURE_CONTROL, 0x03A
+.equ MSR_CLOCK_CST_CONFIG_CONTROL, 0x0E2
+.equ MSR_CLOCK_FLEX_MAX, 0x194
+.equ MSR_IA32_PERF_STS, 0x198
+.equ MSR_IA32_PERF_CTL, 0x199
+.equ MSR_IA32_MISC_ENABLES, 0x1A0
+.equ MSR_IA32_MC8_MISC2, 0x288
+.equ MSR_IA32_MC7_CTL, 0x41C
+
+
+.equ CSR_SVID_SDID, 0x2C # D0:F0:R2Ch
+.equ DEAFULT_SVID_SDID, 0x80868086 # DWORD Access & Write Once ONLY
+
+#
+# Processor MSR definitions
+#
+.equ MSR_BBL_CR_CTL3, 0x11E # L2 cache configuration MSR
+.equ B_MSR_BBL_CR_CTL3_L2_NOT_PRESENT, 23 # L2 not present
+.equ B_MSR_BBL_CR_CTL3_L2_ENABLED, 8 # L2 enabled
+.equ B_MSR_BBL_CR_CTL3_L2_HARDWARE_ENABLED, 0 # L2 hardware enabled
+
+#
+# Local APIC Register Equates
+#
+.equ LOCAL_APIC_ID_REG, 0xFEE00020
+.equ APIC_ICR_HI, 0xFEE00310
+.equ APIC_ICR_LO, 0xFEE00300
+.equ ANDICRMask, 0xFFF32000 # AND mask for ICR Saving reserved bits
+.equ ORSelfINIT, 0x00004500 # OR mask to send INIT IPI to itself
+.equ ORAllButSelf, 0x000C0000 # OR mask to set dest field = "All But Self"
+
+#
+# Cache control macro
+#
+.macro DISABLE_CACHE
+ movl %cr0, %eax
+ orl $(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax
+ wbinvd
+ movl %eax, %cr0
+.endm
+
+.macro ENABLE_CACHE
+ movl %cr0, %eax
+ andl $(~(CR0_CACHE_DISABLE + CR0_NO_WRITE)), %eax
+ wbinvd
+ movl %eax, %cr0
+.endm
+
+
+.equ BLOCK_LENGTH_BYTES, 2048
+
+# define the structure of UpdateHeaderStruc
+.struct 0
+dHeaderVersion: .struct dHeaderVersion + 4 #size 4 # Header version#
+dUpdateRevision: .struct dUpdateRevision + 4 #size 4 # Update revision#
+dDate: .struct dDate + 4 #size 4 # Date in binary (08/13/07 as 0x08132007)
+dProcessorSignature: .struct dProcessorSignature + 4 #size 4 # CPU type, family, model, stepping
+dChecksum: .struct dChecksum + 4 #size 4 # Checksum
+dLoaderRevision: .struct dLoaderRevision + 4 #size 4 # Update loader version#
+dProcessorFlags: .struct dProcessorFlags + 4 #size 4 # Processor Flags
+dDataSize: .struct dDataSize + 4 #size 4 # Size of encrypted data
+dTotalSize: .struct dTotalSize + 4 #size 4 # Total size of update in bytes
+bReserved: .struct dTotalSize + 12 #size 12 # 12 bytes reserved
+# end of UpdateHeaderStruc
+
+# define the structure of HobStruc
+.struct 0
+Sign: .struct Sign + 4 #size 4 # Signiture#
+CarBase: .struct CarBase + 4 #size 4 # Cache As Ram Base Address
+CarSize: .struct CarSize + 4 #size 4 # Cache As Ram Size
+IBBSource: .struct IBBSource + 4 #size 4 # IBB Address in SRAM
+IBBBase: .struct IBBBase + 4 #size 4 # IBB Base in CAR.
+IBBSize: .struct IBBSize + 4 #size 4 # IBB Size
+IBBLSource: .struct IBBLSource + 4 #size 4 # IBBL Address in SRAM
+IBBLBase: .struct IBBLBase + 4 #size 4 # IBBL Base in CAR.
+IBBLSize: .struct IBBLSize + 4 #size 4 # IBBL Size
+# end of HobStruc
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform.inc
new file mode 100644
index 0000000000..cd5faff386
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform.inc
@@ -0,0 +1,99 @@
+;; @file
+; Platform Specific Definitions.
+;
+; Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+;INCLUDE FlashMap.inc ;ECP porting
+
+MKF_SOFTSDV_FLAG EQU 0
+
+; Set "MINIMUM_BOOT_SUPPORT" flag allows BIOS boot as minimum feature in SEC phase.
+MINIMUM_BOOT_SUPPORT EQU 0 ; ="0", Normal Boot;
+ ; ="1", Minimum Feature Boot
+; "RESET_IN_SEC" flag allows BIOS doing RESET in SEC phase
+RESET_IN_SEC EQU 0 ; ="0", RESET occurs in OemIohInit.c
+ ; ="1", RESET occurs in SEC phase
+
+EARLY_MICROCODE_SUPPORT EQU 1
+DETERMINISTIC_BSP_SUPPORT EQU 0
+DEBUG EQU 1
+
+;
+; IO port to access the upper 128-byte of RTC RAM
+;
+RTC_UPPER_INDEX EQU 072h
+RTC_UPPER_DATA EQU 073h
+
+;
+; Offset of data stored in the upper 128-byte of RTC RAM.
+;
+CMOS_CPU_BSP_SELECT EQU 010h ; BspSelection
+CMOS_CPU_UP_MODE EQU 011h ; UpBootSelection
+
+;
+; Cpu Ratio and Vid stored in the upper 128-byte of RTC RAM.
+;
+CMOS_CPU_RATIO_OFFSET EQU 012h ; ProcessorFlexibleRatio
+CMOS_CPU_CORE_HT_OFFSET EQU 013h ; ProcessorHyperThreadingEnable & EnableCoresInSbsp & EnableCoresInNbsp
+
+;
+; CPU Feature
+;
+CMOS_CPU_BIST_OFFSET EQU 015h ; ProcessorBistEnable
+CMOS_CPU_VMX_OFFSET EQU 016h ; ProcessorVmxEnable
+
+;
+; Port80 Selection
+;
+CMOS_PORT80_OFFSET EQU 017h ; Port80Route
+
+;
+;Flash layout map
+;
+PEICODE_REGION_BASE_ADDRESS EQU FLASH_BASE
+PEICODE_REGION_SIZE EQU FLASH_SIZE
+PEICODE_REGION_SIZE_MASK EQU (NOT (PEICODE_REGION_SIZE - 1))
+
+
+PEI_CORE_ENTRY_BASE EQU 0FFFFFFE0h
+FV_MAIN_BASE EQU 0FFFFFFFCh
+
+MAX_NR_BUS EQU 0FFh
+MAX_NR_CPU_SOCKETS EQU 2 ; DP example, MP may have 4 or more
+
+BIT0 EQU 01h
+BIT1 EQU 02h
+BIT2 EQU 04h
+BIT3 EQU 08h
+BIT4 EQU 10h
+BIT5 EQU 20h
+BIT6 EQU 40h
+BIT7 EQU 80h
+BIT8 EQU 100h
+BIT9 EQU 200h
+BIT10 EQU 400h
+BIT11 EQU 800h
+BIT12 EQU 1000h
+BIT13 EQU 2000h
+BIT14 EQU 4000h
+BIT15 EQU 8000h
+BIT16 EQU 10000h
+BIT17 EQU 20000h
+BIT18 EQU 40000h
+BIT19 EQU 80000h
+BIT20 EQU 0100000h
+BIT23 EQU 0800000h
+BIT31 EQU 080000000h
+; Bit definition in MM1
+BadCMOSDetected EQU (BIT0 shl 17)
+BSPApicIDSaveStart EQU 24
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform_S.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform_S.inc
new file mode 100644
index 0000000000..a50fc4aac8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/Platform_S.inc
@@ -0,0 +1,92 @@
+;; @file
+; Platform Specific Definitions.
+;
+; Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+#INCLUDE FlashMap.inc #ECP porting
+
+.equ MKF_SOFTSDV_FLAG, 0
+
+# Set "MINIMUM_BOOT_SUPPORT" flag allows BIOS boot as minimum feature in SEC phase.
+.equ MINIMUM_BOOT_SUPPORT, 0 # ="0", Normal Boot#
+ # ="1", Minimum Feature Boot
+# "RESET_IN_SEC" flag allows BIOS doing RESET in SEC phase
+.equ RESET_IN_SEC, 0 # ="0", RESET occurs in OemIohInit.c
+ # ="1", RESET occurs in SEC phase
+
+.equ EARLY_MICROCODE_SUPPORT, 1
+.equ DETERMINISTIC_BSP_SUPPORT, 0
+.equ DEBUG, 1
+
+#
+# IO port to access the upper 128-byte of RTC RAM
+#
+.equ RTC_UPPER_INDEX, 0x72
+.equ RTC_UPPER_DATA, 0x73
+
+#
+# Offset of data stored in the upper 128-byte of RTC RAM.
+#
+.equ CMOS_CPU_BSP_SELECT, 0x10 # BspSelection
+.equ CMOS_CPU_UP_MODE, 0x11 # UpBootSelection
+
+#
+# Cpu Ratio and Vid stored in the upper 128-byte of RTC RAM.
+#
+.equ CMOS_CPU_RATIO_OFFSET, 0x12 # ProcessorFlexibleRatio
+.equ CMOS_CPU_CORE_HT_OFFSET, 0x13 # ProcessorHyperThreadingEnable & EnableCoresInSbsp & EnableCoresInNbsp
+
+#
+# CPU Feature
+#
+.equ CMOS_CPU_BIST_OFFSET, 0x15 # ProcessorBistEnable
+.equ CMOS_CPU_VMX_OFFSET, 0x16 # ProcessorVmxEnable
+
+#
+# Port80 Selection
+#
+.equ CMOS_PORT80_OFFSET, 0x17 # Port80Route
+
+
+.equ PEI_CORE_ENTRY_BASE, 0xFFFFFFE0
+.equ FV_MAIN_BASE, 0xFFFFFFFC
+
+.equ MAX_NR_BUS, 0xFF
+.equ MAX_NR_CPU_SOCKETS, 2 # DP example, MP may have 4 or more
+
+.equ BIT0, 0x01
+.equ BIT1, 0x02
+.equ BIT2, 0x04
+.equ BIT3, 0x08
+.equ BIT4, 0x10
+.equ BIT5, 0x20
+.equ BIT6, 0x40
+.equ BIT7, 0x80
+.equ BIT8, 0x100
+.equ BIT9, 0x200
+.equ BIT10, 0x400
+.equ BIT11, 0x800
+.equ BIT12, 0x1000
+.equ BIT13, 0x2000
+.equ BIT14, 0x4000
+.equ BIT15, 0x8000
+.equ BIT16, 0x10000
+.equ BIT17, 0x20000
+.equ BIT18, 0x40000
+.equ BIT19, 0x80000
+.equ BIT20, 0x100000
+.equ BIT23, 0x800000
+.equ BIT31, 0x80000000
+# Bit definition in MM1
+.equ BadCMOSDetected, (BIT0 << 17)
+.equ BSPApicIDSaveStart, 24
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore.inc
new file mode 100644
index 0000000000..4df8960534
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore.inc
@@ -0,0 +1,37 @@
+;; @file
+; SecCore constants and macros.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+;
+; Set to 1 to enable debug
+;
+NO_EVICTION_MODE_DEBUG EQU 1
+
+STATUS_CODE MACRO status
+IF NO_EVICTION_MODE_DEBUG
+ mov al, status
+ out 080h, al
+ENDIF
+ENDM
+
+FVHEADER_LEN_OFF EQU 30h
+
+IMAGE_BASE_ADDRESS EQU 0FFFF0000h
+
+;
+; Commands defined in the AP SIPI code
+;
+AP_SIPI_COLLECT_MAX_RATIO EQU 001h
+AP_SIPI_PROGRAM_MAX_RATIO EQU 002h
+AP_SIPI_SWITCH_BSP EQU 003h
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore_S.inc b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore_S.inc
new file mode 100644
index 0000000000..3a9126fcb8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecCore_S.inc
@@ -0,0 +1,37 @@
+;; @file
+; SecCore constants and macros.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+#
+# Set to 1 to enable debug
+#
+.equ NO_EVICTION_MODE_DEBUG, 1
+
+.macro STATUS_CODE status
+.if NO_EVICTION_MODE_DEBUG
+ movb \status, %al
+ outb %al, $0x80
+.endif
+.endm
+
+.equ FVHEADER_LEN_OFF, 0x30
+
+.equ IMAGE_BASE_ADDRESS, 0xFFFF0000
+
+#
+# Commands defined in the AP SIPI code
+#
+.equ AP_SIPI_COLLECT_MAX_RATIO, 0x01
+.equ AP_SIPI_PROGRAM_MAX_RATIO, 0x02
+.equ AP_SIPI_SWITCH_BSP, 0x03
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.S b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.S
new file mode 100644
index 0000000000..534c62c730
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.S
@@ -0,0 +1,570 @@
+## @file
+# This is the code that goes from real-mode to protected mode.
+# It consumes the reset vector.
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+.nolist
+ .include "Platform_S.inc"
+ .include "Ia32_S.inc"
+ .include "Chipset_S.inc"
+ .include "SecCore_S.inc"
+.list
+
+ASM_GLOBAL ASM_PFX(SecStartup)
+
+.text
+
+###############################################################################
+#
+# Macro functions
+#
+###############################################################################
+.macro CALL_MMX RoutineLabel
+
+ movl $0f, %esi
+ movd %esi, %mm7 # Save ReturnAddress into MM7
+ jmp \RoutineLabel
+0:
+
+.endm
+
+.macro RET_ESI
+
+ movd %mm7, %esi # Restore ESP from MM7
+ jmp *%esi
+
+.endm
+
+
+.align 4
+###############################################################################
+#
+# Routine for Module Entry
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (_ModuleEntryPoint)
+ASM_PFX (_ModuleEntryPoint):
+
+ STATUS_CODE $0x02
+ STATUS_CODE $0x03
+
+ CALL_MMX PlatformInitialization
+ STATUS_CODE $0x04
+
+ #
+ # Set BIT16 and BIT17 in REG_SB_BIOS_CONFIG, Port 0x4, Offset 0x6.
+ # These bits need to be set before setting bits [1:0] in BIOS_RESET_CPL
+ # so that PUNIT will not power gate DFX.
+ #
+ movl $0xCF8, %edx # Config MDR
+ movl $0x800000d4, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx # Set BIT16 and BIT17
+ movl $0x30000, %eax
+ outl %eax, %dx
+
+ movl $0xCF8, %edx # Config MCR
+ movl $0x800000d0, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx # Write_opcode + portID + offset
+ movl $0x070406F0, %eax
+ outl %eax, %dx
+
+ #
+ # Set BIOS_RESET_DONE (BIT0) and BIOS_ALL_DONE (BIT1) in
+ # PUNIT.BIOS_RESET_CPL register, Port 0x4, Offset 0x5.
+ #
+ movl $0xCF8, %edx # Config MCD
+ movl $0x800000d4, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx # Set BIT0 and BIT1
+ movl $3, %eax
+ outw %ax, %dx
+
+ movl $0xCF8, %edx # Config MCR
+ movl $0x800000d0, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx # Write_opcode + portID + offset
+ movl $0x070405F0, %eax
+ outl %eax, %dx
+
+ STATUS_CODE $0x0A
+ CALL_MMX EstablishStack # For CPU SV
+
+ STATUS_CODE $0x0B
+
+ jmp ASM_PFX (CallPeiCoreEntryPoint)
+
+# end of _ModuleEntryPoint
+
+
+###############################################################################
+#
+# Routine for Protected Mode EntryPoint
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (ProtectedModeEntryPoint)
+ASM_PFX (ProtectedModeEntryPoint):
+
+ RET_ESI
+
+# end of ProtectedModeEntryPoint
+
+
+###############################################################################
+#
+# Routine for Platform Initialization
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (PlatformInitialization)
+ASM_PFX (PlatformInitialization):
+
+
+ #
+ # Program PCIEXBAR and enable it in 0/0/0
+ # Lo - Offset 0x60
+ # Hi - Offset 0x64
+ #
+
+ movl $0x80000060, %eax
+ movw $0xCF8, %dx
+ outl %eax, %dx
+ movl $(CPU_HEC_BASE | CPU_HEC_EN), %eax
+ movw $0xCFC, %dx
+ outl %eax, %dx
+
+ #
+ # Program and enable all known base addresses
+ #
+
+ #
+ # Program and enable MCH base address.
+ #
+ movl $R_MCH_BASE, %edi
+ movl $(MCH_BASE_ADDRESS + B_MCH_BASE_ADDRESS_EN), (%edi)
+
+ #
+ # Program and enable SPI base address.
+ # B0:D13:F2
+ movl $0xCF8, %edx # Config SPI Base
+ movl $0x8006A010, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx
+ movl $SPI_BASE_ADDRESS, %eax
+ outl %eax, %dx
+
+ movl $0xCF8, %edx # Config SPI Base
+ movl $0x8006A004, %eax
+ outl %eax, %dx
+
+ movl $0xCFC, %edx
+ inl %dx, %eax
+ orl $2, %eax # enable memory space
+ outl %eax, %dx
+
+ movl $R_PMC_ACPI_BASE, %edi
+ movw $ACPI_BASE_ADDRESS, (%edi)
+
+ #
+ # Program PMC Bar0(IPC1 4KB and GCR 4KB) and Bar1(SSRAM, 4KB), are 64bit bars.
+ #
+ movl $R_PMC_MMIO_BAR0, %edi
+ movl $IPC1_BASE_ADDRESS, (%edi)
+
+ movl $(R_PMC_MMIO_BAR0 + $4), %edi
+ movl $0x00, (%edi)
+
+ movl $R_PMC_MMIO_BAR1, %edi
+ movl $SSRAM_BASE_ADDRESS, (%edi)
+
+ movl $( R_PMC_MMIO_BAR1 + $4), %edi
+ movl $0x00, (%edi)
+
+ #
+ # Enable Bus IO space decode
+ #
+ movl $R_PMC_PCI_CMD, %edi
+ movl $0x07, (%edi)
+
+ #
+ # WA for ACPI PM1 timer BXT 0 and 1
+ #
+ movl $0x121, %ecx
+ movl $(BIT16 + ACPI_BASE_ADDRESS + R_ACPI_PM1_TMR), %eax # Bit 16 is enable and 15:0 address
+ wrmsr
+
+ #
+ # End program and enable all known base addresses
+ #
+
+ #
+ # HPET memory address enable
+ #
+
+ movl $R_P2SB_HPTC, %edi
+ movb $HPTC_AE, (%edi)
+
+ #
+ # Check RTC power well first
+ #
+ movl $(PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1), %edi # PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1
+ movw (%edi), %ax
+ testw $0x200, %ax # B_PMC_GEN_PMCON_GEN_RST_STS
+ jz check_RTC_PWR_STS
+
+force_cold_boot_path:
+ movw %ax, %cx # Save
+
+ movw $(ACPI_BASE_ADDRESS + R_ACPI_PM1_CNT), %dx
+ inw %dx, %ax
+ andw $(~V_ACPI_PM1_CNT_S5), %ax # Clear sleep type field SLP_TYP [12:10]
+ outw %ax, %dx
+
+ movw %cx, %ax # restore
+
+check_RTC_PWR_STS:
+ testw $0x4, %ax # B_PMC_GEN_PMCON_RTC_PWR_STS
+ jz no_RTC_pwr_failure
+
+ #
+ # According to CHV BIOS Specification, the following sequence must be programmed
+ # in order to ensure RTC state has been initialized.
+ #
+ # The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization.
+ # This will ensure that the RTC state machine has been initialized.
+ # 1. If the RTC_PWR_STS bit is set, steps 2 through 5 should be executed.
+ # 2. Set RTC Register 0Ah[6:4] to '110' or '111'.
+ # 3. Set RTC Register 0Bh[7].
+ # 4. Set RTC Register 0Ah[6:4] to '010'.
+ # 5. Clear RTC Register 0Bh[7].
+
+init_RTC_state_machine:
+
+ #
+ # Set RTC Register 0Ah[6:4] to '110' or '111'.
+ #
+ movb $0x0A, %al
+ outb %al, $0x70
+ nop # Delay
+ nop # Delay
+ movb $0x66, %al
+ outb %al, $0x71
+ nop # Delay
+ nop # Delay
+
+ #
+ # Set RTC Register 0Bh[7].
+ #
+ movb $0x0B, %al
+ outb %al, $0x70
+ nop # Delay
+ nop # Delay
+ inb $0x71, %al
+ nop # Delay
+ nop # Delay
+ orb $0x80, %al
+ outb %al, $0x71
+ nop # Delay
+ nop # Delay
+
+ #
+ # Set RTC Register 0Ah[6:4] to '010'.
+ #
+ movb $0x0A, %al
+ outb %al, $0x70
+ nop # Delay
+ nop # Delay
+ movb $0x26, %al
+ outb %al, $0x71
+ nop # Delay
+ nop # Delay
+
+ #
+ # Clear RTC Register 0Bh[7].
+ #
+ movb $0x0B, %al
+ outb %al, $0x70
+ nop # Delay
+ nop # Delay
+ inb $0x71, %al
+ nop # Delay
+ nop # Delay
+ andb $(~0x80), %al
+ outb %al, $0x71
+ nop # Delay
+ nop # Delay
+
+no_RTC_pwr_failure:
+ #
+ # Enable SPI Prefetch
+ #
+ movl $(SPI_BASE_ADDRESS + R_SPI_BCR), %edi
+ orl $0x08, (%edi) # Bits [3:2] = '10' - enable prefetching and caching.
+
+ #
+ # Program 8259 Interrupt Controller to disable all interrupts
+ #
+ movb $0xFF, %al
+ outb %al, $0x21 # Mask off all interrupts in master 8259
+ outb %al, $0xa1 # Mask off all interrupts in slave 8259
+
+ #
+ # Halt TCO Timer
+ #
+ movw $(ACPI_BASE_ADDRESS + R_TCO_CNT), %dx
+ inw %dx, %ax
+ orw $B_TCO_CNT_TMR_HLT, %ax
+ outw %ax, %dx
+
+.if 1
+ ; Do nothing
+.else
+ #
+ # Clear the Second Timeout Status bit by writing 1
+ #
+ movl $(ACPI_BASE_ADDRESS + R_TCO_STS), %edx
+ inl %dx, %eax
+ orl $B_TCO_STS_SECOND_TO, %eax
+ outl %eax, %dx
+.endif
+
+ #
+ # Check to see if 0xCF9 Global Reset bit is set. if set clear it.
+ #
+ movl $(PMC_BASE_ADDRESS + R_PMC_PMIR), %edi
+ movl (%edi), %eax
+ testl $B_PMC_PMIR_CF9GR, %eax # Check whether 0xCF9 Global Reset bit is set
+ jz GlobalresetClear # If no, continue
+ andl $(~B_PMC_PMIR_CF9GR), %eax # Clear 0xCF9 Global Reset bit
+ movl %eax, (%edi)
+
+GlobalresetClear:
+ #
+ # Clear HPET Timer 0 Lower and Upper Comparator Value.
+ #
+ xorl %eax, %eax
+ movl $HPET_COMP_1, %esi
+ movl %eax, (%esi)
+ movl $HPET_COMP_2, %esi
+ movl %eax, (%esi)
+
+ #
+ # Read Bunit.BMISC BIT1 to check F-segment set
+ # Determine if INIT or Hard Reset
+ #
+ movl $(MCH_BASE_ADDRESS + BUNIT_BMISC), %edi
+ movl (%edi), %eax
+
+ testl $B_BMISC_RFSDRAM, %eax # Check bit offset 1
+ jnz L1
+
+reset:
+ #
+ # Do a hard Reset if INIT.
+ #
+ movb $6, %al
+ movw $0xCF9, %dx
+ outb %al, %dx # Hard reset
+ jmp .
+
+L1:
+
+
+
+ RET_ESI
+
+# end of PlatformInitialization
+
+
+###############################################################################
+#
+# Routine to Establish Stack
+#
+# STATUS_CODE $0x0A
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (EstablishStack)
+ASM_PFX (EstablishStack):
+
+ #
+ # Enable STACK
+ #
+ # To be programmed...
+.if 0 # equate not defined
+ movl ASM_PFX(PcdGet32 (PcdTemporaryRamBase)), %esp
+ addl ASM_PFX(PcdGet32 (PcdTemporaryRamSize)), %esp
+ subl $4, %esp
+
+ # Pass NEM address into the PEI Core
+ # push PhysBase
+
+ push ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
+
+ # Dispatch table
+
+ push -(LAST_ADDRESS - offset MICROCODE_DISPATCH_DESCRIPTOR)
+
+ # Pass stack size into the PEI Core
+ push ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
+.endif
+ RET_ESI
+
+# end of EstablishStack
+
+
+###############################################################################
+#
+# Routine to Call PeiCore EntryPoint
+#
+# STATUS_CODE $0x0B
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (CallPeiCoreEntryPoint)
+ASM_PFX (CallPeiCoreEntryPoint):
+
+ #
+ # Set stack top pointer
+ #
+ movl %ds:CarBase(%ebp), %esp
+ addl %ds:CarSize(%ebp), %esp
+
+ #
+ # Push CPU count to stack first, then AP's (if there is one)
+ # BIST status, and then BSP's
+ #
+
+ #
+ # Here work around for BIST
+ #
+ # Get number of BSPs
+ movd %mm1, %ecx
+ movzbl %ch, %ecx
+
+ # Save number of BSPs
+ pushl %ecx
+
+GetSBSPBist:
+ # Save SBSP BIST
+ movd %mm0, %eax
+ pushl %eax
+
+ # Save SBSP APIC ID
+ movd %mm1, %eax
+ shrl $BSPApicIDSaveStart, %eax # Resume APIC ID
+ pushl %eax
+
+TransferToSecStartup:
+
+ # Switch to "C" code
+ STATUS_CODE $0x0C
+
+ #
+ # Pass entry point of the PEI core
+ #
+ movl $PEI_CORE_ENTRY_BASE, %edi # 0FFFFFFE0h
+ pushl %ds:(%edi)
+
+ #
+ # Pass BFV into the PEI Core
+ #
+ push %ds:IBBBase(%ebp) # 0FFFFFFFCh
+
+ #
+ # ECPoverride: SecStartup entry point needs 4 parameters
+ #
+ movl %ds:CarBase(%ebp), %edi
+ addl %ds:CarSize(%ebp), %edi
+ subl $0x10000, %edi
+ pushl %edi
+ movl $0x10000, %edi
+ pushl %edi
+ #
+ # Pass stack size into the PEI Core
+ #
+
+
+ #
+ # Pass Control into the PEI Core
+ #
+ call ASM_PFX(SecStartup)
+# end of CallPeiCoreEntryPoint
+
+
+###############################################################################
+#
+# Routine for StartUp Ap
+#
+###############################################################################
+ASM_GLOBAL ASM_PFX (StartUpAp)
+ASM_PFX (StartUpAp):
+
+ movl $HPET_COMP_2, %esi
+ lock incb (%esi)
+
+ DISABLE_CACHE
+ #
+ # Halt the AP and wait for the next SIPI
+ #
+Ap_Halt:
+ cli
+B3:
+ hlt
+ jmp B3
+ ret
+# end of StartUpAp
+
+
+.data
+MtrrInitTable:
+ .word MTRR_DEF_TYPE
+ .word MTRR_FIX_64K_00000
+ .word MTRR_FIX_16K_80000
+ .word MTRR_FIX_16K_A0000
+ .word MTRR_FIX_4K_C0000
+ .word MTRR_FIX_4K_C8000
+ .word MTRR_FIX_4K_D0000
+ .word MTRR_FIX_4K_D8000
+ .word MTRR_FIX_4K_E0000
+ .word MTRR_FIX_4K_E8000
+ .word MTRR_FIX_4K_F0000
+ .word MTRR_FIX_4K_F8000
+
+.equ MtrrCountFixed, ((. - MtrrInitTable) / 2)
+
+ .word MTRR_PHYS_BASE_0
+ .word MTRR_PHYS_MASK_0
+ .word MTRR_PHYS_BASE_1
+ .word MTRR_PHYS_MASK_1
+ .word MTRR_PHYS_BASE_2
+ .word MTRR_PHYS_MASK_2
+ .word MTRR_PHYS_BASE_3
+ .word MTRR_PHYS_MASK_3
+ .word MTRR_PHYS_BASE_4
+ .word MTRR_PHYS_MASK_4
+ .word MTRR_PHYS_BASE_5
+ .word MTRR_PHYS_MASK_5
+ .word MTRR_PHYS_BASE_6
+ .word MTRR_PHYS_MASK_6
+ .word MTRR_PHYS_BASE_7
+ .word MTRR_PHYS_MASK_7
+ .word MTRR_PHYS_BASE_8
+ .word MTRR_PHYS_MASK_8
+ .word MTRR_PHYS_BASE_9
+ .word MTRR_PHYS_MASK_9
+.equ MtrrCount, ((. - MtrrInitTable) / 2)
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.asm b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.asm
new file mode 100644
index 0000000000..ce424caab9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Ia32/SecEntry.asm
@@ -0,0 +1,536 @@
+;; @file
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector.
+;
+; Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+;
+; This program and the accompanying materials
+; 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
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+ INCLUDE Platform.inc
+ INCLUDE Ia32.inc
+ INCLUDE Chipset.inc
+ INCLUDE SecCore.inc
+
+ ;EXTRN PcdGet32(PcdTemporaryRamSize):DWORD
+
+.686p
+.xmm
+.model small, c
+
+ EXTRN SecStartup:NEAR
+
+_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
+ ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
+
+CALL_MMX macro RoutineLabel
+
+ local ReturnAddress
+ mov esi, offset ReturnAddress
+ movd mm7, esi ; save ReturnAddress into MM7
+ jmp RoutineLabel
+ReturnAddress:
+
+endm
+
+RET_ESI macro
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+endm
+
+
+align 4
+_ModuleEntryPoint PROC NEAR PUBLIC
+
+ STATUS_CODE (02h)
+ STATUS_CODE (03h)
+
+ CALL_MMX PlatformInitialization
+ STATUS_CODE (04h)
+
+ ;
+ ; Set BIT16 and BIT17 in REG_SB_BIOS_CONFIG, Port 0x4, Offset 0x6.
+ ; These bits need to be set before setting bits [1:0] in BIOS_RESET_CPL
+ ; so that PUNIT will not power gate DFX.
+ ;
+ mov edx, 0CF8h ; Config MDR
+ mov eax, 800000d4h
+ out dx, eax
+
+ mov edx, 0CFCh ; Set BIT16 and BIT17
+ mov eax, 30000h
+ out dx, eax
+
+ mov edx, 0CF8h ; Config MCR
+ mov eax, 800000d0h
+ out dx, eax
+
+ mov edx, 0CFCh
+ mov eax, 0070406f0h ; Write_opcode + portID + offset
+ out dx, eax
+
+ ;
+ ; Set BIOS_RESET_DONE (BIT0) and BIOS_ALL_DONE (BIT1) in
+ ; PUNIT.BIOS_RESET_CPL register, Port 0x4, Offset 0x5.
+ ;
+ mov edx, 0CF8h ; Config MCD
+ mov eax, 800000d4h
+ out dx, eax
+
+ mov edx, 0CFCh
+ mov eax, 3 ; Set BIT0 and BIT1
+ out dx, ax
+
+ mov edx, 0CF8h ; Config MCR
+ mov eax, 800000d0h
+ out dx, eax
+
+ mov edx, 0CFCh
+ mov eax, 0070405f0h ; Write_opcode + portID + offset
+ out dx, eax
+
+ STATUS_CODE (0Ah)
+; CALL_MMX EstablishStack ; For CPU SV
+
+ STATUS_CODE (0Bh)
+
+ jmp CallPeiCoreEntryPoint
+
+_ModuleEntryPoint ENDP
+
+ProtectedModeEntryPoint PROC NEAR PUBLIC
+
+ RET_ESI
+
+ProtectedModeEntryPoint ENDP
+
+PlatformInitialization PROC NEAR PRIVATE
+
+ ;
+ ; Program PCIEXBAR and enable it in 0/0/0
+ ; Lo - Offset 0x60
+ ; Hi - Offset 0x64
+ ;
+
+ mov eax, 080000060h
+ mov dx, 0CF8h
+ out dx, eax
+ mov eax, CPU_HEC_BASE OR CPU_HEC_EN
+ mov dx, 0CFCh
+ out dx, eax
+
+
+ ;
+ ; Program and enable all known base addresses
+ ;
+
+ ;
+ ; Program and enable MCH base address.
+ ;
+ mov edi, R_MCH_BASE
+ mov Dword Ptr [edi], MCH_BASE_ADDRESS + B_MCH_BASE_ADDRESS_EN
+
+ ;
+ ; Program and enable SPI base address.
+ ; B0:D13:F2
+ mov edx, 0CF8h ; Config SPI Base
+ mov eax, 8006A010h
+ out dx, eax
+
+ mov edx, 0CFCh
+ mov eax, SPI_BASE_ADDRESS
+ out dx, eax
+
+ mov edx, 0CF8h ; Config SPI Base
+ mov eax, 8006A004h
+ out dx, eax
+
+ mov edx, 0CFCh
+ in eax, dx
+ or eax, 2h ; enable memory space
+ out dx, eax
+
+ ;
+ ; Program and enable ACPI base address.
+ ;
+ mov edi, R_PMC_ACPI_BASE
+ mov Word Ptr [edi], ACPI_BASE_ADDRESS
+
+ ;
+ ; Program D13:F1, PMC Bar0(IPC1) and Bar1, are 64bit bars.
+ ; This should be moved into C code - no need to init this early..
+ ;
+ mov edi, R_PMC_MMIO_BAR0
+ mov Dword Ptr [edi], IPC1_BASE_ADDRESS
+
+ mov edi, R_PMC_MMIO_BAR0 + 4h
+ mov Dword Ptr [edi], 0h
+
+ mov edi, R_PMC_MMIO_BAR1
+ mov Dword Ptr [edi], IPC1_BASE2_ADDRESS
+
+ mov edi, R_PMC_MMIO_BAR1 + 4h
+ mov Dword Ptr [edi], 0h
+
+ ; Enable Bus IO space decode
+ mov edi, R_PMC_PCI_CMD
+ mov Word Ptr [edi], 07h
+
+ ; BXT HSDES 1958937
+ ; WA for ACPI PM1 timer BXT 0 and 1
+ mov ecx, 0121h
+ mov eax, BIT16 + ACPI_BASE_ADDRESS + R_ACPI_PM1_TMR ; Bit 16 is enable and 15:0 address
+ mov edx, 2FBA2E25h
+ wrmsr
+
+ ;
+ ; HPET memory address enable
+ ;
+
+ mov edi, R_P2SB_HPTC
+ mov Byte Ptr [edi], HPTC_AE
+
+
+ ;
+ ; Check RTC power well first
+ ;
+ mov edi, PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1
+ mov ax, WORD PTR [edi]
+ test ax, 0FFFFh ; B_PMC_GEN_PMCON_GEN_RST_STS
+ jz check_RTC_PWR_STS
+ test ax, 0200h ; B_PMC_GEN_PMCON_GEN_RST_STS
+ jz check_RTC_PWR_STS
+
+force_cold_boot_path:
+ mov cx, ax ; Save
+ mov dx, ACPI_BASE_ADDRESS + R_ACPI_PM1_CNT
+ in ax, dx
+ and ax, NOT (V_ACPI_PM1_CNT_S5) ; Clear sleep type field SLP_TYP [12:10]
+ out dx, ax
+
+ mov ax, cx ; restore
+
+check_RTC_PWR_STS:
+ test ax, 004h ; B_PMC_GEN_PMCON_RTC_PWR_STS
+ jz no_RTC_pwr_failure
+
+ ;
+ ; According to CHV BIOS Specification, the following sequence must be programmed
+ ; in order to ensure RTC state has been initialized.
+ ;
+ ; The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization.
+ ; This will ensure that the RTC state machine has been initialized.
+ ; 1. If the RTC_PWR_STS bit is set, steps 2 through 5 should be executed.
+ ; 2. Set RTC Register 0Ah[6:4] to '110' or '111'.
+ ; 3. Set RTC Register 0Bh[7].
+ ; 4. Set RTC Register 0Ah[6:4] to '010'.
+ ; 5. Clear RTC Register 0Bh[7].
+
+init_RTC_state_machine:
+
+ ;
+ ; Set RTC Register 0Ah[6:4] to '110' or '111'.
+ ;
+ mov al, 0Ah
+ out 070h, al
+ nop ; Delay
+ nop ; Delay
+ mov al, 066h
+ out 071h, al
+ nop ; Delay
+ nop ; Delay
+
+ ;
+ ; Set RTC Register 0Bh[7].
+ ;
+ mov al, 0Bh
+ out 070h, al
+ nop ; Delay
+ nop ; Delay
+ in al, 071h
+ nop ; Delay
+ nop ; Delay
+ or al, 080h
+ out 071h, al
+ nop ; Delay
+ nop ; Delay
+
+ ;
+ ; Set RTC Register 0Ah[6:4] to '010'.
+ ;
+ mov al, 0Ah
+ out 070h, al
+ nop ; Delay
+ nop ; Delay
+ mov al, 026h
+ out 071h, al
+ nop ; Delay
+ nop ; Delay
+
+ ;
+ ; Clear RTC Register 0Bh[7].
+ ;
+ mov al, 0Bh
+ out 070h, al
+ nop ; Delay
+ nop ; Delay
+ in al, 071h
+ nop ; Delay
+ nop ; Delay
+ and al, NOT 080h
+ out 071h, al
+ nop ; Delay
+ nop ; Delay
+
+no_RTC_pwr_failure:
+ ;
+ ; Enable SPI Prefetch
+ ;
+
+ mov edi, SPI_BASE_ADDRESS + R_SPI_BCR
+ or Dword Ptr [edi], 08h ; Bits [3:2] = '10' - enable prefetching and caching.
+
+ ;
+ ; Program 8259 Interrupt Controller to disable all interrupts
+ ;
+ mov al, 0FFh
+ out 21h, al ; Mask off all interrupts in master 8259
+ out 0a1h, al ; Mask off all interrupts in slave 8259
+
+ ;
+ ; Halt TCO Timer
+ ;
+ mov dx, ACPI_BASE_ADDRESS + R_TCO_CNT
+ in ax, dx
+ or ax, B_TCO_CNT_TMR_HLT
+ out dx, ax
+
+IF 1
+ ; Do nothing
+ELSE
+ ;
+ ; Clear the Second Timeout Status bit by writing 1
+ ;
+ mov dx, ACPI_BASE_ADDRESS + R_TCO_STS
+ in eax, dx
+ or eax, B_TCO_STS_SECOND_TO
+ out dx, eax
+ENDIF
+
+ ;
+ ; Check to see if 0xCF9 Global Reset bit is set. if set clear it.
+ ;
+ mov edi, PMC_BASE_ADDRESS + R_PMC_PMIR
+ mov eax, DWORD PTR [edi]
+ test eax, B_PMC_PMIR_CF9GR ; Check whether 0xCF9 Global Reset bit is set
+ jz GlobalresetClear ; If no, continue
+ and eax, NOT (B_PMC_PMIR_CF9GR) ; Clear 0xCF9 Global Reset bit
+ mov DWORD PTR [edi], eax
+
+GlobalresetClear:
+ ;
+ ; Clear HPET Timer 0 Lower and Upper Comparator Value.
+ ;
+
+ xor eax, eax
+ mov esi, HPET_COMP_1
+ mov Dword Ptr [esi], eax
+ mov esi, HPET_COMP_2
+ mov Dword ptr [esi], eax
+
+ ;
+ ; Read Bunit.BMISC BIT1 to check F-segment set
+ ; Determine if INIT or Hard Reset
+ ;
+ mov edi, MCH_BASE_ADDRESS + BUNIT_BMISC
+ mov eax, Dword Ptr [edi]
+
+
+ test eax, B_BMISC_RFSDRAM ; Check bit offset 1
+ jnz @f
+
+reset:
+ ;
+ ; Do a hard Reset if INIT.
+ ;
+ mov al, 6
+ mov dx, 0cf9h
+ out dx, al ; Hard reset
+ jmp $
+
+@@:
+
+ RET_ESI
+
+PlatformInitialization ENDP
+
+
+
+
+; STATUS_CODE (09h)
+EstablishStack PROC NEAR PRIVATE
+
+ ;
+ ; Enable STACK
+ ;
+ ; To be programmed...
+If 0 ; equate not defined
+ mov esp, PcdGet32 (PcdTemporaryRamBase)
+ add esp, PcdGet32 (PcdTemporaryRamSize)
+ sub esp, 4
+
+ ; Pass NEM address into the PEI Core
+ ; push PhysBase
+
+ push PcdGet32 (PcdTemporaryRamBase)
+
+ ; Dispatch table
+
+ push -(LAST_ADDRESS - offset MICROCODE_DISPATCH_DESCRIPTOR)
+
+ ; Pass stack size into the PEI Core
+ push PcdGet32 (PcdTemporaryRamSize)
+endif
+ RET_ESI
+
+EstablishStack ENDP
+
+
+; STATUS_CODE (0Bh)
+CallPeiCoreEntryPoint PROC NEAR PRIVATE
+
+ ;
+ ; Set stack top pointer
+ ;
+ mov esp, (HobStruc PTR ds:[ebp]).StackHeapBase;
+ add esp, (HobStruc PTR ds:[ebp]).StackHeapSize
+
+ ;
+ ; Push CPU count to stack first, then AP's (if there is one)
+ ; BIST status, and then BSP's
+ ;
+
+ ;
+ ; Here work around for BIST
+ ;
+ ; Get number of BSPs
+ mov ch, 01 ; for client we have only one BSP
+ movzx ecx, ch
+
+ ; Save number of BSPs
+ push ecx
+
+GetSBSPBist:
+ ; Save SBSP BIST
+ movd eax, mm0
+ push eax
+
+ ; Save SBSP APIC ID
+ movd eax, mm1
+ shr eax, BSPApicIDSaveStart ; Resume APIC ID
+ push eax
+
+
+TransferToSecStartup:
+
+ ; Switch to "C" code
+ STATUS_CODE (0Ch)
+ ;jmp $
+
+ ; ECPoverride: SecStartup entry point needs 4 parameters
+
+ ;
+ ; Pass entry point of the PEI core
+ ;
+ mov edi, PEI_CORE_ENTRY_BASE ; 0FFFFFFE0h
+ push DWORD PTR ds:[edi]
+
+ ;
+ ; Pass BFV into the PEI Core
+ ;
+ push (HobStruc PTR ds:[ebp]).IBBBase ; 0FFFFFFFCh
+
+ ;
+ ; Pass stack size into the PEI Core
+ ;
+ Push (HobStruc PTR ds:[ebp]).StackHeapBase ;calc TempRamBase
+
+ push (HobStruc PTR ds:[ebp]).StackHeapSize ;calc TempRamBase
+
+ ;
+ ; Pass Control into the PEI Core
+ ;
+ call SecStartup
+CallPeiCoreEntryPoint ENDP
+
+StartUpAp PROC NEAR
+
+ mov esi, HPET_COMP_2
+ lock inc byte ptr [esi]
+
+ DISABLE_CACHE
+;
+; Halt the AP and wait for the next SIPI
+;
+Ap_Halt:
+ cli
+@@:
+ hlt
+ jmp @B
+ ret
+StartUpAp ENDP
+
+
+MtrrInitTable LABEL BYTE
+ DW MTRR_DEF_TYPE
+ DW MTRR_FIX_64K_00000
+ DW MTRR_FIX_16K_80000
+ DW MTRR_FIX_16K_A0000
+ DW MTRR_FIX_4K_C0000
+ DW MTRR_FIX_4K_C8000
+ DW MTRR_FIX_4K_D0000
+ DW MTRR_FIX_4K_D8000
+ DW MTRR_FIX_4K_E0000
+ DW MTRR_FIX_4K_E8000
+ DW MTRR_FIX_4K_F0000
+ DW MTRR_FIX_4K_F8000
+
+MtrrCountFixed EQU (($ - MtrrInitTable) / 2)
+
+ DW MTRR_PHYS_BASE_0
+ DW MTRR_PHYS_MASK_0
+ DW MTRR_PHYS_BASE_1
+ DW MTRR_PHYS_MASK_1
+ DW MTRR_PHYS_BASE_2
+ DW MTRR_PHYS_MASK_2
+ DW MTRR_PHYS_BASE_3
+ DW MTRR_PHYS_MASK_3
+ DW MTRR_PHYS_BASE_4
+ DW MTRR_PHYS_MASK_4
+ DW MTRR_PHYS_BASE_5
+ DW MTRR_PHYS_MASK_5
+ DW MTRR_PHYS_BASE_6
+ DW MTRR_PHYS_MASK_6
+ DW MTRR_PHYS_BASE_7
+ DW MTRR_PHYS_MASK_7
+ DW MTRR_PHYS_BASE_8
+ DW MTRR_PHYS_MASK_8
+ DW MTRR_PHYS_BASE_9
+ DW MTRR_PHYS_MASK_9
+MtrrCount EQU (($ - MtrrInitTable) / 2)
+
+
+;TopOfCar DD DATA_STACK_BASE_ADDRESS + DATA_STACK_SIZE
+
+_TEXT_PROTECTED_MODE ENDS
+END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.c
new file mode 100644
index 0000000000..e4bee35fb6
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.c
@@ -0,0 +1,124 @@
+/** @file
+ Null instance of Sec Platform Hook Lib.
+
+ Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include "PlatformSecLib.h"
+#include <Library/DebugLib.h>
+
+
+/**
+ Perform those platform specific operations that are requried to be executed as early as possibile.
+
+ @return TRUE always return true.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformSecLibConstructor (
+ )
+{
+ BOOLEAN DefaultsRestored;
+
+ //
+ // Init Apic Timer for Performance collection.
+ // Use EXCEPT_IA32_BOUND as interrupte type.
+ //
+ PERF_CODE (
+ InitializeApicTimer (0, (UINT32) - 1, TRUE, 5);
+ );
+
+ DefaultsRestored = FALSE;
+
+ //
+ // Perform a checksum computation and verify if the checksum is correct. If the checksum is incorrect
+ // initialize all the CMOS location to their default values and recalculate the checksum.
+ //
+ InitCmos (FALSE, &DefaultsRestored);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ A developer supplied function to perform platform specific operations.
+
+ It's a developer supplied function to perform any operations appropriate to a
+ given platform. It's invoked just before passing control to PEI core by SEC
+ core. Platform developer may modify the SecCoreData and PPI list that is
+ passed to PEI Core.
+
+ @param[in, out] SecCoreData The same parameter as passing to PEI core. It
+ could be overridden by this function.
+ @param[in] PpiList The default PPI list passed from generic SEC part.
+
+ @return The final PPI list that platform wishes to passed to PEI core.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+ IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+{
+ return NULL;
+}
+
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in, out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+
+ UINT32 *Bist;
+ UINT32 TopOfCar;
+
+ DEBUG ((EFI_D_INFO, "SecPlatformInformation entry \n"));
+
+ //
+ // The entries of BIST information, together with the number of them,
+ // reside in the bottom of stack, left untouched by normal stack operation.
+ // This routine copies the BIST information to the buffer pointed by
+ // PlatformInformationRecord for output.
+ //
+
+ TopOfCar = CAR_BASE_ADDR + CAR_SIZE;
+ //
+ // At this stage we only have information about the BSP.
+ //
+ Bist = (UINT32 *) (UINTN) (TopOfCar - sizeof (UINT32) - sizeof (UINT32));
+
+ CopyMem (PlatformInformationRecord, Bist, (UINTN) *StructureSize);
+ DEBUG ((EFI_D_INFO, "Bist is = %x \n", Bist ));
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.h
new file mode 100644
index 0000000000..ae87bacd24
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/PlatformSecLib.h
@@ -0,0 +1,36 @@
+/** @file
+ Internal header file for SEC Platform hook library.
+
+ Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PLATFORM_SEC_LIB_H_
+#define _PLATFORM_SEC_LIB_H_
+
+#include <PiPei.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/CmosAccessLib.h>
+
+#define Flat32Start _ModuleEntryPoint
+
+
+#define CAR_BASE_ADDR 0xFEF80000
+#define CAR_SIZE 0x80000
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Vtf0PlatformSecLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Vtf0PlatformSecLib.inf
new file mode 100644
index 0000000000..0ef6ccee2d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecLib/Vtf0PlatformSecLib.inf
@@ -0,0 +1,85 @@
+## @file
+# Library functions for Platform Sec hook library.
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformSecLib
+ FILE_GUID = BA5CD127-1960-4fa0-B024-BA8EF79B5209
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecLib
+ CONSTRUCTOR = PlatformSecLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ PlatformSecLib.c
+ PlatformSecLib.h
+
+[Sources.IA32]
+ Ia32/SecEntry.asm
+ Ia32/SecEntry.S
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ PerformanceLib
+ LocalApicLib
+ CmosAccessLib
+ DebugLib
+
+[Pcd.common]
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+ gPlatformModuleTokenSpaceGuid.PcdTemporaryRamBase
+ gPlatformModuleTokenSpaceGuid.PcdTemporaryRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress
+ gPlatformModuleTokenSpaceGuid.PcdFlashMicroCode2Address
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMSize
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBLBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBLSize
+
+[BuildOptions]
+ MSFT:*_*_IA32_PP_FLAGS = /FIPlatformSecLib.h
+ INTEL:*_*_IA32_PP_FLAGS = /FIPlatformSecLib.h
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.c
new file mode 100644
index 0000000000..2cdd01dc46
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.c
@@ -0,0 +1,952 @@
+/** @file
+ IPC based PlatformFvbLib library instance.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Library/PlatformSecureDefaultsLib.h"
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <Guid/SetupVariable.h>
+
+EFI_GUID mUefiImageSecurityDBGuid = EFI_IMAGE_SECURITY_DATABASE_GUID;
+EFI_GUID mUefiCertTypeRsa2048Guid = EFI_CERT_RSA2048_GUID;
+
+#define WIN_CERT_UEFI_RSA2048_SIZE 256
+#define EFI_SECURE_BOOT_ENABLE_NAME L"SecureBootEnable"
+
+extern EFI_GUID mUefiCertTypeRsa2048Guid;
+extern EFI_GUID gEfiSecureBootEnableDisableGuid;
+
+EFI_GUID gOwnerSignatureGUID = {0x77fa9abd, 0x0359, 0x4d32, {0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b}};
+static EFI_GUID gDbxUpdateImageGuid = {0xa3d48bb3, 0x350f, 0x4bcd, 0xa4, 0xad, 0x44, 0x5b, 0x93, 0x9f, 0x6d, 0x9c };
+
+/**
+ Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
+ descriptor with the input data. NO authentication is required in this function.
+
+ @param[in, out] DataSize On input, the size of Data buffer in bytes.
+ On output, the size of data returned in Data
+ buffer in bytes.
+ @param[in, out] Data On input, Pointer to data buffer to be wrapped or
+ pointer to NULL to wrap an empty payload.
+ On output, Pointer to the new payload date buffer allocated from pool,
+ it's caller's responsibility to free the memory when finish using it.
+
+ @retval EFI_SUCCESS Create time based payload successfully.
+ @retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to create time based payload.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval Others Unexpected error happens.
+
+**/
+EFI_STATUS
+CreateTimeBasedPayload (
+ IN OUT UINTN *DataSize,
+ IN OUT UINT8 **Data
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *NewData;
+ UINT8 *Payload;
+ UINTN PayloadSize;
+ EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData;
+ UINTN DescriptorSize;
+ EFI_TIME Time;
+
+ if (Data == NULL || DataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // In Setup mode or Custom mode, the variable does not need to be signed but the
+ // parameters to the SetVariable() call still need to be prepared as authenticated
+ // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
+ // data in it.
+ //
+ Payload = *Data;
+ PayloadSize = *DataSize;
+
+ DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
+ NewData = (UINT8 *) AllocateZeroPool (DescriptorSize + PayloadSize);
+ if (NewData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if ((Payload != NULL) && (PayloadSize != 0)) {
+ CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
+ }
+
+ DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);
+
+ ZeroMem (&Time, sizeof (EFI_TIME));
+ Status = gRT->GetTime (&Time, NULL);
+ if (EFI_ERROR (Status)) {
+ FreePool(NewData);
+ return Status;
+ }
+ Time.Pad1 = 0;
+ Time.Nanosecond = 0;
+ Time.TimeZone = 0;
+ Time.Daylight = 0;
+ Time.Pad2 = 0;
+ CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));
+
+ DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
+ DescriptorData->AuthInfo.Hdr.wRevision = 0x0200;
+ DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
+ CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid);
+
+ if (Payload != NULL) {
+ FreePool(Payload);
+ }
+
+ *DataSize = DescriptorSize + PayloadSize;
+ *Data = NewData;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Generate the PK signature list from the X509 Certificate storing file (.cer)
+
+ @param[in] X509Data FileHandle of X509 Certificate storing file.
+ @param[in] X509DataSize The size of fileHandle of X509 Certificate storing file.
+ @param[out] PkCert Point to the data buffer to store the signature list.
+
+ @retval EFI_UNSUPPORTED Unsupported Key Length.
+ @retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to form the signature list.
+
+**/
+EFI_STATUS
+CreatePkX509SignatureList (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize,
+ OUT EFI_SIGNATURE_LIST **PkCert
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_DATA *PkCertData;
+
+ PkCertData = NULL;
+ Status = EFI_SUCCESS;
+ ASSERT (X509Data != NULL);
+
+ //
+ // Allocate space for PK certificate list and initialize it.
+ // Create PK database entry with SignatureHeaderSize equals 0.
+ //
+ *PkCert = (EFI_SIGNATURE_LIST *) AllocateZeroPool (
+ sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize
+ );
+ if (*PkCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ (*PkCert)->SignatureListSize = (UINT32) (sizeof (EFI_SIGNATURE_LIST)
+ + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize);
+ (*PkCert)->SignatureSize = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ (*PkCert)->SignatureHeaderSize = 0;
+ CopyGuid (&(*PkCert)->SignatureType, &gEfiCertX509Guid);
+ PkCertData = (EFI_SIGNATURE_DATA *) ((UINTN) (*PkCert)
+ + sizeof (EFI_SIGNATURE_LIST)
+ + (*PkCert)->SignatureHeaderSize);
+ CopyGuid (&PkCertData->SignatureOwner, &gEfiGlobalVariableGuid);
+ //
+ // Fill the PK database with PKpub data from X509 certificate file.
+ //
+ CopyMem (&(PkCertData->SignatureData[0]), X509Data, X509DataSize);
+
+ON_EXIT:
+
+ if (EFI_ERROR(Status) && *PkCert != NULL) {
+ FreePool (*PkCert);
+ *PkCert = NULL;
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EnrollPlatformKey (
+ IN VOID *Buf,
+ IN UINTN BufSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Attr;
+ UINTN DataSize;
+ EFI_SIGNATURE_LIST *PkCert;
+
+ PkCert = NULL;
+
+ //
+ // Prase the selected PK file and generature PK certificate list.
+ //
+ Status = CreatePkX509SignatureList (
+ Buf,
+ BufSize,
+ &PkCert
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ ASSERT (PkCert != NULL);
+
+ //
+ // Set Platform Key variable.
+ //
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ DataSize = PkCert->SignatureListSize;
+ Status = CreateTimeBasedPayload (&DataSize, (UINT8 **) &PkCert);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ DataSize,
+ PkCert
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ DEBUG ((EFI_D_ERROR, "Enroll PK failed with out of resource.\n"));
+ }
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (PkCert != NULL) {
+ FreePool (PkCert);
+ }
+
+ return Status;
+}
+
+
+/**
+ Enroll a new KEK item from X509 certificate file.
+
+ @param[in] PrivateData The module's private data.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported command.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509ToKek (
+ VOID *X509Data,
+ UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_DATA *KEKSigData;
+ EFI_SIGNATURE_LIST *KekSigList;
+ UINTN DataSize;
+ UINTN KekSigListSize;
+ UINT32 Attr;
+
+ KekSigList = NULL;
+ KekSigListSize = 0;
+ DataSize = 0;
+ KEKSigData = NULL;
+
+ ASSERT (X509Data != NULL);
+
+ KekSigListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+ KekSigList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (KekSigListSize);
+ if (KekSigList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ KekSigList->SignatureListSize = (UINT32) KekSigListSize;
+ KekSigList->SignatureHeaderSize = 0;
+ KekSigList->SignatureSize = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&KekSigList->SignatureType, &gEfiCertX509Guid);
+
+ KEKSigData = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekSigList + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&KEKSigData->SignatureOwner, &gOwnerSignatureGUID);
+ CopyMem (KEKSigData->SignatureData, X509Data, X509DataSize);
+
+ //
+ // Check if KEK been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new kek to original variable
+ //
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **) &KekSigList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable(
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ KekSigListSize,
+ KekSigList
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (KekSigList != NULL) {
+ FreePool (KekSigList);
+ }
+
+ return Status;
+}
+
+
+/**
+ Enroll new KEK into the System without PK's authentication.
+ The SignatureOwner GUID will be Private->SignatureGUID.
+
+ @param[in] PrivateData The module's private data.
+
+ @retval EFI_SUCCESS New KEK enrolled successful.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval others Fail to enroll KEK data.
+
+**/
+EFI_STATUS
+EnrollKeyExchangeKey (
+ IN VOID *DataBuf,
+ IN UINTN BufSize
+ )
+{
+ return EnrollX509ToKek (DataBuf, BufSize);
+}
+
+
+EFI_STATUS
+EnrollX509toForbSigDB (
+ IN CHAR16 *VariableName,
+ IN VOID *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN SigDBSize;
+ UINT32 Attr;
+ UINTN DataSize;
+
+ SigDBSize = 0;
+ DataSize = 0;
+ Data = NULL;
+
+ ASSERT (X509Data != NULL);
+
+ SigDBSize = X509DataSize;
+
+ Data = AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ CopyMem ((UINT8 *) Data, X509Data, X509DataSize);
+
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Status = gRT->GetVariable(
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ return Status;
+}
+
+
+/**
+ Enroll X509 certificate into Forbidden Database (DBX) without
+ KEK's authentication.
+
+ @param[in] VariableName Variable name of signature database, must be
+ @param[in] *DataBuf Pointer to Data Buffer
+ @param[in] BufSize Data Buffer size
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollKeyForbiddenSignatureDatabase (
+ IN CHAR16 *VariableName,
+ IN VOID *DataBuf,
+ IN UINTN BufSize
+ )
+{
+ return EnrollX509toForbSigDB (VariableName, DataBuf, BufSize);
+}
+
+
+/**
+ Enroll a new X509 certificate into Signature Database (DB or DBX) without
+ KEK's authentication.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509toSigDB (
+ IN CHAR16 *VariableName,
+ IN VOID *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigDBCert;
+ EFI_SIGNATURE_DATA *SigDBCertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDBSize;
+ UINT32 Attr;
+
+ SigDBSize = 0;
+ DataSize = 0;
+ SigDBCert = NULL;
+ SigDBCertData = NULL;
+ Data = NULL;
+
+ ASSERT (X509Data != NULL);
+
+ SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+
+ Data = AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ SigDBCert = (EFI_SIGNATURE_LIST *) Data;
+ SigDBCert->SignatureListSize = (UINT32) SigDBSize;
+ SigDBCert->SignatureHeaderSize = 0;
+ SigDBCert->SignatureSize = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&SigDBCert->SignatureType, &gEfiCertX509Guid);
+
+ SigDBCertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigDBCert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&SigDBCertData->SignatureOwner, &gOwnerSignatureGUID);
+ CopyMem ((UINT8 *) (SigDBCertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **) &Data);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable(
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EnrollSignatureDatabase (
+ IN CHAR16 *VariableName,
+ IN VOID *DataBuf,
+ IN UINTN BufSize
+ )
+{
+ return EnrollX509toSigDB (VariableName, DataBuf, BufSize);
+}
+
+
+/**
+ Function to Load Secure Keys given the binary GUID
+
+ @param[in] VendorGuid GUID of the Variable.
+ @param[in] VariableName Name of the Variable.
+ @param[in] VendorGuid GUID of the Variable.
+
+ @retval EFI_SUCCESS Set the variable successfully.
+ @retval Others Set variable failed.
+
+**/
+EFI_STATUS
+SetSecureVariabeKeys (
+ IN EFI_GUID *ImageGuid,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ UINTN FvProtocolCount;
+ EFI_HANDLE *FvHandles;
+ UINTN Index1;
+ UINT32 AuthenticationStatus;
+ UINT8 *Buffer=NULL;
+ UINTN BufferSize=0;
+ UINT32 Attr;
+
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ FvHandles = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &FvProtocolCount,
+ &FvHandles
+ );
+
+ if (!EFI_ERROR (Status)) {
+ for (Index1 = 0; Index1 < FvProtocolCount; Index1++) {
+ Status = gBS->HandleProtocol (
+ FvHandles[Index1],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+ BufferSize= 0;
+
+ Status = Fv->ReadSection (
+ Fv,
+ ImageGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **) &Buffer,
+ &BufferSize,
+ &AuthenticationStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ if (Buffer == NULL)
+ return EFI_UNSUPPORTED;
+ if (StrCmp (VariableName, L"PK") == 0){
+ Status = EnrollPlatformKey (Buffer, BufferSize);
+ } else if (StrCmp (VariableName, L"KEK") == 0) {
+ Status = EnrollKeyExchangeKey (Buffer, BufferSize);
+ } else if (CompareGuid (ImageGuid, &gDbxUpdateImageGuid)) {
+ Status = EnrollKeyForbiddenSignatureDatabase (VariableName,Buffer, BufferSize);
+ } else {
+ Status = EnrollSignatureDatabase (VariableName, Buffer, BufferSize);
+ }
+ return Status;
+}
+
+
+/**
+ Internal function to Update User Mode to Setup Mode given its name and GUID, no authentication
+ required.
+
+ @param[in] VariableName Name of the Variable.
+ @param[in] VendorGuid GUID of the Variable.
+
+ @retval EFI_SUCCESS Updated to Setup Mode successfully.
+ @retval Others The driver failed to start the device.
+
+**/
+EFI_STATUS
+UpdateSetupModetoUserMode (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID* Variable;
+ UINT8 SetupMode;
+ UINT8 SecureBootEnable;
+
+ SetupMode = 0;
+ SecureBootEnable = 1;
+
+ GetVariable2 (VariableName, VendorGuid, &Variable, NULL);
+ if (Variable == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 1,
+ &SetupMode
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = gRT->SetVariable (
+ EFI_SECURE_BOOT_ENABLE_NAME,
+ &gEfiSecureBootEnableDisableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &SecureBootEnable
+ );
+ }
+ return Status;
+}
+
+
+/**
+ Enrolls PK, KEK, Db and Dbx.
+
+ Note: Setup variable uses UEFI Runtime Services.
+ Do not call this function from PEI.
+
+**/
+VOID
+EnrollKeys (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 SecureBootCstMde;
+ UINTN DataSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VarSize;
+
+ EFI_GUID KekImageGuid = { 0x5d354a1f, 0x98d7, 0x4938, 0x8f, 0x18, 0xf8, 0x4e, 0x1c, 0x89, 0xb2, 0xed };
+ EFI_GUID Db1ImageGuid = { 0x4de09060, 0x5864, 0x471a, 0xb3, 0x52, 0xd4, 0x50, 0x6e, 0xd7, 0xbb, 0xb0 };
+ EFI_GUID DbxImageGuid = { 0x96b44e98, 0x6c49, 0x4c03, 0xa8, 0xa4, 0x77, 0x93, 0xef, 0x41, 0x68, 0x5a };
+ EFI_GUID PkImageGuid = { 0xc43024ad, 0x8cb8, 0x4393, 0x8a, 0xe1, 0xf3, 0x5c, 0xbf, 0xc7, 0xcd, 0x56 };
+ EFI_GUID Db2ImageGuid = { 0x0f97c7a2, 0xba0c, 0x4e8a, 0x90, 0xf9, 0xb1, 0xcc, 0x40, 0x57, 0x01, 0xf8 };
+ EFI_GUID Db3ImageGuid = { 0x774491b2, 0x85ff, 0x47b0, 0x89, 0xa4, 0xcc, 0xd8, 0xb3, 0x99, 0xaa, 0xd4 };
+ EFI_GUID Kek2ImageGuid = { 0xE989363D, 0x449F, 0x4b32, 0x96, 0xB0, 0xB2, 0x71, 0x73, 0x44, 0xD0, 0xEE };
+ EFI_GUID Db4ImageGuid = { 0xB69B054C, 0x7EA4, 0x4f13, 0xB7, 0xFF, 0x72, 0xC6, 0x32, 0x3B, 0xC8, 0x5A };
+ EFI_GUID Db5ImageGuid = { 0xB8FA2839, 0xE0C1, 0x4368, 0xA5, 0x1B, 0x5F, 0x4A, 0x21, 0x74, 0x61, 0x29 };
+ EFI_GUID Db6ImageGuid = { 0x758FBB84, 0xEF4C, 0x4acf, 0xB1, 0xA6, 0xE8, 0x44, 0xD5, 0xFF, 0x6B, 0xA6 };
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Enroll Key Exchange Key
+ //
+ SetSecureVariabeKeys (&KekImageGuid, EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid);
+ if (!(SystemConfiguration.UseProductKey)) {
+ SetSecureVariabeKeys (&Kek2ImageGuid, EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid);
+ //
+ // Enroll Authenticated database.
+ //
+ SetSecureVariabeKeys (&Db1ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ SetSecureVariabeKeys (&Db4ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ SetSecureVariabeKeys (&Db5ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ SetSecureVariabeKeys (&Db6ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ //
+ // Enroll Platform Key - 219_Microsoft_UEFI_Logo_Test_KEK.cer for WOS and common_PK.x509.cer for AOS
+ //
+ SetSecureVariabeKeys (&PkImageGuid, EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);
+ } else {
+ //
+ // Enroll Platform Key - KEK_MSFTproductionKekCA.cer
+ //
+ SetSecureVariabeKeys (&KekImageGuid, EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);
+ }
+ SetSecureVariabeKeys (&Db2ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ SetSecureVariabeKeys (&Db3ImageGuid, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ //
+ //Enroll Forbidden Database
+ //
+ SetSecureVariabeKeys (&DbxImageGuid, EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid);
+ SetSecureVariabeKeys (&gDbxUpdateImageGuid, EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid);
+
+ //
+ // If secure boot mode in custom mode, change to standard mode.
+ //
+ Status = gRT->GetVariable (
+ EFI_CUSTOM_MODE_NAME,
+ &gEfiCustomModeEnableGuid,
+ NULL,
+ &DataSize,
+ &SecureBootCstMde
+ );
+
+ if (SecureBootCstMde) {
+ SecureBootCstMde = !SecureBootCstMde;
+ Status = gRT->SetVariable (
+ EFI_CUSTOM_MODE_NAME,
+ &gEfiCustomModeEnableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &SecureBootCstMde
+ );
+ }
+}
+
+
+/**
+ Internal function to delete a Variable given its name and GUID, no authentication
+ required.
+
+ @param[in] VariableName Name of the Variable.
+ @param[in] VendorGuid GUID of the Variable.
+
+ @retval EFI_SUCCESS Variable deleted successfully.
+ @retval Others The driver failed to start the device.
+
+**/
+EFI_STATUS
+DeleteVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID* Variable;
+ UINT8 *Data;
+ UINTN DataSize;
+ UINT32 Attr;
+
+ GetVariable2 (VariableName, VendorGuid, &Variable, NULL);
+ if (Variable == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Data = NULL;
+ DataSize = 0;
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ Status = CreateTimeBasedPayload (&DataSize, &Data);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attr,
+ DataSize,
+ Data
+ );
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+ return Status;
+}
+
+
+/**
+ Internal function to Update User Mode to Setup Mode given its name and GUID, no authentication
+ required.
+
+ @param[in] VariableName Name of the Variable.
+ @param[in] VendorGuid GUID of the Variable.
+
+ @retval EFI_SUCCESS Updated to Setup Mode successfully.
+ @retval Others The driver failed to start the device.
+
+**/
+EFI_STATUS
+UpdateUserModetoSetupMode (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID* Variable;
+ UINT8 SetupMode;
+ UINT8 SecureBootDisable;
+
+ SetupMode = 1;
+ SecureBootDisable = 0;
+
+ GetVariable2 (VariableName, VendorGuid, &Variable, NULL);
+ if (Variable == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 1,
+ &SetupMode
+ );
+
+ if (!EFI_ERROR (Status)) {
+ GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &Variable, NULL);
+ Status = gRT->SetVariable (
+ EFI_SECURE_BOOT_ENABLE_NAME,
+ &gEfiSecureBootEnableDisableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &SecureBootDisable
+ );
+ }
+ return Status;
+}
+
+
+/**
+ Deletes PK, KEK, Db and Dbx.
+
+**/
+VOID
+DeleteKeys (
+ )
+{
+ //
+ // 1. Clear PK.
+ //
+ DeleteVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);
+
+ //
+ // 2. Update "SetupMode" variable to SETUP_MODE.
+ //
+ UpdateUserModetoSetupMode (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid);
+
+ //
+ // 3. Clear KEK, DB and DBX.
+ //
+ DeleteVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid);
+ DeleteVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);
+ DeleteVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid);
+}
+
+
+/**
+ Enable Custom Mode.
+
+**/
+ VOID
+ EnableCustomMode (
+ )
+{
+ UINT8 CustomMode;
+ EFI_STATUS Status;
+
+ CustomMode = 1;
+
+ Status = gRT->SetVariable (
+ EFI_CUSTOM_MODE_NAME,
+ &gEfiCustomModeEnableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &CustomMode
+ );
+
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.inf
new file mode 100644
index 0000000000..72a001daf7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformSecureDefaultsLib/PlatformSecureDefaultsLib.inf
@@ -0,0 +1,69 @@
+## @file
+# NULL PlatformFvbLib library instance.
+# This library handles hooks for the EMU Variable FVB driver.
+#
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformSecureDefaultsLib
+ FILE_GUID = 402B0508-781A-4016-A1D7-9740FFE001A0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecureDefaultsLib | DXE_DRIVER DXE_RUNTIME_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ PlatformSecureDefaultsLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DxeServicesTableLib
+ UefiBootServicesTableLib
+ DevicePathLib
+ BaseMemoryLib
+ BaseLib
+ IoLib
+ TimerLib
+ MemoryAllocationLib
+ PcdLib
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid
+
+[Guids]
+ gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
+ gEfiSetupVariableGuid
+ gEfiVariableGuid
+ gEfiImageSecurityDatabaseGuid
+ gEfiCertX509Guid
+ gEfiCertPkcs7Guid
+ gEfiCustomModeEnableGuid
+
+[Depex]
+ TRUE
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.c
new file mode 100644
index 0000000000..276a5dd7ca
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.c
@@ -0,0 +1,47 @@
+/** @file
+ A Base Timer Library implementation which uses the Time Stamp Counter in the processor.
+
+ For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and higher]);
+ for Intel Core Solo and Intel Core Duo processors (family [06H], model [0EH]);
+ for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors (family [06H], model [0FH]);
+ for Intel Core 2 and Intel Xeon processors (family [06H], display_model [17H]);
+ for Intel Atom processors (family [06H], display_model [1CH]):
+ the time-stamp counter increments at a constant rate.
+ That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by
+ the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may
+ differ from the maximum qualified frequency of the processor.
+
+ The specific processor configuration determines the behavior. Constant TSC behavior ensures that the
+ duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if
+ the processor core changes frequency. This is the architectural behavior moving forward.
+
+ A Processor's support for invariant TSC is indicated by CPUID.0x80000007.EDX[8].
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TscTimerLibInternal.h"
+
+/**
+ Get TSC frequency.
+
+ @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalGetTscFrequency (
+ VOID
+ )
+{
+ return InternalCalculateTscFrequency ();
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.inf
new file mode 100644
index 0000000000..8f4d366632
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/BaseTscTimerLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Base Timer Library which uses the Time Stamp Counter in the processor.
+#
+# Note: There will be 1ms penalty to get TSC frequency every time
+# by waiting for 3579 clocks of the ACPI timer, or 1ms.
+#
+# Note: This library is a sample implementation that depends on chipset ACPI timer.
+# It may not work on new generation chipset. PcAtChipsetPkg AcpiTimerLib is
+# the generic timer library that can replace this one.
+#
+# A version of the Timer Library using the processor's TSC.
+# The time stamp counter in newer processors may support an enhancement, referred to as invariant TSC.
+# The invariant TSC runs at a constant rate in all ACPI P-, C-. and T-states.
+# This is the architectural behavior moving forward.
+# TSC reads are much more efficient and do not incur the overhead associated with a ring transition or
+# access to a platform resource.
+#
+# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseTscTimerLib
+ FILE_GUID = D29338B9-50FE-4e4f-B7D4-A150A2C1F4FB
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ TscTimerLibShare.c
+ BaseTscTimerLib.c
+ TscTimerLibInternal.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PerformancePkg/PerformancePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BxtPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciLib
+ IoLib
+ BaseLib
+
+[Pcd.common]
+ gPerformancePkgTokenSpaceGuid.PcdPerfPkgAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.c
new file mode 100644
index 0000000000..4e90f4eaea
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.c
@@ -0,0 +1,105 @@
+/** @file
+ A Dxe Timer Library implementation which uses the Time Stamp Counter in the processor.
+
+ For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and higher]);
+ for Intel Core Solo and Intel Core Duo processors (family [06H], model [0EH]);
+ for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors (family [06H], model [0FH]);
+ for Intel Core 2 and Intel Xeon processors (family [06H], display_model [17H]);
+ for Intel Atom processors (family [06H], display_model [1CH]):
+ the time-stamp counter increments at a constant rate.
+ That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by
+ the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may
+ differ from the maximum qualified frequency of the processor.
+
+ The specific processor configuration determines the behavior. Constant TSC behavior ensures that the
+ duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if
+ the processor core changes frequency. This is the architectural behavior moving forward.
+
+ A Processor's support for invariant TSC is indicated by CPUID.0x80000007.EDX[8].
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/TscFrequency.h>
+#include "TscTimerLibInternal.h"
+
+UINT64 mTscFrequency;
+
+
+/** The constructor function determines the actual TSC frequency.
+
+ First, Get TSC frequency from system configuration table with TSC frequency GUID,
+ if the table is not found, install it.
+ This function will always return EFI_SUCCESS.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeTscTimerLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT64 *TscFrequency;
+
+ TscFrequency = NULL;
+ //
+ // Get TSC frequency from system configuration table with TSC frequency GUID.
+ //
+ Status = EfiGetSystemConfigurationTable (&gEfiTscFrequencyGuid, (VOID **) &TscFrequency);
+ if (Status == EFI_SUCCESS) {
+ ASSERT (TscFrequency != NULL);
+ mTscFrequency = *TscFrequency;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // TSC frequency GUID system configuration table is not found, install it.
+ //
+
+ Status = gBS->AllocatePool (EfiBootServicesData, sizeof (UINT64), (VOID **) &TscFrequency);
+ ASSERT_EFI_ERROR (Status);
+
+ *TscFrequency = InternalCalculateTscFrequency ();
+ //
+ // TscFrequency now points to the number of TSC counts per second, install system configuration table for it.
+ //
+ gBS->InstallConfigurationTable (&gEfiTscFrequencyGuid, TscFrequency);
+
+ mTscFrequency = *TscFrequency;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get TSC frequency.
+
+ @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalGetTscFrequency (
+ VOID
+ )
+{
+ return mTscFrequency;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.inf
new file mode 100644
index 0000000000..a2ff9d05dd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/DxeTscTimerLib.inf
@@ -0,0 +1,66 @@
+## @file
+# Dxe Timer Library which uses the Time Stamp Counter in the processor.
+#
+# Note: This library is a sample implementation that depends on chipset ACPI timer.
+# It may not work on new generation chipset. PcAtChipsetPkg AcpiTimerLib is
+# the generic timer library that can replace this one.
+#
+# A version of the Timer Library using the processor's TSC.
+# The time stamp counter in newer processors may support an enhancement, referred to as invariant TSC.
+# The invariant TSC runs at a constant rate in all ACPI P-, C-. and T-states.
+# This is the architectural behavior moving forward.
+# TSC reads are much more efficient and do not incur the overhead associated with a ring transition or
+# access to a platform resource.
+#
+# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeTscTimerLib
+ FILE_GUID = 95ab030f-b4fd-4ee4-92a5-9e04e87634d9
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
+ CONSTRUCTOR = DxeTscTimerLibConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ TscTimerLibShare.c
+ DxeTscTimerLib.c
+ TscTimerLibInternal.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PerformancePkg/PerformancePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ PcdLib
+ PciLib
+ IoLib
+ BaseLib
+ UefiLib
+ DebugLib
+
+[Guids]
+ gEfiTscFrequencyGuid ## CONSUMES ## SystemTable
+
+[Pcd.common]
+ gPerformancePkgTokenSpaceGuid.PcdPerfPkgAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.c
new file mode 100644
index 0000000000..caf1925748
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.c
@@ -0,0 +1,79 @@
+/** @file
+ A Pei Timer Library implementation which uses the Time Stamp Counter in the processor.
+
+ For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and higher]);
+ for Intel Core Solo and Intel Core Duo processors (family [06H], model [0EH]);
+ for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors (family [06H], model [0FH]);
+ for Intel Core 2 and Intel Xeon processors (family [06H], display_model [17H]);
+ for Intel Atom processors (family [06H], display_model [1CH]):
+ the time-stamp counter increments at a constant rate.
+ That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by
+ the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may
+ differ from the maximum qualified frequency of the processor.
+
+ The specific processor configuration determines the behavior. Constant TSC behavior ensures that the
+ duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if
+ the processor core changes frequency. This is the architectural behavior moving forward.
+
+ A Processor's support for invariant TSC is indicated by CPUID.0x80000007.EDX[8].
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Guid/TscFrequency.h>
+#include "TscTimerLibInternal.h"
+
+
+/**
+ Get TSC frequency from TSC frequency GUID HOB, if the HOB is not found, build it.
+
+ @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalGetTscFrequency (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ UINT64 TscFrequency;
+
+ //
+ // Get TSC frequency from TSC frequency GUID HOB.
+ //
+ GuidHob = GetFirstGuidHob (&gEfiTscFrequencyGuid);
+ if (GuidHob != NULL) {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ TscFrequency = *(UINT64 *) DataInHob;
+ return TscFrequency;
+ }
+
+ //
+ // TSC frequency GUID HOB is not found, build it.
+ //
+ TscFrequency = InternalCalculateTscFrequency ();
+
+ //
+ // TscFrequency is now equal to the number of TSC counts per second, build GUID HOB for it.
+ //
+ BuildGuidDataHob (
+ &gEfiTscFrequencyGuid,
+ &TscFrequency,
+ sizeof (UINT64)
+ );
+
+ return TscFrequency;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.inf
new file mode 100644
index 0000000000..0821983139
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/PeiTscTimerLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Pei Timer Library which uses the Time Stamp Counter in the processor.
+#
+# Note: This library is a sample implementation that depends on chipset ACPI timer.
+# It may not work on new generation chipset. PcAtChipsetPkg AcpiTimerLib is
+# the generic timer library that can replace this one.
+#
+# A version of the Timer Library using the processor's TSC.
+# The time stamp counter in newer processors may support an enhancement, referred to as invariant TSC.
+# The invariant TSC runs at a constant rate in all ACPI P-, C-. and T-states.
+# This is the architectural behavior moving forward.
+# TSC reads are much more efficient and do not incur the overhead associated with a ring transition or
+# access to a platform resource.
+#
+# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiTscTimerLib
+ FILE_GUID = 342C36C0-15DF-43b4-9EC9-FBF748BFB3D1
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib|PEIM PEI_CORE
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ TscTimerLibShare.c
+ PeiTscTimerLib.c
+ TscTimerLibInternal.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PerformancePkg/PerformancePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciLib
+ IoLib
+ BaseLib
+ HobLib
+
+[Guids]
+ gEfiTscFrequencyGuid ## PRODUCES ## HOB
+
+[Pcd.common]
+ gPerformancePkgTokenSpaceGuid.PcdPerfPkgAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibInternal.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibInternal.h
new file mode 100644
index 0000000000..99f6fcdee4
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibInternal.h
@@ -0,0 +1,58 @@
+/** @file
+ Internal header file for TscTimerLib instances.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _TSC_TIMER_LIB_INTERNAL_H_
+#define _TSC_TIMER_LIB_INTERNAL_H_
+
+#include <Ich/GenericIch.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ Get TSC frequency.
+
+ @retval The number of TSC counts per second.
+
+**/
+UINT64
+InternalGetTscFrequency (
+ VOID
+ );
+
+/**
+ Calculate TSC frequency.
+
+ The TSC counting frequency is determined by comparing how far it counts
+ during a 1ms period as determined by the ACPI timer. The ACPI timer is
+ used because it counts at a known frequency.
+ If ACPI I/O space not enabled, this function will enable it. Then the
+ TSC is sampled, followed by waiting for 3579 clocks of the ACPI timer, or 1ms.
+ The TSC is then sampled again. The difference multiplied by 1000 is the TSC
+ frequency. There will be a small error because of the overhead of reading
+ the ACPI timer. An attempt is made to determine and compensate for this error.
+
+ @retval The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+ VOID
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibShare.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibShare.c
new file mode 100644
index 0000000000..c064449d26
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformTscTimerLib/TscTimerLibShare.c
@@ -0,0 +1,283 @@
+/** @file
+ The Timer Library implementation which uses the Time Stamp Counter in the processor.
+
+ For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and higher]);
+ for Intel Core Solo and Intel Core Duo processors (family [06H], model [0EH]);
+ for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors (family [06H], model [0FH]);
+ for Intel Core 2 and Intel Xeon processors (family [06H], display_model [17H]);
+ for Intel Atom processors (family [06H], display_model [1CH]):
+ the time-stamp counter increments at a constant rate.
+ That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by
+ the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may
+ differ from the maximum qualified frequency of the processor.
+
+ The specific processor configuration determines the behavior. Constant TSC behavior ensures that the
+ duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if
+ the processor core changes frequency. This is the architectural behavior moving forward.
+
+ A Processor's support for invariant TSC is indicated by CPUID.0x80000007.EDX[8].
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TscTimerLibInternal.h"
+
+/**
+ Calculate TSC frequency.
+
+ The TSC counting frequency is determined by comparing how far it counts
+ during a 1ms period as determined by the ACPI timer. The ACPI timer is
+ used because it counts at a known frequency.
+ If ACPI I/O space not enabled, this function will enable it. Then the
+ TSC is sampled, followed by waiting for 3579 clocks of the ACPI timer, or 1ms.
+ The TSC is then sampled again. The difference multiplied by 1000 is the TSC
+ frequency. There will be a small error because of the overhead of reading
+ the ACPI timer. An attempt is made to determine and compensate for this error.
+
+ @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+ VOID
+ )
+{
+ UINT64 StartTSC;
+ UINT64 EndTSC;
+ UINT32 TimerAddr;
+ UINT32 Ticks;
+ UINT64 TscFrequency;
+
+ //
+ // ACPI I/O space should be enabled now, locate the ACPI Timer.
+ // ACPI I/O base address maybe have be initialized by other driver with different value,
+ // So get it from PCI space directly.
+ //
+ TimerAddr = PcdGet16 (PcdScAcpiIoPortBaseAddress) + R_ACPI_PM1_TMR;
+ Ticks = IoRead32 (TimerAddr) + (3579); // Set Ticks to 1ms in the future
+ StartTSC = AsmReadTsc (); // Get base value for the TSC
+ //
+ // Wait until the ACPI timer has counted 1ms.
+ // Timer wrap-arounds are handled correctly by this function.
+ // When the current ACPI timer value is greater than 'Ticks', the while loop will exit.
+ //
+ while (((Ticks - IoRead32 (TimerAddr)) & BIT23) == 0) {
+ CpuPause ();
+ }
+ EndTSC = AsmReadTsc (); // TSC value 1ms later
+
+ TscFrequency = MultU64x32 (
+ (EndTSC - StartTSC), // Number of TSC counts in 1ms
+ 1000 // Number of ms in a second
+ );
+
+ return TscFrequency;
+}
+
+
+/**
+ Stalls the CPU for at least the given number of ticks.
+
+ Stalls the CPU for at least the given number of ticks. It's invoked by
+ MicroSecondDelay() and NanoSecondDelay().
+
+ @param[in] Delay A period of time to delay in ticks.
+
+**/
+VOID
+InternalX86Delay (
+ IN UINT64 Delay
+ )
+{
+ UINT64 Ticks;
+
+ //
+ // The target timer count is calculated here
+ //
+ Ticks = AsmReadTsc () + Delay;
+
+ //
+ // Wait until time out
+ // Timer wrap-arounds are NOT handled correctly by this function.
+ // Thus, this function must be called within 10 years of reset since
+ // Intel guarantees a minimum of 10 years before the TSC wraps.
+ //
+ while (AsmReadTsc () <= Ticks) CpuPause ();
+}
+
+
+/**
+ Stalls the CPU for at least the specified number of MicroSeconds.
+
+ @param[in] MicroSeconds The minimum number of microseconds to delay.
+
+ @return The value of MicroSeconds input.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ InternalX86Delay (
+ DivU64x32 (
+ MultU64x64 (
+ InternalGetTscFrequency (),
+ MicroSeconds
+ ),
+ 1000000u
+ )
+ );
+
+ return MicroSeconds;
+}
+
+
+/**
+ Stalls the CPU for at least the specified number of NanoSeconds.
+
+ @param[in] NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return The value of NanoSeconds input.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ InternalX86Delay (
+ DivU64x32 (
+ MultU64x32 (
+ InternalGetTscFrequency (),
+ (UINT32) NanoSeconds
+ ),
+ 1000000000u
+ )
+ );
+
+ return NanoSeconds;
+}
+
+
+/**
+ Retrieves the current value of the 64-bit free running Time-Stamp counter.
+
+ The time-stamp counter (as implemented in the P6 family, Pentium, Pentium M,
+ Pentium 4, Intel Xeon, Intel Core Solo and Intel Core Duo processors and
+ later processors) is a 64-bit counter that is set to 0 following a RESET of
+ the processor. Following a RESET, the counter increments even when the
+ processor is halted by the HLT instruction or the external STPCLK# pin. Note
+ that the assertion of the external DPSLP# pin may cause the time-stamp
+ counter to stop.
+
+ The properties of the counter can be retrieved by the
+ GetPerformanceCounterProperties() function.
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ return AsmReadTsc();
+}
+
+
+/**
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with, 0x0, is returned in StartValue. If EndValue is not NULL, then the value
+ that the performance counter end with, 0xFFFFFFFFFFFFFFFF, is returned in
+ EndValue.
+
+ The 64-bit frequency of the performance counter, in Hz, is always returned.
+ To determine average processor clock frequency, Intel recommends the use of
+ EMON logic to count processor core clocks over the period of time for which
+ the average is required.
+
+
+ @param[out] StartValue Pointer to where the performance counter's starting value is saved, or NULL.
+ @param[out] EndValue Pointer to where the performance counter's ending value is saved, or NULL.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+ if (StartValue != NULL) {
+ *StartValue = 0;
+ }
+ if (EndValue != NULL) {
+ *EndValue = 0xFFFFFFFFFFFFFFFFull;
+ }
+
+ return InternalGetTscFrequency ();
+}
+
+
+/**
+ Converts elapsed ticks of performance counter to time in nanoseconds.
+
+ This function converts the elapsed ticks of running performance counter to
+ time value in unit of nanoseconds.
+
+ @param[in] Ticks The number of elapsed ticks of running performance counter.
+
+ @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+ IN UINT64 Ticks
+ )
+{
+ UINT64 Frequency;
+ UINT64 NanoSeconds;
+ UINT64 Remainder;
+ INTN Shift;
+
+ Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+ //
+ // Ticks
+ // Time = --------- x 1,000,000,000
+ // Frequency
+ //
+ NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+ //
+ // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+ // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+ // i.e. highest bit set in Remainder should <= 33.
+ //
+ Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+ Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+ Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+ NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+ return NanoSeconds;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.c b/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..02b16e8928
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,150 @@
+/** @file
+ System reset Library Services. This library class provides a set of
+ methods to reset whole system by manipulating SC registers.
+
+ Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/ResetSystemLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "ScRegs.h"
+
+#define RESET_GENERATOR_PORT 0xCF9
+
+
+/**
+ Calling this function causes a system-wide reset. This sets
+ all circuitry within the system to its initial state. This type of reset
+ is asynchronous to system operation and operates without regard to
+ cycle boundaries.
+
+ System reset should not return, if it returns, it means the system does
+ not support cold reset.
+
+**/
+VOID
+EFIAPI
+ResetCold (
+ VOID
+ )
+{
+ IoWrite8 (RESET_GENERATOR_PORT, 0x2);
+ IoWrite8 (RESET_GENERATOR_PORT, 0xE);
+}
+
+
+/**
+ Calling this function causes a system-wide initialization. The processors
+ are set to their initial state, and pending cycles are not corrupted.
+
+ System reset should not return, if it returns, it means the system does
+ not support warm reset.
+
+**/
+VOID
+EFIAPI
+ResetWarm (
+ VOID
+ )
+{
+ IoWrite8 (RESET_GENERATOR_PORT, 0x0);
+ IoWrite8 (RESET_GENERATOR_PORT, 0x6);
+}
+
+
+/**
+ Calling this function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ System shutdown should not return, if it returns, it means the system does
+ not support shut down reset.
+
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ UINT16 AcpiBaseAddr;
+ UINT16 Data16;
+ UINT32 Data32;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+ //
+ Data16 = 0;
+ IoWrite16 (
+ (UINTN) (AcpiBaseAddr + R_ACPI_GPE0a_EN),
+ (UINT16) Data16
+ );
+
+ //
+ // Secondly, PwrSts register must be cleared
+ //
+ // Write a "1" to bit[8] of power button status register at
+ // (ABASE + R_ACPI_PM1_STS) to clear this bit
+ //
+ Data16 = B_ACPI_PM1_STS_PWRBTN;
+ IoWrite16 (
+ (UINTN) (AcpiBaseAddr + R_ACPI_PM1_STS),
+ (UINT16) Data16
+ );
+
+ //
+ // Finally, transform system into S5 sleep state
+ //
+ Data32 = IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_PM1_CNT));
+ Data32 = (UINT32) ((Data32 & ~(B_ACPI_PM1_CNT_SLP_TYP + B_ACPI_PM1_CNT_SLP_EN)) | V_ACPI_PM1_CNT_S5);
+
+ IoWrite32 (
+ (UINTN) (AcpiBaseAddr + R_ACPI_PM1_CNT),
+ (UINT32) Data32
+ );
+
+ Data32 = Data32 | B_ACPI_PM1_CNT_SLP_EN;
+
+ IoWrite32 (
+ (UINTN) (AcpiBaseAddr + R_ACPI_PM1_CNT),
+ (UINT32) Data32
+ );
+
+ return;
+}
+
+
+/**
+ Calling this function causes the system to enter a power state for capsule
+ update.
+
+ Reset update should not return, if it returns, it means the system does
+ not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..4cb3057d9a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Reset System Library that layers on top of the I/O Library to directly
+# access a standard SMBUS host controller.
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ResetSystemLib
+ FILE_GUID = D4FF05AA-3C7D-4b8a-A1EE-AA5EFA0B1732
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ResetSystemLib
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources.common]
+ ResetSystemLib.c
+
+[Packages]
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ IoLib
+ BaseLib
+ DebugLib
+ PciLib
+ PcdLib
+
+[Pcd]
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress ## CONSUMES
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/CommonHeader.h b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/CommonHeader.h
new file mode 100644
index 0000000000..29369a4024
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/CommonHeader.h
@@ -0,0 +1,29 @@
+/** @file
+ Common header file shared by all source files.
+ This file includes package header files, library classes.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <Base.h>
+#include <ScAccess.h>
+#include <Library/SmbusLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.c b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.c
new file mode 100644
index 0000000000..0617885291
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.c
@@ -0,0 +1,565 @@
+/** @file
+ Intel ICH9 SMBUS library implementation built upon I/O library.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+
+/**
+ Acquires the ownership of SMBUS.
+
+ This internal function reads the host state register.
+ If the SMBUS is not available, RETURN_TIMEOUT is returned;
+ Otherwise, it performs some basic initializations and returns
+ RETURN_SUCCESS.
+
+ @param IoPortBaseAddress The Io port base address of Smbus Host controller.
+
+ @retval RETURN_SUCCESS The SMBUS command was executed successfully.
+ @retval RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+
+**/
+RETURN_STATUS
+InternalSmBusAcquire (
+ UINTN IoPortBaseAddress
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Starts the SMBUS transaction and waits until the end.
+
+ This internal function start the SMBUS transaction and waits until the transaction
+ of SMBUS is over by polling the INTR bit of Host status register.
+ If the SMBUS is not available, RETURN_TIMEOUT is returned;
+ Otherwise, it performs some basic initializations and returns
+ RETURN_SUCCESS.
+
+ @param[in] IoPortBaseAddress The Io port base address of Smbus Host controller.
+ @param[in] HostControl The Host control command to start SMBUS transaction.
+
+ @retval RETURN_SUCCESS The SMBUS command was executed successfully.
+ @retval RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect).
+ @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
+ in the Host Status Register bit. Device errors are
+ a result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+
+**/
+RETURN_STATUS
+InternalSmBusStart (
+ IN UINTN IoPortBaseAddress,
+ IN UINT8 HostControl
+ )
+{
+
+ return RETURN_DEVICE_ERROR;
+}
+
+
+/**
+ Executes an SMBUS quick, byte or word command.
+
+ This internal function executes an SMBUS quick, byte or word commond.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+
+ @param[in] HostControl The value of Host Control Register to set.
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] Value The byte/word write to the SMBUS.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The byte/word read from the SMBUS.
+
+**/
+UINT16
+InternalSmBusNonBlock (
+ IN UINT8 HostControl,
+ IN UINTN SmBusAddress,
+ IN UINT16 Value,
+ OUT RETURN_STATUS *Status
+ )
+{
+ return Value;
+}
+
+
+/**
+ Executes an SMBUS quick read command.
+ Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If PEC is set in SmBusAddress, then ASSERT().
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+}
+
+
+/**
+ Executes an SMBUS quick write command.
+ Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If PEC is set in SmBusAddress, then ASSERT().
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+}
+
+
+/**
+ Executes an SMBUS receive byte command.
+ Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ The byte received from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT8 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS send byte command.
+ Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+ The byte specified by Value is sent.
+ Only the SMBUS slave address field of SmBusAddress is required. Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] Value The 8-bit value to send.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+ IN UINTN SmBusAddress,
+ IN UINT8 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT8 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS read data byte command.
+ Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 8-bit value read from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT8 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS write data byte command.
+ Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+ The 8-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] Value The 8-bit value to write.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+ IN UINTN SmBusAddress,
+ IN UINT8 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT8 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS read data word command.
+ Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 16-bit value read from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT16 ValueReturn = 0;
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS write data word command.
+ Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+ The 16-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] Value The 16-bit value to write.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+ IN UINTN SmBusAddress,
+ IN UINT16 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT16 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+
+/**
+ Executes an SMBUS process call command.
+ Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+ The 16-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 16-bit value returned by the process call command is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] Value The 16-bit value to write.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+ IN UINTN SmBusAddress,
+ IN UINT16 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINT16 ValueReturn = 0;
+
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return ValueReturn;
+}
+
+/**
+ Executes an SMBUS block command.
+ Executes an SMBUS block read, block write and block write-block read command
+ on the SMBUS device specified by SmBusAddress.
+ Bytes are read from the SMBUS and stored in Buffer.
+ The number of bytes read is returned, and will never return a value larger than 32-bytes.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+ SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+
+ @param[in] HostControl The value of Host Control Register to set.
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] WriteBuffer Pointer to the buffer of bytes to write to the SMBUS.
+ @param[out] ReadBuffer Pointer to the buffer of bytes to read from the SMBUS.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The number of bytes read from the SMBUS.
+
+**/
+UINTN
+InternalSmBusBlock (
+ IN UINT8 HostControl,
+ IN UINTN SmBusAddress,
+ IN UINT8 *WriteBuffer,
+ OUT UINT8 *ReadBuffer,
+ OUT RETURN_STATUS *Status
+ )
+{
+ UINTN BytesCount;
+
+ BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
+
+ return BytesCount;
+}
+
+
+/**
+ Executes an SMBUS read block command.
+ Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Bytes are read from the SMBUS and stored in Buffer.
+ The number of bytes read is returned, and will never return a value larger than 32-bytes.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+ SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Buffer Pointer to the buffer to store the bytes read from the SMBUS.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINTN BytesCount = 0;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return BytesCount;
+}
+
+
+/**
+ Executes an SMBUS write block command.
+ Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+ The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+ Bytes are written to the SMBUS from Buffer.
+ The number of bytes written is returned, and will never return a value larger than 32-bytes.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Buffer Pointer to the buffer to store the bytes read from the SMBUS.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINTN BytesCount = 0;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return BytesCount;
+}
+
+
+/**
+ Executes an SMBUS block process call command.
+ Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+ The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+ Bytes are written to the SMBUS from WriteBuffer. Bytes are then read from the SMBUS into ReadBuffer.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+ SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+ If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+ If WriteBuffer is NULL, then ASSERT().
+ If ReadBuffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[in] WriteBuffer Pointer to the buffer of bytes to write to the SMBUS.
+ @param[out] ReadBuffer Pointer to the buffer of bytes to read from the SMBUS.
+ @param[out] Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+
+ @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+ IN UINTN SmBusAddress,
+ IN VOID *WriteBuffer,
+ OUT VOID *ReadBuffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ UINTN BytesCount = 0;
+
+ ASSERT (WriteBuffer != NULL);
+ ASSERT (ReadBuffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+ return BytesCount;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.inf
new file mode 100644
index 0000000000..e4f66a898a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/SmbusLib/SmbusLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for Intel Ich9 Smbus Library.
+#
+# SMBUS Library that layers on top of the I/O Library to directly
+# access a standard SMBUS host controller.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmbusLib
+ FILE_GUID = 0558CAEA-FEF3-4b6d-915E-8742EFE6DEE1
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SmbusLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ SmbusLib.c
+
+[Packages]
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ PcdLib
+ DebugLib
+ PciLib
+ IoLib
+
+[Pcd.common]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.c b/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.c
new file mode 100644
index 0000000000..c1a0443d47
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.c
@@ -0,0 +1,1089 @@
+/** @file
+ Performance library instance used by SMM Core.
+
+ This library provides the performance measurement interfaces and initializes performance
+ logging for the SMM phase.
+ It initializes SMM phase performance logging by publishing the SMM PerformanceEx Protocol,
+ which is consumed by SmmPerformanceLib to logging performance data in SMM phase.
+
+ This library is mainly used by SMM Core to start performance logging to ensure that
+ SMM PerformanceEx Protocol are installed at the very beginning of SMM phase.
+
+ This library also converts performance log to FPDT record, and report them to boot FPDT table.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiSmm.h>
+#include <Guid/Performance.h>
+#include <Guid/FirmwarePerformance.h>
+#include <Protocol/SmmBase2.h>
+#include <Library/DebugLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <ExtendedFirmwarePerformanceData.h>
+
+//
+// Rmpt Table Data Array to record every module table.
+//
+typedef struct {
+ VOID *Handle;
+ UINTN MaxFunctionNumber;
+ RUNTIME_MODULE_PERFORMANCE_TABLE *RmptTable;
+} RMPT_TABLE_DATA;
+
+#define RMPT_TABLE_NUMBER 40
+
+RMPT_TABLE_DATA *mRmptDataTable = NULL;
+UINTN mRmptTableNumber = 0;
+UINTN mMaxRmptTableNumber = 0;
+BOOLEAN mIsOutOfResource = FALSE;
+PERFORMANCE_EX_PROTOCOL *mPerformanceEx = NULL;
+
+//
+// The data structure to hold global performance data.
+//
+GAUGE_DATA_HEADER *mGaugeData = NULL;
+
+//
+// The current maximum number of logging entries. If current number of
+// entries exceeds this value, it will re-allocate a larger array and
+// migration the old data to the larger array.
+//
+UINT32 mMaxGaugeRecords = 0;
+BOOLEAN mPerformanceMeasurementEnabled;
+SPIN_LOCK mSmmFpdtLock;
+
+/**
+ The function caches the pointers to PerformanceEx Protocol.
+ The function locates PerformanceEx protocol from protocol database.
+
+ @retval EFI_SUCCESS PerformanceEx protocol is successfully located.
+ @retval EFI_NOT_FOUND PerformanceEx protocol is not located to log performance.
+
+**/
+EFI_STATUS
+GetPerformanceExProtocol (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PERFORMANCE_EX_PROTOCOL *PerformanceEx;
+
+ if (mPerformanceEx != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gBS->LocateProtocol (&gPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);
+ if (!EFI_ERROR (Status)) {
+ ASSERT (PerformanceEx != NULL);
+ //
+ // Cache PerformanceEx Protocol.
+ //
+ mPerformanceEx = PerformanceEx;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ Convert performance token to FPDT record.
+
+ @param[in] IsStart TRUE if the performance log is start log.
+ @param[in] Token Pointer to environment specific context used
+ to identify the component being measured.
+ @param[out] RecordType Type of FPDT record
+ @param[out] Identifier Identifier for FPDT records
+
+ @retval EFI_SUCCESS The data was converted correctly.
+ @retval EFI_NOT_FOUND No matched FPDT record is for the input Token.
+ @retval EFI_INVALID_PARAMETER Input Pointer is NULL.
+
+**/
+EFI_STATUS
+ConvertTokenToType (
+ IN BOOLEAN IsStart,
+ IN CONST CHAR8 *Token,
+ OUT UINTN *FpdtRecType,
+ OUT UINT32 *Identifier
+ )
+{
+ UINTN RecordType;
+
+ if (Token == NULL || FpdtRecType == NULL || Identifier == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RecordType = STRING_EVENT_TYPE;
+
+ //
+ // Token to Type and Id.
+ //
+ if (AsciiStrCmp (Token, START_IMAGE_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = MODULE_START_ID;
+ } else {
+ *Identifier = MODULE_END_ID;
+ }
+ } else if (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) {
+ if (IsStart) {
+ *Identifier = MODULE_LOADIMAGE_START_ID;
+ } else {
+ *Identifier = MODULE_LOADIMAGE_END_ID;
+ }
+ } else if (IsStart && AsciiStrCmp (Token, SMM_MODULE_TOK) == 0) {
+ RecordType = RUNTIME_MODULE_TABLE_PTR_TYPE;
+ } else if (!IsStart && AsciiStrCmp (Token, SMM_FUNCTION_TOK) == 0) {
+ RecordType = RUNTIME_FUNCTION_TYPE;
+ } else if (AsciiStrCmp (Token, EVENT_REC_TOK) == 0) {
+ RecordType = STRING_EVENT_TYPE;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ *FpdtRecType = RecordType;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Allocate EfiReservedMemoryType below 4G memory address.
+ This function allocates EfiReservedMemoryType below 4G memory address.
+
+ @param[in] Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+VOID *
+FpdtAllocateReservedMemoryBelow4G (
+ IN UINTN Size
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Pages = EFI_SIZE_TO_PAGES (Size);
+ Address = 0xffffffff;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+
+/**
+ Add performance log to FPDT boot record table.
+
+ @param[in] IsStart TRUE if the performance log is start log.
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] StartTicker 64-bit start ticker of start performance log.
+ @param[in] EndTicker 64-bit end ticker of end performance log.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS Add FPDT boot record.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+ @retval EFI_ABORTED No matched FPDT record.
+
+**/
+EFI_STATUS
+InsertFpdtMeasurement (
+ IN BOOLEAN IsStart,
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 StartTicker,
+ IN UINT64 EndTicker,
+ IN UINT32 Identifier
+ )
+{
+ UINTN FpdtRecType;
+ EFI_STATUS Status;
+ UINT64 Ticker;
+ UINT64 Residency;
+ UINTN Index;
+ VOID *DataBuffer;
+ UINTN RmptTableLength;
+ FPDT_RECORD FpdtRecord;
+ RUNTIME_MODULE_PERFORMANCE_TABLE *RmptTable;
+ RUNTIME_FUNCTION_PERF_RECORD *RuntimeFunctionPerfRecord;
+
+ //
+ // Convert performance log to FPDT record.
+ //
+ Status = ConvertTokenToType (IsStart, Token, &FpdtRecType, &Identifier);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FpdtRecord.RecordHeader.Length = 0;
+ if (IsStart) {
+ Ticker = StartTicker;
+ } else {
+ Ticker = EndTicker;
+ }
+
+ switch (FpdtRecType) {
+ case GUID_EVENT_TYPE:
+ case STRING_EVENT_TYPE:
+ //
+ // Can't find PerformanceEx protocol
+ //
+ Status = GetPerformanceExProtocol ();
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Log SMM Driver Load and Start Image point.
+ //
+ if (IsStart) {
+ mPerformanceEx->StartGaugeEx (Handle, Token, NULL, Ticker, Identifier);
+ } else {
+ mPerformanceEx->EndGaugeEx (Handle, Token, NULL, Ticker, Identifier);
+ }
+ break;
+
+ case RUNTIME_MODULE_TABLE_PTR_TYPE:
+ //
+ // Can't find PerformanceEx protocol
+ //
+ Status = GetPerformanceExProtocol ();
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Handle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ if (mIsOutOfResource) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Allocate Reserved buffer for SMM runtime table.
+ //
+ RmptTableLength = sizeof (RUNTIME_PERF_TABLE_HEADER) + sizeof (RUNTIME_MODULE_PERF_RECORD) +
+ sizeof (RUNTIME_FUNCTION_PERF_RECORD) * Identifier;
+ RmptTable = (RUNTIME_MODULE_PERFORMANCE_TABLE *) FpdtAllocateReservedMemoryBelow4G (RmptTableLength);
+ ASSERT (RmptTable != NULL);
+ FpdtRecord.RuntimeTablePtr.PerformanceTablePointer = (UINT64) (UINTN) RmptTable;
+
+ //
+ // Insert SMM runtime table record.
+ //
+ mPerformanceEx->StartGaugeEx (Handle, Token, NULL, (UINT64) (UINTN) RmptTable, Identifier);
+
+ //
+ // Fill RMPT table
+ //
+ RmptTable->Header.Header.Signature = RMPT_SIG;
+ RmptTable->Header.Header.Length = (UINT32) RmptTableLength;
+ //
+ // Module Guid has been saved in RmptTable record. Don't need to save it here again.
+ //
+ ZeroMem (&RmptTable->Header.Guid, sizeof (EFI_GUID));
+ RmptTable->Module.Header.Type = RUNTIME_MODULE_TYPE;
+ RmptTable->Module.Header.Length = sizeof (RUNTIME_MODULE_PERF_RECORD);
+ RmptTable->Module.Header.Revision = RECORD_REVISION_1;
+
+ //
+ // Add RMPT data into the cached RMPT table.
+ //
+ if (mRmptTableNumber >= mMaxRmptTableNumber) {
+ DataBuffer = AllocatePool ((mRmptTableNumber + RMPT_TABLE_NUMBER) * sizeof (RMPT_TABLE_DATA));
+ if (DataBuffer == NULL) {
+ mIsOutOfResource = TRUE;
+ return EFI_OUT_OF_RESOURCES;
+ }
+ if (mRmptDataTable != NULL) {
+ CopyMem (DataBuffer, mRmptDataTable, mMaxRmptTableNumber * sizeof (RMPT_TABLE_DATA));
+ FreePool (mRmptDataTable);
+ }
+ mRmptDataTable = DataBuffer;
+ mMaxRmptTableNumber = mRmptTableNumber + RMPT_TABLE_NUMBER;
+ }
+ mRmptDataTable[mRmptTableNumber].Handle = (VOID *) Handle;
+ mRmptDataTable[mRmptTableNumber].RmptTable = RmptTable;
+ mRmptDataTable[mRmptTableNumber++].MaxFunctionNumber = Identifier;
+ break;
+
+ case RUNTIME_FUNCTION_TYPE:
+ if (Handle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Base on Handle to find the matched RmptTable.
+ //
+ for (Index = 0; Index < mRmptTableNumber; Index ++) {
+ if (mRmptDataTable[mRmptTableNumber].Handle == Handle) {
+ break;
+ }
+ }
+ if (Index == mRmptTableNumber) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Base on Identifier to find Function Record.
+ //
+ RmptTable = mRmptDataTable[Index].RmptTable;
+ RuntimeFunctionPerfRecord = &RmptTable->Function[0];
+ for (Index = 0; Index < mRmptDataTable[Index].MaxFunctionNumber; Index++) {
+ if (RuntimeFunctionPerfRecord[Index].Header.Type == 0) {
+ //
+ // New Function Id
+ //
+ break;
+ }
+ if (RuntimeFunctionPerfRecord[Index].FunctionId == Identifier) {
+ //
+ // Function Id exists.
+ //
+ break;
+ }
+ }
+
+ if (Index == mRmptDataTable[Index].MaxFunctionNumber) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Update Module Record.
+ //
+ Residency = GetTimeInNanoSecond (EndTicker) - GetTimeInNanoSecond (StartTicker);
+ RmptTable->Module.ModuleCallCount ++;
+ RmptTable->Module.ModuleResidency += Residency;
+
+ //
+ // New function ID is found. Need to add it into FunctionRecord buffer.
+ //
+ if (RuntimeFunctionPerfRecord[Index].Header.Type == 0) {
+ RuntimeFunctionPerfRecord[Index].Header.Type = RUNTIME_FUNCTION_TYPE;
+ RuntimeFunctionPerfRecord[Index].Header.Length = sizeof (RUNTIME_FUNCTION_PERF_RECORD);
+ RuntimeFunctionPerfRecord[Index].Header.Revision = RECORD_REVISION_1;
+ RuntimeFunctionPerfRecord[Index].FunctionId = Identifier;
+ }
+ RuntimeFunctionPerfRecord[Index].FunctionCallCount++;
+ RuntimeFunctionPerfRecord[Index].FunctionResidency += Residency;
+ break;
+
+ default:
+ //
+ // Record is undefined, return EFI_ABORTED
+ //
+ return EFI_ABORTED;
+ break;
+ }
+
+ //
+ // Report record one by one after records have been reported together.
+ //
+ if (FpdtRecord.RecordHeader.Length != 0) {
+ REPORT_STATUS_CODE_EX (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_SMM_DRIVER,
+ 0,
+ NULL,
+ &gEfiFirmwarePerformanceGuid,
+ &FpdtRecord,
+ FpdtRecord.RecordHeader.Length
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Searches in the gauge array with keyword Handle, Token, Module and Identfier.
+
+ This internal function searches for the gauge entry in the gauge array.
+ If there is an entry that exactly matches the given keywords
+ and its end time stamp is zero, then the index of that gauge entry is returned;
+ otherwise, the the number of gauge entries in the array is returned.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] Identifier 32-bit identifier.
+
+ @retval The index of gauge entry in the array.
+
+**/
+UINT32
+SmmSearchForGaugeEntry (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN CONST UINT32 Identifier OPTIONAL
+ )
+{
+ INT32 Index;
+ UINT32 NumberOfEntries;
+ GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;
+
+ if (Token == NULL) {
+ Token = "";
+ }
+ if (Module == NULL) {
+ Module = "";
+ }
+
+ NumberOfEntries = mGaugeData->NumberOfEntries;
+ GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
+
+ for (Index = NumberOfEntries - 1; Index >=0; Index--) {
+ if (GaugeEntryExArray[Index].EndTimeStamp == 0 &&
+ (GaugeEntryExArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&
+ AsciiStrnCmp (GaugeEntryExArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&
+ AsciiStrnCmp (GaugeEntryExArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&
+ (GaugeEntryExArray[Index].Identifier == Identifier)
+ ) {
+ break;
+ }
+ }
+
+ return Index;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, Module and Identifier.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+EFI_STATUS
+EFIAPI
+StartGaugeEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;
+ UINTN GaugeDataSize;
+ GAUGE_DATA_HEADER *NewGaugeData;
+ UINTN OldGaugeDataSize;
+ GAUGE_DATA_HEADER *OldGaugeData;
+ UINT32 Index;
+
+ AcquireSpinLock (&mSmmFpdtLock);
+
+ Index = mGaugeData->NumberOfEntries;
+ if (Index >= mMaxGaugeRecords) {
+ //
+ // Try to enlarge the scale of gauge array.
+ //
+ OldGaugeData = mGaugeData;
+ OldGaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;
+
+ GaugeDataSize = OldGaugeDataSize + (sizeof (GAUGE_DATA_ENTRY_EX) * INIT_SMM_GAUGE_DATA_ENTRIES);
+
+ NewGaugeData = AllocateZeroPool (GaugeDataSize);
+ if (NewGaugeData == NULL) {
+ ReleaseSpinLock (&mSmmFpdtLock);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mGaugeData = NewGaugeData;
+ mMaxGaugeRecords = mMaxGaugeRecords + INIT_SMM_GAUGE_DATA_ENTRIES;
+
+ //
+ // Initialize new data array and migrate old data one.
+ //
+ mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);
+
+ FreePool (OldGaugeData);
+ }
+
+ GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
+ GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;
+
+ if (Token != NULL) {
+ AsciiStrnCpyS (GaugeEntryExArray[Index].Token, SMM_PERFORMANCE_STRING_SIZE, Token, SMM_PERFORMANCE_STRING_LENGTH);
+ }
+ if (Module != NULL) {
+ AsciiStrnCpyS (GaugeEntryExArray[Index].Module, SMM_PERFORMANCE_STRING_SIZE, Module, SMM_PERFORMANCE_STRING_LENGTH);
+ }
+
+ GaugeEntryExArray[Index].EndTimeStamp = 0;
+ GaugeEntryExArray[Index].Identifier = Identifier;
+
+ if (TimeStamp == 0) {
+ TimeStamp = GetPerformanceCounter ();
+ }
+ GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;
+
+ mGaugeData->NumberOfEntries++;
+
+ InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, 0, Identifier);
+ ReleaseSpinLock (&mSmmFpdtLock);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
+ If the record can not be found then return EFI_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the found record
+ is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
+
+ @retval EFI_SUCCESS The end of the measurement was recorded.
+ @retval EFI_NOT_FOUND The specified measurement record could not be found.
+
+**/
+EFI_STATUS
+EFIAPI
+EndGaugeEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;
+ UINT32 Index;
+
+ AcquireSpinLock (&mSmmFpdtLock);
+
+ if (TimeStamp == 0) {
+ TimeStamp = GetPerformanceCounter ();
+ }
+
+ Index = SmmSearchForGaugeEntry (Handle, Token, Module, Identifier);
+ if (Index >= mGaugeData->NumberOfEntries) {
+ ReleaseSpinLock (&mSmmFpdtLock);
+ return EFI_NOT_FOUND;
+ }
+ GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
+ GaugeEntryExArray[Index].EndTimeStamp = TimeStamp;
+
+ InsertFpdtMeasurement (FALSE, Handle, Token, Module, GaugeEntryExArray[Index].StartTimeStamp, TimeStamp, Identifier);
+ ReleaseSpinLock (&mSmmFpdtLock);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Retrieves a previously logged performance measurement.
+ It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
+ and then assign the Identifier with 0.
+
+ Retrieves the performance log entry from the performance log specified by LogEntryKey.
+ If it stands for a valid entry, then EFI_SUCCESS is returned and
+ GaugeDataEntryEx stores the pointer to that entry.
+
+ @param[in] LogEntryKey The key for the previous performance measurement log entry.
+ If 0, then the first performance measurement log entry is retrieved.
+ @param[out] GaugeDataEntryEx The indirect pointer to the extended gauge data entry specified by LogEntryKey
+ if the retrieval is successful.
+
+ @retval EFI_SUCCESS The GuageDataEntryEx is successfully found based on LogEntryKey.
+ @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).
+ @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).
+ @retval EFI_INVALIDE_PARAMETER GaugeDataEntryEx is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetGaugeEx (
+ IN UINTN LogEntryKey,
+ OUT GAUGE_DATA_ENTRY_EX **GaugeDataEntryEx
+ )
+{
+ UINTN NumberOfEntries;
+ GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;
+
+ NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);
+ if (LogEntryKey > NumberOfEntries) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (LogEntryKey == NumberOfEntries) {
+ return EFI_NOT_FOUND;
+ }
+
+ GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
+
+ if (GaugeDataEntryEx == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *GaugeDataEntryEx = &GaugeEntryExArray[LogEntryKey];
+
+ return EFI_SUCCESS;
+}
+
+
+//
+// Interfaces for SMM PerformanceEx Protocol.
+//
+PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {
+ StartGaugeEx,
+ EndGaugeEx,
+ GetGaugeEx
+};
+
+
+/**
+ SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized
+ this function is callbacked to initialize the Smm Performance Lib
+
+ @param[in] Event The event of notify protocol.
+ @param[in] Context Notify event context.
+
+**/
+VOID
+EFIAPI
+InitializeSmmCorePerformanceLib (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ //
+ // Initialize spin lock
+ //
+ InitializeSpinLock (&mSmmFpdtLock);
+
+ mMaxGaugeRecords = INIT_SMM_GAUGE_DATA_ENTRIES;
+
+ mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords));
+ ASSERT (mGaugeData != NULL);
+
+ //
+ // Install the protocol interfaces for SMM performance library instance.
+ //
+ Handle = NULL;
+ Status = gSmst->SmmInstallProtocolInterface (
+ &Handle,
+ &gSmmPerformanceExProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPerformanceExInterface
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ The constructor function initializes the Performance Measurement Enable flag and
+ registers SmmBase2 protocol notify callback.
+ It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmCoreFpdtPerformanceLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+ VOID *Registration;
+
+ mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
+ if (!mPerformanceMeasurementEnabled) {
+ //
+ // Do not initialize performance infrastructure if not required.
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Create the events to do the library init.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InitializeSmmCorePerformanceLib,
+ NULL,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for protocol notifications on this event
+ //
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiSmmBase2ProtocolGuid,
+ Event,
+ &Registration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, Module and Identifier.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the created record
+ is same as the one created by StartPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+ @param[in] Identifier 32-bit identifier. If the value is 0, the found record
+ is same as the one found by EndPerformanceMeasurement.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurementEx (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp,
+ IN UINT32 Identifier
+ )
+{
+ return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
+ and then assign the Identifier with 0.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+ If Identifier is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance log entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+ @param[out] Identifier Pointer to the 32-bit identifier that was recorded when the measurement
+ was ended.
+
+ @return The key for the next performance log entry (in general case).
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurementEx (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp,
+ OUT UINT32 *Identifier
+ )
+{
+ return 0;
+}
+
+
+/**
+ Adds a record at the end of the performance measurement log
+ that records the start time of a performance measurement.
+
+ Adds a record to the end of the performance measurement log
+ that contains the Handle, Token, and Module.
+ The end time of the new record must be set to zero.
+ If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
+ If TimeStamp is zero, the start time in the record is filled in with the value
+ read from the current time stamp.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The start of the measurement was recorded.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
+
+**/
+RETURN_STATUS
+EFIAPI
+StartPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Searches the performance measurement log from the beginning of the log
+ for the first matching record that contains a zero end time and fills in a valid end time.
+
+ Searches the performance measurement log from the beginning of the log
+ for the first record that matches Handle, Token, and Module and has an end time value of zero.
+ If the record can not be found then return RETURN_NOT_FOUND.
+ If the record is found and TimeStamp is not zero,
+ then the end time in the record is filled in with the value specified by TimeStamp.
+ If the record is found and TimeStamp is zero, then the end time in the matching record
+ is filled in with the current time stamp value.
+
+ @param[in] Handle Pointer to environment specific context used
+ to identify the component being measured.
+ @param[in] Token Pointer to a Null-terminated ASCII string
+ that identifies the component being measured.
+ @param[in] Module Pointer to a Null-terminated ASCII string
+ that identifies the module being measured.
+ @param[in] TimeStamp 64-bit time stamp.
+
+ @retval RETURN_SUCCESS The end of the measurement was recorded.
+ @retval RETURN_NOT_FOUND The specified measurement record could not be found.
+
+**/
+RETURN_STATUS
+EFIAPI
+EndPerformanceMeasurement (
+ IN CONST VOID *Handle, OPTIONAL
+ IN CONST CHAR8 *Token, OPTIONAL
+ IN CONST CHAR8 *Module, OPTIONAL
+ IN UINT64 TimeStamp
+ )
+{
+ return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, 0);
+}
+
+
+/**
+ Attempts to retrieve a performance measurement log entry from the performance measurement log.
+ It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
+ and then eliminate the Identifier.
+
+ Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
+ zero on entry, then an attempt is made to retrieve the first entry from the performance log,
+ and the key for the second entry in the log is returned. If the performance log is empty,
+ then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
+ log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
+ returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
+ retrieved and an implementation specific non-zero key value that specifies the end of the performance
+ log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
+ is retrieved and zero is returned. In the cases where a performance log entry can be returned,
+ the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
+ If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
+ If Handle is NULL, then ASSERT().
+ If Token is NULL, then ASSERT().
+ If Module is NULL, then ASSERT().
+ If StartTimeStamp is NULL, then ASSERT().
+ If EndTimeStamp is NULL, then ASSERT().
+
+ @param[in] LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
+ 0, then the first performance measurement log entry is retrieved.
+ On exit, the key of the next performance log entry.
+ @param[out] Handle Pointer to environment specific context used to identify the component
+ being measured.
+ @param[out] Token Pointer to a Null-terminated ASCII string that identifies the component
+ being measured.
+ @param[out] Module Pointer to a Null-terminated ASCII string that identifies the module
+ being measured.
+ @param[out] StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was started.
+ @param[out] EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
+ was ended.
+
+ @return The key for the next performance log entry (in general case).
+
+**/
+UINTN
+EFIAPI
+GetPerformanceMeasurement (
+ IN UINTN LogEntryKey,
+ OUT CONST VOID **Handle,
+ OUT CONST CHAR8 **Token,
+ OUT CONST CHAR8 **Module,
+ OUT UINT64 *StartTimeStamp,
+ OUT UINT64 *EndTimeStamp
+ )
+{
+ return 0;
+}
+
+
+/**
+ Returns TRUE if the performance measurement macros are enabled.
+
+ This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is set.
+ @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
+ PcdPerformanceLibraryPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+PerformanceMeasurementEnabled (
+ VOID
+ )
+{
+ return mPerformanceMeasurementEnabled;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.inf
new file mode 100644
index 0000000000..ab65e16c57
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/SmmCoreFpdtPerformanceLib/SmmCoreFpdtPerformanceLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Performance library instance used by SMM Core.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = SmmCoreFpdtPerformanceLib
+ FILE_GUID = DE02C265-2AD4-4735-8720-FA4A0B459F4C
+ VERSION_STRING = 1.0
+ MODULE_TYPE = SMM_CORE
+ PI_SPECIFICATION_VERSION = 1.10
+ LIBRARY_CLASS = PerformanceLib|SMM_CORE
+ CONSTRUCTOR = SmmCoreFpdtPerformanceLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ PcdLib
+ TimerLib
+ BaseMemoryLib
+ BaseLib
+ DebugLib
+ SynchronizationLib
+ ReportStatusCodeLib
+ SmmServicesTableLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask
+
+[Sources]
+ SmmCoreFpdtPerformanceLib.c
+
+[Protocols]
+ gEfiSmmBase2ProtocolGuid ## NOTIFY
+
+[Guids]
+ gEfiFirmwarePerformanceGuid ## SOMETIMES_PRODUCES # StatusCode Data
+ gSmmPerformanceExProtocolGuid ## SOMETIMES_PRODUCES # Install Protocol Interfaces
+ gPerformanceExProtocolGuid ## SOMETIMES_CONSUMES # Locate Protocol
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmm.c b/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmm.c
new file mode 100644
index 0000000000..9eb9cdf140
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmm.c
@@ -0,0 +1,90 @@
+/** @file
+ SMM Stall implementation.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// Include files
+//
+#include "Library/StallSmmLib.h"
+#include "Pi/PiSmmCis.h"
+#include "PiDxe.h"
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include "ScAccess.h"
+
+
+/**
+ Delay for at least the request number of microseconds.
+ Timer used is ACPI time counter, which has 1us granularity.
+
+ @param[in] Microseconds Number of microseconds to delay.
+
+ @retval None
+
+**/
+VOID
+SmmStall (
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINTN CurrentTick;
+ UINTN OriginalTick;
+ UINTN RemainingTick;
+ UINT16 AcpiBaseAddr;
+
+ if (Microseconds == 0) {
+ return;
+ }
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ OriginalTick = IoRead32 (AcpiBaseAddr + R_ACPI_PM1_TMR);
+ CurrentTick = OriginalTick;
+
+ //
+ // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ //
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ //
+ // The loops needed by timer overflow
+ //
+ Counts = Ticks / V_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // Remaining clocks within one loop
+ //
+ RemainingTick = Ticks % V_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ // one I/O operation, and maybe generate SMI
+ //
+ while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+ CurrentTick = IoRead32 (AcpiBaseAddr + R_ACPI_PM1_TMR);
+ //
+ // Check if timer overflow
+ //
+ if (CurrentTick < OriginalTick) {
+ Counts--;
+ }
+ OriginalTick = CurrentTick;
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmmLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmmLib.inf
new file mode 100644
index 0000000000..75fff1c026
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/StallSmmLib/StallSmmLib.inf
@@ -0,0 +1,47 @@
+## @file
+# Component description file for SmmStall library.
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = StallSmmLib
+ FILE_GUID = A6A16CCB-91B0-42f4-B4F3-D16D7A8662E6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StallSmmLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ StallSmm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciLib
+ IoLib
+ BaseLib
+
+[Pcd.common]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.c b/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.c
new file mode 100644
index 0000000000..098d2a414c
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.c
@@ -0,0 +1,84 @@
+/** @file
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/Tpm12.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/PciLib.h>
+#include <Library/PttPtpLib.h>
+#include <Guid/PttPTPInstanceGuid.h>
+
+#define R_PTT_HCI_BASE_ADDRESS 0xFED40000
+
+
+/**
+ This service enables the sending of commands to the TPM2.
+
+ @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
+ @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
+ @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block.
+ @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+
+**/
+EFI_STATUS
+EFIAPI
+PttSubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ return PttHciSubmitCommand (InputParameterBlock, InputParameterBlockSize, OutputParameterBlock, OutputParameterBlockSize);
+}
+
+EFI_STATUS
+EFIAPI
+PttRequestUseTpm (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+TPM2_DEVICE_INTERFACE mPttInternalTpm2Device = {
+ TPM_DEVICE_INTERFACE_TPM20_PTT_PTP,
+ PttSubmitCommand,
+ PttRequestUseTpm,
+};
+
+
+EFI_STATUS
+EFIAPI
+Tpm2InstanceLibPttConstructor (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = Tpm2RegisterTpm2DeviceLib (&mPttInternalTpm2Device);
+ if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
+ //
+ // Unsupported means platform policy does not need this instance enabled.
+ //
+ return EFI_SUCCESS;
+ }
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.inf b/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.inf
new file mode 100644
index 0000000000..df584e8838
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/Tpm2DeviceLibPtp/Tpm2InstanceLibPtt.inf
@@ -0,0 +1,43 @@
+## @file
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = Tpm2InstanceLibPttPtp
+ FILE_GUID = 93d66f66-55da-4f03-9b5f-32cf9e543b3a
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = NULL
+ CONSTRUCTOR = Tpm2InstanceLibPttConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Tpm2InstanceLibPtt.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ PttPtpLib
+