diff options
Diffstat (limited to 'ReferenceCode/ME/Library/MeKernel/Dxe')
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.c | 2702 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/HeciMsgLib.h | 782 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MbpDebugDumpDxe.c | 150 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.c | 712 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.h | 203 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLib.inf | 68 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.cif | 18 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.mak | 60 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MeLibDxe.sdl | 36 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyDebugDumpDxe.c | 72 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.c | 182 | ||||
-rw-r--r-- | ReferenceCode/ME/Library/MeKernel/Dxe/MePolicyLib.h | 95 |
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 |