summaryrefslogtreecommitdiff
path: root/Silicon
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 13:00:19 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:15:08 +0800
commit387310c8dca74b9b92719242c35b08f36dc7336e (patch)
tree83e3d99ebbb5c2052915171ebab8406c8113716e /Silicon
parent7e5ec7995593295b0a77c0443e8bf82bf9e3dd30 (diff)
downloadedk2-platforms-387310c8dca74b9b92719242c35b08f36dc7336e.tar.xz
BroxtonSiPkg: Add Txe/Include/ and Txe/Library
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Silicon')
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/CoreBiosMsg.h552
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h382
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/Heci2PowerManagementLib.h36
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h2016
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h126
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCChipsetLib.h47
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCLib.h145
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCPolicyLib.h118
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h793
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h42
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h90
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Private/Library/HeciInitLib.h330
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci.h111
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h67
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/IntegratedTouchHid.h74
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCPlatformPolicy.h134
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h56
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/PttPtpRegs.h118
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCAccess.h307
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCChipset.h138
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h64
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.c38
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.inf32
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c860
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf44
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/HeciMsgLib.c1800
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.c204
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf42
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c500
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf41
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c98
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf38
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/HeciMsgLib.c258
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/PeiSeCLib.inf40
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c180
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCPolicyLib.c142
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.c1964
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.h109
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.c202
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.h99
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf53
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.c578
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.h134
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.inf63
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c1626
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c260
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf45
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c190
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.c57
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.inf37
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c91
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf40
52 files changed, 15611 insertions, 0 deletions
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/CoreBiosMsg.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/CoreBiosMsg.h
new file mode 100644
index 0000000000..6cb4839647
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/CoreBiosMsg.h
@@ -0,0 +1,552 @@
+/** @file
+ Core BIOS Messages.
+
+ Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef CORE_BIOS_MSG_H
+#define CORE_BIOS_MSG_H
+
+#include <MkhiMsgs.h>
+
+#pragma pack(1)
+
+#define CBM_RESET_REQ_CMD 0x0B
+#define CBM_RESET_REQ_CMD_ACK 0x8B
+#define CBM_END_OF_POST_CMD 0x0C
+#define CBM_END_OF_POST_CMD_ACK 0x8C
+#define GEN_SET_DEBUG_MEMORY_CMD 0x11
+
+#define FWU_QUERY_STATUS_CMD 0x02
+#define FWU_QUERY_STATUS_GROUP_ID 0x06
+
+#define HECI_CLIENT_CORE_MSG_DISPATCHER 0x07
+#define HOST_FIXED_ADDRESS 0x00
+
+typedef union _HECI_MESSAGE_HEADER {
+ UINT32 Data;
+ struct {
+ UINT32 SeCAddress : 8;
+ UINT32 HostAddress : 8;
+ UINT32 Length : 9;
+ UINT32 Reserved : 6;
+ UINT32 MessageComplete : 1;
+ } Fields;
+} HECI_MESSAGE_HEADER;
+
+//
+// Reset request message
+//
+typedef struct _CBM_RESET_REQ_DATA {
+ UINT8 RequestOrigin;
+ UINT8 ResetType;
+} CBM_RESET_REQ_DATA;
+
+typedef struct _CBM_RESET_REQ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ CBM_RESET_REQ_DATA Data;
+} CBM_RESET_REQ;
+
+typedef struct _MKHI_CBM_RESET_REQ {
+ HECI_MESSAGE_HEADER Header;
+ CBM_RESET_REQ Msg;
+} MKHI_CBM_RESET_REQ;
+
+typedef struct _FWUPDATE_QUERY_UPDATE_STATUS_ACK_DATA {
+ UINT32 PercentComplete;
+ UINT32 CurrentStage;
+ UINT32 TotalStages;
+ UINT32 LastUpdateStatus;
+} FWUPDATE_QUERY_UPDATE_STATUS_ACK_DATA;
+
+typedef union _FWU_INFO_FLAGS {
+ UINT32 Data;
+ struct {
+ UINT32 RecoveryMode : 2;
+ UINT32 IpuNeeded : 1;
+ UINT32 FwuInitDone : 1;
+ UINT32 FwuInProgress : 1;
+ UINT32 SuInProgress : 1;
+ UINT32 NewFtTestS : 1;
+ UINT32 SafeBootCnt : 4;
+ UINT32 FsbFlag : 1;
+ UINT32 LivePingNeeded : 1;
+ UINT32 ResumeUpdateNeeded : 1;
+ UINT32 RollbackNeededMode : 2;
+ UINT32 ResetNeeded : 2;
+ UINT32 SuState : 4;
+ UINT32 Reserve: 10;
+ } Fields;
+} FWU_INFO_FLAGS;
+
+typedef struct _MKHI_FWUPDATE_QUERY_STATUS_REQ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} MKHI_FWUPDATE_QUERY_SATUS_REQ;
+
+typedef struct _MKHI_FWUPDATE_QUERY_STATUS_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ FWUPDATE_QUERY_UPDATE_STATUS_ACK_DATA QueryAckData;
+ UINT32 ResetType;
+ FWU_INFO_FLAGS Flags;
+}MKHI_FWUPDATE_QUERY_STATUS_ACK;
+
+//
+// Reset request ack message
+//
+typedef struct _CBM_RESET_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} CBM_RESET_ACK;
+
+typedef struct _MKHI_CBM_RESET_ACK {
+ HECI_MESSAGE_HEADER Header;
+ CBM_RESET_ACK Msg;
+} MKHI_CBM_RESET_ACK;
+
+//
+// ASF Watch Dog Timer
+//
+#define ASF_MANAGEMENT_CONTROL 0x02
+#define ASF_SUB_COMMAND_START_WDT 0x13
+#define ASF_SUB_COMMAND_STOP_WDT 0x14
+
+//
+// ASF Start Watch Dog
+//
+typedef struct _ASF_START_WDT {
+ UINT8 Command;
+ UINT8 ByteCount;
+ UINT8 SubCommand;
+ UINT8 VersionNumber;
+ UINT8 TimeoutLow;
+ UINT8 TimeoutHigh;
+ UINT8 EventSensorType;
+ UINT8 EventType;
+ UINT8 EventOffset;
+ UINT8 EventSourceType;
+ UINT8 EventSeverity;
+ UINT8 SensorDevice;
+ UINT8 SensorNumber;
+ UINT8 Entity;
+ UINT8 EntityInstance;
+ UINT8 EventData[5];
+} ASF_START_WDT;
+
+#define ASF_START_WDT_LENGTH 0x14
+
+//
+// ASF Stop Watch Dog
+//
+typedef struct _ASF_STOP_WDT {
+ UINT8 Command;
+ UINT8 ByteCount;
+ UINT8 SubCommand;
+ UINT8 VersionNumber;
+} ASF_STOP_WDT;
+
+#define ASF_STOP_WDT_LENGTH 0x04
+
+//
+// HECI Header Definitions for Core BIOS Messages
+//
+#define CBM_END_OF_POST_HECI_HDR 0x80080001
+#define CBM_END_OF_POST_RESPONSE_HECI_HDR 0x80010001
+#define CBM_RESET_REQUEST_HECI_HDR 0x80030001
+#define CBM_RESET_RESPONSE_HECI_HDR 0x80020001
+
+//
+// Enumerations used in Core BIOS Messages
+//
+// End Of Post Codes.
+//
+#define CBM_EOP_EXITING_G3 0x01
+#define CBM_EOP_RESERVED 0x02
+#define CBM_EOP_EXITING_S3 0x03
+#define CBM_EOP_EXITING_S4 0x04
+#define CBM_EOP_EXITING_S5 0x05
+
+//
+// Reset Request Origin Codes.
+//
+#define CBM_RR_REQ_ORIGIN_BIOS_MEMORY_INIT 0x01
+#define CBM_RR_REQ_ORIGIN_BIOS_POST 0x02
+
+//
+// Reset Type Codes.
+//
+#define CBM_HRR_GLOBAL_RESET 0x01
+
+//
+// Reset Response Codes.
+//
+#define CBM_HRR_RES_REQ_NOT_ACCEPTED 0x01
+
+//
+// definitions for ICC MEI Messages
+//
+#define IBEX_PEAK_PLATFORM 0x00010000
+#define COUGAR_POINT_PLATFORM 0x00020000
+
+typedef enum {
+ ICC_STATUS_SUCCESS = 0,
+ ICC_STATUS_SUCCESS_WAITING_FOR_RESET,
+ ICC_STATUS_INCORRECT_API_VERSION,
+ ICC_STATUS_INVALID_FUNCTION,
+ ICC_STATUS_INVALID_BUFFER_LENGTH,
+ ICC_STATUS_INVALID_PARAMETERS,
+ ICC_STATUS_FLASH_WEAR_OUT_VIOLATION,
+ ICC_STATUS_CLOCK_REQ_ENTRY_VIOLATION,
+ ICC_STATUS_STATIC_REGISTER_MASK_VIOLATION,
+ ICC_STATUS_DYNAMIC_REGISTER_MASK_VIOLATION,
+ ICC_STATUS_IMMEDIATE_REQUIRES_POWER_CYCLE,
+ ICC_STATUS_ILLEGAL_RECORD_ID,
+ ICC_STATUS_ENABLED_CLOCK_MASK_VIOLATION,
+ ICC_STATUS_INVALID = 0xFFFFFFFF
+} ICC_MEI_CMD_STATUS;
+
+typedef union _ICC_CLOCK_ENABLES_CONTROL_MASK {
+ UINT32 Dword;
+ struct {
+ UINT32 Flex0 : 1;
+ UINT32 Flex1 : 1;
+ UINT32 Flex2 : 1;
+ UINT32 Flex3 : 1;
+ UINT32 Reserved1 : 3;
+ UINT32 PCI_Clock0 : 1;
+ UINT32 PCI_Clock1 : 1;
+ UINT32 PCI_Clock2 : 1;
+ UINT32 PCI_Clock3 : 1;
+ UINT32 PCI_Clock4 : 1;
+ UINT32 Reserved2 : 4;
+ UINT32 SRC0 : 1;
+ UINT32 SRC1 : 1;
+ UINT32 SRC2 : 1;
+ UINT32 SRC3 : 1;
+ UINT32 SRC4 : 1;
+ UINT32 SRC5 : 1;
+ UINT32 SRC6 : 1;
+ UINT32 SRC7 : 1;
+ UINT32 CSI_SRC8 : 1;
+ UINT32 CSI_DP : 1;
+ UINT32 PEG_A : 1;
+ UINT32 PEG_B : 1;
+ UINT32 DMI : 1;
+ UINT32 Reserved3 : 3;
+ } Fields;
+} ICC_CLOCK_ENABLES_CONTROL_MASK;
+
+typedef enum {
+ LOCK_ICC_REGISTERS = 0x2,
+ SET_CLOCK_ENABLES = 0x3,
+ GET_ICC_PROFILE = 0x4,
+ SET_ICC_PROFILE = 0x5,
+ GET_ICC_CLOCKS_CAPABILITIES = 0x6,
+ GET_OEM_CLOCK_RANGE_DEFINITION_RECORD = 0x7,
+ GET_ICC_RECORD = 0x8,
+ READ_ICC_REGISTER = 0x9,
+ WRITE_ICC_REGISTER = 0xa,
+ WRITE_UOB_RECORD = 0xb
+} ICC_MEI_COMMAND_ID;
+
+typedef struct {
+ UINT32 ApiVersion;
+ ICC_MEI_COMMAND_ID IccCommand;
+ ICC_MEI_CMD_STATUS IccResponse;
+ UINT32 BufferLength;
+ UINT32 Reserved;
+} ICC_HEADER;
+
+typedef struct {
+ ICC_HEADER Header;
+} ICC_GET_PROFILE_MESSAGE;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT8 SupportedProfilesNumber;
+ UINT8 IccProfileSoftStrap;
+ UINT8 IccProfileIndex;
+ UINT8 Padding;
+} ICC_GET_PROFILE_RESPONSE;
+
+typedef union {
+ ICC_GET_PROFILE_MESSAGE message;
+ ICC_GET_PROFILE_RESPONSE response;
+} ICC_GET_PROFILE_BUFFER;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT8 ProfileBIOS;
+ UINT8 PaddingA;
+ UINT16 PaddingB;
+} ICC_SET_PROFILE_MESSAGE;
+
+typedef struct {
+ ICC_HEADER Header;
+} ICC_SET_PROFILE_RESPONSE;
+
+typedef union {
+ ICC_SET_PROFILE_MESSAGE message;
+ ICC_SET_PROFILE_RESPONSE response;
+} ICC_SET_PROFILE_BUFFER;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT32 ClockEnables;
+ UINT32 ClockEnablesMask;
+ UINT32 Params;
+ UINT64 Nonce;
+} ICC_SET_CLK_ENABLES_MESSAGE;
+
+typedef struct {
+ ICC_HEADER Header;
+} ICC_SET_CLK_ENABLES_RESPONSE;
+
+typedef union {
+ ICC_SET_CLK_ENABLES_MESSAGE message;
+ ICC_SET_CLK_ENABLES_RESPONSE response;
+} ICC_SET_CLK_ENABLES_BUFFER;
+
+typedef struct {
+ ICC_HEADER Header;
+} ICC_GET_CLK_CAPABILITIES_MESSAGE;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT32 VersionNumber;
+ UINT8 IccHwSku;
+ UINT8 Reserved;
+ UINT16 MaxSusramRecordSize;
+ UINT64 IccSkuEnforcementTable;
+ UINT32 IccBootStatusReport;
+} ICC_GET_CLK_CAPABILITIES_RESPONSE;
+
+typedef union {
+ ICC_GET_CLK_CAPABILITIES_MESSAGE message;
+ ICC_GET_CLK_CAPABILITIES_RESPONSE response;
+} ICC_GET_CLK_CAPABILITIES_BUFFER;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT8 AccessMode;
+ UINT8 PaddingA;
+ UINT16 PaddingB;
+ UINT64 Nonce;
+ UINT32 RegisterMask[3];
+} ICC_LOCK_REGISTERS_MESSAGE;
+
+typedef struct {
+ ICC_HEADER Header;
+ UINT64 Nonce;
+ UINT32 RegisterMask[3];
+} ICC_LOCK_REGISTERS_RESPONSE;
+
+typedef union {
+ ICC_LOCK_REGISTERS_MESSAGE message;
+ ICC_LOCK_REGISTERS_RESPONSE response;
+} ICC_LOCK_REGISTERS_BUFFER;
+
+typedef union _ICC_CLOCK_ENABLES_PARAMS {
+ UINT32 Dword;
+ struct {
+ UINT32 RetainToResumeFromSx : 1;
+ UINT32 Reserved : 31;
+ } Fields;
+} ICC_CLOCK_ENABLES_PARAMS;
+
+//
+// TR MEI Messages
+//
+typedef struct _TR_BIOS_PARAM_REQUEST {
+ UINT8 Command;
+ UINT8 PollingTimeout;
+ UINT8 SMBusECMsgLen;
+ UINT8 SMBusECMsgPEC;
+ UINT8 DimmNumber;
+} TR_BIOS_PARAM_REQUEST;
+
+typedef struct _MKHI_MPC_BIOS_PARAM_REQUEST {
+ HECI_MESSAGE_HEADER Header;
+ TR_BIOS_PARAM_REQUEST TrBiosParamRequest;
+} MKHI_TR_BIOS_PARAM_REQUEST;
+
+#define TR_HECI_CONFIG_MSG_CMD_ID 0
+
+#define EC_MSG_LEN_1 1
+#define EC_MSG_LEN_2 2
+#define EC_MSG_LEN_5 5
+#define EC_MSG_LEN_9 9
+#define EC_MSG_LEN_10 10
+#define EC_MSG_LEN_14 14
+#define EC_MSG_LEN_20 20
+
+typedef enum {
+ TIME_100MS = 1,
+ TIME_200MS,
+ TIME_300MS,
+ TIME_400MS
+} POLLING_TIME_OUT;
+
+typedef enum {
+ PEC_DISABLED = 0,
+ PEC_ENABLED
+} PEC_SWITCH;
+
+//
+// SPI MEI Messages
+//
+#define HMRFPO_ENABLE_CMD_ID 0x01
+#define HMRFPO_LOCK_CMD_ID 0x02
+#define HMRFPO_GET_STATUS_CMD_ID 0x03
+
+typedef enum {
+ HMRFPO_ENABLE_SUCCESS = 0,
+ HMRFPO_ENABLE_LOCKED,
+ HMRFPO_NVAR_FAILURE,
+ HMRFOP_ATP_POLICY,
+ HMRFPO_ENABLE_UNKNOWN_FAILURE
+} HMRFPO_ENABLE_STATUS;
+
+typedef struct _MKHI_HMRFPO_ENABLE {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+ UINT64 Nonce;
+} MKHI_HMRFPO_ENABLE;
+
+typedef struct _HMRFPO_ENABLE {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_ENABLE Msg;
+} HMRFPO_ENABLE;
+
+typedef struct _MKHI_HMRFPO_ENABLE_RESPONSE {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+ UINT32 FactoryDefaultBase;
+ UINT32 FactoryDefaultLimit;
+ UINT8 Status;
+ UINT8 Rsvd[3];
+} MKHI_HMRFPO_ENABLE_RESPONSE;
+
+typedef struct _HMRFPO_ENABLE_RESPONSE {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_ENABLE_RESPONSE Msg;
+} HMRFPO_ENABLE_RESPONSE;
+
+typedef enum {
+ HMRFPO_LOCK_SUCCESS = 0,
+ HMRFPO_LOCK_FAILURE
+} HMRFPO_LOCK_STATUS;
+
+typedef struct _MKHI_HMRFPO_LOCK {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+} MKHI_HMRFPO_LOCK;
+
+typedef struct _HMRFPO_LOCK {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_LOCK Msg;
+} HMRFPO_LOCK;
+
+typedef struct _MKHI_HMRFPO_LOCK_RESPONSE {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+ UINT64 Nonce;
+ UINT32 FactoryDefaultBase;
+ UINT32 FactoryDefaultLimit;
+ UINT8 Status;
+ UINT8 Reserved[3];
+} MKHI_HMRFPO_LOCK_RESPONSE;
+
+typedef struct _HMRFPO_LOCK_RESPONSE {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_LOCK_RESPONSE Data;
+} HMRFPO_LOCK_RESPONSE;
+
+typedef struct _MKHI_HMRFPO_GET_STATUS {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+} MKHI_HMRFPO_GET_STATUS;
+
+typedef struct _HMRFPO_GET_STATUS {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_GET_STATUS Msg;
+} HMRFPO_GET_STATUS;
+
+typedef struct _MKHI_HMRFPO_GET_STATUS_RESPONSE {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+ UINT8 Status;
+ UINT8 Reserved[3];
+} MKHI_HMRFPO_GET_STATUS_RESPONSE;
+
+typedef struct _HMRFPO_GET_STATUS_RESPONSE {
+ HECI_MESSAGE_HEADER Header;
+ MKHI_HMRFPO_GET_STATUS_RESPONSE Data;
+} HMRFPO_GET_STATUS_RESPONSE;
+
+#define HMRFPO_LOCKED 1
+#define HMRFPO_ENABLED 2
+
+//
+// ME State Control
+//
+#define EFI_SEC_STATE_STALL_1_SECOND 1000000
+#define EFI_SEC_STATE_MAX_TIMEOUT 20000000
+//
+// KVM support
+//
+#define EFI_KVM_MESSAGE_COMMAND 0x08
+#define EFI_KVM_BYTE_COUNT 0x06
+#define EFI_KVM_QUERY_REQUES 0x01
+#define EFI_KVM_QUERY_RESPONSE 0x02
+#define EFI_KVM_VERSION 0x10
+
+#define EFI_KVM_STALL_1_SECOND 1000000 // Stall 1 second
+#define EFI_KVM_MAX_WAIT_TIME (60 * 8) // 8 Mins
+typedef enum {
+ QUERY_REQUEST = 0,
+ CANCEL_REQUEST
+} QUERY_TYPE;
+
+typedef struct _AMT_QUERY_KVM_REQUEST {
+ UINT8 Command;
+ UINT8 ByteCount;
+ UINT8 SubCommand;
+ UINT8 VersionNumber;
+ UINT32 QueryType;
+} AMT_QUERY_KVM_REQUEST;
+
+typedef enum {
+ KVM_SESSION_ESTABLISHED = 1,
+ KVM_SESSION_CANCELLED
+} RESPONSE_CODE;
+
+typedef struct _AMT_QUERY_KVM_RESPONSE {
+ UINT8 Command;
+ UINT8 ByteCount;
+ UINT8 SubCommand;
+ UINT8 VersionNumber;
+ UINT32 ResponseCode;
+} AMT_QUERY_KVM_RESPONSE;
+
+typedef struct _SET_DEBUG_MEMORY_DATA {
+ UINT32 BiosDebugMemoryAddress;
+ UINT32 BiosDebugMemorySize;
+ UINT32 SeCVeDebugMemoryAddress;
+ UINT32 SeCVeDebugMemorySize;
+} SET_DEBUG_MEMORY_DATA;
+
+typedef struct _GEN_SET_DEBUG_MEMORY {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ SET_DEBUG_MEMORY_DATA Data;
+} GEN_SET_DEBUG_MEMORY;
+
+typedef struct _GEN_SET_DEBUG_MEMORY_ACK {
+ MKHI_MESSAGE_HEADER Header;
+} GEN_SET_DEBUG_MEMORY_ACK;
+
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h
new file mode 100644
index 0000000000..bc8d2fa492
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h
@@ -0,0 +1,382 @@
+/** @file
+ Register Definitions for HECI.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HECI_REGS_H
+#define _HECI_REGS_H
+
+#include "PlatformBaseAddresses.h"
+
+#define HECI_BUS SEC_BUS
+#define HECI_DEV SEC_DEVICE_NUMBER
+#define HECI_FUN HECI_FUNCTION_NUMBER
+#define HECI_PCI_ADDR (HECI_BUS << 24) | (HECI_DEV << 16) | (HECI_FUN << 8)
+#define REVID_MSK 0x000000FF
+
+#define BRNGUP_HMRFPO_DISABLE_CMD_MASK 0xF0000000
+#define BRNGUP_HMRFPO_DISABLE_CMD 0x30000000
+#define BRNGUP_HMRFPO_DISABLE_OVR_MASK 0xF0000000
+#define BRNGUP_HMRFPO_DISABLE_OVR_RSP 0x30000000
+
+#define HECI_SYSTEM_RESET_NOTIFY 0xB0
+
+//
+// HECI PCI register definition
+//
+#define R_VENDORID 0x00
+#define R_DEVICEID 0x02
+#define R_COMMAND 0x04
+#define B_BME 0x04
+#define B_MSE 0x02
+#define R_REVID 0x08
+#define R_HECIMBAR0 0x10
+#define R_HECIMBAR1 0x14
+#define R_SEC_FW_STS0 0x40
+#define R_GEN_STS 0x60 //0x4C
+#define R_HOST_TO_CSE 0x70
+#define B_IRRBP BIT31 //IBBL ready for Ring Buffer Protocol
+#define B_UCSTS BIT30 //Status of uCode patch load (0=fail;1=success)
+#define R_HIDM 0xA0
+
+//
+// DRAM Initiailization Response Codes.
+//
+#define CBM_DIR_NON_PCR 0x01
+#define CBM_DIR_PCR 0x02
+#define CBM_DIR_GLOBAL_RESET 0x06
+#define CBM_DIR_CONTINUE_POST 0x07
+
+//
+// HECIMBAR register definition
+//
+
+//
+// fTPM
+//
+#define R_SATT_PTT_CTRL 0x00D0
+#define B_PTT_DISABLED BIT13
+#define R_SATT_PTT_SAP_SIZE 0x00D8
+#define R_SATT_PTT_BRG_BA_LSB 0x00D4
+#define B_ENTRY_VLD BIT0
+#define PTT_CMD_BUFFER_OFFSET 0x80
+#define PTT_ICR 0x8c
+#define SEC_PTT_SAP_SIZE 0x1000
+
+//
+// HECIMBAR register definition
+//
+#define H_CB_WW 0x00
+#define H_CSR 0x04
+#define SEC_CB_RW 0x08
+#define SEC_CSR_HA 0x0C
+#define D0I3C 0x800
+
+//
+// SC related registers address
+//
+#define ACPI_TIMER_MAX_VALUE 0x1000000 // The timer is 24 bit overflow
+//
+// HPET Information
+//
+
+//
+// HPET Registers will be used as DWORD index
+//
+#define HPET_CAPS_REG_LOW 0x00 / 4
+#define HPET_CAPS_REG_HIGH 0x04 / 4
+#define HPET_GEN_CONFIG_LOW 0x10 / 4
+#define HPET_GEN_CONFIG_HIGH 0x14 / 4
+#define HPET_INT_STATUS_LOW 0x20 / 4
+#define HPET_INT_STATUS_HIGH 0x24 / 4
+#define HPET_MAIN_COUNTER_LOW 0xF0 / 4
+#define HPET_MAIN_COUNTER_HIGH 0xF4 / 4
+#define HPET_START 0x01
+#define HPET_TICKS_PER_MICRO 14 ///< 70ns tick so 14.2 ticks per microsecond ish
+
+//
+// PEI Timeout values
+//
+#define PEI_HECI_WAIT_DELAY 50000 ///< 50ms timeout for IO delay
+#define PEI_HECI_INIT_TIMEOUT 10000000 ///< 10 sec timeout in microseconds
+#define PEI_HECI_READ_TIMEOUT 10000000 ///< 10sec timeout in microseconds
+#define PEI_HECI_SEND_TIMEOUT 10000000 ///< 10sec timeout in microseconds
+
+//
+// DXE Timeout values based on HPET
+//
+#define HECI_WAIT_DELAY 1000 ///< 1ms timeout for IO delay
+#define HECI_INIT_TIMEOUT 15000000 ///< 15sec timeout in microseconds
+#define HECI_READ_TIMEOUT_EX 90000000 ///< 90sec timeout in microseconds
+#define HECI_READ_TIMEOUT 5000000 ///< 5sec timeout in microseconds
+#define HECI_SEND_TIMEOUT 5000000 ///< 5sec timeout in microseconds
+#define HECI_MAX_RETRY 3 ///< Value based off HECI HPS
+#define HECI_MSG_DELAY 2000000 ///< show warning msg and stay for 2 seconds.
+#pragma pack(1)
+
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 SEC_IE_HRA : 1; ///< 0 - SEC Interrupt Enable (Host Read Access)
+ UINT32 SEC_IS_HRA : 1; ///< 1 - SEC Interrupt Status (Host Read Access)
+ UINT32 SEC_IG_HRA : 1; ///< 2 - SEC Interrupt Generate (Host Read Access)
+ UINT32 SEC_RDY_HRA : 1; ///< 3 - SEC Ready (Host Read Access)
+ UINT32 SEC_RST_HRA : 1; ///< 4 - SEC Reset (Host Read Access)
+ UINT32 Reserved : 3; ///< 7:5
+ UINT32 SEC_CBRP_HRA : 8; ///< 15:8 - SEC CB Read Pointer (Host Read Access)
+ UINT32 SEC_CBWP_HRA : 8; ///< 23:16 - SEC CB Write Pointer (Host Read Access)
+ UINT32 SEC_CBD_HRA : 8; ///< 31:24 - SEC Circular Buffer Depth (Host Read Access)
+ } r;
+} HECI_SEC_CONTROL_REGISTER;
+
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 H_IE : 1; // 0 - Host Interrupt Enable SEC
+ UINT32 H_IS : 1; // 1 - Host Interrupt Status SEC
+ UINT32 H_IG : 1; // 2 - Host Interrupt Generate
+ UINT32 H_RDY : 1; // 3 - Host Ready
+ UINT32 H_RST : 1; // 4 - Host Reset
+ UINT32 H_DEVIDLEC_IE:1; // 5 - Host sets this bit to 1 to enable the host interrupt (MSI, INTx, SMI or SCI) to be asserted when H_DEVIDLEC_IS is set to 1.
+ UINT32 H_DEVIDLEC_IS:1; // 6 - HW sets this bit to 1 when DEVIDLEC.IR is set and DEVIDLEC.CIP transitions from 1 to 0. [br]Host clears this bit to 0 by writing a 1 to this bit position. H_DEVIDLEC_IE has no effect on this bit.
+ UINT32 Reserved : 1; // 7
+ UINT32 H_CBRP : 8; // 15:8 - Host CB Read Pointer
+ UINT32 H_CBWP : 8; // 23:16 - Host CB Write Pointer
+ UINT32 H_CBD : 8; // 31:24 - Host Circular Buffer Depth
+ } r;
+} HECI_HOST_CONTROL_REGISTER;
+
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 H_ALIVE_REQ : 1; ///< 0 - Aliveness Requested
+ UINT32 Reserved : 31; ///< 1:31 - Reseved
+ } r;
+} SICR_HOST_ALIVENESS_REQ;
+
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 H_ACK:1; ///< 0 - Aliveness ack
+ UINT32 Reserved:31; ///< 1:31 - Reseved
+ } r;
+} HICR_HOST_ALIVENESS_RESP;
+
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 HOST_RDY:1; ///< 0 - Host Ready
+ UINT32 SEC_RDY:1; ///< 1 - SeC Ready
+ UINT32 RDY_CLR:1; ///< 2 - Ready Clear
+ UINT32 Reserved:29; // 3:31 - Reseved
+ } r;
+} SICR_HOST_IPC_READINESS;
+
+///
+/// HICR0 - HICR_HOST_IPC_READINESS
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 HOST_RDY:1; ///< 0 - Host Ready
+ UINT32 SEC_RDY:1; ///< 1 - SeC Ready
+ UINT32 RDY_CLR:1; ///< 2 - Ready Clear
+ UINT32 Reserved:29; // 3:31 - Reseved
+ } r;
+} HICR_SEC_IPC_READINESS;
+
+///
+/// HHISR - Host High-level Interrupt Status Register.
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 INT_BAR0_STS:1; ///< 0 - Host Ready
+ UINT32 INT_BAR1_STS:1; ///< 1 - SeC Ready
+ UINT32 RSVD_31_2:30; ///< 2:31 - Reseved
+ } r;
+} HHISR;
+
+///
+/// SICR_SEC_IPC_OUTPUT_STATUS
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 IPC_OUTPUT_READY:1; ///< 0 - Host Ready
+ UINT32 RSVD_31_2:31; ///< 1:31 - Reseved
+ } r;
+} SICR_SEC_IPC_OUTPUT_STATUS;
+
+///
+/// SEC_IPC_INPUT_STATUS
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 IPC_INPUT_READY:1; ///< 0 - Host Ready
+ UINT32 RSVD_31_2:31; ///< 1:31 - Reseved
+ } r;
+} SEC_IPC_INPUT_STATUS;
+
+///
+/// SEC_IPC_INPUT_DOORBELL
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 IPC_INPUT_DOORBELL:1; ///< 0 - Door bell from host
+ UINT32 RSVD_31_2:31; ///< 1:31 - Reseved
+ } r;
+} SEC_IPC_INPUT_DOORBELL;
+
+///
+/// HICR_SEC_IPC_OUTPUT_DOORBELL
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 IPC_OUTPUT_DOORBELL:1; ///< 0 - Door bell from SeC
+ UINT32 RSVD_31_2:31; ///< 1:31 - Reseved
+ } r;
+} HICR_SEC_IPC_OUTPUT_DOORBELL;
+
+///
+/// FWS
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 CurrentState : 4; ///< 0:3 - Current State
+ UINT32 ManufacturingMode : 1; ///< 4 Manufacturing Mode
+ UINT32 FptBad : 1; ///< 5 FPT(Flash Partition Table ) Bad
+ UINT32 SeCOperationState : 3; ///< 6:8 - SEC Operation State
+ UINT32 FwInitComplete : 1; ///< 9
+ UINT32 FtBupLdFlr : 1; ///< 10 - This bit is set when firmware is not able to load BRINGUP from the fault tolerant (FT) code.
+ UINT32 FwUpdateInprogress : 1; ///< 11
+ UINT32 ErrorCode : 4; ///< 12:15 - Error Code
+ UINT32 SeCOperationMode : 4; ///< 16:19 - Management Engine Current Operation Mode
+ UINT32 Reserved2 : 4; ///< 20:23
+ UINT32 SeCBootOptionsPresent : 1;///< 24 - If this bit is set, an Boot Options is present
+ UINT32 AckData : 3; ///< 25:27 Ack Data
+ UINT32 BiosMessageAck : 4; ///< 28:31 BIOS Message Ack
+ } r;
+} HECI_FWS_REGISTER;
+
+///
+/// MISC_SHDW
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 MUSZ : 6; ///< 0:5 - ME UMA Size
+ UINT32 Reserved : 8; ///< 6:13 - Reserved
+ UINT32 Reserved2 : 2; ///< 14:15 - Reserved
+ UINT32 MUSZV : 1; ///< 16:16 - ME UMA Size Valid
+ UINT32 Reserved3 : 8; ///< 17:24 - Reserved
+ UINT32 Reserved4 : 6; ///< 25:30 - Reserved
+ UINT32 MSVLD : 1; ///< 31:31 - Miscellaneous Shadow Valid
+ } r;
+} HECI_MISC_SHDW_REGISTER;
+
+///
+/// GS_SHDW
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 BistInProg : 1; ///< 0 - BIST in progress
+ UINT32 IccProgSts : 2; ///< 1:2 - ICC Prog STS
+ UINT32 InvokeMEBx : 1; ///< 3 - Invoke MEBX
+ UINT32 CpuReplacedSts : 1; ///< 4 - CPU Replaced STS
+ UINT32 MbpRdy : 1; ///< 5 - MBP RDY
+ UINT32 MfsFailure : 1; ///< 6 - MFS Failure
+ UINT32 WarmRstReqForDF : 1; ///< 7 - Warm Reset Required for Dynamic Fusing
+ UINT32 CpuReplacedValid : 1; ///< 8 - CPU Replaced Valid
+ UINT32 Reserved : 2; ///< 9:10 - Reserved
+ UINT32 FwUpdIpu : 1; ///< 11 - FW UPD IPU Needed
+ UINT32 Reserved2 : 1; ///< 12 - Reserved
+ UINT32 MbpCleared : 1; ///< 13 - MBP Cleared
+ UINT32 Reserved3 : 2; ///< 14:15 - Reserved
+ UINT32 ExtStatCode1 : 8; ///< 16:23 - EXT Status Code 1
+ UINT32 ExtStatCode2 : 4; ///< 24:27 - EXT Status Code 2
+ UINT32 InfPhaseCode : 4; ///< 31:28 - Infra. Phase code
+ } r;
+} HECI_GS_SHDW_REGISTER;
+
+///
+/// HECI_GS2
+///
+typedef union {
+ UINT32 ul;
+ struct {
+ UINT32 MbpGiveUp : 1; ///< 0 - MBP Give Up
+ UINT32 Reserved :31; ///< 1-31 - Reserved
+ } r;
+} HECI_GS2_REGISTER;
+
+//
+// SEC Current State Values
+//
+#define SEC_STATE_RESET 0x00
+#define SEC_STATE_INIT 0x01
+#define SEC_STATE_RECOVERY 0x02
+#define SEC_STATE_NORMAL 0x05
+#define SEC_STATE_DISABLE_WAIT 0x06
+#define SEC_STATE_TRANSITION 0x07
+#define SEC_STATE_INVALID_CPU 0x08
+
+//
+// SEC Firmware FwInitComplete
+//
+#define SEC_FIRMWARE_COMPLETED 0x01
+#define SEC_FIRMWARE_INCOMPLETED 0x00
+
+//
+// SEC Boot Options Present
+//
+#define SEC_BOOT_OPTIONS_PRESENT 0x01
+#define SEC_BOOT_OPTIONS_NOT_PRESENT 0x00
+
+//
+// SEC Operation State Values
+//
+#define SEC_OPERATION_STATE_PREBOOT 0x00
+#define SEC_OPERATION_STATE_M0_UMA 0x01
+#define SEC_OPERATION_STATE_M3 0x04
+#define SEC_OPERATION_STATE_M0 0x05
+#define SEC_OPERATION_STATE_BRINGUP 0x06
+#define SEC_OPERATION_STATE_M0_ERROR 0x07
+
+//
+// SEC Error Code Values
+//
+#define SEC_ERROR_CODE_NO_ERROR 0x00
+#define SEC_ERROR_CODE_UNKNOWN 0x01
+#define SEC_ERROR_CODE_IMAGE_FAILURE 0x03
+#define SEC_ERROR_CODE_DEBUG_FAILURE 0x04
+
+//
+// Management Engine Current Operation Mode
+//
+#define SEC_OPERATION_MODE_NORMAL 0x00
+
+#define SEC_OPERATION_MODE_ALT_DISABLED 0x02
+#define SEC_OPERATION_MODE_SOFT_TEMP_DISABLE 0x03
+#define SEC_OPERATION_MODE_SECOVR_JMPR 0x04
+#define SEC_OPERATION_MODE_SECOVR_HECI_MSG 0x05
+#define SEC_OPERATION_MODE_IN_FWUPDATE_PROGRESS 0xB
+#pragma pack()
+
+#endif // HECI_REGS_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/Heci2PowerManagementLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/Heci2PowerManagementLib.h
new file mode 100644
index 0000000000..c700790021
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/Heci2PowerManagementLib.h
@@ -0,0 +1,36 @@
+/** @file
+ EFI HECI2 Power Management Library.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_HECI2_POWER_MANAGEMENT_LIB_H
+#define _EFI_HECI2_POWER_MANAGEMENT_LIB_H
+
+#include <Protocol/Heci2Pm.h>
+
+/**
+ Returns an instance of the HECI2 Power Management protocol.
+
+ @params[out] Heci2PmProtocol The address to a pointer to the HECI2 PM protocol.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+GetHeci2PmProtocol (
+ OUT EFI_HECI2_PM_PROTOCOL **Heci2PmProtocol
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h
new file mode 100644
index 0000000000..3c0b25aa63
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h
@@ -0,0 +1,2016 @@
+/** @file
+ Header file for Heci Message functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HECI_MESSAGE_LIB_H_
+#define _HECI_MESSAGE_LIB_H_
+
+#include <CoreBiosMsg.h>
+#include <Protocol/Heci.h>
+#include <Protocol/SeCPlatformPolicy.h>
+#include <HeciRegs.h>
+
+///
+/// Reset Request Origin Codes.
+///
+#define PEI_HECI_REQ_ORIGIN_BIOS_MEMORY_INIT 0x01
+#define PEI_HECI_REQ_ORIGIN_BIOS_POST 0x02
+#define PEI_HECI_REQ_ORIGIN_AMTBX_LAN_DISABLE 0x03
+
+///
+/// Unconfiguration Command status
+///
+#define SEC_UNCONFIG_SUCCESS 0x03
+#define SEC_UNCONFIG_IN_PROGRESS 0x01
+#define SEC_UNCONFIG_NOT_IN_PROGRESS 0x02
+#define SEC_UNCONFIG_ERROR 0x80
+
+#define HECI_EOP_STATUS_SUCCESS 0x0
+#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1
+
+#define EFI_SEC_FW_SKU_VARIABLE_GUID \
+ { \
+ 0xe1a21d94, 0x4a20, 0x4e0e, 0xae, 0x9, 0xa9, 0xa2, 0x1f, 0x24, 0xbb, 0x9e \
+ }
+
+typedef struct {
+ UINT32 SeCEnabled : 1; ///< [0] SEC enabled/Disabled
+ UINT32 Reserved : 12; ///< [12:1] Reserved, must set to 0
+ UINT32 AtSupported : 1; ///< [13] AT Support
+ UINT32 Reserved2 : 18; ///< [31:14] Intel KVM supported
+ UINT32 SeCMinorVer : 16; ///< [47:32] SEC FW Minor Version.
+ UINT32 SeCMajorVer : 16; ///< [63:48] SEC FW Major Version.
+ UINT32 SeCBuildNo : 16; ///< [79:64] SEC FW Build Number.
+ UINT32 SeCHotFixNo : 16; ///< [95:80] SEC FW Hotfix Number
+} SEC_CAP;
+
+#define SET_LOCK_MASK 0
+#define GET_LOCK_MASK 1
+
+#define MAX_ASSET_TABLE_ALLOCATED_SIZE 0x2000
+#define HECI_HWA_CLIENT_ID 11
+#define HWA_TABLE_PUSH_CMD 0
+
+#define MAX_FWU_DATA_SEGMENT_SIZE 128
+#define FWU_PWD_MAX_SIZE 32
+#define HECI2_HMAC_SHA256_SIGNATURE_SIZE 32
+
+//
+// Typedef for the commands serviced by the Fw Update service
+//
+typedef enum {
+ FWU_GET_VERSION = 0,
+ FWU_GET_VERSION_REPLY,
+ FWU_START,
+ FWU_START_REPLY,
+ FWU_DATA,
+ FWU_DATA_REPLY,
+ FWU_END,
+ FWU_END_REPLY,
+ FWU_GET_INFO,
+ FWU_GET_INFO_REPLY,
+ FWU_GET_FEATURE_STATE,
+ FWU_GET_FEATURE_STATE_REPLY,
+ FWU_GET_FEATURE_CAPABILITY,
+ FWU_GET_FEATURE_CAPABILITY_REPLY,
+ FWU_GET_PLATFORM_TYPE,
+ FWU_GET_PLATFORM_TYPE_REPLY,
+ FWU_VERIFY_OEMID,
+ FWU_VERIFY_OEMID_REPLY,
+ FWU_GET_OEMID,
+ FWU_GET_OEMID_REPLY,
+ FWU_IMAGE_COMPATABILITY_CHECK,
+ FWU_IMAGE_COMPATABILITY_CHECK_REPLY,
+ FWU_GET_UPDATE_DATA_EXTENSION,
+ FWU_GET_UPDATE_DATA_EXTENSION_REPLY,
+ FWU_GET_RESTORE_POINT_IMAGE,
+ FWU_GET_RESTORE_POINT_IMAGE_REPLY,
+ FWU_GET_IPU_PT_ATTRB,
+ FWU_GET_IPU_PT_ATTRB_REPLY,
+ FWU_GET_FWU_INFO_STATUS,
+ FWU_GET_FWU_INFO_STATUS_REPLY,
+ GET_ME_FWU_INFO,
+ GET_ME_FWU_INFO_REPLY,
+ FWU_CONFIRM_LIVE_PING,
+ FWU_CONFIRM_LIVE_PING_REPLY,
+ FWU_VERIFY_PWD,
+ FWU_VERIFY_PWD_REPLY,
+ FWU_INVALID_REPLY = 0xFF
+} FWU_HECI_MESSAGE_TYPE;
+
+#define HBM_CMD_ENUM 0x04
+#define HBM_CMD_ENUM_REPLY 0x84
+#define HBM_CMD_CLIENT_PROP 0x05
+#define HBM_CMD_CLIENT_PROP_REPLY 0x85
+#define HBM_CMD_CONNECT 0x06
+#define HBM_CMD_CONNECT_REPLY 0x86
+#define HBM_CMD_DISCONNECT 0x07
+#define HBM_CMD_DISCONNECT_REPLY 0x87
+#define HBM_CMD_FLOW_CONTROL 0x08
+
+#define HECI_HBM_MSG_ADDR 0
+#define HECI_MKHI_FWU_GROUP_ID 0x06
+#define HECI_MKHI_FWUSTATUS_CMD_ID 0x02
+
+#define ONE_SECOND_TIMEOUT 1000000
+#define FWU_TIMEOUT 90
+
+#define IPFU_IN_PROGRESS 0x00
+#define IPFU_TRY_AGAIN 0x01
+#define IPFU_SUCCESS 0x02
+#define IPFU_ERROR 0x03
+#define IPFU_TIMEOUT 60 // 60 Sec
+
+#pragma pack(1)
+
+typedef enum _HWAI_TABLE_TYPE_INDEX {
+ HWAI_TABLE_TYPE_INDEX_FRU_DEVICE = 0,
+ HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE,
+ HWAI_TABLE_TYPE_INDEX_SMBIOS,
+ HWAI_TABLE_TYPE_INDEX_ASF,
+ HWAI_TABLE_TYPE_INDEX_MAX = 4,
+} HWAI_TABLE_TYPE_INDEX;
+
+typedef struct _SINGLE_TABLE_POSITION {
+ UINT16 Offset;
+ UINT16 Length;
+} SINGLE_TABLE_POSITION;
+
+typedef struct _TABLE_PUSH_DATA {
+ SINGLE_TABLE_POSITION Tables[HWAI_TABLE_TYPE_INDEX_MAX];
+ UINT8 TableData[1];
+} TABLE_PUSH_DATA;
+
+typedef union {
+ UINT32 Data;
+ struct {
+ UINT32 MessageLength : 16;
+ UINT32 Command : 4; ///< only supported command would be HWA_TABLE_PUSH=0;
+ UINT32 Reserved : 12;
+ } Fields;
+} AU_MESSAGE_HEADER;
+
+typedef struct _AU_TABLE_PUSH_MSG {
+ AU_MESSAGE_HEADER Header;
+ TABLE_PUSH_DATA Data;
+} AU_TABLE_PUSH_MSG;
+
+typedef struct _UPDATE_FLAGS {
+ UINT32 RestorePoint:1;
+ UINT32 RestartOperation:1;
+ UINT32 UserRollback:1;
+ UINT32 Reserved:29;
+ } UPDATE_FLAGS;
+
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+}OEM_UUID;
+
+typedef struct _VERSION {
+ UINT16 Major;
+ UINT16 Minor;
+ UINT16 Hotfix;
+ UINT16 Build;
+} VERSION;
+
+typedef struct _FWU_GET_VERSION_MSG {
+ UINT32 MessageType;
+} FWU_GET_VERSION_MSG;
+
+typedef struct _FWU_GET_VERSION_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status;
+ UINT32 Sku;
+ UINT32 SCVer;
+ UINT32 Vendor;
+ UINT32 LastFwUpdateStatus;
+ UINT32 HwSku;
+ VERSION CodeVersion;
+ VERSION AMTVersion;
+ UINT16 EnabledUpdateInterfaces;
+ UINT16 SvnInFlash;
+ UINT32 DataFormatVersion;
+ UINT32 LastUpdateResetType;
+} FWU_GET_VERSION_MSG_REPLY;
+
+typedef struct _FWU_GET_OEMID_MSG {
+ UINT32 MessageType;
+} FWU_GET_OEMID_MSG;
+
+typedef struct _FWU_GET_OEMID_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status;
+ OEM_UUID OemId;
+} FWU_GET_OEMID_MSG_REPLY;
+
+typedef struct _FWU_VERIFY_OEMID_MSG {
+ UINT32 MessageType;
+ OEM_UUID OemId;
+} FWU_VERIFY_OEMID_MSG;
+
+typedef struct _FWU_VERIFY_OEMID_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status;
+} FWU_VERIFY_OEMID_MSG_REPLY;
+
+typedef struct _FWU_START_MSG {
+ UINT32 MessageType;
+ UINT32 Length; ///< Length of update image
+ UINT8 UpdateType; ///< 0 Full update, 1 parital update
+ UINT8 PasswordLength; ///< Length of password not include NULL. For BXT, no POR
+ UINT8 PasswordData[FWU_PWD_MAX_SIZE]; ///< Password data not include NULL byte. For BXT, no POR
+ UINT32 IpuIdTobeUpdated; ///< Only for partial FWU
+ UINT32 UpdateEnvironment; ///< 0 default to normal update, 1 for emergency IFR update
+ UPDATE_FLAGS UpdateFlags;
+ OEM_UUID OemId;
+ UINT32 Resv[4];
+} FWU_START_MSG;
+
+typedef struct _FWU_START_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status;
+ UINT32 Resv[4];
+} FWU_START_MSG_REPLY;
+
+typedef struct _FWU_DATA_MSG {
+ UINT32 MesageType;
+ UINT32 Length;
+ UINT8 Reserved[3];
+ UINT8 Data[1];
+} FWU_DATA_MSG;
+
+typedef struct _FWU_DATA_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status;
+} FWU_DATA_MSG_REPLY;
+
+typedef struct _FWU_END_MSG {
+ UINT32 MessageType;
+} FWU_END_MSG;
+
+typedef struct _FWU_END_MSG_REPLY {
+ UINT32 MessageType;
+ UINT32 Status; ///< 0 indicate success, else failure
+ UINT32 ResetType;
+ UINT32 Resv[4];
+}FWU_END_MSG_REPLY;
+
+typedef struct _HBM_ENUM_MSG {
+ UINT8 Cmd;
+ UINT8 Resv[3];
+} HBM_ENUM_MSG;
+
+typedef struct _HBM_ENUM_MSG_REPLY {
+ UINT8 CmdReply;
+ UINT8 Resv[3];
+ UINT32 ValidAddresses[8]; ///<Valid addresses. totally 256 bits. Earch bit corresponding to one address.
+} HBM_ENUM_MSG_REPLY;
+
+typedef struct _HBM_CLIENT_PROP_MSG {
+ UINT8 Cmd;
+ UINT8 Address;
+ UINT8 Resv[2];
+} HBM_CLIENT_PROP_MSG;
+
+typedef struct _HBM_CLIENT_RPOP_MSG_REPLY {
+ UINT8 CmdReply;
+ UINT8 Address;
+ UINT8 Status;
+ UINT8 Resv;
+ OEM_UUID ProtocolName;
+ UINT8 ProtocolVersion;
+ UINT8 MaximumConnections;
+ UINT8 FixedAddress;
+ UINT8 SingleRecvBuffer;
+ UINT32 MaxMessageLength;
+} HBM_CLIENT_PROP_MSG_REPLY;
+
+typedef struct _HBM_CONNECT_MSG {
+ UINT8 Cmd;
+ UINT8 SecAddress;
+ UINT8 HostAddress;
+ UINT8 Resv;
+} HBM_CONNECT_MSG;
+
+typedef struct _HBM_CONNECT_MSG_REPLY {
+ UINT8 CmdReply;
+ UINT8 SecAddress;
+ UINT8 HostAddress;
+ UINT8 Status;
+} HBM_CONNECT_MSG_REPLY;
+
+typedef struct _HBM_DISCONNECT_MSG {
+ UINT8 Cmd;
+ UINT8 SecAddress;
+ UINT8 HostAddress;
+ UINT8 Resv;
+} HBM_DISCONNECT_MSG;
+
+typedef struct _HBM_DISCONNECT_MSG_REPLY {
+ UINT8 CmdReply;
+ UINT8 SecAddress;
+ UINT8 HostAddress;
+ UINT8 Status;
+} HBM_DISCONNECT_MSG_REPLY;
+
+typedef struct _HBM_FLOW_CONTROL_MSG {
+ UINT8 Cmd;
+ UINT8 SecAddress;
+ UINT8 HostAddress;
+ UINT8 Resv[5];
+} HBM_FLOW_CONTROL_MSG;
+
+typedef union _MEFWCAPS_SKU {
+ UINT32 Data;
+ struct {
+ UINT32 FullNet : 1; ///< [0] Full network manageability
+ UINT32 StdNet : 1; ///< [1] Standard network manageability
+ UINT32 Manageability : 1; ///< [2] Manageability
+ UINT32 SmallBusiness : 1; ///< [3] Small business technology
+ UINT32 IntegratedTouch : 1; ///< [4] Intel Integrated Touch
+ UINT32 IntelAT : 1; ///< [5] IntelR Anti-Theft (AT)
+ UINT32 IntelCLS : 1; ///< [6] IntelR Capability Licensing Service (CLS)
+ UINT32 Reserved3 : 3; ///< [9:7] Reserved
+ UINT32 IntelMPC : 1; ///< [10] IntelR Power Sharing Technology (MPC)
+ UINT32 IccOverClocking : 1; ///< [11] ICC Over Clocking
+ UINT32 PAVP : 1; ///< [12] Protected Audio Video Path (PAVP)
+ UINT32 NFF : 1; ///< [13] NFF
+ UINT32 Reserved4 : 3; ///< [16:14] Reserved
+ UINT32 IPV6 : 1; ///< [17] IPV6
+ UINT32 KVM : 1; ///< [18] KVM Remote Control (KVM)
+ UINT32 OCH : 1; ///< [19] Outbreak Containment Heuristic (OCH)
+ UINT32 VLAN : 1; ///< [20] Virtual LAN (VLAN)
+ UINT32 TLS : 1; ///< [21] TLS
+ UINT32 Reserved5 : 1; ///< [22] Reserved
+ UINT32 WLAN : 1; ///< [23] Wireless LAN (WLAN)
+ UINT32 Reserved6 : 5; ///< [28:24] Reserved
+ UINT32 PTT : 1; ///< [29] Platform Trust Technoogy (PTT)
+ UINT32 Reserved7 : 1; ///< [30] Reserved
+ UINT32 NFC : 1; ///< [31] NFC
+ } Fields;
+} MEFWCAPS_SKU;
+
+#pragma pack()
+
+/*
+ ***********************************************
+ * HECI return status definitions:
+ ************************************************
+ */
+
+#define BIOS_HECI_STATUS_OK 0x0
+#define BIOS_HECI_STATUS_INVALID_PARAM 0x1
+#define BIOS_HECI_STATUS_FILE_NOT_FOUND 0x2
+#define BIOS_HECI_STATUS_AFTER_EOP 0x3
+#define BIOS_HECI_STATUS_ERROR 0x4
+
+/*
+ ***********************************************
+ * HECI2 connection definitions:
+ ************************************************
+ */
+
+#define HECI2_BIOS_GUID_RR {0x510f0ecb, 0xd19d, 0x46cd, {0x9c, 0x73, 0xaf, 0x61, 0x80, 0xc6, 0xf5, 0x8d}}
+#define HECI2_BIOS_MAX_WRITE_MSG_SIZE 2048 // Max supported HECI2 transaction size
+#define HECI2_BIOS_MAX_READ_MSG_SIZE 512 // Size of the HECI HW circular buffer
+#define HECI2_BIOS_MCA_FIXED_ADDR 14 // TODO - check this value
+
+/*
+ ***********************************************
+ * HECI2 global definitions:
+ ************************************************
+ */
+
+#define MAX_DIR_NAME 12
+#define MAX_FILE_NAME 25
+#define HECI2_MAX_DATA_SIZE_READ_REQ (HECI2_BIOS_MAX_READ_MSG_SIZE - (sizeof(HECI2_TRUSTED_CHANNEL_BIOS_HEADER) + sizeof(HECI2_READ_DATA_RESP)))
+#define HECI2_MAX_DATA_SIZE_WRITE_REQ (HECI2_BIOS_MAX_WRITE_MSG_SIZE - (sizeof(HECI2_TRUSTED_CHANNEL_BIOS_HEADER) + sizeof(HECI2_WRITE_DATA_REQ)))
+#define MAX_HECI2_WRITE_DATA_SIZE (ALIGN_VALUE (HECI2_MAX_DATA_SIZE_WRITE_REQ, sizeof (UINT32)) - sizeof (UINT32))
+#define MAX_HECI2_READ_DATA_SIZE (ALIGN_VALUE (HECI2_MAX_DATA_SIZE_READ_REQ, sizeof (UINT32)) - sizeof (UINT32))
+/*
+ ***********************************************
+ * HECI2 commands definitions:
+ ************************************************
+ */
+
+#define HECI2_READ_DATA_CMD_ID 0x1
+#define HECI2_WRITE_DATA_CMD_ID 0x2
+#define HECI2_FILE_SIZE_CMD_ID 0x3
+#define HECI2_LOCK_DIR_CMD_ID 0x4
+#define HECI2_GET_PROXY_STATE_CMD_ID 0x5
+#define HECI2_GENERAL_ERR_ID 0xF ///< Response for unknown command-id request
+
+#define HECI2_BIOS_TO_CSE 0x0
+#define HECI2_CSE_TO_BIOS 0x1
+
+#pragma pack(push, 1)
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_HEADER {
+ UINT8 Signature[HECI2_HMAC_SHA256_SIGNATURE_SIZE]; ///< HMAC-SHA2 of the message
+ ///< Note: This signature is not part of the hash
+ UINT8 RequestResponse : 1; ///< Request = 0, Response = 1
+ UINT8 CommandId : 7; ///< Command ID (XXX_CMD_ID)
+ UINT32 MonotonicCounter; ///< Counter value of the request
+ ///< This counter is incremented for each request
+} HECI2_TRUSTED_CHANNEL_BIOS_HEADER;
+
+#pragma pack(pop)
+
+/*
+ ***********************************************
+ * HECI2 Requests
+ ************************************************
+ */
+#pragma pack(push, 1)
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 FileName [MAX_FILE_NAME]; ///< File Name in the BIOS directory
+ UINT32 Offset; ///< Offset within the file
+ UINT16 DataSize; ///< Number of bytes to read
+} HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 FileName [MAX_FILE_NAME]; ///< File Name in the BIOS directory
+ UINT32 Offset; ///< Offset within the file
+ UINT16 DataSize; ///< Number of bytes to write
+ UINT8 Truncate; ///< If set, the file will be truncated
+} HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 FileName [MAX_FILE_NAME]; ///< File Name in the BIOS directory
+} HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_LOCKDIR_REQ {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 FileName [MAX_DIR_NAME]; ///< File Name in the BIOS directory
+} HECI2_TRUSTED_CHANNEL_BIOS_LOCKDIR_REQ;
+
+#pragma pack(pop)
+
+typedef struct _HECI2_READ_DATA_REQ {
+ UINT8 FileName [MAX_FILE_NAME]; ///< File Name in the BIOS directory
+ UINT32 Offset; ///< Offset within the file
+ UINT16 DataSize; ///< number of bytes to read/write
+} HECI2_READ_DATA_REQ;
+
+typedef struct _HECI2_WRITE_DATA_REQ {
+ UINT8 FileName [MAX_FILE_NAME]; /// File Name in the BIOS directory
+ UINT32 Offset; ///< Offset within the file
+ UINT16 DataSize; ///< number of bytes to read/write
+ UINT8 Ttruncate; ///< If set the file will be truncated to length 0 before writing
+} HECI2_WRITE_DATA_REQ;
+
+typedef struct _HECI2_FILE_SIZE_REQ {
+ UINT8 FileName [MAX_FILE_NAME]; ///< File Name in the BIOS directory
+} HECI2_FILE_SIZE_REQ;
+
+typedef struct _HECI2_LOCK_DIR_REQ {
+ UINT8 DirName [MAX_DIR_NAME]; ///< Dir Name in the BIOS directory
+} HECI2_LOCK_DIR_REQ;
+
+
+/*
+ ***********************************************
+ * HECI2 Responses
+ ************************************************
+ */
+#pragma pack(push, 1)
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 Status; ///< Status of the read operation
+ UINT16 DataSize; ///< Number of bytes read
+} HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_WRITE_RESP {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 Status; ///< Number of bytes written
+} HECI2_TRUSTED_CHANNEL_BIOS_WRITE_RESP;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_RESP {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 Status; ///< Status of the read operation
+ UINT32 DataSize; ///< Number of bytes read
+} HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_RESP;
+
+typedef struct _HECI2_TRUSTED_CHANNEL_BIOS_LOCKDIR_RESP {
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER TrustedChannelHeader;
+ UINT8 Status; ///< Number of bytes written
+} HECI2_TRUSTED_CHANNEL_BIOS_LOCKDIR_RESP;
+
+#pragma pack(pop)
+
+typedef struct _HECI2_READ_DATA_RESP {
+ UINT8 Status; ///< Status - see error list defined above
+ UINT16 DataSize; ///< number of bytes read
+} HECI2_READ_DATA_RESP;
+
+typedef struct _HECI2_WRITE_DATA_RESP {
+ UINT8 Status; ///< Status - see error list defined above
+} HECI2_WRITE_DATA_RESP;
+
+typedef struct _HECI2_FILE_SIZE_RESP {
+ UINT8 Status; ///< Status - see error list defined above
+ UINT32 FileSize; ///< File size in bytes
+} HECI2_FILE_SIZE_RESP;
+
+typedef struct _HECI2_LOCK_DIR_RESP {
+ UINT8 Status; ///< Status - see error list defined above
+} HECI2_LOCK_DIR_RESP;
+
+/*
+ ***********************************************
+ * HECI2 BIOS massage definition
+ ************************************************
+ */
+
+typedef struct _HECI2_BIOS_HEADER {
+ UINT8 req_resp : 1; ///< request = 0, response = 1 (HECI2_MSG_TYPE_XXX)
+ UINT8 cmd_id : 7; ///< Command ID (XXX_CMD_ID)
+} HECI2_BIOS_HEADER;
+
+typedef struct _HECI2_BIOS_MASSAGE {
+ HECI2_BIOS_HEADER header;
+ union {
+ HECI2_READ_DATA_REQ readReq;
+ HECI2_WRITE_DATA_REQ writeReq;
+ HECI2_FILE_SIZE_REQ fileSizeReq;
+ HECI2_LOCK_DIR_REQ lockDirReq;
+ HECI2_READ_DATA_RESP readResp;
+ HECI2_WRITE_DATA_RESP writeResp;
+ HECI2_FILE_SIZE_RESP fileSizeResp;
+ HECI2_LOCK_DIR_RESP lockDirResp;
+ UINT8 Status;
+ } Body;
+} HECI2_BIOS_MASSAGE;
+
+typedef struct _WRITE_TO_BIOS_DATA_CMD_REQ_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 FileName [25];
+ UINT32 Offset;
+ UINT16 Size;
+ UINT8 Truncate;
+} WRITE_TO_BIOS_DATA_CMD_REQ_DATA;
+
+typedef struct _WRITE_TO_BIOS_DATA_CMD_CMD_RESP_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 Status;
+} WRITE_TO_BIOS_DATA_CMD_RESP_DATA;
+
+typedef struct _READ_TO_BIOS_DATA_CMD_REQ_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 FileName [25];
+ UINT32 Offset;
+ UINT16 Size;
+} READ_TO_BIOS_DATA_CMD_REQ_DATA;
+
+typedef struct _READ_TO_BIOS_DATA_CMD_CMD_RESP_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 Status; ///< Status - see error list defined above
+ UINT16 DataSize; ///< number of bytes read
+} READ_TO_BIOS_DATA_CMD_RESP_DATA;
+
+typedef struct _GET_FILE_SIZE_CMD_REQ_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 FileName [25];
+} GET_FILE_SIZE_CMD_REQ_DATA;
+
+typedef struct _GET_FILE_SIZE_CMD_CMD_RESP_DATA {
+ HECI2_BIOS_HEADER HECIHeader;
+ UINT8 Status; ///< Status - see error list defined above
+ UINT32 FileSize; ///< number of bytes read
+} GET_FILE_SIZE_CMD_RESP_DATA;
+
+typedef struct _HECI2_GET_PROXY_STATE_REQ {
+ HECI2_BIOS_HEADER Header;
+} HECI2_GET_PROXY_STATE_REQ;
+
+typedef struct _HECI2_GET_PROXY_STATE_RESP {
+ HECI2_BIOS_HEADER Header;
+ UINT8 Status;
+} HECI2_GET_PROXY_STATE_RESP;
+
+#pragma pack()
+
+#define MAX_MCA_FILE_SIZE 4096 ///< biggeset new value of file after set size (in bytes)
+#define MCA_MAX_FILE_PATH_SIZE 255
+#define MCA_MAX_FILE_NAME 25
+
+/**
+********************************************************************************
+** Command types:
+********************************************************************************
+**/
+#define GET_FILE_ATTRIBUTES 0x01
+#define READ_FILE 0x02
+#define SET_FILE 0x03
+#define COMMIT_FILES 0x04
+#define COMMIT_TO_FPF 0x06
+#define RPMC_BIND 0x07
+#define GET_RPMC_STATUS 0x08
+#define CDS_GET_ATTRIBUTES 0x09
+#define CDS_READ_FILE 0x0A
+#define CDS_WRITE_FILE 0x0B
+
+//
+// BXT BIOS HECI massage
+//
+#define HECI1_READ_DATA 0x0C
+#define HECI1_WRITE_DATA 0x0D
+#define HECI1_FILE_SIZE 0x0E
+#define HECI1_REQUEST_DEVICE_OWNERSHIP 0x0F
+#define HECI1_LOCK_BIOS_DIRECTORY 0x10
+#define HECI1_EOS 0x11
+#define MCA_COMMAND_MAX 0x10 ///< any larger type value is illegal
+
+/**
+********************************************************************************
+** Command flags:
+********************************************************************************
+**/
+
+#define NVAR_HASH 0x01
+#define GET_DEFAULT 0x02
+#define TRUNCATE 0x01
+
+/**
+********************************************************************************
+** Manufacturing Command status:
+********************************************************************************
+**/
+
+#define MCA_OK 0x00
+#define MCA_GLOBAL_RESET_REQUIERED 0x01
+#define MCA_ACCESS_DENIED 0x02
+#define MCA_NO_FILE 0x03
+#define MCA_BAD_SEEK 0x04
+#define MCA_READ_FAIL 0x05
+#define MCA_CANT_MALLOC 0x06
+#define MCA_NO_FILE_ATTRIBUTE 0x07
+#define MCA_FILE_NO_MANUF 0x08
+#define MCA_MANUF_NOT_ALLOWED 0x09
+#define MCA_AFTER_LOCK 0x0A
+#define MCA_INVALID_INPUT 0x0B
+#define MCA_RESET_FAILED 0x0C
+#define MCA_SIZE_EXCEED_LIMIT 0x0D
+#define MCA_INVALID_ATTR_HASH 0x0E
+#define MCA_FPF_FILE_NOT_WRITTEN 0x0F
+#define MCA_FPF_INTERNAL 0x10
+#define MCA_FPF_CANARY 0x11
+#define MCA_FPF_FATAL 0x12
+#define MCA_NO_QUOTA 0x13
+#define MCA_GENERAL_ERROR 0x14
+
+#define GROUP_ID_MCA 0xA
+
+#define NFC_BITMASK 0x80000000
+#define CLEAR_FEATURE_BIT 0x00000000
+#define STR_NFC_DISABLED L"Disabled"
+#define STR_NFC_MODULE_1 L""
+#define STR_NFC_MODULE_2 L"NXP PN547"
+#define STR_NFC_MODULE_3 L"NXP"
+
+#define NFC_ENABLED 1
+#define NFC_DISABLED 0
+
+#define PTT_BITMASK 0x20000000 //BIT29
+#define CLEAR_PTT_BIT 0x00000000
+
+typedef enum {
+ BOOT_FROM_EMMC = 0,
+ BOOT_FROM_UFS = 1,
+ BOOT_FROM_SPI = 2
+} BOOT_MEDIA;
+
+#pragma pack(1)
+
+typedef struct _GET_FILESIZE_CMD_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 FileName[MCA_MAX_FILE_NAME];
+} GET_FILESIZE_CMD_REQ_DATA;
+
+typedef struct _GET_FILESIZE_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 FileSize;
+} GET_FILESIZE_CMD_RESP_DATA;
+
+typedef struct _MCA_CDS_WRITE_COMMAND {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 FileName[MCA_MAX_FILE_NAME]; ///< cds file name
+ UINT32 Offset; ///< Offset of file
+ UINT32 Size; ///< Size to read
+ UINT8 Truncate; ///< bit 0 - 1 to truncate ile
+} MCA_CDS_WRITE_COMMAND;
+
+typedef struct _MCA_CDS_READ_COMMAND {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 FileName [12];
+ UINT32 Offset;
+ UINT32 Size;
+
+} MCA_CDS_READ_COMMAND;
+
+typedef struct _MCA_CDS_READ_COMMAND_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 DataSize; ///< number of bytes read
+} MCA_CDS_READ_COMMAND_RESP_DATA;
+
+typedef struct _GET_OWNERSHIP_CMD_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GET_OWNERSHIP_CMD_REQ_DATA;
+
+typedef struct _GET_OWNERSHIP_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GET_OWNERSHIP_CMD_RESP_DATA;
+
+typedef struct _READ_FROM_RPMB_STORAGE_CMD_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 FileName [MCA_MAX_FILE_NAME];
+ UINT32 Offset;
+ UINT32 Size;
+ UINT32 DstAddressLower;
+ UINT32 DstAddressUpper;
+} READ_FROM_RPMB_STORAGE_CMD_REQ_DATA;
+
+typedef struct _READ_FROM_RPMB_STORAGE_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 DataSize;
+} READ_FROM_RPMB_STORAGE_CMD_RESP_DATA;
+
+typedef struct _WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 FileName [MCA_MAX_FILE_NAME];
+ UINT32 Offset;
+ UINT32 Size;
+ UINT32 Truncate;
+ UINT32 SrcAddressLower;
+ UINT32 SrcAddressUpper;
+} WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA;
+
+typedef struct _WRITE_TO_RPMB_STORAGE_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} WRITE_TO_RPMB_STORAGE_CMD_RESP_DATA;
+
+#define EOP_GROUP_ID 0xFF
+#define EOP_CMD_ID 0xC
+#define MKHI_GEN_DNX_GROUP_ID 0x0D
+#define CSE_DNX_REQ_SET 0x1
+#define IAFW_DNX_REQ_CLEAR 0x2
+
+//
+// EOP-REQ
+// End of POST message
+//
+typedef struct _GEN_END_OF_POST {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_END_OF_POST;
+
+typedef struct _GEN_END_OF_SERVICES {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_END_OF_SERVICES;
+
+typedef struct _GEN_END_OF_SERVICES_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_END_OF_SERVICES_ACK;
+
+typedef struct _DATA_CLEAR_LOCK_REQ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} DATA_CLEAR_LOCK_REQ;
+
+typedef struct _DATA_CLEAR_LOCK_RES {
+ MKHI_MESSAGE_HEADER Header;
+} DATA_CLEAR_LOCK_RES;
+
+typedef struct _MBP_CMD_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 Flag;
+} MBP_CMD_REQ_DATA;
+
+typedef struct _MBP_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 Length;
+ UINT8 ItemsNum;
+ UINT8 Flags;
+ UINT8 Reserved;
+} MBP_CMD_RESP_DATA;
+
+typedef struct _IAFW_DNX_REQ_CLEAR_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 Flag;
+} IAFW_DNX_REQ_CLEAR_REQ_DATA;
+
+typedef struct _IAFW_DNX_REQ_CLEAR_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} IAFW_DNX_REQ_CLEAR_RESP_DATA;
+
+typedef struct _IAFW_DNX_REQ_SET_REQ_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} IAFW_DNX_REQ_SET_REQ_DATA;
+
+typedef struct _IAFW_DNX_REQ_SET_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 ReqBiosAction;
+} IAFW_DNX_REQ_SET_RESP_DATA;
+
+typedef struct _MBP_ITEM_HEADER {
+ UINT8 AppID;
+ UINT8 ItemID;
+ UINT8 Length;
+ UINT8 Flag;
+} MBP_ITEM_HEADER;
+
+typedef struct _MBP_CURRENT_BOOT_MEDIA {
+ UINT32 BPDTOffset;
+ UINT32 PhysicalData;
+ UINT32 PhysicalDeviceArea;
+ UINT32 LogicalData;
+} MBP_CURRENT_BOOT_MEDIA;
+
+typedef struct _MBP_IFWI_DNX_REQUEST {
+ UINT32 MbpItemHeader;
+ UINT32 EnterRecovery;
+} MBP_IFWI_DNX_REQUEST;
+
+typedef struct _MBP_SMM_TRUSTED_KEY {
+ UINT8 SmmTrustedKey[32];
+ UINT32 MonotonicCounter;
+} MBP_SMM_TRUSTED_KEY;
+
+typedef struct _MBP_NFC_DEVICE_TYPE {
+ UINT32 MbpItemHeader;
+ UINT32 NfcDeviceData;
+} MBP_NFC_DEVICE_TYPE;
+
+typedef struct _MBP_ME_FW_CAPS {
+ UINT32 MbpItemHeader;
+ MEFWCAPS_SKU CurrentFeatures;
+} MBP_ME_FW_CAPS;
+
+#define MKHI_GEN_GROUP_ID 0xFF
+#define FW_VER_CMD_REQ_ID 0x1C
+#define FW_VERSION_CMD_RESP 0x9A
+#define MAX_IMAGE_MODULE_NUMBER 0x06
+
+typedef struct _FW_VER_CMD_REQ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} FW_VER_CMD_REQ;
+
+typedef struct _MODULE_VERSION_DATA {
+ UINT8 EntryName[12];
+ UINT16 Major;
+ UINT16 Minor;
+ UINT16 Hotfix;
+ UINT16 Build;
+} MODULE_VERSION_DATA;
+
+typedef struct _FW_VERSION_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 NumModules;
+ MODULE_VERSION_DATA ModuleEntries[MAX_IMAGE_MODULE_NUMBER];
+} FW_VERSION_CMD_RESP_DATA;
+
+//
+// IFWI Prepare for Update
+//
+typedef struct _IFWI_PREPARE_FOR_UPDATE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 ResetType;
+} IFWI_PREPARE_FOR_UPDATE;
+
+typedef struct _IFWI_PREPARE_FOR_UPDATE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 Flags;
+} IFWI_PREPARE_FOR_UPDATE_ACK;
+
+//
+// Data Clear
+//
+typedef struct _IFWI_UPDATE_DATA_CLEAR {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} IFWI_UPDATE_DATA_CLEAR;
+
+typedef struct _IFWI_UPDATE_DATA_CLEAR_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} IFWI_UPDATE_DATA_CLEAR_ACK;
+
+//
+// Get ARB Status
+//
+typedef struct _GET_ARB_STATUS {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GET_ARB_STATUS;
+
+typedef struct _GET_ARB_STATUS_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 DirtySvns[16];
+ UINT32 CurSvns[128];
+ UINT32 NewSvns[128];
+ UINT8 EnabledSvns[16];
+ UINT8 DynamicSvns[16];
+} GET_ARB_STATUS_ACK;
+
+//
+// Commit ARB SVN Updates
+//
+typedef struct _COMMIT_ARB_SVN_UPDATES {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 CommitSvns[16];
+} COMMIT_ARB_SVN_UPDATES;
+
+typedef struct _COMMIT_ARB_SVN_UPDATES_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} COMMIT_ARB_SVN_UPDATES_ACK;
+
+//
+// Update Image Check
+//
+typedef struct _IFWI_UPDATE_IMAGE_CHECK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 ImageBaseAddrLower32b;
+ UINT32 ImageBaseAddrUpper32b;
+ UINT32 ImageSize;
+} IFWI_UPDATE_IMAGE_CHECK;
+
+typedef struct _IFWI_UPDATE_IMAGE_CHECK_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 ImageErrorValue;
+ UINT32 ArbSvnDowngradeBitMap[4]; // bit127 - bit0 (16 bytes)
+ UINT8 RollBackPossible;
+} IFWI_UPDATE_IMAGE_CHECK_ACK;
+
+#pragma pack()
+
+
+/**
+ Setup a dynamic connection for FWU.
+
+ @param[in, out] SecAddress Returns the SecAddress to be used by other FWU APIs.
+ @param[out] MaxBufferSize Specifies the maximum buffer size the FWU link allows.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciConnectFwuInterface (
+ IN OUT UINT8 *SecAddress,
+ OUT UINT32 *MaxBufferSize
+ );
+
+
+/**
+ Called by each FWU request API when both sec and host needs to inform each other it's ready to accept any input.
+
+ @param[in] SecAddress Returns the SecAddress to be used by other FWU APIs.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciBiDirectionFlowControl (
+ IN UINT8 SecAddress
+ );
+
+/**
+ Called by each FWU request API when host needs to inform SEC it's ready to accept any input.
+
+ @param[in] SecAddress The dynamic sec address the flow control.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHostToSecFlowControl (
+ IN UINT8 SecAddress
+ );
+
+/**
+ Called by each FWU request API when there's a flow control message expected on the link.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSecToHostFlowControl (
+ );
+
+/**
+ Get firmware version from FWU interface instead of MKHI.
+
+ @param[out] Version Returns the version number of current running SEC FW.
+ @param[in] SecAddress Dynamic sec address for FWU connection.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendFwuGetVersionMsg (
+ OUT VERSION* Version,
+ IN UINT8 SecAddress
+ );
+
+/**
+ Send Local Firmware Update start message to firmware thru HECI. THe HECI link might be disconnectd passively
+ by the SEC side due to unexpected error. Supports full update only.
+
+ @param[in] ImageLength Firmware image length to be updated.
+ @param[in] OemId The OemId to be passed to firmware for verification.
+ @param[in] SecAddress Dynamic sec address for FWU connection.
+ @param[in] MaxBufferSizeMaximum Buffer size for replied message.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendFwuStartMsg (
+ IN UINT32 ImageLength,
+ IN OEM_UUID *OemId,
+ IN UINT8 SecAddress,
+ IN UINT32 MaxBufferSize
+ );
+
+
+/**
+ Send Core BIOS Reset Request Message through HECI.
+
+ @param[in] ResetOrigin Reset source.
+ @param[in] ResetType Global or Host reset.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendCbmResetRequest (
+ IN UINT8 ResetOrigin,
+ IN UINT8 ResetType
+ );
+
+/**
+ Send Reset Request Message through HECI. Used in PEI, included in the HeciMsgLib.
+
+ @param[in] ResetOrigin Reset source.
+ @param[in] ResetType Global or Host reset.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendResetRequest (
+ IN UINT8 ResetOrigin,
+ IN UINT8 ResetType
+ );
+
+
+/**
+ Send Get Firmware SKU Request to Sec.
+
+ @param[in, out] MsgGenGetFwCapsSku Return message for Get Firmware Capability SKU.
+ @param[in, out] MsgGenGetFwCapsSkuAck Return message for Get Firmware Capability SKU ACK.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwCapsSkuMsg (
+ IN OUT GEN_GET_FW_CAPSKU *MsgGenGetFwCapsSku,
+ IN OUT GEN_GET_FW_CAPS_SKU_ACK *MsgGenGetFwCapsSkuAck
+ );
+
+/**
+ Send Get Firmware Version Request to Sec.
+
+ @param[in, out] MsgGenGetFwVersionAck Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwVersionMsg (
+ IN OUT GEN_GET_FW_VER_ACK *MsgGenGetFwVersionAck
+ );
+
+
+/**
+ Sends a message to Sec to unlock a specified SPI Flash region for writing and receiving a response message.
+ It is recommended that HMRFPO_ENABLE HECI message needs to be sent after all OROMs finish their initialization.
+
+ @param[in] Nonce Nonce received in previous HMRFPO_ENABLE Response Message.
+ @param[out] Result HMRFPO_ENABLE response.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoEnable (
+ IN UINT64 Nonce,
+ OUT UINT8 *Result
+ );
+
+/**
+ Sends a message to Sec to lock a specified SPI Flash region for writing and receiving a response message.
+
+ @param[out] Nonce Random number generated by Ignition Sec FW. When BIOS.
+ want to unlock region it should use this value.
+ in HMRFPO_ENABLE Request Message.
+ @param[out] FactoryDefaultBase The base of the factory default calculated from the start of the ME region.
+ BIOS sets a Protected Range (PR) register "Protected Range Base" field with this value.
+ + the base address of the region.
+ @param[out] FactoryDefaultLimit The length of the factory image.
+ BIOS sets a Protected Range (PR) register "Protected Range Limit" field with this value.
+ @param[out] Result Status report.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoLock (
+ OUT UINT64 *Nonce,
+ OUT UINT32 *FactoryDefaultBase,
+ OUT UINT32 *FactoryDefaultLimit,
+ OUT UINT8 *Result
+ );
+
+/**
+ System BIOS sends this message to get status for HMRFPO_LOCK message.
+
+ @param[out] Result HMRFPO_GET_STATUS response.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoGetStatus (
+ OUT UINT8 *Result
+ );
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to query the local firmware update interface status.
+
+ @param[out] RuleData 1 - local firmware update interface enable
+ 0 - local firmware update interface disable
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetLocalFwUpdate (
+ OUT UINT32 *RuleData
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to enable or disable the local firmware update interface.
+ The firmware allows a single update once it receives the enable command.
+
+ @param[in] RuleData 1 - local firmware update interface enable
+ 0 - local firmware update interface disable
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciSetLocalFwUpdate (
+ IN UINT8 RuleData
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to enable the Sec State. The firmware allows a single
+ update once it receives the enable command. Once firmware receives this message,
+ the firmware will be in normal mode after a global reset.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS ME enabled message sent.
+
+**/
+EFI_STATUS
+HeciSetSeCEnableMsg (
+ IN VOID
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to disable the Sec State. The firmware allows a single
+ update once it receives the disable command Once firmware receives this message,
+ the firmware will work in "Soft Temporary Disable" mode (HFS[19:16] = 3) after a
+ global reset. Note, this message is not allowed when AT firmware is enrolled/configured.
+
+ @param[in] RuleData Rule data
+ 0 - Disable
+ 1 - Enable
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Sec is disabled.
+
+**/
+EFI_STATUS
+HeciSetSeCDisableMsg (
+ IN UINT8 ruleData
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ Consumer or Corporate SKU size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetPlatformTypeMsg (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ );
+
+
+/**
+ The firmware will respond to GET OEM TAG message even after the End of Post (EOP).
+
+ @param[out] RuleData Default is zero. Tool can create the OEM specific OEM TAG data.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetOemTagMsg (
+ OUT UINT32 *RuleData
+ );
+
+
+/**
+ Sends the MKHI Enable/Disable manageability message.
+
+ @param[in] EnableState Enable Bit Mask
+ @param[in] DisableState Disable Bit Mask
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+HeciFwFeatureStateOverride (
+ IN UINT32 EnableState,
+ IN UINT32 DisableState
+ );
+
+/**
+ The Get FW Feature Status message is based on MKHI interface.
+ This command is used by BIOS/IntelR MEBX to get firmware runtime status.
+ The GET FW RUNTIME STATUS message doesn't need to check the HFS.
+ FWInitComplete value before sending the command.
+ It means this message can be sent regardless of HFS.FWInitComplete.
+
+ @param[out] RuleData MEFWCAPS_SKU message.
+
+ @retval EFI_UNSUPPORTED Current ME mode doesn't support this function.
+ @retval EFI_SUCCESS HECI interfaces disabled by Sec.
+
+**/
+EFI_STATUS
+HeciGetFwFeatureStateMsg (
+ OUT SECFWCAPS_SKU *RuleData
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to disable the SEC State.
+ The firmware allows a single update once it receives the disable command.
+
+ @param[out] CmdStatus Return command status.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciSeCUnconfigurationMsg (
+ OUT UINT32 *CmdStatus
+ );
+
+/**
+ This message is sent by the BIOS prior to the End of Post (EOP) on the boot
+ where host wants to Unconfigure the SEC State.
+
+ @param[in] CmdStatus // return the data
+ 0 = SEC_UNCONFIG_SUCCESS
+ 1 = SEC_UNCONFIG_IN_PROGRESS
+ 2 = SEC_UNCONFIG_NOT_IN_PROGRESS
+ 3 = SEC_UNCONFIG_ERROR
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciSeCUnconfigurationStatusMsg (
+ IN UINT32 *CmdStatus
+ );
+
+/**
+ HeciSendDIDMessage
+
+ @param[in] UMABase
+ @param[in] UMASize
+ @param[out] BiosAction
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+HeciSendDIDMessage (
+ UINT32 UMABase,
+ UINT8 IsS3,
+ UINT32 *UMASize,
+ UINT8 *BiosAction
+ );
+
+
+/**
+ BIOS requests the size of a specific file.
+
+ @param[in] FileName File Name in the BIOS directory.
+ @param[OUT] FileSize Number of bytes to read.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid parameters.
+ @retval EFI_NOT_FOUND File not found.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+HeciGetNVMFileSize (
+ IN UINT8 *FileName,
+ OUT UINTN *FileSize
+ );
+
+/**
+ BIOS requests to write data to directory.
+
+ @param[in] FileName File Name in the BIOS directory.
+ @param[in] Offset Offset in bytes, within a file.
+ @param[in] Data Data to be written.
+ @param[in] DataSize Number of bytes to write.
+ @param[in] Truncate Truncate the file.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid parameters.
+ @retval EFI_NOT_FOUND File not found.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+HeciWriteNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN Truncate
+ );
+
+/**
+ BIOS requests variable from its directory.
+
+ @param[in] FileName File Name in the BIOS directory.
+ @param[in] Offset Offset in bytes, within a file.
+ @param[OUT] Data Data to be read.
+ @param[OUT] DataSize Number of bytes to read.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid parameters.
+ @retval EFI_NOT_FOUND File not found.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+HeciReadNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ OUT UINT8 *Data,
+ OUT UINTN *DataSize
+ );
+
+/**
+ Lock Directory message through HECI2.
+
+ @param[in] DirName The Directory name.
+ @param[in] Heci2Protocol The HECI protocol to send the message to HECI2 device.
+
+ @retval EFI_SUCCESS Send EOP message success.
+ @retval Others Send EOP message failed.
+
+**/
+EFI_STATUS
+Heci2LockDirectory (
+ IN UINT8 *DirName,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ );
+
+/**
+ Get proxy state through HECI.
+
+ @param[in] Heci2Protocol HECI2 protocol
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+Heci2GetProxyStateNoResp (
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ );
+
+/**
+ Returns whether trusted channel is enabled.
+
+ @param[in] None.
+
+ @retval TRUE if trusted channel is enabled.
+ @retval FALSE if trusted channel is disabled.
+
+**/
+BOOLEAN
+IsTrustedChannelEnabled (
+ VOID
+);
+
+/**
+ Updates the SHA256 signature and monotonic counter fields of a HECI message header.
+
+ @param[in] MessageHeader A pointer to the message header.
+ @param[in] TotalHeaderSize The total header size.
+ @param[in] TotalDataSize The total data size.
+
+ @retval Whether the header could be updated.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateTrustedHeader (
+ IN OUT UINT8 *MessageHeader,
+ IN UINT32 TotalHeaderSize,
+ IN UINT32 TotalDataSize
+ );
+
+/**
+ Write data to NVM file through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data content.
+ @param[in] DataSize Data's size.
+ @param[in] Truncate Truncate the file.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid parameters.
+ @retval EFI_NOT_FOUND File not found.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+.
+**/
+EFI_STATUS
+Heci2WriteNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN Truncate
+ );
+
+/**
+ BIOS requests to write data to directory without response.
+
+ @param[in] FileName File Name in the BIOS directory.
+ @param[in] Offset Offset in bytes, within a file.
+ @param[in] Data Data to be written.
+ @param[in] DataSize Number of bytes to write.
+ @param[in] Heci2Protocol HECI2 protocol.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid parameters.
+ @retval EFI_NOT_FOUND File not found.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+Heci2WriteNVMFileNoResp(
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ );
+
+/**
+ Read NVM file data through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[out] Data The data buffer.
+ @param[in, out] DataSize Data's size.
+
+ @retval EFI_SUCCESS Read NVM file success.
+ @retval Others Read NVM file failed.
+
+**/
+EFI_STATUS
+Heci2ReadNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ OUT UINT8 *Data,
+ IN OUT UINTN *DataSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ );
+
+EFI_STATUS
+Heci2ReadNVMFileNoResp (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN *DataSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ );
+
+/**
+ Send End of Post Request Message through HECI.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciEndOfPost (
+ );
+
+/**
+ BIOS send End of Services Message through HECI.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciEndOfServices(
+ );
+
+/**
+ The CSE returns the version number for each module.
+
+ @param[out] MsgGetFwVersionRespData Return Firmware version response data.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetImageFwVerMsg (
+ OUT FW_VERSION_CMD_RESP_DATA *MsgGetFwVersionRespData
+ );
+
+/**
+ Send IAFW DNX request set message throught HECI1.
+
+ @param[in] Resp Buffer to receive the CSE response data.
+
+ @retval EFI_SUCCESS Set request success.
+ @retval Others Set request failed.
+
+**/
+EFI_STATUS
+HeciIafwDnxReqSet (
+ IN OUT IAFW_DNX_REQ_SET_RESP_DATA *Resp
+ );
+
+/**
+ Send IAFW DnX require clear command to CSE.
+
+ @param[in] Flag Require flag.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciIafwDnxReqClear (
+ IN UINT32 Flag
+ );
+
+/**
+ The Get FW Feature Status message is based on MKHI interface.
+ This command is used by BIOS/IntelR MEBX to get firmware runtime status.
+ The GET FW RUNTIME STATUS message doesn't need to check the HFS.
+ FWInitComplete value before sending the command.
+ It means this message can be sent regardless of HFS.FWInitComplete.
+
+ @param[out] RuleData MEFWCAPS_SKU message.
+
+ @retval EFI_UNSUPPORTED Current ME mode doesn't support this function.
+
+**/
+EFI_STATUS
+HeciGetFwFeatureStateMsgII (
+ OUT MEFWCAPS_SKU *RuleData
+ );
+
+/**
+ Get NFC device type from CSE.
+
+ @param[in] Mbp_Nfc_Device_Type NFC Device type data.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetNfcDeviceType (
+ IN MBP_NFC_DEVICE_TYPE *Mbp_Nfc_Device_Type
+ );
+
+/**
+ Get ME FW Capability from MBP.
+
+ @param[out] MBP_ME_FW_CAPS Output data buffer for ME FW Capability.
+
+ @retval EFI_SUCCESS Get ME FW Capability success.
+ @retval Others Get ME FW Capability failed.
+
+**/
+
+EFI_STATUS
+HeciGetMeFwCapability (
+ OUT MBP_ME_FW_CAPS *Mbp_Me_Fw_Caps
+ );
+
+/**
+ Get IFWI DnX request data.
+
+ @param[in] IfwiDnxRequestData IFWI DnX request data.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetIfwiDnxRequest (
+ IN MBP_IFWI_DNX_REQUEST *IfwiDnxRequestData
+ );
+
+/**
+ Send IFWI PREPARE FOR UPDATE(IPFU) Command through HECI1.
+ This command provide necessary synchronization between HOST & CSE when
+ BIOS Performance IFWI Update process.
+
+ @retval EFI_SUCCESS Send IFWI Prepare For Update command succeeded
+ @retval Others Send IFWI Prepare For Update command failed.
+
+**/
+EFI_STATUS
+HeciIfwiPrepareForUpdate (
+ VOID
+ );
+
+/**
+ Send RPMB/Device Extention region Data Clear message through HECI1.
+
+ @retval EFI_SUCCESS Send DataClear message success.
+ @retval Others Send DataClear message failed.
+
+**/
+EFI_STATUS
+HeciDataClear (
+ VOID
+ );
+
+/**
+ Send 'Update Image Check' command to CSE to verify IFWI Image and confirm
+ that appropriate for FW Update. (This command will be sending as part of Capsule Update)
+
+ @param[in] ImageBaseAddr FW Image Base address. 64 Bit Wide
+ @param[in] ImageSize FW Image Size
+ @param[in] *HeciResponse To capture Response Info (Optional)
+ @param[in] ResponseSize Size of Response (Optional)
+
+ @return EFI_SUCCESS Image was checked (best effort) and verified to be appropriate for FW update.
+ @return 0x01 IMAGE_FAILED.
+ @return 0x02 IMG_SIZE_INVALID.
+ @return 0x05 SIZE_ERROR
+ @return 0x89 STATUS_NOT_SUPPORTED.
+ @return 0x8D STATUS_INVALID_COMMAND.
+ @return 0xFF STATUS_UNDEFINED.
+
+**/
+EFI_STATUS
+HeciUpdateImageCheck (
+ IN UINT64 ImageBaseAddr,
+ IN UINT32 ImageSize,
+ IN OUT UINT32 *HeciResponse,
+ IN UINT32 ResponseSize
+ );
+
+/**
+ Checks Platform Trust Technology enablement state.
+
+ @param[out] IsPttEnabledState TRUE if PTT is enabled, FALSE othewrwise.
+
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHeciGetState (
+ OUT BOOLEAN *IsPttEnabledState
+ );
+
+/**
+ Changes current Platform Trust Technology state.
+
+ @param[in] PttEnabledState TRUE to enable, FALSE to disable.
+
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHeciSetState (
+ IN BOOLEAN PttEnabledState
+ );
+
+//
+// -----------------------------------------------------------------------------------------------------------------------
+// PEI Phase protocol declaration
+// -----------------------------------------------------------------------------------------------------------------------
+//
+/**
+ Send Get Firmware SKU Request to SEC.
+
+ @param[in, out] FwCapsSku SEC Firmware Capability SKU.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetFwCapsSkuMsg (
+ IN OUT SECFWCAPS_SKU *FwCapsSku
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX. One of usages is to utilize
+ this command to determine if the platform runs in Consumer or Corporate SKU
+ size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetPlatformTypeMsg (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX. To Get Firmware Version Request to SEC.
+
+ @param[in, out] MsgGenGetFwVersionAck Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetFwVersionMsg (
+ IN OUT GEN_GET_FW_VER_ACK *MsgGenGetFwVersionAck
+ );
+
+/**
+ Wait for CSE reset bit set and then Reset HECI interface.
+
+ @param[out] Reset_Status Reset Status value.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+CheckCseResetAndIssueHeciReset (
+ OUT BOOLEAN *Reset_Status
+ );
+
+typedef struct {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+} CORE_BIOS_DONE;
+
+typedef struct {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+} CORE_BIOS_DONE_ACK;
+
+#define COREBIOS_DONE 1
+#define COREBIOS_NOT_DONE 0
+
+VOID
+EFIAPI
+HeciCoreBiosDoneMsg (
+ void
+ );
+
+EFI_STATUS
+HeciDataClearLock (
+ VOID
+ );
+
+VOID
+EFIAPI
+HeciDXECallback (
+ IN EFI_EVENT Event,
+ IN VOID *ParentImageHandle
+ );
+
+/**
+ Get SMM Trusted Key.
+
+ @param[out] SmmTrustedKeyData Smm trusted data buffer.
+
+ @retval EFI_SUCCESS Get SMM Trusted success.
+ @retval Others Get SMM Trusted failed.
+
+**/
+EFI_STATUS
+HeciGetSMMTrustedKey (
+ OUT MBP_SMM_TRUSTED_KEY *SmmTrustedKeyData
+ );
+
+/**
+ Get ARB Status
+ Send 'Get ARB Status' command to CSE to get ARB Status information in the received buffer.
+ Host Calls this API on boot after ifwi update.
+
+ @param[out] GetArbStatus Structure filled with ARB status info.
+
+ @retval EFI_SUCCESS SVN info populated correctly. Refer ARB Out put structure for info.
+ @retval other values Refer BIOS CSE Interface document.
+
+**/
+EFI_STATUS
+HeciGetArbStatus (
+ IN OUT GET_ARB_STATUS_ACK *GetArbStatus
+ );
+
+/**
+ Commit ARB SVN Updates
+ Send 'Commit ARB SVN Updates' command to CSE to commit ARB SVN information.
+ Host Calls this API on boot after ifwi update.
+
+ @param[in] CommitSvns Structure filled with ARB SVN Commit info.
+
+ @retval EFI_SUCCESS SVN info populated correctly. Refer ARB Out put structure for info.
+ @retval other values Refer BIOS CSE Interface document.
+
+**/
+EFI_STATUS
+HeciCommitArbSvnUpdates (
+ IN UINT8 *CommitSvns
+ );
+
+/**
+ BIOS requests to write bios2ish file for ISH.
+
+ @param[in] Ish2CseData Pointer to ish2cse binary includeing Header .
+
+ @retval EFI_SUCCESS Command succeeded.
+
+**/
+EFI_STATUS
+HeciWriteIshNVMFile (
+ IN ISH_SRV_HECI_SET_FILE_REQUEST *Ish2CseData
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h
new file mode 100644
index 0000000000..71003802f2
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h
@@ -0,0 +1,126 @@
+/** @file
+ Platform Trust Technology (FTPM) PTP (Platform TPM Profile) Device Library.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PTT_PTP_DEVICE_LIB_H_
+#define _PTT_PTP_DEVICE_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <PttPtpRegs.h>
+
+///
+/// Default Timeout values
+///
+#define PTT_HCI_TIMEOUT_A 750 * 1000 ///< 750 ms
+#define PTT_HCI_TIMEOUT_B 2000 * 1000 ///< 2 s
+#define PTT_HCI_TIMEOUT_C 200 * 1000 ///< 200 ms
+#define PTT_HCI_TIMEOUT_D 30 * 1000 ///< 30 ms
+#define PTT_HCI_TIMEOUT_E 30 * 1000 * 1000 ///< 30 s
+#define PTT_HCI_POLLING_PERIOD 140 ///< Poll register every 140 microsecondss
+
+#define PTT_HCI_RESPONSE_HEADER_SIZE 12 ///< TPM2_RESPONSE_HEADER size
+#define TPM_LOCALITY_BUFFER_SIZE 0x10000 ///< Locality Buffer Size
+
+typedef enum {
+ TPM_LOCALITY_0 = 0,
+ TPM_LOCALITY_1 = 1,
+ TPM_LOCALITY_2 = 2,
+ TPM_LOCALITY_3 = 3,
+ TPM_LOCALITY_4 = 4,
+} TPM_LOCALITY_ENUM;
+
+/**
+ Checks whether FTPM is enabled (FTPM_STS::FTPM_EN).
+
+ @param[in] None
+
+ @retval TRUE FTPM is enabled.
+ @retval FALSE FTPM is disabled. All LT writes will be dropped.
+ All LT reads will be returned with read data value of all 0's.
+ The bit can only be written once per ME power cycle.
+
+**/
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck (
+ VOID
+ );
+
+BOOLEAN
+EFIAPI
+PttHciStartupExecuted (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciRequestCommandExec (
+ VOID
+ );
+
+
+EFI_STATUS
+EFIAPI
+PttHciWaitRegisterBits (
+ IN EFI_PHYSICAL_ADDRESS RegAddress,
+ IN UINT32 BitSet,
+ IN UINT32 BitClear,
+ IN UINT32 TimeOut
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciSend (
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciReceive (
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand (
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ );
+
+/**
+ Checks whether PTT is Ready
+
+ @param[in] None
+
+ @retval TRUE PTT is ready.
+ @retval FALSE PTT is not ready
+
+**/
+BOOLEAN
+EFIAPI
+PttHciReadyCheck (
+ VOID
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCChipsetLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCChipsetLib.h
new file mode 100644
index 0000000000..e6f4ca0bd0
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCChipsetLib.h
@@ -0,0 +1,47 @@
+/** @file
+ Header file for SEC Chipset Lib.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_CHIPSET_LIB_H_
+#define _SEC_CHIPSET_LIB_H_
+
+typedef enum {
+ HECI1 = 0,
+ HECI2,
+ HECI3,
+ FTPM = 7
+} SEC_DEVICE;
+
+typedef enum {
+ Disabled = 0,
+ Enabled
+} SEC_DEVICE_FUNC_CTRL;
+
+
+/**
+ Enable/Disable SEC devices
+
+ @param[in] WhichDevice Select of SEC device
+ @param[in] DeviceFuncCtrl Function control
+
+ @retval None
+**/
+VOID
+SeCDeviceControl (
+ IN SEC_DEVICE WhichDevice,
+ IN SEC_DEVICE_FUNC_CTRL DeviceFuncCtrl
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCLib.h
new file mode 100644
index 0000000000..80c7860033
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCLib.h
@@ -0,0 +1,145 @@
+/** @file
+ Header file for SeC functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_LIB_H_
+#define _SEC_LIB_H_
+
+#include "SeCPolicyLib.h"
+#include "HeciMsgLib.h"
+
+/**
+ Check if SeC is enabled.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval EFI_SUCCESS Command succeeded
+
+**/
+EFI_STATUS
+SeCLibInit (
+ VOID
+ );
+
+/**
+ Host client gets Firmware update info from SEC client
+
+ @param[in, out] SECCapability Structure of FirmwareUpdateInfo
+
+ @retval EFI_SUCCESS Command succeeded
+
+**/
+EFI_STATUS
+HeciGetSeCFwInfo (
+ IN OUT SEC_CAP *SECCapability
+ );
+
+/**
+ Send Get Firmware SKU Request to SEC.
+
+ @param[in] FwCapsSku Return Data from Get Firmware Capabilities MKHI Request.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwCapsSku (
+ IN SECFWCAPS_SKU *FwCapsSku
+ );
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get Ibex Peak platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ 4M or 8M size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelSeCFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetPlatformType (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ );
+
+/**
+ Send Get Firmware Version Request to SEC.
+
+ @param[in,out] MsgGenGetFwVersionAckData Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwVersion (
+ IN OUT GEN_GET_FW_VER_ACK_DATA *MsgGenGetFwVersionAckData
+ );
+
+/**
+ Dummy return for SeC signal event use.
+
+ @param[in] Event The event that triggered this notification function.
+ @param[in] ParentImageHandle Pointer to the notification functions context.
+
+ @return EFI_SUCCESS Always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+SeCEmptyEvent (
+ IN EFI_EVENT Event,
+ IN void *ParentImageHandle
+ );
+
+/**
+ Get AT State Information From Stored SEC platform policy.
+
+ @param[in, out] AtState Pointer to AT State Information.
+ @param[in, out] AtLastTheftTrigger Pointer to Variable holding the cause of last AT Stolen Stae.
+ @param[in, out] AtLockState Pointer to variable indicating whether AT is locked or not.
+ @param[in, out] AtAmPref Pointer to variable indicating whether TDTAM or PBA should be used.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+GetAtStateInfo (
+ IN OUT UINT8 *AtState,
+ IN OUT UINT8 *AtLastTheftTrigger,
+ IN OUT UINT16 *AtLockState,
+ IN OUT UINT16 *AtAmPref
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCPolicyLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCPolicyLib.h
new file mode 100644
index 0000000000..9313c2253a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCPolicyLib.h
@@ -0,0 +1,118 @@
+/** @file
+ Header file for SeC Policy functionality.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_POLICY_LIB_H_
+#define _SEC_POLICY_LIB_H_
+
+#include <Protocol/SeCPlatformPolicy.h>
+
+/**
+ Check if SeC is enabled
+
+ @param[in] None
+
+ @retval None
+
+**/
+EFI_STATUS
+SeCPolicyLibInit (
+ VOID
+ );
+
+/**
+ Check if End of Post Message is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE EndOfPost is disabled.
+ @retval TRUE EndOfPost is enabled.
+
+**/
+BOOLEAN
+SeCHECIEnabled (
+ VOID
+ );
+
+/**
+ Check if End of Post Message is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE EndOfPost is disabled.
+ @retval TRUE EndOfPost is enabled.
+
+**/
+BOOLEAN
+SeCEndOfPostEnabled (
+ VOID
+ );
+
+/**
+ Check if Thermal Reporting Message is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE Thermal Reporting is disabled.
+ @retval TRUE Thermal Reporting is enabled.
+
+**/
+BOOLEAN
+SeCTrEnabled (
+ VOID
+ );
+
+/**
+ Show SeC Error message.
+
+ @param[in] MsgId SeC error message ID.
+
+ @retval None
+
+**/
+VOID
+SeCReportError (
+ IN SEC_ERROR_MSG_ID MsgId
+ );
+
+/**
+ Check if SeCFwDowngrade is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE SeCFwDowngrade is disabled.
+ @retval TRUE SeCFwDowngrade is enabled.
+
+**/
+BOOLEAN
+SeCFwDowngradeSupported (
+ VOID
+ );
+
+/**
+ Check if integarted touch is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE itouch is disabled.
+ @retval TRUE itouch is enabled.
+
+**/
+BOOLEAN
+SeCITouchEnabled (
+ VOID
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h
new file mode 100644
index 0000000000..1f86fb8a08
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h
@@ -0,0 +1,793 @@
+/** @file
+ MKHI Messages.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MKHI_MSGS_H
+#define _MKHI_MSGS_H
+
+#pragma pack(1)
+
+#define BIOS_FIXED_HOST_ADDR 0
+#define PREBOOT_FIXED_SEC_ADDR 7
+#define BIOS_ASF_HOST_ADDR 1
+
+#define HECI_CORE_MESSAGE_ADDR 0x07
+#define HECI_ASF_MESSAGE_ADDR 0x02
+#define HECI_FSC_MESSAGE_ADDR 0x03
+#define HECI_POLICY_MANAGER_ADDR 0x05
+#define HECI_TDT_MESSAGE_ADDR 0x05 // Added to support TDT
+#define HECI_SEC_PASSWORD_SERVICE_ADDR 0x06
+#define HECI_ICC_MESSAGE_ADDR 0x08
+#define HECI_TR_MESSAGE_ADDR 0x09
+#define HECI_SPI_MESSAGE_ADDR 0x0A
+#define HECI_ISH_MESSAGE_ADDR 0X03
+
+#define NON_BLOCKING 0
+#define BLOCKING 1
+#define LONG_BLOCKING 2
+
+//
+// command handle by HCI
+//
+#define GEN_GET_MKHI_VERSION_CMD 0x01
+#define GEN_GET_MKHI_VERSION_CMD_ACK 0x81
+#define GEN_GET_FW_VERSION_CMD 0x02
+#define GEN_GET_FW_VERSION_CMD_ACK 0x82
+#define GEN_UNCFG_WO_PWD_CMD 0x0D
+#define GEN_UNCFG_WO_PWD_CMD_ACK 0x8D
+
+#define FWCAPS_GET_RULE_CMD 0x02
+#define FWCAPS_SET_RULE_CMD 0x03
+
+#define TDT_SEC_RULE_ID 0xd0000
+
+#define SEC_SUCCESS 0x00
+#define SEC_ERROR_ALIAS_CHECK_FAILED 0x01
+#define SEC_INVALID_MESSAGE 0x02
+#define SEC_M1_DATA_OLDER_VER 0x03
+#define SEC_M1_DATA_INVALID_VER 0x04
+#define SEC_INVALID_M1_DATA 0x05
+
+#define MDES_ENABLE_MKHI_CMD 0x09
+#define MDES_ENABLE_MKHI_CMD_ACK 0x89
+
+//
+// Manageability State Control
+//
+#define FIRMWARE_CAPABILITY_OVERRIDE_CMD 0x14
+#define FIRMWARE_CAPABILITY_OVERRIDE_CMD_ACK 0x94
+
+//
+// Unconfiguration
+//
+#define SEC_UNCONFIGURATION_CMD 0x0d
+#define SEC_UNCONFIGURATION_CMD_ACK 0x8D
+#define SEC_UNCONFIGURATION_STATUS 0x0e
+#define SEC_UNCONFIGURATION_STATUS_ACK 0x8e
+
+//
+// IFWI Update
+//
+#define MKHI_IFWI_UPDATE_GROUP_ID 0x20
+#define MKHI_SECURE_BOOT_GROUP_ID 0x0C
+
+//
+// Under MKHI_IFWI_UPDATE_GROUP_ID
+//
+#define IFWI_PREPARE_FOR_UPDATE_CMD_ID 0x01
+#define DATA_CLEAR_CMD_ID 0x02
+#define DATA_CLEAR_LOCK_CMD_ID 0x04
+#define UPDATE_IMAGE_CHECK_CMD_ID 0x06
+
+//
+// Under MKHI_SECURE_BOOT_GROUP_ID
+//
+#define VERIFY_MANIFEST_CMD_ID 0x01
+#define GET_ARB_STATUS_CMD_ID 0x02
+#define COMMIT_ARB_SVN_UPDATES_CMD_ID 0x03
+
+#define HECI_MCA_CORE_BIOS_DONE_CMD 0x05
+#define HECI_MKHI_MCA_GROUP_ID 0x0A
+
+
+//
+// Typedef for GroupID
+//
+typedef enum {
+ MKHI_CBM_GROUP_ID = 0,
+ MKHI_PM_GROUP_ID,
+ MKHI_PWD_GROUP_ID,
+ MKHI_FWCAPS_GROUP_ID,
+ MKHI_APP_GROUP_ID,
+ MKHI_SPI_GROUP_ID,
+ MKHI_MDES_GROUP_ID = 8,
+ MKHI_MAX_GROUP_ID,
+ MKHI_GEN_GROUP_ID = 0xFF
+} MKHI_GROUP_ID;
+
+//
+// Typedef for AT State
+//
+typedef enum _TDT_STATE {
+ TDT_STATE_INACTIVE = 0,
+ TDT_STATE_ACTIVE,
+ TDT_STATE_STOLEN,
+ TDT_STATE_SUSPEND,
+ TDT_STATE_MAX
+} TDT_STATE;
+
+typedef union _MKHI_MESSAGE_HEADER {
+ UINT32 Data;
+ struct {
+ UINT32 GroupId : 8;
+ UINT32 Command : 7;
+ UINT32 IsResponse : 1;
+ UINT32 Reserved : 8;
+ UINT32 Result : 8;
+ } Fields;
+} MKHI_MESSAGE_HEADER;
+
+typedef struct _CBM_EOP_ACK_DATA {
+ UINT32 RequestedActions;
+} CBM_EOP_ACK_DATA;
+
+typedef struct _GEN_END_OF_POST_ACK {
+ MKHI_MESSAGE_HEADER Header;
+ CBM_EOP_ACK_DATA Data;
+} GEN_END_OF_POST_ACK;
+
+typedef struct _DRAM_INIT_DONE_IMRS_REQ_DATA {
+ UINT32 BiosImrDisable[2];
+ UINT32 BiosMinImrsBa;
+} DRAM_INIT_DONE_IMRS_REQ_DATA;
+
+typedef struct _DRAM_INIT_DONE_REQ_FLAGS {
+ UINT8 FfsEntryExit :1;
+ UINT8 NonDestructiveAliasCheck :1;
+ UINT8 Rsvd :6;
+} DRAM_INIT_DONE_REQ_FLAGS;
+
+typedef struct _DRAM_INIT_DONE_CMD_REQ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ DRAM_INIT_DONE_IMRS_REQ_DATA ImrData;
+ DRAM_INIT_DONE_REQ_FLAGS Flags;
+ UINT8 MemStatus;
+ UINT8 Reserved[2];
+} DRAM_INIT_DONE_CMD_REQ;
+
+typedef struct _DRAM_INIT_DONE_IMRS_RESP_DATA {
+ UINT32 ImrsSortedRegionBa;
+ UINT32 ImrsSortedRegionLen;
+ UINT8 OemSettingsRejected;
+ UINT8 Rsvd[3];
+} DRAM_INIT_DONE_IMRS_RESP_DATA;
+
+typedef struct _DRAM_INIT_DONE_CMD_RESP_DATA {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ DRAM_INIT_DONE_IMRS_RESP_DATA ImrsData;
+ UINT8 BiosAction;
+ UINT8 Reserved[3];
+} DRAM_INIT_DONE_CMD_RESP_DATA;
+
+#define COMMON_GROUP_ID 0xF0
+#define DRAM_INIT_DONE_CMD 0x01
+
+///
+/// Memory Init Status codes
+///
+#define BIOS_MSG_DID_SUCCESS 0
+#define BIOS_MSG_DID_NO_MEMORY 0x1
+#define BIOS_MSG_DID_INIT_ERROR 0x2
+#define BIOS_MSG_DID_MEM_NOT_PRESERVED 0x3
+
+typedef struct _DRAM_INIT_DONE_CMD_RESP {
+ MKHI_MESSAGE_HEADER MkhiHeader;
+ UINT32 Reset_Request;
+ UINT32 IMRActualBase;
+ UINT32 IMRTotalSize;
+ UINT32 Flag;
+} DRAM_INIT_DONE_CMD_RESP;
+
+///
+/// BIOS action codes
+///
+#define DID_ACK_NON_PCR 0x1
+#define DID_ACK_PCR 0x2
+#define DID_ACK_RSVD3 0x3
+#define DID_ACK_RSVD4 0x4
+#define DID_ACK_RSVD5 0x5
+#define DID_ACK_GRST 0x6
+#define DID_ACK_CONTINUE_POST 0x7
+
+#define MBP_CMD 0x2
+#define MAX_MBP_SIZE 0x1000
+
+typedef union _MKHI_VERSION {
+ UINT32 Data;
+ struct {
+ UINT32 Minor : 16;
+ UINT32 Major : 16;
+ } Fields;
+} MKHI_VERSION;
+
+typedef struct _FW_VERSION {
+ UINT32 CodeMinor : 16;
+ UINT32 CodeMajor : 16;
+ UINT32 CodeBuildNo : 16;
+ UINT32 CodeHotFix : 16;
+ UINT32 RcvyMinor : 16;
+ UINT32 RcvyMajor : 16;
+ UINT32 RcvyBuildNo : 16;
+ UINT32 RcvyHotFix : 16;
+} FW_VERSION;
+
+typedef struct _GEN_GET_MKHI_VERSION {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GET_MKHI_VERSION;
+
+typedef struct _GET_MKHI_VERSION_ACK_DATA {
+ MKHI_VERSION MKHIVersion;
+} GET_MKHI_VERSION_ACK_DATA;
+
+typedef struct _GEN_GET_MKHI_VERSION_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_MKHI_VERSION_ACK_DATA Data;
+} GEN_GET_MKHI_VERSION_ACK;
+
+//
+// FW version messages
+//
+typedef struct _GEN_GET_FW_VER {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GET_FW_VER;
+
+typedef struct _GEN_GET_FW_VER_ACK_DATA {
+ UINT32 CodeMinor :16; // Same as firmware fields
+ UINT32 CodeMajor :16; // same as firmware fields
+ UINT32 CodeBuildNo :16; // same as firmware fields
+ UINT32 CodeHotFix :16; // same as firmware fields
+ UINT32 RcvyMinor :16; // Same as firmware fields
+ UINT32 RcvyMajor :16; // same as firmware fields
+ UINT32 RcvyBuildNo :16; // same as firmware fields
+ UINT32 RcvyHotFix :16; // same as firmware fields
+ UINT32 FITCMinor :16; // same as firmware fields
+ UINT32 FITCMajor :16; // same as firmware fields
+ UINT32 FITCBuildNo :16; // same as firmware fields
+ UINT32 FITCHotFix :16; // same as firmware fields
+
+} GEN_GET_FW_VER_ACK_DATA;
+
+typedef struct _GEN_GET_FW_VER_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GET_FW_VER_ACK_DATA Data;
+} GEN_GET_FW_VER_ACK;
+
+typedef union _GEN_GET_FW_VER_ACK_BUFFER {
+ GEN_GET_FW_VER Request;
+ GEN_GET_FW_VER_ACK Response;
+} GEN_GET_FW_VER_ACK_BUFFER;
+
+//
+// Unconfig without password messages
+//
+typedef struct _GEN_UNCFG_WO_PWD {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_UNCFG_WO_PWD;
+
+typedef struct _GEN_UNCFG_WO_PWD_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_UNCFG_WO_PWD_ACK;
+
+//
+// Get Firmware Capability MKHI
+//
+typedef struct _GET_RULE_DATA {
+ UINT32 RuleId;
+} GET_RULE_DATA;
+
+typedef struct _GEN_GET_FW_CAPSKU {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_GET_FW_CAPSKU;
+
+typedef union _RULE_ID {
+ UINT32 Data;
+ struct {
+ UINT32 RuleTypeId : 16;
+ UINT32 FeatureId : 8;
+ UINT32 Reserved : 8;
+ } Fields;
+} RULE_ID;
+
+typedef struct _SET_RULE_DATA {
+ RULE_ID RuleId;
+ UINT8 RuleDataLen;
+ UINT32 RuleData;
+} SET_RULE_DATA;
+
+typedef struct _SET_RULE_ACK_DATA {
+ UINT32 RuleId;
+} SET_RULE_ACK_DATA;
+
+typedef struct _GEN_SET_FW_CAPSKU {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ SET_RULE_DATA Data;
+} GEN_SET_FW_CAPSKU;
+
+typedef struct _GEN_SET_FW_CAPSKU_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ SET_RULE_ACK_DATA Data;
+} GEN_SET_FW_CAPSKU_ACK;
+
+typedef union _SECFWCAPS_SKU {
+ UINT32 Data;
+ struct {
+ UINT32 Reserved : 5; ///< [4:0] Reserved
+ UINT32 IntelAT : 1; ///< [5] IntelR Anti-Theft (AT)
+ UINT32 Reserved1 : 4; ///< [9:6] Reserved
+ UINT32 IntelMPC : 1; ///< [10] IntelR Power Sharing Technology (MPC)
+ UINT32 IccOverClocking : 1; ///< [11] ICC Over Clocking
+ UINT32 PAVP : 1; ///< [12] Protected Audio Video Path (PAVP)
+ UINT32 Reserved2 : 4; ///< [16:13] Reserved
+ UINT32 IPV6 : 1; ///< [17] IPV6
+ UINT32 KVM : 1; ///< [18] KVM Remote Control (KVM)
+ UINT32 OCH : 1; ///< [19] Outbreak Containment Heuristic (OCH)
+ UINT32 VLAN : 1; ///< [20] Virtual LAN (VLAN)
+ UINT32 TLS : 1; ///< [21] TLS
+ UINT32 Reserved4 : 1; ///< [22] Reserved
+ UINT32 WLAN : 1; ///< [23] Wireless LAN (WLAN)
+ UINT32 Reserved5 : 8; ///< [31:24] Reserved
+ } Fields;
+} SECFWCAPS_SKU;
+
+typedef struct _TDT_STATE_FLAG {
+ UINT16 LockState : 1; ///< Indicate whether the platform is locked
+ UINT16 AuthenticateModule : 1; ///< Preferred Authentication Module
+ UINT16 Reserved : 14;
+} TDT_STATE_FLAG;
+
+typedef struct _TDT_STATE_INFO {
+ UINT8 State;
+ UINT8 LastTheftTrigger;
+ TDT_STATE_FLAG flags;
+} TDT_STATE_INFO;
+
+typedef struct {
+ UINT8 AtState; ///< State of AT FW
+ UINT8 AtLastTheftTrigger; ///< Reason for the last trigger
+ UINT16 AtLockState; ///< If AT Fw locked?
+ UINT16 AtAmPref; ///< TDTAM or PBA
+} AT_STATE_STRUCT;
+
+typedef struct _GEN_GET_FW_CAPS_SKU_ACK_DATA {
+ UINT32 RuleID;
+ UINT8 RuleDataLen;
+ SECFWCAPS_SKU FWCapSku;
+} GEN_GET_FW_CAPS_SKU_ACK_DATA;
+
+typedef struct _GEN_GET_FW_CAPSKU_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GET_FW_CAPS_SKU_ACK_DATA Data;
+} GEN_GET_FW_CAPS_SKU_ACK;
+
+typedef union _GEN_GET_FW_CAPS_SKU_BUFFER {
+ GEN_GET_FW_CAPSKU Request;
+ GEN_GET_FW_CAPS_SKU_ACK Response;
+} GEN_GET_FW_CAPS_SKU_BUFFER;
+
+typedef enum {
+ UPDATE_DISABLED = 0,
+ UPDATE_ENABLED
+} LOCAL_FW_UPDATE;
+
+typedef enum {
+ LOCAL_FW_ALWAYS = 0,
+ LOCAL_FW_NEVER,
+ LOCAL_FW_RESTRICTED,
+} LOCAL_FW_QUALIFIER;
+
+typedef struct _GEN_LOCAL_FW_UPDATE_DATA {
+ UINT32 RuleId;
+ UINT8 RuleDataLen;
+ UINT32 RuleData;
+} GEN_LOCAL_FW_UPDATE_DATA;
+
+typedef struct _GEN_GET_LOCAL_FW_UPDATE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_GET_LOCAL_FW_UPDATE;
+
+typedef struct _GEN_GET_LOCAL_FW_UPDATE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_LOCAL_FW_UPDATE_DATA Data;
+} GEN_GET_LOCAL_FW_UPDATE_ACK;
+
+typedef struct _GEN_SET_LOCAL_FW_UPDATE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_LOCAL_FW_UPDATE_DATA Data;
+} GEN_SET_LOCAL_FW_UPDATE;
+
+typedef struct _GEN_SET_LOCAL_FW_UPDATE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_SET_LOCAL_FW_UPDATE_ACK;
+
+typedef enum {
+ NO_BRAND = 0,
+ INTEL_AMT_BRAND,
+ INTEL_STAND_MANAGEABILITY_BRAND,
+ INTEL_LEVEL_III_MANAGEABILITY_UPGRADE_BRAND,
+} PLATFORM_BRAND;
+
+typedef enum {
+ INTEL_SEC_IGN_FW = 1,
+ RESERVED_FW,
+ INTEL_SEC_1_5MB_FW,
+ INTEL_SEC_5MB_FW,
+} SEC_IMAGE_TYPE;
+
+#define REGULAR_SKU 0
+#define SUPER_SKU 1
+
+#define PLATFORM_MARKET_CORPORATE 1
+#define PLATFORM_MARKET_CONSUMER 2
+
+#define PLATFORM_MOBILE 1
+#define PLATFORM_DESKTOP 2
+#define PLATFORM_SERVER 4
+#define PLATFORM_WORKSTATION 8
+
+typedef union _PLATFORM_TYPE_RULE_DATA {
+ UINT32 Data;
+ struct {
+ UINT32 PlatformTargetUsageType : 4;
+ UINT32 PlatformTargetMarketType : 2;
+ UINT32 SuperSku : 1;
+ UINT32 Reserved : 1;
+ UINT32 IntelSeCFwImageType : 4;
+ UINT32 PlatformBrand : 4;
+ UINT32 Reserved1 : 16;
+ } Fields;
+} PLATFORM_TYPE_RULE_DATA;
+
+typedef struct _GEN_PLATFORM_TYPE_DATA {
+ UINT32 RuleId;
+ UINT8 RuleDataLen;
+ PLATFORM_TYPE_RULE_DATA RuleData;
+ UINT8 Reserved[27];
+} GEN_PLATFORM_TYPE_DATA;
+
+typedef struct _GEN_GET_PLATFORM_TYPE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_GET_PLATFORM_TYPE;
+
+typedef struct _GEN_GET_PLATFORM_TYPE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_PLATFORM_TYPE_DATA Data;
+} GEN_GET_PLATFORM_TYPE_ACK;
+
+typedef union _GEN_GET_PLATFORM_TYPE_BUFFER {
+ GEN_GET_PLATFORM_TYPE Request;
+ GEN_GET_PLATFORM_TYPE_ACK Response;
+} GEN_GET_PLATFORM_TYPE_BUFFER;
+
+typedef struct _GET_TDT_SEC_RULE_CMD {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 RuleId;
+} GET_TDT_SEC_RULE_CMD;
+
+typedef struct _GET_TDT_SEC_RULE_RSP {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 RuleId;
+ UINT8 RuleDataLength;
+ TDT_STATE_INFO TdtRuleData;
+} GET_TDT_SEC_RULE_RSP;
+
+typedef struct _GET_FW_FEATURE_STATUS {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_GET_FW_FEATURE_STATUS;
+
+typedef struct _GET_FW_FEATURE_STATUS_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 RuleId;
+ UINT8 RuleDataLength;
+ SECFWCAPS_SKU RuleData;
+} GEN_GET_FW_FEATURE_STATUS_ACK;
+
+typedef struct _GEN_AMT_BIOS_SYNCH_INFO {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_AMT_BIOS_SYNCH_INFO;
+
+typedef struct _GEN_AMT_BIOS_SYNCH_INFO_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 RuleId;
+ UINT8 RuleDataLength;
+ UINT32 RuleData;
+} GEN_AMT_BIOS_SYNCH_INFO_ACK;
+
+typedef struct _GEN_GET_OEM_TAG_MSG {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GET_RULE_DATA Data;
+} GEN_GET_OEM_TAG_MSG;
+
+typedef struct _GEN_GET_OEM_TAG_MSG_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT32 RuleId;
+ UINT8 RuleDataLength;
+ UINT32 RuleData;
+} GEN_GET_OEM_TAG_MSG_ACK;
+
+typedef struct _GEN_MDES_ENABLE_MKHI_CMD_MSG {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ UINT8 Data;
+} GEN_MDES_ENABLE_MKHI_CMD_MSG;
+
+typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_DATA {
+ UINT32 EnableFeature;
+ UINT32 DisableFeature;
+} FIRMWARE_CAPABILITY_OVERRIDE_DATA;
+
+typedef struct _FIRMWARE_CAPABILITY_OVERRIDE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ FIRMWARE_CAPABILITY_OVERRIDE_DATA FeatureState;
+} FIRMWARE_CAPABILITY_OVERRIDE;
+
+typedef enum _FIRMWARE_CAPABILITY_RESPONSE {
+ SET_FEATURE_STATE_ACCEPTED = 0,
+ SET_FEATURE_STATE_REJECTED
+} FIRMWARE_CAPABILITY_RESPONSE;
+
+typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA {
+ FIRMWARE_CAPABILITY_RESPONSE Response;
+} FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA;
+
+typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_ACK {
+ MKHI_MESSAGE_HEADER Header;
+ FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA Data;
+} FIRMWARE_CAPABILITY_OVERRIDE_ACK;
+
+typedef struct _GEN_GET_IFWI_VER {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GET_IFWI_VER;
+
+typedef struct _GEN_GET_IFWI_VER_ACK_DATA {
+ UINT32 IFWIvendor :32;
+ UINT32 IFWIMajor :16;
+ UINT32 IFWIMinor :16;
+ UINT32 hotfix :16;
+ UINT32 build :16;
+} GEN_GET_IFWI_VER_ACK_DATA;
+
+typedef struct _GEN_GET_IFWI_VER_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GET_IFWI_VER_ACK_DATA Data;
+} GEN_GET_IFWI_VER_ACK;
+
+typedef struct _GEN_GET_RPMB_CONFIG_FILE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GET_RPMB_CONFIG_FILE;
+
+typedef struct _GEN_GET_RPMB_CONFIG_FILE_DATA {
+ UINT32 DataSize;
+ UINT32 Data1;
+ UINT32 Data2;
+ UINT32 Data3;
+ UINT32 Data4;
+ UINT32 Data5;
+} GEN_GET_RPMB_CONFIG_FILE_DATA;
+
+typedef struct _GEN_GET_RPMB_CONFIG_FILE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GET_RPMB_CONFIG_FILE_DATA Data;
+} GEN_GET_RPMB_CONFIG_FILE_ACK;
+
+typedef struct _GEN_SET_RPMB_CONFIG_FILE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_SET_RPMB_CONFIG_FILE;
+
+typedef struct _GEN_SET_RPMB_CONFIG_FILE_DATA {
+ UINT32 DataSize;
+ UINT32 Data1;
+ UINT32 Data2;
+ UINT32 Data3;
+ UINT32 Data4;
+ UINT32 Data5;
+} GEN_SET_RPMB_CONFIG_FILE_DATA;
+
+typedef struct _GEN_SET_RPMB_CONFIG_FILE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_SET_RPMB_CONFIG_FILE_DATA Data;
+} GEN_SET_RPMB_CONFIG_FILE_ACK;
+
+typedef struct _GEN_BOOT_PARTITION_READ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_BOOT_PARTITION_READ;
+
+typedef struct _GEN_BOOT_PARTITION_READ_DATA {
+ UINT32 BPID;
+ UINT32 Offset;
+ UINT32 Size;
+ UINT32 DataSize;
+ UINT32 Data1;
+ UINT32 Data2;
+ UINT32 Data3;
+ UINT32 Data4;
+ UINT32 Data5;
+} GEN_BOOT_PARTITION_READ_DATA;
+
+typedef struct _GEN_BOOT_PARTITION_READ_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_BOOT_PARTITION_READ_DATA Data;
+} GEN_BOOT_PARTITION_READ_ACK;
+
+typedef struct _GEN_MASS_STORAGE_READ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_MASS_STORAGE_READ;
+
+typedef struct _GEN_MASS_STORAGE_READ_DATA {
+ UINT32 DestAddrL;
+ UINT32 DestAddrU;
+ UINT32 PartType;
+ UINT32 PartitionIndex;
+ UINT32 Offset;
+ UINT32 Size;
+} GEN_MASS_STORAGE_READ_DATA;
+
+typedef struct _GEN_MASS_STORAGE_READ_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_MASS_STORAGE_READ_DATA Data;
+} GEN_MASS_STORAGE_READ_ACK;
+
+typedef struct _GEN_REQUEST_DEVICE_OWNERSHIP {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_REQUEST_DEVICE_OWNERSHIP;
+
+typedef struct _GEN_REQUEST_DEVICE_OWNERSHIP_DATA {
+ UINT32 FinalFlag;
+} GEN_REQUEST_DEVICE_OWNERSHIP_DATA;
+
+typedef struct _GEN_REQUEST_DEVICE_OWNERSHIP_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_REQUEST_DEVICE_OWNERSHIP_DATA Data;
+} GEN_REQUEST_DEVICE_OWNERSHIP_ACK;
+
+typedef struct _GEN_GRANT_DEVICE_OWNERSHIP {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GRANT_DEVICE_OWNERSHIP;
+
+typedef struct _GEN_GRANT_DEVICE_OWNERSHIP_DATA {
+ UINT32 FinalFlag;
+} GEN_GRANT_DEVICE_OWNERSHIP_DATA;
+
+typedef struct _GEN_GRANT_DEVICE_OWNERSHIP_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GRANT_DEVICE_OWNERSHIP_DATA Data;
+} GEN_GRANT_DEVICE_OWNERSHIP_ACK;
+
+typedef struct _GEN_SMIP_READ {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_SMIP_READ;
+
+typedef struct _GEN_SMIP_READ_DATA {
+ UINT32 SMIPRegion;
+ UINT32 SMIPOffset;
+ UINT32 NumBytes;
+} GEN_SMIP_READ_DATA;
+
+typedef struct _GEN_SMIP_READ_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_SMIP_READ_DATA Data;
+} GEN_SMIP_READ_ACK;
+
+typedef struct _GEN_AUTH_POLICY_MANIFEST {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_AUTH_POLICY_MANIFEST;
+
+typedef struct _GEN_AUTH_POLICY_MANIFEST_DATA {
+ UINT32 status;
+} GEN_AUTH_POLICY_MANIFEST_DATA;
+
+typedef struct _GEN_AUTH_POLICY_MANIFEST_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_AUTH_POLICY_MANIFEST_DATA Data;
+} GEN_AUTH_POLICY_MANIFEST_ACK;
+
+typedef struct _GEN_BOOT_TYPE {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_BOOT_TYPE;
+
+typedef struct _GEN_BOOT_TYPE_DATA {
+ UINT32 status;
+} GEN_BOOT_TYPE_DATA;
+
+typedef struct _GEN_BOOT_TYPE_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_BOOT_TYPE_DATA Data;
+} GEN_BOOT_TYPE_ACK;
+
+typedef struct _GEN_AUTH_KERNEL {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_AUTH_KERNEL;
+
+typedef struct _GEN_AUTH_KERNEL_DATA {
+ UINT32 status;
+} GEN_AUTH_KERNEL_DATA;
+
+typedef struct _GEN_AUTH_KERNEL_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_AUTH_KERNEL_DATA Data;
+} GEN_AUTH_KERNEL_ACK;
+
+typedef struct _GEN_RSA_OFFLOAD {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_RSA_OFFLOAD;
+
+typedef struct _GEN_RSA_OFFLOAD_DATA {
+ UINT32 status;
+} GEN_RSA_OFFLOAD_DATA;
+
+typedef struct _GEN_RSA_OFFLOAD_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_RSA_OFFLOAD_DATA Data;
+} GEN_RSA_OFFLOAD_ACK;
+
+typedef struct _GEN_GET_MBP {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_GET_MBP;
+
+typedef struct _GEN_GET_MBP_DATA {
+ UINT32 status;
+} GEN_GET_MBP_DATA;
+
+typedef struct _GEN_GET_MBP_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_GET_MBP_DATA Data;
+} GEN_GET_MBP_ACK;
+
+typedef struct _GEN_LOAD_OBB {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+} GEN_LOAD_OBB;
+
+
+typedef struct _GEN_LOAD_OBB_DATA {
+ UINT32 status;
+} GEN_LOAD_OBB_DATA;
+
+typedef struct _GEN_LOAD_OBB_ACK {
+ MKHI_MESSAGE_HEADER MKHIHeader;
+ GEN_LOAD_OBB_DATA Data;
+} GEN_LOAD_OBB_ACK;
+
+typedef struct _ISH_SRV_HECI_REQUEST_HEADER {
+ UINT16 Command;
+ UINT16 Length;
+} ISH_SRV_HECI_REQUEST_HEADER;
+
+typedef struct _ISH_SRV_HECI_SET_FILE_REQUEST {
+ ISH_SRV_HECI_REQUEST_HEADER Header;
+ CHAR8 FileName[12];
+} ISH_SRV_HECI_SET_FILE_REQUEST;
+
+typedef struct _ISH_SRV_HECI_STATUS_REPLY {
+ ISH_SRV_HECI_REQUEST_HEADER Header;
+ UINT32 Status;
+} ISH_SRV_HECI_STATUS_REPLY;
+
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h
new file mode 100644
index 0000000000..3227a07729
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h
@@ -0,0 +1,42 @@
+/** @file
+ EFI HECI PPI.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HECI_PPI_H
+#define _HECI_PPI_H
+
+#include <SeCState.h>
+#include <Protocol/Heci.h>
+
+typedef struct _EFI_HECI_PPI EFI_HECI_PPI;
+
+///
+/// The interface functions are for sending/receiving HECI messages between host and CSE in PEI phase.
+///
+typedef struct _EFI_HECI_PPI {
+ EFI_HECI_SENDWACK SendwACK;
+ EFI_HECI_READ_MESSAGE ReadMsg;
+ EFI_HECI_SEND_MESSAGE SendMsg;
+ EFI_HECI_RESET ResetHeci;
+ EFI_HECI_INIT InitHeci;
+ EFI_HECI_RESET_WAIT SeCResetWait;
+ EFI_HECI_REINIT ReInitHeci;
+ EFI_HECI_GET_SEC_STATUS GetSeCStatus;
+ EFI_HECI_GET_SEC_MODE GetSeCMode;
+} EFI_HECI_PPI;
+
+extern EFI_GUID gEfiHeciPpiGuid;
+
+#endif // _HECI_PPI_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h
new file mode 100644
index 0000000000..59c2613a6f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h
@@ -0,0 +1,90 @@
+/** @file
+ Interface definition details for SEC and UMA.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_UMA_PPI_H_
+#define _SEC_UMA_PPI_H_
+
+#define SEC_UMA_PPI_GUID \
+ { \
+ 0xcbd86677, 0x362f, 0x4c04, 0x94, 0x59, 0xa7, 0x41, 0x32, 0x6e, 0x05, 0xcf \
+ }
+
+#define CSE_EMMC_SELECT_PPI_GUID \
+ { \
+ 0x1e30e33d, 0x1854, 0x437a, 0xbd, 0x68, 0xfc, 0x15, 0x53, 0xaa, 0x8b, 0xe4 \
+ }
+
+#define CSE_UFS_SELECT_PPI_GUID \
+ { \
+ 0xc5a6189e, 0x8c33, 0x4ac6, 0xae, 0x9a, 0xae, 0xd1, 0x8c, 0xab, 0xe2, 0x6d \
+ }
+
+#define CSE_SPI_SELECT_PPI_GUID \
+ { \
+ 0xd35eda81, 0x07d0, 0x4142, 0x94, 0x9, 0xb0, 0x72, 0x33, 0xed, 0x2d, 0x7 \
+ }
+
+extern EFI_GUID gSeCUmaPpiGuid;
+extern EFI_GUID gCseEmmcSelectPpiGuid;
+extern EFI_GUID gCseUfsSelectPpiGuid;
+extern EFI_GUID gCseSpiSelectPpiGuid;
+
+//
+// Revision
+//
+#define SEC_UMA_PPI_REVISION 1
+
+//
+// define the MRC recommended boot modes.
+//
+typedef enum {
+ s3Boot, // In current implementation, bmS3 == bmWarm
+ warmBoot,
+ coldBoot,
+ fastBoot,
+} MRC_BOOT_MODE_T;
+
+typedef
+EFI_STATUS
+(EFIAPI *SEC_SEND_UMA_SIZE) (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *SEC_CONFIG_DID_REG) (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ MRC_BOOT_MODE_T MrcBootMode,
+ UINT8 InitStat,
+ UINT32 SeCUmaBase,
+ UINT32 *SeCUmaSize
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *SEC_TAKE_OWNER_SHIP) (
+ );
+
+//
+// Interface definition details for SEC and UMA
+//
+typedef struct SEC_UMA_PPI {
+ SEC_SEND_UMA_SIZE SeCSendUmaSize;
+ SEC_CONFIG_DID_REG SeCConfigDidReg;
+ SEC_TAKE_OWNER_SHIP SeCTakeOwnerShip;
+} SEC_UMA_PPI;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Private/Library/HeciInitLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Private/Library/HeciInitLib.h
new file mode 100644
index 0000000000..0e719dfb11
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Private/Library/HeciInitLib.h
@@ -0,0 +1,330 @@
+/** @file
+ Header File for HECI Init Lib functionality.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef _HECI_INIT_LIB_H
+#define _HECI_INIT_LIB_H
+
+#define B_EXCLUSION BIT8
+
+UINT32
+MmIoReadDword (
+ UINTN a
+ );
+
+VOID
+MmIoWriteDword (
+ UINTN a,
+ UINT32 b
+ );
+
+//
+// Function Prototype declarations
+//
+EFI_STATUS
+WaitForSECReady (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+HeciReset (
+ IN HECI_DEVICE HeciDev
+ );
+
+EFI_STATUS
+ HeciTakeOwnerShip (
+ );
+
+/**
+ Determines if the HECI device is present and, if present, initializes it for
+ use by the BIOS.
+
+ @param[in] HECI Device
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+InitializeHeciPrivate (
+ IN HECI_DEVICE HeciDev
+ );
+
+
+/**
+ CheckAndFixHeciForAccess
+ This function gets HECI device PCI base address and checks for HECI device availability and provides HECI Device MBAR
+ after enabling Device specific BME, MSE and SERR.
+
+ @param[in] HeciDev HECI Device Number
+
+ @retval Corresponding HECI Device MBAR
+
+**/
+UINTN
+CheckAndFixHeciForAccess (
+ IN HECI_DEVICE HeciDev
+ );
+
+EFI_STATUS
+EFIAPI
+Heci2SendwACK (
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+EFI_STATUS
+EFIAPI
+Heci2SendwoACK (
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+EFI_STATUS
+EFIAPI
+HeciSendwoACK (
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+EFI_STATUS
+HeciGetBootDevice (
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData
+ );
+
+/**
+ HeciMBP
+
+ @param[in] MBPData
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+HeciMBP (
+ UINT32 * MBPData
+ );
+
+/**
+ DumpBuffer_HECI
+
+ @param[in] Buffer1
+
+ @return None
+
+**/
+VOID
+DumpBuffer_HECI (
+ VOID *Buffer1,
+ UINT8 Buffersize
+ );
+
+//
+// DXE-HECI Protocol Function Prototype declarations
+//
+/**
+ Function sends one messsage through the HECI circular buffer and waits
+ for the corresponding ACK message.
+
+ @param[in,out] Message Pointer to the message buffer.
+ @param[in] SendLength Length of the message in bytes.
+ @param[in,out] RecLength Length of the message response in bytes.
+ @param[in] HostAddress Address of the sending entity.
+ @param[in] SeCAddress Address of the ME entity that should receive the message.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSendwACK (
+ IN HECI_DEVICE HeciDev,
+ IN OUT UINT32 *Message,
+ IN OUT UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+/**
+ Reads a message from the SEC across HECI.
+
+ @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING.
+ @param[out] MessageData Pointer to a buffer used to receive a message.
+ @param[in,out] Length Pointer to the length of the buffer on input and the length
+ of the message on return. (in bytes)
+
+ @retval EFI_STATUS
+
+**/
+
+EFI_STATUS
+EFIAPI
+HeciReceive (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Blocking,
+ IN OUT UINT32 *MessageBody,
+ IN OUT UINT32 *Length
+ );
+
+/**
+ Function sends one messsage (of any length) through the HECI circular buffer.
+
+ @param[in] Message Pointer to the message data to be sent.
+ @param[in] Length Length of the message in bytes.
+ @param[in] HostAddress The address of the host processor.
+ @param[in] SeCAddress Address of the ME subsystem the message is being sent to.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSend (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *Message,
+ IN UINT32 Length,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+/**
+ Function forces a reinit of the heci interface by following the reset heci interface via host algorithm
+
+ @param[in] none
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+ResetHeciInterface (
+ IN HECI_DEVICE HeciDev
+ );
+
+//
+// Prototypes
+//
+/**
+ Determines if the HECI device is present and, if present, initializes it for
+ use by the BIOS.
+
+ @param[in] None
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciInitialize (
+ IN HECI_DEVICE HeciDev
+ );
+
+/**
+ Heci Re-initializes it for Host
+
+ @param[in] None
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciReInitialize (
+ IN HECI_DEVICE HeciDev
+ );
+
+/**
+ SeC reset and waiting for ready
+
+ @param[in] Delay The biggest waiting time
+
+ @retval EFI_TIMEOUT Time out
+ @retval EFI_SUCCESS SeC ready
+
+**/
+EFI_STATUS
+EFIAPI
+SeCResetWait (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Delay
+ );
+
+/**
+ Return SEC Status.
+
+ @param[in] SeCStatus Pointer for status report
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciGetSeCStatus (
+ IN UINT32 *SeCStatus
+ );
+
+/**
+ Return SEC Status
+
+ @param[in] SeCStatus Pointer for status report
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciGetSeCMode (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *SeCMode
+ );
+
+/**
+ Function sends bios2ish bin file to CSE through HECI circular buffer and waits
+ for the corresponding ACK message.
+
+ @param[in] Message Pointer to the send message buffer.
+ @param[out] Message Pointer to the receive message buffer.
+ @param[in] SendLength Length of the message in bytes.
+ @param[in, out] RecLength Length of the message response in bytes.
+ @param[in] HostAddress Address of the sending entity.
+ @param[in] SeCAddress Address of the ME entity that should receive the message.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciIshSendwAck (
+ IN HECI_DEVICE HeciDev,
+ IN VOID *SendMessage,
+ OUT VOID *ReceiveMessage,
+ IN UINT32 SendLength,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci.h
new file mode 100644
index 0000000000..4defb074d9
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci.h
@@ -0,0 +1,111 @@
+/** @file
+ EFI HECI Protocol.
+
+ Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_HECI_H
+#define _EFI_HECI_H
+
+#include <SeCState.h>
+#include <SeCChipset.h>
+
+typedef struct _EFI_HECI_PROTOCOL EFI_HECI_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_SENDWACK) (
+ IN HECI_DEVICE HeciDev,
+ IN OUT UINT32 *Message,
+ IN OUT UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SECAddress
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_READ_MESSAGE) (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Blocking,
+ IN UINT32 *MessageBody,
+ IN OUT UINT32 *Length
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_SEND_MESSAGE) (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *Message,
+ IN UINT32 Length,
+ IN UINT8 HostAddress,
+ IN UINT8 SECAddress
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_RESET) (
+ IN HECI_DEVICE HeciDev
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_INIT) (
+ IN HECI_DEVICE HeciDev
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_REINIT) (
+ IN HECI_DEVICE HeciDev
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_RESET_WAIT) (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Delay
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_GET_SEC_STATUS) (
+ IN UINT32 *Status
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HECI_GET_SEC_MODE) (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *Mode
+ );
+
+typedef struct _EFI_HECI_PROTOCOL {
+ EFI_HECI_SENDWACK SendwACK;
+ EFI_HECI_READ_MESSAGE ReadMsg;
+ EFI_HECI_SEND_MESSAGE SendMsg;
+ EFI_HECI_RESET ResetHeci;
+ EFI_HECI_INIT InitHeci;
+ EFI_HECI_RESET_WAIT SeCResetWait;
+ EFI_HECI_REINIT ReInitHeci;
+ EFI_HECI_GET_SEC_STATUS GetSeCStatus;
+ EFI_HECI_GET_SEC_MODE GetSeCMode;
+} EFI_HECI_PROTOCOL;
+
+extern EFI_GUID gEfiHeciProtocolGuid;
+extern EFI_GUID gEfiHeciSmmProtocolGuid;
+extern EFI_GUID gEfiHeciSmmRuntimeProtocolGuid;
+extern EFI_GUID gEfiCseEndofPostGuid;
+extern EFI_GUID gEfiCseEndofServicesGuid;
+
+#endif // _EFI_HECI_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h
new file mode 100644
index 0000000000..24ceb581c4
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h
@@ -0,0 +1,67 @@
+/** @file
+ EFI HECI2 Power Management Protocol.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_HECI2_PM_PROTOCOL_H
+#define _EFI_HECI2_PM_PROTOCOL_H
+
+extern EFI_GUID gEfiHeci2PmProtocolGuid;
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_HECI2_PM_IS_IDLE) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_HECI2_PM_SET_ACTIVE) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_HECI2_PM_SET_IDLE) (
+ VOID
+ );
+
+typedef
+UINTN
+(EFIAPI *EFI_HECI2_PM_GET_HECIBAR) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_HECI2_PM_SET_HECIBAR) (
+ UINTN
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_HECI2_PM_AT_RUNTIME) (
+ VOID
+ );
+
+typedef struct _EFI_HECI2_PM_PROTOCOL {
+ EFI_HECI2_PM_IS_IDLE IsIdle;
+ EFI_HECI2_PM_SET_ACTIVE SetActive;
+ EFI_HECI2_PM_SET_IDLE SetIdle;
+ EFI_HECI2_PM_GET_HECIBAR GetHeciBar;
+ EFI_HECI2_PM_SET_HECIBAR SetHeciBar;
+ EFI_HECI2_PM_AT_RUNTIME AtRuntime;
+} EFI_HECI2_PM_PROTOCOL;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/IntegratedTouchHid.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/IntegratedTouchHid.h
new file mode 100644
index 0000000000..12b2f3e7ee
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/IntegratedTouchHid.h
@@ -0,0 +1,74 @@
+/** @file
+ HID interface for IntegratedTouch feature.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _INTEGRATED_TOUCH_HID_PROTOCOL_H_
+#define _INTEGRATED_TOUCH_HID_PROTOCOL_H_
+
+typedef struct _ITOUCH_HID_PROTOCOL ITOUCH_HID_PROTOCOL;
+
+/**
+ Performs GetFeature function as described in Human Interface Device spec.
+
+ @param[in] This Pointer to instance of protocol.
+ @param[in] Length Size of buffer.
+ @param[in] Buffer On input, contains ReportId in 1st byte. On output, filled with Feature data from iTouch.
+ @param[in] Timeout Parameter added to support Capsule Update. If provided value is 0 default is set GET_SET_FEATURE_TIMEOUT (5000).
+
+ @retval EFI_SUCCESS When iTouch responded with data.
+ @retval EFI_TIMEOUT When there was no response.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *ITOUCH_HID_GET_FEATURE)(
+ IN ITOUCH_HID_PROTOCOL *This,
+ IN UINT32 Length,
+ IN OUT UINT8 *Buffer,
+ IN UINTN Timeout
+ );
+
+/**
+ Performs SetFeature function as described in Human Interface Device spec.
+
+ @param[in] This Pointer to instance of protocol.
+ @param[in] Length Size of buffer.
+ @param[in] Buffer On input, contains data to be sent to iTouch.
+ @param[in] Timeout Parameter added to support Capsule Update. If provided value is 0 default is set GET_SET_FEATURE_TIMEOUT (5000).
+
+ @retval EFI_SUCCESS
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *ITOUCH_HID_SET_FEATURE)(
+ IN ITOUCH_HID_PROTOCOL *This,
+ IN UINT32 Length,
+ IN UINT8 *Buffer,
+ IN UINTN Timeout
+ );
+
+/**
+ IntegratedTouchHid protocol is instaled by iTouch driver on HECI3 device handle apart from
+ AbsolutePointer protocol.
+**/
+struct _ITOUCH_HID_PROTOCOL {
+ ITOUCH_HID_GET_FEATURE GetFeature;
+ ITOUCH_HID_SET_FEATURE SetFeature;
+ };
+
+extern EFI_GUID gIntegratedTouchHidProtocolGuid;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCPlatformPolicy.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCPlatformPolicy.h
new file mode 100644
index 0000000000..2a6a4cde43
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCPlatformPolicy.h
@@ -0,0 +1,134 @@
+/** @file
+ Interface definition details between SEC and platform drivers during DXE phase.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_PLATFORM_POLICY_H_
+#define _SEC_PLATFORM_POLICY_H_
+
+//
+// SEC policy provided by platform for DXE phase
+//
+#define DXE_PLATFORM_SEC_POLICY_GUID \
+ { \
+ 0xf8bff014, 0x18fb, 0x4ef9, 0xb1, 0xc, 0xae, 0x22, 0x73, 0x8d, 0xbe, 0xed \
+ }
+
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION 1
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_2 2
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_3 3
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_4 4
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_5 5
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_6 6
+#define DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_7 7
+
+extern EFI_GUID gDxePlatformSeCPolicyGuid;
+
+#pragma pack(1)
+
+#define TR_CONFIG_EC_MSG_LEN_1 1
+#define TR_CONFIG_EC_MSG_LEN_2 2
+#define TR_CONFIG_EC_MSG_LEN_5 5
+#define TR_CONFIG_EC_MSG_LEN_9 9
+#define TR_CONFIG_EC_MSG_LEN_10 10
+#define TR_CONFIG_EC_MSG_LEN_14 14
+#define TR_CONFIG_EC_MSG_LEN_20 20
+
+#define TR_CONFIG_PEC_DISABLED 0
+#define TR_CONFIG_PEC_ENABLED 1
+
+typedef struct {
+ UINT8 TrEnabled;
+ UINT8 SMBusECMsgLen;
+ UINT8 SMBusECMsgPEC;
+ UINT8 DimmNumber;
+ UINT8 *SmbusAddress;
+} TR_CONFIG;
+
+typedef struct {
+ UINT8 AtState;
+ UINT8 AtLastTheftTrigger;
+ UINT16 AtLockState;
+ UINT16 AtAmPref;
+} AT_CONFIG;
+
+typedef struct {
+ UINT16 CodeMinor;
+ UINT16 CodeMajor;
+ UINT16 CodeBuildNo;
+ UINT16 CodeHotFix;
+} SEC_VERSION;
+
+typedef struct {
+ ///
+ /// Byte 0, bit definition for functionality enable/disable
+ ///
+ UINT8 SeCFwDownGrade : 1; ///< 0: Disabled, 1: Enabled
+ UINT8 SeCLocalFwUpdEnabled : 1; ///< 0: Disabled, 1: Enabled
+ UINT8 Reserved : 1;
+ UINT8 Reserved1 : 1;
+ UINT8 EndOfPostEnabled : 1; ///< 0: Disabled; 1: Enabled
+ UINT8 Reserved2 : 3;
+ ///
+ /// Byte 1-3 Reserved for other bit definitions in future
+ ///
+ UINT8 ByteReserved1[3];
+
+ UINT8 HeciCommunication;
+ UINT8 PlatformBrand;
+ UINT8 SeCFwImageType;
+ ///
+ /// Byte 7-15
+ ///
+ UINT32 FwCapsSku;
+ UINT8 ByteReserved[5];
+
+ ///
+ /// Thermal Reporting Configuration to SEC
+ ///
+ TR_CONFIG *TrConfig;
+ BOOLEAN ITouchEnabled;
+} SEC_CONFIG;
+
+typedef enum {
+ MSG_EOP_ERROR = 0,
+ MSG_SEC_FW_UPDATE_FAILED,
+ MSG_ASF_BOOT_DISK_MISSING,
+ MSG_KVM_TIMES_UP,
+ MSG_KVM_REJECTED,
+ MSG_HMRFPO_LOCK_FAILURE,
+ MSG_HMRFPO_UNLOCK_FAILURE,
+ MSG_SEC_FW_UPDATE_WAIT,
+ MSG_ILLEGAL_CPU_PLUGGED_IN,
+ MSG_KVM_WAIT,
+ MAX_ERROR_ENUM
+} SEC_ERROR_MSG_ID;
+
+typedef
+VOID
+(EFIAPI *SEC_REPORT_ERROR) (
+ SEC_ERROR_MSG_ID
+ );
+
+#pragma pack()
+
+typedef struct _DXE_SEC_POLICY_PROTOCOL {
+ UINT8 Revision;
+ SEC_CONFIG SeCConfig;
+ SEC_VERSION SeCVersion;
+ AT_CONFIG AtConfig;
+ SEC_REPORT_ERROR SeCReportError;
+} DXE_SEC_POLICY_PROTOCOL;
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h
new file mode 100644
index 0000000000..ddfff4c0b2
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h
@@ -0,0 +1,56 @@
+/** @file
+ This file defines the SEC RC Info Protocol.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_RC_INFO_H_
+#define _SEC_RC_INFO_H_
+
+//
+// Define SEC RC INFO protocol GUID
+//
+#define EFI_SEC_RC_INFO_PROTOCOL_GUID \
+ { \
+ 0x11fbfdfb, 0x10d2, 0x43e6, 0xb5, 0xb1, 0xb4, 0x38, 0x6e, 0xdc, 0xcb, 0x9a \
+ }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSeCRcInfoProtocolGuid;
+
+//
+// Revision 1: Original version
+//
+#define SEC_RC_INFO_PROTOCOL_REVISION_1 1
+#define SEC_RC_VERSION 0x00050000
+
+typedef union _RC_VERSION {
+ UINT32 Data;
+ struct {
+ UINT32 RcBuildNo : 8;
+ UINT32 RcRevision : 8;
+ UINT32 RcMinorVersion : 8;
+ UINT32 RcMajorVersion : 8;
+ } Fields;
+} RC_VERSION;
+
+///
+/// This interface defines the SEC RC Info Protocol.
+///
+typedef struct _EFI_SEC_RC_INFO_PROTOCOL {
+ UINT8 Revision;
+ RC_VERSION RCVersion;
+} EFI_SEC_RC_INFO_PROTOCOL;
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/PttPtpRegs.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/PttPtpRegs.h
new file mode 100644
index 0000000000..2c5fc269f7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/PttPtpRegs.h
@@ -0,0 +1,118 @@
+/** @file
+ Register definitions for PTT HCI (Platform Trust Technology - Host Controller Interface).
+
+ Conventions:
+ Prefixes:
+ 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) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PTT_HCI_REGS_H_
+#define _PTT_HCI_REGS_H_
+
+//
+// FTPM HCI register base address
+//
+#define R_PTT_HCI_BASE_ADDRESS 0xFED40000
+
+//
+// FTPM HCI Control Area
+//
+#define R_PTT_LOCALITY_STATE 0x00
+#define R_TPM_LOCALITY_CONTROL 0X08
+#define R_TPM_LOCALITY_STATUS 0x0C
+#define R_TPM_INTERFACE_ID 0x30
+#define R_CRB_CONTROL_EXT 0x38
+#define R_CRB_CONTROL_REQ 0x40
+#define R_CRB_CONTROL_STS 0x44
+#define R_CRB_CONTROL_CANCEL 0x48
+#define R_CRB_CONTROL_START 0x4C
+#define R_CRB_CONTROL_INT 0x50
+#define R_CRB_CONTROL_CMD_SIZE 0x58
+#define R_CRB_CONTROL_CMD_LOW 0x5C
+#define R_CRB_CONTROL_CMD_HIGH 0x60
+#define R_CRB_CONTROL_RESPONSE_SIZE 0x64
+#define R_CRB_CONTROL_RESPONSE_ADDR 0x68
+
+//
+// R_CRB_CONTROL_STS Bits
+//
+#define B_CRB_CONTROL_STS_TPM_STATUS 0x00000001 ///< BIT0
+#define B_CRB_CONTROL_STS_TPM_IDLE 0x00000002 ///< BIT1
+
+//
+// R_CRB_CONTROL_REQ Bits
+//
+#define B_R_CRB_CONTROL_REQ_COMMAND_READY 0x00000001 ///< BIT0
+#define B_R_CRB_CONTROL_REQ_GO_IDLE 0x00000002 ///< BIT1
+
+//
+// R_CRB_CONTROL_START Bits
+//
+#define B_CRB_CONTROL_START 0x00000001 ///< BIT0
+
+//
+// R_TPM_LOCALITY_STATUS Bits
+//
+#define B_CRB_LOCALITY_STS_GRANTED 0x00000001 ///< BIT0
+#define B_CRB_LOCALITY_STS_BEEN_SEIZED 0x00000002 ///< BIT1
+
+//
+// R_TPM_LOCALITY_CONTROL Bits
+//
+#define B_CRB_LOCALITY_CTL_REQUEST_ACCESS 0x00000001 ///< BIT0
+#define B_CRB_LOCALITY_CTL_RELINQUISH 0x00000002 ///< BIT1
+#define B_CRB_LOCALITY_CTL_SEIZE 0x00000004 ///< BIT2
+
+//
+// R_PTT_LOCALITY_STATE Bits
+//
+#define B_CRB_LOCALITY_STATE_TPM_ESTABLISHED 0x00000001 ///< BIT0
+#define B_CRB_LOCALITY_STATE_LOCALITY_ASSIGNED 0x00000002 ///< BIT1
+#define B_CRB_LOCALITY_STATE_REGISTER_VALID 0x00000080 ///< BIT7
+
+//
+// R_PTT_LOCALITY_STATE Mask Values
+//
+#define V_CRB_LOCALITY_STATE_ACTIVE_LOC_MASK 0x0000001C /// Bits [4:2]
+
+//
+// Value written to R_PTT_HCI_CMD and CA_START
+// to indicate that a command is available for processing
+//
+#define V_PTT_HCI_COMMAND_AVAILABLE_START 0x00000001
+#define V_PTT_HCI_COMMAND_AVAILABLE_CMD 0x00000000
+#define V_PTT_HCI_BUFFER_ADDRESS_RDY 0x00000003
+
+//
+// Ignore bit setting mask for WaitRegisterBits
+//
+#define V_PTT_HCI_IGNORE_BITS 0x00000000
+
+//
+// All bits clear mask for WaitRegisterBits
+//
+#define V_PTT_HCI_ALL_BITS_CLEAR 0xFFFFFFFF
+#define V_PTT_HCI_START_CLEAR 0x00000001
+
+//
+// Max FTPM command/reponse buffer length
+//
+#define S_PTT_HCI_CRB_LENGTH 3968 ///< 0xFED40080:0xFED40FFF = 3968 Bytes
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCAccess.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCAccess.h
new file mode 100644
index 0000000000..5db30d6e1a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCAccess.h
@@ -0,0 +1,307 @@
+/** @file
+ Macros to simplify and abstract the interface to PCI configuration.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_ACCESS_H_
+#define _SEC_ACCESS_H_
+
+#include "SeCChipset.h"
+#include <ScAccess.h>
+#include <SaAccess.h>
+#include <Library/PciLib.h>
+
+//
+// HECI PCI Access Macro
+//
+#define HeciPciRead32(Register) PciRead32 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register))
+
+#define HeciPciWrite32(Register, Data) \
+ PciWrite32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define HeciPciOr32(Register, Data) \
+ PciOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define HeciPciAnd32(Register, Data) \
+ PciAnd32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define HeciPciAndThenOr32(Register, AndData, OrData) \
+ PciAndThenOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) AndData, \
+ (UINT32) OrData \
+ )
+
+#define HeciPciRead16(Register) PciRead16 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register))
+
+#define HeciPciWrite16(Register, Data) \
+ PciWrite16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define HeciPciOr16(Register, Data) \
+ PciOr16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define HeciPciAnd16(Register, Data) \
+ PciAnd16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define HeciPciAndThenOr16(Register, AndData, OrData) \
+ PciAndThenOr16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) AndData, \
+ (UINT16) OrData \
+ )
+
+#define HeciPciRead8(Register) PciRead8 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register))
+
+#define HeciPciWrite8(Register, Data) \
+ PciWrite8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define HeciPciOr8(Register, Data) \
+ PciOr8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define HeciPciAnd8(Register, Data) \
+ PciAnd8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define HeciPciAndThenOr8(Register, AndData, OrData) \
+ PciAndThenOr8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) AndData, \
+ (UINT8) OrData \
+ )
+
+//
+// HECI2 PCI Access Macro
+//
+#define Heci2PciRead32(Register) PciRead32 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register))
+
+#define Heci2PciWrite32(Register, Data) \
+ PciWrite32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci2PciOr32(Register, Data) \
+ PciOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci2PciAnd32(Register, Data) \
+ PciAnd32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci2PciAndThenOr32(Register, AndData, OrData) \
+ PciAndThenOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) AndData, \
+ (UINT32) OrData \
+ )
+
+#define Heci2PciRead16(Register) PciRead16 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register))
+
+#define Heci2PciWrite16(Register, Data) \
+ PciWrite16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define Heci2PciOr16(Register, Data) \
+ PciOr16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define Heci2PciAnd16(Register, Data) \
+ PciAnd16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) Data \
+ )
+
+#define Heci2PciAndThenOr16(Register, AndData, OrData) \
+ PciAndThenOr16 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT16) AndData, \
+ (UINT16) OrData \
+ )
+
+#define Heci2PciRead8(Register) PciRead8 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register))
+
+#define Heci2PciWrite8(Register, Data) \
+ PciWrite8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define Heci2PciOr8(Register, Data) \
+ PciOr8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define Heci2PciAnd8(Register, Data) \
+ PciAnd8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) Data \
+ )
+
+#define Heci2PciAndThenOr8(Register, AndData, OrData) \
+ PciAndThenOr8 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI2_FUNCTION_NUMBER, \
+ Register), \
+ (UINT8) AndData, \
+ (UINT8) OrData \
+ )
+
+//
+// HECI3 PCI Access Macro
+//
+#define Heci3PciRead32(Register) PciRead32 (PCI_LIB_ADDRESS (SEC_BUS, SEC_DEVICE_NUMBER, HECI3_FUNCTION_NUMBER, Register))
+
+#define Heci3PciWrite32(Register, Data) \
+ PciWrite32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI3_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci3PciOr32(Register, Data) \
+ PciOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI3_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci3PciAnd32(Register, Data) \
+ PciAnd32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI3_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) Data \
+ )
+
+#define Heci3PciAndThenOr32(Register, AndData, OrData) \
+ PciAndThenOr32 ( \
+ PCI_LIB_ADDRESS (SEC_BUS, \
+ SEC_DEVICE_NUMBER, \
+ HECI3_FUNCTION_NUMBER, \
+ Register), \
+ (UINT32) AndData, \
+ (UINT32) OrData \
+ )
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCChipset.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCChipset.h
new file mode 100644
index 0000000000..eda8c86af1
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCChipset.h
@@ -0,0 +1,138 @@
+/** @file
+ Chipset definition for SEC Devices.
+
+ Conventions:
+ Prefixes:
+ 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
+ In general, SEC registers are denoted by "_SEC_" in register names
+ Registers / bits that are different between SEC generations are denoted by
+ "_SEC_<generation_name>_" in register/bit names. e.g., "_ME_VLV_"
+ Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ Registers / bits of new devices introduced in a ME generation will be just named
+ as "_SEC_" without <generation_name> inserted.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_CHIPSET_H_
+#define _SEC_CHIPSET_H_
+
+#include <Library/SeCChipsetLib.h>
+
+#define SEC_BUS 0
+#define SEC_DEVICE_NUMBER 15
+
+#define HECI_FUNCTION_NUMBER 0x00
+#define HECI2_FUNCTION_NUMBER 0x01
+#define HECI3_FUNCTION_NUMBER 0x02
+#define SOL_FUNCTION_NUMBER 0x03
+
+#define HECI_DEV_FCN ((SEC_DEVICE_NUMBER) << 3 | (HECI_FUNCTION_NUMBER))
+#define HECI2_DEV_FCN ((SEC_DEVICE_NUMBER) << 3 | (HECI2_FUNCTION_NUMBER))
+
+typedef enum {
+ HECI1_DEVICE = 0,
+ HECI2_DEVICE = 1,
+ HECI3_DEVICE = 2
+} HECI_DEVICE;
+
+#define V_SEC_HECI_DEVICE_ID 0x1C3A
+#define V_SEC_HECI2_DEVICE_ID 0x1C3B
+#define V_SEC_IDER_DEVICE_ID 0x1C3C
+#define V_SEC_SOL_DEVICE_ID 0x1C3D
+
+#define R_SEC_DevID_VID 0x0
+#define R_SEC_MEM_REQ 0x44
+#define S_SEC_DevID_MASK 0xFFFF0000
+#define S_SEC_DevID_RANGE_LO 0x5A9A
+#define S_SEC_DevID_RANGE_HI 0x5A9E
+#define R_SATT1_BRG_BA_LSB 0x00C4 // 0xcc
+#define R_SATT1_CTRL 0x00C0
+#define R_SATT1_SAP_SIZE 0x00C8
+#define B_ENTRY_VLD BIT0
+#define R_SEC_FW_STS0 0x40
+#define FPT_BAD BIT5
+#define B_SEC_MEM_REQ_VALID BIT31
+#define B_SEC_MEM_REQ_INVALID BIT30
+#define R_DID_MSG 0x60
+#define S_SEC_UMA_SIZE_MASK 0xFFFF
+#define R_SICR_HOST_ALIVENESS_REQ 0x214C
+#define B_ALIVENESS_REQ BIT0
+
+//
+// BAR values
+//
+#define HECI_BAR0 0x10
+#define HECI_BAR1 0x14
+//
+// BIOS Messages
+//
+#define V_SEC_DID_MSG_MASK 0x10000000
+#define B_SEC_EN_MSG_MASK BIT29
+#define B_HMRFPO_DIS_MASK (BIT28+BIT29)
+//
+// ACK from SeC
+//
+#define B_SEC_DID_ACK_MASK BIT28
+#define B_SEC_BIOS_ACTION_MASK (BIT27 + BIT26 + BIT25)
+#define B_SEC_MESSAGE_TYPE_MASK (BIT31 + BIT30 + BIT29 + BIT28)
+
+#define R_SEC_GS_SHDW 0x48
+#define R_SEC_CPU_REPLACE_STS_MASK BIT5
+
+#define R_SEC_HERS 0xBC
+#define B_SEC_EXTEND_REG_VALID BIT31
+#define B_SEC_EXTEND_REG_ALGORITHM (BIT0 | BIT1 | BIT2 | BIT3)
+#define V_SEC_SHA_1 0x00
+#define V_SEC_SHA_256 0x02
+#define R_SEC_HER1 0xC0
+#define R_SEC_HER2 0xC4
+#define R_SEC_HER3 0xC8
+#define R_SEC_HER4 0xCC
+#define R_SEC_HER5 0xD0
+#define R_SEC_HER6 0xD4
+#define R_SEC_HER7 0xD8
+#define R_SEC_HER8 0xDC
+
+#define R_HECI_DEVIDLEC 0x800
+#define B_HECI_DEVIDLEC_CIP 0x1
+#define B_HECI_DEVIDLEC_IR 0x2
+#define B_HECI_DEVIDLEC_DEVIDLE 0x4
+#define B_HECI_DEVIDLEC_RR 0x8
+#define B_HECI_DEVIDLEC_IRC 0x10
+
+//
+// SEC-related Chipset Definition
+//
+#define HeciEnable() SeCDeviceControl (HECI1, Enabled);
+#define Heci2Enable() SeCDeviceControl (HECI2, Enabled);
+#define Heci3Enable() SeCDeviceControl (HECI3, Enabled);
+#define FTPMEnable() SeCDeviceControl (FTPM, Enabled);
+
+#define HeciDisable() SeCDeviceControl (HECI1, Disabled);
+#define Heci2Disable() SeCDeviceControl (HECI2, Disabled);
+#define Heci3Disable() SeCDeviceControl (HECI3, Disabled);
+#define FTPMDisable() SeCDeviceControl (FTPM, Disabled);
+
+#define DisableAllSECDevices() \
+ HeciDisable(); \
+ Heci2Disable(); \
+ Heci3Disable(); \
+ FTPMDisable();
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h
new file mode 100644
index 0000000000..78e5ec1229
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h
@@ -0,0 +1,64 @@
+/** @file
+ Register Definitions for SeC States.
+
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_STATE_H
+#define _SEC_STATE_H
+
+//
+// Ignore SEC_FW_INIT_COMPLETE status Macro
+//
+#define SEC_STATUS_SEC_STATE_ONLY(a) ((a) & (~(SEC_FW_INIT_COMPLETE | SEC_FW_BOOT_OPTIONS_PRESENT)))
+
+//
+// Macro to check if SEC FW INIT is completed
+//
+#define SEC_STATUS_IS_SEC_FW_INIT_COMPLETE(a) (((a) & SEC_FW_INIT_COMPLETE) == SEC_FW_INIT_COMPLETE)
+
+//
+// Marco to combind the complete bit to status
+//
+#define SEC_STATUS_WITH_SEC_INIT_COMPLETE(a) ((a) | SEC_FW_INIT_COMPLETE)
+
+//
+// Macro to check SEC Boot Option Present
+//
+#define SEC_STATUS_IS_SEC_FW_BOOT_OPTIONS_PRESENT(a) (((a) & SEC_FW_BOOT_OPTIONS_PRESENT) == SEC_FW_BOOT_OPTIONS_PRESENT)
+
+//
+// Abstract SEC Mode Definitions
+//
+#define SEC_MODE_NORMAL 0x00
+#define SEC_DEBUG_MODE_ALT_DIS 0x02
+#define SEC_MODE_TEMP_DISABLED 0x03
+#define SEC_MODE_RECOVER 0x04
+#define SEC_MODE_FAILED 0x06
+
+//
+// Abstract SEC Status definitions
+//
+#define SEC_READY 0x00
+#define SEC_INITIALIZING 0x01
+#define SEC_IN_RECOVERY_MODE 0x02
+#define SEC_DISABLE_WAIT 0x06
+#define SEC_TRANSITION 0x07
+#define SEC_NOT_READY 0x0F
+#define SEC_FW_INIT_COMPLETE 0x80
+#define SEC_FW_BOOT_OPTIONS_PRESENT 0x100
+#define SEC_FW_UPDATES_IN_PROGRESS 0x200
+
+#pragma pack()
+
+#endif // SEC_STATE_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.c
new file mode 100644
index 0000000000..ffc574e995
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.c
@@ -0,0 +1,38 @@
+/** @file
+ Implementation file for the HECI2 Power Management Null library.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Protocol/Heci2Pm.h>
+
+/**
+ Returns an instance of the HECI2 Power Management protocol.
+
+ @params[out] Heci2PmProtocol The address to a pointer to the HECI2 PM protocol.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+GetHeci2PmProtocol (
+ OUT EFI_HECI2_PM_PROTOCOL **Heci2PmProtocol
+ )
+{
+ *Heci2PmProtocol = NULL;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.inf
new file mode 100644
index 0000000000..871bb07478
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.inf
@@ -0,0 +1,32 @@
+## @file
+# HECI 2 Power Management Null Library.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseHeci2PowerManagementNullLib
+ FILE_GUID = 9CF67E2B-3C63-4AF0-B76E-F900B8A8717E
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Heci2PowerManagementLib
+
+[Sources]
+ BaseHeci2PowerManagementNullLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ BaseLib
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c
new file mode 100644
index 0000000000..61e41a6054
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c
@@ -0,0 +1,860 @@
+/** @file
+ Implementation file DXE/SMM specific HECI Message functionality.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiDxeSmmMmPciLib.h>
+#include <Library/TimerLib.h>
+#include <openssl/hmac.h>
+#include <SeCState.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Private/Library/HeciInitLib.h>
+#include <Protocol/Heci.h>
+#include <Protocol/SeCPlatformPolicy.h>
+
+UINT8 Heci2DataBuffer[MAX (HECI2_BIOS_MAX_WRITE_MSG_SIZE, HECI2_BIOS_MAX_READ_MSG_SIZE)];
+
+UINT32 mMonoCount = 0;
+UINT8 mHmacSha256Key[32] = {0};
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.
+
+ @return The size, in bytes, of the context buffer required for HMAC-SHA1 operations.
+
+**/
+UINTN
+EFIAPI
+HmacSha256GetContextSize (
+ VOID
+ )
+{
+ //
+ // Retrieves the OpenSSL HMAC-SHA1 Context Size
+ //
+ return (UINTN) (sizeof (HMAC_CTX));
+}
+
+
+/**
+ Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for
+ subsequent use.
+
+ If HmacSha1Context is NULL, then return FALSE.
+
+ @param[out] HmacSha1Context Pointer to HMAC-SHA1 context being initialized.
+ @param[in] Key Pointer to the user-supplied key.
+ @param[in] KeySize Key size in bytes.
+
+ @retval TRUE HMAC-SHA1 context initialization succeeded.
+ @retval FALSE HMAC-SHA1 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+HmacSha256Init (
+ OUT VOID *HmacSha256Context,
+ IN CONST UINT8 *Key,
+ IN UINTN KeySize
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (HmacSha256Context == NULL || KeySize > INT_MAX) {
+ return FALSE;
+ }
+
+ //
+ // OpenSSL HMAC-SHA1 Context Initialization
+ //
+ HMAC_CTX_init (HmacSha256Context);
+ HMAC_Init_ex (HmacSha256Context, Key, (UINT32) KeySize, EVP_sha256(), NULL);
+
+ return TRUE;
+}
+
+
+/**
+ Makes a copy of an existing HMAC-SHA1 context.
+
+ If HmacSha1Context is NULL, then return FALSE.
+ If NewHmacSha1Context is NULL, then return FALSE.
+
+ @param[in] HmacSha1Context Pointer to HMAC-SHA1 context being copied.
+ @param[out] NewHmacSha1Context Pointer to new HMAC-SHA1 context.
+
+ @retval TRUE HMAC-SHA1 context copy succeeded.
+ @retval FALSE HMAC-SHA1 context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+HmacSha256Duplicate (
+ IN CONST VOID *HmacSha256Context,
+ OUT VOID *NewHmacSha256Context
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (HmacSha256Context == NULL || NewHmacSha256Context == NULL) {
+ return FALSE;
+ }
+
+ CopyMem (NewHmacSha256Context, HmacSha256Context, sizeof (HMAC_CTX));
+
+ return TRUE;
+}
+
+
+/**
+ Digests the input data and updates HMAC-SHA1 context.
+
+ This function performs HMAC-SHA1 digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not
+ be finalized by HmacSha1Final(). Behavior with invalid context is undefined.
+
+ If HmacSha1Context is NULL, then return FALSE.
+
+ @param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE HMAC-SHA1 data digest succeeded.
+ @retval FALSE HMAC-SHA1 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+HmacSha256Update (
+ IN OUT VOID *HmacSha256Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (HmacSha256Context == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Check invalid parameters, in case that only DataLength was checked in OpenSSL
+ //
+ if (Data == NULL && DataSize != 0) {
+ return FALSE;
+ }
+
+ //
+ // OpenSSL HMAC-SHA1 digest update
+ //
+ HMAC_Update (HmacSha256Context, Data, DataSize);
+
+ return TRUE;
+}
+
+
+/**
+ Completes computation of the HMAC-SHA1 digest value.
+
+ This function completes HMAC-SHA1 digest computation and retrieves the digest value into
+ the specified memory. After this function has been called, the HMAC-SHA1 context cannot
+ be used again.
+ HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should
+ not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.
+
+ If HmacSha1Context is NULL, then return FALSE.
+ If HmacValue is NULL, then return FALSE.
+
+ @param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
+ @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA1 digest
+ value (20 bytes).
+
+ @retval TRUE HMAC-SHA1 digest computation succeeded.
+ @retval FALSE HMAC-SHA1 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+HmacSha256Final (
+ IN OUT VOID *HmacSha256Context,
+ OUT UINT8 *HmacValue
+ )
+{
+ UINT32 Length;
+
+ //
+ // Check input parameters.
+ //
+ if (HmacSha256Context == NULL || HmacValue == NULL) {
+ return FALSE;
+ }
+
+ //
+ // OpenSSL HMAC-SHA1 digest finalization
+ //
+ HMAC_Final (HmacSha256Context, HmacValue, &Length);
+ HMAC_CTX_cleanup (HmacSha256Context);
+
+ return TRUE;
+}
+
+
+EFI_STATUS
+ComputeHmacSha256Signature (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *Signature
+ )
+{
+ UINTN ContextSize;
+ VOID *HmacContext;
+ UINT8 Digest[64];
+ BOOLEAN Status;
+
+ //
+ // HMAC-SHA1 Digest Validation
+ //
+ ZeroMem (Digest, 64);
+
+ ContextSize = HmacSha256GetContextSize ();
+ HmacContext = AllocatePool (ContextSize);
+
+ DEBUG ((EFI_D_INFO, "Compute HMAC Signature. DataSize = %x ContextSize = %x\n", DataSize, ContextSize));
+ DEBUG ((EFI_D_INFO, "Init... "));
+
+ Status = HmacSha256Init (HmacContext, mHmacSha256Key, sizeof (mHmacSha256Key));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Fail]"));
+ return EFI_ABORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "Update...\n"));
+
+ Status = HmacSha256Update (HmacContext, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Fail]"));
+ return EFI_ABORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "Finalize...\n"));
+
+ Status = HmacSha256Final (HmacContext, Digest);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Fail]"));
+ return EFI_ABORTED;
+ }
+
+ CopyMem (Signature, Digest, SHA256_DIGEST_SIZE);
+ FreePool (HmacContext);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns whether trusted channel is enabled.
+
+ @param[in] None.
+
+ @retval TRUE if trusted channel is enabled.
+ FALSE if trusted channel is disabled.
+**/
+BOOLEAN
+IsTrustedChannelEnabled (
+ VOID
+ )
+{
+ return (mMonoCount != 0);
+}
+
+
+/**
+ Updates the SHA256 signature and monotonic counter fields of a HECI message header.
+
+ @param[in] MessageHeader A pointer to the message header
+ @param[in] TotalHeaderSize The total header size
+ @param[in] TotalDataSize The total data size
+
+ @retval Whether the header could be updated
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateTrustedHeader (
+ IN OUT UINT8 *MessageHeader,
+ IN UINT32 TotalHeaderSize,
+ IN UINT32 TotalDataSize
+ )
+{
+ EFI_STATUS Status;
+ MBP_SMM_TRUSTED_KEY SmmTrustedKey;
+ HECI2_TRUSTED_CHANNEL_BIOS_HEADER *TrustedChannelHeader = NULL;
+ UINT8 Digest[64];
+
+ if (MessageHeader == NULL || TotalHeaderSize < sizeof (HECI2_TRUSTED_CHANNEL_BIOS_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mMonoCount == 0) {
+ //
+ // Since the is the first message, get the SMM trusted key for this boot
+ //
+ Status = HeciGetSMMTrustedKey (&SmmTrustedKey);
+
+ if (!EFI_ERROR (Status)) {
+ CopyMem (mHmacSha256Key, SmmTrustedKey.SmmTrustedKey, sizeof (mHmacSha256Key));
+ mMonoCount = SmmTrustedKey.MonotonicCounter + 1;
+ DEBUG ((EFI_D_INFO, "HMAC Monotonic Count = %d\n", mMonoCount));
+ } else {
+ DEBUG ((EFI_D_ERROR, "Unable to get the SMM trusted key. Cannot send HECI2 transactions.\n"));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ TrustedChannelHeader = (HECI2_TRUSTED_CHANNEL_BIOS_HEADER *) MessageHeader;
+ TrustedChannelHeader->MonotonicCounter = mMonoCount++;
+
+ DEBUG ((EFI_D_INFO, "Current HMAC monotonic count = %d.\n", TrustedChannelHeader->MonotonicCounter));
+
+ //
+ // Compute the HMAC SHA-256 digest
+ //
+ // Includes all fields except the signature field
+ //
+ ComputeHmacSha256Signature (
+ (UINT8 *) MessageHeader + HECI2_HMAC_SHA256_SIGNATURE_SIZE,
+ (TotalHeaderSize + TotalDataSize) - HECI2_HMAC_SHA256_SIGNATURE_SIZE,
+ Digest
+ );
+
+ CopyMem (&TrustedChannelHeader->Signature, Digest, HECI2_HMAC_SHA256_SIGNATURE_SIZE);
+ DEBUG ((EFI_D_INFO, "Trusted channel signature computed = 0x%x\n", Digest));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Write data to NVM file through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data content.
+ @param[in] DataSize Data's size.
+ @param[in] Truncate Truncate the file.
+
+ @return EFI_SUCCESS Write NVM file success.
+ @return Others Write NVM file failed.
+
+**/
+EFI_STATUS
+Heci2WriteNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN Truncate
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ *WriteFileMessage;
+ UINT32 SeCMode;
+ UINTN CurrentWriteDataSize;
+ INTN RemainingDataSize;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: Heci2WriteNVMFile\n"));
+ DEBUG ((EFI_D_INFO, " Truncate bit: %a.\n", (Truncate) ? "Set" : "Not set"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ RemainingDataSize = DataSize;
+
+ do {
+ if (RemainingDataSize > MAX_HECI2_WRITE_DATA_SIZE) {
+ CurrentWriteDataSize = MAX_HECI2_WRITE_DATA_SIZE;
+ } else {
+ CurrentWriteDataSize = RemainingDataSize;
+ }
+
+ SetMem (Heci2DataBuffer, sizeof (Heci2DataBuffer), 0);
+
+ WriteFileMessage = (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ *) Heci2DataBuffer;
+ WriteFileMessage->Offset = Offset;
+ WriteFileMessage->DataSize = (UINT16) CurrentWriteDataSize;
+ WriteFileMessage->Truncate = (Truncate) ? 1 : 0;
+ Truncate = FALSE;
+
+ WriteFileMessage->TrustedChannelHeader.CommandId = HECI2_WRITE_DATA_CMD_ID;
+
+ //
+ // Copy the name of the NVM file to write
+ //
+ ASSERT (AsciiStrLen (FileName) <= sizeof (WriteFileMessage->FileName));
+ ASSERT (sizeof (Heci2DataBuffer) > sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ));
+ AsciiStrCpyS ((CHAR8 *) WriteFileMessage->FileName, sizeof (WriteFileMessage->FileName), (CONST CHAR8 *) FileName);
+
+ CopyMem ((UINT8 *) Heci2DataBuffer + sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ), Data, CurrentWriteDataSize);
+
+ //
+ // Fill in the HMAC signature and update the monotonic counter
+ //
+ Status = UpdateTrustedHeader (
+ Heci2DataBuffer,
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ),
+ (UINT32) CurrentWriteDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((
+ EFI_D_INFO,
+ "HECI2 write data size = 0x%x.\n",
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ) + CurrentWriteDataSize
+ ));
+
+ HeciSendLength = (UINT32) (sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_REQ) + CurrentWriteDataSize);
+ HeciRecvLength = sizeof (HECI2_TRUSTED_CHANNEL_BIOS_WRITE_RESP);
+
+ Status = Heci2SendwACK (
+ (UINT32 *) Heci2DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "HECI2Write CommandId =%x\n", WriteFileMessage->TrustedChannelHeader.CommandId));
+ DEBUG ((EFI_D_INFO, "HECI2Write RequestResponse =%x\n", WriteFileMessage->TrustedChannelHeader.RequestResponse));
+ DEBUG ((EFI_D_INFO, "HECI2Write Status =%x\n", ((HECI2_TRUSTED_CHANNEL_BIOS_WRITE_RESP *) WriteFileMessage)->Status));
+
+ Data += CurrentWriteDataSize;
+ Offset += (UINT32) CurrentWriteDataSize;
+
+ RemainingDataSize -= CurrentWriteDataSize;
+ } while (RemainingDataSize > 0);
+
+ return Status;
+}
+
+
+/**
+ Read NVM file data through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[out] Data The data buffer.
+ @param[in, out] DataSize Data's size.
+
+ @retval EFI_SUCCESS Read NVM file success.
+ @retval Others Read NVM file failed.
+
+**/
+EFI_STATUS
+Heci2ReadNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ OUT UINT8 *Data,
+ IN OUT UINTN *DataSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ *ReadFileMessage;
+ HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP *Res;
+ UINT32 SeCMode;
+ UINT32 CurrentReadDataSize;
+ INTN RemainingDataSize;
+ UINTN TotalDataSize;
+
+ DEBUG ((DEBUG_INFO, "BIOS Start Send HECI Message: Heci2ReadNVMFile\n"));
+ DEBUG ((DEBUG_INFO, "Size of HECI2_READ_DATA_SIZE = 0x%x.\n", *DataSize));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ RemainingDataSize = *DataSize;
+ TotalDataSize = 0;
+
+ do {
+ if (RemainingDataSize > MAX_HECI2_READ_DATA_SIZE) {
+ CurrentReadDataSize = MAX_HECI2_READ_DATA_SIZE;
+ } else {
+ CurrentReadDataSize = (UINT32) RemainingDataSize;
+ }
+
+ SetMem (Heci2DataBuffer, sizeof (Heci2DataBuffer), 0);
+
+ ReadFileMessage = (HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ *) Heci2DataBuffer;
+
+ ReadFileMessage->Offset = Offset;
+ ReadFileMessage->DataSize = (UINT16) CurrentReadDataSize;
+
+ ReadFileMessage->TrustedChannelHeader.CommandId = HECI2_READ_DATA_CMD_ID;
+
+ //
+ // Copy the name of the NVM file to read
+ //
+ ASSERT (AsciiStrLen (FileName) <= sizeof (ReadFileMessage->FileName));
+ ASSERT (sizeof (Heci2DataBuffer) > sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ));
+ AsciiStrCpyS ((CHAR8 *) ReadFileMessage->FileName, sizeof (ReadFileMessage->FileName), (CONST CHAR8 *) FileName);
+
+ //
+ // Fill in the HMAC signature and update the monotonic counter
+ //
+ Status = UpdateTrustedHeader (
+ Heci2DataBuffer,
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ),
+ 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((
+ EFI_D_INFO,
+ "HECI2 read data header size is[ %x + %x ] = %x\n",
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP),
+ CurrentReadDataSize,
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP) + CurrentReadDataSize
+ ));
+
+ HeciSendLength = sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_REQ);
+ HeciRecvLength = sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP) + CurrentReadDataSize;
+
+ Status = Heci2Protocol->SendwACK(
+ HECI2_DEVICE,
+ (UINT32 *) Heci2DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ Res = (HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP *) Heci2DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "HECI2Read CommandId =%x\n", ReadFileMessage->TrustedChannelHeader.CommandId));
+ DEBUG ((EFI_D_INFO, "HECI2Read RequestResponse =%x\n", ReadFileMessage->TrustedChannelHeader.RequestResponse));
+ DEBUG ((EFI_D_INFO, "HECI2Read Status =%x\n", Res->Status));
+ DEBUG ((EFI_D_INFO, "HECI2Read DataSize =%x\n", Res->DataSize));
+
+ CopyMem (
+ Data,
+ (VOID *) (((UINTN) Heci2DataBuffer) + sizeof (HECI2_TRUSTED_CHANNEL_BIOS_READ_RESP)),
+ Res->DataSize
+ );
+
+ Data += CurrentReadDataSize;
+ Offset += CurrentReadDataSize;
+
+ TotalDataSize += Res->DataSize;
+ RemainingDataSize -= CurrentReadDataSize;
+
+ } while (RemainingDataSize > 0);
+
+ *DataSize = TotalDataSize;
+ DEBUG ((EFI_D_INFO, " HECI2 - Total DataSize =%x\n", *DataSize));
+
+ return Status;
+}
+
+
+/**
+ Get NVM file's size through HECI2.
+
+ @param[in] FileName The file name.
+ @param[out] FileSize The file's size.
+
+ @retval EFI_SUCCESS Get NVM file size success.
+ @retval Others Get NVM file size failed.
+
+**/
+EFI_STATUS
+Heci2GetNVMFileSize (
+ IN UINT8 *FileName,
+ OUT UINTN *FileSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ *GetFileSizeMessage;
+ UINT32 SeCMode;
+ UINTN CurrentWriteDataSize = 0;
+ HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_RESP *Res;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: Heci2GetNVMFileSize\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (Heci2DataBuffer, sizeof (Heci2DataBuffer), 0);
+
+ GetFileSizeMessage = (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ *) Heci2DataBuffer;
+ GetFileSizeMessage->TrustedChannelHeader.CommandId = HECI2_FILE_SIZE_CMD_ID;
+ AsciiStrCpyS ((CHAR8 *) GetFileSizeMessage->FileName, sizeof ((CHAR8 *) GetFileSizeMessage->FileName) / sizeof (CHAR16) ,(CONST CHAR8 *) FileName);
+
+ //
+ // Fill in the HMAC signature and update the monotonic counter
+ //
+ Status = UpdateTrustedHeader (
+ Heci2DataBuffer,
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ),
+ (UINT32) CurrentWriteDataSize
+ );
+
+ DEBUG ((
+ EFI_D_INFO,
+ "HECI2 GetNVMfilesize data size = 0x%x\n",
+ sizeof (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ) + CurrentWriteDataSize
+ ));
+
+ HeciSendLength = (UINT32) (sizeof (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_REQ) + CurrentWriteDataSize);
+ HeciRecvLength = sizeof (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_RESP);
+
+ Status = Heci2Protocol->SendwACK (
+ HECI2_DEVICE,
+ (UINT32 *) Heci2DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+ Res = (HECI2_TRUSTED_CHANNEL_BIOS_NVMSIZE_RESP *) Heci2DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "CommandId =%x\n", Res->TrustedChannelHeader.CommandId));
+ DEBUG ((EFI_D_INFO, "RequestResponse =%x\n", Res->TrustedChannelHeader.RequestResponse));
+ DEBUG ((EFI_D_INFO, "Status =%x\n", Res->Status));
+ DEBUG ((EFI_D_INFO, "DataSize =%x\n", Res->DataSize));
+ *FileSize = Res->DataSize;
+
+ return Status;
+}
+
+
+/**
+ Send Get Proxy State message through Heci2.
+
+ @retval EFI_SUCCESS Send message success.
+ @retval Others Send message failed.
+
+**/
+EFI_STATUS
+Heci2GetProxyState(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_BIOS_MASSAGE *ReadFileMessage;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: Heci2GetProxyState\n"));
+ Status = HeciGetSeCMode (HECI2_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ ReadFileMessage = (HECI2_BIOS_MASSAGE*)DataBuffer;
+ ReadFileMessage->header.cmd_id = HECI2_GET_PROXY_STATE_CMD_ID;
+
+ DEBUG ((EFI_D_INFO, "HECI2_BIOS_MASSAGE size is %x\n", sizeof (HECI2_BIOS_MASSAGE)));
+ HeciSendLength = sizeof (HECI2_BIOS_MASSAGE);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = Heci2SendwoACK (
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+
+ return Status;
+}
+
+
+/**
+ Check is the HECI2 device has interrupt.
+
+ @retval TRUE HECI2 device interrupt.
+ @retval FALSE No interrupt.
+
+**/
+BOOLEAN Heci2GetInterrupt(
+ VOID
+ )
+{
+ volatile HECI_HOST_CONTROL_REGISTER *HostControlReg;
+ UINTN HeciBar;
+
+ HeciBar = CheckAndFixHeciForAccess (HECI2_DEVICE);
+
+ DEBUG ((EFI_D_INFO, "Start Heci2GetInterrupt\n"));
+
+ HostControlReg = (volatile HECI_HOST_CONTROL_REGISTER *) (UINTN) (HeciBar + H_CSR);
+ if (HostControlReg->r.H_IS == 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Lock Directory message through HECI2.
+
+ @param[in] DirName The Directory name.
+ @param[in] Heci2Protocol The HECI protocol to send the message to HECI2 device.
+
+ @retval EFI_SUCCESS Send EOP message success.
+ @retval Others Send EOP message failed.
+
+**/
+EFI_STATUS
+Heci2LockDirectory (
+ IN UINT8 *DirName,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_BIOS_MASSAGE *LockDirMessage;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x40];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: Heci2LockDirectory\n"));
+ Status = HeciGetSeCMode (HECI2_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || ((SeCMode != SEC_MODE_NORMAL) && (SEC_MODE_RECOVER != SeCMode))) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ LockDirMessage = (HECI2_BIOS_MASSAGE *) DataBuffer;
+ LockDirMessage->header.cmd_id = HECI2_LOCK_DIR_CMD_ID;
+ AsciiStrCpyS ((CHAR8 *) LockDirMessage->Body.lockDirReq.DirName, MAX_DIR_NAME, (CONST CHAR8 *) DirName);
+
+ DEBUG ((EFI_D_INFO, "HECI2_BIOS_MASSAGE size is %x\n", sizeof (HECI2_BIOS_MASSAGE)));
+ HeciSendLength = sizeof (HECI2_BIOS_MASSAGE);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = Heci2Protocol->SendwACK (
+ HECI2_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+
+ DEBUG ((EFI_D_INFO, "CommandId =%x\n", LockDirMessage->header.cmd_id));
+ DEBUG ((EFI_D_INFO, "RequestResponse =%x\n", LockDirMessage->header.req_resp));
+ DEBUG ((EFI_D_INFO, "Status =%x\n", LockDirMessage->Body.readResp.Status));
+
+ return Status;
+}
+
+
+/**
+ Send Get proxy State message through HEC2 but not waiting for response.
+
+ @param[in] Heci2Protocol The HECI protocol to send the message to HECI2 device.
+
+ @retval EFI_SUCCESS Send get proxy state message success.
+ @retval Others Send get proxy state message failed.
+
+**/
+EFI_STATUS
+Heci2GetProxyStateNoResp(
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ HECI2_BIOS_MASSAGE *ReadFileMessage;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: Heci2GetProxyState\n"));
+ Status = HeciGetSeCMode (HECI2_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ ReadFileMessage = (HECI2_BIOS_MASSAGE *) DataBuffer;
+ ReadFileMessage->header.cmd_id = HECI2_GET_PROXY_STATE_CMD_ID;
+
+ DEBUG ((EFI_D_INFO, "HECI2_BIOS_MASSAGE size is %x\n", sizeof (HECI2_BIOS_MASSAGE)));
+ HeciSendLength = sizeof (HECI2_BIOS_MASSAGE);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = Heci2Protocol->SendMsg (
+ HECI2_DEVICE,
+ (UINT32 *) DataBuffer,
+ HeciSendLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI2_BIOS_MCA_FIXED_ADDR
+ );
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf
new file mode 100644
index 0000000000..b513efc981
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Implementation DXE/SMM specific HECI Message.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeSmmHeciMsgLib
+ FILE_GUID = E2928B98-B0E4-4C8D-ADFA-A3D7588B8AF5
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HeciMsgLib|DXE_DRIVER DXE_SMM_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
+
+[Sources]
+ HeciMsgLib.c
+ DxeSmmHeciMsgLib.c
+
+[Packages]
+ CryptoPkg/CryptoPkg.dec
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ PciLib
+ BaseLib
+ TimerLib
+ HeciInitLib
+ BaseCryptLib
+ PcdLib
+
+[Guids]
+ gFdoModeEnabledHobGuid
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/HeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/HeciMsgLib.c
new file mode 100644
index 0000000000..075c760ccc
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/HeciMsgLib.c
@@ -0,0 +1,1800 @@
+/** @file
+ Implementation file for common HECI Message functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/TimerLib.h>
+#include <SeCState.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Protocol/Heci.h>
+#include <Private/Library/HeciInitLib.h>
+#include <Library/PeiDxeSmmMmPciLib.h>
+
+#define MIRROR_RANGE_MCHBAR 0x65c8 //0x6458 // 0x65C8
+#define MOT_OUT_BASE_Bunit 0x6AF0
+#define MOT_OUT_MASK_Bunit 0x6AF4
+#define MOT_OUT_BASE_Aunit 0x64C0
+#define MOT_OUT_MASK_Aunit 0x64C4
+#define SPARE_BIOS_MCHBAR 0x647C // BXTM 0x6474
+
+#define MCHBASE MmPciBase(SA_MC_BUS, SA_MC_DEV, SA_MC_FUN)
+#define MCHBASE_BAR MmioRead32(MCHBASE + 0x48) &~BIT0
+#define MCHMmioRead32(offset) MmioRead32((MCHBASE_BAR)+offset)
+#define MCHMmioWrite32(offset, data) MmioWrite32((MCHBASE_BAR)+offset, data)
+
+VOID* WriteCacheBuffer = NULL;
+VOID* ReadCacheBuffer = NULL;
+
+/**
+ Send DID Request Message through HECI.
+
+ @param[in] UMABase The IMR Base address
+ @param[out] UMASize The IMR region size.
+ @param[out] BiosAction ME response to DID
+
+ @retval EFI_SUCCESS Send DID success.
+ @retval Others Send DID failed.
+
+**/
+EFI_STATUS
+HeciSendDIDMessage (
+ IN UINT32 UMABase,
+ IN UINT8 IsS3,
+ OUT UINT32 *UMASize,
+ OUT UINT8 *BiosAction
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ DRAM_INIT_DONE_CMD_REQ *SendDID;
+ DRAM_INIT_DONE_CMD_RESP_DATA *DIDResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+ UINT32 temp32;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciSendDIDMessage\n"));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || ((SeCMode != SEC_MODE_NORMAL)&&(SEC_MODE_RECOVER !=SeCMode))) {
+ DEBUG ((EFI_D_INFO, "CSE Firmware not in normal and SV mode\n"));
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+ temp32 = MCHMmioRead32 (MOT_OUT_MASK_Bunit);
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendDID = (DRAM_INIT_DONE_CMD_REQ *) DataBuffer;
+ SendDID->MKHIHeader.Data = 0;
+ SendDID->MKHIHeader.Fields.Command = DRAM_INIT_DONE_CMD; ///<DRAM INIT DONE =0x01
+ SendDID->MKHIHeader.Fields.IsResponse = 0;
+ SendDID->MKHIHeader.Fields.GroupId = COMMON_GROUP_ID;//Group ID = 0xF0
+ SendDID->ImrData.BiosMinImrsBa = UMABase;
+
+ if (TRUE == IsS3) {
+ DEBUG ((EFI_D_INFO, "Setting NonDestructiveAliasCheck in DID command successful\n"));
+ SendDID->Flags.NonDestructiveAliasCheck=1;
+ }
+ HeciSendLength = sizeof (DRAM_INIT_DONE_CMD_REQ);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ DIDResp = (DRAM_INIT_DONE_CMD_RESP_DATA *) DataBuffer;
+
+ if (DIDResp->MKHIHeader.Fields.Result == 0) {
+ DEBUG ((EFI_D_INFO, "HeciSend DRAM Init Done successful\n"));
+ }
+ MCHMmioWrite32 (MOT_OUT_MASK_Bunit,temp32);
+ DEBUG ((EFI_D_INFO, "ImrsSortedRegionBa =%x\n", DIDResp->ImrsData.ImrsSortedRegionBa));
+ DEBUG ((EFI_D_INFO, "ImrsSortedRegionLen=%x\n", DIDResp->ImrsData.ImrsSortedRegionLen));
+ DEBUG ((EFI_D_INFO, "OemSettingsRejected=%x\n", DIDResp->ImrsData.OemSettingsRejected));
+ DEBUG ((EFI_D_INFO, "BiosAction =%x\n", DIDResp->BiosAction));
+ ASSERT (UMABase == DIDResp->ImrsData.ImrsSortedRegionBa);
+
+ *UMASize = DIDResp->ImrsData.ImrsSortedRegionLen;
+ *BiosAction = DIDResp->BiosAction;
+
+ return Status;
+}
+
+
+/**
+ Get NVM file's size through HECI1.
+
+ @param[in] FileName The file name.
+ @param[out] FileSize The file's size.
+
+ @retval EFI_SUCCESS Get NVM file size success.
+ @retval Others Get NVM file size failed.
+
+**/
+EFI_STATUS
+HeciGetNVMFileSize (
+ IN UINT8 *FileName,
+ OUT UINTN *FileSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GET_FILESIZE_CMD_REQ_DATA *SendNVMGet;
+ GET_FILESIZE_CMD_RESP_DATA *NVMGetResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: GetNVMFileSize\n"));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendNVMGet = (GET_FILESIZE_CMD_REQ_DATA *) DataBuffer;
+ SendNVMGet->MKHIHeader.Fields.GroupId = 0xA;
+ SendNVMGet->MKHIHeader.Fields.Command = HECI1_FILE_SIZE;
+ AsciiStrCpyS ((CHAR8 *) SendNVMGet->FileName, MCA_MAX_FILE_NAME, (CONST CHAR8 *) FileName);
+
+ DEBUG ((EFI_D_INFO, "WRITE_TO_BIOS_DATA_CMD_REQ_DATA size if %x\n", sizeof (GET_FILESIZE_CMD_REQ_DATA)));
+ HeciSendLength = sizeof (GET_FILESIZE_CMD_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ NVMGetResp = (GET_FILESIZE_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%x\n", NVMGetResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%x\n", NVMGetResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%x\n", NVMGetResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%x\n", NVMGetResp->MKHIHeader.Fields.Result));
+
+ switch (NVMGetResp->MKHIHeader.Fields.Result) {
+ case BIOS_HECI_STATUS_OK:
+ Status = EFI_SUCCESS;
+ break;
+ case BIOS_HECI_STATUS_INVALID_PARAM:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ case BIOS_HECI_STATUS_FILE_NOT_FOUND:
+ Status = EFI_NOT_FOUND;
+ break;
+ case BIOS_HECI_STATUS_AFTER_EOP:
+ Status = EFI_DEVICE_ERROR;
+ break;
+ case BIOS_HECI_STATUS_ERROR:
+ Status = EFI_DEVICE_ERROR;
+ break;
+ default:
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FileSize =%x\n", NVMGetResp->FileSize));
+ *FileSize = NVMGetResp->FileSize;
+ }
+
+ return Status;
+}
+
+
+/**
+ Set Read Write Temp memory.
+
+ @param[in] Address Temp memory.
+
+**/
+VOID
+HeciSetReadWriteCache (
+ VOID* Address
+ )
+{
+ WriteCacheBuffer = Address;
+ ReadCacheBuffer = Address;
+}
+
+
+/**
+ Write Data to NVM file through HECI1.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data content.
+ @param[in] DataSize Data's size.
+ @param[in] Truncate Truncate the file.
+
+ @retval EFI_SUCCESS Write NVM file success.
+ @retval Others Write NVM file failed.
+
+**/
+EFI_STATUS
+HeciWriteNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN Truncate
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA *SendNVMWrite;
+ WRITE_TO_RPMB_STORAGE_CMD_RESP_DATA *NVMWriteResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+ VOID *TempBuffer;
+ VOID *AllocatedBuffer;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: WriteNVMFile, FileOffset : 0x%x, DataBuffer: 0x%x, DataSize : 0x%x \n", Offset, Data, DataSize));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ AllocatedBuffer = NULL;
+ TempBuffer = Data;
+ if (WriteCacheBuffer != NULL) {
+ TempBuffer = WriteCacheBuffer;
+ } else {
+ AllocatedBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DataSize));
+ ASSERT (AllocatedBuffer != NULL);
+ if (AllocatedBuffer != NULL) {
+ TempBuffer = AllocatedBuffer;
+ }
+ }
+ CopyMem (TempBuffer, Data, DataSize);
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ SendNVMWrite = (WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA *) DataBuffer;
+ SendNVMWrite->MKHIHeader.Data = 0;
+ SendNVMWrite->MKHIHeader.Fields.GroupId = GROUP_ID_MCA;
+ SendNVMWrite->MKHIHeader.Fields.Command = HECI1_WRITE_DATA;
+ AsciiStrCpyS ((CHAR8 *) SendNVMWrite->FileName, sizeof (SendNVMWrite->FileName), (CONST CHAR8 *) FileName);
+ SendNVMWrite->Offset = Offset;
+ SendNVMWrite->Size = (UINT32) DataSize;
+ SendNVMWrite->Truncate = (Truncate) ? 1 : 0;
+ SendNVMWrite->SrcAddressLower = (UINT32) (UINTN) TempBuffer;
+ SendNVMWrite->SrcAddressUpper = (UINT32) ((PHYSICAL_ADDRESS) (UINTN) TempBuffer >> 32);
+ DEBUG ((EFI_D_INFO, "TempBuffer: 0x%x \n", TempBuffer));
+
+ DEBUG ((EFI_D_INFO, "WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA size if %x\n", sizeof(WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA)));
+ HeciSendLength = sizeof (WRITE_TO_RPMB_STORAGE_CMD_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ NVMWriteResp = (WRITE_TO_RPMB_STORAGE_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", NVMWriteResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", NVMWriteResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", NVMWriteResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", NVMWriteResp->MKHIHeader.Fields.Result));
+
+ if (NVMWriteResp->MKHIHeader.Fields.Result != 0) {
+ DEBUG ((EFI_D_ERROR, "NVM Write Failed. Update is lost. If repeatedly encountered, clear GPP4 and try again\n"));
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ if (AllocatedBuffer != NULL) {
+ FreePages (AllocatedBuffer, EFI_SIZE_TO_PAGES (DataSize));
+ }
+ return Status;
+}
+
+
+/**
+ Read NVM file data from HECI1.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data buffer.
+ @param[in] DataSize Data's size.
+
+ @retval EFI_SUCCESS Read NVM file success.
+ @retval Others Read NVM file failed.
+
+**/
+EFI_STATUS
+HeciReadNVMFile(
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN *DataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ READ_FROM_RPMB_STORAGE_CMD_REQ_DATA *SendNVMRead;
+ READ_FROM_RPMB_STORAGE_CMD_RESP_DATA *NVMReadResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+ VOID *TempBuffer;
+ VOID *AllocatedBuffer;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: ReadNVMFile FileOffset : 0x%x, DataBuffer: 0x%x, DataSize : 0x%x \n", Offset, Data, *DataSize));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ AllocatedBuffer = NULL;
+ TempBuffer = Data;
+ if (ReadCacheBuffer != NULL) {
+ TempBuffer = ReadCacheBuffer;
+ } else {
+ AllocatedBuffer = AllocatePages (EFI_SIZE_TO_PAGES (*DataSize));
+ ASSERT (AllocatedBuffer != NULL);
+ if (AllocatedBuffer != NULL) {
+ TempBuffer = AllocatedBuffer;
+ }
+ }
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ SendNVMRead = (READ_FROM_RPMB_STORAGE_CMD_REQ_DATA *) DataBuffer;
+ SendNVMRead->MKHIHeader.Fields.GroupId = GROUP_ID_MCA;
+ SendNVMRead->MKHIHeader.Fields.Command = HECI1_READ_DATA;
+ AsciiStrCpyS ((CHAR8 *) SendNVMRead->FileName, sizeof (SendNVMRead->FileName), (CONST CHAR8 *) FileName);
+ SendNVMRead->Offset = Offset;
+ SendNVMRead->Size = (UINT16)*DataSize;
+ SendNVMRead->DstAddressLower = (UINT32) (UINTN) TempBuffer;
+ SendNVMRead->DstAddressUpper = (UINT32) ((PHYSICAL_ADDRESS) (UINTN) TempBuffer >> 32);;
+ DEBUG((EFI_D_INFO, "TempBuffer: 0x%x \n", TempBuffer));
+
+ DEBUG ((EFI_D_INFO, "READ_FROM_RPMB_STORAGE_CMD_REQ_DATA size if %x\n", sizeof (READ_FROM_RPMB_STORAGE_CMD_REQ_DATA)));
+ HeciSendLength = sizeof (READ_FROM_RPMB_STORAGE_CMD_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ NVMReadResp = (READ_FROM_RPMB_STORAGE_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", NVMReadResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", NVMReadResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", NVMReadResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", NVMReadResp->MKHIHeader.Fields.Result));
+ DEBUG ((EFI_D_INFO, "DataSize =%08x\n", NVMReadResp->DataSize));
+
+ if (NVMReadResp->MKHIHeader.Fields.Result == 0) {
+ if (Data != TempBuffer) {
+ CopyMem(Data, TempBuffer, NVMReadResp->DataSize);
+ }
+ *DataSize = NVMReadResp->DataSize;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ if (AllocatedBuffer != NULL) {
+ FreePages (AllocatedBuffer, EFI_SIZE_TO_PAGES (*DataSize));
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+HeciDataClearLock (
+void
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ DATA_CLEAR_LOCK_REQ *SendDCL;
+ DATA_CLEAR_LOCK_RES *DCLResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x40];
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ SendDCL = (DATA_CLEAR_LOCK_REQ *) DataBuffer;
+ SendDCL->MKHIHeader.Fields.GroupId = MKHI_IFWI_UPDATE_GROUP_ID;
+ SendDCL->MKHIHeader.Fields.Command = DATA_CLEAR_LOCK_CMD_ID;
+ SendDCL->MKHIHeader.Fields.IsResponse = 0;
+ DEBUG ((EFI_D_INFO, "HeciDataClearLock size is %x\n", sizeof (DATA_CLEAR_LOCK_RES)));
+ HeciSendLength = sizeof (DATA_CLEAR_LOCK_REQ);
+ HeciRecvLength = sizeof (DataBuffer);
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+ DCLResp = (DATA_CLEAR_LOCK_RES *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", DCLResp->Header.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", DCLResp->Header.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", DCLResp->Header.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", DCLResp->Header.Fields.Result));
+
+ return DCLResp->Header.Fields.Result;
+}
+
+
+/**
+ Send EOP message through HECI1.
+
+ @retval EFI_SUCCESS Send EOP message success.
+ @retval Others Send EOP message failed.
+
+**/
+EFI_STATUS
+HeciEndOfPost (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GEN_END_OF_POST *SendEOP;
+ GEN_END_OF_POST_ACK *EOPResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: EndOfPost\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || ((SeCMode != SEC_MODE_NORMAL) && (SeCMode !=SEC_MODE_RECOVER))) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendEOP = (GEN_END_OF_POST *) DataBuffer;
+ SendEOP->MKHIHeader.Fields.GroupId = EOP_GROUP_ID;
+ SendEOP->MKHIHeader.Fields.Command = EOP_CMD_ID;
+
+ DEBUG ((EFI_D_INFO, "GEN_END_OF_POST size is %x\n", sizeof (GEN_END_OF_POST)));
+ HeciSendLength = sizeof (GEN_END_OF_POST);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ EOPResp = (GEN_END_OF_POST_ACK *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", EOPResp->Header.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", EOPResp->Header.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", EOPResp->Header.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", EOPResp->Header.Fields.Result));
+ DEBUG ((EFI_D_INFO, "RequestedActions =%08x\n", EOPResp->Data.RequestedActions));
+
+ return Status;
+}
+
+
+/**
+ Send EOS message through HECI1.
+
+ @retval EFI_SUCCESS Send EOS message success.
+ @retval Others Send EOS message failed.
+
+**/
+EFI_STATUS
+HeciEndOfServices(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GEN_END_OF_SERVICES *SendEOS;
+ GEN_END_OF_SERVICES_ACK *EOSResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: EndOfServices\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendEOS = (GEN_END_OF_SERVICES *) DataBuffer;
+ SendEOS->MKHIHeader.Fields.GroupId = GROUP_ID_MCA;
+ SendEOS->MKHIHeader.Fields.Command = HECI1_EOS;
+
+ DEBUG ((EFI_D_INFO, "GEN_END_OF_SERVICES size is %x\n", sizeof (GEN_END_OF_SERVICES)));
+ HeciSendLength = sizeof (GEN_END_OF_SERVICES);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ EOSResp = (GEN_END_OF_SERVICES_ACK *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", EOSResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", EOSResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", EOSResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", EOSResp->MKHIHeader.Fields.Result));
+
+ return Status;
+}
+
+
+/**
+ Get IFWI DNX request.
+
+ @param[out] IfwiDnxRequestData Dnx request data buffer.
+
+ @retval EFI_SUCCESS Get IFWI DNX success.
+ @retval Others Get IFWI DNX failed.
+
+**/
+
+EFI_STATUS
+HeciGetIfwiDnxRequest (
+ OUT MBP_IFWI_DNX_REQUEST *IfwiDnxRequestData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataBuffer[0x100];
+ MBP_CMD_RESP_DATA *MBPHeader;
+ MBP_ITEM_HEADER *MBPItem;
+ MBP_IFWI_DNX_REQUEST *IfwiDnxRequest;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetIfwiDnxRequest\n"));
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ Status = HeciMBP (DataBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MBPHeader = (MBP_CMD_RESP_DATA *) DataBuffer;
+ DumpBuffer_HECI (MBPHeader, sizeof (MBP_CMD_RESP_DATA));
+ MBPItem = (MBP_ITEM_HEADER *) (MBPHeader + 1);
+ DumpBuffer_HECI (MBPItem, MBPHeader->Length);
+
+ while ((UINT32 *) MBPItem < (UINT32 *) DataBuffer + MBPHeader->Length) {
+ if (MBPItem->AppID == 7 && MBPItem->ItemID == 1) {
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ IfwiDnxRequest = (MBP_IFWI_DNX_REQUEST *) (MBPItem);
+ CopyMem ((VOID *) IfwiDnxRequestData, (VOID *) IfwiDnxRequest, sizeof (MBP_IFWI_DNX_REQUEST));
+
+ return EFI_SUCCESS;
+ }
+ MBPItem = (MBP_ITEM_HEADER *) ((UINT32 *) MBPItem + MBPItem->Length);
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+/**
+ Get Image FW Versions.
+
+ @param[out] MsgGetFwVersionRespData Output FW version response data
+
+ @retval EFI_SUCCESS Get version success.
+ @retval Others Get version failed.
+
+**/
+EFI_STATUS
+HeciGetImageFwVerMsg (
+ OUT FW_VERSION_CMD_RESP_DATA *MsgGetFwVersionRespData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ FW_VER_CMD_REQ *MsgGetFwVersion;
+ FW_VERSION_CMD_RESP_DATA *MsgGetFwVersionResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x20];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetImageFwVerMsg\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ //
+ // Allocate MsgGenGetFwVersion data structure
+ //
+ SetMem (DataBuffer, sizeof (DataBuffer), 0x0);
+
+ MsgGetFwVersion = (FW_VER_CMD_REQ *) DataBuffer;
+ MsgGetFwVersion->MKHIHeader.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MsgGetFwVersion->MKHIHeader.Fields.Command = FW_VER_CMD_REQ_ID;
+ MsgGetFwVersion->MKHIHeader.Fields.IsResponse = 0;
+
+ DEBUG ((EFI_D_INFO, "FW_VER_CMD_REQ size is 0x%x, FW_VERSION_CMD_RESP_DATA size is: 0x%x\n", sizeof (FW_VER_CMD_REQ), sizeof (FW_VERSION_CMD_RESP_DATA)));
+ HeciSendLength = sizeof (FW_VER_CMD_REQ);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ //
+ // Send Get image Firmware Version Request to CSE
+ //
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ DumpBuffer_HECI (DataBuffer, sizeof (DataBuffer));
+ MsgGetFwVersionResp = (FW_VERSION_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", MsgGetFwVersionResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", MsgGetFwVersionResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone =%08x\n", MsgGetFwVersionResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", MsgGetFwVersionResp->MKHIHeader.Fields.Result));
+ DEBUG ((EFI_D_INFO, "NumModules =%08x\n", MsgGetFwVersionResp->NumModules));
+
+ CopyMem (MsgGetFwVersionRespData, DataBuffer, sizeof (FW_VERSION_CMD_RESP_DATA));
+
+ return Status;
+}
+
+
+/**
+ Get NFC Device Type through HECI1.
+
+ @param[out] Mbp_Nfc_Device_Type Output data buffer for NFC device type.
+
+ @retval EFI_SUCCESS Get device success.
+ @retval Others Get device failed.
+
+**/
+EFI_STATUS
+HeciGetNfcDeviceType (
+ OUT MBP_NFC_DEVICE_TYPE *Mbp_Nfc_Device_Type
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataBuffer[0x100];
+ MBP_CMD_RESP_DATA *MBPHeader;
+ MBP_ITEM_HEADER *MBPItem;
+ MBP_NFC_DEVICE_TYPE *Nfc_Device_Type;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetNfcDeviceType\n"));
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ Status = HeciMBP (DataBuffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "HeciGetNfcDeviceType HeciMBP: %r\n", Status));
+ return Status;
+ }
+
+ MBPHeader = (MBP_CMD_RESP_DATA *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "HeciGetNfcDeviceType 1\n"));
+ DumpBuffer_HECI (MBPHeader, sizeof (MBP_CMD_RESP_DATA));
+ MBPItem = (MBP_ITEM_HEADER *) (MBPHeader + 1);
+ DEBUG ((EFI_D_INFO, "HeciGetNfcDeviceType 2\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER));
+
+ while ((UINT32 *) MBPItem < (UINT32 *) DataBuffer + MBPHeader->Length) {
+ if (MBPItem->AppID == 6 && MBPItem->ItemID == 1) {
+ DEBUG ((EFI_D_INFO, "HeciGetNfcDeviceType 3\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ Nfc_Device_Type = (MBP_NFC_DEVICE_TYPE *) (MBPItem);
+ CopyMem ((VOID *) Mbp_Nfc_Device_Type, (VOID *) Nfc_Device_Type, sizeof (MBP_NFC_DEVICE_TYPE));
+ DEBUG ((EFI_D_INFO, "Mbp_Nfc_Device_Type= %x\n",Mbp_Nfc_Device_Type->NfcDeviceData));
+ return EFI_SUCCESS;
+ }
+ MBPItem = (MBP_ITEM_HEADER *) ((UINT32 *) MBPItem + MBPItem->Length);
+ DEBUG ((EFI_D_INFO, "HeciGetNfcDeviceType 4\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+/**
+ Get ME FW Capability from MBP.
+
+ @param[out] MBP_ME_FW_CAPS Output data buffer for ME FW Capability.
+
+ @retval EFI_SUCCESS Get ME FW Capability success.
+ @retval Others Get ME FW Capability failed.
+
+**/
+
+EFI_STATUS
+HeciGetMeFwCapability (
+ OUT MBP_ME_FW_CAPS *Mbp_Me_Fw_Caps
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataBuffer[0x100];
+ MBP_CMD_RESP_DATA *MBPHeader;
+ MBP_ITEM_HEADER *MBPItem;
+ MBP_ME_FW_CAPS *Me_Fw_Caps;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetMeFwCapability\n"));
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ Status = HeciMBP (DataBuffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "HeciGetMeFwCapability HeciMBP: %r\n", Status));
+ return Status;
+ }
+
+ MBPHeader = (MBP_CMD_RESP_DATA *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "HeciGetMeFwCapability 1\n"));
+ DumpBuffer_HECI (MBPHeader, sizeof (MBP_CMD_RESP_DATA));
+ MBPItem = (MBP_ITEM_HEADER *) (MBPHeader + 1);
+ DEBUG ((EFI_D_INFO, "HeciGetMeFwCapability 2\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER));
+
+ while ((UINT32 *) MBPItem < (UINT32 *) DataBuffer + MBPHeader->Length) {
+ if (MBPItem->AppID == 1 && MBPItem->ItemID == 2) {
+ DEBUG ((EFI_D_INFO, "HeciGetMeFwCapability 3\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ Me_Fw_Caps = (MBP_ME_FW_CAPS *) (MBPItem);
+ CopyMem ((VOID *) Mbp_Me_Fw_Caps, (VOID *) Me_Fw_Caps, sizeof (MBP_ME_FW_CAPS));
+ DEBUG ((EFI_D_INFO, "Mbp_Me_Fw_Caps = %x\n", Mbp_Me_Fw_Caps->CurrentFeatures));
+ return EFI_SUCCESS;
+ }
+ MBPItem = (MBP_ITEM_HEADER *) ((UINT32 *) MBPItem + MBPItem->Length);
+ DEBUG ((EFI_D_INFO, "HeciGetMeFwCapability 4\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+/**
+ Send IAFW DNX request set message throught HECI1.
+
+ @param[in] Resp Buffer to receive the CSE response data..
+
+ @retval EFI_SUCCESS Set request success.
+ @retval Others Set request failed.
+
+**/
+EFI_STATUS
+HeciIafwDnxReqSet (
+ IN OUT IAFW_DNX_REQ_SET_RESP_DATA *Resp
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ IAFW_DNX_REQ_SET_REQ_DATA *Req;
+ IAFW_DNX_REQ_SET_RESP_DATA *RespIn;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Starts to send HECI Message: HeciIafwDnxReqSet\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || ((SeCMode != SEC_MODE_NORMAL) && (SEC_MODE_RECOVER !=SeCMode))) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ Req = (IAFW_DNX_REQ_SET_REQ_DATA *) DataBuffer;
+ Req->MKHIHeader.Fields.GroupId = MKHI_GEN_DNX_GROUP_ID;
+ Req->MKHIHeader.Fields.Command = CSE_DNX_REQ_SET;
+
+ DEBUG ((EFI_D_INFO, "IAFW_DNX_REQ_Set_REQ_DATA size is %x\n", sizeof (IAFW_DNX_REQ_CLEAR_REQ_DATA)));
+ HeciSendLength = sizeof (IAFW_DNX_REQ_SET_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ RespIn = (IAFW_DNX_REQ_SET_RESP_DATA *) DataBuffer;
+ CopyMem ((VOID *) Resp, (VOID *) RespIn, sizeof (IAFW_DNX_REQ_SET_RESP_DATA));
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", Resp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", Resp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", Resp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", Resp->MKHIHeader.Fields.Result));
+ DEBUG ((EFI_D_INFO, "Response ReqBiosAction =%08x\n", Resp->ReqBiosAction));
+
+ return Status;
+}
+
+
+/**
+ Send IAFW DNX request clear message throught HECI1.
+
+ @param[in] Flag Flag to decide which type clear operation need be done.
+
+ @retval EFI_SUCCESS Clear request success.
+ @retval Others Clear request failed.
+
+**/
+EFI_STATUS
+HeciIafwDnxReqClear (
+ IN UINT32 Flag
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ IAFW_DNX_REQ_CLEAR_REQ_DATA *Req;
+ IAFW_DNX_REQ_CLEAR_RESP_DATA *Resp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x70];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciIafwDnxReqClear\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || ((SeCMode != SEC_MODE_NORMAL) && (SEC_MODE_RECOVER !=SeCMode))) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ Req = (IAFW_DNX_REQ_CLEAR_REQ_DATA *) DataBuffer;
+ Req->MKHIHeader.Fields.GroupId = MKHI_GEN_DNX_GROUP_ID;
+ Req->MKHIHeader.Fields.Command = IAFW_DNX_REQ_CLEAR;
+ Req->Flag = Flag;
+
+ DEBUG ((EFI_D_INFO, "IAFW_DNX_REQ_CLEAR_REQ_DATA size is %x\n", sizeof (IAFW_DNX_REQ_CLEAR_REQ_DATA)));
+ HeciSendLength = sizeof (IAFW_DNX_REQ_CLEAR_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ Resp = (IAFW_DNX_REQ_CLEAR_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", Resp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", Resp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", Resp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", Resp->MKHIHeader.Fields.Result));
+
+ return Status;
+}
+
+
+/**
+ The Get FW Feature Status message is based on MKHI interface.
+ This command is used by BIOS/IntelR MEBX to get firmware runtime status.
+ The GET FW RUNTIME STATUS message doesn't need to check the HFS.
+ FWInitComplete value before sending the command.
+ It means this message can be sent regardless of HFS.FWInitComplete.
+
+ @param[out] RuleData MEFWCAPS_SKU message
+
+ @retval EFI_UNSUPPORTED Current ME mode doesn't support this function.
+
+**/
+EFI_STATUS
+HeciGetFwFeatureStateMsgII (
+ OUT MEFWCAPS_SKU *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ UINT32 RecvLength;
+ GEN_GET_FW_FEATURE_STATUS_ACK GetFwFeatureStatus;
+ UINT32 SeCMode;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetFwFeatureStateMsgII\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ GetFwFeatureStatus.MKHIHeader.Data = 0;
+ GetFwFeatureStatus.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ GetFwFeatureStatus.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ GetFwFeatureStatus.MKHIHeader.Fields.IsResponse = 0;
+ GetFwFeatureStatus.RuleId = 0x20;
+ Length = sizeof (GEN_GET_FW_FEATURE_STATUS);
+ RecvLength = sizeof (GEN_GET_FW_FEATURE_STATUS_ACK);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32*) &GetFwFeatureStatus,
+ Length,
+ &RecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (!EFI_ERROR (Status)) {
+ RuleData->Data = GetFwFeatureStatus.RuleData.Data;
+ DEBUG ((EFI_D_INFO, "BIOS Get Feature Message: %08x\n", RuleData->Data = GetFwFeatureStatus.RuleData.Data));
+ } else {
+ DEBUG ((EFI_D_ERROR, "BIOS Get Feature Message ERROR: %08x\n", Status));
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+HeciFwFeatureStateOverride (
+ IN UINT32 EnableState,
+ IN UINT32 DisableState
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciLength;
+ UINT32 HeciRecvLength;
+ UINT32 SeCMode;
+ FIRMWARE_CAPABILITY_OVERRIDE MngStateCmd;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciFwFeatureStateOverride\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MngStateCmd.MKHIHeader.Data = 0;
+ MngStateCmd.MKHIHeader.Fields.Command = FIRMWARE_CAPABILITY_OVERRIDE_CMD;
+ MngStateCmd.MKHIHeader.Fields.IsResponse = 0;
+ MngStateCmd.MKHIHeader.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MngStateCmd.MKHIHeader.Fields.Reserved = 0;
+ MngStateCmd.MKHIHeader.Fields.Result = 0;
+ MngStateCmd.FeatureState.EnableFeature = EnableState;
+ MngStateCmd.FeatureState.DisableFeature = DisableState;
+ HeciLength = sizeof (FIRMWARE_CAPABILITY_OVERRIDE);
+ HeciRecvLength = sizeof (FIRMWARE_CAPABILITY_OVERRIDE_ACK);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32*) &MngStateCmd,
+ HeciLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ DEBUG ((EFI_D_INFO, "BIOS HeciFwFeatureStateOverride Message: %x\n", Status));
+
+ return Status;
+}
+
+
+/**
+ Send IFWI PREPARE FOR UPDATE(IPFU) Command through HECI1.
+ This command provide necessary synchronization between HOST & CSE when
+ BIOS Performance IFWI Update process.
+
+ @retval EFI_SUCCESS Send IFWI Prepare For Update command succeeded
+ @retval Others Send IFWI Prepare For Update command failed.
+
+**/
+EFI_STATUS
+HeciIfwiPrepareForUpdate(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ IFWI_PREPARE_FOR_UPDATE *SendDC;
+ IFWI_PREPARE_FOR_UPDATE_ACK *DCResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x2];
+ UINT8 Flags;
+ UINT8 Result;
+ UINT8 TimeOut;
+ UINT8 Count;
+ BOOLEAN Reset_Status;
+
+ DEBUG((EFI_D_INFO, "BIOS Start Send HECI Message: HeciIfwiPrepareForUpdate\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+ DEBUG ((EFI_D_ERROR, "IFWI Prepare For Update: In Progress...\n"));
+
+ Flags = IPFU_TRY_AGAIN;
+ Result = 0;
+ TimeOut = 0;
+
+ //
+ // Keep in while loop until Successful or Error or timeout of 1 min duration
+ //
+ while ((Flags == IPFU_TRY_AGAIN) && (TimeOut <= IPFU_TIMEOUT)) {
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ SendDC = (IFWI_PREPARE_FOR_UPDATE *) DataBuffer;
+ SendDC->MKHIHeader.Fields.GroupId = MKHI_IFWI_UPDATE_GROUP_ID;
+ SendDC->MKHIHeader.Fields.Command = IFWI_PREPARE_FOR_UPDATE_CMD_ID;
+ SendDC->ResetType = 0x01;
+
+ HeciSendLength = sizeof (IFWI_PREPARE_FOR_UPDATE);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ //
+ // When CSE is in reset, Status may fail, so ignore checking of Status
+ //
+ DCResp = (IFWI_PREPARE_FOR_UPDATE_ACK *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group = %08x\n", DCResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command = %08x\n", DCResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone = %08x\n", DCResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result = %08x\n", DCResp->MKHIHeader.Fields.Result));
+ DEBUG ((EFI_D_INFO, "Flags value = %08x\n", DCResp->Flags));
+
+ Result = (UINT8) DCResp->MKHIHeader.Fields.Result;
+ Flags = (UINT8) DCResp->Flags;
+
+ if (Result == EFI_SUCCESS) {
+ if (Flags != IPFU_SUCCESS) {
+ Count = 0;
+ Reset_Status = FALSE;
+ while ((Reset_Status == FALSE) && (Count <= 60)) { // Try checking for 1 min and exit
+ Status = CheckCseResetAndIssueHeciReset (&Reset_Status);
+ if (Reset_Status == FALSE) {
+ MicroSecondDelay (1000 * 1000);
+ Count++;
+ }
+ }
+ if (Count > 60){
+ DEBUG ((EFI_D_ERROR, "CSE Reset or HECI reset not occurred to send Command again \n"));
+ return EFI_TIMEOUT;
+ }
+ TimeOut += Count; // Add time delay counted for reset of CSE too.
+ MicroSecondDelay (1000 * 1000);
+ TimeOut++;
+ } // end if
+ } else {
+ DEBUG ((EFI_D_ERROR, "IFWI Prepare For Update - Failed! Result: 0x%x \n", Result));
+ return Result;
+ } // end if
+
+ } // End of While Loop
+
+ if (Flags == IPFU_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "IFWI Prepare For Update - SUCCESS! Result = 0x%x, Flags = 0x%x \n", Result, Flags));
+ return EFI_SUCCESS;
+ } else {
+ if (TimeOut > IPFU_TIMEOUT) {
+ DEBUG ((EFI_D_ERROR, "IFWI Prepare For Update - TIME OUT! \n"));
+ return EFI_TIMEOUT;
+ }
+ DEBUG ((EFI_D_ERROR, "IFWI Prepare For Update - Flag ERROR! Result = 0x%x, Flags = 0x%x \n", Result, Flags));
+ return EFI_PROTOCOL_ERROR;
+ } //end if
+
+}
+
+
+/**
+ Send RPMB/Device Extention region Data Clear message through HECI1.
+ Note: This command should be send only after successful execution of
+ IFWI_PREPARE_FOR_UPDATE Command.
+
+ @retval EFI_SUCCESS Send DataClear message success.
+ @retval Others Send DataClear message failed.
+
+**/
+EFI_STATUS
+HeciDataClear (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ IFWI_UPDATE_DATA_CLEAR *SendDC;
+ IFWI_UPDATE_DATA_CLEAR_ACK *DCResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x4];
+ UINT8 Result = 0xFF; // Status Undefined
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: DataClear\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful \n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendDC = (IFWI_UPDATE_DATA_CLEAR *) DataBuffer;
+ SendDC->MKHIHeader.Fields.GroupId = MKHI_IFWI_UPDATE_GROUP_ID;
+ SendDC->MKHIHeader.Fields.Command = DATA_CLEAR_CMD_ID;
+
+ DEBUG ((EFI_D_INFO, "IFWI_UPDATE_DATA_CLEAR size is %x\n", sizeof (IFWI_UPDATE_DATA_CLEAR)));
+ HeciSendLength = sizeof (IFWI_UPDATE_DATA_CLEAR);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ DCResp = (IFWI_UPDATE_DATA_CLEAR_ACK *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group = %08x\n", DCResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command = %08x\n", DCResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone = %08x\n", DCResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result = %08x\n", DCResp->MKHIHeader.Fields.Result));
+ Result = (UINT8) DCResp->MKHIHeader.Fields.Result;
+
+ if (Result == 0) {
+ DEBUG ((EFI_D_INFO, "Data Clear SUCCESS! \n"));
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((EFI_D_INFO, "Data Clear FAILED! Result = %08x\n", Result));
+ Status = Result;
+ }
+
+ return Status;
+}
+
+
+/**
+ Send 'Update Image Check' command to CSE to verify IFWI Image and confirm
+ that appropriate for FW Update. (This command will be sending as part of Capsule Update)
+
+ @param[in] ImageBaseAddr FW Image Base address. 64 Bit Wide
+ @param[in] ImageSize FW Image Size
+ @param[in] *HeciResponse To capture Response Info (Optional)
+ @param[in] ResponseSize Size of Response (Optional)
+
+ @return EFI_SUCCESS Image was checked (best effort) and verified to be appropriate for FW update.
+ @return 0x01 IMAGE_FAILED.
+ @return 0x02 IMG_SIZE_INVALID.
+ @return 0x05 SIZE_ERROR
+ @return 0x89 STATUS_NOT_SUPPORTED.
+ @return 0x8D STATUS_INVALID_COMMAND.
+ @return 0xFF STATUS_UNDEFINED.
+
+**/
+EFI_STATUS
+HeciUpdateImageCheck (
+ IN UINT64 ImageBaseAddr,
+ IN UINT32 ImageSize,
+ IN OUT UINT32 *HeciResponse,
+ IN UINT32 ResponseSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ IFWI_UPDATE_IMAGE_CHECK *SendRequest;
+ IFWI_UPDATE_IMAGE_CHECK_ACK *ReceiveResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x7];
+ UINT8 Result = 0xFF;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciUpdateImageCheck\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR(Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful \n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendRequest = (IFWI_UPDATE_IMAGE_CHECK *) DataBuffer;
+ SendRequest->MKHIHeader.Fields.GroupId = MKHI_IFWI_UPDATE_GROUP_ID;
+ SendRequest->MKHIHeader.Fields.Command = UPDATE_IMAGE_CHECK_CMD_ID;
+ SendRequest->ImageBaseAddrLower32b = (UINT32) ImageBaseAddr;
+ SendRequest->ImageBaseAddrUpper32b = (UINT32) (ImageBaseAddr >> 32);
+ SendRequest->ImageSize = ImageSize;
+
+ DEBUG ((EFI_D_INFO, "IFWI_UPDATE_IMAGE_CHECK size is %x\n", sizeof (IFWI_UPDATE_IMAGE_CHECK)));
+ HeciSendLength = sizeof (IFWI_UPDATE_IMAGE_CHECK);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ ReceiveResp = (IFWI_UPDATE_IMAGE_CHECK_ACK *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "Group = %08x\n", ReceiveResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command = %08x\n", ReceiveResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone = %08x\n", ReceiveResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result = %08x\n", ReceiveResp->MKHIHeader.Fields.Result));
+
+ //
+ // Copy Response information if response pointer is available
+ //
+ if ((HeciResponse != NULL) && (ResponseSize != 0)) {
+ if (HeciRecvLength < ResponseSize) {
+ ResponseSize = HeciRecvLength;
+ }
+ CopyMem (HeciResponse, DataBuffer, (UINTN) ResponseSize);
+ }
+
+ Result = (UINT8) ReceiveResp->MKHIHeader.Fields.Result;
+ if (Result == 0) {
+ DEBUG ((EFI_D_INFO, "Update Image Check SUCCESS! \n"));
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((EFI_D_INFO, "Update Image Check FAILED! Result = %08x\n", Result));
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+
+/**
+ Checks Platform Trust Technology enablement state.
+
+ @param[out] IsPttEnabledState TRUE if PTT is enabled, FALSE othewrwise.
+
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHeciGetState (
+ OUT BOOLEAN *IsPttEnabledState
+ )
+{
+ EFI_STATUS Status;
+ MEFWCAPS_SKU CurrentFeatures;
+
+ *IsPttEnabledState = FALSE;
+
+ Status = HeciGetFwFeatureStateMsgII (&CurrentFeatures);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ DEBUG ((EFI_D_INFO, "SkuMgr Data = 0x%X\n", CurrentFeatures.Data));
+
+ if (CurrentFeatures.Fields.PTT) {
+ *IsPttEnabledState = TRUE;
+ }
+
+ DEBUG ((EFI_D_INFO, "PTT SkuMgr: PttState = %d\n", *IsPttEnabledState));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Changes current Platform Trust Technology state.
+
+ @param[in] PttEnabledState TRUE to enable, FALSE to disable.
+
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHeciSetState (
+ IN BOOLEAN PttEnabledState
+ )
+{
+ EFI_STATUS Status;
+ UINT32 EnableBitmap;
+ UINT32 DisableBitmap;
+
+ if (PttEnabledState) {
+ //
+ // Enable PTT
+ //
+ DEBUG ((EFI_D_INFO, "PTT SkuMgr: Enable PTT\n"));
+ EnableBitmap = PTT_BITMASK;
+ DisableBitmap = CLEAR_PTT_BIT;
+ } else {
+ //
+ // Disable PTT
+ //
+ DEBUG ((EFI_D_INFO, "PTT SkuMgr: Disable PTT\n"));
+ EnableBitmap = CLEAR_PTT_BIT;
+ DisableBitmap = PTT_BITMASK;
+ }
+
+ Status = HeciFwFeatureStateOverride (EnableBitmap, DisableBitmap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Send Reset Request Message through HECI.
+
+ @param[in] ResetOrigin Reset source.
+ @param[in] ResetType Global or Host reset.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendResetRequest (
+ IN UINT8 ResetOrigin,
+ IN UINT8 ResetType
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciLength;
+ CBM_RESET_REQ CbmResetRequest;
+ UINT32 HeciRecvLength;
+ UINT32 SeCMode;
+
+ CbmResetRequest.MKHIHeader.Data = 0;
+ CbmResetRequest.MKHIHeader.Fields.Command = CBM_RESET_REQ_CMD;
+ CbmResetRequest.MKHIHeader.Fields.IsResponse = 0;
+ CbmResetRequest.MKHIHeader.Fields.GroupId = MKHI_CBM_GROUP_ID;
+ CbmResetRequest.MKHIHeader.Fields.Reserved = 0;
+ CbmResetRequest.MKHIHeader.Fields.Result = 0;
+ CbmResetRequest.Data.RequestOrigin = ResetOrigin;
+ CbmResetRequest.Data.ResetType = ResetType;
+
+ HeciLength = sizeof (CBM_RESET_REQ);
+ HeciRecvLength = sizeof (CBM_RESET_REQ);
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ Status = HeciSendwoACK (
+ (UINT32 *) &CbmResetRequest,
+ HeciLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Send Reset Request - %r\n", Status));
+ }
+
+ return Status;
+}
+
+
+/**
+ Wait for CSE reset bit set and then Reset HECI interface.
+
+ @param[out] Reset_Status Reset Status value.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+
+EFI_STATUS
+CheckCseResetAndIssueHeciReset (
+ OUT BOOLEAN *Reset_Status
+ )
+{
+ EFI_STATUS Status;
+ volatile HECI_SEC_CONTROL_REGISTER *SecControlReg;
+ UINTN HeciMbar;
+
+ HeciMbar = CheckAndFixHeciForAccess (HECI1_DEVICE);
+ if (HeciMbar == 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Reset_Status = FALSE;
+ SecControlReg = (volatile HECI_SEC_CONTROL_REGISTER *) (UINTN) (HeciMbar + SEC_CSR_HA);
+ if (SecControlReg->r.SEC_RST_HRA == 1) {
+ DEBUG ((EFI_D_INFO, "CheckCseResetAndIssueHeciReset, SecControlReg: %08x\n", SecControlReg->ul));
+ *Reset_Status = TRUE;
+ //
+ // Reset HECI Interface
+ //
+ Status = ResetHeciInterface (HECI1_DEVICE);
+ if (EFI_ERROR (Status)) {
+ *Reset_Status = FALSE;
+ } else {
+ DEBUG((EFI_D_INFO, "CheckCseResetAndIssueHeciReset, HECI Reset success\n"));
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "CheckCseResetAndIssueHeciReset, SecControlReg: %08x\n", SecControlReg->ul));
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+HeciCoreBiosDoneMsg (
+ void
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ UINT32 RespLength;
+ CORE_BIOS_DONE CoreBiosDone;
+ UINT32 SeCMode;
+ Length = sizeof (CORE_BIOS_DONE);
+ RespLength = sizeof (CORE_BIOS_DONE_ACK);
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return;
+ }
+
+ DEBUG ((EFI_D_INFO, "Sending the HeciCoreBiosDoneMsg - Start \n"));
+ CoreBiosDone.MkhiHeader.Data = 0;
+ CoreBiosDone.MkhiHeader.Fields.GroupId = HECI_MKHI_MCA_GROUP_ID;
+ CoreBiosDone.MkhiHeader.Fields.Command = HECI_MCA_CORE_BIOS_DONE_CMD;
+ CoreBiosDone.MkhiHeader.Fields.IsResponse = 0;
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) &CoreBiosDone,
+ Length,
+ &RespLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ DEBUG ((EFI_D_INFO, "Sending the HeciCoreBiosDoneMsg - done \n"));
+
+ return;
+}
+
+
+VOID
+EFIAPI
+HeciDXECallback (
+ IN EFI_EVENT Event,
+ IN VOID *ParentImageHandle
+ )
+{
+ HeciDataClearLock ();
+ HeciCoreBiosDoneMsg ();
+}
+
+
+/**
+ Get SMM Trusted Key.
+
+ @param[out] SmmTrustedKeyData Smm trusted data buffer.
+
+ @retval EFI_SUCCESS Get SMM Trusted success.
+ @retval Others Get SMM Trusted failed.
+
+**/
+
+EFI_STATUS
+HeciGetSMMTrustedKey (
+ OUT MBP_SMM_TRUSTED_KEY *SmmTrustedKeyData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataBuffer[0x100];
+ MBP_CMD_RESP_DATA *MBPHeader;
+ MBP_ITEM_HEADER *MBPItem;
+ MBP_SMM_TRUSTED_KEY *SmmTrustedKey;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetSMMTrustedKey\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ Status = HeciMBP (DataBuffer);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MBPHeader = (MBP_CMD_RESP_DATA *) DataBuffer;
+ MBPItem = (MBP_ITEM_HEADER *) (MBPHeader + 1);
+
+ while ((UINT32 *) MBPItem < (UINT32 *) DataBuffer + MBPHeader->Length) {
+ if (MBPItem->AppID == 8 && MBPItem->ItemID == 2) {
+ SmmTrustedKey = (MBP_SMM_TRUSTED_KEY *) (MBPItem + 1);
+ CopyMem ((VOID *) SmmTrustedKeyData, (VOID *) SmmTrustedKey, sizeof (MBP_SMM_TRUSTED_KEY));
+ return EFI_SUCCESS;
+ }
+ MBPItem = (MBP_ITEM_HEADER *) ((UINT32 *) MBPItem + MBPItem->Length);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+HeciGetArbStatus (
+ IN OUT GET_ARB_STATUS_ACK *GetArbStatus
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GET_ARB_STATUS *SendRequest;
+ GET_ARB_STATUS_ACK *ReceiveResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[sizeof (GET_ARB_STATUS_ACK)];
+ UINT8 Result = 0xFF;
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: HeciGetArbStatus\n"));
+ if (GetArbStatus == NULL) {
+ DEBUG ((EFI_D_INFO, "Invalid Parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR(Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ DEBUG ((EFI_D_INFO, "HeciGetArbStatus-EFI_NOT_READY\n"));
+ return EFI_NOT_READY;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful \n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendRequest = (GET_ARB_STATUS *) DataBuffer;
+ SendRequest->MKHIHeader.Fields.GroupId = MKHI_SECURE_BOOT_GROUP_ID;
+ SendRequest->MKHIHeader.Fields.Command = GET_ARB_STATUS_CMD_ID;
+
+ HeciSendLength = sizeof (GET_ARB_STATUS);
+ HeciRecvLength = sizeof (GET_ARB_STATUS_ACK);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ ReceiveResp = (GET_ARB_STATUS_ACK *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "Group = %08x\n", ReceiveResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command = %08x\n", ReceiveResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone = %08x\n", ReceiveResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result = %08x\n", ReceiveResp->MKHIHeader.Fields.Result));
+
+ //
+ // Copy Response information
+ //
+ CopyMem (GetArbStatus, DataBuffer, (UINTN) HeciRecvLength);
+
+ Result = (UINT8) ReceiveResp->MKHIHeader.Fields.Result;
+ if (Result == 0) {
+ DEBUG ((EFI_D_INFO, "HeciGetArbStatus SUCCESS! \n"));
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((EFI_D_INFO, "HeciGetArbStatus FAILED! Result = %08x\n", Result));
+ Status = Result;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+HeciCommitArbSvnUpdates (
+ IN UINT8 *CommitArbSvns
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ COMMIT_ARB_SVN_UPDATES *SendRequest;
+ COMMIT_ARB_SVN_UPDATES_ACK *ReceiveResp;
+ UINT32 SeCMode;
+ UINT8 DataBuffer[sizeof (COMMIT_ARB_SVN_UPDATES)];
+
+ DEBUG ((EFI_D_INFO, "\nBIOS Start Send HECI Message: HeciCommitArbSvnUpdates\n"));
+ if (CommitArbSvns == NULL) {
+ DEBUG ((EFI_D_INFO, "Invalid Parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ if (SeCMode == SEC_OPERATION_MODE_IN_FWUPDATE_PROGRESS){
+ return EFI_NOT_READY;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful \n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendRequest = (COMMIT_ARB_SVN_UPDATES *) DataBuffer;
+ SendRequest->MKHIHeader.Fields.GroupId = MKHI_SECURE_BOOT_GROUP_ID;
+ SendRequest->MKHIHeader.Fields.Command = COMMIT_ARB_SVN_UPDATES_CMD_ID;
+ CopyMem (SendRequest->CommitSvns, CommitArbSvns, sizeof (SendRequest->CommitSvns)); // 16 Bytes = Size of SVN to commit as per BIOS - CSE Ref doc
+
+ HeciSendLength = sizeof (COMMIT_ARB_SVN_UPDATES);
+ HeciRecvLength = sizeof (COMMIT_ARB_SVN_UPDATES_ACK);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ ReceiveResp = (COMMIT_ARB_SVN_UPDATES_ACK *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "Group = %08x\n", ReceiveResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command = %08x\n", ReceiveResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone = %08x\n", ReceiveResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result = %08x\n", ReceiveResp->MKHIHeader.Fields.Result));
+
+ Status =(UINT8) ReceiveResp->MKHIHeader.Fields.Result;;
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "HeciCommitArbSvnUpdates FAILED! Result = %08x\n", Status));
+ } else {
+ DEBUG ((EFI_D_INFO, "HeciCommitArbSvnUpdates SUCCESS -- Result = %08x\n", Status));
+ }
+
+ return Status;
+}
+
+
+/**
+ Write Data to NVM file for ISH through HECI1.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data content.
+ @param[in] DataSize Data's size.
+
+ @retval EFI_SUCCESS Write NVM file success.
+ @retval Others Write NVM file failed.
+
+**/
+EFI_STATUS
+HeciWriteIshNVMFile (
+ IN ISH_SRV_HECI_SET_FILE_REQUEST *Ish2CseData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength = 0;
+ ISH_SRV_HECI_STATUS_REPLY ReceiveData;
+ UINT32 SeCMode;
+ UINT32 Index = 0;
+ UINT32 *TempPtr = NULL;
+
+ DEBUG ((EFI_D_INFO, "HeciWriteIshNVMFile Entry\n"));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ if (Ish2CseData == NULL) {
+ DEBUG ((EFI_D_ERROR, "Invalid Parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ DEBUG ((EFI_D_INFO, "Dump Bios2ish buffer\n"));
+ TempPtr = (UINT32 *) Ish2CseData;
+ for (Index = 0; Index < 10; Index++ ){
+ DEBUG((EFI_D_INFO, "%x\n", *TempPtr++));
+ }
+
+ HeciSendLength = Ish2CseData->Header.Length + 4; // Including command and msglength
+
+ Status = HeciIshSendwAck (
+ HECI1_DEVICE,
+ (VOID *) Ish2CseData,
+ (VOID *) &ReceiveData,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x03
+ );
+
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", ReceiveData.Header.Command));
+ DEBUG ((EFI_D_INFO, "Length =%08x\n", ReceiveData.Header.Length));
+ DEBUG ((EFI_D_INFO, "Status =%08x\n", ReceiveData.Status));
+
+ if (ReceiveData.Status != 0) {
+ DEBUG ((EFI_D_ERROR, "HeciWriteIshNVMFile Failed.\n"));
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.c
new file mode 100644
index 0000000000..19d2b87958
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.c
@@ -0,0 +1,204 @@
+/** @file
+ Implementation file for PEI specific HECI Message functionality.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/HeciMsgLib.h>
+
+/**
+ Read NVM file data through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[out] Data The data buffer.
+ @param[in,out] DataSize Data's size.
+
+ @retval EFI_SUCCESS Read NVM file success.
+ @retval Others Read NVM file failed.
+
+**/
+EFI_STATUS
+Heci2ReadNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ OUT UINT8 *Data,
+ IN OUT UINTN *DataSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ Data = NULL;
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Write data to NVM file through HECI2.
+
+ @param[in] FileName The file name.
+ @param[in] Offset The offset of data.
+ @param[in] Data The data content.
+ @param[in] DataSize Data's size.
+ @param[in] Truncate Truncate the file.
+
+ @retval EFI_SUCCESS Write NVM file success.
+ @retval Others Write NVM file failed.
+
+**/
+EFI_STATUS
+Heci2WriteNVMFile (
+ IN UINT8 *FileName,
+ IN UINT32 Offset,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN Truncate
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Get NVM file's size through HECI2.
+
+ @param[in] FileName The file name.
+ @param[out] FileSize The file's size.
+
+ @retval EFI_SUCCESS Get NVM file size success.
+ @retval Others Get NVM file size failed.
+
+**/
+EFI_STATUS
+Heci2GetNVMFileSize (
+ IN UINT8 *FileName,
+ OUT UINTN *FileSize,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ *FileSize = 0;
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Send Get Proxy State message through Heci2.
+
+ @retval EFI_SUCCESS Send message success.
+ @retval Others Send message failed.
+
+**/
+EFI_STATUS
+Heci2GetProxyState (
+ VOID
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Check is the HECI2 device has interrupt.
+
+ @retval TRUE HECI2 device interrupt.
+ @retval FALSE No interrupt.
+
+**/
+BOOLEAN
+Heci2GetInterrupt (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+
+/**
+ Lock Directory message through HECI2.
+
+ @param[in] DirName The Directory name.
+ @param[in] Heci2Protocol The HECI protocol to send the message to HECI2 device.
+
+ @retval EFI_SUCCESS Send EOP message success.
+ @retval Others Send EOP message failed.
+
+**/
+EFI_STATUS
+Heci2LockDirectory (
+ IN UINT8 *DirName,
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Send Get proxy State message through HEC2 but not waiting for response.
+
+ @param[in] Heci2Protocol The HECI protocol to send the message to HECI2 device.
+
+ @retval EFI_SUCCESS Send get proxy state message success.
+ @retval Others Send get proxy state message failed.
+
+**/
+EFI_STATUS
+Heci2GetProxyStateNoResp (
+ IN EFI_HECI_PROTOCOL *Heci2Protocol
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+/**
+ Returns whether trusted channel is enabled.
+
+ @param[in] None.
+
+ @retval TRUE if trusted channel is enabled.
+ FALSE if trusted channel is disabled.
+
+**/
+BOOLEAN
+IsTrustedChannelEnabled (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+
+/**
+ Updates the SHA256 signature and monotonic counter fields of a HECI message header.
+
+ @param[in] MessageHeader A pointer to the message header
+ @param[in] TotalHeaderSize The total header size
+ @param[in] TotalDataSize The total data size
+
+ @retval Whether the header could be updated
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateTrustedHeader (
+ IN OUT UINT8 *MessageHeader,
+ IN UINT32 TotalHeaderSize,
+ IN UINT32 TotalDataSize
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf
new file mode 100644
index 0000000000..f023e92b72
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Implementation of PEI specific HECI Message functionality.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiHeciMsgLib
+ FILE_GUID = 088F95B5-DDCE-41A4-917B-8100CD4C54BC
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HeciMsgLib
+
+[Sources]
+ HeciMsgLib.c
+ PeiHeciMsgLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ PciLib
+ BaseLib
+ TimerLib
+ HeciInitLib
+ PcdLib
+
+[Guids]
+ gFdoModeEnabledHobGuid
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c
new file mode 100644
index 0000000000..24e8c5bb68
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c
@@ -0,0 +1,500 @@
+/** @file
+ Implements Platform Trust Technology (FTPM) PTP (Platform TPM Profile) Device Library.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/PerformanceLib.h>
+#include "PttPtpRegs.h"
+#include <Library/PttPtpLib.h>
+
+#ifndef TPM_BASE
+#define TPM_BASE 0
+#endif
+
+#include <IndustryStandard/Tpm20.h>
+
+#define PERF_ID_PTT_SUBMIT_COMMAND 0x3400
+
+#ifdef EFI_DEBUG
+/**
+ Prints command or response buffer for debugging purposes.
+
+ @param[in] Buffer Buffer to print.
+ @param[in] BufferSize Buffer data length.
+
+ @retval None
+
+**/
+VOID
+EFIAPI
+PttHciPrintBuffer (
+ IN UINT8 *Buffer,
+ IN UINT32 BufferSize
+ )
+{
+ UINT32 Index;
+
+ DEBUG ((DEBUG_INFO, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize));
+
+ for (Index = 0; Index < BufferSize; Index++) {
+ DEBUG ((DEBUG_INFO, "%02x ", *(Buffer + Index)));
+ if ((Index+1) % 16 == 0) DEBUG ((DEBUG_INFO, "\n"));
+ }
+ DEBUG ((DEBUG_INFO, "\n"));
+}
+#endif // EFI_DEBUG
+
+UINT32 *
+EFIAPI
+MmioReadBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ OUT UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = Buffer;
+
+ while (Length != 0) {
+ *(Buffer++) = MmioRead32 (StartAddress);
+
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+UINT32 *
+EFIAPI
+MmioWriteBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ IN CONST UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = (UINT32 *) Buffer;
+
+ while (Length != 0) {
+ MmioWrite32 (StartAddress, *(Buffer++));
+
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+EFI_STATUS
+EFIAPI
+PttRequestLocality (
+ IN TPM_LOCALITY_ENUM RequestedLocality
+ )
+{
+ UINT32 LocalityState;
+ UINT32 ControlStatus;
+ UINT32 WaitTime;
+
+ //
+ // Make sure TPM is not in fatal error state
+ //
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ (RequestedLocality * TPM_LOCALITY_BUFFER_SIZE ) +
+ R_CRB_CONTROL_STS);
+
+ if ((ControlStatus & B_CRB_CONTROL_STS_TPM_STATUS ) != 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ LocalityState = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ (RequestedLocality * TPM_LOCALITY_BUFFER_SIZE) +
+ R_PTT_LOCALITY_STATE);
+
+ if ((((LocalityState & V_CRB_LOCALITY_STATE_ACTIVE_LOC_MASK) >> 2) == 0) &&
+ ((LocalityState & B_CRB_LOCALITY_STATE_LOCALITY_ASSIGNED) != 0)) {
+ DEBUG ((DEBUG_INFO, "PTT Locality 0 already assigned\n"));
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_INFO, "PTT Requesting Locality\n"));
+ }
+
+ //
+ // Request access to locality
+ //
+ MmioWrite32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ (RequestedLocality * TPM_LOCALITY_BUFFER_SIZE) +
+ R_TPM_LOCALITY_CONTROL,
+ B_CRB_LOCALITY_CTL_REQUEST_ACCESS
+ );
+ //
+ // Wait for assignment of locality
+ //
+ LocalityState = 0;
+ WaitTime = 0;
+ while ((WaitTime < PTT_HCI_TIMEOUT_A) &&
+ ((LocalityState & B_CRB_LOCALITY_STATE_REGISTER_VALID) != 0) &&
+ ((LocalityState & B_CRB_LOCALITY_STATE_LOCALITY_ASSIGNED) != 0) &&
+ (((LocalityState & V_CRB_LOCALITY_STATE_ACTIVE_LOC_MASK) >> 2) == 0)
+ ) {
+
+ LocalityState = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( RequestedLocality * TPM_LOCALITY_BUFFER_SIZE )+
+ R_PTT_LOCALITY_STATE);
+
+ MicroSecondDelay (PTT_HCI_POLLING_PERIOD);
+ WaitTime += PTT_HCI_POLLING_PERIOD;
+ }
+ if (WaitTime >= PTT_HCI_TIMEOUT_A){
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Sets PTT_CMD and CA_START register to a defined value to indicate that a command is
+ available for processing.
+ Any host write to this register shall result in an interrupt to the ME firmware.
+
+ @param[in] RequestedLocality
+
+ @retval EFI_SUCCESS Register successfully written.
+ @retval TBD
+
+**/
+VOID
+EFIAPI
+RelinquishLocality (
+ IN TPM_LOCALITY_ENUM RequestedLocality
+ )
+{
+ //
+ // Relinguish access to locality
+ //
+ MmioWrite32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( RequestedLocality * TPM_LOCALITY_BUFFER_SIZE )+
+ R_TPM_LOCALITY_CONTROL,
+ B_CRB_LOCALITY_CTL_RELINQUISH
+ );
+}
+
+
+/**
+ Sends command to PTT for execution.
+
+ @param[in] PttBuffer Buffer for TPM command data.
+ @param[in] DataLength TPM command data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *PttBuffer,
+ IN UINT32 DataLength
+ )
+{
+ UINT32 ControlStatus;
+ UINT32 WaitTime;
+
+ //
+ // Make sure that previous command was in fact completed if not, must not
+ // send subsequent commands
+ //
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_START);
+
+ if ((ControlStatus & B_CRB_CONTROL_START) != 0){
+ DEBUG ((DEBUG_INFO, "Start bit was never cleared from previous command, cannot send another command\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Make sure TPM is not in fatal error state
+ //
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_STS);
+
+ if ((ControlStatus & B_CRB_CONTROL_STS_TPM_STATUS) != 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ DEBUG ((DEBUG_INFO, "PTT in idle state, must send command ready signal\n"));
+
+ //
+ // Request TPM to come out of idle
+ //
+ MmioWrite32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_REQ,
+ B_R_CRB_CONTROL_REQ_COMMAND_READY
+ );
+
+ //
+ // Wait for tpm to clear tpmidle
+ //
+ WaitTime = 0;
+ while ((WaitTime < PTT_HCI_TIMEOUT_C) &&
+ ((ControlStatus & B_R_CRB_CONTROL_REQ_COMMAND_READY) != 0)){
+
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_REQ);
+
+ MicroSecondDelay (PTT_HCI_POLLING_PERIOD);
+ WaitTime += PTT_HCI_POLLING_PERIOD;
+ }
+ if (WaitTime >= PTT_HCI_TIMEOUT_C){
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // Align command size to dword before writing to PTT_CRB
+ //
+ if (DataLength % 4 != 0) {
+ DEBUG ((DEBUG_INFO, "Alignment: DataLength change from %d ", DataLength));
+ DataLength += (4 - (DataLength % 4));
+ DEBUG ((DEBUG_INFO, "to %d\n", DataLength));
+ }
+
+ MmioWriteBuffer32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ 0x80,
+ DataLength,
+ (UINT32 *) PttBuffer );
+
+ //
+ // Trigger Command processing by writing to start register
+ //
+ MmioWrite32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_START,
+ B_CRB_CONTROL_START
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Receives response data of last command from PTT.
+
+ @param[out] PttBuffer Buffer for response data.
+ @param[out] RespSize Response data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_DEVICE_ERROR Unexpected device status.
+ @retval EFI_BUFFER_TOO_SMALL Response data is too long.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHciReceive (
+ OUT UINT8 *PttBuffer,
+ OUT UINT32 *RespSize
+ )
+{
+ UINT32 ControlStatus;
+ UINT32 WaitTime;
+ UINT16 Data16;
+ UINT32 Data32;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ DEBUG ((DEBUG_INFO, "PTT: PttHciReceive start\n"));
+
+ //
+ // Wait for command completion
+ //
+ WaitTime = 0;
+ ControlStatus = 0;
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_START);
+
+ while ((WaitTime < PTT_HCI_TIMEOUT_E) &&
+ ((ControlStatus & B_CRB_CONTROL_START) != 0)){
+
+ ControlStatus = MmioRead32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ R_CRB_CONTROL_START);
+
+ MicroSecondDelay (PTT_HCI_POLLING_PERIOD);
+ WaitTime += PTT_HCI_POLLING_PERIOD;
+ }
+ DEBUG ((DEBUG_INFO, "PTT recieve time = %d\n", WaitTime));
+ if (WaitTime >= PTT_HCI_TIMEOUT_E){
+ DEBUG ((DEBUG_INFO, "PTT recieve timeout = %x\n", WaitTime));
+ return EFI_TIMEOUT;
+ }
+ //
+ // Read the response data header
+ //
+ MmioReadBuffer32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ ( TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE )+
+ 0x80,
+ PTT_HCI_RESPONSE_HEADER_SIZE,
+ (UINT32 *) PttBuffer);
+
+ //
+ // Check the reponse data header (tag, parasize and returncode)
+ //
+ CopyMem (&Data16, PttBuffer, sizeof (UINT16));
+ DEBUG ((DEBUG_INFO, "TPM2_RESPONSE_HEADER.tag = 0x%04x\n", SwapBytes16(Data16)));
+
+ if (SwapBytes16 (Data16) == TPM_ST_RSP_COMMAND) {
+ DEBUG ((DEBUG_ERROR, "TPM2_RESPONSE_HEADER.tag = TPM_ST_RSP_COMMAND - Error in response!\n"));
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ CopyMem (&Data32, (PttBuffer + 2), sizeof (UINT32));
+ DEBUG ((DEBUG_INFO, "TPM2_RESPONSE_HEADER.paramSize = 0x%08x\n", SwapBytes32 (Data32)));
+
+ *RespSize = SwapBytes32 (Data32);
+
+ if (*RespSize == sizeof (TPM2_RESPONSE_HEADER)) {
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ if (*RespSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ if (*RespSize > S_PTT_HCI_CRB_LENGTH) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ }
+
+
+ if (*RespSize % 4 != 0){
+ DEBUG ((DEBUG_INFO, "Alignment: RespSize change from %d ", *RespSize));
+ *RespSize += (4 - (*RespSize % 4));
+ DEBUG ((DEBUG_INFO, "to %d\n", *RespSize));
+ }
+
+ //
+ // Read the entire response data header
+ //
+ MmioReadBuffer32 ((UINTN) R_PTT_HCI_BASE_ADDRESS +
+ (TPM_LOCALITY_0 * TPM_LOCALITY_BUFFER_SIZE)+
+ 0x80,
+ *RespSize,
+ (UINT32 *) PttBuffer);
+Exit:
+
+ return Status;
+}
+
+
+/**
+ Sends formatted command to PTT for execution and returns formatted response data.
+
+ @param[in] InputBuffer Buffer for the input data.
+ @param[in] InputBufferSize Size of the input buffer.
+ @param[out] ReturnBuffer Buffer for the output data.
+ @param[out] ReturnBufferSize Size of the output buffer.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+
+**/
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand (
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "PTT: PttHciSubmitCommand start\n"));
+ PERF_START_EX (NULL, "EventRec", "PttHciDeviceLib", AsmReadTsc (), PERF_ID_PTT_SUBMIT_COMMAND);
+
+ if (InputBuffer == NULL || ReturnBuffer == NULL || InputBufferSize == 0) {
+ DEBUG ((DEBUG_ERROR, "Buffer == NULL or InputBufferSize == 0\n"));
+ PERF_END_EX (NULL, "EventRec", "PttHciDeviceLib", AsmReadTsc(), PERF_ID_PTT_SUBMIT_COMMAND + 3);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PttRequestLocality (TPM_LOCALITY_0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "PTT Locality Request timed out due to FWSTS4.BIT19 not set. EFI_ERROR = %r\n", Status));
+ return Status;
+ }
+
+ MmioWrite32 ((UINTN) (R_PTT_HCI_BASE_ADDRESS + R_CRB_CONTROL_CMD_LOW), R_PTT_HCI_BASE_ADDRESS + 0x80);
+ MmioWrite32 ((UINTN) (R_PTT_HCI_BASE_ADDRESS + R_CRB_CONTROL_CMD_SIZE), S_PTT_HCI_CRB_LENGTH);
+
+ MmioWrite32 ((UINTN) (R_PTT_HCI_BASE_ADDRESS + R_CRB_CONTROL_RESPONSE_ADDR), R_PTT_HCI_BASE_ADDRESS + 0x80);
+ MmioWrite32 ((UINTN) (R_PTT_HCI_BASE_ADDRESS + R_CRB_CONTROL_RESPONSE_SIZE), S_PTT_HCI_CRB_LENGTH);
+
+ //
+ // Send the command to TPM
+ //
+ #ifdef EFI_DEBUG
+ DEBUG ((DEBUG_INFO, "PTT Buffer Dump: Command \n"));
+ PttHciPrintBuffer ( InputBuffer, InputBufferSize);
+ #endif // EFI_DEBUG
+ Status = PttHciSend (InputBuffer, InputBufferSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "PttHciSend EFI_ERROR = %r\n", Status));
+ PERF_END_EX (NULL, "EventRec", "PttHciDeviceLib", AsmReadTsc (), PERF_ID_PTT_SUBMIT_COMMAND + 4);
+ return Status;
+ }
+
+ //
+ // Receive the response data from TPM
+ //
+ Status = PttHciReceive (ReturnBuffer, ReturnBufferSize);
+ #ifdef EFI_DEBUG
+ DEBUG ((DEBUG_INFO, "PTT Buffer Dump: Response \n"));
+ PttHciPrintBuffer ( ReturnBuffer, *ReturnBufferSize);
+ #endif // EFI_DEBUG
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "PttHciReceive EFI_ERROR = %r\n", Status));
+ PERF_END_EX (NULL, "EventRec", "PttHciDeviceLib", AsmReadTsc (), PERF_ID_PTT_SUBMIT_COMMAND + 5);
+ return Status;
+ }
+
+ PERF_END_EX (NULL, "EventRec", "PttHciDeviceLib", AsmReadTsc (), PERF_ID_PTT_SUBMIT_COMMAND + 1);
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf
new file mode 100644
index 0000000000..1911c217e7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf
@@ -0,0 +1,41 @@
+## @file
+# PttHciDevice DXE Library.
+# This is a library that contains functions for sending TPM commands to and
+# recieving responses from PTT.
+#
+# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiDxePttPtpLib
+ FILE_GUID = 88a08e5c-ed53-4235-afb9-35e0e873c6ca
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = PttPtpLib
+
+[LibraryClasses]
+ PciLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ TimerLib
+ PerformanceLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Sources]
+ PeiDxePttPtpLib.c
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c
new file mode 100644
index 0000000000..7f56fafb13
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c
@@ -0,0 +1,98 @@
+/** @file
+ SEC Chipset Lib implementation.
+
+ Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/TimerLib.h>
+#include <SeCState.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/MmPciLib.h>
+#include <Library/PcdLib.h>
+
+
+/**
+ Enable/Disable SEC devices
+
+ @param[in] WhichDevice Select of SEC device
+ @param[in] DeviceFuncCtrl Function control
+
+ @retval VOID None
+
+**/
+VOID
+SeCDeviceControl (
+ IN SEC_DEVICE WhichDevice,
+ IN SEC_DEVICE_FUNC_CTRL DeviceFuncCtrl
+ )
+{
+ UINT32 PmcBase;
+ UINT32 FuncDisableReg;
+
+ PmcBase = PMC_BASE_ADDRESS;
+ FuncDisableReg = MmioRead32 (PmcBase + R_PMC_FUNC_DIS);
+
+if (Disabled == DeviceFuncCtrl) {
+ switch (WhichDevice) {
+ case HECI1:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), FuncDisableReg | BIT27);
+ DEBUG ((DEBUG_INFO, "HECI1 Device disabled\n"));
+ break;
+ case HECI2:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), FuncDisableReg | BIT26);
+ DEBUG ((DEBUG_INFO, "HECI2 Device disabled\n"));
+ break;
+ case HECI3:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), FuncDisableReg | BIT25);
+ DEBUG ((DEBUG_INFO, "HECI3 Device disabled\n"));
+ break;
+ case FTPM:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), (FuncDisableReg | BIT27| BIT26 | BIT25));
+ DEBUG ((DEBUG_INFO, "FTPM Device disabled\n"));
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (WhichDevice) {
+ case HECI1:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), (FuncDisableReg & (~BIT27)));
+ DEBUG ((DEBUG_INFO, "HECI1 Device Enabled\n"));
+ break;
+ case HECI2:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), (FuncDisableReg& (~BIT26)));
+ DEBUG ((DEBUG_INFO, "HECI2 Device Enabled\n"));
+ break;
+ case HECI3:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), (FuncDisableReg& (~ BIT25)));
+ DEBUG ((DEBUG_INFO, "HECI3 Device Enabled\n"));
+ break;
+ case FTPM:
+ MmioWrite32 ((PmcBase + R_PMC_FUNC_DIS), (FuncDisableReg & (~(BIT27| BIT26 | BIT25))));
+ DEBUG ((DEBUG_INFO, "FTPM Device Enabled\n"));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf
new file mode 100644
index 0000000000..103c46bdc6
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf
@@ -0,0 +1,38 @@
+## @file
+# PEI/DXE SEC Chipset Lib.
+#
+# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiDxeSeCChipsetLib
+ FILE_GUID = 66F0B027-7479-4BC1-BF95-4D51E5954583
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = SeCChipsetLib
+
+[LibraryClasses]
+ BaseLib
+ PciLib
+ IoLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## CONSUMES
+
+[Sources]
+ PeiDxeSeCChipsetLib.c
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/HeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/HeciMsgLib.c
new file mode 100644
index 0000000000..390f0d71d3
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/HeciMsgLib.c
@@ -0,0 +1,258 @@
+/** @file
+ Implementation file for Heci Message functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/TimerLib.h>
+#include <Ppi/HeciPpi.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+
+/**
+ Calculate if the circular buffer has overflowed.
+
+ @param[in] ReadPointer Location of the read pointer.
+ @param[in] WritePointer Location of the write pointer.
+
+ @return Number of filled slots.
+
+**/
+UINT8
+FilledSlots (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer
+ )
+{
+ UINT8 FilledSlots;
+
+ FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer));
+
+ return FilledSlots;
+}
+
+
+/**
+ Calculate if the circular buffer has overflowed
+
+ @param[in] ReadPointer Value read from host/me read pointer.
+ @param[in] WritePointer Value read from host/me write pointer.
+ @param[in] BufferDepth Value read from buffer depth register.
+
+ @retval EFI_DEVICE_ERROR The circular buffer has overflowed.
+ @retval EFI_SUCCESS The circular buffer does not overflowed.
+
+**/
+EFI_STATUS
+OverflowCB (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer,
+ IN UINT32 BufferDepth
+ )
+{
+ UINT8 FilledSlots;
+
+ FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer));
+
+ //
+ // test for overflow
+ //
+ if (FilledSlots > ((UINT8) BufferDepth)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Send Get Firmware SKU Request to SEC.
+
+ @param[in, out] FwCapsSku SEC Firmware Capability SKU.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetFwCapsSkuMsg (
+ IN OUT SECFWCAPS_SKU *FwCapsSku
+ )
+{
+ EFI_STATUS Status;
+ GEN_GET_FW_CAPS_SKU_BUFFER MsgGenGetFwCapsSku;
+ UINT32 Length;
+ UINT32 RecvLength;
+ UINT32 SeCMode;
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetFwCapsSku.Request.MKHIHeader.Data = 0;
+ MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetFwCapsSku.Request.Data.RuleId = 0;
+ Length = sizeof (GEN_GET_FW_CAPSKU);
+ RecvLength = sizeof (GEN_GET_FW_CAPS_SKU_ACK);
+
+ //
+ // Send Get FW SKU Request to SEC
+ //
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetFwCapsSku,
+ Length,
+ &RecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (!EFI_ERROR (Status) && ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) &&
+ ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.IsResponse) == 1) &&
+ (MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Result == 0)) {
+ *FwCapsSku = MsgGenGetFwCapsSku.Response.Data.FWCapSku;
+ }
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX. One of usages is to utilize
+ this command to determine if the platform runs in Consumer or Corporate SKU
+ size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetPlatformTypeMsg (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ UINT32 RecvLength;
+ GEN_GET_PLATFORM_TYPE_BUFFER MsgGenGetPlatformType;
+ UINT32 SeCMode;
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR(Status) || (MeMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetPlatformType.Request.MKHIHeader.Data = 0;
+ MsgGenGetPlatformType.Request.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetPlatformType.Request.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetPlatformType.Request.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetPlatformType.Request.Data.RuleId = 0x1D;
+ Length = sizeof (GEN_GET_PLATFORM_TYPE);
+ RecvLength = sizeof (GEN_GET_PLATFORM_TYPE_ACK);
+
+ //
+ // Send Get Platform Type Request to SEC
+ //
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetPlatformType,
+ Length,
+ &RecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (!EFI_ERROR (Status)) {
+ *RuleData = MsgGenGetPlatformType.Response.Data.RuleData;
+ }
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX. To Get Firmware Version Request to SEC.
+
+ @param[in,out] MsgGenGetFwVersionAck Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+PeiHeciGetFwVersionMsg (
+ IN OUT GEN_GET_FW_VER_ACK *MsgGenGetFwVersionAck
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ UINT32 RecvLength;
+ GEN_GET_FW_VER_ACK_BUFFER *MsgGenGetFwVersion;
+ UINT32 SeCMode;
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR(Status) || (MeMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetFwVersion.Request.MKHIHeader.Data = 0;
+ MsgGenGetFwVersion.Request.MKHIHeader.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MsgGenGetFwVersion.Request.MKHIHeader.Fields.Command = GEN_GET_FW_VERSION_CMD;
+ MsgGenGetFwVersion.Request.MKHIHeader.Fields.IsResponse = 0;
+ Length = sizeof (GEN_GET_FW_VER);
+ RecvLength = sizeof (GEN_GET_FW_VER_ACK);
+
+ //
+ // Send Get Firmware Version Request to SEC
+ //
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetFwVersion,
+ Length,
+ &RecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (!EFI_ERROR (Status)) {
+ memcpy (MsgGenGetFwVersionAck, &(MsgGenGetFwVersion.Response), RecvLength);
+ }
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/PeiSeCLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/PeiSeCLib.inf
new file mode 100644
index 0000000000..953f21cc27
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/PeiSeCLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Pei Sec library.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SeCLib
+ FILE_GUID = D2F1659B-C8EE-4BF1-8735-2D721596F428
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeiSeCLib
+
+[Sources]
+ SeCLib.c
+ SeCPolicyLib.c
+ HeciMsgLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ PciLib
+ BaseLib
+ HeciInitLib
+
+[Protocols]
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c
new file mode 100644
index 0000000000..7c2af1ed73
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c
@@ -0,0 +1,180 @@
+/** @file
+ Implementation file for SeC functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <MkhiMsgs.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/PeiServicesLib.h>
+
+/**
+ Check if SeC is enabled
+
+ @param[in] VOID Parameter is VOID
+
+ @retval EFI_SUCCESS Command succeeded
+
+**/
+EFI_STATUS
+SeCLibInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ return Status;
+}
+
+/**
+ Send Get Firmware SKU Request to SEC.
+
+ @param[in] FwCapsSku Return Data from Get Firmware Capabilities MKHI Request.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwCapsSku (
+ SECFWCAPS_SKU *FwCapsSku
+ )
+{
+ EFI_STATUS Status;
+ GEN_GET_FW_CAPSKU MsgGenGetFwCapsSku;
+ GEN_GET_FW_CAPS_SKU_ACK MsgGenGetFwCapsSkuAck;
+
+ Status = PeiHeciGetFwCapsSkuMsg (FwCapsSku);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (((MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) &&
+ ((MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.IsResponse) == 1) &&
+ (MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.Result == 0)) {
+ *FwCapsSku = MsgGenGetFwCapsSkuAck.Data.FWCapSku;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get Ibex Peak platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ 4M or 8M size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelSeCFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetPlatformType (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiHeciGetPlatformTypeMsg (RuleData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Send Get Firmware Version Request to SEC.
+
+ @param[in, out] MsgGenGetFwVersionAckData Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwVersion (
+ IN OUT GEN_GET_FW_VER_ACK_DATA *MsgGenGetFwVersionAckData
+ )
+{
+ EFI_STATUS Status;
+ GEN_GET_FW_VER_ACK MsgGenGetFwVersionAck;
+
+ Status = PeiHeciGetFwVersionMsg (&MsgGenGetFwVersionAck);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((MsgGenGetFwVersionAck.MKHIHeader.Fields.Command == GEN_GET_FW_VERSION_CMD) &&
+ (MsgGenGetFwVersionAck.MKHIHeader.Fields.IsResponse == 1) &&
+ (MsgGenGetFwVersionAck.MKHIHeader.Fields.Result == 0)) {
+ *MsgGenGetFwVersionAckData = MsgGenGetFwVersionAck.Data;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Host client gets Firmware update info from SEC client.
+
+ @param[in, out] SECCapability Structure of FirmwareUpdateInfo.
+
+ @retval EFI_SUCCESS Command succeeded.
+
+**/
+EFI_STATUS
+HeciGetSeCFwInfo (
+ IN OUT SEC_CAP *SECCapability
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Dummy return for SeC signal event use.
+
+ @param[in] Event The event that triggered this notification function.
+ @param[in] ParentImageHandle Pointer to the notification functions context.
+
+ @retval EFI_SUCCESS Always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+SeCEmptyEvent (
+ EFI_EVENT Event,
+ void *ParentImageHandle
+ )
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCPolicyLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCPolicyLib.c
new file mode 100644
index 0000000000..594e51f61e
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCPolicyLib.c
@@ -0,0 +1,142 @@
+/** @file
+ Implementation file for SeC Policy functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/SeCPolicyLib.h>
+#include <Protocol/Heci.h>
+#include <Library/PeiServicesLib.h>
+#include <SeCAccess.h>
+
+/**
+ Check if SeC is enabled.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval EFI_SUCCESS Command succeeded
+
+**/
+EFI_STATUS
+SeCPolicyLibInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Check if HECI Communication is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE HECI is disabled.
+ @retval TRUE HECI is enabled.
+
+**/
+BOOLEAN
+SeCHECIEnabled (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+
+/**
+ Check if End of Post Message is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE EndOfPost is disabled.
+ @retval TRUE EndOfPost is enabled.
+
+**/
+BOOLEAN
+SeCEndOfPostEnabled (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+
+/**
+ Check if Thermal Reporting Message is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE Thermal Reporting is disabled.
+ @retval TRUE Thermal Reporting is enabled.
+
+**/
+BOOLEAN
+SeCTrEnabled (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+
+/**
+ Show SeC Error message.
+
+ @param[in] MsgId SeC error message ID.
+
+ @retval None.
+**/
+VOID
+SeCReportError (
+ SEC_ERROR_MSG_ID MsgId
+ )
+{
+ return;
+}
+
+
+/**
+ SeC platform Hook function.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval None.
+
+**/
+VOID
+SeCPlatformHook (
+ VOID
+ )
+{
+ return;
+}
+
+
+/**
+ Check if SeCFwDowngrade is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE SeCFwDowngrade is disabled.
+ @retval TRUE SeCFwDowngrade is enabled.
+
+**/
+BOOLEAN
+SeCFwDowngradeSupported (
+ VOID
+ )
+{
+ return TRUE;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.c
new file mode 100644
index 0000000000..92934090df
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.c
@@ -0,0 +1,1964 @@
+/** @file
+ Heci driver core. For Dxe Phase, determines the HECI device and initializes it.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HeciCore.h"
+#include "HeciHpet.h"
+#include <Uefi/UefiBaseType.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/Heci2PowerManagementLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/Heci.h>
+#include <Private/Library/HeciInitLib.h>
+
+extern EFI_GUID gEfiHeciMbpDataHobGuid;
+
+BOOLEAN mFdoModeEnabled = FALSE;
+
+//
+// Macro definition for function used in Heci driver
+//
+/**
+ The routing of MmIo Read Dword
+
+ @param[in] a The address of Mmio
+
+ @retval Return the value of MmIo Read
+
+**/
+UINT32
+MmIoReadDword (
+ UINTN a
+ )
+{
+ volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr;
+
+ HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a;
+
+ return HeciRegHCsrPtr->ul;
+}
+
+
+/**
+ The routing of MmIo Write Dword
+
+ @param[in] a The address of Mmio
+ @param[in] b Value revised
+
+ @retval None
+
+**/
+VOID
+MmIoWriteDword (
+ UINTN a,
+ UINT32 b
+ )
+{
+ volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr;
+
+ HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a;
+
+ HeciRegHCsrPtr->ul = b;
+}
+
+#define MMIOREADDWORD(a) MmIoReadDword (a)
+#define MMIOWRITEDWORD(a, b) MmIoWriteDword (a, b)
+
+//
+// Heci driver function definitions
+//
+
+/**
+ WaitForCseReady
+
+ @param[in] HECI Device Number
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+WaitForCseReady (
+ IN HECI_DEVICE HeciDev
+ );
+
+#ifdef EFI_DEBUG
+/**
+ For serial debugger used, it will show the buffer message to serila consol.
+
+ @param[in] Message The address point of buffer message
+ @param[in] Length Message length
+
+ @retval None
+**/
+VOID
+ShowBuffer (
+ UINT8 *Message,
+ UINT32 Length
+ )
+{
+ UINT32 LineBreak;
+ UINT32 Index;
+ LineBreak = 0;
+ Index = 0;
+
+ while (Length-- > 0) {
+ if (LineBreak == 0) {
+ DEBUG ((EFI_D_ERROR, "%02x: ", (Index & 0xF0)));
+ }
+ DEBUG ((EFI_D_ERROR, "%02x ", Message[Index++]));
+ LineBreak++;
+ if (LineBreak == 16) {
+ DEBUG ((EFI_D_ERROR, "\n"));
+ LineBreak = 0;
+ }
+ if (LineBreak == 8) {
+ DEBUG ((EFI_D_ERROR, "- "));
+ }
+ }
+ DEBUG ((EFI_D_ERROR, "\n"));
+
+ return ;
+}
+
+#endif // End Of EFI_DEBUG
+
+//
+// Heci driver function definitions
+//
+/**
+ Determines if the HECI device is present and, if present, initializes it for
+ use by the BIOS.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+InitializeHeciPrivate (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ volatile SICR_HOST_ALIVENESS_REQ *SicrHostAlivenessReqPtr;
+ volatile HICR_HOST_ALIVENESS_RESP *HicrHostAlivenessRespPtr;
+ volatile SICR_HOST_IPC_READINESS *SicrHostIPCReadinessPtr;
+ volatile HICR_SEC_IPC_READINESS *HicrSeCIPCReadinessPtr;
+ volatile HHISR *HostInterruptPtr;
+
+ EFI_STATUS Status;
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+ UINT32 SeC_Exclusion_req;
+ UINT32 SeC_Exclusion_cause;
+ UINTN HeciBaseAddress;
+ UINT16 DeviceInfo;
+ UINTN HeciMBAR = 0;
+
+
+ SeC_Exclusion_req = Mmio32 (PMC_BASE_ADDRESS, 0xc);
+ if ((SeC_Exclusion_req & B_EXCLUSION) == B_EXCLUSION) {
+ DEBUG ((EFI_D_INFO, "Error: SeC exclusion error \n"));
+ SeC_Exclusion_cause = Mmio32 (PMC_BASE_ADDRESS, 0x2c);
+ switch (SeC_Exclusion_cause & 0x0f) {
+ case 0x0:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ DEBUG ((EFI_D_INFO, "Error: No HECI command send \n"));
+ return EFI_UNSUPPORTED;
+ default:
+ break;
+ }
+ }
+ Status = EFI_SUCCESS;
+
+ //
+ // Check for SEC MemValid status
+ //
+ HeciBaseAddress = MmPciBase (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER + HeciDev);
+
+ if ((MmioRead32 (HeciBaseAddress + R_SEC_MEM_REQ) & B_SEC_MEM_REQ_INVALID) == B_SEC_MEM_REQ_INVALID) {
+ //
+ // SEC failed to start so no HECI
+ //
+ DEBUG ((EFI_D_ERROR, "SEC failed to start so no HECI\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ SaveHpet ();
+ do {
+ //
+ // Store HECI vendor and device information away
+ //
+ DeviceInfo = (UINT16) MmioRead32 (HeciBaseAddress + PCI_DEVICE_ID_OFFSET);
+
+ //
+ // Check for HECI-1 PCI device availability
+ //
+ if (DeviceInfo == 0xFFFF) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ SeCFirmwareStatus.ul = MmioRead32 (HeciBaseAddress + R_SEC_FW_STS0);
+
+ //
+ if (SeCFirmwareStatus.r.SeCOperationMode != SEC_MODE_NORMAL && SeCFirmwareStatus.r.SeCOperationState != SEC_IN_RECOVERY_MODE) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Check for SEC FPT Bad
+ //
+ if (SeCFirmwareStatus.r.FptBad) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ //
+ // Check for SEC error status
+ //
+ if (SeCFirmwareStatus.r.ErrorCode) {
+ //
+ // SEC failed to start so no HECI
+ //
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ //
+ // Get HECI_MBAR and see if it is programmed
+ // to a useable value
+ //
+ HeciMBAR = MmioRead32 (HeciBaseAddress + R_HECIMBAR0) & 0xFFFFFFF0;
+
+ //
+ // Load temporary address for HECI_MBAR if one is not assigned
+ //
+ if (HeciMBAR == 0) {
+ DEBUG ((EFI_D_ERROR, "Heci MMIO Bar not programmed in DXE phase\n"));
+ }
+ //
+ // Enable HECI BME, MSE and SERR
+ //
+ MmioOr32(
+ HeciBaseAddress + PCI_COMMAND_OFFSET,
+ EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_SERR
+ );
+
+ //
+ // Set HECI interrupt delivery mode.
+ // HECI-1 using legacy/MSI interrupt
+ //
+ MmioOr32 (HeciBaseAddress + R_HIDM, 0xFC);
+#ifdef TESTMENU_FLAG
+ SeCPolicyLibInit ();
+ if (SeCHECIEnabled () != TRUE) {
+ DEBUG ((EFI_D_ERROR, "HECI Unsupported ++ \n "));
+ return EFI_UNSUPPORTED;
+ }
+#endif
+
+ //
+ // HECI MSG is unsupported if SEC MODE is in SEC ALT Disabled & SECOVR JMPR
+ //
+ if ((SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_SECOVR_JMPR) ||
+ (SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_ALT_DISABLED) ||
+ (SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_SOFT_TEMP_DISABLE) ||
+ (SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_SECOVR_HECI_MSG)) {
+ return EFI_UNSUPPORTED;
+ }
+
+
+ SicrHostAlivenessReqPtr = (VOID *) (UINTN) (HeciMBAR + 0x214C);
+ HicrHostAlivenessRespPtr = (VOID *) (UINTN) (HeciMBAR + 0x2044);
+
+ while (SicrHostAlivenessReqPtr->r.H_ALIVE_REQ != HicrHostAlivenessRespPtr->r.H_ACK);
+
+ if (SicrHostAlivenessReqPtr->r.H_ALIVE_REQ == 1) {
+ SeCAlivenessRequest (&HeciMBAR, 0);
+ }
+
+ SicrHostIPCReadinessPtr = (VOID *) (UINTN) (HeciMBAR + 0x2150);
+ SicrHostIPCReadinessPtr->r.RDY_CLR = 1;
+
+
+ HicrSeCIPCReadinessPtr = (VOID *) (UINTN) (HeciMBAR + 0x2040);
+
+ while (HicrSeCIPCReadinessPtr->r.SEC_RDY != 1);
+
+
+ HostInterruptPtr = (VOID *) (UINTN) (HeciMBAR + 0x2020);
+ HostInterruptPtr->r.INT_BAR0_STS = 0;
+ HostInterruptPtr->r.INT_BAR1_STS = 0;
+
+
+ Mmio32Or (HeciMBAR, 0x2154, 1);
+
+
+ SicrHostIPCReadinessPtr->r.HOST_RDY = 1;
+
+ } while (EFI_ERROR (Status));
+
+ RestoreHpet ();
+
+ DEBUG ((EFI_D_INFO, "InitializeHeciPrivate -- \n "));
+ SeCAlivenessRequest (&HeciMBAR, 1);
+
+ return Status;
+}
+
+UINTN
+CheckAndFixHeciForAccess (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ UINTN HeciBaseAddress;
+ UINT32 Buffer[2];
+
+ //
+ // Check if HECI_MBAR has changed
+ //
+ HeciBaseAddress = MmPciBase (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER + HeciDev);
+
+ DEBUG ((DEBUG_INFO, "CheckAndFixHeciForAccess Entry, For HECI Dev-%d \n", HeciDev));
+ //
+ // Check for HECI PCI device availability
+ //
+ if (MmioRead16 (HeciBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+ DEBUG ((DEBUG_ERROR, "HECI PCI Device %d not found\n", HeciDev));
+ return 0;
+ }
+
+ Buffer[0] = MmioRead32(HeciBaseAddress + R_HECIMBAR0) & 0xFFFFFFF0;
+ Buffer[1] = 0x0;
+ if ((MmioRead32 (HeciBaseAddress + R_HECIMBAR0) & 0x6) == 0x4) {
+ Buffer[1] = MmioRead32 (HeciBaseAddress + R_HECIMBAR1);
+ }
+
+ DEBUG ((DEBUG_INFO, "HECI Device's R_HECIMBAR0 = 0x%x, R_HECIMBAR1 = 0x%x\n", Buffer[0], Buffer[1]));
+
+ if (Buffer[0] == 0x0 && Buffer[1] == 0x0) {
+ DEBUG ((DEBUG_ERROR, "HECI Device %d MMIO Bar isn't programmed in this phase\n", HeciDev ));
+ } else if (Buffer[0] == 0xFFFFFFFF) {
+ DEBUG ((DEBUG_ERROR, "HECI Device %d is not enabled in this phase\n", HeciDev));
+ } else {
+ //
+ // Enable HECI BME, MSE and SERR
+ //
+ MmioOr32 (
+ HeciBaseAddress + PCI_COMMAND_OFFSET,
+ EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_SERR
+ );
+ DEBUG ((DEBUG_INFO, "CheckAndFixHeciForAccess Exit with MBAR\n"));
+ return *((UINTN *) (&Buffer[0]));
+ }
+
+ return 0;
+}
+
+
+/**
+ Waits for the CSE to report that it is ready for communication over the HECI
+ interface.
+
+ @param[in] HECI Device Number
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+WaitForCseReady (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ UINT32 TimerStart;
+ UINT32 TimerEnd;
+ volatile HECI_SEC_CONTROL_REGISTER *HeciRegSeCCsrHaPtr;
+ UINTN HeciMBAR;
+ volatile UINT32 *HpetTimer;
+
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+
+ //
+ // Wait for SEC ready
+ //
+ DEBUG((DEBUG_INFO, "WaitForCseReady \n"));
+ //
+ // Check for SEC ready status
+ //
+ HpetTimer = StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT);
+ HeciRegSeCCsrHaPtr = (VOID *) (UINTN) (HeciMBAR + SEC_CSR_HA);
+ while (1) {
+ if (HeciRegSeCCsrHaPtr->r.SEC_RST_HRA != 0) {
+ //
+ // CSE requests HECI reset
+ //
+ return ResetHeciInterface (HeciDev);
+ }
+ if (HeciRegSeCCsrHaPtr->r.SEC_RDY_HRA != 0) {
+ //
+ // CSE is ready!!!
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If 15 second timeout has expired, return fail
+ //
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ MicroSecondDelay (HECI_WAIT_DELAY);
+ }
+ //
+ // CSE is ready!!!
+ //
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Checks if HECI reset has occured.
+
+ @param[in] HECI Device Number
+
+ @retval TRUE HECI reset occurred
+ @retval FALSE No HECI reset occurred
+
+**/
+BOOLEAN
+CheckForHeciReset (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ UINTN HeciMBAR;
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ HECI_SEC_CONTROL_REGISTER HeciRegSeCCsrHa;
+
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+ if (HeciMBAR == 0) {
+ return FALSE;
+ }
+
+ //
+ // Init Host & CSE CSR
+ //
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ HeciRegSeCCsrHa.ul = MMIOREADDWORD (HeciMBAR + SEC_CSR_HA);
+
+ if ((HeciRegSeCCsrHa.r.SEC_RDY_HRA == 0) || (HeciRegHCsr.r.H_RDY == 0)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ HeciSendwACK
+
+ @param[in, out] Message
+ @param[in, out] Length
+ @param[in, out] RecLength
+ @param[in] HostAddress
+ @param[in] SeCAddress
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSendwACK(
+ IN HECI_DEVICE HeciDev,
+ IN OUT UINT32 *Message,
+ IN OUT UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Send the message
+ //
+ DEBUG ((DEBUG_INFO, "HeciSendwAck () - Start\n"));
+ Status = HeciSend (HeciDev, Message, Length, HostAddress, SeCAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Wait for ACK message
+ //
+ Status = HeciReceive (HeciDev, BLOCKING, Message, RecLength);
+
+ return Status;
+}
+
+
+/**
+ HeciReceive
+
+ @param[in] Blocking
+ @param[in, out] Message
+ @param[in, out] Length
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciReceive (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Blocking,
+ IN OUT UINT32 *MessageBody,
+ IN OUT UINT32 *Length
+)
+{
+ UINTN ReadSize;
+ UINTN Size;
+ UINTN Index;
+ UINTN HeciMBAR;
+ HECI_MESSAGE_HEADER MessageHeader;
+ volatile UINT32 *ReadBuffer;
+ volatile HECI_HOST_CONTROL_REGISTER *HostControlReg;
+ volatile HECI_SEC_CONTROL_REGISTER *SecControlReg;
+ UINTN StallCount;
+ UINTN MaxCount;
+ UINTN OverAllDelay;
+ BOOLEAN TimeOut;
+ EFI_HECI2_PM_PROTOCOL *Heci2PmProtocol = NULL;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "Start HeciReceive\n"));
+ Size = 0;
+ ReadSize = 0;
+
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+
+ if (HeciMBAR == 0) {
+ if (EFI_ERROR (GetHeci2PmProtocol (&Heci2PmProtocol))) {
+ Heci2PmProtocol = NULL;
+ DEBUG ((EFI_D_ERROR, "HeciReceive: Error getting HECI2 PM protocol.\n"));
+ return EFI_DEVICE_ERROR;
+ } else if (Heci2PmProtocol != NULL) {
+ HeciMBAR = Heci2PmProtocol->GetHeciBar ();
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if (CheckForHeciReset (HeciDev)) {
+ //
+ // If HECI reset than try to re-init HECI
+ //
+ Status = HeciInitialize (HeciDev);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ HostControlReg = (volatile HECI_HOST_CONTROL_REGISTER *) (UINTN) (HeciMBAR + H_CSR);
+ SecControlReg = (volatile HECI_SEC_CONTROL_REGISTER *) (UINTN) (HeciMBAR + SEC_CSR_HA);
+ ReadBuffer = (UINT32 *) (UINTN) (HeciMBAR + SEC_CB_RW);
+ DEBUG ((EFI_D_INFO, "Waiting for CSE notify, HostControlReg: %08x SecControlReg: %08x\n", HostControlReg->ul, SecControlReg->ul));
+
+ MaxCount = 0;
+ OverAllDelay = 0;
+ TimeOut = FALSE;
+
+ DEBUG_CODE_BEGIN ();
+ MaxCount = CSE_WAIT_TIMEOUT * 1000 * 6;
+ DEBUG_CODE_END ();
+
+ if (MaxCount == 0) {
+ MaxCount = CSE_WAIT_TIMEOUT * 1000;
+ }
+
+ while (TRUE) {
+ DEBUG ((EFI_D_INFO, "Waiting for CSE notify, HostControlReg: %08x\n", HostControlReg->ul));
+ if (HostControlReg->ul == 0x800B0909) {
+ DEBUG ((EFI_D_INFO, "Need CSE to finish loading and release NVM control...\n"));
+ DEBUG ((EFI_D_INFO, "\nIf you're stuck here for more than 30sec, Please check that your eMMC has GPP4.\n"));
+ }
+ StallCount = 0;
+ while ((HostControlReg->r.H_IS == 0) && (SecControlReg->r.SEC_CBRP_HRA == SecControlReg->r.SEC_CBWP_HRA) && (StallCount < MaxCount)) {
+ MicroSecondDelay (STALL_1_MILLISECOND);
+ StallCount += 1;
+ }
+ if (StallCount == MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+
+ OverAllDelay += StallCount; // in Millisec
+ DEBUG ((EFI_D_INFO, "Get CSE notify, HostControlReg: %08x\n", HostControlReg->ul));
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IE = 0;
+ DEBUG ((EFI_D_INFO, "Disable Interrupt, HostControlReg: %08x\n", HostControlReg->ul));
+ DEBUG ((EFI_D_INFO, "Check SecControlReg: %08x\n", SecControlReg->ul));
+
+ StallCount = 0;
+ while ((SecControlReg->r.SEC_CBRP_HRA == SecControlReg->r.SEC_CBWP_HRA) && (StallCount < MaxCount)) {
+ MicroSecondDelay(STALL_1_MILLISECOND);
+ StallCount += 1;
+ }
+ if (StallCount >= MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+
+ OverAllDelay += StallCount; // in Millisec
+ MessageHeader.Data = *ReadBuffer;
+ *Length = MessageHeader.Fields.Length;
+ DEBUG ((EFI_D_INFO, "Get Message Header: %08x\n", MessageHeader.Data));
+ for (Index = 0; Index < (MessageHeader.Fields.Length + 3) / 4; Index++) {
+ StallCount = 0;
+ while ((SecControlReg->r.SEC_CBRP_HRA == SecControlReg->r.SEC_CBWP_HRA) && (StallCount < MaxCount)) {
+ MicroSecondDelay (STALL_1_MILLISECOND);
+ StallCount += 1;
+ }
+ if (StallCount >= MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+ OverAllDelay += StallCount; // in Millisec
+
+ MessageBody[Index + ReadSize] = *ReadBuffer;
+ DEBUG ((EFI_D_INFO, "MessageBody[%x] = %08x\n", Index+ReadSize, MessageBody[Index + ReadSize]));
+ }
+ DEBUG ((EFI_D_INFO, "Enable Host to get CSE interrupt: %08x\n", HostControlReg->ul));
+ HostControlReg->r.H_IS = 1;
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IE = 1;
+ HostControlReg->r.H_IG = 1;
+ DEBUG ((EFI_D_INFO, "get CSE interrupt Enabled: %08x\n", HostControlReg->ul));
+ if (MessageHeader.Fields.MessageComplete == 1) {
+ DEBUG((EFI_D_INFO, "Not more data need be receive, end\n"));
+ TimeOut = FALSE;
+ break;
+ } else {
+ MicroSecondDelay (STALL_1_MILLISECOND);
+ OverAllDelay += 1;
+ ReadSize += Index;
+ if (OverAllDelay >= MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (TimeOut == TRUE) {
+ DEBUG ((EFI_D_INFO, "HeciReceive TIMEOUT\n"));
+ return EFI_TIMEOUT;
+ }
+ DEBUG ((EFI_D_INFO, "End HeciReceive \n"));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ HeciSend
+
+ @param[in] HeciDev
+ @param[in] Message
+ @param[in] Length
+ @param[in] HostAddress
+ @param[in] SeCAddress
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSend (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *Message,
+ IN UINT32 Length,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ UINTN LeftSize;
+ UINTN MaxBuffer;
+ UINTN WriteSize;
+ UINTN Size;
+ UINTN Index;
+ UINTN HeciMBAR;
+ UINTN StallCount;
+ UINTN MaxCount;
+ UINTN OverAllDelay;
+ BOOLEAN TimeOut;
+ HECI_MESSAGE_HEADER MessageHeader;
+ EFI_HECI2_PM_PROTOCOL *Heci2PmProtocol;
+ EFI_STATUS Status;
+
+ volatile UINT32 *WriteBuffer;
+ volatile HECI_HOST_CONTROL_REGISTER *HostControlReg;
+ volatile HECI_SEC_CONTROL_REGISTER *SecControlReg;
+
+ Heci2PmProtocol = NULL;
+
+ DEBUG ((EFI_D_INFO, "Start HeciSend \n"));
+
+ //
+ // Make sure that HECI device BAR is correct and device is enabled.
+ //
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+
+ if (HeciMBAR == 0) {
+ if (EFI_ERROR (GetHeci2PmProtocol (&Heci2PmProtocol))) {
+ Heci2PmProtocol = NULL;
+ DEBUG ((EFI_D_ERROR, "HeciReceive: Error getting HECI2 PM protocol.\n"));
+ return EFI_DEVICE_ERROR;
+ } else if (Heci2PmProtocol != NULL) {
+ HeciMBAR = Heci2PmProtocol->GetHeciBar ();
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if (CheckForHeciReset (HeciDev)) {
+ //
+ // If HECI reset than try to re-init HECI
+ //
+ Status = HeciInitialize (HeciDev);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ HostControlReg = (volatile HECI_HOST_CONTROL_REGISTER *) (UINTN) (HeciMBAR + H_CSR);
+ SecControlReg = (volatile HECI_SEC_CONTROL_REGISTER *) (UINTN) (HeciMBAR + SEC_CSR_HA);
+ WriteBuffer = (UINT32 *)(UINTN)(HeciMBAR + H_CB_WW);
+
+ MaxBuffer = HostControlReg->r.H_CBD;
+
+ MaxCount = 0;
+ OverAllDelay = 0;
+ TimeOut = FALSE;
+
+ DEBUG_CODE_BEGIN ();
+ MaxCount = CSE_WAIT_TIMEOUT * 1000 * 6;
+ DEBUG_CODE_END ();
+
+ if (MaxCount == 0) {
+ MaxCount = CSE_WAIT_TIMEOUT * 1000;
+ }
+
+ MaxBuffer -= 1;
+ LeftSize = (Length + 3) / 4;
+ WriteSize = 0;
+ HostControlReg->r.H_RDY = 1;
+ while (LeftSize > 0) {
+ DEBUG ((EFI_D_INFO, "Wait for CSE ready, SecControlReg %x\n", SecControlReg->ul));
+ StallCount = 0;
+ while ((SecControlReg->r.SEC_RDY_HRA == 0) && (StallCount < MaxCount)) {
+ MicroSecondDelay (STALL_1_MILLISECOND);
+ StallCount += 1;
+ }
+ if (StallCount == MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "CSE ready SecControlReg %x\n", SecControlReg->ul));
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IE = 0;
+
+ Size = (LeftSize > MaxBuffer) ? MaxBuffer : LeftSize;
+
+ LeftSize -= Size;
+ //
+ // Prepare message header
+ //
+ MessageHeader.Data = 0;
+ MessageHeader.Fields.SeCAddress = SeCAddress;
+ MessageHeader.Fields.HostAddress = HostAddress;
+ MessageHeader.Fields.MessageComplete = (LeftSize > 0) ? 0 : 1;
+ MessageHeader.Fields.Length = (UINT32) ((LeftSize > 0) ? Size * sizeof (UINT32) : Length - WriteSize * sizeof (UINT32));
+ DEBUG ((EFI_D_INFO, "Heci Message Header: %08x\n", MessageHeader.Data));
+ *WriteBuffer = MessageHeader.Data;
+ for (Index = 0; Index < Size; Index++) {
+ DEBUG((EFI_D_INFO, "Message[%x] = %08x\n", Index, Message[Index + WriteSize]));
+ *WriteBuffer = Message[Index + WriteSize];
+ }
+ //
+ // Send the Interrupt;
+ //
+ DEBUG ((EFI_D_INFO, "Prepare Send Interrupt to CSE: %08x\n", HostControlReg->ul));
+ HostControlReg->r.H_IS = 1;
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IE = 1;
+ HostControlReg->r.H_IG = 1;
+ DEBUG ((EFI_D_INFO, "Send Interrupt to CSE: %08x\n", HostControlReg->ul));
+
+ WriteSize += Size;
+ if (LeftSize > 0) {
+ DEBUG ((EFI_D_INFO, "More Data Need be sent, waiting CSE notify\n"));
+ DEBUG ((EFI_D_INFO, "HostControlReg %x\n", SecControlReg->ul));
+ StallCount = 0;
+ while ((HostControlReg->r.H_IS == 0) && (StallCount < MaxCount)) {
+ MicroSecondDelay (STALL_1_MILLISECOND);
+ StallCount += 1;
+ }
+ if (StallCount == MaxCount) {
+ TimeOut = TRUE;
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "Get CSE notify, HostControlReg %x\n", SecControlReg->ul));
+ }
+ }
+ DEBUG ((EFI_D_INFO, "No More Data Need be sent."));
+ DEBUG ((EFI_D_INFO, "End HeciSend \n"));
+
+ if (TimeOut == TRUE) {
+ DEBUG ((EFI_D_INFO, "HeciReceive TIMEOUT\n"));
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Function forces a reinit of the heci interface by following the reset heci interface via host algorithm
+
+ @param[in] HeciDev Heci Device
+
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+ResetHeciInterface(
+ IN HECI_DEVICE HeciDev
+ )
+{
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ HECI_SEC_CONTROL_REGISTER HeciRegSeCCsrHa;
+ UINT32 TimerStart;
+ UINT32 TimerEnd;
+ volatile UINT32 *HpetTimer;
+ UINTN HeciMBAR;
+
+ //
+ // Make sure that HECI device BAR is correct and device is enabled.
+ //
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+
+ //
+ // Enable Reset
+ //
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+
+ //
+ // CSE reset may be asserted, mask H_IS bit as write 1 will clear the bit.
+ //
+ HeciRegHCsr.ul &= (~ BIT1);
+
+ HeciRegHCsr.r.H_RST = 1;
+ HeciRegHCsr.r.H_IG = 1;
+ MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul);
+
+ //
+ // Make sure that the reset started
+ //
+ HpetTimer = StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT);
+ do {
+ //
+ // If 5 second timeout has expired, return fail
+ //
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // Read the SEC CSR
+ //
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ } while (HeciRegHCsr.r.H_RDY == 1);
+
+ //
+ // Wait for SEC to perform reset
+ //
+ HpetTimer = StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT);
+ do {
+ //
+ // If 5 second timeout has expired, return fail
+ //
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // Read the SEC CSR
+ //
+ HeciRegSeCCsrHa.ul = MMIOREADDWORD (HeciMBAR + SEC_CSR_HA);
+ } while (HeciRegSeCCsrHa.r.SEC_RDY_HRA == 0);
+
+ //
+ // Make sure IS has been signaled on the HOST side
+ //
+ HpetTimer = StartTimer(&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT);
+ do {
+ //
+ // If 5 second timeout has expired, return fail
+ //
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // Read the SEC CSR
+ //
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ } while (HeciRegHCsr.r.H_IS == 0);
+
+ //
+ // Enable host side interface
+ //
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);;
+ HeciRegHCsr.r.H_RST = 0;
+ HeciRegHCsr.r.H_IG = 1;
+ HeciRegHCsr.r.H_RDY = 1;
+ MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Determines if the HECI device is present and, if present, initializes it for
+ use by the BIOS.
+
+ @param[in] HeciDev HECI Device No.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciInitialize(
+ IN HECI_DEVICE HeciDev
+ )
+{
+ UINTN HeciBaseAddress;
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr;
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+ UINTN HeciMBAR;
+ EFI_STATUS Status;
+ UINT32 SeCMode;
+
+ DEBUG ((EFI_D_INFO, "HECI Initialize ++ \n "));
+
+ SeCMode = SEC_MODE_NORMAL;
+
+ //
+ // Make sure that HECI device BAR is correct and device is enabled.
+ //
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+ HeciBaseAddress = MmPciBase (SEC_BUS, SEC_DEVICE_NUMBER, HECI_FUNCTION_NUMBER);
+
+ HeciRegHCsrPtr = (VOID *) (UINTN) (HeciMBAR + H_CSR);
+ HeciRegHCsr.ul = HeciRegHCsrPtr->ul;
+
+ //
+ // Read H_RDY bit to check if we're already initialized
+ //
+ if (HeciRegHCsr.r.H_RDY == 1) {
+ return EFI_SUCCESS;
+ }
+ SeCFirmwareStatus.ul = MmioRead32 (HeciBaseAddress + R_SEC_FW_STS0);
+ DEBUG ((DEBUG_INFO, "HECI Dev HfSts1 = 0x%x \n", SeCFirmwareStatus.ul));
+ if (SeCFirmwareStatus.ul == 0 || SeCFirmwareStatus.ul == 0xFFFFFFFF) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check for SEC FPT Bad
+ //
+ if (SeCFirmwareStatus.r.FptBad != 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check for SEC error status
+ //
+ if (SeCFirmwareStatus.r.ErrorCode != SEC_ERROR_CODE_NO_ERROR) {
+ //
+ // SEC failed to start so no HECI
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // HECI MSG is unsupported if ME MODE is in ME ALT Disabled & SECOVR JMPR
+ //
+ if ((SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_SECOVR_JMPR) ||
+ (SeCFirmwareStatus.r.SeCOperationMode == SEC_OPERATION_MODE_ALT_DISABLED)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MmioAnd8 (HeciBaseAddress + R_HIDM, 0xFC);
+
+ Status = WaitForCseReady (HeciDev);
+
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "InitializeHeci () - Set H_RDY\n"));
+ HeciRegHCsr.ul = HeciRegHCsrPtr->ul;
+ if (HeciRegHCsrPtr->r.H_RDY == 0) {
+ HeciRegHCsr.r.H_RST = 0;
+ HeciRegHCsr.r.H_RDY = 1;
+ HeciRegHCsr.r.H_IG = 1;
+ HeciRegHCsrPtr->ul = HeciRegHCsr.ul;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "HECI Initialize -- \n "));
+
+ return Status;
+}
+
+
+/**
+ Heci Re-initializes it for Host
+
+ @param[in] HeciDev Heci Device
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciReInitialize (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ EFI_STATUS Status;
+ UINTN HeciMBAR;
+
+ Status = EFI_SUCCESS;
+
+ if (SeCResetWait (HeciDev, HECI_INIT_TIMEOUT) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ if (HeciRegHCsr.r.H_RDY == 0) {
+ Status = ResetHeciInterface (HeciDev);
+ }
+
+ return Status;
+}
+
+
+/**
+ SeC reset and waiting for ready.
+
+ @param[in] Delay The biggest waiting time.
+
+ @retval EFI_TIMEOUT Time out.
+ @retval EFI_SUCCESS SeC ready.
+
+**/
+EFI_STATUS
+EFIAPI
+SeCResetWait (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 Delay
+ )
+{
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ UINT32 TimerStart;
+ UINT32 TimerEnd;
+ volatile UINT32 *HpetTimer;
+ UINTN HeciMBAR;
+
+ //
+ // Make sure that HECI device BAR is correct and device is enabled.
+ //
+ HeciMBAR = CheckAndFixHeciForAccess (HeciDev);
+
+ //
+ // Wait for the HOST Ready bit to be cleared to signal a reset
+ //
+ HpetTimer = StartTimer (&TimerStart, &TimerEnd, Delay);
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ while (HeciRegHCsr.r.H_RDY == 1) {
+ //
+ // If timeout has expired, return fail
+ //
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Return SEC Status.
+
+ @param[in] SeCStatus Pointer for status report.
+
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciGetSeCStatus (
+ IN UINT32 *SeCStatus
+ )
+{
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+
+ if (SeCStatus == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SeCFirmwareStatus.ul = HeciPciRead32 (R_SEC_FW_STS0);
+
+ if (SeCFirmwareStatus.r.CurrentState == SEC_STATE_NORMAL && SeCFirmwareStatus.r.ErrorCode == SEC_ERROR_CODE_NO_ERROR) {
+ *SeCStatus = SEC_READY;
+ } else if (SeCFirmwareStatus.r.CurrentState == SEC_STATE_RECOVERY) {
+ *SeCStatus = SEC_IN_RECOVERY_MODE;
+ } else if (SeCFirmwareStatus.r.CurrentState == SEC_STATE_INIT) {
+ *SeCStatus = SEC_INITIALIZING;
+ } else if (SeCFirmwareStatus.r.CurrentState == SEC_STATE_DISABLE_WAIT) {
+ *SeCStatus = SEC_DISABLE_WAIT;
+ } else if (SeCFirmwareStatus.r.CurrentState == SEC_STATE_TRANSITION) {
+ *SeCStatus = SEC_TRANSITION;
+ } else {
+ *SeCStatus = SEC_NOT_READY;
+ }
+
+ if (SeCFirmwareStatus.r.FwUpdateInprogress) {
+ *SeCStatus |= SEC_FW_UPDATES_IN_PROGRESS;
+ }
+
+ if (SeCFirmwareStatus.r.FwInitComplete == SEC_FIRMWARE_COMPLETED) {
+ *SeCStatus |= SEC_FW_INIT_COMPLETE;
+ }
+
+ if (SeCFirmwareStatus.r.SeCBootOptionsPresent == SEC_BOOT_OPTIONS_PRESENT) {
+ *SeCStatus |= SEC_FW_BOOT_OPTIONS_PRESENT;
+ }
+
+ DEBUG ((EFI_D_INFO, "HECI SeCStatus %X\n", SeCFirmwareStatus.ul));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+HeciGetSeCMode (
+ IN HECI_DEVICE HeciDev,
+ IN UINT32 *SeCMode
+ )
+{
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+
+ if (SeCMode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (mFdoModeEnabled) {
+ *SeCMode = SEC_MODE_RECOVER;
+ DEBUG ((EFI_D_INFO, "HECI FDO Jumper ASSERT SeCMode %X\n", *SeCMode));
+ return EFI_SUCCESS;
+ }
+
+ switch (HeciDev) {
+ case HECI1_DEVICE:
+ SeCFirmwareStatus.ul = HeciPciRead32 (R_SEC_FW_STS0);
+ break;
+
+ case HECI2_DEVICE:
+ SeCFirmwareStatus.ul = Heci2PciRead32 (R_SEC_FW_STS0);
+ break;
+
+ case HECI3_DEVICE:
+ SeCFirmwareStatus.ul = Heci3PciRead32 (R_SEC_FW_STS0);
+ break;
+
+ default:
+ SeCFirmwareStatus.ul = HeciPciRead32 (R_SEC_FW_STS0);
+ }
+
+ switch (SeCFirmwareStatus.r.SeCOperationMode) {
+ case SEC_OPERATION_MODE_NORMAL:
+ *SeCMode = SEC_MODE_NORMAL;
+ break;
+
+ case SEC_OPERATION_MODE_ALT_DISABLED:
+ *SeCMode = SEC_DEBUG_MODE_ALT_DIS; //debug Mode
+ break;
+
+ case SEC_OPERATION_MODE_SOFT_TEMP_DISABLE:
+ *SeCMode = SEC_MODE_TEMP_DISABLED;
+ break;
+
+ case SEC_OPERATION_MODE_SECOVR_JMPR:
+ case SEC_OPERATION_MODE_SECOVR_HECI_MSG:
+ *SeCMode = SEC_MODE_RECOVER;
+ break;
+
+ default:
+ *SeCMode = SEC_MODE_FAILED;
+ }
+
+ DEBUG ((EFI_D_INFO, "HECI SeCMode %X\n", SeCFirmwareStatus.r.SeCOperationMode));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ HeciTakeOwnerShip
+
+ @param[in] None
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+HeciTakeOwnerShip (
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GET_OWNERSHIP_CMD_REQ_DATA *SendNVMGet;
+ GET_OWNERSHIP_CMD_RESP_DATA *NVMGetResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x40];
+
+ DEBUG ((EFI_D_INFO, "BIOS Start Send HECI Message: TakeOwnerShip\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (SeCMode != SEC_MODE_NORMAL && SeCMode != SEC_MODE_RECOVER) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendNVMGet = (GET_OWNERSHIP_CMD_REQ_DATA *) DataBuffer;
+ SendNVMGet->MKHIHeader.Fields.GroupId = 0xA;
+ SendNVMGet->MKHIHeader.Fields.Command = HECI1_REQUEST_DEVICE_OWNERSHIP;
+
+ DEBUG ((EFI_D_INFO, "WRITE_TO_BIOS_DATA_CMD_REQ_DATA size if %x\n", sizeof (GET_OWNERSHIP_CMD_REQ_DATA)));
+ HeciSendLength = sizeof (GET_OWNERSHIP_CMD_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ NVMGetResp = (GET_OWNERSHIP_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%x\n", NVMGetResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%x\n", NVMGetResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%x\n", NVMGetResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%x\n", NVMGetResp->MKHIHeader.Fields.Result));
+
+ return Status;
+}
+
+
+/**
+ Calculate if the circular buffer has overflowed.
+
+ @param[in] ReadPointer Location of the read pointer.
+ @param[in] WritePointer Location of the write pointer.
+
+ @retval Number of filled slots.
+
+**/
+UINT8
+FilledSlots (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer
+ )
+{
+ UINT8 FilledSlots;
+
+ FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer));
+
+ return FilledSlots;
+}
+
+
+/**
+ Calculate if the circular buffer has overflowed
+
+ @param[in] ReadPointer Value read from host/me read pointer
+ @param[in] WritePointer Value read from host/me write pointer
+ @param[in] BufferDepth Value read from buffer depth register
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+OverflowCB (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer,
+ IN UINT32 BufferDepth
+ )
+{
+ UINT8 FilledSlots;
+
+ FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer));
+
+ //
+ // test for overflow
+ //
+ if (FilledSlots > ((UINT8) BufferDepth)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ HeciReset
+
+ @param[in] HeciBar
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciReset (
+ IN HECI_DEVICE HeciDev
+ )
+{
+ EFI_STATUS Status;
+ UINTN HeciBar;
+ UINT32 SeCMode;
+ volatile HECI_HOST_CONTROL_REGISTER *HostControlReg;
+ volatile HECI_SEC_CONTROL_REGISTER *SecControlReg;
+
+ DEBUG ((EFI_D_INFO, "HeciReset-CSE status updated only in HECI1 interface not in HECI2 \n"));
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (SeCMode != SEC_MODE_NORMAL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HeciBar = CheckAndFixHeciForAccess (HeciDev);
+ HostControlReg = (volatile HECI_HOST_CONTROL_REGISTER *) (UINTN) (HeciBar + H_CSR);
+ SecControlReg = (volatile HECI_SEC_CONTROL_REGISTER *) (UINTN) (HeciBar + SEC_CSR_HA);
+
+ //
+ // SEC_RDY could already be set in CSE BUP
+ // Only reset if SEC_RDY is not set
+ //
+ if (SecControlReg->r.SEC_RDY_HRA != 1) {
+ while (TRUE) {
+ HostControlReg->r.H_RST = 1;
+ HostControlReg->r.H_IG = 1;
+ if (HostControlReg->r.H_RDY == 0) {
+ break;
+ }
+ }
+ }
+
+ while (TRUE) {
+ if (SecControlReg->r.SEC_RDY_HRA == 1) {
+ break;
+ }
+ }
+
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IG = 1;
+ HostControlReg->r.H_RST = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ HeciSendTest
+
+ @param[in] HeciBar
+ @param[in] Message
+ @param[in] Length
+ @param[in] HostAddress
+ @param[in] SeCAddress
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSendTest (
+ IN UINTN HeciBar,
+ IN UINT32 *Message,
+ IN UINT32 Length,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ UINTN LeftSize;
+ UINTN MaxBuffer;
+ UINTN WriteSize;
+ UINTN Size;
+ UINTN Index;
+ UINT32 *MessageBody;
+ HECI_MESSAGE_HEADER MessageHeader;
+ volatile UINT32 *WriteBuffer;
+ volatile HECI_HOST_CONTROL_REGISTER *HostControlReg;
+ volatile HECI_SEC_CONTROL_REGISTER *SecControlReg;
+
+ DEBUG ((EFI_D_INFO, "Start HeciSendTest \n"));
+ HostControlReg = (volatile HECI_HOST_CONTROL_REGISTER *) (UINTN) (HeciBar + H_CSR);
+ SecControlReg = (volatile HECI_SEC_CONTROL_REGISTER *) (UINTN) (HeciBar + SEC_CSR_HA);
+ DEBUG((EFI_D_INFO, "Start HeciSendTest %08x %08x\n", SecControlReg->ul, HostControlReg->ul));
+ WriteBuffer = (UINT32 *) (UINTN) (HeciBar + H_CB_WW);
+ MessageBody = (UINT32 *) Message;
+
+ MaxBuffer = HostControlReg->r.H_CBD;
+
+ //
+ // The first DWORD used for send MessageHeader, so useable Buffer Size should Be MaxBuffer -1;
+ //
+ MaxBuffer -= 1;
+ LeftSize = (Length + 3) / 4;
+ WriteSize = 0;
+ HostControlReg->r.H_RDY = 1;
+ while (LeftSize > 0) {
+ DEBUG ((EFI_D_INFO, "Wait for CSE ready, SecControlReg %x\n", SecControlReg->ul));
+ while (SecControlReg->r.SEC_RDY_HRA == 0) {
+ MicroSecondDelay (100000);
+ }
+ DEBUG ((EFI_D_INFO, "CSE ready SecControlReg %x\n", SecControlReg->ul));
+ HostControlReg->r.H_RDY = 1;
+ HostControlReg->r.H_IE = 0;
+
+ Size = (LeftSize > MaxBuffer) ? MaxBuffer : LeftSize;
+
+ LeftSize -= Size;
+ //
+ // Prepare message header
+ //
+ MessageHeader.Data = 0;
+ MessageHeader.Fields.SeCAddress = SeCAddress;
+ MessageHeader.Fields.HostAddress = HostAddress;
+ MessageHeader.Fields.MessageComplete = 1;
+ MessageHeader.Fields.Length = (UINT32)((LeftSize > 0) ? Size * sizeof (UINT32) : Length - WriteSize * sizeof (UINT32));
+ DEBUG((EFI_D_INFO, "Heci Message Header: %08x\n", MessageHeader.Data));
+ *WriteBuffer = MessageHeader.Data;
+ for (Index = 0; Index < Size; Index ++) {
+ DEBUG ((EFI_D_INFO, "MessageBody[%x] = %08x\n", Index, MessageBody[Index + WriteSize]));
+ *WriteBuffer = MessageBody[Index + WriteSize];
+ }
+ //
+ // Send the Interrupt;
+ //
+ DEBUG ((EFI_D_INFO, "Prepare Send Interrupt to CSE: %08x\n", HostControlReg->ul));
+ HostControlReg->r.H_IE = 1;
+ HostControlReg->r.H_IG = 1;
+ DEBUG ((EFI_D_INFO, "Send Interrupt to CSE: %08x\n", HostControlReg->ul));
+
+ while (HostControlReg->r.H_IS == 0) {
+ MicroSecondDelay (100000);
+ }
+ HostControlReg->r.H_IS = 1;
+ WriteSize += Size;
+ if (LeftSize > 0) {
+ DEBUG ((EFI_D_INFO, "More Data Need be sent, waiting CSE notify\n"));
+ DEBUG ((EFI_D_INFO, "HostControlReg %x\n", SecControlReg->ul));
+ while (HostControlReg->r.H_IS == 0) {
+ MicroSecondDelay (100000);
+ }
+ DEBUG ((EFI_D_INFO, "Get CSE notify, HostControlReg %x\n", SecControlReg->ul));
+ }
+ }
+ DEBUG ((EFI_D_INFO, "No More Data Need be sent.\n"));
+ DEBUG ((EFI_D_INFO, "End HeciSend %08x %08x\n", SecControlReg->ul, HostControlReg->ul));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Function sends one messsage through the HECI buffer and waits
+ for the corresponding ACK message.
+
+ @param[in, out] Message Pointer to the message buffer.
+ SendLength - Length of the message in bytes.
+ RecLength - Length of the message response in bytes.
+ @param[in] Length EDES_TODO: Add parameter description
+ @param[in, out] RecLength EDES_TODO: Add parameter description
+ @param[in] HostAddress Address of the sending entity.
+ MeAddress - Address of the SEC entity that should receive the message.
+ @param[in] SeCAddress EDES_TODO: Add parameter description
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+Heci2SendwACK(
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ UINTN Heci2Bar;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HECI2_PM_PROTOCOL *Heci2PmProtocol = NULL;
+ BOOLEAN Heci2Idle = FALSE;
+
+ Heci2Bar = CheckAndFixHeciForAccess (HECI2_DEVICE);
+
+ if (EFI_ERROR (GetHeci2PmProtocol (&Heci2PmProtocol))) {
+ Heci2PmProtocol = NULL;
+ DEBUG ((EFI_D_INFO, "Heci2SendwACK: Error getting HECI2 PM protocol.\n"));
+ } else if (Heci2PmProtocol != NULL) {
+ if (Heci2Bar != 0) {
+ Heci2PmProtocol->SetHeciBar (Heci2Bar);
+ }
+ if (Heci2PmProtocol->IsIdle ()) {
+ if (Heci2PmProtocol->AtRuntime ()) {
+ Heci2Idle = TRUE;
+ }
+ Heci2PmProtocol->SetActive ();
+ }
+ }
+ //
+ // Send the message
+ //
+ DEBUG ((DEBUG_INFO, "Heci2SendwAck () - Start\n"));
+ DEBUG ((DEBUG_INFO, "Message at 0x%x. Length = %d. RecLength at 0x%x. HostAddress = 0x%x. SecAddress = 0x%x.\n", (UINTN) Message, (UINTN) Length, (UINTN) RecLength, (UINTN) HostAddress, SeCAddress));
+
+ Status = HeciSend (HECI2_DEVICE, Message, Length, HostAddress, SeCAddress);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Heci2SendwACK: Error in HeciSend.\n"));
+ if (Heci2Idle) {
+ Heci2PmProtocol->SetIdle ();
+ }
+
+ return Status;
+ }
+
+ //
+ // Wait for ACK message
+ //
+ Status = HeciReceive (HECI2_DEVICE, BLOCKING, Message, RecLength);
+
+ if (Heci2Idle) {
+ Heci2PmProtocol->SetIdle ();
+ }
+
+ return Status;
+}
+
+
+/**
+ Heci2SendwoACK
+
+ @param[in, out] Message Pointer to the message buffer.
+ SendLength - Length of the message in bytes.
+ RecLength - Length of the message response in bytes.
+ @param[in] Length EDES_TODO: Add parameter description
+ @param[in, out] RecLength EDES_TODO: Add parameter description
+ @param[in] HostAddress Address of the sending entity.
+ MeAddress - Address of the SEC entity that should receive the message.
+ @param[in] SeCAddress EDES_TODO: Add parameter description
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+Heci2SendwoACK (
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ EFI_STATUS Status;
+ UINTN HeciBar;
+
+ Status = EFI_SUCCESS;
+
+ HeciBar = CheckAndFixHeciForAccess (HECI2_DEVICE);
+ DEBUG ((EFI_D_INFO, "Heci2SendwACK HeciBar %08x\n", HeciBar));
+
+ //
+ // Send the message
+ //
+ DEBUG ((DEBUG_INFO, "HeciSendwAck () - Start\n"));
+ Status = HeciSendTest (HeciBar, Message, Length, HostAddress, SeCAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ HeciSendwoACK
+
+ @param[in, out] Message
+ @param[in] Length
+ @param[in, out] RecLength
+ @param[in] HostAddress
+ @param[in] SeCAddress
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciSendwoACK(
+ IN OUT UINT32 *Message,
+ IN UINT32 Length,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Send the message
+ //
+ DEBUG ((DEBUG_INFO, "HeciSendwoACK () - HeciSend\n"));
+ Status = HeciSend (HECI1_DEVICE, Message, Length, HostAddress, SeCAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+
+ HeciGetMBPData
+
+ @param[in] MBPData
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+HeciGetMBPData (
+ UINT32 * MBPData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ MBP_CMD_REQ_DATA *SendMBP;
+ MBP_CMD_RESP_DATA *MBPResp;
+ UINT32 SeCMode;
+ UINT32 DataBuffer[0x100];
+
+ DEBUG((EFI_D_INFO, "BIOS Start Send HECI Message: HeciMBP\n"));
+
+ Status = HeciGetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (SeCMode != SEC_MODE_NORMAL && SeCMode != SEC_MODE_RECOVER) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG ((EFI_D_INFO, "GetSeCMode successful\n"));
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+
+ SendMBP= (MBP_CMD_REQ_DATA *) DataBuffer;
+ SendMBP->MKHIHeader.Fields.GroupId = 0xF0;
+ SendMBP->MKHIHeader.Fields.Command = 2;
+
+ DEBUG ((EFI_D_INFO, "MBP_CMD_REQ_DATA size is %x\n", sizeof (MBP_CMD_REQ_DATA)));
+ HeciSendLength = sizeof (MBP_CMD_REQ_DATA);
+ HeciRecvLength = sizeof (DataBuffer);
+
+ Status = HeciSendwACK (
+ HECI1_DEVICE,
+ DataBuffer,
+ HeciSendLength,
+ &HeciRecvLength,
+ BIOS_FIXED_HOST_ADDR,
+ 0x7
+ );
+
+ MBPResp = (MBP_CMD_RESP_DATA *) DataBuffer;
+
+ DEBUG ((EFI_D_INFO, "Group =%08x\n", MBPResp->MKHIHeader.Fields.GroupId));
+ DEBUG ((EFI_D_INFO, "Command =%08x\n", MBPResp->MKHIHeader.Fields.Command));
+ DEBUG ((EFI_D_INFO, "IsRespone=%08x\n", MBPResp->MKHIHeader.Fields.IsResponse));
+ DEBUG ((EFI_D_INFO, "Result =%08x\n", MBPResp->MKHIHeader.Fields.Result));
+
+ if (MBPResp->MKHIHeader.Fields.Result == 0) {
+ CopyMem (MBPData, DataBuffer, (MBPResp->Length + 1)* sizeof (UINT32));
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+
+/**
+ HeciMBP
+
+ @param[in] MBPData
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+HeciMBP(
+ UINT32 * MBPData
+ )
+{
+ UINT32 HeciMBPData[0x100];
+ UINT32 *pHeciMBPData = NULL;
+ EFI_HOB_GUID_TYPE *GuidHobPtr;
+ EFI_STATUS Status;
+
+ GuidHobPtr = GetFirstGuidHob (&gEfiHeciMbpDataHobGuid);
+ if (GuidHobPtr == NULL) {
+ Status = HeciGetMBPData (HeciMBPData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ BuildGuidDataHob (
+ &gEfiHeciMbpDataHobGuid,
+ &HeciMBPData,
+ (sizeof (UINT32) * 0x100)
+ );
+ //
+ // Get Hob again for the first time to read the MBP data.
+ //
+ GuidHobPtr = GetFirstGuidHob (&gEfiHeciMbpDataHobGuid);
+ }
+
+ pHeciMBPData = (UINT32 *) GET_GUID_HOB_DATA (GuidHobPtr);
+ CopyMem (MBPData, pHeciMBPData , 0x100 * sizeof (UINT32));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ DumpBuffer_HECI
+
+ @param[in] Buffer1
+
+ @return None
+
+**/
+VOID
+DumpBuffer_HECI (
+ VOID *Buffer1,
+ UINT8 bufferSize
+ )
+{
+ DEBUG_CODE_BEGIN ();
+
+ UINTN Index;
+ UINT8 *Buffer;
+
+ Buffer = (UINT8 *) Buffer1;
+ DEBUG ((EFI_D_INFO, "DumpBuffer 0x%08x\n", Buffer));
+ for (Index = 0; Index < bufferSize; Index++) {
+ DEBUG ((EFI_D_INFO, "%02x ", Buffer[Index]));
+ if ((bufferSize % 16) == 0){
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+
+ DEBUG_CODE_END ();
+}
+
+
+/**
+ HeciGetBootDevice
+
+ @param[in] BootMediaData
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+HeciGetBootDevice (
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataBuffer[0x100];
+ MBP_CMD_RESP_DATA *MBPHeader;
+ MBP_ITEM_HEADER *MBPItem;
+ MBP_CURRENT_BOOT_MEDIA *BootMedia;
+
+ SetMem (DataBuffer, sizeof (DataBuffer), 0);
+ Status = HeciMBP (DataBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ MBPHeader = (MBP_CMD_RESP_DATA *) DataBuffer;
+ DEBUG ((EFI_D_INFO, "HeciGetBootDevice 1\n"));
+ DumpBuffer_HECI (MBPHeader, sizeof (MBP_CMD_RESP_DATA));
+
+ MBPItem = (MBP_ITEM_HEADER *) (MBPHeader + 1);
+ DEBUG ((EFI_D_INFO, "HeciGetBootDevice 2\n"));
+ DumpBuffer_HECI (MBPItem, MBPHeader->Length);
+
+ while ((UINT32 *) MBPItem < (UINT32 *) DataBuffer + MBPHeader->Length) {
+ if (MBPItem->AppID == 8 && MBPItem->ItemID == 1) {
+ DEBUG ((EFI_D_INFO, "HeciGetBootDevice 3\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ BootMedia = (MBP_CURRENT_BOOT_MEDIA *) (MBPItem + 1);
+ CopyMem ((VOID *) BootMediaData, (VOID *) BootMedia, sizeof (MBP_CURRENT_BOOT_MEDIA));
+ return EFI_SUCCESS;
+ }
+ MBPItem = (MBP_ITEM_HEADER *) ((UINT32 *) MBPItem + MBPItem->Length);
+ DEBUG ((EFI_D_INFO, "HeciGetBootDevice 4\n"));
+ DumpBuffer_HECI (MBPItem, sizeof (MBP_ITEM_HEADER) + MBPItem->Length);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+SeCAlivenessRequest (
+ IN UINTN *HeciMemBar,
+ IN UINT32 Request
+ )
+{
+ UINT32 HostAlivenessResponse;
+ UINT32 TimerStart;
+ UINT32 TimerEnd;
+ volatile UINT32 *HpetTimer;
+
+ //
+ // Check for SEC ready status
+ //
+ HpetTimer = StartTimer (&TimerStart, &TimerEnd, PEI_HECI_INIT_TIMEOUT);
+
+ if (Request == 1) {
+ Mmio32Or (*HeciMemBar, R_SICR_HOST_ALIVENESS_REQ, Request);
+ } else {
+ Mmio32And (*HeciMemBar, R_SICR_HOST_ALIVENESS_REQ, 0xfffffffe);
+ }
+ HostAlivenessResponse = Mmio32 (*HeciMemBar, 0x2044);
+ while ((HostAlivenessResponse & Request) != Request) {
+ HostAlivenessResponse = Mmio32 (*HeciMemBar, 0x2044);
+ if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) {
+ return EFI_TIMEOUT;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+HeciInitLibConstructor (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL;
+
+ FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid);
+ mFdoModeEnabled = (FdoEnabledGuidHob != NULL);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ HeciIshSendwAck
+
+ @param[in] SendMessage
+ @param[out] ReceiveMessage
+ @param[in, out] Length
+ @param[in, out] RecLength
+ @param[in] HostAddress
+ @param[in] SeCAddress
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciIshSendwAck (
+ IN HECI_DEVICE HeciDev,
+ IN VOID *SendMessage,
+ OUT VOID *ReceiveMessage,
+ IN UINT32 SendLength,
+ IN OUT UINT32 *RecLength,
+ IN UINT8 HostAddress,
+ IN UINT8 SeCAddress
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Send the message
+ //
+ DEBUG ((DEBUG_INFO, "HeciIshSendwAck () - Start\n"));
+ Status = HeciSend (HeciDev, (UINT32 *) SendMessage, SendLength, HostAddress, SeCAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Wait for ACK message
+ //
+ Status = HeciReceive (HeciDev, BLOCKING, (UINT32 *) ReceiveMessage, RecLength);
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.h
new file mode 100644
index 0000000000..77ec2618cf
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.h
@@ -0,0 +1,109 @@
+/** @file
+ Definitions for HECI driver.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HECI_CORE_H
+#define _HECI_CORE_H
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/TimerLib.h>
+#include <SeCState.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/MmPciLib.h>
+#include <Library/SeCLib.h>
+
+//
+// HECI bus function version
+//
+#define HBM_MINOR_VERSION 0
+#define HBM_MAJOR_VERSION 1
+
+#define STALL_1_MILLISECOND 1000
+#define CSE_WAIT_TIMEOUT 50
+
+//
+// Local/Private functions not part of EFIAPI for HECI
+//
+/**
+ Waits for the ME to report that it is ready for communication over the HECI
+ interface.
+
+ @param[in] None
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+WaitForSECInputReady (
+ VOID
+ );
+
+/**
+ Calculate if the circular buffer has overflowed.
+
+ @param[in] ReadPointer Location of the read pointer.
+ @param[in] WritePointer Location of the write pointer.
+
+ @retval Number of filled slots.
+
+**/
+UINT8
+FilledSlots (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer
+ );
+
+/**
+ Calculate if the circular buffer has overflowed.
+
+ @param[in] ReadPointer Value read from host/me read pointer
+ @param[in] WritePointer Value read from host/me write pointer
+ @param[in] BufferDepth Value read from buffer depth register
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+OverflowCB (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer,
+ IN UINT32 BufferDepth
+ );
+
+/**
+ SeCAlivenessRequest
+
+ @param[in] HeciMemBar
+ @param[in] Request
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+SeCAlivenessRequest (
+ IN UINTN *HeciMemBar,
+ IN UINT32 Request
+ );
+
+#endif // _HECI_CORE_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.c
new file mode 100644
index 0000000000..85847a4e54
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.c
@@ -0,0 +1,202 @@
+/** @file
+ Definitions for HECI driver.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HeciHpet.h"
+
+//
+// Extern for shared HECI data and protocols
+//
+volatile UINT32 mSaveHpetConfigReg;
+
+/**
+ Enable Hpet function.
+
+ @param[in] None
+
+ @retval UINT32 Return the High Precision Event Timer base address
+
+**/
+volatile
+UINT32 *
+EnableHpet (
+ VOID
+ )
+{
+ volatile UINT32 *HpetTimer;
+
+ HpetTimer = (VOID *) (UINTN) (HPET_BASE_ADDRESS);
+
+ //
+ // Start the timer so it is up and running
+ //
+ HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START;
+
+ DEBUG ((EFI_D_INFO, "EnableHpet %x %x\n\n ", HPET_GEN_CONFIG_LOW, HpetTimer));
+ return HpetTimer;
+
+}
+
+
+/**
+ Store the value of High Performance Timer
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+SaveHpet (
+ VOID
+ )
+{
+}
+
+/**
+ Restore the value of High Performance Timer
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+RestoreHpet (
+ VOID
+ )
+{
+}
+
+/**
+ Used for calculating timeouts
+
+ @param[in] Start Snapshot of the HPET timer
+ @param[in] End Calculated time when timeout period will be done
+ @param[in] Time Timeout period in microseconds
+
+ @retval None
+
+**/
+volatile
+UINT32 *
+StartTimer (
+ OUT UINT32 *Start,
+ OUT UINT32 *End,
+ IN UINT32 Time
+ )
+{
+ UINT32 Ticks;
+ volatile UINT32 *HpetTimer;
+
+ //
+ // Make sure that HPET is enabled and running
+ //
+ HpetTimer = EnableHpet ();
+
+ //
+ // Read current timer value into start time from HPET
+ //
+ *Start = HpetTimer[HPET_MAIN_COUNTER_LOW];
+
+ //
+ // Convert microseconds into 70ns timer ticks
+ //
+ Ticks = Time * HPET_TICKS_PER_MICRO;
+
+ //
+ // Compute end time
+ //
+ *End = *Start + Ticks;
+
+ return HpetTimer;
+}
+
+
+/**
+ Used to determine if a timeout has occured.
+
+ @param[in] Start Snapshot of the HPET timer when the timeout period started.
+ @param[in] End Calculated time when timeout period will be done.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+Timeout (
+ IN UINT32 Start,
+ IN UINT32 End,
+ IN volatile UINT32 *HpetTimer
+ )
+{
+ UINT32 Current;
+
+ //
+ // Read HPET and assign the value as the current time.
+ //
+ Current = HpetTimer[HPET_MAIN_COUNTER_LOW];
+
+ //
+ // Test basic case (no overflow)
+ //
+ if ((Start < End) && (End <= Current)) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // Test basic start/end conditions with overflowed timer
+ //
+ if ((Start < End) && (Current < Start)) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // Test for overflowed start/end condition
+ //
+ if ((Start > End) && ((Current < Start) && (Current > End))) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // Catch corner case of broken arguments
+ //
+ if (Start == End) {
+ return EFI_TIMEOUT;
+ }
+
+ DEBUG ((EFI_D_INFO, "crnt %X start %X end %X\n", Current, Start, End));
+
+ //
+ // Else, we have not yet timed out
+ //
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Delay for at least the request number of microseconds
+
+ @param[in] delayTime Number of microseconds to delay.
+
+ @retval None
+
+**/
+VOID
+IoDelay (
+ UINT32 delayTime
+ )
+{
+ MicroSecondDelay(delayTime);
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.h
new file mode 100644
index 0000000000..3ed613ac66
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.h
@@ -0,0 +1,99 @@
+/** @file
+ Definitions for HECI driver.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HECI_HPET_H
+#define _HECI_HPET_H
+
+#include "HeciCore.h"
+#include <IndustryStandard/Pci22.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+
+volatile
+UINT32 *
+EnableHpet (
+ VOID
+ );
+
+VOID
+SaveHpet (
+ VOID
+ );
+
+/**
+ Restore the value of High Performance Timer
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+RestoreHpet (
+ VOID
+ );
+
+/**
+ Used for calculating timeouts
+
+ @param[in] Start Snapshot of the HPET timer
+ @param[in] End Calculated time when timeout period will be done
+ @param[in] Time Timeout period in microseconds
+
+ @retval None
+
+**/
+volatile
+UINT32 *
+StartTimer (
+ OUT UINT32 *Start,
+ OUT UINT32 *End,
+ IN UINT32 Time
+ );
+
+/**
+ Used to determine if a timeout has occured.
+
+ @param[in] Start Snapshot of the HPET timer when the timeout period started.
+ @param[in] End Calculated time when timeout period will be done.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+Timeout (
+ IN UINT32 Start,
+ IN UINT32 End,
+ IN volatile UINT32 *HpetTimer
+ );
+
+/**
+ Delay for at least the request number of microseconds
+
+ @param[in] delayTime Number of microseconds to delay.
+
+ @retval None
+
+**/
+VOID
+IoDelay (
+ UINT32 delayTime
+ );
+
+#endif ///< _HECI_HPET_H
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf
new file mode 100644
index 0000000000..6a9bf8de5f
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Heci init library.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiDxeHeciInitLib
+ FILE_GUID = E1EFE2E8-FFAF-44e3-A99F-ABAFDDEF9C7B
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HeciInitLib
+ CONSTRUCTOR = HeciInitLibConstructor
+
+[Sources]
+ HeciCore.c
+ HeciCore.h
+ HeciHpet.c
+ HeciHpet.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ PciLib
+ BaseLib
+ MmPciLib
+ Heci2PowerManagementLib
+ HobLib
+ DebugLib
+ PcdLib
+
+[Pcd]
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiHeciMbpDataHobGuid ## UNDEFINED
+ gFdoModeEnabledHobGuid
+
+[Protocols]
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.c
new file mode 100644
index 0000000000..06d1c260ab
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.c
@@ -0,0 +1,578 @@
+/** @file
+ Framework PEIM to SeCUma.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <SeCUma.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SideBandLib.h>
+#include <Private/Library/HeciInitLib.h>
+#include <Library/HobLib.h>
+
+#ifndef FSP_FLAG
+#include <Library/PeiServicesLib.h>
+#include <Library/PerformanceLib.h>
+#include <Ppi/EndOfPeiPhase.h>
+#endif
+
+#include <Library/PcdLib.h>
+#include <Library/MmPciLib.h>
+
+#ifdef FSP_FLAG
+#include <Library/FspCommonLib.h>
+#include <FspmUpd.h>
+#endif
+
+extern EFI_GUID gEfiBootMediaHobGuid;
+extern EFI_GUID gEfiIfwiDnxRequestHobGuid;
+extern EFI_PEI_STALL_PPI mStallPpi;
+extern BOOLEAN ImageInMemory;
+
+#define S3 0x20
+
+#ifndef FSP_FLAG
+/**
+ Txe End of PEI callback function. This is the last event before entering DXE and OS in S3 resume.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS Succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+TxeOnEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mTxeNotifyList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiEndOfPeiSignalPpiGuid,
+ TxeOnEndOfPei
+ }
+};
+#endif
+
+//
+// Function Declarations
+//
+static SEC_UMA_PPI mSeCUmaPpi = {
+ SeCSendUmaSize,
+ SeCConfigDidReg,
+ SeCTakeOwnerShip
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mSeCUmaPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gSeCUmaPpiGuid,
+ &mSeCUmaPpi
+ }
+};
+EFI_PEI_PPI_DESCRIPTOR mCseEmmcSelectPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCseEmmcSelectPpiGuid,
+ NULL
+ }
+};
+EFI_PEI_PPI_DESCRIPTOR mCseUfsSelectPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCseUfsSelectPpiGuid,
+ NULL
+ }
+};
+EFI_PEI_PPI_DESCRIPTOR mCseSpiSelectPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCseSpiSelectPpiGuid,
+ NULL
+ }
+};
+
+/**
+
+ This procedure will read and return the amount of SeC UMA requested
+ by SeC ROM from the HECI device.
+
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @return Return SeC UMA Size
+
+**/
+UINT32
+SeCSendUmaSize (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ return 0;
+}
+
+/**
+ This procedure will enforce the BIOS Action that was requested by SEC FW
+ as part of the DRAM Init Done message.
+
+ @param[in] BiosAction Me requests BIOS to act
+
+ @retval EFI_SUCCESS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+HandleSecBiosAction (
+ IN UINT8 BiosAction
+ )
+{
+ EFI_STATUS Status;
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+
+ //
+ // Read SEC FWSTS
+ //
+ SeCFirmwareStatus.ul = HeciPciRead32 (R_SEC_FW_STS0);
+ DEBUG ((DEBUG_INFO, "SecFwsts = %x.\n", SeCFirmwareStatus.ul));
+
+ switch (BiosAction) {
+ case 0:
+ //
+ // Case: DID ACK was not received
+ //
+ DEBUG ((DEBUG_ERROR, "DID Ack was not received, no BIOS Action to process.\n"));
+ break;
+
+ case CBM_DIR_NON_PCR:
+ //
+ // Case: Perform Non-Power Cycle Reset
+ //
+ DEBUG ((DEBUG_ERROR, "SEC FW has requested a Non-PCR.\n"));
+ Status = PerformReset (CBM_DIR_NON_PCR);
+ break;
+
+ case CBM_DIR_PCR:
+ //
+ // Case: Perform Power Cycle Reset
+ //
+ DEBUG ((DEBUG_ERROR, "SEC FW has requested a PCR.\n"));
+ Status = PerformReset (CBM_DIR_PCR);
+ break;
+
+ case 3:
+ //
+ // Case: Go To S3
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S3. Not defined, continuing to POST.\n"));
+ break;
+
+ case 4:
+ //
+ // Case: Go To S4
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S4. Not defined, continuing to POST.\n"));
+ break;
+
+ case 5:
+ //
+ // Case: Go To S5
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S5. Not defined, continuing to POST.\n"));
+ break;
+
+ case CBM_DIR_GLOBAL_RESET:
+ //
+ // Case: Perform Global Reset
+ //
+ DEBUG ((DEBUG_ERROR, "SEC FW has requested a Global Reset.\n"));
+ Status = PerformReset (CBM_DIR_GLOBAL_RESET);
+ break;
+
+ case CBM_DIR_CONTINUE_POST:
+ //
+ // Case: Continue to POST
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID Ack requested to continue to POST.\n"));
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This procedure will configure the SEC Host General Status register,
+ indicating that DRAM Initialization is complete and SeC FW may
+ begin using the allocated SeC UMA space.
+
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param MrcBootMode MRC BootMode
+ @param InitStat H_GS[27:24] Status
+ @param SeCUmaBase LSB of base address
+ SeCUmaBaseEx - MSB of base address
+ SeCUmaSIze - Allocated size of UMA
+ @param SeCUmaSize EDES_TODO: Add parameter description
+
+ @retval EFI_SUCCESS
+
+**/
+
+EFI_STATUS
+SeCConfigDidReg (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ MRC_BOOT_MODE_T MrcBootMode,
+ UINT8 InitStat,
+ UINT32 SeCUmaBase,
+ UINT32 *SeCUmaSize
+ )
+{
+ return EFI_SUCCESS;
+}
+
+#ifdef FSP_FLAG
+VOID FspCheckBootDevice (
+ IN OUT INTN *DeviceIndex,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+}
+#endif
+
+VOID CheckBootDevice (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ INTN DeviceIndex;
+ EFI_STATUS Status;
+ MBP_CURRENT_BOOT_MEDIA BootMediaData;
+ MBP_IFWI_DNX_REQUEST IfwiDnxRequest;
+
+ SetMem (&BootMediaData, sizeof (MBP_CURRENT_BOOT_MEDIA), 0xFF);
+
+
+ Status = HeciGetIfwiDnxRequest (&IfwiDnxRequest);
+ if (EFI_ERROR (Status)) {
+ SetMem (&IfwiDnxRequest, sizeof (MBP_IFWI_DNX_REQUEST), 0x0);
+ }
+
+ Status = HeciGetBootDevice (&BootMediaData);
+
+ DeviceIndex = BootMediaData.PhysicalData;
+
+ if (DeviceIndex == 0) {
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is EMMC.\n"));
+ Status = (*PeiServices)->InstallPpi(PeiServices, mCseEmmcSelectPpiList);
+ } else if (DeviceIndex == 1) {
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is UFS.\n"));
+ Status = (*PeiServices)->InstallPpi(PeiServices, mCseUfsSelectPpiList);
+ } else if (DeviceIndex == 2) {
+ DEBUG ((DEBUG_INFO, "CSE Boot Device is SPI.\n"));
+ Status = (*PeiServices)->InstallPpi(PeiServices, mCseSpiSelectPpiList);
+ } else {
+ DEBUG ((EFI_D_ERROR, "\nCSE Boot device is unknown (DevIndx: 0x%x). Cannot continue!\n", DeviceIndex));
+ CpuDeadLoop ();
+ }
+
+ //
+ // Build HOB for BootMediaData
+ //
+ BuildGuidDataHob (
+ &gEfiBootMediaHobGuid,
+ &BootMediaData,
+ sizeof (MBP_CURRENT_BOOT_MEDIA)
+ );
+
+ //
+ // Build HOB for IfwiDnxRequest
+ //
+ BuildGuidDataHob (
+ &gEfiIfwiDnxRequestHobGuid,
+ &IfwiDnxRequest,
+ sizeof (MBP_IFWI_DNX_REQUEST)
+ );
+ if (DeviceIndex != 2) {
+ HeciTakeOwnerShip();
+ }
+}
+
+
+EFI_STATUS
+SeCTakeOwnerShip (
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This procedure will issue a Non-Power Cycle, Power Cycle, or Global Rest.
+
+ @param ResetType Type of reset to be issued.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+PerformReset (
+ UINT8 ResetType
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32;
+ UINT32 GpioBase;
+ UINT8 Reset;
+ UINT32 ETR;
+
+ Reset = 0;
+ GpioBase = 0;
+
+ Status = ClearDISB ();
+
+ ETR = (UINT32) MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PMC, PCI_FUNCTION_NUMBER_PMC_IPC1, R_PMC_PMIR);
+ MmioAnd32 (
+ (UINTN) ETR,
+ (UINT32)~(B_PMC_PMIR_CF9GR)
+ );
+
+ Reset = IoRead8 (R_RST_CNT);
+ Reset &= 0xF1;
+
+ switch (ResetType) {
+ case 0:
+ //
+ // Case: DID ACK was not received
+ //
+ DEBUG ((DEBUG_ERROR, "DID Ack was not received, no BIOS Action to process.\n"));
+ break;
+
+ case CBM_DIR_NON_PCR:
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested a Non Power Cycle Reset.\n"));
+ Reset |= 0x06;
+ break;
+
+ case CBM_DIR_PCR:
+ //
+ // Power Cycle Reset requested
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested a Power Cycle Reset.\n"));
+ Reset |= 0x0E;
+ break;
+
+ case 3:
+ //
+ // Case: Go To S3
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S3. Not defined, continuing to POST.\n"));
+ break;
+
+ case 4:
+ //
+ // Case: Go To S4
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S4. Not defined, continuing to POST.\n"));
+ break;
+
+ case 5:
+ //
+ // Case: Go To S5
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID ACK has requested entry to S5. Not defined, continuing to POST.\n"));
+ break;
+
+ case CBM_DIR_GLOBAL_RESET:
+ //
+ // Global Reset
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID Ack requested a global reset.\n"));
+
+ Data32 = IoRead32 (GpioBase + 0x60);
+ Data32 |= BIT30;
+ IoWrite32 (GpioBase + 0x60, Data32);
+ MmioOr32 (
+ (UINTN) ETR,
+ (UINT32) (B_PMC_PMIR_CF9GR)
+ );
+
+ DEBUG ((DEBUG_INFO, "Issuing global reset.\n"));
+ Reset |= 0x0E;
+ break;
+
+ case CBM_DIR_CONTINUE_POST:
+ //
+ // Case: Continue to POST
+ //
+ DEBUG ((DEBUG_INFO, "SEC FW DID Ack requested to continue to POST.\n"));
+ break;
+ }
+ //
+ // Write SC RST CNT, Issue Reset
+ //
+ IoWrite8 (R_RST_CNT, Reset);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This procedure will clear the DISB.
+
+ @param VOID
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+ClearDISB (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SeCUmaEntry (
+ IN EFI_PEI_FILE_HANDLE *FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+#ifndef FSP_FLAG
+ EFI_BOOT_MODE BootMode;
+#endif
+
+ if (!ImageInMemory) {
+ Status = (*PeiServices)->InstallPpi (PeiServices, mSeCUmaPpiList);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // locate the SecUma PPI
+ //
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gSeCUmaPpiGuid, // GUID
+ 0, // INSTANCE
+ &PeiPpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ NULL // PPI
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Reinstall the SecUma PPI
+ //
+ Status = (**PeiServices).ReInstallPpi (
+ PeiServices,
+ PeiPpiDescriptor,
+ mSeCUmaPpiList
+ );
+ }
+#ifndef FSP_FLAG
+ Status = (*PeiServices)->GetBootMode (
+ PeiServices,
+ &BootMode
+ );
+
+ if (EFI_ERROR (Status) || BootMode != BOOT_ON_S3_RESUME) {
+ DEBUG((DEBUG_INFO, "SeCUmaEntry() CheckBootDevice, %r\n", Status));
+ CheckBootDevice (PeiServices);
+ } else {
+ Status = PeiServicesNotifyPpi (mTxeNotifyList);
+ HeciReset (HECI2_DEVICE);
+ }
+#endif
+ }
+
+ return Status;
+}
+
+
+#ifndef FSP_FLAG
+VOID
+HideHeci23 (
+ VOID
+ )
+{
+}
+
+
+/**
+ Check it's SPI boot path or not.
+
+ @retval TRUE SPI Boot path
+ @retval FALSE Not SPI boot path
+
+**/
+BOOLEAN
+IsSpiBoot (
+ VOID
+ )
+{
+ VOID *HobList;
+ MBP_CURRENT_BOOT_MEDIA *BootMediaData;
+
+ DEBUG ((EFI_D_INFO, "IsSpiBoot Start!\n"));
+
+ HobList = GetFirstGuidHob (&gEfiBootMediaHobGuid);
+ if (HobList != NULL) {
+ DEBUG ((EFI_D_INFO, "IsSpiBoot HobList != NULL\n"));
+ BootMediaData = GET_GUID_HOB_DATA (HobList);
+ if (BootMediaData->PhysicalData == BOOT_FROM_SPI) {
+ DEBUG ((EFI_D_INFO, "BootMediaData->PhysicalData == IsSpiBoot\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Not boot from SPI\n"));
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Txe End of PEI callback function. This is the last event before entering DXE and OS in S3 resume.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS Succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+TxeOnEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ DEBUG ((EFI_D_INFO, "TxeOnEndOfPei Start!\n"));
+
+ PERF_START_EX (NULL, NULL, NULL, 0, 0x8100);
+ HideHeci23 ();
+ PERF_END_EX (NULL, NULL, NULL, 0, 0x8101);
+
+ DEBUG ((EFI_D_INFO, "TxeOnEndOfPei Exit!\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.h
new file mode 100644
index 0000000000..0f8765c8a1
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.h
@@ -0,0 +1,134 @@
+/** @file
+ Header file for Framework PEIM to SeCUma.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_UMA_H_
+#define _SEC_UMA_H_
+
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PerformanceLib.h>
+#include <Library/TimerLib.h>
+#include <Ppi/SeCUma.h>
+#include <Ppi/Stall.h>
+#include "PlatformBaseAddresses.h"
+#include <ScRegs/RegsPmc.h>
+
+#define R_MESEG_BASE 0x70 // Removed in BXT
+#define B_EXCLUSION BIT8
+
+//
+// SEC FW communication timeout value definitions
+//
+#define DID_TIMEOUT_MULTIPLIER 0x1388
+
+//
+// SEC FW HOST ALIVENESS RESP timeout
+//
+#define HOST_ALIVENESS_RESP_TIMEOUT_MULTIPLIER 0x1388
+#define MUSZV_TIMEOUT_MULTIPLIER 0x1388
+#define CPURV_TIMEOUT_MULTIPLIER 0x32
+#define STALL_1_MILLISECOND 1000
+#define STALL_100_MICROSECONDS 100
+
+//
+// Function Prototype(s)
+//
+/**
+ This procedure will read and return the amount of SEC UMA requested
+ by SEC ROM from the HECI device.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @return Return SEC UMA Size in KBs
+
+**/
+EFI_STATUS
+SeCSendUmaSize (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This procedure will configure the SEC Host General Status register,
+ indicating that DRAM Initialization is complete and SEC FW may
+ begin using the allocated SEC UMA space.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param MrcBootMode MRC BootMode
+ @param InitStat H_GS[27:24] Status
+ @param SeCUmaBase Memory Location ** must be with in 4GB range
+ @param SeCUmaSize EDES_TODO: Add parameter description
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+SeCConfigDidReg (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ MRC_BOOT_MODE_T MrcBootMode,
+ UINT8 InitStat,
+ UINT32 SeCUmaBase,
+ UINT32 *SeCUmaSize
+ );
+
+EFI_STATUS
+SeCTakeOwnerShip (
+ );
+
+/**
+ This procedure will issue a Non-Power Cycle, Power Cycle, or Global Rest.
+
+ @param ResetType Type of reset to be issued.
+
+ @return Return EFI_SUCCESS
+
+**/
+EFI_STATUS
+PerformReset (
+ UINT8 ResetType
+ );
+
+/**
+ This procedure will clear the DISB.
+
+ @param VOID EDES_TODO: Add parameter description
+
+ @return Return EFI_SUCCESS
+
+**/
+EFI_STATUS
+ClearDISB (
+ VOID
+ );
+
+/**
+ This procedure will check the exposure of SeC device.
+
+ @param PeiServices EDES_TODO: Add parameter description
+
+ @return Return EFI_SUCCESS
+
+**/
+EFI_STATUS
+isSeCExpose (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.inf
new file mode 100644
index 0000000000..253ffe66c3
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.inf
@@ -0,0 +1,63 @@
+## @file
+# SeCUma library.
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SeCUma
+ FILE_GUID = b6a2aff3-767c-5658-c37a-d1c82ef76543
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = SeCUmaLib
+
+[Sources.common]
+ SeCUma.c
+ SeCUma.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ PciLib
+ PerformanceLib
+ IoLib
+ PeimEntryPoint
+ TimerLib
+ HeciInitLib
+ HeciMsgLib
+ SideBandLib
+ HobLib
+ PcdLib
+ MmPciLib
+
+[Ppis]
+ gSeCUmaPpiGuid ## NOTIFY
+ gCseUfsSelectPpiGuid ## SOMETIMES_PRODUCES
+ gCseEmmcSelectPpiGuid ## SOMETIMES_PRODUCES
+ gCseSpiSelectPpiGuid ## SOMETIMES_PRODUCES
+ gEfiEndOfPeiSignalPpiGuid
+
+[Guids]
+ gEfiBootMediaHobGuid ## UNDEFINED
+ gEfiIfwiDnxRequestHobGuid ## UNDEFINED
+ gFdoModeEnabledHobGuid
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES
+
+[Depex]
+ TRUE
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c
new file mode 100644
index 0000000000..2f3d0badca
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c
@@ -0,0 +1,1626 @@
+/** @file
+ Implementation file for Heci Message functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Heci.h>
+#include <Protocol/ScReset.h>
+#include <CoreBiosMsg.h>
+#include <HeciRegs.h>
+#include <SeCAccess.h>
+
+/**
+ Send Core BIOS Reset Request Message through HECI.
+
+ @param[in] ResetOrigin Reset source.
+ @param[in] ResetType Global or Host reset.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendCbmResetRequest (
+ IN UINT8 ResetOrigin,
+ IN UINT8 ResetType
+ )
+{
+ EFI_HECI_PROTOCOL *Heci;
+ EFI_STATUS Status;
+ UINT32 HeciLength;
+ CBM_RESET_REQ CbmResetRequest;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CbmResetRequest.MKHIHeader.Data = 0;
+ CbmResetRequest.MKHIHeader.Fields.Command = CBM_RESET_REQ_CMD;
+ CbmResetRequest.MKHIHeader.Fields.IsResponse = 0;
+ CbmResetRequest.MKHIHeader.Fields.GroupId = MKHI_CBM_GROUP_ID;
+ CbmResetRequest.MKHIHeader.Fields.Reserved = 0;
+ CbmResetRequest.MKHIHeader.Fields.Result = 0;
+ CbmResetRequest.Data.RequestOrigin = ResetOrigin;
+ CbmResetRequest.Data.ResetType = ResetType;
+
+ HeciLength = sizeof (CBM_RESET_REQ);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &CbmResetRequest,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Send Reset Request - %r\n", Status));
+ }
+
+ return Status;
+}
+
+
+/**
+ Called by each FWU request API when there's a flow control message expected on the link.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSecToHostFlowControl (
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ HBM_FLOW_CONTROL_MSG FlowCtrlMsg;
+ UINT32 MsgLen = sizeof (HBM_FLOW_CONTROL_MSG);
+
+ DEBUG ((EFI_D_INFO, "####Sec to Heci flow control####\n"));
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // First get flow control from SEC
+ //
+ ZeroMem (&FlowCtrlMsg, sizeof (HBM_FLOW_CONTROL_MSG));
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &FlowCtrlMsg,
+ &MsgLen
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "#####Fwuflow control: wait for SEC failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Called by each FWU request API when host needs to inform SEC it's ready to accept any input.
+
+ @param[in] SecAddress The dynamic sec address the flow control.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHostToSecFlowControl (
+ IN UINT8 SecAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ HBM_FLOW_CONTROL_MSG FlowCtrlMsg;
+
+ DEBUG ((EFI_D_INFO, "####Host to SeC flow control####\n"));
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Send flow control to SEC
+ //
+ ZeroMem (&FlowCtrlMsg, sizeof (HBM_FLOW_CONTROL_MSG));
+ FlowCtrlMsg.Cmd = HBM_CMD_FLOW_CONTROL;
+ FlowCtrlMsg.HostAddress = BIOS_FIXED_HOST_ADDR + 1;
+ FlowCtrlMsg.SecAddress = SecAddress;
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &FlowCtrlMsg,
+ sizeof (HBM_FLOW_CONTROL_MSG),
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HBM_MSG_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "#####Fwuflow control: Send to SEC failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Called by each FWU request API when both sec and host needs to inform each other it's ready to accept any input.
+
+ @param[in] SecAddress Returns the SecAddress to be used by other FWU APIs.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciBiDirectionFlowControl (
+ IN UINT8 SecAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ HBM_FLOW_CONTROL_MSG FlowCtrlMsg;
+ UINT32 MsgLen = sizeof (HBM_FLOW_CONTROL_MSG);
+
+ DEBUG ((EFI_D_INFO, "####Bi-Directional flow control####\n"));
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // First get flow control from SEC
+ //
+ gBS->Stall (200);
+
+ ZeroMem (&FlowCtrlMsg, sizeof (HBM_FLOW_CONTROL_MSG));
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32*)&FlowCtrlMsg,
+ &MsgLen
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "#####Fwuflow control: wait for SEC failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ //
+ // Then send flow control to SEC
+ //
+ ZeroMem (&FlowCtrlMsg, sizeof (HBM_FLOW_CONTROL_MSG));
+ FlowCtrlMsg.Cmd = HBM_CMD_FLOW_CONTROL;
+ FlowCtrlMsg.HostAddress = BIOS_FIXED_HOST_ADDR + 1;
+ FlowCtrlMsg.SecAddress = SecAddress;
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &FlowCtrlMsg,
+ sizeof (HBM_FLOW_CONTROL_MSG),
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HBM_MSG_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "#####Fwuflow control: Send to SEC failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Setup a dynamic connection for FWU.
+
+ @param[in, out] SecAddress Returns the SecAddress to be used by other FWU APIs
+ @param[in] MaxBufferSize Specifies the maximum buffer size the FWU link allows.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciConnectFwuInterface (
+ IN OUT UINT8 *SecAddress,
+ OUT UINT32 *MaxBufferSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ HBM_ENUM_MSG EnumMsg;
+ HBM_ENUM_MSG_REPLY EnumMsgReply;
+ HBM_CLIENT_PROP_MSG PropMsg;
+ HBM_CLIENT_PROP_MSG_REPLY PropMsgReply;
+ HBM_CONNECT_MSG ConnectMsg;
+ HBM_CONNECT_MSG_REPLY ConnectMsgReply;
+ OEM_UUID FwuClientGuid;
+ UINT32 MsgReplyLen = 0;
+ UINT8 AddrIdx = 0;
+ UINTN EnumIdx = 0;
+ UINT8 GuidData4Array[8] = {0x8F, 0x78, 0x60, 0x01, 0x15, 0xA3, 0x43, 0x27};
+
+ FwuClientGuid.Data1 = 0x309DCDE8;
+ FwuClientGuid.Data2 = 0xCCB1;
+ FwuClientGuid.Data3 = 0x4062;
+ CopyMem (&FwuClientGuid.Data4[0], &GuidData4Array[0], 8);
+
+ DEBUG ((EFI_D_INFO, "HeciConnectFwuInterface +++.\n"));
+
+ //
+ // Check NULL Pointer
+ //
+ if (SecAddress == NULL) {
+ DEBUG ((EFI_D_ERROR, "Invalid SecAdress assigned.\n"));
+ return EFI_ABORTED;
+ }
+ *SecAddress = 0;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (SecAddress == NULL) {
+ DEBUG ((EFI_D_ERROR, "Invalid SecAdress assigned.\n"));
+ return EFI_ABORTED;
+ }
+
+ ZeroMem (&EnumMsg, sizeof (HBM_ENUM_MSG));
+ ZeroMem (&EnumMsgReply, sizeof (HBM_ENUM_MSG_REPLY));
+ EnumMsg.Cmd = HBM_CMD_ENUM;
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &EnumMsg,
+ sizeof (HBM_ENUM_MSG),
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HBM_MSG_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to send HBM_ENUM_MSG.\n"));
+ return Status;
+ }
+
+ MsgReplyLen = sizeof (HBM_ENUM_MSG_REPLY);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &EnumMsgReply,
+ &MsgReplyLen
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "HeciHBMEnum failed with ReadMsg, Status is: %d.\n", Status));
+ return EFI_ABORTED;
+ }
+
+ if (EnumMsgReply.CmdReply != HBM_CMD_ENUM_REPLY ) {
+ DEBUG ((EFI_D_ERROR, "HBM enum get invalid reply:%d\n", EnumMsgReply.CmdReply));
+ return EFI_ABORTED;
+ }
+
+ for (AddrIdx = 8; AddrIdx > 0; AddrIdx--) {
+ DEBUG ((EFI_D_INFO, "Idx:%d, Value:%08x\n", 8 - AddrIdx, EnumMsgReply.ValidAddresses[AddrIdx - 1]));
+ }
+
+ ZeroMem (&PropMsg, sizeof (HBM_CLIENT_PROP_MSG));
+ ZeroMem (&PropMsgReply, sizeof (HBM_CLIENT_PROP_MSG_REPLY));
+
+ for (EnumIdx = 0; EnumIdx <= 255; EnumIdx++) {
+ ZeroMem (&PropMsg, sizeof (HBM_CLIENT_PROP_MSG));
+ ZeroMem (&PropMsgReply, sizeof (HBM_CLIENT_PROP_MSG_REPLY));
+
+ PropMsg.Cmd = HBM_CMD_CLIENT_PROP;
+ PropMsg.Address = (UINT8) EnumIdx;
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &PropMsg,
+ sizeof (HBM_CLIENT_PROP_MSG),
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HBM_MSG_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to send HBM_CLIENT_PROP_MSG.\n"));
+ return Status;
+ }
+
+ MsgReplyLen = sizeof (HBM_CLIENT_PROP_MSG_REPLY);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &PropMsgReply,
+ &MsgReplyLen
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ if (PropMsgReply.Status != 0) {
+ continue;
+ }
+ if (!CompareMem (&FwuClientGuid, &PropMsgReply.ProtocolName, sizeof (OEM_UUID))) {
+ DEBUG ((EFI_D_ERROR, "####Match:%d - Guid:%08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x.\n", \
+ EnumIdx, \
+ PropMsgReply.ProtocolName.Data1, \
+ PropMsgReply.ProtocolName.Data2, \
+ PropMsgReply.ProtocolName.Data3, \
+ PropMsgReply.ProtocolName.Data4[0], \
+ PropMsgReply.ProtocolName.Data4[1], \
+ PropMsgReply.ProtocolName.Data4[2], \
+ PropMsgReply.ProtocolName.Data4[3], \
+ PropMsgReply.ProtocolName.Data4[4], \
+ PropMsgReply.ProtocolName.Data4[5], \
+ PropMsgReply.ProtocolName.Data4[6], \
+ PropMsgReply.ProtocolName.Data4[7] \
+ ));
+ *SecAddress = PropMsgReply.Address;
+ *MaxBufferSize = PropMsgReply.MaxMessageLength;
+ break;
+ }
+ } //end for.
+
+ if (*SecAddress == 0) {
+ DEBUG ((EFI_D_ERROR, "Failed to retrieve SEC address for FWU.\n"));
+ return EFI_ABORTED;
+ } else {
+ DEBUG ((EFI_D_INFO, "####Connection property#####\n"));
+ DEBUG ((EFI_D_INFO, "Address:%d, Protcol Ver:%d, MaxConnections:%d, FixedAddress:%d, SglRcvBuf:%d, MTU:%d.\n", \
+ PropMsgReply.Address, PropMsgReply.ProtocolVersion, PropMsgReply.MaximumConnections, \
+ PropMsgReply.FixedAddress, PropMsgReply.SingleRecvBuffer, PropMsgReply.MaxMessageLength));
+
+ }
+
+ //
+ // Now try to connect to the FWU update interace.
+ //
+ ZeroMem (&ConnectMsg, sizeof (HBM_CONNECT_MSG));
+ ZeroMem (&ConnectMsgReply, sizeof (HBM_CONNECT_MSG_REPLY));
+
+ ConnectMsg.Cmd = HBM_CMD_CONNECT;
+ ConnectMsg.SecAddress = *SecAddress;
+ ConnectMsg.HostAddress = BIOS_FIXED_HOST_ADDR + 1;
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &ConnectMsg,
+ sizeof (HBM_CONNECT_MSG),
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HBM_MSG_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FwuConnect Send failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ MsgReplyLen = sizeof (HBM_CONNECT_MSG_REPLY);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &ConnectMsgReply,
+ &MsgReplyLen
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FwuConnect Recv failed with status:%d.\n", Status));
+ return Status;
+ }
+
+ if (ConnectMsgReply.CmdReply != HBM_CMD_CONNECT_REPLY) {
+ DEBUG ((EFI_D_ERROR, "####Reply Msg of connect is not HBM_CMD_CONNECT_REPLY.\n"));
+ return EFI_ABORTED;
+ }
+
+ if (ConnectMsgReply.Status == 0 || ConnectMsgReply.Status == 2) { //Connection setup succeed, or already connected.
+ DEBUG ((EFI_D_ERROR, "######CONNECTION SETUP SUCCESSFULLY######: \n"));
+ } else {
+ DEBUG ((EFI_D_ERROR, "####Failed to setup connection. Aborted with Status:%d.\n", Status));
+ return EFI_ABORTED;
+ }
+
+ Status = HeciSecToHostFlowControl ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "HeciConnectFwuInterface ---.\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get firmware version from FWU interface instead of MKHI.
+
+ @param[out] Version Returns the version number of current running SEC FW.
+ @param[in] SecAddress Dynamic sec address for FWU connection.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciSendFwuGetVersionMsg (
+ OUT VERSION *Version,
+ IN UINT8 SecAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ FWU_GET_VERSION_MSG Msg;
+ FWU_GET_VERSION_MSG_REPLY MsgReply;
+ UINT32 ReplyLength = sizeof (FWU_GET_VERSION_MSG_REPLY);
+
+ DEBUG ((EFI_D_INFO, "####HeciSendFwuGetVersion +++\n"));
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = HeciHostToSecFlowControl (SecAddress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "###HeciSendFwuGetVersion: flow control fail.\n"));
+ }
+
+ Msg.MessageType = FWU_GET_VERSION;
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32*)&Msg,
+ sizeof(FWU_GET_VERSION_MSG),
+ BIOS_FIXED_HOST_ADDR + 1,
+ SecAddress
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FwuGetVersion Error: Failed to send FWU_GET_VERSION_MSG.\n"));
+ return Status;
+ }
+
+ ZeroMem (&MsgReply, sizeof (FWU_GET_VERSION_MSG_REPLY));
+
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32*)&MsgReply,
+ &ReplyLength
+ );
+ //
+ // What we get might be a flow control message, or the get version reply. Treat accordingly.
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "HeciSendFwuGetVersionMsg failed with ReadMsg #1, Status is: %d.\n", Status));
+ return EFI_ABORTED;
+ }
+
+ if (ReplyLength == 8) {
+ //
+ // Got a flow control message. proceed to get the FWU version message.
+ //
+ ZeroMem (&MsgReply, sizeof (FWU_GET_VERSION_MSG_REPLY));
+ ReplyLength = sizeof (FWU_GET_VERSION_MSG_REPLY);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgReply,
+ &ReplyLength
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "HeciSendFwuGetVersionMsg failed with ReadMsg #2, Status is: %d.\n", Status));
+ return EFI_ABORTED;
+ } else {
+ if (MsgReply.MessageType == FWU_GET_VERSION_REPLY) {
+ CopyMem (Version, &MsgReply.CodeVersion, sizeof (VERSION));
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((EFI_D_ERROR, "HeciSendFwuGetVersionMsg: the readmsg after flow control does not return fwu version reply.\n"));
+ return EFI_ABORTED;
+ }
+ }
+ } else {
+ //
+ // It's get version reply already. Get the version information and then retrieve the flow control msg from SEC.
+ //
+ if (MsgReply.MessageType == FWU_GET_VERSION_REPLY) {
+ CopyMem (Version, &MsgReply.CodeVersion, sizeof (VERSION));
+ Status = HeciSecToHostFlowControl ();
+ return Status;
+ } else {
+ //
+ // Any exception, we mark this as failed.
+ //
+ return EFI_ABORTED;
+ }
+ } // endif.
+}
+
+
+/**
+ Send Get Firmware SKU Request to Sec.
+
+ @param[in, out] MsgGenGetFwCapsSku Return message for Get Firmware Capability SKU.
+ @param[in, out] MsgGenGetFwCapsSkuAck Return message for Get Firmware Capability SKU ACK.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwCapsSkuMsg (
+ IN OUT GEN_GET_FW_CAPSKU *MsgGenGetFwCapsSku,
+ IN OUT GEN_GET_FW_CAPS_SKU_ACK *MsgGenGetFwCapsSkuAck
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetFwCapsSku->MKHIHeader.Data = 0;
+ MsgGenGetFwCapsSku->MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetFwCapsSku->MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetFwCapsSku->MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetFwCapsSku->Data.RuleId = 0;
+ Length = sizeof (GEN_GET_FW_CAPSKU);
+
+ //
+ // Send Get FW SKU Request to SEC
+ //
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) MsgGenGetFwCapsSku,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_FW_CAPS_SKU_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) MsgGenGetFwCapsSkuAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Send Get Firmware Version Request to Sec.
+
+ @param[in, out] MsgGenGetFwVersionAck Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwVersionMsg (
+ IN OUT GEN_GET_FW_VER_ACK *MsgGenGetFwVersionAck
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ GEN_GET_FW_VER *MsgGenGetFwVersion;
+ GEN_GET_FW_VER GenGetFwVersion;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Allocate MsgGenGetFwVersion data structure
+ //
+ MsgGenGetFwVersion = &GenGetFwVersion;
+ MsgGenGetFwVersion->MKHIHeader.Data = 0;
+ MsgGenGetFwVersion->MKHIHeader.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MsgGenGetFwVersion->MKHIHeader.Fields.Command = GEN_GET_FW_VERSION_CMD;
+ MsgGenGetFwVersion->MKHIHeader.Fields.IsResponse = 0;
+ Length = sizeof (GEN_GET_FW_VER);
+
+ //
+ // Send Get Firmware Version Request to SEC
+ //
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) MsgGenGetFwVersion,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_FW_VER_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) MsgGenGetFwVersionAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Sends a message to Sec to unlock a specified SPI Flash region for writing and receiving a response message.
+ It is recommended that HMRFPO_ENABLE HECI message needs to be sent after all OROMs finish their initialization.
+
+ @param[in] Nonce Nonce received in previous HMRFPO_ENABLE Response Message.
+ @param[out] Result HMRFPO_ENABLE response.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoEnable (
+ IN UINT64 Nonce,
+ OUT UINT8 *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ MKHI_HMRFPO_ENABLE HmrfpoEnableRequest;
+ MKHI_HMRFPO_ENABLE_RESPONSE HmrfpoEnableResponse;
+ UINT32 HeciLength;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HmrfpoEnableRequest.MkhiHeader.Data = 0;
+ HmrfpoEnableRequest.MkhiHeader.Fields.GroupId = MKHI_SPI_GROUP_ID;
+ HmrfpoEnableRequest.MkhiHeader.Fields.Command = HMRFPO_ENABLE_CMD_ID;
+ HmrfpoEnableRequest.MkhiHeader.Fields.IsResponse = 0;
+ HmrfpoEnableRequest.Nonce = Nonce;
+
+ HeciLength = sizeof (MKHI_HMRFPO_ENABLE);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &HmrfpoEnableRequest,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Send HMRFPO_ENABLE_CMD_ID Request - %r\n", Status));
+ return Status;
+ }
+
+ HeciLength = sizeof (MKHI_HMRFPO_ENABLE_RESPONSE);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &HmrfpoEnableResponse,
+ &HeciLength
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Read HMRFPO_ENABLE_CMD_ID Result - %r\n", Status));
+ return Status;
+ }
+
+ *Result = HmrfpoEnableResponse.Status;
+
+ return Status;
+}
+
+
+/**
+ Sends a message to Sec to lock a specified SPI Flash region for writing and receiving a response message.
+
+ @param[out] Nonce Random number generated by Ignition Sec FW. When BIOS.
+ want to unlock region it should use this value.
+ in HMRFPO_ENABLE Request Message.
+ @param[out] FactoryDefaultBase The base of the factory default calculated from the start of the ME region.
+ BIOS sets a Protected Range (PR) register "Protected Range Base" field with this value.
+ + the base address of the region.
+ @param[out] FactoryDefaultLimit The length of the factory image.
+ BIOS sets a Protected Range (PR) register "Protected Range Limit" field with this value.
+ @param[out] Result Status report.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoLock (
+ OUT UINT64 *Nonce,
+ OUT UINT32 *FactoryDefaultBase,
+ OUT UINT32 *FactoryDefaultLimit,
+ OUT UINT8 *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ MKHI_HMRFPO_LOCK HmrfpoLockRequest;
+ MKHI_HMRFPO_LOCK_RESPONSE HmrfpoLockResponse;
+ UINT32 HeciLength;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HmrfpoLockRequest.MkhiHeader.Data = 0;
+ HmrfpoLockRequest.MkhiHeader.Fields.GroupId = MKHI_SPI_GROUP_ID;
+ HmrfpoLockRequest.MkhiHeader.Fields.Command = HMRFPO_LOCK_CMD_ID;
+ HmrfpoLockRequest.MkhiHeader.Fields.IsResponse = 0;
+
+ HeciLength = sizeof (MKHI_HMRFPO_LOCK);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &HmrfpoLockRequest,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Send HMRFPO_LOCK_CMD_ID Request - %r\n", Status));
+ return Status;
+ }
+
+ HeciLength = sizeof (MKHI_HMRFPO_LOCK_RESPONSE);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &HmrfpoLockResponse,
+ &HeciLength
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to read HMRFPO_LOCK_CMD_ID response - %r.\n", Status));
+ return Status;
+ }
+
+ *Nonce = HmrfpoLockResponse.Nonce;
+ *FactoryDefaultBase = HmrfpoLockResponse.FactoryDefaultBase;
+ *FactoryDefaultLimit = HmrfpoLockResponse.FactoryDefaultLimit;
+ *Result = HmrfpoLockResponse.Status;
+
+ return Status;
+}
+
+
+/**
+ System BIOS sends this message to get status for HMRFPO_LOCK message.
+
+ @param[out] Result HMRFPO_GET_STATUS response.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+
+**/
+EFI_STATUS
+HeciHmrfpoGetStatus (
+ OUT UINT8 *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ MKHI_HMRFPO_GET_STATUS HmrfpoGetStatusRequest;
+ MKHI_HMRFPO_GET_STATUS_RESPONSE HmrfpoGetStatusResponse;
+ UINT32 HeciLength;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HmrfpoGetStatusRequest.MkhiHeader.Data = 0;
+ HmrfpoGetStatusRequest.MkhiHeader.Fields.GroupId = MKHI_SPI_GROUP_ID;
+ HmrfpoGetStatusRequest.MkhiHeader.Fields.Command = HMRFPO_GET_STATUS_CMD_ID;
+ HmrfpoGetStatusRequest.MkhiHeader.Fields.IsResponse = 0;
+
+ HeciLength = sizeof (MKHI_HMRFPO_GET_STATUS);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &HmrfpoGetStatusRequest,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Send HMRFPO_GET_STATUS_CMD_ID - %r\n", Status));
+ return Status;
+ }
+
+ HeciLength = sizeof (MKHI_HMRFPO_GET_STATUS_RESPONSE);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &HmrfpoGetStatusResponse,
+ &HeciLength
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Read HMRFPO_GET_STATUS_CMD_ID Result - %r\n", Status));
+ }
+ *Result = HmrfpoGetStatusResponse.Status;
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to query the local firmware update interface status.
+
+ @param[out] RuleData 1 - local firmware update interface enable.
+ 0 - local firmware update interface disable.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetLocalFwUpdate (
+ OUT UINT32 *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_GET_LOCAL_FW_UPDATE MsgGenGetLocalFwUpdate;
+ GEN_GET_LOCAL_FW_UPDATE_ACK MsgGenGetLocalFwUpdatekuAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetLocalFwUpdate.MKHIHeader.Data = 0;
+ MsgGenGetLocalFwUpdate.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetLocalFwUpdate.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetLocalFwUpdate.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetLocalFwUpdate.Data.RuleId = 7;
+ Length = sizeof (GEN_GET_LOCAL_FW_UPDATE);
+
+ //
+ // Send Get Local FW update Request to SEC
+ //
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetLocalFwUpdate,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_LOCAL_FW_UPDATE_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgGenGetLocalFwUpdatekuAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *RuleData = MsgGenGetLocalFwUpdatekuAck.Data.RuleData;
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to enable or disable the local firmware update interface.
+ The firmware allows a single update once it receives the enable command.
+
+ @param[in] RuleData 1 - local firmware update interface enable
+ 0 - local firmware update interface disable
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciSetLocalFwUpdate (
+ IN UINT8 RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_SET_LOCAL_FW_UPDATE MsgGenSetLocalFwUpdate;
+ GEN_SET_LOCAL_FW_UPDATE_ACK MsgGenSetLocalFwUpdateAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenSetLocalFwUpdate.MKHIHeader.Data = 0;
+ MsgGenSetLocalFwUpdate.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenSetLocalFwUpdate.MKHIHeader.Fields.Command = FWCAPS_SET_RULE_CMD;
+ MsgGenSetLocalFwUpdate.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenSetLocalFwUpdate.Data.RuleId = 7;
+ MsgGenSetLocalFwUpdate.Data.RuleDataLen = 4;
+ MsgGenSetLocalFwUpdate.Data.RuleData = RuleData;
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE);
+
+ //
+ // Send Get Local FW update Request to SEC
+ //
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenSetLocalFwUpdate,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgGenSetLocalFwUpdateAck,
+ &Length
+ );
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to enable the Sec State. The firmware allows a single
+ update once it receives the enable command. Once firmware receives this message,
+ the firmware will be in normal mode after a global reset.
+
+ @param[in] None
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS ME enabled message sent.
+
+**/
+EFI_STATUS
+HeciSetSeCEnableMsg (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ HECI_FWS_REGISTER SeCFirmwareStatus;
+ UINTN HeciPciAddressBase;
+ UINT16 TimeOut;
+
+ TimeOut = 0;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HeciPciAddressBase = PCI_LIB_ADDRESS (
+ SEC_BUS,
+ SEC_DEVICE_NUMBER,
+ HECI_FUNCTION_NUMBER,
+ 0
+ );
+ PciWrite8 (HeciPciAddressBase + R_GEN_STS + 3, 0x20);
+ do {
+ SeCFirmwareStatus.ul = PciRead32 (HeciPciAddressBase + R_SEC_FW_STS0);
+ gBS->Stall (EFI_SEC_STATE_STALL_1_SECOND);
+ TimeOut++;
+ } while ((SeCFirmwareStatus.r.FwInitComplete != SEC_FIRMWARE_COMPLETED) && (TimeOut > EFI_SEC_STATE_MAX_TIMEOUT));
+
+
+ Status = HeciSetSeCDisableMsg (1);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "HeciSetSeCDisableMsg Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Send Global reset
+ //
+ HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET);
+ CpuDeadLoop ();
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to disable the Sec State. The firmware allows a single
+ update once it receives the disable command Once firmware receives this message,
+ the firmware will work in "Soft Temporary Disable" mode (HFS[19:16] = 3) after a
+ global reset. Note, this message is not allowed when AT firmware is enrolled/configured.
+
+ @param[in] RuleData Rule data
+ 0 - Disable
+ 1 - Enable
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function
+ @retval EFI_SUCCESS Sec is disabled
+
+**/
+EFI_STATUS
+HeciSetSeCDisableMsg (
+ IN UINT8 ruleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_SET_FW_CAPSKU MsgSeCStateControl;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode(HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgSeCStateControl.MKHIHeader.Data = 0;
+ MsgSeCStateControl.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgSeCStateControl.MKHIHeader.Fields.Command = FWCAPS_SET_RULE_CMD;
+ MsgSeCStateControl.MKHIHeader.Fields.IsResponse = 0;
+ MsgSeCStateControl.Data.RuleId.Data = 6;
+ MsgSeCStateControl.Data.RuleDataLen = 4;
+ MsgSeCStateControl.Data.RuleData = ruleData;
+
+ Length = sizeof (GEN_SET_FW_CAPSKU);
+
+ Status = Heci->SendwACK (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgSeCStateControl,
+ Length,
+ &Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET);
+ CpuDeadLoop ();
+
+ return Status;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ Consumer or Corporate SKU size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetPlatformTypeMsg (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_GET_PLATFORM_TYPE MsgGenGetPlatformType;
+ GEN_GET_PLATFORM_TYPE_ACK MsgGenGetPlatformTypeAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetPlatformType.MKHIHeader.Data = 0;
+ MsgGenGetPlatformType.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetPlatformType.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetPlatformType.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetPlatformType.Data.RuleId = 0x1D;
+ Length = sizeof (GEN_GET_PLATFORM_TYPE);
+
+ //
+ // Send Get Platform Type Request to SEC
+ //
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetPlatformType,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_PLATFORM_TYPE_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgGenGetPlatformTypeAck,
+ &Length
+ );
+
+ *RuleData = MsgGenGetPlatformTypeAck.Data.RuleData;
+
+ return Status;
+}
+
+
+/**
+ The firmware will respond to GET OEM TAG message even after the End of Post (EOP).
+
+ @param[out] RuleData Default is zero. Tool can create the OEM specific OEM TAG data.
+
+ @retval EFI_UNSUPPORTED Current Sec mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetOemTagMsg (
+ OUT UINT32 *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_GET_OEM_TAG_MSG MsgGenGetOemTagMsg;
+ GEN_GET_OEM_TAG_MSG_ACK MsgGenGetOemTagMsgAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode(HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenGetOemTagMsg.MKHIHeader.Data = 0;
+ MsgGenGetOemTagMsg.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenGetOemTagMsg.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenGetOemTagMsg.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenGetOemTagMsg.Data.RuleId = 0x2B;
+ Length = sizeof (GEN_GET_OEM_TAG_MSG);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgGenGetOemTagMsg,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_OEM_TAG_MSG_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgGenGetOemTagMsgAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *RuleData = MsgGenGetOemTagMsgAck.RuleData;
+
+ return Status;
+}
+
+EFI_STATUS
+HeciGetFwFeatureStateMsg (
+ OUT SECFWCAPS_SKU *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ GEN_GET_FW_FEATURE_STATUS GetFwFeatureStatus;
+ GEN_GET_FW_FEATURE_STATUS_ACK GetFwFeatureStatusAck;
+ UINT32 SeCMode;
+ EFI_HECI_PROTOCOL *Heci;
+
+ DEBUG ((EFI_D_INFO, "HeciGetFwFeatureStateMsg ++\n"));
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode(HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ GetFwFeatureStatus.MKHIHeader.Data = 0;
+ GetFwFeatureStatus.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ GetFwFeatureStatus.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ GetFwFeatureStatus.MKHIHeader.Fields.IsResponse = 0;
+ GetFwFeatureStatus.Data.RuleId = 0x20;
+
+ Length = sizeof (GEN_GET_FW_FEATURE_STATUS);
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &GetFwFeatureStatus,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_FW_FEATURE_STATUS_ACK);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &GetFwFeatureStatusAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RuleData->Data = GetFwFeatureStatusAck.RuleData.Data;
+ DEBUG ((EFI_D_INFO, "HeciGetFwFeatureStateMsg --\n"));
+
+ return Status;
+}
+
+
+EFI_STATUS
+HeciSeCUnconfigurationMsg (
+ OUT UINT32 *CmdStatus
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ MKHI_MESSAGE_HEADER MsgSeCUnConfigure;
+ MKHI_MESSAGE_HEADER MsgSeCUnConfigureAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode (HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgSeCUnConfigure.Data = 0;
+ MsgSeCUnConfigure.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MsgSeCUnConfigure.Fields.Command = SEC_UNCONFIGURATION_CMD;
+ MsgSeCUnConfigure.Fields.IsResponse = 0;
+
+ Length = sizeof (MKHI_MESSAGE_HEADER);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgSeCUnConfigure,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (MKHI_MESSAGE_HEADER);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgSeCUnConfigureAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *CmdStatus = MsgSeCUnConfigureAck.Fields.Reserved;
+ return Status;
+
+}
+
+
+EFI_STATUS
+HeciSeCUnconfigurationStatusMsg (
+ IN UINT32 *CmdStatus
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ MKHI_MESSAGE_HEADER MsgSeCUnConfigureStatus;
+ MKHI_MESSAGE_HEADER MsgSeCUnConfigureStatusAck;
+ UINT32 SeCMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetSeCMode(HECI1_DEVICE, &SeCMode);
+ if (EFI_ERROR (Status) || (SeCMode != SEC_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgSeCUnConfigureStatus.Data = 0;
+ MsgSeCUnConfigureStatus.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ MsgSeCUnConfigureStatus.Fields.Command = SEC_UNCONFIGURATION_STATUS;
+ MsgSeCUnConfigureStatus.Fields.IsResponse = 0;
+
+ Length = sizeof (MKHI_MESSAGE_HEADER);
+
+ Status = Heci->SendMsg (
+ HECI1_DEVICE,
+ (UINT32 *) &MsgSeCUnConfigureStatus,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (MKHI_MESSAGE_HEADER);
+ Status = Heci->ReadMsg (
+ HECI1_DEVICE,
+ BLOCKING,
+ (UINT32 *) &MsgSeCUnConfigureStatusAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *CmdStatus = MsgSeCUnConfigureStatusAck.Fields.Result;
+ return Status;
+}
+
+
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c
new file mode 100644
index 0000000000..1ef9c28cd7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c
@@ -0,0 +1,260 @@
+/** @file
+ Implementation file for SeC functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <MkhiMsgs.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Check if SeC is enabled
+
+ @param[in] VOID Parameter is VOID
+
+ @retval EFI_SUCCESS Command succeeded
+
+**/
+EFI_STATUS
+SeCLibInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ return Status;
+}
+
+
+/**
+ Send Get Firmware SKU Request to SEC.
+
+ @param[in] FwCapsSku Return Data from Get Firmware Capabilities MKHI Request.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwCapsSku (
+ IN SECFWCAPS_SKU *FwCapsSku
+ )
+{
+ EFI_STATUS Status;
+ GEN_GET_FW_CAPSKU MsgGenGetFwCapsSku;
+ GEN_GET_FW_CAPS_SKU_ACK MsgGenGetFwCapsSkuAck;
+
+ Status = HeciGetFwCapsSkuMsg (&MsgGenGetFwCapsSku, &MsgGenGetFwCapsSkuAck);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (((MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) &&
+ ((MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.IsResponse) == 1) &&
+ (MsgGenGetFwCapsSkuAck.MKHIHeader.Fields.Result == 0)) {
+ *FwCapsSku = MsgGenGetFwCapsSkuAck.Data.FWCapSku;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get Ibex Peak platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ 4M or 8M size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelSeCFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetPlatformType (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+{
+ EFI_STATUS Status;
+
+ Status = HeciGetPlatformTypeMsg (RuleData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Send Get Firmware Version Request to SEC.
+
+ @param[in, out] MsgGenGetFwVersionAckData Return themessage of FW version.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+HeciGetFwVersion (
+ IN OUT GEN_GET_FW_VER_ACK_DATA *MsgGenGetFwVersionAckData
+ )
+{
+ EFI_STATUS Status;
+ GEN_GET_FW_VER_ACK MsgGenGetFwVersionAck;
+
+ Status = HeciGetFwVersionMsg (&MsgGenGetFwVersionAck);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((MsgGenGetFwVersionAck.MKHIHeader.Fields.Command == GEN_GET_FW_VERSION_CMD) &&
+ (MsgGenGetFwVersionAck.MKHIHeader.Fields.IsResponse == 1) &&
+ (MsgGenGetFwVersionAck.MKHIHeader.Fields.Result == 0)) {
+ *MsgGenGetFwVersionAckData = MsgGenGetFwVersionAck.Data;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Host client gets Firmware update info from SEC client.
+
+ @param[in, out] SECCapability Structure of FirmwareUpdateInfo.
+
+ @retval EFI_SUCCESS Command succeeded.
+
+**/
+EFI_STATUS
+HeciGetSeCFwInfo (
+ IN OUT SEC_CAP *SECCapability
+ )
+{
+ EFI_STATUS Status;
+ DXE_SEC_POLICY_PROTOCOL *mDxePlatformSeCPolicy;
+ SECFWCAPS_SKU FwCapsSku;
+
+ //
+ // Get the SEC platform policy.
+ //
+ Status = gBS->LocateProtocol (&gDxePlatformSeCPolicyGuid, NULL, (VOID **) &mDxePlatformSeCPolicy);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "No SEC Platform Policy Protocol available"));
+ return EFI_UNSUPPORTED;
+ }
+
+ SECCapability->SeCEnabled = 1;
+
+ FwCapsSku.Data = mDxePlatformSeCPolicy->SeCConfig.FwCapsSku;
+ if (FwCapsSku.Fields.IntelAT) {
+ SECCapability->AtSupported = 1;
+ }
+
+ if (FwCapsSku.Fields.KVM) {
+ }
+
+ if (mDxePlatformSeCPolicy->SeCConfig.PlatformBrand == INTEL_AMT_BRAND) {
+ }
+
+ if (mDxePlatformSeCPolicy->SeCConfig.PlatformBrand == INTEL_STAND_MANAGEABILITY_BRAND) {
+ }
+
+ SECCapability->SeCMinorVer = mDxePlatformSeCPolicy->SeCVersion.CodeMinor;
+ SECCapability->SeCMajorVer = mDxePlatformSeCPolicy->SeCVersion.CodeMajor;
+ SECCapability->SeCBuildNo = mDxePlatformSeCPolicy->SeCVersion.CodeBuildNo;
+ SECCapability->SeCHotFixNo = mDxePlatformSeCPolicy->SeCVersion.CodeHotFix;
+
+ return Status;
+}
+
+
+/**
+ Dummy return for SeC signal event use.
+
+ @param[in] Event The event that triggered this notification function.
+ @param[in] ParentImageHandle Pointer to the notification functions context.
+
+ @retval EFI_SUCCESS Always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+SeCEmptyEvent (
+ IN EFI_EVENT Event,
+ IN void *ParentImageHandle
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get AT State Information From Stored SEC platform policy.
+
+ @param[in, out] AtState Pointer to AT State Information.
+ @param[in, out] AtLastTheftTrigger Pointer to Variable holding the cause of last AT Stolen Stae.
+ @param[in, out] AtLockState Pointer to variable indicating whether AT is locked or not.
+ @param[in, out] AtAmPref Pointer to variable indicating whether TDTAM or PBA should be used.
+
+ @retval EFI_UNSUPPORTED Current SEC mode doesn't support this function.
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally.
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout.
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge.
+
+**/
+EFI_STATUS
+GetAtStateInfo (
+ IN OUT UINT8 *AtState,
+ IN OUT UINT8 *AtLastTheftTrigger,
+ IN OUT UINT16 *AtLockState,
+ IN OUT UINT16 *AtAmPref
+ )
+{
+ EFI_STATUS Status;
+ DXE_SEC_POLICY_PROTOCOL *mDxePlatformSeCPolicy;
+
+ //
+ // Get the SEC platform policy.
+ //
+ Status = gBS->LocateProtocol (&gDxePlatformSeCPolicyGuid, NULL, (VOID **) &mDxePlatformSeCPolicy);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "No SEC Platform Policy Protocol available"));
+ return EFI_UNSUPPORTED;
+ }
+
+ *AtState = mDxePlatformSeCPolicy->AtConfig.AtState;
+ *AtLastTheftTrigger = mDxePlatformSeCPolicy->AtConfig.AtLastTheftTrigger;
+ *AtLockState = mDxePlatformSeCPolicy->AtConfig.AtLockState;
+ *AtAmPref = mDxePlatformSeCPolicy->AtConfig.AtAmPref;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf
new file mode 100644
index 0000000000..8841e1af55
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf
@@ -0,0 +1,45 @@
+## @file
+# SeC dxe library.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SeCLib
+ FILE_GUID = CDEE83DA-5B0D-47fa-9420-D75E96F943B6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SeCLib
+
+[Sources]
+ SeCLib.c
+ SeCPolicyLib.c
+ HeciMsgLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiBootServicesTableLib
+ DebugLib
+ PerformanceLib
+ PciLib
+ BaseLib
+
+[Protocols]
+ gDxePlatformSeCPolicyGuid ## CONSUMES
+ gScResetProtocolGuid ## CONSUMES
+ gEfiHeciProtocolGuid
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c
new file mode 100644
index 0000000000..69b4053796
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c
@@ -0,0 +1,190 @@
+/** @file
+ Implementation file for SeC Policy functionality.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/SeCPolicyLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Heci.h>
+#include <SeCAccess.h>
+
+//
+// Global variables
+//
+DXE_SEC_POLICY_PROTOCOL *mDxePlatformSeCPolicy;
+
+/**
+ Check if SeC is enabled.
+
+ @param[in] None
+
+ @retval None
+
+**/
+EFI_STATUS
+SeCPolicyLibInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Get the desired platform setup policy.
+ //
+ Status = gBS->LocateProtocol (&gDxePlatformSeCPolicyGuid, NULL, (VOID **) &mDxePlatformSeCPolicy);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "No SEC Platform Policy Protocol available"));
+ }
+
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Check if HECI Communication is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE HECI is disabled.
+ @retval TRUE HECI is enabled.
+
+**/
+BOOLEAN
+SeCHECIEnabled (
+ VOID
+ )
+{
+ BOOLEAN Supported;
+
+ if (mDxePlatformSeCPolicy->SeCConfig.HeciCommunication != 1) {
+ Supported = FALSE;
+ } else {
+ Supported = TRUE;
+ }
+ return Supported;
+}
+
+
+/**
+ Check if End of Post Message is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID
+
+ @retval FALSE EndOfPost is disabled.
+ @retval TRUE EndOfPost is enabled.
+
+**/
+BOOLEAN
+SeCEndOfPostEnabled (
+ VOID
+ )
+{
+ BOOLEAN Supported;
+
+ if (mDxePlatformSeCPolicy->SeCConfig.EndOfPostEnabled != 1) {
+ Supported = FALSE;
+ } else {
+ Supported = TRUE;
+ }
+
+ return Supported;
+}
+
+
+/**
+ Check if Thermal Reporting Message is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID.
+
+ @retval FALSE Thermal Reporting is disabled.
+ @retval TRUE Thermal Reporting is enabled.
+
+**/
+BOOLEAN
+SeCTrEnabled (
+ VOID
+ )
+{
+ if (mDxePlatformSeCPolicy->SeCConfig.TrConfig->TrEnabled == 1) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Show SeC Error message.
+
+ @param[in] MsgId SeC error message ID.
+
+ @retval None.
+
+**/
+VOID
+SeCReportError (
+ IN SEC_ERROR_MSG_ID MsgId
+ )
+{
+ if (mDxePlatformSeCPolicy->Revision >= DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_3) {
+ mDxePlatformSeCPolicy->SeCReportError (MsgId);
+ }
+
+ return ;
+}
+
+
+/**
+ Check if SeCFwDowngrade is enabled in setup options.
+
+ @param[in] None
+
+ @retval FALSE SeCFwDowngrade is disabled.
+ @retval TRUE SeCFwDowngrade is enabled.
+
+**/
+BOOLEAN
+SeCFwDowngradeSupported (
+ VOID
+ )
+{
+ if (mDxePlatformSeCPolicy->Revision >= DXE_PLATFORM_SEC_POLICY_PROTOCOL_REVISION_7) {
+ if (mDxePlatformSeCPolicy->SeCConfig.SeCFwDownGrade == 1) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Check if integarted touch is enabled in setup options.
+
+ @param[in] VOID Parameter is VOID.
+
+ @retval FALSE itouch is disabled.
+ @retval TRUE itouch is enabled.
+
+**/
+BOOLEAN
+SeCITouchEnabled (
+ VOID
+ )
+{
+ return mDxePlatformSeCPolicy->SeCConfig.ITouchEnabled;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.c
new file mode 100644
index 0000000000..4bf66dc78c
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.c
@@ -0,0 +1,57 @@
+/** @file
+ Implementation file for the HECI2 Power Management library.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/Heci2Pm.h>
+
+EFI_HECI2_PM_PROTOCOL *mHeci2PmProtocol = NULL;
+
+/**
+ Returns an instance of the HECI2 Power Management protocol.
+
+ @params[out] Heci2PmProtocol The address to a pointer to the HECI2 PM protocol.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+GetHeci2PmProtocol (
+ OUT EFI_HECI2_PM_PROTOCOL **Heci2PmProtocol
+ )
+{
+ EFI_STATUS Status;
+
+ if (mHeci2PmProtocol == NULL) {
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiHeci2PmProtocolGuid,
+ NULL,
+ &mHeci2PmProtocol
+ );
+
+ if (EFI_ERROR (Status)) {
+ mHeci2PmProtocol = NULL;
+ return Status;
+ }
+ }
+
+ *Heci2PmProtocol = mHeci2PmProtocol;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.inf
new file mode 100644
index 0000000000..c180a93d7a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.inf
@@ -0,0 +1,37 @@
+## @file
+# HECI 2 SMM Power Management Library.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmHeci2PowerManagementLib
+ FILE_GUID = CD37C23A-AF81-4E33-BD80-71ED07DCE2BE
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Heci2PowerManagementLib
+
+[Sources]
+ SmmHeci2PowerManagementLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ SmmServicesTableLib
+
+[Protocols]
+ gEfiHeci2PmProtocolGuid ## CONSUMES
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c
new file mode 100644
index 0000000000..d2d3da37cb
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c
@@ -0,0 +1,91 @@
+/** @file
+ Implementation file for Heci Message functionality.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HeciMsgLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+UINT8 *mNonSmmData = NULL;
+
+/**
+ Set Read Write Temp memory.
+
+ @param[in] Address Temp memory.
+
+**/
+VOID
+HeciSetReadWriteCache (
+ VOID* Address
+ );
+
+/**
+ SmmEndOfDxeCallback
+
+ @param[in] Protocol
+ @param[in] Interface
+ @param[in] Handle
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+HeciMsgLibSmmEndOfDxeNotification (
+ IN CONST EFI_GUID *Protocol,
+ IN VOID *Interface,
+ IN EFI_HANDLE Handle
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+HeciMsgLibSmmConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ VOID *SmmEndOfDxeRegistration;
+
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (SIZE_64KB),
+ (EFI_PHYSICAL_ADDRESS *) (UINTN) &mNonSmmData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (mNonSmmData == NULL) {
+ ASSERT (mNonSmmData != NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ HeciSetReadWriteCache (mNonSmmData);
+
+ Status = gSmst->SmmRegisterProtocolNotify (
+ &gEfiSmmEndOfDxeProtocolGuid,
+ HeciMsgLibSmmEndOfDxeNotification,
+ &SmmEndOfDxeRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf
new file mode 100644
index 0000000000..bd2f662dd6
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Implementation for Heci Message functionality Module.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmHeciMsgLib
+ FILE_GUID = D4346F95-3498-461D-A6F6-5D45501B4EC6
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ LIBRARY_CLASS = SmmHeciMsgLib
+ CONSTRUCTOR = HeciMsgLibSmmConstructor
+
+[Sources]
+ SmmHeciMsgLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Protocols]
+ gEfiSmmEndOfDxeProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HeciMsgLib
+ UefiBootServicesTableLib