summaryrefslogtreecommitdiff
path: root/Silicon
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-22 19:41:14 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:15:02 +0800
commita674eea1c47a6aa0170b2beb07d4f2bbefc798e0 (patch)
tree3db2b004775c74c311c7c5b7b3998f0c6dc91c32 /Silicon
parentf0a77159beb39438f311993bf6cd4136aa7e02fc (diff)
downloadedk2-platforms-a674eea1c47a6aa0170b2beb07d4f2bbefc798e0.tar.xz
BroxtonSiPkg: Add Cpu Include file and Library
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Silicon')
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/BiosGuardDefinitions.h222
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuAccess.h24
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuDataStruct.h197
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h174
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h1054
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPlatformLib.h89
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPolicyLib.h67
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h55
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h52
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h141
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h51
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuOverclockingConfig.h52
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h54
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h167
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h41
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/CpuInitDataHob.h39
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuCommonLib.h211
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuS3Lib.h33
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/MpServiceLib.h819
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/PowerMgmtNvsStruct.h123
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Protocol/PowerMgmtInitDone.h35
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuGlobalNvsArea.h110
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h127
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c113
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c378
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf51
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h49
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c38
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c182
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibPreMem.inf45
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h45
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c256
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h33
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf44
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h229
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c753
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h45
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc49
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S210
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm206
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf59
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c683
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/PeiDxeSmmCpuCommonLib.inf44
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Features.h120
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.h45
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc49
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEquNasm.inc49
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S316
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.asm365
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.nasm361
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Microcode.c221
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.c1756
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.h211
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c273
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/PeiMpServiceLib.inf65
55 files changed, 11280 insertions, 0 deletions
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/BiosGuardDefinitions.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/BiosGuardDefinitions.h
new file mode 100644
index 0000000000..b25f31798e
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/BiosGuardDefinitions.h
@@ -0,0 +1,222 @@
+/** @file
+ Describes the functions visible to the rest of the BIOS Guard.
+
+ 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.
+
+**/
+
+#ifndef _BIOSGUARD_DEFINITIONS_H_
+#define _BIOSGUARD_DEFINITIONS_H_
+
+#ifndef ALIGN_256KB
+#define ALIGN_256KB 0x00040000
+#endif
+#ifndef EFI_PAGE_SIZE
+#define EFI_PAGE_SIZE 0x00001000
+#endif
+
+///
+/// SPI component size selection
+///
+typedef enum {
+ EnumSpiCompSize512KB = 0,
+ EnumSpiCompSize1MB,
+ EnumSpiCompSize2MB,
+ EnumSpiCompSize4MB,
+ EnumSpiCompSize8MB,
+ EnumSpiCompSize16MB,
+ EnumSpiCompSize32MB,
+ EnumSpiCompSize64MB,
+ EnumSpiCompSize128MB
+} SPI_COMPONENT_SIZE;
+
+#define MIN_SFAM_COUNT 1
+#define MAX_SFAM_COUNT 64
+
+///
+/// Signed Flash map descriptor definition.
+///
+typedef struct {
+ UINT32 FirstByte; ///< Linear flash address of the first byte of the signed range, must be aligned to be first byte in the block. Ordering is little-endian.
+ UINT32 LastByte; ///< Linear flash address of the last byte of the signed range, must be aligned to be last byte in the block. Ordering is little-endian.
+} SFAM_DATA;
+
+///
+/// BIOS Guard Platform Data Table (BGPDT)
+/// Provides platform specific data required by BIOS Guard Module
+///
+typedef struct {
+ UINT32 BgpdtSize; ///< Size in bytes of BGPDT including SFAM.
+ UINT16 BgpdtMajVer; ///< Indicates major version of BGPDT.
+ UINT16 BgpdtMinVer; ///< Indicates minor version of BGPDT.
+ UINT8 PlatId[16]; ///< PLAT_ID used to be compared against the one found in the BGUP Header to prevent cross platform flashing.
+ UINT8 PkeySlot0[32]; ///< SHA256 hash for BGUP verification key 0.
+ UINT8 PkeySlot1[32]; ///< SHA256 hash for BGUP verification key 1.
+ UINT8 PkeySlot2[32]; ///< SHA256 hash for BGUP verification key 2.
+ UINT32 BgModSvn; ///< BIOS Guard Module SVN.
+ UINT32 BiosSvn; ///< BIOS_SVN to prevent back-flashing.
+ UINT32 ExecLim; ///< Limit the number of opcodes that can be executed on any invocation of BIOS Guard.
+ /**
+ Bitmap of Policy attributes
+ - BIT[0]: Reserved. Must be 0
+ - BIT[2:1]: EC_PRESENT
+ - 00b = EC does not exist in the system.
+ - 01b = There exists an EC in the system, BIOS Guard does not extend any protection to the EC.
+ - 11b = There exist an EC in the system, BIOS Guard extends protection to the EC.
+ - 10b = Reserved. Must not be used.
+ - BIT[3]: DESCRIPTOR_OVERRIDE_POLICY
+ - 0b = Do not override BIOS Guard security policy.
+ - 1b = Override BIOS Guard security policy.
+ - BIT[4]: FLASH WEAR-OUT POLICY
+ - 0b = Legacy BIOS Guard behavior.
+ - 1b = Enable Flash Wear-Out Protection mitigation.
+ - BIT[24:5]: Reserved, must be 0
+
+ - BIT[31:4]: Reserved. Must be 0
+ **/
+ UINT32 PlatAttr;
+ /**
+ Read/Write command sent to EC
+ - BIT[9:0]: 8 bit IO port used for sending EC commands (writes), and reading EC status (reads).
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:10]: Reserved. Must be 0.
+ **/
+ UINT32 EcCmd;
+ /**
+ Data read or written to EC
+ - BIT[9:0]: 8 bit IO port used for reading and writing data to the EC based on a command issued to EC_CMD.
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:10]: Reserved. Must be 0
+ **/
+ UINT32 EcData;
+ /**
+ EC command indicating a read of the current EC firmware SVN.
+ - BIT[7:0]: EC command.
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:8]: Reserved. Must be 0.
+ **/
+ UINT32 EcCmdGetSvn;
+ /**
+ EC command indicating begin of flash update session.
+ - BIT[7:0]: EC command.
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:8]: Reserved. Must be 0.
+ **/
+ UINT32 EcCmdOpen;
+ /**
+ EC command indicating the termination of BIOS Guard protected session.
+ - BIT[7:0]: EC command indicating the termination of BIOS Guard protected session.
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:8]: Reserved. Must be 0.
+ **/
+ UINT32 EcCmdClose;
+ /**
+ EC command used to verify connectivity between BIOS Guard and EC.
+ - BIT[7:0]: EC command.
+ - This field must be populated if PLAT_ATTR.EC_PRESENT != 0.
+ - This field must be zero if PLAT_ATTR.EC_PRESENT == 0.
+ - BIT[31:8]: Reserved. Must be 0.
+ **/
+ UINT32 EcCmdPortTest;
+ UINT8 Reserved1[4]; ///< Reserved bits.
+ /**
+ Defines number of elements in SFAM array
+ - BIT[5..0]: Index of the last SFAM element
+ - BIT[7..6]: Reserved for future use. Must be 0
+ **/
+ UINT8 LastSfam;
+ UINT8 Reserved2[3]; ///< Reserved 3 bits.
+ SFAM_DATA SfamData[MAX_SFAM_COUNT]; ///< Array of flash address map descriptors. sizeof (SFAM_DATA) == 8
+} BGPDT;
+
+///
+/// BIOS Guard update Package Header
+///
+typedef struct {
+ UINT16 Version; ///< Version of the update package header. Must be 0x0002.
+ UINT8 Reserved3[2]; ///< Reserved bits.
+ UINT8 PlatId[16]; ///< PLAT_ID used to be compared against the one found in the BGPDT to prevent cross platform flashing.
+ /**
+ If any bit set in this field then BGUP must be signed and valid BGUPC must be provided for BGUP to be processed.
+ - BIT[0]: Indicates write/erase operations will be executed on protected flash area indicated in the BGPDT SFAM.
+ - BIT[1]: Indicates protected EC operations included.
+ **/
+ UINT16 PkgAttributes;
+ UINT8 Reserved4[2]; ///< Reserved bits.
+ UINT16 PslMajorVer; ///< Indicates the PSL major version. Must be 2.
+ UINT16 PslMinorVer; ///< Indicates the PSL minor version. Must be 0.
+ UINT32 ScriptSectionSize; ///< Size in bytes of the script.
+ UINT32 DataSectionSize; ///< Size of the data region in bytes.
+ UINT32 BiosSvn; ///< BIOS SVN.
+ UINT32 EcSvn; ///< EC SVN.
+ UINT32 VendorSpecific; ///< Vendor specific data.
+} BGUP_HEADER;
+
+
+///
+/// Memory Size for BIOS Guard Update Package when in TSEG
+///
+#define BGUP_TSEG_BUFFER_SIZE 0x00014000 ///< 16KB Script + 64KB Flash Block.
+
+///
+/// BIOS Guard update package definition for BIOS SMM Initiated runtime calls
+///
+typedef struct {
+ BGUP_HEADER BgupHeader; ///< BIOS Guard update package header.
+ UINT64 BgupBuffer[BGUP_TSEG_BUFFER_SIZE / 8]; ///< BIOS Guard update buffer - Designed to contain the BIOS Guard Script followed immediately by the Update Data
+} BGUP;
+
+///
+/// BIOS Guard Log
+/// The logging facility is used to communicate detailed information regarding the execution of a BIOS Guard script
+/// from the SMI handler which invoked the BIOS Guard module itself.
+///
+typedef struct {
+ UINT16 Version; ///< Indicates the version of the log. Must be 0x0001.
+ UINT16 LastPage; ///< Last valid page index for the log.
+ /**
+ Bitmap indicating what events to log
+ - BIT[0]: Step trace. This indicates a full execution trace. Each line is entered into the log with an EXECUTION_TRACE entry.
+ - BIT[1]: Branch trace. All taken jumps are logged with a BRANCH_TRACE entry.
+ - BIT[2]: Flash write All flash write operations are logged with a FLASH_WRITE entry.
+ - BIT[3]: Flash erase All flash erase operations are logged with a FLASH_ERASE entry.
+ - BIT[4]: Flash error. All error conditions from flash operations are logged with FLASH_ERROR entry.
+ - BIT[5]: Debug. Log Debug opcode execution.
+ - BIT[6]: BIOS Guard module debug message. Log implementation specific debug messages from debug module.
+ - BIT[31:7]: Reserved. Must be 0. If any reserved bits are set in Header.LoggingOptions, the BIOS Guard module must disable the logging feature.
+ **/
+ UINT32 LoggingOptions;
+ UINT8 Reserved5[8]; ///< Reserved bits.
+ UINT32 BgModSvn; ///< Indicates a version number of the BIOS Guard module.
+ UINT32 NumOfEntriesInLog; ///< Total number of log entries that have been written to the log.
+} BIOSGUARD_LOG;
+
+///
+/// HOB used to pass data through every phase of BIOS Guard Bios.
+/// BIOS Guard BIOS code is executed in PEI, DXE and SMM and HOB is the only method to properly pass data between every phase.
+///
+typedef struct {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ BGPDT Bgpdt; ///< BIOS Guard Platform Data Table.
+ BGUP_HEADER BgupHeader; ///< BIOS Guard update package header, this header will be appended to all flash updates along with PSL script.
+ UINT16 TotalFlashSize; ///< Total Flash Size on the system in KB
+ UINT16 BiosSize; ///< BIOS Size in KB
+ UINT64 BiosGuardToolsIntIoTrapAdd; ///< IO Trap address required to Initialize BIOS Guard Tools Interface.
+ BIOSGUARD_LOG BiosGuardLog; ///< Header for BIOS Guard Log Buffer.
+} BIOSGUARD_HOB;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuAccess.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuAccess.h
new file mode 100644
index 0000000000..0902a735f6
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuAccess.h
@@ -0,0 +1,24 @@
+/** @file
+ Macros to simplify and abstract the interface to CPU configuration.
+
+ 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 _CPUACCESS_H_
+#define _CPUACCESS_H_
+
+#include "CpuRegs.h"
+#include "CpuDataStruct.h"
+#include "CpuPowerMgmt.h"
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuDataStruct.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuDataStruct.h
new file mode 100644
index 0000000000..a7eff6e66b
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuDataStruct.h
@@ -0,0 +1,197 @@
+/** @file
+ This file declares various data structures used in CPU reference code.
+
+ 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.
+
+**/
+
+#ifndef _CPU_DATA_STRUCT_H
+#define _CPU_DATA_STRUCT_H
+
+//
+// The reason for changing the state of the processor Only applies to Disabling processors.
+// In future, we can add add/remove support
+//
+#define CPU_CAUSE_NOT_DISABLED 0x0000
+#define CPU_CAUSE_INTERNAL_ERROR 0x0001
+#define CPU_CAUSE_THERMAL_ERROR 0x0002
+#define CPU_CAUSE_SELFTEST_FAILURE 0x0004
+#define CPU_CAUSE_PREBOOT_TIMEOUT 0x0008
+#define CPU_CAUSE_FAILED_TO_START 0x0010
+#define CPU_CAUSE_CONFIG_ERROR 0x0020
+#define CPU_CAUSE_USER_SELECTION 0x0080
+#define CPU_CAUSE_BY_ASSOCIATION 0x0100
+#define CPU_CAUSE_UNSPECIFIED 0x8000
+
+typedef UINT32 CPU_STATE_CHANGE_CAUSE;
+
+///
+/// The data structure is used retrieve data required for MP initialization during S3 resume.
+///
+typedef struct {
+ BOOLEAN APState; ///< Indicates whether the newstate of the AP is enabled or disabled.
+ BOOLEAN S3BootPath; ///< TRUE: S3 Boot path. FALSE: Regular boot path.
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer; ///< Buffer location used during AP Initialization
+ EFI_PHYSICAL_ADDRESS GdtrProfile; ///< Address of Global Descriptor Table
+ EFI_PHYSICAL_ADDRESS IdtrProfile; ///< address of Interrupt Descriptor Table
+ EFI_PHYSICAL_ADDRESS CpuPrivateData; ///< Address of MP_CPU_S3_DATA_POINTER structure
+ EFI_PHYSICAL_ADDRESS StackAddress; ///< Address of APs's stacks
+ EFI_PHYSICAL_ADDRESS SmramBase; ///< Address of SMRAM base as seen by software executing on the processors
+ EFI_PHYSICAL_ADDRESS SmmStartImageBase; ///< Address of SMM Start Image Base
+ UINT32 SmmStartImageSize; ///< Size of SMM Start Image
+ UINT32 NumberOfCpus; ///< Number of processors
+} ACPI_CPU_DATA;
+
+///
+/// CPU information stored in SMRAM during DXE.
+///
+typedef struct {
+ //
+ // Guid as Signature.
+ //
+ EFI_GUID HeaderGuid;
+ EFI_PHYSICAL_ADDRESS AcpiCpuPointer;
+ ACPI_CPU_DATA AcpiCpuData;
+ //
+ // It points the data defined below.
+ //
+ EFI_PHYSICAL_ADDRESS GdtrProfileOffset;
+ EFI_PHYSICAL_ADDRESS GdtOffset;
+ EFI_PHYSICAL_ADDRESS IdtrProfileOffset;
+ EFI_PHYSICAL_ADDRESS IdtOffset;
+ EFI_PHYSICAL_ADDRESS CpuPrivateDataOffset;
+ EFI_PHYSICAL_ADDRESS S3BootScriptTableOffset;
+ EFI_PHYSICAL_ADDRESS S3BspMtrrTableOffset;
+ ///
+ /// We need put all the data buffer here as well.
+ /// These data will be copied to original location in S3.
+ ///
+ //
+ // DataBuffer size
+ //
+ UINT32 GdtrProfileSize;
+ UINT32 GdtSize;
+ UINT32 IdtrProfileSize;
+ UINT32 IdtSize;
+ UINT32 CpuPrivateDataSize;
+ UINT32 S3BootScriptTableSize;
+ UINT32 S3BspMtrrTableSize;
+} SMRAM_CPU_DATA;
+
+///
+/// Structure to hold the return value of AsmCpuid instruction
+///
+typedef struct {
+ UINT32 RegEax; ///< Value of EAX.
+ UINT32 RegEbx; ///< Value of EBX.
+ UINT32 RegEcx; ///< Value of ECX.
+ UINT32 RegEdx; ///< Value of EDX.
+} EFI_CPUID_REGISTER;
+
+///
+/// Structure to describe microcode header
+///
+typedef struct {
+ UINT32 HeaderVersion; ///< Version number of the update header.
+ UINT32 UpdateRevision; ///< Unique version number for the update.
+ UINT32 Date; ///< Date of the update creation.
+ UINT32 ProcessorId; ///< Signature of the processor that requires this update.
+ UINT32 Checksum; ///< Checksum of update data and header.
+ UINT32 LoaderRevision; ///< Version number of the microcode loader program.
+ UINT32 ProcessorFlags; ///< Lower 4 bits denoting platform type information.
+ UINT32 DataSize; ///< Size of encoded data in bytes.
+ UINT32 TotalSize; ///< Total size of microcode update in bytes.
+ UINT8 Reserved[12]; ///< Reserved bits.
+} CPU_MICROCODE_HEADER;
+
+///
+/// Structure to describe the extended signature table header of the microcode update
+///
+typedef struct {
+ UINT32 ExtendedSignatureCount; ///< Number of extended signature structures.
+ UINT32 ExtendedTableChecksum; ///< Checksum of update extended processor signature table.
+ UINT8 Reserved[12]; ///< Reserved bits.
+} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+///
+/// Structure to describe the data of the extended table of the microcode update
+///
+typedef struct {
+ UINT32 ProcessorSignature; ///< Extended signature of the processor that requires this update
+ UINT32 ProcessorFlag; ///< Lower 4 bits denoting platform type information
+ UINT32 ProcessorChecksum; ///< checksum of each of the extended update
+} CPU_MICROCODE_EXTENDED_TABLE;
+
+#pragma pack(1)
+///
+/// MSR_REGISTER definition as a Union of QWORDS, DWORDS and BYTES
+///
+typedef union _MSR_REGISTER {
+ UINT64 Qword; ///< MSR value in 64 bit QWORD.
+
+ ///
+ /// MSR value represented in two DWORDS
+ ///
+ struct _DWORDS {
+ UINT32 Low; ///< Lower DWORD of the 64 bit MSR value.
+ UINT32 High; ///< Higher DWORD of the 64 bit MSR value.
+ } Dwords;
+
+ ///
+ /// MSR value represented in eight bytes.
+ ///
+ struct _BYTES {
+ UINT8 FirstByte; ///< First byte of the 64 bit MSR value.
+ UINT8 SecondByte; ///< Second byte of the 64 bit MSR value.
+ UINT8 ThirdByte; ///< Third byte of the 64 bit MSR value.
+ UINT8 FouthByte; ///< Fourth byte of the 64 bit MSR value.
+ UINT8 FifthByte; ///< Fifth byte of the 64 bit MSR value.
+ UINT8 SixthByte; ///< Sixth byte of the 64 bit MSR value.
+ UINT8 SeventhByte; ///< Seventh byte of the 64 bit MSR value.
+ UINT8 EighthByte; ///< Eigth byte of the 64 bit MSR value.
+ } Bytes;
+} MSR_REGISTER;
+
+///
+/// HOB to save CPU BIST Info data
+///
+typedef struct {
+ UINT32 ApicId;
+ UINT32 Health;
+} BIST_HOB_DATA;
+
+///
+/// Processor trace buffer size selection.
+///
+typedef enum {
+ Enum4K = 0,
+ Enum8K,
+ Enum16K,
+ Enum32K,
+ Enum64K,
+ Enum128K,
+ Enum256K,
+ Enum512K,
+ Enum1M,
+ Enum2M,
+ Enum4M,
+ Enum8M,
+ Enum16M,
+ Enum32M,
+ Enum64M,
+ Enum128M,
+ EnumProcTraceMemDisable
+} PROC_TRACE_MEM_SIZE;
+
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h
new file mode 100644
index 0000000000..bc22c051fe
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h
@@ -0,0 +1,174 @@
+/** @file
+ This file contains define definitions specific to processor.
+
+ 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 _POWER_MGMT_DEFINITIONS_H_
+#define _POWER_MGMT_DEFINITIONS_H_
+
+#define PPM_ENABLE 1
+#define PPM_DISABLE 0
+
+#define POWER_MGMT_VR_DISABLE 0
+#define CSTATE_SUPPORTED 0x1
+#define ENHANCED_CSTATE_SUPPORTED 0x2
+#define C6_C7_SHORT_LATENCY_SUPPORTED 0x01
+#define C6_C7_LONG_LATENCY_SUPPORTED 0x02
+#define C7s_SHORT_LATENCY_SUPPORTED 0x03
+#define C7s_LONG_LATENCY_SUPPORTED 0x04
+//
+// Voltage offset definitions
+//
+#define OC_LIB_OFFSET_ADAPTIVE 0
+#define OC_LIB_OFFSET_OVERRIDE 1
+//
+// Platform Power Management Flags Bit Definitions:
+// These defines are also used in CPU0CST.ASL to check platform configuration
+// and build C-state table accordingly.
+//
+#define PPM_EIST 0x1 ///< BIT 0 : Enhanced Intel Speed Step Technology.
+#define PPM_C1 0x2 ///< BIT 1 : C1 enabled, supported.
+#define PPM_C1E 0x4 ///< BIT 2 : C1E enabled.
+#define PPM_C3 0x8 ///< BIT 3 : C3 enabled, supported.
+#define PPM_C6 0x10 ///< BIT 4 : C6 enabled, supported.
+#define PPM_C7 0x20 ///< BIT 5 : C7 enabled, supported.
+#define PPM_C7S 0x40 ///< BIT 6 : C7S enabled, supported
+#define PPM_TM 0x80 ///< BIT 7 : Adaptive Thermal Monitor.
+#define PPM_TURBO 0x100 ///< BIT 8 : Long duration turbo mode
+#define PPM_CMP 0x200 ///< BIT 9 : CMP.
+#define PPM_TSTATES 0x400 ///< BIT 10: CPU throttling states
+#define PPM_MWAIT_EXT 0x800 ///< BIT 11: MONITIOR/MWAIT Extensions supported.
+#define PPM_EEPST 0x1000 ///< BIT 12: Energy efficient P-State Feature enabled
+#define PPM_TSTATE_FINE_GRAINED 0x2000 ///< BIT 13: Fine grained CPU Throttling states
+#define PPM_CD 0x4000 ///< BIT 14: Deep Cstate - C8/C9/C10
+#define PPM_TIMED_MWAIT 0x8000 ///< BIT 15: Timed Mwait support
+#define C6_LONG_LATENCY_ENABLE 0x10000 ///< BIT 16: 1=C6 Long and Short,0=C6 Short only
+#define C7_LONG_LATENCY_ENABLE 0x20000 ///< BIT 17: 1=C7 Long and Short,0=C7 Short only
+#define C7s_LONG_LATENCY_ENABLE 0x40000 ///< BIT 18: 1=C7s Long and Short,0=C7s Short only
+#define PPM_C8 0x80000 ///< Bit 19: 1= C8 enabled/supported
+#define PPM_C9 0x100000 ///< Bit 20: 1= C9 enabled/supported
+#define PPM_C10 0x200000 ///< Bit 21: 1= C10 enabled/supported
+#define PPM_HWP 0x400000 ///< Bit 22: 1= HWP enabled/supported
+#define PPM_HWP_LVT 0x800000 ///< Bit 23: 1= HWP LVT enabled/supported
+
+#define PPM_C_STATES 0x7A ///< PPM_C1 + PPM_C3 + PPM_C6 + PPM_C7 + PPM_C7S
+#define C3_LATENCY 0x42
+#define C6_C7_SHORT_LATENCY 0x73
+#define C6_C7_LONG_LATENCY 0x91
+#define C8_LATENCY 0xE4
+#define C9_LATENCY 0x145
+#define C10_LATENCY 0x1EF
+
+#define CPUID_FUNCTION_6 0x00000006
+
+//
+// C-State Latency (us) and Power (mW) for C1
+//
+#define C1_LATENCY 1
+#define C1_POWER 0x3E8
+#define C3_POWER 0x1F4
+#define C6_POWER 0x15E
+#define C7_POWER 0xC8
+#define C8_POWER 0xC8
+#define C9_POWER 0xC8
+#define C10_POWER 0xC8
+
+#define MAX_POWER_LIMIT_1_TIME_IN_SECONDS 32767
+#define AUTO 0
+#define END_OF_TABLE 0xFF
+
+#define CONFIG_TDP_DOWN 1
+#define CONFIG_TDP_UP 2
+#define CONFIG_TDP_DEACTIVATE 0xFF
+//
+// MMIO definitions
+//
+#define MMIO_PACKAGE_THERMAL_LIMIT_CONTROL 0x7104
+#define B_THERMAL_LIMIT_TEMP_ENABLE BIT8
+#define V_THERMAL_LIMIT_TEMP 0x69
+
+#define MMIO_PACKAGE_THERMAL_INTERRUPT 0x7010
+#define B_THRESHOLD1_INT_ENABLE BIT0
+#define B_THRESHOLD2_INT_ENABLE BIT1
+#define V_THRESHOLD1_TEMP 0x5A00
+#define V_THRESHOLD2_TEMP 0x550000
+#define V_TIME_WINDOW 0x2C000000
+
+#define MMIO_PL3_CONTROL 0x71F0
+#define V_PL3_POWER_LIMIT 0x1E00 // 30W for all SKU's
+#define B_PL3_ENABLE BIT15
+#define V_PL3_TIME_WINDOW 0x500000
+#define V_PL3_DUTY_CYCLE 0x0A000000
+#define V_PL4_PMAX 0x1E0000000000 // 30W for all SKU's
+#define B_PL4_ENABLE BIT47
+
+#define MMIO_RAPL_LIMIT 0x70A8
+
+///
+/// For Mobile, default PL1 time window value is 28 seconds
+///
+#define MB_POWER_LIMIT1_TIME_DEFAULT 28
+///
+/// For Desktop, default PL1 time window value is 8 second
+///
+#define DT_POWER_LIMIT1_TIME_DEFAULT 8
+///
+/// Mobile Sku in Watts
+///
+#define MOBILE_SKU_6W 0x600
+#define MOBILE_SKU_4W 0x400
+#define DESKTOP_SKU_10 0xA00
+
+///
+/// PL1, PL2 limits
+///
+#define DT_POWER_LIMIT1 10
+
+#define MB_POWER_LIMIT2 15
+#define DT_POWER_LIMIT2 25
+
+#define PROCESSOR_FLAVOR_MOBILE 0x04
+#define PROCESSOR_FLAVOR_DESKTOP 0x00
+#define PROCESSOR_FLAVOR_MASK (BIT3 | BIT2)
+
+//
+// Power definitions (Based on EMTS V1.0 for standard voltage 2.4-2.6 GHz dual-core parts.)
+//
+#define FVID_MAX_POWER 35000
+#define FVID_TURBO_POWER 35000
+#define FVID_SUPERLFM_POWER 12000
+//
+// Power definitions for LFM and Turbo mode TBD.
+//
+#define FVID_MIN_POWER 15000
+///
+/// S3- MSR restore SW SMI
+///
+#ifndef SW_SMI_S3_RESTORE_MSR
+#define SW_SMI_S3_RESTORE_MSR 0x48
+#endif
+
+///
+/// Limit the number of P-states to 16. Up to Windows 7, the OS allocates 1KB buffer for the PSS package.
+/// So the maximum number of P-state OS can handle is 19. This is not an OS issue. Having too many P-states
+/// is not good for the system performance.
+///
+#define FVID_MAX_STATES 20
+
+///
+/// VR Commands
+///
+#define WRITE_VR_CURRENT_CONFIG_CMD 0x80000129
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h
new file mode 100644
index 0000000000..72712d87bb
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h
@@ -0,0 +1,1054 @@
+/** @file
+ Register names for CPU registers.
+
+ <b>Conventions</b>
+ Definitions beginning with "MSR_" are MSRs
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+
+ 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.
+
+**/
+
+#ifndef _CPU_REGS_H_
+#define _CPU_REGS_H_
+
+//
+// Local APIC defines
+//
+#define APIC_REGISTER_LOCAL_ID_OFFSET 0x00000020
+#define APIC_REGISTER_APIC_VERSION_OFFSET 0x00000030
+#define APIC_REGISTER_SPURIOUS_VECTOR_OFFSET 0x000000F0
+#define APIC_REGISTER_ICR_LOW_OFFSET 0x00000300
+#define APIC_REGISTER_ICR_HIGH_OFFSET 0x00000310
+#define APIC_REGISTER_LINT0_VECTOR_OFFSET 0x00000350
+#define APIC_REGISTER_LINT1_VECTOR_OFFSET 0x00000360
+
+#define BROADCAST_MODE_SPECIFY_CPU 0x00
+#define BROADCAST_MODE_ALL_INCLUDING_SELF 0x01
+#define BROADCAST_MODE_ALL_EXCLUDING_SELF 0x02
+
+#ifndef DELIVERY_MODE_FIXED
+#define DELIVERY_MODE_FIXED 0x0
+#endif
+#ifndef DELIVERY_MODE_LOWEST_PRIORITY
+#define DELIVERY_MODE_LOWEST_PRIORITY 0x1
+#endif
+#ifndef DELIVERY_MODE_SMI
+#define DELIVERY_MODE_SMI 0x2
+#endif
+#ifndef DELIVERY_MODE_REMOTE_READ
+#define DELIVERY_MODE_REMOTE_READ 0x3
+#endif
+#ifndef DELIVERY_MODE_NMI
+#define DELIVERY_MODE_NMI 0x4
+#endif
+#ifndef DELIVERY_MODE_INIT
+#define DELIVERY_MODE_INIT 0x5
+#endif
+#ifndef DELIVERY_MODE_SIPI
+#define DELIVERY_MODE_SIPI 0x6
+#endif
+#ifndef DELIVERY_MODE_MAX
+#define DELIVERY_MODE_MAX 0x7
+#endif
+
+#ifndef TRIGGER_MODE_EDGE
+#define TRIGGER_MODE_EDGE 0x00
+#endif
+#ifndef TRIGGER_MODE_LEVEL
+#define TRIGGER_MODE_LEVEL 0x01
+#endif
+
+#ifndef CPU_FEATURE_DISABLE
+#define CPU_FEATURE_DISABLE 0
+#endif
+#ifndef CPU_FEATURE_ENABLE
+#define CPU_FEATURE_ENABLE 1
+#endif
+
+#ifndef CPU_FEATURE_ALL_CORES_ENABLE
+#define CPU_FEATURE_ALL_CORES_ENABLE 4
+#endif
+
+#define CACHE_UNCACHEABLE 0
+#define CACHE_WRITECOMBINING 1
+#define CACHE_WRITETHROUGH 4
+#define CACHE_WRITEPROTECTED 5
+#define CACHE_WRITEBACK 6
+
+#define CPUID_SIGNATURE 0x0
+#define CPUID_VERSION_INFO 0x1
+#define CPUID_FUNCTION_4 0x4
+#define CPU_CACHE_TYPE_MASK 0x1F
+#define CPU_CACHE_LEVEL_MASK 0x07
+#define CPU_CACHE_ASSOCIATIVITY_MASK 0x03FF
+#define CPU_CACHE_PARTITION_MASK 0x03FF
+#define CPU_CACHE_LINE_SIZE_MASK 0x0FFF
+#define B_CPUID_VERSION_INFO_ECX_MWAIT BIT3
+#define B_CPUID_VERSION_INFO_ECX_VME BIT5
+#define B_CPUID_VERSION_INFO_ECX_SME BIT6
+#define B_CPUID_VERSION_INFO_ECX_EIST BIT7
+#define B_CPUID_VERSION_INFO_ECX_TM2 BIT8
+#define B_CPUID_VERSION_INFO_ECX_DCA BIT18
+#define B_CPUID_VERSION_INFO_ECX_AES BIT25
+#define B_CPUID_VERSION_INFO_ECX_X2APIC BIT21
+#define B_CPUID_VERSION_INFO_EDX_XD BIT20
+#define B_CPUID_VERSION_INFO_EDX_HT BIT28
+#define B_CPUID_VERSION_INFO_EDX_TM1 BIT29
+
+#define CPUID_CACHE_INFO 0x2
+#define CPUID_SERIAL_NUMBER 0x3
+#define CPUID_CACHE_PARAMS 0x4
+
+//
+// CPU ID Instruction defines
+//
+#define V_CPUID_CACHE_TYPE_MASK 0x1F
+#define B_CPUID_CACHE_TYPE_DATA 0x1
+#define B_CPUID_CACHE_TYPE_INSTRUCTION 0x2
+#define B_CPUID_CACHE_TYPE_UNIFIED 0x3
+#define V_CPUID_CACHE_LEVEL_MASK 0xE0
+#define B_CPUID_CACHE_LEVEL_SHIFT 5
+#define B_CPUID_CACHE_PARAMS_WAYS_SHIFT 22
+#define B_CPUID_CACHE_PARAMS_PARTITIONS_SHIFT 12
+#define CPUID_MONITOR_MWAIT_PARAMS 0x5
+#define B_CPUID_MONITOR_MWAIT_ECX_EXTENSIONS BIT0
+#define B_CPUID_MONITOR_MWAIT_EDX_CSTATE BIT0
+#define V_CPUID_MONITOR_MWAIT_EDX_ENHANCED_CSTATE 0x2
+#define CPUID_POWER_MANAGEMENT_PARAMS 0x6
+#define B_CPUID_POWER_MANAGEMENT_EAX_TURBO BIT1
+#define B_CPUID_POWER_MANAGEMENT_EAX_FINE_GRAINED_CLOCK_MODULATION BIT5
+#define B_CPUID_POWER_MANAGEMENT_ECX_ENERGY_EFFICIENT_POLICY_SUPPORT BIT3
+#define B_CPUID_POWER_MANAGEMENT_EAX_HWP BIT7
+#define B_CPUID_POWER_MANAGEMENT_EAX_HWP_LVT_INTERRUPT_SUPPORT BIT9
+#define B_CPUID_FUNCTION7_EBX_RTIT_SUPPORT BIT25
+#define B_CPUID_FUNCTION20_ECX_TOPA_SUPPORT BIT0
+#define B_CPUID_FUNCTION20_ECX_SINGLE_RANGE_SUPPORT BIT2
+#define CPUID_EDRAM_CAPABILITY 0x4
+#define CPUID_FUNCTION_7 0x7
+#define CPUID_FUNCTION_8 0x8
+#define CPUID_FUNCTION_20 0x14
+#define CPUID_DCA_PARAMS 0x9
+#define CPUID_FUNCTION_A 0xA
+#define CPUID_CORE_TOPOLOGY 0xB
+
+#define CPUID_EXTENDED_FUNCTION 0x80000000
+#define CPUID_EXTENDED_CPU_SIG 0x80000001
+#define CPUID_BRAND_STRING1 0x80000002
+#define CPUID_BRAND_STRING2 0x80000003
+#define CPUID_BRAND_STRING3 0x80000004
+#define CPUID_L2_CACHE_FEATURE 0x80000006
+#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008
+
+//
+// MSR defines
+//
+#define MSR_IA32_PLATFORM_ID 0x00000017
+#define N_PLATFORM_ID_SHIFT 50
+#define B_PLATFORM_ID_MASK 0x7 ///< Bits 52:50
+#define MSR_IA32_APIC_BASE 0x0000001B
+#define B_MSR_IA32_APIC_BASE_G_XAPIC BIT11
+#define B_MSR_IA32_APIC_BASE_M_XAPIC BIT10
+#define B_MSR_IA32_APIC_BASE_BSP BIT8
+#define B_PIC_THREAD_CONTROL_TPR_DIS BIT10
+#define MSR_CORE_THREAD_COUNT 0x00000035
+#define N_CORE_COUNT_OFFSET 16
+#define B_THREAD_COUNT_MASK 0xFFFF
+#define MSR_IA32_FEATURE_CONTROL 0x0000003A
+#define B_MSR_IA32_FEATURE_CONTROL_LOCK BIT0
+#define B_MSR_IA32_FEATURE_CONTROL_ELT BIT1
+#define B_MSR_IA32_FEATURE_CONTROL_EVT BIT2
+#define B_MSR_IA32_FEATURE_CONTROL_SLFE (BIT8 | BIT9 | BIT10 | BIT11 | BIT12 | BIT13 | BIT14)
+#define B_MSR_IA32_FEATURE_CONTROL_SGE BIT15
+
+#define MSR_IA32_MTRRCAP 0x000000FE
+
+#define MSR_IA32_BIOS_UPDT_TRIG 0x00000079
+#define MSR_IA32_BIOS_SIGN_ID 0x0000008B
+#define MSR_IA32_SMM_MONITOR_CONTROL 0x0000009B
+#define MSR_IA32_PMC0_MSR 0x000000C1
+#define MSR_IA32_PMC1_MSR 0x000000C2
+#define MSR_IA32_PMC2_MSR 0x000000C3
+#define MSR_IA32_PMC3_MSR 0x000000C4
+#define MSR_IA32_PMC4_MSR 0x000000C5
+#define MSR_IA32_PMC5_MSR 0x000000C6
+#define MSR_IA32_PMC6_MSR 0x000000C7
+#define MSR_IA32_PMC7_MSR 0x000000C8
+#define MSR_PLATFORM_INFO 0x000000CE
+#define V_MSR_PRMRR_MASK 0x0000007FFFFFFFFF
+#define N_PLATFORM_INFO_MIN_RATIO 40
+#define B_PLATFORM_INFO_RATIO_MASK 0xFF
+#define N_PLATFORM_INFO_MAX_RATIO 8
+#define B_MSR_PLATFORM_INFO_BIOSGUARD_AVAIL BIT35
+#define N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET 33
+#define V_CONFIG_TDP_NUM_LEVELS_MASK (BIT34 | BIT33)
+#define B_PLATFORM_INFO_TDC_TDP_LIMIT BIT29
+#define N_PLATFORM_INFO_RATIO_LIMIT 28
+#define B_PLATFORM_INFO_RATIO_LIMIT BIT28
+#define B_FIVR_RFI_TUNING_AVAIL BIT25
+#define B_PLATFORM_INFO_SMM_SAVE_CONTROL BIT16
+#define N_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET 30
+#define B_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET BIT30
+#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED BIT37
+#define B_PLATFORM_INFO_EDRAM_EN BIT57
+#define B_PLATFORM_INFO_PRODUCTION BIT27
+#define MSR_PMG_CST_CONFIG 0x000000E2
+#define B_CST_CONTROL_LOCK BIT15
+#define B_IO_MWAIT_REDIRECTION_ENABLE BIT10
+#define B_TIMED_MWAIT_ENABLE BIT31
+#define B_PACKAGE_C_STATE_LIMIT (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PKG_CSTATE_LIMIT_C2 0x02
+#define V_PKG_CSTATE_LIMIT_C1 0x01
+#define V_PKG_CSTATE_LIMIT_C0 0x00
+#define V_CSTATE_LIMIT_UNLIMIT 0x00
+#define V_CSTATE_LIMIT_C1 0x10
+#define V_CSTATE_LIMIT_C3 0x20
+#define V_CSTATE_LIMIT_C6 0x30
+#define V_CSTATE_LIMIT_C7 0x40
+#define V_CSTATE_LIMIT_C8 0x50
+#define V_CSTATE_LIMIT_C9 0x60
+#define V_CSTATE_LIMIT_C10 0x70
+#define V_CSTATE_LIMIT_MASK 0x000000F0
+#define B_C3_AUTO_DEMOTION_ENABLE BIT25
+#define B_C1_AUTO_DEMOTION_ENABLE BIT26
+#define B_C3_AUTO_UNDEMOTION_ENABLE BIT27
+#define B_C1_AUTO_UNDEMOTION_ENABLE BIT28
+#define B_PKG_CSTATE_DEMOTION_ENABLE BIT29
+#define B_PKG_CSTATE_UNDEMOTION_ENABLE BIT30
+#define V_FREQ_TUNING_MASK 0xFFFF
+#define MSR_PMG_IO_CAPTURE_BASE 0x000000E4
+#define B_MSR_PMG_CST_RANGE (BIT18 | BIT17 | BIT16)
+#define V_IO_CAPT_LVL2 (0x0 << 16) ///< C3
+#define V_IO_CAPT_LVL3 (0x1 << 16) ///< C6
+#define V_IO_CAPT_LVL4 (0x2 << 16) ///< C7
+#define V_IO_CAPT_LVL5 (0x3 << 16) ///< C8
+#define V_IO_CAPT_LVL6 (0x4 << 16) ///< C9
+#define V_IO_CAPT_LVL7 (0x5 << 16) ///< C10
+#define V_IO_CAPT_LVL2_BASE_ADDR_MASK 0xFFFF
+#define V_IO_CAPT_LVL2_BASE_ADDR_C3 0x414
+#define IA32_MTRR_CAP 0x000000FE
+#define B_IA32_MTRR_VARIABLE_SUPPORT 0xFF
+#define B_IA32_MTRR_CAP_FIXED_SUPPORT BIT8
+#define B_IA32_MTRR_CAP_SMRR_SUPPORT BIT11
+#define B_IA32_MTRR_CAP_EMRR_SUPPORT BIT12
+
+#define IA32_MCG_CAP 0x00000179
+#define IA32_MCG_STATUS 0x0000017A
+#define MSR_FLEX_RATIO 0x00000194
+#define N_FLEX_RATIO 8
+#define B_FLEX_RATIO (0xFF << 8)
+#define B_FLEX_EN BIT16
+#define B_MAX_EXTRA_VOLTAGE 0xFF
+#define N_OVERCLOCKING_BINS 17
+#define B_OVERCLOCKING_BINS (0x7 << 17)
+#define B_OVERCLOCKING_LOCK BIT20
+#define RATIO_FLEX_CLEAR_MASK 0xFFFFFFFFFFFF00FFULL
+#define MSR_IA32_PERF_STS 0x00000198
+#define N_IA32_PERF_STSP_STATE_TARGET 8
+#define B_IA32_PERF_STSP_STATE_MASK 0xFF
+#define MSR_IA32_PERF_CTRL 0x00000199
+#define N_IA32_PERF_CTRLP_STATE_TARGET 8
+#define B_IA32_PERF_CTRLP_STATE_TARGET (0x7F << 8)
+#define B_IA32_PERF_CTRL_TURBO_DIS BIT32
+#define MSR_IA32_CLOCK_MODULATION 0x0000019A
+#define IA32_THERM_INTERRUPT 0x0000019B
+#define B_IA32_THERM_INTERRUPT_VIE BIT4
+#define MSR_IA32_THERM_STATUS 0x0000019C
+#define MSR_IA32_MISC_ENABLE 0x000001A0
+#define B_MSR_IA32_MISC_ENABLE_FSE BIT0
+#define B_MSR_IA32_MISC_ENABLE_TME BIT3
+#define N_MSR_IA32_MISC_ENABLE_EIST_OFFSET 16
+#define B_MSR_IA32_MISC_ENABLE_EIST BIT16
+#define B_MSR_IA32_MISC_ENABLE_MONITOR BIT18
+#define B_MSR_IA32_MISC_ENABLE_CPUID_MAX BIT22
+#define B_MSR_IA32_MISC_ENABLE_TPR_DIS BIT23
+#define B_MSR_IA32_MISC_ENABLE_XD BIT34
+#define B_MSR_IA32_MISC_DISABLE_TURBO BIT38
+#define MSR_TEMPERATURE_TARGET 0x000001A2
+#define N_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LIMIT 24
+#define N_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_OFFSET (16)
+#define B_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_MASK (0xFF << 16)
+#define N_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET 8
+#define B_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET (0xFF << 8)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_TIME_WINDOW (0x7F)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_MASK 0xFF
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_CLAMP_ENABLE BIT7
+#define MISC_FEATURE_CONTROL 0x000001A4
+#define B_MISC_FEATURE_CONTROL_MLC_STRP BIT0
+#define B_MISC_FEATURE_CONTROL_MLC_SPAP BIT1
+#define B_MISC_FEATURE_CONTROL_DCU_STRP BIT2
+#define B_MISC_FEATURE_CONTROL_DCU_IPP BIT3
+#define B_MISC_FEATURE_CONTROL_3_STRIKE_CNT BIT11
+#define MSR_MISC_PWR_MGMT 0x000001AA
+#define B_MISC_PWR_MGMT_SINGLE_PCTL_EN BIT0
+#define B_MISC_PWR_MGMT_ENABLE_HWP BIT6
+#define B_MISC_PWR_MGMT_ENABLE_HWP_INTERRUPT BIT7
+#define N_MISC_PWR_MGMT_ENABLE_HWP_INTERRUPT 7
+#define B_MISC_PWR_MGMT_ENABLE_OUT_OF_BAND_AUTONOMOUS BIT8
+#define B_MISC_PWR_MGMT_ENABLE_SDC_OOB BIT9
+#define N_MISC_PWR_MGMT_ENABLE_SDC_OOB 9
+#define B_MISC_PWR_MGMT_ENABLE_SDC BIT10
+#define N_MISC_PWR_MGMT_ENABLE_SDC 10
+#define B_MISC_PWR_MGMT_SDC_OOB_CAPABLE BIT11
+#define B_MISC_PWR_MGMT_ENABLE_HWP_EPP BIT12
+#define N_MISC_PWR_MGMT_ENABLE_HWP_EPP 12
+#define B_MISC_PWR_MGMT_LOCK_TERM_INT BIT22
+#define MSR_TURBO_POWER_CURRENT_LIMIT 0x000001AC
+#define B_MSR_TURBO_POWER_CURRENT_LIMIT_TDC_EN BIT31
+#define N_MSR_TURBO_POWER_CURRENT_LIMIT_TDC_LIMIT 16
+#define B_MSR_TURBO_POWER_CURRENT_LIMIT_TDC_LIMIT (0x7F << 16)
+#define B_MSR_TURBO_POWER_CURRENT_LIMIT_TDP_EN BIT15
+#define N_MSR_TURBO_POWER_CURRENT_LIMIT_TDP_LIMIT 0
+#define B_MSR_TURBO_POWER_CURRENT_LIMIT_TDP_LIMIT (0x7F << 0)
+#define MSR_TURBO_RATIO_LIMIT 0x000001AD
+#define N_MSR_TURBO_RATIO_LIMIT_1C 0
+#define B_MSR_TURBO_RATIO_LIMIT_1C (0xFF << 0)
+#define N_MSR_TURBO_RATIO_LIMIT_2C 8
+#define B_MSR_TURBO_RATIO_LIMIT_2C (0xFF << 8)
+#define N_MSR_TURBO_RATIO_LIMIT_3C 16
+#define B_MSR_TURBO_RATIO_LIMIT_3C (0xFF << 16)
+#define N_MSR_TURBO_RATIO_LIMIT_4C 24
+#define B_MSR_TURBO_RATIO_LIMIT_4C (0xFF << 24)
+#define MSR_IA32_ENERGY_PERFORMANCE_BIAS 0x1B0
+#define B_ENERGY_POLICY_MASK 0xF
+#define MSR_IA32_PLATFORM_DCA_CAP 0x000001F8
+#define B_MSR_IA32_PLATFORM_DCA_CAP_TYPE0_EN BIT0
+#define MSR_IA32_CPU_DCA_CAP 0x000001F9
+#define B_MSR_IA32_CPU_DCA_CAP_TYPE0_SUP BIT0
+#define MSR_IA32_DCA_0_CAP 0x000001FA
+#define B_MSR_IA32_CPU_DCA_CAP_ENDID BIT11
+#define N_MSR_IA32_CPU_DCA_CAP_DELAY 13
+#define B_MSR_IA32_CPU_DCA_CAP_DELAY (BIT13 | BIT14 | BIT15 | BIT16)
+#define B_MSR_IA32_CPU_DCA_CAP_SW_LOCK BIT24
+#define B_MSR_IA32_CPU_DCA_CAP_SW_FLUSH BIT25
+#define B_MSR_IA32_CPU_DCA_CAP_HW_LOCK BIT26
+#define MSR_POWER_CTL 0x000001FC
+#define B_MSR_POWER_CTL_BI_PROCHOT BIT0
+#define B_MSR_POWER_CTL_C1E BIT1
+#define B_ENERGY_EFFICIENT_P_STATE_FEATURE_ENABLE BIT18
+#define B_MSR_POWER_CTL_DISABLE_PROCHOT_OUT BIT21
+#define B_MSR_POWER_CTL_PROCHOT_RESPONSE BIT22
+#define B_MSR_POWER_CTL_PROCHOT_LOCK BIT23
+#define B_MSR_POWER_CTL_DISABLE_VR_THERMAL_ALERT BIT24
+#define B_MSR_POWER_CTL_CSTATE_PRE_WAKE_DISABLE BIT30
+#define B_MSR_FERR_ENABLE BIT0
+
+#define V_POWER_LIMIT_4_MASK (0x1FFF)
+#define B_CURRENT_LIMIT_LOCK BIT31
+#define B_CURRENT_LIMIT_MASK 0x1FFF
+
+#define MSR_PACKAGE_POWER_SKU_UNIT 0x606
+#define PACKAGE_POWER_UNIT_MASK 0xF
+#define PACKAGE_TIME_UNIT_MASK 0xF0000
+
+#define B_PKG_IRTL_VALID BIT15
+#define B_INTERRUPT_RESPONSE_TIME_LIMIT_MASK 0x3FF
+#define B_TIME_UNIT_MASK (0x7 << 10)
+#define N_TIME_UNIT_OFFSET 10
+#define MSR_PACKAGE_POWER_LIMIT 0x610
+#define MSR_PACKAGE_POWER_SKU 0x614
+#define B_POWER_LIMIT_ENABLE BIT15
+#define B_CRITICAL_POWER_CLAMP_ENABLE BIT16
+#define B_POWER_LIMIT_LOCK BIT31
+#define POWER_SKU_MASK (0x7FFF)
+#define POWER_LIMIT_MASK (0x7FFF)
+#define POWER_LIMIT_1_TIME_MASK (0xFE0000)
+#define PACKAGE_TDP_POWER_MASK (0x7FFF)
+#define PACKAGE_MIN_POWER_MASK (0x7FFF0000)
+#define PACKAGE_MAX_POWER_MASK (0x7FFF)
+#define MSR_PL3_CONTROL 0x615
+#define POWER_LIMIT_3_TIME_MASK (0xFE0000)
+#define POWER_LIMIT_3_DUTY_CYCLE_MASK (0x7F000000)
+#define MSR_DDR_RAPL_LIMIT 0x618
+#define MSR_MAX_RING_RATIO_LIMIT_MASK 0x7F
+#define MSR_CONFIG_TDP_NOMINAL 0x648
+#define CONFIG_TDP_NOMINAL_RATIO_MASK 0xFF
+#define MSR_CONFIG_TDP_LVL1 0x649
+#define CONFIG_TDP_LVL1_RATIO_OFFSET 16
+#define CONFIG_TDP_LVL1_RATIO_MASK (0xFF << 16)
+#define CONFIG_TDP_LVL1_PKG_TDP_MASK (0x7FFF)
+#define MSR_CONFIG_TDP_LVL2 0x64A
+#define CONFIG_TDP_LVL2_RATIO_OFFSET 16
+#define CONFIG_TDP_LVL2_RATIO_MASK (0xFF << 16)
+#define CONFIG_TDP_LVL2_PKG_TDP_MASK (0x7FFF)
+#define MSR_CONFIG_TDP_CONTROL 0x64B
+#define CONFIG_TDP_CONTROL_LOCK (1 << 31)
+#define CONFIG_TDP_CONTROL_LVL_MASK 0x3
+#define CONFIG_TDP_NOMINAL 0
+#define CONFIG_TDP_LEVEL1 1
+#define CONFIG_TDP_LEVEL2 2
+#define MSR_TURBO_ACTIVATION_RATIO 0x64C
+#define MSR_TURBO_ACTIVATION_RATIO_LOCK (1 << 31)
+#define MSR_TURBO_ACTIVATION_RATIO_MASK 0xFF
+#define MSR_PKG_HDC_CONFIG_CTL 0x00000652
+#define B_PKG_HDC_CONFIG_CTL_SDC_CX_MONITOR (BIT0 | BIT1 | BIT2)
+#define N_PKG_HDC_CONFIG_CTL_SDC_CX_MONITOR 0
+#define B_PKG_HDC_CONFIG_CTL_SDC_MCNT_COUNT_METHOD BIT3
+#define N_PKG_HDC_CONFIG_CTL_SDC_MCNT_COUNT_METHOD 3
+#define B_PKG_HDC_CONFIG_CTL_SDC_MAX_FORCE_IDLE_DURATION_TIME (BIT5 | BIT6 | BIT7 | BIT8 | BIT9 | BIT10)
+#define N_PKG_HDC_CONFIG_CTL_SDC_MAX_FORCE_IDLE_DURATION_TIME 5
+#define B_PKG_HDC_CONFIG_CTL_SDC_DIRECT_CONTROL (BIT12 | BIT13 | BIT14 | BIT15 | BIT16 | BIT17 | BIT18)
+#define N_PKG_HDC_CONFIG_CTL_SDC_DIRECT_CONTROL 12
+#define B_PKG_HDC_CONFIG_CTL_MIN_ACTIVE_TIME (BIT19 | BIT20 | BIT21 | BIT22 | BIT23 | BIT24 | BIT25 | BIT26)
+#define N_PKG_HDC_CONFIG_CTL_MIN_ACTIVE_TIME 19
+#define MSR_IA32_HDC_PKG_CTL 0x00000DB0
+#define B_HDC_PKG_CTL_SDC_PACKAGE_ENABLE BIT0
+#define N_HDC_PKG_CTL_SDC_PACKAGE_ENABLE 0
+#define B_HDC_PKG_CTL_SDC_WAS_ONCE_ENABLED BIT1
+#define N_HDC_PKG_CTL_SDC_WAS_ONCE_ENABLED 1
+#define MSR_IA32_PM_CTL1 0x00000DB1
+#define B_PM_CTL1_SDC_ALLOWED BIT0
+#define N_PM_CTL1_SDC_ALLOWED 0
+#define SMRR_PHYS_BASE 0x000001F2
+#define SMRR_PHYS_MASK 0x000001F3
+#define EMRR_PHYS_BASE 0x000001F4
+#define EMRR_PHYS_MASK 0x000001F5
+#define B_MSR_EMRR_PHYS_MASK_EN BIT11
+#define B_MSR_EMRR_PHYS_MASK_LOCK BIT10
+#define V_MAXIMUM_VARIABLE_MTRR_NUMBER 10
+#define CACHE_VARIABLE_MTRR_BASE 0x00000200
+#define V_FIXED_MTRR_NUMBER 11
+#define IA32_MTRR_FIX64K_00000 0x00000250
+#define IA32_MTRR_FIX16K_80000 0x00000258
+#define IA32_MTRR_FIX16K_A0000 0x00000259
+#define IA32_MTRR_FIX4K_C0000 0x00000268
+#define IA32_MTRR_FIX4K_C8000 0x00000269
+#define IA32_MTRR_FIX4K_D0000 0x0000026A
+#define IA32_MTRR_FIX4K_D8000 0x0000026B
+#define IA32_MTRR_FIX4K_E0000 0x0000026C
+#define IA32_MTRR_FIX4K_E8000 0x0000026D
+#define IA32_MTRR_FIX4K_F0000 0x0000026E
+#define IA32_MTRR_FIX4K_F8000 0x0000026F
+#define MSR_IA32_CR_PAT 0x00000277
+#define CACHE_IA32_MTRR_DEF_TYPE 0x000002FF
+#define B_CACHE_MTRR_VALID BIT11
+#define B_CACHE_FIXED_MTRR_VALID BIT10
+#define NO_EVICT_MODE 0x000002E0
+#define B_NO_EVICT_MODE_SETUP BIT0
+#define B_NO_EVICT_MODE_RUN BIT1
+#define B_LOCK_MEM_CFG BIT1
+#define IA32_MC0_CTL 0x00000400
+#define IA32_MC0_STATUS 0x00000401
+#define IA32_MC0_ADDR 0x00000402
+#define IA32_MC0_MISC 0x00000403
+#define IA32_MC8_CTL (IA32_MC0_CTL + (8 * 4))
+#define IA32_MC5_STATUS (IA32_MC0_STATUS + (5 * 4))
+#define IA32_MC6_STATUS (IA32_MC0_STATUS + (6 * 4))
+#define IA32_MC7_STATUS (IA32_MC0_STATUS + (7 * 4))
+#define IA32_MC8_STATUS (IA32_MC0_STATUS + (8 * 4))
+#define MSR_IA32_VMX_BASIC 0x00000480
+#define MSR_IA32_VMX_MISC 0x00000485
+#define APIC_GLOBAL_ENABLE 0x00000800
+#define EXT_XAPIC_LOGICAL_APIC_ID 0x00000802
+#define EXT_XAPIC_VERSION 0x00000803
+#define EXT_XAPIC_SVR 0x0000080F
+#define EXT_XAPIC_ICR 0x00000830
+#define MSR_EXT_XAPIC_LVT_THERM 0x00000833
+#define EXT_XAPIC_LVT_LINT0 0x00000835
+#define EXT_XAPIC_LVT_LINT1 0x00000836
+#define MSR_IA32_DEBUG_INTERFACE 0x00000C80
+#define B_DEBUG_INTERFACE_ENABLE BIT0
+#define B_DEBUG_INTERFACE_LOCK BIT30
+#define B_DEBUG_INTERFACE_DEBUG_STATUS BIT31
+#define NUM_TENTHS_TO_PERCENTAGE 1000
+#define FIVR_NOTCH_MASK 0x0000FF00
+#define FIVR_SSC_MASK 0x000000FF
+#define FIVR_SSC_LOCK_BIT BIT31
+#define MAX_FIVR_SSC_PERCENT 60
+#define MAX_FIVR_NOTCH_PERCENT 50
+
+//
+// MSRs for SMM State Save Register
+//
+#define MSR_SMM_MCA_CAP 0x17D
+#define B_TARGETED_SMI BIT56
+#define N_TARGETED_SMI 56
+#define B_SMM_CPU_SVRSTR BIT57
+#define N_SMM_CPU_SVRSTR 57
+#define B_SMM_CODE_ACCESS_CHK BIT58
+#define N_SMM_CODE_ACCESS_CHK 58
+#define B_LONG_FLOW_INDICATION BIT59
+#define N_LONG_FLOW_INDICATION 59
+#define MSR_SMM_FEATURE_CONTROL 0x4E0
+#define B_SMM_FEATURE_CONTROL_LOCK BIT0
+#define B_SMM_CPU_SAVE_EN BIT1
+#define B_SMM_CODE_CHK_EN BIT2
+#define MSR_SMM_DELAYED 0x4E2
+#define MSR_SMM_BLOCKED 0x4E3
+
+#define TXT_PUBLIC_BASE 0xFED30000
+#define R_CPU_BOOT_GUARD_ERRORCODE 0x30
+#define R_CPU_BOOT_GUARD_BOOTSTATUS 0xA0
+#define R_CPU_BOOT_GUARD_ACM_STATUS 0x328
+#define V_CPU_BOOT_GUARD_LOAD_ACM_SUCCESS 0x8000000000000000
+#define B_BOOT_GUARD_ACM_ERRORCODE_MASK 0x00007FF0
+
+///
+/// Local APIC definitions
+///
+#define MSR_XAPIC_BASE 0x1B
+#define MMIO_LOCAL_APIC_THERMAL_DEF 0xFEE00330
+#define B_INTERRUPT_MASK (1 << 16)
+#define B_DELIVERY_MODE (0x07 << 8)
+#define V_MODE_SMI (0x02 << 8)
+#define B_VECTOR (0xFF << 0)
+//
+// Processor Definitions
+//
+#define CPUID_FULL_STEPPING 0x0000000F
+#define CPUID_FULL_FAMILY_MODEL 0x0FFF0FF0
+#define CPUID_FULL_FAMILY_MODEL_STEPPING 0x0FFF0FFF
+#define CPUID_FULL_FAMILY_MODEL_BROXTON 0x000506C0
+
+#define CPUID_PROCESSOR_TOPOLOGY 0xB
+
+#ifndef SLE_FLAG
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND 1000
+#endif
+#else // SLE FLAG
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 0
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND 0
+#endif
+#endif // SLE_FLAG
+
+#define BITS(x) (1 << (x))
+
+/**
+Notes :
+ 1. Bit position always starts at 0.
+ 2. Following macros are applicable only for Word aligned integers.
+**/
+#define BIT(Pos, Value) (1 << (Pos) & (Value))
+#define BITRANGE(From, Width, Value) (((Value) >> (From)) & ((1 << (Width)) - 1))
+
+typedef enum {
+ EnumCpuBroxton = CPUID_FULL_FAMILY_MODEL_BROXTON,
+ EnumCpuMax = CPUID_FULL_FAMILY_MODEL
+} CPU_FAMILY;
+
+///
+/// Enums for CPU Stepping IDs
+///
+typedef enum {
+ ///
+ /// Broxton Steppings
+ ///
+ EnumBxtA0 = 0,
+ ///
+ /// Max Stepping
+ ///
+ EnumCpuSteppingMax = CPUID_FULL_STEPPING
+} CPU_STEPPING;
+
+
+
+#define EFI_CACHE_UNCACHEABLE 0
+#define EFI_CACHE_WRITECOMBINING 1
+#define EFI_CACHE_WRITETHROUGH 4
+#define EFI_CACHE_WRITEPROTECTED 5
+#define EFI_CACHE_WRITEBACK 6
+
+//
+// CPUID defines
+//
+#define EFI_CPUID_SIGNATURE 0x0
+
+#define EFI_CPUID_VERSION_INFO 0x1
+#define B_EFI_CPUID_VERSION_INFO_EAX_MASK 0x0FFF0FFF
+#define B_EFI_CPUID_VERSION_INFO_EAX_FULL_FAMILY_MODEL_MASK 0x0FFF0FF0
+#define B_EFI_CPUID_VERSION_INFO_EAX_EXT_FAMILY_ID_MASK 0x0FF00000
+#define B_EFI_CPUID_VERSION_INFO_EAX_EXT_MODEL_ID_MASK 0x000F0000
+#define N_EFI_CPUID_VERSION_INFO_EAX_EXT_FAMILY_ID 20
+#define N_EFI_CPUID_VERSION_INFO_EAX_EXT_MODEL_ID 16
+#define N_EFI_CPUID_VERSION_INFO_EAX_TYPE 12
+#define N_EFI_CPUID_VERSION_INFO_EAX_FAMILY_ID 8
+#define N_EFI_CPUID_VERSION_INFO_EAX_MODEL 4
+#define N_EFI_CPUID_VERSION_INFO_EAX_STEPPING_ID 0
+#define B_EFI_CPUID_VERSION_INFO_EBX_DEFAULT_APIC_ID (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define B_EFI_CPUID_VERSION_INFO_EBX_LOGICAL_CPU_PER_PACKAGE (BIT23 | BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define B_EFI_CPUID_VERSION_INFO_EBX_CLFLUSH_CHUNK_COUNT (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_CPUID_VERSION_INFO_ECX_AES BIT25
+#define B_EFI_CPUID_VERSION_INFO_ECX_XAPIC BIT21
+#define B_EFI_CPUID_VERSION_INFO_ECX_SSE4_2 BIT20
+#define B_EFI_CPUID_VERSION_INFO_ECX_SSE4_1 BIT19
+#define B_EFI_CPUID_VERSION_INFO_ECX_DCA BIT18
+#define B_EFI_CPUID_VERSION_INFO_ECX_XTPR_UPDATE BIT14
+#define B_EFI_CPUID_VERSION_INFO_ECX_CMPXCHG16B BIT13
+#define B_EFI_CPUID_VERSION_INFO_ECX_L1_CONTEXT_ID BIT10
+#define B_EFI_CPUID_VERSION_INFO_ECX_SUP_SSE3 BIT9
+#define B_EFI_CPUID_VERSION_INFO_ECX_TM2 BIT8
+#define B_EFI_CPUID_VERSION_INFO_ECX_EIST BIT7
+#define B_EFI_CPUID_VERSION_INFO_ECX_SME BIT6
+#define B_EFI_CPUID_VERSION_INFO_ECX_VME BIT5
+#define B_EFI_CPUID_VERSION_INFO_ECX_QPL BIT4
+#define B_EFI_CPUID_VERSION_INFO_ECX_MWAIT BIT3
+#define B_EFI_CPUID_VERSION_INFO_ECX_SSE3 BIT0
+#define B_EFI_CPUID_VERSION_INFO_EDX_PBE BIT31
+#define B_EFI_CPUID_VERSION_INFO_EDX_THERMAL_CLOCK_CONTROL BIT29
+#define B_EFI_CPUID_VERSION_INFO_EDX_HT BIT28
+#define B_EFI_CPUID_VERSION_INFO_EDX_SELF_SNOOP BIT27
+#define B_EFI_CPUID_VERSION_INFO_EDX_SSE2 BIT26
+#define B_EFI_CPUID_VERSION_INFO_EDX_SSE BIT25
+#define B_EFI_CPUID_VERSION_INFO_EDX_FAST_SAVE_RESTORE BIT24
+#define B_EFI_CPUID_VERSION_INFO_EDX_MMX BIT23
+#define B_EFI_CPUID_VERSION_INFO_EDX_ACPI_SUPPORT BIT22
+#define B_EFI_CPUID_VERSION_INFO_EDX_DEBUG_TRACE_STORE BIT21
+#define B_EFI_CPUID_VERSION_INFO_EDX_CLFLUSH_INTR BIT19
+#define B_EFI_CPUID_VERSION_INFO_EDX_CPU_SERIAL_NUMBER BIT18
+#define B_EFI_CPUID_VERSION_INFO_EDX_PSE BIT17
+#define B_EFI_CPUID_VERSION_INFO_EDX_PAT BIT16
+#define B_EFI_CPUID_VERSION_INFO_EDX_CON_MOVE_INTR BIT15
+#define B_EFI_CPUID_VERSION_INFO_EDX_MCA BIT14
+#define B_EFI_CPUID_VERSION_INFO_EDX_PGE BIT13
+#define B_EFI_CPUID_VERSION_INFO_EDX_MTRR BIT12
+#define B_EFI_CPUID_VERSION_INFO_EDX_SEP BIT11
+#define B_EFI_CPUID_VERSION_INFO_EDX_ON_CHIP_APIC BIT9
+#define B_EFI_CPUID_VERSION_INFO_EDX_CMPXCHG8 BIT8
+#define B_EFI_CPUID_VERSION_INFO_EDX_MCE BIT7
+#define B_EFI_CPUID_VERSION_INFO_EDX_PAE BIT6
+#define B_EFI_CPUID_VERSION_INFO_EDX_MSR BIT5
+#define B_EFI_CPUID_VERSION_INFO_EDX_TIME_STAMP_COUNTER BIT4
+#define B_EFI_CPUID_VERSION_INFO_EDX_PAGE_SIZE_EXT BIT3
+#define B_EFI_CPUID_VERSION_INFO_EDX_DEBUG_EXT BIT2
+#define B_EFI_CPUID_VERSION_INFO_EDX_VME_8086 BIT1
+#define B_EFI_CPUID_VERSION_INFO_EDX_FP_386 BIT0
+
+#define EFI_CPUID_CACHE_INFO 0x2
+#define EFI_CPUID_SERIAL_NUMBER 0x3
+
+#define EFI_CPUID_CACHE_PARAMS 0x4
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_MAX_CORES_IN_PACKAGE (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26)
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_TOTAL_THREADS_SHARE_CACHE (BIT25 | BIT24 | BIT23 | BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | BIT15 | BIT14)
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_FULLY_ASSOCIATIVE_CACHE BIT9
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_SELF_INITIALIZING BIT8
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL (BIT7 | BIT6 | BIT5)
+#define B_EFI_CPUID_CACHE_PARAMS_EAX_CACHE_TYPE (BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define B_EFI_CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIATIVITY (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24 | BIT23 | BIT22)
+#define B_EFI_CPUID_CACHE_PARAMS_EBX_PHYSICAL_LINE_PARTITIONS (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | BIT15 | BIT14 | BIT13 | BIT12)
+#define B_EFI_CPUID_CACHE_PARAMS_EBX_SYSTEM_COHERENCY_LINE_SIZE (BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define B_EFI_CPUID_CACHE_PARAMS_EDX_PREFETCH_STRIDE (BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define B_EFI_CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVE_IN_LOWER_CACHE BIT1
+#define B_EFI_CPUID_CACHE_PARAMS_EDX_WBINVD_INVD_ON_LOWER_CACHE BIT0
+
+#define EFI_CPUID_MONITOR_MWAIT_PARAMS 0x5
+#define B_EFI_CPUID_MONITOR_MWAIT_ECX_INTERRUPTS_BREAK_MWAIT BIT1
+#define B_EFI_CPUID_MONITOR_MWAIT_ECX_MWAIT_SUPPORT BIT0
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C7 (BIT31 | BIT30 | BIT29 | BIT28)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C7 28
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C6 (BIT27 | BIT26 | BIT25 | BIT24)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C6 24
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C5 (BIT23 | BIT22 | BIT21 | BIT20)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C5 20
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C4 (BIT19 | BIT18 | BIT17 | BIT16)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C4 16
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C3 (BIT15 | BIT14 | BIT13 | BIT12)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C3 12
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C2 (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C2 8
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C1 (BIT7 | BIT6 | BIT5 | BIT4)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C1 4
+#define B_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C0 (BIT3 | BIT2 | BIT1 | BIT0)
+#define N_EFI_CPUID_MONITOR_MWAIT_EDX_PARAMS_C0 0
+
+#define EFI_CPUID_POWER_MANAGEMENT_PARAMS 0x6
+#define EFI_CPUID_POWER_MANAGEMENT_EAX_PECI BIT0
+#define EFI_CPUID_POWER_MANAGEMENT_EBX_NUM_INT_THRESHOLDS (BIT3 | BIT2 | BIT1 | BIT0)
+#define EFI_CPUID_POWER_MANAGEMENT_ECX_HW_COORDINATION_FEEDBACK BIT0
+
+#define EFI_CPUID_REV7 0x7
+#define EFI_CPUID_REV8 0x8
+#define EFI_CPUID_DCA_PARAMS 0x9
+#define EFI_CPUID_ARCH_PERF_MON 0xA
+#define EFI_CPUID_CORE_TOPOLOGY 0xB
+
+#define EFI_CPUID_EXTENDED_FUNCTION 0x80000000
+
+#define EFI_CPUID_EXTENDED_FEATURE_BITS 0x80000001
+#define EFI_CPUID_EXTENDED_FEATURE_BITS_ECX_LAHF_SAHF BIT0
+#define EFI_CPUID_EXTENDED_FEATURE_BITS_EDX_XD BIT20
+#define EFI_CPUID_EXTENDED_FEATURE_BITS_EDX_SYSCALL BIT11
+
+//
+// This constant defines the maximum length of the CPU brand string. According to the
+// IA manual, the brand string is in EAX through EDX (thus 16 bytes) after executing
+// the CPUID instructions with EAX as 80000002, 80000003, 80000004.
+//
+#define MAXIMUM_CPU_BRAND_STRING_LENGTH 48
+
+#define EFI_CPUID_BRAND_STRING1 0x80000002
+#define EFI_CPUID_BRAND_STRING2 0x80000003
+#define EFI_CPUID_BRAND_STRING3 0x80000004
+
+#define EFI_CPUID_ADVANCED_POWER_MANAGEMENT 0x80000007
+#define EFI_CPUID_ADVANCED_POWER_MANAGEMENT_EDX_TSC_INVARIANCE BIT8
+
+#define EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE 0x80000008
+#define B_EFI_CPUID_VIRTUAL_ADDRESS_BITS (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_CPUID_PHYSICAL_ADDRESS_BITS (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+//
+// Common MSR
+//
+#ifndef EFI_MSR_IA32_PLATFORM_ID
+#define EFI_MSR_IA32_PLATFORM_ID 0x00000017
+#endif // EFI_MSR_IA32_PLATFORM_ID
+#define N_EFI_MSR_IA32_PLATFORM_ID_PLATFORM_ID_BITS 50
+#define B_EFI_MSR_IA32_PLATFORM_ID_PLATFORM_ID_BITS_MASK (BIT52 | BIT51 | BIT50)
+#define N_EFI_MSR_IA32_PLATFORM_ID_PLATFORM_ID_BITS_MASK_START 50
+#define N_EFI_MSR_IA32_PLATFORM_ID_PLATFORM_ID_BITS_MASK_END 52
+
+#ifndef EFI_MSR_IA32_APIC_BASE
+#define EFI_MSR_IA32_APIC_BASE 0x0000001B
+
+
+#define B_EFI_MSR_IA32_APIC_BASE_APIC_BASE_ADDRESS 0xFFFFFF000 //For Nehalem, base address can be up to 43 bits but not cover here yet
+#define B_EFI_MSR_IA32_APIC_BASE_APIC_GLOBAL_ENABLE BIT11
+#define B_EFI_MSR_IA32_APIC_BASE_M_XAPIC BIT10
+#define B_EFI_MSR_IA32_APIC_BASE_BSP BIT8
+#endif // EFI_MSR_IA32_APIC_BASE
+//
+// Local APIC defines, offset from APIC base address
+//
+#define APIC_REGISTER_LOCAL_ID_OFFSET 0x00000020
+#define N_APIC_REGISTER_LOCAL_ID_OFFSET_XAPIC_ID_MASK 24
+#define B_APIC_REGISTER_LOCAL_ID_OFFSET_XAPIC_ID_MASK 0xFF000000
+
+#define APIC_REGISTER_APIC_VERSION_OFFSET 0x00000030
+#define B_APIC_REGISTER_APIC_VERSION_OFFSET_VERSION_MASK 0xFF
+
+#define APIC_REGISTER_SPURIOUS_VECTOR_OFFSET 0x000000F0
+#define APIC_REGISTER_ICR_LOW_OFFSET 0x00000300
+#define APIC_REGISTER_ICR_HIGH_OFFSET 0x00000310
+#define APIC_REGISTER_LINT0_VECTOR_OFFSET 0x00000350
+#define APIC_REGISTER_LINT1_VECTOR_OFFSET 0x00000360
+
+#define EFI_MSR_IA32_FEATURE_CONTROL 0x0000003A
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_SGE BIT15
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_SLFE (BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_SMRR BIT3
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_EVT BIT2
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_ELT BIT1
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_LOCK BIT0
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_VT_SECURE 0x0000FF02
+
+#ifndef EFI_MSR_IA32_BIOS_UPDT_TRIG
+#define EFI_MSR_IA32_BIOS_UPDT_TRIG 0x00000079
+#endif
+#ifndef EFI_MSR_IA32_BIOS_SIGN_ID
+#define EFI_MSR_IA32_BIOS_SIGN_ID 0x0000008B
+#endif
+
+#define EFI_MSR_IA32_MCG_CAP 0x00000179
+#define EFI_MSR_IA32_MCG_STATUS 0x0000017A
+
+#define EFI_MSR_PMG_CST_CONFIG 0x000000E2
+#define B_EFI_MSR_PMG_CST_CONFIG_CST_CONTROL_LOCK BIT15
+#define B_EFI_MSR_PMG_CST_CONFIG_IO_MWAIT_REDIRECTION_ENABLE BIT10
+#define B_EFI_MSR_PMG_CST_CONFIG_PACKAGE_C_STATE_LIMIT (BIT2 | BIT1 | BIT0)
+
+#define EFI_MSR_PMG_IO_CAPTURE_ADDR 0x000000E4 //For Nehalem Spec: EFI_IA32_PMG_IO_CAPTURE_BASE
+#define N_EFI_MSR_PMG_IO_CAPTURE_ADDR_CST_RANGE 16
+#define B_EFI_MSR_PMG_IO_CAPTURE_ADDR_LVL_2_BASE_ADDRESS_MASK 0xFFFF
+
+#define EFI_MSR_IA32_MPERF 0x000000E7
+#define EFI_MSR_IA32_APERF 0x000000E8
+
+#define EFI_MSR_IA32_MTRR_CAP 0x000000FE
+#define B_EFI_MSR_IA32_MTRR_CAP_EMRR_SUPPORT BIT12
+#define B_EFI_MSR_IA32_MTRR_CAP_SMRR_SUPPORT BIT11
+#define B_EFI_MSR_IA32_MTRR_CAP_WC_SUPPORT BIT10
+#define B_EFI_MSR_IA32_MTRR_CAP_FIXED_SUPPORT BIT8
+#define B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#define EFI_MSR_CLOCK_FLEX_MAX 0x00000194
+#define B_EFI_MSR_CLOCK_FLEX_MAX_FLEX_EN BIT16
+#define B_EFI_MSR_CLOCK_FLEX_MAX_FLEX_RATIO_MASK 0x1F
+#define N_EFI_MSR_CLOCK_FLEX_MAX_FLEX_RATIO 8
+
+#define EFI_MSR_IA32_PERF_STS 0x00000198
+#define EFI_MSR_IA32_PERF_CTRL 0x00000199
+
+#ifndef EFI_MSR_IA32_THERM_INTERRUPT
+#define EFI_MSR_IA32_THERM_INTERRUPT 0x0000019B
+#endif
+
+#define B_EFI_MSR_IA32_THERM_INTERRUPT_VIE BIT4
+
+#ifndef EFI_MSR_IA32_THERM_STATUS
+#define EFI_MSR_IA32_THERM_STATUS 0x0000019C
+#endif
+
+#ifndef EFI_MSR_IA32_MISC_ENABLE
+#define EFI_MSR_IA32_MISC_ENABLE 0x000001A0
+#endif
+
+
+#define B_EFI_MSR_IA32_MISC_ENABLE_XD BIT34
+#define B_EFI_MSR_IA32_MISC_ENABLE_CPUID_MAX BIT22
+#define B_EFI_MSR_IA32_MISC_ENABLE_MONITOR BIT18
+#define B_EFI_MSR_IA32_MISC_ENABLE_EIST BIT16
+#define B_EFI_MSR_IA32_MISC_ENABLE_TM1_EN BIT3
+
+#define EFI_MSR_SMRR_PHYS_BASE 0x000001F2
+#define EFI_MSR_SMRR_PHYS_MASK 0x000001F3
+
+#define EFI_MSR_CACHE_VARIABLE_MTRR_BASE 0x00000200
+#define EFI_MSR_CACHE_VARIABLE_MTRR_END 0x0000020F
+#define V_EFI_FIXED_MTRR_NUMBER 11
+
+#define EFI_MSR_IA32_MTRR_FIX64K_00000 0x00000250
+#define EFI_MSR_IA32_MTRR_FIX16K_80000 0x00000258
+#define EFI_MSR_IA32_MTRR_FIX16K_A0000 0x00000259
+#define EFI_MSR_IA32_MTRR_FIX4K_C0000 0x00000268
+#define EFI_MSR_IA32_MTRR_FIX4K_C8000 0x00000269
+#define EFI_MSR_IA32_MTRR_FIX4K_D0000 0x0000026A
+#define EFI_MSR_IA32_MTRR_FIX4K_D8000 0x0000026B
+#define EFI_MSR_IA32_MTRR_FIX4K_E0000 0x0000026C
+#define EFI_MSR_IA32_MTRR_FIX4K_E8000 0x0000026D
+#define EFI_MSR_IA32_MTRR_FIX4K_F0000 0x0000026E
+#define EFI_MSR_IA32_MTRR_FIX4K_F8000 0x0000026F
+#define EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE 0x000002FF
+#define B_EFI_MSR_CACHE_MTRR_VALID BIT11
+#define B_EFI_MSR_GLOBAL_MTRR_ENABLE BIT11
+#define B_EFI_MSR_FIXED_MTRR_ENABLE BIT10
+#define B_EFI_MSR_CACHE_MEMORY_TYPE (BIT2 | BIT1 | BIT0)
+
+#define EFI_MSR_VALID_MASK 0xFFFFFFFFF
+#define EFI_CACHE_VALID_ADDRESS 0xFFFFFF000
+#define EFI_SMRR_CACHE_VALID_ADDRESS 0xFFFFF000
+#define EFI_CACHE_VALID_EXTENDED_ADDRESS 0xFFFFFFFFFF000
+
+// Leave one MTRR pairs for OS use
+#define EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS 1
+#define EFI_CACHE_LAST_VARIABLE_MTRR_FOR_BIOS (EFI_MSR_CACHE_VARIABLE_MTRR_END) - \
+ (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2)
+
+#define EFI_MSR_NO_EVICT_MODE 0x000002E0
+#define B_EFI_MSR_NO_EVICT_MODE_RUN BIT1
+#define B_EFI_MSR_NO_EVICT_MODE_SETUP BIT0
+
+#define EFI_MSR_IA32_MC0_CTL 0x00000400
+#define EFI_MSR_IA32_MC0_STATUS 0x00000401
+#define EFI_MSR_IA32_MC0_ADDR 0x00000402
+#define EFI_MSR_IA32_MC0_MISC 0x00000403
+#define EFI_MSR_IA32_MC8_CTL (EFI_IA32_MC0_CTL + (8*4))
+#define EFI_MSR_IA32_MC8_STATUS (EFI_IA32_MC0_STATUS + (8*4))
+
+#define EFI_MSR_EXT_XAPIC_LOGICAL_APIC_ID 0x00000802
+#define EFI_MSR_EXT_XAPIC_VERSION 0x00000803
+#define B_EFI_MSR_EXT_XAPIC_VERSION_VERSION 0xFF
+#define EFI_MSR_EXT_XAPIC_ICR 0x00000830
+#define EFI_MSR_EXT_XAPIC_LVT_LINT0 0x00000835
+#define EFI_MSR_EXT_XAPIC_LVT_LINT1 0x00000836
+
+#define EFI_MSR_EBL_CR_POWERON 0x0000002A
+#define B_EFI_MSR_EBL_CR_POWERON_EXECUTEBIST BIT9
+
+#ifndef EFI_MSR_IA32_FEATURE_CONTROL
+#define EFI_MSR_IA32_FEATURE_CONTROL 0x0000003A
+#endif
+#define B_EFI_MSR_IA32_FEATURE_CONTROL_C_STATE_SMI BIT16
+
+#ifndef EFI_MSR_PMG_CST_CONFIG
+#define EFI_MSR_PMG_CST_CONFIG 0x000000E2
+#endif
+#define B_EFI_MSR_PMG_CST_CONFIG_L2_SHRINK_THRESHOLD_MASK (BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define B_EFI_MSR_PMG_CST_CONFIG_EIST_HARWARE_COORDINATION BIT11
+#define B_EFI_MSR_PMG_CST_CONFIG_STPGNT_ISSUE BIT9
+#define B_EFI_MSR_PMG_CST_CONFIG_C4VID_DISABLE BIT7
+#define B_EFI_MSR_PMG_CST_CONFIG_CSM_TRIGGER_MASK (BIT6 | BIT5 | BIT4)
+
+#define EFI_MSR_PMG_IO_BASE_ADDR 0x000000E3
+#define B_EFI_MSR_PMG_IO_BASE_ADDR_PMB1_MASK 0xFFFF0000
+#define B_EFI_MSR_PMG_IO_BASE_ADDR_PMB0_MASK 0x0000FFFF
+
+#define B_EFI_MSR_PMG_IO_CAPTURE_ADDR_CST_RANGE (BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+
+#define EFI_BBL_CR_CTL3 0x0000011E
+#define B_EFI_BBL_CR_CTL3_L2_WAY_SHRINK_MIN (BIT31 | BIT30)
+#define B_EFI_BBL_CR_CTL3_L2_WAY_SHRINK_RATE (BIT29 | BIT28)
+#define B_EFI_BBL_CR_CTL3_L2_WAY_CHUNK_SIZE (BIT27 | BIT26 | BIT25)
+#define B_EFI_BBL_CR_CTL3_L2_REDUCTION_CONF_LOCK BIT24
+#define B_EFI_BBL_CR_CTL3_L2_NOT_PRESENT BIT23
+#define B_EFI_BBL_CR_CTL3_SIZE_OF_WAY (BIT17 | BIT16 | BIT15 | BIT14 | BIT13)
+#define B_EFI_BBL_CR_CTL3_L2_ENABLED BIT8
+#define B_EFI_BBL_CR_CTL3_NUMBER_OF_WAYS (BIT4 | BIT3 | BIT2 | BIT1)
+#define B_EFI_BBL_CR_CTL3_L2_HW_ENABLED BIT0
+
+#define B_EFI_MSR_CLOCK_FLEX_MAX_FLEX_RATIO_PINEVIEW (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_MSR_CLOCK_FLEX_MAX_FLEX_VID (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#ifndef EFI_MSR_IA32_PERF_STS
+#define EFI_MSR_IA32_PERF_STS 0x00000198
+#endif
+
+#define B_EFI_MSR_IA32_PERF_STS_BUS_RATIO_BOOT (BIT60 | BIT59 | BIT58 | BIT57 | BIT56)
+#define B_EFI_MSR_IA32_PERF_STS_VID_BOOT (BIT53 | BIT52 | BIT51 | BIT50 | BIT49 | BIT48)
+#define B_EFI_MSR_IA32_PERF_STS_BUS_RATIO_MAX (BIT44 | BIT43 | BIT42 | BIT41 | BIT40)
+#define B_EFI_MSR_IA32_PERF_STS_VID_MAX (BIT37 | BIT36 | BIT35 | BIT34 | BIT33 | BIT32)
+#define N_EFI_MSR_IA32_PERF_STS_BUT_RATIO_MIN 24
+#define B_EFI_MSR_IA32_PERF_STS_BUT_RATIO_MIN_MASK (BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define B_EFI_MSR_IA32_PERF_STS_TS BIT21
+#define B_EFI_MSR_IA32_PERF_STS_CMD_SEEK BIT20
+#define B_EFI_MSR_IA32_PERF_STS_THERM_THROT BIT19
+#define B_EFI_MSR_IA32_PERF_STS_TT BIT18
+#define B_EFI_MSR_IA32_PERF_STS_VIP BIT17
+#define B_EFI_MSR_IA32_PERF_STS_FIP BIT16
+#define B_EFI_MSR_IA32_PERF_STS_BUS_RATIO_STS (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_EFI_MSR_IA32_PERF_STS_BUS_RATIO_STS 8
+#define B_EFI_MSR_IA32_PERF_STS_VID_STS (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#ifndef EFI_MSR_IA32_PERF_CTRL
+#define EFI_MSR_IA32_PERF_CTRL 0x00000199
+#endif
+
+
+#define B_EFI_MSR_IA32_PERF_CTRL_BUS_RATIO_SEL (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_MSR_IA32_PERF_CTRL_VID_SEL (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#define EFI_MSR_THERM2_CTL 0x0000019D
+#define B_EFI_MSR_THERM2_CTL_BUS_RATIO_THROT (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_MSR_THERM2_CTL_VID_THROT (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#ifndef EFI_MSR_IA32_MISC_ENABLE
+#define EFI_MSR_IA32_MISC_ENABLE 0x000001A0
+#endif
+#define B_EFI_MSR_IA32_MISC_ENABLE_HARD_C4E_EN BIT33
+#define B_EFI_MSR_IA32_MISC_ENABLE_C4E_EN BIT32
+#define B_EFI_MSR_IA32_MISC_ENABLE_C2E_EN BIT26
+#define B_EFI_MSR_IA32_MISC_ENABLE_C1E_EN BIT25
+#define B_EFI_MSR_IA32_MISC_ENABLE_FORCEPR_INPUT_EN BIT21
+#define B_EFI_MSR_IA32_MISC_ENABLE_EIST_LOCK BIT20
+#define B_EFI_MSR_IA32_MISC_ENABLE_BI_DIRECTIONAL_PROCHOT_EN BIT17
+#define B_EFI_MSR_IA32_MISC_ENABLE_TM2_EN BIT13
+#define B_EFI_MSR_IA32_MISC_ENABLE_FERR_MULTIPLEXING_EN BIT10
+
+#ifndef EFI_MSR_PIC_SENS_CFG
+#define EFI_MSR_PIC_SENS_CFG 0x000001AA
+#endif
+#define B_EFI_MSR_PIC_SENS_CFG_LOCK_THERMAL_INT BIT22
+#define B_EFI_MSR_PIC_SENS_CFG_LOCK_TM1 BIT21
+#define B_EFI_MSR_PIC_SENS_CFG_TM1_ON_TM2 BIT20
+#define B_EFI_MSR_PIC_SENS_CFG_CONVERSION_TIME (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_EFI_MSR_PIC_SENS_CFG_BYPASS_FILTER BIT4
+
+#ifndef MSR_PLATFORM_INFO
+#define MSR_PLATFORM_INFO 0xCE
+#endif
+#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED BIT37
+#define B_PLATFORM_INFO_MAX_NON_TURBO_LIM_RATIO (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_PLATFORM_INFO_MAX_NON_TURBO_LIM_RATIO 8
+#define B_PLATFORM_INFO_MAX_EFFICIENCY_RATIO (BIT47 | BIT46 | BIT45 | BIT44 | BIT43 | BIT42 | BIT41 | BIT40)
+#define N_PLATFORM_INFO_MAX_EFFICIENCY_RATIO 40
+
+#ifndef MSR_IACORE_RATIOS
+#define MAX_RATIO_4C_OFFSET 24
+#define MAX_RATIO_3C_OFFSET 16
+#define MAX_RATIO_2C_OFFSET 8
+#define MAX_RATIO_1C_OFFSET 0
+#define MAX_RATIO_1C_MASK 0x000000ff
+#define MAX_RATIO_2C_MASK 0x0000ff00
+#define MAX_RATIO_3C_MASK 0x00ff0000
+#define MAX_RATIO_4C_MASK 0xff000000
+#define MAX_VID_4C_OFFSET 24
+#define MAX_VID_3C_OFFSET 16
+#define MAX_VID_2C_OFFSET 8
+#define MAX_VID_1C_OFFSET 0
+#define MAX_RATIO_1C_MASK 0x000000ff
+#define MAX_RATIO_2C_MASK 0x0000ff00
+#define MAX_RATIO_3C_MASK 0x00ff0000
+#define MAX_RATIO_4C_MASK 0xff000000
+
+#define MSR_PM_CFG_CTRL 0xE2
+#define C0_SUB_STATES_MASK 0x0000000f
+#define C1_SUB_STATES_MASK 0x000000f0
+#define C2_SUB_STATES_MASK 0x00000f00
+#define C3_SUB_STATES_MASK 0x0000f000
+#define C4_SUB_STATES_MASK 0x000f0000
+#define C5_SUB_STATES_MASK 0x00f00000
+#define C6_SUB_STATES_MASK 0x0f000000
+#define C7_SUB_STATES_MASK 0xf0000000
+#define CSTATE_LIMIT_MASK 0xF
+#define CSTATE_LIMIT_NO_LIMIT 0x0
+#define CSTATE_LIMIT_C1 0x0
+#define CSTATE_LIMIT_C3 0x0
+#define CSTATE_LIMIT_C6 0x1
+#define CSTATE_LIMIT_C7 0x1
+#define CSTATE_LIMIT_C7S 0x1
+#define CSTATE_LIMIT_C8 0x2
+#define CSTATE_LIMIT_C9 0x2
+#define CSTATE_LIMIT_C10 0x2
+#define B_TIMED_MWAIT_ENABLE BIT31
+#define B_SINGLE_PCTL (1 << 11)
+//
+// Turbo
+//
+#define MAX_RATIO_LIMIT_4C_OFFSET 24
+#define MAX_RATIO_LIMIT_3C_OFFSET 16
+#define MAX_RATIO_LIMIT_2C_OFFSET 8
+#define MAX_RATIO_LIMIT_1C_OFFSET 0
+#define MAX_RATIO_LIMIT_MASK1 0x000000ff
+#define MAX_RATIO_LIMIT_MASK2 0x0000ff00
+#define MAX_RATIO_LIMIT_MASK3 0x00ff0000
+#define MAX_RATIO_LIMIT_MASK4 0xff000000
+#define TURBO_DISABLE_MASK ((UINT64)1 << 38)
+#define TURBO_MODE_DISABLE_BIT 38
+//
+// P-State
+//
+#define MSR_CLOCK_FLEX_MAX MSR_FLEX_RATIO
+#define ENABLE_FLEX (1 << 16)
+#define RATIO_FLEX_BYTE_MASK 0xFF // Bits 15:8
+#define RATIO_FLEX_EN_MASK 0x0000000000010000 // Clear all but bit 16
+#define MAX_NON_TURBO_MASK 0x000000000000FF00
+#define MAX_EFFICIENCY_MASK 0x0000FF0000000000
+//
+// ACPI P-State Coordination Type
+//
+#define PSD_SW_ALL 0xfc
+#define PSD_SW_ANY 0xfd
+#define PSD_HW_ALL 0xfe
+#endif
+//-----------------------------------------------------------------------------
+// Thermal Management Registers
+//-----------------------------------------------------------------------------
+#define EFI_MSR_IA32_CR_THERM_INTERRUPT 0x19b
+#define EFI_MSR_IA32_CR_THERM_STATUS 0x19c
+#define EFI_MSR_CPU_THERM_TEMPERATURE 0x1a2
+
+
+#define EFI_MSR_PKGC6_IRTL 0x60B
+#define EFI_MSR_PKGC7_IRTL 0x60C
+#define EFI_MSR_TURBO_POWER_LIMIT 0x610
+#define EFI_MSR_PACKAGE_POWER_SKU 0x614
+#define STOP_ENABLE (1 << 19)
+#define CURRENT_LIMIT_MASK 0x1FFF // Bits 12:0
+
+#define EFI_MSR_PRIMARY_PLANE_TURBO_POWER_LIMIT 0x638
+#define EFI_MSR_SECONDARY_PLANE_TURBO_POWER_LIMIT 0x640
+#define PLANE_POWER_LIMIT_MASK (0x7FFF)
+#define PLANE_POWER_LIMIT_ENABLE (1 << 15)
+#define PLANE_POWER_LIMIT_TIME_MASK (0x7F)
+#define PLANE_POWER_LIMIT_TIME_OFFSET 17
+#define PLANE_POWER_LIMIT_LOCK (1 << 31)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPlatformLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPlatformLib.h
new file mode 100644
index 0000000000..02c813dc33
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPlatformLib.h
@@ -0,0 +1,89 @@
+/** @file
+ Header file for CpuPlatform Lib.
+
+ 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 _CPU_PLATFORM_LIB_H_
+#define _CPU_PLATFORM_LIB_H_
+
+#include <CpuRegs.h>
+#include <CpuDataStruct.h>
+
+/**
+ Check CPU Type of the platform
+
+ @retval CPU_FAMILY CPU type
+
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+ VOID
+ );
+
+/**
+ Return Cpu stepping type
+
+ @retval CPU_STEPPING Cpu stepping type
+
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+ VOID
+ );
+
+/**
+ Returns the processor microcode revision of the processor installed in the system.
+
+ @retval Processor Microcode Revision
+
+**/
+UINT32
+GetCpuUcodeRevision (
+ VOID
+ );
+
+/**
+ Check if this microcode is correct one for processor
+
+ @param[in] Cpuid Processor CPUID
+ @param[in] MicrocodeEntryPoint Entry point of microcode
+ @param[in] Revision Revision of microcode
+
+ @retval CorrectMicrocode If this microcode is correct
+
+**/
+BOOLEAN
+CheckMicrocode (
+ IN UINT32 Cpuid,
+ IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+ IN UINT32 *Revision
+ );
+
+/**
+ This function will set and lock PRMRR which is required to be locked before enabling normal mode
+ for memory.
+
+ @param[in] PrmrrBase Base address of PRMRR range. Must be naturally algined
+ @param[in] PrmrrSize Size of the PRMRR range in Bytes
+
+**/
+VOID
+SetUncorePrmrr (
+ IN UINT32 PrmrrBase,
+ IN UINT32 PrmrrSize
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPolicyLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPolicyLib.h
new file mode 100644
index 0000000000..9ce0325829
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPolicyLib.h
@@ -0,0 +1,67 @@
+/** @file
+ Prototype of the CpuPolicy 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.
+
+**/
+
+#ifndef _CPU_POLICY_LIB_H_
+#define _CPU_POLICY_LIB_H_
+
+#include <Ppi/CpuPolicy.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock.h>
+
+/**
+ Print whole CPU_POLICY_PPI and serial out.
+
+ @param[in] SiCpuPolicyPpi The RC Policy PPI instance
+
+**/
+VOID
+CpuPrintPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ );
+
+/**
+ CreateCpuConfigBlocks creates the Config Blocks for CPU Policy.
+
+ @param[in, out] SiCpuPolicyPpi The pointer to get CPU Policy PPI instance
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CreateCpuConfigBlocks (
+ IN OUT SI_CPU_POLICY_PPI **SiCpuPolicyPpi
+ );
+
+/**
+ CpuInstallPolicyPpi installs SiCpuPolicyPpi.
+ While installed, RC assumes the Policy is ready and finalized. So please update and override
+ any setting before calling this function.
+
+ @param[in] SiCpuPolicyPpi The pointer to PEI Cpu Policy PPI instance
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ );
+
+#endif // _PEI_CPU_POLICY_LIB_H_
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h
new file mode 100644
index 0000000000..c4efb1f0da
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h
@@ -0,0 +1,55 @@
+/** @file
+ Header file for CpuRng Lib.
+
+ 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 _CPU_RNG_LIB_H_
+#define _CPU_RNG_LIB_H_
+
+/**
+ Gets a random number from the CPU's 16 bits random number.
+
+ @param[out] UINT16 Random value
+
+**/
+UINT16
+EFIAPI
+GetRandomNumber16 (
+ VOID
+ );
+
+/**
+ Gets a random number from the CPU's 32 bits random number.
+
+ @param[out] UINT32 Random value
+
+**/
+UINT32
+EFIAPI
+GetRandomNumber32 (
+ VOID
+ );
+
+/**
+ Gets a random number from the CPU's 64 bits random number and only in 64 bits environment.
+
+ @param[out] UINT64 Random value
+
+**/
+UINT64
+EFIAPI
+GetRandomNumber64 (
+ VOID
+ );
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h
new file mode 100644
index 0000000000..4eae2c81e8
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h
@@ -0,0 +1,52 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _BIOS_GUARD_CONFIG_H_
+#define _BIOS_GUARD_CONFIG_H_
+
+#include "BiosGuardDefinitions.h"
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gBiosGuardConfigGuid;
+
+#pragma pack(push, 1)
+
+#define BIOS_GUARD_CONFIG_REVISION 1
+
+/**
+ Platform policies for BIOS Guard Configuration for all processor security features configuration.
+ Platform code can pass relevant configuration data through this structure.
+ @note The policies are marked are either <b>(Required)</b> or <b>(Optional)</b>
+ - <b>(Required)</b> : This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization
+ - <b>(Optional)</b> : This policy is recommended for validation purpose only.
+**/
+typedef struct {
+ CONFIG_BLOCK_HEADER Header; ///< Offset 0 GUID number for main entry of config block
+ BGUP_HEADER BgupHeader; ///< BIOS Guard update package header that will be packaged along with BIOS Guard script and update data.
+ BGPDT Bgpdt; ///< BIOS Guard Platform Data Table contains all the platform data that will be parsed by BIOS Guard module.
+ UINT64 BgpdtHash[4]; ///< Hash of the BGPDT that will be programmed to PLAT_FRMW_PROT_HASH_0/1/2/3 MSR.
+ UINT8 EcCmdDiscovery; ///< EC Command discovery.
+ UINT8 EcCmdProvisionEav; ///< EC Command Provision Eav.
+ UINT8 EcCmdLock; ///< EC Command Lock.
+ UINT8 Rsvd; ///< Reserved for DWORD alignment.
+ BIOSGUARD_LOG BiosGuardLog; ///< BIOS Guard log.
+} BIOS_GUARD_CONFIG;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h
new file mode 100644
index 0000000000..8e59736b37
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h
@@ -0,0 +1,141 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _CPU_CONFIG_H_
+#define _CPU_CONFIG_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gCpuConfigGuid;
+
+#pragma pack(push, 1)
+
+//
+// CPU_CONFIG revisions
+//
+#define CPU_CONFIG_REVISION 1
+
+///
+/// Enums for EC Command Type
+///
+typedef enum {
+ SendEcCmds = 1,
+ SendEcValue,
+ ReceiveEcValue,
+ EcCmdMax
+} EC_COMMAND_TYPE;
+
+/**
+ This function is for platform code to provide EC Commands since different BIOS might have different EC.
+ Platform code need to provide a function for CPU code to call to communicate with EC.
+
+ @param[in] This Driver context.
+ @param[in] EcCmdType EC Command Type.
+ @param[in] EcCmd EC Command Byte to send.
+ @param[in] SendData EC Data Byte to send.
+ @param[in] ReceiveData EC Data Byte received.
+
+ @retval EFI_SUCCESS Command Read/ Write Success
+ @retval EFI_DEVICE_ERROR Command Read/ Write Error
+ @retval EFI_OUT_OF_RESOURCES No enough resources (such as out of memory).
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLATFORM_SEND_EC_COMMAND) (
+ IN EC_COMMAND_TYPE EcCmdType,
+ IN UINT8 EcCmd,
+ IN UINT8 SendData,
+ IN OUT UINT8 *ReceiveData
+ );
+
+///
+/// Platform Specific Socket Information
+///
+typedef struct {
+ EFI_PHYSICAL_ADDRESS SocketDesignation;
+ EFI_PHYSICAL_ADDRESS SerialNumber;
+ EFI_PHYSICAL_ADDRESS AssetTag;
+ EFI_PHYSICAL_ADDRESS PartNumber;
+ UINT16 MaxSpeed;
+ UINT8 ProcessorUpgrade;
+ UINT8 Rsvd;
+} SMBIOS_SOCKET_INFO;
+
+/**
+ Platform Policies for CPU features configuration Platform code can enable/disable/configure features through this structure.
+ @note The policies are marked are either <b>(Required)</b> or <b>(Optional)</b>.
+ - <b>(Required)</b>: This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization.
+ - <b>(Optional)</b>: This policy is recommended for validation purpose only.
+**/
+typedef struct {
+ CONFIG_BLOCK_HEADER Header; ///< Offset 0 GUID number for main entry of config block
+ //
+ // Bit definition for functionality enable/disable.
+ //
+ UINT32 HyperThreading : 1; ///< <b>(Optional)</b> Enable or Disable Hyper Threading; 0: Disable; <b>1: Enable</b>.
+ UINT32 VmxEnable : 1; ///< <b>(Optional)</b> Enable or Disable VMX; 0: Disable; <b>1: Enable</b>.
+ UINT32 MlcStreamerPrefetcher : 1; ///< <b>(Optional)</b> Enable or Disable MLC Streamer Prefetcher; 0: Disable; <b>1: Enable</b>.
+ UINT32 MlcSpatialPrefetcher : 1; ///< <b>(Optional)</b> Enable or Disable MLC Spatial Prefetcher; 0: Disable; <b>1: Enable</b>.
+ UINT32 SmxEnable : 1; ///< <b>(Optional)</b> Enable or Disable Secure Mode Extensions feature; 0: Disable; <b>1: Enable</b>.
+ UINT32 MonitorMwaitEnable : 1; ///< <b>(Optional)</b> Enable or Disable Monitor /MWAIT instructions; 0: Disable; <b>1: Enable</b>.
+ UINT32 MachineCheckEnable : 1; ///< <b>(Optional)</b> Enable or Disable initialization of machine check registers; 0: Disable; <b>1: Enable</b>.
+ UINT32 AesEnable : 1; ///< <b>(Optional)</b> Enable or Disable Advanced Encryption Standard (AES) feature; 0: Disable; <b>1: Enable</b>.
+ UINT32 DebugInterfaceEnable : 1; ///< <b>(Optional)</b> Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+ UINT32 DebugInterfaceLockEnable : 1; ///< <b>(Optional)</b> Lock or Unlock debug interface features; 0: Disable; <b>1: Enable</b>.
+ /**
+ <b>(Required)</b> Policies to obtain CPU temperature.
+ - <b>0: ACPI thermal management uses EC reported temperature values</b>.
+ - 1: ACPI thermal management uses DTS SMM mechanism to obtain CPU temperature values.
+ - 2: ACPI Thermal Management uses EC reported temperature values and DTS SMM is used to handle Out of Spec condition.
+ **/
+ UINT32 EnableDts : 2;
+ UINT32 ApIdleManner : 2; ///< <b>(Optional)</b> AP Idle Manner of waiting for SIPI; <b>1: HALT loop</b>; 2: MWAIT loop; 3: RUN loop.
+ UINT32 ApHandoffManner : 2; ///< <b>(Debug)</b> Settings for AP Handoff to OS; <b>1: HALT loop</b>; 2: MWAIT loop.
+ UINT32 ActiveProcessorCores : 3; ///< <b>(Debug)</b> Number of active cores. <b>0: All</b>.
+ UINT32 DisableCore1 : 1; ///< <b>(Debug)</b> Enable/Disable Core 1 <b>
+ UINT32 DisableCore2 : 1; ///< <b>(Debug)</b> Enable/Disable Core 2 <b>
+ UINT32 DisableCore3 : 1; ///< <b>(Debug)</b> Enable/Disable Core 3 <b>
+ /**
+ <b>(Debug)</b> Processor Early Power On Configuration FCLK setting.
+ - <b>0: 800 MHz (ULT/ULX)</b>.
+ - <b>1: 1 GHz (DT/Halo)</b>
+ - 2: 400 MHz.
+ - 3: Reserved.
+ **/
+ UINT32 FClkFrequency : 2;
+ UINT32 JtagC10PowerGateDisable : 1; ///< <b>(Debug)</b> Power JTAG in C10 and deeper power states; <b>0: Disable</b>; 1: Enable.
+ UINT32 ProcTraceOutputScheme : 1; ///< <b>(Debug)</b> Control on Processor Trace output scheme; <b>0: Single Range Output</b>; 1: ToPA Output.
+ UINT32 ProcTraceEnable : 1; ///< <b>(Debug)</b> Enable or Disable Processor Trace feature; <b>0: Disable</b>; 1: Enable.
+ UINT32 ThreeStrikeCounterDisable : 1; ///< <b>(Debug)</b> Disable Three strike counter; <b>0: Enable counter</b>; 1: Disable counter.
+ UINT32 VoltageOptimizer : 1; ///< <b>(Optional)</b> Enable or Disable Voltage Optimizer feature <b>0: Disable</b>; 1: Enable
+ UINT32 FlashWearOutProtection : 1; ///< Flash Wear-out Protection; <b>0: Disable</b>; 1: Enable
+ UINT32 SkipMpInit : 2; /// < For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if enabled. For non-FSP, this should always be 0.
+ UINT32 PackageDts : 1; ///< <b>(Debug)</b> Power JTAG in C10 and deeper power states; <b>0: Disable</b>; 1: Enable.
+ UINT32 RsvdBits :31; ///< Bits reserved for DWORD alignment.
+ UINT8 CpuRatio; ///< <b>(Debug)</b> CPU ratio value.
+ UINT8 SmmbaseSwSmiNumber; ///< <b>(Required)</b> Software SMI Number from Smbase.
+ UINT8 ProcTraceMemSize; ///< <b>(Optional)</b> Memory region allocation for Processor Trace, allowed range is from 4K (0x0) to 128MB (0xF); <b>0xFF: Disable</b>.
+ UINT8 Rsvd; ///< Reserved for DWORD alignment.
+ EFI_PHYSICAL_ADDRESS MicrocodePatchAddress; ///< <b>(Required)</b> Platform code provides the address of the correct microcode patch.
+ PLATFORM_SEND_EC_COMMAND SendEcCmd; ///< Platform code can provide interface to communicate with EC through this function.
+ EFI_PHYSICAL_ADDRESS SmbiosSocketInfo; ///< This points to SMBIOS_SOCKET_INFO structure which is used to fill in the socket-related info for SMBIOS table type 4.
+} CPU_CONFIG;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h
new file mode 100644
index 0000000000..e75d5cbbf2
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h
@@ -0,0 +1,51 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _CPU_CONFIG_PREMEM_H_
+#define _CPU_CONFIG_PREMEM_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gCpuConfigPreMemGuid;
+
+#pragma pack(push, 1)
+
+//
+// CPU_CONFIG_PREMEM revisions
+//
+#define CPU_CONFIG_PREMEM_REVISION 1
+
+/**
+ Platform Policies for CPU features configuration Platform code can enable/disable/configure features through this structure.
+
+**/
+typedef struct {
+ CONFIG_BLOCK_HEADER Header; ///< Offset 0 GUID number for main entry of config block
+ UINT32 BistOnReset : 1; ///< Enable or Disable BIST on Reset; <b>0: Disable</b>; 1 Enable.
+ UINT32 Txt : 1; ///< Enable or Disable TXT; <b>0: Disable</b>; 1: Enable.
+ UINT32 SkipStopPbet : 1; ///< Skip Stop PBET Timer <b>0: Disabled</b>, 1: Enabled
+ UINT32 BiosGuard : 1; ///< Enable or Disable BIOS Guard; 0: Disable, <b>1:Enable</b>
+ UINT32 EnableC6Dram : 1; ///< C6DRAM Memory. <b>0: C6DRAM Disabled</b>; 1: C6DRAM Enabled.
+ UINT32 FlashWearOutProtection : 1; ///< Flash Wear-Out Protection; <b>0: Disable</b>; 1: Enable
+ UINT32 RsvdBits :25; ///< Bits reserved for DWORD alignment.
+ UINT16 TotalFlashSize; ///< Total Flash Size on the system in KB
+ UINT16 BiosSize; ///< BIOS Size in KB
+} CPU_CONFIG_PREMEM;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuOverclockingConfig.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuOverclockingConfig.h
new file mode 100644
index 0000000000..0fdb00fe73
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuOverclockingConfig.h
@@ -0,0 +1,52 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _CPU_OVERCLOCKING_CONFIG_H_
+#define _CPU_OVERCLOCKING_CONFIG_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gCpuOverclockingConfigGuid;
+
+#pragma pack(push, 1)
+
+#define CPU_OVERCLOCKING_CONFIG_REVISION 1
+
+/**
+ Overclocking Configuration controls which use the CPU overclocking mailbox interface are defined in this structure.
+ Platform code can pass in data to the mailbox through this structure.
+
+**/
+typedef struct {
+ CONFIG_BLOCK_HEADER Header; ///< Offset 0 GUID number for main entry of config block
+ UINT32 CoreVoltageMode : 1; ///< Core voltage mode; <b>0: Adaptive</b>; 1: Override.
+ UINT32 RingVoltageMode : 1; ///< CLR voltage mode; <b>0: Adaptive</b>; 1:Override
+ UINT32 OcSupport : 1; ///< Over clocking support; <b>0: Disable</b>; 1: Enable.
+ UINT32 RsvdBits : 29; ///< Bits reserved for DWORD alignment.
+ INT16 CoreVoltageOffset; ///< The voltage offset applied to the core while operating in turbo mode.
+ UINT16 CoreVoltageOverride; ///< The core voltage override which is applied to the entire range of cpu core frequencies.
+ UINT16 CoreExtraTurboVoltage; ///< Extra Turbo voltage applied to the cpu core when the cpu is operating in turbo mode.
+ UINT16 CoreMaxOcTurboRatio; ///< Maximum core turbo ratio override allows to increase CPU core frequency beyond the fused max turbo ratio limit.
+ INT16 RingVoltageOffset; ///< The voltage offset applied to CLR while operating in turbo mode.
+ UINT16 RingVoltageOverride; ///< The clr voltage override which is applied to the entire range of cpu frequencies.
+ UINT16 RingExtraTurboVoltage; ///< Extra Turbo voltage applied to clr.
+ UINT16 RingMaxOcTurboRatio; ///< Maximum clr turbo ratio override allows to increase CPU clr frequency beyond the fused max turbo ratio limit.
+} CPU_OVERCLOCKING_CONFIG;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h
new file mode 100644
index 0000000000..70545c6384
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h
@@ -0,0 +1,54 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _CPU_POLICY_PPI_H_
+#define _CPU_POLICY_PPI_H_
+
+#include <ConfigBlock.h>
+#include <CpuAccess.h>
+#include <CpuDataStruct.h>
+#include <Ppi/BiosGuardConfig.h>
+#include <Ppi/CpuConfigPreMem.h>
+#include <Ppi/CpuConfig.h>
+#include <Ppi/CpuOverclockingConfig.h>
+#include <Ppi/PowerMgmtConfig.h>
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gSiCpuPolicyPpiGuid;
+
+#pragma pack(1)
+
+//
+// SI_CPU_POLICY_PPI revisions
+//
+#define SI_CPU_POLICY_PPI_REVISION 1
+
+/**
+ The PPI allows the platform code to publish a set of configuration information that the
+ CPU drivers will use to configure the processor in the PEI phase.
+ This Policy PPI needs to be initialized for CPU configuration.
+ @note The PPI has to be published before processor PEIMs are dispatched.
+
+**/
+typedef struct {
+ CONFIG_BLOCK_TABLE_HEADER ConfigBlockTableHeader;
+} SI_CPU_POLICY_PPI;
+
+#pragma pack()
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h
new file mode 100644
index 0000000000..1038ac2c1f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h
@@ -0,0 +1,167 @@
+/** @file
+ CPU policy PPI produced by a platform driver specifying various
+ expected CPU settings. This PPI is consumed by CPU PEI modules.
+
+ 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 _POWER_MGMT_CONFIG_H_
+#define _POWER_MGMT_CONFIG_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gPowerMgmtConfigGuid;
+
+#pragma pack(push, 1)
+
+#define POWER_MGMT_CONFIG_REVISION 1
+
+///
+/// Define maximum number of custom ratio states supported
+///
+#define MAX_CUSTOM_RATIO_TABLE_ENTRIES 20
+
+///
+/// PPM Package C State Limit
+///
+typedef enum {
+ PkgC0 = 0,
+ PkgC1,
+ PkgC2,
+ PkgCpuDefault = 254
+} MAX_PKG_C_STATE;
+
+///
+/// Custom Power Uints.User can choose to enter in MilliWatts or Watts
+///
+typedef enum {
+ PowerUnitWatts = 0, ///< in Watts
+ PowerUnit125MilliWatts, ///< in 125 Milli Watts. Example 11.250 W Value to use for Power limits 90
+ PowerUnitMax
+} CUSTOM_POWER_UNIT;
+
+/**
+ Power management Configuration for all Processor Power Management Features
+ Configs are in this field. Platform code can enable/disable features through this field.
+ @note The policies are marked are either <b>(Required)</b> or <b>(Optional)</b>.
+ - <b>(Required)</b>: This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization.
+ - <b>(Optional)</b>: This policy is recommended for validation purpose only.
+**/
+typedef struct {
+ CONFIG_BLOCK_HEADER Header; ///< Offset 0 GUID number for main entry of config block
+ UINT32 Eist : 1; ///< <b>(Test)</b> Enable or Disable Intel SpeedStep Technology. 0: Disable; <b>1: Enable</b>
+ UINT32 Cx : 1; ///< <b>(Test)</b> Enable or Disable CPU power states (C-states). 0: Disable; <b>1: Enable</b>
+ UINT32 C1e : 1; ///< <b>(Test)</b> Enable or Disable Enhanced C-states. 0: Disable; <b>1: Enable</b>
+ UINT32 C1AutoDemotion : 1; ///< <b>(Test)</b> Enable or Disable C6/C7 auto demotion to C1. 0: Disabled; <b>1: C1 Auto demotion</b>;
+ UINT32 C3AutoDemotion : 1; ///< <b>(Test)</b> Enable or Disable C6/C7 auto demotion to C3 0: Disabled; <b>1: C3 Auto demotion</b>;
+ UINT32 TurboMode : 1; ///< <b>(Test)</b> Enable or Disable long duration Turbo Mode. Disable; <b>1: Enable</b>
+ UINT32 PowerLimit2Enable : 1; ///< Enable or Disable short duration Turbo Mode. Disable; <b>1: Enable</b>
+ UINT32 C1UnDemotion : 1; ///< Enable or Disable C1UnDemotion. 0: Disabled; <b>1: C1 Auto undemotion</b>;
+ UINT32 C3UnDemotion : 1; ///< <b>(Test)</b> Enable or Disable C3UnDemotion. 0: Disabled; <b>1: C3 Auto undemotion</b>;
+ UINT32 PkgCStateDemotion : 1; ///< <b>(Test)</b> Enable or Disable Package Cstate Demotion. <b>Disable</b>; 1: Enable
+ UINT32 PkgCStateUnDemotion : 1; ///< <b>(Test)</b> Enable or Disable Package Cstate UnDemotion. <b>Disable</b>; 1: Enable
+ UINT32 TimedMwait : 1; ///< <b>(Test)</b> Enable or Disable TimedMwait Support. <b>Disable</b>; 1: Enable
+ UINT32 PlatformPowerLimit1 : 1; ///< MSR 0x65C[15]: PL1 Enable activates the PL1 value to limit average platform power
+ UINT32 PlatformPowerLimit2 : 1; ///< MSR 0x65C[47]: PL2 Enable activates the PL2 value to limit average platform power
+ UINT32 SkipSetBootPState : 1; ///< Choose whether to skip SetBootPState function for all APs; <b>0: Do not skip</b>; 1: Skip.
+ UINT32 TurboPowerLimitLock : 1; ///< MSR 0x610[63] and 0x618[63]: Lock all Turbo settings; <b>0: Disable</b>; 1: Enable.
+ UINT32 PowerLimit3Lock : 1; ///< Package PL3 MSR 615h lock; <b>0: Disable</b>; 1: Enable.
+ UINT32 PowerLimit4Lock : 1; ///< Package PL4 MSR 601h lock; <b>0: Disable</b>; 1: Enable.
+ UINT32 PowerLimit3DutyCycle : 8; ///< Package PL3 Duty Cycle; <b>0</b>.
+ UINT32 PowerLimit1Enable : 1; ///< Enable or Disable long duration Turbo Mode
+ UINT32 PowerLimit1ClampEnable : 1; ///< Enable or Disable clamp mode for long duration Turbo
+ UINT32 Rsvd1Bits : 4; ///< Bits reserved for DWORD alignment.
+ UINT32 PlatformPowerLimit1Time : 8; ///< MSR 0x65C[23:17]: PL1 timewindow in seconds.
+ UINT32 PmgCstCfgCtrIoMwaitRedirection : 1; ///< <b>(Test)</b> Enable or Disable IO to MWAIT redirection; <b>0: Disable</b>; 1: Enable.
+ UINT32 PmgCstCfgCtrlLock : 1; ///< <b>(Test)</b> If enabled, sets MSR 0xE2[15]; 0: Disable; <b>1: Enable</b>.
+ UINT32 ProcHotLock : 1; ///< <b>(Test)</b> If enabled, sets MSR 0x1FC[23]; <b>0: Disable</b>; 1: Enable.
+ UINT32 BiProcHot : 1; ///< <b>(Test)</b> Enable or Disable Bi-Directional PROCHOT#; 0: Disable; <b>1: Enable</b>.
+ UINT32 TStates : 1; ///< <b>(Test)</b> Enable or Disable T states; <b>0: Disable</b>; 1: Enable.
+ UINT32 DisableProcHotOut : 1; ///< <b>(Test)</b> Enable or Disable PROCHOT# signal being driven externally; 0: Disable; <b>1: Enable</b>.
+ UINT32 DisableVrThermalAlert : 1; ///< <b>(Test)</b> Enable or Disable VR Thermal Alert; <b>0: Disable</b>; 1: Enable.
+ UINT32 ProcHotResponse : 1; ///< <b>(Test)</b> Enable or Disable PROCHOT# Response; <b>0: Disable</b>; 1: Enable.
+ UINT32 AutoThermalReporting : 1; ///< <b>(Test)</b> Enable or Disable Thermal Reporting through ACPI tables; 0: Disable; <b>1: Enable</b>.
+ UINT32 ThermalMonitor : 1; ///< <b>(Test)</b> Enable or Disable Thermal Monitor; 0: Disable; <b>1: Enable</b>.
+ UINT32 EnableCCx : 1; ///< <b>(Optional)</b> Max Core Cstate, fused value
+ UINT32 UnlimitedCstate : 1; ///< <b>(Optional)</b> Max Core Cstate, no limit
+ UINT32 EnableC1 : 1; ///< <b>(Optional)</b> Max Core Cstate, C1
+ UINT32 EnableC3 : 1; ///< <b>(Optional)</b> Max Core Cstate, C3
+ UINT32 EnableC6 : 1; ///< <b>(Optional)</b> Max Core Cstate, C6
+ UINT32 EnableC7 : 1; ///< <b>(Optional)</b> Max Core Cstate, C7
+ UINT32 EnableC8 : 1; ///< <b>(Optional)</b> Max Core Cstate, C8
+ UINT32 EnableC9 : 1; ///< <b>(Optional)</b> Max Core Cstate, C9
+ UINT32 EnableC10 : 1; ///< <b>(Optional)</b> Max Core Cstate, C10
+ UINT32 BootPState : 1; ///< <b>(Optional)</b> Boot PState with HFM or LFM. 0: HFM; <b>1: LFM</b>;
+ UINT32 VrConfig : 1; ///< <b>(Optional)</b> Enable or Disable VR Config for VCC and VNN Rails; <b>0: Disable</b>; 1: Enable.
+ UINT32 Rsvd2Bits : 3; ///< Bits reserved for DWORD alignment.
+ UINT16 CustomPowerLimit1; ///< Custom Package Long duration turbo mode power limit in 1/8 watt units.
+ UINT16 CustomPowerLimit1Time; ///< Custom Package Long duration turbo mode time window in seconds.
+ UINT16 PowerLimit1; ///< Package Long duration turbo mode power limit in 1/8 watt units.
+ UINT16 PowerLimit2; ///< Package Short duration turbo mode power limit in 1/8 watt units.
+ UINT16 PowerLimit3; ///< Package PL3 power limit in 1/8 watt units.
+ UINT16 PowerLimit4; ///< Package PL4 power limit in 1/8 watt units.
+ UINT16 PlatformPowerLimit1Power; ///< MSR 0x65C[14:0]: Platform PL1 power in 1/8 watt units.
+ UINT16 PlatformPowerLimit2Power; ///< MSR 0x65C[46:32]]: Platform PL2 power in 1/8 watt units.
+ UINT32 PowerLimit1Time; ///< Package Long duration turbo mode time window in seconds.
+ UINT32 PowerLimit3Time; ///< Package PL3 time window range for this policy from 3ms to 64ms.
+ UINT16 DdrPowerLimit; ///< DDR Power Limits
+ UINT16 RatioLimitProgramable; ///< RatioLimitProgramable
+
+ /**
+ - 1-Core Ratio Limit: For XE part: LFM to 255, For overclocking part: LFM to Fused 1-Core Ratio Limit + OC Bins.
+ - This 1-Core Ratio Limit Must be greater than or equal to 2-Core Ratio Limit, 3-Core Ratio Limit, 4-Core Ratio Limit.
+ - 2-Core Ratio Limit: For XE part: LFM to 255, For overclocking part: LFM to Fused 2-Core Ratio Limit + OC Bins.
+ - This 2-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+ - 3-Core Ratio Limit: For XE part: LFM to 255, For overclocking part: LFM to Fused 3-Core Ratio Limit + OC Bins.
+ - This 3-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+ - 4-Core Ratio Limit: For XE part: LFM to 255, For overclocking part: LFM to Fused 4-Core Ratio Limit + OC Bins.
+ - This 4-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+ **/
+ UINT8 RatioLimit[4];
+ /**
+ TCC Activation Offset. Offset from factory set TCC activation temperature at which the Thermal Control Circuit must be activated
+ TCC will be activated at TCC Activation Temperature, in volts.
+ For SKL Y SKU, the recommended default for this policy is <b>10</b>, For all other SKUs the recommended default are <b>0</b>
+ @note The policy is recommended for validation purpose only.
+ **/
+ UINT8 TccActivationOffset;
+ UINT8 TccOffsetTimeWindow; ///< @deprecated Tcc Offset Time Window value (0 ~ 128) for Runtime Average Temperature Limit (RATL). Deprecated since revision 2
+ UINT8 S3RestoreMsrSwSmiNumber; ///< SW SMI number to restore the power Mgmt MSRs during S3 resume.
+
+ /**
+ Default power unit for following items changes to MilliWatts.
+ - POWER_MGMT_CONFIG.PowerLimit1
+ - POWER_MGMT_CONFIG.PowerLimit2
+ - POWER_MGMT_CONFIG.PowerLimit3
+ - POWER_MGMT_CONFIG.CustomPowerLimit1
+ - POWER_MGMT_CONFIG.CustomPowerLimit2
+ **/
+ CUSTOM_POWER_UNIT CustomPowerUnit; ///< Power Management Custom Power Limit Unit in milli watts.
+ MAX_PKG_C_STATE PkgCStateLimit; ///< <b>(Test)</b> This field is used to set the Max Pkg Cstate. Default set to Auto which limits the Max Pkg Cstate to deep C-state.
+
+ /**
+ custom processor ratio table desired by the platform
+ **/
+ UINT16 MaxRatio; ///< The maximum ratio of the custom ratio table.
+ UINT8 NumberOfEntries; ///< The number of custom ratio state entries, ranges from 2 to 16 for a valid custom ratio table.
+ UINT8 Rsvd1; ///< Reserved for DWORD alignment.
+ UINT32 Cpuid; ///< The CPU ID for which this custom ratio table applies.
+ UINT16 StateRatio[MAX_CUSTOM_RATIO_TABLE_ENTRIES]; ///< The processor ratios in the custom ratio table.
+#if (MAX_CUSTOM_RATIO_TABLE_ENTRIES % 2)
+ UINT16 Rsvd2; ///< If there is an odd number of array entries, add padding for dword alignment.
+#endif
+} POWER_MGMT_CONFIG;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h
new file mode 100644
index 0000000000..c46ce09303
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h
@@ -0,0 +1,41 @@
+/** @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.
+
+**/
+
+#ifndef _PRAM_H_
+#define _PRAM_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi20.h>
+#include "Platform.h"
+#include <Uefi.h>
+
+#define EFI_ACPI_PRAM_BASE_ADDRESS_TABLE_SIGNATURE 0x4D415250
+
+#define EFI_ACPI_OEM_PRAM_REVISION 0x00000001
+
+#define EFI_ACPI_PRAM_BASE_ADDRESS_TABLE_REVISION 0x01
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ EFI_PHYSICAL_ADDRESS PramBaseAddress;
+ UINT32 PramSize;
+} EFI_ACPI_PRAM_BASE_ADDRESS_TABLE;
+
+#pragma pack()
+
+#endif //
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/CpuInitDataHob.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/CpuInitDataHob.h
new file mode 100644
index 0000000000..9b82768123
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/CpuInitDataHob.h
@@ -0,0 +1,39 @@
+/** @file
+ Struct and GUID definitions for CpuInitDataHob.
+
+ 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 _CPU_INIT_DATA_HOB_H_
+#define _CPU_INIT_DATA_HOB_H_
+
+#include <Ppi/CpuPolicy.h>
+#include <CpuDataStruct.h>
+
+extern EFI_GUID gCpuInitDataHobGuid;
+
+///
+/// This HOB is used to pass only the required information from PEI for DXE consumption.
+///
+typedef struct {
+ UINT32 Revision;
+ EFI_PHYSICAL_ADDRESS CpuConfig; ///< CPU_CONFIG CPU configuration Policies.
+ EFI_PHYSICAL_ADDRESS PowerMgmtConfig; ///< POWER_MGMT_CONFIG PPM configuration Policies.
+ EFI_PHYSICAL_ADDRESS SoftwareGuardConfig; ///< SOFTWARE_GUARD_CONFIG SGX configuration Policies.
+ EFI_PHYSICAL_ADDRESS CpuGnvsPointer; ///< CPU_GLOBAL_NVS_AREA Pointer.
+ EFI_PHYSICAL_ADDRESS MpData; ///< Points to ACPI_CPU_DATA structure with multiprocessor data.
+ EFI_PHYSICAL_ADDRESS FvidTable; ///< FVID Table.
+ UINT32 SiliconInfo; ///< SILICON_INFO data
+} CPU_INIT_DATA_HOB;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuCommonLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuCommonLib.h
new file mode 100644
index 0000000000..60047b57e8
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuCommonLib.h
@@ -0,0 +1,211 @@
+/** @file
+ Header file for Cpu Common Lib implementation.
+
+ 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 _CPU_COMMON_LIB_H_
+#define _CPU_COMMON_LIB_H_
+
+typedef UINT32 CPU_RESET_TYPE;
+
+#define NO_RESET 0
+#define WARM_RESET BIT0
+#define COLD_RESET (BIT0 | BIT1)
+#define RESET_PPI_WARM_RESET 0
+#define RESET_PPI_COLD_RESET 3
+#define POWER_LEVEL_DATA UINT8
+#define MAILBOX_PL_WIDTH 6
+#define MAILBOX_PL_WIDTH_MASK 0x3F
+#define READ_PCH_POWER_LEVELS_CMD 0x8000000A
+#define NUM_PL_SUPP_PCH_POWER_LEVELS_CMD 4
+#define READ_EXT_PCH_POWER_LEVELS_CMD 0x8000000B
+#define NUM_PL_SUPP_EXT_PCH_POWER_LEVELS_CMD 3
+
+///
+/// Enums for Time Window Convert Type
+///
+typedef enum {
+ PL1TimeWindowConvert = 1,
+ PL3TimeWindowConvert,
+ TccOffsetTimeWindowConvert,
+ TimeWindowConvertMaximum
+} TIME_WINDOW_CONV;
+
+/**
+ Initialize prefetcher settings
+
+ @param[in] MlcStreamerprefecterEnabled Enable/Disable MLC streamer prefetcher
+ @param[in] MlcSpatialPrefetcherEnabled Enable/Disable MLC spatial prefetcher
+
+**/
+VOID
+ProcessorsPrefetcherInitialization (
+ IN UINTN MlcStreamerprefecterEnabled,
+ IN UINTN MlcSpatialPrefetcherEnabled
+ );
+
+/**
+ Set up flags in CR4 for XMM instruction enabling
+
+**/
+VOID
+EFIAPI
+XmmInit (
+ VOID
+ );
+
+/**
+ Enable "Machine Check Enable"
+
+**/
+VOID
+EFIAPI
+EnableMce (
+ VOID
+ );
+
+/**
+ Mtrr Synch Up Entry
+
+**/
+UINTN
+EFIAPI
+MpMtrrSynchUpEntry (
+ VOID
+ );
+
+/**
+ Mtrr Synch Up Exit
+
+**/
+VOID
+EFIAPI
+MpMtrrSynchUpExit (
+ UINTN Cr4
+ );
+
+/**
+ This procedure sends an IPI to the designated processor in
+ the requested delivery mode with the requested vector.
+
+ @param[in] ApicID APIC ID of processor.
+ @param[in] VectorNumber Vector number.
+ @param[in] DeliveryMode I/O APIC Interrupt Deliver Modes
+
+ @retval EFI_INVALID_PARAMETER Input paramters were not correct.
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSendIpi (
+ IN UINT32 ApicID,
+ IN UINTN VectorNumber,
+ IN UINTN DeliveryMode
+ );
+
+/**
+ Private helper function to convert various Turbo Power Limit Time from Seconds to CPU units
+
+ @param[in] TimeInSeconds Time in seconds
+ @param[in] TimeWindowConvType Time Window Convert Type
+
+ @retval UINT8 Converted time in CPU units
+
+**/
+UINT8
+GetConvertedTime (
+ IN UINT32 TimeInSeconds,
+ IN TIME_WINDOW_CONV TimeWindowConvType
+ );
+
+/**
+ Get APIC ID of processor
+
+ @retval APIC ID of processor
+
+**/
+UINT32
+GetCpuApicId (
+ VOID
+ );
+
+/**
+ Programs XAPIC registers.
+
+ @param[in] Bsp Is this BSP?
+
+**/
+VOID
+ProgramXApic (
+ BOOLEAN Bsp
+ );
+
+/**
+ This function returns the maximum number of cores supported in this physical processor package.
+
+ @retval Maximum number of supported cores in the package.
+
+**/
+UINT8
+GetMaxSupportedCoreCount (
+ VOID
+ );
+
+/**
+ This function returns the actual factory-configured number of threads per core,
+ and actual factory-configured number of cores in this physical processor package.
+
+ @param[out] NumberOfEnabledThreadsPerCore Variable that will store Maximum enabled threads per core
+ @param[out] NumberOfEnabledCoresPerDie Variable that will store Maximum enabled cores per die
+
+**/
+VOID
+GetSupportedCount (
+ OUT UINT16 *ThreadsPerCore, OPTIONAL
+ OUT UINT16 *NumberOfCores OPTIONAL
+ );
+
+/**
+ This function returns the maximum enabled Core per die, maximum enabled threads per core,
+ maximum number of dies and packages
+
+ @param[out] NumberOfEnabledThreadsPerCore Variable that will store Maximum enabled threads per core
+ @param[out] NumberOfEnabledCoresPerDie Variable that will store Maximum enabled cores per die
+ @param[out] NumberOfDiesPerPackage Variable that will store Maximum dies per package
+ @param[out] NumberOfPackages Variable that will store Maximum Packages
+
+**/
+VOID
+GetEnabledCount (
+ OUT UINT16 *NumberOfEnabledThreadsPerCore,
+ OUT UINT16 *NumberOfEnabledCoresPerDie,
+ OUT UINT16 *NumberOfDiesPerPackage,
+ OUT UINT16 *NumberOfPackages
+ );
+
+/**
+ Check to see if the executing thread is BSP
+
+ @retval TRUE Executing thread is BSP
+ @retval FALSE Executing thread is AP
+
+**/
+BOOLEAN
+IsBsp (
+ VOID
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuS3Lib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuS3Lib.h
new file mode 100644
index 0000000000..48b4ac574f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuS3Lib.h
@@ -0,0 +1,33 @@
+/** @file
+ Header file for Cpu Init Lib Pei Phase.
+
+ 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 _CPU_S3_LIB_H_
+#define _CPU_S3_LIB_H_
+
+/**
+ Notification function that gets called during S3 resume to take care
+ of CPU related activities in PEI phase
+
+ @param[in] PeiServices Pointer to PEI Services Table
+
+ @retval EFI_SUCCESS Multiple processors are intialized successfully
+
+**/
+EFI_STATUS
+S3InitializeCpu (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/MpServiceLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/MpServiceLib.h
new file mode 100644
index 0000000000..125c02b60b
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/MpServiceLib.h
@@ -0,0 +1,819 @@
+/** @file
+ Definitions for MP and HT driver.
+
+ Copyright (c) 2005 - 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 _MP_SERVICE_LIB_
+#define _MP_SERVICE_LIB_
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/HobLib.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/CpuPolicy.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Private/Library/CpuCommonLib.h>
+#include <CpuAccess.h>
+#include <Private/PowerMgmtNvsStruct.h>
+
+#define INTERRUPT_HANDLER_DIVIDE_ZERO 0x00
+#define INTERRUPT_HANDLER_DEBUG 0x01
+#define INTERRUPT_HANDLER_NMI 0x02
+#define INTERRUPT_HANDLER_BREAKPOINT 0x03
+#define INTERRUPT_HANDLER_OVERFLOW 0x04
+#define INTERRUPT_HANDLER_BOUND 0x05
+#define INTERRUPT_HANDLER_INVALID_OPCODE 0x06
+#define INTERRUPT_HANDLER_DEVICE_NOT_AVAILABLE 0x07
+#define INTERRUPT_HANDLER_DOUBLE_FAULT 0x08
+#define INTERRUPT_HANDLER_COPROCESSOR_OVERRUN 0x09
+#define INTERRUPT_HANDLER_INVALID_TSS 0x0A
+#define INTERRUPT_HANDLER_SEGMENT_NOT_PRESENT 0x0B
+#define INTERRUPT_HANDLER_STACK_SEGMENT_FAULT 0x0C
+#define INTERRUPT_HANDLER_GP_FAULT 0x0D
+#define INTERRUPT_HANDLER_PAGE_FAULT 0x0E
+#define INTERRUPT_HANDLER_RESERVED 0x0F
+#define INTERRUPT_HANDLER_MATH_FAULT 0x10
+#define INTERRUPT_HANDLER_ALIGNMENT_FAULT 0x11
+#define INTERRUPT_HANDLER_MACHINE_CHECK 0x12
+#define INTERRUPT_HANDLER_STREAMING_SIMD 0x13
+#define INTERRUPT_VECTOR_NUMBER 256
+#define RENDEZVOUS_PROC_LENGTH 0x1000
+#define MAX_CPU_S3_MTRR_ENTRY 0x0020
+#define MAX_CPU_S3_TABLE_SIZE 0x0400
+#define VacantFlag 0x00
+#define NotVacantFlag 0xff
+#define MICROSECOND 10
+#define MAXIMUM_CPU_NUMBER 0x40
+#define STACK_SIZE_PER_PROC 0x8000
+#define MAXIMUM_CPU_S3_TABLE_SIZE 0x1000
+#define MP_CPU_EXCHANGE_INFO_OFFSET (0x1000 - 0x400)
+#define PSIX_THRESHOLD_MASK 0x3FFFFFFF ///< Bits 61:32 - Mask value respect to Dword.High
+#define EFI_MP_HEALTH_FLAGS_STATUS_HEALTHY 0x0
+#define EFI_MP_HEALTH_FLAGS_STATUS_PERFORMANCE_RESTRICTED 0x1
+#define EFI_MP_HEALTH_FLAGS_STATUS_FUNCTIONALLY_RESTRICTED 0x2
+
+///
+/// The MP data structure follows.
+///
+#define CPU_SWITCH_STATE_IDLE 0
+#define CPU_SWITCH_STATE_STORED 1
+#define CPU_SWITCH_STATE_LOADED 2
+
+extern UINTN FixedMtrrNumber;
+extern UINTN MtrrDefTypeNumber;
+extern SI_CPU_POLICY_PPI *mSiCpuPolicyPpi;
+extern CPU_CONFIG_PREMEM *mCpuConfigPreMem;
+extern CPU_CONFIG *mCpuConfig;
+
+#pragma pack(1)
+typedef struct {
+ UINT16 Offset15To0;
+ UINT16 SegmentSelector;
+ UINT16 Attributes;
+ UINT16 Offset31To16;
+ } INTERRUPT_GATE_DESCRIPTOR;
+
+#define SIZE_OF_MCE_HANDLER 16
+
+typedef struct {
+ UINT16 LimitLow;
+ UINT16 BaseLow;
+ UINT8 BaseMiddle;
+ UINT16 Attributes;
+ UINT8 BaseHigh;
+} SEGMENT_DESCRIPTOR;
+#pragma pack()
+
+//
+// Define CPU feature information
+//
+#define MAX_FEATURE_NUM 6
+typedef struct {
+ UINTN Index;
+ UINT32 ApicId;
+ UINT32 Version;
+ UINT32 FeatureDelta;
+ UINT32 Features[MAX_FEATURE_NUM];
+} LEAST_FEATURE_PROC;
+
+typedef enum {
+ CPU_STATE_IDLE,
+ CPU_STATE_BLOCKED,
+ CPU_STATE_READY,
+ CPU_STATE_BUSY,
+ CPU_STATE_FINISHED,
+ CPU_STATE_DISABLED
+} CPU_STATE;
+
+typedef struct {
+ UINT16 Index;
+ UINT64 Value;
+} EFI_MTRR_VALUES;
+
+typedef struct {
+ UINT32 ApicId;
+ UINT32 MsrIndex;
+ UINT64 MsrValue;
+} MP_CPU_S3_SCRIPT_DATA;
+
+typedef struct {
+ UINT32 S3BootScriptTable;
+ UINT32 S3BspMtrrTable;
+ UINT32 VirtualWireMode;
+} MP_CPU_S3_DATA_POINTER;
+
+typedef struct {
+ UINT32 Number;
+ UINT32 BIST;
+} BIST_INFO;
+
+typedef union {
+ struct {
+ UINT32 Status : 2;
+ UINT32 Tested : 1;
+ UINT32 Reserved1 : 13;
+ UINT32 VirtualMemoryUnavailable : 1;
+ UINT32 Ia32ExecutionUnavailable : 1;
+ UINT32 FloatingPointUnavailable : 1;
+ UINT32 MiscFeaturesUnavailable : 1;
+ UINT32 Reserved2 : 12;
+ } Bits;
+ UINT32 Uint32;
+} EFI_MP_HEALTH_FLAGS;
+
+typedef struct {
+ EFI_MP_HEALTH_FLAGS Flags;
+ UINT32 TestStatus;
+} EFI_MP_HEALTH;
+
+typedef enum {
+ EfiCpuAP = 0,
+ EfiCpuBSP,
+ EfiCpuDesignationMaximum
+} EFI_CPU_DESIGNATION;
+
+typedef struct {
+ UINT32 ApicID;
+ BOOLEAN Enabled;
+ EFI_CPU_DESIGNATION Designation;
+ EFI_MP_HEALTH Health;
+ UINTN PackageNumber;
+ UINTN NumberOfCores;
+ UINTN NumberOfThreads;
+ UINT64 ProcessorPALCompatibilityFlags;
+ UINT64 ProcessorTestMask;
+} EFI_MP_PROC_CONTEXT;
+
+/**
+ Functions of this type are used with the MP Services to execute a procedure on enabled APs.
+ The context the AP should use during execution is specified by Buffer.
+
+ @param[in] Buffer The pointer to the procedure's argument.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_AP_PROCEDURE) (
+ IN VOID *Buffer
+ );
+
+///
+/// Structure that describes the physical location of a logical CPU.
+///
+typedef struct {
+ ///
+ /// Zero-based physical package number that identifies the cartridge of the processor.
+ ///
+ UINT32 Package;
+ ///
+ /// Zero-based physical core number within package of the processor.
+ ///
+ UINT32 Core;
+ ///
+ /// Zero-based logical thread number within core of the processor.
+ ///
+ UINT32 Thread;
+} EFI_CPU_PHYSICAL_LOCATION;
+
+///
+/// Define Individual Processor Data block.
+///
+typedef struct {
+ UINT32 ApicID;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *Parameter;
+ UINT8 StateLock;
+ UINT8 ProcedureLock;
+ EFI_MP_HEALTH_FLAGS Health;
+ BOOLEAN SecondaryCpu;
+ EFI_CPU_PHYSICAL_LOCATION PhysicalLocation;
+ CPU_STATE State;
+} CPU_DATA_BLOCK;
+
+#define MP_SERVICES_DATA_SIGNATURE SIGNATURE_32 ('c', 'p', 'u', 'm')
+
+typedef struct {
+ UINT8 Lock; ///< offset 0
+ UINT8 State; ///< offset 1
+ UINTN StackPointer; ///< offset 4 / 8
+ IA32_DESCRIPTOR Gdtr; ///< offset 8 / 16
+ IA32_DESCRIPTOR Idtr; ///< offset 14 / 26
+} CPU_EXCHANGE_ROLE_INFO;
+
+///
+/// Define MP data block which consumes individual processor block.
+///
+typedef struct {
+ UINT8 ApSerializeLock;
+ BOOLEAN VmxEnable;
+ BOOLEAN TxtEnable;
+ BOOLEAN ThreeStrikeCounterDisable;
+ BOOLEAN MonitorMwaitEnable;
+ BOOLEAN MachineCheckEnable;
+ BOOLEAN AesEnable;
+ BOOLEAN DebugInterfaceEnable;
+ BOOLEAN DebugInterfaceLockEnable;
+ BOOLEAN EnableSecondaryCpu;
+ BOOLEAN HyperThreadingEnable;
+ UINT8 ProcTraceMemSize;
+ UINT8 ProcTraceOutputScheme;
+ BOOLEAN ProcTraceEnable;
+ UINTN NumberOfCpus;
+ UINTN MaximumCpusForThisSystem;
+ UINTN BSP;
+ CPU_DATA_BLOCK CpuData[MAXIMUM_CPU_NUMBER];
+ CPU_STATE_CHANGE_CAUSE DisableCause[MAXIMUM_CPU_NUMBER];
+ UINT8 S3BootScriptLock;
+ UINT32 S3BootScriptCount;
+ MP_CPU_S3_DATA_POINTER S3DataPointer;
+ MP_CPU_S3_SCRIPT_DATA S3BootScriptTable[MAX_CPU_S3_TABLE_SIZE];
+ EFI_MTRR_VALUES S3BspMtrrTable[MAX_CPU_S3_MTRR_ENTRY];
+ UINT8 FeatureLock;
+ UINTN CommonFeatures;
+ UINTN SetupFeatures;
+ UINT8 Lock;
+ LEAST_FEATURE_PROC LeastFeatureProcessor;
+ CPU_EXCHANGE_ROLE_INFO BspInfo;
+ CPU_EXCHANGE_ROLE_INFO ApInfo;
+} MP_SYSTEM_DATA;
+
+///
+/// Data structure for MP framework
+///
+typedef struct {
+ UINTN Signature;
+ CONST EFI_PEI_SERVICES **PeiServices;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ ACPI_CPU_DATA AcpiCpuData;
+ MP_SYSTEM_DATA MpSystemData;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINT64 MtrrValues[MAX_CPU_S3_MTRR_ENTRY];
+ CPU_CONFIG CpuConfig;
+ POWER_MGMT_CONFIG PowerMgmtConfig;
+ FVID_TABLE FvidTable[FVID_MAX_STATES + 1];
+} MP_CPU_RUNTIME_DATA;
+
+typedef struct {
+ UINT32 Lock;
+ UINT32 StackStart;
+ UINT32 StackSize;
+ UINT32 ApFunction;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINT32 BufferStart;
+ UINT32 PmodeOffset;
+ UINT32 AcpiCpuDataAddress;
+ UINT32 MtrrValuesAddress;
+ UINT32 FinishedCount;
+ UINT32 WakeupCount;
+ UINT32 SerializeLock;
+ MP_CPU_S3_SCRIPT_DATA *S3BootScriptTable;
+ UINT32 StartState;
+ UINT32 VirtualWireMode;
+ VOID (*SemaphoreCheck) (UINT32 *SemaphoreAddress);
+ UINT32 McuLoadCount;
+ IN CONST EFI_PEI_SERVICES **PeiServices;
+ UINT64 CpuPerfCtrlValue;
+ SI_CPU_POLICY_PPI *SiCpuPolicyPpi;
+ UINT32 MpSystemDataAddress;
+ UINT32 MpServicePpiAddress;
+ UINT32 ApArgument;
+ BIST_INFO BistBuffer[MAXIMUM_CPU_NUMBER];
+} MP_CPU_EXCHANGE_INFO;
+
+/**
+ Get CPU platform features settings to fill MP data.
+
+ @retval MP_SYSTEM_DATA* Return MpSystemData pointer
+
+**/
+MP_SYSTEM_DATA *
+EFIAPI
+GetMpSystemData (
+ VOID
+ );
+
+/**
+ Initialize multi-processor service.
+
+ @param[in] SiCpuPolicyPpi The Cpu Policy PPI instance
+
+ @retval EFI_SUCCESS Multi-processor initialization has been done successfully
+
+**/
+EFI_STATUS
+InitializeMpServices (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ );
+
+/**
+ Initialize CPU Data Hob
+
+ @retval EFI_SUCCESS The driver installs/initialized correctly.
+
+**/
+EFI_STATUS
+InitializeCpuDataHob (
+ VOID
+ );
+
+/**
+ Check if this is non-core processor - HT AP thread
+
+ @retval TRUE If this is HT AP thread
+ @retval FALSE If this is core thread
+
+**/
+BOOLEAN
+EFIAPI
+IsSecondaryThread (
+ VOID
+ );
+
+/**
+ Get protected mode code offset
+
+ @retval Offset of protected mode code
+
+**/
+VOID *
+AsmGetPmodeOffset (
+ VOID
+ );
+
+/**
+ Get code offset of SemaphoreCheck
+
+ @retval Offset of SemaphoreCheck
+
+**/
+UINT32
+AsmGetSemaphoreCheckOffset (
+ VOID
+ );
+
+/**
+ Read MTRR settings
+
+ @param[in] MtrrValues Buffer to store MTRR settings
+
+**/
+VOID
+ReadMtrrRegisters (
+ UINT64 *MtrrValues
+ );
+
+/**
+ Syncup MTRR settings between all processors
+
+ @param[in] MtrrValues Buffer to store MTRR settings
+
+**/
+VOID
+MpMtrrSynchUp (
+ UINT64 *MtrrValues
+ );
+
+/**
+ Set MTRR registers
+
+ @param[in] MtrrArray Buffer with MTRR settings
+
+**/
+VOID
+SetMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ );
+
+/**
+ This will check if the microcode address is valid for this processor, and if so, it will
+ load it to the processor.
+
+ @param[in] ExchangeInfo Pointer to the exchange info buffer for output.
+ @param[in] MicrocodeAddress The address of the microcode update binary (in memory).
+ @param[out] FailedRevision The microcode revision that fails to be loaded.
+
+ @retval EFI_SUCCESS A new microcode update is loaded.
+ @retval Other Due to some reason, no new microcode update is loaded.
+
+**/
+EFI_STATUS
+InitializeMicrocode (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN CPU_MICROCODE_HEADER *MicrocodeAddress,
+ OUT UINT32 *FailedRevision
+ );
+
+///
+/// Functions shared in MP/HT drivers
+///
+/**
+ Send interrupt to CPU
+
+ @param[in] BroadcastMode Interrupt broadcast mode
+ @param[in] ApicID APIC ID for sending interrupt
+ @param[in] VectorNumber Vector number
+ @param[in] DeliveryMode Interrupt delivery mode
+ @param[in] TriggerMode Interrupt trigger mode
+ @param[in] Assert Interrupt pin polarity
+
+ @retval EFI_INVALID_PARAMETER Input parameter not correct
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+SendInterrupt (
+ IN UINT32 BroadcastMode,
+ IN UINT32 ApicID,
+ IN UINT32 VectorNumber,
+ IN UINT32 DeliveryMode,
+ IN UINT32 TriggerMode,
+ IN BOOLEAN Assert
+ );
+
+/**
+ Lock APs
+
+ @param[in] Lock Lock state
+
+**/
+VOID
+AsmAcquireMPLock (
+ IN UINT8 *Lock
+ );
+
+/**
+ Release APs
+
+ @param[in] Lock Lock state
+
+**/
+VOID
+AsmReleaseMPLock (
+ IN UINT8 *Lock
+ );
+
+/**
+ Get address map of RendezvousFunnelProc.
+
+ @retval AddressMap Output buffer for address map information
+
+**/
+VOID *
+AsmGetAddressMap (
+ VOID
+ );
+
+/**
+ Patch the Rendezvous Code properly.
+
+ @param[in] RendezvousCodeBase Rendezvous code base in memory
+
+**/
+VOID
+AsmPatchRendezvousCode (
+ VOID *RendezvousCodeBase
+ );
+
+/**
+ Wake up all the application processors
+
+ @param[in] MtrrValues Pointer to a buffer which stored MTRR settings
+ @param[in] Function Pointer to AP Procedure Function
+
+ @retval EFI_SUCCESS APs are successfully waked up
+
+**/
+EFI_STATUS
+WakeUpAPs (
+ UINT64 *MtrrValues,
+ EFI_AP_PROCEDURE Function
+ );
+
+
+/**
+ Based on ResetType, perform warm or cold reset using PCH reset PPI.
+
+ @param[in] ResetType CPU_RESET_TYPE to indicate which reset should be performed.
+
+ @retval EFI_SUCCESS Function successful (system should already reset).
+ @retval EFI_UNSUPPORTED Reset type unsupported.
+
+**/
+EFI_STATUS
+PerformWarmOrColdReset (
+ IN CPU_RESET_TYPE ResetType
+ );
+
+/**
+ Initialize performance and power management features before RESET_CPL at Post-memory phase.
+
+ @param[in] CpuPolicyPpi The Cpu Policy PPI instance
+
+**/
+VOID
+CpuInitPreResetCpl (
+ IN SI_CPU_POLICY_PPI *CpuPolicyPpi
+ );
+
+/**
+ Get general MP information
+
+ @param[in] NumberOfCpus Number of processors
+ @param[in] MaxiumNumberOfCpus Max supported number of processors
+ @param[in] NumberOfEnabledCpus Number of processors enabled
+ @param[in] RendezvousIntNumber Number of Rendezvous procedure
+ @param[in] RendezvousProcLength Length of Rendezvous procedure
+
+ @retval EFI_SUCCESS Always return success
+**/
+EFI_STATUS
+EFIAPI
+GetGeneralMpInfo (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxiumNumberOfCpus,
+ OUT UINTN *NumberOfEnabledCpus,
+ OUT UINTN *RendezvousIntNumber,
+ OUT UINTN *RendezvousProcLength
+ );
+
+/**
+ Get processor context
+
+ @param[in] CpuNumber The handle number of processor.
+ @param[in] BufferLength Buffer length
+ @param[in] ProcessorContextBuffer Pointer to the buffer that will be updated
+
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or CpuNumber our of range
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small
+ @retval EFI_SUCCESS Got processor context successfully
+
+**/
+EFI_STATUS
+EFIAPI
+GetProcessorContext (
+ IN UINTN CpuNumber,
+ IN OUT UINTN *BufferLength,
+ IN OUT EFI_MP_PROC_CONTEXT *ProcessorContextBuffer
+ );
+
+/**
+ MP Service to get specified application processor (AP)
+ to execute a caller-provided code stream.
+
+ @param[in] Procedure The procedure to be assigned to AP.
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[in] WaitEvent If timeout, the event to be triggered after this AP finishes.
+ @param[in] TimeoutInMicroSecs The timeout value in microsecond. Zero means infinity.
+ @param[in] ProcArguments Argument for Procedure.
+
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+ @retval EFI_INVALID_PARAMETER Number of CPU out of range, or it belongs to BSP.
+ @retval EFI_INVALID_PARAMETER Specified CPU is not idle.
+ @retval EFI_SUCCESS The AP has finished.
+ @retval EFI_TIMEOUT Time goes out before the AP has finished.
+
+**/
+EFI_STATUS
+EFIAPI
+StartupThisAP (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN OUT VOID *ProcArguments OPTIONAL
+ );
+
+/**
+ MP Service to get all the available application processors (APs)
+ to execute a caller-provided code stream.
+
+ @param[in] Function The procedure to be assigned to APs.
+ @param[in] ProcArguments Argument for Procedure.
+
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+ @retval EFI_SUCCESS Only 1 logical processor exists.
+ @retval EFI_SUCCESS All APs have finished.
+ @retval EFI_TIMEOUT Time goes out before all APs have finished.
+
+**/
+
+EFI_STATUS
+StartupAllAps (
+ IN EFI_AP_PROCEDURE Function,
+ IN OUT VOID *ProcArguments OPTIONAL
+ );
+
+/**
+ MP Service to makes the current BSP into an AP and then switches the
+ designated AP into the AP. This procedure is usually called after a CPU
+ test that has found that BSP is not healthy to continue it's responsibilities.
+
+ @param[in] CpuNumber The handle number of processor.
+ @param[in] EnableOldBsp Whether to enable or disable the original BSP.
+
+ @retval EFI_INVALID_PARAMETER Number for Specified AP out of range.
+ @retval EFI_INVALID_PARAMETER Number of specified CPU belongs to BSP.
+ @retval EFI_NOT_READY Specified AP is not idle.
+ @retval EFI_SUCCESS BSP successfully switched.
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchBsp (
+ IN UINTN CpuNumber,
+ IN BOOLEAN EnableOldBsp
+ );
+
+/**
+ Implementation of EnableDisableAp() service of MP Services Protocol.
+
+ This service lets the caller enable or disable an AP.
+ This service may only be called from the BSP.
+
+ @param[in] CpuNumber The handle number of processor.
+ @param[in] NewAPState Indicates whether the newstate of the AP is enabled or disabled.
+ @param[in] HealthState Indicates new health state of the AP..
+
+ @retval EFI_SUCCESS AP successfully enabled or disabled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETERS ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDisableAp (
+ IN UINTN CpuNumber,
+ IN BOOLEAN NewApState,
+ IN EFI_MP_HEALTH *HealthState OPTIONAL
+ );
+
+/**
+ Implementation of WhoAmI() service of MP Services Protocol.
+
+ This service lets the caller processor get its handle number.
+ This service may be called from the BSP and APs.
+
+ @param[in] ProcessorNumber Pointer to the handle number of AP.
+
+ @retval EFI_SUCCESS Processor number successfully returned.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL
+
+**/
+EFI_STATUS
+EFIAPI
+WhoAmI (
+ OUT UINTN *ProcessorNumber
+ );
+
+/**
+ AP initialization
+
+**/
+VOID
+InitialMpProcedure (
+ VOID
+ );
+
+/**
+ Write 64bits MSR with script
+
+ @param[in] Index MSR index that will be written
+ @param[in] Value Value written to MSR
+
+**/
+VOID
+AsmWriteMsr64WithScript (
+ IN UINT32 Index,
+ IN UINT64 Value
+ );
+
+/**
+ Write 64bits MSR to script
+
+ @param[in] Index MSR index that will be written
+ @param[in] Value Value written to MSR
+
+**/
+VOID
+WriteMsr64ToScript (
+ IN UINT32 Index,
+ IN UINT64 Value
+ );
+
+/**
+ Send interrupt to CPU
+
+ @param[in] BroadcastMode Interrupt broadcast mode
+ @param[in] ApicID APIC ID for sending interrupt
+ @param[in] VectorNumber Vector number
+ @param[in] DeliveryMode Interrupt delivery mode
+ @param[in] TriggerMode Interrupt trigger mode
+ @param[in] Assert Interrupt pin polarity
+
+ @retval EFI_INVALID_PARAMETER Input parameter not correct
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+SendInterrupt (
+ IN UINT32 BroadcastMode,
+ IN UINT32 ApicID,
+ IN UINT32 VectorNumber,
+ IN UINT32 DeliveryMode,
+ IN UINT32 TriggerMode,
+ IN BOOLEAN Assert
+ );
+
+/**
+ Set APIC BSP bit
+
+ @param[in] Enable Enable as BSP or not
+
+ @retval EFI_SUCCESS Always return success
+
+**/
+EFI_STATUS
+SetApicBspBit (
+ IN BOOLEAN Enable
+ );
+
+/**
+ Switch current BSP processor to AP
+
+ @param[in] MPSystemData Pointer to the data structure containing MP related data
+
+**/
+VOID
+EFIAPI
+FutureBspProc (
+ VOID
+ );
+
+/**
+ Change CPU state
+
+ @param[in] CpuNumber CPU number
+ @param[in] NewState The new state that will be changed to
+ @param[in] Cause Cause
+
+ @retval EFI_SUCCESS Always return success
+
+**/
+EFI_STATUS
+ChangeCpuState (
+ IN UINTN CpuNumber,
+ IN BOOLEAN NewState,
+ IN CPU_STATE_CHANGE_CAUSE Cause
+ );
+
+#ifdef EFI_DEBUG
+/**
+ Print MTRR settings in debug build BIOS
+
+ @param[in] MtrrArray Buffer with MTRR settings
+
+**/
+VOID
+ShowMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ );
+#endif
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/PowerMgmtNvsStruct.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/PowerMgmtNvsStruct.h
new file mode 100644
index 0000000000..7af13c16a7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/PowerMgmtNvsStruct.h
@@ -0,0 +1,123 @@
+/** @file
+ This file contains CPU Gnvs Struct specific to processor.
+
+ 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 _POWER_MGMT_NVS_STRUCT_H_
+#define _POWER_MGMT_NVS_STRUCT_H_
+
+//
+// Processor Power Management GlobalNvs Revisions
+//
+#define CPU_GLOBAL_NVS_AREA_REVISION_1 1
+
+//
+// Structure Declarations
+//
+#pragma pack(1)
+///
+/// CPU Global NVS Area definition
+///
+typedef struct {
+ UINT8 Revision; ///< (0) CPU GlobalNvs Revision
+ //
+ // PPM Flag Values
+ //
+ UINT32 PpmFlags; ///< (1-4) PPM Flags
+ //
+ // Number of Logical Processors Values
+ //
+ UINT8 LogicalProcessorCount; ///< (5) Number of Logical Processors
+ //
+ // Thermal Configuration Values
+ //
+ UINT8 AutoCriticalTripPoint; ///< (6) Auto Critical Trip Point
+ UINT8 AutoPassiveTripPoint; ///< (7) Auto Passive Trip Point
+ UINT8 AutoActiveTripPoint; ///< (8) Auto Active Trip Point
+ UINT32 Cpuid; ///< (9-12) CPUID
+
+ UINT8 Reserved[28]; ///< (13-40) Reserved
+ //
+ // Mwait Hints and Latency values for C3/C6/C7/C7S
+ //
+ UINT8 C3MwaitValue; ///< (41) Mwait Hint value for C3
+ UINT8 C6MwaitValue; ///< (42) Mwait Hint value for C6
+ UINT8 C7MwaitValue; ///< (43) Mwait Hint value for C6
+ UINT8 CDMwaitValue; ///< (44) Mwait Hint value for C7/C8/C9/C10
+ UINT16 C3Latency; ///< (45-46) Latency value for C3
+ UINT16 C6Latency; ///< (47-48) Latency Value for C6
+ UINT16 C7Latency; ///< (49-50) Latency Value for C6
+ UINT16 CDLatency; ///< (51-52) Latency Value for C7/C8/C9/C10
+ UINT16 CDIOLevel; ///< (53-54) IO Level Value for C7/C8/C9/C10
+ UINT16 CDPowerValue; ///< (55-56) Power Value for C7/C8/C9/C10
+ UINT8 MiscPowerManagementFlags; ///< (57) MiscPowerManagementFlags
+ //
+ // DTS
+ //
+ UINT8 EnableDigitalThermalSensor; ///< (58) DTS Function enable
+ UINT8 BspDigitalThermalSensorTemperature; ///< (59) Temperature of BSP
+ UINT8 ApDigitalThermalSensorTemperature; ///< (60) Temperature of AP
+ UINT8 DigitalThermalSensorSmiFunction; ///< (61) SMI function call via DTS IO Trap
+ UINT8 PackageDTSTemperature; ///< (62) Package temperature
+ UINT8 IsPackageTempMSRAvailable; ///< (63) Package Temperature MSR available
+ UINT8 Ap2DigitalThermalSensorTemperature; ///< (64) Temperature of the second AP
+ UINT8 Ap3DigitalThermalSensorTemperature; ///< (65) Temperature of the third AP
+
+ UINT8 Reserved1[16]; ///< (66-81) Reserved
+ UINT8 DtsAcpiEnable; ///< (82) DTS is in ACPI Mode Enabled
+ //
+ // Software Guard Extension
+ //
+ UINT8 SgxStatus; ///< (83) SE Status
+ UINT64 EpcBaseAddress; ///< (84-91) EPC Base Address
+ UINT64 EpcLength; ///< (92-99) EPC Length
+ //
+ // HWP
+ //
+ UINT8 HwpVersion; ///< (100) HWP Status
+ UINT16 HwpIoTrapAddress; ///< (101-102) IoTrap Address for HWP
+ UINT16 HwpIoTrapLength; ///< (103-104) IoTrap Length for HWP
+ UINT8 PowerState; ///< (105) Power State
+ UINT8 EnableHdcPolicy; ///< (106) Hardware Duty Cycling Policy
+ UINT8 HwpInterruptStatus; ///< (107) HWP Interrupt Status
+
+ UINT8 MonitorMwaitEnable; ///< (108) Mwait Enable
+} CPU_GLOBAL_NVS;
+#pragma pack()
+
+typedef struct _CPU_GLOBAL_NVS_AREA_CONFIG {
+ CPU_GLOBAL_NVS *Area;
+} CPU_GLOBAL_NVS_AREA_CONFIG;
+
+#pragma pack(1)
+typedef struct _FVID_HEADER {
+ UINT32 Stepping; ///< Matches value returned by CPUID function 1
+ UINT16 MaxBusRatio; ///< Matches BUS_RATIO_MAX field in PERF_STS_MSR
+ UINT16 EistStates; ///< Number of states of FVID (N)
+} FVID_HEADER;
+
+typedef struct _FVID_STATE {
+ UINT32 State; ///< State Number (0 - N-1)
+ UINT16 BusRatio; ///< BUS_RATIO_SEL value to be written to PERF_CTL
+ UINT32 Power; ///< Typical power consumed by CPU in this state
+} FVID_STATE;
+
+typedef union _FVID_TABLE {
+ FVID_HEADER FvidHeader;
+ FVID_STATE FvidState;
+ UINT64 FvidData;
+} FVID_TABLE;
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Protocol/PowerMgmtInitDone.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Protocol/PowerMgmtInitDone.h
new file mode 100644
index 0000000000..c7e56087af
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Protocol/PowerMgmtInitDone.h
@@ -0,0 +1,35 @@
+/** @file
+ This file defines the PowerMgmtInitDone Protocol.
+
+ 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.
+
+**/
+
+#ifndef _POWER_MGMT_INIT_DONE_H_
+#define _POWER_MGMT_INIT_DONE_H_
+
+///
+/// Define PPM INFO protocol GUID
+///
+#define POWER_MGMT_INIT_DONE_PROTOCOL_GUID \
+ { \
+ 0xd71db106, 0xe32d, 0x4225, 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 \
+ }
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gPowerMgmtInitDoneProtocolGuid;
+
+typedef struct _EFI_POWER_MGMT_INIT_DONE_PROTOCOL EFI_POWER_MGMT_INIT_DONE_PROTOCOL;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuGlobalNvsArea.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuGlobalNvsArea.h
new file mode 100644
index 0000000000..589bc541c0
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuGlobalNvsArea.h
@@ -0,0 +1,110 @@
+/** @file
+ Definition of the CPU global NVS area protocol. This protocol
+ publishes the address and format of a global ACPI NVS buffer used as a communications
+ buffer between SMM/DXE/PEI code and ASL code.
+
+ 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.
+
+**/
+
+#ifndef _CPU_GLOBAL_NVS_AREA_H_
+#define _CPU_GLOBAL_NVS_AREA_H_
+
+typedef struct _CPU_GLOBAL_NVS_AREA_PROTOCOL CPU_GLOBAL_NVS_AREA_PROTOCOL;
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gCpuGlobalNvsAreaProtocolGuid;
+
+//
+// Processor Power Management GlobalNvs Revisions
+//
+#define CPU_GLOBAL_NVS_AREA_REVISION_1 1 ///< Initial Version
+
+#pragma pack(1)
+///
+/// CPU Global NVS Area definition
+///
+typedef struct {
+ UINT8 Revision; ///< (0) CPU GlobalNvs Revision
+ //
+ // PPM Flag Values
+ //
+ UINT32 PpmFlags; ///< (1-4) PPM Flags
+ //
+ // Number of Logical Processors Values
+ //
+ UINT8 LogicalProcessorCount; ///< (5) Number of Logical Processors
+ //
+ // Thermal Configuration Values
+ //
+ UINT8 AutoCriticalTripPoint; ///< (6) Auto Critical Trip Point
+ UINT8 AutoPassiveTripPoint; ///< (7) Auto Passive Trip Point
+ UINT8 AutoActiveTripPoint; ///< (8) Auto Active Trip Point
+ UINT32 Cpuid; ///< (9-12) CPUID
+ UINT8 Reserved[28]; ///< (13-40) Reserved
+ //
+ // Mwait Hints and Latency values for C3/C6/C7/C7S
+ //
+ UINT8 C3MwaitValue; ///< (41) Mwait Hint value for C3
+ UINT8 C6MwaitValue; ///< (42) Mwait Hint value for C6
+ UINT8 C7MwaitValue; ///< (43) Mwait Hint value for C6
+ UINT8 CDMwaitValue; ///< (44) Mwait Hint value for C7/C8/C9/C10
+ UINT16 C3Latency; ///< (45-46) Latency value for C3
+ UINT16 C6Latency; ///< (47-48) Latency Value for C6
+ UINT16 C7Latency; ///< (49-50) Latency Value for C6
+ UINT16 CDLatency; ///< (51-52) Latency Value for C7/C8/C9/C10
+ UINT16 CDIOLevel; ///< (53-54) IO Level Value for C7/C8/C9/C10
+ UINT16 CDPowerValue; ///< (55-56) Power Value for C7/C8/C9/C10
+ UINT8 MiscPowerManagementFlags; ///< (57) MiscPowerManagementFlags
+ //
+ // DTS
+ //
+ UINT8 EnableDigitalThermalSensor; ///< (58) DTS Function enable
+ UINT8 BspDigitalThermalSensorTemperature; ///< (59) Temperature of BSP
+ UINT8 ApDigitalThermalSensorTemperature; ///< (60) Temperature of AP
+ UINT8 DigitalThermalSensorSmiFunction; ///< (61) SMI function call via DTS IO Trap
+ UINT8 PackageDTSTemperature; ///< (62) Package temperature
+ UINT8 IsPackageTempMSRAvailable; ///< (63) Package Temperature MSR available
+ UINT8 Ap2DigitalThermalSensorTemperature; ///< (64) Temperature of the second AP
+ UINT8 Ap3DigitalThermalSensorTemperature; ///< (65) Temperature of the third AP
+
+ UINT8 Reserved1[16]; ///< (66-81) Reserved
+ UINT8 DtsAcpiEnable; ///< (82) DTS is in ACPI Mode Enabled
+ //
+ // Software Guard Extension
+ //
+ UINT8 SgxStatus; ///< (83) SE Status
+ UINT64 EpcBaseAddress; ///< (84-91) EPC Base Address
+ UINT64 EpcLength; ///< (92-99) EPC Length
+ //
+ // HWP
+ //
+ UINT8 HwpVersion; ///< (100) HWP Status
+ UINT16 HwpIoTrapAddress; ///< (101-102) IoTrap Address for HWP
+ UINT16 HwpIoTrapLength; ///< (103-104) IoTrap Length for HWP
+ UINT8 PowerState; ///< (105) Power State
+ UINT8 EnableHdcPolicy; ///< (106) Hardware Duty Cycling Policy
+ UINT8 HwpInterruptStatus; ///< (107) HWP Interrupt Status
+
+ UINT8 MonitorMwaitEnable; ///< (108) Mwait Enable
+} CPU_GLOBAL_NVS_AREA;
+#pragma pack()
+///
+/// CPU Global NVS Area Protocol
+///
+struct _CPU_GLOBAL_NVS_AREA_PROTOCOL {
+ CPU_GLOBAL_NVS_AREA *Area;
+};
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h
new file mode 100644
index 0000000000..79806392b4
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h
@@ -0,0 +1,127 @@
+/** @file
+ Protocol used to report CPU information.
+
+ 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 _CPU_INFO_H_
+#define _CPU_INFO_H_
+
+#include <CpuDataStruct.h>
+
+typedef struct _CPU_INFO_PROTOCOL CPU_INFO_PROTOCOL;
+
+extern EFI_GUID gCpuInfoProtocolGuid;
+
+//
+// DXE_CPU_INFO_PROTOCOL revisions
+//
+#define CPU_INFO_PROTOCOL_REVISION 1
+
+//
+// Processor feature definitions.
+//
+#define TXT_SUPPORT BIT0
+#define VMX_SUPPORT BIT1
+#define XD_SUPPORT BIT2
+#define DCA_SUPPORT BIT3
+#define X2APIC_SUPPORT BIT4
+#define AES_SUPPORT BIT5
+#define HT_SUPPORT BIT6
+#define DEBUG_SUPPORT BIT7
+#define DEBUG_LOCK_SUPPORT BIT8
+#define PROC_TRACE_SUPPORT BIT9
+#define HDC_SUPPORT BIT10
+
+
+#pragma pack(1)
+///
+/// Cache descriptor information
+///
+typedef struct {
+ UINT8 Desc; ///< Cache Descriptor
+ UINT8 Level; ///< Cache Level
+ UINT8 Type; ///< Cache Type. 0: Data, 1: Instruction, 3: Unified
+ UINT32 Size; ///< Cache Size.
+ UINT16 Associativity; ///< Cache Ways of Associativity.
+} CACHE_DESCRIPTOR_INFO;
+
+///
+/// Processor information
+///
+typedef struct {
+ UINT32 CpuSignature; ///< Processor signature and version information.
+ UINT64 Features; ///< Features availability in the CPU based on reading ECX after doing Asmcpuid(EAX=1).
+ CHAR8 *BrandString; ///< Processor Brand String.
+ UINT8 NumSupportedCores; ///< Total Number of Supported Cores in CPU Package. If Dual core, 2 cores.
+ UINT8 NumSupportedThreadsPerCore; ///< Number of Supported Threads per Core.
+ UINT8 NumCores; ///< Number of Enabled or Active Cores.
+ UINT8 NumHts; ///< Number of Hyper threading. This will be 0 or 2.
+ UINT32 IntendedFreq; ///< Maximum non turbo ratio in MHz
+ UINT32 ActualFreq; ///< Actual frequency in MHz
+ UINT32 Voltage; ///< Current operating voltage.
+ CACHE_DESCRIPTOR_INFO *CacheInfo; ///< Cache descriptor information.
+ UINT8 MaxCacheSupported; ///< Maximum cache supported.
+ UINT8 SmmbaseSwSmiNumber; ///< Software SMI Number from Smbase.
+} CPU_INFO;
+
+///
+/// This HOB is data structure representing two different address location in SMRAM to hold SMRAM CPU DATA.
+///
+typedef struct {
+ EFI_PHYSICAL_ADDRESS LockBoxData; ///< First location (address) of SMRAM CPU DATA.
+ EFI_PHYSICAL_ADDRESS SmramCpuData; ///< Second location (Address) of SMRAM CPU DATA.
+ UINT64 LockBoxSize; ///< Size of SMRAM CPU DATA.
+} SMRAM_CPU_INFO;
+
+#pragma pack()
+
+///
+/// This protocol provides information about the common features available in this CPU.
+///
+struct _CPU_INFO_PROTOCOL {
+ /**
+ Revision for the protocol structure.
+ Any backwards compatible changes to this protocol will result in an update in the revision number.
+ Major changes will require publication of a new protocol
+
+ <b>Revision 1</b>:
+ - Initial version
+ **/
+ UINT8 Revision;
+ /**
+ CPU Supported Feature.
+ - BIT0: If set then processor supports TXT.
+ - BIT1: If set then processor supports virtual mode extensions.
+ - BIT2: If set then processor supports execute disable bit.
+ - BIT3: If set then processor supports DCA.
+ - BIT4: If set then processor supports X2APIC.
+ - BIT5: If set then processor supports Advanced Encryption Standard.
+ - BIT6: If set then processor supports hyperthreading.
+ - BIT7: If set then processor supports debug interface.
+ - BIT8: If set then processor supports debug interface lock.
+ - BIT9: If set then processor supports processor trace.
+ - BIT10: If Set then processor supports supports HDC.
+ **/
+ UINT64 CpuCommonFeatures;
+ /**
+ Processor Basic Information
+ **/
+ CPU_INFO *CpuInfo;
+ /**
+ SMRAM CPU Information
+ **/
+ SMRAM_CPU_INFO *SmramCpuInfo;
+};
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
new file mode 100644
index 0000000000..daecf01e86
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
@@ -0,0 +1,113 @@
+/** @file
+ This file is CpuPrintPolicy 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.
+
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+
+/**
+ Print whole CPU_POLICY_PPI and serial out in PostMem.
+
+ @param[in] SiCpuPolicyPpi The RC Policy PPI instance
+
+**/
+VOID
+CpuPrintPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ )
+{
+#ifdef EFI_DEBUG
+ EFI_STATUS Status;
+ UINTN Index;
+ CPU_CONFIG *CpuConfig;
+ POWER_MGMT_CONFIG *PowerMgmtConfig;
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gCpuConfigGuid,(VOID *) &CpuConfig);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, " Get config block for GUIId = %g \n", &gCpuConfigGuid));
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER*)SiCpuPolicyPpi, &gPowerMgmtConfigGuid,(VOID *)&PowerMgmtConfig);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, " Get config block for GUIId = %g \n", &gPowerMgmtConfigGuid));
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ SiCpuPolicyPpi Print Begin in PostMem-----------------\n"));
+ //
+ // CPU_CONFIG
+ //
+ DEBUG ((DEBUG_INFO, " CPU:: HyperThreading : 0x%X\n", CpuConfig->HyperThreading));
+ DEBUG ((DEBUG_INFO, " CPU:: VmxEnable : 0x%X\n", CpuConfig->VmxEnable));
+ DEBUG ((DEBUG_INFO, " CPU:: ProcTraceMemSize : 0x%X\n", CpuConfig->ProcTraceMemSize));
+ DEBUG ((DEBUG_INFO, " CPU:: ProcTraceEnable : 0x%X\n", CpuConfig->ProcTraceEnable));
+ DEBUG ((DEBUG_INFO, " CPU:: ActiveProcessorCores : 0x%X\n", CpuConfig->ActiveProcessorCores));
+ DEBUG ((DEBUG_INFO, " CPU:: Core1 : 0x%X\n", CpuConfig->DisableCore1));
+ DEBUG ((DEBUG_INFO, " CPU:: Core2 : 0x%X\n", CpuConfig->DisableCore2));
+ DEBUG ((DEBUG_INFO, " CPU:: Core3 : 0x%X\n", CpuConfig->DisableCore3));
+ //
+ // POWER_MGMT_CONFIG
+ //
+ DEBUG ((DEBUG_INFO, " PPM:: TccActivationOffset : 0x%X\n", PowerMgmtConfig->TccActivationOffset));
+ DEBUG ((DEBUG_INFO, " PPM:: RatioLimit[4] : 0x%X , 0x%X , 0x%X , 0x%X \n", PowerMgmtConfig->RatioLimit[0], \
+ PowerMgmtConfig->RatioLimit[1], \
+ PowerMgmtConfig->RatioLimit[2], \
+ PowerMgmtConfig->RatioLimit[3]));
+ DEBUG ((DEBUG_INFO, " S3RestoreMsrSwSmiNumber : %x\n", PowerMgmtConfig->S3RestoreMsrSwSmiNumber));
+ DEBUG ((DEBUG_INFO, "\n Ppm Lock Enables... \n"));
+ DEBUG ((DEBUG_INFO, " PmgCstCfgCtrlLock : %x\n", PowerMgmtConfig->PmgCstCfgCtrlLock));
+ DEBUG ((DEBUG_INFO, " ProcHotLock : %x\n", PowerMgmtConfig->ProcHotLock));
+ DEBUG ((DEBUG_INFO, "\n PowerMgmtConfig... \n"));
+ DEBUG ((DEBUG_INFO, " Eist : %x\n", PowerMgmtConfig->Eist));
+ DEBUG ((DEBUG_INFO, " Cx : %x\n", PowerMgmtConfig->Cx));
+ DEBUG ((DEBUG_INFO, " C1e : %x\n", PowerMgmtConfig->C1e));
+ DEBUG ((DEBUG_INFO, " C1Autodemotion : %x\n", PowerMgmtConfig->C1AutoDemotion));
+ DEBUG ((DEBUG_INFO, " C3AutoDemotion : %x\n", PowerMgmtConfig->C3AutoDemotion));
+ DEBUG ((DEBUG_INFO, " C1Undemotion : %x\n", PowerMgmtConfig->C1UnDemotion));
+ DEBUG ((DEBUG_INFO, " C3UnDemotion : %x\n", PowerMgmtConfig->C3UnDemotion));
+ DEBUG ((DEBUG_INFO, " PkgCstateUndemotion : %x\n", PowerMgmtConfig->PkgCStateUnDemotion));
+ DEBUG ((DEBUG_INFO, " PkgCState Demotion : %x\n", PowerMgmtConfig->PkgCStateDemotion));
+ DEBUG ((DEBUG_INFO, " TurboMode : %x\n", PowerMgmtConfig->TurboMode));
+ DEBUG ((DEBUG_INFO, " PowerLimit2 : %x\n", PowerMgmtConfig->PowerLimit2));
+ DEBUG ((DEBUG_INFO, " PkgCStateLimit : %x\n", PowerMgmtConfig->PkgCStateLimit));
+ DEBUG ((DEBUG_INFO, " TimedMwait : %x\n", PowerMgmtConfig->TimedMwait));
+
+ DEBUG ((DEBUG_INFO, "\n Turbo settings... \n"));
+ DEBUG ((DEBUG_INFO, " PowerLimit1 Enable : %x\n", PowerMgmtConfig->PowerLimit1Enable));
+ DEBUG ((DEBUG_INFO, " PowerLimit1 Clamp Mode : %x\n", PowerMgmtConfig->PowerLimit1ClampEnable));
+ DEBUG ((DEBUG_INFO, " PowerLimit1 : %x\n", PowerMgmtConfig->PowerLimit1));
+ DEBUG ((DEBUG_INFO, " Custom PowerLimit1 : %x\n", PowerMgmtConfig->CustomPowerLimit1));
+ DEBUG ((DEBUG_INFO, " PowerLimit1Time : %x\n", PowerMgmtConfig->PowerLimit1Time));
+ DEBUG ((DEBUG_INFO, " Custom PowerLimit1Time : %x\n", PowerMgmtConfig->CustomPowerLimit1Time));
+ DEBUG ((DEBUG_INFO, " PowerLimit2 : %x\n", PowerMgmtConfig->PowerLimit2));
+ DEBUG ((DEBUG_INFO, " PowerLimit3 : %x\n", PowerMgmtConfig->PowerLimit3));
+ DEBUG ((DEBUG_INFO, " PowerLimit3Time : %x\n", PowerMgmtConfig->PowerLimit3Time));
+ DEBUG ((DEBUG_INFO, " PowerLimit3DutyCycle : %x\n", PowerMgmtConfig->PowerLimit3DutyCycle));
+ DEBUG ((DEBUG_INFO, " PowerLimit3Lock : %x\n", PowerMgmtConfig->PowerLimit3Lock));
+ DEBUG ((DEBUG_INFO, " PowerLimit4 : %x\n", PowerMgmtConfig->PowerLimit4));
+ DEBUG ((DEBUG_INFO, " PowerLimit4Lock : %x\n", PowerMgmtConfig->PowerLimit4Lock));
+ DEBUG ((DEBUG_INFO, " TurboPowerLimitLock : %x\n", PowerMgmtConfig->TurboPowerLimitLock));
+ DEBUG ((DEBUG_INFO, " VidNumber : %x\n", PowerMgmtConfig->NumberOfEntries));
+ DEBUG ((DEBUG_INFO, " VidCpuid : %x\n", PowerMgmtConfig->Cpuid));
+ DEBUG ((DEBUG_INFO, " VidMaxRatio : %x\n", PowerMgmtConfig->MaxRatio));
+ for (Index = 0; Index < MAX_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+ DEBUG ((DEBUG_INFO, " StateRatio[%d] : %x\n", Index, PowerMgmtConfig->StateRatio[Index]));
+ }
+ DEBUG ((DEBUG_INFO, " BiProcHot : %x\n", PowerMgmtConfig->BiProcHot));
+ DEBUG ((DEBUG_INFO, " DisableProcHotOut : %x\n", PowerMgmtConfig->DisableProcHotOut));
+ DEBUG ((DEBUG_INFO, " ProcHotResponse : %x\n", PowerMgmtConfig->ProcHotResponse));
+ DEBUG ((DEBUG_INFO, " TStates : %x\n", PowerMgmtConfig->TStates));
+ DEBUG ((DEBUG_INFO, " AutoThermalReporting : %x\n", PowerMgmtConfig->AutoThermalReporting));
+ DEBUG ((DEBUG_INFO, " ThermalMonitor : %x\n", PowerMgmtConfig->ThermalMonitor));
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ SiCpuPolicyPpi Print End -----------------\n\n"));
+#endif
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
new file mode 100644
index 0000000000..1b67c9813d
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
@@ -0,0 +1,378 @@
+/** @file
+ This file is PeiCpuPolicy 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.
+
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 SocketNameString[] = "U3E1";
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 FillByOemString[] = "To Be Filled By O.E.M.";
+
+//
+// Function call to Load defaults for Individial IP Blocks
+//
+EFI_STATUS
+EFIAPI
+LoadCpuPreMemDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_CONFIG_PREMEM *CpuConfigPreMem;
+
+ CpuConfigPreMem = ConfigBlockPointer;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadBiosGuardDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ BIOS_GUARD_CONFIG *BiosGuardConfig;
+
+ BiosGuardConfig = ConfigBlockPointer;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadCpuDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_CONFIG *CpuConfig;
+ SMBIOS_SOCKET_INFO *SmbiosSocketInfo;
+ UINT64 MsrValue;
+
+ CpuConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "CpuConfig->BlockSize = 0x%x\n", CpuConfig->Header.Size));
+
+ //
+ // Policy initialization commented out here is because it's the same with default 0 and no need to re-do again.
+ //
+ CpuConfig->SmmbaseSwSmiNumber = SW_SMI_FROM_SMMBASE;
+ CpuConfig->CpuRatio = 63;
+ CpuConfig->HyperThreading = CPU_FEATURE_DISABLE;
+ CpuConfig->ProcTraceEnable = CPU_FEATURE_DISABLE;
+ CpuConfig->VmxEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->SmxEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->MonitorMwaitEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->MachineCheckEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->AesEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->DebugInterfaceLockEnable = CPU_FEATURE_ENABLE;
+ CpuConfig->ApIdleManner = 1;
+ CpuConfig->ApHandoffManner = 1;
+ CpuConfig->ActiveProcessorCores = CPU_FEATURE_ALL_CORES_ENABLE;
+ CpuConfig->DisableCore1 = CPU_FEATURE_DISABLE;
+ CpuConfig->DisableCore2 = CPU_FEATURE_DISABLE;
+ CpuConfig->DisableCore3 = CPU_FEATURE_DISABLE;
+ CpuConfig->EnableDts = CPU_FEATURE_DISABLE;
+ CpuConfig->PackageDts = CPU_FEATURE_DISABLE;
+
+ //
+ // Processor Trace
+ //
+ CpuConfig->ProcTraceMemSize = EnumProcTraceMemDisable;
+ CpuConfig->SmbiosSocketInfo = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool (sizeof (SMBIOS_SOCKET_INFO));
+ SmbiosSocketInfo = (SMBIOS_SOCKET_INFO *) (UINTN) CpuConfig->SmbiosSocketInfo;
+ if (SmbiosSocketInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MsrValue = AsmReadMsr64 (MSR_PLATFORM_INFO);
+ SmbiosSocketInfo->MaxSpeed = (100 * (((UINT32) MsrValue >> N_PLATFORM_INFO_MAX_RATIO) & B_PLATFORM_INFO_RATIO_MASK));
+
+ SmbiosSocketInfo->ProcessorUpgrade = ProcessorUpgradeOther;
+ CpuConfig->MlcStreamerPrefetcher = CPU_FEATURE_ENABLE;
+ CpuConfig->MlcSpatialPrefetcher = CPU_FEATURE_ENABLE;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadCpuOverclockingDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_OVERCLOCKING_CONFIG *CpuOverclockingConfig;
+
+ CpuOverclockingConfig = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "CpuOverclockingConfig->BlockSize = 0x%x\n", CpuOverclockingConfig->Header.Size));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadPowerMgmtDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ POWER_MGMT_CONFIG *PowerMgmtConfig;
+
+ PowerMgmtConfig = ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "PowerMgmtConfig->BlockSize = 0x%x\n", PowerMgmtConfig->Header.Size));
+
+ //
+ // Initialize RATL (Runtime Average Temperature Limit) Config
+ //
+ PowerMgmtConfig->TccActivationOffset = 10;
+
+ PowerMgmtConfig->Eist = TRUE;
+ PowerMgmtConfig->Cx = TRUE;
+ PowerMgmtConfig->C1e = TRUE;
+ PowerMgmtConfig->C1AutoDemotion = TRUE;
+ PowerMgmtConfig->C3AutoDemotion = TRUE;
+ PowerMgmtConfig->C1UnDemotion = TRUE;
+ PowerMgmtConfig->C3UnDemotion = TRUE;
+ PowerMgmtConfig->BiProcHot = TRUE;
+ PowerMgmtConfig->DisableProcHotOut = TRUE;
+ PowerMgmtConfig->TurboMode = TRUE;
+ PowerMgmtConfig->PowerLimit2Enable = TRUE;
+ PowerMgmtConfig->AutoThermalReporting = TRUE;
+ PowerMgmtConfig->ThermalMonitor = TRUE;
+ PowerMgmtConfig->CustomPowerUnit = PowerUnit125MilliWatts;
+ PowerMgmtConfig->PowerLimit1 = AUTO;
+ PowerMgmtConfig->PowerLimit2 = AUTO;
+ PowerMgmtConfig->PowerLimit1Time = AUTO;
+ PowerMgmtConfig->PowerLimit3 = AUTO;
+ PowerMgmtConfig->PowerLimit4 = AUTO;
+ PowerMgmtConfig->PowerLimit3Time = AUTO;
+ PowerMgmtConfig->PowerLimit3DutyCycle = AUTO;
+ PowerMgmtConfig->PowerLimit3Lock = TRUE;
+ PowerMgmtConfig->PlatformPowerLimit1Power = AUTO;
+ PowerMgmtConfig->PlatformPowerLimit1Time = AUTO;
+ PowerMgmtConfig->PlatformPowerLimit2Power = AUTO;
+ PowerMgmtConfig->DdrPowerLimit = AUTO;
+ PowerMgmtConfig->PmgCstCfgCtrlLock = TRUE;
+ PowerMgmtConfig->S3RestoreMsrSwSmiNumber = SW_SMI_S3_RESTORE_MSR;
+ PowerMgmtConfig->PkgCStateLimit = PkgCpuDefault;
+ PowerMgmtConfig->TurboPowerLimitLock = FALSE;
+ PowerMgmtConfig->ProcHotLock = FALSE;
+ PowerMgmtConfig->RatioLimitProgramable = FALSE;
+ PowerMgmtConfig->TStates = TRUE;
+ PowerMgmtConfig->SkipSetBootPState = CPU_FEATURE_DISABLE;
+ PowerMgmtConfig->VrConfig = CPU_FEATURE_DISABLE;
+ PowerMgmtConfig->PowerLimit1Enable = TRUE;
+ PowerMgmtConfig->PowerLimit1ClampEnable = TRUE;
+ PowerMgmtConfig->CustomPowerLimit1 = AUTO;
+ PowerMgmtConfig->CustomPowerLimit1Time = AUTO;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize default settings for each CPU Config block
+
+ @param[in] ConfigBlockPointer The buffer pointer that will be initialized as specific config block.
+ @param[in] BlockId Request to initialize defaults of specified config block by given Block ID.
+
+ @retval EFI_SUCCESS The given buffer has contained the defaults of requested config block.
+ @retval EFI_NOT_FOUND Block ID is not defined so no default Config block will be initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+LoadCpuConfigBlockDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CONFIG_BLOCK *ConfigBlkPtr;
+
+ ConfigBlkPtr = (CONFIG_BLOCK *) ConfigBlockPointer;
+
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gCpuConfigPreMemGuid)) {
+ LoadCpuPreMemDefault (ConfigBlockPointer);
+ }
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gBiosGuardConfigGuid)) {
+ LoadBiosGuardDefault(ConfigBlockPointer);
+ }
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gCpuConfigGuid)) {
+ LoadCpuDefault (ConfigBlockPointer);
+ }
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gCpuOverclockingConfigGuid)) {
+ LoadCpuOverclockingDefault (ConfigBlockPointer);
+ }
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gPowerMgmtConfigGuid)) {
+ LoadPowerMgmtDefault(ConfigBlockPointer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ CreateCpuConfigBlocks creates the default setting of PEI Cpu Policy.
+ It allocates and zero out buffer, and fills in the Intel default settings.
+
+ @param[out] SiCpuPolicyPpi The pointer to get PEI Cpu Policy PPI instance.
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateCpuConfigBlocks (
+ OUT SI_CPU_POLICY_PPI **SiCpuPolicyPpi
+ )
+{
+ SI_CPU_POLICY_PPI *SiCpuPolicy;
+ UINT32 ConfigBlockTableTotalSize;
+ UINT8 TotalBlockCount;
+ EFI_STATUS Status;
+ UINT8 BlockCount;
+ VOID *ConfigBlockPointer;
+ CONFIG_BLOCK_HEADER mBxtCpuIpBlocksPostMem [4];
+
+ PostCode (0xC00);
+ CopyMem (&mBxtCpuIpBlocksPostMem[0].Guid, &gBiosGuardConfigGuid, sizeof (EFI_GUID));
+ CopyMem (&mBxtCpuIpBlocksPostMem[1].Guid, &gCpuConfigGuid, sizeof (EFI_GUID));
+ CopyMem (&mBxtCpuIpBlocksPostMem[2].Guid, &gCpuOverclockingConfigGuid, sizeof (EFI_GUID));
+ CopyMem (&mBxtCpuIpBlocksPostMem[3].Guid, &gPowerMgmtConfigGuid, sizeof (EFI_GUID));
+
+ mBxtCpuIpBlocksPostMem[0].Size = sizeof (BIOS_GUARD_CONFIG);
+ mBxtCpuIpBlocksPostMem[1].Size = sizeof (CPU_CONFIG);
+ mBxtCpuIpBlocksPostMem[2].Size = sizeof (CPU_OVERCLOCKING_CONFIG);
+ mBxtCpuIpBlocksPostMem[3].Size = sizeof (POWER_MGMT_CONFIG);
+ mBxtCpuIpBlocksPostMem[0].Revision = BIOS_GUARD_CONFIG_REVISION;
+ mBxtCpuIpBlocksPostMem[1].Revision = CPU_CONFIG_REVISION;
+ mBxtCpuIpBlocksPostMem[2].Revision = CPU_OVERCLOCKING_CONFIG_REVISION;
+ mBxtCpuIpBlocksPostMem[3].Revision = POWER_MGMT_CONFIG_REVISION;
+
+ TotalBlockCount = sizeof (mBxtCpuIpBlocksPostMem) / sizeof (CONFIG_BLOCK_HEADER);
+
+ ConfigBlockTableTotalSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockCount * 4;
+ for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+ ConfigBlockTableTotalSize += (UINT32) mBxtCpuIpBlocksPostMem[BlockCount].Size;
+ }
+
+ //
+ // Allocate memory for the CPU Policy Ppi and Descriptor
+ //
+ DEBUG ((DEBUG_INFO, "CreateCpuConfigBlocksPostMem Start\n"));
+ Status = CreateConfigBlockTable ((VOID *) &SiCpuPolicy, TotalBlockCount, ConfigBlockTableTotalSize);
+ if (SiCpuPolicy == NULL) {
+ ASSERT (SiCpuPolicy != NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize Policy Revision
+ //
+ SiCpuPolicy->ConfigBlockTableHeader.Header.Revision = SI_CPU_POLICY_PPI_REVISION;
+
+ //
+ // Initialize ConfigBlockPointer to NULL
+ //
+ ConfigBlockPointer = NULL;
+
+ //
+ // Put IP_BLOCK_STRUCT and target structure into the right place in SI_CPU_POLICY_PPI
+ //
+ for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+ ConfigBlockPointer = (VOID *) &mBxtCpuIpBlocksPostMem [BlockCount];
+ Status = AddConfigBlock ((VOID *) SiCpuPolicy, (VOID *) &ConfigBlockPointer);
+ ASSERT_EFI_ERROR (Status);
+ LoadCpuConfigBlockDefault ((VOID *) ConfigBlockPointer);
+ }
+
+ //
+ // Assignment for returning CpuInitPolicy config block base address
+ //
+ *SiCpuPolicyPpi = SiCpuPolicy;
+ PostCode (0xC0F);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ CpuInstallPolicyPpi installs SiCpuPolicyPpi.
+ While installed, RC assumes the Policy is ready and finalized. So please update and override
+ any setting before calling this function.
+
+ @param[in] SiCpuPolicyPpi The pointer to PEI Cpu Policy PPI instance.
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *NewSiCpuPolicyPpiDesc;
+ EFI_PEI_PPI_DESCRIPTOR *OldSiCpuPolicyPpiDesc;
+ SI_CPU_POLICY_PPI *OldSiCpuPolicy;
+
+ NewSiCpuPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ if (NewSiCpuPolicyPpiDesc == NULL) {
+ ASSERT (NewSiCpuPolicyPpiDesc != NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewSiCpuPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ NewSiCpuPolicyPpiDesc->Guid = &gSiCpuPolicyPpiGuid;
+ NewSiCpuPolicyPpiDesc->Ppi = SiCpuPolicyPpi;
+
+ //
+ // Print whole SI_CPU_POLICY_PPI and serial out in PostMem.
+ //
+ CpuPrintPolicyPpi (SiCpuPolicyPpi);
+ //
+ // Locate Cpu Policy Ppi
+ //
+ Status = PeiServicesLocatePpi (
+ &gSiCpuPolicyPpiGuid,
+ 0,
+ &OldSiCpuPolicyPpiDesc,
+ (VOID **) &OldSiCpuPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Install PEI Cpu Policy PPI
+ //
+ DEBUG ((DEBUG_ERROR, "Locate Old Si CPU Policy Ppi fail in Post-Memory\n"));
+ Status = PeiServicesInstallPpi (NewSiCpuPolicyPpiDesc);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Install Si CPU Policy Ppi fail in Post-Memory\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // ReInstall PEI Cpu Policy PPI
+ //
+ DEBUG ((EFI_D_INFO, "Re-Install Si CPU Policy Ppi in Post-Memory\n"));
+ Status = PeiServicesReInstallPpi (OldSiCpuPolicyPpiDesc, NewSiCpuPolicyPpiDesc);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Re-Install Si CPU Policy Ppi fail in Post-Memory\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
new file mode 100644
index 0000000000..a72beee561
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
@@ -0,0 +1,51 @@
+## @file
+# PeiCpuPolicyLib 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 = PeiCpuPolicyLib
+ FILE_GUID = 5baafc8f-25c6-4d19-b141-585757509372
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = CpuPolicyLib
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ PeiServicesLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ ConfigBlockLib
+ CpuPlatformLib
+ PostCodeLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonSiPkg/BroxtonSiPrivate.dec
+
+[Sources]
+ PeiCpuPolicyLib.c
+ PeiCpuPolicyLibrary.h
+ CpuPrintPolicy.c
+
+[Ppis]
+ gSiCpuPolicyPpiGuid ## CONSUMES
+ gBiosGuardConfigGuid ## CONSUMES
+ gCpuConfigPreMemGuid ## CONSUMES
+ gCpuConfigGuid ## CONSUMES
+ gPowerMgmtConfigGuid ## CONSUMES
+ gSoftwareGuardConfigGuid ## CONSUMES
+ gCpuOverclockingConfigGuid ## CONSUMES
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
new file mode 100644
index 0000000000..fcb208003f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for the PeiCpuPolicyLib 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.
+
+**/
+
+#ifndef _PEI_CPU_POLICY_LIBRARY_H_
+#define _PEI_CPU_POLICY_LIBRARY_H_
+
+#include <PiPei.h>
+#include <CpuAccess.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/CpuPolicy.h>
+#include <Library/CpuPolicyLib.h>
+#include <IndustryStandard/SmBios.h>
+
+#include <Library/CpuPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+
+#define SMM_FROM_SMBASE_DRIVER 0x55
+#define SW_SMI_FROM_SMMBASE SMM_FROM_SMBASE_DRIVER
+
+//
+// TXT configuration defines
+//
+#define TXT_SINIT_MEMORY_SIZE 0x50000
+#define TXT_HEAP_MEMORY_SIZE 0xE0000
+
+#define TXT_LCP_PD_BASE 0x0 ///< Platform default LCP
+#define TXT_LCP_PD_SIZE 0x0 ///< Platform default LCP
+#define TXT_TGA_MEMORY_SIZE 0x0 ///< Maximum 512K of TGA memory (aperture)
+
+#endif // _PEI_CPU_POLICY_LIBRARY_H_
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c
new file mode 100644
index 0000000000..1968937bc0
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c
@@ -0,0 +1,38 @@
+/** @file
+ This file is PeiCpuPolicy 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.
+
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+
+/**
+ Print whole SI_CPU_POLICY_PPI and serial out in PreMem.
+
+ @param[in] SiCpuPolicyPpi The RC Policy PPI instance
+
+**/
+VOID
+CpuPrintPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ CPU_CONFIG_PREMEM *CpuConfigPreMem;
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gCpuConfigPreMemGuid, (VOID *) &CpuConfigPreMem);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, " Get config block for GUID = %g",&gCpuConfigPreMemGuid));
+ DEBUG ((DEBUG_INFO, "\n------------------------ SiCpuPolicy Print End -----------------\n\n"));
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c
new file mode 100644
index 0000000000..92e8a5520f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c
@@ -0,0 +1,182 @@
+/** @file
+ This file is PeiCpuPolicy 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.
+
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/PostCodeLib.h>
+
+EFI_STATUS
+EFIAPI
+LoadCpuPreMemDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_CONFIG_PREMEM *CpuConfigPreMem;
+
+ CpuConfigPreMem = ConfigBlockPointer;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize default settings for each CPU Config block
+
+ @param[in] ConfigBlockPointer The buffer pointer that will be initialized as specific config block.
+ @param[in] BlockId Request to initialize defaults of specified config block by given Block ID.
+
+ @retval EFI_SUCCESS The given buffer has contained the defaults of requested config block.
+ @retval EFI_NOT_FOUND Block ID is not defined so no default Config block will be initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+LoadCpuConfigBlockDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CONFIG_BLOCK *ConfigBlkPtr;
+
+ ConfigBlkPtr = (CONFIG_BLOCK *) ConfigBlockPointer;
+ DEBUG ((DEBUG_INFO, "load:GUID A=%g,GUIDB=%g\n", &(ConfigBlkPtr->Header.Guid), &gCpuConfigPreMemGuid));
+
+ if (CompareGuid (&(ConfigBlkPtr->Header.Guid), &gCpuConfigPreMemGuid)) {
+ LoadCpuPreMemDefault (ConfigBlockPointer);
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ CreateCpuConfigBlocks creates the default setting of PEI Cpu Policy.
+ It allocates and zero out buffer, and fills in the Intel default settings.
+
+ @param[out] SiCpuPolicyPpi The pointer to get PEI Cpu Policy PPI instance.
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateCpuConfigBlocks (
+ OUT SI_CPU_POLICY_PPI **SiCpuPolicyPpi
+ )
+{
+ UINT32 ConfigBlockTableTotalSize;
+ UINT8 TotalBlockCount;
+ EFI_STATUS Status;
+ UINT8 BlockCount;
+ VOID *ConfigBlockPointer;
+ SI_CPU_POLICY_PPI *SiCpuPolicy;
+ CONFIG_BLOCK_HEADER mBxtCpuIpBlocksPreMem [1];
+
+ PostCode (0xC00);
+ CopyMem (&mBxtCpuIpBlocksPreMem[0].Guid, &gCpuConfigPreMemGuid, sizeof (EFI_GUID));
+ mBxtCpuIpBlocksPreMem[0].Size = sizeof (CPU_CONFIG_PREMEM);
+ mBxtCpuIpBlocksPreMem[0].Revision = CPU_CONFIG_PREMEM_REVISION;
+
+ TotalBlockCount = sizeof (mBxtCpuIpBlocksPreMem) / sizeof (CONFIG_BLOCK_HEADER);
+
+ ConfigBlockTableTotalSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockCount * 4;
+ for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+ ConfigBlockTableTotalSize += (UINT32) mBxtCpuIpBlocksPreMem[BlockCount].Size;
+ }
+
+ //
+ // Allocate memory for the CPU Policy Ppi and Descriptor
+ //
+ DEBUG ((DEBUG_INFO, "CreateCpuConfigBlocksPreMem Start\n"));
+ Status = CreateConfigBlockTable ((void **) &SiCpuPolicy, TotalBlockCount, ConfigBlockTableTotalSize);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "CreateConfigBlockTable Done\n"));
+ if (SiCpuPolicy == NULL) {
+ ASSERT (SiCpuPolicy != NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize ConfigBlockPointer to NULL
+ //
+ ConfigBlockPointer = NULL;
+
+ //
+ // Put IP_BLOCK_STRUCT and target structure into the right place in SI_CPU_POLICY_PPI
+ //
+ for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+ ConfigBlockPointer = (VOID *) &mBxtCpuIpBlocksPreMem[BlockCount];
+ DEBUG ((DEBUG_INFO, "Addnew config block for Guid = %g \n", &(((CONFIG_BLOCK_HEADER *) ConfigBlockPointer)->Guid)));
+ Status = AddConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicy, (VOID *) &ConfigBlockPointer);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "Addnew config block for mBxtCpuIpBlocksPreMem[BlockCount].Guid = 0x%x \n",
+ mBxtCpuIpBlocksPreMem[BlockCount].Guid));
+ LoadCpuConfigBlockDefault ((VOID *) ConfigBlockPointer);
+ }
+ //
+ // Assignment for returning CpuInitPolicy config block base address
+ //
+ *SiCpuPolicyPpi = SiCpuPolicy;
+ PostCode (0xC2F);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ CpuInstallPolicyPpi installs SiCpuPolicyPpi.
+ While installed, RC assumes the Policy is ready and finalized. So please update and override
+ any setting before calling this function.
+
+ @param[in] SiCpuPolicyPpi The pointer to PEI Cpu Policy PPI instance.
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyPpi (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicy
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *SiCpuPolicyPpiDesc;
+
+ SiCpuPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ if (SiCpuPolicyPpiDesc == NULL) {
+ ASSERT (SiCpuPolicyPpiDesc != NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SiCpuPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ SiCpuPolicyPpiDesc->Guid = &gSiCpuPolicyPpiGuid;
+ SiCpuPolicyPpiDesc->Ppi = SiCpuPolicy;
+
+ //
+ // Print whole SI_CPU_POLICY_PPI and serial out in PreMem.
+ //
+ CpuPrintPolicyPpi (SiCpuPolicy);
+
+ //
+ // Install PEI Cpu Policy PPI
+ //
+ Status = PeiServicesInstallPpi (SiCpuPolicyPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibPreMem.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibPreMem.inf
new file mode 100644
index 0000000000..476309966e
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibPreMem.inf
@@ -0,0 +1,45 @@
+## @file
+# PeiCpuPolicyLibPreMem 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 = PeiCpuPolicyLibPreMem
+ FILE_GUID = 5F4C2CF1-9DFE-4D99-9318-98FD31C8517D
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = CpuPolicyLib
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ PeiServicesLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ CpuPlatformLib
+ PostCodeLib
+ ConfigBlockLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Sources]
+ PeiCpuPolicyLib.c
+ PeiCpuPolicyLibrary.h
+ CpuPrintPolicy.c
+
+[Ppis]
+ gSiCpuPolicyPpiGuid ## PRODUCES
+ gCpuConfigPreMemGuid ## CONSUMES
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h
new file mode 100644
index 0000000000..204fac09a7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h
@@ -0,0 +1,45 @@
+/** @file
+ Header file for the PeiCpuPolicyLib 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.
+
+**/
+
+#ifndef _PEI_CPU_POLICY_LIBRARY_H_
+#define _PEI_CPU_POLICY_LIBRARY_H_
+
+#include <PiPei.h>
+#include <CpuAccess.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/CpuPolicy.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/CpuPlatformLib.h>
+
+#define SMM_FROM_SMBASE_DRIVER 0x55
+#define SW_SMI_FROM_SMMBASE SMM_FROM_SMBASE_DRIVER
+
+//
+// TXT configuration defines
+//
+#define TXT_SINIT_MEMORY_SIZE 0x50000
+#define TXT_HEAP_MEMORY_SIZE 0xE0000
+
+#define TXT_LCP_PD_BASE 0x0 ///< Platform default LCP
+#define TXT_LCP_PD_SIZE 0x0 ///< Platform default LCP
+#define TXT_TGA_MEMORY_SIZE 0x0 ///< Maximum 512K of TGA memory (aperture)
+
+#endif // _PEI_CPU_POLICY_LIBRARY_H_
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
new file mode 100644
index 0000000000..db4fea1566
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
@@ -0,0 +1,256 @@
+/** @file
+ CPU Platform Lib implementation.
+
+ 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 "CpuPlatformLibrary.h"
+#include <Library/MmPciLib.h>
+#include <SaRegs.h>
+
+#define SKIP_MICROCODE_CHECKSUM_CHECK 1
+
+/**
+ Return CPU Family ID
+
+ @retval CPU_FAMILY CPU Family ID
+
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+
+ //
+ // Read the CPUID information
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ return ((CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL));
+}
+
+
+/**
+ Return Cpu stepping type
+
+ @retval UINT8 Cpu stepping type
+
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+
+ //
+ // Read the CPUID information
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ return ((CPU_STEPPING) (Cpuid.RegEax & CPUID_FULL_STEPPING));
+}
+
+
+/**
+ Returns the processor microcode revision of the processor installed in the system.
+
+ @retval Processor Microcode Revision
+
+**/
+UINT32
+GetCpuUcodeRevision (
+ VOID
+ )
+{
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+
+ return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+
+/**
+ Verify the DWORD type checksum
+
+ @param[in] ChecksumAddr The start address to be checkumed
+ @param[in] ChecksumLen The length of data to be checksumed
+
+ @retval EFI_SUCCESS Checksum correct
+ @retval EFI_CRC_ERROR Checksum incorrect
+
+**/
+EFI_STATUS
+Checksum32Verify (
+ IN UINT32 *ChecksumAddr,
+ IN UINT32 ChecksumLen
+ )
+{
+#if SKIP_MICROCODE_CHECKSUM_CHECK
+ return EFI_SUCCESS;
+#else
+ UINT32 Checksum;
+ UINT32 Index;
+
+ Checksum = 0;
+
+ for (Index = 0; Index < ChecksumLen; Index++) {
+ Checksum += ChecksumAddr[Index];
+ }
+
+ return (Checksum == 0) ? EFI_SUCCESS : EFI_CRC_ERROR;
+#endif
+}
+
+
+/**
+ This function checks the MCU revision to decide if BIOS needs to load
+ microcode.
+
+ @param[in] MicrocodePointer Microcode in memory
+ @param[in] Revision Current CPU microcode revision
+
+ @retval EFI_SUCCESS BIOS needs to load microcode
+ @retval EFI_ABORTED Don't need to update microcode
+
+**/
+EFI_STATUS
+CheckMcuRevision (
+ IN CPU_MICROCODE_HEADER *MicrocodePointer,
+ IN UINT32 Revision
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_ABORTED;
+ if ((MicrocodePointer->UpdateRevision & 0x80000000) ||
+ (MicrocodePointer->UpdateRevision > Revision) ||
+ (Revision == 0)){
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+/**
+ Check if this microcode is correct one for processor
+
+ @param[in] Cpuid Processor CPUID
+ @param[in] MicrocodeEntryPoint Entry point of microcode
+ @param[in] Revision Revision of microcode
+
+ @retval CorrectMicrocode If this microcode is correct
+
+**/
+BOOLEAN
+CheckMicrocode (
+ IN UINT32 Cpuid,
+ IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+ IN UINT32 *Revision
+ )
+{
+ EFI_STATUS Status;
+ UINT8 ExtendedIndex;
+ UINT8 MsrPlatform;
+ UINT32 ExtendedTableLength;
+ UINT32 ExtendedTableCount;
+ BOOLEAN CorrectMicrocode;
+ CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
+ CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+
+ Status = EFI_NOT_FOUND;
+ ExtendedTableLength = 0;
+ CorrectMicrocode = FALSE;
+
+ if (MicrocodeEntryPoint == NULL) {
+ return FALSE;
+ }
+
+ //
+ // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
+ //
+ MsrPlatform = (UINT8) (RShiftU64 (AsmReadMsr64 (MSR_IA32_PLATFORM_ID), N_PLATFORM_ID_SHIFT) & B_PLATFORM_ID_MASK);
+
+ //
+ // Check if the microcode is for the Cpu and the version is newer
+ // and the update can be processed on the platform
+ //
+ if ((MicrocodeEntryPoint->HeaderVersion == 0x00000001) &&
+ !EFI_ERROR (CheckMcuRevision (MicrocodeEntryPoint, *Revision))) {
+ if ((MicrocodeEntryPoint->ProcessorId == Cpuid) && (MicrocodeEntryPoint->ProcessorFlags & (1 << MsrPlatform))) {
+ if (MicrocodeEntryPoint->DataSize == 0) {
+ Status = Checksum32Verify ((UINT32 *) MicrocodeEntryPoint, 2048 / sizeof (UINT32));
+ } else {
+ Status = Checksum32Verify (
+ (UINT32 *) MicrocodeEntryPoint,
+ (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)) / sizeof (UINT32)
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ CorrectMicrocode = TRUE;
+ }
+ } else if ((MicrocodeEntryPoint->DataSize != 0)) {
+ //
+ // Check the Extended Signature if the entended signature exist
+ // Only the data size != 0 the extended signature may exist
+ //
+ ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
+ if (ExtendedTableLength != 0) {
+ //
+ // Extended Table exist, check if the CPU in support list
+ //
+ ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + 48);
+ //
+ // Calulate Extended Checksum
+ //
+ if ((ExtendedTableLength % 4) == 0) {
+ Status = Checksum32Verify ((UINT32 *) ExtendedTableHeader, ExtendedTableLength / sizeof (UINT32));
+ if (!EFI_ERROR (Status)) {
+ //
+ // Checksum correct
+ //
+ ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
+ ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
+ for (ExtendedIndex = 0; ExtendedIndex < ExtendedTableCount; ExtendedIndex++) {
+ //
+ // Verify Header
+ //
+ if ((ExtendedTable->ProcessorSignature == Cpuid) && (ExtendedTable->ProcessorFlag & (1 << MsrPlatform))) {
+ Status = Checksum32Verify (
+ (UINT32 *) ExtendedTable,
+ sizeof (CPU_MICROCODE_EXTENDED_TABLE) / sizeof (UINT32)
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Find one
+ //
+ CorrectMicrocode = TRUE;
+ break;
+ }
+ }
+
+ ExtendedTable++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return CorrectMicrocode;
+}
+
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
new file mode 100644
index 0000000000..67d69a9aa6
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
@@ -0,0 +1,33 @@
+/** @file
+ Header file for Cpu Platform Lib implementation.
+
+ 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 _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+#include <CpuAccess.h>
+#include <Library/CpuPlatformLib.h>
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
new file mode 100644
index 0000000000..25bb5d9b59
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
@@ -0,0 +1,44 @@
+## @file
+# CPU Platform Lib.
+#
+# 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 = PeiDxeSmmCpuPlatformLib
+ FILE_GUID = 11647130-6AA4-41A4-A3A8-5FA296ABD977
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = CpuPlatformLib
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ PcdLib
+ PciLib
+ CpuLib
+ TimerLib
+ SynchronizationLib
+ MmPciLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+
+[Sources]
+ CpuPlatformLibrary.h
+ CpuPlatformLibrary.c
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h
new file mode 100644
index 0000000000..3ab1813b75
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h
@@ -0,0 +1,229 @@
+/** @file
+ Definitions for S3 Resume.
+
+ 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 _CPU_S3_
+#define _CPU_S3_
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/TimerLib.h>
+#include <Library/HobLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Private/Library/CpuCommonLib.h>
+#include <Ppi/SmmAccess.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/CpuPolicy.h>
+#include "CpuAccess.h"
+
+#define VacantFlag 0x00
+#define NotVacantFlag 0xff
+
+#define MICROSECOND 10
+
+#define MAXIMUM_CPU_NUMBER 0x40
+#define STACK_SIZE_PER_PROC 0x8000
+
+#define MAXIMUM_CPU_S3_TABLE_SIZE 0x1000
+
+#define IO_APIC_INDEX_REGISTER 0xFEC00000
+#define IO_APIC_DATA_REGISTER 0xFEC00010
+
+extern UINTN FixedMtrrNumber;
+extern UINTN MtrrDefTypeNumber;
+
+typedef struct {
+ UINT16 Index;
+ UINT64 Value;
+} EFI_MTRR_VALUES;
+
+typedef struct {
+ UINT32 ApicId;
+ UINT32 MsrIndex;
+ UINT64 MsrValue;
+} MP_CPU_S3_SCRIPT_DATA;
+
+typedef struct {
+ UINT32 S3BootScriptTable;
+ UINT32 S3BspMtrrTable;
+ UINT32 VirtualWireMode;
+} MP_CPU_S3_DATA_POINTER;
+
+typedef struct {
+ UINT32 Lock;
+ UINT32 StackStart;
+ UINT32 StackSize;
+ UINT32 ApFunction;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINT32 BufferStart;
+ UINT32 PmodeOffset;
+ UINT32 AcpiCpuDataAddress;
+ UINT32 MtrrValuesAddress;
+ UINT32 FinishedCount;
+ UINT32 WakeupCount;
+ UINT32 SerializeLock;
+ MP_CPU_S3_SCRIPT_DATA *S3BootScriptTable;
+ UINT32 StartState;
+ UINT32 VirtualWireMode;
+ VOID (*SemaphoreCheck)(UINT32 *SemaphoreAddress);
+ UINT32 McuLoadCount;
+ IN CONST EFI_PEI_SERVICES **PeiServices;
+ UINT64 CpuPerfCtrlValue;
+ SI_CPU_POLICY_PPI *SiCpuPolicyPpi;
+} MP_CPU_EXCHANGE_INFO;
+
+/**
+ Get protected mode code offset
+
+ @retval Offset of protected mode code
+
+**/
+VOID *
+S3AsmGetPmodeOffset (
+ VOID
+ );
+
+/**
+ Get code offset of SemaphoreCheck
+
+ @retval Offset of SemaphoreCheck
+
+**/
+UINT32
+S3AsmGetSemaphoreCheckOffset (
+ VOID
+ );
+
+/**
+ Read MTRR settings
+
+ @param[in] MtrrValues Buffer to store MTRR settings
+
+**/
+VOID
+ReadMtrrRegisters (
+ UINT64 *MtrrValues
+ );
+
+/**
+ Syncup MTRR settings between all processors
+
+ @param[in] MtrrValues Buffer to store MTRR settings
+
+**/
+VOID
+MpMtrrSynchUp (
+ UINT64 *MtrrValues
+ );
+
+/**
+ Set MTRR registers
+
+ @param[in] MtrrArray Buffer with MTRR settings
+
+**/
+VOID
+SetMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ );
+
+#ifdef EFI_DEBUG
+/**
+ Print MTRR settings in debug build BIOS
+
+ @param[in] MtrrArray Buffer with MTRR settings
+
+**/
+VOID
+ShowMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ );
+#endif
+
+/**
+ This will check if the microcode address is valid for this processor, and if so, it will
+ load it to the processor.
+
+ @param[in] ExchangeInfo Pointer to the exchange info buffer for output.
+ @param[in] MicrocodeAddress The address of the microcode update binary (in memory).
+ @param[out] FailedRevision The microcode revision that fails to be loaded.
+
+ @retval EFI_SUCCESS A new microcode update is loaded.
+ @retval Other Due to some reason, no new microcode update is loaded.
+
+**/
+EFI_STATUS
+InitializeMicrocode (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN CPU_MICROCODE_HEADER *MicrocodeAddress,
+ OUT UINT32 *FailedRevision
+ );
+
+///
+/// Functions shared in MP/HT drivers
+///
+/**
+ Send interrupt to CPU
+
+ @param[in] BroadcastMode Interrupt broadcast mode
+ @param[in] ApicID APIC ID for sending interrupt
+ @param[in] VectorNumber Vector number
+ @param[in] DeliveryMode Interrupt delivery mode
+ @param[in] TriggerMode Interrupt trigger mode
+ @param[in] Assert Interrupt pin polarity
+
+ @retval EFI_INVALID_PARAMETER Input parameter not correct
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+SendInterrupt (
+ IN UINT32 BroadcastMode,
+ IN UINT32 ApicID,
+ IN UINT32 VectorNumber,
+ IN UINT32 DeliveryMode,
+ IN UINT32 TriggerMode,
+ IN BOOLEAN Assert
+ );
+
+/**
+ Programs Local APIC registers for virtual wire mode.
+
+ @param[in] BSP Is this BSP?
+
+**/
+VOID
+ProgramXApic (
+ BOOLEAN BSP
+ );
+
+/**
+ Get address map of S3RendezvousFunnelProc.
+
+ @retval AddressMap Output buffer for address map information
+
+**/
+VOID *
+S3AsmGetAddressMap (
+ VOID
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c
new file mode 100644
index 0000000000..8c4c8f34ee
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c
@@ -0,0 +1,753 @@
+/** @file
+ Cpu S3 library running on S3 resume paths.
+
+ 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 <Private/Library/CpuS3Lib.h>
+#include "CpuS3.h"
+#include <Library/CpuPolicyLib.h>
+#include <Library/PostCodeLib.h>
+
+extern EFI_GUID gSmramCpuDataHeaderGuid;
+extern EFI_GUID gPeiAcpiCpuDataGuid;
+
+typedef VOID (*S3_AP_PROCEDURE) (
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ UINT64 *MtrrValues
+ );
+
+/**
+ This function handles CPU S3 resume task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+STATIC
+EFI_STATUS
+CpuS3ResumeAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+
+STATIC EFI_PEI_NOTIFY_DESCRIPTOR mCpuS3ResumeNotifyDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ CpuS3ResumeAtEndOfPei
+};
+
+
+/**
+ Restore all MSR settings
+
+ @param[in] ScriptTable Contain the MSR settings that will be restored.
+
+**/
+VOID
+InitializeFeatures (
+ IN MP_CPU_S3_SCRIPT_DATA *ScriptTable
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegisters;
+ UINT32 ApicId;
+ UINT8 SkipMsr;
+
+ //
+ // Restore all the MSRs for processor
+ //
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ ApicId = (CpuidRegisters.RegEbx >> 24);
+
+ while (ScriptTable->MsrIndex != 0) {
+ if (ApicId == ScriptTable->ApicId) {
+ SkipMsr = 0;
+ if ((ScriptTable->MsrIndex == MSR_PMG_CST_CONFIG) && (AsmReadMsr64 (MSR_PMG_CST_CONFIG) & B_CST_CONTROL_LOCK)) {
+ SkipMsr = 1;
+ }
+ if ((ScriptTable->MsrIndex == MSR_IA32_FEATURE_CONTROL) && (AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL) & B_MSR_IA32_FEATURE_CONTROL_LOCK)) {
+ SkipMsr = 1;
+ }
+ if (SkipMsr == 0) {
+ AsmWriteMsr64 (ScriptTable->MsrIndex, ScriptTable->MsrValue);
+ }
+ }
+ ScriptTable++;
+ }
+}
+
+
+/**
+ Restore all MSR settings with debug message output
+
+ @param[in] ScriptTable Script table contain all MSR settings that will be restored
+
+**/
+VOID
+InitializeFeaturesLog (
+ IN MP_CPU_S3_SCRIPT_DATA *ScriptTable
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegisters;
+ UINT32 ApicId;
+ BOOLEAN SkipMsr;
+
+ PostCode (0xC41);
+
+ //
+ // Restore all the MSRs for processor
+ //
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ ApicId = (CpuidRegisters.RegEbx >> 24);
+
+ while (ScriptTable->MsrIndex != 0) {
+ if (ApicId == ScriptTable->ApicId) {
+ DEBUG ((DEBUG_INFO, "MSR Index - %x, MSR value - %x\n", ScriptTable->MsrIndex, ScriptTable->MsrValue));
+ SkipMsr = FALSE;
+ if ((ScriptTable->MsrIndex == MSR_PMG_CST_CONFIG) && (AsmReadMsr64 (MSR_PMG_CST_CONFIG) & B_CST_CONTROL_LOCK)) {
+ SkipMsr = TRUE;
+ }
+ if ((ScriptTable->MsrIndex == MSR_IA32_FEATURE_CONTROL) && (AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL) & B_MSR_IA32_FEATURE_CONTROL_LOCK)) {
+ SkipMsr = TRUE;
+ }
+ if (ScriptTable->MsrIndex == MSR_IA32_DEBUG_INTERFACE) {
+ //
+ // Debug interface is supported if CPUID (EAX=1): ECX[11] = 1
+ //
+ if ((CpuidRegisters.RegEcx & BIT11) && (AsmReadMsr64 (MSR_IA32_DEBUG_INTERFACE) & B_DEBUG_INTERFACE_LOCK)) {
+ SkipMsr = TRUE;
+ }
+ }
+ if (!SkipMsr) {
+ AsmWriteMsr64 (ScriptTable->MsrIndex, ScriptTable->MsrValue);
+ }
+ }
+ ScriptTable++;
+ }
+ PostCode (0xC44);
+}
+
+
+/**
+ AP initialization
+
+ @param[in] ExchangeInfo Pointer to the exchange info buffer for output.
+ @param[in] MtrrValues Buffer contains MTRR settings
+
+**/
+VOID
+MPRendezvousProcedure (
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ UINT64 *MtrrValues
+ )
+{
+ EFI_STATUS Status;
+ UINT32 FailedRevision;
+ ACPI_CPU_DATA *AcpiCpuData;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+ EFI_CPUID_REGISTER CpuidRegisters;
+ CPU_CONFIG *CpuConfig;
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) ExchangeInfo->SiCpuPolicyPpi, &gCpuConfigGuid , (VOID *) &CpuConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+
+ //
+ // Init XMM support on all APs
+ //
+ XmmInit ();
+
+ //
+ // Switch AP speed to BSP speed
+ //
+ if ((CpuidRegisters.RegEcx & B_CPUID_VERSION_INFO_ECX_EIST) != 0) {
+ AsmWriteMsr64 (MSR_IA32_PERF_CTRL, ExchangeInfo->CpuPerfCtrlValue);
+ }
+
+ AcpiCpuData = (ACPI_CPU_DATA *) (ExchangeInfo->AcpiCpuDataAddress);
+
+ ProgramXApic (FALSE);
+
+ InitializeFeatures (ExchangeInfo->S3BootScriptTable);
+
+ InterlockedIncrement (&(ExchangeInfo->SerializeLock));
+ while (ExchangeInfo->SerializeLock < AcpiCpuData->NumberOfCpus) {
+ CpuPause ();
+ }
+
+ InitializeMicrocode (
+ ExchangeInfo,
+ (CPU_MICROCODE_HEADER *) (UINTN) CpuConfig->MicrocodePatchAddress,
+ &FailedRevision
+ );
+
+ ProcessorsPrefetcherInitialization (
+ CpuConfig->MlcStreamerPrefetcher,
+ CpuConfig->MlcSpatialPrefetcher
+ );
+
+ //
+ // wait till all CPUs done the Microcode Load
+ //
+ while (ExchangeInfo->McuLoadCount < AcpiCpuData->NumberOfCpus) {
+ CpuPause ();
+ }
+
+ MpMtrrSynchUp (MtrrValues);
+
+ InterlockedIncrement (&(ExchangeInfo->FinishedCount));
+
+ //
+ // Sempahore check loop executed in memory
+ //
+ (*ExchangeInfo->SemaphoreCheck) (&ExchangeInfo->FinishedCount);
+
+ InterlockedIncrement (&(ExchangeInfo->WakeupCount));
+
+ //
+ // Restore the MTRR programmed before OS boot
+ //
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+ SetMtrrRegisters ((EFI_MTRR_VALUES *) CpuS3DataPtr->S3BspMtrrTable);
+
+ while (ExchangeInfo->WakeupCount < AcpiCpuData->NumberOfCpus - 1) {
+ CpuPause ();
+ }
+
+ InterlockedIncrement (&(ExchangeInfo->FinishedCount));
+}
+
+
+/**
+ Wake up all the application processors
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table
+ @param[in] AcpiCpuData Pointer to ACPI_CPU_DATA structure
+ @param[in] MtrrValues Pointer to a buffer which stored MTRR settings
+
+ @retval EFI_SUCCESS APs are successfully waked up
+
+**/
+EFI_STATUS
+S3WakeUpAps (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ ACPI_CPU_DATA *AcpiCpuData,
+ UINT64 *MtrrValues,
+ S3_AP_PROCEDURE Function
+ )
+{
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+
+ PostCode (0xC45);
+ WakeUpBuffer = AcpiCpuData->WakeUpBuffer;
+ CopyMem ((VOID *) (UINTN) WakeUpBuffer, S3AsmGetAddressMap (), 0x1000 - 0x200);
+
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + (0x1000 - 0x200));
+
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->StackStart = (UINTN) AcpiCpuData->StackAddress;
+ ExchangeInfo->StackSize = STACK_SIZE_PER_PROC;
+ ExchangeInfo->ApFunction = (UINT32) Function;
+ ExchangeInfo->BufferStart = (UINT32) WakeUpBuffer;
+ ExchangeInfo->PmodeOffset = (UINT32) (S3AsmGetPmodeOffset ());
+ ExchangeInfo->SemaphoreCheck = (VOID (*)(UINT32 *)) (S3AsmGetSemaphoreCheckOffset () + (UINT32) WakeUpBuffer);
+ ExchangeInfo->AcpiCpuDataAddress = (UINT32) AcpiCpuData;
+ ExchangeInfo->MtrrValuesAddress = (UINT32) MtrrValues;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+ ExchangeInfo->SerializeLock = (UINT32) 0;
+ ExchangeInfo->StartState = (UINT32) 0;
+
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+ ExchangeInfo->S3BootScriptTable = (MP_CPU_S3_SCRIPT_DATA *) (UINTN) CpuS3DataPtr->S3BootScriptTable;
+ ExchangeInfo->VirtualWireMode = CpuS3DataPtr->VirtualWireMode;
+ ExchangeInfo->PeiServices = PeiServices;
+ ExchangeInfo->CpuPerfCtrlValue = AsmReadMsr64 (MSR_IA32_PERF_CTRL);
+
+ ExchangeInfo->SiCpuPolicyPpi = NULL;
+ PeiServicesLocatePpi (
+ &gSiCpuPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &(ExchangeInfo->SiCpuPolicyPpi)
+ );
+
+ CopyMem (
+ (VOID *) (UINTN) &ExchangeInfo->GdtrProfile,
+ (VOID *) (UINTN) AcpiCpuData->GdtrProfile,
+ sizeof (IA32_DESCRIPTOR)
+ );
+ CopyMem (
+ (VOID *) (UINTN) &ExchangeInfo->IdtrProfile,
+ (VOID *) (UINTN) AcpiCpuData->IdtrProfile,
+ sizeof (IA32_DESCRIPTOR)
+ );
+
+ DEBUG ((DEBUG_INFO, "Cpu S3 Bootscript at %08X\n", (UINT32) ExchangeInfo->S3BootScriptTable));
+
+ //
+ // Don't touch MPCPU private data
+ // Here we use ExchangeInfo instead
+ //
+ //
+ // Send INIT IPI - SIPI to all APs
+ //
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ 0,
+ DELIVERY_MODE_INIT,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (10 * STALL_ONE_MILLI_SECOND); //< 10ms
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (200 * STALL_ONE_MICRO_SECOND); //< 200us
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (200 * STALL_ONE_MICRO_SECOND); //< 200us
+ PostCode (0xC48);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This routine is used to search SMRAM and get SmramCpuData point.
+
+ @param[in] PeiServices PEI services global pointer
+ @param[in] SmmAccessPpi SmmAccess PPI instance
+
+ @retval SmramCpuData The pointer of CPU information in SMRAM.
+
+**/
+STATIC
+SMRAM_CPU_DATA *
+GetSmmCpuData (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *SmmAccessPpi
+ )
+{
+ EFI_SMRAM_DESCRIPTOR *SmramRanges;
+ UINTN SmramRangeCount;
+ UINTN Size;
+ EFI_STATUS Status;
+ UINT32 Address;
+ SMRAM_CPU_DATA *SmramCpuData;
+
+ //
+ // Get all SMRAM range
+ //
+ Size = 0;
+ Status = SmmAccessPpi->GetCapabilities ((EFI_PEI_SERVICES **) PeiServices, SmmAccessPpi, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Status = PeiServicesAllocatePool (
+ Size,
+ (VOID **) &SmramRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SmmAccessPpi->GetCapabilities ((EFI_PEI_SERVICES **) PeiServices, SmmAccessPpi, &Size, SmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ Size /= sizeof (*SmramRanges);
+ SmramRangeCount = Size;
+
+ //
+ // We assume TSEG is the last range of SMRAM in SmramRanges
+ //
+ SmramRanges += SmramRangeCount - 1;
+
+ DEBUG ((DEBUG_INFO, "TsegBase - %x\n", SmramRanges->CpuStart));
+ DEBUG ((DEBUG_INFO, "TsegTop - %x\n", SmramRanges->CpuStart + SmramRanges->PhysicalSize));
+
+ //
+ // Search SMRAM on page alignment for the SMMNVS signature
+ //
+ for (Address = (UINT32) (SmramRanges->CpuStart + SmramRanges->PhysicalSize - EFI_PAGE_SIZE);
+ Address >= (UINT32) SmramRanges->CpuStart;
+ Address -= EFI_PAGE_SIZE
+ ) {
+ SmramCpuData = (SMRAM_CPU_DATA *) (UINTN) Address;
+ if (CompareGuid (&SmramCpuData->HeaderGuid, &gSmramCpuDataHeaderGuid)) {
+ return SmramCpuData;
+ }
+ }
+
+ ASSERT (FALSE);
+
+ return NULL;
+}
+
+/**
+ This routine is restore the CPU information from SMRAM to original reserved memory region.
+
+ @param[in] PeiServices PEI services global pointer
+
+ @retval AcpiCpuData The pointer of CPU information in reserved memory.
+
+**/
+ACPI_CPU_DATA *
+RestoreSmramCpuData (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ PEI_SMM_ACCESS_PPI *SmmAccessPpi;
+ SMRAM_CPU_DATA *SmramCpuData;
+ EFI_STATUS Status;
+ ACPI_CPU_DATA *AcpiCpuData;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+ IA32_DESCRIPTOR *Idtr;
+ IA32_DESCRIPTOR *Gdtr;
+ UINTN Index;
+
+ Status = PeiServicesLocatePpi (
+ &gPeiSmmAccessPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SmmAccessPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Open all SMM regions
+ //
+ Index = 0;
+ do {
+ Status = SmmAccessPpi->Open ((EFI_PEI_SERVICES **) PeiServices, SmmAccessPpi, Index);
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+ SmramCpuData = GetSmmCpuData ((CONST EFI_PEI_SERVICES **) PeiServices, SmmAccessPpi);
+ if (SmramCpuData == NULL) {
+ ASSERT (FALSE);
+ return NULL;
+ }
+ DEBUG ((DEBUG_INFO, "CpuS3 SmramCpuData - 0x%x \n", SmramCpuData));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->GdtrProfileSize - %x\n", SmramCpuData->GdtrProfileSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->GdtSize - %x\n", SmramCpuData->GdtSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->IdtrProfileSize - %x\n", SmramCpuData->IdtrProfileSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->IdtSize - %x\n", SmramCpuData->IdtSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->CpuPrivateDataSize - %x\n", SmramCpuData->CpuPrivateDataSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->S3BootScriptTableSize - %x\n", SmramCpuData->S3BootScriptTableSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->S3BspMtrrTableSize - %x\n", SmramCpuData->S3BspMtrrTableSize));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->GdtrProfileOffset - %x\n", SmramCpuData->GdtrProfileOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->GdtOffset - %x\n", SmramCpuData->GdtOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->IdtrProfileOffset - %x\n", SmramCpuData->IdtrProfileOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->IdtOffset - %x\n", SmramCpuData->IdtOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->CpuPrivateDataOffset - %x\n", SmramCpuData->CpuPrivateDataOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->S3BootScriptTableOffset - %x\n", SmramCpuData->S3BootScriptTableOffset));
+ DEBUG ((DEBUG_INFO, "SmramCpuData->S3BspMtrrTableOffset - %x\n", SmramCpuData->S3BspMtrrTableOffset));
+
+ //
+ // Start restore data to NVS
+ //
+ AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) SmramCpuData->AcpiCpuPointer;
+ CopyMem (AcpiCpuData, &SmramCpuData->AcpiCpuData, sizeof (ACPI_CPU_DATA));
+
+ CopyMem (
+ (VOID *) (UINTN) AcpiCpuData->GdtrProfile,
+ (UINT8 *) SmramCpuData + SmramCpuData->GdtrProfileOffset,
+ SmramCpuData->GdtrProfileSize
+ );
+ Gdtr = (IA32_DESCRIPTOR *) (UINTN) AcpiCpuData->GdtrProfile;
+ CopyMem (
+ (VOID *) (UINTN) Gdtr->Base,
+ (UINT8 *) SmramCpuData + SmramCpuData->GdtOffset,
+ SmramCpuData->GdtSize
+ );
+ CopyMem (
+ (VOID *) (UINTN) AcpiCpuData->IdtrProfile,
+ (UINT8 *) SmramCpuData + SmramCpuData->IdtrProfileOffset,
+ SmramCpuData->IdtrProfileSize
+ );
+ Idtr = (IA32_DESCRIPTOR *) (UINTN) AcpiCpuData->IdtrProfile;
+ CopyMem (
+ (VOID *) (UINTN) Idtr->Base,
+ (UINT8 *) SmramCpuData + SmramCpuData->IdtOffset,
+ SmramCpuData->IdtSize
+ );
+ CopyMem (
+ (VOID *) (UINTN) AcpiCpuData->CpuPrivateData,
+ (UINT8 *) SmramCpuData + SmramCpuData->CpuPrivateDataOffset,
+ SmramCpuData->CpuPrivateDataSize
+ );
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+ CopyMem (
+ (VOID *) (UINTN) CpuS3DataPtr->S3BootScriptTable,
+ (UINT8 *) SmramCpuData + SmramCpuData->S3BootScriptTableOffset,
+ SmramCpuData->S3BootScriptTableSize
+ );
+ CopyMem (
+ (VOID *) (UINTN) CpuS3DataPtr->S3BspMtrrTable,
+ (UINT8 *) SmramCpuData + SmramCpuData->S3BspMtrrTableOffset,
+ SmramCpuData->S3BspMtrrTableSize
+ );
+ //
+ // Close all SMM regions
+ //
+ Index = 0;
+ do {
+ Status = SmmAccessPpi->Close ((EFI_PEI_SERVICES **) PeiServices, SmmAccessPpi, Index);
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+ return AcpiCpuData;
+}
+
+
+/**
+ Cpu initialization called during S3 resume to take care
+ of CPU related activities in PEI phase
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table
+
+ @retval EFI_SUCCESS Multiple processors are intialized successfully.
+
+**/
+EFI_STATUS
+S3InitializeCpu (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ ACPI_CPU_DATA *AcpiCpuData;
+ UINT64 *MtrrValues;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+ UINTN VariableMtrrNumber;
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINT32 FailedRevision;
+ VOID *Hob;
+ EFI_BOOT_MODE BootMode;
+ CPU_CONFIG *CpuConfig;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ DEBUG ((DEBUG_INFO, "CPU: BootMode = %X\n", BootMode));
+ if ((Status == EFI_SUCCESS) && (BootMode != BOOT_ON_S3_RESUME)) {
+ DEBUG ((DEBUG_INFO,"CPU: Normal Boot\n"));
+ return EFI_SUCCESS;
+ }
+
+ DEBUG((DEBUG_INFO, "S3InitializeCpu Start \n"));
+ PostCode (0xC40);
+
+ //
+ // Restore ACPI Nvs data from SMRAM
+ //
+ AcpiCpuData = RestoreSmramCpuData ((CONST EFI_PEI_SERVICES **) PeiServices);
+ if (AcpiCpuData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DEBUG ((DEBUG_INFO, "CpuS3 RestoreSmramCpuData - 0x%x \n", AcpiCpuData));
+
+ AcpiCpuData->S3BootPath = TRUE;
+
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+
+ VariableMtrrNumber = (UINTN) ((UINT64) AsmReadMsr64 (IA32_MTRR_CAP) & B_IA32_MTRR_VARIABLE_SUPPORT) * 2;
+ Status = PeiServicesAllocatePool (
+ (FixedMtrrNumber + MtrrDefTypeNumber + VariableMtrrNumber) * sizeof (UINT64),
+ (VOID **) &MtrrValues
+ );
+ ASSERT_EFI_ERROR (Status);
+ ReadMtrrRegisters (MtrrValues);
+
+ WakeUpBuffer = AcpiCpuData->WakeUpBuffer;
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + (0x1000 - 0x200));
+ ExchangeInfo->WakeupCount = (UINT32) 0;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+ ExchangeInfo->SerializeLock = (UINT32) 0;
+
+ //
+ // Restore features for BSP
+ //
+ InitializeFeaturesLog ((MP_CPU_S3_SCRIPT_DATA *) CpuS3DataPtr->S3BootScriptTable);
+
+ //
+ // Restore AP configuration
+ //
+ S3WakeUpAps ((CONST EFI_PEI_SERVICES **)PeiServices, AcpiCpuData, MtrrValues, MPRendezvousProcedure);
+
+ //
+ // Program XApic register
+ //
+ ProgramXApic (
+ TRUE
+ );
+
+ InterlockedIncrement (&(ExchangeInfo->SerializeLock));
+ while (ExchangeInfo->SerializeLock < AcpiCpuData->NumberOfCpus) {
+ CpuPause ();
+ }
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) ExchangeInfo->SiCpuPolicyPpi, &gCpuConfigGuid , (VOID *) &CpuConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "Initialize Microcode Start \n"));
+ PostCode (0xC49);
+ InitializeMicrocode (
+ ExchangeInfo,
+ (CPU_MICROCODE_HEADER *) (UINTN) CpuConfig->MicrocodePatchAddress,
+ &FailedRevision
+ );
+
+ DEBUG ((DEBUG_INFO, "BuildGuid Data Hob Start \n"));
+ PostCode (0xC4D);
+ //
+ // Save acpi cpu data into one hob, it will be used by a callback when End of Pei Signal installed.
+ //
+ Hob = BuildGuidDataHob (
+ &gPeiAcpiCpuDataGuid,
+ (VOID *) (UINTN) AcpiCpuData,
+ (UINTN) sizeof (ACPI_CPU_DATA)
+ );
+ ASSERT (Hob != NULL);
+ DEBUG ((DEBUG_INFO, "CPU S3: Register notification to be trigerred at End of Pei event\n"));
+ Status = PeiServicesNotifyPpi (&mCpuS3ResumeNotifyDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Wait for all APs to complete
+ //
+ while (ExchangeInfo->FinishedCount < AcpiCpuData->NumberOfCpus - 1) {
+ CpuPause ();
+ }
+
+ DEBUG ((DEBUG_INFO, "S3InitializeCpu Done \n"));
+ PostCode (0xC5F);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function handles CPU S3 resume task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+STATIC
+EFI_STATUS
+CpuS3ResumeAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ ACPI_CPU_DATA *AcpiCpuData;
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ VOID *Hob;
+
+ DEBUG ((DEBUG_INFO, "Cpu S3 callback Entry\n"));
+
+ PostCode (0xC51);
+
+ //
+ // Find the saved acpi cpu data from HOB.
+ //
+ AcpiCpuData = NULL;
+ Hob = GetFirstGuidHob (&gPeiAcpiCpuDataGuid);
+ if (Hob != NULL) {
+ AcpiCpuData = (ACPI_CPU_DATA *) ((UINTN) Hob + sizeof (EFI_HOB_GUID_TYPE));
+ ASSERT (AcpiCpuData != NULL);
+ if (AcpiCpuData == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ WakeUpBuffer = AcpiCpuData->WakeUpBuffer;
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + (0x1000 - 0x200));
+
+ //
+ // Have APs to continue the task - Restore S3BspMtrrTable
+ //
+ ExchangeInfo->WakeupCount = (UINT32) 0;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+
+ //
+ // Set MTRR to the final values
+ // Do not do it too early so as to avoid performance penalty
+ //
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+
+#ifdef EFI_DEBUG
+ ShowMtrrRegisters ((EFI_MTRR_VALUES *) CpuS3DataPtr->S3BspMtrrTable);
+#endif
+
+ SetMtrrRegisters ((EFI_MTRR_VALUES *) CpuS3DataPtr->S3BspMtrrTable);
+
+ MicroSecondDelay (1 * STALL_ONE_MILLI_SECOND); //< 1ms
+
+ while (ExchangeInfo->FinishedCount < AcpiCpuData->NumberOfCpus - 1) {
+ CpuPause ();
+ }
+ PostCode (0xC54);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h
new file mode 100644
index 0000000000..d8ec879d1e
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h
@@ -0,0 +1,45 @@
+/** @file
+ This is the equates file for HT (Hyper-threading) support.
+
+ 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.
+
+**/
+
+#define VacantFlag 0x00
+#define NotVacantFlag 0xff
+
+#define LockLocation (0x1000 - 0x0200)
+#define StackStartAddressLocation (LockLocation + 0x04)
+#define StackSizeLocation (LockLocation + 0x08)
+#define CProcedureLocation (LockLocation + 0x0C)
+#define GdtrLocation (LockLocation + 0x10)
+#define IdtrLocation (LockLocation + 0x16)
+#define BufferStartLocation (LockLocation + 0x1C)
+#define PmodeOffsetLocation (LockLocation + 0x20)
+#define AcpiCpuDataAddressLocation (LockLocation + 0x24)
+#define MtrrValuesAddressLocation (LockLocation + 0x28)
+#define FinishedCountAddressLocation (LockLocation + 0x2C)
+#define WakeupCountAddressLocation (LockLocation + 0x30)
+#define SerializeLockAddressLocation (LockLocation + 0x34)
+#define MicrocodeAddressLocation (LockLocation + 0x38)
+#define BootScriptAddressLocation (LockLocation + 0x3C)
+#define StartStateLocation (LockLocation + 0x40)
+#define VirtualWireMode (LockLocation + 0x44)
+#define SemaphoreCheck (LockLocation + 0x48)
+#define PeiServices (LockLocation + 0x4C)
+#define PeiStall (LockLocation + 0x50)
+#define CpuPerfCtrlValue (LockLocation + 0x54)
+#define SiCpuPolicyPpi (LockLocation + 0x5C)
+#define MpSystemDataAddressLocation (LockLocation + 0x64)
+#define MpServicePpiAddressLocation (LockLocation + 0x68)
+#define CArgumentLocation (LockLocation + 0x6C)
+#define BistBufferLocation (LockLocation + 0x70)
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc
new file mode 100644
index 0000000000..8fa3dc30a9
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc
@@ -0,0 +1,49 @@
+;; @file
+; This is the equates file used in MpFuncs.asm, for MP support.
+;
+; 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
+;
+;;
+
+VacantFlag Equ 00h
+NotVacantFlag Equ 0ffh
+
+LockLocation equ 1000h - 0200h
+StackStartAddressLocation equ LockLocation + 04h
+StackSizeLocation equ LockLocation + 08h
+CProcedureLocation equ LockLocation + 0Ch
+GdtrLocation equ LockLocation + 10h
+IdtrLocation equ LockLocation + 16h
+BufferStartLocation equ LockLocation + 1Ch
+PmodeOffsetLocation equ LockLocation + 20h
+AcpiCpuDataAddressLocation equ LockLocation + 24h
+MtrrValuesAddressLocation equ LockLocation + 28h
+FinishedCountAddressLocation equ LockLocation + 2Ch
+WakeupCountAddressLocation equ LockLocation + 30h
+SerializeLockAddressLocation equ LockLocation + 34h
+MicrocodeAddressLocation equ LockLocation + 38h
+BootScriptAddressLocation equ LockLocation + 3Ch
+StartStateLocation equ LockLocation + 40h
+VirtualWireMode equ LockLocation + 44h
+SemaphoreCheck equ LockLocation + 48h
+PeiServices equ LockLocation + 4Ch
+PeiStall equ LockLocation + 50h
+CpuPerfCtrlValue equ LockLocation + 54h
+SiCpuPolicyPpi equ LockLocation + 5Ch
+MpSystemDataAddressLocation equ LockLocation + 64h
+MpServicePpiAddressLocation equ LockLocation + 68h
+CArgumentLocation equ LockLocation + 6Ch
+BistBufferLocation equ LockLocation + 70h
+
+PAUSE32 MACRO
+ DB 0F3h
+ DB 090h
+ ENDM
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S
new file mode 100644
index 0000000000..8127ec30f8
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S
@@ -0,0 +1,210 @@
+## @file
+# This is the assembly code for MP support.
+#
+# 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 "MpEqu.h"
+
+ .text
+ ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+
+//-------------------------------------------------------------------------------------
+//S3RendezvousFunnelProc procedure follows. All APs execute their procedure. This
+//procedure serializes all the AP processors through an Init sequence. It must be
+//noted that APs arrive here very raw...ie: real mode, no stack.
+//ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
+//IS IN MACHINE CODE.
+//-------------------------------------------------------------------------------------
+//S3RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
+
+.globl ASM_PFX(S3RendezvousFunnelProc)
+ASM_PFX(S3RendezvousFunnelProc):
+L_S3RendezvousFunnelProcStart:
+
+ .code16
+
+// At this point CS = 0x(vv00) and ip= 0x0.
+ mov %eax, %ebp
+ mov %cs, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %ss
+ xor %ax, %ax
+ mov %ax, %fs
+ mov %ax, %gs
+
+// Get APIC ID
+ mov $1, %eax
+ cpuid
+ shr $24, %ebx
+ and $0xff, %ebx // EBX is APIC ID
+
+// If it is the first time AP wakes up, just record AP's BIST
+// Otherwise, switch to protected mode.
+
+ mov $StartStateLocation, %si
+ cmpl $0, (%si)
+ jnz L_SkipRecordBist
+
+// Record BIST information
+//
+ mov $8, %al
+ mul %bl
+ mov $BistBufferLocation, %si
+ add %ax, %si
+
+ movl $1, (%si) // Set Valid Flag
+ mov %ebp, 4(%si) // Store BIST value
+
+L_SkipRecordBist:
+// Switch to flat mode.
+
+ mov $BufferStartLocation, %si
+ mov (%si), %ebx
+
+ mov $PmodeOffsetLocation, %di
+ mov (%di), %eax
+ mov %ax, %di
+ sub $6, %di
+ add %ebx, %eax
+ mov %eax, (%di)
+
+ mov $0, %esi
+ mov $GdtrLocation, %si
+ lgdtl %cs:(%esi)
+
+ xor %ax, %ax
+ mov %ax, %ds
+
+ mov %cr0, %eax
+ or $0x00000003, %eax
+ mov %eax, %cr0
+
+ .byte 0x66, 0x67, 0xea // far jump
+ .long 0x00 // 32-bit offset
+ .short 0x20 // 16-bit selector
+
+ .code32
+L_NemInit: // protected mode entry point
+ mov $0x18, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+
+ mov %ebx, %esi
+
+ mov %esi, %edi
+ add $StartStateLocation, %edi
+ mov $1, %eax
+ movl %eax, (%edi)
+
+ mov %esi, %edi
+ add $LockLocation, %edi
+ mov $NotVacantFlag, %eax
+L_TestLock:
+ xchg %eax, (%edi)
+ cmp $NotVacantFlag, %eax
+ jz L_TestLock
+
+L_ProgramStack:
+
+ mov %esi, %edi
+ add $StackSizeLocation, %edi
+ mov (%edi), %eax
+ mov %esi, %edi
+ add $StackStartAddressLocation, %edi
+ add (%edi), %eax
+ mov %eax, %esp
+ movl %eax, (%edi)
+
+L_Releaselock:
+
+ mov $VacantFlag, %eax
+ mov %esi, %edi
+ add $LockLocation, %edi
+ xchg %eax, (%edi)
+
+L_CProcedureInvoke:
+
+ mov %esi, %edi
+ add $CArgumentLocation, %edi
+ mov (%edi), %eax
+ push %eax
+
+ mov %esi, %edi
+ add $CProcedureLocation, %edi
+ mov (%edi), %eax
+
+ call *%eax
+ add $4, %esp
+
+L_InterlockedIncrementFinishedCount:
+ mov %esi, %edi
+ add $FinishedCountAddressLocation, %edi
+ lock incl (%edi)
+
+1:
+ cli
+
+ hlt
+ jmp 1b
+
+
+//-------------------------------------------------------------------------------------
+// S3SemaphoreStartAddress
+//-------------------------------------------------------------------------------------
+
+L_S3SemaphoreStartAddress:
+ push %ebp
+ mov %esp, %ebp
+ mov 0x8(%ebp), %eax
+1:
+ cmpl $0, (%eax)
+ jz 1f
+
+ pause
+ jmp 1b
+
+1:
+ pop %ebp
+ ret
+
+//-------------------------------------------------------------------------------
+// S3AsmGetAddressMap
+//-------------------------------------------------------------------------------------
+.set L_NemInitOffset, L_NemInit - L_S3RendezvousFunnelProcStart
+.set L_SemaphoreOffset, L_S3SemaphoreStartAddress - L_S3RendezvousFunnelProcStart
+
+.globl ASM_PFX(S3AsmGetAddressMap)
+ASM_PFX(S3AsmGetAddressMap):
+ mov $L_S3RendezvousFunnelProcStart, %eax
+ ret
+
+
+//-------------------------------------------------------------------------------
+// S3AsmGetPmodeOffset
+//-------------------------------------------------------------------------------------
+.globl ASM_PFX(S3AsmGetPmodeOffset)
+ASM_PFX(S3AsmGetPmodeOffset):
+ mov $L_NemInitOffset, %eax
+ ret
+
+//-------------------------------------------------------------------------------
+// S3AsmGetSemaphoreCheckOffset
+//-------------------------------------------------------------------------------------
+.globl ASM_PFX(S3AsmGetSemaphoreCheckOffset)
+ASM_PFX(S3AsmGetSemaphoreCheckOffset):
+ mov $L_SemaphoreOffset, %eax
+ ret \ No newline at end of file
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm
new file mode 100644
index 0000000000..9e3450d0d3
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm
@@ -0,0 +1,206 @@
+;; @file
+; This is the assembly code for MP support.
+;
+; Copyright (c) 2005 - 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 MpEqu.inc
+
+;-------------------------------------------------------------------------------------
+;S3RendezvousFunnelProc procedure follows. All APs execute their procedure. This
+;procedure serializes all the AP processors through an Init sequence. It must be
+;noted that APs arrive here very raw...ie: real mode, no stack.
+;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
+;IS IN MACHINE CODE.
+;-------------------------------------------------------------------------------------
+;S3RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
+
+.686p
+.model flat
+.code
+
+PAUSE32 MACRO
+ DB 0F3h
+ DB 090h
+ ENDM
+
+S3RendezvousFunnelProc PROC PUBLIC
+S3RendezvousFunnelProcStart::
+
+;Step-1: Grab a lock. At this point CS = 0x(vv00) and ip= 0x0.
+
+ db 8ch,0c8h ; mov ax,cs
+ db 8eh,0d8h ; mov ds,ax
+ db 8eh,0c0h ; mov es,ax
+ db 8eh,0d0h ; mov ss,ax
+ db 33h,0c0h ; xor ax,ax
+ db 8eh,0e0h ; mov fs,ax
+ db 8eh,0e8h ; mov gs,ax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
+
+ db 0BFh ; opcode of mov di, mem16
+ dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
+ db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
+ db 8Bh, 0F8h ; mov di, ax
+ db 83h, 0EFh,06h ; sub di, 06h
+ db 66h, 03h, 0C3h ; add eax, ebx
+ db 66h, 89h, 05h ; mov dword ptr [di],eax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw GdtrLocation ; mov si, GdtrLocation
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh ; opcode of mov si, mem16
+ dw IdtrLocation ; mov si, IdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 33h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
+ db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+ db 66h, 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 20h ; 16-bit selector
+
+NemInit:: ; protected mode entry point
+
+ db 66h, 0B8h, 18h, 00h ; mov ax, 18h
+ db 66h, 8Eh, 0D8h ; mov ds, ax
+ db 66h, 8Eh, 0C0h ; mov es, ax
+ db 66h, 8Eh, 0E0h ; mov fs, ax
+ db 66h, 8Eh, 0E8h ; mov gs, ax
+ db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.
+
+ mov esi, ebx
+
+ mov edi, esi
+ add edi, StartStateLocation
+ mov eax, 1
+ mov dword ptr [edi], eax
+
+ mov edi, esi
+ add edi, LockLocation
+ mov eax, NotVacantFlag
+TestLock::
+ xchg dword ptr [edi], eax
+ cmp eax, NotVacantFlag
+ jz TestLock
+
+ProgramStack::
+
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov eax, dword ptr [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add eax, dword ptr [edi]
+ mov esp, eax
+ mov dword ptr [edi], eax
+
+Releaselock::
+
+ mov eax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg dword ptr [edi], eax
+
+CProcedureInvoke::
+
+ mov edi, esi
+ add edi, MtrrValuesAddressLocation
+ mov eax, dword ptr [edi]
+ push eax
+
+ mov eax, esi
+ add eax, LockLocation
+ push eax
+
+ mov edi, esi
+ add edi, CProcedureLocation
+ mov eax, dword ptr [edi]
+
+;
+; itp.threads[n].msr(0x121, 0x2FBA2E2500010408)
+; WA for ACPI PM1 timer BXT 0 and 1
+;
+ push ecx
+ push eax
+ push edx
+
+ mov ecx, 0121h
+ rdmsr
+ test eax, eax
+ jnz SkipAcpiTimerWA
+ mov eax, 00010408h ; Bit 16 is enable and 15:0 address
+ mov edx, 2FBA2E25h
+ wrmsr
+SkipAcpiTimerWA:
+ pop edx
+ pop eax
+ pop ecx
+
+ call eax
+ add esp, 8
+
+ cli
+ hlt
+ jmp $-2
+
+S3RendezvousFunnelProc ENDP
+
+S3SemaphoreStartAddress PROC C, SemaphoreAddress:PTR DWORD
+ mov eax, SemaphoreAddress
+@@:
+ cmp dword ptr [eax], 0
+ jz @F
+
+ PAUSE32
+ jmp @B
+@@:
+ ret
+S3SemaphoreStartAddress ENDP
+
+S3RendezvousFunnelProcEnd::
+
+
+;-------------------------------------------------------------------------------------
+; S3AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+S3AsmGetAddressMap PROC near C PUBLIC
+
+ mov eax, S3RendezvousFunnelProcStart
+ ret
+
+S3AsmGetAddressMap ENDP
+
+S3AsmGetPmodeOffset PROC near C PUBLIC
+
+ mov eax, NemInit - S3RendezvousFunnelProcStart
+ ret
+
+S3AsmGetPmodeOffset ENDP
+
+S3AsmGetSemaphoreCheckOffset PROC near C PUBLIC
+ mov eax, S3SemaphoreStartAddress - S3RendezvousFunnelProcStart
+ ret
+S3AsmGetSemaphoreCheckOffset ENDP
+
+END
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf
new file mode 100644
index 0000000000..749dd98ad7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf
@@ -0,0 +1,59 @@
+## @file
+# Component information file for CPU S3 module.
+#
+# 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 = PeiCpuS3Lib
+ FILE_GUID = 6351F303-B76A-44F9-9171-026BDDCA8654
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = CpuS3Lib
+
+[LibraryClasses]
+ CpuPlatformLib
+ DebugLib
+ BaseLib
+ PeiServicesLib
+ BaseMemoryLib
+ SynchronizationLib
+ HobLib
+ ReportStatusCodeLib
+ MemoryAllocationLib
+ IoLib
+ TimerLib
+ CpuCommonLib
+ PostCodeLib
+ MpServiceLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonSiPkg/BroxtonSiPrivate.dec
+
+[Sources]
+ CpuS3Lib.c
+
+[Sources.IA32]
+ Ia32/MpFuncs.S | GCC
+ Ia32/MpFuncs.asm | MSFT
+
+[Ppis]
+ gSiCpuPolicyPpiGuid ## CONSUMES
+ gPeiSmmAccessPpiGuid ## CONSUMES
+ gEfiEndOfPeiSignalPpiGuid ## NOTIFY
+
+[Guids]
+ gSmramCpuDataHeaderGuid ## UNDEFINED
+ gPeiAcpiCpuDataGuid ## UNDEFINED
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c
new file mode 100644
index 0000000000..556fa49a6a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c
@@ -0,0 +1,683 @@
+/** @file
+ CPU Common Lib implementation.
+
+ 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PostCodeLib.h>
+#include <CpuAccess.h>
+#include <Private/Library/CpuCommonLib.h>
+
+#define INTERRUPT_VECTOR_NUMBER 256
+#define END_OF_TABLE 0xFF
+
+///
+/// Table to convert PL1 / Pl2 / RATL Seconds into equivalent MSR values
+/// This table is used for TDP Time Window programming
+///
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSecondsToMsrValueMapTable[][2] = {
+ ///
+ /// Seconds, MSR Value
+ ///
+ { 1, 0x0A },
+ { 2, 0x0B },
+ { 3, 0x4B },
+ { 4, 0x0C },
+ { 5, 0x2C },
+ { 6, 0x4C },
+ { 7, 0x6C },
+ { 8, 0x0D },
+ { 10, 0x2D },
+ { 12, 0x4D },
+ { 14, 0x6D },
+ { 16, 0x0E },
+ { 20, 0x2E },
+ { 24, 0x4E },
+ { 28, 0x6E },
+ { 32, 0x0F },
+ { 40, 0x2F },
+ { 48, 0x4F },
+ { 56, 0x6F },
+ { 64, 0x10 },
+ { 80, 0x30 },
+ { 96, 0x50 },
+ { 112, 0x70 },
+ { 128, 0x11 },
+ { END_OF_TABLE, END_OF_TABLE }
+};
+
+///
+/// Table to convert PL3 Milli Seconds into equivalent MSR values
+/// This table is used for TDP Time Window programming
+///
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mMilliSecondsToMsrValueMapTable[][2] = {
+ ///
+ /// MilliSeconds, MSR Value
+ ///
+ { 3, 0x41 },
+ { 4, 0x02 },
+ { 5, 0x22 },
+ { 6, 0x42 },
+ { 7, 0x62 },
+ { 8, 0x03 },
+ { 10, 0x23 },
+ { 12, 0x43 },
+ { 14, 0x63 },
+ { 16, 0x04 },
+ { 20, 0x24 },
+ { 24, 0x44 },
+ { 28, 0x64 },
+ { 32, 0x05 },
+ { 40, 0x25 },
+ { 48, 0x45 },
+ { 56, 0x65 },
+ { 64, 0x06 },
+ { END_OF_TABLE, END_OF_TABLE }
+};
+
+/**
+ Initialize prefetcher settings.
+
+ @param[in] MlcStreamerprefecterEnabled Enable/Disable MLC streamer prefetcher
+ @param[in] MlcSpatialPrefetcherEnabled Enable/Disable MLC spatial prefetcher
+
+**/
+VOID
+ProcessorsPrefetcherInitialization (
+ IN UINTN MlcStreamerprefecterEnabled,
+ IN UINTN MlcSpatialPrefetcherEnabled
+ )
+{
+ UINT64 MsrValue;
+
+ MsrValue = AsmReadMsr64 (MISC_FEATURE_CONTROL);
+
+ if (MlcStreamerprefecterEnabled == 0) {
+ MsrValue |= B_MISC_FEATURE_CONTROL_MLC_STRP;
+ }
+
+ if (MlcSpatialPrefetcherEnabled == 0) {
+ MsrValue |= B_MISC_FEATURE_CONTROL_MLC_SPAP;
+ }
+
+ if ((MsrValue & (B_MISC_FEATURE_CONTROL_MLC_STRP | B_MISC_FEATURE_CONTROL_MLC_SPAP)) != 0) {
+ AsmWriteMsr64 (MISC_FEATURE_CONTROL, MsrValue);
+ }
+
+ return;
+}
+
+
+/**
+ Set up flags in CR4 for XMM instruction enabling.
+
+**/
+VOID
+EFIAPI
+XmmInit (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+ UINTN Cr0;
+ UINTN Cr4;
+
+ //
+ // Read the CPUID information
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+
+ //
+ // Check whether SSE2 is supported
+ //
+ if (Cpuid.RegEdx & BIT26) {
+
+ //
+ // Enable XMM
+ //
+ Cr0 = AsmReadCr0 ();
+ Cr0 |= BIT1;
+ AsmWriteCr0 (Cr0);
+
+ Cr4 = AsmReadCr4 ();
+ Cr4 |= (BIT9 | BIT10);
+ AsmWriteCr4 (Cr4);
+ }
+}
+
+
+/**
+ Enable "Machine Check Enable" bit in Cr4.
+
+**/
+VOID
+EFIAPI
+EnableMce (
+ VOID
+ )
+{
+ UINTN Cr4;
+
+ //
+ // Enable MCE
+ //
+ Cr4 = AsmReadCr4 ();
+ Cr4 |= BIT6;
+ AsmWriteCr4 (Cr4);
+}
+
+
+/**
+ Mtrr Synch Up Entry.
+
+**/
+UINTN
+EFIAPI
+MpMtrrSynchUpEntry (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+ UINT64 MsrData;
+ UINTN Cr0;
+ UINTN Cr4;
+
+ //
+ // Read the CPUID and MSR 1Bh information
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ MsrData = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+
+ //
+ // Set CD(Bit30) bit and clear NW(Bit29) bit of CR0 followed by a WBINVD.
+ //
+ if (!(Cpuid.RegEdx & BIT24) || (MsrData & BIT8)) {
+ AsmDisableCache ();
+ } else {
+ //
+ // We could bypass the wbinvd by
+ // checking MSR 1Bh(MSR_IA32_APIC_BASE) Bit8 (1 = BSP, 0 = AP) to see if we're the BSP?
+ // and checking CPUID if the processor support self-snooping.
+ //
+ Cr0 = AsmReadCr0 ();
+ Cr0 &= ~BIT29;
+ Cr0 |= BIT30;
+ AsmWriteCr0 (Cr0);
+ }
+
+ //
+ // Clear PGE flag Bit 7
+ //
+ Cr4 = AsmReadCr4 ();
+ Cr4 &= ~BIT7;
+ AsmWriteCr4 (Cr4);
+
+ //
+ // Flush all TLBs
+ //
+ CpuFlushTlb ();
+
+ return Cr4;
+}
+
+
+/**
+ Mtrr Synch Up Exit
+
+**/
+VOID
+EFIAPI
+MpMtrrSynchUpExit (
+ UINTN Cr4
+ )
+{
+ UINTN Cr0;
+
+ //
+ // Flush all TLBs the second time
+ //
+ CpuFlushTlb ();
+
+ //
+ // Clear both the CD and NW bits of CR0.
+ //
+ Cr0 = AsmReadCr0 ();
+ Cr0 &= ~(BIT29 | BIT30);
+ AsmWriteCr0 (Cr0);
+
+ //
+ // Set PGE Flag in CR4 if set
+ //
+ AsmWriteCr4 (Cr4);
+}
+
+
+/**
+ This procedure sends an IPI to the designated processor in
+ the requested delivery mode with the requested vector.
+
+ @param[in] ApicID APIC ID of processor.
+ @param[in] VectorNumber Vector number.
+ @param[in] DeliveryMode I/O APIC Interrupt Deliver Modes
+
+ @retval EFI_INVALID_PARAMETER Input paramters were not correct.
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSendIpi (
+ IN UINT32 ApicID,
+ IN UINTN VectorNumber,
+ IN UINTN DeliveryMode
+ )
+{
+ UINT64 ApicBaseReg;
+ UINT64 MsrValue;
+ EFI_PHYSICAL_ADDRESS ApicBase;
+ UINT32 IcrLow;
+ UINT32 IcrHigh;
+ BOOLEAN XapicEnabled;
+ UINT32 TriggerMode;
+
+ //
+ // Check for valid input parameters.
+ //
+ if (VectorNumber >= INTERRUPT_VECTOR_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DeliveryMode >= DELIVERY_MODE_MAX) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Fix the vector number for special interrupts like SMI and INIT.
+ //
+ if (DeliveryMode == DELIVERY_MODE_SMI || DeliveryMode == DELIVERY_MODE_INIT) {
+ VectorNumber = 0x0;
+ }
+
+ //
+ // Initialze ICR high dword, since P6 family processor needs
+ // the destination field to be 0x0F when it is a broadcast
+ //
+ IcrHigh = 0x0f000000;
+ IcrLow = (UINT32) (VectorNumber | (LShiftU64 (DeliveryMode, 8)));
+
+ TriggerMode = TRIGGER_MODE_EDGE;
+
+ //
+ // Interrupt trigger mode
+ //
+ if (TriggerMode == TRIGGER_MODE_LEVEL) {
+ IcrLow |= 0x8000;
+ }
+
+ //
+ // Interrupt pin polarity
+ //
+ IcrLow |= 0x4000;
+
+ //
+ // xAPIC Enabled
+ //
+ MsrValue = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ if (MsrValue & B_MSR_IA32_APIC_BASE_G_XAPIC) {
+ if (MsrValue & B_MSR_IA32_APIC_BASE_M_XAPIC) {
+ XapicEnabled = TRUE;
+ } else {
+ XapicEnabled = FALSE;
+ }
+ } else {
+ XapicEnabled = FALSE;
+ }
+
+ if (XapicEnabled) {
+ IcrHigh = (UINT32) ApicID;
+ } else {
+ IcrHigh = (UINT32) LShiftU64 (ApicID, 24);
+ }
+
+ ApicBaseReg = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBase = ApicBaseReg & 0xffffff000;
+
+ /* If Extended XAPIC Mode is enabled,
+ legacy xAPIC is no longer working.
+ So, previous MMIO offset must be transferred to MSR offset R/W.
+ ----------------------------------------------------------------
+ MMIO Offset MSR Offset Register Name
+ ----------------------------------------------------------------
+ 300h-310h 830h Interrupt Command Register [63:0]
+ 831h [Reserved]
+ ----------------------------------------------------------------
+ */
+ //
+ // To write APIC register by MSR or MMIO
+ //
+ if (XapicEnabled) {
+ AsmWriteMsr64 (EXT_XAPIC_ICR, (((UINT64) LShiftU64 (IcrHigh, 32)) | (UINT64) IcrLow));
+ } else {
+ *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_HIGH_OFFSET) = (UINT32) IcrHigh;
+ *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET) = (UINT32) IcrLow;
+ }
+
+ MicroSecondDelay (10);
+
+ //
+ // To get APIC register from MSR or MMIO
+ //
+ if (XapicEnabled) {
+ IcrLow = (UINT32) AsmReadMsr64 (EXT_XAPIC_ICR);
+ } else {
+ IcrLow = (UINT32) *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET);
+ }
+
+ if (IcrLow & BIT12) {
+ return EFI_NOT_READY;
+ }
+
+ MicroSecondDelay (100);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Private helper function to convert various Turbo Power Limit Time from Seconds to CPU units
+
+ @param[in] TimeInSeconds Time in seconds
+ @param[in] TimeWindowConvType Time Window Convert Type
+
+ @retval UINT8 Converted time in CPU units
+
+**/
+UINT8
+GetConvertedTime (
+ IN UINT32 TimeInSeconds,
+ IN TIME_WINDOW_CONV TimeWindowConvType
+ )
+{
+ UINT8 ConvertedPowerLimitTime;
+ UINT8 Index;
+
+ //
+ // Convert seconds to MSR value. Since not all values are programmable, we'll select
+ // the entry from mapping table which is either equal to the user selected value. OR to a value in the mapping table
+ // which is closest (but less than) to the user-selected value.
+ //
+ ConvertedPowerLimitTime = 0;
+ switch (TimeWindowConvType) {
+ case PL1TimeWindowConvert:
+ case TccOffsetTimeWindowConvert:
+ ConvertedPowerLimitTime = mSecondsToMsrValueMapTable[0][1];
+ for (Index = 0; mSecondsToMsrValueMapTable[Index][0] != END_OF_TABLE; Index++) {
+ if (TimeInSeconds == mSecondsToMsrValueMapTable[Index][0]) {
+ ConvertedPowerLimitTime = mSecondsToMsrValueMapTable[Index][1];
+ break;
+ }
+ if (TimeInSeconds > mSecondsToMsrValueMapTable[Index][0]) {
+ ConvertedPowerLimitTime = mSecondsToMsrValueMapTable[Index][1];
+ } else {
+ break;
+ }
+ }
+ break;
+ case PL3TimeWindowConvert:
+ ConvertedPowerLimitTime = mMilliSecondsToMsrValueMapTable[0][1];
+ for (Index = 0; mMilliSecondsToMsrValueMapTable[Index][0] != END_OF_TABLE; Index++) {
+ if (TimeInSeconds == mMilliSecondsToMsrValueMapTable[Index][0]) {
+ ConvertedPowerLimitTime = mMilliSecondsToMsrValueMapTable[Index][1];
+ break;
+ }
+ if (TimeInSeconds > mMilliSecondsToMsrValueMapTable[Index][0]) {
+ ConvertedPowerLimitTime = mMilliSecondsToMsrValueMapTable[Index][1];
+ } else {
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ConvertedPowerLimitTime;
+}
+
+
+/**
+ Get APIC ID of processor.
+
+ @retval APIC ID of processor.
+
+**/
+UINT32
+GetCpuApicId (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegisters;
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ return (UINT32) (CpuidRegisters.RegEbx >> 24);
+}
+
+
+/**
+ Programs XAPIC registers.
+
+ @param[in] Bsp Is this BSP?
+
+**/
+VOID
+ProgramXApic (
+ BOOLEAN Bsp
+ )
+{
+ UINT64 ApicBaseReg;
+ EFI_PHYSICAL_ADDRESS ApicBase;
+ volatile UINT32 *EntryAddress;
+ UINT32 EntryValue;
+
+ ApicBaseReg = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBase = ApicBaseReg & 0xffffff000ULL;
+
+ //
+ // Program the spurious vector entry
+ //
+ EntryAddress = (UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_SPURIOUS_VECTOR_OFFSET);
+ EntryValue = *EntryAddress;
+ EntryValue &= 0xFFFFFD0F;
+ EntryValue |= 0x10F;
+ *EntryAddress = EntryValue;
+
+ //
+ // Program the LINT1 vector entry as extINT
+ //
+ EntryAddress = (UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_LINT0_VECTOR_OFFSET);
+ EntryValue = *EntryAddress;
+
+ if (Bsp) {
+ EntryValue &= 0xFFFE00FF;
+ EntryValue |= 0x700;
+ } else {
+ EntryValue |= 0x10000;
+ }
+
+ *EntryAddress = EntryValue;
+
+ //
+ // Program the LINT1 vector entry as NMI
+ //
+ EntryAddress = (UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_LINT1_VECTOR_OFFSET);
+ EntryValue = *EntryAddress;
+ EntryValue &= 0xFFFE00FF;
+ if (Bsp) {
+ EntryValue |= 0x400;
+ } else {
+ EntryValue |= 0x10400;
+ }
+
+ *EntryAddress = EntryValue;
+}
+
+
+/**
+ This function returns the maximum number of core supported in this physical processor package.
+
+ @retval Maximum number of cores in the package.
+
+**/
+UINT8
+GetMaxSupportedCoreCount (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+
+ AsmCpuidEx (
+ 4,
+ 0,
+ &Cpuid.RegEax,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ return (UINT8) (RShiftU64 (Cpuid.RegEax, 26) & 0x3f) + 1;
+}
+
+
+/**
+ This function returns the actual factory-configured number of threads per core,
+ and actual factory-configured number of cores in this physical processor package.
+
+ @param[out] NumberOfEnabledThreadsPerCore Variable that will store Maximum enabled threads per core.
+ @param[out] NumberOfEnabledCoresPerDie Variable that will store Maximum enabled cores per die.
+
+**/
+VOID
+GetSupportedCount (
+ OUT UINT16 *ThreadsPerCore, OPTIONAL
+ OUT UINT16 *NumberOfCores OPTIONAL
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegs;
+ UINT16 Threads;
+
+ AsmCpuidEx (CPUID_CORE_TOPOLOGY, 0, NULL, &CpuidRegs.RegEbx, NULL, NULL);
+ Threads = (UINT16) CpuidRegs.RegEbx;
+
+ if (ThreadsPerCore != NULL) {
+ *ThreadsPerCore = Threads;
+ }
+
+ if (NumberOfCores != NULL) {
+ AsmCpuidEx (CPUID_CORE_TOPOLOGY, 1, NULL, &CpuidRegs.RegEbx, NULL, NULL);
+ *NumberOfCores = (UINT16) (CpuidRegs.RegEbx / Threads);
+ }
+}
+
+
+/**
+ This function returns the maximum enabled Core per die, maximum enabled threads per core,
+ maximum number of dies and packages.
+
+ @param[out] NumberOfEnabledThreadsPerCore Variable that will store Maximum enabled threads per core.
+ @param[out] NumberOfEnabledCoresPerDie Variable that will store Maximum enabled cores per die.
+ @param[out] NumberOfDiesPerPackage Variable that will store Maximum dies per package.
+ @param[out] NumberOfPackages Variable that will store Maximum Packages.
+
+**/
+VOID
+GetEnabledCount (
+ OUT UINT16 *NumberOfEnabledThreadsPerCore, OPTIONAL
+ OUT UINT16 *NumberOfEnabledCoresPerDie, OPTIONAL
+ OUT UINT16 *NumberOfDiesPerPackage, OPTIONAL
+ OUT UINT16 *NumberOfPackages OPTIONAL
+ )
+{
+ UINT64 MsrValue;
+ UINT16 NumCores;
+
+ PostCode (0xC81);
+
+ //
+ // Read MSR_CORE_THREAD_COUNT (0x35)
+ //
+ MsrValue = AsmReadMsr64 (MSR_CORE_THREAD_COUNT);
+
+ NumCores = (UINT16) RShiftU64 (MsrValue, N_CORE_COUNT_OFFSET);
+
+ //
+ // Get enabled core count in the package (BITS[31:16])
+ //
+ if (NumberOfEnabledCoresPerDie != NULL) {
+ *NumberOfEnabledCoresPerDie = NumCores;
+ }
+
+ //
+ // Get enabled thread count in the package (BITS[15:0])
+ //
+ if (NumberOfEnabledThreadsPerCore != NULL) {
+ *NumberOfEnabledThreadsPerCore = (UINT16)DivU64x32((UINT64)(MsrValue & B_THREAD_COUNT_MASK), (UINT32) NumCores);
+ }
+
+ //
+ // For client, the number of dies and packages will be one
+ //
+ if (NumberOfDiesPerPackage != NULL) {
+ *NumberOfDiesPerPackage = 1;
+ }
+
+ if (NumberOfPackages != NULL) {
+ *NumberOfPackages = 1;
+ }
+ PostCode (0xC84);
+}
+
+
+/**
+ Check to see if the executing thread is BSP.
+
+ @retval TRUE Executing thread is BSP
+ @retval FALSE Executing thread is AP
+
+**/
+BOOLEAN
+IsBsp (
+ VOID
+)
+{
+ BOOLEAN BspIndicator;
+
+ BspIndicator = (AsmReadMsr64 (MSR_IA32_APIC_BASE) & B_MSR_IA32_APIC_BASE_BSP) ? TRUE : FALSE;
+
+ return BspIndicator;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/PeiDxeSmmCpuCommonLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/PeiDxeSmmCpuCommonLib.inf
new file mode 100644
index 0000000000..5b97d26b9d
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/PeiDxeSmmCpuCommonLib.inf
@@ -0,0 +1,44 @@
+## @file
+# CPU Common Lib.
+#
+# 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 = PeiDxeSmmCpuCommonLib
+ FILE_GUID = B4E0E3E8-DCE9-46FE-9670-03FDD2F08D6C
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = CpuCommonLib
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ PcdLib
+ PciLib
+ CpuLib
+ TimerLib
+ SynchronizationLib
+ TimerLib
+ CpuPlatformLib
+ PostCodeLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonSiPkg/BroxtonSiPrivate.dec
+
+[Sources]
+ CpuCommonLib.c
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Features.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Features.h
new file mode 100644
index 0000000000..52209a5df4
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Features.h
@@ -0,0 +1,120 @@
+/** @file
+ Header file of CPU feature control module.
+
+ 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 _FEATURES_H_
+#define _FEATURES_H_
+
+#include <Private/Library/MpServiceLib.h>
+
+///
+/// Processor feature definitions.
+///
+#define TXT_SUPPORT 1
+#define VMX_SUPPORT (1 << 1)
+#define XD_SUPPORT (1 << 2)
+#define DCA_SUPPORT (1 << 3)
+#define X2APIC_SUPPORT (1 << 4)
+#define AES_SUPPORT (1 << 5)
+#define HT_SUPPORT (1 << 6)
+#define DEBUG_SUPPORT (1 << 7)
+#define DEBUG_LOCK_SUPPORT (1 << 8)
+#define PROC_TRACE_SUPPORT (1 << 9)
+
+#define OPTION_FEATURE_RESERVED_MASK 0xFFFB00F8 ///< bits 30:16, 18, 7:3
+#define OPTION_FEATURE_CONFIG_RESERVED_MASK 0xFFFFFFFC ///< bits 2:31
+
+#define MAX_TOPA_ENTRY_COUNT 2
+
+typedef struct {
+ UINT64 TopaEntry[MAX_TOPA_ENTRY_COUNT];
+} PROC_TRACE_TOPA_TABLE;
+
+/**
+ Create feature control structure which will be used to program each feature on each core.
+
+**/
+VOID
+InitializeFeaturePerSetup (
+ VOID
+ );
+
+/**
+ Program all processor features basing on desired settings
+
+**/
+VOID
+EFIAPI
+ProgramProcessorFeature (
+ VOID
+ );
+
+/**
+ Program CPUID Limit before booting to OS
+
+**/
+VOID
+EFIAPI
+ProgramCpuidLimit (
+ VOID
+ );
+
+/**
+ Initialize prefetcher settings
+
+ @param[in] MlcStreamerprefecterEnabled Enable/Disable MLC streamer prefetcher
+ @param[in] MlcSpatialPrefetcherEnabled Enable/Disable MLC spatial prefetcher
+
+**/
+VOID
+InitializeProcessorsPrefetcher (
+ IN UINTN MlcStreamerprefecterEnabled,
+ IN UINTN MlcSpatialPrefetcherEnabled
+ );
+
+/**
+ Detect each processor feature and log all supported features
+
+**/
+VOID
+EFIAPI
+CollectProcessorFeature (
+ VOID
+ );
+
+/**
+ Lock VMX/TXT feature bits on the processor.
+ Set "CFG Lock" (MSR 0E2h Bit[15]
+
+**/
+VOID
+LockFeatureBit (
+ VOID
+ );
+
+
+/**
+ Provide access to the CPU misc enables MSR
+
+ @param[in] Enable Enable or Disable Misc Features
+ @param[in] BitMask The register bit offset of MSR MSR_IA32_MISC_ENABLE
+
+**/
+VOID
+CpuMiscEnable (
+ BOOLEAN Enable,
+ UINT64 BitMask
+ );
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.h
new file mode 100644
index 0000000000..df13a04a58
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.h
@@ -0,0 +1,45 @@
+/** @file
+ This is the equates file for HT (Hyper-threading) support.
+
+ 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.
+
+**/
+
+#define VacantFlag 0x00
+#define NotVacantFlag 0xff
+
+#define LockLocation (0x1000 - 0x0400)
+#define StackStartAddressLocation (LockLocation + 0x04)
+#define StackSizeLocation (LockLocation + 0x08)
+#define CProcedureLocation (LockLocation + 0x0C)
+#define GdtrLocation (LockLocation + 0x10)
+#define IdtrLocation (LockLocation + 0x16)
+#define BufferStartLocation (LockLocation + 0x1C)
+#define PmodeOffsetLocation (LockLocation + 0x20)
+#define AcpiCpuDataAddressLocation (LockLocation + 0x24)
+#define MtrrValuesAddressLocation (LockLocation + 0x28)
+#define FinishedCountAddressLocation (LockLocation + 0x2C)
+#define WakeupCountAddressLocation (LockLocation + 0x30)
+#define SerializeLockAddressLocation (LockLocation + 0x34)
+#define MicrocodeAddressLocation (LockLocation + 0x38)
+#define BootScriptAddressLocation (LockLocation + 0x3C)
+#define StartStateLocation (LockLocation + 0x40)
+#define VirtualWireMode (LockLocation + 0x44)
+#define SemaphoreCheck (LockLocation + 0x48)
+#define PeiServices (LockLocation + 0x4C)
+#define PeiStall (LockLocation + 0x50)
+#define CpuPerfCtrlValue (LockLocation + 0x54)
+#define SiCpuPolicyPpi (LockLocation + 0x5C)
+#define MpSystemDataAddressLocation (LockLocation + 0x64)
+#define MpServicePpiAddressLocation (LockLocation + 0x68)
+#define CArgumentLocation (LockLocation + 0x6C)
+#define BistBufferLocation (LockLocation + 0x70)
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc
new file mode 100644
index 0000000000..196019fefb
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc
@@ -0,0 +1,49 @@
+;; @file
+; This is the equates file used in MpFuncs.asm, for MP support.
+;
+; 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
+;
+;;
+
+VacantFlag Equ 00h
+NotVacantFlag Equ 0ffh
+
+LockLocation equ 1000h - 0400h
+StackStartAddressLocation equ LockLocation + 04h
+StackSizeLocation equ LockLocation + 08h
+CProcedureLocation equ LockLocation + 0Ch
+GdtrLocation equ LockLocation + 10h
+IdtrLocation equ LockLocation + 16h
+BufferStartLocation equ LockLocation + 1Ch
+PmodeOffsetLocation equ LockLocation + 20h
+AcpiCpuDataAddressLocation equ LockLocation + 24h
+MtrrValuesAddressLocation equ LockLocation + 28h
+FinishedCountAddressLocation equ LockLocation + 2Ch
+WakeupCountAddressLocation equ LockLocation + 30h
+SerializeLockAddressLocation equ LockLocation + 34h
+MicrocodeAddressLocation equ LockLocation + 38h
+BootScriptAddressLocation equ LockLocation + 3Ch
+StartStateLocation equ LockLocation + 40h
+VirtualWireMode equ LockLocation + 44h
+SemaphoreCheck equ LockLocation + 48h
+PeiServices equ LockLocation + 4Ch
+PeiStall equ LockLocation + 50h
+CpuPerfCtrlValue equ LockLocation + 54h
+SiCpuPolicyPpi equ LockLocation + 5Ch
+MpSystemDataAddressLocation equ LockLocation + 64h
+MpServicePpiAddressLocation equ LockLocation + 68h
+CArgumentLocation equ LockLocation + 6Ch
+BistBufferLocation equ LockLocation + 70h
+
+PAUSE32 MACRO
+ DB 0F3h
+ DB 090h
+ ENDM
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEquNasm.inc b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEquNasm.inc
new file mode 100644
index 0000000000..0590cd88de
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEquNasm.inc
@@ -0,0 +1,49 @@
+;; @file
+; This is the equates file used in MpFuncs.asm, for MP support.
+;
+; 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
+;
+;;
+
+%define VacantFlag 0x0
+%define NotVacantFlag 0xff
+
+%define LockLocation 0x1000 - 0x400
+%define StackStartAddressLocation LockLocation + 0x4
+%define StackSizeLocation LockLocation + 0x8
+%define CProcedureLocation LockLocation + 0xC
+%define GdtrLocation LockLocation + 0x10
+%define IdtrLocation LockLocation + 0x16
+%define BufferStartLocation LockLocation + 0x1C
+%define PmodeOffsetLocation LockLocation + 0x20
+%define AcpiCpuDataAddressLocation LockLocation + 0x24
+%define MtrrValuesAddressLocation LockLocation + 0x28
+%define FinishedCountAddressLocation LockLocation + 0x2C
+%define WakeupCountAddressLocation LockLocation + 0x30
+%define SerializeLockAddressLocation LockLocation + 0x34
+%define MicrocodeAddressLocation LockLocation + 0x38
+%define BootScriptAddressLocation LockLocation + 0x3C
+%define StartStateLocation LockLocation + 0x40
+%define VirtualWireMode LockLocation + 0x44
+%define SemaphoreCheck LockLocation + 0x48
+%define PeiServices LockLocation + 0x4C
+%define PeiStall LockLocation + 0x50
+%define CpuPerfCtrlValue LockLocation + 0x54
+%define SiCpuPolicyPpi LockLocation + 0x5C
+%define MpSystemDataAddressLocation LockLocation + 0x64
+%define MpServicePpiAddressLocation LockLocation + 0x68
+%define CArgumentLocation LockLocation + 0x6C
+%define BistBufferLocation LockLocation + 0x70
+
+%macro PAUSE32 0
+ DB 0xF3
+ DB 0x90
+ %endmacro
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S
new file mode 100644
index 0000000000..91ca56e85a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S
@@ -0,0 +1,316 @@
+## @file
+# This is the assembly code for MP support.
+#
+# 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 "MpEqu.h"
+
+ .text
+ ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+
+//-------------------------------------------------------------------------------
+// AsmAcquireMPLock (&Lock);
+//-------------------------------------------------------------------------------
+.globl ASM_PFX(AsmAcquireMPLock)
+ASM_PFX(AsmAcquireMPLock):
+
+ pusha
+ mov %esp, %ebp
+
+ mov $NotVacantFlag, %al
+ mov 0x24(%ebp), %ebx
+L_TryGetLock:
+ xchg (%ebx), %al
+ cmp $VacantFlag, %al
+ jz L_LockObtained
+
+ pause
+ jmp L_TryGetLock
+
+L_LockObtained:
+ popa
+ ret
+
+//-------------------------------------------------------------------------------
+// AsmReleaseMPLock (&Lock);
+//-------------------------------------------------------------------------------------
+.globl ASM_PFX(AsmReleaseMPLock)
+ASM_PFX(AsmReleaseMPLock):
+
+ pusha
+ mov %esp, %ebp
+
+ mov $VacantFlag, %al
+ movl 0x24(%ebp), %ebx
+ xchg (%ebx), %al
+
+ popa
+ ret
+
+//-------------------------------------------------------------------------------------
+//RendezvousFunnelProc procedure follows. All APs execute their procedure. This
+//procedure serializes all the AP processors through an Init sequence. It must be
+//noted that APs arrive here very raw...ie: real mode, no stack.
+//ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
+//IS IN MACHINE CODE.
+//-------------------------------------------------------------------------------------
+//RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
+
+.globl ASM_PFX(RendezvousFunnelProc)
+ASM_PFX(RendezvousFunnelProc):
+L_RendezvousFunnelProcStart:
+
+ .code16
+
+// At this point CS = 0x(vv00) and ip= 0x0.
+ mov %eax, %ebp
+ mov %cs, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %ss
+ xor %ax, %ax
+ mov %ax, %fs
+ mov %ax, %gs
+
+// Get APIC ID
+ mov $1, %eax
+ cpuid
+ shr $24, %ebx
+ and $0xff, %ebx // EBX is APIC ID
+
+// If it is the first time AP wakes up, just record AP's BIST
+// Otherwise, switch to protected mode.
+
+ mov $StartStateLocation, %si
+ cmpl $0, (%si)
+ jnz L_SkipRecordBist
+
+// Record BIST information
+//
+ mov $8, %al
+ mul %bl
+ mov $BistBufferLocation, %si
+ add %ax, %si
+
+ movl $1, (%si) // Set Valid Flag
+ mov %ebp, 4(%si) // Store BIST value
+
+L_SkipRecordBist:
+// Switch to flat mode.
+
+ mov $BufferStartLocation, %si
+ mov (%si), %ebx
+
+ mov $PmodeOffsetLocation, %di
+ mov (%di), %eax
+ mov %ax, %di
+ sub $6, %di
+ add %ebx, %eax
+ mov %eax, (%di)
+
+ mov $0, %esi
+ mov $GdtrLocation, %si
+ lgdtl %cs:(%esi)
+
+ xor %ax, %ax
+ mov %ax, %ds
+
+ mov %cr0, %eax
+ or $0x00000003, %eax
+ mov %eax, %cr0
+
+ .byte 0x66, 0x67, 0xea // far jump
+ .long 0x00 // 32-bit offset
+ .short 0x20 // 16-bit selector
+
+ .code32
+L_NemInit: // protected mode entry point
+ mov $0x18, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+
+ mov %ebx, %esi
+
+ mov %esi, %edi
+ add $StartStateLocation, %edi
+ mov $1, %eax
+ movl %eax, (%edi)
+
+ mov %esi, %edi
+ add $LockLocation, %edi
+ mov $NotVacantFlag, %eax
+L_TestLock:
+ xchg %eax, (%edi)
+ cmp $NotVacantFlag, %eax
+ jz L_TestLock
+
+L_ProgramStack:
+
+ mov %esi, %edi
+ add $StackSizeLocation, %edi
+ mov (%edi), %eax
+ mov %esi, %edi
+ add $StackStartAddressLocation, %edi
+ add (%edi), %eax
+ mov %eax, %esp
+ movl %eax, (%edi)
+
+L_Releaselock:
+
+ mov $VacantFlag, %eax
+ mov %esi, %edi
+ add $LockLocation, %edi
+ xchg %eax, (%edi)
+
+L_CProcedureInvoke:
+
+ mov %esi, %edi
+ add $CArgumentLocation, %edi
+ mov (%edi), %eax
+ push %eax
+
+ mov %esi, %edi
+ add $CProcedureLocation, %edi
+ mov (%edi), %eax
+
+ call *%eax
+ add $4, %esp
+
+L_InterlockedIncrementFinishedCount:
+ mov %esi, %edi
+ add $FinishedCountAddressLocation, %edi
+ lock incl (%edi)
+
+1:
+ cli
+
+ hlt
+ jmp 1b
+
+
+//-------------------------------------------------------------------------------------
+// SemaphoreStartAddress
+//-------------------------------------------------------------------------------------
+
+L_SemaphoreStartAddress:
+ push %ebp
+ mov %esp, %ebp
+ mov 0x8(%ebp), %eax
+1:
+ cmpl $0, (%eax)
+ jz 1f
+
+ pause
+ jmp 1b
+
+1:
+ pop %ebp
+ ret
+
+//-------------------------------------------------------------------------------
+// AsmGetAddressMap
+//-------------------------------------------------------------------------------------
+.set L_NemInitOffset, L_NemInit - L_RendezvousFunnelProcStart
+.set L_SemaphoreOffset, L_SemaphoreStartAddress - L_RendezvousFunnelProcStart
+
+.globl ASM_PFX(AsmGetAddressMap)
+ASM_PFX(AsmGetAddressMap):
+ mov $L_RendezvousFunnelProcStart, %eax
+ ret
+
+
+//-------------------------------------------------------------------------------
+// AsmGetPmodeOffset
+//-------------------------------------------------------------------------------------
+.globl ASM_PFX(AsmGetPmodeOffset)
+ASM_PFX(AsmGetPmodeOffset):
+ mov $L_NemInitOffset, %eax
+ ret
+
+//-------------------------------------------------------------------------------
+// AsmGetSemaphoreCheckOffset
+//-------------------------------------------------------------------------------------
+.globl ASM_PFX(AsmGetSemaphoreCheckOffset)
+ASM_PFX(AsmGetSemaphoreCheckOffset):
+ mov $L_SemaphoreOffset, %eax
+ ret
+
+//-------------------------------------------------------------------------------------
+//AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
+//about to become an AP. It switches it'stack with the current AP.
+//AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
+//-------------------------------------------------------------------------------------
+#define CPU_SWITCH_STATE_IDLE 0
+#define CPU_SWITCH_STATE_STORED 1
+#define CPU_SWITCH_STATE_LOADED 2
+
+.globl ASM_PFX(AsmExchangeRole)
+ASM_PFX(AsmExchangeRole):
+ // DO NOT call other functions in this function, since 2 CPU may use 1 stack
+ // at the same time. If 1 CPU try to call a functiosn, stack will be corrupted.
+
+ pusha
+ mov %ebp, %esp
+
+
+ // esi contains MyInfo pointer
+ mov %ecx, %esi
+
+ // edi contains OthersInfo pointer
+ mov %edx, %edi
+
+ //Store EFLAGS, GDTR and IDTR regiter to stack
+ pushf
+ sgdt 8(%esi)
+ sidt 14(%esi)
+
+ // Store the its StackPointer
+ mov %esp, 4(%esi)
+
+ // update its switch state to STORED
+ movb $CPU_SWITCH_STATE_STORED, 1(%esi)
+ xchg %al, (%esi)
+
+L_WaitForOtherStored:
+ // wait until the other CPU finish storing its state
+ cmp $CPU_SWITCH_STATE_STORED, %edi
+ jb L_WaitForOtherStored
+
+ // Since another CPU already stored its state, load them
+ // load GDTR value
+ lgdt 8(%edi)
+
+ // load IDTR value
+ lidt 14(%edi)
+
+ // load its future StackPointer
+ mov 4(%edi), %esp
+
+ // update its switch state to LOADED
+ movb $CPU_SWITCH_STATE_LOADED, 1(%edi)
+ xchg %al, (%edi)
+
+L_WaitForOtherLoaded:
+ // wait until the other CPU finish loading new state,
+ // otherwise the data in stack may corrupt
+ cmp $CPU_SWITCH_STATE_LOADED, %esi
+ jb L_WaitForOtherLoaded
+
+ // since the other CPU already get the data it want, leave this procedure
+ popf
+
+ popa
+ ret
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.asm b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.asm
new file mode 100644
index 0000000000..58a481d091
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.asm
@@ -0,0 +1,365 @@
+;; @file
+; This is the assembly code for MP support.
+;
+; 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 MpEqu.inc
+
+;-------------------------------------------------------------------------------------
+;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
+;procedure serializes all the AP processors through an Init sequence. It must be
+;noted that APs arrive here very raw...ie: real mode, no stack.
+;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
+;IS IN MACHINE CODE.
+;-------------------------------------------------------------------------------------
+;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
+
+.686p
+.model flat
+.code
+
+PAUSE32 MACRO
+ DB 0F3h
+ DB 090h
+ ENDM
+
+;-------------------------------------------------------------------------------
+; AsmAcquireMPLock (&Lock);
+;-------------------------------------------------------------------------------
+AsmAcquireMPLock PROC near C PUBLIC
+
+ pushad
+ mov ebp,esp
+
+ mov al, NotVacantFlag
+ mov ebx, dword ptr [ebp+24h]
+TryGetLock:
+ xchg al, byte ptr [ebx]
+ cmp al, VacantFlag
+ jz LockObtained
+
+ PAUSE32
+ jmp TryGetLock
+
+LockObtained:
+ popad
+ ret
+AsmAcquireMPLock ENDP
+
+;-------------------------------------------------------------------------------
+; AsmReleaseMPLock (&Lock);
+;-------------------------------------------------------------------------------------
+AsmReleaseMPLock PROC near C PUBLIC
+
+ pushad
+ mov ebp,esp
+
+ mov al, VacantFlag
+ mov ebx, dword ptr [ebp+24h]
+ xchg al, byte ptr [ebx]
+
+ popad
+ ret
+AsmReleaseMPLock ENDP
+
+RendezvousFunnelProc PROC PUBLIC
+RendezvousFunnelProcStart::
+
+;Step-1: Grab a lock. At this point CS = 0x(vv00) and ip= 0x0.
+ db 66h, 08bh, 0e8h ; mov ebp, eax
+ db 8ch,0c8h ; mov ax,cs
+ db 8eh,0d8h ; mov ds,ax
+ db 8eh,0c0h ; mov es,ax
+ db 8eh,0d0h ; mov ss,ax
+ db 33h,0c0h ; xor ax,ax
+ db 8eh,0e0h ; mov fs,ax
+ db 8eh,0e8h ; mov gs,ax
+; Get APIC ID
+;
+ db 66h, 0B8h
+ dd 00000001h ; mov eax, 1
+ db 0Fh, 0A2h ; cpuid
+ db 66h, 0C1h, 0EBh, 18h ; shr ebx, 24
+ db 66h, 81h, 0E3h
+ dd 000000FFh ; and ebx, 0ffh ; EBX is APIC ID
+
+; If it is the first time AP wakes up, just record AP's BIST
+; Otherwise, switch to protected mode.
+
+ db 0BEh ; opcode of mov si, imm16
+ dw StartStateLocation ; mov si, StartState
+ db 66h, 83h, 3Ch, 00h ; cmp dword ptr [si], 0
+ db 75h ; opcode of jnz
+ db SkipRecordBist - ($ + 1) ; jnz SkipRecordBist
+
+; Record BIST information
+;
+ db 0B0h, 08h ; mov al, 8
+ db 0F6h, 0E3h ; mul bl
+
+ db 0BEh ; opcode of mov si, imm16
+ dw BistBufferLocation ; mov si, BistBufferLocation
+ db 03h, 0F0h ; add si, ax
+
+ db 66h, 0C7h, 04h
+ dd 00000001h ; mov dword ptr [si], 1 ; Set Valid Flag
+ db 66h, 89h, 6Ch, 04h ; mov dword ptr [si + 4], ebp ; Store BIST value
+
+SkipRecordBist::
+ db 0BEh ; opcode of mov si, mem16
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
+
+ db 0BFh ; opcode of mov di, mem16
+ dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
+ db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
+ db 8Bh, 0F8h ; mov di, ax
+ db 83h, 0EFh,06h ; sub di, 06h
+ db 66h, 03h, 0C3h ; add eax, ebx
+ db 66h, 89h, 05h ; mov dword ptr [di],eax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw GdtrLocation ; mov si, GdtrLocation
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh ; opcode of mov si, mem16
+ dw IdtrLocation ; mov si, IdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 33h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
+ db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+ db 66h, 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+BspCS::
+ dw 00h ; 16-bit selector
+
+NemInit:: ; protected mode entry point
+
+ db 66h, 0B8h ; mov ax, 18h
+BspDS::
+ dw 00h
+ db 66h, 8Eh, 0D8h ; mov ds, ax
+ db 66h, 8Eh, 0C0h ; mov es, ax
+ db 66h, 8Eh, 0E0h ; mov fs, ax
+ db 66h, 8Eh, 0E8h ; mov gs, ax
+ db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.
+
+ mov esi, ebx
+
+ mov edi, esi
+ add edi, StartStateLocation
+ mov eax, 1
+ mov dword ptr [edi], eax
+
+ mov edi, esi
+ add edi, LockLocation
+ mov eax, NotVacantFlag
+TestLock::
+ xchg dword ptr [edi], eax
+ cmp eax, NotVacantFlag
+ jz TestLock
+
+ProgramStack::
+
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov eax, dword ptr [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add eax, dword ptr [edi]
+ mov esp, eax
+ mov dword ptr [edi], eax
+
+Releaselock::
+
+ mov eax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg dword ptr [edi], eax
+
+CProcedureInvoke::
+
+ mov edi, esi
+ add edi, CArgumentLocation
+ mov eax, dword ptr [edi]
+ push eax
+
+ mov edi, esi
+ add edi, CProcedureLocation
+ mov eax, dword ptr [edi]
+
+
+ push ecx
+ push eax
+ push edx
+
+ mov ecx, 0121h
+ rdmsr
+ test eax, eax
+ jnz SkipAcpiTimerWA
+ mov eax, 00010408h ; Bit 16 is enable and 15:0 address
+ mov edx, 2FBA2E25h
+ wrmsr
+SkipAcpiTimerWA:
+ pop edx
+ pop eax
+ pop ecx
+
+
+ call eax
+ add esp, 4
+
+InterlockedIncrementFinishedCount::
+ mov edi, esi
+ add edi, FinishedCountAddressLocation
+ lock inc dword ptr [edi]
+ cli
+ hlt
+ jmp $-2
+
+RendezvousFunnelProc ENDP
+
+SemaphoreStartAddress PROC C, SemaphoreAddress:PTR DWORD
+ mov eax, SemaphoreAddress
+@@:
+ cmp dword ptr [eax], 0
+ jz @F
+
+ PAUSE32
+ jmp @B
+@@:
+ ret
+SemaphoreStartAddress ENDP
+
+RendezvousFunnelProcEnd::
+
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+AsmGetAddressMap PROC near C PUBLIC
+
+ mov eax, RendezvousFunnelProcStart
+ ret
+
+AsmGetAddressMap ENDP
+
+AsmGetPmodeOffset PROC near C PUBLIC
+
+ mov eax, NemInit - RendezvousFunnelProcStart
+ ret
+
+AsmGetPmodeOffset ENDP
+
+AsmGetSemaphoreCheckOffset PROC near C PUBLIC
+ mov eax, SemaphoreStartAddress - RendezvousFunnelProcStart
+ ret
+AsmGetSemaphoreCheckOffset ENDP
+
+AsmPatchRendezvousCode PROC near C PUBLIC
+ mov eax, dword ptr [esp + 4]
+ push esi
+ push edi
+ mov edi, eax
+ mov ax, cs
+ mov esi, edi
+ add esi, BspCS - RendezvousFunnelProcStart
+ mov word ptr [esi], ax
+ mov ax, ds
+ mov esi, edi
+ add esi, BspDS - RendezvousFunnelProcStart
+ mov word ptr [esi], ax
+ pop edi
+ pop esi
+ xor eax, eax
+ ret
+AsmPatchRendezvousCode ENDP
+
+;-------------------------------------------------------------------------------------
+;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
+;about to become an AP. It switches it'stack with the current AP.
+;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
+;-------------------------------------------------------------------------------------
+CPU_SWITCH_STATE_IDLE equ 0
+CPU_SWITCH_STATE_STORED equ 1
+CPU_SWITCH_STATE_LOADED equ 2
+
+AsmExchangeRole PROC near C PUBLIC
+ ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
+ ; at the same time. If 1 CPU try to call a functiosn, stack will be corrupted.
+ pushad
+ mov ebp,esp
+
+ ; esi contains MyInfo pointer
+ mov esi, dword ptr [ebp+24h]
+
+ ; edi contains OthersInfo pointer
+ mov edi, dword ptr [ebp+28h]
+
+ ;Store EFLAGS, GDTR and IDTR regiter to stack
+ pushfd
+ sgdt fword ptr [esi+8]
+ sidt fword ptr [esi+14]
+
+ ; Store the its StackPointer
+ mov dword ptr [esi+4],esp
+
+ ; update its switch state to STORED
+ mov byte ptr [esi], CPU_SWITCH_STATE_STORED
+
+WaitForOtherStored::
+ ; wait until the other CPU finish storing its state
+ cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
+ jz OtherStored
+ PAUSE32
+ jmp WaitForOtherStored
+
+OtherStored::
+ ; Since another CPU already stored its state, load them
+ ; load GDTR value
+ lgdt fword ptr [edi+8]
+
+ ; load IDTR value
+ lidt fword ptr [edi+14]
+
+ ; load its future StackPointer
+ mov esp, dword ptr [edi+4]
+
+ ; update the other CPU's switch state to LOADED
+ mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
+
+WaitForOtherLoaded::
+ ; wait until the other CPU finish loading new state,
+ ; otherwise the data in stack may corrupt
+ cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
+ jz OtherLoaded
+ PAUSE32
+ jmp WaitForOtherLoaded
+
+OtherLoaded::
+ ; since the other CPU already get the data it want, leave this procedure
+ popfd
+
+ popad
+ ret
+AsmExchangeRole ENDP
+
+END
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.nasm b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.nasm
new file mode 100644
index 0000000000..deb580b6bb
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.nasm
@@ -0,0 +1,361 @@
+;; @file
+; This is the assembly code for MP support.
+;
+; Copyright (c) 2005 - 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 "MpEquNasm.inc"
+
+;-------------------------------------------------------------------------------------
+;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
+;procedure serializes all the AP processors through an Init sequence. It must be
+;noted that APs arrive here very raw...ie: real mode, no stack.
+;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
+;IS IN MACHINE CODE.
+;-------------------------------------------------------------------------------------
+;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
+
+SECTION .text
+
+%macro PAUSE32 0
+ DB 0xF3
+ DB 0x90
+ %endmacro
+
+;-------------------------------------------------------------------------------
+; AsmAcquireMPLock (&Lock);
+;-------------------------------------------------------------------------------
+global ASM_PFX(AsmAcquireMPLock)
+ASM_PFX(AsmAcquireMPLock):
+
+ pushad
+ mov ebp,esp
+
+ mov al, NotVacantFlag
+ mov ebx, dword [ebp+0x24]
+L_TryGetLock:
+ xchg al, byte [ebx]
+ cmp al, VacantFlag
+ jz L_LockObtained
+
+ PAUSE32
+ jmp L_TryGetLock
+
+L_LockObtained:
+ popad
+ ret
+
+;-------------------------------------------------------------------------------
+; AsmReleaseMPLock (&Lock);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmReleaseMPLock)
+ASM_PFX(AsmReleaseMPLock):
+
+ pushad
+ mov ebp,esp
+
+ mov al, VacantFlag
+ mov ebx, dword [ebp+0x24]
+ xchg al, byte [ebx]
+
+ popad
+ ret
+
+global ASM_PFX(RendezvousFunnelProc)
+ASM_PFX(RendezvousFunnelProc):
+L_RendezvousFunnelProcStart:
+
+;Step-1: Grab a lock. At this point CS = 0x(vv00) and ip= 0x0.
+ db 0x66, 0x8b, 0xe8 ; mov ebp, eax
+ db 0x8c,0xc8 ; mov ax,cs
+ db 0x8e,0xd8 ; mov ds,ax
+ db 0x8e,0xc0 ; mov es,ax
+ db 0x8e,0xd0 ; mov ss,ax
+ db 0x33,0xc0 ; xor ax,ax
+ db 0x8e,0xe0 ; mov fs,ax
+ db 0x8e,0xe8 ; mov gs,ax
+; Get APIC ID
+;
+ db 0x66, 0xB8
+ dd 0x1 ; mov eax, 1
+ db 0xF, 0xA2 ; cpuid
+ db 0x66, 0xC1, 0xEB, 0x18 ; shr ebx, 24
+ db 0x66, 0x81, 0xE3
+ dd 0xFF ; and ebx, 0ffh ; EBX is APIC ID
+
+; If it is the first time AP wakes up, just record AP's BIST
+; Otherwise, switch to protected mode.
+
+ db 0xBE ; opcode of mov si, imm16
+ dw StartStateLocation ; mov si, StartState
+ db 0x66, 0x83, 0x3C, 0x0 ; cmp dword ptr [si], 0
+ db 0x75 ; opcode of jnz
+ db L_SkipRecordBist - ($ + 1) ; jnz SkipRecordBist
+
+; Record BIST information
+;
+ db 0xB0, 0x8 ; mov al, 8
+ db 0xF6, 0xE3 ; mul bl
+
+ db 0xBE ; opcode of mov si, imm16
+ dw BistBufferLocation ; mov si, BistBufferLocation
+ db 0x3, 0xF0 ; add si, ax
+
+ db 0x66, 0xC7, 0x4
+ dd 0x1 ; mov dword ptr [si], 1 ; Set Valid Flag
+ db 0x66, 0x89, 0x6C, 0x4 ; mov dword ptr [si + 4], ebp ; Store BIST value
+
+L_SkipRecordBist:
+ db 0xBE ; opcode of mov si, mem16
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 0x66, 0x8B, 0x1C ; mov ebx,dword ptr [si]
+
+ db 0xBF ; opcode of mov di, mem16
+ dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
+ db 0x66, 0x8B, 0x5 ; mov eax,dword ptr [di]
+ db 0x8B, 0xF8 ; mov di, ax
+ db 0x83, 0xEF,0x6 ; sub di, 06h
+ db 0x66, 0x3, 0xC3 ; add eax, ebx
+ db 0x66, 0x89, 0x5 ; mov dword ptr [di],eax
+
+ db 0xBE ; opcode of mov si, mem16
+ dw GdtrLocation ; mov si, GdtrLocation
+ db 0x66 ; db 66h
+ db 0x2E, 0xF, 0x1, 0x14 ; lgdt fword ptr cs:[si]
+
+ db 0xBE ; opcode of mov si, mem16
+ dw IdtrLocation ; mov si, IdtrProfile
+ db 0x66 ; db 66h
+ db 0x2E, 0xF, 0x1, 0x1C ; lidt fword ptr cs:[si]
+
+ db 0x33, 0xC0 ; xor ax, ax
+ db 0x8E, 0xD8 ; mov ds, ax
+
+ db 0xF, 0x20, 0xC0 ; mov eax, cr0 ;Get control register 0
+ db 0x66, 0x83, 0xC8, 0x3 ; or eax, 000000003h ;Set PE bit (bit #0) & MP
+ db 0xF, 0x22, 0xC0 ; mov cr0, eax
+
+ db 0x66, 0x67, 0xEA ; far jump
+ dd 0x0 ; 32-bit offset
+BspCS:
+ dw 0x0 ; 16-bit selector
+
+L_NemInit: ; protected mode entry point
+
+ db 0x66, 0xB8 ; mov ax, 18h
+BspDS:
+ dw 0x0
+ db 0x66, 0x8E, 0xD8 ; mov ds, ax
+ db 0x66, 0x8E, 0xC0 ; mov es, ax
+ db 0x66, 0x8E, 0xE0 ; mov fs, ax
+ db 0x66, 0x8E, 0xE8 ; mov gs, ax
+ db 0x66, 0x8E, 0xD0 ; mov ss, ax ; Flat mode setup.
+
+ mov esi, ebx
+
+ mov edi, esi
+ add edi, StartStateLocation
+ mov eax, 1
+ mov dword [edi], eax
+
+ mov edi, esi
+ add edi, LockLocation
+ mov eax, NotVacantFlag
+L_TestLock:
+ xchg dword [edi], eax
+ cmp eax, NotVacantFlag
+ jz L_TestLock
+
+ProgramStack:
+
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov eax, dword [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add eax, dword [edi]
+ mov esp, eax
+ mov dword [edi], eax
+
+L_Releaselock:
+
+ mov eax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg dword [edi], eax
+
+L_CProcedureInvoke:
+
+ mov edi, esi
+ add edi, CArgumentLocation
+ mov eax, dword [edi]
+ push eax
+
+ mov edi, esi
+ add edi, CProcedureLocation
+ mov eax, dword [edi]
+
+;
+; reserved for SV_HOOKS START
+; itp.threads[n].msr(0x121, 0x2FBA2E2500010408)
+; WA for ACPI PM1 timer BXT 0 and 1
+ push ecx
+ push eax
+ push edx
+
+ mov ecx, 0x121
+ rdmsr
+ test eax, eax
+ jnz SkipAcpiTimerWA
+ mov eax, 0x10408 ; Bit 16 is enable and 15:0 address
+ mov edx, 0x2FBA2E25
+ wrmsr
+SkipAcpiTimerWA:
+ pop edx
+ pop eax
+ pop ecx
+;
+; Reserved for SV_HOOKS END
+
+ call eax
+ add esp, 4
+
+L_InterlockedIncrementFinishedCount:
+ mov edi, esi
+ add edi, FinishedCountAddressLocation
+ lock inc dword [edi]
+ cli
+ hlt
+ jmp $-2
+
+global ASM_PFX(SemaphoreStartAddress)
+ASM_PFX(SemaphoreStartAddress):
+ push ebp
+ mov ebp, esp
+ mov eax, dword [ebp + 0x8]
+.0:
+ cmp dword [eax], 0
+ jz .1
+
+ PAUSE32
+ jmp .0
+.1:
+ ret
+
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmGetAddressMap)
+ASM_PFX(AsmGetAddressMap):
+
+ mov eax, L_RendezvousFunnelProcStart
+ ret
+
+global ASM_PFX(AsmGetPmodeOffset)
+ASM_PFX(AsmGetPmodeOffset):
+
+ mov eax, L_NemInit - L_RendezvousFunnelProcStart
+ ret
+
+global ASM_PFX(AsmGetSemaphoreCheckOffset)
+ASM_PFX(AsmGetSemaphoreCheckOffset):
+ mov eax, SemaphoreStartAddress - L_RendezvousFunnelProcStart
+ ret
+
+global ASM_PFX(AsmPatchRendezvousCode)
+ASM_PFX(AsmPatchRendezvousCode):
+ mov eax, dword [esp + 4]
+ push esi
+ push edi
+ mov edi, eax
+ mov ax, cs
+ mov esi, edi
+ add esi, BspCS - L_RendezvousFunnelProcStart
+ mov word [esi], ax
+ mov ax, ds
+ mov esi, edi
+ add esi, BspDS - L_RendezvousFunnelProcStart
+ mov word [esi], ax
+ pop edi
+ pop esi
+ xor eax, eax
+ ret
+
+;-------------------------------------------------------------------------------------
+;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
+;about to become an AP. It switches it'stack with the current AP.
+;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
+;-------------------------------------------------------------------------------------
+%define CPU_SWITCH_STATE_IDLE 0
+%define CPU_SWITCH_STATE_STORED 1
+%define CPU_SWITCH_STATE_LOADED 2
+
+global ASM_PFX(AsmExchangeRole)
+ASM_PFX(AsmExchangeRole):
+ ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
+ ; at the same time. If 1 CPU try to call a functiosn, stack will be corrupted.
+ pushad
+ mov ebp,esp
+
+ ; esi contains MyInfo pointer
+ mov esi, dword [ebp+0x24]
+
+ ; edi contains OthersInfo pointer
+ mov edi, dword [ebp+0x28]
+
+ ;Store EFLAGS, GDTR and IDTR regiter to stack
+ pushfd
+ sgdt [esi+8]
+ sidt [esi+14]
+
+ ; Store the its StackPointer
+ mov dword [esi+4],esp
+
+ ; update its switch state to STORED
+ mov byte [esi], CPU_SWITCH_STATE_STORED
+
+L_WaitForOtherStored:
+ ; wait until the other CPU finish storing its state
+ cmp byte [edi], CPU_SWITCH_STATE_STORED
+ jz L_OtherStored
+ PAUSE32
+ jmp L_WaitForOtherStored
+
+L_OtherStored:
+ ; Since another CPU already stored its state, load them
+ ; load GDTR value
+ lgdt [edi+8]
+
+ ; load IDTR value
+ lidt [edi+14]
+
+ ; load its future StackPointer
+ mov esp, dword [edi+4]
+
+ ; update the other CPU's switch state to LOADED
+ mov byte [edi], CPU_SWITCH_STATE_LOADED
+
+L_WaitForOtherLoaded:
+ ; wait until the other CPU finish loading new state,
+ ; otherwise the data in stack may corrupt
+ cmp byte [esi], CPU_SWITCH_STATE_LOADED
+ jz L_OtherLoaded
+ PAUSE32
+ jmp L_WaitForOtherLoaded
+
+L_OtherLoaded:
+ ; since the other CPU already get the data it want, leave this procedure
+ popfd
+
+ popad
+ ret
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Microcode.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Microcode.c
new file mode 100644
index 0000000000..1b4a0b581e
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Microcode.c
@@ -0,0 +1,221 @@
+/** @file
+ CPU microcode update 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.
+
+**/
+
+#include <Private/Library/MpServiceLib.h>
+#include <CpuRegs.h>
+
+/**
+ Check if this is non-core processor - HT AP thread
+
+ @retval TRUE If this is HT AP thread
+ @retval FALSE If this is core thread
+
+**/
+BOOLEAN
+IsSecondaryThread (
+ VOID
+ )
+{
+ UINT32 ApicID;
+ EFI_CPUID_REGISTER CpuidRegisters;
+ UINT8 CpuCount;
+ UINT8 CoreCount;
+ UINT8 CpuPerCore;
+ UINT32 Mask;
+
+ ApicID = GetCpuApicId ();
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ if ((CpuidRegisters.RegEdx & 0x10000000) == 0) {
+ return FALSE;
+ }
+
+ CpuCount = (UINT8) ((CpuidRegisters.RegEbx >> 16) & 0xff);
+ if (CpuCount == 1) {
+ return FALSE;
+ }
+
+ AsmCpuid (
+ CPUID_SIGNATURE,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ if (CpuidRegisters.RegEax > 3) {
+
+ CoreCount = GetMaxSupportedCoreCount ();
+ } else {
+ CoreCount = 1;
+ }
+ //
+ // Assumes there is symmetry across core boundary, i.e. each core within a package has the same number of logical processors
+ //
+ if (CpuCount == CoreCount) {
+ return FALSE;
+ }
+
+ CpuPerCore = CpuCount / CoreCount;
+
+ //
+ // Assume 1 Core has no more than 8 threads
+ //
+ if (CpuPerCore == 2) {
+ Mask = 0x1;
+ } else if (CpuPerCore <= 4) {
+ Mask = 0x3;
+ } else {
+ Mask = 0x7;
+ }
+
+ if ((ApicID & Mask) == 0) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+
+/**
+ Wait until all primary threads are done with the microcode load.
+
+ @param[in] ExchangeInfo Pointer to the exchange info buffer for output.
+
+**/
+VOID
+WaitForPrimaryThreadMcuUpdate (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo
+ )
+{
+ UINTN CoreNumber;
+
+ CoreNumber = (UINTN) ((RShiftU64 (AsmReadMsr64 (MSR_CORE_THREAD_COUNT), 16)) & 0xffff);
+ if (IsSecondaryThread ()) {
+ while (ExchangeInfo->McuLoadCount < CoreNumber) {
+ CpuPause ();
+ }
+ }
+}
+
+
+/**
+ This will load the microcode to the processors.
+
+ @param[in] MicrocodeEntryPoint The microcode update pointer
+ @param[in, out] Revision The current (before load this microcode update) microcode revision
+ as output parameter, the microcode revision after microcode update is loaded
+
+ @retval EFI_SUCCESS Microcode loaded
+ @retval EFI_LOAD_ERROR Microcode not loaded
+
+**/
+EFI_STATUS
+LoadMicrocode (
+ IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+ IN OUT UINT32 *Revision
+ )
+{
+ EFI_STATUS Status;
+ UINT32 NewRevision;
+
+ Status = EFI_SUCCESS;
+
+#ifdef EFI_DEBUG
+ if (IsBsp()) {
+ DEBUG ((DEBUG_INFO, "LoadMicrocode: Before load, revision = 0x%x\n", *Revision));
+ }
+#endif
+
+ //
+ // Load the Processor Microcode
+ //
+ AsmWriteMsr64 (
+ MSR_IA32_BIOS_UPDT_TRIG,
+ (UINT64) ((UINTN) MicrocodeEntryPoint + sizeof (CPU_MICROCODE_HEADER))
+ );
+
+ NewRevision = GetCpuUcodeRevision ();
+
+#ifdef EFI_DEBUG
+ if (IsBsp ()) {
+ DEBUG ((DEBUG_INFO, "LoadMicrocode: After load, revision = 0x%x\n", NewRevision));
+ }
+#endif
+
+ //
+ // Verify that the microcode has been loaded
+ //
+ if (NewRevision == *Revision) {
+ return EFI_LOAD_ERROR;
+ }
+ *Revision = MicrocodeEntryPoint->UpdateRevision;
+
+ return Status;
+}
+
+
+/**
+ This will check if the microcode address is valid for this processor, and if so, it will
+ load it to the processor.
+
+ @param[in] ExchangeInfo Pointer to the exchange info buffer for output.
+ @param[in] MicrocodeAddress The address of the microcode update binary (in memory).
+ @param[out] FailedRevision The microcode revision that fails to be loaded.
+
+ @retval EFI_SUCCESS A new microcode update is loaded.
+ @retval Other Due to some reason, no new microcode update is loaded.
+
+**/
+EFI_STATUS
+InitializeMicrocode (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN CPU_MICROCODE_HEADER *MicrocodeAddress,
+ OUT UINT32 *FailedRevision
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPUID_REGISTER Cpuid;
+ UINT32 UcodeRevision;
+ ACPI_CPU_DATA *mAcpiCpuData;
+
+ Status = EFI_NOT_FOUND;
+
+ mAcpiCpuData = (ACPI_CPU_DATA *) (ExchangeInfo->AcpiCpuDataAddress);
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &Cpuid.RegEax,
+ &Cpuid.RegEbx,
+ &Cpuid.RegEcx,
+ &Cpuid.RegEdx
+ );
+
+ WaitForPrimaryThreadMcuUpdate (ExchangeInfo);
+ UcodeRevision = GetCpuUcodeRevision ();
+
+ if (CheckMicrocode (Cpuid.RegEax, MicrocodeAddress, &UcodeRevision)) {
+ Status = LoadMicrocode (MicrocodeAddress, &UcodeRevision);
+ *FailedRevision = UcodeRevision;
+ }
+ InterlockedIncrement (&(ExchangeInfo->McuLoadCount));
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.c
new file mode 100644
index 0000000000..55e38c632b
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.c
@@ -0,0 +1,1756 @@
+/** @file
+ PEIM to initialize multi-processor.
+
+ 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 <Private/Library/CpuCommonLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Library/HobLib.h>
+#include <Library/TimerLib.h>
+#include "MpService.h"
+#include <Ppi/CpuPolicy.h>
+#include <Private/CpuInitDataHob.h>
+#include <Features.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/MtrrLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED MP_CPU_RUNTIME_DATA *mMpCpuRuntimeData = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED MP_SYSTEM_DATA *mMpSystemData = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CPU_POLICY_PPI *mSiCpuPolicyPpi = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED CPU_CONFIG *mCpuConfig = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED CPU_CONFIG_PREMEM *mCpuConfigPreMem = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED POWER_MGMT_CONFIG *mPowerMgmtConfig = NULL;
+
+
+/**
+ This function handles CPU MP service task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+STATIC
+EFI_STATUS
+CpuMpServiceAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+STATIC EFI_PEI_NOTIFY_DESCRIPTOR mCpuMpServiceNotifyDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ CpuMpServiceAtEndOfPei
+};
+
+
+/**
+ Allocate a temporary memory under 1MB for MP Init to perform INIT-SIPI.
+ This buffer also provides memory for stack/data to run MP routine.
+
+ @param[in] WakeUpBuffer - Return buffer location
+
+ @retval EFI_SUCCESS if ok to get a memory under 1MB for MP running.
+**/
+EFI_STATUS
+AllocateWakeUpBuffer (
+ OUT EFI_PHYSICAL_ADDRESS *WakeUpBuffer
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ *WakeUpBuffer = 0x58000;
+
+ return Status;
+}
+
+
+/**
+ Prepare Wakeup Buffer and stack for APs.
+
+ @param[in] WakeUpBuffer Pointer to the address of wakeup buffer for output.
+ @param[in] StackAddressStart Pointer to the stack address of APs for output.
+ @param[in] MaximumCPUsForThisSystem Maximum CPUs in this system.
+
+ @retval EFI_SUCCESS Memory successfully prepared for APs.
+ @retval Other Error occurred while allocating memory.
+
+**/
+EFI_STATUS
+PrepareMemoryForAPs (
+ OUT EFI_PHYSICAL_ADDRESS *WakeUpBuffer,
+ OUT VOID **StackAddressStart,
+ IN UINTN MaximumCPUsForThisSystem
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Release All APs with a lock and wait for them to retire to rendezvous procedure.
+ // We need a page (4KB) of memory for IA-32 to use broadcast APIs, on a temporary basis.
+ //
+ Status = AllocateWakeUpBuffer (WakeUpBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Claim memory for AP stack
+ //
+ *StackAddressStart = AllocateRuntimePool (MaximumCPUsForThisSystem * STACK_SIZE_PER_PROC);
+
+ if (*StackAddressStart == NULL) {
+ FreePool (WakeUpBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Prepare GDTR and IDTR for AP
+
+ @param[in] Gdtr The GDTR profile
+ @param[in] Idtr The IDTR profile
+
+ @retval EFI_STATUS Status returned by each sub-routine
+ @retval EFI_SUCCESS GDTR and IDTR has been prepared for AP
+
+**/
+EFI_STATUS
+PrepareGdtIdtForAP (
+ OUT IA32_DESCRIPTOR *Gdtr,
+ OUT IA32_DESCRIPTOR *Idtr
+ )
+{
+ INTERRUPT_GATE_DESCRIPTOR *IdtForAP;
+ SEGMENT_DESCRIPTOR *GdtForAP;
+ IA32_DESCRIPTOR IdtrForBSP;
+ IA32_DESCRIPTOR GdtrForBSP;
+ UINT16 *MceHandler;
+
+ //
+ // Get Global Descriptor Table Register(GDTR) descriptor
+ //
+ AsmReadGdtr (&GdtrForBSP);
+
+ //
+ // Get Interrupt Descriptor Table Register(IDTR) descriptor
+ //
+ AsmReadIdtr (&IdtrForBSP);
+
+ //
+ // Allocate reserved memory for IDT
+ //
+ IdtForAP = (INTERRUPT_GATE_DESCRIPTOR *) AllocateAlignedRuntimePages (EFI_SIZE_TO_PAGES (IdtrForBSP.Limit + 1), sizeof (INTERRUPT_GATE_DESCRIPTOR));
+ if (IdtForAP == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Allocate reserved memory for GDT
+ //
+ GdtForAP = (SEGMENT_DESCRIPTOR *) AllocateAlignedRuntimePages (EFI_SIZE_TO_PAGES (GdtrForBSP.Limit + 1), sizeof (SEGMENT_DESCRIPTOR));
+ if (GdtForAP == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MceHandler = AllocateRuntimePool (SIZE_OF_MCE_HANDLER);
+ if (MceHandler == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // MceHandler content: iret (opcode = 0xcf)
+ //
+ *MceHandler = 0xCF48;
+
+ CopyMem (GdtForAP, (VOID *) GdtrForBSP.Base, GdtrForBSP.Limit + 1);
+ CopyMem (IdtForAP, (VOID *) IdtrForBSP.Base, IdtrForBSP.Limit + 1);
+
+ IdtForAP[INTERRUPT_HANDLER_MACHINE_CHECK].Offset15To0 = (UINT16) (UINTN) MceHandler;
+ IdtForAP[INTERRUPT_HANDLER_MACHINE_CHECK].Offset31To16 = (UINT16) ((UINTN) MceHandler >> 16);
+
+ //
+ // Create Gdtr, IDTR profile
+ //
+ Gdtr->Base = (UINTN) GdtForAP;
+ Gdtr->Limit = GdtrForBSP.Limit;
+
+ Idtr->Base = (UINTN) IdtForAP;
+ Idtr->Limit = IdtrForBSP.Limit;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize CPU Data Hob
+
+ @retval EFI_SUCCESS The driver installes/initialized correctly.
+ @retval EFI_OUT_OF_RESOURCES Allocation of the hob failed.
+
+**/
+EFI_STATUS
+InitializeCpuDataHob (
+ VOID
+ )
+{
+ CPU_INIT_DATA_HOB *CpuInitDataHob;
+ CPU_CONFIG *CpuConfig;
+ POWER_MGMT_CONFIG *PowerMgmtConfig;
+ VOID *Hob;
+
+ PostCode (0xC3B);
+
+ //
+ // Initial cpu data into one hob, it will be used by MP CPU DXE.
+ //
+ CpuInitDataHob = AllocateRuntimeZeroPool (sizeof (CPU_INIT_DATA_HOB));
+ if (CpuInitDataHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CpuConfig = &mMpCpuRuntimeData->CpuConfig;
+ PowerMgmtConfig = &mMpCpuRuntimeData->PowerMgmtConfig;
+
+ CopyMem (
+ (VOID *) (UINTN) PowerMgmtConfig,
+ (VOID *) (UINTN) mPowerMgmtConfig,
+ sizeof (POWER_MGMT_CONFIG)
+ );
+ CopyMem (
+ (VOID *) (UINTN) CpuConfig,
+ (VOID *) (UINTN) mCpuConfig,
+ sizeof (CPU_CONFIG)
+ );
+
+ CpuInitDataHob->CpuConfig = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->CpuConfig;
+ CpuInitDataHob->PowerMgmtConfig = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->PowerMgmtConfig;
+
+ CpuInitDataHob->MpData = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->AcpiCpuData;
+ CpuInitDataHob->FvidTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->FvidTable;
+
+ Hob = BuildGuidDataHob (
+ &gCpuInitDataHobGuid,
+ (VOID *) CpuInitDataHob,
+ (UINTN) sizeof (CPU_INIT_DATA_HOB)
+ );
+ ASSERT (Hob != NULL);
+
+ PostCode (0xC3E);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize multi-processor service.
+
+**/
+EFI_STATUS
+InitializeMpServices (
+ IN SI_CPU_POLICY_PPI *SiCpuPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_BOOT_MODE BootMode;
+ UINT64 *MtrrValues;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ VOID *StackAddressStart;
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MTRR_SETTINGS MtrrSetting;
+ UINT16 MaxEnabledThreadsPerCore;
+ UINT16 MaxEnabledCoresPerDie;
+ UINT16 MaxDiesPerPackage;
+ UINT16 MaxPackages;
+ UINTN MaximumCPUsForThisSystem;
+ UINT32 ResponseProcessorCount;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ DEBUG ((DEBUG_INFO, "InitializeMpServices: BootMode = %X\n", BootMode));
+ if ((Status == EFI_SUCCESS) && (BootMode == BOOT_ON_S3_RESUME)) {
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((DEBUG_INFO, "Set Cpu MP Service Environment entry point\n"));
+ PostCode (0xC20);
+
+ //
+ // Allocate MP data structure memory.
+ //
+ mMpCpuRuntimeData = (MP_CPU_RUNTIME_DATA *) AllocateRuntimeZeroPool (sizeof (MP_CPU_RUNTIME_DATA));
+ if (mMpCpuRuntimeData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize ACPI_CPU_DATA data
+ //
+ mMpCpuRuntimeData->AcpiCpuData.GdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->GdtrProfile;
+ mMpCpuRuntimeData->AcpiCpuData.IdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &mMpCpuRuntimeData->IdtrProfile;
+ mMpCpuRuntimeData->AcpiCpuData.S3BootPath = FALSE;
+
+ mSiCpuPolicyPpi = SiCpuPolicyPpi;
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gCpuConfigGuid , (VOID *)&mCpuConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((CONFIG_BLOCK_TABLE_HEADER *) SiCpuPolicyPpi, &gPowerMgmtConfigGuid , (VOID *)&mPowerMgmtConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Save the MTRR registers to global variables
+ //
+ MtrrValues = mMpCpuRuntimeData->MtrrValues;
+ ReadMtrrRegisters (MtrrValues);
+
+ //
+ // Get information on enabled threads, cores, dies and package for the CPU(s) on this platform
+ //
+ GetEnabledCount (
+ &MaxEnabledThreadsPerCore,
+ &MaxEnabledCoresPerDie,
+ &MaxDiesPerPackage,
+ &MaxPackages
+ );
+
+ //
+ // Get the total CPU count
+ //
+ MaximumCPUsForThisSystem = MaxEnabledThreadsPerCore * MaxEnabledCoresPerDie * MaxDiesPerPackage * MaxPackages;
+
+ //
+ // Prepare Wakeup Buffer and Stack for APs
+ //
+ Status = PrepareMemoryForAPs (
+ &WakeUpBuffer,
+ &StackAddressStart,
+ MaximumCPUsForThisSystem
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, "Specify memory cacheable type as Write Back Start\n"));
+
+ //
+ // Set specify memory cacheable type as Write Back
+ //
+ Status = MtrrSetMemoryAttributeInMtrrSettings (
+ &MtrrSetting,
+ 0x50000,
+ 0x10000,
+ CacheWriteBack
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Fill MP Data
+ //
+ Status = FillMpData (
+ (UINTN) WakeUpBuffer,
+ StackAddressStart,
+ MaximumCPUsForThisSystem
+ );
+
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+
+ //
+ // Wake up all APs at the first time
+ //
+ WakeUpAPs (MtrrValues, (EFI_AP_PROCEDURE) InitialMpProcedure);
+
+ //
+ // Program XApic register
+ //
+ ProgramXApic (TRUE);
+
+ //
+ // Wait for all APs to complete
+ //
+ while (ExchangeInfo->FinishedCount < mMpCpuRuntimeData->AcpiCpuData.NumberOfCpus - 1) {
+ CpuPause ();
+ }
+
+ //
+ // Collect all APs BIST status
+ //
+ for (Index = 1, ResponseProcessorCount = 1; Index < MAXIMUM_CPU_NUMBER; Index++) {
+ if (ExchangeInfo->BistBuffer[Index].Number == 1) {
+ ExchangeInfo->BistBuffer[Index].Number = ResponseProcessorCount++;
+ }
+ }
+
+ //
+ // Switch BSP to Lowest Feature Processor (LFP)
+ //
+ Status = SwitchToLowestFeatureProcess ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Register notification for CPU MP service task at the End of PEI
+ //
+ Status = PeiServicesNotifyPpi (&mCpuMpServiceNotifyDesc);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, "Cpu MP Service End\n"));
+ PostCode (0xC9F);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get general MP information
+
+ @param[in] NumberOfCpus Number of processors
+ @param[in] MaximumNumberOfCpus Max supported number of processors
+ @param[in] NumberOfEnabledCpus Number of processors enabled
+ @param[in] RendezvousIntNumber Number of Rendezvous procedure
+ @param[in] RendezvousProcLength Length of Rendezvous procedure
+
+ @retval EFI_SUCCESS Always return success
+
+**/
+EFI_STATUS
+EFIAPI
+GetGeneralMpInfo (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaximumNumberOfCpus,
+ OUT UINTN *NumberOfEnabledCpus,
+ OUT UINTN *RendezvousIntNumber,
+ OUT UINTN *RendezvousProcLength
+ )
+{
+ UINTN Index;
+ CPU_DATA_BLOCK *CpuData;
+
+ if (NumberOfCpus) {
+ *NumberOfCpus = mMpSystemData->NumberOfCpus;
+ }
+
+ if (MaximumNumberOfCpus) {
+ *MaximumNumberOfCpus = mMpSystemData->MaximumCpusForThisSystem;
+ }
+
+ if (RendezvousProcLength) {
+ *RendezvousProcLength = RENDEZVOUS_PROC_LENGTH;
+ }
+
+ if (RendezvousIntNumber) {
+ *RendezvousIntNumber = 0;
+ }
+
+ if (NumberOfEnabledCpus) {
+ *NumberOfEnabledCpus = mMpSystemData->NumberOfCpus;
+ for (Index = 0; Index < mMpSystemData->NumberOfCpus; Index++) {
+ CpuData = &mMpSystemData->CpuData[Index];
+ if (mMpSystemData->EnableSecondaryCpu) {
+ if (CpuData->State != CPU_STATE_DISABLED) {
+ (*NumberOfEnabledCpus)++;
+ }
+ } else {
+ if (CpuData->State != CPU_STATE_DISABLED && !mMpSystemData->CpuData[Index].SecondaryCpu) {
+ (*NumberOfEnabledCpus)++;
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get processor context
+
+ @param[in] CpuNumber Cpu number
+ @param[in] BufferLength Buffer length
+ @param[in] ProcessorContextBuffer Pointer to the buffer that will be updated
+
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or CpuNumber our of range
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small
+ @retval EFI_SUCCESS Got processor context successfully
+
+**/
+EFI_STATUS
+EFIAPI
+GetProcessorContext (
+ IN UINTN CpuNumber,
+ IN OUT UINTN *BufferLength,
+ IN OUT EFI_MP_PROC_CONTEXT *ProcessorContextBuffer
+ )
+{
+ EFI_MP_PROC_CONTEXT *ProcessorBuffer;
+ CPU_DATA_BLOCK *CpuData;
+
+ if (BufferLength == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*BufferLength < sizeof (EFI_MP_PROC_CONTEXT)) {
+ *BufferLength = sizeof (EFI_MP_PROC_CONTEXT);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if ((mMpSystemData->NumberOfCpus <= CpuNumber) || (ProcessorContextBuffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpuData = &mMpSystemData->CpuData[CpuNumber];
+
+ *BufferLength = sizeof (EFI_MP_PROC_CONTEXT);
+ ProcessorBuffer = ProcessorContextBuffer;
+
+ ProcessorBuffer->ApicID = CpuData->ApicID;
+
+ ProcessorBuffer->Enabled = TRUE;
+ if (!mMpSystemData->EnableSecondaryCpu) {
+ if (CpuData->SecondaryCpu) {
+ ProcessorBuffer->Enabled = FALSE;
+ }
+ }
+
+ if (CpuData->State == CPU_STATE_DISABLED) {
+ ProcessorBuffer->Enabled = FALSE;
+ }
+
+ if (CpuNumber == mMpSystemData->BSP) {
+ ProcessorBuffer->Designation = EfiCpuBSP;
+ } else {
+ ProcessorBuffer->Designation = EfiCpuAP;
+ }
+
+ ProcessorBuffer->Health.Flags = CpuData->Health;
+ ProcessorBuffer->Health.TestStatus = 0;
+
+ ProcessorBuffer->PackageNumber = CpuData->PhysicalLocation.Package;
+ ProcessorBuffer->NumberOfCores = CpuData->PhysicalLocation.Core;
+ ProcessorBuffer->NumberOfThreads = CpuData->PhysicalLocation.Thread;
+
+ ProcessorBuffer->ProcessorTestMask = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ MP Service to get specified application processor (AP)
+ to execute a caller-provided code stream.
+
+ @param[in] Function The procedure to be assigned to AP.
+ @param[in] CpuNumber Number of the specified processor.
+ @param[in] ProcArguments Argument for Procedure.
+
+ @retval EFI_INVALID_PARAMETER Procudure is NULL.
+ @retval EFI_INVALID_PARAMETER Number of CPU out of range, or it belongs to BSP.
+ @retval EFI_INVALID_PARAMETER Specified CPU is not idle.
+ @retval EFI_SUCCESS The AP has finished.
+ @retval EFI_TIMEOUT Time goes out before the AP has finished.
+
+**/
+EFI_STATUS
+EFIAPI
+StartupThisAP (
+ IN EFI_AP_PROCEDURE Function,
+ IN UINTN CpuNumber,
+ IN OUT VOID *ProcArguments OPTIONAL
+ )
+{
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINT64 *MtrrValues;
+
+ WakeUpBuffer = mMpCpuRuntimeData->AcpiCpuData.WakeUpBuffer;
+ MtrrValues = mMpCpuRuntimeData->MtrrValues;
+ ReadMtrrRegisters (MtrrValues);
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->ApFunction = (UINT32) Function;
+ ExchangeInfo->ApArgument = (UINT32) ProcArguments;
+ ExchangeInfo->MtrrValuesAddress = (UINT32) MtrrValues;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+ ExchangeInfo->SerializeLock = (UINT32) 0;
+ ExchangeInfo->StartState = (UINT32) 0;
+ ExchangeInfo->StackStart = (UINTN) ((ACPI_CPU_DATA *) (ExchangeInfo->AcpiCpuDataAddress))->StackAddress;
+
+ //
+ // Send INIT IPI - SIPI to the AP
+ //
+ SendInterrupt (
+ BROADCAST_MODE_SPECIFY_CPU,
+ CpuNumber,
+ 0,
+ DELIVERY_MODE_INIT,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ SendInterrupt (
+ BROADCAST_MODE_SPECIFY_CPU,
+ CpuNumber,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ //
+ // Wait for the AP to complete
+ //
+ while (ExchangeInfo->FinishedCount != 1) {
+ CpuPause ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Wake up all the application processors
+
+ @param[in] Function The procedure to be assigned to AP.
+ @param[in] ProcArguments Argument for Procedure.
+
+ @retval EFI_SUCCESS APs are successfully waked up
+
+**/
+EFI_STATUS
+StartupAllAps (
+ IN EFI_AP_PROCEDURE Function,
+ IN OUT VOID *ProcArguments OPTIONAL
+ )
+{
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINT64 *MtrrValues;
+ UINTN NumberOfCpus;
+
+ WakeUpBuffer = mMpCpuRuntimeData->AcpiCpuData.WakeUpBuffer;
+ MtrrValues = mMpCpuRuntimeData->MtrrValues;
+ ReadMtrrRegisters (MtrrValues);
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->ApFunction = (UINT32) Function;
+ ExchangeInfo->ApArgument = (UINT32) ProcArguments;
+ ExchangeInfo->MtrrValuesAddress = (UINT32) MtrrValues;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+ ExchangeInfo->SerializeLock = (UINT32) 0;
+ ExchangeInfo->StackStart = (UINTN) ((ACPI_CPU_DATA *) (ExchangeInfo->AcpiCpuDataAddress))->StackAddress;
+ NumberOfCpus = ((ACPI_CPU_DATA *) (ExchangeInfo->AcpiCpuDataAddress))->NumberOfCpus;
+
+ //
+ // Send INIT IPI - SIPI to all APs
+ //
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ 0,
+ DELIVERY_MODE_INIT,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+ MicroSecondDelay (10 * STALL_ONE_MILLI_SECOND); ///< 10ms
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+ MicroSecondDelay (200 * STALL_ONE_MICRO_SECOND); ///< 200us
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ //
+ // Wait for all APs to complete
+ //
+ DEBUG ((DEBUG_INFO, "FinishedCount = %x, NumberOfCpus = %x\n", ExchangeInfo->FinishedCount, NumberOfCpus));
+ while (ExchangeInfo->FinishedCount < NumberOfCpus - 1) {
+ CpuPause ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ MP Service to makes the current BSP into an AP and then switches the
+ designated AP into the AP. This procedure is usually called after a CPU
+ test that has found that BSP is not healthy to continue it's responsbilities.
+
+ @param[in] CpuNumber The number of the specified AP.
+ @param[in] EnableOldBsp Whether to enable or disable the original BSP.
+
+ @retval EFI_INVALID_PARAMETER Number for Specified AP out of range.
+ @retval EFI_INVALID_PARAMETER Number of specified CPU belongs to BSP.
+ @retval EFI_NOT_READY Specified AP is not idle.
+ @retval EFI_SUCCESS BSP successfully switched.
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchBsp (
+ IN UINTN CpuNumber,
+ IN BOOLEAN EnableOldBsp
+ )
+{
+ EFI_STATUS Status;
+ CPU_DATA_BLOCK *CpuData;
+ CPU_STATE CpuState;
+ UINT64 *MtrrValues;
+
+ MtrrValues = mMpCpuRuntimeData->MtrrValues;
+ ReadMtrrRegisters (MtrrValues);
+
+ //
+ // Check if the specified CPU number is valid
+ //
+ if (CpuNumber >= mMpSystemData->NumberOfCpus) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check if the specified CPU is already BSP
+ //
+ if (CpuNumber == mMpSystemData->BSP) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpuData = &mMpSystemData->CpuData[CpuNumber];
+ if (CpuData->State != CPU_STATE_IDLE) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Before send both BSP and AP to a procedure to exchange their roles,
+ // interrupt must be disabled. This is because during the exchange role
+ // process, 2 CPU may use 1 stack. If interrupt happens, the stack will
+ // be corrputed, since interrupt return address will be pushed to stack
+ // by hardware.
+ //
+ DisableInterrupts ();
+
+ //
+ // Unprogram virtual wire mode for the old BSP
+ //
+ ProgramXApic (FALSE);
+ SetApicBspBit (FALSE);
+
+ mMpSystemData->BspInfo.State = CPU_SWITCH_STATE_IDLE;
+ mMpSystemData->BspInfo.Lock = VacantFlag;
+ mMpSystemData->ApInfo.State = CPU_SWITCH_STATE_IDLE;
+ mMpSystemData->ApInfo.Lock = VacantFlag;
+
+ //
+ // Need to wakeUp AP (future BSP)
+ //
+ WakeUpAPs (MtrrValues, (EFI_AP_PROCEDURE) FutureBspProc);
+
+ AsmExchangeRole (&mMpSystemData->BspInfo, &mMpSystemData->ApInfo);
+
+ //
+ // The new BSP has come out. Since it carries the register value of the AP, need
+ // to pay attention to variable which are stored in registers (due to optimization)
+ //
+ SetApicBspBit (TRUE);
+ ProgramXApic (TRUE);
+
+ EnableInterrupts ();
+
+ CpuData = &mMpSystemData->CpuData[mMpSystemData->BSP];
+ while (TRUE) {
+ AsmAcquireMPLock (&CpuData->StateLock);
+ CpuState = CpuData->State;
+ AsmReleaseMPLock (&CpuData->StateLock);
+
+ if (CpuState == CPU_STATE_FINISHED) {
+ break;
+ }
+ }
+
+ Status = ChangeCpuState (mMpSystemData->BSP, EnableOldBsp, CPU_CAUSE_NOT_DISABLED);
+ mMpSystemData->BSP = CpuNumber;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This procedure enables Or disables APs.
+
+ @param[in] CpuNumber The number of the specified AP.
+ @param[in] NewApState Indicate new desired AP state
+ @param[in] HealthState If not NULL, it points to the value that specifies
+ the new health status of the AP. If it is NULL,
+ this parameter is ignored.
+
+ @retval EFI_INVALID_PARAMETER Input paramters were not correct.
+ @retval EFI_SUCCESS Function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDisableAp (
+ IN UINTN CpuNumber,
+ IN BOOLEAN NewApState,
+ IN EFI_MP_HEALTH *HealthState OPTIONAL
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+
+ //
+ // Check for valid input parameters.
+ //
+ if (CpuNumber >= mMpSystemData->NumberOfCpus || CpuNumber == mMpSystemData->BSP) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpuData = &mMpSystemData->CpuData[CpuNumber];
+
+ if (HealthState != NULL) {
+ CopyMem (&CpuData->Health, HealthState, sizeof (EFI_MP_HEALTH));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This procedure returns the calling CPU handle.
+
+ @dot
+ digraph G {
+ subgraph cluster_c0 {
+ node [shape = box];
+ b1[label="GetApicID ()" fontsize=12 style=filled color=lightblue];
+ b2[label="Index + 1" fontsize=12 style=filled color=lightblue];
+ b3[label="*CpuNumber = Index" fontsize=12 style=filled color=lightblue];
+
+ node [shape = ellipse];
+ e1[label="Start" fontsize=12 style=filled color=lightblue];
+ e2[label="End" fontsize=12 style=filled color=lightblue];
+
+ node [shape = diamond,style=filled,color=lightblue];
+ d1[label="Index < NumOfCpus" fontsize=12];
+ d2[label="Is ApicID equal to\n mMpSystemData->CpuData[Index].ApicID" fontsize=12];
+
+ label = "WhoAmI Flow"; fontsize=15; fontcolor=black; color=lightblue;
+ e1 -> b1
+ b1 -> d1
+ d1 -> d2 [label="Yes" fontsize=9]
+ d1 -> b3 [label="No" fontsize=9]
+ d2 -> b3 [label="Yes" fontsize=9]
+ d2 -> b2 [label="No" fontsize=9]
+ b2 -> d1
+ b3 -> e2
+
+ }
+ }
+ @enddot
+
+ @param[out] CpuNumber The number of the specified AP.
+
+ @retval EFI_SUCCESS Function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+WhoAmI (
+ OUT UINTN *CpuNumber
+ )
+{
+ UINTN ApicID;
+ UINTN NumOfCpus;
+ UINTN Index;
+
+ ApicID = GetCpuApicId ();
+ NumOfCpus = mMpSystemData->NumberOfCpus;
+
+ for (Index = 0; Index < NumOfCpus; Index++) {
+ if (ApicID == mMpSystemData->CpuData[Index].ApicID) {
+ break;
+ }
+ }
+ *CpuNumber = Index;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function handles CPU MP service task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+STATIC
+EFI_STATUS
+CpuMpServiceAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Send INIT IPI - to all APs
+ //
+ Status = SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ 0,
+ DELIVERY_MODE_INIT,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ return Status;
+}
+
+
+/**
+ AP initialization
+
+**/
+VOID
+InitialMpProcedure (
+ VOID
+ )
+{
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINT64 *MtrrValues;
+ EFI_CPUID_REGISTER CpuidRegisters;
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (mMpCpuRuntimeData->AcpiCpuData.WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+
+ //
+ // Init XMM
+ //
+ XmmInit ();
+
+ MtrrValues = (UINT64 *)ExchangeInfo->MtrrValuesAddress;
+ ProgramXApic (FALSE);
+
+ MpMtrrSynchUp (MtrrValues);
+}
+
+
+/**
+ Get CPU platform features settings to fill MP data.
+
+ @param[in] WakeUpBuffer The address of wakeup buffer.
+ @param[in] StackAddressStart The start address of APs's stacks.
+ @param[in] MaximumCPUsForThisSystem Maximum CPUs in this system.
+
+ @retval EFI_SUCCESS Function successfully executed.
+ @retval Other Error occurred while allocating memory.
+
+**/
+EFI_STATUS
+EFIAPI
+FillMpData (
+ IN UINTN WakeUpBuffer,
+ IN VOID *StackAddressStart,
+ IN UINTN MaximumCPUsForThisSystem
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN HyperThreadingEnabled;
+
+ mMpSystemData = &mMpCpuRuntimeData->MpSystemData;
+
+ //
+ // First check if the MP data structures and AP rendezvous routine have been
+ // supplied by the PEIMs that executed in early boot stage.
+ //
+ //
+ // Clear the data structure area first.
+ //
+ ZeroMem (mMpSystemData, sizeof (MP_SYSTEM_DATA));
+ HyperThreadingEnabled = FALSE;
+
+ mMpCpuRuntimeData->AcpiCpuData.CpuPrivateData = (EFI_PHYSICAL_ADDRESS) (UINTN) (&mMpSystemData->S3DataPointer);
+ mMpCpuRuntimeData->AcpiCpuData.WakeUpBuffer = WakeUpBuffer;
+ mMpCpuRuntimeData->AcpiCpuData.NumberOfCpus = MaximumCPUsForThisSystem;
+ mMpCpuRuntimeData->AcpiCpuData.APState = HyperThreadingEnabled;
+ mMpCpuRuntimeData->AcpiCpuData.StackAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) StackAddressStart;
+
+ Status = PrepareGdtIdtForAP (
+ (IA32_DESCRIPTOR *) (UINTN) mMpCpuRuntimeData->AcpiCpuData.GdtrProfile,
+ (IA32_DESCRIPTOR *) (UINTN) mMpCpuRuntimeData->AcpiCpuData.IdtrProfile
+ );
+
+ //
+ // First BSP fills and inits all known values, including it's own records.
+ //
+ mMpSystemData->ApSerializeLock = VacantFlag;
+ mMpSystemData->NumberOfCpus = MaximumCPUsForThisSystem;
+ mMpSystemData->EnableSecondaryCpu = HyperThreadingEnabled;
+
+ mMpSystemData->VmxEnable = (BOOLEAN) mCpuConfig->VmxEnable;
+ mMpSystemData->TxtEnable = (BOOLEAN) mCpuConfig->SmxEnable;
+ mMpSystemData->MonitorMwaitEnable = (BOOLEAN) mCpuConfig->MonitorMwaitEnable;
+ mMpSystemData->MachineCheckEnable = (BOOLEAN) mCpuConfig->MachineCheckEnable;
+ mMpSystemData->AesEnable = (BOOLEAN) mCpuConfig->AesEnable;
+ mMpSystemData->DebugInterfaceEnable = (BOOLEAN) mCpuConfig->DebugInterfaceEnable;
+ mMpSystemData->DebugInterfaceLockEnable = (BOOLEAN) mCpuConfig->DebugInterfaceLockEnable;
+
+ mMpSystemData->ProcTraceMemSize = mCpuConfig->ProcTraceMemSize;
+ mMpSystemData->ProcTraceEnable = (BOOLEAN) mCpuConfig->ProcTraceEnable;
+ mMpSystemData->ProcTraceOutputScheme = (UINT8) mCpuConfig->ProcTraceOutputScheme;
+ mMpSystemData->HyperThreadingEnable = (BOOLEAN) mCpuConfig->HyperThreading;
+
+ mMpSystemData->S3DataPointer.S3BootScriptTable = (UINT32) (UINTN) mMpSystemData->S3BootScriptTable;
+ mMpSystemData->S3DataPointer.S3BspMtrrTable = (UINT32) (UINTN) mMpSystemData->S3BspMtrrTable;
+
+ mMpSystemData->MaximumCpusForThisSystem = MaximumCPUsForThisSystem;
+
+ mMpSystemData->BSP = 0;
+
+ //
+ // Collect CPU_DATA_BLOCK for BSP. All APs call ones, too.
+ //
+ FillInProcessorInformation (TRUE, 0);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get CPU platform features settings to fill MP data.
+
+ @retval MP_SYSTEM_DATA* Return MpSystemData pointer.
+
+**/
+MP_SYSTEM_DATA *
+EFIAPI
+GetMpSystemData (
+ VOID
+ )
+{
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+
+ WakeUpBuffer = 0x58000;
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+
+ return (MP_SYSTEM_DATA *) (VOID *) ExchangeInfo->MpSystemDataAddress;
+}
+
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects MP related data.
+
+ @param[in] BSP TRUE if the CPU is BSP
+ @param[in] BistParam BIST (build-in self test) data for the processor. This data
+ is only valid for processors that are waked up for the 1ast
+ time in this CPU DXE driver.
+
+ @retval EFI_SUCCESS Data for the processor collected and filled in.
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN BSP,
+ IN UINT32 BistParam
+ )
+{
+ UINT32 Health;
+ UINT32 ApicID;
+ CPU_DATA_BLOCK *CpuData;
+ UINT32 BIST;
+ UINTN CpuNumber;
+ ACPI_CPU_DATA *AcpiCpuData;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+
+ AcpiCpuData = &mMpCpuRuntimeData->AcpiCpuData;
+ ApicID = GetCpuApicId ();
+ BIST = 0;
+
+ if (BSP) {
+ CpuNumber = 0;
+ BIST = BistParam;
+ } else {
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (AcpiCpuData->WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+ CpuNumber = ExchangeInfo->BistBuffer[ApicID].Number;
+ BIST = ExchangeInfo->BistBuffer[ApicID].BIST;
+ }
+
+ CpuData = &mMpSystemData->CpuData[CpuNumber];
+ CpuData->SecondaryCpu = IsSecondaryThread ();
+ CpuData->ApicID = ApicID;
+ CpuData->Procedure = NULL;
+ CpuData->Parameter = NULL;
+ CpuData->StateLock = VacantFlag;
+ CpuData->ProcedureLock = VacantFlag;
+ CpuData->State = CPU_STATE_IDLE;
+
+ Health = BIST;
+ if (Health > 0) {
+ CpuData->State = CPU_STATE_DISABLED;
+ mMpSystemData->DisableCause[CpuNumber] = CPU_CAUSE_SELFTEST_FAILURE;
+ } else {
+ mMpSystemData->DisableCause[CpuNumber] = CPU_CAUSE_NOT_DISABLED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Wake up all the application processors
+
+ @param[in] MtrrValues Pointer to a buffer which stored MTRR settings
+ @param[in] Function Pointer to AP Procedure Function
+
+ @retval EFI_SUCCESS APs are successfully waked up
+
+**/
+EFI_STATUS
+WakeUpAPs (
+ UINT64 *MtrrValues,
+ EFI_AP_PROCEDURE Function
+ )
+{
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ MP_CPU_S3_DATA_POINTER *CpuS3DataPtr;
+ ACPI_CPU_DATA *AcpiCpuData;
+
+ AcpiCpuData = &mMpCpuRuntimeData->AcpiCpuData;
+ WakeUpBuffer = AcpiCpuData->WakeUpBuffer;
+ CopyMem (
+ (VOID *) (UINTN) WakeUpBuffer,
+ AsmGetAddressMap (),
+ MP_CPU_EXCHANGE_INFO_OFFSET
+ );
+ AsmPatchRendezvousCode ((VOID *) (UINTN) WakeUpBuffer);
+
+ ExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeUpBuffer + MP_CPU_EXCHANGE_INFO_OFFSET);
+
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->StackStart = (UINTN) AcpiCpuData->StackAddress;
+ ExchangeInfo->StackSize = STACK_SIZE_PER_PROC;
+ ExchangeInfo->ApFunction = (UINT32) Function;
+ ExchangeInfo->ApArgument = 0;
+ ExchangeInfo->BufferStart = (UINT32) WakeUpBuffer;
+ ExchangeInfo->PmodeOffset = (UINT32) (AsmGetPmodeOffset ());
+ ExchangeInfo->SemaphoreCheck = (VOID (*)(UINT32 *)) (AsmGetSemaphoreCheckOffset () + (UINT32) WakeUpBuffer);
+ ExchangeInfo->AcpiCpuDataAddress = (UINT32) AcpiCpuData;
+ ExchangeInfo->MtrrValuesAddress = (UINT32) MtrrValues;
+ ExchangeInfo->FinishedCount = (UINT32) 0;
+ ExchangeInfo->SerializeLock = (UINT32) 0;
+ ExchangeInfo->StartState = (UINT32) 0;
+
+ CpuS3DataPtr = (MP_CPU_S3_DATA_POINTER *) (UINTN) AcpiCpuData->CpuPrivateData;
+ ExchangeInfo->S3BootScriptTable = (MP_CPU_S3_SCRIPT_DATA *) (UINTN) CpuS3DataPtr->S3BootScriptTable;
+ ExchangeInfo->VirtualWireMode = CpuS3DataPtr->VirtualWireMode;
+ ExchangeInfo->CpuPerfCtrlValue = AsmReadMsr64 (MSR_IA32_PERF_CTRL);
+ ExchangeInfo->McuLoadCount = 0;
+ ExchangeInfo->MpSystemDataAddress = (UINT32) &mMpCpuRuntimeData->MpSystemData;
+ ExchangeInfo->MpServicePpiAddress = 0;
+ ExchangeInfo->SiCpuPolicyPpi = mSiCpuPolicyPpi;
+
+ CopyMem (
+ (VOID *) (UINTN) &ExchangeInfo->GdtrProfile,
+ (VOID *) (UINTN) AcpiCpuData->GdtrProfile,
+ sizeof (IA32_DESCRIPTOR)
+ );
+ CopyMem (
+ (VOID *) (UINTN) &ExchangeInfo->IdtrProfile,
+ (VOID *) (UINTN) AcpiCpuData->IdtrProfile,
+ sizeof (IA32_DESCRIPTOR)
+ );
+
+ //
+ // Don't touch MPCPU private data
+ // Here we use ExchangeInfo instead
+ //
+ //
+ // Send INIT IPI - SIPI to all APs
+ //
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ 0,
+ DELIVERY_MODE_INIT,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (10 * STALL_ONE_MILLI_SECOND); //< 10ms
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (200 * STALL_ONE_MICRO_SECOND); //< 200us
+
+ SendInterrupt (
+ BROADCAST_MODE_ALL_EXCLUDING_SELF,
+ 0,
+ (UINT32) RShiftU64 (WakeUpBuffer, 12),
+ DELIVERY_MODE_SIPI,
+ TRIGGER_MODE_EDGE,
+ TRUE
+ );
+
+ MicroSecondDelay (200 * STALL_ONE_MICRO_SECOND); //< 200us
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Send interrupt to CPU
+
+ @param[in] BroadcastMode Interrupt broadcast mode
+ @param[in] ApicID APIC ID for sending interrupt
+ @param[in] VectorNumber Vector number
+ @param[in] DeliveryMode Interrupt delivery mode
+ @param[in] TriggerMode Interrupt trigger mode
+ @param[in] Assert Interrupt pin polarity
+
+ @retval EFI_INVALID_PARAMETER Input parameter not correct
+ @retval EFI_NOT_READY There was a pending interrupt
+ @retval EFI_SUCCESS Interrupt sent successfully
+
+**/
+EFI_STATUS
+SendInterrupt (
+ IN UINT32 BroadcastMode,
+ IN UINT32 ApicID,
+ IN UINT32 VectorNumber,
+ IN UINT32 DeliveryMode,
+ IN UINT32 TriggerMode,
+ IN BOOLEAN Assert
+ )
+{
+ UINT64 ApicBaseReg;
+ EFI_PHYSICAL_ADDRESS ApicBase;
+ UINT32 IcrLow;
+ UINT32 IcrHigh;
+
+ //
+ // Initialze ICR high dword, since P6 family processor needs
+ // the destination field to be 0x0F when it is a broadcast
+ //
+ IcrHigh = 0x0f000000;
+ IcrLow = VectorNumber | (DeliveryMode << 8);
+
+ if (TriggerMode == TRIGGER_MODE_LEVEL) {
+ IcrLow |= 0x8000;
+ }
+
+ if (Assert) {
+ IcrLow |= 0x4000;
+ }
+
+ switch (BroadcastMode) {
+ case BROADCAST_MODE_SPECIFY_CPU:
+ IcrHigh = ApicID << 24;
+ break;
+
+ case BROADCAST_MODE_ALL_INCLUDING_SELF:
+ IcrLow |= 0x80000;
+ break;
+
+ case BROADCAST_MODE_ALL_EXCLUDING_SELF:
+ IcrLow |= 0xC0000;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ApicBaseReg = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBase = ApicBaseReg & 0xffffff000ULL;
+
+ *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_HIGH_OFFSET) = IcrHigh;
+ *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET) = IcrLow;
+
+ MicroSecondDelay (10 * STALL_ONE_MICRO_SECOND);
+
+ IcrLow = *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET);
+ if (IcrLow & 0x1000) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Switch BSP to the processor which has least features
+
+ @retval EFI_STATUS Status code returned from each sub-routines
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchToLowestFeatureProcess (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CurrentProcessor;
+
+ Status = WhoAmI (&CurrentProcessor);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ReportStatusCode (
+ EFI_PROGRESS_CODE,
+ EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT
+ );
+
+ //
+ // Take current BSP as the least feature
+ //
+ UpdateProcessorInfo (CurrentProcessor, &mMpSystemData->LeastFeatureProcessor);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get processor feature
+
+ @param[in] Features Pointer to a buffer which stores feature information
+
+**/
+VOID
+EFIAPI
+GetProcessorFeatures (
+ IN UINT32 *Features
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegisters;
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ Features[0] = CpuidRegisters.RegEcx;
+ Features[1] = CpuidRegisters.RegEdx;
+ AsmCpuid (
+ CPUID_EXTENDED_CPU_SIG,
+ &CpuidRegisters.RegEax,
+ &CpuidRegisters.RegEbx,
+ &CpuidRegisters.RegEcx,
+ &CpuidRegisters.RegEdx
+ );
+ Features[2] = CpuidRegisters.RegEax;
+ Features[3] = CpuidRegisters.RegEbx;
+ Features[4] = CpuidRegisters.RegEcx;
+ Features[5] = CpuidRegisters.RegEdx;
+
+ return;
+}
+
+
+/**
+ Find out the common features supported by all core/threads
+
+**/
+VOID
+EFIAPI
+GetProcessorCommonFeature (
+ VOID
+ )
+{
+ UINTN Index;
+ UINT32 Features[MAX_FEATURE_NUM];
+
+ GetProcessorFeatures (Features);
+ AsmAcquireMPLock (&mMpSystemData->Lock);
+
+ for (Index = 0; Index < MAX_FEATURE_NUM; Index++) {
+ mMpSystemData->LeastFeatureProcessor.Features[Index] &= Features[Index];
+ }
+ AsmReleaseMPLock (&mMpSystemData->Lock);
+}
+
+
+/**
+ Get the processor data with least features
+
+**/
+VOID
+EFIAPI
+GetProcessorWithLeastFeature (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CurrentProcessor;
+ LEAST_FEATURE_PROC LeastFeatureProcessor;
+
+ Status = WhoAmI (&CurrentProcessor);
+ ASSERT_EFI_ERROR (Status);
+
+ GetProcessorFeatures (mMpSystemData->LeastFeatureProcessor.Features);
+ LeastFeatureProcessor.FeatureDelta = GetProcessorFeatureDelta (
+ LeastFeatureProcessor.Features,
+ mMpSystemData->LeastFeatureProcessor.Features
+ );
+
+ AsmAcquireMPLock (&mMpSystemData->Lock);
+ if (LeastFeatureProcessor.FeatureDelta < mMpSystemData->LeastFeatureProcessor.FeatureDelta) {
+ mMpSystemData->LeastFeatureProcessor.FeatureDelta = LeastFeatureProcessor.FeatureDelta;
+ UpdateProcessorInfo (CurrentProcessor, &mMpSystemData->LeastFeatureProcessor);
+ } else if (LeastFeatureProcessor.FeatureDelta == mMpSystemData->LeastFeatureProcessor.FeatureDelta) {
+ UpdateProcessorInfo (CurrentProcessor, &LeastFeatureProcessor);
+ if (LeastFeatureProcessor.Version < mMpSystemData->LeastFeatureProcessor.Version) {
+ UpdateProcessorInfo (CurrentProcessor, &mMpSystemData->LeastFeatureProcessor);
+ } else if (LeastFeatureProcessor.Version == mMpSystemData->LeastFeatureProcessor.Version) {
+ if (LeastFeatureProcessor.ApicId < mMpSystemData->LeastFeatureProcessor.ApicId) {
+ UpdateProcessorInfo (CurrentProcessor, &mMpSystemData->LeastFeatureProcessor);
+ }
+ }
+ }
+
+ AsmReleaseMPLock (&mMpSystemData->Lock);
+}
+
+
+/**
+ Extract CPU detail version infomation
+
+ @param[in] FamilyId FamilyId, including ExtendedFamilyId
+ @param[in] Model Model, including ExtendedModel
+ @param[in] SteppingId SteppingId
+ @param[in] 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;
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &Register.RegEax,
+ &Register.RegEbx,
+ &Register.RegEcx,
+ &Register.RegEdx
+ );
+
+ 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 |= (Register.RegEax >> 12) & 0xF0;
+ }
+ }
+
+ if (FamilyId != NULL) {
+ *FamilyId = TempFamilyId;
+ if (TempFamilyId == 0xF) {
+ *FamilyId = *FamilyId + (UINT16) ((Register.RegEax >> 20) & 0xFF);
+ }
+ }
+ }
+}
+
+
+/**
+ Update some processor info into LEAST_FEATURE_PROC data structure.
+
+ @param[in] Index Indicate which processor calling this routine
+ @param[in] LeastFeatureProcessor The data structure that will be updated
+
+**/
+VOID
+EFIAPI
+UpdateProcessorInfo (
+ IN UINTN Index,
+ IN LEAST_FEATURE_PROC *LeastFeatureProcessor
+ )
+{
+ UINT16 FamilyId;
+ UINT8 Model;
+ UINT8 SteppingId;
+
+ EfiCpuVersion (&FamilyId, &Model, &SteppingId, NULL);
+ LeastFeatureProcessor->Index = Index;
+ LeastFeatureProcessor->ApicId = GetCpuApicId ();
+ LeastFeatureProcessor->Version = EfiMakeCpuVersion (FamilyId, Model, SteppingId);
+}
+
+
+/**
+ Get processor feature delta
+
+ @param[in] FeaturesInput Supported features for input processor
+ @param[in] CommonFeatures Supported features for processor (subset of FeaturesInput)
+
+ @retval The least of processor features
+
+**/
+UINT32
+EFIAPI
+GetProcessorFeatureDelta (
+ IN UINT32 *FeaturesInput,
+ IN UINT32 *CommonFeatures
+ )
+{
+ UINT32 Delta;
+ UINTN Index;
+
+ //
+ // CommonFeatures is the subset of FeaturesInput
+ //
+ Delta = 0;
+ for (Index = 0; Index < MAX_FEATURE_NUM; Index++) {
+ Delta += GetBitsNumberOfOne (FeaturesInput[Index] - CommonFeatures[Index]);
+ }
+
+ return 0;
+}
+
+
+/**
+ Calculate how many bits are one from given number
+
+ @param[in] Value Number that will be calculated bits
+
+ @retval Number of bits
+
+**/
+UINT32
+EFIAPI
+GetBitsNumberOfOne (
+ IN UINT32 Value
+ )
+{
+ UINT32 Result;
+
+ Result = 0;
+ while (Value) {
+ if (Value & 1) {
+ Result++;
+ }
+ Value >>= 1;
+ }
+
+ return Result;
+}
+
+
+/**
+ Write 64bits MSR with script
+
+ @param[in] Index MSR index that will be written
+ @param[in] Value Value written to MSR
+
+**/
+VOID
+AsmWriteMsr64WithScript (
+ IN UINT32 Index,
+ IN UINT64 Value
+ )
+{
+ AsmWriteMsr64 (Index, Value);
+ WriteMsr64ToScript (Index, Value);
+}
+
+/**
+ Write 64bits MSR to script
+
+ @param[in] Index MSR index that will be written
+ @param[in] Value Value written to MSR
+
+**/
+VOID
+WriteMsr64ToScript (
+ IN UINT32 Index,
+ IN UINT64 Value
+ )
+{
+ UINTN TableIndex;
+ MP_SYSTEM_DATA *MpSystemData;
+
+ MpSystemData = GetMpSystemData ();
+ if (MpSystemData == NULL) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ //
+ // Save it into script
+ //
+ AsmAcquireMPLock (&MpSystemData->S3BootScriptLock);
+ TableIndex = MpSystemData->S3BootScriptCount++;
+ AsmReleaseMPLock (&MpSystemData->S3BootScriptLock);
+
+ ASSERT (TableIndex < MAX_CPU_S3_TABLE_SIZE - 1);
+ MpSystemData->S3BootScriptTable[TableIndex].ApicId = GetCpuApicId ();
+ MpSystemData->S3BootScriptTable[TableIndex].MsrIndex = Index;
+ MpSystemData->S3BootScriptTable[TableIndex].MsrValue = Value;
+}
+
+
+/**
+ Set APIC BSP bit
+
+ @param[in] Enable Enable as BSP or not
+
+ @retval EFI_SUCCESS Always return success
+
+**/
+EFI_STATUS
+SetApicBspBit (
+ IN BOOLEAN Enable
+ )
+{
+ UINT64 ApicBaseReg;
+
+ ApicBaseReg = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+
+ if (Enable) {
+ ApicBaseReg |= 0x100;
+ } else {
+ ApicBaseReg &= 0xfffffffffffffe00;
+ }
+
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseReg);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Switch current BSP processor to AP
+
+ @param[in] MPSystemData Pointer to the data structure containing MP related data
+
+**/
+VOID
+EFIAPI
+FutureBspProc (
+ VOID
+ )
+{
+ AsmExchangeRole (&mMpSystemData->ApInfo, &mMpSystemData->BspInfo);
+ return;
+}
+
+
+/**
+ Change CPU state
+
+ @param[in] CpuNumber CPU number
+ @param[in] NewState The new state that will be changed to
+ @param[in] Cause Cause
+
+ @retval EFI_SUCCESS Always return success
+
+**/
+EFI_STATUS
+ChangeCpuState (
+ IN UINTN CpuNumber,
+ IN BOOLEAN NewState,
+ IN CPU_STATE_CHANGE_CAUSE Cause
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+
+ CpuData = &mMpSystemData->CpuData[CpuNumber];
+
+ mMpSystemData->DisableCause[CpuNumber] = Cause;
+
+ if (!NewState) {
+ AsmAcquireMPLock (&CpuData->StateLock);
+ CpuData->State = CPU_STATE_DISABLED;
+ AsmReleaseMPLock (&CpuData->StateLock);
+
+ ReportStatusCode (
+ EFI_ERROR_MINOR | EFI_ERROR_CODE,
+ EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_DISABLED
+ );
+ } else {
+ AsmAcquireMPLock (&CpuData->StateLock);
+ CpuData->State = CPU_STATE_IDLE;
+ AsmReleaseMPLock (&CpuData->StateLock);
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.h
new file mode 100644
index 0000000000..16cd80e538
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.h
@@ -0,0 +1,211 @@
+/** @file
+ Some definitions for MP services Ppi.
+
+ 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 _MP_SERVICE_H_
+#define _MP_SERVICE_H_
+
+#include <Library/ReportStatusCodeLib.h>
+#include <Private/Library/MpServiceLib.h>
+
+///
+/// Combine f(FamilyId), m(Model), s(SteppingId) to a single 32 bit number
+///
+#define EfiMakeCpuVersion(f, m, s) (((UINT32) (f) << 16) | ((UINT32) (m) << 8) | ((UINT32) (s)))
+
+/**
+ Get CPU platform features settings to fill MP data.
+
+ @param[in] WakeUpBuffer The address of wakeup buffer.
+ @param[in] StackAddressStart The start address of APs's stacks.
+ @param[in] MaximumCPUsForThisSystem Maximum CPUs in this system.
+
+ @retval EFI_SUCCESS Function successfully executed.
+ @retval Other Error occurred while allocating memory.
+
+**/
+EFI_STATUS
+EFIAPI
+FillMpData (
+ IN UINTN WakeUpBuffer,
+ IN VOID *StackAddressStart,
+ IN UINTN MaximumCPUsForThisSystem
+ );
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects MP related data
+
+ @param[in] BSP TRUE if the CPU is BSP
+ @param[in] BistParam BIST (build-in self test) data for the processor. This data
+ is only valid for processors that are waked up for the 1st
+ time in this CPU DXE driver.
+
+ @retval EFI_SUCCESS Data for the processor collected and filled in
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN BSP,
+ IN UINT32 BistParam
+ );
+
+/**
+ Notification function that gets called once permanent memory installed to take care
+ of MP CPU related activities in PEI phase
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS Multiple processors are intialized successfully
+
+**/
+EFI_STATUS
+InitializeMpSupport (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ Re-load microcode patch.
+
+ @retval EFI_SUCCESS Multiple processors re-load microcode patch
+
+**/
+EFI_STATUS
+ReloadMicrocode (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo
+ );
+
+/**
+ Get processor feature
+
+ @param[in] Features Pointer to a buffer which stores feature information
+
+**/
+VOID
+EFIAPI
+GetProcessorFeatures (
+ IN UINT32 *Features
+ );
+
+/**
+ Switch BSP to the processor which has least features
+
+ @retval EFI_STATUS Status code returned from each sub-routines
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchToLowestFeatureProcess (
+ VOID
+ );
+
+/**
+ Find out the common features supported by all core/threads
+
+**/
+VOID
+EFIAPI
+GetProcessorCommonFeature (
+ VOID
+ );
+
+/**
+ Get the processor data with least features
+
+**/
+VOID
+EFIAPI
+GetProcessorWithLeastFeature (
+ VOID
+ );
+
+/**
+ Extract CPU detail version infomation
+
+ @param[in] FamilyId FamilyId, including ExtendedFamilyId
+ @param[in] Model Model, including ExtendedModel
+ @param[in] SteppingId SteppingId
+ @param[in] 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
+ );
+
+/**
+ Update some processor info into LEAST_FEATURE_PROC data structure.
+
+ @param[in] Index Indicate which processor calling this routine
+ @param[in] LeastFeatureProcessor The data structure that will be updated
+
+**/
+VOID
+EFIAPI
+UpdateProcessorInfo (
+ IN UINTN Index,
+ IN LEAST_FEATURE_PROC *LeastFeatureProcessor
+ );
+
+/**
+ Get processor feature delta
+
+ @param[in] FeaturesInput Supported features for input processor
+ @param[in] CommonFeatures Supported features for processor (subset of FeaturesInput)
+
+ @retval The least of processor features
+
+**/
+UINT32
+EFIAPI
+GetProcessorFeatureDelta (
+ IN UINT32 *FeaturesInput,
+ IN UINT32 *CommonFeatures
+ );
+
+/**
+ Calculate how many bits are one from given number
+
+ @param[in] Value Number that will be calculated bits
+
+ @retval Number of bits
+
+**/
+UINT32
+EFIAPI
+GetBitsNumberOfOne (
+ IN UINT32 Value
+ );
+
+/**
+ Exchange 2 processors (BSP to AP or AP to BSP)
+
+ @param[in] MyInfo CPU info for current processor
+ @param[in] OthersInfo CPU info that will be exchanged with
+
+**/
+VOID
+AsmExchangeRole (
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
+ );
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c
new file mode 100644
index 0000000000..5c33674367
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c
@@ -0,0 +1,273 @@
+/** @file
+ Synchronization of MTRRs on S3 boot path.
+
+ Copyright (c) 2005 - 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.
+
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#include "CpuAccess.h"
+#include <Private/Library/MpServiceLib.h>
+
+UINTN
+MpMtrrSynchUpEntry (
+ VOID
+ );
+
+VOID
+MpMtrrSynchUpExit (
+ UINTN Cr4
+ );
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mFixedMtrrIndex[] = {
+ IA32_MTRR_FIX64K_00000,
+ IA32_MTRR_FIX16K_80000,
+ IA32_MTRR_FIX16K_A0000,
+ IA32_MTRR_FIX4K_C0000,
+ IA32_MTRR_FIX4K_C8000,
+ IA32_MTRR_FIX4K_D0000,
+ IA32_MTRR_FIX4K_D8000,
+ IA32_MTRR_FIX4K_E0000,
+ IA32_MTRR_FIX4K_E8000,
+ IA32_MTRR_FIX4K_F0000,
+ IA32_MTRR_FIX4K_F8000,
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mMtrrDefType[] = { CACHE_IA32_MTRR_DEF_TYPE };
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mVariableMtrrIndex[] = {
+ CACHE_VARIABLE_MTRR_BASE,
+ CACHE_VARIABLE_MTRR_BASE + 1,
+ CACHE_VARIABLE_MTRR_BASE + 2,
+ CACHE_VARIABLE_MTRR_BASE + 3,
+ CACHE_VARIABLE_MTRR_BASE + 4,
+ CACHE_VARIABLE_MTRR_BASE + 5,
+ CACHE_VARIABLE_MTRR_BASE + 6,
+ CACHE_VARIABLE_MTRR_BASE + 7,
+ CACHE_VARIABLE_MTRR_BASE + 8,
+ CACHE_VARIABLE_MTRR_BASE + 9,
+ CACHE_VARIABLE_MTRR_BASE + 10,
+ CACHE_VARIABLE_MTRR_BASE + 11,
+ CACHE_VARIABLE_MTRR_BASE + 12,
+ CACHE_VARIABLE_MTRR_BASE + 13,
+ CACHE_VARIABLE_MTRR_BASE + 14,
+ CACHE_VARIABLE_MTRR_BASE + 15,
+ CACHE_VARIABLE_MTRR_BASE + 16,
+ CACHE_VARIABLE_MTRR_BASE + 17,
+ CACHE_VARIABLE_MTRR_BASE + 18,
+ CACHE_VARIABLE_MTRR_BASE + 19,
+ ///
+ /// CACHE_VARIABLE_MTRR_END,
+ ///
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN FixedMtrrNumber = sizeof (mFixedMtrrIndex) / sizeof (UINT16);
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN MtrrDefTypeNumber = sizeof (mMtrrDefType) / sizeof (UINT16);
+
+/**
+ Save the MTRR registers to global variables
+
+ @param[in] MtrrValues Pointer to the buffer which stores MTRR settings
+
+**/
+VOID
+ReadMtrrRegisters (
+ IN UINT64 *MtrrValues
+ )
+{
+ UINT32 Index;
+ UINT32 VariableMtrrNumber;
+
+ //
+ // Read all Mtrrs
+ //
+ for (Index = 0; Index < FixedMtrrNumber; Index++) {
+ *MtrrValues = AsmReadMsr64 (mFixedMtrrIndex[Index]);
+ MtrrValues++;
+ }
+
+ for (Index = 0; Index < MtrrDefTypeNumber; Index++) {
+ *MtrrValues = AsmReadMsr64 (mMtrrDefType[Index]);
+ MtrrValues++;
+ }
+
+ VariableMtrrNumber = ((UINT32) (AsmReadMsr64 (IA32_MTRR_CAP) & B_IA32_MTRR_VARIABLE_SUPPORT));
+ if (VariableMtrrNumber > V_MAXIMUM_VARIABLE_MTRR_NUMBER) {
+ VariableMtrrNumber = V_MAXIMUM_VARIABLE_MTRR_NUMBER;
+ }
+ for (Index = 0; Index < VariableMtrrNumber * 2; Index++) {
+ *MtrrValues = AsmReadMsr64 (mVariableMtrrIndex[Index]);
+ MtrrValues++;
+ }
+
+ return;
+}
+
+
+/**
+ Synch up the MTRR values for all processors
+
+ @param[in] MtrrValues Pointer to the buffer which stores MTRR settings
+
+**/
+VOID
+MpMtrrSynchUp (
+ UINT64 *MtrrValues
+ )
+{
+ UINT32 Index;
+ UINT32 VariableMtrrNumber;
+ UINTN Cr4;
+ UINT64 *FixedMtrr;
+ UINT64 *MtrrDefType;
+ UINT64 *VariableMtrr;
+ UINT64 ValidMtrrAddressMask;
+ EFI_CPUID_REGISTER FeatureInfo;
+ EFI_CPUID_REGISTER FunctionInfo;
+ UINT8 PhysicalAddressBits;
+
+ //
+ // Get physical CPU MTRR width in case of difference from BSP
+ //
+ AsmCpuid (
+ CPUID_EXTENDED_FUNCTION,
+ &FunctionInfo.RegEax,
+ &FunctionInfo.RegEbx,
+ &FunctionInfo.RegEcx,
+ &FunctionInfo.RegEdx
+ );
+ PhysicalAddressBits = 36;
+ if (FunctionInfo.RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (
+ CPUID_VIR_PHY_ADDRESS_SIZE,
+ &FeatureInfo.RegEax,
+ &FeatureInfo.RegEbx,
+ &FeatureInfo.RegEcx,
+ &FeatureInfo.RegEdx
+ );
+ PhysicalAddressBits = (UINT8) FeatureInfo.RegEax;
+ }
+
+ ValidMtrrAddressMask = (LShiftU64 (1, PhysicalAddressBits) - 1) & 0xfffffffffffff000ULL;
+
+ FixedMtrr = MtrrValues;
+ MtrrDefType = MtrrValues + FixedMtrrNumber;
+ VariableMtrr = MtrrValues + FixedMtrrNumber + MtrrDefTypeNumber;
+
+ //
+ // ASM code to setup processor register before synching up the MTRRs
+ //
+ Cr4 = MpMtrrSynchUpEntry ();
+
+ //
+ // Disable Fixed Mtrrs
+ //
+ AsmWriteMsr64 (CACHE_IA32_MTRR_DEF_TYPE, MtrrDefType[0] & 0xFFFFF7FF);
+
+ //
+ // Update Fixed Mtrrs
+ //
+ for (Index = 0; Index < FixedMtrrNumber; Index++) {
+ AsmWriteMsr64 (mFixedMtrrIndex[Index], FixedMtrr[Index]);
+ }
+ //
+ // Synchup Base Variable Mtrr
+ //
+ VariableMtrrNumber = (UINT32) (AsmReadMsr64 (IA32_MTRR_CAP) & B_IA32_MTRR_VARIABLE_SUPPORT);
+ if (VariableMtrrNumber > V_MAXIMUM_VARIABLE_MTRR_NUMBER) {
+ VariableMtrrNumber = V_MAXIMUM_VARIABLE_MTRR_NUMBER;
+ }
+
+ for (Index = 0; Index < VariableMtrrNumber * 2; Index++) {
+ AsmWriteMsr64 (
+ mVariableMtrrIndex[Index],
+ (VariableMtrr[Index] & 0x0FFF) | (VariableMtrr[Index] & ValidMtrrAddressMask)
+ );
+ }
+ //
+ // Synchup def type Fixed Mtrrs
+ //
+ AsmWriteMsr64 (CACHE_IA32_MTRR_DEF_TYPE, MtrrDefType[0]);
+
+ //
+ // ASM code to setup processor register after synching up the MTRRs
+ //
+ MpMtrrSynchUpExit (Cr4);
+
+ return;
+}
+
+
+/**
+ Set MTRR registers
+
+ @param[in] MtrrArray Buffer with MTRR settings
+
+**/
+VOID
+SetMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ )
+{
+ UINT32 Index;
+ UINTN Cr4;
+
+ //
+ // ASM code to setup processor register before synching up the MTRRs
+ //
+ Cr4 = MpMtrrSynchUpEntry ();
+
+ Index = 0;
+ while ((MtrrArray[Index].Index != 0) && (MtrrArray[Index].Index >= CACHE_VARIABLE_MTRR_BASE)) {
+ AsmWriteMsr64 (MtrrArray[Index].Index, MtrrArray[Index].Value);
+ Index++;
+ }
+ //
+ // ASM code to setup processor register after synching up the MTRRs
+ //
+ MpMtrrSynchUpExit (Cr4);
+}
+
+
+#ifdef EFI_DEBUG
+/**
+ Print MTRR settings in debug build BIOS
+
+ @param[in] MtrrArray Buffer with MTRR settings
+**/
+VOID
+ShowMtrrRegisters (
+ IN EFI_MTRR_VALUES *MtrrArray
+ )
+{
+ UINT32 Index;
+
+ Index = 0;
+ while ((MtrrArray[Index].Index != 0) && (MtrrArray[Index].Index >= CACHE_VARIABLE_MTRR_BASE)) {
+ DEBUG ((DEBUG_INFO, "MTRR: MtrrArray Index = %x\n", Index));
+ DEBUG (
+ (DEBUG_INFO,
+ "MTRR: MtrrArray[%x].Index = %x MtrrArray[%x].Value = %x\n",
+ Index,
+ MtrrArray[Index].Index,
+ Index,
+ MtrrArray[Index].Value)
+ );
+ Index++;
+ }
+
+ DEBUG ((DEBUG_INFO, "MTRR: Total Index = %x\n", Index));
+}
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/PeiMpServiceLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/PeiMpServiceLib.inf
new file mode 100644
index 0000000000..ef76dd49b5
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/PeiMpServiceLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Component information file for CPU module.
+#
+# 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 = PeiMpServiceLib
+ FILE_GUID = 59E4C67A-59A8-4DEA-9072-F9CDB6CA3E2C
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = MpServiceLib
+
+[BuildOptions]
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+
+[LibraryClasses]
+ HobLib
+ CpuPlatformLib
+ DebugLib
+ BaseLib
+ PeiServicesLib
+ BaseMemoryLib
+ SynchronizationLib
+ ReportStatusCodeLib
+ MemoryAllocationLib
+ TimerLib
+ PostCodeLib
+ MtrrLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonSiPkg/BroxtonSiPrivate.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources]
+ MtrrSync.c
+ Microcode.c
+ MpService.c
+ Ia32/MpFuncs.asm|MSFT
+ Ia32/MpFuncs.nasm|GCC
+
+[Ppis]
+ gEfiEndOfPeiSignalPpiGuid ## NOTIFY
+
+[Guids]
+ gCpuInitDataHobGuid ## UNDEFINED
+ gMicroCodepointerGuid ## UNDEFINED