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 | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/ME/Library')
90 files changed, 13947 insertions, 0 deletions
diff --git a/ReferenceCode/ME/Library/AMT/AmtLibrary.cif b/ReferenceCode/ME/Library/AMT/AmtLibrary.cif new file mode 100644 index 0000000..c5be1a2 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/AmtLibrary.cif @@ -0,0 +1,11 @@ +<component> + name = "AmtLibrary" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\AMT\" + RefName = "AmtLibrary" +[files] +"AmtLibrary.sdl" +[parts] +"AmtLibDxe" +"AmtLibPei" +<endComponent> diff --git a/ReferenceCode/ME/Library/AMT/AmtLibrary.sdl b/ReferenceCode/ME/Library/AMT/AmtLibrary.sdl new file mode 100644 index 0000000..0e43375 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/AmtLibrary.sdl @@ -0,0 +1,20 @@ +TOKEN + Name = "AmtLibrary_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AmtLibDxe support in Project" +End + +PATH + Name = "AmtLibrary_DIR" + Help = "iAMT Library file source directory" +End + +ELINK + Name = "/I$(AmtLibrary_DIR)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.c b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.c new file mode 100644 index 0000000..6b69b16 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.c @@ -0,0 +1,526 @@ +/** @file + Implementation file for AMT 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 "AmtLib.h" +#include "MeLib.h" + +#include EFI_PROTOCOL_CONSUMER (Heci) +#include EFI_PROTOCOL_CONSUMER (ActiveManagement) +#include EFI_PROTOCOL_CONSUMER (AmtPlatformPolicy) +#include EFI_GUID_DEFINITION (MeBiosExtensionSetup) +#endif + +EFI_ACTIVE_MANAGEMENT_PROTOCOL *mActiveManagement = NULL; +// +// AMT GUID and Variable Name +// +EFI_GUID mEfiMeBiosExtensionSetupGuid = EFI_ME_BIOS_EXTENSION_SETUP_GUID; +CHAR16 mEfiMeBiosExtensionSetupName[] = EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME; + +/** + Check if Asf is enabled in setup options. + + @param[in] None. + @retval EFI_SUCCESS mActiveManagement is not NULL + @retval Error Status code returned by + LocateProtocol. +**/ +EFI_STATUS +AmtLibInit ( + VOID + ) +{ + EFI_STATUS Status; + + if (mActiveManagement == NULL) { + Status = gBS->LocateProtocol ( + &gEfiActiveManagementProtocolGuid, + NULL, + (VOID **) &mActiveManagement + ); + } else { + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + This will return IDE Redirection Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True IDE-R is enabled. + @retval False IDE-R is disabled. +**/ +BOOLEAN +ActiveManagementEnableIdeR ( + VOID + ) +{ + BOOLEAN CurrentState; + UINTN VariableSize; + EFI_STATUS Status; + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetupData; + + CurrentState = FALSE; + VariableSize = 0; + + if (mActiveManagement != NULL) { + mActiveManagement->GetIderState (mActiveManagement, &CurrentState); + } + + VariableSize = sizeof (MeBiosExtensionSetupData); + Status = gRT->GetVariable ( + mEfiMeBiosExtensionSetupName, + &mEfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBiosExtensionSetupData + ); + if (!EFI_ERROR (Status)) { + if ((MeBiosExtensionSetupData.AmtSolIder & IDER_ENABLE) == 0) { + CurrentState = FALSE; + } + } + + return CurrentState; +} + +/** + This will return Enforce Secure Boot over IDER Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Enforce Secure Boot is enabled. + @retval False Enforce Secure Boot is disabled. +**/ +BOOLEAN +ActiveManagementEnforceSecureBoot ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetEnforceSecureBootState (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + This will return BIOS Pause Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True BIOS Pause is enabled. + @retval False BIOS Pause is disabled. +**/ +BOOLEAN +ActiveManagementPauseBoot ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetBiosPauseState (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + This will return BIOS Setup Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True BIOS Setup is enabled. + @retval False BIOS Setup is disabled. +**/ +BOOLEAN +ActiveManagementEnterSetup ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetBiosSetupState (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Console Lock is enabled. + @retval False Console Lock is disabled. +**/ +BOOLEAN +ActiveManagementConsoleLocked ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetConsoleLockState (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + This will return KVM Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True KVM is enabled. + @retval False KVM is disabled. +**/ +BOOLEAN +ActiveManagementEnableKvm ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetKvmState (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Serial-over-Lan is enabled. + @retval False Serial-over-Lan is disabled. +**/ +BOOLEAN +ActiveManagementEnableSol ( + VOID + ) +{ + BOOLEAN CurrentState; + UINTN VariableSize; + EFI_STATUS Status; + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetupData; + + CurrentState = FALSE; + VariableSize = 0; + + if (mActiveManagement != NULL) { + mActiveManagement->GetSolState (mActiveManagement, &CurrentState); + } + + VariableSize = sizeof (MeBiosExtensionSetupData); + Status = gRT->GetVariable ( + mEfiMeBiosExtensionSetupName, + &mEfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBiosExtensionSetupData + ); + if (!EFI_ERROR (Status)) { + if ((MeBiosExtensionSetupData.AmtSolIder & SOL_ENABLE) == 0) { + CurrentState = FALSE; + } + } + + return CurrentState; +} + +/** + This will return IDE Redirection boot device index to boot + + @param[in] None. + + @retval IdeBootDevice Return the boot device number to boot + Bits 0-1: If IDER boot is selected in Perimeter 1 then Bits 1,2 define the drive on the IDER controller to be used as the boot driver. + Bit 1 Bit0 + 0 0 Primary Master Drive + 0 1 Primary Slave Drive + 1 0 Secondary Master Drive + 1 1 Secondary Slave Drive + Bits 2-7: Reserved set to 0 +**/ +UINT8 +ActiveManagementIderBootDeviceGet ( + VOID + ) +{ + UINT8 IderBootDevice; + IderBootDevice = 0; + + if (mActiveManagement != NULL) { + mActiveManagement->GetIderBootDeviceSelectd (mActiveManagement, &IderBootDevice); + } + + return IderBootDevice; +} + +/** + Stop ASF Watch Dog Timer + + @param[in] None. + + @retval None +**/ +VOID +AsfStopWatchDog ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 HeciLength; + ASF_STOP_WDT AsfStopWdt; + UINT32 MeStatus; + UINT32 MeMode; + EFI_HECI_PROTOCOL *Heci; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (!EFI_ERROR (Status)) { + Status = Heci->GetMeMode (&MeMode); + if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) { + DEBUG ((EFI_D_ERROR, "MeMode is %x, Unable to Stop ME BIOS Watch Dog Timer", MeMode)); + + return ; + } + /// + /// Check ME Status + /// + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + /// + /// Send EOP/WDT message when ME is ready. Do not care about if ME FW INIT is completed. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) { + /// + /// Check if watch dog is enabled in BIOS Setup + /// + if (AmtWatchDog ()) { + ZeroMem ((VOID *) &AsfStopWdt, sizeof (ASF_STOP_WDT)); + AsfStopWdt.Command = EFI_ASF_MESSAGE_COMMAND_MANAGEMENT_CONTROL; + AsfStopWdt.ByteCount = EFI_ASF_STOP_WDT_BYTE_COUNT; + AsfStopWdt.SubCommand = ASF_SUB_COMMAND_STOP_WDT; + AsfStopWdt.VersionNumber = EFI_ASF_STOP_WDT_VERSION; + + HeciLength = ASF_STOP_WDT_LENGTH; + Status = Heci->SendMsg ( + (UINT32 *) &AsfStopWdt, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to Stop ME BIOS Watch Dog Timer")); + } + } + } + } + + return ; +} + +/** + Start ASF Watch Dog Timer + + @param[in] WatchDogType Which kind of WatchDog, ASF OS WatchDog Timer setting or ASF BIOS WatchDog Timer setting + + @retval None +**/ +VOID +AsfStartWatchDog ( + IN UINT8 WatchDogType + ) +{ + EFI_STATUS Status; + UINT32 HeciLength; + ASF_START_WDT AsfStartWdt; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeStatus; + UINT32 MeMode; + UINT16 WaitTimer; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (!EFI_ERROR (Status)) { + Status = Heci->GetMeMode (&MeMode); + if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) { + DEBUG ((EFI_D_ERROR, "MeMode is %x, Unable to Start ME Watch Dog Timer", MeMode)); + + return ; + } + /// + /// Check ME Status + /// + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + /// + /// Send EOP/WDT message when ME is ready. Do not care about if ME FW INIT is completed. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) { + /// + /// Check if watch dog is enabled in BIOS Setup + /// + if (AmtWatchDog ()) { + ZeroMem ((VOID *) &AsfStartWdt, sizeof (ASF_START_WDT)); + AsfStartWdt.Command = EFI_ASF_MESSAGE_COMMAND_MANAGEMENT_CONTROL; + AsfStartWdt.ByteCount = EFI_ASF_START_WDT_BYTE_COUNT; + AsfStartWdt.SubCommand = ASF_SUB_COMMAND_START_WDT; + AsfStartWdt.VersionNumber = EFI_ASF_START_WDT_VERSION_NUMBER; + AsfStartWdt.EventSensorType = EFI_ASF_START_WDT_EVENT_SENSOR_TYPE; + AsfStartWdt.EventType = EFI_ASF_START_WDT_EVENT_TYPE; + AsfStartWdt.EventOffset = EFI_ASF_START_WDT_EVENT_OFFSET; + AsfStartWdt.EventSeverity = EFI_ASF_START_WDT_EVENT_SEVERITY; + AsfStartWdt.SensorDevice = EFI_ASF_START_WDT_SENSOR_DEVICE; + AsfStartWdt.SensorNumber = EFI_ASF_START_WDT_SENSOR_NUMBER; + AsfStartWdt.Entity = EFI_ASF_START_WDT_ENTITY; + AsfStartWdt.EntityInstance = EFI_ASF_START_WDT_ENTITY_INSTANCE; + AsfStartWdt.EventData[0] = EFI_ASF_START_WDT_EVENT_DATA_BYTE_0; + if (WatchDogType == ASF_START_BIOS_WDT) { + AsfStartWdt.EventSourceType = EFI_ASF_START_WDT_EVENT_SOURCE_TYPE_BIOS; + AsfStartWdt.EventData[1] = EFI_ASF_START_WDT_EVENT_DATA_BYTE_1_BIOS_TIMEOUT; + WaitTimer = AmtWatchDogTimerBiosGet (); + } else { + AsfStartWdt.EventSourceType = EFI_ASF_START_WDT_EVENT_SOURCE_TYPE_OS; + AsfStartWdt.EventData[1] = EFI_ASF_START_WDT_EVENT_DATA_BYTE_1_OS_TIMEOUT; + WaitTimer = AmtWatchDogTimerOsGet (); + } + + AsfStartWdt.TimeoutLow = (UINT8) WaitTimer; + AsfStartWdt.TimeoutHigh = (UINT8) (WaitTimer >> 8); + + HeciLength = ASF_START_WDT_LENGTH; + + Status = Heci->SendMsg ( + (UINT32 *) &AsfStartWdt, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to Start ME Watch Dog Timer")); + } + } + } + } + + return ; +} + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] None. + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +ActiveManagementFwProgress ( + VOID + ) +{ + BOOLEAN CurrentState; + + CurrentState = FALSE; + + if (mActiveManagement != NULL) { + mActiveManagement->GetProgressMsgRequest (mActiveManagement, &CurrentState); + } + + return CurrentState; +} + +/** + Sent initialize KVM message + + @param[in] None. + + @retval True KVM Initialization is successful + @retval False KVM is not enabled +**/ +BOOLEAN +BdsKvmInitialization ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 ResponseCode; + + MeReportError (MSG_KVM_WAIT); + Status = HeciQueryKvmRequest (QUERY_REQUEST, &ResponseCode); + if (EFI_ERROR (Status)) { + MeReportError (MSG_KVM_TIMES_UP); + Status = HeciQueryKvmRequest (CANCEL_REQUEST, &ResponseCode); + } else if (ResponseCode == KVM_SESSION_CANCELLED) { + MeReportError (MSG_KVM_REJECTED); + } else { + return TRUE; + } + + return FALSE; +} diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.h b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.h new file mode 100644 index 0000000..b89ae0a --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.h @@ -0,0 +1,257 @@ +/** @file + Header file for AMT 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 _AMT_LIB_H_ +#define _AMT_LIB_H_ + +#include "AmtPolicyLib.h" + +// +// ASF Message +// +#define EFI_ASF_START_WDT_VERSION 0x10 +#define EFI_ASF_STOP_WDT_VERSION 0x10 + +#define EFI_ASF_MESSAGE_COMMAND_SENSE_DEVICE_SYSTEM_STATE 0x01 +#define EFI_ASF_MESSAGE_COMMAND_MANAGEMENT_CONTROL 0x02 +#define EFI_ASF_MESSAGE_COMMAND_ASF_CONFIGURATION 0x03 +#define EFI_ASF_MESSAGE_COMMAND_MESSAGE 0x04 +#define EFI_ASF_MESSAGE_COMMAND_GETUUID 0xC7 + +// +// HECI ASF Command +// +#define EFI_ASF_START_WDT_BYTE_COUNT 0x0F +#define EFI_ASF_START_WDT_VERSION_NUMBER 0x10 +#define EFI_ASF_START_WDT_EVENT_SENSOR_TYPE 0x23 +#define EFI_ASF_START_WDT_EVENT_TYPE 0x6F +#define EFI_ASF_START_WDT_EVENT_OFFSET 0x00 +#define EFI_ASF_START_WDT_EVENT_SOURCE_TYPE_OS 0x48 +#define EFI_ASF_START_WDT_EVENT_SOURCE_TYPE_BIOS 0x00 +#define EFI_ASF_START_WDT_EVENT_SOURCE_TYPE 0x00 ///< 0x00 - BIOs, 0x48 - OS +#define EFI_ASF_START_WDT_EVENT_SEVERITY 0x10 ///< critical +#define EFI_ASF_START_WDT_SENSOR_DEVICE 0xFF ///< unspecified +#define EFI_ASF_START_WDT_SENSOR_NUMBER 0xFF ///< unspecified +#define EFI_ASF_START_WDT_ENTITY 0x00 ///< unspecified +#define EFI_ASF_START_WDT_ENTITY_INSTANCE 0x00 ///< unspecified +#define EFI_ASF_START_WDT_EVENT_DATA_BYTE_0 0x40 +#define EFI_ASF_START_WDT_EVENT_DATA_BYTE_1 0x02 ///< 0x02 BIOS POST WDT Timeout, 0x04 OS WDT timeout +#define EFI_ASF_START_WDT_EVENT_DATA_BYTE_1_BIOS_TIMEOUT 0x02 +#define EFI_ASF_START_WDT_EVENT_DATA_BYTE_1_OS_TIMEOUT 0x04 + +#define EFI_ASF_STOP_WDT_BYTE_COUNT 0x02 + +#define ASF_START_BIOS_WDT 0 +#define ASF_START_OS_WDT 1 + +/** + Check if Asf is enabled in setup options. + + @param[in] None. + @retval EFI_SUCCESS mActiveManagement is not NULL + @retval Error Status code returned by + LocateProtocol. +**/ +EFI_STATUS +AmtLibInit ( + VOID + ) +; + +/** + This will return IDE Redirection Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True IDE-R is enabled. + @retval False IDE-R is disabled. +**/ +BOOLEAN +ActiveManagementEnableIdeR ( + VOID + ) +; + +/** + This will return Enforce Secure Boot over IDER Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Enforce Secure Boot is enabled. + @retval False Enforce Secure Boot is disabled. +**/ +BOOLEAN +ActiveManagementEnforceSecureBoot ( + VOID + ) +; + +/** + This will return BIOS Pause Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True BIOS Pause is enabled. + @retval False BIOS Pause is disabled. +**/ +BOOLEAN +ActiveManagementPauseBoot ( + VOID + ) +; + +/** + This will return BIOS Setup Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True BIOS Setup is enabled. + @retval False BIOS Setup is disabled. +**/ +BOOLEAN +ActiveManagementEnterSetup ( + VOID + ) +; + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Console Lock is enabled. + @retval False Console Lock is disabled. +**/ +BOOLEAN +ActiveManagementConsoleLocked ( + VOID + ) +; + +/** + This will return KVM Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True KVM is enabled. + @retval False KVM is disabled. +**/ +BOOLEAN +ActiveManagementEnableKvm ( + VOID + ) +; + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] None. + + @retval True Serial-over-Lan is enabled. + @retval False Serial-over-Lan is disabled. +**/ +BOOLEAN +ActiveManagementEnableSol ( + VOID + ) +; + +/** + This will return IDE Redirection boot device index to boot + + @param[in] None. + + @retval IdeBootDevice Return the boot device number to boot + Bits 0-1: If IDER boot is selected in Perimeter 1 then Bits 1,2 define the drive on the IDER controller to be used as the boot driver. + Bit 1 Bit0 + 0 0 Primary Master Drive + 0 1 Primary Slave Drive + 1 0 Secondary Master Drive + 1 1 Secondary Slave Drive + Bits 2-7: Reserved set to 0 +**/ +UINT8 +ActiveManagementIderBootDeviceGet ( + VOID + ) +; + +/** + Stop ASF Watch Dog Timer + + @param[in] None. + + @retval None +**/ +VOID +AsfStopWatchDog ( + VOID + ) +; + +/** + Start ASF Watch Dog Timer + + @param[in] WatchDogType Which kind of WatchDog, ASF OS WatchDog Timer setting or ASF BIOS WatchDog Timer setting + + @retval None +**/ +VOID +AsfStartWatchDog ( + IN UINT8 WatchDogType + ) +; + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] None. + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +ActiveManagementFwProgress ( + VOID + ) +; + +/** + Sent initialize KVM message + + @param[in] None. + + @retval True KVM Initialization is successful + @retval False KVM is not enabled +**/ +BOOLEAN +BdsKvmInitialization ( + VOID + ) +; +#endif diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.inf b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.inf new file mode 100644 index 0000000..4089248 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLib.inf @@ -0,0 +1,75 @@ +## @file +# Component description file for AMT 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 = AmtLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + AmtLib.c + AmtLib.h + AmtPolicyLib.c + AmtPolicyLib.h + AmtPolicyDebugDumpDxe.c + MebxSetupDebugDumpDxe.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode + +# +# 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] + MeLib + MeProtocolLib + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueDxeReportStatusCodeLib + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.cif b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.cif new file mode 100644 index 0000000..9aae0a8 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.cif @@ -0,0 +1,16 @@ +<component> + name = "AmtLibDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\AMT\Dxe\" + RefName = "AmtLibDxe" +[files] +"AmtLib.c" +"AmtLib.h" +"AmtLib.inf" +"AmtLibDxe.mak" +"AmtLibDxe.sdl" +"AmtPolicyLib.c" +"AmtPolicyLib.h" +"AmtPolicyDebugDumpDxe.c" +"MebxSetupDebugDumpDxe.c" +<endComponent> diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.mak b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.mak new file mode 100644 index 0000000..1d0a64b --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.mak @@ -0,0 +1,54 @@ +# /*++ +# 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:AmtLibDxe +all : AmtLibDxe + +$(BUILD_DIR)\AmtLibDxe.lib : AmtLibDxe + +AmtLibDxe : $(BUILD_DIR)\AmtLibDxe.mak AmtLibDxeBin + +$(BUILD_DIR)\AmtLibDxe.mak : $(AmtLibDxe_DIR)\$(@B).cif $(AmtLibDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AmtLibDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +AmtLibDxe_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + +AmtLibDxe_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__\ + +AmtLibDxe_LIBS=\ + $(MeProtocolLib_LIB)\ + $(MeLibDxe_LIB) + +AmtLibDxeBin : $(AmtLibDxe_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + /f $(BUILD_DIR)\AmtLibDxe.mak all \ + "MY_INCLUDES=$(AmtLibDxe_INCLUDES)" \ + "MY_DEFINES=$(AmtLibDxe_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/AMT/Dxe/AmtLibDxe.sdl b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.sdl new file mode 100644 index 0000000..054446f --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtLibDxe.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "AmtLibDxe_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AmtLibDxe support in Project" +End + +MODULE + Help = "Includes AmtLibDxe.mak to Project" + File = "AmtLibDxe.mak" +End + +PATH + Name = "AmtLibDxe_DIR" + Help = "iAMT Library file source directory" +End + +ELINK + Name = "AmtLibDxe_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\AmtLibDxe.lib" + Parent = "AmtLibDxe_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(AmtLibDxe_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyDebugDumpDxe.c b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyDebugDumpDxe.c new file mode 100644 index 0000000..608f886 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyDebugDumpDxe.c @@ -0,0 +1,115 @@ +/** @file + Dump whole DXE_AMT_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 +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AmtPolicyLib.h" +#endif + +extern DXE_AMT_POLICY_PROTOCOL *mDxePlatformAmtPolicy; + +/** + Dump DXE Amt Platform Policy + + @param[in] None. + + @retval None +**/ +VOID +DxeAmtPolicyDebugDump ( + VOID + ) +{ + EFI_STATUS Status; + + Status = AmtPolicyLibInit (); + if (EFI_ERROR(Status)) { + return; + } + + DEBUG ((EFI_D_INFO, "\n------------------------ AmtPlatformPolicy Dump Begin -----------------\n")); + DEBUG ((EFI_D_INFO, " Revision : 0x%x\n", mDxePlatformAmtPolicy->Revision)); + DEBUG ((EFI_D_INFO, "AmtConfig ---\n")); + // + // Byte 0, bit definition for functionality enable/disable + // + DEBUG ((EFI_D_INFO, " AsfEnabled : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.AsfEnabled)); + DEBUG ((EFI_D_INFO, " iAmtEnabled : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.iAmtEnabled)); + DEBUG ((EFI_D_INFO, " iAmtbxPasswordWrite : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.iAmtbxPasswordWrite)); + DEBUG ((EFI_D_INFO, " WatchDog : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.WatchDog)); + DEBUG ((EFI_D_INFO, " CiraRequest : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.CiraRequest)); + DEBUG ((EFI_D_INFO, " ManageabilityMode : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.ManageabilityMode)); + DEBUG ((EFI_D_INFO, " UnConfigureMe : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.UnConfigureMe)); + DEBUG ((EFI_D_INFO, " MebxDebugMsg : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.MebxDebugMsg)); + + // + // Byte 1, bit definition for functionality enable/disable + // + DEBUG ((EFI_D_INFO, " ForcMebxSyncUp : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.ForcMebxSyncUp)); + DEBUG ((EFI_D_INFO, " UsbrEnabled : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.UsbrEnabled)); + DEBUG ((EFI_D_INFO, " UsbLockingEnabled : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.UsbLockingEnabled)); + DEBUG ((EFI_D_INFO, " HideUnConfigureMeConfirm : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.HideUnConfigureMeConfirm)); + DEBUG ((EFI_D_INFO, " USBProvision : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.USBProvision)); + DEBUG ((EFI_D_INFO, " FWProgress : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.FWProgress)); + DEBUG ((EFI_D_INFO, " iAmtbxHotKeyPressed : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.iAmtbxHotkeyPressed)); + DEBUG ((EFI_D_INFO, " iAmtbxSelectionScreen : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.iAmtbxSelectionScreen)); + + // + // Byte 2, bit definition for functionality enable/disable + // + DEBUG ((EFI_D_INFO, " AtEnabled : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.AtEnabled)); + + // + // Byte 3-4 OS WatchDog Timer + // + DEBUG ((EFI_D_INFO, " WatchDogTimerOs : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.WatchDogTimerOs)); + + // + // Byte 5-6 BIOS WatchDog Timer + // + DEBUG ((EFI_D_INFO, " WatchDogTimerBios : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.WatchDogTimerBios)); + + // + // Byte 7 CIRA Timeout, Client Initiated Remote Access Timeout + // OEM defined timeout for MPS connection to be established. + // + DEBUG ((EFI_D_INFO, " CiraTimeout : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.CiraTimeout)); + + // + // Byte 8 CPU Replacement Timeout + // + DEBUG ((EFI_D_INFO, " CPU Replacement Timeout : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.CpuReplacementTimeout)); + + // + // Byte 9-10 OemResolutionSettings + // + DEBUG ((EFI_D_INFO, " MebxNonUiTextMode : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.MebxNonUiTextMode)); + DEBUG ((EFI_D_INFO, " MebxUiTextMode : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.MebxUiTextMode)); + DEBUG ((EFI_D_INFO, " MebxGraphicsMode : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.MebxGraphicsMode)); + + // + // Byte 11-14 Pointer to a list which contain on-board devices bus/device/fun number + // + DEBUG ((EFI_D_INFO, " PciDeviceFilterOutTable Pointer : 0x%x\n", mDxePlatformAmtPolicy->AmtConfig.PciDeviceFilterOutTable)); + + DEBUG ((EFI_D_INFO, "\n------------------------ AmtPlatformPolicy Dump End -------------------\n")); +} + diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.c b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.c new file mode 100644 index 0000000..4448504 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.c @@ -0,0 +1,547 @@ +/** @file + Implementation file for AMT 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 "AmtPolicyLib.h" +#include "MeLib.h" + +#include EFI_PROTOCOL_CONSUMER (ActiveManagement) +#include EFI_PROTOCOL_CONSUMER (AmtPlatformPolicy) +#endif +// +// Global variables +// +DXE_AMT_POLICY_PROTOCOL *mDxePlatformAmtPolicy = NULL; + +/** + Check if AMT is enabled in setup options. + + @param[in] None. + + @retval EFI_SUCCESS AMT platform policy pointer is initialized. + @retval All other error conditions encountered when no AMT platform policy available. +**/ +EFI_STATUS +AmtPolicyLibInit ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy != NULL) { + return EFI_SUCCESS; + } + // + // Get the desired platform setup policy. + // + Status = gBS->LocateProtocol (&gDxePlatformAmtPolicyGuid, NULL, (VOID **) &mDxePlatformAmtPolicy); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "No AMT Platform Policy Protocol available")); + ASSERT_EFI_ERROR(Status); + } else if (mDxePlatformAmtPolicy == NULL) { + DEBUG ((EFI_D_ERROR, "No AMT Platform Policy Protocol available")); + Status = EFI_UNSUPPORTED; + } + + return Status; +} + +/** + Check if Asf is enabled in setup options. + + @param[in] None. + + @retval FALSE Asf is disabled. + @retval TRUE Asf is enabled. +**/ +BOOLEAN +AsfSupported ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + // + // First check if ASF support is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.AsfEnabled != 1) { + return FALSE; + } + + return TRUE; +} + +/** + Check if Amt is enabled in setup options. + + @param[in] None. + + @retval FALSE Amt is disabled. + @retval TRUE Amt is enabled. +**/ +BOOLEAN +AmtSupported ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + // + // First check if AMT support is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.iAmtEnabled != 1) { + return FALSE; + } + + return TRUE; +} + +/** + Check if AMT BIOS Extension hotkey was pressed during BIOS boot. + + @param[in] None. + + @retval FALSE MEBx hotkey was not pressed. + @retval TRUE MEBx hotkey was pressed. +**/ +BOOLEAN +AmtHotkeyPressed ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + // + // First check if AMT Setup Prompt is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.iAmtbxHotkeyPressed == 1) { + Supported = TRUE; + } else { + Supported = FALSE; + } + + return Supported; +} + +/** + Check if AMT BIOS Extension Selection Screen is enabled in setup options. + + @param[in] None. + + @retval FALSE AMT Selection Screen is disabled. + @retval TRUE AMT Selection Screen is enabled. +**/ +BOOLEAN +AmtSelectionScreen ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + // + // First check if AMT Selection Screen is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.iAmtbxSelectionScreen == 1) { + Supported = TRUE; + } else { + Supported = FALSE; + } + + return Supported; +} + +/** + Check if AMT WatchDog is enabled in setup options. + + @param[in] None. + + @retval FALSE AMT WatchDog is disabled. + @retval TRUE AMT WatchDog is enabled. +**/ +BOOLEAN +AmtWatchDog ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + Supported = FALSE; + if (ManageabilityModeSetting () != 0) { + // + // First check if AMT WatchDog is enabled in Setup. + // + if (AsfSupported ()) { + if (mDxePlatformAmtPolicy->AmtConfig.WatchDog == 1) { + Supported = TRUE; + } + } + } + + return Supported; +} + +/** + Return BIOS watchdog timer + + @param[in] None. + + @retval UINT16 BIOS ASF Watchdog Timer +**/ +UINT16 +AmtWatchDogTimerBiosGet ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return 0; + } + } + return mDxePlatformAmtPolicy->AmtConfig.WatchDogTimerBios; +} + +/** + Return OS watchdog timer + + @param[in] None. + + @retval UINT16 OS ASF Watchdog Timer +**/ +UINT16 +AmtWatchDogTimerOsGet ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return 0; + } + } + return mDxePlatformAmtPolicy->AmtConfig.WatchDogTimerOs; +} + +/** + Provide CIRA request information from OEM code. + + @param[in] None. + + @retval Check if any CIRA requirement during POST +**/ +BOOLEAN +AmtCiraRequestTrigger ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + return mDxePlatformAmtPolicy->AmtConfig.CiraRequest == 1; +} + +/** + Provide CIRA request Timeout from OEM code. + + @param[in] None. + + @retval CIRA require Timeout for MPS connection to be estabilished +**/ +UINT8 +AmtCiraRequestTimeout ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + return mDxePlatformAmtPolicy->AmtConfig.CiraTimeout; +} + +/** + Provide Manageability Mode setting from MEBx BIOS Sync Data + + @param[in] None + + @retval UINT8 Manageability Mode = MNT_AMT or MNT_ASF +**/ +UINT8 +ManageabilityModeSetting ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return 0; + } + } + return (UINT8) (mDxePlatformAmtPolicy->AmtConfig.ManageabilityMode); +} + +/** + Provide UnConfigure ME without password request from OEM code. + + @param[in] None. + + @retval Check if unConfigure ME without password request +**/ +BOOLEAN +AmtUnConfigureMe ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + return mDxePlatformAmtPolicy->AmtConfig.UnConfigureMe == 1; +} + +/** + Provide 'Hiding the Unconfigure ME without password confirmation prompt' request from OEM code. + + @param[in] None. + + @retval Check if 'Hide unConfigure ME without password Confirmation prompt' request +**/ +BOOLEAN +AmtHideUnConfigureMeConfPrompt ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + return mDxePlatformAmtPolicy->AmtConfig.HideUnConfigureMeConfirm == 1; +} + +/** + Provide show MEBx debug message request from OEM code. + + @param[in] None. + + @retval Check show MEBx debug message request + **/ +BOOLEAN +AmtMebxDebugMsg ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + return mDxePlatformAmtPolicy->AmtConfig.MebxDebugMsg == 1; +} + +/** + Provide on-board device list table and do not need to report them to AMT. AMT only need to know removable PCI device + information. + + @param[in] None. + + @retval on-board device list table pointer other than system device. +**/ +UINT32 +AmtPciDeviceFilterOutTable ( + VOID + ) +{ + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return 0; + } + } + return mDxePlatformAmtPolicy->AmtConfig.PciDeviceFilterOutTable; +} + +/** + Check if USB provisioning enabled/disabled in platform policy. + + @param[in] None. + + @retval FALSE USB provisioning is disabled. + @retval TRUE USB provisioning is enabled. +**/ +BOOLEAN +USBProvisionSupport ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + Supported = FALSE; + + // + // First check if USB Provision is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.USBProvision == 1) { + Supported = TRUE; + } + + return Supported; +} + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] None. + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +FwProgressSupport ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + Supported = FALSE; + + // + // First check if FW Progress is enabled in Setup. + // + if (mDxePlatformAmtPolicy->AmtConfig.FWProgress == 1) { + Supported = TRUE; + } + + return Supported; +} + +/** + Check if ForcMebxSyncUp is enabled in setup options. + + @param[in] None. + + @retval FALSE ForcMebxSyncUp is disabled. + @retval TRUE ForcMebxSyncUp is enabled. +**/ +BOOLEAN +AmtForcMebxSyncUp ( + VOID + ) +{ + BOOLEAN Supported; + EFI_STATUS Status; + + if (mDxePlatformAmtPolicy == NULL) { + Status = AmtPolicyLibInit(); + if (EFI_ERROR(Status)) { + return FALSE; + } + } + if (mDxePlatformAmtPolicy->AmtConfig.ForcMebxSyncUp == 1) { + Supported = TRUE; + } else { + Supported = FALSE; + } + + return Supported; +} diff --git a/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.h b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.h new file mode 100644 index 0000000..866c5c0 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/AmtPolicyLib.h @@ -0,0 +1,298 @@ +/** @file + Header file for AMT 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 _AMT_POLICY_LIB_H_ +#define _AMT_POLICY_LIB_H_ + +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) +#include EFI_GUID_DEFINITION (MeBiosExtensionSetup) + +/** + Check if AMT is enabled in setup options. + + @param[in] None. + + @retval EFI_SUCCESS AMT platform policy is initialized. + @retval All other error conditions encountered when no AMT platform policy available. +**/ +EFI_STATUS +AmtPolicyLibInit ( + VOID + ) +; + +/** + Check if Asf is enabled in setup options. + + @param[in] None. + + @retval FALSE Asf is disabled. + @retval TRUE Asf is enabled. +**/ +BOOLEAN +AsfSupported ( + VOID + ) +; + +/** + Check if Amt is enabled in setup options. + + @param[in] None. + + @retval FALSE Amt is disabled. + @retval TRUE Amt is enabled. +**/ +BOOLEAN +AmtSupported ( + VOID + ) +; + +/** + Check if AMT BIOS Extension hotkey was pressed during BIOS boot. + + @param[in] None. + + @retval FALSE MEBx hotkey was not pressed. + @retval TRUE MEBx hotkey was pressed. +**/ +BOOLEAN +AmtHotkeyPressed ( + VOID + ) +; + +/** + Check if AMT BIOS Extension Selection Screen is enabled in setup options. + + @param[in] None. + + @retval FALSE AMT Selection Screen is disabled. + @retval TRUE AMT Selection Screen is enabled. +**/ +BOOLEAN +AmtSelectionScreen ( + VOID + ) +; + +/** + Check if AMT WatchDog is enabled in setup options. + + @param[in] None. + + @retval FALSE AMT WatchDog is disabled. + @retval TRUE AMT WatchDog is enabled. +**/ +BOOLEAN +AmtWatchDog ( + VOID + ) +; + +/** + Return BIOS watchdog timer + + @param[in] None. + + @retval UINT16 BIOS ASF Watchdog Timer +**/ +UINT16 +AmtWatchDogTimerBiosGet ( + VOID + ) +; + +/** + Return OS watchdog timer + + @param[in] None. + + @retval UINT16 OS ASF Watchdog Timer +**/ +UINT16 +AmtWatchDogTimerOsGet ( + VOID + ) +; + +/** + Provide CIRA request information from OEM code. + + @param[in] None. + + @retval Check if any CIRA requirement during POST +**/ +BOOLEAN +AmtCiraRequestTrigger ( + VOID + ) +; + +/** + Provide CIRA request Timeout from OEM code. + + @param[in] None. + + @retval CIRA require Timeout for MPS connection to be estabilished +**/ +UINT8 +AmtCiraRequestTimeout ( + VOID + ) + +; + +/** + Provide Manageability Mode setting from MEBx BIOS Sync Data + + @param[in] None + + @retval UINT8 Manageability Mode = MNT_AMT or MNT_ASF +**/ +UINT8 +ManageabilityModeSetting ( + VOID + ) +; + +/** + Provide UnConfigure ME without password request from OEM code. + + @param[in] None. + + @retval Check if unConfigure ME without password request +**/ +BOOLEAN +AmtUnConfigureMe ( + VOID + ) +; + +/** + Provide 'Hiding the Unconfigure ME without password confirmation prompt' request from OEM code. + + @param[in] None. + + @retval Check if 'Hide unConfigure ME without password Confirmation prompt' request +**/ +BOOLEAN +AmtHideUnConfigureMeConfPrompt ( + VOID + ) +; + +/** + Provide show MEBx debug message request from OEM code. + + @param[in] None. + + @retval Check show MEBx debug message request + **/ +BOOLEAN +AmtMebxDebugMsg ( + VOID + ) +; + +/** + Provide on-board device list table and do not need to report them to AMT. AMT only need to know removable PCI device + information. + + @param[in] None. + + @retval on-board device list table pointer other than system device. +**/ +UINT32 +AmtPciDeviceFilterOutTable ( + VOID + ) +; + +/** + Check if USB provisioning enabled/disabled in platform policy. + + @param[in] None. + + @retval FALSE USB provisioning is disabled. + @retval TRUE USB provisioning is enabled. +**/ +BOOLEAN +USBProvisionSupport ( + VOID + ) +; + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] None. + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +FwProgressSupport ( + VOID + ) +; + +/** + Check if ForcMebxSyncUp is enabled in setup options. + + @param[in] None. + + @retval FALSE ForcMebxSyncUp is disabled. + @retval TRUE ForcMebxSyncUp is enabled. +**/ +BOOLEAN +AmtForcMebxSyncUp ( + VOID + ) +; + +/** + Dump DXE Amt Platform Policy + + @param[in] None. + + @retval None +**/ +VOID +DxeAmtPolicyDebugDump ( + VOID + ) +; + +/** + Dump ME_BIOS_EXTENSION_SETUP variable + + @param[in] MeBiosExtensionSetup Pointer to ME_BIOS_EXTENSION_SETUP variable + + @retval None +**/ +VOID +DxeMebxSetupVariableDebugDump ( + IN ME_BIOS_EXTENSION_SETUP *MeBiosExtensionSetup OPTIONAL + ) +; +#endif diff --git a/ReferenceCode/ME/Library/AMT/Dxe/MebxSetupDebugDumpDxe.c b/ReferenceCode/ME/Library/AMT/Dxe/MebxSetupDebugDumpDxe.c new file mode 100644 index 0000000..7fd5048 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Dxe/MebxSetupDebugDumpDxe.c @@ -0,0 +1,75 @@ +/** @file + Dump whole ME_BIOS_EXTENSION_SETUP 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 +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AmtPolicyLib.h" +#endif + +/** + Dump ME_BIOS_EXTENSION_SETUP variable + + @param[in] MeBiosExtensionSetup Pointer to ME_BIOS_EXTENSION_SETUP variable + + @retval None +**/ +VOID +DxeMebxSetupVariableDebugDump ( + IN ME_BIOS_EXTENSION_SETUP *MeBiosExtensionSetup OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN VariableSize; + ME_BIOS_EXTENSION_SETUP MeBxSetup; + ME_BIOS_EXTENSION_SETUP *MeBxSetupPtr; + + if (MeBiosExtensionSetup == NULL) { + Status = gRT->GetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBxSetup + ); + if (EFI_ERROR(Status)) { + return; + } + MeBxSetupPtr = &MeBxSetup; + } else { + MeBxSetupPtr = MeBiosExtensionSetup; + } + + DEBUG ((EFI_D_INFO, "\n------------------------ MeBiosExtensionSetup Dump Begin -----------------\n")); + DEBUG ((EFI_D_INFO, " InterfaceVersion : 0x%x\n", MeBxSetupPtr->InterfaceVersion)); + DEBUG ((EFI_D_INFO, " Flags : 0x%x\n", MeBxSetupPtr->Flags)); + DEBUG ((EFI_D_INFO, " PlatformMngSel : 0x%x\n", MeBxSetupPtr->PlatformMngSel)); + DEBUG ((EFI_D_INFO, " AmtSolIder : 0x%x\n", MeBxSetupPtr->AmtSolIder)); + DEBUG ( + (EFI_D_INFO, + " RemoteAssistanceTriggerAvailablilty : 0x%x\n", + MeBxSetupPtr->RemoteAssistanceTriggerAvailablilty) + ); + DEBUG ((EFI_D_INFO, " KvmEnable : 0x%x\n", MeBxSetupPtr->KvmEnable)); + DEBUG ((EFI_D_INFO, " MebxDefaultSolIder : 0x%x\n", MeBxSetupPtr->MebxDefaultSolIder)); + + DEBUG ((EFI_D_INFO, "\n------------------------ MeBiosExtensionSetup Dump End -------------------\n")); + +} diff --git a/ReferenceCode/ME/Library/AMT/Include/Amt.h b/ReferenceCode/ME/Library/AMT/Include/Amt.h new file mode 100644 index 0000000..9698218 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Include/Amt.h @@ -0,0 +1,59 @@ +/** @file + Header file for common Active Management Technology defines. + +@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 _AMT_H_ +#define _AMT_H_ + +/// +/// Intel Internet Assigned Numbers Authority Manufacturer ID +/// (The firmware sends 0x57010000 for decimal value 343) +/// +#define INTEL_IANA_SWAP32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) +#define ASF_INTEL_IANA 0x00000157 +#define ASF_INTEL_CONVERTED_IANA INTEL_IANA_SWAP32 (ASF_INTEL_IANA) ///< 0X57010000, received from ME +/// +/// Intel OEM Special Command +/// +#define ASF_INTEL_OEM_CMD 0xC1 + +/// +/// Intel OEM Parameters 16 bit OEM Parameter values +/// +#define USE_SOL 0x0001 ///< 0000 0000 0000 0001 - bit 0, use SOL on the next boot +// +// Intel OEM Command 16 bit special command parameter values +// +#define USE_IDER 0x0001 ///< 0000 0000 0000 0001 - bit 0 Paramater 2 will be used to indicate the channel +#define ENFORCE_SECURE_BOOT 0x0002 ///< 0000 0000 0000 0010 - bit 1 Enforce secure boot over IDER +#define REFLASH_BIOS 0x0004 ///< 0000 0000 0000 0100 - bit 2 +#define BIOS_SETUP 0x0008 ///< 0000 0000 0000 1000 - bit 3 +#define BIOS_PAUSE 0x0010 ///< 0000 0000 0001 0000 - bit 4 +#define USE_KVM 0x0020 ///< 0000 0000 0010 0000 - bit 5 +#define IDER_CD 0x0100 ///< 0000 0001 0000 0000 - bit 8 Primary Slave Drive +#define IDER_PRIMARY_MASTER 0x0000 +#define IDER_PRIMARY_SLAVE 0x0100 +#define IDER_SECONDARY_MASTER 0x0200 +#define IDER_SECONDARY_SLAVE 0x0300 + +#define IDER_BOOT_DEVICE_MASK 0x0300 +#define IDER_BOOT_DEVICE_SHIFT 8 + +#endif diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.cif b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.cif new file mode 100644 index 0000000..1c34f45 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.cif @@ -0,0 +1,13 @@ +<component> + name = "AmtLibPei" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\AMT\Pei\" + RefName = "AmtLibPei" +[files] +"AmtLibPei.sdl" +"AmtLibPei.mak" +"AmtPolicyLibPei.c" +"AmtPolicyLibPei.h" +"AmtLibPei.h" +"AmtLibPei.inf" +<endComponent> diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.h b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.h new file mode 100644 index 0000000..4b29fc9 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.h @@ -0,0 +1,26 @@ +/** @file + Header file for PEI AMT 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_AMT_LIB_H_ +#define _PEI_AMT_LIB_H_ + +#include "AmtPolicyLibPei.h" + +#endif diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.inf b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.inf new file mode 100644 index 0000000..44d88ad --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.inf @@ -0,0 +1,51 @@ +## @file +# Component description file for AMT 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 = AmtLibPei +COMPONENT_TYPE = LIBRARY + +[sources.common] + AmtPolicyLibPei.c + AmtPolicyLibPei.h + AmtLibPei.h + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_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] + EdkIIGluePeiServicesLib + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_PEI_SERVICES_LIB__ diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.mak b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.mak new file mode 100644 index 0000000..e31ecc5 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.mak @@ -0,0 +1,50 @@ +# /*++ +# 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:AmtLibPei +all : AmtLibPei + +$(BUILD_DIR)\AmtLibPei.lib : AmtLibPei + +AmtLibPei : $(BUILD_DIR)\AmtLibPei.mak AmtLibPeiBin + +$(BUILD_DIR)\AmtLibPei.mak : $(AmtLibPei_DIR)\$(@B).cif $(AmtLibPei_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AmtLibPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +AmtLibPei_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES) \ + +AmtLibPei_DEFINES=\ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ + +AmtLibPei_LIBS=\ + $(EdkIIGluePeiServicesLib_LIB)\ + +AmtLibPeiBin : $(AmtLibPei_LIBS) $(MeLibPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + /f $(BUILD_DIR)\AmtLibPei.mak all \ + "MY_INCLUDES=$(AmtLibPei_INCLUDES)" \ + "CFLAGS=$(CFLAGS) $(AmtLibPei_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/AMT/Pei/AmtLibPei.sdl b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.sdl new file mode 100644 index 0000000..b3a63bd --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtLibPei.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "AmtLibPei_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AmtLibPei support in Project" +End + +MODULE + Help = "Includes AmtLibPei.mak to Project" + File = "AmtLibPei.mak" +End + +PATH + Name = "AmtLibPei_DIR" + Help = "iAMT Library file source directory" +End + +ELINK + Name = "AmtLibPei_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\AmtLibPei.lib" + Parent = "AmtLibPei_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(AmtLibPei_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.c b/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.c new file mode 100644 index 0000000..472ebbc --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.c @@ -0,0 +1,241 @@ +/** @file + Implementation file for AMT 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 "AmtPolicyLibPei.h" +#endif + +EFI_GUID mPeiAmtStatusCodePpiGuid = PEI_AMT_STATUS_CODE_PPI_GUID; + +/** + Check if Amt is enabled in setup options. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] PeiAmtPlatformPolicy The AMT Platform Policy protocol instance + + @retval EFI_SUCCESS AMT platform policy Ppi located + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PeiAmtPolicyLibInit ( + EFI_PEI_SERVICES **PeiServices, + PEI_AMT_PLATFORM_POLICY_PPI **PeiAmtPlatformPolicy + ) +{ + EFI_STATUS Status; + + /// + /// Locate system configuration variable + /// + Status = PeiServicesLocatePpi ( + &gPeiAmtPlatformPolicyPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) PeiAmtPlatformPolicy // PPI + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Check if AMT WatchDog is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE AMT WatchDog is disabled. + @retval TRUE AMT WatchDog is enabled. +**/ +BOOLEAN +PeiAmtWatchDog ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + BOOLEAN Supported; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Supported = FALSE; + if (ManageabilityModeSetting (PeiServices) != 0) { + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + // + // First check if AMT WatchDog is enabled in Setup. + // + if (PeiAmtPlatformPolicy->WatchDog == 1) { + Supported = TRUE; + } + } + + return Supported; +} + +/** + Get WatchDog BIOS Timmer. + + @param[in] PeiServices Point to Pei Services structure + + @retval UINT16 WatchDog BIOS Timer +**/ +UINT16 +PeiAmtWatchTimerBiosGet ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + + return PeiAmtPlatformPolicy->WatchDogTimerBios; +} + +/** + Check if AMT is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE ActiveManagement is disabled. + @retval TRUE ActiveManagement is enabled. +**/ +BOOLEAN +PeiAmtSupported ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + BOOLEAN Supported; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + + // + // First check if AMT support is enabled in Setup. + // + if (PeiAmtPlatformPolicy->iAmtEnabled == 1) { + Supported = TRUE; + } else { + Supported = FALSE; + } + + return Supported; +} + +/** + Check if ASF is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE ASF is disabled. + @retval TRUE ASF is enabled. +**/ +BOOLEAN +PeiAsfSupported ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + BOOLEAN Supported; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + + if (PeiAmtPlatformPolicy->Revision < PEI_AMT_PLATFORM_POLICY_PPI_REVISION_2) { + return FALSE; + } + // + // First check if ASF support is enabled in Setup. + // + if (PeiAmtPlatformPolicy->AsfEnabled == 1) { + Supported = TRUE; + } else { + Supported = FALSE; + } + + return Supported; +} + +/** + Provide Manageability Mode setting from MEBx BIOS Sync Data + + @param[in] PeiServices Point to Pei Services structure + + @retval UINT8 Manageability Mode = MNT_AMT or MNT_ASF +**/ +UINT8 +ManageabilityModeSetting ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + + if (PeiAmtPlatformPolicy->Revision < PEI_AMT_PLATFORM_POLICY_PPI_REVISION_2) { + return 0; + } + + return (UINT8) (PeiAmtPlatformPolicy->ManageabilityMode); +} + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] PeiServices Point to Pei Services structure + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +PeiFwProgressSupport ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + BOOLEAN Supported; + PEI_AMT_PLATFORM_POLICY_PPI *PeiAmtPlatformPolicy; + + Status = PeiAmtPolicyLibInit (PeiServices, &PeiAmtPlatformPolicy); + ASSERT_EFI_ERROR (Status); + + Supported = FALSE; + + if (PeiAmtPlatformPolicy->Revision >= PEI_AMT_PLATFORM_POLICY_PPI_REVISION_3) { + // + // Check if progress event is enabled in Setup. + // + if (PeiAmtPlatformPolicy->FWProgress == 1) { + Supported = TRUE; + } + } + + return Supported; +} diff --git a/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.h b/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.h new file mode 100644 index 0000000..b7361f4 --- /dev/null +++ b/ReferenceCode/ME/Library/AMT/Pei/AmtPolicyLibPei.h @@ -0,0 +1,126 @@ +/** @file + Header file for PEI AMT 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 _PEI_AMT_POLICY_LIB_H_ +#define _PEI_AMT_POLICY_LIB_H_ + +#include EFI_PPI_DEFINITION (AmtPlatformPolicyPei) +#include EFI_PPI_DEFINITION (AmtStatusCode) + +/** + Check if Amt is enabled in setup options. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] PeiAmtPlatformPolicy The AMT Platform Policy protocol instance + + @retval EFI_SUCCESS AMT platform policy Ppi located + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PeiAmtPolicyLibInit ( + EFI_PEI_SERVICES **PeiServices, + PEI_AMT_PLATFORM_POLICY_PPI **PeiAmtPlatformPolicy + ) +; + +/** + Check if AMT WatchDog is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE AMT WatchDog is disabled. + @retval TRUE AMT WatchDog is enabled. +**/ +BOOLEAN +PeiAmtWatchDog ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + Get WatchDog BIOS Timmer. + + @param[in] PeiServices Point to Pei Services structure + + @retval UINT16 WatchDog BIOS Timer +**/ +UINT16 +PeiAmtWatchTimerBiosGet ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + Check if AMT is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE ActiveManagement is disabled. + @retval TRUE ActiveManagement is enabled. +**/ +BOOLEAN +PeiAmtSupported ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + Check if ASF is enabled in setup options. + + @param[in] PeiServices Point to Pei Services structure + + @retval FALSE ASF is disabled. + @retval TRUE ASF is enabled. +**/ +BOOLEAN +PeiAsfSupported ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + Provide Manageability Mode setting from MEBx BIOS Sync Data + + @param[in] PeiServices Point to Pei Services structure + + @retval UINT8 Manageability Mode = MNT_AMT or MNT_ASF +**/ +UINT8 +ManageabilityModeSetting ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] PeiServices Point to Pei Services structure + + @retval True progress event is enabled. + @retval False progress event is disabled. +**/ +BOOLEAN +PeiFwProgressSupport ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +#endif diff --git a/ReferenceCode/ME/Library/AtLibrary/AtLibrary.cif b/ReferenceCode/ME/Library/AtLibrary/AtLibrary.cif new file mode 100644 index 0000000..1584c4d --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/AtLibrary.cif @@ -0,0 +1,10 @@ +<component> + name = "AtLibrary" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\AtLibrary\" + RefName = "AtLibrary" +[files] +"AtLibrary.sdl" +[parts] +"AtDxeLib" +<endComponent> diff --git a/ReferenceCode/ME/Library/AtLibrary/AtLibrary.sdl b/ReferenceCode/ME/Library/AtLibrary/AtLibrary.sdl new file mode 100644 index 0000000..c712a95 --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/AtLibrary.sdl @@ -0,0 +1,20 @@ +TOKEN + Name = "AtLibrary_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AmtLibDxe support in Project" +End + +PATH + Name = "AtLibrary_DIR" + Help = "iAMT Library file source directory" +End + +ELINK + Name = "/I$(AtLibrary_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.c b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.c new file mode 100644 index 0000000..54b5959 --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.c @@ -0,0 +1,630 @@ +/** @file + AT authetication module for using AT DXE driver. + This driver uses the AT protocol, HECI Protocol and AT Platform Policy to implement Theft Deterrence Technology AM module. + +@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 + +**/ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// + +#include "AtAmHelper.h" + +const CHAR8 *PEMCodes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-!="; +const CHAR8 *LineBreak = " \n\t"; + +/** + Convert Hex values into Base32 values + + @param[in] encodedStr Array of encoded BASE values. + @param[in] encodedLen Length of encoded values. + @param[out] rawData Array of Hex strings that needs to be encoded into BASE32. + @param[out] rawDataLen Length of Hex values. + + @retval EFI_BUFFER_TOO_SMALL Buffer to store encoded string too small. + @retval EFI_SUCCESS Initialization complete. +**/ +EFI_STATUS +Base32Encode ( + IN UINT8 *encodedStr, + IN UINTN *encodedLen, + OUT UINT8 *rawData, + OUT UINTN rawDataLen + ) +{ + UINTN i; + UINTN j; + UINT8 value; + INTN shift; + INTN shifttable[] = { 3, -2, 1, -4, -1, 2, -3, 0 }; + + if (encodedLen && *encodedLen < (rawDataLen * 8) / 5) { + DEBUG ((EFI_D_ERROR, "ATAm::Base32Encode: Buffer to store encoded string too small")); + return EFI_BUFFER_TOO_SMALL; + } + + for (i = 0, j = 0; i < rawDataLen; j++) { + shift = shifttable[j % 8]; + if (shift > 0) { + value = (UINT8) (rawData[i] >> shift); + } else { + value = (UINT8) (rawData[i] << (-shift)); + if (i++ < rawDataLen - 1) { + value |= (rawData[i] >> (8 + shift)); + } + } + + value &= 0x1f; + if (25 >= value) { + value += 'A'; + } else { + value += '2' - 26; + } + + if (encodedStr && encodedLen) { + encodedStr[j] = value; + } + } + + if (encodedStr && encodedLen) { + *encodedLen = j; + encodedStr[j] = L'\0'; + } + + return EFI_SUCCESS; +} + +/** + Convert Base32 values into Hex values. + + @param[in] encodedStr Array of Decimal numbers. + @param[out] decodedData Converted Hex values. + + @retval Length of the Hex Strings that expected. +**/ +INTN +Base32Decode ( + IN UINT8 *encodedStr, + IN UINT8 *decodedData + ) +{ + UINTN i; + UINTN j; + INTN retVal; + UINT8 value; + UINTN decodedLen; + INTN shifttable[] = { 3, -2, 1, -4, -1, 2, -3, 0 }; + INTN shift; + UINTN encodedLen; + + retVal = 1; + encodedLen = AsciiStrLen ((char *) encodedStr); + + decodedLen = (encodedLen * 5) / 8; + + decodedData[0] = 0; + for (i = 0, j = 0; i < encodedLen; i++) { + if ('A' <= encodedStr[i] && 'Z' >= encodedStr[i]) { + value = encodedStr[i] - 'A'; + } else if ('a' <= encodedStr[i] && 'z' >= encodedStr[i]) { + value = encodedStr[i] - 'a'; + } else if ('2' <= encodedStr[i] && '7' >= encodedStr[i]) { + value = encodedStr[i] - '2' + 26; + } else { + retVal = 0; + break; + } + + shift = shifttable[i % 8]; + if (shift > 0) { + decodedData[j] |= (value << shift); + } else { + decodedData[j] |= (value >> (-shift)); + /// + /// Pack the bits that are going to fall off due to right shift in next byte + /// (left justfied) unless decoding the last character. In case of last + /// character, the extra bits are just padding to make the length of input + /// bits a multiple of 5 while encoding - so ignore them + /// + if (i != encodedLen - 1) { + decodedData[++j] = (UINT8) (value << (8 + shift)); + } + } + } + + return retVal; +} + +/** + Decimal large (BASE10) into hex value. + + @param[in][out] decStr Array of Decimal numbers. + @param[out] u8Hex Converted Hex values. + @param[in] hexIndex Length of the Hex Strings that expected + + @retval None +**/ +VOID +DecimalToHexString ( + IN OUT CHAR8 *decStr, + OUT UINT8 *u8Hex, + IN UINTN hexIndex + ) +{ + + UINTN i; + UINTN j; + UINTN Remainder; + CHAR8 Quotient; + UINTN num; + UINTN len; + UINTN leadingZero; + + leadingZero = 1; + + len = AsciiStrLen ((CHAR8 *) decStr); + Remainder = decStr[0] - '0'; + + if (len > 1) { + Remainder = Remainder * 10 + decStr[1] - '0'; + } + + if (len < 3) { + u8Hex[hexIndex] = (UINT8) Remainder; + return; + } + + i = 2; + j = 0; + while (i < len) { + num = Remainder * 10 + decStr[i] - '0'; + Quotient = (CHAR8) (num / 256); + if (!leadingZero || Quotient) { + decStr[j++] = '0' + Quotient; + leadingZero = 0; + } + + Remainder = num % 256; + i++; + + } + + decStr[j] = L'\0'; + u8Hex[hexIndex--] = (UINT8) Remainder; + + if (decStr[0] != L'\0') { + DecimalToHexString (decStr, u8Hex, hexIndex); + } + + return; +} + +/** + Convert the CHAR8 ASCII into CHAR16 Unicode strings. + + @param[in] AsciiString Ascii String. + @param[out] UnicodeString Buffer for converted Unicode string. + + @retval None +**/ +VOID +Uint8ToUnicode ( + IN CHAR8 *AsciiString, + OUT CHAR16 *UnicodeString + ) +{ + UINT8 Index; + + Index = 0; + + while (AsciiString[Index] != 0) { + UnicodeString[Index] = (CHAR16) AsciiString[Index]; + Index++; + } +} + +/** + Decode a PEM-encoded character. + + @param[in] pemChar PEM-encoded character. + + @retval Value orresponding to the character, or PEM_INVALID_CHARACTER if the input character could not be decoded. +**/ +UINT8 +DecodePEMChar ( + IN UINT8 pemChar + ) +{ + if ((pemChar >= 'A') && (pemChar <= 'Z')) { + return pemChar - 'A'; + } + + if ((pemChar >= 'a') && (pemChar <= 'z')) { + return (pemChar - 'a') + 26; + } + + if ((pemChar >= '0') && (pemChar <= '9')) { + return (pemChar - '0') + 52; + } + + if (pemChar == '-') { + return 62; + } + + if (pemChar == '!') { + return 63; + } + + if (pemChar == '=') { + return PEM_PAD_CHAR; + + } + + DEBUG ((EFI_D_ERROR, "DecodePEMChar: Invalid character %d\n", pemChar)); + return PEM_INVALID_CHAR; +} + +/** + Decode character in ASCII to hexadecimal + + @param[in] base16char Character in ASCII + + @retval Value in hexadecimal. +**/ +UINT8 +DecodeBase16Char ( + IN UINT8 base16char + ) +{ + if (base16char >= '0' && base16char <= '9') { + return base16char - '0'; + } else if (base16char >= 'A' && base16char <= 'F') { + return base16char - 'A' + 0xA; + } else if (base16char >= 'a' && base16char <= 'f') { + return base16char - 'a' + 0xA; + } + + return 0; +} + +/** + Decode ASCII string to hexadecimal string + + @param[in] pString Pointer of ASCII string + @param[in] stringLen Size of the ASCII string + @param[out] pDecodedData Pointer of hexadecimal string + @param[out] pBufLength Pointer to buffer length returned + + @retval FALSE Failed to decode the string by invalid length or buffer size + @retval TRUE The hexadecimal string returned +**/ +BOOLEAN +Base16Decode ( + IN UINT8 *pString, + IN UINT32 stringLen, + OUT UINT8 *pDecodedData, + OUT UINT32 *pBufLength + ) +{ + UINT32 i; + if (stringLen % 2 != 0) { + DEBUG ((EFI_D_ERROR, "Cannot decode hexadecimal string -- invalid length\n")); + } else if (*pBufLength < stringLen / 2) { + DEBUG ((EFI_D_ERROR, "Base16 decode - output buffer too small\n")); + } else { + for (i = 0; i < (UINT32) stringLen / 2; i++) { + pDecodedData[i] = DecodeBase16Char (pString[2 * i]) << 4; + pDecodedData[i] |= DecodeBase16Char (pString[2 * i + 1]); + } + + *pBufLength = i; + return TRUE; + } + + return FALSE; +} + +/** + Encode string to ASCII code + + @param[in] pData Pointer of string to be encoded + @param[in] dataLength Size of the string to be + @param[out] pEncodedData Pointer of encoded string + @param[out] pBufLength Pointer to buffer length returned + + @retval FALSE Failed to encode the string by invalid length or buffer size + @retval TRUE The encoded string returned +**/ +BOOLEAN +Base16Encode ( + IN UINT8 *pData, + IN UINT32 dataLength, + OUT UINT8 *pEncodedData, + OUT UINT32 *pBufLength + ) +{ + UINT32 i; + if (*pBufLength < 2 * dataLength) { + DEBUG ((EFI_D_ERROR, "Cannot encode data -- output buffer too small\n")); + return FALSE; + } + + DEBUG ((EFI_D_ERROR, "Base16Encode dataLength : %d\n", dataLength)); + + for (i = 0; i < dataLength; i++) { + AsciiSPrint ((CHAR8 *) &pEncodedData[2 * i], 3 * sizeof (UINT8), "%02x", pData[i] & 0xFF); + } + + DEBUG ((EFI_D_ERROR, "Base16Encode AsciiSPrint : %s\n", (char *) pEncodedData)); + DEBUG ((EFI_D_ERROR, "Base16Encode Sprint : %s\n", (char *) pEncodedData)); + + *pBufLength = 2 * dataLength; + + return TRUE; +} + +/** + Decode PEM-Encoded data + + @param[in] pPEMString Pointer to PEM-Encoded buffer + @param[in] lineLength Length in bytes + @param[in] pDecodedData Pointer to buffer to receive decoded bytes + @param[in] pBufLength Pointer to the size of the output buffer. Upon return this will + contain the length of the decoded data + + @retval Returns status code indicating outcome of operation +**/ +BOOLEAN +PEMSMSDecode ( + IN UINT8 *pPEMString, + IN UINT32 lineLength, + OUT UINT8 *pDecodedData, + OUT UINT32 *pBufLength + ) +{ + UINT8 *pStr; + UINT32 curOutLen; + UINT8 *pOut; + UINT32 i; + UINT32 padBytes; + UINT8 val1; + UINT8 val2; + UINT8 decodedValue[4]; + UINT32 ii; + UINT32 unitCount; + UINT32 decodedBytes; + + pStr = pPEMString; + curOutLen = *pBufLength; + pOut = pDecodedData; + padBytes = 0; + + if (pStr != NULL) { + if ((lineLength % 4) != 0) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- invalid length -1\n")); + return FALSE; + } + + unitCount = lineLength / 4; + + for (i = 0; (i < unitCount) && (padBytes == 0); i++) { + val1 = DecodePEMChar (*pStr++); + val2 = DecodePEMChar (*pStr++); + + if ((val1 == PEM_INVALID_CHAR) || (val2 == PEM_INVALID_CHAR)) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- invalid character -2\n")); + return FALSE; + } + + decodedValue[0] = ((val1 << 2) | (val2 >> 4)); + val1 = DecodePEMChar (*pStr++); + if (val1 == PEM_INVALID_CHAR) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- invalid character -3\n")); + return FALSE; + } + + if (val1 != PEM_PAD_CHAR) { + decodedValue[1] = ((val2 << 4) | (val1 >> 2)); + val2 = DecodePEMChar (*pStr++); + if (val2 == PEM_INVALID_CHAR) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- invalid character -4\n")); + return FALSE; + } + + if (val2 == PEM_PAD_CHAR) { + padBytes = 1; + } else { + decodedValue[2] = ((val1 << 6) | val2); + } + } else { + val2 = DecodePEMChar (*pStr++); + if (val2 != PEM_PAD_CHAR) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- invalid encoding -4\n")); + return FALSE; + } + + padBytes = 2; + } + + decodedBytes = (3 - padBytes); + if (curOutLen < decodedBytes) { + DEBUG ((EFI_D_ERROR, "Cannot decode PEM string -- out buffer too small-5\n")); + return FALSE; + } + + for (ii = 0; ii < decodedBytes; ii++) { + pOut[ii] = decodedValue[ii]; + + } + + curOutLen -= decodedBytes; + pOut += decodedBytes; + } + } + + *pBufLength = *pBufLength - curOutLen; + return TRUE; +} + +/** + Encoded data + + @param[in] pData Pointer to buffer + @param[in] dataLength Length in bytes + @param[out] pPEMString Pointer to buffer to receive encoded bytes + @param[out] pBufLength Pointer to the size of the output buffer. Upon return this will + contain the length of the encoded data + + @retval Returns status code indicating outcome of operation +**/ +BOOLEAN +PEMSMSEncode ( + IN UINT8 *pData, + IN UINT32 dataLength, + OUT UINT8 *pPEMString, + OUT UINT32 *pBufLength + ) +{ + UINT32 encodeUnits; + UINT32 paddedInputLength; + UINT32 padBytes; + UINT32 outLength; + UINT8 encodeBuf[3]; + UINT32 i; + UINT8 *pOctet; + UINT32 ipos; + UINT32 opos; + UINT32 index; + + encodeUnits = (dataLength + 2) / 3; + paddedInputLength = encodeUnits * 3; + padBytes = paddedInputLength - dataLength; + outLength = encodeUnits * 4; + pOctet = pData; + ipos = 0; + opos = 0; + + outLength = encodeUnits * 4; + if (outLength % 64) { + outLength += ((outLength / 64) + 1); + } else { + outLength += (outLength / 64); + + } + + outLength++; + DEBUG ((EFI_D_ERROR, "ATAM: Pbuflength: %d OutLength: %d \n", *pBufLength, outLength)); + if (*pBufLength < outLength) { + DEBUG ((EFI_D_ERROR, "ATAM: Failed \n")); + return FALSE; + } + + for (i = 0; i < encodeUnits; i++) { + if ((i == encodeUnits - 1) && (padBytes > 0)) { + // + // Encode last piece, with padding + // + encodeBuf[0] = *pOctet++; + encodeBuf[1] = (padBytes == 1) ? encodeBuf[1] = *pOctet++ : 0; + encodeBuf[2] = 0; + ipos += (3 - padBytes); + + index = encodeBuf[0] >> 2; + pPEMString[opos++] = PEMCodes[index]; + index = ((encodeBuf[0] & 0x03) << 4) | (encodeBuf[1] >> 4); + pPEMString[opos++] = PEMCodes[index]; + + if (padBytes == 1) { + index = ((encodeBuf[1] & 0x0f) << 2) | (encodeBuf[2] >> 6); + pPEMString[opos++] = PEMCodes[index]; + pPEMString[opos++] = '='; + } else { + pPEMString[opos++] = '='; + pPEMString[opos++] = '='; + } + } else { + // + // Encode next 3 bytes + // + encodeBuf[0] = *pOctet++; + encodeBuf[1] = *pOctet++; + encodeBuf[2] = *pOctet++; + ipos += 3; + index = encodeBuf[0] >> 2; + pPEMString[opos++] = PEMCodes[index]; + index = ((encodeBuf[0] & 0x03) << 4) | (encodeBuf[1] >> 4); + pPEMString[opos++] = PEMCodes[index]; + index = ((encodeBuf[1] & 0x0f) << 2) | (encodeBuf[2] >> 6); + pPEMString[opos++] = PEMCodes[index]; + index = encodeBuf[2] & 0x3f; + pPEMString[opos++] = PEMCodes[index]; + } + } + + pPEMString[opos] = 0; + *pBufLength = opos; + + return TRUE; +} + +#ifdef EFI_DEBUG + +/** + This routine displays the debug message in ASCII + + @param[in] Message Message to be displayed + @param[in] Length Length of the message + + @retval None +**/ +VOID +ShowBuffer ( + IN UINT8 *Message, + IN UINT32 Length + ) +{ + UINT32 LineBreak; + UINT32 Index; + LineBreak = 0; + Index = 0; + + while (Length-- > 0) { + if (LineBreak == 0) { + DEBUG ((EFI_D_ERROR, "%02x: ", (Index & 0xF0))); + } + + DEBUG ((EFI_D_ERROR, "%02x ", Message[Index++])); + LineBreak++; + if (LineBreak == 16) { + DEBUG ((EFI_D_ERROR, "\n")); + LineBreak = 0; + } + + if (LineBreak == 8) { + DEBUG ((EFI_D_ERROR, "- ")); + } + } + + DEBUG ((EFI_D_ERROR, "\n")); + return ; +} + +#endif // End Of EFI_DEBUG diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.h b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.h new file mode 100644 index 0000000..43f2ffe --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtAmHelper.h @@ -0,0 +1,119 @@ +/** @file + AT authetication module for using AT DXE driver. + This library is utilized by the AT and related drivers to implement Theft Deterrence Technology AM module. + +@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 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 _ATAM_HELPER_H_ +#define _ATAM_HELPER_H_ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#endif +#include "Tiano.h" + +#define PEM_LINE_SIZE 64 +#define PEM_INPUT_LINE_SIZE 48 +#define PEM_UNITS_PER_LINE (PEM_INPUT_LINE_SIZE / 3) +#define PEM_DECODED_LINE_SIZE 48 +#define PEM_INVALID_CHAR 255 +#define PEM_PAD_CHAR 64 + +/** + Convert Hex values into Base32 values + + @param[in] encodedStr Array of encoded BASE values. + @param[in] encodedLen Length of encoded values. + @param[out] rawData Array of Hex strings that needs to be encoded into BASE32. + @param[out] rawDataLen Length of Hex values. + + @retval EFI_BUFFER_TOO_SMALL Buffer to store encoded string too small. + @retval EFI_SUCCESS Initialization complete. +**/ +EFI_STATUS +Base32Encode ( + IN UINT8 *encodedStr, + IN UINTN *encodedLen, + OUT UINT8 *rawData, + OUT UINTN rawDataLen + ) +; + +/** + Convert Base32 values into Hex values. + + @param[in] encodedStr Array of Decimal numbers. + @param[out] decodedData Converted Hex values. + + @retval Length of the Hex Strings that expected. +**/ +INTN +Base32Decode ( + IN UINT8 *encodedStr, + IN UINT8 *decodedData + ) +; + +/** + Decimal large (BASE10) into hex value. + + @param[in][out] decStr Array of Decimal numbers. + @param[out] u8Hex Converted Hex values. + @param[in] hexIndex Length of the Hex Strings that expected + + @retval None +**/ +VOID +DecimalToHexString ( + IN OUT CHAR8 *decStr, + OUT UINT8 *u8Hex, + IN UINTN hexIndex + ) +; + +/** + Convert the CHAR8 ASCII into CHAR16 Unicode strings. + + @param[in] AsciiString Ascii String. + @param[out] UnicodeString Buffer for converted Unicode string. + + @retval None +**/ +VOID +Uint8ToUnicode ( + IN CHAR8 *AsciiString, + OUT CHAR16 *UnicodeString +) +; + +/** + This routine displays the debug message in ASCII + + @param[in] Message Message to be displayed + @param[in] Length Length of the message + + @retval None +**/ +VOID +ShowBuffer ( + IN UINT8 *Message, + IN UINT32 Length + ) +; + +#endif // _ATAM_HELPER_H_ diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.cif b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.cif new file mode 100644 index 0000000..f7268fd --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.cif @@ -0,0 +1,14 @@ +<component> + name = "AtDxeLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\AtLibrary\Dxe\" + RefName = "AtDxeLib" +[files] +"AtDxeLib.mak" +"AtDxeLib.sdl" +"AtAmHelper.c" +"AtDxeLib.inf" +"AtPolicyDebugDumpDxe.c" +"AtAmHelper.h" +"AtPolicyLib.h" +<endComponent> diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.inf b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.inf new file mode 100644 index 0000000..e99a072 --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.inf @@ -0,0 +1,69 @@ +## @file +# Component description file for AT functionality +# +#@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 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 = AtDxeLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + AtAmHelper.c + AtAmHelper.h + AtPolicyLib.h + AtPolicyDebugDumpDxe.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode + +# +# 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] + MeLib + MeProtocolLib + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueDxeReportStatusCodeLib + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.mak b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.mak new file mode 100644 index 0000000..67282e9 --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.mak @@ -0,0 +1,54 @@ +# /*++ +# 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:AtDxeLib +all : AtDxeLib + +$(BUILD_DIR)\AtDxeLib.lib : AtDxeLib + +AtDxeLib : $(BUILD_DIR)\AtDxeLib.mak AtDxeLibBin + +$(BUILD_DIR)\AtDxeLib.mak : $(AtDxeLib_DIR)\$(@B).cif $(AtDxeLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AtDxeLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +AtDxeLib_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES)\ + +AtDxeLib_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__\ + +AtDxeLib_LIBS=\ + $(MeProtocolLib_LIB)\ + $(MeLibDxe_LIB) + +AtDxeLibBin : $(AtDxeLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + /f $(BUILD_DIR)\AtDxeLib.mak all \ + "MY_INCLUDES=$(AtDxeLib_INCLUDES)" \ + "MY_DEFINES=$(AtDxeLib_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/AtLibrary/Dxe/AtDxeLib.sdl b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.sdl new file mode 100644 index 0000000..746b618 --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtDxeLib.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "AtDxeLib_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AtDxeLib support in Project" +End + +MODULE + Help = "Includes AtDxeLib.mak to Project" + File = "AtDxeLib.mak" +End + +PATH + Name = "AtDxeLib_DIR" + Help = "iAMT Library file source directory" +End + +ELINK + Name = "AtDxeLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\AtDxeLib.lib" + Parent = "AtDxeLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(AtDxeLib_DIR)" + Parent = "AT_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyDebugDumpDxe.c b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyDebugDumpDxe.c new file mode 100644 index 0000000..699ed1b --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyDebugDumpDxe.c @@ -0,0 +1,51 @@ +/** @file + Dump whole DXE_AT_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 +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AtPolicyLib.h" +#endif + +extern DXE_AT_POLICY_PROTOCOL *mDxePlatformAtPolicy; + +/** + Dump DXE AT Platform Policy + + @param[in] None. + + @retval None +**/ +VOID +DxeAtPolicyDebugDump ( + VOID + ) +{ + if (mDxePlatformAtPolicy == NULL) { + return; + } + DEBUG ((EFI_D_INFO, "\n------------------------ AtPlatformPolicy Dump Begin ------------------\n")); + DEBUG ((EFI_D_INFO, " Revision : 0x%x\n", mDxePlatformAtPolicy->Revision)); + DEBUG ((EFI_D_INFO, "At ---\n")); + DEBUG ((EFI_D_INFO, " AtConfig : 0x%x\n", mDxePlatformAtPolicy->At.AtAmBypass)); + DEBUG ((EFI_D_INFO, " AtEnterSuspendState : 0x%x\n", mDxePlatformAtPolicy->At.AtEnterSuspendState)); + DEBUG ((EFI_D_INFO, "\n------------------------ AtPlatformPolicy Dump End --------------------\n")); +} + diff --git a/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyLib.h b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyLib.h new file mode 100644 index 0000000..edde46a --- /dev/null +++ b/ReferenceCode/ME/Library/AtLibrary/Dxe/AtPolicyLib.h @@ -0,0 +1,39 @@ +/** @file + Header file for AT Policy functionality + +@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 +**/ +#ifndef _AT_POLICY_LIB_H_ +#define _AT_POLICY_LIB_H_ + +#include EFI_PROTOCOL_DEFINITION (AtPlatformPolicy) + +/** + Dump DXE AT Platform Policy + + @param[in] None. + + @retval None +**/ +VOID +DxeAtPolicyDebugDump ( + VOID + ) +; + +#endif 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 diff --git a/ReferenceCode/ME/Library/MeLibrary.cif b/ReferenceCode/ME/Library/MeLibrary.cif new file mode 100644 index 0000000..76bce81 --- /dev/null +++ b/ReferenceCode/ME/Library/MeLibrary.cif @@ -0,0 +1,22 @@ +<component> + name = "MeLibrary" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\" + RefName = "MeLibrary" +[files] +"MeLibrary.sdl" +"MeKernel\include\CoreBiosMsg.h" +"MeKernel\include\MkhiMsgs.h" +"MeKernel\include\MeAccess.h" +"MeKernel\include\MeChipset.h" +"MeKernel\include\MeChipsetLib.h" +"MeKernel\include\MeState.h" +"AMT\Include\Amt.h" +"PttHeci\Include\PttHeciLib.h" +[parts] +"MeKernelLibrary" +"AmtLibrary" +"AtLibrary" +"PttLibrary" +"PttHeciDxeLib" +<endComponent> diff --git a/ReferenceCode/ME/Library/MeLibrary.sdl b/ReferenceCode/ME/Library/MeLibrary.sdl new file mode 100644 index 0000000..6617dce --- /dev/null +++ b/ReferenceCode/ME/Library/MeLibrary.sdl @@ -0,0 +1,32 @@ +TOKEN + Name = "MeLibrary_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeLibrary support in Project" +End + +PATH + Name = "MeLibrary_DIR" + Help = "Me Library file source directory" +End + +ELINK + Name = "/I$(MeLibrary_DIR)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeLibrary_DIR)\PttHeci\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(INTEL_PCH_INCLUDES)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.c b/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.c new file mode 100644 index 0000000..38b33b5 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.c @@ -0,0 +1,606 @@ +/** @file + Implements Platform Trust Technology (FTPM) HCI Device Library. + +@copyright + Copyright (c) 2012 - 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 + +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#endif + +#ifdef PTT_FLAG +#include "PttHciRegs.h" +#include "PttHciDeviceLib.h" +#include <IndustryStandard/Tpm20.h> + + +#ifdef EFI_DEBUG +/** + Prints command or response buffer for debugging purposes. + + @param[in] Buffer Buffer to print. + @param[in] BufferSize Buffer data length. +**/ +VOID +EFIAPI +PttHciPrintBuffer(IN UINT8 *Buffer, IN UINT32 BufferSize) +{ + UINT32 Index; + + DEBUG ((EFI_D_INFO, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize)); + for(Index = 0; Index < BufferSize; Index++){ + DEBUG ((EFI_D_INFO, "%02x ", *(Buffer + Index))); + if((Index+1) % 16 == 0) DEBUG ((EFI_D_INFO, "\n")); + } + DEBUG ((EFI_D_INFO, "\n")); +} +#endif // EFI_DEBUG + + +VOID MicroSecDelay ( + UINTN Delay +) +{ + UINTN Counter, i; + UINT32 Data32, PrevData; + UINT32 Remainder; + + Counter = (UINTN)DivU64x32Remainder ((UINT64)(Delay * 10), 3, &Remainder); + if (Remainder != 0) { + Counter++; + } + // + // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick + // periods, thus attempting to ensure Microseconds of stall time. + // + if (Counter != 0) { + + PrevData = IoRead32(PM_BASE_ADDRESS + 8); + for (i = 0; i < Counter; ) { + Data32 = IoRead32(PM_BASE_ADDRESS + 8); + if (Data32 < PrevData) { // Reset if there is a overlap + PrevData=Data32; + continue; + } + i += (Data32 - PrevData); + PrevData = Data32; + } + } + return; +} + + +/** + Copy data from the MMIO region to system memory by using 32-bit access. + + Copy data from the MMIO region specified by starting address StartAddress + to system memory specified by Buffer by using 32-bit access. The total + number of byte to be copied is specified by Length. Buffer is returned. + + If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). + + If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + If Length is not aligned on a 32-bit boundary, then ASSERT(). + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + + @param StartAddress The starting address for the MMIO region to be copied from. + @param Length The size, in bytes, of Buffer. + @param Buffer The pointer to a system memory buffer receiving the data read. + + @return Buffer +**/ +UINT32 * +EFIAPI +MmioReadBuffer32 ( + IN UINTN StartAddress, + IN UINTN Length, + OUT UINT32 *Buffer + ) +{ + UINT32 *ReturnBuffer; + + ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); + + ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); + ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); + + ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); + ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); + + ReturnBuffer = Buffer; + + while (Length != 0) { + *(Buffer++) = MmioRead32 (StartAddress); + StartAddress += sizeof (UINT32); + Length -= sizeof (UINT32); + } + + return ReturnBuffer; +} + +/** + Copy data from system memory to the MMIO region by using 32-bit access. + + Copy data from system memory specified by Buffer to the MMIO region specified + by starting address StartAddress by using 32-bit access. The total number + of byte to be copied is specified by Length. Buffer is returned. + + If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). + + If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). + If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). + + If Length is not aligned on a 32-bit boundary, then ASSERT(). + + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + + @param StartAddress The starting address for the MMIO region to be copied to. + @param Length The size, in bytes, of Buffer. + @param Buffer The pointer to a system memory buffer containing the data to write. + + @return Buffer +**/ +UINT32 * +EFIAPI +MmioWriteBuffer32 ( + IN UINTN StartAddress, + IN UINTN Length, + IN CONST UINT32 *Buffer + ) +{ + UINT32 *ReturnBuffer; + + ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); + + ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); + ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); + + ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); + ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); + + ReturnBuffer = (UINT32 *) Buffer; + + while (Length != 0) { + MmioWrite32 (StartAddress, *(Buffer++)); + + StartAddress += sizeof (UINT32); + Length -= sizeof (UINT32); + } + + return ReturnBuffer; +} + +/** + Checks whether FTPM is enabled (FTPM_STS::FTPM_EN). + + @retval TRUE FTPM is enabled. + @retval FALSE FTPM is disabled. All LT writes will be dropped. + All LT reads will be returned with read data value of all 0's. + The bit can only be written once per ME power cycle. + +**/ +BOOLEAN +EFIAPI +PttHciPresenceCheck ( + VOID + ) +{ + EFI_STATUS Status; + DEBUG ((EFI_D_INFO, "PTT: PttHciPresenceCheck start\n")); + + DEBUG ((EFI_D_INFO, "Check FTPM_STS - ENABLED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS))); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS), + B_PTT_HCI_STS_ENABLED, + V_PTT_HCI_IGNORE_BITS, + PTT_HCI_TIMEOUT_A + ); + if(Status == EFI_SUCCESS){ + return TRUE; + } + + return FALSE; +} + +/** + Checks whether PTT is Ready + + @retval TRUE PTT is ready. + @retval FALSE PTT is not ready + +**/ +BOOLEAN +EFIAPI +PttHciReadyCheck ( + VOID + ) +{ + UINT32 RegRead; + + RegRead = MmioRead32 ((UINTN) ( R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS )); + DEBUG ((EFI_D_INFO, "Check PTT_STS - READY bit (@ 0x%08x)\n", RegRead)); + + if(( B_PTT_HCI_STS_READY & RegRead) != 0){ + return TRUE; + } + + return FALSE; +} + +/** + Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC). + If command was executed, it should not be redundantly issued again. + + @retval TRUE Startup command executed already. + @retval FALSE Startup command not executed yet. + +**/ +BOOLEAN +EFIAPI +PttHciStartupExecuted ( + VOID + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PTT: PttHciStartupExecuted start\n")); + DEBUG ((EFI_D_INFO, "Check FTPM_STS - STARTUP_EXECECUTED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS))); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS), + B_PTT_HCI_STS_STARTUP_EXEC, + V_PTT_HCI_IGNORE_BITS, + PTT_HCI_TIMEOUT_A + ); + if(Status == EFI_SUCCESS){ + return TRUE; + } + + return FALSE; +} + +/** + Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is + available for processing. + Any host write to this register shall result in an interrupt to the ME firmware. + + @retval EFI_SUCCESS Register successfully written. + @retval TBD + +**/ +EFI_STATUS +EFIAPI +PttHciRequestCommandExec ( + VOID + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + DEBUG ((EFI_D_INFO, "PTT: PttHciRequestCommandExec start\n")); + + DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CA_START register (@ 0x%08x)\n", + V_PTT_HCI_COMMAND_AVAILABLE_START, + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START))); + MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START, V_PTT_HCI_COMMAND_AVAILABLE_START); + + /// + /// Write 0x1 to HCI CMD register to indicate that a command is available for processing + /// + DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CMD register (@ 0x%08x)\n", + V_PTT_HCI_COMMAND_AVAILABLE_CMD, + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD))); + MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD, V_PTT_HCI_COMMAND_AVAILABLE_CMD); + + return Status; +} + +/** + Checks whether the value of a FTPM register satisfies the input BIT setting. + + @param[in] Register Address port of register to be checked. + @param[in] BitSet Check these data bits are set. + @param[in] BitClear Check these data bits are clear. + @param[in] TimeOut The max wait time (unit MicroSecond) when checking register. + + @retval EFI_SUCCESS The register satisfies the check bit. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciWaitRegisterBits( + IN EFI_PHYSICAL_ADDRESS RegAddress, + IN UINT32 BitSet, + IN UINT32 BitClear, + IN UINT32 TimeOut + ) +{ + UINT32 RegRead; + UINT32 WaitTime; + + DEBUG ((EFI_D_INFO, "PTT: PttHciWaitRegisterBits start\n")); + + for (WaitTime = 0; WaitTime < TimeOut; WaitTime += PTT_HCI_POLLING_PERIOD){ + RegRead = MmioRead32 ((UINTN)RegAddress); + DEBUG ((EFI_D_INFO, "RegRead: 0x%08x, BitSetMask: 0x%08x, BitClearMask: 0x%08x, WaitTime: %d (microsec)\n", RegRead, BitSet, BitClear, WaitTime)); + + if (RegRead == 0xFFFFFFFF) + continue; + + if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) { + return EFI_SUCCESS; + } +// MicroSecondDelay (PTT_HCI_POLLING_PERIOD); Override + MicroSecDelay(PTT_HCI_POLLING_PERIOD); + } + return EFI_TIMEOUT; +} + +/** + Sends command to FTPM for execution. + + @param[in] FtpmBuffer Buffer for TPM command data. + @param[in] DataLength TPM command data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciSend( + IN UINT8 *FtpmBuffer, + IN UINT32 DataLength + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PTT: PttHciSend start\n")); + + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_START_CLEAR, + PTT_HCI_TIMEOUT_A + ); + + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 command cannot be sent! EFI_ERROR = %r\n", Status)); + return EFI_NOT_READY; + } + /// + /// Align command size to dword before writing to FTPM_CRB + /// + if(DataLength % 4 != 0){ + DEBUG ((EFI_D_INFO, "Alignment: DataLength change from %d ", DataLength)); + DataLength += (4 - (DataLength % 4)); + DEBUG ((EFI_D_INFO, "to %d\n", DataLength)); + } + + MmioWriteBuffer32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB), (UINTN)DataLength, (UINT32*)FtpmBuffer); + + /// + /// FTPM_CA_CMD - the physical address to which the TPM 2.0 driver will write the command to execute + /// + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB); + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), S_PTT_HCI_CRB_LENGTH); + + DEBUG ((EFI_D_INFO, "FTPM_CA_CMD (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), + R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB)); + DEBUG ((EFI_D_INFO, "FTPM_CA_CMD_SZ (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), DataLength)); + + /// + /// Set FTPM_CMD and FTPM_CA_START registers to indicate TPM command ready for execution + /// + Status = PttHciRequestCommandExec(); +#ifdef EFI_DEBUG + if(Status == EFI_SUCCESS){ + DEBUG ((EFI_D_INFO, "FTPM_CMD register written - TPM2 command available for processing\n")); + } +#endif + + return Status; +} + +/** + Receives response data of last command from FTPM. + + @param[out] FtpmBuffer Buffer for response data. + @param[out] RespSize Response data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + @retval EFI_DEVICE_ERROR Unexpected device status. + @retval EFI_BUFFER_TOO_SMALL Response data is too long. +**/ +EFI_STATUS +EFIAPI +PttHciReceive( + OUT UINT8 *FtpmBuffer, + OUT UINT32 *RespSize + ) +{ + EFI_STATUS Status; + UINT16 Data16; + UINT32 Data32; + DEBUG ((EFI_D_INFO, "PTT: PttHciReceive start\n")); + + /// + /// Wait for the command completion - poll FTPM_CA_START clear + /// + DEBUG ((EFI_D_INFO, "PTT: Check Start status (FTPM_CA_START)\n")); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_START_CLEAR, + PTT_HCI_TIMEOUT_D + ); + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 response cannot be read! EFI_ERROR = %r\n", Status)); + goto Exit; + } + + /// + /// Check for error condition - FTPM_CA_ERROR + /// + DEBUG ((EFI_D_INFO, "PTT: Check Error status (FTPM_CA_ERROR)\n")); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_ERROR), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_ALL_BITS_CLEAR, + PTT_HCI_TIMEOUT_A + ); + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_ERROR register set - TPM2 response cannot be provided! EFI_ERROR = %r\n", Status)); + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + DEBUG ((EFI_D_INFO, "FTPM_CA_START register clear - TPM2 command processing completed - ready to read\n")); + + /// + /// Read the response data header + /// + MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, PTT_HCI_RESPONSE_HEADER_SIZE, (UINT32*)FtpmBuffer); + + /// + /// Check the reponse data header (tag, parasize and returncode) + /// + CopyMem (&Data16, FtpmBuffer, sizeof (UINT16)); + DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.tag = 0x%04x\n", SwapBytes16(Data16))); + + /// + /// TPM Rev 2.0 Part 2 - 6.9 TPM_ST (Structure Tags) + /// TPM_ST_RSP_COMMAND - Used in a response that has an error in the tag. + /// + if (SwapBytes16(Data16) == TPM_ST_RSP_COMMAND) { + DEBUG ((EFI_D_ERROR, "TPM2_RESPONSE_HEADER.tag = TPM_ST_RSP_COMMAND - Error in response!\n")); + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + CopyMem(&Data32, (FtpmBuffer + 2), sizeof(UINT32)); + DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.paramSize = 0x%08x\n", SwapBytes32(Data32))); + + *RespSize = SwapBytes32(Data32); + + if(*RespSize == sizeof(TPM2_RESPONSE_HEADER)) { + Status = EFI_SUCCESS; + goto Exit; + } + if(*RespSize < sizeof(TPM2_RESPONSE_HEADER)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + if(*RespSize > S_PTT_HCI_CRB_LENGTH) { + Status = EFI_BUFFER_TOO_SMALL; + goto Exit; + } + + /// + /// Align command size to dword before writing to FTPM_CRB + /// + if(*RespSize % 4 != 0){ + DEBUG ((EFI_D_INFO, "Alignment: RespSize change from %d ", *RespSize)); + *RespSize += (4 - (*RespSize % 4)); + DEBUG ((EFI_D_INFO, "to %d\n", *RespSize)); + } + + /// + /// Reading the entire response data + /// + MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, *RespSize, (UINT32*)FtpmBuffer); + + Exit: + if(!EFI_ERROR(Status)){ + /// + /// FTPM_CA_CMD - the physical address from which the TPM 2.0 driver will read command responses + /// + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB); + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ),S_PTT_HCI_CRB_LENGTH); + DEBUG ((EFI_D_INFO, "FTPM_CA_RSP (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB))); + DEBUG ((EFI_D_INFO, "FTPM_CA_RSP_SZ (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ), *RespSize)); + } + + return Status; +} + +/** + Sends formatted command to FTPM for execution and returns formatted response data. + + @param[in] InputBuffer Buffer for the input data. + @param[in] InputBufferSize Size of the input buffer. + @param[out] ReturnBuffer Buffer for the output data. + @param[out] ReturnBufferSize Size of the output buffer. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciSubmitCommand( + IN UINT8 *InputBuffer, + IN UINT32 InputBufferSize, + OUT UINT8 *ReturnBuffer, + OUT UINT32 *ReturnBufferSize + ) +{ + EFI_STATUS Status; + DEBUG ((EFI_D_INFO, "PTT: PttHciSubmitCommand start\n")); + + if(!PttHciReadyCheck()){ + DEBUG ((EFI_D_ERROR, "PTT device not ready. \n")); + return EFI_NOT_READY; + } + + if(InputBuffer == NULL || ReturnBuffer == NULL || InputBufferSize == 0){ + DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputBufferSize == 0\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((EFI_D_INFO, "PTT: Command Buffer dump\n")); + + /// + /// Send the command to TPM + /// + Status = PttHciSend(InputBuffer, InputBufferSize); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FTpmHciSend EFI_ERROR = %r\n", Status)); + return Status; + } + + /// + /// Receive the response data from TPM + /// + Status = PttHciReceive(ReturnBuffer, ReturnBufferSize); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FTpmHciReceive EFI_ERROR = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_INFO, "PTT: Response Buffer dump\n")); + + return Status; +} + +#endif // PTT_FLAG diff --git a/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.cif b/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.cif new file mode 100644 index 0000000..56a7865 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Common/PttHciDeviceLib.cif @@ -0,0 +1,8 @@ +<component> + name = "PTT Common Library" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Library\Ptt\Common\" + RefName = "PttHciDeviceLib" +[files] +"PttHciDeviceLib.c" +<endComponent> diff --git a/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.cif b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.cif new file mode 100644 index 0000000..341920f --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.cif @@ -0,0 +1,9 @@ +<component> + name = "PTT Dxe Library" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\Ptt\Dxe\" + RefName = "PttHciDeviceDxeLib" +[files] +"PttHciDeviceDxeLib.inf" +"PttHciDeviceDxeLib.h" +<endComponent> diff --git a/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.h b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.h new file mode 100644 index 0000000..c8a042f --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.h @@ -0,0 +1,37 @@ +/** @file + Platform Trust Technology (FTPM) HCI Device Dxe Library + +@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 +**/ +#ifndef _PTT_HCI_DEVICE_DXE_LIB_H_ +#define _PTT_HCI_DEVICE_DXE_LIB_H_ + +#ifdef PTT_FLAG +/// +/// 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" +#endif +/// +/// Common header for HCI Library +/// +#include "PttHciDeviceLib.h" +#endif // PTT_FLAG +#endif diff --git a/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.inf b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.inf new file mode 100644 index 0000000..7bc28ad --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Dxe/PttHciDeviceDxeLib.inf @@ -0,0 +1,73 @@ +## @file +# Component description file for PttHciDevice DXE Library. +# +#@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 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 = PttHciDeviceDxeLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + PttHciDeviceDxeLib.h + ../Common/PttHciDeviceLib.c + ../Include/PttHciRegs.h + ../Include/PttHciDeviceLib.h + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/Ptt/Include +# +# Path to Tpm20.h should be updated when available in the code tree (core) +# $(EFI_SOURCE)/SecurityPkg/Include/IndustryStandard + +# +# 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 + +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode/Include + +[libraries.common] + EdkIIGlueBaseLib + EdkIIGlueUefiLib + EdkIIGlueBaseMemoryLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueBaseTimerLibLocalApic + EdkIIGlueDxeDebugLibReportStatusCode + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D PTT_FLAG diff --git a/ReferenceCode/ME/Library/Ptt/Include/PttHciDeviceLib.h b/ReferenceCode/ME/Library/Ptt/Include/PttHciDeviceLib.h new file mode 100644 index 0000000..e6e92de --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Include/PttHciDeviceLib.h @@ -0,0 +1,175 @@ +/** @file + Platform Trust Technology (FTPM) HCI Device Library + +@copyright + Copyright (c) 2012 -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 _PTT_HCI_DEVICE_LIB_H_ +#define _PTT_HCI_DEVICE_LIB_H_ + +#ifdef PTT_FLAG + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#endif + +/// +/// Default Timeout values +/// @todo these values should be adjusted on actual silicon after power-on +/// +#define PTT_HCI_TIMEOUT_A 500 ///< 500 microseconds +// AMI-Core Override for PTT + +//#define PTT_HCI_TIMEOUT_B 10 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms) +#define PTT_HCI_TIMEOUT_B 500 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms) +// AMI-Core Override for PTT - +#define PTT_HCI_TIMEOUT_C 1000 * 1000 ///< 1s +#define PTT_HCI_TIMEOUT_D 500 * 1000 ///< 500 ms +#define PTT_HCI_POLLING_PERIOD 140 ///< Poll register every 140 microsecondss + +/// TPM2_RESPONSE_HEADER size (10B) aligned to dword +#define PTT_HCI_RESPONSE_HEADER_SIZE 12 ///< 12B + +/** + Checks whether FTPM is enabled (FTPM_STS::FTPM_EN). + + @retval TRUE FTPM is enabled. + @retval FALSE FTPM is disabled. All LT writes will be dropped. + All LT reads will be returned with read data value of all 0's. + The bit can only be written once per ME power cycle. +**/ +BOOLEAN +EFIAPI +PttHciPresenceCheck ( + VOID + ); + +/** + Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC). + If command was executed, it should not be redundantly issued again. + + @retval TRUE Startup command executed already. + @retval FALSE Startup command not executed yet. +**/ +BOOLEAN +EFIAPI +PttHciStartupExecuted ( + VOID + ); + +/** + Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is + available for processing. + Any host write to this register shall result in an interrupt to the ME firmware. + + @retval EFI_SUCCESS Register successfully written. + @retval TBD +**/ +EFI_STATUS +EFIAPI +PttHciRequestCommandExec ( + VOID + ); + +/** + Checks whether the value of a FTPM register satisfies the input BIT setting. + + @param[in] Register Address port of register to be checked. + @param[in] BitSet Check these data bits are set. + @param[in] BitClear Check these data bits are clear. + @param[in] TimeOut The max wait time (unit MicroSecond) when checking register. + + @retval EFI_SUCCESS The register satisfies the check bit. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciWaitRegisterBits( + IN EFI_PHYSICAL_ADDRESS RegAddress, + IN UINT32 BitSet, + IN UINT32 BitClear, + IN UINT32 TimeOut + ); + +/** + Sends command to FTPM for execution. + + @param[in] FtpmBuffer Buffer for TPM command data. + @param[in] DataLength TPM command data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciSend( + IN UINT8 *FtpmBuffer, + IN UINT32 DataLength + ); + +/** + Receives response data of last command from FTPM. + + @param[out] FtpmBuffer Buffer for response data. + @param[out] RespSize Response data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + @retval EFI_DEVICE_ERROR Unexpected device status. + @retval EFI_BUFFER_TOO_SMALL Response data is too long. +**/ +EFI_STATUS +EFIAPI +PttHciReceive( + OUT UINT8 *FtpmBuffer, + OUT UINT32 *RespSize + ); + +/** + Sends formatted command to FTPM for execution and returns formatted response data. + + @param[in] InputBuffer Buffer for the input data. + @param[in] InputBufferSize Size of the input buffer. + @param[out] ReturnBuffer Buffer for the output data. + @param[out] ReturnBufferSize Size of the output buffer. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. +**/ +EFI_STATUS +EFIAPI +PttHciSubmitCommand( + IN UINT8 *InputBuffer, + IN UINT32 InputBufferSize, + OUT UINT8 *ReturnBuffer, + OUT UINT32 *ReturnBufferSize + ); + +/** + Checks whether PTT is Ready + + @retval TRUE PTT is ready. + @retval FALSE PTT is not ready + +**/ +BOOLEAN +EFIAPI +PttHciReadyCheck ( + VOID + ); + +#endif // PTT_FLAG +#endif diff --git a/ReferenceCode/ME/Library/Ptt/Include/PttHciRegs.h b/ReferenceCode/ME/Library/Ptt/Include/PttHciRegs.h new file mode 100644 index 0000000..cba0c8a --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Include/PttHciRegs.h @@ -0,0 +1,100 @@ +/** @file + Register definitions for PTT HCI (Platform Trust Technology - Host Controller Interface). + + Conventions: + + - Prefixes: + Definitions beginning with "R_" are registers + Definitions beginning with "B_" are bits within registers + Definitions beginning with "V_" are meaningful values of bits within the registers + Definitions beginning with "S_" are register sizes + Definitions beginning with "N_" are the bit position + +@copyright + 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 +**/ +#ifndef _PTT_HCI_REGS_H_ +#define _PTT_HCI_REGS_H_ + +#ifdef PTT_FLAG + +/// +/// FTPM HCI register base address +/// +#define R_PTT_HCI_BASE_ADDRESS 0xFED70000 + +// +// FTPM HCI Control Area +// +#define R_PTT_HCI_CA_RSVD 0x00 +#define R_PTT_HCI_CA_ERROR 0x04 +#define R_PTT_HCI_CA_CANCEL 0x08 +#define R_PTT_HCI_CA_START 0x0C +#define R_PTT_HCI_CA_INT_RSVD 0x10 +#define R_PTT_HCI_CA_CMD_SZ 0x18 +#define R_PTT_HCI_CA_CMD 0x1C +#define R_PTT_HCI_CA_RSP_SZ 0x24 +#define R_PTT_HCI_CA_RSP 0x28 + +// +// FTPM HCI Private Area +// +#define R_PTT_HCI_CMD 0x40 +#define R_PTT_HCI_STS 0x44 + +/// +/// FTPM HCI Command and Response Buffer +/// +#define R_PTT_HCI_CRB 0x80 + +// +// R_PTT_HCI_STS Flags +// +#define B_PTT_HCI_STS_ENABLED 0x00000001 ///< BIT0 +#define B_PTT_HCI_STS_READY 0x00000002 ///< BIT1 +#define B_PTT_HCI_STS_ACM_AS_CRTM 0x00000004 ///< BIT2 +#define B_PTT_HCI_STS_STARTUP_EXEC 0x00000008 ///< BIT3 + +// +// Value written to R_PTT_HCI_CMD and CA_START +// to indicate that a command is available for processing +// +#define V_PTT_HCI_COMMAND_AVAILABLE_START 0x00000001 +#define V_PTT_HCI_COMMAND_AVAILABLE_CMD 0x00000000 +#define V_PTT_HCI_BUFFER_ADDRESS_RDY 0x00000003 + +/// +/// Ignore bit setting mask for WaitRegisterBits +/// +#define V_PTT_HCI_IGNORE_BITS 0x00000000 + +/// +/// All bits clear mask for WaitRegisterBits +/// +#define V_PTT_HCI_ALL_BITS_CLEAR 0xFFFFFFFF +#define V_PTT_HCI_START_CLEAR 0x00000001 + +/// +/// Max FTPM command/reponse buffer length +/// +#define S_PTT_HCI_CRB_LENGTH 3968 ///< 0xFED70080:0xFED70FFF = 3968 Bytes +// AMI-Core Override for PTT + +#define PM_BASE_ADDRESS 0x1800 +// AMI-Core Override for PTT - + +#endif // PTT_FLAG +#endif diff --git a/ReferenceCode/ME/Library/Ptt/Include/PttLibInc.cif b/ReferenceCode/ME/Library/Ptt/Include/PttLibInc.cif new file mode 100644 index 0000000..a444f07 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Include/PttLibInc.cif @@ -0,0 +1,9 @@ +<component> + name = "PttLibrary Include" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\Ptt\Include" + RefName = "PttLibInc" +[files] +"PttHciDeviceLib.h" +"PttHciRegs.h" +<endComponent> diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDeviceLib.c b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDeviceLib.c new file mode 100644 index 0000000..107a3ca --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDeviceLib.c @@ -0,0 +1,590 @@ +/** + 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 +**/ +/** + +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. + + @file + PttHciDeviceLib.c + + @brief + Implements Platform Trust Technology (FTPM) HCI Device Library. + +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#endif + +#ifdef PTT_FLAG +#include "PttHciRegs.h" +#include "PttHciDeviceLib.h" +#include <IndustryStandard/Tpm20.h> + +#ifdef EFI_DEBUG +/** + + Prints command or response buffer for debugging purposes. + + @param[in] Buffer Buffer to print. + @param[in] BufferSize Buffer data length. + +**/ +VOID +EFIAPI +PttHciPrintBuffer(IN UINT8 *Buffer, IN UINT32 BufferSize) +{ + UINT32 Index; + + DEBUG ((EFI_D_INFO, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize)); + for(Index = 0; Index < BufferSize; Index++){ + DEBUG ((EFI_D_INFO, "%02x ", *(Buffer + Index))); + if((Index+1) % 16 == 0) DEBUG ((EFI_D_INFO, "\n")); + } + DEBUG ((EFI_D_INFO, "\n")); +} +#endif // EFI_DEBUG + + + +VOID MicroSecDelay ( + UINTN Delay +) +{ + UINTN Counter, i; + UINT32 Data32, PrevData; + UINT32 Remainder; + + Counter = (UINTN)DivU64x32Remainder ((UINT64)(Delay * 10), 3, &Remainder); + if (Remainder != 0) { + Counter++; + } + // + // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick + // periods, thus attempting to ensure Microseconds of stall time. + // + if (Counter != 0) { + + PrevData = IoRead32(PM_BASE_ADDRESS + 8); + for (i = 0; i < Counter; ) { + Data32 = IoRead32(PM_BASE_ADDRESS + 8); + if (Data32 < PrevData) { // Reset if there is a overlap + PrevData=Data32; + continue; + } + i += (Data32 - PrevData); + PrevData = Data32; + } + } + return; +} + +/** + Copy data from the MMIO region to system memory by using 32-bit access. + + Copy data from the MMIO region specified by starting address StartAddress + to system memory specified by Buffer by using 32-bit access. The total + number of byte to be copied is specified by Length. Buffer is returned. + + If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). + + If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + If Length is not aligned on a 32-bit boundary, then ASSERT(). + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + + @param StartAddress The starting address for the MMIO region to be copied from. + @param Length The size, in bytes, of Buffer. + @param Buffer The pointer to a system memory buffer receiving the data read. + + @return Buffer + +**/ +UINT32 * +EFIAPI +MmioReadBuffer32 ( + IN UINTN StartAddress, + IN UINTN Length, + OUT UINT32 *Buffer + ) +{ + UINT32 *ReturnBuffer; + + ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); + + ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); + ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); + + ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); + ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); + + ReturnBuffer = Buffer; + + while (Length != 0) { + *(Buffer++) = MmioRead32 (StartAddress); + StartAddress += sizeof (UINT32); + Length -= sizeof (UINT32); + } + + return ReturnBuffer; +} + +/** + Copy data from system memory to the MMIO region by using 32-bit access. + + Copy data from system memory specified by Buffer to the MMIO region specified + by starting address StartAddress by using 32-bit access. The total number + of byte to be copied is specified by Length. Buffer is returned. + + If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). + + If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). + If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). + + If Length is not aligned on a 32-bit boundary, then ASSERT(). + + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + + @param StartAddress The starting address for the MMIO region to be copied to. + @param Length The size, in bytes, of Buffer. + @param Buffer The pointer to a system memory buffer containing the data to write. + + @return Buffer + +**/ +UINT32 * +EFIAPI +MmioWriteBuffer32 ( + IN UINTN StartAddress, + IN UINTN Length, + IN CONST UINT32 *Buffer + ) +{ + UINT32 *ReturnBuffer; + + ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); + + ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); + ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); + + ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); + ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); + + ReturnBuffer = (UINT32 *) Buffer; + + while (Length != 0) { + MmioWrite32 (StartAddress, *(Buffer++)); + + StartAddress += sizeof (UINT32); + Length -= sizeof (UINT32); + } + + return ReturnBuffer; +} + +/** + + Checks whether FTPM is enabled (FTPM_STS::FTPM_EN). + + @retval TRUE FTPM is enabled. + @retval FALSE FTPM is disabled. All LT writes will be dropped. + All LT reads will be returned with read data value of all 0’s. + The bit can only be written once per ME power cycle. + +**/ +BOOLEAN +EFIAPI +PttHciPresenceCheck() +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PTT: PttHciPresenceCheck start\n")); + DEBUG ((EFI_D_INFO, "Check FTPM_STS - ENABLED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS))); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS), + B_PTT_HCI_STS_ENABLED, + V_PTT_HCI_IGNORE_BITS, + PTT_HCI_TIMEOUT_A + ); + if(Status == EFI_SUCCESS){ + return TRUE; + } + + return FALSE; +} + +/** + + Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC). + If command was executed, it should not be redundantly issued again. + + @retval TRUE Startup command executed already. + @retval FALSE Startup command not executed yet. + +**/ +BOOLEAN +EFIAPI +PttHciStartupExecuted() +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PTT: PttHciStartupExecuted start\n")); + DEBUG ((EFI_D_INFO, "Check FTPM_STS - STARTUP_EXECECUTED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS))); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS), + B_PTT_HCI_STS_STARTUP_EXEC, + V_PTT_HCI_IGNORE_BITS, + PTT_HCI_TIMEOUT_A + ); + if(Status == EFI_SUCCESS){ + return TRUE; + } + + return FALSE; +} + +/** + + Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is + available for processing. + Any host write to this register shall result in an interrupt to the ME firmware. + + @retval EFI_SUCCESS Register successfully written. + @retval TBD + +**/ +EFI_STATUS +EFIAPI +PttHciRequestCommandExec() +{ + EFI_STATUS Status = EFI_SUCCESS; + + DEBUG ((EFI_D_INFO, "PTT: PttHciRequestCommandExec start\n")); + + DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CA_START register (@ 0x%08x)\n", + V_PTT_HCI_COMMAND_AVAILABLE_START, + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START))); + MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START, V_PTT_HCI_COMMAND_AVAILABLE_START); + + /// + /// Write 0x1 to HCI CMD register to indicate that a command is available for processing + /// + DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CMD register (@ 0x%08x)\n", + V_PTT_HCI_COMMAND_AVAILABLE_CMD, + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD))); + MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD, V_PTT_HCI_COMMAND_AVAILABLE_CMD); + + return Status; +} + +/** + + Checks whether the value of a FTPM register satisfies the input BIT setting. + + @param[in] Register Address port of register to be checked. + @param[in] BitSet Check these data bits are set. + @param[in] BitClear Check these data bits are clear. + @param[in] TimeOut The max wait time (unit MicroSecond) when checking register. + + @retval EFI_SUCCESS The register satisfies the check bit. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + +**/ +EFI_STATUS +EFIAPI +PttHciWaitRegisterBits( + IN EFI_PHYSICAL_ADDRESS RegAddress, + IN UINT32 BitSet, + IN UINT32 BitClear, + IN UINT32 TimeOut + ) +{ + UINT32 RegRead; + UINT32 WaitTime; + + DEBUG ((EFI_D_INFO, "PTT: PttHciWaitRegisterBits start\n")); + + for (WaitTime = 0; WaitTime < TimeOut; WaitTime += PTT_HCI_POLLING_PERIOD){ + RegRead = MmioRead32 ((UINTN)RegAddress); + DEBUG ((EFI_D_INFO, "RegRead: 0x%08x, BitSetMask: 0x%08x, BitClearMask: 0x%08x, WaitTime: %d (microsec)\n", RegRead, BitSet, BitClear, WaitTime)); + + if (RegRead == 0xFFFFFFFF) + continue; + + if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) { + return EFI_SUCCESS; + } + +// MicroSecondDelay (PTT_HCI_POLLING_PERIOD); + MicroSecDelay(PTT_HCI_POLLING_PERIOD); + } + return EFI_TIMEOUT; +} + +/** + + Sends command to FTPM for execution. + + @param[in] FtpmBuffer Buffer for TPM command data. + @param[in] DataLength TPM command data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + +**/ +EFI_STATUS +EFIAPI +PttHciSend( + IN UINT8 *FtpmBuffer, + IN UINT32 DataLength + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PTT: PttHciSend start\n")); + + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_START_CLEAR, + PTT_HCI_TIMEOUT_A + ); + + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 command cannot be sent! EFI_ERROR = %r\n", Status)); + return EFI_NOT_READY; + } + /// + /// Align command size to dword before writing to FTPM_CRB + /// + if(DataLength % 4 != 0){ + DEBUG ((EFI_D_INFO, "Alignment: DataLength change from %d ", DataLength)); + DataLength += (4 - (DataLength % 4)); + DEBUG ((EFI_D_INFO, "to %d\n", DataLength)); + } + + MmioWriteBuffer32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB), (UINTN)DataLength, (UINT32*)FtpmBuffer); + + /// + /// FTPM_CA_CMD - the physical address to which the TPM 2.0 driver will write the command to execute + /// + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB); + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), S_PTT_HCI_CRB_LENGTH); + + DEBUG ((EFI_D_INFO, "FTPM_CA_CMD (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), + R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB)); + DEBUG ((EFI_D_INFO, "FTPM_CA_CMD_SZ (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), DataLength)); + + /// + /// Set FTPM_CMD and FTPM_CA_START registers to indicate TPM command ready for execution + /// + Status = PttHciRequestCommandExec(); +#ifdef EFI_DEBUG + if(Status == EFI_SUCCESS){ + DEBUG ((EFI_D_INFO, "FTPM_CMD register written - TPM2 command available for processing\n")); + } +#endif + + return Status; +} + +/** + + Receives response data of last command from FTPM. + + @param[out] FtpmBuffer Buffer for response data. + @param[out] RespSize Response data length. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + @retval EFI_DEVICE_ERROR Unexpected device status. + @retval EFI_BUFFER_TOO_SMALL Response data is too long. + +**/ +EFI_STATUS +EFIAPI +PttHciReceive( + OUT UINT8 *FtpmBuffer, + OUT UINT32 *RespSize + ) +{ + EFI_STATUS Status; + UINT16 Data16; + UINT32 Data32; + DEBUG ((EFI_D_INFO, "PTT: PttHciReceive start\n")); + + /// + /// Wait for the command completion - poll FTPM_CA_START clear + /// + DEBUG ((EFI_D_INFO, "PTT: Check Start status (FTPM_CA_START)\n")); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_START_CLEAR, + PTT_HCI_TIMEOUT_B + ); + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 response cannot be read! EFI_ERROR = %r\n", Status)); + goto Exit; + } + + /// + /// Check for error condition - FTPM_CA_ERROR + /// + DEBUG ((EFI_D_INFO, "PTT: Check Error status (FTPM_CA_ERROR)\n")); + Status = PttHciWaitRegisterBits( + (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_ERROR), + V_PTT_HCI_IGNORE_BITS, + V_PTT_HCI_ALL_BITS_CLEAR, + PTT_HCI_TIMEOUT_A + ); + if(EFI_ERROR (Status)){ + DEBUG ((EFI_D_ERROR, "FTPM_CA_ERROR register set - TPM2 response cannot be provided! EFI_ERROR = %r\n", Status)); + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + DEBUG ((EFI_D_INFO, "FTPM_CA_START register clear - TPM2 command processing completed - ready to read\n")); + + /// + /// Read the response data header + /// + MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, PTT_HCI_RESPONSE_HEADER_SIZE, (UINT32*)FtpmBuffer); + + /// + /// Check the reponse data header (tag, parasize and returncode) + /// + CopyMem (&Data16, FtpmBuffer, sizeof (UINT16)); + DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.tag = 0x%04x\n", SwapBytes16(Data16))); + + /// + /// TPM Rev 2.0 Part 2 - 6.9 TPM_ST (Structure Tags) + /// TPM_ST_RSP_COMMAND - Used in a response that has an error in the tag. + /// + if (SwapBytes16(Data16) == TPM_ST_RSP_COMMAND) { + DEBUG ((EFI_D_ERROR, "TPM2_RESPONSE_HEADER.tag = TPM_ST_RSP_COMMAND - Error in response!\n")); + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + CopyMem(&Data32, (FtpmBuffer + 2), sizeof(UINT32)); + DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.paramSize = 0x%08x\n", SwapBytes32(Data32))); + + *RespSize = SwapBytes32(Data32); + + if(*RespSize == sizeof(TPM2_RESPONSE_HEADER)) { + Status = EFI_SUCCESS; + goto Exit; + } + if(*RespSize < sizeof(TPM2_RESPONSE_HEADER)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + if(*RespSize > S_PTT_HCI_CRB_LENGTH) { + Status = EFI_BUFFER_TOO_SMALL; + goto Exit; + } + + /// + /// Align command size to dword before writing to FTPM_CRB + /// + if(*RespSize % 4 != 0){ + DEBUG ((EFI_D_INFO, "Alignment: RespSize change from %d ", *RespSize)); + *RespSize += (4 - (*RespSize % 4)); + DEBUG ((EFI_D_INFO, "to %d\n", *RespSize)); + } + + /// + /// Reading the entire response data + /// + MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, *RespSize, (UINT32*)FtpmBuffer); + + Exit: + if(!EFI_ERROR(Status)){ + /// + /// FTPM_CA_CMD - the physical address from which the TPM 2.0 driver will read command responses + /// + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB); + MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ),S_PTT_HCI_CRB_LENGTH); + DEBUG ((EFI_D_INFO, "FTPM_CA_RSP (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB))); + DEBUG ((EFI_D_INFO, "FTPM_CA_RSP_SZ (@ 0x%08x) written, value = 0x%08x\n", + (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ), *RespSize)); + } + + return Status; +} + +/** + + Sends formatted command to FTPM for execution and returns formatted response data. + + @param[in] InputBuffer Buffer for the input data. + @param[in] InputBufferSize Size of the input buffer. + @param[out] ReturnBuffer Buffer for the output data. + @param[out] ReturnBufferSize Size of the output buffer. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected status in time. + +**/ +EFI_STATUS +EFIAPI +PttHciSubmitCommand( + IN UINT8 *InputBuffer, + IN UINT32 InputBufferSize, + OUT UINT8 *ReturnBuffer, + OUT UINT32 *ReturnBufferSize + ) +{ + EFI_STATUS Status; + DEBUG ((EFI_D_INFO, "PTT: PttHciSubmitCommand start\n")); + + if(InputBuffer == NULL || ReturnBuffer == NULL || InputBufferSize == 0){ + DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputBufferSize == 0\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((EFI_D_INFO, "PTT: Command Buffer dump\n")); + + /// + /// Send the command to TPM + /// + Status = PttHciSend(InputBuffer, InputBufferSize); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FTpmHciSend EFI_ERROR = %r\n", Status)); + return Status; + } + + /// + /// Receive the response data from TPM + /// + Status = PttHciReceive(ReturnBuffer, ReturnBufferSize); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "FTpmHciReceive EFI_ERROR = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_INFO, "PTT: Response Buffer dump\n")); + + return Status; +} + +#endif // PTT_FLAG
\ No newline at end of file diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.cif b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.cif new file mode 100644 index 0000000..c0c66b4 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.cif @@ -0,0 +1,12 @@ +<component> + name = "PTT Pei Library" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\Ptt\Pei\" + RefName = "PttHciDevicePeiLib" +[files] +"PttHciDevicePeiLib.inf" +"PttHciDeviceLib.c" +"PttHciDevicePeiLib.h" +"PttHciDevicePeiLib.sdl" +"PttHciDevicePeiLib.mak" +<endComponent> diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.h b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.h new file mode 100644 index 0000000..2decd76 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.h @@ -0,0 +1,37 @@ +/** @file + Platform Trust Technology (FTPM) HCI Device Pei Library + +@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 +**/ +#ifndef _PTT_HCI_DEVICE_PEI_LIB_H_ +#define _PTT_HCI_DEVICE_PEI_LIB_H_ + +#ifdef PTT_FLAG +/// +/// 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" +#endif +/// +/// Common header for HCI Library +/// +#include "PttHciDeviceLib.h" +#endif // PTT_FLAG +#endif diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.inf b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.inf new file mode 100644 index 0000000..faac249 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.inf @@ -0,0 +1,71 @@ +## @file +# Component description file for PttHciDevice PEI Library. +# +#@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 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 = PttHciDevicePeiLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + PttHciDevicePeiLib.h + ../Common/PttHciDeviceLib.c + ../Include/PttHciRegs.h + ../Include/PttHciDeviceLib.h + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/Ptt/Include +# Path to Tpm20.h should be updated when available in the code tree (core) +# $(EFI_SOURCE)/SecurityPkg/Include/IndustryStandard + +# +# 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 + +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode/Include + +[libraries.common] + EdkIIGlueBaseLib + EdkIIGlueBaseMemoryLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueBaseTimerLibLocalApic + EdkIIGluePeiDebugLibReportStatusCode + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D PTT_FLAG + diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.mak b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.mak new file mode 100644 index 0000000..d791a33 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.mak @@ -0,0 +1,80 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* +#********************************************************************** +# +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/MeLibrary/PTT/PTT Pei Library/PttHciDevicePeiLib.mak 1 12/18/12 5:48a Klzhan $ +# +# $Revision: 1 $ +# +# $Date: 12/18/12 5:48a $ +# +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/MeLibrary/PTT/PTT Pei Library/PttHciDevicePeiLib.mak $ +# +# 1 12/18/12 5:48a Klzhan +# [TAG] EIPNone +# [Category] Improvement +# [Description] AMI modify for TPM2.0 +# +#********************************************************************** +# +#<AMI_FHDR_START> +#---------------------------------------------------------------------------- +# +# Name: +# +# Description: +# +#---------------------------------------------------------------------------- +#<AMI_FHDR_END> +all : PttHciDevicePeiLib + +PttHciDevicePeiLib : $(BUILD_DIR)\PttHciDevicePeiLib.mak PttHciDevicePeiLibBin + +$(BUILD_DIR)\PttHciDevicePeiLib.mak : $(PttHciDevicePeiLib_DIR)\PttHciDevicePeiLib.cif $(PttHciDevicePeiLib_DIR)\PttHciDevicePeiLib.mak $(BUILD_RULES) + $(CIF2MAK) $(PttHciDevicePeiLib_DIR)\PttHciDevicePeiLib.cif $(CIF2MAK_DEFAULTS) + +PttHciDevicePeiLib_INCLUDES= \ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(EdkIIGlueInclude)\ + $(IndustryStandard_INCLUDES)\ + /IReferenceCode\ME\SampleCode\ + $(INTEL_PCH_INCLUDES)\ + + +PttHciDevicePeiLib_DEFINES = $(MY_DEFINES)\ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ \ +!IF "$(IntelPTT_SUPPORT)"=="1" + /D PTT_FLAG +!ENDIF + + +PttHciDevicePeiLib_LIB_LINKS =\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueBaseTimerLibLocalApic_LIB) + + +PttHciDevicePeiLibBin: $(PttHciDevicePeiLib_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PttHciDevicePeiLib.mak all\ + "MY_INCLUDES=$(PttHciDevicePeiLib_INCLUDES)"\ + "MY_DEFINES=$(PttHciDevicePeiLib_DEFINES)"\ + GUID=D58E4250-FDFF-4f6c-B972-9FCA453B3397\ + TYPE=PEI_LIBRARY diff --git a/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.sdl b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.sdl new file mode 100644 index 0000000..fc3f8cf --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/Pei/PttHciDevicePeiLib.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "PttHciDevicePeiLib_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PttHciDevicePeiLib support in Project" +End + +MODULE + Help = "Includes PttHciDevicePeiLib.mak to Project" + File = "PttHciDevicePeiLib.mak" +End + +PATH + Name = "PttHciDevicePeiLib_DIR" + Help = "" +End + +ELINK + Name = "PttHciDevicePeiLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PttHciDevicePeiLib.lib" + Parent = "PttHciDevicePeiLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(PttHciDevicePeiLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/Ptt/PttLibrary.cif b/ReferenceCode/ME/Library/Ptt/PttLibrary.cif new file mode 100644 index 0000000..f768f03 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/PttLibrary.cif @@ -0,0 +1,14 @@ +<component> + name = "PttLibrary" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\Ptt\" + RefName = "PttLibrary" +[files] +"PttLibrary.sdl" +"PttLibrary.mak" +[parts] +"PttHciDeviceLib" +"PttHciDeviceDxeLib" +"PttHciDevicePeiLib" +"PttLibInc" +<endComponent> diff --git a/ReferenceCode/ME/Library/Ptt/PttLibrary.mak b/ReferenceCode/ME/Library/Ptt/PttLibrary.mak new file mode 100644 index 0000000..0f65d78 --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/PttLibrary.mak @@ -0,0 +1,101 @@ +# /*++ +# 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:AtDxeLib +all : PttDxeLib PttPeiLib + + +$(BUILD_DIR)\PttDxeLibrary.lib : PttDxeLib + +PttDxeLib : $(BUILD_DIR)\PttLibrary.mak PttDxeLibBin + +PttDxeLib_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES) \ + -IReferenceCode\ME\SampleCode\Include\IndustryStandard\ + +PttDxeLib_DEFINES=\ + -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D TIANO_RELEASE_VERSION=0x00080006\ + -D PTT_FLAG + +$(BUILD_DIR)\PttLibrary.mak : $(MePttLibrary_DIR)\Common\PttHciDeviceLib.cif $(MePttLibrary_DIR)\PttLibrary.mak $(BUILD_RULES) + $(CIF2MAK) $(MePttLibrary_DIR)\Common\PttHciDeviceLib.cif $(CIF2MAK_DEFAULTS) + +PttDxeLib_LIBS=\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueBaseTimerLibLocalApic_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + +PttDxeLibBin : $(PttDxeLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + MAKEFILE=$(BUILD_DIR)\PttLibrary.mak \ + /f $(BUILD_DIR)\PttLibrary.mak all \ + "MY_INCLUDES=$(PttDxeLib_INCLUDES)" \ + "MY_DEFINES=$(PttDxeLib_DEFINES)"\ + LIBRARY_NAME=$(BUILD_DIR)\PttDxeLibrary.lib\ + TYPE=LIBRARY \ + +$(BUILD_DIR)\PttPeiLibrary.lib : PttPeiLib + +PttPeiLib : $(BUILD_DIR)\PttLibrary.mak PttPeiLibBin + +PttPeiLib_DEFINES=\ + -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D TIANO_RELEASE_VERSION=0x00080006\ + -D PTT_FLAG + +PttPeiLib_LIBS=\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueBaseTimerLibLocalApic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + +PttPeiLibBin : $(PttPeiLib_LIBS) +!IF "$(x64_BUILD)"=="1" + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ +!ELSE + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ +!ENDIF + MAKEFILE=$(BUILD_DIR)\PttLibrary.mak \ + /f $(BUILD_DIR)\PttLibrary.mak all \ + "MY_INCLUDES=$(PttDxeLib_INCLUDES)" \ + "MY_DEFINES=$(PttPeiLib_DEFINES)"\ + LIBRARY_NAME=$(BUILD_DIR)\PttPeiLibrary.lib\ + 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/Ptt/PttLibrary.sdl b/ReferenceCode/ME/Library/Ptt/PttLibrary.sdl new file mode 100644 index 0000000..3dd234e --- /dev/null +++ b/ReferenceCode/ME/Library/Ptt/PttLibrary.sdl @@ -0,0 +1,59 @@ +TOKEN + Name = "MePttLibrary_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 = "MePttLibrary_DIR" + Help = "Me Library file source directory" +End + +ELINK + Name = "/I$(MePttLibrary_DIR)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MePttLibrary_DIR)\Pei" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MePttLibrary_DIR)\Dxe" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +MODULE + Help = "Includes PttLibrary.mak to Project" + File = "PttLibrary.mak" +End + +ELINK + Name = "PttPei_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "PttDxe_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PttPeiLibrary.lib" + Parent = "PttPei_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\PttDxeLibrary.lib" + Parent = "PttDxe_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.c b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.c new file mode 100644 index 0000000..2e87dd6 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.c @@ -0,0 +1,145 @@ +/** @file + Implements Platform Trust Technology (FTPM) HECI SkuMgr Interface Library. + +@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 + +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#endif + +#ifdef PTT_FLAG +#include "PttHeciLib.h" +#include "HeciMsgLib.h" + +#define PTT_BITMASK 0x20000000 //BIT29 + +#define CLEAR_PTT_BIT 0x00000000 + +/** + Checks whether ME FW has the Platform Trust Technology capability. + + @param[out] PttCapability TRUE if PTT is supported, FALSE othewrwise. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciGetCapability( + OUT BOOLEAN *PttCapability + ) +{ + EFI_STATUS Status; + GEN_GET_FW_CAPSKU MsgGenGetFwCapsSku; + GEN_GET_FW_CAPS_SKU_ACK MsgGenGetFwCapsSkuAck; + + *PttCapability = FALSE; + + 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) + ) { + + if (MsgGenGetFwCapsSkuAck.Data.FWCapSku.Fields.PTT) { + *PttCapability = TRUE; + } + } + DEBUG ((EFI_D_INFO, "PTT SkuMgr: PttCapability = %d\n", *PttCapability)); + + return EFI_SUCCESS; +} + +/** + Checks Platform Trust Technology enablement state. + + @param[out] IsPttEnabledState TRUE if PTT is enabled, FALSE othewrwise. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciGetState( + OUT BOOLEAN *IsPttEnabledState + ) +{ + EFI_STATUS Status; + MEFWCAPS_SKU CurrentFeatures; + + *IsPttEnabledState = FALSE; + + Status = HeciGetFwFeatureStateMsg (&CurrentFeatures); + if (EFI_ERROR (Status)) { + return Status; + } + + if (CurrentFeatures.Fields.PTT) { + *IsPttEnabledState = TRUE; + } + + DEBUG ((EFI_D_INFO, "PTT SkuMgr: PttState = %d\n", *IsPttEnabledState)); + + return EFI_SUCCESS; +} + +/** + Changes current Platform Trust Technology state. + + @param[in] PttEnabledState TRUE to enable, FALSE to disable. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciSetState( + IN BOOLEAN PttEnabledState + ) +{ + EFI_STATUS Status; + UINT32 EnableBitmap; + UINT32 DisableBitmap; + + if (PttEnabledState) { + // + // Enable PTT + // + DEBUG ((EFI_D_INFO, "PTT SkuMgr: Enable PTT\n")); + EnableBitmap = PTT_BITMASK; + DisableBitmap = CLEAR_PTT_BIT; + } else { + // + // Disable PTT + // + DEBUG ((EFI_D_INFO, "PTT SkuMgr: Disable PTT\n")); + EnableBitmap = CLEAR_PTT_BIT; + DisableBitmap = PTT_BITMASK; + } + Status = HeciFwFeatureStateOverride (EnableBitmap, DisableBitmap); + + return Status; +} + +#endif // PTT_FLAG diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.cif b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.cif new file mode 100644 index 0000000..60dd251 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.cif @@ -0,0 +1,12 @@ +<component> + name = "PttHeciDxeLib" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Library\PttHeci\Dxe\" + RefName = "PttHeciDxeLib" +[files] +"PttHeciDxeLib.sdl" +"PttHeciDxeLib.mak" +"PttHeciDxeLib.c" +"PttHeciDxeLib.h" +"PttHeciDxeLib.inf" +<endComponent> diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.h b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.h new file mode 100644 index 0000000..6b370f4 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.h @@ -0,0 +1,37 @@ +/** @file + Platform Trust Technology (FTPM) HECI SkuMgr Dxe Library + +@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 +**/ +#ifndef _PTT_HECI_DXE_LIB_H_ +#define _PTT_HECI_DXE_LIB_H_ + +#ifdef PTT_FLAG +/// +/// 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" +#endif +/// +/// Common header for HECI Library +/// +#include "PttHeciLib.h" +#endif // PTT_FLAG +#endif diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.inf b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.inf new file mode 100644 index 0000000..da2f485 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.inf @@ -0,0 +1,68 @@ +## @file +# Component description file for PTT Heci DXE Library. +# +#@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 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 = PttHeciDxeLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + PttHeciDxeLib.h + PttHeciDxeLib.c + ../Include/PttHeciLib.h + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/PttHeci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + +# +# 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 + +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode/Include + +[libraries.common] + EdkIIGlueBaseLib + EdkIIGlueUefiLib + EdkIIGlueDxeDebugLibReportStatusCode + MeLib + +[nmake.common] + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D PTT_FLAG
\ No newline at end of file diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.mak b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.mak new file mode 100644 index 0000000..ed8afdd --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.mak @@ -0,0 +1,40 @@ +all : PttHeciDxeLib + +$(BUILD_DIR)\PttHeciDxeLib.lib : PttHeciDxeLib + +PttHeciDxeLib : $(BUILD_DIR)\PttHeciDxeLib.mak PttHeciDxeLibBin + +$(BUILD_DIR)\PttHeciDxeLib.mak : $(PttHeciDxeLib_DIR)\$(@B).cif $(PttHeciDxeLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PttHeciDxeLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PttHeciDxeLib_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES) \ + -I$(INTEL_COUGAR_POINT_DIR)\ + $(INTEL_PCH_INCLUDES) + +PttHeciDxeLib_DEFINES=$(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_UEFI_LIB__ \ + /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D PTT_FLAG + +PttHeciDxeLib_LIBS=\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(MeProtocolLib_LIB)\ + + +PttHeciDxeLibBin : $(PttHeciDxeLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \ + /f $(BUILD_DIR)\PttHeciDxeLib.mak all \ + "MY_INCLUDES=$(PttHeciDxeLib_INCLUDES)" \ + "MY_DEFINES=$(PttHeciDxeLib_DEFINES)"\ + TYPE=LIBRARY \ diff --git a/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.sdl b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.sdl new file mode 100644 index 0000000..8d6ba28 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Dxe/PttHeciDxeLib.sdl @@ -0,0 +1,36 @@ +TOKEN + Name = "PttHeciDxeLib_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PttHeciDxeLib support in Project" +End + +MODULE + Help = "Includes PttHeciDxeLib.mak to Project" + File = "PttHeciDxeLib.mak" +End + +PATH + Name = "PttHeciDxeLib_DIR" + Help = "Me Library file source directory" +End + +ELINK + Name = "PttHeciDxeLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PttHeciDxeLib.lib" + Parent = "PttHeciDxeLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(PttHeciDxeLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Library/PttHeci/Include/PttHeciLib.h b/ReferenceCode/ME/Library/PttHeci/Include/PttHeciLib.h new file mode 100644 index 0000000..4b74795 --- /dev/null +++ b/ReferenceCode/ME/Library/PttHeci/Include/PttHeciLib.h @@ -0,0 +1,73 @@ +/** @file + Platform Trust Technology (FTPM) HECI SkuMgr Library + +@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 +**/ +#ifndef _PTT_HECI_LIB_H_ +#define _PTT_HECI_LIB_H_ + +#ifdef PTT_FLAG + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#endif + +/** + Checks whether ME FW has the Platform Trust Technology capability. + + @param[out] PttCapability TRUE if PTT is supported, FALSE othewrwise. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciGetCapability( + OUT BOOLEAN *PttCapability + ); + +/** + Checks Platform Trust Technology enablement state. + + @param[out] IsPttEnabledState TRUE if PTT is enabled, FALSE othewrwise. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciGetState( + OUT BOOLEAN *IsPttEnabledState + ); + +/** + Changes current Platform Trust Technology state. + + @param[in] PttEnabledState TRUE to enable, FALSE to disable. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally +**/ +EFI_STATUS +EFIAPI +PttHeciSetState( + IN BOOLEAN PttEnabledState + ); + +#endif // PTT_FLAG +#endif |