From a674eea1c47a6aa0170b2beb07d4f2bbefc798e0 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 22 Dec 2016 19:41:14 +0800 Subject: BroxtonSiPkg: Add Cpu Include file and Library Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Cpu/Include/BiosGuardDefinitions.h | 222 +++ .../BroxtonSiPkg/Cpu/Include/CpuAccess.h | 24 + .../BroxtonSiPkg/Cpu/Include/CpuDataStruct.h | 197 +++ .../BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h | 174 ++ .../BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h | 1054 ++++++++++++ .../Cpu/Include/Library/CpuPlatformLib.h | 89 + .../Cpu/Include/Library/CpuPolicyLib.h | 67 + .../BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h | 55 + .../BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h | 52 + .../BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h | 141 ++ .../BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h | 51 + .../Cpu/Include/Ppi/CpuOverclockingConfig.h | 52 + .../BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h | 54 + .../BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h | 167 ++ Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h | 41 + .../Cpu/Include/Private/CpuInitDataHob.h | 39 + .../Cpu/Include/Private/Library/CpuCommonLib.h | 211 +++ .../Cpu/Include/Private/Library/CpuS3Lib.h | 33 + .../Cpu/Include/Private/Library/MpServiceLib.h | 819 +++++++++ .../Cpu/Include/Private/PowerMgmtNvsStruct.h | 123 ++ .../Include/Private/Protocol/PowerMgmtInitDone.h | 35 + .../Cpu/Include/Protocol/CpuGlobalNvsArea.h | 110 ++ .../BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h | 127 ++ .../Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c | 113 ++ .../Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c | 378 +++++ .../Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf | 51 + .../Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h | 49 + .../Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c | 38 + .../PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c | 182 ++ .../PeiCpuPolicyLibPreMem.inf | 45 + .../PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h | 45 + .../PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c | 256 +++ .../PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h | 33 + .../PeiDxeSmmCpuPlatformLib.inf | 44 + .../Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h | 229 +++ .../Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c | 753 +++++++++ .../Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h | 45 + .../Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc | 49 + .../Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S | 210 +++ .../Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm | 206 +++ .../Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf | 59 + .../Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c | 683 ++++++++ .../PeiDxeSmmCpuCommonLib.inf | 44 + .../Cpu/Library/Private/PeiMpServiceLib/Features.h | 120 ++ .../Library/Private/PeiMpServiceLib/Ia32/MpEqu.h | 45 + .../Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc | 49 + .../Private/PeiMpServiceLib/Ia32/MpEquNasm.inc | 49 + .../Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S | 316 ++++ .../Private/PeiMpServiceLib/Ia32/MpFuncs.asm | 365 ++++ .../Private/PeiMpServiceLib/Ia32/MpFuncs.nasm | 361 ++++ .../Library/Private/PeiMpServiceLib/Microcode.c | 221 +++ .../Library/Private/PeiMpServiceLib/MpService.c | 1756 ++++++++++++++++++++ .../Library/Private/PeiMpServiceLib/MpService.h | 211 +++ .../Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c | 273 +++ .../Private/PeiMpServiceLib/PeiMpServiceLib.inf | 65 + 55 files changed, 11280 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/BiosGuardDefinitions.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuAccess.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuDataStruct.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuPowerMgmt.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/CpuRegs.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPlatformLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuPolicyLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Library/CpuRngLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/BiosGuardConfig.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfig.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuConfigPreMem.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuOverclockingConfig.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/CpuPolicy.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Ppi/PowerMgmtConfig.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Pram.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/CpuInitDataHob.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuCommonLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/CpuS3Lib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Library/MpServiceLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/PowerMgmtNvsStruct.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Private/Protocol/PowerMgmtInitDone.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuGlobalNvsArea.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Include/Protocol/CpuInfo.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/CpuPrintPolicy.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibPreMem.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiCpuPolicyLibPreMem/PeiCpuPolicyLibrary.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/CpuS3Lib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpEqu.inc create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.S create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/Ia32/MpFuncs.asm create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiCpuS3Lib/PeiCpuS3Lib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/CpuCommonLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiDxeSmmCpuCommonLib/PeiDxeSmmCpuCommonLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Features.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEqu.inc create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpEquNasm.inc create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.S create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.asm create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Ia32/MpFuncs.nasm create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/Microcode.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MpService.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/MtrrSync.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/Library/Private/PeiMpServiceLib/PeiMpServiceLib.inf (limited to 'Silicon/BroxtonSoC') 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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. + + Conventions + 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.
+ + 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.
+ + 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 +#include + +/** + 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.
+ + 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 +#include +#include + +/** + 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.
+ + 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.
+ + 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 (Required) or (Optional) + - (Required) : This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization + - (Optional) : 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.
+ + 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 (Required) or (Optional). + - (Required): This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization. + - (Optional): 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; ///< (Optional) Enable or Disable Hyper Threading; 0: Disable; 1: Enable. + UINT32 VmxEnable : 1; ///< (Optional) Enable or Disable VMX; 0: Disable; 1: Enable. + UINT32 MlcStreamerPrefetcher : 1; ///< (Optional) Enable or Disable MLC Streamer Prefetcher; 0: Disable; 1: Enable. + UINT32 MlcSpatialPrefetcher : 1; ///< (Optional) Enable or Disable MLC Spatial Prefetcher; 0: Disable; 1: Enable. + UINT32 SmxEnable : 1; ///< (Optional) Enable or Disable Secure Mode Extensions feature; 0: Disable; 1: Enable. + UINT32 MonitorMwaitEnable : 1; ///< (Optional) Enable or Disable Monitor /MWAIT instructions; 0: Disable; 1: Enable. + UINT32 MachineCheckEnable : 1; ///< (Optional) Enable or Disable initialization of machine check registers; 0: Disable; 1: Enable. + UINT32 AesEnable : 1; ///< (Optional) Enable or Disable Advanced Encryption Standard (AES) feature; 0: Disable; 1: Enable. + UINT32 DebugInterfaceEnable : 1; ///< (Optional) Enable or Disable processor debug features; 0: Disable; 1: Enable. + UINT32 DebugInterfaceLockEnable : 1; ///< (Optional) Lock or Unlock debug interface features; 0: Disable; 1: Enable. + /** + (Required) Policies to obtain CPU temperature. + - 0: ACPI thermal management uses EC reported temperature values. + - 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; ///< (Optional) AP Idle Manner of waiting for SIPI; 1: HALT loop; 2: MWAIT loop; 3: RUN loop. + UINT32 ApHandoffManner : 2; ///< (Debug) Settings for AP Handoff to OS; 1: HALT loop; 2: MWAIT loop. + UINT32 ActiveProcessorCores : 3; ///< (Debug) Number of active cores. 0: All. + UINT32 DisableCore1 : 1; ///< (Debug) Enable/Disable Core 1 + UINT32 DisableCore2 : 1; ///< (Debug) Enable/Disable Core 2 + UINT32 DisableCore3 : 1; ///< (Debug) Enable/Disable Core 3 + /** + (Debug) Processor Early Power On Configuration FCLK setting. + - 0: 800 MHz (ULT/ULX). + - 1: 1 GHz (DT/Halo) + - 2: 400 MHz. + - 3: Reserved. + **/ + UINT32 FClkFrequency : 2; + UINT32 JtagC10PowerGateDisable : 1; ///< (Debug) Power JTAG in C10 and deeper power states; 0: Disable; 1: Enable. + UINT32 ProcTraceOutputScheme : 1; ///< (Debug) Control on Processor Trace output scheme; 0: Single Range Output; 1: ToPA Output. + UINT32 ProcTraceEnable : 1; ///< (Debug) Enable or Disable Processor Trace feature; 0: Disable; 1: Enable. + UINT32 ThreeStrikeCounterDisable : 1; ///< (Debug) Disable Three strike counter; 0: Enable counter; 1: Disable counter. + UINT32 VoltageOptimizer : 1; ///< (Optional) Enable or Disable Voltage Optimizer feature 0: Disable; 1: Enable + UINT32 FlashWearOutProtection : 1; ///< Flash Wear-out Protection; 0: Disable; 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; ///< (Debug) Power JTAG in C10 and deeper power states; 0: Disable; 1: Enable. + UINT32 RsvdBits :31; ///< Bits reserved for DWORD alignment. + UINT8 CpuRatio; ///< (Debug) CPU ratio value. + UINT8 SmmbaseSwSmiNumber; ///< (Required) Software SMI Number from Smbase. + UINT8 ProcTraceMemSize; ///< (Optional) Memory region allocation for Processor Trace, allowed range is from 4K (0x0) to 128MB (0xF); 0xFF: Disable. + UINT8 Rsvd; ///< Reserved for DWORD alignment. + EFI_PHYSICAL_ADDRESS MicrocodePatchAddress; ///< (Required) 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.
+ + 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; 0: Disable; 1 Enable. + UINT32 Txt : 1; ///< Enable or Disable TXT; 0: Disable; 1: Enable. + UINT32 SkipStopPbet : 1; ///< Skip Stop PBET Timer 0: Disabled, 1: Enabled + UINT32 BiosGuard : 1; ///< Enable or Disable BIOS Guard; 0: Disable, 1:Enable + UINT32 EnableC6Dram : 1; ///< C6DRAM Memory. 0: C6DRAM Disabled; 1: C6DRAM Enabled. + UINT32 FlashWearOutProtection : 1; ///< Flash Wear-Out Protection; 0: Disable; 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.
+ + 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; 0: Adaptive; 1: Override. + UINT32 RingVoltageMode : 1; ///< CLR voltage mode; 0: Adaptive; 1:Override + UINT32 OcSupport : 1; ///< Over clocking support; 0: Disable; 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include + +// +// 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.
+ + 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 (Required) or (Optional). + - (Required): This policy is recommended to be properly configured for proper functioning of reference code and silicon initialization. + - (Optional): 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; ///< (Test) Enable or Disable Intel SpeedStep Technology. 0: Disable; 1: Enable + UINT32 Cx : 1; ///< (Test) Enable or Disable CPU power states (C-states). 0: Disable; 1: Enable + UINT32 C1e : 1; ///< (Test) Enable or Disable Enhanced C-states. 0: Disable; 1: Enable + UINT32 C1AutoDemotion : 1; ///< (Test) Enable or Disable C6/C7 auto demotion to C1. 0: Disabled; 1: C1 Auto demotion; + UINT32 C3AutoDemotion : 1; ///< (Test) Enable or Disable C6/C7 auto demotion to C3 0: Disabled; 1: C3 Auto demotion; + UINT32 TurboMode : 1; ///< (Test) Enable or Disable long duration Turbo Mode. Disable; 1: Enable + UINT32 PowerLimit2Enable : 1; ///< Enable or Disable short duration Turbo Mode. Disable; 1: Enable + UINT32 C1UnDemotion : 1; ///< Enable or Disable C1UnDemotion. 0: Disabled; 1: C1 Auto undemotion; + UINT32 C3UnDemotion : 1; ///< (Test) Enable or Disable C3UnDemotion. 0: Disabled; 1: C3 Auto undemotion; + UINT32 PkgCStateDemotion : 1; ///< (Test) Enable or Disable Package Cstate Demotion. Disable; 1: Enable + UINT32 PkgCStateUnDemotion : 1; ///< (Test) Enable or Disable Package Cstate UnDemotion. Disable; 1: Enable + UINT32 TimedMwait : 1; ///< (Test) Enable or Disable TimedMwait Support. Disable; 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; 0: Do not skip; 1: Skip. + UINT32 TurboPowerLimitLock : 1; ///< MSR 0x610[63] and 0x618[63]: Lock all Turbo settings; 0: Disable; 1: Enable. + UINT32 PowerLimit3Lock : 1; ///< Package PL3 MSR 615h lock; 0: Disable; 1: Enable. + UINT32 PowerLimit4Lock : 1; ///< Package PL4 MSR 601h lock; 0: Disable; 1: Enable. + UINT32 PowerLimit3DutyCycle : 8; ///< Package PL3 Duty Cycle; 0. + 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; ///< (Test) Enable or Disable IO to MWAIT redirection; 0: Disable; 1: Enable. + UINT32 PmgCstCfgCtrlLock : 1; ///< (Test) If enabled, sets MSR 0xE2[15]; 0: Disable; 1: Enable. + UINT32 ProcHotLock : 1; ///< (Test) If enabled, sets MSR 0x1FC[23]; 0: Disable; 1: Enable. + UINT32 BiProcHot : 1; ///< (Test) Enable or Disable Bi-Directional PROCHOT#; 0: Disable; 1: Enable. + UINT32 TStates : 1; ///< (Test) Enable or Disable T states; 0: Disable; 1: Enable. + UINT32 DisableProcHotOut : 1; ///< (Test) Enable or Disable PROCHOT# signal being driven externally; 0: Disable; 1: Enable. + UINT32 DisableVrThermalAlert : 1; ///< (Test) Enable or Disable VR Thermal Alert; 0: Disable; 1: Enable. + UINT32 ProcHotResponse : 1; ///< (Test) Enable or Disable PROCHOT# Response; 0: Disable; 1: Enable. + UINT32 AutoThermalReporting : 1; ///< (Test) Enable or Disable Thermal Reporting through ACPI tables; 0: Disable; 1: Enable. + UINT32 ThermalMonitor : 1; ///< (Test) Enable or Disable Thermal Monitor; 0: Disable; 1: Enable. + UINT32 EnableCCx : 1; ///< (Optional) Max Core Cstate, fused value + UINT32 UnlimitedCstate : 1; ///< (Optional) Max Core Cstate, no limit + UINT32 EnableC1 : 1; ///< (Optional) Max Core Cstate, C1 + UINT32 EnableC3 : 1; ///< (Optional) Max Core Cstate, C3 + UINT32 EnableC6 : 1; ///< (Optional) Max Core Cstate, C6 + UINT32 EnableC7 : 1; ///< (Optional) Max Core Cstate, C7 + UINT32 EnableC8 : 1; ///< (Optional) Max Core Cstate, C8 + UINT32 EnableC9 : 1; ///< (Optional) Max Core Cstate, C9 + UINT32 EnableC10 : 1; ///< (Optional) Max Core Cstate, C10 + UINT32 BootPState : 1; ///< (Optional) Boot PState with HFM or LFM. 0: HFM; 1: LFM; + UINT32 VrConfig : 1; ///< (Optional) Enable or Disable VR Config for VCC and VNN Rails; 0: Disable; 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 10, For all other SKUs the recommended default are 0 + @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; ///< (Test) 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.
+ + 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 +#include "Platform.h" +#include + +#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.
+ + 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 +#include + +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.
+ + 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.
+ + 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+ + 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.
+ + 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.
+ + 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.
+ + 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 + +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 + + Revision 1: + - 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.
+ + 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.
+ + 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.
+# +# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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.
+ + 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.
+ + 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 + +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.
+# +# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+ + 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 +#include + +#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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+# +# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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.
+ + 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 +#include "CpuS3.h" +#include +#include + +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.
+ + 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.
+; +; 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.
+# +# 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.
+; +; 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.
+# +# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+# +# 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.
+ + 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 + +/// +/// 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.
+ + 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.
+; +; 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.
+; +; 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.
+# +# 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.
+; +; 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.
+; +; 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.
+ + 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 +#include + +/** + 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.
+ + 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 +#include +#include +#include +#include +#include "MpService.h" +#include +#include +#include +#include +#include +#include + +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.
+ + 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 +#include + +/// +/// 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.
+ + 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 + +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.
+# +# 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 -- cgit v1.2.3