summaryrefslogtreecommitdiff
path: root/ReferenceCode/ME/Library/MeKernel/Dxe
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/ME/Library/MeKernel/Dxe')
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.c2702
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.h782
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MbpDebugDumpDxe.c150
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.c712
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.h203
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.inf68
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.cif18
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.mak60
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.sdl36
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyDebugDumpDxe.c72
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.c182
-rw-r--r--ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.h95
12 files changed, 5080 insertions, 0 deletions
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.c b/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.c
new file mode 100644
index 0000000..fd83e9b
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.c
@@ -0,0 +1,2702 @@
+/** @file
+ Implementation file for Heci Message functionality
+
+@copyright
+ Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "HeciMsgLib.h"
+#include "MeAccess.h"
+#include "HeciRegs.h"
+#include "CoreBiosMsg.h"
+#include EFI_PROTOCOL_CONSUMER (Wdt)
+#include EFI_PROTOCOL_CONSUMER (PchReset)
+#endif
+
+BOOLEAN
+IsAfterEndOfPost (
+ VOID
+ );
+
+//
+// Internal function for HeciMsgLib used only
+//
+
+/**
+ Convert EFI Status Code severity to Mdes severity.
+
+ @param[in] statusToConv EFI Status Code severity.
+
+ @retval UINT16 Mdes severity.
+**/
+STATIC
+UINT16
+BiosToMdesSeverity (
+ IN EFI_STATUS statusToConv
+ )
+{
+ UINT16 MdesSev;
+
+ MdesSev = SEV_NO_ERROR;
+ switch (statusToConv & EFI_STATUS_CODE_SEVERITY_MASK) {
+ case (EFI_ERROR_MINOR):
+ MdesSev = SEV_LOW_ERROR;
+ break;
+
+ case (EFI_ERROR_MAJOR):
+ MdesSev = SEV_HIGH_ERROR;
+ break;
+
+ case (EFI_ERROR_UNRECOVERED):
+ MdesSev = SEV_CRITICAL_ERROR;
+ break;
+
+ case (EFI_ERROR_UNCONTAINED):
+ MdesSev = SEV_CRITICAL_ERROR;
+ break;
+ }
+
+ return MdesSev;
+}
+
+//
+// Interface functions of HeciMsgLib
+//
+
+/**
+ Send the required system ChipsetInit Table to ME FW.
+
+ @param[in] ChipsetInitTable The required system ChipsetInit Table.
+ @param[in] ChipsetInitTableLen Length of the table in bytes
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciChipsetInitSyncMsg (
+ IN UINT8 *ChipsetInitTable,
+ IN UINT32 ChipsetInitTableLen
+ )
+{
+ EFI_HECI_PROTOCOL *Heci;
+ EFI_STATUS Status;
+ UINT32 ReqSize;
+ PCH_RESET_PROTOCOL *PchResetProtocol;
+ EFI_GUID PchResetProtocolGuid = PCH_RESET_PROTOCOL_GUID;
+ MPHY_WRITE_SETTINGS_REQ *MPhyWriteSettingsReqPtr;
+
+ DEBUG ((EFI_D_ERROR, "HeciChipsetInitSyncMsg(0x%08X, %d): Start\n", ChipsetInitTable, ChipsetInitTableLen));
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8130);
+ ASSERT(ChipsetInitTableLen <= 1024); // ChipsetInit table should not get too large
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "EfiHeciProtocol not found.\n"));
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (
+ &PchResetProtocolGuid,
+ NULL,
+ (VOID **) &PchResetProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "PchResetProtocol not found.\n"));
+ return Status;
+ }
+
+ //
+ // Allocate a buffer for the Request Structure and the ChipsetInit Table
+ //
+ ReqSize = sizeof (MPHY_WRITE_SETTINGS_REQ) + ChipsetInitTableLen;
+ MPhyWriteSettingsReqPtr = AllocateZeroPool (ReqSize);
+ if (MPhyWriteSettingsReqPtr == NULL) {
+ DEBUG ((EFI_D_ERROR, "(MPHY) HeciChipsetInitSyncMsg: Could not allocate Memory\n"));
+ return EFI_ABORTED;
+ }
+
+ //
+ // Setup the HECI message for a MPHY Write
+ //
+ MPhyWriteSettingsReqPtr->Header.ApiVersion = LYNX_POINT_PLATFORM;
+ MPhyWriteSettingsReqPtr->Header.IccCommand = WRITE_MPHY_SETTINGS;
+ MPhyWriteSettingsReqPtr->Header.BufferLength = ReqSize - sizeof (ICC_HEADER);
+ MPhyWriteSettingsReqPtr->PostedWrite = FALSE;
+ CopyMem (MPhyWriteSettingsReqPtr+1, ChipsetInitTable, ChipsetInitTableLen);
+
+ DEBUG ((EFI_D_ERROR, "(MPHY) mPhyChipsetInitTable[] = \n"));
+ DEBUG ((EFI_D_ERROR, " Ver=%d CRC=0x%04X NumEntries=%d\n",
+ *((UINT16*)&ChipsetInitTable[2]), *((UINT16*)&ChipsetInitTable[0]), ChipsetInitTable[4]));
+ #ifdef EFI_DEBUG
+ {
+ int ii;
+ UINT8* entry_ptr = &ChipsetInitTable[5];
+ for (ii = 0; ii < ChipsetInitTable[4]; ii++) {
+ DEBUG ((EFI_D_ERROR, " %d: EP=0x%02X OFFSET=0x%04X VALUE=0x%08X\n",
+ ii, entry_ptr[6],*((UINT16*)&entry_ptr[0]),*((UINT32*)&entry_ptr[2])));
+ entry_ptr += 7;
+ }
+ }
+ #endif
+
+ //
+ // Send ChipsetInit Table to ME
+ //
+ Status = Heci->SendwACK (
+ (UINT32 *)MPhyWriteSettingsReqPtr,
+ ReqSize,
+ &ReqSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "(MPHY) Write MPHY Settings Message failed! EFI_STATUS = %r\n", Status));
+ }
+ else if (MPhyWriteSettingsReqPtr->Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG ((EFI_D_ERROR,"(MPHY) Write MPHY Settings failed!: FW Response=0x%x\n",MPhyWriteSettingsReqPtr->Header.IccResponse));
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ FreePool (MPhyWriteSettingsReqPtr);
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8140);
+ return Status;
+ }
+
+ if (PchResetProtocol != NULL) {
+ DEBUG ((EFI_D_ERROR, "HeciChipsetInitSyncMsg(): Reset required for ChipsetInit Settings synch\n"));
+ PchResetProtocol->Reset (PchResetProtocol, ColdReset);
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8140);
+ DEBUG ((EFI_D_ERROR, "HeciChipsetInitSyncMsg(): End\n"));
+ return Status;
+}
+
+//
+// Interface functions of HeciMsgLib
+//
+
+/**
+ Send Core BIOS Reset Request Message through HECI to reset the system.
+
+ @param[in] ResetOrigin Reset source
+ @param[in] ResetType Global or Host reset
+
+ @exception EFI_UNSUPPORTED Current ME 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;
+ PLATFORM_ME_HOOK_PROTOCOL *PlatformMeHook;
+ EFI_GUID WdtProtocolGuid = WDT_PROTOCOL_GUID;
+ WDT_PROTOCOL *WdtProtocol;
+ UINT32 MeMode;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gPlatformMeHookProtocolGuid,
+ NULL,
+ (VOID **) &PlatformMeHook
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Locate PlatformMeHook Protocol for Global Reset Hook, so skip instead.- %r\n", Status));
+ } else {
+ PlatformMeHook->PreGlobalReset ();
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ 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 = gBS->LocateProtocol (&WdtProtocolGuid, NULL, (VOID **) &WdtProtocol);
+ ASSERT_EFI_ERROR (Status);
+ WdtProtocol->AllowKnownReset ();
+
+ Status = Heci->SendMsg (
+ (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;
+}
+
+/**
+ Send Hardware Asset Tables to Firmware
+
+ @param[in] Handle A handle for this module
+ @param[in] AssetTableData Hardware Asset Table Data
+ @param[in] TableDataSize Size of Asset table
+
+ @retval EFI_SUCCESS Table sent
+ @retval EFI_ABORTED Could not allocate Memory
+**/
+EFI_STATUS
+HeciAssetUpdateFwMsg (
+ IN EFI_HANDLE Handle,
+ IN TABLE_PUSH_DATA *AssetTableData,
+ IN UINT16 TableDataSize
+ )
+{
+ AU_TABLE_PUSH_MSG *SendAssetTableDataMsg;
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+
+ Status = EFI_SUCCESS;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Subtract off single byte from TABLE_PUSH_DATA.TableData[1]
+ ///
+ SendAssetTableDataMsg = AllocateZeroPool (sizeof (AU_TABLE_PUSH_MSG) + MAX_ASSET_TABLE_ALLOCATED_SIZE - 1);
+ if (SendAssetTableDataMsg == NULL) {
+ DEBUG ((EFI_D_ERROR, "AssetUpdateFwMsg Error: Could not allocate Memory\n"));
+ return EFI_ABORTED;
+ }
+
+ if (TableDataSize > MAX_ASSET_TABLE_ALLOCATED_SIZE) {
+ TableDataSize = MAX_ASSET_TABLE_ALLOCATED_SIZE;
+ }
+
+ SendAssetTableDataMsg->Header.Data = 0;
+ ///
+ /// Subtract off single byte from TABLE_PUSH_DATA.TableData[1]
+ ///
+ SendAssetTableDataMsg->Header.Fields.MessageLength = TableDataSize + sizeof (TABLE_PUSH_DATA) - 1;
+ SendAssetTableDataMsg->Header.Fields.Command = HWA_TABLE_PUSH_CMD;
+ SendAssetTableDataMsg->Header.Fields.FRUTablePresent = 1;
+ SendAssetTableDataMsg->Header.Fields.SMBIOSTablePresent = 1;
+ SendAssetTableDataMsg->Header.Fields.ASFTablePresent = 1;
+ if (AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE].Length == 0) {
+ SendAssetTableDataMsg->Header.Fields.MediaTablePresent = 0;
+ } else {
+ SendAssetTableDataMsg->Header.Fields.MediaTablePresent = 1;
+ }
+
+ CopyMem (&SendAssetTableDataMsg->Data, AssetTableData, SendAssetTableDataMsg->Header.Fields.MessageLength);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8020);
+ Status = Heci->SendMsg (
+ (UINT32 *) SendAssetTableDataMsg,
+ SendAssetTableDataMsg->Header.Fields.MessageLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_HWA_CLIENT_ID
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "AssetUpdateFwMsg: Failed to Send SendAssetTableDataMsg\n"));
+
+ }
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8021);
+
+ FreePool (SendAssetTableDataMsg);
+
+ return Status;
+
+}
+
+/**
+ Send End of Post Request Message through HECI.
+
+ @param[in] Handle A handle for this module
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciSendEndOfPostMessage (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ GEN_END_OF_POST_ACK CbmEndOfPost;
+ UINT32 MeMode;
+ EFI_HECI_PROTOCOL *Heci;
+ PCH_RESET_PROTOCOL *PchResetProtocol;
+ EFI_GUID PchResetProtocolGuid = PCH_RESET_PROTOCOL_GUID;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&PchResetProtocolGuid, NULL, (VOID **) &PchResetProtocol);
+
+ if (EFI_ERROR (Status)) {
+ PchResetProtocol = NULL;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CbmEndOfPost.Header.Data = 0;
+ CbmEndOfPost.Header.Fields.Command = CBM_END_OF_POST_CMD;
+ CbmEndOfPost.Header.Fields.IsResponse = 0;
+ CbmEndOfPost.Header.Fields.GroupId = MKHI_GEN_GROUP_ID;
+ CbmEndOfPost.Data.RequestedActions = 0;
+
+ HeciSendLength = sizeof (MKHI_MESSAGE_HEADER);
+ HeciRecvLength = sizeof (GEN_END_OF_POST_ACK);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8030);
+ Status = Heci->SendMsg (
+ (UINT32 *) &CbmEndOfPost,
+ HeciSendLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &CbmEndOfPost,
+ &HeciRecvLength
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8031);
+
+ if (CbmEndOfPost.Data.RequestedActions == HECI_EOP_PERFORM_GLOBAL_RESET) {
+ if (PchResetProtocol != NULL) {
+ DEBUG ((EFI_D_ERROR, "HeciSendEndOfPostMessage(): Reset requested by FW EOP ACK %r\n"));
+ PchResetProtocol->Reset (PchResetProtocol, GlobalReset);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Send Get Firmware SKU Request to ME
+
+ @param[in] MsgGenGetFwCapsSku Return message for Get Firmware Capability SKU
+ @param[in] MsgGenGetFwCapsSkuAck Return message for Get Firmware Capability SKU ACK
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8040);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) MsgGenGetFwCapsSkuAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8042);
+ return Status;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8041);
+ return Status;
+}
+
+/**
+ Send Get Firmware Version Request to ME
+
+ @param[in][out] MsgGenGetFwVersionAck Return themessage of FW version
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8050);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) MsgGenGetFwVersionAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8052);
+ return Status;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8051);
+ return Status;
+}
+
+/**
+ Sends a message to ME to unlock a specified SPI Flash region for writing and receiving a response message.
+ It is recommended that HMRFPO_ENABLE MEI message needs to be sent after all OROMs finish their initialization.
+
+ @param[in] Nonce Nonce received in previous HMRFPO_ENABLE Response Message
+ @param[in] Result HMRFPO_ENABLE response
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8070);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &HmrfpoEnableResponse,
+ &HeciLength
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Read HMRFPO_ENABLE_CMD_ID Result - %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8072);
+ return Status;
+ }
+
+ *Result = HmrfpoEnableResponse.Status;
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8071);
+
+ return Status;
+}
+
+/**
+ Sends a message to ME to lock a specified SPI Flash region for writing and receiving a response message.
+
+ @param[out] Nonce Random number generated by Ignition ME 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
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8080);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &HmrfpoLockResponse,
+ &HeciLength
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to read HMRFPO_LOCK_CMD_ID response - %r.\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8082);
+ return Status;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8081);
+
+ *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
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8090);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &HmrfpoGetStatusResponse,
+ &HeciLength
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Read HMRFPO_GET_STATUS_CMD_ID Result - %r\n", Status));
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8091);
+ *Result = HmrfpoGetStatusResponse.Status;
+
+ return Status;
+}
+
+/**
+ This is used to send KVM request message to Intel ME. When
+ Bootoptions indicate that a KVM session is requested then BIOS
+ will send this message before any graphical display output to
+ ensure that FW is ready for KVM session.
+
+ @param[in] QueryType 0 - Query Request
+ 1 - Cancel Request
+ @param[out] ResponseCode 1h - Continue, KVM session established.
+ 2h - Continue, KVM session cancelled.
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciQueryKvmRequest (
+ IN UINT32 QueryType,
+ OUT UINT32 *ResponseCode
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ AMT_QUERY_KVM_REQUEST QueryKvmRequest;
+ AMT_QUERY_KVM_RESPONSE QueryKvmResponse;
+ UINT32 HeciLength;
+ UINT16 TimeOut;
+ UINT32 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ QueryKvmRequest.Command = EFI_KVM_MESSAGE_COMMAND;
+ QueryKvmRequest.ByteCount = EFI_KVM_BYTE_COUNT;
+ QueryKvmRequest.SubCommand = EFI_KVM_QUERY_REQUES;
+ QueryKvmRequest.VersionNumber = EFI_KVM_VERSION;
+ QueryKvmRequest.QueryType = QueryType;
+
+ HeciLength = sizeof (AMT_QUERY_KVM_REQUEST);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8060);
+ Status = Heci->SendMsg (
+ (UINT32 *) &QueryKvmRequest,
+ HeciLength,
+ BIOS_ASF_HOST_ADDR,
+ HECI_ASF_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Query KVM failed %r\n", Status));
+ }
+
+ TimeOut = 0;
+ HeciLength = sizeof (AMT_QUERY_KVM_RESPONSE);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &QueryKvmResponse,
+ &HeciLength
+ );
+
+ if (QueryType == QUERY_REQUEST) {
+ while (EFI_ERROR (Status)) {
+ gBS->Stall (EFI_KVM_STALL_1_SECOND);
+ TimeOut++;
+
+ if (TimeOut > EFI_KVM_MAX_WAIT_TIME) {
+ break;
+ }
+
+ HeciLength = sizeof (AMT_QUERY_KVM_RESPONSE);
+ Status = Heci->ReadMsg (
+ NON_BLOCKING,
+ (UINT32 *) &QueryKvmResponse,
+ &HeciLength
+ );
+ }
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8061);
+ *ResponseCode = QueryKvmResponse.ResponseCode;
+
+ 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
+
+ @exception EFI_UNSUPPORTED Current ME 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 UINT8 *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_GET_LOCAL_FW_UPDATE MsgGenGetLocalFwUpdate;
+ GEN_GET_LOCAL_FW_UPDATE_ACK MsgGenGetLocalFwUpdatekuAck;
+ UINT32 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80A0);
+ Status = Heci->SendMsg (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &MsgGenGetLocalFwUpdatekuAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80A2);
+ return Status;
+ }
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80A1);
+ *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
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 = 1;
+ MsgGenSetLocalFwUpdate.Data.RuleData = RuleData;
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE);
+
+ ///
+ /// Send Get Local FW update Request to ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80B0);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgGenSetLocalFwUpdate,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80B2);
+ return Status;
+ }
+
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgGenSetLocalFwUpdateAck,
+ &Length
+ );
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80B1);
+ 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 ME 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
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS ME enabled message sent
+**/
+EFI_STATUS
+HeciSetMeEnableMsg (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_SET_FW_CAPSKU_ACK MsgMeStateControlAck;
+ HECI_FWS_REGISTER MeFirmwareStatus;
+ UINTN HeciPciAddressBase;
+ UINT16 TimeOut;
+ UINT32 MeMode;
+
+ TimeOut = 0;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (MeMode == ME_MODE_NORMAL) {
+ return EFI_SUCCESS;
+ }
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_TEMP_DISABLED)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HeciPciAddressBase = PCI_LIB_ADDRESS (
+ ME_BUS,
+ ME_DEVICE_NUMBER,
+ HECI_FUNCTION_NUMBER,
+ 0
+ );
+ PciWrite8 (HeciPciAddressBase + R_GEN_STS + 3, 0x20);
+ do {
+ MeFirmwareStatus.ul = PciRead32 (HeciPciAddressBase + R_FWSTATE);
+ gBS->Stall (EFI_ME_STATE_STALL_1_SECOND);
+ TimeOut++;
+ } while ((MeFirmwareStatus.r.FwInitComplete != ME_FIRMWARE_COMPLETED) && (TimeOut < EFI_ME_STATE_MAX_TIMEOUT));
+
+ Length = sizeof (GEN_SET_FW_CAPSKU_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgMeStateControlAck,
+ &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 disable the ME 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] None
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS ME is disabled
+**/
+EFI_STATUS
+HeciSetMeDisableMsg (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_SET_FW_CAPSKU MsgMeStateControl;
+ UINT32 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (MeMode == ME_MODE_TEMP_DISABLED) {
+ return EFI_SUCCESS;
+ }
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgMeStateControl.MKHIHeader.Data = 0;
+ MsgMeStateControl.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgMeStateControl.MKHIHeader.Fields.Command = FWCAPS_SET_RULE_CMD;
+ MsgMeStateControl.MKHIHeader.Fields.IsResponse = 0;
+ MsgMeStateControl.Data.RuleId.Data = 6;
+ MsgMeStateControl.Data.RuleDataLen = 1;
+ MsgMeStateControl.Data.RuleData = 0;
+
+ Length = sizeof (GEN_SET_FW_CAPSKU);
+
+ Status = Heci->SendwACK (
+ (UINT32 *) &MsgMeStateControl,
+ Length,
+ &Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ 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 Ibex Peak platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ 1.5M or 5M size firmware.
+
+ @param[in] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80C0);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgGenGetPlatformType,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80C2);
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_PLATFORM_TYPE_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgGenGetPlatformTypeAck,
+ &Length
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80C1);
+ *RuleData = MsgGenGetPlatformTypeAck.Data.RuleData;
+
+ return Status;
+}
+
+/**
+ This message is sent by the BIOS on the boot where the host wants to get the firmware provisioning state.
+ The firmware will respond to AMT BIOS SYNCH INFO message even after the End of Post.
+
+ @param[out] RuleData Bit [2:0] Reserved
+ Bit [4:3] Provisioning State
+ 00 - Pre -provisioning
+ 01 - In -provisioning
+ 02 - Post !Vprovisioning
+ Bit [31:5] Reserved
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Firmware provisioning state returned
+ @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
+HeciAmtBiosSynchInfo (
+ OUT UINT32 *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_AMT_BIOS_SYNCH_INFO MsgGenAmtBiosSynchInfo;
+ GEN_AMT_BIOS_SYNCH_INFO_ACK MsgGenAmtBiosSynchInfoAck;
+ UINT32 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgGenAmtBiosSynchInfo.MKHIHeader.Data = 0;
+ MsgGenAmtBiosSynchInfo.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID;
+ MsgGenAmtBiosSynchInfo.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD;
+ MsgGenAmtBiosSynchInfo.MKHIHeader.Fields.IsResponse = 0;
+ MsgGenAmtBiosSynchInfo.Data.RuleId = 0x30005;
+ Length = sizeof (GEN_AMT_BIOS_SYNCH_INFO);
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8130);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgGenAmtBiosSynchInfo,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8132);
+ return Status;
+ }
+
+ Length = sizeof (GEN_AMT_BIOS_SYNCH_INFO_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgGenAmtBiosSynchInfoAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8133);
+ return Status;
+ }
+
+ *RuleData = MsgGenAmtBiosSynchInfoAck.RuleData;
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8131);
+ return Status;
+}
+
+/**
+ The firmware will respond to GET OEM TAG message even after the End of Post (EOP).
+
+ @param[in] RuleData Default is zero. Tool can create the OEM specific OEM TAG data.
+
+ @exception EFI_UNSUPPORTED Current ME 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 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &MsgGenGetOemTagMsgAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *RuleData = MsgGenGetOemTagMsgAck.RuleData;
+
+ return Status;
+}
+
+/**
+ Enables/disables clocks. Used to turn off clocks in unused pci/pcie slots.
+ BIOS use this command when it enumerates PCI slots. When PCI slot is found unpopulated, the
+ BIOS can disable its clock through this MEI message. It is the BIOS requirement to know which
+ slot is controlled by which control bit.
+
+ @param[in] Enables each bit means corresponding clock should be turned on (1) or off (0)
+ @param[in] EnablesMask each bit means corresponding enable bit is valid (1) or should be ignored (0)
+ @param[in] ResponseMode 0 wait for response, 1 - skip
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY ME is not ready
+ @retval EFI_INVALID_PARAMETER ResponseMode is invalid value
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+HeciSetIccClockEnables (
+ IN UINT32 Enables,
+ IN UINT32 EnablesMask,
+ IN UINT8 ResponseMode
+ )
+{
+ EFI_STATUS Status;
+ ICC_SET_CLK_ENABLES_BUFFER Buffer;
+ UINT32 CommandSize;
+ UINT32 ResponseSize;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((ResponseMode != ICC_RESPONSE_MODE_SKIP) && (ResponseMode != ICC_RESPONSE_MODE_WAIT)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ if (EFI_ERROR (Status) || ((MeStatus & 0xF) != ME_READY)) {
+ return EFI_NOT_READY;
+ }
+
+ CommandSize = sizeof (ICC_SET_CLK_ENABLES_MESSAGE);
+ ResponseSize = sizeof (ICC_SET_CLK_ENABLES_RESPONSE);
+
+ Buffer.message.Header.ApiVersion = LYNX_POINT_PLATFORM;
+ Buffer.message.Header.IccCommand = SET_CLOCK_ENABLES;
+ Buffer.message.Header.IccResponse = 0;
+ Buffer.message.Header.BufferLength = CommandSize - sizeof (ICC_HEADER);
+ Buffer.message.Header.Reserved = 0;
+ Buffer.message.ClockEnables = Enables;
+ Buffer.message.ClockEnablesMask = EnablesMask;
+ Buffer.message.Params = ResponseMode;
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D0);
+ Status = Heci->SendMsg (
+ (UINT32 *) &Buffer,
+ CommandSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+
+ if (ResponseMode == ICC_RESPONSE_MODE_WAIT) {
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &Buffer,
+ &ResponseSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "(ICC) IccSetClockEnables: Message failed! EFI_STATUS = %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D2);
+ return Status;
+ }
+
+ if (ResponseMode == ICC_RESPONSE_MODE_SKIP) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D3);
+ return EFI_SUCCESS;
+ }
+
+ if (Buffer.response.Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "(ICC) IccSetClockEnables: Wrong response! IccHeader.Response = 0x%x\n",
+ Buffer.response.Header.IccResponse)
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D4);
+ return EFI_DEVICE_ERROR;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D1);
+ return Status;
+}
+
+/**
+ Sets or reads Lock mask on ICC registers.
+ @param[in] AccessMode 0 - set, 1 - get
+ @param[in] ResponseMode 0 - firmware will answer, 1 - firmware will not answer
+ @param[in][out] LockRegInfo bundle count info and mask of registers to become (for 'set' mode) or are
+ (for 'get' mode) locked. Each bit represents a register. 0=lock, 1=don't lock
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_INVALID_PARAMETER ResponseMode or pointer of Mask is invalid value
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciLockIccRegisters (
+ IN UINT8 AccessMode,
+ IN UINT8 ResponseMode,
+ IN OUT ICC_LOCK_REGS_INFO *LockRegInfo
+ )
+{
+ EFI_STATUS Status;
+ ICC_LOCK_REGISTERS_BUFFER Buffer;
+ UINT32 CommandSize;
+ UINT32 ResponseSize;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+ UINT32 i;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((ResponseMode != ICC_RESPONSE_MODE_SKIP) && (ResponseMode != ICC_RESPONSE_MODE_WAIT)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ if (EFI_ERROR (Status) || ((MeStatus & 0xF) != ME_READY)) {
+ return EFI_NOT_READY;
+ }
+
+ DEBUG ((EFI_D_INFO, "(ICC) LockIccRegisters\n"));
+ if (LockRegInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+
+ }
+
+ CommandSize = sizeof (ICC_LOCK_REGISTERS_MESSAGE) -
+ sizeof(UINT32) * ICC_LOCK_MASK_COUNT +
+ sizeof(UINT32) * LockRegInfo->RegBundles.BundlesCnt;
+ ResponseSize = sizeof (ICC_LOCK_REGISTERS_RESPONSE);
+
+ Buffer.message.Header.ApiVersion = LYNX_POINT_PLATFORM;
+ Buffer.message.Header.IccCommand = LOCK_ICC_REGISTERS;
+ Buffer.message.Header.IccResponse = 0;
+ Buffer.message.Header.BufferLength = CommandSize - sizeof (ICC_HEADER);
+ Buffer.message.Header.Reserved = 0;
+ Buffer.message.AccessMode = AccessMode;
+ Buffer.message.Parameters = ResponseMode;
+ Buffer.message.Reserved[0] = 0;
+ Buffer.message.Reserved[1] = 0;
+ Buffer.message.LockRegInfo.RegBundles = LockRegInfo->RegBundles;
+ for (i = 0; i < LockRegInfo->RegBundles.BundlesCnt; i++) {
+ Buffer.message.LockRegInfo.RegMask[i] = LockRegInfo->RegMask[i];
+ }
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80E0);
+ Status = Heci->SendMsg (
+ (UINT32 *) &Buffer,
+ CommandSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+
+ if (ResponseMode == ICC_RESPONSE_MODE_WAIT) {
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &Buffer,
+ &ResponseSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "(ICC) LockIccRegisters: Message failed! EFI_STATUS = %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80E2);
+ return Status;
+ }
+
+ if (ResponseMode == ICC_RESPONSE_MODE_SKIP) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80E3);
+ return EFI_SUCCESS;
+ }
+
+ if (Buffer.response.Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "(ICC) LockIccRegisters: Wrong response! IccHeader.Response = 0x%x\n",
+ Buffer.response.Header.IccResponse)
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80E4);
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (AccessMode == ICC_LOCK_ACCESS_MODE_GET) {
+ LockRegInfo->RegBundles = Buffer.response.LockRegInfo.RegBundles;
+ LockRegInfo->RegMask[0] = Buffer.response.LockRegInfo.RegMask[0];
+ LockRegInfo->RegMask[1] = Buffer.response.LockRegInfo.RegMask[1];
+ LockRegInfo->RegMask[2] = Buffer.response.LockRegInfo.RegMask[2];
+ }
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80E1);
+
+ return Status;
+}
+
+/**
+ retrieves the number of currently used ICC clock profile
+
+ @param[out] Profile number of current ICC clock profile
+
+ @exception EFI_UNSUPPORTED ICC clock profile doesn't support
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciGetIccProfile (
+ OUT UINT8 *Profile
+ )
+{
+ EFI_STATUS Status;
+ ICC_GET_PROFILE_BUFFER Buffer;
+ UINT32 CommandSize;
+ UINT32 ResponseSize;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ if (EFI_ERROR (Status) || ((MeStatus & 0xF) != ME_READY)) {
+ return EFI_NOT_READY;
+ }
+
+ DEBUG ((EFI_D_INFO, "(ICC) GetIccProfile\n"));
+ CommandSize = sizeof (ICC_GET_PROFILE_MESSAGE);
+ ResponseSize = sizeof (ICC_GET_PROFILE_RESPONSE);
+
+ Buffer.message.Header.ApiVersion = LYNX_POINT_PLATFORM;
+ Buffer.message.Header.IccCommand = GET_ICC_PROFILE;
+ Buffer.message.Header.IccResponse = 0;
+ Buffer.message.Header.BufferLength = CommandSize - sizeof (ICC_HEADER);
+ Buffer.message.Header.Reserved = 0;
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80F0);
+ Status = Heci->SendwACK (
+ (UINT32 *) &Buffer,
+ CommandSize,
+ &ResponseSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "(ICC) GetIccProfile: Message failed! EFI_STATUS = %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80F2);
+ return Status;
+ }
+
+ if (Buffer.response.Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "(ICC) GetIccProfile: Wrong response! IccHeader.Response = 0x%x\n",
+ Buffer.response.Header.IccResponse)
+ );
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ DEBUG ((EFI_D_INFO, "(ICC) GetIccProfile: Current profile = 0x%x\n", Buffer.response.IccProfileIndex));
+ }
+
+ if (Profile != NULL) {
+ *Profile = Buffer.response.IccProfileIndex;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80F1);
+
+ return Status;
+}
+
+/**
+ Sets ICC clock profile to be used on next and following boots
+
+ @param[in] Profile number of profile to be used
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciSetIccProfile (
+ IN UINT8 Profile
+ )
+{
+ EFI_STATUS Status;
+ ICC_SET_PROFILE_BUFFER Buffer;
+ UINT32 CommandSize;
+ UINT32 ResponseSize;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ if (EFI_ERROR (Status) || ((MeStatus & 0xF) != ME_READY)) {
+ return EFI_NOT_READY;
+ }
+
+ DEBUG ((EFI_D_INFO, "(ICC) SetIccProfile\n"));
+
+ CommandSize = sizeof (ICC_SET_PROFILE_MESSAGE);
+ ResponseSize = sizeof (ICC_SET_PROFILE_RESPONSE);
+
+ Buffer.message.Header.ApiVersion = LYNX_POINT_PLATFORM;
+ Buffer.message.Header.IccCommand = SET_ICC_PROFILE;
+ Buffer.message.Header.IccResponse = 0;
+ Buffer.message.Header.BufferLength = CommandSize - sizeof (ICC_HEADER);
+ Buffer.message.Header.Reserved = 0;
+ Buffer.message.ProfileBIOS = Profile;
+ Buffer.message.PaddingA = 0;
+ Buffer.message.PaddingB = 0;
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8100);
+ Status = Heci->SendwACK (
+ (UINT32 *) &Buffer,
+ CommandSize,
+ &ResponseSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "(ICC) SetIccProfile: Message failed! EFI_STATUS = %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8102);
+ return Status;
+ }
+
+ if (Buffer.response.Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "(ICC) SetIccProfile: Wrong response! IccHeader.Response = 0x%x\n",
+ Buffer.response.Header.IccResponse)
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8103);
+ return EFI_DEVICE_ERROR;
+ }
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8101);
+
+ return Status;
+}
+
+/**
+ Writes 1 dword of data to the icc register offset specified by RegOffset in the ICC Aux space
+ @param[in] RegOffset Register Offset in ICC Aux Space to write
+ @param[in] RegData Dword ICC register data to write
+ @param[in] ResponseMode 0 Wait for response, 1 - skip
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY ME is not ready
+ @retval EFI_INVALID_PARAMETER ResponseMode is invalid value
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+HeciWriteIccRegDword (
+ IN UINT16 RegOffset,
+ IN UINT32 RegData,
+ IN UINT8 ResponseMode
+ )
+{
+ EFI_STATUS Status;
+ ICC_WRITE_ICC_REG_BUFFER Buffer;
+ UINT32 CommandSize;
+ UINT32 ResponseSize;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((ResponseMode != ICC_RESPONSE_MODE_SKIP) && (ResponseMode != ICC_RESPONSE_MODE_WAIT)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ if (EFI_ERROR (Status) || ((MeStatus & 0xF) != ME_READY)) {
+ return EFI_NOT_READY;
+ }
+
+ CommandSize = sizeof (ICC_WRITE_ICC_REG_DWORD_MESSAGE);
+ ResponseSize = sizeof (ICC_WRITE_ICC_REG_DWORD_RESPONSE);
+
+ Buffer.message.Header.ApiVersion = LYNX_POINT_PLATFORM;
+ Buffer.message.Header.IccCommand = WRITE_ICC_REGISTER;
+ Buffer.message.Header.IccResponse = 0;
+ Buffer.message.Header.BufferLength = CommandSize - sizeof (ICC_HEADER);
+ Buffer.message.Header.Reserved = 0;
+ Buffer.message.Reserved = 0;
+ Buffer.message.Reserved1 = 0;
+ Buffer.message.Params = ResponseMode;
+ Buffer.message.RecordDword.RecordFlags = WRITE_ICC_RECORD_FLAGS;
+ Buffer.message.RecordDword.BundleCount.BundlesCnt = WRITE_ICC_REG_BUNDLE_COUNT;
+ Buffer.message.RecordDword.BundleCount.AU = 0;
+ Buffer.message.RecordDword.BundleCount.Reserved = 0;
+ Buffer.message.RecordDword.AddressMask.AddressMaskData = RegOffset | ADDRESS_MASK_FIXED_DATA;
+ Buffer.message.RecordDword.RegValue = RegData;
+
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D0);
+ Status = Heci->SendMsg (
+ (UINT32 *) &Buffer,
+ CommandSize,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_ICC_MESSAGE_ADDR
+ );
+
+ if (ResponseMode == ICC_RESPONSE_MODE_WAIT) {
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &Buffer,
+ &ResponseSize
+ );
+
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "(ICC) HeciWriteIccRegDword: Message failed! EFI_STATUS = %r\n", Status));
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D2);
+ return Status;
+ }
+
+ if (ResponseMode == ICC_RESPONSE_MODE_SKIP) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D3);
+ return EFI_SUCCESS;
+ }
+
+ if (Buffer.response.Header.IccResponse != ICC_STATUS_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "(ICC) HeciWriteIccRegDword: Wrong response! IccHeader.Response = 0x%x\n",
+ Buffer.response.Header.IccResponse)
+ );
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D4);
+ return EFI_DEVICE_ERROR;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x80D1);
+ return Status;
+}
+
+/**
+ This message is used to turn on the Intel ME firmware MDES
+ capability, Intel SVT for PCH capability or both when the
+ system is in a post-manufactured state. Once firmware receives
+ this message, the firmware will enable selected platform debug
+ capabilities . The firmware will automatically disable all
+ platform debug capabilities if this message is not received
+ before receiving End Of Post.
+
+ @param[in] Data capabilities to be enabled
+ @param[out] Result 0x00 : Enable Success
+ Others : Enable Failure
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciPlatformDebugCapabilityMsg (
+ IN PLATFORM_DEBUG_CAP Data,
+ OUT UINT8 *Result
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_PLATFORM_DEBUG_CAP_MKHI_CMD_MSG PlatformDebug;
+ UINT32 MeMode;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ PlatformDebug.MKHIHeader.Data = 0;
+ PlatformDebug.MKHIHeader.Fields.GroupId = MKHI_MDES_GROUP_ID;
+ PlatformDebug.MKHIHeader.Fields.Command = MDES_ENABLE_MKHI_CMD;
+ PlatformDebug.MKHIHeader.Fields.IsResponse = 0;
+ PlatformDebug.Capability = Data;
+ Length = sizeof (GEN_PLATFORM_DEBUG_CAP_MKHI_CMD_MSG);
+
+ Status = Heci->SendwACK (
+ (UINT32 *) &PlatformDebug,
+ Length,
+ &Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (Status == EFI_SUCCESS) {
+ *Result = (UINT8) PlatformDebug.MKHIHeader.Fields.Result;
+ }
+
+ return Status;
+}
+
+/**
+ It creates and sends Heci messages.
+
+ Remark:
+ Functionality is available only in release mode.
+ Using MDES in debug mode causes recursive calling of this function
+ because debug messages are sending from Heci->SendMsg function.
+
+ @param[in] CodeType Indicates the type of status code being reported.
+ @param[in] Value Describes the current status of a hardware or software entity.
+ This included information about the class and subclass that is
+ used to classify the entity as well as an operation.
+ @param[in] Instance The enumeration of a hardware or software entity within
+ the system. Valid instance numbers start with 1.
+ @param[in] CallerId This optional parameter may be used to identify the caller.
+ This parameter allows the status code driver to apply different
+ rules to different callers.
+ @param[in] Data This optional parameter may be used to pass additional data.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Opcode evaluation success.
+ @retval Other Opcode evaluation failed.
+**/
+EFI_STATUS
+HeciSendMdesStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID * CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA * Data OPTIONAL
+ )
+{
+ CBM_BIOS_MDES_MSG_REQ MsgData;
+ EFI_STATUS Status;
+ UINT32 HeciLength;
+ UINT32 MeMode;
+ EFI_HECI_PROTOCOL *Heci;
+ static UINT32 sNr = 0;
+ UINT32 ExtendedDataSize;
+ UINT32 StringCnt;
+
+ ExtendedDataSize = 0;
+ StringCnt = 0;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgData.MKHIHeader.Fields.GroupId = MKHI_MDES_GROUP_ID;
+ MsgData.MKHIHeader.Fields.Command = MDES_BIOS_MSG_LOG_REQ_CMD;
+ MsgData.MKHIHeader.Fields.IsResponse = 0;
+ MsgData.MKHIHeader.Fields.Result = 0;
+
+ MsgData.Data.MdesAttr.Severity = BiosToMdesSeverity (CodeType);
+ MsgData.Data.MdesAttr.PayLoadType = EFI_STATUS_CODE;
+ MsgData.Data.BiosAttr.CallerIdData = (CallerId == 0) ? 0 : 1;
+ MsgData.Data.BiosAttr.ExtendedDataHeader = (Data == 0) ? 0 : 1;
+ MsgData.Data.Serial = sNr++;
+ MsgData.Data.StatusType = CodeType;
+ MsgData.Data.StatusCode = Value;
+ MsgData.Data.Instance = Instance;
+
+ if (CallerId != 0) {
+ CopyMem (&MsgData.Data.CallerId, CallerId, sizeof(EFI_GUID));
+ }
+
+ if (Data != 0) {
+ ExtendedDataSize = Data->Size;
+ if (ExtendedDataSize > SIZE_OF_MDES_EXTENDED_DATA) {
+ ASSERT (FALSE);
+ //
+ // extended data too long
+ //
+ ExtendedDataSize = SIZE_OF_MDES_EXTENDED_DATA;
+ }
+
+ if (CompareGuid (&gEfiStatusCodeDataTypeStringGuid, &Data->Type)) {
+
+ EFI_STATUS_CODE_STRING_DATA *str_data;
+
+ str_data = (EFI_STATUS_CODE_STRING_DATA *) Data;
+ MsgData.Data.ExtendedData[0] = (UINT8) (str_data->StringType);
+ MsgData.Data.ExtendedData[1] = 0;
+ MsgData.Data.ExtendedData[2] = 0;
+ MsgData.Data.ExtendedData[3] = 0;
+
+ if (str_data->StringType == EfiStringAscii) {
+ AsciiStrnCpy ((CHAR8 *) &MsgData.Data.ExtendedData[4], str_data->String.Ascii, SIZE_OF_MDES_EXTENDED_DATA);
+ StringCnt = (UINT32) AsciiStrLen ((CHAR8 *) &MsgData.Data.ExtendedData[4]);
+ ExtendedDataSize = 4 + StringCnt;
+ if (ExtendedDataSize > SIZE_OF_MDES_EXTENDED_DATA) {
+ ExtendedDataSize = SIZE_OF_MDES_EXTENDED_DATA;
+ }
+
+ } else if (str_data->StringType == EfiStringUnicode) {
+ StrnCpy ((CHAR16 *) &MsgData.Data.ExtendedData[4], str_data->String.Unicode, SIZE_OF_MDES_EXTENDED_DATA);
+ StringCnt = (UINT32) StrLen ((CHAR16 *) &MsgData.Data.ExtendedData[4]);
+ ExtendedDataSize = 4 + StringCnt;
+ if (ExtendedDataSize > SIZE_OF_MDES_EXTENDED_DATA) {
+ ExtendedDataSize = SIZE_OF_MDES_EXTENDED_DATA;
+ }
+
+ } else if (str_data->StringType == EfiStringToken) {
+ CopyMem (MsgData.Data.ExtendedData, Data + Data->HeaderSize, ExtendedDataSize);
+ }
+ } else {
+ CopyMem (MsgData.Data.ExtendedData, Data + Data->HeaderSize, ExtendedDataSize);
+ }
+
+ MsgData.Data.ExtendedDataHeader.Size = (UINT16) ExtendedDataSize;
+ MsgData.Data.ExtendedDataHeader.HeaderSize = sizeof (MDES_EXTENDED_DATA_HEADER);
+ CopyMem (&MsgData.Data.ExtendedDataHeader.Type, &Data->Type, sizeof(EFI_GUID));
+ }
+
+ if (CallerId != 0) {
+ HeciLength = sizeof (CBM_BIOS_MDES_MSG_REQ) - SIZE_OF_MDES_EXTENDED_DATA - sizeof (MDES_EXTENDED_DATA_HEADER);
+ } else {
+ HeciLength = sizeof (CBM_BIOS_MDES_MSG_REQ) -
+ SIZE_OF_MDES_EXTENDED_DATA -
+ sizeof (MDES_EXTENDED_DATA_HEADER) -
+ sizeof (EFI_GUID);
+ }
+
+ if (Data != 0) {
+ HeciLength = sizeof (CBM_BIOS_MDES_MSG_REQ) - SIZE_OF_MDES_EXTENDED_DATA + ExtendedDataSize;
+ }
+
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgData,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ return Status;
+}
+
+/**
+ Provides an interface to call function to send HECI message.
+
+ @param[in] Flags Indicates the status of the BIOS MDES.
+ @param[in] BiosEventFilters Indicates the status of the BIOS event filter group.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI sent with success.
+**/
+EFI_STATUS
+HeciGetMdesConfig (
+ OUT MDES_BIOS_FLAGS *Flags,
+ OUT UINT32 *BiosEventFilters
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 Length;
+ MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_ACK MsgMdesAvailabilityAck;
+ MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_REQ MsgMdesAvailabilityReq;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgMdesAvailabilityReq.MKHIHeader.Fields.GroupId = MKHI_MDES_GROUP_ID;
+ MsgMdesAvailabilityReq.MKHIHeader.Fields.Command = MDES_BIOS_MSG_GET_CONFIG_CMD;
+ MsgMdesAvailabilityReq.MKHIHeader.Fields.IsResponse = 0;
+ MsgMdesAvailabilityReq.MKHIHeader.Fields.Result = 0;
+
+ Length = sizeof (MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_REQ);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgMdesAvailabilityReq,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Length = sizeof (MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgMdesAvailabilityAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *Flags = MsgMdesAvailabilityAck.Data.Flags;
+ *BiosEventFilters = MsgMdesAvailabilityAck.Data.BiosEventFilters;
+
+ return Status;
+}
+
+
+/**
+ Sends the MKHI Enable/Disable manageability message.
+ The message will only work if bit 2 in the bitmasks is toggled.
+ To enable manageability:
+ EnableState = 0x00000004, and
+ DisableState = 0x00000000.
+ To disable manageability:
+ EnableState = 0x00000000, and
+ DisableState = 0x00000004
+
+ @param[in] EnableState Enable Bit Mask
+ @param[in] DisableState Disable Bit Mask
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciFwFeatureStateOverride (
+ IN UINT32 EnableState,
+ IN UINT32 DisableState
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciLength;
+ UINT32 MeMode;
+ FIRMWARE_CAPABILITY_OVERRIDE MngStateCmd;
+ FIRMWARE_CAPABILITY_OVERRIDE_ACK MngStateAck;
+ EFI_HECI_PROTOCOL *Heci;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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);
+
+ Status = Heci->SendMsg (
+ (UINT32 *) &MngStateCmd,
+ HeciLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HeciLength = sizeof (FIRMWARE_CAPABILITY_OVERRIDE_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MngStateAck,
+ &HeciLength
+ );
+
+ 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
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+**/
+EFI_STATUS
+HeciGetFwFeatureStateMsg (
+ OUT MEFWCAPS_SKU *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ GEN_GET_FW_FEATURE_STATUS GetFwFeatureStatus;
+ GEN_GET_FW_FEATURE_STATUS_ACK GetFwFeatureStatusAck;
+ UINT32 MeMode;
+ EFI_HECI_PROTOCOL *Heci;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 (
+ (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 (
+ BLOCKING,
+ (UINT32 *) &GetFwFeatureStatusAck,
+ &Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RuleData->Data = GetFwFeatureStatusAck.RuleData.Data;
+
+ return Status;
+}
+
+/**
+ This message is sent by the BIOS when it wants to query
+ the independent firmware recovery (IFR).
+
+ @param[in] RuleData 1 - local firmware update interface enable
+
+ 0 - local firmware update interface disable
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciGetIfrUpdate (
+ OUT UINT8 *RuleData
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ GEN_GET_LOCAL_FW_UPDATE MsgGenGetLocalFwUpdate;
+ GEN_GET_LOCAL_FW_UPDATE_ACK MsgGenGetLocalFwUpdatekuAck;
+ UINT32 MeMode;
+
+ Status = EFI_SUCCESS;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 = MEFWCAPS_ME_FWU_IFR_RULE;
+ Length = sizeof (GEN_GET_LOCAL_FW_UPDATE);
+
+ ///
+ /// Send Get Local FW update Request to ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8110);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgGenGetLocalFwUpdate,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8112);
+ return Status;
+ }
+
+ Length = sizeof (GEN_GET_LOCAL_FW_UPDATE_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgGenGetLocalFwUpdatekuAck,
+ &Length
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8113);
+ return Status;
+ }
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8111);
+ *RuleData = MsgGenGetLocalFwUpdatekuAck.Data.RuleData;
+
+ return Status;
+}
+
+/**
+ This message is sent by the BIOS when it wants to set
+ the independent firmware recovery (IFR) state.
+
+ @param[in] RuleData 1 - local firmware update interface enable
+ 0 - local firmware update interface disable
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciSetIfrUpdate (
+ 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 MeMode;
+
+ Status = EFI_SUCCESS;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Heci->GetMeMode (&MeMode);
+ if (EFI_ERROR (Status) || (MeMode != ME_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 = MEFWCAPS_ME_FWU_IFR_RULE;
+ MsgGenSetLocalFwUpdate.Data.RuleDataLen = 1;
+ MsgGenSetLocalFwUpdate.Data.RuleData = RuleData;
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE);
+
+ ///
+ /// Send Set Local FW update Request to ME
+ ///
+ PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8120);
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgGenSetLocalFwUpdate,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR (Status)) {
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8122);
+ return Status;
+ }
+
+ Length = sizeof (GEN_SET_LOCAL_FW_UPDATE_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgGenSetLocalFwUpdateAck,
+ &Length
+ );
+
+ PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8121);
+ return Status;
+}
+
+/**
+ This message is sent by the BIOS if EOP-ACK not received to force ME to disable
+ HECI interfaces.
+
+ @param[in] None
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI interfaces disabled by ME
+**/
+EFI_STATUS
+HeciDisableHeciBusMsg (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ EFI_HECI_PROTOCOL *Heci;
+ HECI_BUS_DISABLE_CMD_ACK MsgHeciBusDisable;
+
+ ZeroMem(&MsgHeciBusDisable, sizeof(HECI_BUS_DISABLE_CMD_ACK));
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MsgHeciBusDisable.Command.Data = HECI_BUS_DISABLE_OPCODE;
+ Length = sizeof (HECI_BUS_DISABLE_CMD_ACK);
+
+ Status = Heci->SendMsg (
+ (UINT32 *) &MsgHeciBusDisable,
+ Length,
+ BIOS_FIXED_HOST_ADDR,
+ ME_HECI_FIXED_ADDRESS
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &MsgHeciBusDisable,
+ &Length
+ );
+ if ((MsgHeciBusDisable.Command.Data != HECI_BUS_DISABLE_ACK_OPCODE)
+ || (MsgHeciBusDisable.Status != 0)) {
+ Status = EFI_ABORTED;
+ }
+
+ return Status;
+}
+
+/**
+ This message is sent by the BIOS to inform ME FW whether or not to take the
+ TPM 1.2 Deactivate flow
+
+ @param[in] UINT8 TpmDeactivate 0 - ME FW should not take the
+ deactivate flow.
+ 1 - ME FW should take the deactivate
+ flow.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI interfaces disabled by ME
+**/
+EFI_STATUS
+HeciSendTpmData (
+ IN UINT8 TpmDeactivate
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HeciSendLength;
+ UINT32 HeciRecvLength;
+ EFI_HECI_PROTOCOL *Heci;
+ BIOSNV_SET_ACM_TPM SetAcmTpmMsg;
+ BIOSNV_SET_ACM_TPM_ACK SetAcmTpmMsgAck;
+
+ DEBUG ((EFI_D_ERROR, "HeciSendTpmData Message. TpmDeactivate Setup Data = %d\n", TpmDeactivate));
+
+ ZeroMem(&SetAcmTpmMsg, sizeof(BIOSNV_SET_ACM_TPM));
+ ZeroMem(&SetAcmTpmMsgAck, sizeof(BIOSNV_SET_ACM_TPM_ACK));
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (IsAfterEndOfPost ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SetAcmTpmMsg.MKHIHeader.Data = ACM_TPM_DATA_MKHI_DATA;
+ SetAcmTpmMsg.AcmTpmData.RuleId.Fields.RuleTypeId = ACM_TPM_DATA_RULE_TYPE_ID;
+ SetAcmTpmMsg.AcmTpmData.RuleDataLen = ACM_TPM_DATA_RULE_DATA_LENGTH;
+ SetAcmTpmMsg.AcmTpmData.TpmState.Fields.TpmDeactivate = FALSE;
+
+ if (TpmDeactivate == 1) {
+ SetAcmTpmMsg.AcmTpmData.TpmState.Fields.TpmDeactivate = TRUE;
+ }
+
+ //
+ // Send Set ACM TPM Data MKHI message
+ //
+ HeciSendLength = sizeof (BIOSNV_SET_ACM_TPM);
+ Status = Heci->SendMsg (
+ (UINT32 *) &SetAcmTpmMsg,
+ HeciSendLength,
+ BIOS_FIXED_HOST_ADDR,
+ HECI_CORE_MESSAGE_ADDR
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Get Set ACM TPM Data MKHI ACK message
+ //
+ HeciRecvLength = sizeof (BIOSNV_SET_ACM_TPM_ACK);
+ Status = Heci->ReadMsg (
+ BLOCKING,
+ (UINT32 *) &SetAcmTpmMsgAck,
+ &HeciRecvLength
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.h b/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.h
new file mode 100644
index 0000000..4622608
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.h
@@ -0,0 +1,782 @@
+/** @file
+ Header file for Heci Message functionality
+
+@copyright
+ Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+--*/
+#ifndef _HECI_MESSAGE_LIB_H_
+#define _HECI_MESSAGE_LIB_H_
+
+#include "CoreBiosMsg.h"
+
+#include EFI_PROTOCOL_DEFINITION (HECI)
+#include EFI_PROTOCOL_DEFINITION (PlatformMeHook)
+#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy)
+
+//
+// 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
+
+//
+// End of Post Codes
+//
+#define HECI_EOP_STATUS_SUCCESS 0x0
+#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1
+#define MAX_EOP_SEND_RETRIES 0x2
+
+//
+// IFR Update states
+//
+#define IFR_UPDATE_ENABLE 1
+#define IFR_UPDATE_DISABLE 0
+
+#define EFI_ME_FW_SKU_VARIABLE_GUID \
+ { \
+ 0xe1a21d94, 0x4a20, 0x4e0e, 0xae, 0x9, 0xa9, 0xa2, 0x1f, 0x24, 0xbb, 0x9e \
+ }
+
+//
+// Heci Bus Disable defines
+//
+#define HECI_BUS_DISABLE_OPCODE 0x0C
+#define HECI_BUS_DISABLE_ACK_OPCODE 0x8C
+#define ME_HECI_FIXED_ADDRESS 0x0
+
+//
+// Defines the HECI request buffer format for the ICC_MPHY_WRITE_SETTINGS_CMD.
+//
+typedef struct _ICC_MPHY_WRITE_SETTINGS_REQ
+{
+ ICC_HEADER Header; // Standard ICC HECI Header
+ UINT32 Reserved : 4; // Reserved for future use
+ UINT32 PostedWrite : 1; // 0-Response returned, 1-No Response returned
+ UINT32 Reserved2 : 23; // Reserved for future use
+}MPHY_WRITE_SETTINGS_REQ;
+
+typedef union _HBM_COMMAND {
+ UINT8 Data;
+ struct {
+ UINT8 Command : 7;
+ UINT8 IsResponse : 1;
+ } Fields;
+} HBM_COMMAND;
+
+typedef struct _HECI_BUS_DISABLE_CMD {
+ HBM_COMMAND Command;
+ UINT8 Reserved[3];
+} HECI_BUS_DISABLE_CMD;
+
+typedef struct _HECI_BUS_DISABLE_CMD_ACK {
+ HBM_COMMAND Command;
+ UINT8 Status;
+ UINT8 Reserved[2];
+} HECI_BUS_DISABLE_CMD_ACK;
+
+typedef struct {
+ UINT32 MeEnabled : 1; ///< [0] ME enabled/Disabled
+ UINT32 Reserved : 2; ///< [2:1] Reserved, must set to 0
+ UINT32 IntelAmtFw : 1; ///< [3] Intel AMT FW support
+ UINT32 IntelAmtFwStandard : 1; ///< [4] Intel AMT Standard FW support
+ UINT32 IntelSmallBusiness : 1; ///< [5] Intel Small Business Technology support
+ UINT32 Reserved1 : 7; ///< [12:6] Reserved
+ UINT32 AtSupported : 1; ///< [13] AT Support
+ UINT32 IntelKVM : 1; ///< [14] Intel KVM supported
+ UINT32 LocalWakeupTimer : 1; ///< [15] Local Wakeup Timer support
+ UINT32 Reserved2 : 16; ///< [31:16] Reserved, must set to 0
+ UINT32 MeMinorVer : 16; ///< [47:32] ME FW Minor Version.
+ UINT32 MeMajorVer : 16; ///< [63:48] ME FW Major Version.
+ UINT32 MeBuildNo : 16; ///< [79:64] ME FW Build Number.
+ UINT32 MeHotFixNo : 16; ///< [95:80] ME FW Hotfix Number
+} ME_CAP;
+
+#define MAX_ASSET_TABLE_ALLOCATED_SIZE 0x3000
+#define HECI_HWA_CLIENT_ID 11
+#define HWA_TABLE_PUSH_CMD 0
+
+#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 FRUTablePresent : 1;
+ UINT32 MediaTablePresent : 1;
+ UINT32 SMBIOSTablePresent : 1;
+ UINT32 ASFTablePresent : 1;
+ UINT32 Reserved : 8;
+ } Fields;
+} AU_MESSAGE_HEADER;
+
+typedef struct _AU_TABLE_PUSH_MSG {
+ AU_MESSAGE_HEADER Header;
+ TABLE_PUSH_DATA Data;
+} AU_TABLE_PUSH_MSG;
+
+typedef enum {
+ SEV_NO_ERROR = 0,
+ SEV_LOW_ERROR,
+ SEV_HIGH_ERROR,
+ SEV_CRITICAL_ERROR
+} MDES_SEVERITY_LEVEL;
+
+typedef enum {
+ EFI_STATUS_CODE = 1,
+ RAW_BUFFER,
+ ASCII_DATA,
+} MDES_BIOS_PAYLOAD_TYPE;
+
+#pragma pack()
+
+/**
+ Send the required system ChipsetInit Table to ME FW.
+
+ @param[in] ChipsetInitTable The required system ChipsetInit Table.
+ @param[in] ChipsetInitTableLen Length of the table in bytes
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciChipsetInitSyncMsg (
+ IN UINT8 *ChipsetInitTable,
+ IN UINT32 ChipsetInitTableLen
+ )
+;
+
+/**
+ Send Core BIOS Reset Request Message through HECI to reset the system.
+
+ @param[in] ResetOrigin Reset source
+ @param[in] ResetType Global or Host reset
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+**/
+EFI_STATUS
+HeciSendCbmResetRequest (
+ IN UINT8 ResetOrigin,
+ IN UINT8 ResetType
+ )
+;
+
+/**
+ Send Hardware Asset Tables to Firmware
+
+ @param[in] Handle A handle for this module
+ @param[in] AssetTableData Hardware Asset Table Data
+ @param[in] TableDataSize Size of Asset table
+
+ @retval EFI_SUCCESS Table sent
+ @retval EFI_ABORTED Could not allocate Memory
+**/
+EFI_STATUS
+HeciAssetUpdateFwMsg (
+ IN EFI_HANDLE Handle,
+ IN TABLE_PUSH_DATA *AssetTableData,
+ IN UINT16 TableDataSize
+ )
+;
+
+/**
+ Send End of Post Request Message through HECI.
+
+ @param[in] Handle A handle for this module
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciSendEndOfPostMessage (
+ IN EFI_HANDLE Handle
+ )
+;
+
+/**
+ Send Get Firmware SKU Request to ME
+
+ @param[in] MsgGenGetFwCapsSku Return message for Get Firmware Capability SKU
+ @param[in] MsgGenGetFwCapsSkuAck Return message for Get Firmware Capability SKU ACK
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge
+**/
+EFI_STATUS
+HeciGetFwCapsSkuMsg (
+ IN OUT GEN_GET_FW_CAPSKU *MsgGenGetFwCapsSku,
+ IN OUT GEN_GET_FW_CAPS_SKU_ACK *MsgGenGetFwCapsSkuAck
+ )
+;
+
+/**
+ Send Get Firmware Version Request to ME
+
+ @param[in][out] MsgGenGetFwVersionAck Return themessage of FW version
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge
+**/
+EFI_STATUS
+HeciGetFwVersionMsg (
+ IN OUT GEN_GET_FW_VER_ACK *MsgGenGetFwVersionAck
+ )
+;
+
+/**
+ Sends a message to ME to unlock a specified SPI Flash region for writing and receiving a response message.
+ It is recommended that HMRFPO_ENABLE MEI message needs to be sent after all OROMs finish their initialization.
+
+ @param[in] Nonce Nonce received in previous HMRFPO_ENABLE Response Message
+ @param[in] Result HMRFPO_ENABLE response
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+**/
+EFI_STATUS
+HeciHmrfpoEnable (
+ IN UINT64 Nonce,
+ OUT UINT8 *Result
+ )
+;
+
+/**
+ Sends a message to ME to lock a specified SPI Flash region for writing and receiving a response message.
+
+ @param[out] Nonce Random number generated by Ignition ME 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
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+**/
+EFI_STATUS
+HeciHmrfpoLock (
+ OUT UINT64 *Nonce,
+ OUT UINT32 *FactoryDefaultBase,
+ OUT UINT32 *FactoryDefaultLimit,
+ OUT UINT8 *Result
+ )
+;
+
+/**
+ System BIOS sends this message to get status for HMRFPO_LOCK message.
+
+ @param[out] Result HMRFPO_GET_STATUS response
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+**/
+EFI_STATUS
+HeciHmrfpoGetStatus (
+ OUT UINT8 *Result
+ )
+;
+
+/**
+ This is used to send KVM request message to Intel ME. When
+ Bootoptions indicate that a KVM session is requested then BIOS
+ will send this message before any graphical display output to
+ ensure that FW is ready for KVM session.
+
+ @param[in] QueryType 0 - Query Request
+ 1 - Cancel Request
+ @param[out] ResponseCode 1h - Continue, KVM session established.
+ 2h - Continue, KVM session cancelled.
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciQueryKvmRequest (
+ IN UINT32 QueryType,
+ OUT UINT32 *ResponseCode
+ )
+;
+
+/**
+ 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
+
+ @exception EFI_UNSUPPORTED Current ME 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 UINT8 *RuleData
+ )
+;
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP) on the boot
+ where host wants to enable 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
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Command succeeded
+ @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally
+ @retval EFI_TIMEOUT HECI does not return the buffer before timeout
+ @retval EFI_BUFFER_TOO_SMALL Message Buffer is too smallfor the Acknowledge
+**/
+EFI_STATUS
+HeciSetLocalFwUpdate (
+ IN UINT8 RuleData
+ )
+;
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to enable the ME 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
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS ME enabled message sent
+**/
+EFI_STATUS
+HeciSetMeEnableMsg (
+ VOID
+ )
+;
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to disable the ME 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] None
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS ME is disabled
+**/
+EFI_STATUS
+HeciSetMeDisableMsg (
+ VOID
+ )
+;
+
+/**
+ This message is sent by the BIOS or IntelR MEBX prior to the End of Post (EOP)
+ on the boot where host wants to get Ibex Peak platform type.
+ One of usages is to utilize this command to determine if the platform runs in
+ 1.5M or 5M size firmware.
+
+ @param[in] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @exception EFI_UNSUPPORTED Current ME 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
+ )
+;
+
+/**
+ This message is sent by the BIOS on the boot where the host wants to get the firmware provisioning state.
+ The firmware will respond to AMT BIOS SYNCH INFO message even after the End of Post.
+
+ @param[out] RuleData Bit [2:0] Reserved
+ Bit [4:3] Provisioning State
+ 00 - Pre -provisioning
+ 01 - In -provisioning
+ 02 - Post !Vprovisioning
+ Bit [31:5] Reserved
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Firmware provisioning state returned
+ @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
+HeciAmtBiosSynchInfo (
+ OUT UINT32 *RuleData
+ )
+;
+
+/**
+ The firmware will respond to GET OEM TAG message even after the End of Post (EOP).
+
+ @param[in] RuleData Default is zero. Tool can create the OEM specific OEM TAG data.
+
+ @exception EFI_UNSUPPORTED Current ME 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
+ )
+;
+
+/**
+ Enables/disables clocks. Used to turn off clocks in unused pci/pcie slots.
+ BIOS use this command when it enumerates PCI slots. When PCI slot is found unpopulated, the
+ BIOS can disable its clock through this MEI message. It is the BIOS requirement to know which
+ slot is controlled by which control bit.
+
+ @param[in] Enables each bit means corresponding clock should be turned on (1) or off (0)
+ @param[in] EnablesMask each bit means corresponding enable bit is valid (1) or should be ignored (0)
+ @param[in] ResponseMode 0 wait for response, 1 - skip
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY ME is not ready
+ @retval EFI_INVALID_PARAMETER ResponseMode is invalid value
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+HeciSetIccClockEnables (
+ IN UINT32 Enables,
+ IN UINT32 EnablesMask,
+ IN UINT8 ResponseMode
+ )
+;
+
+/**
+ Sets or reads Lock mask on ICC registers.
+ @param[in] AccessMode 0 - set, 1 - get
+ @param[in] ResponseMode 0 - firmware will answer, 1 - firmware will not answer
+ @param[in][out] LockRegInfo bundle count info and mask of registers to become (for 'set' mode) or are
+ (for 'get' mode) locked. Each bit represents a register. 0=lock, 1=don't lock
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_INVALID_PARAMETER ResponseMode or pointer of Mask is invalid value
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciLockIccRegisters (
+ IN UINT8 AccessMode,
+ IN UINT8 ResponseMode,
+ IN OUT ICC_LOCK_REGS_INFO *LockRegInfo
+ )
+;
+
+/**
+ retrieves the number of currently used ICC clock profile
+
+ @param[out] Profile number of current ICC clock profile
+
+ @exception EFI_UNSUPPORTED ICC clock profile doesn't support
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciGetIccProfile (
+ OUT UINT8 *Profile
+ )
+;
+
+/**
+ Sets ICC clock profile to be used on next and following boots
+
+ @param[in] Profile number of profile to be used
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY Heci device hasn't ready yet
+**/
+EFI_STATUS
+HeciSetIccProfile (
+ IN UINT8 Profile
+ )
+;
+
+/**
+ Writes 1 dword of data to the icc register offset specified by RegOffset in the ICC Aux space
+ @param[in] RegOffset Register Offset in ICC Aux Space to write
+ @param[in] RegData Dword ICC register data to write
+ @param[in] ResponseMode 0 Wait for response, 1 - skip
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_DEVICE_ERROR Wrong response
+ @retval EFI_NOT_READY ME is not ready
+ @retval EFI_INVALID_PARAMETER ResponseMode is invalid value
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+HeciWriteIccRegDword (
+ IN UINT16 RegOffset,
+ IN UINT32 RegData,
+ IN UINT8 ResponseMode
+ )
+;
+/**
+ This message is used to turn on the Intel ME firmware MDES
+ capability, Intel SVT for PCH capability or both when the
+ system is in a post-manufactured state. Once firmware receives
+ this message, the firmware will enable selected platform debug
+ capabilities . The firmware will automatically disable all
+ platform debug capabilities if this message is not received
+ before receiving End Of Post.
+
+ @param[in] Data capabilities to be enabled
+ @param[out] Result 0x00 : Enable Success
+ Others : Enable Failure
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciPlatformDebugCapabilityMsg (
+ IN PLATFORM_DEBUG_CAP Data,
+ OUT UINT8 *Result
+ )
+;
+
+/**
+ It creates and sends Heci messages.
+
+ Remark:
+ Functionality is available only in release mode.
+ Using MDES in debug mode causes recursive calling of this function
+ because debug messages are sending from Heci->SendMsg function.
+
+ @param[in] CodeType Indicates the type of status code being reported.
+ @param[in] Value Describes the current status of a hardware or software entity.
+ This included information about the class and subclass that is
+ used to classify the entity as well as an operation.
+ @param[in] Instance The enumeration of a hardware or software entity within
+ the system. Valid instance numbers start with 1.
+ @param[in] CallerId This optional parameter may be used to identify the caller.
+ This parameter allows the status code driver to apply different
+ rules to different callers.
+ @param[in] Data This optional parameter may be used to pass additional data.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS Opcode evaluation success.
+ @retval Other Opcode evaluation failed.
+**/
+EFI_STATUS
+HeciSendMdesStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID * CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA * Data OPTIONAL
+ )
+;
+
+/**
+ Provides an interface to call function to send HECI message.
+
+ @param[in] Flags Indicates the status of the BIOS MDES.
+ @param[in] BiosEventFilters Indicates the status of the BIOS event filter group.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI sent with success.
+**/
+EFI_STATUS
+HeciGetMdesConfig (
+ OUT MDES_BIOS_FLAGS *Flags,
+ OUT UINT32 *BiosEventFilters
+ )
+;
+
+
+/**
+ Sends the MKHI Enable/Disable manageability message.
+ The message will only work if bit 2 in the bitmasks is toggled.
+ To enable manageability:
+ EnableState = 0x00000004, and
+ DisableState = 0x00000000.
+ To disable manageability:
+ EnableState = 0x00000000, and
+ DisableState = 0x00000004
+
+ @param[in] EnableState Enable Bit Mask
+ @param[in] DisableState Disable Bit Mask
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciFwFeatureStateOverride (
+ IN UINT32 EnableState,
+ IN UINT32 DisableState
+ )
+;
+
+/**
+ The Get FW Feature Status message is based on MKHI interface.
+ This command is used by BIOS/IntelR MEBX to get firmware runtime status.
+ The GET FW RUNTIME STATUS message doesn't need to check the HFS.
+ FWInitComplete value before sending the command.
+ It means this message can be sent regardless of HFS.FWInitComplete.
+
+ @param[out] RuleData MEFWCAPS_SKU message
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+**/
+EFI_STATUS
+HeciGetFwFeatureStateMsg (
+ OUT MEFWCAPS_SKU *RuleData
+ )
+;
+
+/**
+ This message is sent by the BIOS when it wants to query
+ the independent firmware recovery (IFR).
+
+ @param[in] RuleData 1 - local firmware update interface enable
+
+ 0 - local firmware update interface disable
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciGetIfrUpdate (
+ OUT UINT8 *RuleData
+ )
+;
+
+/**
+ This message is sent by the BIOS when it wants to set
+ the independent firmware recovery (IFR) state.
+
+ @param[in] RuleData 1 - local firmware update interface enable
+ 0 - local firmware update interface disable
+
+ @exception EFI_UNSUPPORTED Current ME 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
+HeciSetIfrUpdate (
+ IN UINT8 RuleData
+ )
+;
+
+/**
+ This message is sent by the BIOS if EOP-ACK not received to force ME to disable
+ HECI interfaces.
+
+ @param[in] None
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI interfaces disabled by ME
+**/
+EFI_STATUS
+HeciDisableHeciBusMsg (
+ VOID
+ )
+;
+
+/**
+ This message is sent by the BIOS to inform ME FW whether or not to take the
+ TPM 1.2 Deactivate flow
+
+ @param[in] UINT8 TpmDeactivate 0 - ME FW should not take the
+ deactivate flow.
+ 1 - ME FW should take the deactivate
+ flow.
+
+ @exception EFI_UNSUPPORTED Current ME mode doesn't support this function
+ @retval EFI_SUCCESS HECI interfaces disabled by ME
+**/
+EFI_STATUS
+HeciSendTpmData (
+ IN UINT8 TpmDeactivate
+ )
+;
+
+#endif
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MbpDebugDumpDxe.c b/ReferenceCode/ME/Library/MeKernel/Dxe/MbpDebugDumpDxe.c
new file mode 100644
index 0000000..b7cc842
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MbpDebugDumpDxe.c
@@ -0,0 +1,150 @@
+/** @file
+ Dump whole DXE_MBP_DATA_PROTOCOL and serial out.
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include EFI_PROTOCOL_CONSUMER (MeBiosPayloadData)
+#endif
+
+/**
+ Dump DXE_MBP_DATA_PROTOCOL
+
+ @param[in] MbpData Pointer to DXE_MBP_DATA_PROTOCOL
+
+ @retval None
+**/
+VOID
+DxeMbpDebugDump (
+ IN DXE_MBP_DATA_PROTOCOL *MbpPtr
+ )
+{
+ UINTN i;
+
+ if (MbpPtr == NULL) {
+ return;
+ }
+ DEBUG ((EFI_D_INFO, "\n------------------------ MeBiosPayload Data Protocol Dump Begin -----------------\n"));
+ DEBUG ((EFI_D_INFO, " Revision : 0x%x\n", MbpPtr->Revision));
+ DEBUG ((EFI_D_INFO, "MeBiosPayload FwVersionName ---\n"));
+ DEBUG ((EFI_D_INFO, " ME FW MajorVersion : 0x%x\n", MbpPtr->MeBiosPayload.FwVersionName.MajorVersion));
+ DEBUG ((EFI_D_INFO, " ME FW MinorVersion : 0x%x\n", MbpPtr->MeBiosPayload.FwVersionName.MinorVersion));
+ DEBUG ((EFI_D_INFO, " ME FW HotfixVersion : 0x%x\n", MbpPtr->MeBiosPayload.FwVersionName.HotfixVersion));
+ DEBUG ((EFI_D_INFO, " ME FW BuildVersion : 0x%x\n", MbpPtr->MeBiosPayload.FwVersionName.BuildVersion));
+
+ if (MbpPtr->MeBiosPayload.FwCapsSku.Available == TRUE) {
+ DEBUG ((EFI_D_INFO, "MeBiosPayload FwCapabilities ---\n"));
+ DEBUG ((EFI_D_INFO, " FullNet : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.FullNet));
+ DEBUG ((EFI_D_INFO, " StdNet : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.StdNet));
+ DEBUG ((EFI_D_INFO, " Manageability : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.Manageability));
+ DEBUG ((EFI_D_INFO, " SmallBusiness : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.SmallBusiness));
+ DEBUG ((EFI_D_INFO, " IntelAT : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IntelAT));
+ DEBUG ((EFI_D_INFO, " IntelCLS : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IntelCLS));
+ DEBUG ((EFI_D_INFO, " IntelMPC : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IntelMPC));
+ DEBUG ((EFI_D_INFO, " IccOverClocking : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IccOverClocking));
+ DEBUG ((EFI_D_INFO, " PAVP : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.PAVP));
+ DEBUG ((EFI_D_INFO, " IPV6 : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IPV6));
+ DEBUG ((EFI_D_INFO, " KVM : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.KVM));
+ DEBUG ((EFI_D_INFO, " OCH : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.OCH));
+ DEBUG ((EFI_D_INFO, " VLAN : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.VLAN));
+ DEBUG ((EFI_D_INFO, " TLS : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.TLS));
+ DEBUG ((EFI_D_INFO, " WLAN : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.WLAN));
+ DEBUG ((EFI_D_INFO, " NFC : 0x%x\n", MbpPtr->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.NFC));
+ }
+
+ if (MbpPtr->MeBiosPayload.FwFeaturesState.Available == TRUE) {
+ DEBUG ((EFI_D_INFO, "MeBiosPayload FwFeaturesState ---\n"));
+ DEBUG ((EFI_D_INFO, " FullNet : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.FullNet));
+ DEBUG ((EFI_D_INFO, " StdNet : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.StdNet));
+ DEBUG ((EFI_D_INFO, " Manageability : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.Manageability));
+ DEBUG ((EFI_D_INFO, " SmallBusiness : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.SmallBusiness));
+ DEBUG ((EFI_D_INFO, " IntelAT : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.IntelAT));
+ DEBUG ((EFI_D_INFO, " IntelCLS : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.IntelCLS));
+ DEBUG ((EFI_D_INFO, " IntelMPC : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.IntelMPC));
+ DEBUG ((EFI_D_INFO, " IccOverClocking : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.IccOverClocking));
+ DEBUG ((EFI_D_INFO, " PAVP : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.PAVP));
+ DEBUG ((EFI_D_INFO, " IPV6 : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.IPV6));
+ DEBUG ((EFI_D_INFO, " KVM : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.KVM));
+ DEBUG ((EFI_D_INFO, " OCH : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.OCH));
+ DEBUG ((EFI_D_INFO, " VLAN : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.VLAN));
+ DEBUG ((EFI_D_INFO, " TLS : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.TLS));
+ DEBUG ((EFI_D_INFO, " WLAN : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.WLAN));
+ DEBUG ((EFI_D_INFO, " NFC : 0x%x\n", MbpPtr->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.NFC));
+ }
+
+ DEBUG ((EFI_D_INFO, "MeBiosPayload RomBistData ---\n"));
+ DEBUG ((EFI_D_INFO, " DeviceId : 0x%x\n", MbpPtr->MeBiosPayload.RomBistData.DeviceId));
+ DEBUG ((EFI_D_INFO, " FuseTestFlags : 0x%x\n", MbpPtr->MeBiosPayload.RomBistData.FuseTestFlags));
+ for (i = 0; i < 4; i++) {
+ DEBUG ((EFI_D_INFO, " UMCHID[0x%x] : 0x%x \n", i, MbpPtr->MeBiosPayload.RomBistData.UMCHID[i]));
+ }
+
+ DEBUG ((EFI_D_INFO, "MeBiosPayload Platform Key ---\n"));
+ for (i = 0; i < 8; i++) {
+ DEBUG ((EFI_D_INFO, " Key[0x%x] : 0x%x \n", i, MbpPtr->MeBiosPayload.PlatformKey.Key[i]));
+ }
+
+ if (MbpPtr->MeBiosPayload.FwPlatType.Available == TRUE) {
+ DEBUG ((EFI_D_INFO, "MeBiosPayload ME Platform TYpe ---\n"));
+ DEBUG ((EFI_D_INFO, " PlatformTargetUsageType : 0x%x\n", MbpPtr->MeBiosPayload.FwPlatType.RuleData.Fields.PlatformTargetUsageType));
+ DEBUG ((EFI_D_INFO, " PlatformTargetMarketType : 0x%x\n", MbpPtr->MeBiosPayload.FwPlatType.RuleData.Fields.PlatformTargetMarketType));
+ DEBUG ((EFI_D_INFO, " SuperSku : 0x%x\n", MbpPtr->MeBiosPayload.FwPlatType.RuleData.Fields.SuperSku));
+ DEBUG ((EFI_D_INFO, " IntelMeFwImageType : 0x%x\n", MbpPtr->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType));
+ DEBUG ((EFI_D_INFO, " PlatformBrand : 0x%x\n", MbpPtr->MeBiosPayload.FwPlatType.RuleData.Fields.PlatformBrand));
+ }
+
+ DEBUG ((EFI_D_INFO, "MeBiosPayload IccProfile ---\n"));
+ DEBUG ((EFI_D_INFO, " NumIccProfiles : 0x%x\n", MbpPtr->MeBiosPayload.IccProfile.NumIccProfiles));
+ DEBUG ((EFI_D_INFO, " IccProfileSoftStrap : 0x%x\n", MbpPtr->MeBiosPayload.IccProfile.IccProfileSoftStrap));
+ DEBUG ((EFI_D_INFO, " IccProfileIndex : 0x%x\n", MbpPtr->MeBiosPayload.IccProfile.IccProfileIndex));
+ DEBUG ((EFI_D_INFO, " RegBundles : 0x%x\n", MbpPtr->MeBiosPayload.IccProfile.IccLockRegInfo.RegBundles));
+ for (i = 0; i < MbpPtr->MeBiosPayload.IccProfile.IccLockRegInfo.RegBundles.BundlesCnt; i++) {
+ DEBUG ((EFI_D_INFO, " RegMask[0x%x] : 0x%x\n", i, MbpPtr->MeBiosPayload.IccProfile.IccLockRegInfo.RegMask[i]));
+ }
+
+ DEBUG ((EFI_D_INFO, "MeBiosPayload AtState ---\n"));
+ DEBUG ((EFI_D_INFO, " State : 0x%x\n", MbpPtr->MeBiosPayload.AtState.State));
+ DEBUG ((EFI_D_INFO, " LastTheftTrigger : 0x%x\n", MbpPtr->MeBiosPayload.AtState.LastTheftTrigger));
+ DEBUG ((EFI_D_INFO, " LockState : 0x%x\n", MbpPtr->MeBiosPayload.AtState.flags.LockState));
+ DEBUG ((EFI_D_INFO, " AuthenticateModule : 0x%x\n", MbpPtr->MeBiosPayload.AtState.flags.AuthenticateModule));
+ DEBUG ((EFI_D_INFO, " S3Authentication : 0x%x\n", MbpPtr->MeBiosPayload.AtState.flags.S3Authentication));
+ DEBUG ((EFI_D_INFO, " FlashWearOut : 0x%x\n", MbpPtr->MeBiosPayload.AtState.flags.FlashWearOut));
+ DEBUG ((EFI_D_INFO, " FlashVariableSecurity : 0x%x\n", MbpPtr->MeBiosPayload.AtState.flags.FlashVariableSecurity));
+
+ DEBUG ((EFI_D_INFO, "MeBiosPayload MFSIntegrity: 0x%x\n", MbpPtr->MeBiosPayload.MFSIntegrity));
+
+ if (MbpPtr->MeBiosPayload.HwaRequest.Available == TRUE) {
+ DEBUG ((EFI_D_INFO, "MeBiosPayload HwaRequest ---\n"));
+ DEBUG ((EFI_D_INFO, " MediaTablePush : 0x%x\n", MbpPtr->MeBiosPayload.HwaRequest.Data.Fields.MediaTablePush));
+ }
+
+ if (MbpPtr->MeBiosPayload.NfcSupport.Available == TRUE) {
+ DEBUG ((EFI_D_INFO, "MeBiosPayload NFC ---\n"));
+ DEBUG ((EFI_D_INFO, " DeviceType : 0x%x\n", MbpPtr->MeBiosPayload.NfcSupport.NfcData.DeviceType));
+ DEBUG ((EFI_D_INFO, " Hide : 0x%x\n", MbpPtr->MeBiosPayload.NfcSupport.NfcData.Hide));
+ }
+
+ DEBUG ((EFI_D_INFO, "\n------------------------ MeBiosPayload Data Protocol Dump End -------------------\n"));
+}
+
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.c b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.c
new file mode 100644
index 0000000..b0df6c6
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.c
@@ -0,0 +1,712 @@
+/** @file
+ This is a library to get Intel ME information
+
+@copyright
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "MeLib.h"
+#include "MeAccess.h"
+#endif
+
+/**
+ Check if Me is enabled
+
+ @param[in] None.
+
+ @retval None
+**/
+EFI_STATUS
+MeLibInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ return Status;
+}
+
+/**
+ Send Get Firmware SKU Request to ME
+
+ @param[in] FwCapsSku Return Data from Get Firmware Capabilities MKHI Request
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+HeciGetFwCapsSku (
+ MEFWCAPS_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[in] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+HeciGetPlatformType (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+{
+ EFI_STATUS Status;
+
+ Status = HeciGetPlatformTypeMsg (RuleData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+MbpGiveUp (
+ IN VOID
+ )
+{
+ UINT32 HECI_BASE_ADDRESS;
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr;
+
+ HECI_BASE_ADDRESS = PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_HECIMBAR)) & 0xFFFFFFF0;
+ HeciRegHCsrPtr = (VOID *) (UINTN) (HECI_BASE_ADDRESS + H_CSR);
+
+ //
+ // Set MBP_GIVE_UP bit
+ //
+ HeciPciOr32(R_ME_H_GS2, B_ME_MBP_GIVE_UP);
+
+ //
+ // Set H_RST and H_IG bits to reset HECI
+ //
+ HeciRegHCsr.ul = HeciRegHCsrPtr->ul;
+ HeciRegHCsr.r.H_RST = 1;
+ HeciRegHCsr.r.H_IG = 1;
+ HeciRegHCsrPtr->ul = HeciRegHCsr.ul;
+}
+
+/**
+ Routine checks whether MBP buffer has been cleared form HECI buffer or not.
+ BIOS must check this before executing any 3rd paty code or Oprom
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+**/
+VOID
+EFIAPI
+MbpCleared (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ HECI_GS_SHDW_REGISTER MeFwsts2;
+ DXE_MBP_DATA_PROTOCOL *MbpData;
+ HECI_FWS_REGISTER MeFirmwareStatus;
+ UINT32 Timeout;
+
+ gBS->CloseEvent (Event);
+
+ Status = gBS->LocateProtocol (&gMeBiosPayloadDataProtocolGuid, NULL, (VOID **) &MbpData);
+ if (!EFI_ERROR (Status)) {
+ //
+ // UnInstall the MBP protocol
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ MbpData->Handle,
+ &gMeBiosPayloadDataProtocolGuid,
+ MbpData,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to Uninstall Mbp protocol and Status is %r\n", Status));
+ }
+ }
+
+ //
+ // Check for MEI1 PCI device availability
+ //
+ if (HeciPciRead32 (R_VENDORID) == 0xFFFFFFFF) {
+ DEBUG ((EFI_D_ERROR, "MEI1 PCI device does not exist\n"));
+ return;
+ }
+
+ //
+ // BIOS polls on FWSTS.MbpCleared until it is set or 1s timeout reached
+ //
+ Timeout = 0;
+
+ do {
+ MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW);
+
+ if (MeFwsts2.r.MbpCleared) {
+ break;
+ }
+
+ gBS->Stall (FIVE_MS_TIMEOUT);
+ Timeout += FIVE_MS_TIMEOUT;
+ } while (Timeout <= HECI_MBP_CLR_TIMEOUT);
+
+ DEBUG ((EFI_D_ERROR, "MbpCleared = %x\n", MeFwsts2.r.MbpCleared));
+
+ if (!MeFwsts2.r.MbpCleared) {
+ MbpGiveUp();
+ }
+
+ MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE);
+ if (MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_UNKNOWN || MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_IMAGE_FAILURE) {
+ DisableAllMEDevices ();
+ }
+
+ return;
+}
+
+/**
+ Calculate if the circular buffer has overflowed.
+ Corresponds to HECI HPS (part of) section 4.2.1
+
+ @param[in] ReadPointer Location of the read pointer.
+ @param[in] WritePointer Location of the write pointer.
+
+ @retval UINT8 Number of filled slots.
+**/
+UINT8
+FilledSlots2 (
+ IN UINT32 ReadPointer,
+ IN UINT32 WritePointer
+ )
+{
+ UINT8 FilledSlots;
+
+ ///
+ /// Calculation documented in HECI HPS 0.68 section 4.2.1
+ ///
+ FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer));
+
+ return FilledSlots;
+}
+
+/**
+ This routine returns ME-BIOS Payload information.
+
+ @param[out] MbpPtr ME-BIOS Payload information.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_DEVICE_ERROR Failed to consume MBP
+**/
+EFI_STATUS
+PrepareMeBiosPayload (
+ OUT ME_BIOS_PAYLOAD *MbpPtr
+ )
+{
+ EFI_STATUS Status;
+ UINT32 *Ptr;
+ UINT32 MbpItemId;
+ UINT32 MbpItemSize;
+ UINT32 i;
+ UINT32 Index;
+ UINT32 Timeout;
+ UINT8 MbpReadAttempts;
+ MBP_HEADER MbpHeader;
+ MBP_ITEM_HEADER MbpItemHeader;
+ VOID *Registration;
+ EFI_EVENT Event;
+
+ HECI_GS_SHDW_REGISTER MeFwsts2;
+ UINT32 HECI_BASE_ADDRESS;
+ HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa;
+ HECI_HOST_CONTROL_REGISTER HeciRegHCsr;
+ VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr;
+ VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr;
+ VOLATILE UINT32 *HeciRegMeCbrwPtr;
+ VOID *DestPtr;
+ UINTN DestSize;
+ BOOLEAN MbpReadError;
+
+ Ptr = NULL;
+ Status = EFI_SUCCESS;
+
+ //
+ // Initialize memory mapped register pointers
+ //
+ HECI_BASE_ADDRESS = PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_HECIMBAR)) & 0xFFFFFFF0;
+ HeciRegHCsrPtr = (VOID *) (UINTN) (HECI_BASE_ADDRESS + H_CSR);
+ HeciRegMeCsrHaPtr = (VOID *) (UINTN) (HECI_BASE_ADDRESS + ME_CSR_HA);
+ HeciRegMeCbrwPtr = (VOID *) (UINTN) (HECI_BASE_ADDRESS + ME_CB_RW);
+
+ MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW);
+
+ for (MbpReadAttempts = 0; MbpReadAttempts <= HECI_MBP_READ_MAX_RETRIES; MbpReadAttempts++) {
+
+ DEBUG ((EFI_D_INFO, "MbpPresent = %x\n", MeFwsts2.r.MbpRdy));
+
+ if (MeFwsts2.r.MbpRdy) {
+
+ MbpReadError = FALSE;
+ HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul;
+
+ if (FilledSlots2 (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) == 0) {
+ //
+ // Exit if the circular buffer is empty
+ //
+ DEBUG ((EFI_D_ERROR, "MBP is present but circular buffer is empty, exit.\n"));
+ MbpReadError = TRUE;
+ } else {
+
+ MbpHeader.Data = *HeciRegMeCbrwPtr;
+
+ DEBUG ((EFI_D_INFO, "MBP header: %x\n", MbpHeader.Data));
+ DEBUG ((EFI_D_INFO, "MbpSize: %x\n", MbpHeader.Fields.MbpSize));
+ DEBUG ((EFI_D_INFO, "No. of Mbp Entries: %x\n", MbpHeader.Fields.NumEntries));
+
+ MbpPtr->FwCapsSku.Available = FALSE;
+ MbpPtr->FwPlatType.Available = FALSE;
+ MbpPtr->HwaRequest.Available = FALSE;
+ MbpPtr->PlatBootPerfData.Available = FALSE;
+ MbpPtr->HwaRequest.Data.Fields.MediaTablePush = FALSE;
+ MbpPtr->NfcSupport.Available = FALSE;
+
+ for (i = 0; i < MbpHeader.Fields.NumEntries; i++) {
+ //
+ // If MBP Data Item is available but, RD and WR pointer are same, it indicates an error
+ // ME FW indication of number of MBP entries and size are wrong
+ //
+ HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul;
+ if (FilledSlots2 (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) == 0) {
+ //
+ // Exit if the circular buffer is empty
+ //
+ DEBUG ((EFI_D_ERROR, "MBP Item is present but circular buffer is empty, exit.\n"));
+ MbpReadError = TRUE;
+ break;
+ }
+ //
+ // Consume MBP Item Header
+ //
+ MbpItemHeader.Data = *HeciRegMeCbrwPtr;
+ DEBUG ((EFI_D_INFO, "MBP Item %x header: %x\n", i + 1, MbpItemHeader.Data));
+
+ MbpItemId = (MbpItemHeader.Fields.AppId << 4) | MbpItemHeader.Fields.ItemId;
+ //
+ // Copy data from HECI buffer per size of each MBP item
+ //
+ MbpItemSize = MbpItemHeader.Fields.Length - 1;
+ Ptr = AllocateZeroPool ((MbpItemSize) * 4);
+ ASSERT (Ptr);
+ if (Ptr == NULL) {
+ goto MbpGiveup;
+ }
+
+ for (Index = 0; Index < MbpItemSize; Index++) {
+ Ptr[Index] = *HeciRegMeCbrwPtr;
+ DEBUG ((EFI_D_INFO, "MBP Item Data: %x\n", Ptr[Index]));
+ }
+
+ switch (MbpItemId) {
+ case 0x11:
+ //
+ // FW Version Name
+ //
+ DestSize = sizeof (MbpPtr->FwVersionName);
+ DestPtr = &MbpPtr->FwVersionName;
+ break;
+
+ case 0x12:
+ //
+ // FW Capabilities
+ //
+ DestSize = sizeof (MbpPtr->FwCapsSku.FwCapabilities);
+ DestPtr = &MbpPtr->FwCapsSku.FwCapabilities;
+ MbpPtr->FwCapsSku.Available = TRUE;
+ break;
+
+ case 0x13:
+ //
+ // ROM BIST Data
+ //
+ DestSize = sizeof (MbpPtr->RomBistData);
+ DestPtr = &MbpPtr->RomBistData;
+ break;
+
+ case 0x14:
+ //
+ // Platform Key
+ //
+ DestSize = sizeof (MbpPtr->PlatformKey);
+ DestPtr = &MbpPtr->PlatformKey;
+ break;
+
+ case 0x15:
+ //
+ // ME Platform TYpe
+ //
+ DestSize = sizeof (MbpPtr->FwPlatType.RuleData);
+ DestPtr = &MbpPtr->FwPlatType.RuleData;
+ MbpPtr->FwPlatType.Available = TRUE;
+ break;
+
+ case 0x16:
+ //
+ // ME MFS status
+ //
+ DestSize = sizeof (MbpPtr->MFSIntegrity);
+ DestPtr = &MbpPtr->MFSIntegrity;
+ break;
+
+ case 0x17:
+ ///
+ /// Platform timing information
+ ///
+ DestSize = sizeof (MbpPtr->PlatBootPerfData.MbpPerfData);
+ DestPtr = &MbpPtr->PlatBootPerfData.MbpPerfData;
+ MbpPtr->PlatBootPerfData.Available = TRUE;
+ break;
+
+ case 0x19:
+ //
+ // FW Features State
+ //
+ DestSize = sizeof (MbpPtr->FwFeaturesState.FwFeatures);
+ DestPtr = &MbpPtr->FwFeaturesState.FwFeatures;
+ MbpPtr->FwFeaturesState.Available = TRUE;
+ break;
+
+ case 0x31:
+ //
+ // AT State
+ //
+ DestSize = sizeof (MbpPtr->AtState);
+ DestPtr = &MbpPtr->AtState;
+ break;
+
+ case 0x41:
+ //
+ // HWA Request
+ //
+ DestSize = sizeof (MbpPtr->HwaRequest.Data);
+ DestPtr = &MbpPtr->HwaRequest.Data;
+ MbpPtr->HwaRequest.Available = TRUE;
+ break;
+
+ case 0x51:
+ //
+ // ICC Profile
+ //
+ DestSize = sizeof (MbpPtr->IccProfile);
+ DestPtr = &MbpPtr->IccProfile;
+ break;
+
+ case 0x61:
+ //
+ // NFC Data
+ //
+ DestSize = sizeof (MbpPtr->NfcSupport.NfcData);
+ DestPtr = &MbpPtr->NfcSupport.NfcData;
+ MbpPtr->NfcSupport.Available = TRUE;
+ break;
+
+ default:
+ //
+ // default case
+ //
+ DestSize = 0;
+ DestPtr = NULL;
+ break;
+ }
+ if (DestPtr != NULL) {
+ if ((MbpItemSize * 4) <= DestSize) {
+ CopyMem (DestPtr, Ptr, (MbpItemSize * 4));
+ } else {
+ DEBUG ((EFI_D_INFO, "Data size is larger than destination buffer. This item is not copied.\n"));
+ }
+ //
+ // Clear buffer
+ //
+ ZeroMem (Ptr, MbpItemSize * 4);
+ FreePool (Ptr);
+ }
+ }
+
+ //
+ // Check if after consuming MBP R/W counters are ok:
+ // ME_CBRP_HRA == ME_CBWP_HRA != 0
+ //
+ HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul;
+
+ if (FilledSlots2 (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) != 0
+ || HeciRegMeCsrHa.r.ME_CBWP_HRA == 0) {
+ DEBUG ((EFI_D_INFO, "R/W pointers mismatch after MBP consume: ME_CBRP_HRA = %x, ME_CBWP_HRA = %x\n",
+ HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA));
+ MbpReadError = TRUE;
+ }
+
+ if (!MbpReadError) {
+ //
+ // Interrupt ME FW so FW can clear HECI buffer after MBP is consumed
+ //
+ HeciRegHCsr.ul = HeciRegHCsrPtr->ul;
+ HeciRegHCsr.r.H_IG = 1;
+ HeciRegHCsrPtr->ul = HeciRegHCsr.ul;
+
+ //
+ // Create a callback event to check MBP FWSTS bit
+ //
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ MbpCleared,
+ NULL,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Register EXIT_PM_AUTH_PROTOCOL notify function
+ //
+ Status = gBS->RegisterProtocolNotify (
+ &gExitPmAuthProtocolGuid,
+ Event,
+ &Registration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ goto Done;
+ }
+ }
+ } else {
+ //
+ // If MBP_RDY not set, give up reading MBP and continue
+ //
+ goto MbpGiveup;
+ }
+
+ //
+ // If MAX_RETRIES exceeded, give up
+ //
+ if (MbpReadError && MbpReadAttempts == HECI_MBP_READ_MAX_RETRIES) {
+ goto MbpGiveup;
+ }
+
+ //
+ // Interrupt ME FW so FW knows we're done with this MBP read attempt
+ //
+ HeciRegHCsr.ul = HeciRegHCsrPtr->ul;
+ HeciRegHCsr.r.H_IG = 1;
+ HeciRegHCsrPtr->ul = HeciRegHCsr.ul;
+
+ //
+ // Wait for MBP_RDY after failed read attempt
+ //
+ Timeout = 0;
+
+ do {
+ MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW);
+
+ if (MeFwsts2.r.MbpRdy) {
+ break;
+ }
+
+ gBS->Stall (FIVE_MS_TIMEOUT);
+ Timeout += FIVE_MS_TIMEOUT;
+ } while (Timeout <= HECI_MBP_RDY_TIMEOUT);
+ }
+
+MbpGiveup:
+ MbpGiveUp();
+ Status = EFI_DEVICE_ERROR;
+
+Done:
+ return Status;
+}
+
+/**
+ Send Get Firmware Version Request to ME
+
+ @param[in] MsgGenGetFwVersionAckData Return themessage of FW version
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+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 ME client
+
+ @param[in] MECapability Structure of FirmwareUpdateInfo
+
+ @exception EFI_UNSUPPORTED No MBP Data Protocol available
+**/
+EFI_STATUS
+HeciGetMeFwInfo (
+ IN OUT ME_CAP *MECapability
+ )
+{
+ EFI_STATUS Status;
+ DXE_MBP_DATA_PROTOCOL *MbpData;
+ MEFWCAPS_SKU FwCapsSku;
+
+ //
+ // Get the MBP Data.
+ //
+ Status = gBS->LocateProtocol (&gMeBiosPayloadDataProtocolGuid, NULL, (VOID **) &MbpData);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "HeciGetMeFwInfo: No MBP Data Protocol available\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ MECapability->MeEnabled = 1;
+
+ FwCapsSku.Data = MbpData->MeBiosPayload.FwCapsSku.FwCapabilities.Data;
+ if (FwCapsSku.Fields.IntelAT) {
+ MECapability->AtSupported = 1;
+ }
+
+ if (FwCapsSku.Fields.KVM) {
+ MECapability->IntelKVM = 1;
+ }
+
+ switch (MbpData->MeBiosPayload.FwPlatType.RuleData.Fields.PlatformBrand) {
+ case INTEL_AMT_BRAND:
+ MECapability->IntelAmtFw = 1;
+ MECapability->LocalWakeupTimer = 1;
+ break;
+
+ case INTEL_STAND_MANAGEABILITY_BRAND:
+ MECapability->IntelAmtFwStandard = 1;
+ break;
+
+ case INTEL_SMALL_BUSINESS_TECHNOLOGY_BRAND:
+ MECapability->IntelSmallBusiness = 1;
+ break;
+ }
+
+ MECapability->MeMajorVer = MbpData->MeBiosPayload.FwVersionName.MajorVersion;
+ MECapability->MeMinorVer = MbpData->MeBiosPayload.FwVersionName.MinorVersion;
+ MECapability->MeBuildNo = MbpData->MeBiosPayload.FwVersionName.BuildVersion;
+ MECapability->MeHotFixNo = MbpData->MeBiosPayload.FwVersionName.HotfixVersion;
+
+ return Status;
+}
+
+/**
+ Dummy return for Me signal event use
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+**/
+VOID
+EFIAPI
+MeEmptyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+/**
+ Get AT State Information From Stored ME platform policy
+
+ @param[in] AtState Pointer to AT State Information
+ @param[in] AtLastTheftTrigger Pointer to Variable holding the cause of last AT Stolen Stae
+ @param[in] AtLockState Pointer to variable indicating whether AT is locked or not
+ @param[in] AtAmPref Pointer to variable indicating whether ATAM or PBA should be used
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED No MBP Data Protocol available
+**/
+EFI_STATUS
+GetAtStateInfo (
+ IN AT_STATE_INFO *AtStateInfo
+ )
+{
+ EFI_STATUS Status;
+ DXE_MBP_DATA_PROTOCOL *MbpData;
+
+ //
+ // Get the ME platform policy.
+ //
+ Status = gBS->LocateProtocol (&gMeBiosPayloadDataProtocolGuid, NULL, (VOID **) &MbpData);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "GetAtStateInfo: No MBP Data Protocol available\n"));
+ return EFI_UNSUPPORTED;
+ }
+ AtStateInfo->State = MbpData->MeBiosPayload.AtState.State;
+ AtStateInfo->LastTheftTrigger = MbpData->MeBiosPayload.AtState.LastTheftTrigger;
+ AtStateInfo->flags.LockState = MbpData->MeBiosPayload.AtState.flags.LockState;
+ AtStateInfo->flags.AuthenticateModule = MbpData->MeBiosPayload.AtState.flags.AuthenticateModule;
+ AtStateInfo->flags.S3Authentication = MbpData->MeBiosPayload.AtState.flags.S3Authentication;
+ AtStateInfo->flags.FlashVariableSecurity = MbpData->MeBiosPayload.AtState.flags.FlashVariableSecurity;
+ AtStateInfo->flags.FlashWearOut = MbpData->MeBiosPayload.AtState.flags.FlashWearOut;
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.h b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.h
new file mode 100644
index 0000000..00ceec0
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.h
@@ -0,0 +1,203 @@
+/** @file
+ Header file for functions to get Intel ME information
+
+@copyright
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _ME_LIB_H_
+#define _ME_LIB_H_
+
+#include "MePolicyLib.h"
+#include "HeciMsgLib.h"
+#include "MeChipset.h"
+#include "HeciRegs.h"
+#include EFI_PROTOCOL_CONSUMER (MeBiosPayloadData)
+
+#define MBP_PRESENT_MASK 0x00000020
+#define FIVE_MS_TIMEOUT 5000
+
+extern EFI_GUID gExitPmAuthProtocolGuid;
+
+#pragma pack(push, 1)
+
+typedef union _MBP_HEADER {
+ UINT32 Data;
+ struct {
+ UINT32 MbpSize : 8; ///< Byte 0 - MBP Size in DW including Header
+ UINT32 NumEntries : 8; ///< Byte 1 - Number of Entries (Data Items) in MBP
+ UINT32 Rsvd : 16; ///< Byte 3:2 - Reserved
+ } Fields;
+} MBP_HEADER;
+
+typedef union _MBP_ITEM_HEADER {
+ UINT32 Data;
+ struct {
+ UINT32 AppId : 8; ///< Byte 0 - Application ID
+ UINT32 ItemId : 8; ///< Byte 1 - Item ID
+ UINT32 Length : 8; ///< Byte 2 - Length in DW
+ UINT32 Rsvd : 8; ///< Byte 3 - Reserved
+ } Fields;
+} MBP_ITEM_HEADER;
+
+#pragma pack(pop)
+
+/**
+ Check if Me is enabled
+
+ @param[in] None.
+
+ @retval None
+**/
+EFI_STATUS
+MeLibInit (
+ VOID
+ )
+;
+
+/**
+ Send Get Firmware SKU Request to ME
+
+ @param[in] FwCapsSku Return Data from Get Firmware Capabilities MKHI Request
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+HeciGetFwCapsSku (
+ MEFWCAPS_SKU *FwCapsSku
+ )
+;
+
+/**
+ This message is sent by the BIOS or Intel(R) MEBX prior to the End of Post (EOP) on the boot
+ where host wants to get Lynx Point platform type. One of usages is to utilize this command to
+ determine if the platform runs in 1.5M or 5M size firmware.
+
+ @param[out] RuleData PlatformBrand,
+ IntelMeFwImageType,
+ SuperSku,
+ PlatformTargetMarketType,
+ PlatformTargetUsageType
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+HeciGetPlatformType (
+ OUT PLATFORM_TYPE_RULE_DATA *RuleData
+ )
+;
+
+/**
+ Routine checks whether MBP buffer has been cleared form HECI buffer or not.
+ BIOS must check this before executing any 3rd paty code or Oprom
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+**/
+VOID
+EFIAPI
+MbpCleared (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+;
+
+/**
+ This routine returns ME-BIOS Payload information from HECI buffer
+
+ @param[out] MbpPtr ME-BIOS Payload information.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_DEVICE_ERROR Failed to consume MBP
+**/
+EFI_STATUS
+PrepareMeBiosPayload (
+ OUT ME_BIOS_PAYLOAD *MbpPtr
+ )
+;
+
+/**
+ Send Get Firmware Version Request to ME
+
+ @param[in] MsgGenGetFwVersionAckData Return themessage of FW version
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+HeciGetFwVersion (
+ IN OUT GEN_GET_FW_VER_ACK_DATA *MsgGenGetFwVersionAckData
+ )
+;
+
+/**
+ Host client gets Firmware update info from ME client for SMBIOS Table 131
+
+ @param[in][out] MECapability Structure of FirmwareUpdateInfo
+
+ @exception EFI_UNSUPPORTED No MBP Data Protocol available
+**/
+EFI_STATUS
+HeciGetMeFwInfo (
+ IN OUT ME_CAP *MECapability
+ )
+;
+
+/**
+ This is a dummy event to be hooked to provide ME or Platform
+ code before EOP Heci message is sent
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+**/
+VOID
+EFIAPI
+MeEmptyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+;
+
+/**
+ Get AT State Information From ME FW
+
+ @param[in] AtState Pointer to AT State Information
+ @param[in] AtLastTheftTrigger Pointer to Variable holding the cause of last AT Stolen Stae
+ @param[in] AtLockState Pointer to variable indicating whether AT is locked or not
+ @param[in] AtAmPref Pointer to variable indicating whether ATAM or PBA should be used
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED No MBP Data Protocol available
+**/
+EFI_STATUS
+GetAtStateInfo (
+ IN AT_STATE_INFO *AtStateInfo
+ )
+;
+
+/**
+ Dump DXE_MBP_DATA_PROTOCOL
+
+ @param[in] MbpData Pointer to DXE_MBP_DATA_PROTOCOL
+
+ @retval None
+**/
+VOID
+DxeMbpDebugDump (
+ IN DXE_MBP_DATA_PROTOCOL *MbpPtr
+ )
+;
+
+#endif
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.inf b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.inf
new file mode 100644
index 0000000..5e340e4
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.inf
@@ -0,0 +1,68 @@
+## @file
+# Component description file for Me functionality
+#
+#@copyright
+# Copyright (c) 2010 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = MeLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ MeLib.c
+ MeLib.h
+ MePolicyLib.c
+ MePolicyLib.h
+ HeciMsgLib.c
+ HeciMsgLib.h
+ MePolicyDebugDumpDxe.c
+ MbpDebugDumpDxe.c
+
+[includes.common]
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ MeProtocolLib
+ MeChipsetLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkFrameworkProtocolLib
+ PrintLib
+ EfiCommonLib
+ EdkIIGlueDxeFirmwarePerformanceLib
+
+[nmake.common]
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.cif b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.cif
new file mode 100644
index 0000000..3fc38ab
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "MeLibDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\ME\Library\MeKernel\Dxe\"
+ RefName = "MeLibDxe"
+[files]
+"MeLib.c"
+"MeLib.h"
+"MeLibDxe.mak"
+"MeLibDxe.sdl"
+"MePolicyLib.c"
+"MePolicyLib.h"
+"MeLib.inf"
+"HeciMsgLib.c"
+"HeciMsgLib.h"
+"MbpDebugDumpDxe.c"
+"MePolicyDebugDumpDxe.c"
+<endComponent>
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.mak b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.mak
new file mode 100644
index 0000000..367e4c0
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.mak
@@ -0,0 +1,60 @@
+# /*++
+# Copyright (c) 2009 Intel Corporation. All rights reserved.
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+# --*/
+# MAK file for the ModulePart:MeLibDxe
+all : MeLibDxe
+
+$(BUILD_DIR)\MeLibDxe.lib : MeLibDxe
+
+MeLibDxe : $(BUILD_DIR)\MeLibDxe.mak MeLibDxeBin
+
+$(BUILD_DIR)\MeLibDxe.mak : $(MeLibDxe_DIR)\$(@B).cif $(MeLibDxe_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MeLibDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MeLibDxe_INCLUDES=\
+ $(EDK_INCLUDES) \
+ $(EdkIIGlueLib_INCLUDES) \
+ $(ME_INCLUDES) \
+ -I$(INTEL_COUGAR_POINT_DIR)\
+ $(INTEL_PCH_INCLUDES)
+
+MeLibDxe_DEFINES=\
+ $(MY_DEFINES)/D __EDKII_GLUE_BASE_MEMORY_LIB__\
+ /D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__\
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+MeLibDxe_LIBS=\
+ $(MeProtocolLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(COMPILERSTUB)\
+ $(EdkIIGlueSmmFirmwarePerformanceLib_LIB)\
+ $(EDKFRAMEWORKGUIDLIB)\
+
+
+MeLibDxeBin : $(MeLibDxe_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\MeLibDxe.mak all \
+ "MY_INCLUDES=$(MeLibDxe_INCLUDES)" \
+ "MY_DEFINES=$(MeLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.sdl b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.sdl
new file mode 100644
index 0000000..f69bf74
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "MeLibDxe_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable MeLibDxe support in Project"
+End
+
+MODULE
+ Help = "Includes MeLibDxe.mak to Project"
+ File = "MeLibDxe.mak"
+End
+
+PATH
+ Name = "MeLibDxe_DIR"
+ Help = "Me Library file source directory"
+End
+
+ELINK
+ Name = "MeLibDxe_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MeLibDxe.lib"
+ Parent = "MeLibDxe_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(MeLibDxe_DIR)"
+ Parent = "ME_INCLUDES"
+ InvokeOrder = AfterParent
+End
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyDebugDumpDxe.c b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyDebugDumpDxe.c
new file mode 100644
index 0000000..bdfe7e5
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyDebugDumpDxe.c
@@ -0,0 +1,72 @@
+/** @file
+ Dump whole DXE_ME_POLICY_PROTOCOL and serial out.
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "MePolicyLib.h"
+#endif
+
+extern DXE_ME_POLICY_PROTOCOL *mDxePlatformMePolicy;
+
+/**
+ Dump DXE ME Platform Policy
+
+ @param[in] None.
+
+ @retval None
+**/
+VOID
+DxeMePolicyDebugDump (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = MePolicyLibInit ();
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "\n------------------------ MePlatformPolicy Dump Begin -----------------\n"));
+ DEBUG ((EFI_D_INFO, " Revision : 0x%x\n", mDxePlatformMePolicy->Revision));
+ DEBUG ((EFI_D_INFO, "MeConfig ---\n"));
+ //
+ // Byte 0, bit definition for functionality enable/disable
+ //
+ DEBUG ((EFI_D_INFO, " MeFwDownGrade : 0x%x\n", mDxePlatformMePolicy->MeConfig.MeFwDownGrade));
+ DEBUG ((EFI_D_INFO, " MeLocalFwUpdEnabled : 0x%x\n", mDxePlatformMePolicy->MeConfig.MeLocalFwUpdEnabled));
+ DEBUG ((EFI_D_INFO, " EndOfPostEnabled : 0x%x\n", mDxePlatformMePolicy->MeConfig.EndOfPostEnabled));
+ DEBUG ((EFI_D_INFO, " EndOfPostDone : 0x%x\n", mDxePlatformMePolicy->MeConfig.EndOfPostDone));
+ DEBUG ((EFI_D_INFO, " MdesCapability : 0x%x\n", mDxePlatformMePolicy->MeConfig.MdesCapability));
+ DEBUG ((EFI_D_INFO, " SvtForPchCap : 0x%x\n", mDxePlatformMePolicy->MeConfig.SvtForPchCap));
+ DEBUG ((EFI_D_INFO, " MdesForBiosState : 0x%x\n", mDxePlatformMePolicy->MeConfig.MdesForBiosState));
+
+ DEBUG ((EFI_D_INFO, "MeMiscConfig ---\n"));
+ DEBUG ((EFI_D_INFO, " FviSmbiosType : 0x%x\n", mDxePlatformMePolicy->MeMiscConfig.FviSmbiosType));
+ DEBUG ((EFI_D_INFO, "\n------------------------ MePlatformPolicy Dump End -------------------\n"));
+#endif
+}
+
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.c b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.c
new file mode 100644
index 0000000..5f69857
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.c
@@ -0,0 +1,182 @@
+/** @file
+ Implementation file for Me Policy functionality
+
+@copyright
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "MePolicyLib.h"
+#include "MeAccess.h"
+#include EFI_PROTOCOL_DEFINITION (HECI)
+#endif
+
+//
+// Global variables
+//
+DXE_ME_POLICY_PROTOCOL *mDxePlatformMePolicy = NULL;
+
+/**
+ Check if Me is enabled.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS ME platform policy pointer is initialized.
+ @retval All other error conditions encountered when no ME platform policy available.
+**/
+EFI_STATUS
+MePolicyLibInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mDxePlatformMePolicy != NULL) {
+ return EFI_SUCCESS;
+ }
+ //
+ // Get the desired platform setup policy.
+ //
+ Status = gBS->LocateProtocol (&gDxePlatformMePolicyGuid, NULL, (VOID **) &mDxePlatformMePolicy);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "No ME Platform Policy Protocol available"));
+ ASSERT_EFI_ERROR (Status);
+ } else if (mDxePlatformMePolicy == NULL) {
+ DEBUG ((EFI_D_ERROR, "No ME Platform Policy Protocol available"));
+ Status = EFI_UNSUPPORTED;
+ }
+ return Status;
+}
+
+/**
+ 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
+MeEndOfPostEnabled (
+ VOID
+ )
+{
+ BOOLEAN Supported;
+ EFI_STATUS Status;
+
+ if (mDxePlatformMePolicy == NULL) {
+ Status = MePolicyLibInit();
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+ }
+ if (mDxePlatformMePolicy->MeConfig.EndOfPostEnabled != 1) {
+ Supported = FALSE;
+ } else {
+ Supported = TRUE;
+ }
+
+ return Supported;
+}
+
+/**
+ Checks if EndOfPost event already happened
+
+ @param[in] None
+
+ @retval TRUE if end of post happened
+ @retval FALSE if not yet
+**/
+BOOLEAN
+IsAfterEndOfPost (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mDxePlatformMePolicy == NULL) {
+ Status = MePolicyLibInit();
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+ }
+
+ if (mDxePlatformMePolicy->MeConfig.EndOfPostDone == TRUE) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Show Me Error message. This is used to support display error message on the screen for localization
+ description
+
+ @param[in] MsgId Me error message ID for displaying on screen message
+
+ @retval None
+**/
+VOID
+MeReportError (
+ IN ME_ERROR_MSG_ID MsgId
+ )
+{
+ EFI_STATUS Status;
+
+ if (mDxePlatformMePolicy == NULL) {
+ Status = MePolicyLibInit();
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ }
+ mDxePlatformMePolicy->MeReportError (MsgId);
+
+ return ;
+}
+
+/**
+ Check if MeFwDowngrade is enabled in setup options.
+
+ @param[in] None.
+
+ @retval FALSE MeFwDowngrade is disabled.
+ @retval TRUE MeFwDowngrade is enabled.
+**/
+BOOLEAN
+MeFwDowngradeSupported (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mDxePlatformMePolicy == NULL) {
+ Status = MePolicyLibInit();
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+ }
+ if (mDxePlatformMePolicy->MeConfig.MeFwDownGrade == 1) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.h b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.h
new file mode 100644
index 0000000..1d315b5
--- /dev/null
+++ b/ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.h
@@ -0,0 +1,95 @@
+/** @file
+ Header file for Me Policy functionality
+
+@copyright
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _ME_POLICY_LIB_H_
+#define _ME_POLICY_LIB_H_
+
+#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy)
+
+/**
+ Check if Me is enabled.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS ME platform policy pointer is initialized.
+ @retval All other error conditions encountered when no ME platform policy available.
+**/
+EFI_STATUS
+MePolicyLibInit (
+ 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
+MeEndOfPostEnabled (
+ VOID
+ )
+;
+
+
+/**
+ Show Me Error message. This is used to support display error message on the screen for localization
+ description
+
+ @param[in] MsgId Me error message ID for displaying on screen message
+
+ @retval None
+**/
+VOID
+MeReportError (
+ IN ME_ERROR_MSG_ID MsgId
+ )
+;
+
+/**
+ Check if MeFwDowngrade is enabled in setup options.
+
+ @param[in] None.
+
+ @retval FALSE MeFwDowngrade is disabled.
+ @retval TRUE MeFwDowngrade is enabled.
+**/
+BOOLEAN
+MeFwDowngradeSupported (
+ VOID
+ )
+;
+
+/**
+ Dump DXE ME Platform Policy
+
+ @param[in] None.
+
+ @retval None
+**/
+VOID
+DxeMePolicyDebugDump (
+ VOID
+ )
+;
+#endif