diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/ME/Library/MeKernel | |
download | zprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz |
Diffstat (limited to 'ReferenceCode/ME/Library/MeKernel')
34 files changed, 7791 insertions, 0 deletions
diff --git a/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.c b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.c new file mode 100644 index 0000000..aac3afb --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.c @@ -0,0 +1,112 @@ +/** @file + Me Chipset Lib implementation. + +@copyright + Copyright (c) 2004 - 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 +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#include "MeAccess.h" +#include "PchPlatformLib.h" +#endif + +/** + Enable/Disable Me devices + + @param[in] WhichDevice Select of Me device + @param[in] DeviceFuncCtrl Function control + + @retval None +**/ +VOID +MeDeviceControl ( + IN ME_DEVICE WhichDevice, + IN ME_DEVICE_FUNC_CTRL DeviceFuncCtrl + ) +{ + switch (WhichDevice) { + case HECI1: + case HECI2: + case IDER: + case SOL: + if (DeviceFuncCtrl) { + Mmio16And (PCH_RCRB_BASE, R_PCH_RCRB_FD2, ~(BIT0 << WhichDevice)); + } else { + Mmio16Or (PCH_RCRB_BASE, R_PCH_RCRB_FD2, BIT0 << WhichDevice); + } + Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FD2); + break; + + case USBR1: + if (DeviceFuncCtrl) { + MmioOr16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_USB, + PCI_FUNCTION_NUMBER_PCH_EHCI, + 0x7A), + (UINT16) (0x100) + ); + } else { + MmioAnd16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_USB, + PCI_FUNCTION_NUMBER_PCH_EHCI, + 0x7A), + (UINT16) (~0x100) + ); + } + break; + + case USBR2: + if (GetPchSeries() == PchH) { + if (DeviceFuncCtrl) { + MmioOr16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_USB_EXT, + PCI_FUNCTION_NUMBER_PCH_EHCI2, + 0x7A), + (UINT16) (0x100) + ); + } else { + MmioAnd16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_USB_EXT, + PCI_FUNCTION_NUMBER_PCH_EHCI2, + 0x7A), + (UINT16) (~0x100) + ); + } + } + break; + + /// + /// Function Disable SUS well lockdown + /// + case FDSWL: + if (DeviceFuncCtrl) { + Mmio16Or (PCH_RCRB_BASE, R_PCH_RCRB_FDSW, (UINT16) B_PCH_RCRB_FDSW_FDSWL); + } else { + Mmio16And (PCH_RCRB_BASE, R_PCH_RCRB_FDSW, (UINT16)~(B_PCH_RCRB_FDSW_FDSWL)); + } + Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FDSW); + break; + } +}
\ No newline at end of file diff --git a/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.cif b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.cif new file mode 100644 index 0000000..d4962a1 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.cif @@ -0,0 +1,11 @@ +<component> + name = "MeChipsetLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\MeKernel\Common\MeChipsetLib\" + RefName = "MeChipsetLib" +[files] +"MeChipsetLib.mak" +"MeChipsetLib.sdl" +"MeChipsetLib.c" +"MeChipsetLib.inf" +<endComponent> diff --git a/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.inf b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.inf new file mode 100644 index 0000000..aa44c98 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.inf @@ -0,0 +1,61 @@ +## @file +# Component description file for PEI/DXE ME Chipset Lib +# +#@copyright +# Copyright (c) 1999 - 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 = MeChipsetLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + MeChipsetLib.c + +[sources.ia32] + +[sources.x64] + +[sources.ipf] + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + +# +# 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 + PchPlatformLib + +[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/Common/MeChipsetLib/MeChipsetLib.mak b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.mak new file mode 100644 index 0000000..91ac39a --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.mak @@ -0,0 +1,53 @@ +# MAK file for the ModulePart:MeChipsetLib +EDK : MeChipsetLib + +MeChipsetLib : MeChipsetSmmLib MeChipsetDxeLib MeChipsetPeiLib + +$(MeChipsetSmmLib_LIB) : MeChipsetSmmLib +$(MeChipsetDxeLib_LIB) : MeChipsetDxeLib +$(MeChipsetPeiLib_LIB) : MeChipsetPeiLib + +MeChipsetSmmLib : $(BUILD_DIR)\MeChipsetLib.mak MeChipsetLibSmmBin + +MeChipsetDxeLib : $(BUILD_DIR)\MeChipsetLib.mak MeChipsetLibDxeBin + +MeChipsetPeiLib : $(BUILD_DIR)\MeChipsetLib.mak MeChipsetLibPeiBin + +$(BUILD_DIR)\MeChipsetLib.mak : $(MeChipsetLib_DIR)\$(@B).cif $(MeChipsetLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeChipsetLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeChipsetLib_INCLUDES =\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES) \ + $(INTEL_PCH_INCLUDES) + +MeChipsetLibSmmBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeChipsetLib.mak all\ + "MY_INCLUDES=$(MeChipsetLib_INCLUDES)" \ + TYPE=LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(MeChipsetSmmLib_LIB) + +MeChipsetLibDxeBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeChipsetLib.mak all\ + "MY_INCLUDES=$(MeChipsetLib_INCLUDES)" \ + "CFLAGS=$(CFLAGS) $(MeChipsetLib_DEFINES)"\ + TYPE=LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(MeChipsetDxeLib_LIB) + +MeChipsetLibPeiBin : +!IF "$(x64_BUILD)"=="1" + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ +!ELSE + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ +!ENDIF + /f $(BUILD_DIR)\MeChipsetLib.mak all\ + "MY_INCLUDES=$(MeChipsetLib_INCLUDES)"\ + "CFLAGS=$(CFLAGS) $(MeChipsetLib_DEFINES)"\ + TYPE=PEI_LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(MeChipsetPeiLib_LIB) diff --git a/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.sdl b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.sdl new file mode 100644 index 0000000..a668016 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Common/MeChipsetLib/MeChipsetLib.sdl @@ -0,0 +1,70 @@ +TOKEN + Name = "MeChipsetLib_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeChipsetLib support in Project" +End + +MODULE + Help = "Includes MeChipsetLib.mak to Project" + File = "MeChipsetLib.mak" +End + +PATH + Name = "MeChipsetLib_DIR" + Help = "Me Chipset Library file source directory" +End + +ELINK + Name = "MeChipsetPeiLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeChipsetPeiLib.lib" + Parent = "MeChipsetPeiLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeChipsetLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "MeChipsetDxeLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeChipsetDxeLib.lib" + Parent = "MeChipsetDxeLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeChipsetLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "MeChipsetSmmLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeChipsetSmmLib.lib" + Parent = "MeChipsetSmmLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeChipsetLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End 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 diff --git a/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.cif b/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.cif new file mode 100644 index 0000000..eaef885 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.cif @@ -0,0 +1,12 @@ +<component> + name = "MeKernelLibrary" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\MeKernel\" + RefName = "MeKernelLibrary" +[files] +"MeKernelLibrary.sdl" +[parts] +"MeChipsetLib" +"MeLibDxe" +"MeLibPei" +<endComponent> diff --git a/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.sdl b/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.sdl new file mode 100644 index 0000000..6055d0a --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/MeKernelLibrary.sdl @@ -0,0 +1,20 @@ +TOKEN + Name = "MeKernelLibrary_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable Me Kernel Library support in Project" +End + +PATH + Name = "MeKernelLibrary_DIR" + Help = "Me Library file source directory" +End + +ELINK + Name = "/I$(MeKernelLibrary_DIR)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.c b/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.c new file mode 100644 index 0000000..905020b --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.c @@ -0,0 +1,185 @@ +/** @file + Implementation file for Heci Message 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 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 "EdkIIGluePeim.h" +#include "CoreBiosMsg.h" +#include "HeciMsgLibPei.h" +#include EFI_PPI_CONSUMER (Wdt) + +#endif + +/** + Start Watch Dog Timer HECI message + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] HeciPpi The pointer to HECI PPI + @param[in] HeciMemBar HECI Memory BAR + @param[in] WaitTimerBios The value of waiting limit + + @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 +PeiHeciAsfStartWatchDog ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *HeciPpi, + IN UINT32 HeciMemBar, + IN UINT16 WaitTimerBios + ) +{ + EFI_STATUS Status; + ASF_START_WDT AsfStartWdt; + UINT32 HeciLength; + UINT32 MeMode; + + Status = HeciPpi->GetMeMode (PeiServices, &MeMode); + if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) { + return EFI_UNSUPPORTED; + } + /// + /// Clear Start Watch Dog Timer HECI message + /// + ZeroMem ((VOID *) &AsfStartWdt, sizeof (ASF_START_WDT)); + + AsfStartWdt.Command = ASF_MANAGEMENT_CONTROL; + AsfStartWdt.ByteCount = START_WDT_BYTE_COUNT; + AsfStartWdt.SubCommand = ASF_SUB_COMMAND_START_WDT; + AsfStartWdt.VersionNumber = START_WDT_VERSION_NUMBER; + AsfStartWdt.TimeoutLow = (UINT8) WaitTimerBios; + AsfStartWdt.TimeoutHigh = (UINT8) (WaitTimerBios >> 8); + AsfStartWdt.EventSensorType = START_WDT_EVENT_SENSOR_TYPE; + AsfStartWdt.EventType = START_WDT_EVENT_TYPE; + AsfStartWdt.EventOffset = START_WDT_EVENT_OFFSET; + AsfStartWdt.EventSourceType = START_WDT_EVENT_SOURCE_TYPE_BIOS; + AsfStartWdt.EventSeverity = START_WDT_EVENT_SEVERITY; + AsfStartWdt.SensorDevice = START_WDT_SENSOR_DEVICE; + AsfStartWdt.SensorNumber = START_WDT_SENSOR_NUMBER; + AsfStartWdt.Entity = START_WDT_ENTITY; + AsfStartWdt.EntityInstance = START_WDT_ENTITY_INSTANCE; + AsfStartWdt.EventData[0] = START_WDT_EVENT_DATA_BYTE_0; + AsfStartWdt.EventData[1] = START_WDT_EVENT_DATA_BYTE_1_BIOS_TIMEOUT; + + HeciLength = ASF_START_WDT_LENGTH; + + Status = HeciPpi->SendMsg ( + PeiServices, + HeciPpi, + (UINT32 *) &AsfStartWdt, + HeciMemBar, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + + return Status; +} + +/** + Send Core BIOS Reset Request Message through HECI to reset the system. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] ResetOrigin Reset source + @param[in] ResetType Global or Host reset + + @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 +PeiHeciSendCbmResetRequest ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT8 ResetOrigin, + IN UINT8 ResetType + ) +{ + EFI_STATUS Status; + PEI_HECI_PPI *HeciPpi; + CBM_RESET_REQ CbmResetRequest; + UINT32 HeciLength; + UINT32 HeciMemBar; + PLATFORM_ME_HOOK_PPI *PlatformMeHookPpi; + EFI_GUID WdtPpiGuid = WDT_PPI_GUID; + WDT_PPI *WdtPpi; + + Status = PeiServicesLocatePpi ( + &gPlatformMeHookPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) &PlatformMeHookPpi // PPI + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to Locate PlatformMeHook Protocol for Global Reset Hook, so skip instead.", Status)); + } else { + PlatformMeHookPpi->PreGlobalReset (PeiServices, PlatformMeHookPpi); + } + + Status = PeiServicesLocatePpi ( + &gPeiHeciPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) &HeciPpi // PPI + ); + ASSERT_EFI_ERROR (Status); + + Status = HeciPpi->InitializeHeci (PeiServices, HeciPpi, &HeciMemBar); + if (EFI_ERROR (Status)) { + return Status; + } + + CbmResetRequest.MKHIHeader.Data = 0; + CbmResetRequest.MKHIHeader.Fields.Command = CBM_RESET_REQ_CMD; + CbmResetRequest.MKHIHeader.Fields.IsResponse = 0; + CbmResetRequest.MKHIHeader.Fields.GroupId = MKHI_CBM_GROUP_ID; + CbmResetRequest.MKHIHeader.Fields.Reserved = 0; + CbmResetRequest.MKHIHeader.Fields.Result = 0; + CbmResetRequest.Data.RequestOrigin = CBM_RR_REQ_ORIGIN_BIOS_MEMORY_INIT; + CbmResetRequest.Data.ResetType = CBM_HRR_GLOBAL_RESET; + + HeciLength = sizeof (CBM_RESET_REQ); + + Status = PeiServicesLocatePpi ( + &WdtPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) &WdtPpi // PPI + ); + ASSERT_EFI_ERROR (Status); + WdtPpi->AllowKnownReset (); + + Status = HeciPpi->SendMsg ( + PeiServices, + HeciPpi, + (UINT32 *) &CbmResetRequest, + HeciMemBar, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_CORE_MESSAGE_ADDR + ); + + return Status; +} diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.h b/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.h new file mode 100644 index 0000000..7d5c7ce --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/HeciMsgLibPei.h @@ -0,0 +1,86 @@ +/** @file + Header file for Heci Message 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 _PEI_HECI_MESSAGE_LIB_H_ +#define _PEI_HECI_MESSAGE_LIB_H_ + +#include EFI_PPI_DEFINITION (Heci) +#include EFI_PPI_DEFINITION (PlatformMeHook) + +#define START_WDT_BYTE_COUNT 0x0F +#define START_WDT_VERSION_NUMBER 0x10 +#define START_WDT_EVENT_SENSOR_TYPE 0x23 +#define START_WDT_EVENT_TYPE 0x6F +#define START_WDT_EVENT_OFFSET 0x00 +#define START_WDT_EVENT_SOURCE_TYPE_OS 0x48 +#define START_WDT_EVENT_SOURCE_TYPE_BIOS 0x00 +#define START_WDT_EVENT_SOURCE_TYPE 0x00 ///< 0x00 - BIOs, 0x48 - OS +#define START_WDT_EVENT_SEVERITY 0x10 ///< critical +#define START_WDT_SENSOR_DEVICE 0xFF ///< unspecified +#define START_WDT_SENSOR_NUMBER 0xFF ///< unspecified +#define START_WDT_ENTITY 0x00 ///< unspecified +#define START_WDT_ENTITY_INSTANCE 0x00 ///< unspecified +#define START_WDT_EVENT_DATA_BYTE_0 0x40 +#define START_WDT_EVENT_DATA_BYTE_1 0x02 ///< 0x02 BIOS POST WDT Timeout, 0x04 OS WDT timeout +#define START_WDT_EVENT_DATA_BYTE_1_BIOS_TIMEOUT 0x02 +#define START_WDT_EVENT_DATA_BYTE_1_OS_TIMEOUT 0x04 + +/** + Start Watch Dog Timer HECI message + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] HeciPpi The pointer to HECI PPI + @param[in] HeciMemBar HECI Memory BAR + @param[in] WaitTimerBios The value of waiting limit + + @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 +PeiHeciAsfStartWatchDog ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *HeciPpi, + IN UINT32 HeciMemBar, + IN UINT16 WaitTimerBios + ) +; + +/** + Send Core BIOS Reset Request Message through HECI to reset the system. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] ResetOrigin Reset source + @param[in] ResetType Global or Host reset + + @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 +PeiHeciSendCbmResetRequest ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT8 ResetOrigin, + IN UINT8 ResetType + ) +; + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.cif b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.cif new file mode 100644 index 0000000..195b908 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.cif @@ -0,0 +1,15 @@ +<component> + name = "MeLibPei" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\MeKernel\Pei\" + RefName = "MeLibPei" +[files] +"MeLibPei.sdl" +"MeLibPei.mak" +"MePolicyLibPei.c" +"MePolicyLibPei.h" +"HeciMsgLibPei.c" +"HeciMsgLibPei.h" +"MeLibPei.h" +"MeLibPei.inf" +<endComponent> diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.h b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.h new file mode 100644 index 0000000..af3ad62 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.h @@ -0,0 +1,27 @@ +/** @file + Header file for PEI Me 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 _PEI_ME_LIB_H_ +#define _PEI_ME_LIB_H_ + +#include "MePolicyLibPei.h" +#include "HeciMsgLibPei.h" + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.inf b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.inf new file mode 100644 index 0000000..78478c4 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.inf @@ -0,0 +1,56 @@ +## @file +# Component description file for Me Library functions for PEIMs +# +#@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 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 = MeLibPei +COMPONENT_TYPE = LIBRARY + +[sources.common] + MePolicyLibPei.c + MePolicyLibPei.h + HeciMsgLibPei.c + HEciMsgLibPei.h + MeLibPei.h + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + +# +# 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/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + MeLibPpi + EdkIIGluePeiServicesLib + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_PEI_SERVICES_LIB__ diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.mak b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.mak new file mode 100644 index 0000000..b9abbdf --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.mak @@ -0,0 +1,53 @@ +# /*++ +# 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:MeLibPei +all : MeLibPei + +$(BUILD_DIR)\MeLibPei.lib : MeLibPei + +MeLibPei : $(BUILD_DIR)\MeLibPei.mak MeLibPeiBin + +$(BUILD_DIR)\MeLibPei.mak : $(MeLibPei_DIR)\$(@B).cif $(MeLibPei_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeLibPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeLibPei_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES) \ + /I$(NB_BOARD_DIR)\ + -I$(INTEL_COUGAR_POINT_DIR)\ + +MeLibPei_DEFINES=\ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ + +MeLibPei_LIBS=\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(MeLibPpi_LIB) + +MeLibPeiBin : $(MeLibPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + /f $(BUILD_DIR)\MeLibPei.mak all \ + "MY_INCLUDES=$(MeLibPei_INCLUDES)" \ + "CFLAGS=$(CFLAGS) $(MeLibPei_DEFINES)"\ + TYPE=PEI_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/Pei/MeLibPei.sdl b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.sdl new file mode 100644 index 0000000..9dfe312 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MeLibPei.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "MeLibPei_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeLibPei support in Project" +End + +MODULE + Help = "Includes MeLibPei.mak to Project" + File = "MeLibPei.mak" +End + +PATH + Name = "MeLibPei_DIR" + Help = "Me Library file source directory" +End + +ELINK + Name = "MeLibPei_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeLibPei.lib" + Parent = "MeLibPei_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeLibPei_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.c b/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.c new file mode 100644 index 0000000..733d6e3 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.c @@ -0,0 +1,59 @@ +/** @file + Implementation file for Me Policy functionality for PEIM + +@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 "EdkIIGluePeim.h" +#include "MePolicyLibPei.h" +#endif + +/** + Check if Me is enabled. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] PeiMePlatformPolicy The Me Platform Policy protocol instance + + @retval EFI_SUCCESS ME platform policy Ppi loacted + @retval All other error conditions encountered when no ME platform policy Ppi +**/ +EFI_STATUS +PeiMePolicyLibInit ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ME_PLATFORM_POLICY_PPI **PeiMePlatformPolicy + ) +{ + EFI_STATUS Status; + + // + // Locate system configuration variable + // + Status = PeiServicesLocatePpi ( + &gPeiMePlatformPolicyPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) PeiMePlatformPolicy // PPI + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.h b/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.h new file mode 100644 index 0000000..7de458b --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/Pei/MePolicyLibPei.h @@ -0,0 +1,42 @@ +/** @file + Header file to define some function for getting the Intel ME policy PEI phase. + +@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 _PEI_ME_POLICY_LIB_H_ +#define _PEI_ME_POLICY_LIB_H_ + +#include EFI_PPI_DEFINITION (MePlatformPolicyPei) + +/** + Check if Me is enabled. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] PeiMePlatformPolicy The Me Platform Policy protocol instance + + @retval EFI_SUCCESS ME platform policy Ppi loacted + @retval All other error conditions encountered when no ME platform policy Ppi +**/ +EFI_STATUS +PeiMePolicyLibInit ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ME_PLATFORM_POLICY_PPI **PeiMePlatformPolicy + ) +; + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/include/CoreBiosMsg.h b/ReferenceCode/ME/Library/MeKernel/include/CoreBiosMsg.h new file mode 100644 index 0000000..bda1bc4 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/CoreBiosMsg.h @@ -0,0 +1,625 @@ +/** @file + Core BIOS Messages + +@copyright + Copyright (c) 2008 - 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 CORE_BIOS_MSG_H +#define CORE_BIOS_MSG_H + +#include "MkhiMsgs.h" + +#pragma pack(1) + +#define CBM_RESET_REQ_CMD 0x0B +#define CBM_RESET_REQ_CMD_ACK 0x8B +#define CBM_END_OF_POST_CMD 0x0C +#define CBM_END_OF_POST_CMD_ACK 0x8C +#define GEN_SET_DEBUG_MEMORY_CMD 0x11 + +// +// HECI Client Address - Core Messages +// Core messages to coordinate memory initialization and UMA allocation with ME +// as well as to inform ME of the end of POST event +// +#define HECI_CLIENT_CORE_MSG_DISPATCHER 0x07 +#define HOST_FIXED_ADDRESS 0x00 + +typedef union _HECI_MESSAGE_HEADER { + UINT32 Data; + struct { + UINT32 MeAddress : 8; + UINT32 HostAddress : 8; + UINT32 Length : 9; + UINT32 Reserved : 6; + UINT32 MessageComplete : 1; + } Fields; +} HECI_MESSAGE_HEADER; + +/// +/// Reset request message +/// +typedef struct _CBM_RESET_REQ_DATA { + UINT8 RequestOrigin; + UINT8 ResetType; +} CBM_RESET_REQ_DATA; + +typedef struct _CBM_RESET_REQ { + MKHI_MESSAGE_HEADER MKHIHeader; + CBM_RESET_REQ_DATA Data; +} CBM_RESET_REQ; + +typedef struct _MKHI_CBM_RESET_REQ { + HECI_MESSAGE_HEADER Header; + CBM_RESET_REQ Msg; +} MKHI_CBM_RESET_REQ; + +/// +/// Reset request ack message +/// +typedef struct _CBM_RESET_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; +} CBM_RESET_ACK; + +typedef struct _MKHI_CBM_RESET_ACK { + HECI_MESSAGE_HEADER Header; + CBM_RESET_ACK Msg; +} MKHI_CBM_RESET_ACK; + +// +// ASF Watch Dog Timer +// +#define ASF_MANAGEMENT_CONTROL 0x02 +#define ASF_SUB_COMMAND_START_WDT 0x13 +#define ASF_SUB_COMMAND_STOP_WDT 0x14 + +/// +/// ASF Start Watch Dog +/// +typedef struct _ASF_START_WDT { + UINT8 Command; + UINT8 ByteCount; + UINT8 SubCommand; + UINT8 VersionNumber; + UINT8 TimeoutLow; + UINT8 TimeoutHigh; + UINT8 EventSensorType; + UINT8 EventType; + UINT8 EventOffset; + UINT8 EventSourceType; + UINT8 EventSeverity; + UINT8 SensorDevice; + UINT8 SensorNumber; + UINT8 Entity; + UINT8 EntityInstance; + UINT8 EventData[5]; +} ASF_START_WDT; + +#define ASF_START_WDT_LENGTH 0x14 + +/// +/// ASF Stop Watch Dog +/// +typedef struct _ASF_STOP_WDT { + UINT8 Command; + UINT8 ByteCount; + UINT8 SubCommand; + UINT8 VersionNumber; +} ASF_STOP_WDT; + +#define ASF_STOP_WDT_LENGTH 0x04 + +// +// HECI Header Definitions for Core BIOS Messages +// +#define CBM_END_OF_POST_HECI_HDR 0x80080001 +#define CBM_END_OF_POST_RESPONSE_HECI_HDR 0x80010001 +#define CBM_RESET_REQUEST_HECI_HDR 0x80030001 +#define CBM_RESET_RESPONSE_HECI_HDR 0x80020001 + +// +// Enumerations used in Core BIOS Messages +// +// End Of Post Codes. +// +#define CBM_EOP_EXITING_G3 0x01 +#define CBM_EOP_RESERVED 0x02 +#define CBM_EOP_EXITING_S3 0x03 +#define CBM_EOP_EXITING_S4 0x04 +#define CBM_EOP_EXITING_S5 0x05 + +// +// Reset Request Origin Codes. +// +#define CBM_RR_REQ_ORIGIN_BIOS_MEMORY_INIT 0x01 +#define CBM_RR_REQ_ORIGIN_BIOS_POST 0x02 +#define CBM_RR_REQ_ORIGIN_MEBX 0x03 + +// +// Reset Type Codes. +// +#define CBM_HRR_GLOBAL_RESET 0x01 + +// +// Reset Response Codes. +// +#define CBM_HRR_RES_REQ_NOT_ACCEPTED 0x01 + +// +// definitions for ICC MEI Messages +// +#define IBEX_PEAK_PLATFORM 0x00010000 +#define COUGAR_POINT_PLATFORM 0x00020000 +#define LYNX_POINT_PLATFORM 0x00030000 + +typedef enum { + ICC_STATUS_SUCCESS = 0, + ICC_STATUS_SUCCESS_WAITING_FOR_RESET, + ICC_STATUS_INCORRECT_API_VERSION, + ICC_STATUS_INVALID_FUNCTION, + ICC_STATUS_INVALID_BUFFER_LENGTH, + ICC_STATUS_INVALID_PARAMETERS, + ICC_STATUS_FLASH_WEAR_OUT_VIOLATION, + ICC_STATUS_CLOCK_REQ_ENTRY_VIOLATION, + ICC_STATUS_STATIC_REGISTER_MASK_VIOLATION, + ICC_STATUS_DYNAMIC_REGISTER_MASK_VIOLATION, + ICC_STATUS_IMMEDIATE_REQUIRES_POWER_CYCLE, + ICC_STATUS_ILLEGAL_RECORD_ID, + ICC_STATUS_ENABLED_CLOCK_MASK_VIOLATION, + ICC_STATUS_INVALID = 0xFFFFFFFF +} ICC_MEI_CMD_STATUS; + +typedef union _ICC_CLOCK_ENABLES_CONTROL_MASK { + UINT32 Dword; + struct { + UINT32 Flex0 : 1; + UINT32 Flex1 : 1; + UINT32 Flex2 : 1; + UINT32 Flex3 : 1; + UINT32 Reserved1 : 3; + UINT32 PCI_Clock0 : 1; + UINT32 PCI_Clock1 : 1; + UINT32 PCI_Clock2 : 1; + UINT32 PCI_Clock3 : 1; + UINT32 PCI_Clock4 : 1; + UINT32 Reserved2 : 4; + UINT32 SRC0 : 1; + UINT32 SRC1 : 1; + UINT32 SRC2 : 1; + UINT32 SRC3 : 1; + UINT32 SRC4 : 1; + UINT32 SRC5 : 1; + UINT32 SRC6 : 1; + UINT32 SRC7 : 1; + UINT32 CSI_SRC8 : 1; + UINT32 CSI_DP : 1; + UINT32 PEG_A : 1; + UINT32 PEG_B : 1; + UINT32 DMI : 1; + UINT32 Reserved3 : 3; + } Fields; +} ICC_CLOCK_ENABLES_CONTROL_MASK; + +typedef enum { + LOCK_ICC_REGISTERS = 0x2, + SET_CLOCK_ENABLES = 0x3, + GET_ICC_PROFILE = 0x4, + SET_ICC_PROFILE = 0x5, + GET_ICC_CLOCKS_CAPABILITIES = 0x6, + GET_OEM_CLOCK_RANGE_DEFINITION_RECORD = 0x7, + GET_ICC_RECORD = 0x8, + READ_ICC_REGISTER = 0x9, + WRITE_ICC_REGISTER = 0xa, + WRITE_UOB_RECORD = 0xb, + READ_MPHY_SETTINGS = 0xe, + WRITE_MPHY_SETTINGS = 0xf +} ICC_MEI_COMMAND_ID; + +typedef struct { + UINT32 ApiVersion; + ICC_MEI_COMMAND_ID IccCommand; + ICC_MEI_CMD_STATUS IccResponse; + UINT32 BufferLength; + UINT32 Reserved; +} ICC_HEADER; + +typedef struct { + ICC_HEADER Header; +} ICC_GET_PROFILE_MESSAGE; + +typedef struct { + ICC_HEADER Header; + UINT8 SupportedProfilesNumber; + UINT8 IccProfileSoftStrap; + UINT8 IccProfileIndex; + UINT8 Padding; +} ICC_GET_PROFILE_RESPONSE; + +typedef union { + ICC_GET_PROFILE_MESSAGE message; + ICC_GET_PROFILE_RESPONSE response; +} ICC_GET_PROFILE_BUFFER; + +typedef struct { + ICC_HEADER Header; + UINT8 ProfileBIOS; + UINT8 PaddingA; + UINT16 PaddingB; +} ICC_SET_PROFILE_MESSAGE; + +typedef struct { + ICC_HEADER Header; +} ICC_SET_PROFILE_RESPONSE; + +typedef union { + ICC_SET_PROFILE_MESSAGE message; + ICC_SET_PROFILE_RESPONSE response; +} ICC_SET_PROFILE_BUFFER; + +typedef struct { + ICC_HEADER Header; + UINT32 ClockEnables; + UINT32 ClockEnablesMask; + UINT32 Params; +} ICC_SET_CLK_ENABLES_MESSAGE; + +typedef struct { + ICC_HEADER Header; +} ICC_SET_CLK_ENABLES_RESPONSE; + +typedef union { + ICC_SET_CLK_ENABLES_MESSAGE message; + ICC_SET_CLK_ENABLES_RESPONSE response; +} ICC_SET_CLK_ENABLES_BUFFER; + +typedef struct { + ICC_HEADER Header; +} ICC_GET_CLK_CAPABILITIES_MESSAGE; + +typedef struct { + ICC_HEADER Header; + UINT32 VersionNumber; + UINT8 IccHwSku; + UINT8 Reserved; + UINT16 MaxSusramRecordSize; + UINT64 IccSkuEnforcementTable; + UINT32 IccBootStatusReport; +} ICC_GET_CLK_CAPABILITIES_RESPONSE; + +typedef union { + ICC_GET_CLK_CAPABILITIES_MESSAGE message; + ICC_GET_CLK_CAPABILITIES_RESPONSE response; +} ICC_GET_CLK_CAPABILITIES_BUFFER; + +#define ICC_RESPONSE_MODE_WAIT 0 +#define ICC_RESPONSE_MODE_SKIP 1 +#define ICC_LOCK_ACCESS_MODE_SET 0 +#define ICC_LOCK_ACCESS_MODE_GET 1 +#define ICC_LOCK_MASK_COUNT 255 +#define WRITE_ICC_REG_BUNDLE_COUNT 1 ///< 1 bundle for 1 DWORD register write +#define ADDRESS_MASK_FIXED_DATA 0x00017F01 ///< Target ID = 7F (Aux), MWM = 1(16 bits) +#define WRITE_ICC_RECORD_FLAGS 0x00012010 ///< 16 byte record length, No param section, valid bit + +typedef struct _ICC_REG_BUNDLES +{ + UINT32 BundlesCnt :16; ///< Bundles Count - number of Address Mask entries + UINT32 AU :1; ///< AU=1 -> All regisaters are Unlocked + UINT32 Reserved :15; +} ICC_REG_BUNDLES; + +typedef struct { + ICC_REG_BUNDLES RegBundles; + UINT32 RegMask[ICC_LOCK_MASK_COUNT]; +} ICC_LOCK_REGS_INFO; + +typedef struct { + ICC_HEADER Header; + UINT8 AccessMode; + UINT8 Parameters; + UINT8 Reserved[2]; + ICC_LOCK_REGS_INFO LockRegInfo; +} ICC_LOCK_REGISTERS_MESSAGE; + +typedef struct { + ICC_HEADER Header; + UINT32 Reserved; + ICC_LOCK_REGS_INFO LockRegInfo; +} ICC_LOCK_REGISTERS_RESPONSE; + +typedef union { + ICC_LOCK_REGISTERS_MESSAGE message; + ICC_LOCK_REGISTERS_RESPONSE response; +} ICC_LOCK_REGISTERS_BUFFER; + +typedef union _ICC_ADDRESS_MASK +{ + UINT32 AddressMaskData; + struct + { + UINT32 MaskWidthModifier :2; + UINT32 Offset :6; + UINT32 TargetId :7; + UINT32 Reserved :1; + }Fields; +} ICC_ADDRESS_MASK; + +typedef struct _ICC_DWORD_RECORD +{ + UINT32 RecordFlags; + ICC_REG_BUNDLES BundleCount; + ICC_ADDRESS_MASK AddressMask; + UINT32 RegValue; +} ICC_RECORD_DWORD; + +typedef struct { + ICC_HEADER Header; + UINT16 Reserved; + UINT8 Params; + UINT8 Reserved1; + ICC_RECORD_DWORD RecordDword; +} ICC_WRITE_ICC_REG_DWORD_MESSAGE; + +typedef struct { + ICC_HEADER Header; + UINT16 BytesProcessed; + UINT16 Reserved; +} ICC_WRITE_ICC_REG_DWORD_RESPONSE; + +typedef union { + ICC_WRITE_ICC_REG_DWORD_MESSAGE message; + ICC_WRITE_ICC_REG_DWORD_RESPONSE response; +} ICC_WRITE_ICC_REG_BUFFER; + +// +// SPI MEI Messages +// +#define HMRFPO_ENABLE_CMD_ID 0x01 +#define HMRFPO_LOCK_CMD_ID 0x02 +#define HMRFPO_GET_STATUS_CMD_ID 0x03 + +typedef enum { + HMRFPO_ENABLE_SUCCESS = 0, + HMRFPO_ENABLE_LOCKED, + HMRFPO_NVAR_FAILURE, + HMRFOP_ATP_POLICY, + HMRFPO_ENABLE_UNKNOWN_FAILURE +} HMRFPO_ENABLE_STATUS; + +typedef struct _MKHI_HMRFPO_ENABLE { + MKHI_MESSAGE_HEADER MkhiHeader; + UINT64 Nonce; +} MKHI_HMRFPO_ENABLE; + +typedef struct _HMRFPO_ENABLE { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_ENABLE Msg; +} HMRFPO_ENABLE; + +typedef struct _MKHI_HMRFPO_ENABLE_RESPONSE { + MKHI_MESSAGE_HEADER MkhiHeader; + UINT32 FactoryDefaultBase; + UINT32 FactoryDefaultLimit; + UINT8 Status; + UINT8 Rsvd[3]; +} MKHI_HMRFPO_ENABLE_RESPONSE; + +typedef struct _HMRFPO_ENABLE_RESPONSE { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_ENABLE_RESPONSE Msg; +} HMRFPO_ENABLE_RESPONSE; + +typedef enum { + HMRFPO_LOCK_SUCCESS = 0, + HMRFPO_LOCK_FAILURE +} HMRFPO_LOCK_STATUS; + +typedef struct _MKHI_HMRFPO_LOCK { + MKHI_MESSAGE_HEADER MkhiHeader; +} MKHI_HMRFPO_LOCK; + +typedef struct _HMRFPO_LOCK { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_LOCK Msg; +} HMRFPO_LOCK; + +typedef struct _MKHI_HMRFPO_LOCK_RESPONSE { + MKHI_MESSAGE_HEADER MkhiHeader; + UINT64 Nonce; + UINT32 FactoryDefaultBase; + UINT32 FactoryDefaultLimit; + UINT8 Status; + UINT8 Reserved[3]; +} MKHI_HMRFPO_LOCK_RESPONSE; + +typedef struct _HMRFPO_LOCK_RESPONSE { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_LOCK_RESPONSE Data; +} HMRFPO_LOCK_RESPONSE; + +typedef struct _MKHI_HMRFPO_GET_STATUS { + MKHI_MESSAGE_HEADER MkhiHeader; +} MKHI_HMRFPO_GET_STATUS; + +typedef struct _HMRFPO_GET_STATUS { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_GET_STATUS Msg; +} HMRFPO_GET_STATUS; + +typedef struct _MKHI_HMRFPO_GET_STATUS_RESPONSE { + MKHI_MESSAGE_HEADER MkhiHeader; + UINT8 Status; + UINT8 Reserved[3]; +} MKHI_HMRFPO_GET_STATUS_RESPONSE; + +typedef struct _HMRFPO_GET_STATUS_RESPONSE { + HECI_MESSAGE_HEADER Header; + MKHI_HMRFPO_GET_STATUS_RESPONSE Data; +} HMRFPO_GET_STATUS_RESPONSE; + +#define HMRFPO_LOCKED 1 +#define HMRFPO_ENABLED 2 + +// +// ME State Control +// +#define EFI_ME_STATE_STALL_1_SECOND 1000000 +#define EFI_ME_STATE_MAX_TIMEOUT 20 +// +// KVM support +// +#define EFI_KVM_MESSAGE_COMMAND 0x08 +#define EFI_KVM_BYTE_COUNT 0x06 +#define EFI_KVM_QUERY_REQUES 0x01 +#define EFI_KVM_QUERY_RESPONSE 0x02 +#define EFI_KVM_VERSION 0x10 + +#define EFI_KVM_STALL_1_SECOND 1000000 ///< Stall 1 second +#define EFI_KVM_MAX_WAIT_TIME (60 * 8) ///< 8 Mins +typedef enum { + QUERY_REQUEST = 0, + CANCEL_REQUEST +} QUERY_TYPE; + +typedef struct _AMT_QUERY_KVM_REQUEST { + UINT8 Command; + UINT8 ByteCount; + UINT8 SubCommand; + UINT8 VersionNumber; + UINT32 QueryType; +} AMT_QUERY_KVM_REQUEST; + +typedef enum { + KVM_SESSION_ESTABLISHED = 1, + KVM_SESSION_CANCELLED +} RESPONSE_CODE; + +typedef struct _AMT_QUERY_KVM_RESPONSE { + UINT8 Command; + UINT8 ByteCount; + UINT8 SubCommand; + UINT8 VersionNumber; + UINT32 ResponseCode; +} AMT_QUERY_KVM_RESPONSE; + +/// +/// ME Memory Debug support +/// +typedef struct _SET_DEBUG_MEMORY_DATA { + UINT32 BiosDebugMemoryAddress; + UINT32 BiosDebugMemorySize; + UINT32 MeVeDebugMemoryAddress; + UINT32 MeVeDebugMemorySize; +} SET_DEBUG_MEMORY_DATA; + +typedef struct _GEN_SET_DEBUG_MEMORY { + MKHI_MESSAGE_HEADER MKHIHeader; + SET_DEBUG_MEMORY_DATA Data; +} GEN_SET_DEBUG_MEMORY; + +typedef struct _GEN_SET_DEBUG_MEMORY_ACK { + MKHI_MESSAGE_HEADER Header; +} GEN_SET_DEBUG_MEMORY_ACK; + +// +// BIOS MDES messaging +// +#define MDES_BIOS_MSG_LOG_REQ_CMD 0x0B +#define MDES_BIOS_MSG_GET_CONFIG_CMD 0x0C + +typedef struct _MDES_ATTR { + UINT16 Severity : 2; + UINT16 PayLoadType : 6; + UINT16 Reserved : 8; +} MDES_ATTR; + +typedef struct _BIOS_ATTR { + UINT16 CallerIdData : 1; + UINT16 ExtendedDataHeader : 1; + UINT16 Reserved : 14; +} BIOS_ATTR; + +typedef struct { + UINT16 HeaderSize; + UINT16 Size; + EFI_GUID Type; +} MDES_EXTENDED_DATA_HEADER; + +#define SIZE_OF_MDES_EXTENDED_DATA (2048 - \ + ( \ + 16 + sizeof (MDES_ATTR) + sizeof (BIOS_ATTR) + sizeof (EFI_GUID) + sizeof (MDES_EXTENDED_DATA_HEADER) + \ + sizeof (MKHI_MESSAGE_HEADER) \ + ) \ + ) + +typedef struct _CBM_BIOS_MDES_MSG_DATA { + MDES_ATTR MdesAttr; + BIOS_ATTR BiosAttr; + UINT32 Serial; + UINT32 StatusType; + UINT32 StatusCode; + UINT32 Instance; + EFI_GUID CallerId; + MDES_EXTENDED_DATA_HEADER ExtendedDataHeader; + UINT8 ExtendedData[SIZE_OF_MDES_EXTENDED_DATA]; +} CBM_BIOS_MDES_MSG_DATA; + +typedef struct _CBM_BIOS_MDES_MSG_REQ { + MKHI_MESSAGE_HEADER MKHIHeader; + CBM_BIOS_MDES_MSG_DATA Data; +} CBM_BIOS_MDES_MSG_REQ; + +typedef struct _MKHI_CBM_BIOS_MDES_MSG_REQ { + HECI_MESSAGE_HEADER Header; + CBM_BIOS_MDES_MSG_REQ Msg; +} MKHI_CBM_BIOS_MDES_MSG_REQ; + +typedef struct _MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_REQ { + MKHI_MESSAGE_HEADER MKHIHeader; +} MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_REQ; + +typedef union _MDES_BIOS_FLAGS { + volatile UINT32 ul; + struct { + UINT32 MdesEnabled : 1; ///< High level indication if MDES is enabled + UINT32 MdesLogPaused : 1; ///< A caller paused MDES logging as part of the log retrieval process + UINT32 LanInterfaceEnabled : 1; ///< The user configuration has enabled the LAN debug interface + UINT32 SmbusInterfaceEnabled : 1; ///< The user configuration has enabled the SMBus debug interface + UINT32 PramLogEnabled : 1; ///< The user configuration has enabled the PRAM debug log + UINT32 FlashLogEnabled : 1; ///< The user configuration has enabled the flash error log + UINT32 MdesBlockingModeEn : 1; ///< Set to 0 when operating in buffered mode, set to 1 when MDES blocks the caller until the event is dispatched. + UINT32 Reserved7 : 2; + UINT32 SensitiveMsgEnabled : 1; ///< Set to 1 to indicate Sensitive messages are enabled + UINT32 DescriptorUnlocked : 1; ///< Set when FW reads all regions are unlocked. Enables 'none' sensitivity messages. + UINT32 MdesPolicyEnabled : 1; ///< Set to 1 to indicate MDES is enabled due to BIOS sending the enable message (on current or previous boot) + UINT32 MdesEnableRcvdFromBios : 1; ///< BIOS has sent the MDES policy to 'enabled' via a MKHI message on this current boot + UINT32 Reserved13 : 19; + } fl; +} MDES_BIOS_FLAGS; + +typedef struct _CBM_BIOS_MDES_MSG_GET_CONFIG_DATA { + MDES_BIOS_FLAGS Flags; + UINT32 BiosEventFilters; +} CBM_BIOS_MDES_MSG_GET_CONFIG_DATA; + +typedef struct _MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_ACK { + MKHI_MESSAGE_HEADER Header; + CBM_BIOS_MDES_MSG_GET_CONFIG_DATA Data; +} MKHI_CBM_BIOS_MDES_MSG_GET_CONFIG_ACK; + +#pragma pack() + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/include/MeAccess.h b/ReferenceCode/ME/Library/MeKernel/include/MeAccess.h new file mode 100644 index 0000000..6a7c16d --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/MeAccess.h @@ -0,0 +1,338 @@ +/** @file + Macros to simplify and abstract the interface to PCI configuration. + +@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 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_ACCESS_H_ +#define _ME_ACCESS_H_ + +#include "MeChipset.h" +#include "PchAccess.h" + +/// +/// HECI PCI Access Macro +/// +#define HeciPciRead32(Register) PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register)) + +#define HeciPciWrite32(Register, Data) \ + PciWrite32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define HeciPciOr32(Register, Data) \ + PciOr32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define HeciPciAnd32(Register, Data) \ + PciAnd32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define HeciPciAndThenOr32(Register, AndData, OrData) \ + PciAndThenOr32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT32) AndData, \ + (UINT32) OrData \ + ) + +#define HeciPciRead16(Register) PciRead16 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register)) + +#define HeciPciWrite16(Register, Data) \ + PciWrite16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define HeciPciOr16(Register, Data) \ + PciOr16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define HeciPciAnd16(Register, Data) \ + PciAnd16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define HeciPciAndThenOr16(Register, AndData, OrData) \ + PciAndThenOr16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT16) AndData, \ + (UINT16) OrData \ + ) + +#define HeciPciRead8(Register) PciRead8 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, Register)) + +#define HeciPciWrite8(Register, Data) \ + PciWrite8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define HeciPciOr8(Register, Data) \ + PciOr8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define HeciPciAnd8(Register, Data) \ + PciAnd8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define HeciPciAndThenOr8(Register, AndData, OrData) \ + PciAndThenOr8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI_FUNCTION_NUMBER, \ + Register), \ + (UINT8) AndData, \ + (UINT8) OrData \ + ) + +/// +/// HECI2 PCI Access Macro +/// +#define Heci2PciRead32(Register) PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register)) + +#define Heci2PciWrite32(Register, Data) \ + PciWrite32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define Heci2PciOr32(Register, Data) \ + PciOr32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define Heci2PciAnd32(Register, Data) \ + PciAnd32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT32) Data \ + ) + +#define Heci2PciAndThenOr32(Register, AndData, OrData) \ + PciAndThenOr32 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT32) AndData, \ + (UINT32) OrData \ + ) + +#define Heci2PciRead16(Register) PciRead16 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register)) + +#define Heci2PciWrite16(Register, Data) \ + PciWrite16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define Heci2PciOr16(Register, Data) \ + PciOr16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define Heci2PciAnd16(Register, Data) \ + PciAnd16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT16) Data \ + ) + +#define Heci2PciAndThenOr16(Register, AndData, OrData) \ + PciAndThenOr16 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT16) AndData, \ + (UINT16) OrData \ + ) + +#define Heci2PciRead8(Register) PciRead8 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI2_FUNCTION_NUMBER, Register)) + +#define Heci2PciWrite8(Register, Data) \ + PciWrite8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define Heci2PciOr8(Register, Data) \ + PciOr8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define Heci2PciAnd8(Register, Data) \ + PciAnd8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT8) Data \ + ) + +#define Heci2PciAndThenOr8(Register, AndData, OrData) \ + PciAndThenOr8 ( \ + PCI_LIB_ADDRESS (ME_BUS, \ + ME_DEVICE_NUMBER, \ + HECI2_FUNCTION_NUMBER, \ + Register), \ + (UINT8) AndData, \ + (UINT8) OrData \ + ) + +#ifndef MmPciAddress +#define MmPciAddress(Segment, Bus, Device, Function, Register) \ + ( \ + (UINTN) (PciRead32 (PCI_LIB_ADDRESS (0,0,0,0x60)) & 0xFC000000) + \ + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) \ + (Function << 12) + (UINTN) (Register) \ + ) +#endif +/// +/// ME Macro Setting +/// +#define McD0PciCfg64(Register) MmPci64 (0, SA_MC_BUS, 0, 0, Register) +#define McD0PciCfg32And(Register, AndData) PciAnd32 (PCI_LIB_ADDRESS (SA_MC_BUS, 0, 0, Register), (UINT32) AndData) +#define McD0PciCfg16And(Register, AndData) PciAnd16 (PCI_LIB_ADDRESS (SA_MC_BUS, 0, 0, Register), (UINT16) AndData) + +/// +/// MMIO access macros +/// +#define MmioAddress(BaseAddr, Register) ((UINTN) BaseAddr + (UINTN) (Register)) + +/// +/// 16 bit MMIO access +/// +#define Mmio16Ptr(BaseAddr, Register) ((volatile UINT16 *) MmioAddress (BaseAddr, Register)) + +#define Mmio16(BaseAddr, Register) *Mmio16Ptr (BaseAddr, Register) + +#define Mmio16Or(BaseAddr, Register, OrData) \ + Mmio16 (BaseAddr, Register) = (UINT16) \ + (Mmio16 (BaseAddr, Register) | (UINT16) (OrData)) + +#define Mmio16And(BaseAddr, Register, AndData) \ + Mmio16 (BaseAddr, Register) = (UINT16) \ + (Mmio16 (BaseAddr, Register) & (UINT16) (AndData)) + +#define Mmio16AndThenOr(BaseAddr, Register, AndData, OrData) \ + Mmio16 (BaseAddr, Register) = (UINT16) \ + ((Mmio16 (BaseAddr, Register) & (UINT16) (AndData)) | (UINT16) (OrData)) + +/// +/// 32 bit MMIO access +/// +#define Mmio32Ptr(BaseAddr, Register) ((volatile UINT32 *) MmioAddress (BaseAddr, Register)) + +#define Mmio32(BaseAddr, Register) *Mmio32Ptr (BaseAddr, Register) + +#define Mmio32Or(BaseAddr, Register, OrData) \ + Mmio32 (BaseAddr, Register) = (UINT32) \ + (Mmio32 (BaseAddr, Register) | (UINT32) (OrData)) + +#define Mmio32And(BaseAddr, Register, AndData) \ + Mmio32 (BaseAddr, Register) = (UINT32) \ + (Mmio32 (BaseAddr, Register) & (UINT32) (AndData)) + +#define Mmio32AndThenOr(BaseAddr, Register, AndData, OrData) \ + Mmio32 (BaseAddr, Register) = (UINT32) \ + ((Mmio32 (BaseAddr, Register) & (UINT32) (AndData)) | (UINT32) (OrData)) + +/// +/// Memory Controller PCI access macros +/// +#define MCH_REGION_BASE (McD0PciCfg64 (MC_MCHBAR_OFFSET) &~BIT0) +#define McMmioAddress(Register) ((UINTN) MCH_REGION_BASE + (UINTN) (Register)) + +#define McMmio8Ptr(Register) ((volatile UINT8 *) McMmioAddress (Register)) +#define McMmio8(Register) *McMmio8Ptr (Register) +#define McMmio8Or(Register, OrData) (McMmio8 (Register) |= (UINT8) (OrData)) +#define McMmio8And(Register, AndData) (McMmio8 (Register) &= (UINT8) (AndData)) +#define McMmio8AndThenOr(Register, AndData, OrData) \ + (McMmio8 (Register) = (McMmio8 (Register) & (UINT8) (AndData)) | (UINT8) (OrData)) + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/include/MeChipset.h b/ReferenceCode/ME/Library/MeKernel/include/MeChipset.h new file mode 100644 index 0000000..f18ac61 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/MeChipset.h @@ -0,0 +1,196 @@ +/** @file + Chipset definition for ME Devices. + + Conventions: + + - Prefixes: + Definitions beginning with "R_" are registers + Definitions beginning with "B_" are bits within registers + Definitions beginning with "V_" are meaningful values of bits within the registers + Definitions beginning with "S_" are register sizes + Definitions beginning with "N_" are the bit position + - In general, ME registers are denoted by "_ME_" in register names + - Registers / bits that are different between ME generations are denoted by + "_ME_<generation_name>_" in register/bit names. e.g., "_ME_CPT_" + - Registers / bits that are different between SKUs are denoted by "_<SKU_name>" + at the end of the register/bit names + - Registers / bits of new devices introduced in a ME generation will be just named + as "_ME_" without <generation_name> inserted. + +@copyright + Copyright (c) 2011 - 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 _ME_CHIPSET_H_ +#define _ME_CHIPSET_H_ + +#include "MeChipsetLib.h" + +#define ME_BUS 0 +#define ME_DEVICE_NUMBER 22 + +#define HECI_FUNCTION_NUMBER 0x00 +#define HECI2_FUNCTION_NUMBER 0x01 +#define IDER_FUNCTION_NUMBER 0x02 +#define SOL_FUNCTION_NUMBER 0x03 + +#define IDER_BUS_NUMBER ME_BUS +#define IDER_DEVICE_NUMBER ME_DEVICE_NUMBER +#define SOL_BUS_NUMBER ME_BUS +#define SOL_DEVICE_NUMBER ME_DEVICE_NUMBER +#define HECI_DEV_FCN ((ME_DEVICE_NUMBER) << 3 | (HECI_FUNCTION_NUMBER)) +#define HECI2_DEV_FCN ((ME_DEVICE_NUMBER) << 3 | (HECI2_FUNCTION_NUMBER)) + +/// +/// Default Vendor ID and Device ID +/// +#define V_INTEL_VENDOR_ID 0x8086 + +#define V_ME_HECI_VENDOR_ID V_INTEL_VENDOR_ID +#define V_ME_IDER_VENDOR_ID V_INTEL_VENDOR_ID +#define V_ME_SOL_VENDOR_ID V_INTEL_VENDOR_ID + +#define V_ME_HECI_DEVICE_ID 0x8C3A +#define V_ME_HECI2_DEVICE_ID 0x8C3B +#define V_ME_IDER_DEVICE_ID 0x8C3C +#define V_ME_SOL_DEVICE_ID 0x8C3D + +#define V_ME_LPTLP_HECI_DEVICE_ID 0x9C3A +#define V_ME_LPTLP_HECI2_DEVICE_ID 0x9C3B +#define V_ME_LPTLP_IDER_DEVICE_ID 0x9C3C +#define V_ME_LPTLP_SOL_DEVICE_ID 0x9C3D + +#define R_ME_HFS 0x40 +#define R_ME_MISC_SHDW 0x44 +#define R_ME_GS_SHDW 0x48 +#define R_ME_HFS_4 0x64 +#define R_ME_HFS_5 0x68 +#define R_ME_HFS_6 0x6C +#define B_BOOT_GUARD_ENF_MASK 0x0200 +#define B_TPM_DISCONNECT 0x1000 +#define B_TPM1_2_DEACTIVATED 0x0100 + +#define R_ME_H_GS 0x4C +#define B_ME_DID_RAPID_START_BIT BIT23 +#define B_ME_DID_TYPE_MASK BIT28 +#define R_ME_H_GS2 0x70 +#define B_ME_MBP_GIVE_UP BIT0 +#define R_ME_HERS 0xBC +#define B_ME_EXTEND_REG_VALID BIT31 +#define B_ME_EXTEND_REG_ALGORITHM (BIT0 | BIT1 | BIT2 | BIT3) +#define V_ME_SHA_1 0x00 +#define V_ME_SHA_256 0x02 +#define R_ME_HER1 0xC0 +#define R_ME_HER2 0xC4 +#define R_ME_HER3 0xC8 +#define R_ME_HER4 0xCC +#define R_ME_HER5 0xD0 +#define R_ME_HER6 0xD4 +#define R_ME_HER7 0xD8 +#define R_ME_HER8 0xDC + +/// +/// ME-related Chipset Definition +/// +#define HeciEnable() MeDeviceControl (HECI1, Enabled); +#define Heci2Enable() MeDeviceControl (HECI2, Enabled); +#define IderEnable() MeDeviceControl (IDER, Enabled); +#define SolEnable() MeDeviceControl (SOL, Enabled); +#define Usbr1Enable() MeDeviceControl (USBR1, Enabled); +#define Usbr2Enable() MeDeviceControl (USBR2, Enabled); + +#define HeciDisable() MeDeviceControl (HECI1, Disabled); +#define Heci2Disable() MeDeviceControl (HECI2, Disabled); +#define IderDisable() MeDeviceControl (IDER, Disabled); +#define SolDisable() MeDeviceControl (SOL, Disabled); +#define Usbr1Disable() MeDeviceControl (USBR1, Disabled); +#define Usbr2Disable() MeDeviceControl (USBR2, Disabled); +#define DisableAllMEDevices() \ + HeciDisable (); \ + Heci2Disable (); \ + IderDisable (); \ + SolDisable (); + +#define IS_PCH_LPTH_HECI_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_HECI_DEVICE_ID) \ + ) + +#define IS_PCH_LPTLP_HECI_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_LPTLP_HECI_DEVICE_ID) \ + ) + +#define IS_PCH_LPT_HECI_DEVICE_ID(DeviceId) \ + ( \ + IS_PCH_LPTH_HECI_DEVICE_ID(DeviceId) || \ + IS_PCH_LPTLP_HECI_DEVICE_ID(DeviceId) \ + ) + +#define IS_PCH_LPTH_HECI2_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_HECI2_DEVICE_ID) \ + ) + +#define IS_PCH_LPTLP_HECI2_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_LPTLP_HECI2_DEVICE_ID) \ + ) + +#define IS_PCH_LPT_HECI2_DEVICE_ID(DeviceId) \ + ( \ + IS_PCH_LPTH_HECI2_DEVICE_ID(DeviceId) || \ + IS_PCH_LPTLP_HECI2_DEVICE_ID(DeviceId) \ + ) + +#define IS_PCH_LPTH_IDER_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_IDER_DEVICE_ID) \ + ) + +#define IS_PCH_LPTLP_IDER_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_LPTLP_IDER_DEVICE_ID) \ + ) + +#define IS_PCH_LPT_IDER_DEVICE_ID(DeviceId) \ + ( \ + IS_PCH_LPTH_IDER_DEVICE_ID(DeviceId) || \ + IS_PCH_LPTLP_IDER_DEVICE_ID(DeviceId) \ + ) + +#define IS_PCH_LPTH_SOL_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_SOL_DEVICE_ID) \ + ) + +#define IS_PCH_LPTLP_SOL_DEVICE_ID(DeviceId) \ + ( \ + (DeviceId == V_ME_LPTLP_SOL_DEVICE_ID) \ + ) + +#define IS_PCH_LPT_SOL_DEVICE_ID(DeviceId) \ + ( \ + IS_PCH_LPTH_SOL_DEVICE_ID(DeviceId) || \ + IS_PCH_LPTLP_SOL_DEVICE_ID(DeviceId) \ + ) + +/// +/// Function Disable SUS well lockdown +/// +#define FunctionDisableWellLockdown() MeDeviceControl (FDSWL, Enabled); + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/include/MeChipsetLib.h b/ReferenceCode/ME/Library/MeKernel/include/MeChipsetLib.h new file mode 100644 index 0000000..dfa9417 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/MeChipsetLib.h @@ -0,0 +1,54 @@ +/** @file + Header file for Me Chipset Lib + +@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 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_CHIPSET_LIB_H_ +#define _ME_CHIPSET_LIB_H_ + +typedef enum { + HECI1 = 1, + HECI2, + IDER, + SOL, + USBR1, + USBR2, + FDSWL, +} ME_DEVICE; + +typedef enum { + Disabled= 0, + Enabled, +} ME_DEVICE_FUNC_CTRL; + +/** + Enable/Disable Me devices + + @param[in] WhichDevice Select of Me device + @param[in] DeviceFuncCtrl Function control + + @retval None +**/ +VOID +MeDeviceControl ( + IN ME_DEVICE WhichDevice, + IN ME_DEVICE_FUNC_CTRL DeviceFuncCtrl + ) +; + +#endif diff --git a/ReferenceCode/ME/Library/MeKernel/include/MeState.h b/ReferenceCode/ME/Library/MeKernel/include/MeState.h new file mode 100644 index 0000000..55bb7bd --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/MeState.h @@ -0,0 +1,67 @@ +/** @file + Register Definitions for Me States + +@copyright + Copyright (c) 2009 - 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_STATE_H +#define _ME_STATE_H +/// +/// Ignore ME_FW_INIT_COMPLETE status Macro +/// +#define ME_STATUS_ME_STATE_ONLY(a) ((a) & (~(ME_FW_INIT_COMPLETE | ME_FW_BOOT_OPTIONS_PRESENT))) + +/// +/// Macro to check if ME FW INIT is completed +/// +#define ME_STATUS_IS_ME_FW_INIT_COMPLETE(a) (((a) & ME_FW_INIT_COMPLETE) == ME_FW_INIT_COMPLETE) + +/// +/// Marco to combind the complete bit to status +/// +#define ME_STATUS_WITH_ME_INIT_COMPLETE(a) ((a) | ME_FW_INIT_COMPLETE) + +/// +/// Macro to check ME Boot Option Present +/// +#define ME_STATUS_IS_ME_FW_BOOT_OPTIONS_PRESENT(a) (((a) & ME_FW_BOOT_OPTIONS_PRESENT) == ME_FW_BOOT_OPTIONS_PRESENT) + +// +// Abstract ME Mode Definitions +// +#define ME_MODE_NORMAL 0x00 +#define ME_MODE_DEBUG 0x02 +#define ME_MODE_TEMP_DISABLED 0x03 +#define ME_MODE_SECOVER 0x04 +#define ME_MODE_FAILED 0x06 + +// +// Abstract ME Status definitions +// +#define ME_READY 0x00 +#define ME_INITIALIZING 0x01 +#define ME_IN_RECOVERY_MODE 0x02 +#define ME_DISABLE_WAIT 0x06 +#define ME_TRANSITION 0x07 +#define ME_NOT_READY 0x0F +#define ME_FW_INIT_COMPLETE 0x80 +#define ME_FW_BOOT_OPTIONS_PRESENT 0x100 +#define ME_FW_UPDATES_IN_PROGRESS 0x200 + +#pragma pack() + +#endif // ME_STATE_H diff --git a/ReferenceCode/ME/Library/MeKernel/include/MkhiMsgs.h b/ReferenceCode/ME/Library/MeKernel/include/MkhiMsgs.h new file mode 100644 index 0000000..9005d62 --- /dev/null +++ b/ReferenceCode/ME/Library/MeKernel/include/MkhiMsgs.h @@ -0,0 +1,533 @@ +/** @file + MKHI Messages + +@copyright + Copyright (c) 2010 - 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 _MKHI_MSGS_H +#define _MKHI_MSGS_H + +#pragma pack(1) + +#define BIOS_FIXED_HOST_ADDR 0 +#define PREBOOT_FIXED_ME_ADDR 7 +#define BIOS_ASF_HOST_ADDR 1 + +#define HECI_CORE_MESSAGE_ADDR 0x07 +#define HECI_ASF_MESSAGE_ADDR 0x02 +#define HECI_FSC_MESSAGE_ADDR 0x03 +#define HECI_POLICY_MANAGER_ADDR 0x05 +#define HECI_AT_MESSAGE_ADDR 0x05 ///< Added to support AT +#define HECI_ME_PASSWORD_SERVICE_ADDR 0x06 +#define HECI_ICC_MESSAGE_ADDR 0x08 +#define HECI_TR_MESSAGE_ADDR 0x09 +#define HECI_SPI_MESSAGE_ADDR 0x0A + +#define NON_BLOCKING 0 +#define BLOCKING 1 + +// +// command handle by HCI +// +#define GEN_GET_MKHI_VERSION_CMD 0x01 +#define GEN_GET_MKHI_VERSION_CMD_ACK 0x81 +#define GEN_GET_FW_VERSION_CMD 0x02 +#define GEN_GET_FW_VERSION_CMD_ACK 0x82 +#define GEN_UNCFG_WO_PWD_CMD 0x0D +#define GEN_UNCFG_WO_PWD_CMD_ACK 0x8D + +#define FWCAPS_GET_RULE_CMD 0x02 +#define FWCAPS_SET_RULE_CMD 0x03 + +#define AT_ME_RULE_ID 0xd0000 + +// +// Enums for Result field of MHKI Header +// +#define ME_SUCCESS 0x00 +#define ME_ERROR_ALIAS_CHECK_FAILED 0x01 +#define ME_INVALID_MESSAGE 0x02 +#define ME_M1_DATA_OLDER_VER 0x03 +#define ME_M1_DATA_INVALID_VER 0x04 +#define ME_INVALID_M1_DATA 0x05 + +// +// MDES +// +#define MDES_ENABLE_MKHI_CMD 0x09 +#define MDES_ENABLE_MKHI_CMD_ACK 0x89 + +/// +/// IFR Update +/// +#define MEFWCAPS_ME_FWU_IFR_RULE 0x2E + +// +// Manageability State Control +// +#define FIRMWARE_CAPABILITY_OVERRIDE_CMD 0x14 +#define FIRMWARE_CAPABILITY_OVERRIDE_CMD_ACK 0x94 + +/// +/// Typedef for GroupID +/// +typedef enum { + MKHI_CBM_GROUP_ID = 0, + MKHI_PM_GROUP_ID, + MKHI_PWD_GROUP_ID, + MKHI_FWCAPS_GROUP_ID, + MKHI_APP_GROUP_ID, + MKHI_SPI_GROUP_ID, + MKHI_MDES_GROUP_ID = 8, + MKHI_MAX_GROUP_ID, + MKHI_GEN_GROUP_ID = 0xFF +} MKHI_GROUP_ID; + +/// +/// Typedef for AT State +/// +typedef enum _AT_STATE +{ + AT_STATE_INACTIVE = 0, + AT_STATE_ACTIVE, + AT_STATE_STOLEN, + AT_STATE_SUSPEND, + AT_STATE_MAX +} AT_STATE; + +/// +/// MKHI host message header. This header is part of HECI message sent from MEBx via +/// Host Configuration Interface (HCI). ME Configuration Manager or Power Configuration +/// Manager also include this header with appropriate fields set as part of the +/// response message to the HCI. +/// +typedef union _MKHI_MESSAGE_HEADER { + UINT32 Data; + struct { + UINT32 GroupId : 8; + UINT32 Command : 7; + UINT32 IsResponse : 1; + UINT32 Reserved : 8; + UINT32 Result : 8; + } Fields; +} MKHI_MESSAGE_HEADER; + +/// +/// End of Post ACK message +/// +typedef struct _CBM_EOP_ACK_DATA { + UINT32 RequestedActions; +} CBM_EOP_ACK_DATA; + +typedef struct _GEN_END_OF_POST_ACK { + MKHI_MESSAGE_HEADER Header; + CBM_EOP_ACK_DATA Data; +} GEN_END_OF_POST_ACK; + +typedef union _MKHI_VERSION { + UINT32 Data; + struct { + UINT32 Minor : 16; + UINT32 Major : 16; + } Fields; +} MKHI_VERSION; + +/// +/// MKHI version messages +/// +typedef struct _GEN_GET_MKHI_VERSION { + MKHI_MESSAGE_HEADER MKHIHeader; +} GEN_GET_MKHI_VERSION; + +typedef struct _GET_MKHI_VERSION_ACK_DATA { + MKHI_VERSION MKHIVersion; +} GET_MKHI_VERSION_ACK_DATA; + +typedef struct _GEN_GET_MKHI_VERSION_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_MKHI_VERSION_ACK_DATA Data; +} GEN_GET_MKHI_VERSION_ACK; + +/// +/// FW version messages +/// +typedef struct _GEN_GET_FW_VER { + MKHI_MESSAGE_HEADER MKHIHeader; +} GEN_GET_FW_VER; + +typedef struct _GEN_GET_FW_VER_ACK_DATA { + UINT32 CodeMinor : 16; + UINT32 CodeMajor : 16; + UINT32 CodeBuildNo : 16; + UINT32 CodeHotFix : 16; + UINT32 RcvyMinor : 16; + UINT32 RcvyMajor : 16; + UINT32 RcvyBuildNo : 16; + UINT32 RcvyHotFix : 16; + UINT32 FitcMinor : 16; + UINT32 FitcMajor : 16; + UINT32 FitcBuildNo : 16; + UINT32 FitcHotFix : 16; +} GEN_GET_FW_VER_ACK_DATA; + +typedef struct _GEN_GET_FW_VER_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GEN_GET_FW_VER_ACK_DATA Data; +} GEN_GET_FW_VER_ACK; + +/// +/// Unconfig without password messages +/// +typedef struct _GEN_UNCFG_WO_PWD { + MKHI_MESSAGE_HEADER MKHIHeader; +} GEN_UNCFG_WO_PWD; + +typedef struct _GEN_UNCFG_WO_PWD_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; +} GEN_UNCFG_WO_PWD_ACK; + +/// +/// Get Firmware Capability MKHI +/// +typedef struct _GET_RULE_DATA { + UINT32 RuleId; +} GET_RULE_DATA; + +typedef struct _GEN_GET_FW_CAPSKU { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_GET_FW_CAPSKU; + +typedef union _RULE_ID { + UINT32 Data; + struct { + UINT32 RuleTypeId : 16; + UINT32 FeatureId : 8; + UINT32 Reserved : 8; + } Fields; +} RULE_ID; + +typedef struct _SET_RULE_DATA { + RULE_ID RuleId; + UINT8 RuleDataLen; + UINT8 RuleData; +} SET_RULE_DATA; + +typedef struct _SET_RULE_ACK_DATA { + UINT32 RuleId; +} SET_RULE_ACK_DATA; + +typedef struct _GEN_SET_FW_CAPSKU { + MKHI_MESSAGE_HEADER MKHIHeader; + SET_RULE_DATA Data; +} GEN_SET_FW_CAPSKU; + +typedef struct _GEN_SET_FW_CAPSKU_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + SET_RULE_ACK_DATA Data; +} GEN_SET_FW_CAPSKU_ACK; +typedef union _MEFWCAPS_SKU { + UINT32 Data; + struct { + UINT32 FullNet : 1; ///< [0] Full network manageability + UINT32 StdNet : 1; ///< [1] Standard network manageability + UINT32 Manageability : 1; ///< [2] Manageability + UINT32 SmallBusiness : 1; ///< [3] Small business technology + UINT32 Reserved2 : 1; ///< [4] Reserved + UINT32 IntelAT : 1; ///< [5] IntelR Anti-Theft (AT) + UINT32 IntelCLS : 1; ///< [6] IntelR Capability Licensing Service (CLS) + UINT32 Reserved : 3; ///< [9:7] Reserved + UINT32 IntelMPC : 1; ///< [10] IntelR Power Sharing Technology (MPC) + UINT32 IccOverClocking : 1; ///< [11] ICC Over Clocking + UINT32 PAVP : 1; ///< [12] Protected Audio Video Path (PAVP) + UINT32 Reserved1 : 4; ///< [16:13] Reserved + UINT32 IPV6 : 1; ///< [17] IPV6 + UINT32 KVM : 1; ///< [18] KVM Remote Control (KVM) + UINT32 OCH : 1; ///< [19] Outbreak Containment Heuristic (OCH) + UINT32 VLAN : 1; ///< [20] Virtual LAN (VLAN) + UINT32 TLS : 1; ///< [21] TLS + UINT32 Reserved4 : 1; ///< [22] Reserved + UINT32 WLAN : 1; ///< [23] Wireless LAN (WLAN) + UINT32 Reserved5 : 5; ///< [28:24] Reserved + UINT32 PTT : 1; ///< [29] Platform Trust Technoogy (PTT) + UINT32 Reserved6 : 1; ///< [30] Reserved + UINT32 NFC : 1; ///< [31] NFC + } Fields; +} MEFWCAPS_SKU; + +typedef struct _AT_STATE_FLAG { + UINT16 LockState : 1; ///< Indicate whether the platform is locked */ + UINT16 AuthenticateModule : 1; ///< Preferred Authentication Module */ + UINT16 S3Authentication : 1; ///< indicates whether S3 authentication is enabled */ + UINT16 FlashWearOut : 1; ///< indicates whether the AT flash partition is currently in violation of flash wear out rules */ + UINT16 FlashVariableSecurity : 1; ///< indicates whether the AT flash variables have been tampered with */ + UINT16 Reserved : 11; +} AT_STATE_FLAG; + +typedef struct _AT_STATE_INFO { + UINT8 State; + UINT8 LastTheftTrigger; + AT_STATE_FLAG flags; +} AT_STATE_INFO; + +typedef struct { + UINT8 AtState; ///< State of AT + UINT8 AtLastTheftTrigger; ///< Reason for the last trigger + AT_STATE_FLAG AtStateFlags; ///< State of AT Fw +} AT_STATE_STRUCT; + +typedef struct _GEN_GET_FW_CAPS_SKU_ACK_DATA { + UINT32 RuleID; + UINT8 RuleDataLen; + MEFWCAPS_SKU FWCapSku; +} GEN_GET_FW_CAPS_SKU_ACK_DATA; + +typedef struct _GEN_GET_FW_CAPSKU_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GEN_GET_FW_CAPS_SKU_ACK_DATA Data; +} GEN_GET_FW_CAPS_SKU_ACK; + +typedef union _GEN_GET_FW_CAPS_SKU_BUFFER { + GEN_GET_FW_CAPSKU Request; + GEN_GET_FW_CAPS_SKU_ACK Response; +} GEN_GET_FW_CAPS_SKU_BUFFER; + +typedef enum { + UPDATE_DISABLED = 0, + UPDATE_ENABLED +} LOCAL_FW_UPDATE; + +typedef enum { + LOCAL_FW_ALWAYS = 0, + LOCAL_FW_NEVER, + LOCAL_FW_RESTRICTED, +} LOCAL_FW_QUALIFIER; + +typedef struct _GEN_LOCAL_FW_UPDATE_DATA { + UINT32 RuleId; + UINT8 RuleDataLen; + UINT8 RuleData; + UINT8 Reserved[30]; +} GEN_LOCAL_FW_UPDATE_DATA; + +typedef struct _GEN_GET_LOCAL_FW_UPDATE { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_GET_LOCAL_FW_UPDATE; + +typedef struct _GEN_GET_LOCAL_FW_UPDATE_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GEN_LOCAL_FW_UPDATE_DATA Data; +} GEN_GET_LOCAL_FW_UPDATE_ACK; + +typedef struct _GEN_SET_LOCAL_FW_UPDATE { + MKHI_MESSAGE_HEADER MKHIHeader; + GEN_LOCAL_FW_UPDATE_DATA Data; +} GEN_SET_LOCAL_FW_UPDATE; + +typedef struct _GEN_SET_LOCAL_FW_UPDATE_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_SET_LOCAL_FW_UPDATE_ACK; + +typedef enum { + NO_BRAND = 0, + INTEL_AMT_BRAND, + INTEL_STAND_MANAGEABILITY_BRAND, + INTEL_LEVEL_III_MANAGEABILITY_UPGRADE_BRAND, + INTEL_RESERVED_BRAND, + INTEL_SMALL_BUSINESS_TECHNOLOGY_BRAND, +} PLATFORM_BRAND; + +typedef enum { + INTEL_ME_1_5MB_FW = 3, + INTEL_ME_5MB_FW, +} ME_IMAGE_TYPE; + +#define REGULAR_SKU 0 +#define SUPER_SKU 1 + +#define PLATFORM_MARKET_CORPORATE 1 +#define PLATFORM_MARKET_CONSUMER 2 + +#define PLATFORM_MOBILE 1 +#define PLATFORM_DESKTOP 2 +#define PLATFORM_SERVER 4 +#define PLATFORM_WORKSTATION 8 + +typedef union _PLATFORM_TYPE_RULE_DATA { + UINT32 Data; + struct { + UINT32 PlatformTargetUsageType : 4; + UINT32 PlatformTargetMarketType : 2; + UINT32 SuperSku : 1; + UINT32 Reserved : 1; + UINT32 IntelMeFwImageType : 4; + UINT32 PlatformBrand : 4; + UINT32 Reserved1 : 16; + } Fields; +} PLATFORM_TYPE_RULE_DATA; + +typedef struct _GEN_PLATFORM_TYPE_DATA { + UINT32 RuleId; + UINT8 RuleDataLen; + PLATFORM_TYPE_RULE_DATA RuleData; + UINT8 Reserved[27]; +} GEN_PLATFORM_TYPE_DATA; + +typedef struct _GEN_GET_PLATFORM_TYPE { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_GET_PLATFORM_TYPE; + +typedef struct _GEN_GET_PLATFORM_TYPE_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + GEN_PLATFORM_TYPE_DATA Data; +} GEN_GET_PLATFORM_TYPE_ACK; + +typedef union _GEN_GET_PLATFORM_TYPE_BUFFER { + GEN_GET_PLATFORM_TYPE Request; + GEN_GET_PLATFORM_TYPE_ACK Response; +} GEN_GET_PLATFORM_TYPE_BUFFER; + +typedef struct _GET_AT_ME_RULE_CMD { + MKHI_MESSAGE_HEADER MKHIHeader; + UINT32 RuleId; + +} GET_AT_ME_RULE_CMD; + +typedef struct _GET_AT_ME_RULE_RSP { + MKHI_MESSAGE_HEADER MKHIHeader; + UINT32 RuleId; + UINT8 RuleDataLength; + AT_STATE_INFO AtRuleData; + +} GET_AT_ME_RULE_RSP; + +typedef struct _GET_FW_FEATURE_STATUS { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_GET_FW_FEATURE_STATUS; + +typedef struct _GET_FW_FEATURE_STATUS_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + UINT32 RuleId; + UINT8 RuleDataLength; + MEFWCAPS_SKU RuleData; +} GEN_GET_FW_FEATURE_STATUS_ACK; + +typedef struct _GEN_AMT_BIOS_SYNCH_INFO { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_AMT_BIOS_SYNCH_INFO; + +typedef struct _GEN_AMT_BIOS_SYNCH_INFO_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + UINT32 RuleId; + UINT8 RuleDataLength; + UINT32 RuleData; +} GEN_AMT_BIOS_SYNCH_INFO_ACK; + +typedef struct _GEN_GET_OEM_TAG_MSG { + MKHI_MESSAGE_HEADER MKHIHeader; + GET_RULE_DATA Data; +} GEN_GET_OEM_TAG_MSG; + +typedef struct _GEN_GET_OEM_TAG_MSG_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + UINT32 RuleId; + UINT8 RuleDataLength; + UINT32 RuleData; +} GEN_GET_OEM_TAG_MSG_ACK; + +typedef union _PLATFORM_DEBUG_CAP { + UINT8 Data; + struct { + UINT8 Mdes : 1; + UINT8 SvtForPch : 1; + UINT8 Reserved : 6; + } Fields; +} PLATFORM_DEBUG_CAP; + +typedef struct _GEN_PLATFORM_DEBUG_CAP_MKHI_CMD_MSG { + MKHI_MESSAGE_HEADER MKHIHeader; + PLATFORM_DEBUG_CAP Capability; +} GEN_PLATFORM_DEBUG_CAP_MKHI_CMD_MSG; + +/// +/// Manageability State Control MKHI definitions +/// +typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_DATA { + UINT32 EnableFeature; + UINT32 DisableFeature; +} FIRMWARE_CAPABILITY_OVERRIDE_DATA; + +typedef struct _FIRMWARE_CAPABILITY_OVERRIDE { + MKHI_MESSAGE_HEADER MKHIHeader; + FIRMWARE_CAPABILITY_OVERRIDE_DATA FeatureState; +} FIRMWARE_CAPABILITY_OVERRIDE; + +typedef enum _FIRMWARE_CAPABILITY_RESPONSE +{ + SET_FEATURE_STATE_ACCEPTED = 0, + SET_FEATURE_STATE_REJECTED +} FIRMWARE_CAPABILITY_RESPONSE; + +typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA { + FIRMWARE_CAPABILITY_RESPONSE Response; +} FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA; + +typedef struct _FIRMWARE_CAPABILITY_OVERRIDE_ACK { + MKHI_MESSAGE_HEADER Header; + FIRMWARE_CAPABILITY_OVERRIDE_ACK_DATA Data; +} FIRMWARE_CAPABILITY_OVERRIDE_ACK; + +/// +/// Set ACM TPM Data MKHI +/// +#define ACM_TPM_DATA_MKHI_DATA 0x00000303 +#define ACM_TPM_DATA_RULE_TYPE_ID 0x2F +#define ACM_TPM_DATA_RULE_DATA_LENGTH 0x04 + +typedef union _TPM_STATE { + UINT16 Data; + struct { + UINT16 Reserved_0: 8; + UINT16 TpmDeactivate: 1; + UINT16 Reserved_1: 7; + } Fields; +} TPM_STATE; + +typedef struct _ACM_TPM_DATA { + RULE_ID RuleId; + UINT8 RuleDataLen; + TPM_STATE TpmState; + UINT8 Reserved[2]; +} ACM_TPM_DATA; + +typedef struct _BIOSNV_SET_ACM_TPM_DATA { + MKHI_MESSAGE_HEADER MKHIHeader; + ACM_TPM_DATA AcmTpmData; +} BIOSNV_SET_ACM_TPM; + +typedef struct _BIOSNV_SET_ACM_TPM_DATA_ACK { + MKHI_MESSAGE_HEADER MKHIHeader; + RULE_ID RuleId; +} BIOSNV_SET_ACM_TPM_ACK; + +#pragma pack() + +#endif // _MKHI_MSGS_H |