From 387310c8dca74b9b92719242c35b08f36dc7336e Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 13:00:19 +0800 Subject: BroxtonSiPkg: Add Txe/Include/ and Txe/Library Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../BroxtonSiPkg/Txe/Include/CoreBiosMsg.h | 552 ++++++ .../BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h | 382 ++++ .../Txe/Include/Library/Heci2PowerManagementLib.h | 36 + .../BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h | 2016 ++++++++++++++++++++ .../BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h | 126 ++ .../Txe/Include/Library/SeCChipsetLib.h | 47 + .../BroxtonSiPkg/Txe/Include/Library/SeCLib.h | 145 ++ .../Txe/Include/Library/SeCPolicyLib.h | 118 ++ .../BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h | 793 ++++++++ .../BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h | 42 + .../BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h | 90 + .../Txe/Include/Private/Library/HeciInitLib.h | 330 ++++ .../BroxtonSiPkg/Txe/Include/Protocol/Heci.h | 111 ++ .../BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h | 67 + .../Txe/Include/Protocol/IntegratedTouchHid.h | 74 + .../Txe/Include/Protocol/SeCPlatformPolicy.h | 134 ++ .../BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h | 56 + .../BroxtonSiPkg/Txe/Include/PttPtpRegs.h | 118 ++ .../BroxtonSiPkg/Txe/Include/SeCAccess.h | 307 +++ .../BroxtonSiPkg/Txe/Include/SeCChipset.h | 138 ++ .../BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h | 64 + .../BaseHeci2PowerManagementNullLib.c | 38 + .../BaseHeci2PowerManagementNullLib.inf | 32 + .../Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c | 860 +++++++++ .../Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf | 44 + .../Txe/Library/HeciMsgLib/HeciMsgLib.c | 1800 +++++++++++++++++ .../Txe/Library/HeciMsgLib/PeiHeciMsgLib.c | 204 ++ .../Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf | 42 + .../Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c | 500 +++++ .../Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf | 41 + .../PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c | 98 + .../PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf | 38 + .../Txe/Library/PeiSecLib/HeciMsgLib.c | 258 +++ .../Txe/Library/PeiSecLib/PeiSeCLib.inf | 40 + .../BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c | 180 ++ .../Txe/Library/PeiSecLib/SeCPolicyLib.c | 142 ++ .../Library/Private/PeiDxeHeciInitLib/HeciCore.c | 1964 +++++++++++++++++++ .../Library/Private/PeiDxeHeciInitLib/HeciCore.h | 109 ++ .../Library/Private/PeiDxeHeciInitLib/HeciHpet.c | 202 ++ .../Library/Private/PeiDxeHeciInitLib/HeciHpet.h | 99 + .../PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf | 53 + .../Txe/Library/Private/PeiSeCUma/SeCUma.c | 578 ++++++ .../Txe/Library/Private/PeiSeCUma/SeCUma.h | 134 ++ .../Txe/Library/Private/PeiSeCUma/SeCUma.inf | 63 + .../BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c | 1626 ++++++++++++++++ .../BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c | 260 +++ .../BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf | 45 + .../BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c | 190 ++ .../SmmHeci2PowerManagementLib.c | 57 + .../SmmHeci2PowerManagementLib.inf | 37 + .../Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c | 91 + .../Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf | 40 + 52 files changed, 15611 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/CoreBiosMsg.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/HeciRegs.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/Heci2PowerManagementLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/HeciMsgLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/PttPtpLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCChipsetLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Library/SeCPolicyLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/MkhiMsgs.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/HeciPpi.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Ppi/SeCUma.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Private/Library/HeciInitLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/Heci2Pm.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/IntegratedTouchHid.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCPlatformPolicy.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/Protocol/SeCRcInfo.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/PttPtpRegs.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCAccess.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCChipset.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Include/SeCState.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/BaseHeci2PowerManagementNullLib/BaseHeci2PowerManagementNullLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/DxeSmmHeciMsgLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/HeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/HeciMsgLib/PeiHeciMsgLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxePttPtpLib/PeiDxePttPtpLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiDxeSeCChipsetLib/PeiDxeSeCChipsetLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/HeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/PeiSeCLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/PeiSecLib/SeCPolicyLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciCore.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/HeciHpet.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiDxeHeciInitLib/PeiDxeHeciInitLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/Private/PeiSeCUma/SeCUma.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/HeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SeCLib/SeCPolicyLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeci2PowerManagementLib/SmmHeci2PowerManagementLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Txe/Library/SmmHeciMsgLib/SmmHeciMsgLib.inf (limited to 'Silicon') 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 + +#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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 + +/** + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include + +/// +/// 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]; /// + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include +#include +#include +#include + +/// +/// 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 + +/** + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include + +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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include + +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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include + +// +// 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__" in register/bit names. e.g., "_ME_VLV_" + Registers / bits that are different between SKUs are denoted by "_" + 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 inserted. + + Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_CHIPSET_H_ +#define _SEC_CHIPSET_H_ + +#include + +#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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +/** + 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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; ///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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +/** + 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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include "PttPtpRegs.h" +#include + +#ifndef TPM_BASE +#define TPM_BASE 0 +#endif + +#include + +#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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/** + 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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + 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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include + +/** + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +/** + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include +#include +#include +#include + +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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include +#include +#include + +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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef FSP_FLAG +#include +#include +#include +#endif + +#include +#include + +#ifdef FSP_FLAG +#include +#include +#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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlatformBaseAddresses.h" +#include + +#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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include + +/** + 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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +// +// 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +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.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# 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 -- cgit v1.2.3