diff options
Diffstat (limited to 'ReferenceCode/ME')
366 files changed, 58848 insertions, 0 deletions
diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.asl b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.asl new file mode 100644 index 0000000..3cd5a1a --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.asl @@ -0,0 +1,56 @@ +/*++ + 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 - 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. + +Module Name: + + MeSsdt.asl + +Abstract: + + Me SSDT Table ASL code + +--*/ + + +DefinitionBlock ( + "MeSsdt.aml", + "SSDT", + 0x01, + "MeSsdt", + "MeSsdt ", + 0x3000 + ) +{ + + OperationRegion(MENV,SystemMemory,0xFFFF0000,0xAA55) + Field(MENV,AnyAcc,Lock,Preserve) + { + MERV, 32, /// (000) ME NVS Protocol Revision + /// + /// PTT Solution + /// + PTTS, 8, /// (004) PTT Solution Method Selection + /// + /// PTT Allocated Buffer Address + /// + PTTB, 64, /// (005) PTT Allocated Buffer Address + + } +}
\ No newline at end of file diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.cif b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.cif new file mode 100644 index 0000000..4ae2bc5 --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.cif @@ -0,0 +1,12 @@ +<component> + name = "MeSsdt" + category = ModulePart + LocalRoot = "ReferenceCode\Me\AcpiTables\MeSsdt\" + RefName = "MeAcpiTableSsdt" +[files] +"MeSsdt.sdl" +"MeSsdt.mak" +"MeSsdt.inf" +"MeSsdt_Edk.inf" +"MeSsdt.asl" +<endComponent> diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.inf b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.inf new file mode 100644 index 0000000..6af6685 --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.inf @@ -0,0 +1,69 @@ +## @file +# Component description file for the ACPI tables +# +#@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 +# + + +[defines] +BASE_NAME = MeSsdt +FILE_GUID = 9A8F82D5-39B1-48DA-92DC-A22DA8834DF6 +COMPONENT_TYPE = ACPITABLE +FFS_EXT = .ffs + +[sources.common] + MeSsdt.ASL + +[libraries.common] + +[includes.common] + . + $(EFI_SOURCE) + $(EFI_SOURCE)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework +# +# 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/Include + +# +# Edk II Glue Library, some headers are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[nmake.common] diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.mak b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.mak new file mode 100644 index 0000000..b768a60 --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.mak @@ -0,0 +1,64 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: MeSsdt.mak +# +# Description: MAK file for the ModulePart:MeSsdt +# +# +#<AMI_FHDR_END> +#************************************************************************* +all : BuildMeSsdt + +BuildMeSsdt : $(BUILD_DIR)\MeSsdt.ffs + +#----------------------------------------------------------------------- +# ASL compiler definition +#----------------------------------------------------------------------- +!IF "$(ACPIPLATFORM_ASL_COMPILER)"=="" +!ERROR It is an invalid path, please check your ASL compiler path. +!ENDIF + +IASL = $(ACPIPLATFORM_ASL_COMPILER) +#----------------------------------------------------------------------- +$(BUILD_DIR)\MeSsdt.aml : $(INTEL_MESSDT_ASL_FILE) + $(CP) /FI$(BUILD_DIR)\tokenasl.h $(INTEL_MESSDT_ASL_FILE) > $(BUILD_DIR)\MeSsdt.asl + $(ASLEXPANDER) $(BUILD_DIR)\MeSsdt.asl $(BUILD_DIR)\MeSsdt_Temp.asl $(BUILD_DIR) + $(IASL) -p $(BUILD_DIR)\MeSsdt.aml $(BUILD_DIR)\MeSsdt_Temp.asl + + +$(BUILD_DIR)\MeSsdt.sec: $(BUILD_DIR)\MeSsdt.aml + $(GENSECTION) -I $*.aml -O $@ -S EFI_SECTION_RAW + +$(BUILD_DIR)\MeSsdt.ffs: $(BUILD_DIR)\MeSsdt.sec + $(GENFFSFILE) -B $(BUILD_DIR) -V -o $@ -P1 <<$(BUILD_DIR)\MeSsdt.pkg + +PACKAGE.INF +[.] +BASE_NAME = MeSsdt +FFS_FILEGUID = 9A8F82D5-39B1-48DA-92DC-A22DA8834DF6 +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress (dummy) { + $(PROJECT_DIR)\$(BUILD_DIR)\MeSsdt.sec + } +} +<<KEEP + diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.sdl b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.sdl new file mode 100644 index 0000000..d1974ef --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt.sdl @@ -0,0 +1,31 @@ +TOKEN + Name = "MeSsdt_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeSsdt support in Project" +End + +MODULE + Help = "Includes MeSsdt.mak to Project" + File = "MeSsdt.mak" +End + +PATH + Name = "MeSsdt_DIR" +End + +TOKEN + Name = "INTEL_MESSDT_ASL_FILE" + Value = "$(MeSsdt_DIR)\MeSsdt.asl" + TokenType = Expression + TargetMAK = Yes +End + +ELINK + Name = "$(BUILD_DIR)\MeSsdt.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt_Edk.inf b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt_Edk.inf new file mode 100644 index 0000000..464e98b --- /dev/null +++ b/ReferenceCode/ME/AcpiTables/MeSsdt/MeSsdt_Edk.inf @@ -0,0 +1,69 @@ +## @file +# Component description file for the ACPI tables (for EDK1117) +# +#@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 +# + + +[defines] +BASE_NAME = MeSsdt +FILE_GUID = 9a8f82d5-39b1-48da-92dc-a22da8834df6 +COMPONENT_TYPE = ME_SSDT_ACPITABLE +FFS_EXT = .ffs + +[sources.common] + MeSsdt.ASL + +[libraries.common] + +[includes.common] + . + $(EFI_SOURCE) + $(EFI_SOURCE)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework +# +# 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/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[nmake.common] diff --git a/ReferenceCode/ME/ActiveManagement/ActiveManagement.cif b/ReferenceCode/ME/ActiveManagement/ActiveManagement.cif new file mode 100644 index 0000000..9730d82 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/ActiveManagement.cif @@ -0,0 +1,14 @@ +<component> + name = "ActiveManagement" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\" + RefName = "ActiveManagement" +[files] +"ActiveManagement.sdl" +[parts] +"AmtBootOptions" +"AlertStandardFormat" +"IdeRController" +"PciSerial" +"StartWatchDog" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/ActiveManagement.sdl b/ReferenceCode/ME/ActiveManagement/ActiveManagement.sdl new file mode 100644 index 0000000..7f4c373 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/ActiveManagement.sdl @@ -0,0 +1,16 @@ +TOKEN + Name = "iAMT_SUPPORT" + Value = "1" + Help = "Main switch to enable iAMT support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Token = "iME_SUPPORT" "=" "1" +End + +PATH + Name = "AMT_DIR" + Help = "iAMT Driver files source directory" +End diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.cif b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.cif new file mode 100644 index 0000000..ad65d2c --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.cif @@ -0,0 +1,12 @@ +<component> + name = "AlertStandardFormat" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AlertStandardFormat\Heci\" + RefName = "AlertStandardFormat" +[files] +"AlertStandardFormat.sdl" +[parts] +"AlertStandardFormatCommon" +"AlertStandardFormatDxe" +"AlertStandardFormatPei" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.sdl b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.sdl new file mode 100644 index 0000000..d02eb68 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/AlertStandardFormat.sdl @@ -0,0 +1,19 @@ +TOKEN + Name = AlertStandardFormat_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AlertStandardFormat support in Project" +End + +PATH + Name = "AlertStandardFormat_SOURCE" + Help = "AlertStandardFormat Driver files source directory" +End + +ELINK + Name = "AlertStandardFormat_INCLUDES" + InvokeOrder = ReplaceParent +End diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.c b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.c new file mode 100644 index 0000000..7f5bf69 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.c @@ -0,0 +1,1561 @@ +/** @file + Processes ASF messages + +@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 +**/ +EFI_ASF_DATA_HUB_MAP mAsfProgressDataHubMap[] = { + { + EfiAsfMessageBiosPresent, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT + }, + { + EfiAsfMessageMemInit, + EFI_COMPUTING_UNIT_MEMORY | EFI_CU_HP_PC_RAM_INIT + }, + { + EfiAsfMessageMemInitDone, + EFI_COMPUTING_UNIT_MEMORY | EFI_CU_PC_INIT_END + }, + { + EfiAsfMessageCacheInit, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT + }, + { + EfiAsfMessageSmbusInit, + EFI_IO_BUS_SMBUS | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageOSWakeVector, + EFI_SOFTWARE_PEI_MODULE | EFI_SW_DXE_RT_PC_S3 + }, + { + EfiAsfMessageMotherBoardInit, + EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PC_INIT_BEGIN + }, + { + EfiAsfMessageBspInit, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT + }, +#ifndef ASF_PEI + { + EfiAsfMessageHddInit, + EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageApInit, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT + }, + { + EfiAsfMessageUserAuthentication, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_AUTHENTICATE_BEGIN + }, + { + EfiAsfMessageUserInitSetup, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP + }, + { + EfiAsfMessageUsbResourceConfig, + EFI_IO_BUS_USB | EFI_P_PC_ENABLE + }, + { + EfiAsfMessagePciResourceConfig, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM + }, + { + EfiAsfMessageOptionRomInit, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT + }, + { + EfiAsfMessageVideoInit, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageKbcInit, + EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageEmControllerInit, + EFI_PERIPHERAL_EMBEDDED_CONTROLLER | EFI_P_PC_INIT + }, + { + EfiAsfMessageDockAttached, + EFI_PERIPHERAL_DOCK | EFI_P_PC_INIT + }, + { + EfiAsfMessageEnableDock, + EFI_PERIPHERAL_DOCK | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageDockEject, + EFI_PERIPHERAL_DOCK | EFI_P_PC_RESET + }, + { + EfiAsfMessageDisableDock, + EFI_PERIPHERAL_DOCK | EFI_P_PC_DISABLE + }, + { + EfiAsfMessageFdcInit, + EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE + }, + { + EfiAsfMessageKeyboardTest, + EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST + }, + { + EfiAsfMessageMouseTest, + EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST + }, + { + EfiAsfMessageAmtBxDone, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_OPROM_DONE + }, + { + EfiAsfMessageBatteryPresenceDetected, + EFI_PERIPHERAL_BATTERY | EFI_P_PC_PRESENCE_DETECT + }, +#endif +}; + +EFI_ASF_DATA_HUB_MAP mAsfErrorDataHubMap[] = { + { + EfiAsfMessageNoMemory, + EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED + }, + { + EfiAsfMessageMemoryFailure, + EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL + }, + { + EfiAsfMessageBoardFailure, + EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_EC_NOT_CONFIGURED + }, + { + EfiAsfMessageFirmwareCorruption, + EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT + }, + { + EfiAsfMessageChassisIntrusion, + EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CHIPSET_PC_INTRUDER_DETECT + }, +#ifndef ASF_PEI + { + EfiAsfMessageHddFailure, + EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED + }, + { + EfiAsfMessageFdcFailure, + EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR + }, + { + EfiAsfMessageHdcFailure, + EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_CONTROLLER_ERROR + }, + { + EfiAsfMessageKbdFailure, + EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED + }, + { + EfiAsfMessageNoFdd, + EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_NOT_DETECTED + }, + { + EfiAsfMessageVideoControllerFailure, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR + }, + { + EfiAsfMessageNoVideo, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED + }, + { + EfiAsfMessageCpuVidMismatch, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_VID_MISMATCH + }, + { + EfiAsfMessageCpuSpeedMatchingFailure, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SPEED_MATCHING_FAILURE + }, + { + EfiAsfMessageNoBootMedia, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_NO_BOOT_MEDIA + }, + { + EfiAsfMessageUserAuthenticationInvalid, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_AUTHENTICATE_USER_INVALID + }, + { + EfiAsfMessageHddAuthenticationInvalid, + EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_AUTHENTICATE_HDD_INVALID, + }, + { + EfiAsfMessageTemperatureGenericCritical, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_EC_GENERIC_CRITICAL + }, + { + EfiAsfMessageTemperatureOverCritical, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_EC_OVER_CRITICAL + }, + { + EfiAsfMessageTemperatureUnderCritical, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_EC_UNDER_CRITICAL + }, + { + EfiAsfMessageVoltageGenericCritical, + EFI_PERIPHERAL_VOLTAGE | EFI_P_VOLTAGE_EC_GENERIC_CRITICAL + }, + { + EfiAsfMessageVoltageOverCritical, + EFI_PERIPHERAL_VOLTAGE | EFI_P_VOLTAGE_EC_OVER_CRITICAL + }, + { + EfiAsfMessageVoltageUnderCritical, + EFI_PERIPHERAL_VOLTAGE | EFI_P_VOLTAGE_EC_UNDER_CRITICAL + }, + { + EfiAsfMessageFanGenericCritical, + EFI_PERIPHERAL_FAN | EFI_P_FAN_EC_GENERIC_CRITICAL + }, + { + EfiAsfMessageFanPredictiveFailure, + EFI_PERIPHERAL_FAN | EFI_P_FAN_EC_PREDICTIVE_FAILURE + }, + { + EfiAsfMessageFanLowSpeedCritical, + EFI_PERIPHERAL_FAN | EFI_P_FAN_EC_LOW_SPEED_CRITICAL + }, + { + EfiAsfMessageBatteryLowCritical, + EFI_PERIPHERAL_BATTERY | EFI_P_BATTERY_EC_LOW_CRITICAL + }, + { + EfiAsfMessageTemperatureGenericWarning, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_PC_GENERIC_WARNING + }, + { + EfiAsfMessageTemperatureOverWarning, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_PC_OVER_WARNING + }, + { + EfiAsfMessageTemperatureUnderWarning, + EFI_PERIPHERAL_TEMPERATURE | EFI_P_TEMERATURE_PC_UNDER_WARNING + }, + { + EfiAsfMessageFanLowSpeedWarning, + EFI_PERIPHERAL_FAN | EFI_P_FAN_PC_LOW_SPEED_WARNING + }, + { + EfiAsfMessageBatteryLowWarning, + EFI_PERIPHERAL_BATTERY | EFI_P_BATTERY_PC_LOW_WARNING + }, + { + EfiAsfMessagePowerFailure, + EFI_PERIPHERAL_POWER_SUPPLY | EFI_P_BATTERY_PC_LOW_WARNING + }, + { + EfiAsfMessageAmtBxNotStarted, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_OPROM_NOT_STARTED + }, + { + EfiAsfMessageAmtBxSleepS4ReportedNotTaken, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_SLEEP_S4_NOT_TAKEN + }, + { + EfiAsfMessageAmtBxSleepS5ReportedNotTaken, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_SLEEP_S5_NOT_TAKEN + }, + { + EfiAsfMessageAmtBxSleepUnspecifiedReportedNotTaken, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_SLEEP_UNSPECD_NOT_TAKEN + }, + { + EfiAsfMessageAmtBxErrActionIntF, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_ERROR_ACTION_INTF + }, + { + EfiAsfMessageAmtBxErrActionInv, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_ERROR_ACTION_INV + }, + { + EfiAsfMessageAmtBxErrActionSetup, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_ERROR_ACTION_SETUP + }, + { + EfiAsfMessageAmtBxErrActionFailure, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_ERROR_ACTION_FAIL + }, + { + EfiAsfMessageAmtBxErrActionUnspecified, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_ERROR_ACTION_UNSPECD + }, + { + EfiAsfMessageAmtBxOtherUnspecified, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_AMTBX_OTHER_UNSPECD + }, +#endif +}; + +EFI_ASF_FRAMEWORK_MESSAGE mAsfFrameworkMessage[] = { + { + EfiAsfMessageBiosPresent, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_ENTITY_PRESENCE, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_BIOS, + 0, + 0x40, + EFI_ASF_FP_BOARD_INIT + } + }, + { + EfiAsfMessageMemInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_MEMORY, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_MEMORY_INIT + } + }, + { + EfiAsfMessageMemInitDone, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS | 0x80, // Exit + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_MEMORY, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_MEMORY_INIT + } + }, + { + EfiAsfMessageCacheInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_PROCESSOR, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_CACHE_INIT + } + }, + { + EfiAsfMessageSmbusInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_SMBUS_INIT + } + }, + { + EfiAsfMessageOSWakeVector, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_UNSPECIFIED, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_WAKE_OS + } + }, + { + EfiAsfMessageMotherBoardInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_BOARD_INIT + } + }, + // + // Error Event + // + { + EfiAsfMessageNoMemory, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_MEMORY, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_NO_MEMORY + } + }, + { + EfiAsfMessageMemoryFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_MEMORY, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_MEMORY_FAILURE + } + }, + { + EfiAsfMessageBoardFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_BOARD_FAILURE + } + }, + { + EfiAsfMessageFirmwareCorruption, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Insnce + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_ROM_CORRUPTED + } + }, + // + // Chassis Intrusion + // + { + EfiAsfMessageChassisIntrusion, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_CHASSIS_INTRUSION, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_CHASSIS_INTRUSION_GENERIC, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, +#ifndef ASF_PEI + // + // Progress Event + // + { + EfiAsfMessageHddInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_HDD_INIT + } + }, + { + EfiAsfMessageApInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_PROCESSOR, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_AP_INIT + } + }, + { + EfiAsfMessageUserAuthentication, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_USER_AUTHENTICATION + } + }, + { + EfiAsfMessageUserInitSetup, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_USER_SETUP + } + }, + { + EfiAsfMessageUsbResourceConfig, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_USB_RESOURCE_CONFIG + } + }, + { + EfiAsfMessagePciResourceConfig, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_PCI_RESOURCE_CONFIG + } + }, + { + EfiAsfMessageOptionRomInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_ADDIN_CARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_OPTION_ROM_INIT + } + }, + { + EfiAsfMessageVideoInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_VIDEO_INIT + } + }, + { + EfiAsfMessageKbcInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_KBC_INIT + } + }, + { + EfiAsfMessageEmControllerInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_EC_INIT + } + }, + { + EfiAsfMessageDockAttached, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_ATTACH_DOCK + } + }, + { + EfiAsfMessageEnableDock, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_ENABLE_DOCK + } + }, + { + EfiAsfMessageDockEject, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_EJECT_DOCK + } + }, + { + EfiAsfMessageDisableDock, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_DISABLE_DOCK + } + }, + { + EfiAsfMessageFdcInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_FDC_INIT + } + }, + { + EfiAsfMessageKeyboardTest, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_KBD_TEST + } + }, + { + EfiAsfMessageMouseTest, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_MOUSE_TEST + } + }, + { + EfiAsfMessageBspInit, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_PROCESSOR, + 0, // Instance + EFI_ASF_FP_EVENT_DATA0, + EFI_ASF_FP_BSP_INIT + } + }, + // + // Error Event + // + { + EfiAsfMessageHddFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_HDD_FAILURE + } + }, + { + EfiAsfMessageFdcFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_FDC_FAILURE + } + }, + { + EfiAsfMessageHdcFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_HDC_FAILURE + } + }, + { + EfiAsfMessageKbdFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_KBD_FAILURE + } + }, + { + EfiAsfMessageNoFdd, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_REMOVABLE_BOOT_MEDIA_NOT_FOUND + } + }, + { + EfiAsfMessageVideoControllerFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_VIDEO_CONTROLLER_FAILURE + } + }, + { + EfiAsfMessageNoVideo, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_VIDEO_DEVICE_NOT_FOUND + } + }, + { + EfiAsfMessageCpuVidMismatch, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_PROCESSOR, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_CPU_VOLTAGE_FAILURE + } + }, + { + EfiAsfMessageCpuSpeedMatchingFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_PROCESSOR, + 0, // Instance + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_CPU_MISMATCH_FAILURE + } + }, + { + EfiAsfMessageUserAuthenticationInvalid, + { + EFI_ASF_MESSAGE_SUBCOMMAND_RETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SECURITY_VIOLATION, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_USER_PASSWORD, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + } + }, + { + EfiAsfMessageHddAuthenticationInvalid, + { + EFI_ASF_MESSAGE_SUBCOMMAND_RETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SECURITY_VIOLATION, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_OTHER_PASSWORD, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_BIOS, + 0, // Instance + } + }, + // + // Boot Error + // + { + EfiAsfMessageNoBootMedia, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_DISK, + 0, // Insnce + EFI_ASF_FE_EVENT_DATA0, + EFI_ASF_FE_REMOVABLE_BOOT_MEDIA_NOT_FOUND + } + }, + { + EfiAsfMessageAmtBxDone, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FP_AMTBX_INIT + } + }, + { + EfiAsfMessageAmtBxNotStarted, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxSleepS4ReportedNotTaken, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxSleepS5ReportedNotTaken, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxSleepUnspecifiedReportedNotTaken, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxErrActionIntF, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxErrActionInv, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxErrActionSetup, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxErrActionFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxErrActionUnspecified, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + { + EfiAsfMessageAmtBxOtherUnspecified, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + 0xFF, + 0xFF, + EFI_ASF_ENTITY_INTEL_AMT, + 0, + 0x40, + EFI_ASF_FE_AMTBX_FAILURE + } + }, + // + // Temperature + // + { + EfiAsfMessageTemperatureGenericCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_SEVERITY_STATE, + EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageTemperatureGenericWarning, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_SEVERITY_STATE, + EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_NONCRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageTemperatureOverCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageTemperatureOverWarning, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_NONCRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageTemperatureUnderCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageTemperatureUnderWarning, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONCRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + // + // Voltage + // + { + EfiAsfMessageVoltageGenericCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_VOLTAGE, + EFI_ASF_EVENT_TYPE_SEVERITY_STATE, + EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageVoltageOverCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_VOLTAGE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageVoltageUnderCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_VOLTAGE, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + // + // Fan + // + { + EfiAsfMessageFanGenericCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_FAN, + EFI_ASF_EVENT_TYPE_SEVERITY_STATE, + EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageFanPredictiveFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_FAN, + EFI_ASF_EVENT_TYPE_DISCRETE_EVENT_PREDICTIVE_FAIL, + EFI_ASF_EVENT_OFFSET_DISCRETE_EVENT_PREDICTIVE_FAIL_ASSERT, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageFanLowSpeedCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_FAN, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + { + EfiAsfMessageFanLowSpeedWarning, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_FAN, + EFI_ASF_EVENT_TYPE_THRESHOLD_BASED, + EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONCRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Instance + } + }, + // + // Battery + // + { + EfiAsfMessageBatteryLowWarning, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_BATTERY, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_BATTERY_LOW_WARNING, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_POWER_SUPPLY, + 0, // Instance + } + }, + { + EfiAsfMessageBatteryLowCritical, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_BATTERY, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_BATTERY_LOW_CRITICAL, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_POWER_SUPPLY, + 0, // Insnce + } + }, + { + EfiAsfMessageBatteryPresenceDetected, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_BATTERY, + EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC, + EFI_ASF_EVENT_OFFSET_BATTERY_PRESENCE_DETECTED, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_MONITOR, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_POWER_SUPPLY, + 0, // Insnce + } + }, + { + EfiAsfMessagePowerFailure, + { + EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT, + EFI_ASF_VERSION, + EFI_ASF_EVENT_SENSOR_TYPE_POWER_SUPPLY, + EFI_ASF_EVENT_TYPE_SEVERITY_STATE, + EFI_ASF_EVENT_OFFSET_POWER_SUPPLY_FAILURE, + EFI_ASF_EVENT_SOURCE_TYPE_ASF10, + EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE, + EFI_ASF_SENSOR_DEVICE, + EFI_ASF_SENSOR_NUMBER, + EFI_ASF_ENTITY_SYSTEM_BOARD, + 0, // Insnce + } + }, +#endif +}; diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.cif b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.cif new file mode 100644 index 0000000..ee34575 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.cif @@ -0,0 +1,10 @@ +<component> + name = "AlertStandardFormatCommon" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AlertStandardFormat\Heci\Common\" + RefName = "AlertStandardFormatCommon" +[files] +"AlertStandardFormatCommon.sdl" +"AlertStandardFormatCommon.c" +"AlertStandardFormatCommon.h" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.h b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.h new file mode 100644 index 0000000..5949fb9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.h @@ -0,0 +1,397 @@ +/** @file + Include file for ASF Driver + +@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 _ALERT_STANDARD_FORMAT_COMMON_H +#define _ALERT_STANDARD_FORMAT_COMMON_H + +#define EFI_ASF_VERSION 0x10 + +// +// ASF SMBUS Messages +// +#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 + +#define EFI_ASF_MESSAGE_BYTECOUNT_RETURN_BOOT_OPT 0x0D +#define EFI_ASF_MESSAGE_BYTECOUNT_CLEAR_BOOT_OPT 0x02 +#define EFI_ASF_MESSAGE_BYTEOUNTT_GET_BOOT_OPT 0x02 +#define EFI_ASF_MESSAGE_BYTECOUNT_DEVICE_TYPE_POLL 0x03 +#define EFI_ASF_MESSAGE_BYTECOUNT_STOP_WATCH_DOG_TIMER 0x02 +#define EFI_ASF_MESSAGE_BYTECOUNT_START_WATCH_DOG_TIMER 0x0D + +#define EFI_ASF_MESSAGE_SUBCOMMAND_RETURN_BOOT_OPT 0x16 +#define EFI_ASF_MESSAGE_SUBCOMMAND_CLEAR_BOOT_OPT 0x15 +#define EFI_ASF_MESSAGE_SUBCOMMAND_DEVICE_TYPE_POLL 0x13 +#define EFI_ASF_MESSAGE_SUBCOMMAND_STOP_WATCH_DOG_TIMER 0x14 +#define EFI_ASF_MESSAGE_SUBCOMMAND_START_WATCH_DOG_TIMER 0x13 +#define EFI_ASF_MESSAGE_SUBCOMMAND_RETRANSMIT 0x15 +#define EFI_ASF_MESSAGE_SUBCOMMAND_NORETRANSMIT 0x16 +#define EFI_ASF_MESSAGE_SUBCOMMAND_SYSTEM_STATE 0x18 + +#define EFI_ASF_MESSAGE_VERSIONNUMBER 0x10 + +// +// ASF Event Sensor Type Codes +// +#define EFI_ASF_EVENT_SENSOR_TYPE_SYS_FW_ERR_PROG 0x0F +#define EFI_ASF_EVENT_SENSOR_TYPE_POST_ERR_PROG 0x0F +#define EFI_ASF_EVENT_SENSOR_TYPE_BOOT_ERROR 0x1E +#define EFI_ASF_EVENT_SENSOR_TYPE_OS_BOOT 0x1F +#define EFI_ASF_EVENT_SENSOR_TYPE_ENTITY_PRESENCE 0x25 +#define EFI_ASF_EVENT_SENSOR_TYPE_WATCHDOG2 0x23 + +#define EFI_ASF_EVENT_SENSOR_TYPE_TEMPERATURE 0x01 +#define EFI_ASF_EVENT_SENSOR_TYPE_VOLTAGE 0x02 +#define EFI_ASF_EVENT_SENSOR_TYPE_FAN 0x04 +#define EFI_ASF_EVENT_SENSOR_TYPE_CHASSIS_INTRUSION 0x05 +#define EFI_ASF_EVENT_SENSOR_TYPE_SECURITY_VIOLATION 0x06 +#define EFI_ASF_EVENT_SENSOR_TYPE_PROCESSOR 0x07 +#define EFI_ASF_EVENT_SENSOR_TYPE_POWER_SUPPLY 0x08 +#define EFI_ASF_EVENT_SENSOR_TYPE_POWER_UNIT 0x09 +#define EFI_ASF_EVENT_SENSOR_TYPE_CHIPSET 0x19 +#define EFI_ASF_EVENT_SENSOR_TYPE_BATTERY 0x29 + +// +// ASF Event Type Codes +// IPMI/PET related stuff +// +#define EFI_ASF_EVENT_TYPE_SENSOR_SPECIFIC 0x6F + +#define EFI_ASF_EVENT_TYPE_THRESHOLD_BASED 0x01 +#define EFI_ASF_EVENT_TYPE_USAGE_STATE 0x02 +#define EFI_ASF_EVENT_TYPE_DISCRETE_EVENT_STATE 0x03 +#define EFI_ASF_EVENT_TYPE_DISCRETE_EVENT_PREDICTIVE_FAIL 0x04 +#define EFI_ASF_EVENT_TYPE_DISCRETE_EVENT_LIMIT 0x05 +#define EFI_ASF_EVENT_TYPE_DISCRETE_EVENT_PERFORMANCE 0x06 +#define EFI_ASF_EVENT_TYPE_SEVERITY_STATE 0x07 +#define EFI_ASF_EVENT_TYPE_AVAILABILITY_STATUS_PRESENT 0x08 +#define EFI_ASF_EVENT_TYPE_AVAILABILITY_STATUS_ENABLE 0x09 +#define EFI_ASF_EVENT_TYPE_AVAILABILITY_STATUS_RUNNING 0x0A +#define EFI_ASF_EVENT_TYPE_AVAILABILITY_STATUS_OTHER 0x0B +#define EFI_ASF_EVENT_TYPE_DEVICE_POWER_STATES 0x0C + +// +// ASF Event Offset Codes +// IPMI/PET related stuff +// +#define EFI_ASF_EVENT_OFFSET_ENTITY_PRESENT 0x00 +#define EFI_ASF_EVENT_OFFSET_TIMER_EXPIRED 0x00 +#define EFI_ASF_EVENT_OFFSET_SYS_FW_ERROR 0x00 +#define EFI_ASF_EVENT_OFFSET_SYS_FW_HANG 0x01 +#define EFI_ASF_EVENT_OFFSET_SYS_FW_PROGRESS 0x02 + +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONCRITICAL 0x00 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONCRITICAL_GO_HIGH 0x01 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_CRITICAL 0x02 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_CRITICAL_GO_HIGH 0x03 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONRECOVERABLE 0x04 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_LOWER_NONRECOVERABLE_GO_HIGH 0x05 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_NONCRITICAL_GO_LOW 0x06 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_NONCRITICAL 0x07 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_CRITICAL_GO_LOW 0x08 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_CRITICAL 0x09 +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_NONRECOVERABLE_GO_LOW 0x0A +#define EFI_ASF_EVENT_OFFSET_THRESHOLD_UPPER_NONRECOVERABLE 0x0B + +#define EFI_ASF_EVENT_OFFSET_DISCRETE_EVENT_PREDICTIVE_FAIL_DEASSERT 0x00 +#define EFI_ASF_EVENT_OFFSET_DISCRETE_EVENT_PREDICTIVE_FAIL_ASSERT 0x01 + +#define EFI_ASF_EVENT_OFFSET_SEVERITY_TO_OK 0x00 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_NONCRITICAL 0x01 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_CRITICAL 0x02 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_MORE_NONRECOVERABLE 0x03 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_LESS_NONCRITICAL 0x04 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_LESS_CRITICAL 0x05 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_TO_NONRECOVERABLE 0x06 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_MONITOR 0x07 +#define EFI_ASF_EVENT_OFFSET_SEVERITY_INFORMATIONAL 0x08 + +#define EFI_ASF_EVENT_OFFSET_CHASSIS_INTRUSION_GENERIC 0x00 + +#define EFI_ASF_EVENT_OFFSET_PROCESSOR_IERR 0x00 + +#define EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_USER_PASSWORD 0x01 +#define EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_SUPERVISOR_PASSWORD 0x02 +#define EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_NETWORK_PASSWORD 0x03 +#define EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_OTHER_PASSWORD 0x04 +#define EFI_ASF_EVENT_OFFSET_SECURITY_VIOLATION_OUTOFBAND_PASSWORD 0x05 + +#define EFI_ASF_EVENT_OFFSET_BATTERY_LOW_WARNING 0x00 +#define EFI_ASF_EVENT_OFFSET_BATTERY_LOW_CRITICAL 0x01 +#define EFI_ASF_EVENT_OFFSET_BATTERY_PRESENCE_DETECTED 0x02 + +#define EFI_ASF_EVENT_OFFSET_POWER_SUPPLY_PRESENCE 0x00 +#define EFI_ASF_EVENT_OFFSET_POWER_SUPPLY_FAILURE 0x01 +#define EFI_ASF_EVENT_OFFSET_POWER_SUPPLY_PREDICTIVE_FAILURE 0x02 + +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_DOWN 0x00 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_CYCLE 0x01 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_240VA_DOWN 0x02 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_INTERLOCK_DOWN 0x03 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_AC_LOST 0x04 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_SOFT_CONTROL_FAILURE 0x05 +#define EFI_ASF_EVENT_OFFSET_POWER_UNIT_FAILURE 0x06 + +// +// ASF Event Source Type Code +// IPMI/PET related stuff +// +#define EFI_ASF_EVENT_SOURCE_TYPE_ASF10 0x68 +#define EFI_ASF_EVENT_SOURCE_TYPE_PLATFORM_FIRMWARE 0x00 +#define EFI_ASF_EVENT_SOURCE_TYPE_OS 0x48 + +// +// ASF Event Severity Codes +// IPMI/PET related stuff +// +#define EFI_ASF_EVENT_SEVERITY_CODE_MONITOR 0x01 +#define EFI_ASF_EVENT_SEVERITY_CODE_INFORMATION 0x02 +#define EFI_ASF_EVENT_SEVERITY_CODE_OK 0x04 +#define EFI_ASF_EVENT_SEVERITY_CODE_NONCRITICAL 0x08 +#define EFI_ASF_EVENT_SEVERITY_CODE_CRITICAL 0x10 +#define EFI_ASF_EVENT_SEVERITY_CODE_NONRECOVERABLE 0x20 + +/// +/// ASF Sensor Device Codes +/// IPMI/PET related stuff +/// +#define EFI_ASF_SENSOR_DEVICE 0xFF + +/// +/// ASF Sensor Number Codes +/// IPMI/PET related stuff +/// +#define EFI_ASF_SENSOR_NUMBER 0xFF + +// +// ASF Entity Codes +// IPMI/PET related stuff +// +#define EFI_ASF_ENTITY_UNSPECIFIED 0x00 +#define EFI_ASF_ENTITY_OTHER 0x01 +#define EFI_ASF_ENTITY_UNKNOWN 0x02 +#define EFI_ASF_ENTITY_PROCESSOR 0x03 +#define EFI_ASF_ENTITY_DISK 0x04 +#define EFI_ASF_ENTITY_PERIPHERAL 0x05 +#define EFI_ASF_ENTITY_SYSTEM_MGMT_MOD 0x06 +#define EFI_ASF_ENTITY_SYSTEM_BOARD 0x07 +#define EFI_ASF_ENTITY_POWER_SUPPLY 0x0A +#define EFI_ASF_ENTITY_ADDIN_CARD 0x0B +#define EFI_ASF_ENTITY_CHASIS_BACK_PANEL_BOARD 0x17 +#define EFI_ASF_ENTITY_MEMORY 0x20 +#define EFI_ASF_ENTITY_SYSTEM_MGMT_SW 0x21 +#define EFI_ASF_ENTITY_BIOS 0x22 +#define EFI_ASF_ENTITY_OS 0x23 +#define EFI_ASF_ENTITY_REMOTE_OOB_MGMT 0x26 +#define EFI_ASF_ENTITY_INTEL_AMT 0x26 + +/// +/// ASF Event Data Codes for System Firmware Progress Events +/// IPMI/PET related stuff +/// +#define EFI_ASF_FP_EVENT_DATA0 0x40 + +#define EFI_ASF_FP_UNSPECIFIED 0x00 +#define EFI_ASF_FP_MEMORY_INIT 0x01 +#define EFI_ASF_FP_HDD_INIT 0x02 +#define EFI_ASF_FP_AP_INIT 0x03 +#define EFI_ASF_FP_USER_AUTHENTICATION 0x04 +#define EFI_ASF_FP_USER_SETUP 0x05 +#define EFI_ASF_FP_USB_RESOURCE_CONFIG 0x06 +#define EFI_ASF_FP_PCI_RESOURCE_CONFIG 0x07 +#define EFI_ASF_FP_OPTION_ROM_INIT 0x08 +#define EFI_ASF_FP_VIDEO_INIT 0x09 +#define EFI_ASF_FP_CACHE_INIT 0x0A +#define EFI_ASF_FP_SMBUS_INIT 0x0B +#define EFI_ASF_FP_KBC_INIT 0x0C +#define EFI_ASF_FP_EC_INIT 0x0D +#define EFI_ASF_FP_AMTBX_INIT 0x0D +#define EFI_ASF_FP_ATTACH_DOCK 0x0E +#define EFI_ASF_FP_ENABLE_DOCK 0x0F +#define EFI_ASF_FP_EJECT_DOCK 0x10 +#define EFI_ASF_FP_DISABLE_DOCK 0x11 +#define EFI_ASF_FP_WAKE_OS 0x12 +#define EFI_ASF_FP_BOOT_OS 0x13 +#define EFI_ASF_FP_BOARD_INIT 0x14 +#define EFI_ASF_FP_RESERVED 0x15 +#define EFI_ASF_FP_FDC_INIT 0x16 +#define EFI_ASF_FP_KBD_TEST 0x17 +#define EFI_ASF_FP_MOUSE_TEST 0x18 +#define EFI_ASF_FP_BSP_INIT 0x19 + +/// +/// ASF Event Data Codes for System Firmware Error Events +/// IPMI/PET related stuff +/// +#define EFI_ASF_FE_EVENT_DATA0 0x40 + +#define EFI_ASF_FE_UNSPECIFIED 0x00 +#define EFI_ASF_FE_AMTBX_FAILURE 0x00 +#define EFI_ASF_FE_NO_MEMORY 0x01 +#define EFI_ASF_FE_MEMORY_FAILURE 0x02 +#define EFI_ASF_FE_HDD_FAILURE 0x03 +#define EFI_ASF_FE_BOARD_FAILURE 0x04 +#define EFI_ASF_FE_FDC_FAILURE 0x05 +#define EFI_ASF_FE_HDC_FAILURE 0x06 +#define EFI_ASF_FE_KBD_FAILURE 0x07 +#define EFI_ASF_FE_REMOVABLE_BOOT_MEDIA_NOT_FOUND 0x08 +#define EFI_ASF_FE_VIDEO_CONTROLLER_FAILURE 0x09 +#define EFI_ASF_FE_VIDEO_DEVICE_NOT_FOUND 0x0A +#define EFI_ASF_FE_ROM_CORRUPTED 0x0B +#define EFI_ASF_FE_CPU_VOLTAGE_FAILURE 0x0C +#define EFI_ASF_FE_CPU_MISMATCH_FAILURE 0x0D + +// +// AMT BX Software Class DXE Subclass Progress Code definitions. +// +#define EFI_SW_DXE_AMTBX_OPROM_DONE (EFI_OEM_SPECIFIC | 0x00000000) +#define EFI_SW_DXE_AMTBX_OPROM_NOT_STARTED (EFI_OEM_SPECIFIC | 0x00000001) +#define EFI_SW_DXE_AMTBX_SLEEP_S4_NOT_TAKEN (EFI_OEM_SPECIFIC | 0x00000002) +#define EFI_SW_DXE_AMTBX_SLEEP_S5_NOT_TAKEN (EFI_OEM_SPECIFIC | 0x00000003) +#define EFI_SW_DXE_AMTBX_SLEEP_UNSPECD_NOT_TAKEN (EFI_OEM_SPECIFIC | 0x00000004) +#define EFI_SW_DXE_AMTBX_ERROR_ACTION_INTF (EFI_OEM_SPECIFIC | 0x00000005) +#define EFI_SW_DXE_AMTBX_ERROR_ACTION_INV (EFI_OEM_SPECIFIC | 0x00000006) +#define EFI_SW_DXE_AMTBX_ERROR_ACTION_SETUP (EFI_OEM_SPECIFIC | 0x00000007) +#define EFI_SW_DXE_AMTBX_ERROR_ACTION_FAIL (EFI_OEM_SPECIFIC | 0x00000008) +#define EFI_SW_DXE_AMTBX_ERROR_ACTION_UNSPECD (EFI_OEM_SPECIFIC | 0x00000009) +#define EFI_SW_DXE_AMTBX_OTHER_UNSPECD (EFI_OEM_SPECIFIC | 0x00000009) + +typedef enum { + EfiAsfMessageBiosPresent, + EfiAsfMessageMemInit, + EfiAsfMessageMemInitDone, + EfiAsfMessageHddInit, + EfiAsfMessageApInit, + EfiAsfMessageUserAuthentication, + EfiAsfMessageUserInitSetup, + EfiAsfMessageUsbResourceConfig, + EfiAsfMessagePciResourceConfig, + EfiAsfMessageOptionRomInit, + EfiAsfMessageVideoInit, + EfiAsfMessageCacheInit, + EfiAsfMessageSmbusInit, + EfiAsfMessageKbcInit, + EfiAsfMessageEmControllerInit, + EfiAsfMessageDockAttached, + EfiAsfMessageEnableDock, + EfiAsfMessageDockEject, + EfiAsfMessageDisableDock, + EfiAsfMessageOSWakeVector, + EfiAsfMessageMotherBoardInit, + EfiAsfMessageFdcInit, + EfiAsfMessageKeyboardTest, + EfiAsfMessageMouseTest, + EfiAsfMessageBspInit, + EfiAsfMessageAmtBxDone, + EfiAsfMessageAmtBxNotStarted, + EfiAsfMessageAmtBxSleepS4ReportedNotTaken, + EfiAsfMessageAmtBxSleepS5ReportedNotTaken, + EfiAsfMessageAmtBxSleepUnspecifiedReportedNotTaken, + EfiAsfMessageAmtBxErrActionIntF, + EfiAsfMessageAmtBxErrActionInv, + EfiAsfMessageAmtBxErrActionSetup, + EfiAsfMessageAmtBxErrActionFailure, + EfiAsfMessageAmtBxErrActionUnspecified, + EfiAsfMessageAmtBxOtherUnspecified, + EfiAsfMessageNoMemory, + EfiAsfMessageMemoryFailure, + EfiAsfMessageHddFailure, + EfiAsfMessageBoardFailure, + EfiAsfMessageFdcFailure, + EfiAsfMessageHdcFailure, + EfiAsfMessageKbdFailure, + EfiAsfMessageNoFdd, + EfiAsfMessageVideoControllerFailure, + EfiAsfMessageNoVideo, + EfiAsfMessageFirmwareCorruption, + EfiAsfMessageCpuVidMismatch, + EfiAsfMessageCpuSpeedMatchingFailure, + EfiAsfMessageUserAuthenticationInvalid, + EfiAsfMessageHddAuthenticationInvalid, + EfiAsfMessageNoBootMedia, + EfiAsfMessageTemperatureGenericCritical, + EfiAsfMessageTemperatureGenericWarning, + EfiAsfMessageTemperatureOverCritical, + EfiAsfMessageTemperatureOverWarning, + EfiAsfMessageTemperatureUnderCritical, + EfiAsfMessageTemperatureUnderWarning, + EfiAsfMessageVoltageGenericCritical, + EfiAsfMessageVoltageOverCritical, + EfiAsfMessageVoltageUnderCritical, + EfiAsfMessageFanGenericCritical, + EfiAsfMessageFanPredictiveFailure, + EfiAsfMessageFanLowSpeedCritical, + EfiAsfMessageFanLowSpeedWarning, + EfiAsfMessageBatteryLowWarning, + EfiAsfMessageBatteryLowCritical, + EfiAsfMessageBatteryPresenceDetected, + EfiAsfMessagePowerFailure, + EfiAsfMessageChassisIntrusion, +} EFI_FRAMEWORK_MESSAGE_TYPE; + +// +// StatusCode extension for ASF -- start +// +#define EFI_CU_HP_EC_VID_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x0000000E) +#define EFI_CU_HP_EC_SPEED_MATCHING_FAILURE (EFI_SUBCLASS_SPECIFIC | 0x0000000F) + +#define EFI_PERIPHERAL_EMBEDDED_CONTROLLER (EFI_PERIPHERAL | 0x000D0000) +#define EFI_PERIPHERAL_DOCK (EFI_PERIPHERAL | 0x000E0000) + +#define EFI_PERIPHERAL_BATTERY (EFI_PERIPHERAL | 0x000F0000) +#define EFI_P_BATTERY_PC_LOW_WARNING (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_BATTERY_EC_LOW_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000000) + +#define EFI_PERIPHERAL_FAN (EFI_PERIPHERAL | 0x00100000) +#define EFI_P_FAN_EC_GENERIC_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_FAN_EC_PREDICTIVE_FAILURE (EFI_SUBCLASS_SPECIFIC | 0x00000001) +#define EFI_P_FAN_EC_LOW_SPEED_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000002) +#define EFI_P_FAN_PC_LOW_SPEED_WARNING (EFI_SUBCLASS_SPECIFIC | 0x00000002) + +#define EFI_PERIPHERAL_TEMPERATURE (EFI_PERIPHERAL | 0x00110000) +#define EFI_P_TEMERATURE_EC_GENERIC_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_TEMERATURE_PC_GENERIC_WARNING (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_TEMERATURE_EC_OVER_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000001) +#define EFI_P_TEMERATURE_PC_OVER_WARNING (EFI_SUBCLASS_SPECIFIC | 0x00000001) +#define EFI_P_TEMERATURE_EC_UNDER_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000002) +#define EFI_P_TEMERATURE_PC_UNDER_WARNING (EFI_SUBCLASS_SPECIFIC | 0x00000002) + +#define EFI_PERIPHERAL_VOLTAGE (EFI_PERIPHERAL | 0x00120000) +#define EFI_P_VOLTAGE_EC_GENERIC_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_VOLTAGE_EC_OVER_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000001) +#define EFI_P_VOLTAGE_EC_UNDER_CRITICAL (EFI_SUBCLASS_SPECIFIC | 0x00000002) + +#define EFI_PERIPHERAL_POWER_SUPPLY (EFI_PERIPHERAL | 0x00130000) +#define EFI_P_POWER_SUPPLY_EC_FAILURE (EFI_SUBCLASS_SPECIFIC | 0x00000000) +#define EFI_P_POWER_SUPPLY_EC_PREDICTIVE_FAILURE (EFI_SUBCLASS_SPECIFIC | 0x00000001) + +#define EFI_CU_CHIPSET_PC_INTRUDER_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000000) + +#define EFI_SW_DXE_BS_EC_NO_BOOT_MEDIA (EFI_SUBCLASS_SPECIFIC | 0x00000001) +#define EFI_SW_DXE_BS_EC_AUTHENTICATE_USER_INVALID (EFI_SUBCLASS_SPECIFIC | 0x00000002) +#define EFI_SW_DXE_BS_EC_AUTHENTICATE_HDD_INVALID (EFI_SUBCLASS_SPECIFIC | 0x00000003) + +// +// StatusCode extension for ASF -- end +// +#endif diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.sdl b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.sdl new file mode 100644 index 0000000..8ec0f9c --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Common/AlertStandardFormatCommon.sdl @@ -0,0 +1,10 @@ +PATH + Name = "AlertStandardFormatCommon_DIR" + Help = "AlertStandardFormat files source directory" +End + +ELINK + Name = "/I$(AlertStandardFormatCommon_DIR)" + Parent = "AlertStandardFormat_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.c b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.c new file mode 100644 index 0000000..5119b8e --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.c @@ -0,0 +1,1234 @@ +/** @file + Processes ASF messages + +@copyright + Copyright (c) 2005 - 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 "AlertStandardFormatDxe.h" +#include "MeLib.h" +#endif + +#include "AlertStandardFormatCommon.c" + +UINT64 mAsfMonotonicCount; +EFI_ASF_BOOT_OPTIONS mAsfBootOptions; +BOOLEAN mBootOptionsValid; +BOOLEAN mAsfAddressValid; +BOOLEAN mProgressEventEnabled; + +ALERT_STANDARD_FORMAT_INSTANCE *mAsfContext; + +EFI_GUID gAmtForcePushPetVariableGuid = AMT_FORCE_PUSH_PET_VARIABLE_GUID; +EFI_GUID gAmtPetQueueHobGuid = AMT_PET_QUEUE_HOB_GUID; +EFI_GUID gAmtForcePushPetHobGuid = AMT_FORCE_PUSH_PET_HOB_GUID; + +AMT_PET_QUEUE_PROTOCOL gAmtPetQueue; +AMT_PET_QUEUE_PROTOCOL *gAmtPetQueueProtocol; +AMT_FORCE_PUSH_PET_POLICY_HOB *gAmtForcePushPETPolicyHob; + +/** + Update ASF Boot Options data in ACPI ASF RCMP table + + @param[in] AsfBootOptions ASF Boot Options data for ACPI ASF RCMP table used +**/ +VOID +UpdateAcpiAsfRcmpBootOptions ( + EFI_ASF_BOOT_OPTIONS *AsfBootOptions + ) +{ + EFI_STATUS Status; + EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE *AcpiAsfTable; + UINTN Handle; + UINTN VersionCount; + UINT16 *WordPointer; + EFI_ACPI_TABLE_VERSION Version[] = { + EFI_ACPI_TABLE_VERSION_1_0B, + EFI_ACPI_TABLE_VERSION_2_0, + EFI_ACPI_TABLE_VERSION_3_0 + }; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + /// + /// Locate ACPI Table Protocol + /// + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + + /// + /// Initialize ASL manipulation library + /// + InitializeAslUpdateLib (); + + for (VersionCount = 0; VersionCount < sizeof (Version) / sizeof (EFI_ACPI_TABLE_VERSION); VersionCount++) { + Handle = 0; + /// + /// Locate the ASF Table + /// + Status = LocateAcpiTableBySignature ( + EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE, + (EFI_ACPI_DESCRIPTION_HEADER **) &AcpiAsfTable, + &Handle, + &Version[VersionCount] + ); + if (EFI_ERROR (Status)) { + continue; + } + + if (AsfBootOptions->SubCommand == ASF_BOOT_OPTIONS_PRESENT) { + /// + /// Check Asf table if get boot option successfully + /// + AcpiAsfTable->AsfRmcp.RMCPCompletionCode = 00; + AcpiAsfTable->AsfRmcp.RMCPIANA = AsfBootOptions->IanaId; + AcpiAsfTable->AsfRmcp.RMCPSpecialCommand = AsfBootOptions->SpecialCommand; + WordPointer = (UINT16 *) &AcpiAsfTable->AsfRmcp.RMCPSpecialCommandParameter; + *WordPointer = AsfBootOptions->SpecialCommandParam; + WordPointer = (UINT16 *) &AcpiAsfTable->AsfRmcp.RMCPBootOptions; + *WordPointer = AsfBootOptions->BootOptions; + WordPointer = (UINT16 *) &AcpiAsfTable->AsfRmcp.RMCPOEMParameters; + *WordPointer = AsfBootOptions->OemParameters; + } else { + /// + /// Failed to get boot option, update the completion code to 0x1 + /// + AcpiAsfTable->AsfRmcp.RMCPCompletionCode = 01; + } + if (Handle != 0) { + Status = AcpiTable->UninstallAcpiTable ( + AcpiTable, + Handle + ); + } + /// + /// Update the Acpi Asf table + /// + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + AcpiAsfTable, + sizeof(EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE), + &Handle + ); + FreePool (AcpiAsfTable); + } +} + +/** + 16 bits are changed backward for string transfer to value used + + @param[in] Value The value to be transferred + + @retval UINT16 Value The value after transferring +**/ +UINT16 +Swap16 ( + IN UINT16 Value + ) +{ + UINT16 OutValue; + UINT8 *TempIn; + UINT8 *TempOut; + + TempIn = (UINT8 *) &Value; + TempOut = (UINT8 *) &OutValue; + + TempOut[0] = TempIn[1]; + TempOut[1] = TempIn[0]; + + return OutValue; +} + +/** + The driver entry point - detect ASF support or not, if support, will install relative protocol. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The driver installed without error. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +EFIAPI +AlertStandardFormatDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_DATA_HUB_PROTOCOL *DataHub; + EFI_EVENT DataHubEvent; + UINT64 DataClass; + EFI_ASF_BOOT_OPTIONS *AsfBootOptions; + + /// + /// First check if ASF support is enabled in Setup. + /// + if (!AsfSupported ()) { + return EFI_UNSUPPORTED; + } + + mBootOptionsValid = FALSE; + mAsfAddressValid = FALSE; + + mAsfContext = AllocateZeroPool (sizeof (ALERT_STANDARD_FORMAT_INSTANCE)); + ASSERT (mAsfContext != NULL); + if (mAsfContext == NULL) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// Get the Data Hub Protocol. Assume only one instance + /// of Data Hub Protocol is available in the system. + /// + Status = gBS->LocateProtocol ( + &gEfiDataHubProtocolGuid, + NULL, + (VOID **) &DataHub + ); + ASSERT_EFI_ERROR (Status); + + mAsfContext->Handle = ImageHandle; + mAsfContext->Signature = ALERT_STANDARD_FORMAT_PRIVATE_DATA_SIGNATURE; + mAsfContext->AlertStandardFormat.GetSmbusAddr = GetSmbusAddr; + mAsfContext->AlertStandardFormat.SetSmbusAddr = SetSmbusAddr; + mAsfContext->AlertStandardFormat.GetBootOptions = GetBootOptions; + mAsfContext->AlertStandardFormat.SendAsfMessage = SendAsfMessage; + + /// + /// Sending ASF Messaging if ManageabilityMode is not zero + /// + if (ManageabilityModeSetting () != MNT_OFF) { + /// + /// ActiveManagement Protocol is not ready at this point. Need to Check Boot Options Manually + /// + mProgressEventEnabled = FALSE; + Status = GetBootOptions (&(mAsfContext->AlertStandardFormat), &AsfBootOptions); + if (!EFI_ERROR (Status)) { + if (AsfBootOptions->SubCommand == ASF_BOOT_OPTIONS_PRESENT) { + if ((AsfBootOptions->BootOptions & FORCE_PROGRESS_EVENTS) == FORCE_PROGRESS_EVENTS) { + mProgressEventEnabled = TRUE; + } + } + } + /// + /// If no boot options available, check policy + /// + if (!mProgressEventEnabled) { + mProgressEventEnabled = FwProgressSupport (); + } + /// + /// Create message queue + /// + AmtCreateMessageQueue (); + + /// + /// Get ForcePushPetPolicy Hob + /// + gAmtForcePushPETPolicyHob = GetForcePushPetPolicy (); + + /// + /// save PEI force push error event from hob to variable + /// + SaveForcePushErrorEventFromPeiToDxe (); + + /// + /// Try to send message + /// + SendPETMessageInQueue (); + + /// + /// Register our Setup Data Filter Function. + /// This function is notified at the lowest TPL + /// + Status = gBS->CreateEvent ( + EVENT_NOTIFY_SIGNAL, + TPL_CALLBACK, + DataHubEventCallback, + NULL, + &DataHubEvent + ); + ASSERT_EFI_ERROR (Status); + + if (mProgressEventEnabled) { + DataClass = EFI_DATA_RECORD_CLASS_ERROR | EFI_DATA_RECORD_CLASS_PROGRESS_CODE; + } else { + DataClass = EFI_DATA_RECORD_CLASS_ERROR; + } + + Status = DataHub->RegisterFilterDriver ( + DataHub, + DataHubEvent, + EFI_TPL_APPLICATION, + DataClass, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + /// + /// Install the AlertStandardFormat interface + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &mAsfContext->Handle, + &gEfiAlertStandardFormatProtocolGuid, + &mAsfContext->AlertStandardFormat, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Return the SMBus address used by the ASF driver. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @param[in] This The address of protocol + @param[in] SmbusDeviceAddress Out put the Smbus Address + + @exception EFI_UNSUPPORTED The function is unsupported by this driver +**/ +EFI_STATUS +EFIAPI +GetSmbusAddr ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + OUT UINTN *SmbusDeviceAddress + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Set the SMBus address used by the ASF driver. 0 is an invalid address. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @param[in] This The address of protocol + @param[in] SmbusDeviceAddress SMBus address of the device + + @exception EFI_UNSUPPORTED The function is unsupported by this driver +**/ +EFI_STATUS +EFIAPI +SetSmbusAddr ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN UINTN SmbusDeviceAddress + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Return EFI_SUCCESS if Firmware Init Complete is set in HFS[9]. + + @param[in] Heci EFI_HECI_PROTOCOL + @param[in] Timeout Time in second + + @retval EFI_SUCCESS Firmware Init Complete is set + @retval EFI_TIMEOUT Firmware Init Complete is not set in 5 seconds +**/ +EFI_STATUS +WaitFirmwareInitDone ( + EFI_HECI_PROTOCOL *Heci, + UINT32 Timeout + ) +{ + UINT32 idx; + EFI_STATUS Status; + UINT32 MeStatus; + + Status = EFI_SUCCESS; + idx = 0; + + Heci->GetMeStatus (&MeStatus); + + while (!ME_STATUS_IS_ME_FW_INIT_COMPLETE (MeStatus)) { + gBS->Stall (100000); + idx++; + if (idx > Timeout * 10) { + Status = EFI_TIMEOUT; + break; + } + + Heci->GetMeStatus (&MeStatus); + } + + return Status; +} + +/** + Initialize KVM by sending HECI messafe to ME + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event handler. +**/ +VOID +EFIAPI +QueryKvm ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + BdsKvmInitialization (); + gBS->CloseEvent (Event); +} + +/** + Return the ASF Boot Options obtained from the controller. If the + Boot Options parameter is NULL and no boot options have been retrieved, + Query the ASF controller for its boot options. + Get ASF Boot Options through HECI. + + @param[in] This The address of protocol + @param[in] AsfBootOptions Pointer to ASF boot options to copy current ASF Boot options + + @retval EFI_SUCCESS Boot options copied + @retval EFI_NOT_READY No boot options +**/ +EFI_STATUS +EFIAPI +GetBootOptions ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +{ + EFI_STATUS Status; + UINT8 ConsoleLock; + UINT32 MeStatus; + UINT32 MeMode; + EFI_STATUS TempStatus; + VOID *AfterConsolOutNotifyReg; + EFI_EVENT AfterConsolOutInstalledEvent; + EFI_GUID guidConOutStarted = EFI_CONSOLE_OUT_DEVICE_GUID; + EFI_HECI_PROTOCOL *Heci; + HECI_ASF_GET_BOOT_OPTIONS_RESPONSE HeciAsfGetBootOptionsResponse; + HECI_ASF_CLEAR_BOOT_OPTION HeciAsfClearBootOption; + UINT32 HeciLength; + + if (!mBootOptionsValid) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ASF Get Boot Options failed!, Status = %r\n", Status)); + return Status; + } + + ZeroMem ((VOID *) &mAsfBootOptions, sizeof (EFI_ASF_BOOT_OPTIONS)); + mAsfBootOptions.SubCommand = ASF_BOOT_OPTIONS_NOT_PRESENT; + mAsfBootOptions.Version = 0x10; + UpdateAcpiAsfRcmpBootOptions (&mAsfBootOptions); + + /// + /// Get ME Status + /// + TempStatus = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (TempStatus); + + /// + /// Get ME Operation Mode + /// + Heci->GetMeMode (&MeMode); + + /// + /// Only Send ASF Get Boot Options message when ME is ready and ME FW INIT is completed + /// + if (ME_STATUS_IS_ME_FW_BOOT_OPTIONS_PRESENT (MeStatus) && + (ManageabilityModeSetting () != MNT_OFF) && + (MeMode == ME_MODE_NORMAL) + ) { + if (WaitFirmwareInitDone (Heci, 5) != EFI_TIMEOUT) { + /// + /// Prepare Boot Option Command header + /// + HeciAsfGetBootOptionsResponse.Command = EFI_ASF_MESSAGE_COMMAND_ASF_CONFIGURATION; + HeciAsfGetBootOptionsResponse.ByteCount = EFI_ASF_MESSAGE_BYTEOUNTT_GET_BOOT_OPT; + HeciAsfGetBootOptionsResponse.AsfBootOptions.SubCommand = EFI_ASF_MESSAGE_SUBCOMMAND_RETURN_BOOT_OPT; + HeciAsfGetBootOptionsResponse.AsfBootOptions.Version = 0x10; + HeciLength = HECI_ASF_GET_BOOT_OPTIONS_LENGTH; + Status = Heci->SendMsg ( + (UINT32 *) &HeciAsfGetBootOptionsResponse, + HeciLength, + BIOS_ASF_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ASF Get Boot Options failed!(SendwACK), Status = %r\n", Status)); + return Status; + } + + HeciLength = HECI_ASF_GET_BOOT_OPTIONS_RESPONSE_LENGTH; + Status = Heci->ReadMsg ( + BLOCKING, + (UINT32 *) &HeciAsfGetBootOptionsResponse, + &HeciLength + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ASF Get Boot Options failed!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + CopyMem ( + (VOID *) &mAsfBootOptions, + (VOID *) &(HeciAsfGetBootOptionsResponse.AsfBootOptions), + sizeof (EFI_ASF_BOOT_OPTIONS) + ); + + /// + /// By default, this table is belong to all ACPI table versions. + /// It is ok if the table is not found and that means the platform does not publish that version. + /// + UpdateAcpiAsfRcmpBootOptions (&mAsfBootOptions); + + mAsfBootOptions.SpecialCommandParam = Swap16 (mAsfBootOptions.SpecialCommandParam); + + /// + /// ASF Get Boot Options - Clear Boot Options + /// Need to do this so don't get caught in an endless loop plus by + /// definition get boot options is a one time boot situation. + /// So if server on other end of ASF device wants another back to back + /// boot it will request it. Do this only if there were boot options + /// + if (mAsfBootOptions.SubCommand == ASF_BOOT_OPTIONS_PRESENT) { + HeciAsfClearBootOption.Command = EFI_ASF_MESSAGE_COMMAND_ASF_CONFIGURATION; + HeciAsfClearBootOption.AsfClearBootOptions.SubCommand = EFI_ASF_MESSAGE_SUBCOMMAND_CLEAR_BOOT_OPT; + HeciAsfClearBootOption.AsfClearBootOptions.Version = EFI_ASF_MESSAGE_VERSIONNUMBER; + HeciAsfClearBootOption.ByteCount = EFI_ASF_MESSAGE_BYTECOUNT_CLEAR_BOOT_OPT; + HeciLength = HECI_ASF_CLEAR_BOOT_OPTION_LENGTH; + + Status = Heci->SendMsg ( + (UINT32 *) &HeciAsfClearBootOption, + HeciLength, + BIOS_ASF_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ASF Clear Boot Options failed!, Status = %r\n", Status)); + return Status; + } + } + } + } + /// + /// Set flag so we don't try to get the Boot options again. + /// + mBootOptionsValid = TRUE; + + /// + /// Set up Event for KVM for when Output Display Console is installed + /// + if ((mAsfBootOptions.SpecialCommandParam & USE_KVM) == USE_KVM) { + + Status = gBS->CreateEvent ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_NOTIFY, + QueryKvm, + NULL, + &AfterConsolOutInstalledEvent + ); + + Status = gBS->RegisterProtocolNotify ( + &guidConOutStarted, + AfterConsolOutInstalledEvent, + &AfterConsolOutNotifyReg + ); + + } + /// + /// Check for keyboard locking in the boot options + /// + ConsoleLock = NO_LOCK_CONSOLE; + + if (mAsfBootOptions.SubCommand == ASF_BOOT_OPTIONS_PRESENT) { + if ((mAsfBootOptions.BootOptions & LOCK_KEYBOARD) == LOCK_KEYBOARD) { + ConsoleLock = LOCK_CONSOLE; + } + } + /// + /// Save the console lock flag for later usage in console locking determination + /// + gRT->SetVariable ( + EFI_CONSOLE_LOCK_VARIABLE_NAME, + &gEfiConsoleLockGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (ConsoleLock), + &ConsoleLock + ); + } + + if (AsfBootOptions) { + *AsfBootOptions = &mAsfBootOptions; + + /// + /// If we're asking for the options, then resend them to the debug output just encase they've been hosed. + /// + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.SubCommand = 0x%x\n", mAsfBootOptions.SubCommand)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.Version = 0x%x\n", mAsfBootOptions.Version)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.IanaId = 0x%x\n", mAsfBootOptions.IanaId)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.SpecialCommand = 0x%x\n", mAsfBootOptions.SpecialCommand)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.SpecialCommandParam = 0x%x\n", mAsfBootOptions.SpecialCommandParam)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.BootOptions = 0x%x\n", mAsfBootOptions.BootOptions)); + DEBUG ((EFI_D_ERROR, "mAsfBootOptions.OemParameters = 0x%x\n", mAsfBootOptions.OemParameters)); + } + + return EFI_SUCCESS; +} + +/** + Send ASF Message through HECI. + + @param[in] This The address of protocol + @param[in] AsfMessage Pointer to ASF message + + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +EFIAPI +SendAsfMessage ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN EFI_ASF_MESSAGE *AsfMessage + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + UINT32 HeciLength; + HECI_ASF_PUSH_PROGRESS_CODE HeciAsfPushProgressCode; + UINT32 MeStatus; + UINT32 MeMode; + EFI_STATUS TempStatus; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (!EFI_ERROR (Status)) { + TempStatus = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (TempStatus); + + /// + /// Get ME Operation Mode + /// + Heci->GetMeMode (&MeMode); + + /// + /// Only send ASF Push Progress code when ME is ready and ME is in normal mode. Ignore FW Init Status. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY && MeMode == ME_MODE_NORMAL) { + ZeroMem ((VOID *) &HeciAsfPushProgressCode, sizeof (HECI_ASF_PUSH_PROGRESS_CODE)); + HeciAsfPushProgressCode.Command = EFI_ASF_MESSAGE_COMMAND_MESSAGE; + HeciAsfPushProgressCode.ByteCount = 0x10; + HeciLength = HECI_ASF_PUSH_PROGRESS_CODE_LENGTH; + CopyMem ((VOID *) &(HeciAsfPushProgressCode.AsfMessage), (VOID *) AsfMessage, sizeof (EFI_ASF_MESSAGE)); + + Status = Heci->SendMsg ( + (UINT32 *) &HeciAsfPushProgressCode, + HeciLength, + BIOS_ASF_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + } + } + + return Status; +} + +/** + This routine returns ForcePushPetPolicy information. + + @param[in] None + + @retval AMT_FORCE_PUSH_PET_POLICY_HOB ForcePushPetPolicy information. +**/ +AMT_FORCE_PUSH_PET_POLICY_HOB * +GetForcePushPetPolicy ( + VOID + ) +{ + AMT_FORCE_PUSH_PET_POLICY_HOB *AmtForcePushPETPolicyHob; + EFI_STATUS Status; + + Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &AmtForcePushPETPolicyHob); + ASSERT_EFI_ERROR (Status); + + return GetNextGuidHob (&gAmtForcePushPetPolicyGuid, AmtForcePushPETPolicyHob); +} + +/** + This routine checks whethre current message is ForcePush message. + + @param[in] MessageType AMT PET Message Type. + + @retval TRUE It is ForcePush message. + @retval FALSE It is not ForcePush message. +**/ +BOOLEAN +IsForcePushErrorEvent ( + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + UINTN Index; + UINTN Number; + + Number = (gAmtForcePushPETPolicyHob->EfiHobGuidType.Header.HobLength - sizeof (EFI_HOB_GUID_TYPE)) / + sizeof (EFI_FRAMEWORK_MESSAGE_TYPE); + for (Index = 0; Index < Number; Index++) { + if (gAmtForcePushPETPolicyHob->MessageType[Index] == MessageType) { + return TRUE; + } + } + + return FALSE; +} + +/** + Filters all the progress and error codes for Asf. + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event handler. +**/ +VOID +EFIAPI +DataHubEventCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_DATA_HUB_PROTOCOL *DataHub; + EFI_DATA_RECORD_HEADER *Record; + DATA_HUB_STATUS_CODE_DATA_RECORD *StatusRecord; + UINTN Index; + + /// + /// Get the Data Hub Protocol. Assume only one instance + /// + Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &DataHub); + ASSERT_EFI_ERROR (Status); + + /// + /// Get all available data records from data hub + /// + Record = NULL; + + do { + Status = DataHub->GetNextRecord (DataHub, &mAsfMonotonicCount, &Event, &Record); + if (!EFI_ERROR (Status)) { + if (mProgressEventEnabled) { + if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_PROGRESS_CODE) { + StatusRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record + 1); + for (Index = 0; Index < sizeof (mAsfProgressDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfProgressDataHubMap[Index].StatusCodeValue == StatusRecord->Value) { + Status = SendPostPacket (mAsfProgressDataHubMap[Index].MessageType); + break; + } + } + } + } + + if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_ERROR) { + StatusRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record + 1); + for (Index = 0; Index < sizeof (mAsfErrorDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfErrorDataHubMap[Index].StatusCodeValue == StatusRecord->Value) { + Status = SendPostPacket (mAsfErrorDataHubMap[Index].MessageType); + if ((Status == EFI_DEVICE_ERROR) && IsForcePushErrorEvent (mAsfErrorDataHubMap[Index].MessageType)) { + SaveForcePushErrorEvent (mAsfErrorDataHubMap[Index].MessageType); + } + break; + } + } + } + } + } while (!EFI_ERROR (Status) && (mAsfMonotonicCount != 0)); +} + +/** + Sends a POST packet across ASF + + @param[in] MessageType POST Status Code + + @retval EFI_DEVICE_ERROR No message found + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPostPacket ( + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + EFI_STATUS Status; + UINTN Index; + + Status = EFI_DEVICE_ERROR; + /// + /// Find the message to send across the wire + /// + for (Index = 0; Index < sizeof (mAsfFrameworkMessage) / sizeof (EFI_ASF_FRAMEWORK_MESSAGE); Index++) { + if (mAsfFrameworkMessage[Index].MessageType == MessageType) { + Status = SendAsfMessage (NULL, &mAsfFrameworkMessage[Index].Message); + break; + } + } + + return Status; +} + +/** + Provides an interface that a software module can call to report an ASF DXE status code. + + @param[in] Type 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. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. +**/ +EFI_STATUS +EFIAPI +AmtReportStatusCode ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) +{ + UINTN Index; + EFI_STATUS Status; + + if (mProgressEventEnabled) { + if ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { + for (Index = 0; Index < sizeof (mAsfProgressDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfProgressDataHubMap[Index].StatusCodeValue == Value) { + return SendPostPacket (mAsfProgressDataHubMap[Index].MessageType); + } + } + } + } + + if ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { + for (Index = 0; Index < sizeof (mAsfErrorDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfErrorDataHubMap[Index].StatusCodeValue == Value) { + Status = SendPostPacket (mAsfErrorDataHubMap[Index].MessageType); + if ((Status == EFI_DEVICE_ERROR) && IsForcePushErrorEvent (mAsfErrorDataHubMap[Index].MessageType)) { + SaveForcePushErrorEvent (mAsfErrorDataHubMap[Index].MessageType); + } + + return Status; + } + } + } + + return EFI_SUCCESS; +} + +/** + This routine puts PET message to MessageQueue, which will be sent later. + + @param[in] Type StatusCode message type. + @param[in] Value StatusCode message value. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +QueuePetMessage ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value + ) +{ + AMT_PET_QUEUE_NODE *NewNode; + + NewNode = AllocateZeroPool (sizeof (AMT_PET_QUEUE_NODE)); + ASSERT (NewNode != NULL); + if (NewNode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewNode->Signature = AMT_PET_QUEUE_NODE_SIGNATURE; + NewNode->Type = Type; + NewNode->Value = Value; + InsertTailList ((LIST_ENTRY *) &gAmtPetQueueProtocol->MessageList, (LIST_ENTRY *) &NewNode->Link); + + return EFI_SUCCESS; +} + +/** + This routine sends PET message in MessageQueue. + + @param[in] PeiServices PeiServices pointer. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPETMessageInQueue ( + VOID + ) +{ + EFI_STATUS Status; + AMT_PET_QUEUE_HOB *PETQueueHob; + EFI_LIST_ENTRY *Link; + AMT_PET_QUEUE_NODE *Node; + EFI_PEI_HOB_POINTERS Hob; + + EFI_HECI_PROTOCOL *Heci; + UINT32 MeStatus; + EFI_STATUS TempStatus; + + /// + /// Try HECI state + /// + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_READY; + } + + TempStatus = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (TempStatus); + + /// + /// Only send ASF Push Progress code when ME is ready. Ignore FW Init Status. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) != ME_READY) { + return EFI_NOT_READY; + } + /// + /// Get PETQueueHob + /// + Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &PETQueueHob); + + while (TRUE) { + PETQueueHob = GetNextGuidHob (&gAmtPetQueueHobGuid, PETQueueHob); + if (PETQueueHob == NULL) { + break; + } + /// + /// Send message + /// + AmtReportStatusCode (PETQueueHob->Type, PETQueueHob->Value, 0, NULL, NULL); + + /// + /// Mark it as sent + /// + PETQueueHob->Type = (UINT32) -1; + + /// + /// Need find next one + /// + Hob.Raw = (VOID *) PETQueueHob; + PETQueueHob = (AMT_PET_QUEUE_HOB *) GET_NEXT_HOB (Hob); + } + /// + /// Send DXEQueue + /// + Link = (EFI_LIST_ENTRY *) GetFirstNode ((LIST_ENTRY *) &gAmtPetQueueProtocol->MessageList); + + while (!IsNull ((LIST_ENTRY *) &gAmtPetQueueProtocol->MessageList, (LIST_ENTRY *) Link)) { + Node = AMT_PET_QUEUE_NODE_FROM_LINK (Link); + + /// + /// Send message + /// + AmtReportStatusCode (Node->Type, Node->Value, 0, NULL, NULL); + + /// + /// Mark it as sent + /// + Node->Type = (UINT32) -1; + + Link = (EFI_LIST_ENTRY *) GetNextNode ( + (LIST_ENTRY *) &gAmtPetQueueProtocol->MessageList, + (LIST_ENTRY *) &Node->Link + ); + } + + return EFI_SUCCESS; +} + +/** + This routine creats PET MessageQueue. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +AmtCreateMessageQueue ( + VOID + ) +{ + /// + /// Create Queue for later usage + /// + gAmtPetQueueProtocol = &gAmtPetQueue; + + InitializeListHead ((LIST_ENTRY *) &gAmtPetQueueProtocol->MessageList); + + return EFI_SUCCESS; +} + +/** + This routine saves current ForcePush ErrorEvent to Variable, which will be sent again. + + @param[in] MessageType ASF PET message type. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +SaveForcePushErrorEvent ( + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + EFI_STATUS Status; + UINTN Size; + EFI_FRAMEWORK_MESSAGE_TYPE *Message; + + /// + /// Create PET queue variable + /// + Message = NULL; + Size = 0; + Status = gRT->GetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + NULL, + &Size, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + /// + /// Get the exist message + /// + Message = AllocateZeroPool (Size + sizeof (MessageType)); + ASSERT (Message != NULL); + if (Message == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + NULL, + &Size, + Message + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Fill new item + /// + *(EFI_FRAMEWORK_MESSAGE_TYPE *) ((UINTN) Message + Size) = MessageType; + Size += sizeof (MessageType); + } else if (Status == EFI_NOT_FOUND) { + /// + /// Create a new one + /// + Size = sizeof (MessageType); + Message = AllocateZeroPool (sizeof (MessageType)); + ASSERT (Message != NULL); + if (Message == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *Message = MessageType; + } else { + ASSERT (FALSE); + } + /// + /// Set PET message to variable + /// + if (Message != NULL) { + Status = gRT->SetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + Size, + Message + ); + ASSERT_EFI_ERROR (Status); + + FreePool (Message); + } + + return EFI_SUCCESS; +} + +/** + This routine converts Hob ForcePush ErrorEvent to Variable, which will be sent again. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SaveForcePushErrorEventFromPeiToDxe ( + VOID + ) +{ + AMT_FORCE_PUSH_PET_HOB *AmtForcePushPETHob; + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + + /// + /// Find ASF ForcePush PET Hob + /// + Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &AmtForcePushPETHob); + + while (TRUE) { + AmtForcePushPETHob = GetNextGuidHob (&gAmtForcePushPetHobGuid, AmtForcePushPETHob); + if (AmtForcePushPETHob == NULL) { + break; + } + + SaveForcePushErrorEvent (AmtForcePushPETHob->MessageType); + + /// + /// Need find next one + /// + Hob.Raw = (VOID *) AmtForcePushPETHob; + AmtForcePushPETHob = (AMT_FORCE_PUSH_PET_HOB *) GET_NEXT_HOB (Hob); + } + + return EFI_SUCCESS; +} + +/** + This routine tries to send all ForcePush ErrorEvent. + If message is sent, it will be deleted from Variable. + If message is not sent, it will be still stored to Variable. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +SendAllForcePushErrorEvent ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + EFI_FRAMEWORK_MESSAGE_TYPE *Message; + UINTN Index; + EFI_FRAMEWORK_MESSAGE_TYPE *NewMessage; + UINTN NewIndex; + + /// + /// Create PET queue variable + /// + Message = NULL; + Size = 0; + Status = gRT->GetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + NULL, + &Size, + NULL + ); + if (Status == EFI_NOT_FOUND) { + return EFI_SUCCESS; + } + + if (Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + /// + /// Get the exist message + /// + Message = AllocateZeroPool (Size); + ASSERT (Message != NULL); + if (Message == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewMessage = AllocateZeroPool (Size); + ASSERT (NewMessage != NULL); + if (NewMessage == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + NULL, + &Size, + Message + ); + ASSERT_EFI_ERROR (Status); + + NewIndex = 0; + for (Index = 0; Index < Size / sizeof (EFI_FRAMEWORK_MESSAGE_TYPE); Index++) { + Status = SendPostPacket (Message[Index]); + if (EFI_ERROR (Status)) { + /// + /// Fail, save it again. + /// + NewMessage[NewIndex] = Message[Index]; + NewIndex++; + } + } + + FreePool (Message); + + /// + /// SetVariable again + /// + if (NewIndex == 0) { + FreePool (NewMessage); + NewMessage = NULL; + } + + Status = gRT->SetVariable ( + AMT_FORCE_PUSH_PET_VARIABLE_NAME, + &gAmtForcePushPetVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + NewIndex * sizeof (EFI_FRAMEWORK_MESSAGE_TYPE), + NewMessage + ); + + if (NewMessage != NULL) { + FreePool (NewMessage); + } + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.cif b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.cif new file mode 100644 index 0000000..f091a20 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.cif @@ -0,0 +1,13 @@ +<component> + name = "AlertStandardFormatDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AlertStandardFormat\Heci\Dxe\" + RefName = "AlertStandardFormatDxe" +[files] +"AlertStandardFormatDxe.sdl" +"AlertStandardFormatDxe.mak" +"AlertStandardFormatDxe.c" +"AlertStandardFormatDxe.dxs" +"AlertStandardFormatDxe.h" +"AlertStandardFormatDxe.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.dxs b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.dxs new file mode 100644 index 0000000..dd340c9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.dxs @@ -0,0 +1,47 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 2005 - 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 + +**/ + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" + +#include EFI_PROTOCOL_DEFINITION (DataHub) +#include EFI_PROTOCOL_DEFINITION (Heci) +#include EFI_PROTOCOL_DEFINITION (AcpiSupport) +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) + +#endif + +DEPENDENCY_START + EFI_DATA_HUB_PROTOCOL_GUID AND + EFI_HECI_PROTOCOL_GUID AND + EFI_ACPI_SUPPORT_GUID AND + DXE_PLATFORM_AMT_POLICY_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.h b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.h new file mode 100644 index 0000000..0e6b947 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.h @@ -0,0 +1,340 @@ +/** @file + Include file for ASF Driver + +@copyright + Copyright (c) 2005 - 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 _ALERT_STANDARD_FORMAT_H +#define _ALERT_STANDARD_FORMAT_H + +#include "AslUpdateLib.h" +#include "AlertStandardFormatTable.h" +#include "AmtLib.h" +#include "AlertStandardFormatCommon.h" + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_CONSUMER (DataHub) +#include EFI_PROTOCOL_CONSUMER (AlertStandardFormat) +#include EFI_PROTOCOL_CONSUMER (HECI) +#include EFI_PROTOCOL_CONSUMER (ConsoleControl) +#include EFI_GUID_DEFINITION (ConsoleLock) +#include EFI_GUID_DEFINITION (AmtForcePushPetPolicy) + +/// +/// ASF Over HECI +/// +typedef struct _HECI_ASF_PUSH_PROGRESS_CODE { + UINT8 Command; + UINT8 ByteCount; + EFI_ASF_MESSAGE AsfMessage; + UINT8 EventData[3]; + UINT8 Reserved[2]; +} HECI_ASF_PUSH_PROGRESS_CODE; + +#define HECI_ASF_PUSH_PROGRESS_CODE_LENGTH 0x12 + +typedef struct _HECI_ASF_GET_BOOT_OPTIONS { + UINT8 Command; + UINT8 ByteCount; + UINT8 SubCommand; + UINT8 VersionNumber; +} HECI_ASF_GET_BOOT_OPTIONS; + +#define HECI_ASF_GET_BOOT_OPTIONS_LENGTH 0x04 + +typedef struct _HECI_ASF_GET_BOOT_OPTIONS_RESPONSE { + UINT8 Command; + UINT8 ByteCount; + EFI_ASF_BOOT_OPTIONS AsfBootOptions; + UINT8 Reserved; +} HECI_ASF_GET_BOOT_OPTIONS_RESPONSE; + +#define HECI_ASF_GET_BOOT_OPTIONS_RESPONSE_LENGTH 0x0F + +typedef struct _HECI_ASF_CLEAR_BOOT_OPTION { + UINT8 Command; + UINT8 ByteCount; + EFI_ASF_CLEAR_BOOT_OPTIONS AsfClearBootOptions; +} HECI_ASF_CLEAR_BOOT_OPTION; + +#define HECI_ASF_CLEAR_BOOT_OPTION_LENGTH 0x04 + +typedef enum _HASFM_COMMAND_CODE +{ + ASF_MESSAGING_CMD = 0x04, + ASF_PUSH_PROGESS_CODE_SUBCMD = 0x12, + ASF_MENAGEMENT_CONTROL = 0x02, + ASF_WDT_START_SUBCMD = 0x13, + ASF_WDT_STOP_SUBCMD = 0x14, + ASF_CONFIGURATION_CMD = 0x03, + ASF_CLEAR_BOOT_OPTION_SUBCMD = 0x15, + ASF_RETURN_BOOT_OPTION_SUBCMD = 0x16, + ASF_NO_BOOT_OPTION_SUBCMD = 0x17 +} HASFM_COMMAND_CODE; + +typedef struct { + EFI_FRAMEWORK_MESSAGE_TYPE MessageType; + EFI_ASF_MESSAGE Message; +} EFI_ASF_FRAMEWORK_MESSAGE; + +typedef struct { + EFI_FRAMEWORK_MESSAGE_TYPE MessageType; + EFI_STATUS_CODE_VALUE StatusCodeValue; +} EFI_ASF_DATA_HUB_MAP; + +#define ALERT_STANDARD_FORMAT_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('a', 's', 'f', 'd') + +/// +/// Declare a local instance structure for this driver +/// +typedef struct _ALERT_STANDARD_FORMAT_INSTANCE { + UINTN Signature; + EFI_HANDLE Handle; + + /// + /// Published interface + /// + EFI_ALERT_STANDARD_FORMAT_PROTOCOL AlertStandardFormat; + +} ALERT_STANDARD_FORMAT_INSTANCE; + +#include "Pei.h" +#include EFI_PPI_DEFINITION (AmtStatusCode) + +#define EFI_CONSOLE_OUT_DEVICE_GUID \ + { \ + 0xd3b36f2c, 0xd551, 0x11d4, \ + { \ + 0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d \ + } \ + } + +#define AMT_FORCE_PUSH_PET_VARIABLE_GUID \ + { \ + 0xd7ac94af, 0xa498, 0x45ec, 0xbf, 0xa2, 0xa5, 0x6e, 0x95, 0x34, 0x61, 0x8b \ + } + +#define AMT_FORCE_PUSH_PET_VARIABLE_NAME L"AmtForcePushErrorPET" + +#define AMT_PET_QUEUE_NODE_SIGNATURE EFI_SIGNATURE_32 ('A', 'M', 'T', 'Q') + +typedef struct _AMT_PET_QUEUE_NODE { + UINT32 Signature; + EFI_LIST_ENTRY Link; + EFI_STATUS_CODE_VALUE Value; + EFI_STATUS_CODE_TYPE Type; +} AMT_PET_QUEUE_NODE; + +#define AMT_PET_QUEUE_NODE_FROM_LINK(_node) CR (_node, AMT_PET_QUEUE_NODE, Link, AMT_PET_QUEUE_NODE_SIGNATURE) + +typedef struct { + EFI_LIST_ENTRY MessageList; +} AMT_PET_QUEUE_PROTOCOL; + +// +// Prototypes +// + +/** + The driver entry point - detect ASF support or not, if support, will install relative protocol. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The driver installed without error. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +EFIAPI +AlertStandardFormatDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +/** + Return the SMBus address used by the ASF driver. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @param[in] This The address of protocol + @param[in] SmbusDeviceAddress Out put the Smbus Address + + @exception EFI_UNSUPPORTED The function is unsupported by this driver +**/ +EFI_STATUS +EFIAPI +GetSmbusAddr ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + OUT UINTN *SmbusDeviceAddress + ) +; + +/** + Set the SMBus address used by the ASF driver. 0 is an invalid address. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @param[in] This The address of protocol + @param[in] SmbusDeviceAddress SMBus address of the device + + @exception EFI_UNSUPPORTED The function is unsupported by this driver +**/ +EFI_STATUS +EFIAPI +SetSmbusAddr ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN UINTN SmbusDeviceAddress + ) +; + +/** + Return the ASF Boot Options obtained from the controller. If the + Boot Options parameter is NULL and no boot options have been retrieved, + Query the ASF controller for its boot options. + Get ASF Boot Options through HECI. + + @param[in] This The address of protocol + @param[in] AsfBootOptions Pointer to ASF boot options to copy current ASF Boot options + + @retval EFI_SUCCESS Boot options copied + @retval EFI_NOT_READY No boot options +**/ +EFI_STATUS +EFIAPI +GetBootOptions ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +; + +/** + Send ASF Message through HECI. + + @param[in] This The address of protocol + @param[in] AsfMessage Pointer to ASF message + + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +EFIAPI +SendAsfMessage ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN EFI_ASF_MESSAGE *AsfMessage + ) +; + +/** + This routine returns ForcePushPetPolicy information. + + @param[in] None + + @retval AMT_FORCE_PUSH_PET_POLICY_HOB ForcePushPetPolicy information. +**/ +AMT_FORCE_PUSH_PET_POLICY_HOB * +GetForcePushPetPolicy ( + VOID + ) +; + +/** + Filters all the progress and error codes for Asf. + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event handler. +**/ +VOID +EFIAPI +DataHubEventCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + +/** + Sends a POST packet across ASF + + @param[in] MessageType POST Status Code + + @retval EFI_DEVICE_ERROR No message found + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPostPacket ( + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +; + +/** + This routine sends PET message in MessageQueue. + + @param[in] PeiServices PeiServices pointer. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPETMessageInQueue ( + VOID + ) +; + +/** + This routine creats PET MessageQueue. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +AmtCreateMessageQueue ( + VOID + ) +; + +/** + This routine saves current ForcePush ErrorEvent to Variable, which will be sent again. + + @param[in] MessageType ASF PET message type. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +SaveForcePushErrorEvent ( + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +; + +/** + This routine converts Hob ForcePush ErrorEvent to Variable, which will be sent again. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SaveForcePushErrorEventFromPeiToDxe ( + VOID + ) +; +#endif diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.inf b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.inf new file mode 100644 index 0000000..b484230 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.inf @@ -0,0 +1,99 @@ +## @file +# Component description file for Alert Standard Format driver. +# +#@copyright +# Copyright (c) 2005 - 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 = AlertStandardFormatDxe +FILE_GUID = 33c6406d-2f6b-41b5-8705-52bafb633c09 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + AlertStandardFormatDxe.c + AlertStandardFormatDxe.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[libraries.common] + AmtLib + MeGuidLib + MeProtocolLib + AslUpdateLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeHobLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueDxeMemoryAllocationLib + +[includes.common] + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/ActiveManagement/AlertStandardFormat/Heci/Common + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = AlertStandardFormatDxe.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=AlertStandardFormatDriverEntryPoint + 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/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.mak b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.mak new file mode 100644 index 0000000..202d1c9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.mak @@ -0,0 +1,59 @@ +# MAK file for the ModulePart:AlertStandardFormatDxe + +all : AlertStandardFormatDxe + +AlertStandardFormatDxe : $(BUILD_DIR)\AlertStandardFormatDxe.mak AlertStandardFormatDxeBin + +$(BUILD_DIR)\AlertStandardFormatDxe.mak : $(AlertStandardFormatDxe_DIR)\$(@B).cif $(AlertStandardFormatDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AlertStandardFormatDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +AlertStandardFormatDxe_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(AlertStandardFormat_INCLUDES)\ + $(IndustryStandard_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + +AlertStandardFormatDxe_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(AmtLibDxe_LIB)\ + $(MeGuidLib_LIB)\ + $(MeProtocolLib_LIB)\ + $(MeAslUpdateLib_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueDxeHobLib_LIB)\ + +AlertStandardFormatDxe_DEFINES=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=AlertStandardFormatDriverEntryPoint"\ + /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__\ + +AlertStandardFormatDxeBin : $(AlertStandardFormatDxe_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\AlertStandardFormatDxe.mak all\ + "MY_INCLUDES=$(AlertStandardFormatDxe_INCLUDES)" \ + "MY_DEFINES=$(AlertStandardFormatDxe_DEFINES)"\ + GUID=33c6406d-2f6b-41b5-8705-52bafb633c09 \ + ENTRY_POINT=_ModuleEntryPoint \ + EDKIIModule=DXEDRIVER\ + TYPE=BS_DRIVER \ + DEPEX1=$(AlertStandardFormatDxe_DIR)\AlertStandardFormatDxe.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1 diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.sdl b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.sdl new file mode 100644 index 0000000..938ff01 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Dxe/AlertStandardFormatDxe.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = AlertStandardFormatDxe_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AlertStandardFormatDxe support in Project" +End + +MODULE + Help = "Includes AlertStandardFormatDxe.mak to Project" + File = "AlertStandardFormatDxe.mak" +End + +PATH + Name = "AlertStandardFormatDxe_DIR" + Help = "AlertStandardFormatDxe files source directory" +End + +ELINK + Name = "$(BUILD_DIR)\AlertStandardFormatDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.c b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.c new file mode 100644 index 0000000..10afe73 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.c @@ -0,0 +1,437 @@ +/** @file + Processes ASF messages + +@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 "AlertStandardFormatPei.h" +#include "MeLibPei.h" +#endif + +#define ASF_PEI +#include "AlertStandardFormatCommon.c" + +static PEI_AMT_STATUS_CODE_PPI mPeiAmtStatusCodePpi = { PeiAmtReportStatusCode }; + +static EFI_PEI_PPI_DESCRIPTOR mInstallPeiAmtStatusCodePpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiAmtStatusCodePpiGuid, + &mPeiAmtStatusCodePpi +}; + +/** + Perform AMT PET message sending + + @param[in] FfsHeader FFS file header pointer of this driver. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS if the AMT StatusCode PPI is successfully installed. + @exception EFI_UNSUPPORTED ASF is not enabled or ManageabilityMode is zero. +**/ +EFI_STATUS +EFIAPI +AlertStandardFormatDriverPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + /// + /// First check if ASF support is enabled in Setup. + /// + if (!PeiAsfSupported (PeiServices)) { + return EFI_UNSUPPORTED; + } + /// + /// Sending ASF Messaging if ManageabilityMode is not zero + /// + if (ManageabilityModeSetting (PeiServices) == MNT_OFF) { + return EFI_UNSUPPORTED; + } + /// + /// Install AMT report status code PPI + /// + Status = (**PeiServices).InstallPpi (PeiServices, &mInstallPeiAmtStatusCodePpi); + ASSERT_EFI_ERROR (Status); + + /// + /// Try to send PET message + /// + SendPETMessageInQueue (PeiServices); + + return EFI_SUCCESS; +} + +/** + Send ASF Message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] AsfMessage Pointer to ASF message + + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error +**/ +EFI_STATUS +SendAsfMessage ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_ASF_MESSAGE *AsfMessage + ) +{ + EFI_STATUS Status; + PEI_HECI_PPI *Heci; + UINT32 HeciMemBar; + UINT32 HeciLength; + HECI_ASF_PUSH_PROGRESS_CODE HeciAsfPushProgressCode; + UINT32 MeStatus; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gPeiHeciPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) &Heci // PPI + ); + ASSERT_EFI_ERROR (Status); + + Status = Heci->InitializeHeci (PeiServices, Heci, &HeciMemBar); + if (EFI_ERROR (Status)) { + return EFI_NOT_READY; + } + + Status = Heci->GetMeStatus (PeiServices, &MeStatus); + ASSERT_EFI_ERROR (Status); + + /// + /// Only send ASF Push Progress code when ME is ready. Ignore FW Init Status. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) != ME_READY) { + return EFI_NOT_READY; + } + + ZeroMem ((VOID *) &HeciAsfPushProgressCode, sizeof (HECI_ASF_PUSH_PROGRESS_CODE)); + HeciAsfPushProgressCode.Command = EFI_ASF_MESSAGE_COMMAND_MESSAGE; + HeciAsfPushProgressCode.ByteCount = 0x10; + HeciLength = HECI_ASF_PUSH_PROGRESS_CODE_LENGTH; + CopyMem ((VOID *) &(HeciAsfPushProgressCode.AsfMessage), (VOID *) AsfMessage, sizeof (EFI_ASF_MESSAGE)); + + Status = Heci->SendMsg ( + PeiServices, + Heci, + (UINT32 *) &HeciAsfPushProgressCode, + HeciMemBar, + HeciLength, + BIOS_ASF_HOST_ADDR, + HECI_ASF_MESSAGE_ADDR + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This routine checks whethre current message is ForcePush message. + + @param[in] PeiServices PeiServices pointer. + @param[in] MessageType AMT PET Message Type. + + @retval TRUE It is ForcePush message. + @retval FALSE It is not ForcePush message. +**/ +BOOLEAN +IsForcePushErrorEvent ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + AMT_FORCE_PUSH_PET_POLICY_HOB *AmtForcePushPETPolicyHob; + UINTN Index; + UINTN Number; + EFI_STATUS Status; + + Status = (*PeiServices)->GetHobList (PeiServices, (VOID **) &AmtForcePushPETPolicyHob); + ASSERT_EFI_ERROR (Status); + + AmtForcePushPETPolicyHob = GetNextGuidHob (&gAmtForcePushPetPolicyGuid, AmtForcePushPETPolicyHob); + if (AmtForcePushPETPolicyHob == NULL) { + return FALSE; + } + + Number = (AmtForcePushPETPolicyHob->EfiHobGuidType.Header.HobLength - sizeof (EFI_HOB_GUID_TYPE)) / + sizeof (EFI_FRAMEWORK_MESSAGE_TYPE); + for (Index = 0; Index < Number; Index++) { + if (AmtForcePushPETPolicyHob->MessageType[Index] == MessageType) { + return TRUE; + } + } + + return FALSE; +} + +/** + Provides an interface that a software module can call to report an ASF PEI status code. + + @param[in] PeiServices PeiServices pointer. + @param[in] This This interface. + @param[in] Type 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. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. +**/ +EFI_STATUS +EFIAPI +PeiAmtReportStatusCode ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_AMT_STATUS_CODE_PPI * This, + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) +{ + UINTN Index; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if (PeiFwProgressSupport (PeiServices)) { + if ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { + for (Index = 0; Index < sizeof (mAsfProgressDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfProgressDataHubMap[Index].StatusCodeValue == Value) { + /// + /// Queue Progress Code and send PET after checking Boot Options + /// + QueuePetMessage (PeiServices, Type, Value); + } + } + } + } + + if ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { + for (Index = 0; Index < sizeof (mAsfErrorDataHubMap) / sizeof (EFI_ASF_DATA_HUB_MAP); Index++) { + if (mAsfErrorDataHubMap[Index].StatusCodeValue == Value) { + Status = SendPostPacket (PeiServices, mAsfErrorDataHubMap[Index].MessageType); + if ((Status == EFI_DEVICE_ERROR) && IsForcePushErrorEvent (PeiServices, mAsfErrorDataHubMap[Index].MessageType)) { + SaveForcePushErrorEvent (PeiServices, mAsfErrorDataHubMap[Index].MessageType); + } + + if (Status == EFI_NOT_READY) { + QueuePetMessage (PeiServices, Type, Value); + } + } + } + } + + return Status; +} + +/** + Sends a POST packet across ASF + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MessageType POST Status Code + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SendPostPacket ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + UINTN Index; + + /// + /// Find the message to send across the wire + /// + for (Index = 0; Index < sizeof (mAsfFrameworkMessage) / sizeof (EFI_ASF_FRAMEWORK_MESSAGE); Index++) { + if (mAsfFrameworkMessage[Index].MessageType == MessageType) { + return SendAsfMessage (PeiServices, &mAsfFrameworkMessage[Index].Message); + } + } + + return EFI_SUCCESS; +} + +/** + This routine saves current ForcePush ErrorEvent to Hob, which will be sent again. + + @param[in] PeiServices PeiServices pointer. + @param[in] MessageType ASF PET message type. + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SaveForcePushErrorEvent ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +{ + AMT_FORCE_PUSH_PET_HOB *ForcePushPETHob; + EFI_STATUS Status; + + /// + /// Create PET queue hob + /// + Status = (**PeiServices).CreateHob ( + PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + sizeof (AMT_FORCE_PUSH_PET_HOB), + (VOID **) &ForcePushPETHob + ); + ASSERT_EFI_ERROR (Status); + + ForcePushPETHob->EfiHobGuidType.Name = gAmtForcePushPetHobGuid; + ForcePushPETHob->MessageType = MessageType; + + return EFI_SUCCESS; +} + +/** + This routine puts PET message to MessageQueue, which will be sent later. + + @param[in] PeiServices PeiServices pointer. + @param[in] Type StatusCode message type. + @param[in] Value StatusCode message value. + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +QueuePetMessage ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value + ) +{ + AMT_PET_QUEUE_HOB *PETQueueHob; + EFI_STATUS Status; + + /// + /// Create PET queue hob + /// + Status = (**PeiServices).CreateHob ( + PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + sizeof (AMT_PET_QUEUE_HOB), + (VOID **) &PETQueueHob + ); + ASSERT_EFI_ERROR (Status); + PETQueueHob->EfiHobGuidType.Name = gAmtPetQueueHobGuid; + PETQueueHob->Value = Value; + + return EFI_SUCCESS; +} + +/** + This routine sends PET message in MessageQueue. + + @param[in] PeiServices PeiServices pointer. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPETMessageInQueue ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + AMT_PET_QUEUE_HOB *PETQueueHob; + EFI_PEI_HOB_POINTERS Hob; + + PEI_HECI_PPI *Heci; + UINT32 HeciMemBar; + UINT32 MeStatus; + + /// + /// Try HECI state + /// + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gPeiHeciPpiGuid, // GUID + 0, // INSTANCE + NULL, // EFI_PEI_PPI_DESCRIPTOR + (VOID **) &Heci // PPI + ); + ASSERT_EFI_ERROR (Status); + + Status = Heci->InitializeHeci (PeiServices, Heci, &HeciMemBar); + if (EFI_ERROR (Status)) { + return EFI_NOT_READY; + } + + Status = Heci->GetMeStatus (PeiServices, &MeStatus); + ASSERT_EFI_ERROR (Status); + + /// + /// Only send ASF Push Progress code when ME is ready. Ignore FW Init Status. + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) != ME_READY) { + return EFI_NOT_READY; + } + /// + /// Get PETQueueHob + /// + Status = (*PeiServices)->GetHobList (PeiServices, (VOID **) &PETQueueHob); + ASSERT_EFI_ERROR (Status); + + while (TRUE) { + PETQueueHob = GetNextGuidHob (&gAmtPetQueueHobGuid, PETQueueHob); + if (PETQueueHob == NULL) { + break; + } + /// + /// Send message + /// + PeiAmtReportStatusCode (PeiServices, NULL, PETQueueHob->Type, PETQueueHob->Value, 0, NULL, NULL); + + /// + /// Mark it as sent + /// + PETQueueHob->Type = (UINT32) -1; + + /// + /// Need find next one + /// + Hob.Raw = (VOID *) PETQueueHob; + PETQueueHob = (AMT_PET_QUEUE_HOB *) GET_NEXT_HOB (Hob); + } + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.cif b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.cif new file mode 100644 index 0000000..ee123bf --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.cif @@ -0,0 +1,13 @@ +<component> + name = "AlertStandardFormatPei" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AlertStandardFormat\Heci\Pei\" + RefName = "AlertStandardFormatPei" +[files] +"AlertStandardFormatPei.sdl" +"AlertStandardFormatPei.mak" +"AlertStandardFormatPei.c" +"AlertStandardFormatPei.dxs" +"AlertStandardFormatPei.h" +"AlertStandardFormatPei.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.dxs b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.dxs new file mode 100644 index 0000000..236c6ec --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.dxs @@ -0,0 +1,29 @@ +/** @file + Dependency expression source file. + +@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 + +**/ + +#include "EfiDepex.h" + +#include EFI_PPI_DEFINITION (Heci) +#include EFI_PPI_DEFINITION (AmtPlatformPolicyPei) + +DEPENDENCY_START + PEI_HECI_PPI_GUID AND + PEI_AMT_PLATFORM_POLICY_PPI_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.h b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.h new file mode 100644 index 0000000..b24dd69 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.h @@ -0,0 +1,204 @@ +/** @file + Processes ASF messages + +@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 _ALERT_STANDARD_FORMAT_PEI_H +#define _ALERT_STANDARD_FORMAT_PEI_H + +#include "AmtLibPei.h" +#include "MkhiMsgs.h" +#include "AlertStandardFormatCommon.h" + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PPI_CONSUMER (HECI) +#include EFI_PPI_PRODUCER (AmtStatusCode) +#include EFI_GUID_DEFINITION (MeBiosExtensionSetup) +#include EFI_GUID_DEFINITION (AmtForcePushPetPolicy) + +/// +/// ASF Over HECI +/// +#pragma pack(1) +typedef struct { + UINT8 SubCommand; + UINT8 Version; + UINT8 EventSensorType; + UINT8 EventType; + UINT8 EventOffset; + UINT8 EventSourceType; + UINT8 EventSeverity; + UINT8 SensorDevice; + UINT8 SensorNumber; + UINT8 Entity; + UINT8 EntityInstance; + UINT8 Data0; + UINT8 Data1; +} EFI_ASF_MESSAGE; +#pragma pack() + +typedef struct _HECI_ASF_PUSH_PROGRESS_CODE { + UINT8 Command; + UINT8 ByteCount; + EFI_ASF_MESSAGE AsfMessage; + UINT8 EventData[3]; + UINT8 Reserved[2]; +} HECI_ASF_PUSH_PROGRESS_CODE; + +#define HECI_ASF_PUSH_PROGRESS_CODE_LENGTH 0x12 + +typedef enum _HASFM_COMMAND_CODE +{ + ASF_MESSAGING_CMD = 0x04, + ASF_PUSH_PROGESS_CODE_SUBCMD = 0x12, + ASF_MENAGEMENT_CONTROL = 0x02, + ASF_WDT_START_SUBCMD = 0x13, + ASF_WDT_STOP_SUBCMD = 0x14, + ASF_CONFIGURATION_CMD = 0x03, + ASF_CLEAR_BOOT_OPTION_SUBCMD = 0x15, + ASF_RETURN_BOOT_OPTION_SUBCMD = 0x16, + ASF_NO_BOOT_OPTION_SUBCMD = 0x17 +} HASFM_COMMAND_CODE; + +typedef struct { + EFI_FRAMEWORK_MESSAGE_TYPE MessageType; + EFI_ASF_MESSAGE Message; +} EFI_ASF_FRAMEWORK_MESSAGE; + +typedef struct { + EFI_FRAMEWORK_MESSAGE_TYPE MessageType; + EFI_STATUS_CODE_VALUE StatusCodeValue; +} EFI_ASF_DATA_HUB_MAP; + +// +// Prototypes +// + +/** + Send ASF Message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] AsfMessage Pointer to ASF message + + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error +**/ +EFI_STATUS +SendAsfMessage ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_ASF_MESSAGE *AsfMessage + ) +; + +/** + Provides an interface that a software module can call to report an ASF PEI status code. + + @param[in] PeiServices PeiServices pointer. + @param[in] This This interface. + @param[in] Type 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. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. +**/ +EFI_STATUS +EFIAPI +PeiAmtReportStatusCode ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_AMT_STATUS_CODE_PPI * This, + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) +; + +/** + Sends a POST packet across ASF + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MessageType POST Status Code + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SendPostPacket ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +; + +/** + This routine saves current ForcePush ErrorEvent to Hob, which will be sent again. + + @param[in] PeiServices PeiServices pointer. + @param[in] MessageType ASF PET message type. + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SaveForcePushErrorEvent ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FRAMEWORK_MESSAGE_TYPE MessageType + ) +; + +/** + This routine puts PET message to MessageQueue, which will be sent later. + + @param[in] PeiServices PeiServices pointer. + @param[in] Type StatusCode message type. + @param[in] Value StatusCode message value. + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +QueuePetMessage ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value + ) +; + +/** + This routine sends PET message in MessageQueue. + + @param[in] PeiServices PeiServices pointer. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_READY No controller +**/ +EFI_STATUS +SendPETMessageInQueue ( + IN EFI_PEI_SERVICES **PeiServices + ) +; +#endif diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.inf b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.inf new file mode 100644 index 0000000..8bd8d0f --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.inf @@ -0,0 +1,93 @@ +## @file +# Component description file for Alert Standard Format driver. +# +#@copyright +# Copyright (c) 2005 - 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 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 = AlertStandardFormatPei +FILE_GUID = 3e4817fd-2742-4351-b59f-91493280329c +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + AlertStandardFormatPei.c + AlertStandardFormatPei.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[libraries.common] + PeiLib + AmtLibPei + MeGuidLib + MeLibPpi + EdkIIGlueBaseIoLibIntrinsic + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + EdkIIGluePeiHobLib + +[includes.common] + $(EDK_SOURCE)/Foundation/library/Pei/Include + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Library/Pei + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/ActiveManagement/AlertStandardFormat/Heci/Common + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Pei + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Pei + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = AlertStandardFormatPei.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=AlertStandardFormatDriverPeiEntryPoint + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.mak b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.mak new file mode 100644 index 0000000..8ff971a --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.mak @@ -0,0 +1,50 @@ +# MAK file for the ModulePart:AlertStandardFormat +all : AlertStandardFormatPei + +AlertStandardFormatPei : $(BUILD_DIR)\AlertStandardFormatPei.mak AlertStandardFormatPeiBin + +$(BUILD_DIR)\AlertStandardFormatPei.mak : $(AlertStandardFormatPei_DIR)\$(@B).cif $(AlertStandardFormatPei_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AlertStandardFormatPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +AlertStandardFormatPei_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(AlertStandardFormat_INCLUDES)\ + $(IndustryStandard_INCLUDES)\ + +AlertStandardFormatPei_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(MeGuidLib_LIB)\ + $(MeLibPpi_LIB)\ + $(AmtLibPei_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGluePeiHobLib_LIB)\ + +AlertStandardFormatPei_DEFINES=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=AlertStandardFormatDriverPeiEntryPoint"\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_PEI_SERVICES_LIB__\ + /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + +AlertStandardFormatPeiBin : $(AlertStandardFormatPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\AlertStandardFormatPei.mak all\ + "MY_INCLUDES=$(AlertStandardFormatPei_INCLUDES)"\ + "MY_DEFINES=$(AlertStandardFormatPei_DEFINES)"\ + GUID=3e4817fd-2742-4351-b59f-91493280329c \ + ENTRY_POINT=_ModuleEntryPoint \ + EDKIIModule=PEIM\ + TYPE=PEIM \ + DEPEX1=$(AlertStandardFormatPei_DIR)\AlertStandardFormatPei.dxs \ + DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 diff --git a/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.sdl b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.sdl new file mode 100644 index 0000000..ec7b2cd --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AlertStandardFormat/Heci/Pei/AlertStandardFormatPei.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = AlertStandardFormatPei_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AlertStandardFormat support in Project" +End + +MODULE + Help = "Includes AlertStandardFormat.mak to Project" + File = "AlertStandardFormatPei.mak" +End + +PATH + Name = "AlertStandardFormatPei_DIR" + Help = "AlertStandardFormatPei files source directory" +End + +ELINK + Name = "$(BUILD_DIR)\AlertStandardFormatPei.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.cif b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.cif new file mode 100644 index 0000000..a1c7a9f --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.cif @@ -0,0 +1,10 @@ +<component> + name = "AmtBootOptions" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AmtBootOptions\" + RefName = "AmtBootOptions" +[files] +"AmtBootOptions.sdl" +[parts] +"AmtDxe" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.sdl b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.sdl new file mode 100644 index 0000000..86d7fc9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/AmtBootOptions.sdl @@ -0,0 +1,21 @@ +TOKEN + Name = AmtBootOptions_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AMT support in Project" +End + +PATH + Name = "AmtBootOptions_SOURCE" + Help = "AMT Driver files source directory" +End + +ELINK + Name = "/I$(AmtBootOptions_SOURCE)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.cif b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.cif new file mode 100644 index 0000000..295ac90 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.cif @@ -0,0 +1,13 @@ +<component> + name = "AMTDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\AmtBootOptions\Dxe\" + RefName = "AMTDxe" +[files] +"AMTDxe.sdl" +"AMTDxe.mak" +"ActiveManagement.c" +"ActiveManagement.dxs" +"ActiveManagement.h" +"ActiveManagement.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.mak b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.mak new file mode 100644 index 0000000..981a295 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.mak @@ -0,0 +1,58 @@ +# MAK file for the eModule:AMTDxe + +all : AMTDxe + + +AMTDxe : $(BUILD_DIR)\AMTDxe.mak AMTDxeBin + +$(BUILD_DIR)\AMTDxe.mak : $(AMTDxe_DIR)\$(@B).cif $(AMTDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AMTDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + + +AMTDxe_INCLUDES=\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + + +AMTDxe_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=ActiveManagementEntryPoint"\ + /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_BASE_PCI_LIB_PCI_EXPRESS__ \ + + +AMTDxe_LIB_LINKS =\ + $(EDKPROTOCOLLIB)\ + $(ProtocolLib_LIB)\ + $(EFISCRIPTLIB)\ + $(AmtLibDxe_LIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(PchPlatformDxeLib_LIB) + + +AMTDxeBin : $(AMTDxe_LIB_LINKS) $(MeDxe_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\AMTDxe.mak all\ + "MY_INCLUDES=$(AMTDxe_INCLUDES)"\ + "MY_DEFINES=$(AMTDxe_DEFINES)"\ + GUID=D739F969-FB2D-4bc2-AFE7-081327D3FEDE \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(AMTDxe_DIR)\ActiveManagement.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.sdl b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.sdl new file mode 100644 index 0000000..be1bfc0 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/AMTDxe.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = "AMTDxe_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AMT Dxe support in Project" +End +MODULE + Help = "Includes AMTDxe.mak to Project" + File = "AMTDxe.mak" +End + +PATH + Name = "AMTDxe_DIR" + Help = "AMT Driver files source directory" +End + +PATH + Name = "AMTDxe_SOURCE" + Help = "AMT Driver files source directory" +End + +ELINK + Name = "$(BUILD_DIR)\AMTDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.c b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.c new file mode 100644 index 0000000..681bb6b --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.c @@ -0,0 +1,553 @@ +/** @file + Defines and prototypes for the ActiveManagement driver. + This driver implements the ActiveManagement protocol for iAMT. + It provides some functions to get Boot Options from ASF. + +@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 +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "ActiveManagement.h" +#include "MeLib.h" +#include "MeAccess.h" +#endif +// +// Global variables +// +EFI_ASF_BOOT_OPTIONS *mAsfBootOptions; + +ACTIVE_MANAGEMENT_INSTANCE ActiveManagementInstance = { + ACTIVE_MANAGEMENT_PRIVATE_DATA_SIGNATURE, + NULL, + { + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetIderState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetEnforceSecureBootState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetSolState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetRemoteFlashState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetBiosSetupState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetBiosPauseState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetConsoleLockState, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetKvmState, + (EFI_ACTIVE_MANAGEMENT_IDER_BOOT_DEVICE_SELECTED) GetIderBootDeviceSelectd, + (EFI_ACTIVE_MANAGEMENT_ASF_BOOT_OPTIONS_GET) GetAsfBootOptions, + (EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) GetProgressMsgRequest + }, + NULL +}; + +// +// Function implementations +// + +/** + Check if ASF boot options is present. + + @param[in] None. + + @retval True ASF boot option is present. + @retval False ASF boot option is not present +**/ +BOOLEAN +IsBootOptionsPresent ( + VOID + ) +{ + return mAsfBootOptions->SubCommand == ASF_BOOT_OPTIONS_PRESENT; +} + +/** + Check if LANA ID of ASF boot options is Industry ID. + + @param[in] None. + + @retval True IANA ID of ASF boot options is Industry ID. + @retval False IANA ID of ASF boot options is not Industry ID. +**/ +BOOLEAN +IsIndustryIanaId ( + VOID + ) +{ + volatile BOOLEAN RetVal; + + RetVal = FALSE; + if (IsBootOptionsPresent ()) { + if (mAsfBootOptions->IanaId == ASF_INDUSTRY_CONVERTED_IANA) { + RetVal = TRUE; + } + } + + return RetVal; +} + +/** + Check if LANA ID of ASF boot options is Intel ID. + + @param[in] None. + + @retval True IANA ID of ASF boot options is Intel ID. + @retval False IANA ID of ASF boot options is not Intel ID. +**/ +BOOLEAN +IsIntelIanaId ( + VOID + ) +{ + volatile BOOLEAN RetVal; + + RetVal = FALSE; + + if (IsBootOptionsPresent ()) { + if (mAsfBootOptions->IanaId == ASF_INTEL_CONVERTED_IANA) { + RetVal = TRUE; + } + } + + return RetVal; +} + +/** + Check if it is Intel ASF boot options. + + @param[in] None. + + @retval True It is Intel ASF boot options. + @retval False It is not Intel ASF boot options. +**/ +BOOLEAN +IsIntelAmtBootOptions ( + VOID + ) +{ + BOOLEAN RetVal; + + RetVal = FALSE; + + if (IsIntelIanaId ()) { + if (mAsfBootOptions->SpecialCommand == ASF_INTEL_OEM_CMD) { + RetVal = TRUE; + } + } + + return RetVal; +} + +/** + Check the Special Command Parameter of Intel ASF boot options + + @param[in] Options Special Command Parameter bit we want to check + Bit 0: Set if IDER is to be used on the next boot. Parameter 2 is set + to the driver number to be used. + Bit 1: Set if Secure Boot is enforced over IDER + Bit 2: Set if the BIOS is to be re-flashed on the next boot + Bit 3: Set if the BIOS is to boot into the BIOS set-up screen. + Bit 4: Boot into BIOS Pause on the next boot is supported + Bit 5: Set if the BIOS is to participate in KVM session + @param[in] CurrentState Return the state of result + True - Special Command Parameter bit in Options is enabled. + False - Special Command Parameter bit in Options is disabled. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +GetSpecialParamState ( + IN UINT16 Options, + IN OUT BOOLEAN *CurrentState + ) +{ + *CurrentState = FALSE; + if (IsIntelAmtBootOptions ()) { + if ((mAsfBootOptions->SpecialCommandParam & Options) == Options) { + *CurrentState = TRUE; + } + } + + return EFI_SUCCESS; +} + +/** + Check the OEM Parameter of Intel ASF boot options + + @param[in] Options OEM Parameter bit we want to check + Bit 0: Set if SOL is to be used on the next boot. + @param[in] CurrentState Return the state of result + True : OEM Parameter bit in Options is enabled. + False : OEM Parameter bit in Options is disabled. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +GetOemParamatersState ( + IN UINT16 Options, + IN OUT BOOLEAN *CurrentState + ) +{ + *CurrentState = FALSE; + if (IsIntelAmtBootOptions ()) { + if ((mAsfBootOptions->OemParameters & Options) == Options) { + *CurrentState = TRUE; + } + } + + return EFI_SUCCESS; +} + +/** + Check the OEM Parameter of Intel ASF boot options + + @param[in] Options OEM Parameter bit we want to check + Bit 0: Set if SOL is to be used on the next boot. + @param[in] CurrentState Return the state of result + True : OEM Parameter bit in Options is enabled. + False : OEM Parameter bit in Options is disabled. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +GetBootOptionsMaskState ( + IN UINT16 Options, + IN OUT BOOLEAN *CurrentState + ) +{ + *CurrentState = FALSE; + if (IsBootOptionsPresent ()) { + if ((mAsfBootOptions->BootOptions & Options) == Options) { + *CurrentState = TRUE; + } + } + + return EFI_SUCCESS; +} + +/** + This will return IDE Redirection Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of IDE Redireciton Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIderState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (USE_IDER, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return IDE Redirection boot device to boot + + @param[in] This The address of protocol + @param[in] 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 + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIderBootDeviceSelectd ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT UINT8 *IdeBootDevice + ) +{ + *IdeBootDevice = (UINT8) ((mAsfBootOptions->SpecialCommandParam & IDER_BOOT_DEVICE_MASK) >> IDER_BOOT_DEVICE_SHIFT); + return EFI_SUCCESS; +} + +/** + This will return Enforce Secure Boot over IDER Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Enforce Secure Boot over IDER Boot Option + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetEnforceSecureBootState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (ENFORCE_SECURE_BOOT, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Serial-over-Lan Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetSolState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetOemParamatersState (USE_SOL, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return Remote Flash Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Remote Flash Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetRemoteFlashState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (REFLASH_BIOS, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return BIOS Setup Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Setup Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetBiosSetupState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (BIOS_SETUP, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return BIOS Pause Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Pause Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetBiosPauseState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (BIOS_PAUSE, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return Console Lock Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Pause Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetConsoleLockState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetBootOptionsMaskState (LOCK_KEYBOARD, CurrentState); + return EFI_SUCCESS; +} + +/** + This will return KVM Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of KVM Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetKvmState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetSpecialParamState (USE_KVM, CurrentState); + return EFI_SUCCESS; +} + +/** + Return current ASF Boot Options + + @param[in] This Pointer to the EFI_ACTIVE_MANAGEMENT_PROTOCOL instance. + @param[in] AsfBootOptions ASF Boot Options + + @retval EFI_SUCCESS Boot options updated +**/ +EFI_STATUS +EFIAPI +GetAsfBootOptions ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +{ + *AsfBootOptions = mAsfBootOptions; + return EFI_SUCCESS; +} + +/** + Disable these two driver of Sol & Ider + + @param[in] None +**/ +VOID +SolIderDisable ( + VOID + ) +{ + IderDisable (); + SolDisable (); +} + +/** + Disable Usbr + + @param[in] None +**/ +VOID +UsbrDisable ( + VOID + ) +{ + Usbr1Disable (); + Usbr2Disable (); +} + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of progress event Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetProgressMsgRequest ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +{ + GetBootOptionsMaskState (FORCE_PROGRESS_EVENTS, CurrentState); + return EFI_SUCCESS; +} + +/** + Entry point for the Active Management Driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +ActiveManagementEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + /// + /// Check policy if AMT is supported + /// + if (!AmtSupported () || !AsfSupported ()) { + SolIderDisable (); + UsbrDisable (); + return EFI_UNSUPPORTED; + } + /// + /// Get Protocol for ASF + /// + Status = gBS->LocateProtocol ( + &gEfiAlertStandardFormatProtocolGuid, + NULL, + (VOID **) &(ActiveManagementInstance.Asf) + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + /// + /// Get ASF Boot Options + /// + Status = ActiveManagementInstance.Asf->GetBootOptions (ActiveManagementInstance.Asf, &mAsfBootOptions); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + /// + /// Install the EFI_ACTIVE_MANAGEMENT_PROTOCOL interface + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &(ActiveManagementInstance.Handle), + &gEfiActiveManagementProtocolGuid, + &(ActiveManagementInstance.ActiveManagementProtocol), + NULL + ); + + return Status; +} diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.dxs b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.dxs new file mode 100644 index 0000000..6c5fd38 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.dxs @@ -0,0 +1,45 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 2005 - 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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" + +#include EFI_PROTOCOL_DEFINITION (AlertStandardFormat) +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) +#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy) +#endif + +DEPENDENCY_START + EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GUID AND + DXE_PLATFORM_AMT_POLICY_GUID AND + DXE_PLATFORM_ME_POLICY_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.h b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.h new file mode 100644 index 0000000..72bb113 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.h @@ -0,0 +1,272 @@ +/** @file + Header file for the Active Management Driver. + +@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 + +**/ +#ifndef _ACTIVE_MANAGEMENT_H_ +#define _ACTIVE_MANAGEMENT_H_ +#include "Amt.h" +#include "AmtLib.h" + +// +// Used during initialization +// +#include EFI_PROTOCOL_CONSUMER (AlertStandardFormat) + +// +// Driver Produced Protocols +// +#include EFI_PROTOCOL_PRODUCER (ActiveManagement) + +// +// Private data structure definitions for the driver +// +#define ACTIVE_MANAGEMENT_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('A', 'M', 'T', 'P') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_ACTIVE_MANAGEMENT_PROTOCOL ActiveManagementProtocol; + EFI_ALERT_STANDARD_FORMAT_PROTOCOL *Asf; +} ACTIVE_MANAGEMENT_INSTANCE; + +#define ACTIVE_MANAGEMENT_INSTANCE_FROM_ACTIVE_MANAGEMENT_PROTOCOL(a) \ + CR ( \ + a, \ + ACTIVE_MANAGEMENT_INSTANCE, \ + ActiveManagementProtocol, \ + ACTIVE_MANAGEMENT_PRIVATE_DATA_SIGNATURE \ + ) + +// +// Function prototypes used by the AMT protocol. +// + +/** + This will return IDE Redirection Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of IDE Redireciton Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIderState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return IDE Redirection boot device to boot + + @param[in] This The address of protocol + @param[in] 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 + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIderBootDeviceSelectd ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT UINT8 *IdeBootDevice + ) +; + +/** + This will return Enforce Secure Boot over IDER Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Enforce Secure Boot over IDER Boot Option + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetEnforceSecureBootState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return Serial-over-Lan Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Serial-over-Lan Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetSolState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return Remote Flash Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of Remote Flash Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetRemoteFlashState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return BIOS Setup Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Setup Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetBiosSetupState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return BIOS Pause Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Pause Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetBiosPauseState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return Console Lock Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of BIOS Pause Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetConsoleLockState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return KVM Boot Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of KVM Boot Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetKvmState ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + Return current ASF Boot Options + + @param[in] This Pointer to the EFI_ACTIVE_MANAGEMENT_PROTOCOL instance. + @param[in] AsfBootOptions ASF Boot Options + + @retval EFI_SUCCESS Boot options updated +**/ +EFI_STATUS +EFIAPI +GetAsfBootOptions ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +; + +/** + This will return progress event Option. + True if the option is enabled. + + @param[in] This The address of protocol + @param[in] CurrentState Return the state of progress event Opiton + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetProgressMsgRequest ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + Entry point for the Active Management Driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +ActiveManagementEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +#endif diff --git a/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.inf b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.inf new file mode 100644 index 0000000..3dd5fe3 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/AmtBootOptions/Dxe/ActiveManagement.inf @@ -0,0 +1,100 @@ +## @file +# Component description file for the AMT driver. +# +#@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 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 = ActiveManagement +FILE_GUID = D739F969-FB2D-4bc2-AFE7-081327D3FEDE +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + ActiveManagement.h + ActiveManagement.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + AmtLib + MeProtocolLib + MeLib + MeChipsetLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = Activemanagement.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=ActiveManagementEntryPoint + C_FLAGS = $(C_FLAGS) -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__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ + diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.c b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.c new file mode 100644 index 0000000..8465de8 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.c @@ -0,0 +1,927 @@ +/** @file + This driver module produces IDE_CONTROLLER_INIT protocol and will be used by + IDE Bus driver to support platform dependent timing information. This driver + is responsible for early initialization of IDE Redirect controller. + +@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 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 "IdeRController.h" +#include "MeLib.h" +#endif + +/// +/// EFI_DRIVER_BINDING_PROTOCOL instance +/// +EFI_DRIVER_BINDING_PROTOCOL mIdeRControllerDriverBinding = { + IdeRControllerSupported, + IdeRControllerStart, + IdeRControllerStop, + 1, // Version + NULL, // ImageHandle + NULL // DriverBindingHandle +}; + +/** + This function is used to calculate the best PIO mode supported by + specific IDE device + + Since the LPT IDE-R doesn't support changing the timing + registers because they are RO 0x00, we'll just return PIO mode 2. + + @param[in] IdentifyData The identify data of specific IDE device + @param[in] DisPioMode Disqualified PIO modes collection + @param[in] SelectedMode Available PIO modes collection + + @retval EFI_SUCCESS SelectedMode calculated. +**/ +EFI_STATUS +CalculateBestPioMode ( + IN EFI_IDENTIFY_DATA *IdentifyData, + IN UINT16 *DisPioMode OPTIONAL, + OUT UINT16 *SelectedMode + ) +{ + /// + /// ATA_PIO_MODE_2; + /// + *SelectedMode = 2; + + return EFI_SUCCESS; +} + +/** + This function is used to calculate the best UDMA mode supported by + specific IDE device + + Since the LPT IDE-R doesn't support changing the timing + registers because they are RO 0x00, we'll just return DMA mode 2. + + @param[in] IdentifyData The identify data of specific IDE device + @param[in] DisUDmaMode Disqualified UDMA modes collection + @param[in] SelectedMode Available UMDA modes collection + + @retval EFI_SUCCESS SelectedMode calculated. +**/ +EFI_STATUS +CalculateBestUdmaMode ( + IN EFI_IDENTIFY_DATA *IdentifyData, + IN UINT16 *DisUDmaMode OPTIONAL, + OUT UINT16 *SelectedMode + ) +{ + /// + /// ATA_UDMA_MODE_2; + /// + *SelectedMode = 2; + + return EFI_SUCCESS; +} + +/** + This function is used to set appropriate PIO timing on Ide + controller according supported PIO modes + + @param[in] Channel IDE channel number (0 based, either 0 or 1). + For LPT IDE-R there is only one (See IDER_MAX_CHANNEL). + @param[in] Device IDE device number + @param[in] PciIo Pointer to PciIo protocol opened by Ide controller driver + @param[in] IdentifyData The identify struct submitted by IDE device + @param[in] Modes The PIO mode collection supported by IDE device + + @retval EFI_SUCCESS PIO timing initialized or no need to program PIO mode +**/ +EFI_STATUS +IdeInitSetPioTiming ( + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_IDENTIFY_DATA *IdentifyData, + IN EFI_ATA_COLLECTIVE_MODE *Modes + ) +{ + /// + /// Since the Cantiga version of the ME IDER doesn't support registers 40-4F (they are RO), + /// there is no need to program PIO mode. + /// + return EFI_SUCCESS; +} + +/** + This function is used to set appropriate UDMA timing on Ide + controller according supported UDMA modes + + @param[in] Channel IDE channel number (0 based, either 0 or 1). + For LPT IDE-R there is only one (See IDER_MAX_CHANNEL). + @param[in] Device IDE device number + @param[in] PciIo Pointer to PciIo protocol opened by Ide controller driver + @param[in] Modes The UDMA mode collection supported by IDE device + + @retval Status code returned by PciIo operations +**/ +EFI_STATUS +IdeInitSetUdmaTiming ( + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_ATA_COLLECTIVE_MODE *Modes + ) +{ + /// + /// Since the Cantiga version of the ME IDE-R doesn't support registers 40-C7 (they are RO), + /// there is no need to program PIO/UDMA mode. + /// + EFI_STATUS Status; + UINT16 PciCommandReg; + UINT8 BusMasterIdeStatusReg; + + /// + /// PCI Command Register, offset 0x4, default 00 + /// + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + PCI_COMMAND_REGISTER, + 1, + &PciCommandReg + ); + /// + /// Now set the PCH IDE Bus Master Enable bit, one bit for PCH controller + /// If BME bit is not set, set it + /// + if (!(PciCommandReg & BME_BUS_MASTER_ENABLE_BIT)) { + PciCommandReg |= BME_BUS_MASTER_ENABLE_BIT; + + Status = PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint16, + PCI_COMMAND_REGISTER, // offset 0x4 + 1, + &PciCommandReg + ); + } + + Status = PciIo->Io.Read ( + PciIo, + EfiPciIoWidthUint8, + 4, + (Channel == 0 ? 0x2 : 0xA), + 1, + &BusMasterIdeStatusReg + ); + + BusMasterIdeStatusReg = (UINT8) (BusMasterIdeStatusReg | (Device == 0 ? BIT5 : BIT6)); + + Status = PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint8, + 4, + (Channel == 0 ? 0x2 : 0xA), + 1, + &BusMasterIdeStatusReg + ); + + return Status; +} + +/** + This function is called after IdeBus driver submits its EFI_IDENTIFY_DATA data struct + to IDE controller driver. The main purpose is to detect IDE + cable type. + + @param[in] Channel IDE channel number (0 based, either 0 or 1). + For LPT IDE-R there is only one (See IDER_MAX_CHANNEL). + @param[in] Device IDE device number + @param[in] PciIo Pointer to PciIo protocol instance opened by Ide driver + @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure + + @retval EFI_SUCCESS Cable type detected +**/ +EFI_STATUS +IdeDetectCableType ( + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_IDENTIFY_DATA *IdentifyData + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +AdjustUdmaModeByCableType ( + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN OUT EFI_ATA_COLLECTIVE_MODE *Modes + ) +/** + This function is called AFTER IdeBus driver submits its EFI_IDENTIFY_DATA data struct. + The main objective of this function is to adjust best calculated UDMA mode + according to current cable type. LPT IDE-R is hardcoded to 40 pin UDMA-2/33 mode. + Note that the cable reporting bits should be set prior to this function call + + @param[in] Channel IDE channel number (0 based, either 0 or 1). + For LPT IDE-R there is only one (See IDER_MAX_CHANNEL). + @param[in] Device IDE device number + @param[in] PciIo Pointer to PciIo protocol instance opened by Ide driver + @param[in] Modes The current best supported mode calculated by this driver + + @retval EFI_SUCCESS UdmaMode copied +**/ +{ + Modes->UdmaMode.Mode = 2; + return EFI_SUCCESS; +} + +/// +/// Interface functions of IDE_CONTROLLER_INIT protocol +/// + +/** + This function can be used to obtain information about a specified channel. + It's usually used by IDE Bus driver during enumeration process. + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel Channel number (0 based, either 0 or 1) + @param[in] Enabled TRUE if the channel is enabled. If the channel is disabled, + then it will no be enumerated. + @param[in] MaxDevices The Max number of IDE devices that the bus driver can expect + on this channel. For ATA/ATAPI, this number is either 1 or 2. + + @retval EFI_SUCCESS Information copied + @retval EFI_INVALID_PARAMETER Invalid channel +**/ +EFI_STATUS +EFIAPI +IdeInitGetChannelInfo ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + OUT BOOLEAN *Enabled, + OUT UINT8 *MaxDevices + ) +{ + /// + /// Channel number (0 based, either 0 or 1) + /// For LPT IDE-R there is only one (See IDER_MAX_CHANNEL). + /// + if (Channel < IDER_MAX_CHANNEL) { + *Enabled = TRUE; + *MaxDevices = IDER_MAX_DEVICES; + return EFI_SUCCESS; + + } else { + return EFI_INVALID_PARAMETER; + } +} + +/** + This function is called by IdeBus driver before executing certain actions. + This allows IDE Controller Init to prepare for each action. + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Phase Phase indicator defined by IDE_CONTROLLER_INIT protocol + @param[in] Channel Channel number (0 based, either 0 or 1) + + @retval EFI_SUCCESS Preparation done + @retval EFI_INVALID_PARAMETER Invalid channel + @exception EFI_UNSUPPORTED Invalid phase +**/ +EFI_STATUS +EFIAPI +IdeInitNotifyPhase ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase, + IN UINT8 Channel + ) +{ + if (Channel >= IDER_MAX_CHANNEL) { + return EFI_INVALID_PARAMETER; + } + + switch (Phase) { + + case EfiIdeBeforeChannelEnumeration: + case EfiIdeAfterChannelEnumeration: + case EfiIdeBeforeChannelReset: + case EfiIdeAfterChannelReset: + case EfiIdeBusBeforeDevicePresenceDetection: + case EfiIdeBusAfterDevicePresenceDetection: + case EfiIdeResetMode: + /// + /// Do nothing at present + /// + break; + + default: + return EFI_UNSUPPORTED; + break; + } + + return EFI_SUCCESS; +} + +/** + This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure + obtained from IDE deivce. This structure is used to set IDE timing + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure + + @retval EFI_SUCCESS Data submitted + @retval EFI_INVALID_PARAMETER Invalid channel +**/ +EFI_STATUS +EFIAPI +IdeInitSubmitData ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_IDENTIFY_DATA *IdentifyData + ) +{ + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + + if (Channel >= IDER_MAX_CHANNEL || Device >= IDER_MAX_DEVICES) { + return EFI_INVALID_PARAMETER; + } + + IdePrivateData = IDE_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); + ASSERT (IdePrivateData); + + /// + /// Make a local copy of device's IdentifyData and mark the valid flag + /// + if (IdentifyData != NULL) { + CopyMem ( + &(IdePrivateData->IdentifyData[Channel][Device]), + IdentifyData, + sizeof (EFI_IDENTIFY_DATA) + ); + + IdePrivateData->IdentifyValid[Channel][Device] = TRUE; + + /// + /// Detect cable type and set cable type reg once we get identify data + /// + IdeDetectCableType ( + Channel, + Device, + IdePrivateData->PciIo, + &(IdePrivateData->IdentifyData[Channel][Device]) + ); + + } else { + IdePrivateData->IdentifyValid[Channel][Device] = FALSE; + } + + return EFI_SUCCESS; +} + +/** + This function is called by IdeBus driver to disqualify unsupported operation + mode on specfic IDE device + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] BadModes Operation mode indicator + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid BadModes pointer +**/ +EFI_STATUS +EFIAPI +IdeInitDisqualifyMode ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *BadModes + ) +{ + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + + if (Channel >= IDER_MAX_CHANNEL || Device >= IDER_MAX_DEVICES || BadModes == NULL) { + return EFI_INVALID_PARAMETER; + } + + IdePrivateData = IDE_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); + ASSERT (IdePrivateData); + + /// + /// Record the disqualified modes per channel per device. From ATA/ATAPI spec, + /// if a mode is not supported, the modes higher than it is also not + /// supported + /// + CopyMem ( + &(IdePrivateData->DisqulifiedModes[Channel][Device]), + BadModes, + sizeof (EFI_ATA_COLLECTIVE_MODE) + ); + + return EFI_SUCCESS; +} + +/** + This function is called by IdeBus driver to calculate the best operation mode + supported by specific IDE device + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] SupportedModes Modes collection supported by IDE device + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid SupportedModes pointer + @retval EFI_NOT_READY IdentifyData is not valid + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +EFIAPI +IdeInitCalculateMode ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes + ) +{ + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + EFI_IDENTIFY_DATA *IdentifyData; + BOOLEAN IdentifyValid; + EFI_ATA_COLLECTIVE_MODE *DisqulifiedModes; + UINT16 SelectedMode; + EFI_STATUS Status; + + if (Channel >= IDER_MAX_CHANNEL || Device >= IDER_MAX_DEVICES || SupportedModes == NULL) { + return EFI_INVALID_PARAMETER; + } + + IdePrivateData = IDE_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); + ASSERT (IdePrivateData); + + IdentifyData = &(IdePrivateData->IdentifyData[Channel][Device]); + DisqulifiedModes = &(IdePrivateData->DisqulifiedModes[Channel][Device]); + IdentifyValid = IdePrivateData->IdentifyValid[Channel][Device]; + + /// + /// Make sure we've got the valid identify data of the device from SubmitData() + /// + if (!IdentifyValid) { + return EFI_NOT_READY; + } + + *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE)); + if (*SupportedModes == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = CalculateBestPioMode ( + IdentifyData, + (DisqulifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqulifiedModes->PioMode.Mode)) : NULL), + &SelectedMode + ); + if (!EFI_ERROR (Status)) { + (*SupportedModes)->PioMode.Valid = TRUE; + (*SupportedModes)->PioMode.Mode = SelectedMode; + + } else { + (*SupportedModes)->PioMode.Valid = FALSE; + } + + Status = CalculateBestUdmaMode ( + IdentifyData, + (DisqulifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqulifiedModes->UdmaMode.Mode)) : NULL), + &SelectedMode + ); + if (!EFI_ERROR (Status)) { + (*SupportedModes)->UdmaMode.Valid = TRUE; + (*SupportedModes)->UdmaMode.Mode = SelectedMode; + + } else { + (*SupportedModes)->UdmaMode.Valid = FALSE; + } + /// + /// It is only referenced here. + /// + (*SupportedModes)->ExtModeCount = 1; + /// + /// The modes other than PIO and UDMA are not supported by Ide controller + /// + return EFI_SUCCESS; +} + +/** + This function is called by IdeBus driver to set appropriate timing on IDE + controller according supported operation mode + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] Modes IDE device mode + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid Modes pointer + @retval EFI_NOT_READY IdentifyData is not valid + @exception EFI_UNSUPPORTED Failed to set PIO/MDMA/SDMA timing +**/ +EFI_STATUS +EFIAPI +IdeInitSetTiming ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *Modes + ) +{ + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + + if (Channel >= IDER_MAX_CHANNEL || Device >= IDER_MAX_DEVICES || Modes == NULL) { + return EFI_INVALID_PARAMETER; + } + + IdePrivateData = IDE_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); + ASSERT (IdePrivateData); + + /// + /// Make sure we've got the valid identify data of the device from SubmitData() + /// + if (!(IdePrivateData->IdentifyValid[Channel][Device])) { + return EFI_NOT_READY; + } + /// + /// Set UMDA timing + /// + if (Modes->UdmaMode.Valid) { + IdeInitSetUdmaTiming ( + Channel, + Device, + IdePrivateData->PciIo, + Modes + ); + } + /// + /// Set PIO/MDMA/SDMA timing (They generally share the same timing values) + /// + if (Modes->PioMode.Valid) { + IdeInitSetPioTiming ( + Channel, + Device, + IdePrivateData->PciIo, + &(IdePrivateData->IdentifyData[Channel][Device]), + Modes + ); + + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/// +/// IDE-R Controller Binding protocol declaration +/// + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND Relative environment not ready + @exception EFI_UNSUPPORTED The device doesn't support +**/ +EFI_STATUS +EFIAPI +IdeRControllerSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 PciData; + + + /// + /// Ide Controller is a device driver, and should ingore the + /// "RemainingDevicePath" according to EFI spec + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID *) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + /// + /// EFI_ALREADY_STARTED is also an error + /// + return Status; + } + /// + /// Close the protocol because we don't use it here + /// + gBS->CloseProtocol ( + Controller, // handle of the controller + &gEfiDevicePathProtocolGuid, // Porotcol to be closed + This->DriverBindingHandle, // agent of opening the protocol + Controller + ); + + /// + /// Now test the EfiPciIoProtocol + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Now further check the PCI header: Base class (offset 0x0B) and + /// Sub Class (offset 0x0A). This controller should be an Ide controller + /// + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + 0, + sizeof (PciData), + &PciData + ); + + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_UNSUPPORTED; + } + /// + /// Examine IDE-R PCI Configuration table fields + /// + if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || + (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE) || + (PciData.Hdr.VendorId != V_ME_IDER_VENDOR_ID) || + !IS_PCH_LPT_IDER_DEVICE_ID(PciData.Hdr.DeviceId) + ) { + + Status = EFI_UNSUPPORTED; + } + /// + /// Close the I/O Abstraction(s) used to perform the supported test + /// + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +/** + This routine is called right after the .Supported() called and return + EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols + are closed. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures + @retval EFI_DEVICE_ERROR The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +IdeRControllerStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + UINT64 CommandVal; + + /// + /// Now test and open the EfiPciIoProtocol + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + /// + /// Status == 0 - A normal execution flow, SUCCESS and the program proceeds. + /// Status == ALREADY_STARTED - A non-zero Status code returned. It indicates + /// that the protocol has been opened and should be treated as a + /// normal condition and the program proceeds. The Protocol will not + /// opened 'again' by this call. + /// Status != ALREADY_STARTED - Error status, terminate program execution + /// + if (EFI_ERROR (Status)) { + /// + /// EFI_ALREADY_STARTED is also an error + /// + return Status; + } + /// + /// Allocate Ide private data structure + /// + IdePrivateData = AllocatePool (sizeof (EFI_IDE_CONTROLLER_PRIVATE_DATA)); + ASSERT (IdePrivateData != NULL); + if (IdePrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// Initialize IdeR controller private data + /// + ZeroMem (IdePrivateData, sizeof (EFI_IDE_CONTROLLER_PRIVATE_DATA)); + IdePrivateData->Signature = IDER_CONTROLLER_SIGNATURE; + IdePrivateData->PciIo = PciIo; + IdePrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo; + IdePrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase; + IdePrivateData->IdeInit.SubmitData = IdeInitSubmitData; + IdePrivateData->IdeInit.DisqualifyMode = IdeInitDisqualifyMode; + IdePrivateData->IdeInit.CalculateMode = IdeInitCalculateMode; + IdePrivateData->IdeInit.SetTiming = IdeInitSetTiming; + IdePrivateData->IdeInit.EnumAll = IDER_ENUMER_ALL; + IdePrivateData->IdeInit.ChannelCount = IDER_MAX_CHANNEL; + + // + // Get device capabilities + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &CommandVal + ); + ASSERT_EFI_ERROR (Status); + + // + // Enable Command Register + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + CommandVal & EFI_PCI_DEVICE_ENABLE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Install IDE_CONTROLLER_INIT protocol & private data to this instance + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiIderControllerDriverProtocolGuid, + IdePrivateData, + &gEfiIdeControllerInitProtocolGuid, + &(IdePrivateData->IdeInit), + NULL + ); + + return Status; +} + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @exception EFI_UNSUPPORTED Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +IdeRControllerStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + EFI_IDE_CONTROLLER_PRIVATE_DATA *IdePrivateData; + + /// + /// Get private data + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiIderControllerDriverProtocolGuid, + (VOID **) &IdePrivateData, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Close protocols opened by Ide controller driver + /// + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiIderControllerDriverProtocolGuid, + IdePrivateData, + &gEfiIdeControllerInitProtocolGuid, + &(IdePrivateData->IdeInit), + NULL + ); + + FreePool (IdePrivateData); + + return EFI_SUCCESS; +} + +/// +/// IDE-R Controller Driver Entry Point +/// + +/** + Chipset Ide Driver EntryPoint function. It follows the standard EFI driver + model. It's called by StartImage() of DXE Core + + @param[in] ImageHandle - While the driver image loaded be the ImageLoader(), + an image handle is assigned to this driver binary, + all activities of the driver is tied to this ImageHandle + @param[in] SystemTable - A pointer to the system table, for all BS(Boo Services) and + RT(Runtime Services) + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +InitializeIdeRControllerDriver ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.cif b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.cif new file mode 100644 index 0000000..08416f6 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.cif @@ -0,0 +1,13 @@ +<component> + name = "IdeRController" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\IdeR\Dxe\" + RefName = "IdeRController" +[files] +"IdeRController.sdl" +"IdeRController.mak" +"IdeRController.c" +"IdeRControllerName.c" +"IdeRController.h" +"IdeRController.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.h b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.h new file mode 100644 index 0000000..86ab159 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.h @@ -0,0 +1,422 @@ +/** @file + Header file for chipset IDER ATA controller driver. + +@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 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 _IDER_ATA_CONTROLLER_H +#define _IDER_ATA_CONTROLLER_H + +#include "pci22.h" +#include "AmtLib.h" +#include "MeAccess.h" + +// +// Constant definition +// +#include EFI_PROTOCOL_DEFINITION (PciIo) +#include EFI_PROTOCOL_DEFINITION (IdeControllerInit) +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) +#include EFI_PROTOCOL_DEFINITION (IderControllerDriver) + +// +// Global Variables definitions +// +extern EFI_COMPONENT_NAME_PROTOCOL mIdeRControllerName; +extern EFI_DRIVER_BINDING_PROTOCOL mIdeRControllerDriverBinding; + +// +// Symbol definition, for PCI IDE configuration field +// +#define PCI_SUB_CLASS_IDE 0x01 + +#define IDER_MAX_CHANNEL 0x01 ///< Max channels number of single sata controller +#define IDER_MAX_DEVICES 0x02 ///< Max devices number of single sata channel +#define IDER_ENUMER_ALL TRUE + +// +// PIO and DMA Mode Timing and Control Registers definition +// +#define PCI_COMMAND_REGISTER 0x04 +#define PCI_BUS_MASTER_IDE_BASE 0x20 +#define IDE_TIMING_REGISTER_1 0x40 +#define IDE_TIMING_REGISTER_2 0x42 +#define IDE_SLAVE_TIMING_REGISTER 0x44 +#define ULTRA_DMA_CONTROL_REGISTER 0x48 +#define ULTRA_DMA_TIMING_REGISTER 0x4A +#define IDE_IO_CONFIG_REGISTER 0x54 + +#define R_PCI_SVID 0x2C + +// +// IDE Register Field definition +// +#define ENABLE_DECODE_PRIMARY 0x8000 + +#define BME_BUS_MASTER_ENABLE_BIT BIT2 + +// +// Ide Timing Register 1/2 Field offset 0x40-41 / 0x42-43 +// +#define DTE0_DRIVE_0_DMA_TIMING_ENABLE bit3 +#define DTE1_DRIVE_1_DMA_TIMING_ENABLE bit7 + +// +// UDMA Control Register field offset 0x48 +// +#define PSDE0_PRIMARY_DRIVE_0_UDMA_ENABLE bit0 +#define PSDE1_PRIMARY_DRIVE_1_UDMA_ENABLE bit1 +#define SSDE0_SECONDARY_DRIVE_0_UDMA_ENABLE bit2 +#define SSDE1_SECONDARY_DRIVE_1_UDMA_ENABLE bit3 + +// +// UDMA Timing Register +// +#define CT4_RP6 0x00 +#define CT3_RP5 0x01 +#define CT2_RP4 0x02 + +#define CT3_RP8 0x01 +#define CT2_RP8 0x02 + +#define CT3_RP16 0x01 + +// +// Ide I/O Configuration Register Field offset 0x54 +// +#define PCB0_PRIMARY_DRIVE_0_BASE_CLOCK bit0 +#define PCB1_PRIMARY_DRIVE_1_BASE_CLOCK bit1 +#define SCB0_SECONDARY_DRIVE_0_BASE_CLOCK bit2 +#define SCB1_SECONDARY_DRIVE_1_BASE_CLOCK bit3 +#define ATA_FAST_PCB0_PRIMARY_DRIVE_0 bit12 +#define ATA_FAST_PCB1_PRIMARY_DRIVE_1 bit13 +#define ATA_FAST_SCB0_SECONDARY_DRIVE_0 bit14 +#define ATA_FAST_SCB1_SECONDARY_DRIVE_1 bit15 + +// +// PCH timing register structure +// +#pragma pack(1) + +typedef struct _IDER_TIMING_REG { + // + // PIO/MDMA/SDMA timing control for drive 0 + // + UINT16 Time0 : 1; + UINT16 Ie0 : 1; + UINT16 Ppe0 : 1; + UINT16 Dte0 : 1; + + // + // PIO/MDMA/SDMA timing control for drive 1 + // + UINT16 Time1 : 1; + UINT16 Ie1 : 1; + UINT16 Ppe1 : 1; + UINT16 Dte1 : 1; + + // + // PIO/MDMA/SDMA timing + // + UINT16 RecoveryTime : 2; + UINT16 Reserved0 : 2; + UINT16 IoRdySample : 2; + UINT16 Sitre : 1; + UINT16 IdeDecode : 1; + +} IDER_TIMING_REG; + +typedef struct _IDER_SLAVE_TIMING_REG { + // + // PIO/MDMA/SDMA timing control for primary slave device + // + UINT16 PrimaryRecoveryTime : 2; + UINT16 PrimaryIoRdySample : 2; + + // + // PIO/MDMA/SDMA timing control for secondary slave device + // + UINT16 SecondaryRecoveryTime : 2; + UINT16 SecondaryIoRdySample : 2; + +} IDER_SLAVE_TIMING_REG; + +#pragma pack() + +#define IDER_CONTROLLER_SIGNATURE EFI_SIGNATURE_32 ('I', 'D', 'E', 'R') + +/// +/// Ide controller driver private data structure +/// +typedef struct _EFI_IDE_CONTROLLER_PRIVATE_DATA { + /// + /// Standard signature used to identify Ide controller private data + /// + UINT32 Signature; + + /// + /// Protocol instance of IDE_CONTROLLER_INIT produced by this driver + /// + EFI_IDE_CONTROLLER_INIT_PROTOCOL IdeInit; + + /// + /// copy of protocol pointers used by this driver + /// + EFI_PCI_IO_PROTOCOL *PciIo; + + /// + /// The highest disqulified mode for each attached Ide device. + /// Per ATA/ATAPI spec, if a mode is not supported, the modes higher than + /// it should not be supported + /// + EFI_ATA_COLLECTIVE_MODE DisqulifiedModes[IDER_MAX_CHANNEL][IDER_MAX_DEVICES]; + + /// + /// A copy of EFI_IDENTIFY_DATA data for each attached Ide device and its flag + /// + EFI_IDENTIFY_DATA IdentifyData[IDER_MAX_CHANNEL][IDER_MAX_DEVICES]; + BOOLEAN IdentifyValid[IDER_MAX_CHANNEL][IDER_MAX_DEVICES]; +} EFI_IDE_CONTROLLER_PRIVATE_DATA; + +#define IDE_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) \ + CR ( \ + a, \ + EFI_IDE_CONTROLLER_PRIVATE_DATA, \ + IdeInit, \ + IDER_CONTROLLER_SIGNATURE \ + ) + +// +// IDE-R controller IDE_CONTROLLER_INIT protocol declaration +// + +/** + This function can be used to obtain information about a specified channel. + It's usually used by IDE Bus driver during enumeration process. + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel Channel number (0 based, either 0 or 1) + @param[in] Enabled TRUE if the channel is enabled. If the channel is disabled, + then it will no be enumerated. + @param[in] MaxDevices The Max number of IDE devices that the bus driver can expect + on this channel. For ATA/ATAPI, this number is either 1 or 2. + + @retval EFI_SUCCESS Information copied + @retval EFI_INVALID_PARAMETER Invalid channel +**/ +EFI_STATUS +EFIAPI +IdeInitGetChannelInfo ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + OUT BOOLEAN *Enabled, + OUT UINT8 *MaxDevices + ) +; + +/** + This function is called by IdeBus driver before executing certain actions. + This allows IDE Controller Init to prepare for each action. + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Phase Phase indicator defined by IDE_CONTROLLER_INIT protocol + @param[in] Channel Channel number (0 based, either 0 or 1) + + @retval EFI_SUCCESS Preparation done + @retval EFI_INVALID_PARAMETER Invalid channel + @exception EFI_UNSUPPORTED Invalid phase +**/ +EFI_STATUS +EFIAPI +IdeInitNotifyPhase ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase, + IN UINT8 Channel + ) +; + +/** + This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure + obtained from IDE deivce. This structure is used to set IDE timing + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure + + @retval EFI_SUCCESS Data submitted + @retval EFI_INVALID_PARAMETER Invalid channel +**/ +EFI_STATUS +EFIAPI +IdeInitSubmitData ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_IDENTIFY_DATA *IdentifyData + ) +; + +/** + This function is called by IdeBus driver to disqualify unsupported operation + mode on specfic IDE device + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] BadModes Operation mode indicator + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid BadModes pointer +**/ +EFI_STATUS +EFIAPI +IdeInitDisqualifyMode ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *BadModes + ) +; + +/** + This function is called by IdeBus driver to calculate the best operation mode + supported by specific IDE device + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] SupportedModes Modes collection supported by IDE device + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid SupportedModes pointer + @retval EFI_NOT_READY IdentifyData is not valid + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures +**/ +EFI_STATUS +EFIAPI +IdeInitCalculateMode ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes + ) +; + +/** + This function is called by IdeBus driver to set appropriate timing on IDE + controller according supported operation mode + + @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel IDE channel number (0 based, either 0 or 1) + @param[in] Device IDE device number + @param[in] Modes IDE device mode + + @retval EFI_SUCCESS Disqulified Modes recorded + @retval EFI_INVALID_PARAMETER Invalid channel or invalid Modes pointer + @retval EFI_NOT_READY IdentifyData is not valid + @exception EFI_UNSUPPORTED Failed to set PIO/MDMA/SDMA timing +**/ +EFI_STATUS +EFIAPI +IdeInitSetTiming ( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *Modes + ) +; + +// +// IDE-R Controller Binding protocol declaration +// + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND Relative environment not ready + @exception EFI_UNSUPPORTED The device doesn't support +**/ +EFI_STATUS +EFIAPI +IdeRControllerSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + This routine is called right after the .Supported() called and return + EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols + are closed. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures + @retval EFI_DEVICE_ERROR The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +IdeRControllerStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @exception EFI_UNSUPPORTED Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +IdeRControllerStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +#endif // _IDER_ATA_CONTROLLER_H diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.inf b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.inf new file mode 100644 index 0000000..954e20e --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.inf @@ -0,0 +1,86 @@ +## @file +# Component description file for IDE-R Controller Driver module. +# +#@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 = IdeRController +FILE_GUID = C4F2D007-37FD-422d-B63D-7ED73886E6CA +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + IdeRController.h + IdeRController.c + IdeRControllerName.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Include + $(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 + +# +# 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] + MeGuidLib + AmtLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiLib + EdkIIGlueUefiDriverModelLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeIdeRControllerDriver \ + -D __EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mIdeRControllerDriverBinding \ + -D __EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mIdeRControllerName + 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__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.mak b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.mak new file mode 100644 index 0000000..e7abc52 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.mak @@ -0,0 +1,55 @@ +# MAK file for the ModulePart:IdeRController +all : IdeRController + +$(BUILD_DIR)\IdeRController.mak : $(IdeRController_DIR)\$(@B).cif $(IdeRController_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(IdeRController_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +IdeRController : $(BUILD_DIR)\IdeRController.mak IdeRControllerBin + +IdeRController_INCLUDES=\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(EDK_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + +IdeRController_DEFINES=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeIdeRControllerDriver"\ + /D"__EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mIdeRControllerDriverBinding"\ + /D"__EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mIdeRControllerName"\ + /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_LIB__ \ + /D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ + +IdeRController_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(AmtGuidLib_LIB)\ + $(AmtLibDxe_LIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueUefiDriverModelLib_LIB)\ + + +IdeRControllerBin : $(IdeRController_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\IdeRController.mak all \ + "MY_INCLUDES=$(IdeRController_INCLUDES)"\ + "MY_DEFINES=$(IdeRController_DEFINES)"\ + GUID=C4F2D007-37FD-422d-B63D-7ED73886E6CA \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + COMPRESS=1 diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.sdl b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.sdl new file mode 100644 index 0000000..b73480f --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRController.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "IdeRController_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable IdeRController support in Project" +End +MODULE + Help = "Includes IdeRController.mak to Project" + File = "IdeRController.mak" +End + +PATH + Name = "IdeRController_DIR" + Help = "iAMT IdeRController file source directory" +End + +ELINK + Name = "$(BUILD_DIR)\IdeRController.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRControllerName.c b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRControllerName.c new file mode 100644 index 0000000..15f3bf9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/IdeR/Dxe/IdeRControllerName.c @@ -0,0 +1,172 @@ +/** @file + This portion is to register the IDE Redirect Controller Driver name + +@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 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 "IdeRController.h" +#endif + +// +// Forward reference declaration +// +EFI_STATUS +EFIAPI +IdeRControllerGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +IdeRControllerGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +/// +/// EFI Component Name Protocol +/// This portion declares a gloabl variable of EFI_COMPONENT_NAME_PROTOCOL type. +/// It initializes the followings: +/// - GetDriverName() to PlatformIdeGetDriverName() +/// - SupportedLanguages to "eng" (3 char ISO639-2 language indetifier) +/// +EFI_COMPONENT_NAME_PROTOCOL mIdeRControllerName = { + IdeRControllerGetDriverName, + IdeRControllerGetControllerName, + "eng" // English +}; + +// +// Define the Driver's unicode name string +// IDE controller Driver name string and IDE Controller Name string +// +static EFI_UNICODE_STRING_TABLE mIdeRControllerDriverNameTable[] = { + { + "eng", + L"IDER Controller Init Driver" + }, + { + NULL, + NULL + } +}; + +static EFI_UNICODE_STRING_TABLE mIdeRControllerControllerNameTable[] = { + { + "eng", + L"IDER Controller" + }, + { + NULL, + NULL + } +}; + +/** + This is a function definition of EFI_COMPONENT_NAME_PROTOCOL.GetDriverName(). This function + is to provide the user readable name of IDE Driver, defined in mPlaformIdeNameTable + This function is called by the platform management utilities to display the name of component. + + @param[in] This The address of protocol + @param[in] Language If the caller specificed Language matches SupportedLanguage, a pointer + to the Driver name is returned in the DriverName. + @param[in] DriverName If the caller specificed Language matches SupportedLanguage, a pointer + to the Driver name is returned in the DriverName. + + @retval EFI_SUCCESS If the caller specificed Language matches SupportedLanguage. + i.e. Language == gPlatformIdeName.SupportedLanguages + @exception EFI_UNSUPPORTED If the caller specificed Language doesn't match SupportedLanguage. +**/ +EFI_STATUS +EFIAPI +IdeRControllerGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + + return LookupUnicodeString ( + Language, + mIdeRControllerName.SupportedLanguages, + mIdeRControllerDriverNameTable, + DriverName + ); + +} + +/** + Retrieves a Unicode string that is the user readable name of + the controller that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[in] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language + specified by Language from the point of view of the + driver specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. Language + or ControllerName is NULL. + @exception EFI_UNSUPPORTED The driver specified by this is not currently + managing the controller specified by + ControllerHandle and ChildHandle. Or the driver + specified by This does not support the language specified + by Language. +**/ +EFI_STATUS +EFIAPI +IdeRControllerGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return LookupUnicodeString ( + Language, + mIdeRControllerName.SupportedLanguages, + mIdeRControllerControllerNameTable, + ControllerName + ); +} diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c new file mode 100644 index 0000000..3e6ba9f --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c @@ -0,0 +1,187 @@ +/** @file + This portion is to register the Serial over Lan Controller Driver name + +@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 +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "PciSerial.h" +#endif +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +PciSerialComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +PciSerialComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL mPciSerialComponentName = { + PciSerialComponentNameGetDriverName, + PciSerialComponentNameGetControllerName, + "eng" +}; + +static EFI_UNICODE_STRING_TABLE mPciSerialDriverNameTable[] = { + { + "eng", + L"PCI Serial Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[in] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned in DriverName. + @retval EFI_INVALID_PARAMETER Language or DriverName is NULL. + @exception EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. +**/ +EFI_STATUS +EFIAPI +PciSerialComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString ( + Language, + mPciSerialComponentName.SupportedLanguages, + mPciSerialDriverNameTable, + DriverName + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[in] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language + specified by Language from the point of view of the + driver specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. Language or + ControllerName is NULL. + @exception EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. The driver specified by This + does not support the language specified by Language. +**/ +EFI_STATUS +EFIAPI +PciSerialComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + SERIAL_DEV *SerialDevice; + + /// + /// This is a device driver, so ChildHandle must be NULL. + /// + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + /// + /// Get the Block I/O Protocol on Controller + /// + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + mPciSerialControllerDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Get the Serial Controller's Device structure + /// + SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); + + return LookupUnicodeString ( + Language, + mPciSerialComponentName.SupportedLanguages, + SerialDevice->ControllerNameTable, + ControllerName + ); +} diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c new file mode 100644 index 0000000..6dba7fa --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c @@ -0,0 +1,1807 @@ +/** @file + PCI Serial driver for standard UARTS on an PCI bus. + Customized for Intel AMT SErial OVer LAN (82573E-Tekoa) 16550 UART Driver. + +@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 +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "PciSerial.h" +#include "MeAccess.h" +#endif + +// +// PCI Serial Driver Binding Protocol +// +EFI_DRIVER_BINDING_PROTOCOL mPciSerialControllerDriverBinding = { + PciSerialControllerDriverSupported, + PciSerialControllerDriverStart, + PciSerialControllerDriverStop, + 0x10, + NULL, + NULL +}; + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND The device doesn't support or relative environment not ready +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + UART_DEVICE_PATH UartNode; + UINT16 Buffer[2]; + UINT16 Temp; + UINT8 *ByteBuffer; + + /// + /// Init AMT library + /// + Status = AmtLibInit (); + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// We don't want the SOL Controller enabled unless + /// there is an remote control request. The AMT usage model + /// dictates this. Thus here we check for the ASF Remote + /// Control command wants SOL before we start the controller. + /// + if (ActiveManagementEnableSol () == FALSE) { + return EFI_NOT_FOUND; + } + /// + /// Open the IO Abstraction(s) needed to perform the supported test + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + /// + /// Now test the EfiPciIoProtocol + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Use the PCI I/O Protocol to see if Controller is standard ISA UART that + /// can be managed by this driver. + /// + Status = EFI_SUCCESS; + + /// + /// Looks for a PCI CLASS / SUBCLASS / INTERFACE of 0x07 / 0x00 / 0x02 + /// To allow supportting all PCI Devices that are 16550 compatible UARTS. + /// + /// This is point where Tekoa iAMT SOL support enabling via + /// Get Boot Options ASF info is used to customize PCISerial + /// to work for iAMT. + /// + /// Also if want general PCI Serial com devices to work as well + /// can duplicate this driver one for tekoa and iAMT and the other + /// for general serial devices. + /// + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + (UINT32) PCI_VENDOR_ID_OFFSET, + (UINTN) 1, + (VOID *) &Buffer + ); + /// + /// If Buffer is Not Valid (no setup info in NVRAM/FLASH) use auto mode for PTBx cfg. + /// + if ((Buffer[0] != V_ME_SOL_VENDOR_ID) || !IS_PCH_LPT_SOL_DEVICE_ID(Buffer[1]) + ) { + Status = EFI_UNSUPPORTED; + goto Error; + } + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + (UINT32) PCI_REVISION_ID_OFFSET, + (UINTN) 1, + (VOID *) &Buffer + ); + ByteBuffer = (UINT8 *) Buffer; + if ((ByteBuffer[3] != PCI_CLASS_SCC) || (ByteBuffer[2] != PCI_SUBCLASS_SERIAL) || (ByteBuffer[1] != PCI_IF_16550)) { + Status = EFI_UNSUPPORTED; + goto Error; + } + /// + /// Make sure the PCI io space is enabled + /// + Temp = 0x0003; + PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint16, + PCI_COMMAND_OFFSET, + 0x01, + (VOID*) &Temp + ); + + /// + /// Make sure RemainingDevicePath is valid + /// + if (RemainingDevicePath != NULL) { + Status = EFI_UNSUPPORTED; + CopyMem (&UartNode, (UART_DEVICE_PATH *) RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + if (UartNode.Header.Type != MESSAGING_DEVICE_PATH || + UartNode.Header.SubType != MSG_UART_DP || + DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode) != sizeof (UART_DEVICE_PATH) + ) { + goto Error; + } + + if (UartNode.BaudRate > SERIAL_PORT_MAX_BAUD_RATE) { + goto Error; + } + + if (UartNode.Parity < NoParity || UartNode.Parity > SpaceParity) { + goto Error; + } + + if (UartNode.DataBits < 5 || UartNode.DataBits > 8) { + goto Error; + } + + if (UartNode.StopBits < OneStopBit || UartNode.StopBits > TwoStopBits) { + goto Error; + } + + if ((UartNode.DataBits == 5) && (UartNode.StopBits == TwoStopBits)) { + goto Error; + } + + if ((UartNode.DataBits >= 6) && (UartNode.DataBits <= 8) && (UartNode.StopBits == OneFiveStopBits)) { + goto Error; + } + + Status = EFI_SUCCESS; + } + +Error: + /// + /// Close the I/O Abstraction(s) used to perform the supported test + /// + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; +} + +/** + This routine is called right after the .Supported() called + and return EFI_SUCCESS. Notes: The supported protocols are + checked but the Protocols are closed. + + @param[in] This A pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval Other The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + SERIAL_DEV *SerialDevice; + UINTN Index; + UART_DEVICE_PATH Node; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + CHAR16 SerialPortName[sizeof (PCI_SERIAL_PORT_NAME)]; + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; + UINTN EntryCount; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + UINT64 *Supports; + UINT64 Temp; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + VOID **Resources; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Temp1; + + SerialDevice = NULL; + + /// + /// Get the Parent Device Path + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + /// + /// Grab the IO abstraction we need to get any work done + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + goto Error; + } + + if (Status == EFI_ALREADY_STARTED) { + + if (RemainingDevicePath == NULL) { + return EFI_SUCCESS; + } + /// + /// Make sure a child handle does not already exist. This driver can only + /// produce one child per serial port. + /// + Status = gBS->OpenProtocolInformation ( + Controller, + &gEfiPciIoProtocolGuid, + &OpenInfoBuffer, + &EntryCount + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = EFI_ALREADY_STARTED; + for (Index = 0; Index < EntryCount; Index++) { + if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) { + Status = gBS->OpenProtocol ( + OpenInfoBuffer[Index].ControllerHandle, + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + Status = SerialIo->SetAttributes ( + SerialIo, + Node.BaudRate, + SerialIo->Mode->ReceiveFifoDepth, + SerialIo->Mode->Timeout, + Node.Parity, + Node.DataBits, + Node.StopBits + ); + } + break; + } + } + + FreePool (OpenInfoBuffer); + return Status; + } + /// + /// Initialize the serial device instance + /// + SerialDevice = AllocatePool (sizeof (SERIAL_DEV)); + if (SerialDevice == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + ZeroMem (SerialDevice, sizeof (SERIAL_DEV)); + + SerialDevice->PciIo = PciIo; + SerialDevice->ParentDevicePath = ParentDevicePath; + SerialDevice->ControllerNameTable = NULL; + + StrCpy (SerialPortName, L"PCI Serial Port # "); + SerialPortName[sizeof (PCI_SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0'); + AddUnicodeString ( + "eng", + mPciSerialComponentName.SupportedLanguages, + &SerialDevice->ControllerNameTable, + (CHAR16 *) SerialPortName + ); + + Ptr = &Temp1; + Resources = (VOID **) &Ptr; + Supports = &Temp; + *Supports = 0x01; + for (Index = 0; Index < PCI_MAX_BAR; Index++) { + Status = SerialDevice->PciIo->GetBarAttributes ( + PciIo, + (UINT8) Index, + Supports, + Resources + ); + Ptr = *Resources; + if (Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { + SerialDevice->BarIndex = (UINT16) Index; + Status = EFI_SUCCESS; + break; + } + } + + if (PciSerialPortPresent (SerialDevice) != TRUE) { + Status = EFI_DEVICE_ERROR; + goto Error; + } + + SerialDevice->Signature = SERIAL_DEV_SIGNATURE; + SerialDevice->Type = UART16450; + SerialDevice->SoftwareLoopbackEnable = FALSE; + SerialDevice->HardwareFlowControl = FALSE; + SerialDevice->Handle = NULL; + SerialDevice->Receive.First = 0; + SerialDevice->Receive.Last = 0; + SerialDevice->Receive.Surplus = SERIAL_MAX_BUFFER_SIZE; + SerialDevice->Transmit.First = 0; + SerialDevice->Transmit.Last = 0; + SerialDevice->Transmit.Surplus = SERIAL_MAX_BUFFER_SIZE; + + /// + /// Serial I/O + /// + SerialDevice->SerialIo.Revision = EFI_SERIAL_IO_PROTOCOL_REVISION; + SerialDevice->SerialIo.Reset = PciSerialReset; + SerialDevice->SerialIo.SetAttributes = PciSerialSetAttributes; + SerialDevice->SerialIo.SetControl = PciSerialSetControl; + SerialDevice->SerialIo.GetControl = PciSerialGetControl; + SerialDevice->SerialIo.Write = PciSerialWrite; + SerialDevice->SerialIo.Read = PciSerialRead; + SerialDevice->SerialIo.Mode = &(SerialDevice->SerialMode); + + if (RemainingDevicePath != NULL) { + /// + /// Match the configuration of the RemainingDevicePath. IsHandleSupported() + /// already checked to make sure the RemainingDevicePath contains settings + /// that we can support. + /// + CopyMem (&SerialDevice->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + } else { + /// + /// Build the device path by appending the UART node to the ParentDevicePath + /// from the WinNtIo handle. The Uart setings are zero here, since + /// SetAttribute() will update them to match the default setings. + /// + ZeroMem (&SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH)); + SerialDevice->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH; + SerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP; + SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH)); + } + /// + /// Build the device path by appending the UART node to the ParentDevicePath + /// from the WinNtIo handle. The Uart setings are zero here, since + /// SetAttribute() will update them to match the current setings. + /// + SerialDevice->DevicePath = AppendDevicePathNode ( + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath + ); + + if (SerialDevice->DevicePath == NULL) { + Status = EFI_DEVICE_ERROR; + goto Error; + } + /// + /// Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults. + /// + SerialDevice->SerialMode.ControlMask = SERIAL_PORT_DEFAULT_CONTROL_MASK; + SerialDevice->SerialMode.Timeout = SERIAL_PORT_DEFAULT_TIMEOUT; + SerialDevice->SerialMode.BaudRate = SerialDevice->UartDevicePath.BaudRate; + SerialDevice->SerialMode.ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH; + SerialDevice->SerialMode.DataBits = SerialDevice->UartDevicePath.DataBits; + SerialDevice->SerialMode.Parity = SerialDevice->UartDevicePath.Parity; + SerialDevice->SerialMode.StopBits = SerialDevice->UartDevicePath.StopBits; + + /// + /// Issue a reset to initialize the COM port + /// + Status = SerialDevice->SerialIo.Reset (&SerialDevice->SerialIo); + if (EFI_ERROR (Status)) { + Status = EFI_SUCCESS; + goto Error; + } + /// + /// Install protocol interfaces for the serial device. + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &SerialDevice->Handle, + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + &gEfiSerialIoProtocolGuid, + &SerialDevice->SerialIo, + NULL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + /// + /// Open For Child Device + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + SerialDevice->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + +Error: + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + if (SerialDevice) { + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + FreeUnicodeStringTable (SerialDevice->ControllerNameTable); + FreePool (SerialDevice); + } + } + + return Status; +} + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @retval EFI_DEVICE_ERROR Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + SERIAL_DEV *SerialDevice; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status = gBS->HandleProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath + ); + + /// + /// Complete all outstanding transactions to Controller. + /// Don't allow any new transaction to Controller to be started. + /// + if (NumberOfChildren == 0) { + /// + /// Close the bus driver + /// + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + Status = gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + AllChildrenStopped = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + Status = gBS->OpenProtocol ( + ChildHandleBuffer[Index], + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + + SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); + + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ChildHandleBuffer[Index] + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + &gEfiSerialIoProtocolGuid, + &SerialDevice->SerialIo, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + ChildHandleBuffer[Index], + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + } else { + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + FreeUnicodeStringTable (SerialDevice->ControllerNameTable); + FreePool (SerialDevice); + } + } + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (AllChildrenStopped == FALSE) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Detect whether specific FIFO is full or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is full + @retval FALSE The FIFO is not full +**/ +BOOLEAN +PciSerialFifoFull ( + IN SERIAL_DEV_FIFO *Fifo + ) +{ + if (Fifo->Surplus == 0) { + return TRUE; + } + + return FALSE; +} + +/** + Detect whether specific FIFO is empty or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is empty + @retval FALSE The FIFO is not empty +**/ +BOOLEAN +PciSerialFifoEmpty ( + IN SERIAL_DEV_FIFO *Fifo + ) +{ + if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) { + return TRUE; + } + + return FALSE; +} + +/** + Add data to specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data added to FIFO + + @retval EFI_SUCCESS Add data to specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to add data because FIFO is already full +**/ +EFI_STATUS +PciSerialFifoAdd ( + IN SERIAL_DEV_FIFO *Fifo, + IN UINT8 Data + ) +{ + /// + /// if FIFO full can not add data + /// + if (PciSerialFifoFull (Fifo)) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// FIFO is not full can add data + /// + Fifo->Data[Fifo->Last] = Data; + Fifo->Surplus--; + Fifo->Last++; + if (Fifo->Last == SERIAL_MAX_BUFFER_SIZE) { + Fifo->Last = 0; + } + + return EFI_SUCCESS; +} + +/** + Remove data from specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data removed from FIFO + + @retval EFI_SUCCESS Remove data from specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to remove data because FIFO is empty +**/ +EFI_STATUS +PciSerialFifoRemove ( + IN SERIAL_DEV_FIFO *Fifo, + OUT UINT8 *Data + ) +{ + /// + /// if FIFO is empty, no data can remove + /// + if (PciSerialFifoEmpty (Fifo)) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// FIFO is not empty, can remove data + /// + *Data = Fifo->Data[Fifo->First]; + Fifo->Surplus++; + Fifo->First++; + if (Fifo->First == SERIAL_MAX_BUFFER_SIZE) { + Fifo->First = 0; + } + + return EFI_SUCCESS; +} + +/** + Reads and writes all avaliable data. + + @param[in] SerialDevice The device to flush + + @retval EFI_SUCCESS Data was read/written successfully. + @retval EFI_OUT_OF_RESOURCES Failed because software receive FIFO is full. Note, when + this happens, pending writes are not done. +**/ +EFI_STATUS +PciSerialReceiveTransmit ( + IN SERIAL_DEV *SerialDevice + ) +{ + SERIAL_PORT_LSR Lsr; + UINT8 Data; + BOOLEAN ReceiveFifoFull; + SERIAL_PORT_MSR Msr; + SERIAL_PORT_MCR Mcr; + UINTN TimeOut; + + Data = 0; + + /// + /// Begin the read or write + /// + if (SerialDevice->SoftwareLoopbackEnable) { + do { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + if (!PciSerialFifoEmpty (&SerialDevice->Transmit)) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + if (ReceiveFifoFull) { + return EFI_OUT_OF_RESOURCES; + } + + PciSerialFifoAdd (&SerialDevice->Receive, Data); + } + } while (!PciSerialFifoEmpty (&SerialDevice->Transmit)); + } else { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + do { + Lsr.Data = READ_LSR (SerialDevice->PciIo, SerialDevice->BarIndex); +#ifdef EFI_NT_EMULATOR + /// + /// This is required for NT to avoid a forever-spin... + /// This would be better if READ_LSR was a polling operation + /// that would timeout. + /// + Lsr.Bits.THRE = 1; +#endif + /// + /// Flush incomming data to prevent a an overrun during a long write + /// + if (Lsr.Bits.DR && !ReceiveFifoFull) { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + if (!ReceiveFifoFull) { + if (Lsr.Bits.FIFOE || Lsr.Bits.OE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) { + if (Lsr.Bits.FIFOE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) { + Data = READ_RBR (SerialDevice->PciIo, SerialDevice->BarIndex); + continue; + } + } + /// + /// Make sure the receive data will not be missed, Assert DTR + /// + if (SerialDevice->HardwareFlowControl) { + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC &= 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + + Data = READ_RBR (SerialDevice->PciIo, SerialDevice->BarIndex); + + /// + /// Deassert DTR + /// + if (SerialDevice->HardwareFlowControl) { + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + + PciSerialFifoAdd (&SerialDevice->Receive, Data); + + continue; + } + } + /// + /// Do the write + /// + if (Lsr.Bits.THRE && !PciSerialFifoEmpty (&SerialDevice->Transmit)) { + /// + /// Make sure the transmit data will not be missed + /// + if (SerialDevice->HardwareFlowControl) { + /// + /// Send RTS + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.RTS |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + /// + /// Wait for CTS + /// + TimeOut = 0; + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + while (!Msr.Bits.CTS) { + gBS->Stall (TIMEOUT_STALL_INTERVAL); + TimeOut++; + if (TimeOut > 5) { + break; + } + + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + } + + if (Msr.Bits.CTS) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + WRITE_THR (SerialDevice->PciIo, SerialDevice->BarIndex, Data); + } + } + /// + /// write the data out + /// + if (!SerialDevice->HardwareFlowControl) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + WRITE_THR (SerialDevice->PciIo, SerialDevice->BarIndex, Data); + } + /// + /// Make sure the transmit data will not be missed + /// + if (SerialDevice->HardwareFlowControl) { + /// + /// Assert RTS + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.RTS &= 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + } + } while (Lsr.Bits.THRE && !PciSerialFifoEmpty (&SerialDevice->Transmit)); + } + + return EFI_SUCCESS; +} + +/// +/// Interface Functions +/// + +/** + Reset serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + + @retval EFI_SUCCESS Reset successfully + @retval EFI_DEVICE_ERROR Failed to reset +**/ +EFI_STATUS +EFIAPI +PciSerialReset ( + IN EFI_SERIAL_IO_PROTOCOL *This + ) +{ + EFI_STATUS Status; + SERIAL_DEV *SerialDevice; + SERIAL_PORT_LCR Lcr; + SERIAL_PORT_IER Ier; + SERIAL_PORT_MCR Mcr; + SERIAL_PORT_FCR Fcr; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + /// + /// Make sure DLAB is 0. + /// + Lcr.Data = READ_LCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Lcr.Bits.DLAB = 0; + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Turn off all interrupts + /// + Ier.Data = READ_IER (SerialDevice->PciIo, SerialDevice->BarIndex); + Ier.Bits.RAVIE = 0; + Ier.Bits.THEIE = 0; + Ier.Bits.RIE = 0; + Ier.Bits.MIE = 0; + WRITE_IER (SerialDevice->PciIo, SerialDevice->BarIndex, Ier.Data); + + /// + /// Disable the FIFO. + /// + Fcr.Bits.TRFIFOE = 0; + WRITE_FCR (SerialDevice->PciIo, SerialDevice->BarIndex, Fcr.Data); + + /// + /// Turn off loopback and disable device interrupt. + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.OUT1 = 0; + Mcr.Bits.OUT2 = 0; + Mcr.Bits.LME = 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + /// + /// Clear the scratch pad register + /// + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0); + + /// + /// Go set the current attributes + /// + Status = This->SetAttributes ( + This, + This->Mode->BaudRate, + This->Mode->ReceiveFifoDepth, + This->Mode->Timeout, + This->Mode->Parity, + (UINT8) This->Mode->DataBits, + This->Mode->StopBits + ); + + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + /// + /// Go set the current control bits + /// + Status = This->SetControl ( + This, + This->Mode->ControlMask + ); + + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + + gBS->RestoreTPL (Tpl); + + /// + /// Device reset is complete + /// + return EFI_SUCCESS; +} + +/** + Set new attributes to a serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BaudRate The baudrate of the serial device + @param[in] ReceiveFifoDepth Fifo depth + @param[in] Timeout The request timeout for a single char + @param[in] Parity The type of parity used in serial device + @param[in] DataBits Number of databits used in serial device + @param[in] StopBits Number of stopbits used in serial device + + @retval EFI_SUCCESS The new attributes were set + @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value + @exception EFI_UNSUPPORTED Data Bits can not set to 5 or 6 + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) +**/ +EFI_STATUS +EFIAPI +PciSerialSetAttributes ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ) +{ + EFI_STATUS Status; + SERIAL_DEV *SerialDevice; + UINT32 Divisor; + UINT32 Remained; + SERIAL_PORT_LCR Lcr; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + /// + /// DEBUG ((EFI_D_ERROR, "Info: Timeout = %d\n", Timeout)); + /// + /// Increase timeout by a factor of 3 to fix character drop-out with SOL. + /// + Timeout = Timeout * 100; + + /// + /// Check for default settings and fill in actual values. + /// + if (BaudRate == 0) { + BaudRate = SERIAL_PORT_DEFAULT_BAUD_RATE; + } + + if (ReceiveFifoDepth == 0) { + ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH; + } + + if (Timeout == 0) { + Timeout = SERIAL_PORT_DEFAULT_TIMEOUT; + } + + if (Parity == DefaultParity) { + Parity = SERIAL_PORT_DEFAULT_PARITY; + } + + if (DataBits == 0) { + DataBits = SERIAL_PORT_DEFAULT_DATA_BITS; + } + + if (StopBits == DefaultStopBits) { + StopBits = SERIAL_PORT_DEFAULT_STOP_BITS; + } + /// + /// 5 and 6 data bits can not be verified on a 16550A UART + /// Return EFI_INVALID_PARAMETER if an attempt is made to use these settings. + /// + if ((DataBits == 5) || (DataBits == 6)) { + return EFI_INVALID_PARAMETER; + } + /// + /// Make sure all parameters are valid + /// + if ((BaudRate > SERIAL_PORT_MAX_BAUD_RATE) || (BaudRate < SERIAL_PORT_MIN_BAUD_RATE)) { + return EFI_INVALID_PARAMETER; + } + /// + /// 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200, + /// 38400,57600,115200 + /// + if (BaudRate < 75) { + BaudRate = 50; + } else if (BaudRate < 110) { + BaudRate = 75; + } else if (BaudRate < 134) { + BaudRate = 110; + } else if (BaudRate < 150) { + BaudRate = 134; + } else if (BaudRate < 300) { + BaudRate = 150; + } else if (BaudRate < 600) { + BaudRate = 300; + } else if (BaudRate < 1200) { + BaudRate = 600; + } else if (BaudRate < 1800) { + BaudRate = 1200; + } else if (BaudRate < 2000) { + BaudRate = 1800; + } else if (BaudRate < 2400) { + BaudRate = 2000; + } else if (BaudRate < 3600) { + BaudRate = 2400; + } else if (BaudRate < 4800) { + BaudRate = 3600; + } else if (BaudRate < 7200) { + BaudRate = 4800; + } else if (BaudRate < 9600) { + BaudRate = 7200; + } else if (BaudRate < 19200) { + BaudRate = 9600; + } else if (BaudRate < 38400) { + BaudRate = 19200; + } else if (BaudRate < 57600) { + BaudRate = 38400; + } else if (BaudRate < 115200) { + BaudRate = 57600; + } else if (BaudRate <= SERIAL_PORT_MAX_BAUD_RATE) { + BaudRate = 115200; + } + + if ((ReceiveFifoDepth < 1) || (ReceiveFifoDepth > SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH)) { + return EFI_INVALID_PARAMETER; + } + + if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) { + return EFI_INVALID_PARAMETER; + } + + if ((Parity < NoParity) || (Parity > SpaceParity)) { + return EFI_INVALID_PARAMETER; + } + + if ((DataBits < 5) || (DataBits > 8)) { + return EFI_INVALID_PARAMETER; + } + + if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) { + return EFI_INVALID_PARAMETER; + } + /// + /// for DataBits = 5, StopBits can not set TwoStopBits + /// + /// if ((DataBits == 5) && (StopBits == TwoStopBits)) { + /// return EFI_INVALID_PARAMETER; + /// } + /// + /// for DataBits = 6,7,8, StopBits can not set OneFiveStopBits + /// + if ((DataBits >= 6) && (DataBits <= 8) && (StopBits == OneFiveStopBits)) { + return EFI_INVALID_PARAMETER; + } + /// + /// See if the new attributes already match the current attributes + /// + if (SerialDevice->UartDevicePath.BaudRate == BaudRate && + SerialDevice->UartDevicePath.DataBits == DataBits && + SerialDevice->UartDevicePath.Parity == Parity && + SerialDevice->UartDevicePath.StopBits == StopBits && + SerialDevice->SerialMode.ReceiveFifoDepth == ReceiveFifoDepth && + SerialDevice->SerialMode.Timeout == Timeout + ) { + return EFI_SUCCESS; + } + /// + /// Compute divisor use to program the baud rate using a round determination + /// + Divisor = (UINT32) DivU64x32Remainder (SERIAL_PORT_INPUT_CLOCK, ((UINT32) BaudRate * 16), &Remained); + if (Remained) { + Divisor += 1; + } + + if ((Divisor == 0) || (Divisor & 0xffff0000)) { + return EFI_INVALID_PARAMETER; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + /// + /// Compute the actual baud rate that the serial port will be programmed for. + /// + BaudRate = SERIAL_PORT_INPUT_CLOCK / Divisor / 16; + + /// + /// Put serial port on Divisor Latch Mode + /// + Lcr.Data = READ_LCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Lcr.Bits.DLAB = 1; + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Write the divisor to the serial port + /// + WRITE_DLL (SerialDevice->PciIo, SerialDevice->BarIndex, (UINT8) (Divisor & 0xff)); + WRITE_DLM (SerialDevice->PciIo, SerialDevice->BarIndex, (UINT8) ((Divisor >> 8) & 0xff)); + + /// + /// Put serial port back in normal mode and set remaining attributes. + /// + Lcr.Bits.DLAB = 0; + + switch (Parity) { + case NoParity: + Lcr.Bits.PAREN = 0; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 0; + break; + + case EvenParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 1; + Lcr.Bits.STICPAR = 0; + break; + + case OddParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 0; + break; + + case SpaceParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 1; + Lcr.Bits.STICPAR = 1; + break; + + case MarkParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 1; + break; + default: + break; + } + + switch (StopBits) { + case OneStopBit: + Lcr.Bits.STOPB = 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + Lcr.Bits.STOPB = 1; + break; + default: + break; + } + /// + /// DataBits + /// + Lcr.Bits.SERIALDB = (UINT8) ((DataBits - 5) & 0x03); + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Set the Serial I/O mode + /// + This->Mode->BaudRate = BaudRate; + This->Mode->ReceiveFifoDepth = ReceiveFifoDepth; + This->Mode->Timeout = Timeout; + This->Mode->Parity = Parity; + This->Mode->DataBits = DataBits; + This->Mode->StopBits = StopBits; + + /// + /// See if Device Path Node has actually changed + /// + if (SerialDevice->UartDevicePath.BaudRate == BaudRate && + SerialDevice->UartDevicePath.DataBits == DataBits && + SerialDevice->UartDevicePath.Parity == Parity && + SerialDevice->UartDevicePath.StopBits == StopBits + ) { + gBS->RestoreTPL (Tpl); + return EFI_SUCCESS; + } + /// + /// Update the device path + /// + SerialDevice->UartDevicePath.BaudRate = BaudRate; + SerialDevice->UartDevicePath.DataBits = DataBits; + SerialDevice->UartDevicePath.Parity = (UINT8) Parity; + SerialDevice->UartDevicePath.StopBits = (UINT8) StopBits; + + NewDevicePath = AppendDevicePathNode ( + SerialDevice->ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath + ); + if (NewDevicePath == NULL) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + + if (SerialDevice->Handle != NULL) { + Status = gBS->ReinstallProtocolInterface ( + SerialDevice->Handle, + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + NewDevicePath + ); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return Status; + } + } + + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + SerialDevice->DevicePath = NewDevicePath; + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Set ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control bits that can be settable + + @retval EFI_SUCCESS New Control bits were set successfully + @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported +**/ +EFI_STATUS +EFIAPI +PciSerialSetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ) +{ + SERIAL_DEV *SerialDevice; + SERIAL_PORT_MCR Mcr; + EFI_TPL Tpl; + + /// + /// The control bits that can be set are : + /// EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO + /// EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO + /// EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW + /// EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW + /// + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + /// + /// first determine the parameter is invalid + /// + if (Control & 0xffff8ffc) { + return EFI_UNSUPPORTED; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC = 0; + Mcr.Bits.RTS = 0; + Mcr.Bits.LME = 0; + SerialDevice->SoftwareLoopbackEnable = FALSE; + SerialDevice->HardwareFlowControl = FALSE; + + if (Control & EFI_SERIAL_DATA_TERMINAL_READY) { + Mcr.Bits.DTRC = 1; + } + + if (Control & EFI_SERIAL_REQUEST_TO_SEND) { + Mcr.Bits.RTS = 1; + } + + if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { + Mcr.Bits.LME = 1; + } + + if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { + SerialDevice->HardwareFlowControl = TRUE; + } + + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) { + SerialDevice->SoftwareLoopbackEnable = TRUE; + } + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Get ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control signals of the serial device + + @retval EFI_SUCCESS Get Control signals successfully +**/ +EFI_STATUS +EFIAPI +PciSerialGetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ) +{ + SERIAL_DEV *SerialDevice; + SERIAL_PORT_MSR Msr; + SERIAL_PORT_MCR Mcr; + EFI_TPL Tpl; + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + *Control = 0; + + /// + /// Read the Modem Status Register + /// + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + + if (Msr.Bits.CTS) { + *Control |= EFI_SERIAL_CLEAR_TO_SEND; + } + + if (Msr.Bits.DSR) { + *Control |= EFI_SERIAL_DATA_SET_READY; + } + + if (Msr.Bits.RI) { + *Control |= EFI_SERIAL_RING_INDICATE; + } + + if (Msr.Bits.DCD) { + *Control |= EFI_SERIAL_CARRIER_DETECT; + } + /// + /// Read the Modem Control Register + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + + if (Mcr.Bits.DTRC) { + *Control |= EFI_SERIAL_DATA_TERMINAL_READY; + } + + if (Mcr.Bits.RTS) { + *Control |= EFI_SERIAL_REQUEST_TO_SEND; + } + + if (Mcr.Bits.LME) { + *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; + } + + if (SerialDevice->HardwareFlowControl) { + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + /// + /// See if the Transmit FIFO is empty + /// + PciSerialReceiveTransmit (SerialDevice); + + if (PciSerialFifoEmpty (&SerialDevice->Transmit)) { + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + /// + /// See if the Receive FIFO is empty. + /// + PciSerialReceiveTransmit (SerialDevice); + + if (PciSerialFifoEmpty (&SerialDevice->Receive)) { + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + if (SerialDevice->SoftwareLoopbackEnable) { + *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; + } + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Write the specified number of bytes to serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data actually written + @param[in] Buffer The buffer of data to write + + @retval EFI_SUCCESS The data were written successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The write operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialWrite ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + SERIAL_DEV *SerialDevice; + UINT8 *CharBuffer; + UINT32 Index; + UINTN Elapsed; + UINTN ActualWrite; + EFI_TPL Tpl; + SERIAL_PORT_MCR Mcr; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + Elapsed = 0; + ActualWrite = 0; + + if (*BufferSize == 0) { + return EFI_SUCCESS; + } + + if (!Buffer) { + return EFI_DEVICE_ERROR; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + CharBuffer = (UINT8 *) Buffer; + + for (Index = 0; Index < *BufferSize; Index++) { + PciSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]); + + while + ( + PciSerialReceiveTransmit (SerialDevice) != EFI_SUCCESS || + PciSerialFifoEmpty (&SerialDevice->Transmit) == FALSE + ) { + /// + /// Unsuccessful write so check if timeout has expired, if not, + /// stall for a bit, increment time elapsed, and try again + /// + if (Elapsed >= This->Mode->Timeout) { + *BufferSize = ActualWrite; + if (PciSerialFifoEmpty (&SerialDevice->Transmit)) { + gBS->RestoreTPL (Tpl); + return EFI_TIMEOUT; + } + } + + gBS->Stall (TIMEOUT_STALL_INTERVAL); + + Elapsed += TIMEOUT_STALL_INTERVAL; + } // end while + ActualWrite++; + /// + /// Successful write so reset timeout + /// + Elapsed = 0; + + } // end for + /// + /// FW expects DTR bit to be SET before sending data. So enable DTR bit always. + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Read the specified number of bytes from serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data returned in buffer + @param[in] Buffer The buffer to return the data into + + @retval EFI_SUCCESS The data were read successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The read operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialRead ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + SERIAL_DEV *SerialDevice; + UINT32 Index; + UINT8 *CharBuffer; + UINTN Elapsed; + EFI_STATUS Status; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + Elapsed = 0; + + if (*BufferSize == 0) { + return EFI_SUCCESS; + } + + if (!Buffer) { + return EFI_DEVICE_ERROR; + } + /// + /// SerialDevice->Receive.First = 0; + /// SerialDevice->Receive.Last = 0; + /// SerialDevice->Receive.Surplus = SERIAL_MAX_BUFFER_SIZE; + /// + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = PciSerialReceiveTransmit (SerialDevice); + + if (EFI_ERROR (Status)) { + *BufferSize = 0; + + gBS->RestoreTPL (Tpl); + + return EFI_DEVICE_ERROR; + } + + CharBuffer = (UINT8 *) Buffer; + for (Index = 0; Index < *BufferSize; Index++) { + while (PciSerialFifoRemove (&SerialDevice->Receive, &(CharBuffer[Index])) != EFI_SUCCESS) { + /// + /// Unsuccessful read so check if timeout has expired, if not, + /// stall for a bit, increment time elapsed, and try again + /// Need this time out to get conspliter to work. + /// + if (Elapsed >= This->Mode->Timeout) { + *BufferSize = Index; + gBS->RestoreTPL (Tpl); + return EFI_TIMEOUT; + } + + gBS->Stall (TIMEOUT_STALL_INTERVAL); + Elapsed += TIMEOUT_STALL_INTERVAL; + + Status = PciSerialReceiveTransmit (SerialDevice); + if (Status == EFI_DEVICE_ERROR) { + *BufferSize = Index; + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + } // end while + /// + /// Successful read so reset timeout + /// + Elapsed = 0; + } // end for + PciSerialReceiveTransmit (SerialDevice); + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Check serial port status. + + @param[in] SerialDevice The serial device instance + + @retval True It is present. + @retval False No present. +**/ +BOOLEAN +PciSerialPortPresent ( + IN SERIAL_DEV *SerialDevice + ) +{ + UINT8 Temp; + BOOLEAN Status; + + Status = TRUE; + + /// + /// Save SCR reg + /// + Temp = READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex); + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0xAA); + + if (READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex) != 0xAA) { +#ifndef EFI_NT_EMULATOR + Status = FALSE; +#endif + } + + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0x55); + + if (READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex) != 0x55) { +#ifndef EFI_NT_EMULATOR + Status = FALSE; +#endif + } + /// + /// Restore SCR + /// + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, Temp); + return Status; +} + +/** + PCI I/O read for byte only + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + + @retval Return value read +**/ +UINT8 +PciSerialReadPort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset + ) +{ + UINT8 Data; + + /// + /// Use PciIo to access IO + /// + PciIo->Io.Read ( + PciIo, + EfiPciIoWidthUint8, + (UINT8) BarIndex, + (UINT16) Offset, + (UINTN) 1, + &Data + ); + return Data; +} + +/** + PCI I/O - write a byte + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + @param[in] Data Written value +**/ +VOID +PciSerialWritePort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset, + IN UINT8 Data + ) +{ + /// + /// Use PciIo to access IO + /// + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint8, + (UINT8) BarIndex, + (UINT16) Offset, + (UINTN) 1, + &Data + ); +} + +/** + Sol driver entry + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif new file mode 100644 index 0000000..950205e --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif @@ -0,0 +1,13 @@ +<component> + name = "PciSerial" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\Sol\Dxe\" + RefName = "PciSerial" +[files] +"PciSerial.sdl" +"PciSerial.mak" +"PciSerial.c" +"ComponentName.c" +"PciSerial.h" +"PciSerial.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h new file mode 100644 index 0000000..320de88 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h @@ -0,0 +1,787 @@ +/** @file + Include for Pci Serial Driver + +@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 + +**/ +#ifndef _PCI_SERIAL_H +#define _PCI_SERIAL_H +#include "Pci22.h" +#include "Acpi.h" +#include "AmtLib.h" + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (PciIo) +#include EFI_PROTOCOL_DEFINITION (DevicePath) +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DriverBinding) +#include EFI_PROTOCOL_DEFINITION (ComponentName) +#include EFI_PROTOCOL_DEFINITION (SerialIo) + +// +// Status code GUID +// +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) + +// +// Internal Data Structures +// +#define SERIAL_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'e', 'r', 'd') +#define SERIAL_MAX_BUFFER_SIZE 16 +#define TIMEOUT_STALL_INTERVAL 300 + +/// +/// Name: SERIAL_DEV_FIFO +/// Purpose: To define Receive FIFO and Transmit FIFO +/// Context: Used by serial data transmit and receive +/// Fields: +/// First UINT32: The index of the first data in array Data[] +/// Last UINT32: The index, which you can put a new data into array Data[] +/// Surplus UINT32: Identify how many data you can put into array Data[] +/// Data[] UINT8 : An array, which used to store data +/// +typedef struct { + UINT32 First; + UINT32 Last; + UINT32 Surplus; + UINT8 Data[SERIAL_MAX_BUFFER_SIZE]; +} SERIAL_DEV_FIFO; + +typedef enum { + UART8250 = 0, + UART16450 = 1, + UART16550 = 2, + UART16550A= 3 +} EFI_UART_TYPE; + +/// +/// Name: SERIAL_DEV +/// Purpose: To provide device specific information +/// Context: +/// Fields: +/// Signature UINTN: The identity of the serial device +/// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface +/// SerialMode SERIAL_IO_MODE: +/// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device +/// Handle EFI_HANDLE: The handle instance attached to serial device +/// BarIndex UINT16: The bar index in pci cfg space that contains the base address +/// of specific serial device +/// Receive SERIAL_DEV_FIFO: The FIFO used to store data, +/// which is received by UART +/// Transmit SERIAL_DEV_FIFO: The FIFO used to store data, +/// which you want to transmit by UART +/// SoftwareLoopbackEnable BOOLEAN: +/// Type EFI_UART_TYPE: Specify the UART type of certain serial device +/// +typedef struct { + UINTN Signature; + + EFI_HANDLE Handle; + EFI_SERIAL_IO_PROTOCOL SerialIo; + EFI_SERIAL_IO_MODE SerialMode; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + UART_DEVICE_PATH UartDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + + UINT16 BarIndex; + SERIAL_DEV_FIFO Receive; + SERIAL_DEV_FIFO Transmit; + BOOLEAN SoftwareLoopbackEnable; + BOOLEAN HardwareFlowControl; + EFI_UART_TYPE Type; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} SERIAL_DEV; + +#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE) + +// +// Globale Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL mPciSerialControllerDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL mPciSerialComponentName; + +// +// Serial Driver Defaults +// +#define SERIAL_PORT_DEFAULT_BAUD_RATE 115200 +#define SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH 1 +#define SERIAL_PORT_DEFAULT_TIMEOUT 1000000 ///< 1 seconds +#define SERIAL_PORT_DEFAULT_PARITY NoParity +#define SERIAL_PORT_DEFAULT_DATA_BITS 8 +#define SERIAL_PORT_DEFAULT_STOP_BITS 1 +#define SERIAL_PORT_DEFAULT_CONTROL_MASK EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE + +/// +/// (24000000/13)MHz input clock +/// +#define SERIAL_PORT_INPUT_CLOCK 1843200 + +/// +/// 115200 baud with rounding errors +/// +#define SERIAL_PORT_MAX_BAUD_RATE 115400 +#define SERIAL_PORT_MIN_BAUD_RATE 50 + +#define SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH 16 +#define SERIAL_PORT_MIN_TIMEOUT 1 ///< 1 uS +#define SERIAL_PORT_MAX_TIMEOUT 10000000000 ///< 10000 seconds +// +// UART Registers +// +#define SERIAL_REGISTER_THR 0 ///< WO Transmit Holding Register +#define SERIAL_REGISTER_RBR 0 ///< RO Receive Buffer Register +#define SERIAL_REGISTER_DLL 0 ///< R/W Divisor Latch LSB +#define SERIAL_REGISTER_DLM 1 ///< R/W Divisor Latch MSB +#define SERIAL_REGISTER_IER 1 ///< R/W Interrupt Enable Register +#define SERIAL_REGISTER_IIR 2 ///< RO Interrupt Identification Register +#define SERIAL_REGISTER_FCR 2 ///< WO FIFO Cotrol Register +#define SERIAL_REGISTER_LCR 3 ///< R/W Line Control Register +#define SERIAL_REGISTER_MCR 4 ///< R/W Modem Control Register +#define SERIAL_REGISTER_LSR 5 ///< R/W Line Status Register +#define SERIAL_REGISTER_MSR 6 ///< R/W Modem Status Register +#define SERIAL_REGISTER_SCR 7 ///< R/W Scratch Pad Register +#define TEKOA_SOL_VENDOR_ID 0x8086 +#define TEKOA_SOL_DEVICE_ID 0x108F + +#define PCI_CLASS_SCC 0x07 +#define PCI_SUBCLASS_SERIAL 0x00 +#define PCI_IF_GENERIC_XT 0x00 +#define PCI_IF_16450 0x01 +#define PCI_IF_16550 0x02 +#define PCI_IF_16650 0x03 +#define PCI_IF_16750 0x04 +#define PCI_IF_16850 0x05 +#define PCI_IF_16950 0x06 +#define PCI_SUBCLASS_PARALLEL 0x01 +#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02 +#define PCI_SUBCLASS_MODEM 0x03 +#define PCI_SUBCLASS_OTHER 0x80 + +#pragma pack(1) +/// +/// Name: SERIAL_PORT_IER_BITS +/// Purpose: Define each bit in Interrupt Enable Register +/// Context: +/// Fields: +/// RAVIE Bit0: Receiver Data Available Interrupt Enable +/// THEIE Bit1: Transmistter Holding Register Empty Interrupt Enable +/// RIE Bit2: Receiver Interrupt Enable +/// MIE Bit3: Modem Interrupt Enable +/// Reserved Bit4-Bit7: Reserved +/// +typedef struct { + UINT8 RAVIE : 1; + UINT8 THEIE : 1; + UINT8 RIE : 1; + UINT8 MIE : 1; + UINT8 Reserved : 4; +} SERIAL_PORT_IER_BITS; + +/// +/// Name: SERIAL_PORT_IER +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_IER_BITS: Bits of the IER +/// Data UINT8: the value of the IER +/// +typedef union { + SERIAL_PORT_IER_BITS Bits; + UINT8 Data; +} SERIAL_PORT_IER; + +/// +/// Name: SERIAL_PORT_IIR_BITS +/// Purpose: Define each bit in Interrupt Identification Register +/// Context: +/// Fields: +/// IPS Bit0: Interrupt Pending Status +/// IIB Bit1-Bit3: Interrupt ID Bits +/// Reserved Bit4-Bit5: Reserved +/// FIFOES Bit6-Bit7: FIFO Mode Enable Status +/// +typedef struct { + UINT8 IPS : 1; + UINT8 IIB : 3; + UINT8 Reserved : 2; + UINT8 FIFOES : 2; +} SERIAL_PORT_IIR_BITS; + +/// +/// Name: SERIAL_PORT_IIR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_IIR_BITS: Bits of the IIR +/// Data UINT8: the value of the IIR +/// +typedef union { + SERIAL_PORT_IIR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_IIR; + +/// +/// Name: SERIAL_PORT_FCR_BITS +/// Purpose: Define each bit in FIFO Control Register +/// Context: +/// Fields: +/// TRFIFOE Bit0: Transmit and Receive FIFO Enable +/// RESETRF Bit1: Reset Reciever FIFO +/// RESETTF Bit2: Reset Transmistter FIFO +/// DMS Bit3: DMA Mode Select +/// Reserved Bit4-Bit5: Reserved +/// RTB Bit6-Bit7: Receive Trigger Bits +/// +typedef struct { + UINT8 TRFIFOE : 1; + UINT8 RESETRF : 1; + UINT8 RESETTF : 1; + UINT8 DMS : 1; + UINT8 Reserved : 2; + UINT8 RTB : 2; +} SERIAL_PORT_FCR_BITS; + +/// +/// Name: SERIAL_PORT_FCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_FCR_BITS: Bits of the FCR +/// Data UINT8: the value of the FCR +/// +typedef union { + SERIAL_PORT_FCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_FCR; + +/// +/// Name: SERIAL_PORT_LCR_BITS +/// Purpose: Define each bit in Line Control Register +/// Context: +/// Fields: +/// SERIALDB Bit0-Bit1: Number of Serial Data Bits +/// STOPB Bit2: Number of Stop Bits +/// PAREN Bit3: Parity Enable +/// EVENPAR Bit4: Even Parity Select +/// STICPAR Bit5: Sticky Parity +/// BRCON Bit6: Break Control +/// DLAB Bit7: Divisor Latch Access Bit +/// +typedef struct { + UINT8 SERIALDB : 2; + UINT8 STOPB : 1; + UINT8 PAREN : 1; + UINT8 EVENPAR : 1; + UINT8 STICPAR : 1; + UINT8 BRCON : 1; + UINT8 DLAB : 1; +} SERIAL_PORT_LCR_BITS; + +/// +/// Name: SERIAL_PORT_LCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_LCR_BITS: Bits of the LCR +/// Data UINT8: the value of the LCR +/// +typedef union { + SERIAL_PORT_LCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_LCR; + +/// +/// Name: SERIAL_PORT_MCR_BITS +/// Purpose: Define each bit in Modem Control Register +/// Context: +/// Fields: +/// DTRC Bit0: Data Terminal Ready Control +/// RTS Bit1: Request To Send Control +/// OUT1 Bit2: Output1 +/// OUT2 Bit3: Output2, used to disable interrupt +/// LME; Bit4: Loopback Mode Enable +/// Reserved Bit5-Bit7: Reserved +/// +typedef struct { + UINT8 DTRC : 1; + UINT8 RTS : 1; + UINT8 OUT1 : 1; + UINT8 OUT2 : 1; + UINT8 LME : 1; + UINT8 Reserved : 3; +} SERIAL_PORT_MCR_BITS; + +/// +/// Name: SERIAL_PORT_MCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_MCR_BITS: Bits of the MCR +/// Data UINT8: the value of the MCR +/// +typedef union { + SERIAL_PORT_MCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_MCR; + +/// +/// Name: SERIAL_PORT_LSR_BITS +/// Purpose: Define each bit in Line Status Register +/// Context: +/// Fields: +/// DR Bit0: Receiver Data Ready Status +/// OE Bit1: Overrun Error Status +/// PE Bit2: Parity Error Status +/// FE Bit3: Framing Error Status +/// BI Bit4: Break Interrupt Status +/// THRE Bit5: Transmistter Holding Register Status +/// TEMT Bit6: Transmitter Empty Status +/// FIFOE Bit7: FIFO Error Status +/// +typedef struct { + UINT8 DR : 1; + UINT8 OE : 1; + UINT8 PE : 1; + UINT8 FE : 1; + UINT8 BI : 1; + UINT8 THRE : 1; + UINT8 TEMT : 1; + UINT8 FIFOE : 1; +} SERIAL_PORT_LSR_BITS; + +/// +/// Name: SERIAL_PORT_LSR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_LSR_BITS: Bits of the LSR +/// Data UINT8: the value of the LSR +/// +typedef union { + SERIAL_PORT_LSR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_LSR; + +/// +/// Name: SERIAL_PORT_MSR_BITS +/// Purpose: Define each bit in Modem Status Register +/// Context: +/// Fields: +/// DeltaCTS Bit0: Delta Clear To Send Status +/// DeltaDSR Bit1: Delta Data Set Ready Status +/// TrailingEdgeRI Bit2: Trailing Edge of Ring Indicator Status +/// DeltaDCD Bit3: Delta Data Carrier Detect Status +/// CTS Bit4: Clear To Send Status +/// DSR Bit5: Data Set Ready Status +/// RI Bit6: Ring Indicator Status +/// DCD Bit7: Data Carrier Detect Status +/// +typedef struct { + UINT8 DeltaCTS : 1; + UINT8 DeltaDSR : 1; + UINT8 TrailingEdgeRI : 1; + UINT8 DeltaDCD : 1; + UINT8 CTS : 1; + UINT8 DSR : 1; + UINT8 RI : 1; + UINT8 DCD : 1; +} SERIAL_PORT_MSR_BITS; + +/// +/// Name: SERIAL_PORT_MSR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_MSR_BITS: Bits of the MSR +/// Data UINT8: the value of the MSR +/// +typedef union { + SERIAL_PORT_MSR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_MSR; + +#pragma pack() +// +// Define serial register I/O macros +// +#define READ_RBR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_RBR) +#define READ_DLL(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_DLL) +#define READ_DLM(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_DLM) +#define READ_IER(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_IER) +#define READ_IIR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_IIR) +#define READ_LCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_LCR) +#define READ_MCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_MCR) +#define READ_LSR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_LSR) +#define READ_MSR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_MSR) +#define READ_SCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_SCR) + +#define WRITE_THR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_THR, D) +#define WRITE_DLL(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_DLL, D) +#define WRITE_DLM(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_DLM, D) +#define WRITE_IER(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_IER, D) +#define WRITE_FCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_FCR, D) +#define WRITE_LCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_LCR, D) +#define WRITE_MCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_MCR, D) +#define WRITE_LSR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_LSR, D) +#define WRITE_MSR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_MSR, D) +#define WRITE_SCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_SCR, D) + +#define PCI_SERIAL_PORT_NAME "PCI Serial Port # " + +#define R_PCI_SVID 0x2C + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND The device doesn't support or relative environment not ready +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + This routine is called right after the .Supported() called + and return EFI_SUCCESS. Notes: The supported protocols are + checked but the Protocols are closed. + + @param[in] This A pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval Other The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @retval EFI_DEVICE_ERROR Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +/** + Detect whether specific FIFO is full or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is full + @retval FALSE The FIFO is not full +**/ +BOOLEAN +PciSerialFifoFull ( + IN SERIAL_DEV_FIFO *Fifo + ) +; + +/** + Detect whether specific FIFO is empty or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is empty + @retval FALSE The FIFO is not empty +**/ +BOOLEAN +PciSerialFifoEmpty ( + IN SERIAL_DEV_FIFO *Fifo + ) +; + +/** + Add data to specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data added to FIFO + + @retval EFI_SUCCESS Add data to specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to add data because FIFO is already full +**/ +EFI_STATUS +PciSerialFifoAdd ( + IN SERIAL_DEV_FIFO *Fifo, + IN UINT8 Data + ) +; + +/** + Remove data from specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data removed from FIFO + + @retval EFI_SUCCESS Remove data from specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to remove data because FIFO is empty +**/ +EFI_STATUS +PciSerialFifoRemove ( + IN SERIAL_DEV_FIFO *Fifo, + OUT UINT8 *Data + ) +; + +/** + Reads and writes all avaliable data. + + @param[in] SerialDevice The device to flush + + @retval EFI_SUCCESS Data was read/written successfully. + @retval EFI_OUT_OF_RESOURCES Failed because software receive FIFO is full. Note, when + this happens, pending writes are not done. +**/ +EFI_STATUS +PciSerialReceiveTransmit ( + IN SERIAL_DEV *SerialDevice + ) +; +/// +/// Serial I/O Protocol Interface +/// +/** + Reset serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + + @retval EFI_SUCCESS Reset successfully + @retval EFI_DEVICE_ERROR Failed to reset +**/ +EFI_STATUS +EFIAPI +PciSerialReset ( + IN EFI_SERIAL_IO_PROTOCOL *This + ) +; + +/** + Set new attributes to a serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BaudRate The baudrate of the serial device + @param[in] ReceiveFifoDepth Fifo depth + @param[in] Timeout The request timeout for a single char + @param[in] Parity The type of parity used in serial device + @param[in] DataBits Number of databits used in serial device + @param[in] StopBits Number of stopbits used in serial device + + @retval EFI_SUCCESS The new attributes were set + @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value + @exception EFI_UNSUPPORTED Data Bits can not set to 5 or 6 + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) +**/ +EFI_STATUS +EFIAPI +PciSerialSetAttributes ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ) +; + +/** + Set ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control bits that can be settable + + @retval EFI_SUCCESS New Control bits were set successfully + @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported +**/ +EFI_STATUS +EFIAPI +PciSerialSetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ) +; + +/** + Get ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control signals of the serial device + + @retval EFI_SUCCESS Get Control signals successfully +**/ +EFI_STATUS +EFIAPI +PciSerialGetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ) +; + +/** + Write the specified number of bytes to serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data actually written + @param[in] Buffer The buffer of data to write + + @retval EFI_SUCCESS The data were written successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The write operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialWrite ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +; + +/** + Read the specified number of bytes from serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data returned in buffer + @param[in] Buffer The buffer to return the data into + + @retval EFI_SUCCESS The data were read successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The read operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialRead ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +; + +/// +/// Internal Functions +/// +/** + Check serial port status. + + @param[in] SerialDevice The serial device instance + + @retval True It is present. + @retval False No present. +**/ +BOOLEAN +PciSerialPortPresent ( + IN SERIAL_DEV *SerialDevice + ) +; + +/** + PCI I/O read for byte only + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + + @retval Return value read +**/ +UINT8 +PciSerialReadPort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset + ) +; + +/** + PCI I/O - write a byte + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + @param[in] Data Written value +**/ +VOID +PciSerialWritePort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset, + IN UINT8 Data + ) +; + +/** + Sol driver entry + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; +#endif diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf new file mode 100644 index 0000000..a3b4e0b --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf @@ -0,0 +1,87 @@ +## @file +# Component description file for PciSerial 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 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 = PciSerial +FILE_GUID = FB142B99-DF57-46cb-BC69-0BF858A734F9 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + PciSerial.c + PciSerial.h + ComponentName.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(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] + AmtLib + EdkProtocolLib + EdkIIGlueBaseLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiDevicePathLib + EdkIIGlueUefiLib + EdkIIGlueUefiDriverModelLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PciSerialControllerDriverEntryPoint \ + -D __EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mPciSerialControllerDriverBinding \ + -D __EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mPciSerialComponentName + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \ + -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__ \ + -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak new file mode 100644 index 0000000..a94fda5 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak @@ -0,0 +1,55 @@ +# MAK file for the ModulePart:PciSerial + +all : PciSerial + +$(BUILD_DIR)\PciSerial.mak : $(PciSerial_DIR)\$(@B).cif $(PciSerial_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PciSerial_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PciSerial : $(BUILD_DIR)\PciSerial.mak PciSerialBin + +PciSerial_INCLUDES=\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + +PciSerial_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(AmtLibDxe_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiDevicePathLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueUefiDriverModelLib_LIB)\ + +PciSerial_DEFINES=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PciSerialControllerDriverEntryPoint"\ + /D"__EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mPciSerialControllerDriverBinding"\ + /D"__EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mPciSerialComponentName"\ + /D __EDKII_GLUE_BASE_LIB__\ + /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_DEVICE_PATH_LIB__\ + /D __EDKII_GLUE_UEFI_LIB__ \ + /D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ + +PciSerialBin : $(PciSerial_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PciSerial.mak all \ + "MY_INCLUDES=$(PciSerial_INCLUDES)"\ + "MY_DEFINES=$(PciSerial_DEFINES)"\ + GUID=FB142B99-DF57-46cb-BC69-0BF858A734F9 \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + COMPRESS=1 diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl new file mode 100644 index 0000000..b485486 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "PciSerial_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PciSerial support in Project" +End +MODULE + Help = "Includes PciSerial.mak to Project" + File = "PciSerial.mak" +End + +PATH + Name = "PciSerial_DIR" + Help = "iAMT PciSerial file source directory" +End + +ELINK + Name = "$(BUILD_DIR)\PciSerial.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.c b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.c new file mode 100644 index 0000000..87c0818 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.c @@ -0,0 +1,96 @@ +/** @file + Start Watchdog timer in PEI phase + +@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 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 "StartWatchDog.h" +#include "MeLibPei.h" +#endif + +/** + Perform the platform spefific initializations. + + @param[in] FfsHeader FFS file header pointer of this driver. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS if the interface could be successfully installed. +**/ +EFI_STATUS +EFIAPI +PeiInitStartWatchDog ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + PEI_HECI_PPI *HeciPpi; + UINT32 HeciMemBar; + UINT16 WaitTimerBios; + UINT32 MeStatus; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) { + return EFI_SUCCESS; + } + + if (PeiAmtWatchDog (PeiServices)) { + 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)) { + /// + /// Get ME Status + /// + Status = HeciPpi->GetMeStatus (PeiServices, &MeStatus); + ASSERT_EFI_ERROR (Status); + + /// + /// If ME is ready, send AsfStartWatchDog message + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) { + WaitTimerBios = PeiAmtWatchTimerBiosGet (PeiServices); + + Status = PeiHeciAsfStartWatchDog ( + PeiServices, + HeciPpi, + HeciMemBar, + WaitTimerBios + ); + ASSERT_EFI_ERROR (Status); + } + } + } + + return Status; +} diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.cif b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.cif new file mode 100644 index 0000000..0dfa5a9 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.cif @@ -0,0 +1,13 @@ +<component> + name = "StartWatchDog" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\StartWatchDog\Pei\" + RefName = "StartWatchDog" +[files] +"StartWatchDog.sdl" +"StartWatchDog.mak" +"StartWatchDog.h" +"StartWatchDog.c" +"StartWatchDog.dxs" +"StartWatchDog.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.dxs b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.dxs new file mode 100644 index 0000000..3c05cbb --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.dxs @@ -0,0 +1,47 @@ +/** @file + Dependency expression file for the StartWatchDog 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 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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "PeimDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" + +#include EFI_PPI_DEFINITION (Heci) +#include EFI_PPI_DEFINITION (AmtPlatformPolicyPei) +#include EFI_PPI_CONSUMER (BootMode) +#endif + +DEPENDENCY_START + PEI_HECI_PPI_GUID AND + PEI_MASTER_BOOT_MODE_PEIM_PPI AND + PEI_AMT_PLATFORM_POLICY_PPI_GUID +DEPENDENCY_END + + diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.h b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.h new file mode 100644 index 0000000..5415206 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.h @@ -0,0 +1,49 @@ +/** @file + StartWatchDog header file + +@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 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 _EFI_START_WATCH_DOG_H_ +#define _EFI_START_WATCH_DOG_H_ + +#include "BootMode.h" +#include "AmtLibPei.h" + +#include EFI_PPI_DEPENDENCY (Heci) + +// +// Function Prototypes +// + +/** + Perform the platform spefific initializations. + + @param[in] FfsHeader FFS file header pointer of this driver. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS if the interface could be successfully installed. +**/ +EFI_STATUS +EFIAPI +PeiInitStartWatchDog ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +; + +#endif // _EFI_START_WATCH_DOG_H_ diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.inf b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.inf new file mode 100644 index 0000000..1dd3811 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.inf @@ -0,0 +1,74 @@ +## @file +# Component description file for the Start Watch Dog PEIM driver. +# +#@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 = StartWatchDog +FILE_GUID = 5479E09C-2E74-481b-89F8-B0172E388D1F +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + StartWatchDog.h + StartWatchDog.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Pei + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Pei + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + MeLibPpi + MeLibPei + AmtLibPei + EdkIIGlueBaseMemoryLib + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = StartWatchDog.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeiInitStartWatchDog + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.mak b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.mak new file mode 100644 index 0000000..489c455 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.mak @@ -0,0 +1,52 @@ +# MAK file for the ModulePart:StartWatchDog + +all: StartWatchDog + +StartWatchDog: $(BUILD_DIR)\StartWatchDog.mak StartWatchDogBin + +$(BUILD_DIR)\StartWatchDog.mak : $(StartWatchDog_DIR)\$(@B).cif $(StartWatchDog_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(StartWatchDog_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + + +StartWatchDog_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + +StartWatchDog_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PeiInitStartWatchDog"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_PEI_SERVICES_LIB__\ + /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + +StartWatchDog_LIBS =\ + $(EDKPROTOCOLLIB)\ + $(AmtLibPei_LIB)\ + $(MeLibPpi_LIB)\ + $(MeLibPei_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGluePeiMemoryAllocationLib_LIB)\ + +StartWatchDogBin : $(StartWatchDog_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\StartWatchDog.mak all\ + NAME=StartWatchDog\ + MAKEFILE=$(BUILD_DIR)\StartWatchDog.mak \ + GUID=5479E09C-2E74-481b-89F8-B0172E388D1F\ + "MY_INCLUDES=$(StartWatchDog_INCLUDES)"\ + "MY_DEFINES=$(StartWatchDog_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(StartWatchDog_DIR)\StartWatchDog.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 diff --git a/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.sdl b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.sdl new file mode 100644 index 0000000..ec760e6 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/StartWatchDog/Pei/StartWatchDog.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "StartWatchDog_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable StartWatchDog support in Project" +End + +MODULE + Help = "Includes StartWatchDog.mak to Project" + File = "StartWatchDog.mak" +End + +PATH + Name = "StartWatchDog_DIR" + Help = "iAMT Heci Pei file source directory" +End + +ELINK + Name = "$(BUILD_DIR)\StartWatchDog.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/At/At.cif b/ReferenceCode/ME/At/At.cif new file mode 100644 index 0000000..16018b3 --- /dev/null +++ b/ReferenceCode/ME/At/At.cif @@ -0,0 +1,10 @@ +<component> + name = "Anti-Theft" + category = ModulePart + LocalRoot = "ReferenceCode\ME\At\" + RefName = "AntiTheft" +[files] +"At.sdl" +[parts] +"AtAmDxe" +<endComponent> diff --git a/ReferenceCode/ME/At/At.sdl b/ReferenceCode/ME/At/At.sdl new file mode 100644 index 0000000..587d4a2 --- /dev/null +++ b/ReferenceCode/ME/At/At.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "AT_SUPPORT" + Value = "1" + Help = "Main switch to enable TDT support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "AT_DIR" + Help = "TDT Driver files source directory" +End + +ELINK + Name = "/I$(AT_DIR)" + Parent = "AT_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "AT_INCLUDES" + InvokeOrder = ReplaceParent +End diff --git a/ReferenceCode/ME/At/AtAm/Dxe/At.c b/ReferenceCode/ME/At/AtAm/Dxe/At.c new file mode 100644 index 0000000..a47ddeb --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/At.c @@ -0,0 +1,1015 @@ +/** @file + Implementation for the AT driver. + This driver implements the AT protocol. + +@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 + +**/ + +#include "At.h" + +AT_INSTANCE mAtInstance = { + AT_PRIVATE_DATA_SIGNATURE, + NULL, + { + (UINT8) AT_PROTOCOL_REVISION, + (EFI_AT_AUTHETICATE_CREDENTIAL) AuthenticateCredential, + (EFI_AT_COMPUTE_HASH) ComputeHash, + (EFI_AT_GET_NONCE) GetNonce, + (EFI_AT_GET_TIMER_INFO) GetTimerInfo, + (EFI_AT_GET_RECOVERY_STRING) GetRecoveryString, + (EFI_AT_GET_ISV_ID) GetIsvId, + (EFI_AT_SEND_ASSERT_STOLEN) SendAssertStolen, + (EFI_AT_SET_SUSPEND_STATE) SetSuspendState, + (EFI_AT_INIT_WWAN_RECOV) InitWWANREcov, + (EFI_AT_GET_WWAN_NIC_STATUS) GetWWANNicStatus, + (EFI_AT_GET_STATE_UNSIGNED) GetStateUnsigned + + } +}; + +EFI_HECI_PROTOCOL *mHeci = NULL; + +/** + Entry point for the AT Driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +AtEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "ATAM: AtEntryPoint()\n")); + /// + /// Install the EFI_AT_PROTOCOL interface + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &(mAtInstance.Handle), + &gEfiAtProtocolGuid, + &(mAtInstance.AtProtocol), + NULL + ); + + return Status; +} + +/** + This function sends a request to ME AT Services to validate AT + recovery credentials. The user input is captured in UTF-16 + format and then passed to this funtion. This function converts + the User recovery password into a HASH by using Salt & Nonce + and then send the password HASH to ME AT Services for + validation. ME AT Service compares the Password HASH and + returns either pass or fail. + + @param[in] This The address of protocol + @param[in] PassPhrase Passphrase that needs to be authenticated sent to ME + @param[in] PassType Password type user or server generated + @param[in][out] IsAuthenticated The return of the password match 1 for success and 0 for fail + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +EFIAPI +AuthenticateCredential ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN UINT32 *PassType, + IN OUT UINT8 *IsAuthenticated + ) +{ + UINT32 HeciLength; + EFI_STATUS Status; + EFI_HECI_PROTOCOL *mHeci; + ATHI_AUTHENTICATE_CREDENTIAL_CMD *AtAuthCmd; + ATHI_AUTHENTICATE_CREDENTIAL_RSP AtAuthRsp; + + mHeci = NULL; + + AtAuthCmd = AllocateZeroPool (sizeof (ATHI_AUTHENTICATE_CREDENTIAL_CMD) + AT_PASSWORD_LENGTH); + if (AtAuthCmd == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *) &AtAuthRsp, sizeof (ATHI_AUTHENTICATE_CREDENTIAL_RSP)); + + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential Password Type: %x\n", *PassType)); + + AtAuthCmd->Credential.Type = *PassType; + AtAuthCmd->Credential.Length = (UINT32) AT_USR_PASS_HASH_LENGTH_MAX; + AtAuthCmd->Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtAuthCmd->Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtAuthCmd->Header.Command.Category = ATHI_CMD_GROUP_RECOVERY; + AtAuthCmd->Header.Command.IsResponse = AT_COMMAND; + AtAuthCmd->Header.Command.Code = ATHI_RECOVERY_GRP_AUTH_CREDENTIAL_CMD; + AtAuthCmd->Header.Length = sizeof (AT_CREDENTIAL) + AT_USR_PASS_HASH_LENGTH_MAX - sizeof (UINT8); + + HeciLength = sizeof (ATHI_AUTHENTICATE_CREDENTIAL_CMD) + AT_USR_PASS_HASH_LENGTH_MAX - sizeof (UINT8); + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthCmd Body 1: \n")); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) AtAuthCmd, HeciLength); + ); +#endif + + CopyMem (&AtAuthCmd->Credential.Value, PassPhrase, AT_USR_PASS_HASH_LENGTH_MAX); + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthCmd Body 2: \n")); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) AtAuthCmd, HeciLength); + ); + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential PassPhrase Body 3: \n")); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) PassPhrase, AtAuthCmd->Credential.Length); + ); +#endif + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AutheticateCrdential: Locating for HECI Driver Failed!, Status = %r\n", Status)); + FreePool (AtAuthCmd); + return Status; + } + } + + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential PassPhrase Length: %x\n", AtAuthCmd->Credential.Length)); + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthCmd HeciLength: %x\n", HeciLength)); +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthCmd Body 3: \n")); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) AtAuthCmd, HeciLength); + ); +#endif + + Status = mHeci->SendMsg ( + (UINT32 *) AtAuthCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AutheticateCrdential failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + FreePool (AtAuthCmd); + return Status; + } + + FreePool (AtAuthCmd); + + HeciLength = sizeof (ATHI_AUTHENTICATE_CREDENTIAL_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtAuthRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AutheticateCrdential failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthCmd Body 4: %x\n", AtAuthCmd)); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) AtAuthCmd, HeciLength); + ); +#endif + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthRsp HeciLength: %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AT::AutheticateCrdential AtAuthRsp.CompletionCode: %x\n", AtAuthRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, + "AT::AutheticateCrdential AtAuthRsp.Header.Command.IsResponse: %x\n", AtAuthRsp.Header.Command. + IsResponse)); + DEBUG ((EFI_D_ERROR, "checkRecoveryPassword AtAuthRsp.Authenticated: %d\n", AtAuthRsp.Authenticated)); + + /// + /// Assuming 0 is for success + /// + *IsAuthenticated = AtAuthRsp.Authenticated; + + return EFI_SUCCESS; +} + +/** + This API compute the SHA1 hash of the user enterted password + + @param[in] This The address of protocol + @param[in] PassPhrase The passphrase for which SHA1 hash to be computed + @param[in][out] Hash The return value of the SHA1 hash + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +ComputeHash ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN OUT UINT8 *Hash + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + + ATHI_COMPUTE_HASH_CMD AtComputeHashCmd; + ATHI_COMPUTE_HASH_RSP AtComputeHashRsp; + + ZeroMem ((VOID *) &AtComputeHashCmd, sizeof (ATHI_COMPUTE_HASH_CMD)); + ZeroMem ((VOID *) &AtComputeHashRsp, sizeof (ATHI_COMPUTE_HASH_RSP)); + + DEBUG ((EFI_D_ERROR, "AT::AtComputeHashRsp DEBUG in ComputHash\n")); + + AtComputeHashCmd.Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtComputeHashCmd.Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtComputeHashCmd.Header.Command.Category = ATHI_CMD_GROUP_RECOVERY; + AtComputeHashCmd.Header.Command.IsResponse = AT_COMMAND; + AtComputeHashCmd.Header.Command.Code = ATHI_RECOVERY_GRP_COMPUTE_HASH_CMD; + + AtComputeHashCmd.Algorithm = AT_HASH_ALGO_ID_SHA1; + AtComputeHashCmd.InputLength = (UINT8) AsciiStrLen ((CHAR8 *) PassPhrase); + + // + // Check for length + // + // + // 0- Length 0 only header with command is send as message + // + AtComputeHashCmd.Header.Length = sizeof (ATHI_COMPUTE_HASH_CMD) - + 48 - + sizeof (ATHI_HEADER) + + AtComputeHashCmd.InputLength; + + CopyMem (&AtComputeHashCmd.InputBuffer, PassPhrase, AtComputeHashCmd.InputLength); + HeciLength = sizeof (ATHI_COMPUTE_HASH_CMD) - AT_MAX_HASH_OUTPUT_SIZE + AtComputeHashCmd.InputLength; + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AtComputeHashCmd message length = %x\n", HeciLength)); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) &AtComputeHashCmd, HeciLength); + ); + DEBUG ((EFI_D_ERROR, "AT::Look for UINT8Pass\n")); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) PassPhrase, AtComputeHashCmd.InputLength); + ); +#endif + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtComputeHash: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + Status = mHeci->SendMsg ( + (UINT32 *) &AtComputeHashCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtComputeHashCmd failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_COMPUTE_HASH_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtComputeHashRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtComputeHashRsp failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "AT::AtComputeHashRsp response message length %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtComputeHashRsp.CompletionCode = %x\n", AtComputeHashRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, "AtComputeHashRsp.OutputLength = %x\n", AtComputeHashRsp.OutputLength)); + + if (AtComputeHashRsp.OutputLength != 0) { + DEBUG ((EFI_D_ERROR, "AtComputeHashRsp.OutputLength = %x\n", AtComputeHashRsp.OutputLength)); + } + + CopyMem (Hash, &AtComputeHashRsp.OutputBuffer, AtComputeHashRsp.OutputLength); + + return EFI_SUCCESS; +} + +/** + This API get the AT Unlock Timer values + + @param[in] This The address of protocol + @param[in] Interval The return value of the Unlock Time Interval that was set by AT Server + @param[in] TimeLeft The Timeleft in the Unlock Timer + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetTimerInfo ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT32 *Interval, + IN OUT UINT32 *TimeLeft + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + + ATHI_GET_TIMER_INFO_CMD AtGetTimerInfoCmd; + ATHI_GET_TIMER_INFO_RSP AtGetTimerInfoRsp; + + ZeroMem ((VOID *) &AtGetTimerInfoCmd, sizeof (ATHI_GET_TIMER_INFO_CMD)); + ZeroMem ((VOID *) &AtGetTimerInfoRsp, sizeof (ATHI_GET_TIMER_INFO_RSP)); + + AtGetTimerInfoCmd.Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtGetTimerInfoCmd.Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtGetTimerInfoCmd.Header.Command.Category = ATHI_CMD_GROUP_THEFT_DETECTION; + AtGetTimerInfoCmd.Header.Command.IsResponse = AT_COMMAND; + AtGetTimerInfoCmd.Header.Command.Code = ATHI_THEFT_DETECT_GRP_GET_TIMER_INFO_CMD; + // + // 0- Length 0 only header with command is send as message + // + AtGetTimerInfoCmd.Header.Length = sizeof (ATHI_GET_TIMER_INFO_CMD) - sizeof (ATHI_HEADER); + AtGetTimerInfoCmd.TimerId = AT_TID_UNLOCK_TIMER; + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetTimerInfo: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + HeciLength = sizeof (ATHI_GET_TIMER_INFO_CMD); + + Status = mHeci->SendMsg ( + (UINT32 *) &AtGetTimerInfoCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetTimerInfo failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_GET_TIMER_INFO_RSP); + + DEBUG ((EFI_D_ERROR, "AT::AtGetTimerInfo response message length = %x\n", HeciLength)); + + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtGetTimerInfoRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetTimerInfoRsp failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "AT::AtGetTimerInfo response message length = %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtGetTimerInfoRsp.CompletionCode = %x\n", AtGetTimerInfoRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, "AtGetTimerInfoRsp.TimerInfo.Interval = %x\n", AtGetTimerInfoRsp.TimerInfo.Interval)); + DEBUG ((EFI_D_ERROR, "AtGetTimerInfoRsp.TimerInfo.TimeLeft = %x\n", AtGetTimerInfoRsp.TimerInfo.TimeLeft)); + + *Interval = AtGetTimerInfoRsp.TimerInfo.Interval; + *TimeLeft = AtGetTimerInfoRsp.TimerInfo.TimeLeft; + + return EFI_SUCCESS; + +} + +/** + This gets the ME nonce + @param[in] This The address of protocol + @param[in][out] Nonce The return value of the 16 Byte nonce received from ME + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetNonce ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *Nonce + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + + ATHI_GET_NONCE_CMD AtGetNonceCmd; + ATHI_GET_NONCE_RSP AtGetNonceRsp; + + ZeroMem ((VOID *) &AtGetNonceCmd, sizeof (ATHI_GET_NONCE_CMD)); + ZeroMem ((VOID *) &AtGetNonceRsp, sizeof (ATHI_GET_NONCE_RSP)); + + AtGetNonceCmd.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtGetNonceCmd.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtGetNonceCmd.Command.Category = ATHI_CMD_GROUP_GENERAL; + AtGetNonceCmd.Command.IsResponse = AT_COMMAND; + AtGetNonceCmd.Command.Code = ATHI_GENERAL_GRP_GET_NONCE_CMD; + + // + // 0- Length 0 only header with command is send as message + // + AtGetNonceCmd.Length = sizeof (ATHI_GET_STATE_CMD) - sizeof (ATHI_HEADER); + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetNonce: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + HeciLength = sizeof (ATHI_GET_NONCE_CMD); + + Status = mHeci->SendMsg ( + (UINT32 *) &AtGetNonceCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetNonce failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_GET_NONCE_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtGetNonceRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetNonce failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AtGetNonce response message length %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtGetNonceRsp.CompletionCode = %x\n", AtGetNonceRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, "AtGetNonceRsp.Nonce = %x\n", AtGetNonceRsp.Nonce)); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) &AtGetNonceRsp.Nonce, AT_NONCE_LENGTH); + ); +#endif + + if (AtGetNonceRsp.CompletionCode == ATHI_COMPCODE_SUCCESS) { + DEBUG ((EFI_D_ERROR, "AtGetNonceRsp.CompletionCode = %x\n", AtGetNonceRsp.CompletionCode)); + } + + CopyMem (Nonce, &AtGetNonceRsp.Nonce, AT_NONCE_LENGTH); + + return EFI_SUCCESS; + +} + +/** + This retrives the ISV String stored by AT Server that BIOS will display during Platform lock state + + @param[in] This The address of protocol + @param[in] StringId The String buffer ID to retrive the ISV String + @param[out] IsvString 256 Bytes of ISV string array, the + @param[out] IsvStringLength The String length + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetRecoveryString ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 *StringId, + OUT UINT8 *IsvString, + OUT UINT32 *IsvStringLength + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + ATHI_GET_VENDOR_STRING_CMD AtIsvStringCmd; + ATHI_GET_VENDOR_STRING_RSP AtIsvStringRsp; + + ZeroMem ((VOID *) &AtIsvStringCmd, sizeof (ATHI_GET_VENDOR_STRING_CMD)); + ZeroMem ((VOID *) &AtIsvStringRsp, sizeof (ATHI_GET_VENDOR_STRING_RSP)); + // + // Setting the length of IsvString to 0 here. + // + *IsvStringLength = 0; + + AtIsvStringCmd.Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtIsvStringCmd.Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtIsvStringCmd.Header.Command.Category = ATHI_CMD_GROUP_DATA_STORAGE; + AtIsvStringCmd.Header.Command.IsResponse = AT_COMMAND; + AtIsvStringCmd.Header.Command.Code = ATHI_DATA_STORE_GRP_GET_VENDOR_STRING_CMD; + AtIsvStringCmd.Header.Length = sizeof (ATHI_GET_VENDOR_STRING_CMD) - sizeof (ATHI_HEADER); + AtIsvStringCmd.Id = (UINT8) *StringId; + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtIsvStringCmd: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + HeciLength = sizeof (ATHI_GET_VENDOR_STRING_CMD); + + PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8200); + Status = mHeci->SendMsg ( + (UINT32 *) &AtIsvStringCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtIsvStringCmd failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_GET_VENDOR_STRING_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtIsvStringRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtIsvStringRsp failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8202); + return Status; + } + + PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8201); + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "AT::AtIsvStringRsp response message length = %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtIsvStringRsp.CompletionCode = %x\n", AtIsvStringRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, "AtIsvStringRsp.String.Length = %x\n", AtIsvStringRsp.String.Length)); + DEBUG_CODE ( + ShowBuffer ((UINT8 *) &AtIsvStringRsp.String.Value, (UINT32) AtIsvStringRsp.String.Length); + ); +#endif + + if ((AtIsvStringRsp.CompletionCode == 0) && + (AtIsvStringRsp.String.Length > 0 && AtIsvStringRsp.String.Length < 256) + ) { + + CopyMem (IsvString, &AtIsvStringRsp.String.Value, AtIsvStringRsp.String.Length); + *IsvStringLength = AtIsvStringRsp.String.Length; + return EFI_SUCCESS; + } + + return EFIERR (AtIsvStringRsp.CompletionCode);; +} + +/** + This send an AssertStolen Message to ME when OEM has set the AllowAssertStolen bit to be accepted by BIOS. + + @param[in] This The address of protocol + @param[out] CompletionCode The return ME Firmware return code for this request + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SendAssertStolen ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *CompletionCode + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + ATHI_ASSERT_STOLEN_CMD AtAssertStolenCmd; + ATHI_ASSERT_STOLEN_RSP AtAssertStolenRsp; + + // + // Initialize Variables + // + ZeroMem ((VOID *) &AtAssertStolenCmd, sizeof (ATHI_ASSERT_STOLEN_CMD)); + ZeroMem ((VOID *) &AtAssertStolenRsp, sizeof (ATHI_ASSERT_STOLEN_RSP)); + + /// + /// Populate AtAssertStolenCmd + /// + AtAssertStolenCmd.Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtAssertStolenCmd.Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtAssertStolenCmd.Header.Command.Category = ATHI_CMD_GROUP_THEFT_DETECTION; + AtAssertStolenCmd.Header.Command.IsResponse = AT_COMMAND; + AtAssertStolenCmd.Header.Command.Code = ATHI_THEFT_DETECT_GRP_UNSIGNED_ASSERT_STOLEN_CMD; + AtAssertStolenCmd.Header.Length = sizeof (ATHI_ASSERT_STOLEN_CMD) - sizeof (ATHI_HEADER); + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SendAssertStolen: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + /// + /// Send AtAssertStolenCmd Request + /// + HeciLength = sizeof (ATHI_ASSERT_STOLEN_CMD); + + Status = mHeci->SendMsg ( + (UINT32 *) &AtAssertStolenCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtAssertStolenCmd failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + /// + /// Receive AtAssertStolenCmd Response + /// + HeciLength = sizeof (ATHI_ASSERT_STOLEN_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtAssertStolenRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtAssertStolenRsp failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "ATAM: AtAssertStolen response message length %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "ATAM: AtAssertStolenRsp.CompletionCode = %x\n", AtAssertStolenRsp.CompletionCode)); + + *CompletionCode = AtAssertStolenRsp.CompletionCode; + + return EFI_SUCCESS; + +} + +/** + This receives the ISV ID from ME and display the ID, when the platform is in stolen state + + @param[in] This The address of protocol + @param[out] IsvId The pointer to 4 byte ISV ID + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIsvId ( + IN EFI_AT_PROTOCOL *This, + OUT UINT32 *IsvId + ) +{ + + UINT32 HeciLength; + EFI_STATUS Status; + + ATHI_GET_ISVID_CMD AtGetIsvIdCmd; + ATHI_GET_ISVID_RSP AtGetIsvIdRsp; + + ZeroMem ((VOID *) &AtGetIsvIdCmd, sizeof (ATHI_GET_ISVID_CMD)); + ZeroMem ((VOID *) &AtGetIsvIdRsp, sizeof (ATHI_GET_ISVID_RSP)); + + AtGetIsvIdCmd.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtGetIsvIdCmd.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtGetIsvIdCmd.Command.Category = ATHI_CMD_GROUP_RECOVERY; + AtGetIsvIdCmd.Command.IsResponse = AT_COMMAND; + AtGetIsvIdCmd.Command.Code = ATHI_RECOVERY_GRP_GET_ISVID_CMD; + AtGetIsvIdCmd.Length = sizeof (ATHI_GET_ISVID_CMD) - sizeof (ATHI_HEADER); + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "GetIsvId: Locating for HECI Driver Failed!, Status = %r\n", Status)); + return Status; + } + } + + HeciLength = sizeof (ATHI_GET_ISVID_CMD); + + Status = mHeci->SendMsg ( + (UINT32 *) &AtGetIsvIdCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "GetIsvId failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_GET_ISVID_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtGetIsvIdRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "GetIsvId failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "AT::AtGetIsvIdRsp response message length = %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtGetIsvIdRsp.CompletionCode = %x\n", AtGetIsvIdRsp.CompletionCode)); + DEBUG ((EFI_D_ERROR, "AtGetIsvIdRsp.IsvId = %x\n", AtGetIsvIdRsp.IsvId)); + + if (!AtGetIsvIdRsp.CompletionCode) { + *IsvId = AtGetIsvIdRsp.IsvId; + } + + return EFI_SUCCESS; + +} + +/** + This requests FW to enter or exit Suspend mode based on user input + + @param[in] This The address of protocol + @param[in] TransitionState 0: Exit Suspend Mode + 1: Enter Suspend Mode + @param[in] Token SSTK generated Token + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +EFIAPI +SetSuspendState ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ) +{ + UINT32 HeciLength; + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + + ATHI_SET_SUSPEND_STATE_CMD *AtSetSuspendStateCmd; + ATHI_SET_SUSPEND_STATE_RSP AtSetSuspendStateRsp; + + AtSetSuspendStateCmd = AllocateZeroPool (sizeof (ATHI_SET_SUSPEND_STATE_CMD) + AT_USR_PASS_HASH_LENGTH_MAX); + if (AtSetSuspendStateCmd == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *) &AtSetSuspendStateRsp, sizeof (ATHI_SET_SUSPEND_STATE_RSP)); + + AtSetSuspendStateCmd->Header.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtSetSuspendStateCmd->Header.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtSetSuspendStateCmd->Header.Command.Category = ATHI_CMD_GROUP_GENERAL; + AtSetSuspendStateCmd->Header.Command.IsResponse = AT_COMMAND; + AtSetSuspendStateCmd->Header.Command.Code = ATHI_GENERAL_GRP_SET_SUSPEND_CMD; + AtSetSuspendStateCmd->TransitionState = TransitionState; + + // + // AT_CREDENTIAL has extra UINT8 (can't have zero length array like FW) that must be subtracted + // + AtSetSuspendStateCmd->Header.Length = (sizeof (ATHI_SET_SUSPEND_STATE_CMD) - sizeof (UINT8)) - (sizeof (ATHI_HEADER)) + AT_USR_PASS_HASH_LENGTH_MAX; + AtSetSuspendStateCmd->Credential.Type = AT_CREDENTIAL_TYPE_SSTK; + AtSetSuspendStateCmd->Credential.Length = AT_USR_PASS_HASH_LENGTH_MAX; + CopyMem (AtSetSuspendStateCmd->Credential.Value, Token, AT_USR_PASS_HASH_LENGTH_MAX); + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SetSuspendState: Locating for HECI Driver Failed!, Status = %r\n", Status)); + FreePool (AtSetSuspendStateCmd); + return Status; + } + + HeciLength = sizeof (ATHI_SET_SUSPEND_STATE_CMD) - sizeof (UINT8) + AT_USR_PASS_HASH_LENGTH_MAX; + + Status = Heci->SendMsg ( + (UINT32 *) AtSetSuspendStateCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SetSuspendState failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + FreePool (AtSetSuspendStateCmd); + return Status; + } + + FreePool (AtSetSuspendStateCmd); + + HeciLength = sizeof (ATHI_SET_SUSPEND_STATE_RSP); + Status = Heci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtSetSuspendStateRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SetSuspendState failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "AT::SetSuspendState response message length %x\n", HeciLength)); + DEBUG ((EFI_D_ERROR, "AtSetSuspendStateRsp.CompletionCode = %x\n", AtSetSuspendStateRsp.CompletionCode)); + + if (AtSetSuspendStateRsp.CompletionCode) { + return EFIERR (AtSetSuspendStateRsp.CompletionCode); + } + + return EFI_SUCCESS; +} + +/** + This instructs FW that a WWAN recovery is desired and thus the Radio needs to be initialized. + + This command in not supported. + + @param[in] This The address of protocol +**/ +EFI_STATUS +InitWWANREcov ( + IN EFI_AT_PROTOCOL *This + ) +{ + /// + /// This command in not supported. + /// + return EFI_UNSUPPORTED; +} + +/** + This queries FW of the NIC Radio Status + + This command in not supported. + + @param[in] This The address of protocol + @param[in] RadioStatus Radio status + @param[in] NetworkStatus Network status +**/ +EFI_STATUS +GetWWANNicStatus ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *RadioStatus, + IN OUT UINT8 *NetworkStatus + ) +{ + /// + /// This command in not supported. + /// + return EFI_UNSUPPORTED; +} + +/** + This queries FW of the AT Status in Unsigned mode + + @param[in] This The address of protocol + @param[out] StateUnsigned Structure retrieved from ME describing current AT state + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +GetStateUnsigned ( + IN EFI_AT_PROTOCOL *This, + OUT AT_STATE_INFO *StateUnsigned + ) +{ + UINT32 HeciLength; + EFI_STATUS Status; + + ATHI_GET_STATE_CMD AtGetStateCmd; + ATHI_GET_STATE_RSP AtGetStateRsp; + + ZeroMem ((VOID *) &AtGetStateCmd, sizeof (ATHI_GET_STATE_CMD)); + ZeroMem ((VOID *) &AtGetStateRsp, sizeof (ATHI_GET_STATE_RSP)); + + AtGetStateCmd.Version.Major = ATHI_PROTOCOL_VERSION_MAJOR; + AtGetStateCmd.Version.Minor = ATHI_PROTOCOL_VERSION_MINOR; + AtGetStateCmd.Command.Code = ATHI_THEFT_DETECT_GRP_GET_STATE_UNSIGNED; + AtGetStateCmd.Command.Category = ATHI_CMD_GROUP_THEFT_DETECTION; + AtGetStateCmd.Command.IsResponse = AT_COMMAND; + AtGetStateCmd.Length = sizeof (ATHI_GET_STATE_CMD) - sizeof (ATHI_HEADER); + + if (mHeci == NULL) { + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &mHeci + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetStateUnsigned: Locating HECI Protocol failed!, Status = %r\n", Status)); + return Status; + } + } + + HeciLength = sizeof (ATHI_GET_STATE_CMD); + + Status = mHeci->SendMsg ( + (UINT32 *) &AtGetStateCmd, + HeciLength, + BIOS_FIXED_HOST_ADDR, + HECI_AT_MESSAGE_ADDR + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetStateUnsigned failed to send message over HECI!(SendMsg), Status = %r\n", Status)); + return Status; + } + + HeciLength = sizeof (ATHI_GET_STATE_RSP); + Status = mHeci->ReadMsg ( + BLOCKING, + (UINT32 *) &AtGetStateRsp, + &HeciLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "AtGetStateUnsigned failed to receive message over HECI!(ReadMsg), Status = %r\n", Status)); + return Status; + } + + if (AtGetStateRsp.CompletionCode == ATHI_COMPCODE_SUCCESS) { + DEBUG ((EFI_D_ERROR, "AtGetStateRsp.CompletionCode = %x\n", AtGetStateRsp.CompletionCode)); + CopyMem (StateUnsigned, &(AtGetStateRsp.StateInfo), sizeof (AT_STATE_INFO)); + } + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/At/AtAm/Dxe/At.h b/ReferenceCode/ME/At/AtAm/Dxe/At.h new file mode 100644 index 0000000..cc19c9d --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/At.h @@ -0,0 +1,280 @@ +/** @file + Defines and prototypes for the AT driver. + This driver implements the AT protocol. + +@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 + +**/ +#ifndef _AT_H_ +#define _AT_H_ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AtHi.h" +#include "MeLib.h" +#include "AtAmHelper.h" +#endif + +// +// Used during initialization +// +#include EFI_PROTOCOL_CONSUMER (FirmwareVolume) +#include EFI_PROTOCOL_CONSUMER (HECI) + +// +// Driver Produced Protocols +// +#include EFI_PROTOCOL_PRODUCER (At) + +// +// extern EFI_GUID gDxePlatformAtGuid; +// +#define AT_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('A', 'T', 'D', 'R') + +#pragma pack(1) +/// +/// 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 struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_AT_PROTOCOL AtProtocol; + +} AT_INSTANCE; + +#define AT_INSTANCE_FROM_AT_PROTOCOL(a) CR (a, AT_INSTANCE, At, AT_PRIVATE_DATA_SIGNATURE) + +#pragma pack() + +/** + Entry point for the AT Driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +AtEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +/** + This function sends a request to ME AT Services to validate AT + recovery credentials. The user input is captured in UTF-16 + format and then passed to this funtion. This function converts + the User recovery password into a HASH by using Salt & Nonce + and then send the password HASH to ME AT Services for + validation. ME AT Service compares the Password HASH and + returns either pass or fail. + + @param[in] This The address of protocol + @param[in] PassPhrase Passphrase that needs to be authenticated sent to ME + @param[in] PassType Password type user or server generated + @param[in][out] IsAuthenticated The return of the password match 1 for success and 0 for fail + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +EFIAPI +AuthenticateCredential ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN UINT32 *PassType, + IN OUT UINT8 *IsAuthenticated + ) +; + +/** + This API compute the SHA1 hash of the user enterted password + + @param[in] This The address of protocol + @param[in] PassPhrase The passphrase for which SHA1 hash to be computed + @param[in][out] Hash The return value of the SHA1 hash + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +ComputeHash ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN OUT UINT8 *Hash + ) +; + +/** + This API get the AT Unlock Timer values + + @param[in] This The address of protocol + @param[in] Interval The return value of the Unlock Time Interval that was set by AT Server + @param[in] TimeLeft The Timeleft in the Unlock Timer + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetTimerInfo ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT32 *Interval, + IN OUT UINT32 *TimeLeft + ) +; + +/** + This gets the ME nonce + @param[in] This The address of protocol + @param[in][out] Nonce The return value of the 16 Byte nonce received from ME + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetNonce ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *Nonce + ) +; + +/** + This retrives the ISV String stored by AT Server that BIOS will display during Platform lock state + + @param[in] This The address of protocol + @param[in] StringId The String buffer ID to retrive the ISV String + @param[out] IsvString 256 Bytes of ISV string array, the + @param[out] IsvStringLength The String length + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetRecoveryString ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 *StringId, + OUT UINT8 *IsvString, + OUT UINT32 *IsvStringLength + ) +; + +/** + This send an AssertStolen Message to ME when OEM has set the AllowAssertStolen bit to be accepted by BIOS. + + @param[in] This The address of protocol + @param[out] CompletionCode The return ME Firmware return code for this request + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SendAssertStolen ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *CompletionCode + ) +; + +/** + This receives the ISV ID from ME and display the ID, when the platform is in stolen state + + @param[in] This The address of protocol + @param[out] IsvId The pointer to 4 byte ISV ID + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +GetIsvId ( + IN EFI_AT_PROTOCOL *This, + OUT UINT32 *IsvId + ) +; + +/** + This requests FW to enter or exit Suspend mode based on user input + + @param[in] This The address of protocol + @param[in] TransitionState 0: Exit Suspend Mode + 1: Enter Suspend Mode + @param[in] Token SRTK generated Token + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +EFIAPI +SetSuspendState ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ) +; + +/** + This instructs FW that a WWAN recovery is desired and thus the Radio needs to be initialized. + + This command in not supported. + + @param[in] This The address of protocol +**/ +EFI_STATUS +InitWWANREcov ( + IN EFI_AT_PROTOCOL *This + ) +; + +/** + This queries FW of the NIC Radio Status + + This command in not supported. + + @param[in] This The address of protocol + @param[in] RadioStatus Radio status + @param[in] NetworkStatus Network status +**/ +EFI_STATUS +GetWWANNicStatus ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *RadioStatus, + IN OUT UINT8 *NetworkStatus + ) +; + +/** + This queries FW of the AT Status in Unsigned mode + + @param[in] This The address of protocol + @param[out] StateUnsigned Structure retrieved from ME describing current AT state + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +GetStateUnsigned ( + IN EFI_AT_PROTOCOL *This, + OUT AT_STATE_INFO *StateUnsigned + ) +; + +#endif diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAm.c b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.c new file mode 100644 index 0000000..4be107f --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.c @@ -0,0 +1,694 @@ +/** @file + This file contines routines responsible for hangling AT and provide interface for creating UI. + +@copyright + Copyright (c) 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 + +**/ +#include "AtAm.h" + +DXE_AT_POLICY_PROTOCOL *mDxePlatformAtPolicy; +static AT_BIOS_RECOVERY_CONFIG gBiosRecoveryGlobalVar; +static AT_STATE_INFO gAtStateGlobalVar; +static UINT16 gRecoveryAMGlobalVar; +static BOOLEAN gAtAmPrefUpdatedToATAM = FALSE; + +EFI_GUID gEfiPBAVariableGuid = PBA_FAILED_COUNT_VARIABLE_GUID; +EFI_GUID gEfiAtAmProtocolGuid = EFI_ATAM_PROTOCOL_GUID; + +extern AT_INSTANCE mAtInstance; + +ATAM_INSTANCE AtAmInstance = { + ATAM_PRIVATE_DATA_SIGNATURE, + NULL, + { + (UINT8) ATAM_PROTOCOL_REVISION, + (EFI_ATAM_GET_ISV_ID) AtAmGetIsvId, + (EFI_ATAM_GET_RECOVERY_CONFIG) AtAmGetRecoveryConfig, + (EFI_ATAM_GET_TIMER) AtAmGetTimer, + (EFI_ATAM_GET_NONCE) AtAmGetNonce, + (EFI_ATAM_VERIFY_PASSWORD) AtAmVerifyPassword, + (EFI_ATAM_SET_SUSPEND_STATE) AtAmSetSuspendState, + (EFI_ATAM_GET_AT_STATE_INFO) AtAmGetAtStateInfo, + (EFI_ATAM_GET_PBA_COUNTER) AtAmGetPbaCounter + } +}; + +/** + Driver entry point. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 MeStatus; + EFI_HECI_PROTOCOL *Heci; + UINT8 AtState; + UINT16 AtAmPref; + DXE_MBP_DATA_PROTOCOL *MbpData; + + + MeStatus = 0; + AtState = 0; + AtAmPref = 0; + + /// + ///Install AT protocol + /// + Status = AtEntryPoint(0, 0); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AT Protocol isn't installed, Status = %r\n", Status)); + return Status; + } + + Status = gBS->LocateProtocol ( + &gDxePlatformAtPolicyGuid, + NULL, + (VOID **) &mDxePlatformAtPolicy + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: No AT Platform Policy Protocol available")); + return Status; + } + ASSERT_EFI_ERROR (Status); + +#ifdef EFI_DEBUG + /// + /// Dump the AT platform policy + /// + DxeAtPolicyDebugDump (); +#endif + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: failed to locate HECI driver, Status = %r\n", Status)); + return Status; + } + + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + + if (mDxePlatformAtPolicy->At.AtAmBypass == 0) { + + /// + /// Check if ME is Normal State or Recovery Mode + /// + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY || + ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE || + ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_FW_UPDATES_IN_PROGRESS) { + /// + /// Get the MBP Data. + /// + Status = gBS->LocateProtocol (&gMeBiosPayloadDataProtocolGuid, NULL, (VOID **) &MbpData); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: No MBP Data Protocol available - Exit Early")); + return EFI_SUCCESS; + } + + if (!MbpData->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.IntelAT) { + DEBUG ((EFI_D_INFO, "ATAM: Exit Early - MEFWCAPS_SKU_RULE_ID indicates AT does not exist")); + return EFI_SUCCESS; + } else { + DEBUG ((EFI_D_INFO, "ATAM: ME FW SKU Info Variables indicates that AT exists")); + } + + DEBUG ((EFI_D_INFO, "ATAM::GetMeStatus is ME_READY\n", Status)); + + Status = GetAtStateInfo ( + &gAtStateGlobalVar + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM::GetAtStateInfo failed, Status = %r\n", Status)); + return Status; + } + + /// + /// Update Static Variable + /// + gRecoveryAMGlobalVar = gAtStateGlobalVar.flags.AuthenticateModule; + + DEBUG ((EFI_D_INFO, "ATAM: MeAtRuleDate AtState = %x\n", gAtStateGlobalVar.State)); + DEBUG ((EFI_D_INFO, "ATAM: MeAtRuleDate AtAmPref = %x\n", gAtStateGlobalVar.flags.AuthenticateModule)); + + /// + /// Check for PBA_ERROR_THRESHOLDS Level .... i.e. if PBA fails for x number of times then BIOS AM will + /// Ignore the PREFERRED_AM Selection + /// + AtAmPref = gAtStateGlobalVar.flags.AuthenticateModule; + AtState = gAtStateGlobalVar.State; + + Status = AtAmValidatePreferredAM (&AtState, &AtAmPref); + DEBUG ((EFI_D_INFO, "ATAM: ValidatePreferredAM, AtAmPref = %d\n", AtAmPref)); + + /// + /// Ignore the PREFERRED_AM Selection + /// + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "ATAM: ValidatePreferredAM failed, Status = %r\n", Status)); + } + } else { + DEBUG ((EFI_D_INFO, "ATAM: ME_READY Failed\n")); + Status = EFI_DEVICE_ERROR; + } + } else { + DEBUG ((EFI_D_INFO, "ATAM: AT Disabled in the BIOS\n")); + + Status = GetAtStateInfo ( + &gAtStateGlobalVar + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM::GetAtStateInfo failed, Status = %r\n", Status)); + return Status; + } + } + + Status = gBS->InstallMultipleProtocolInterfaces ( + &(AtAmInstance.Handle), + &gEfiAtAmProtocolGuid, + &(AtAmInstance.AtAmProtocol), + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol NOT Installed, Status = %r\n", Status)); + } else { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol Installed, Status = %r\n", Status)); + } + + return Status; +} + +/** + This function gets the ISV Strings stored by AT Server that BIOS will display. + + @param[in] This The address of protocol + @param[out] IsvString Isv string pointer + @param[out] IsvId Intel(R) Anti-Theft service provider Id + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmGetIsvId ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *IsvString, + OUT UINT32 *IsvId + ) +{ + EFI_STATUS Status; + UINT32 StringLength; + UINT32 StringId; + + StringLength = 0; + + Status = mAtInstance.AtProtocol.GetIsvId (&mAtInstance.AtProtocol, IsvId); + if (EFI_ERROR (Status)) { + /// + /// Let it continue even if the error .... + /// + DEBUG ((EFI_D_ERROR, "ATAM: GetIsvId failed, Status = %r\n", Status)); + } else { + DEBUG ((EFI_D_ERROR, "ATAM: GetIsvId IsvId = %r\n", *IsvId)); + } + + StringId = AT_VENDOR_STRING_ID_RECOVERY_HELP; + Status = mAtInstance.AtProtocol.GetRecoveryString (&mAtInstance.AtProtocol, &StringId, IsvString, &StringLength); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: GetRecoveryString AT_VENDOR_STRING_ID_RECOVERY_HELP failed, Status = %r\n", Status)); + /// + /// Let it continue even if the error + /// + } + + return Status; +} + +/** + This function returns time left to enter password. + + @param[in] This The address of protocol + @param[out] TimeLeft Time + @param[out] TimeInterval Time interval + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetTimer ( + IN EFI_AT_PROTOCOL *This, + OUT UINT32 *TimeLeft, + OUT UINT32 *TimeInterval + ) +{ + EFI_STATUS Status; + + Status = mAtInstance.AtProtocol.GetTimerInfo (&mAtInstance.AtProtocol, TimeInterval, TimeLeft); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: GetTimerInfo failed, Status = %r\n", Status)); + } + + return Status; +} + +/** + This function gets 16 bytes nonce from firmware and also converts it to string according to format "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XX". + + @param[in] This The address of protocol + @param[out] NonceStr Pointer to Nonce string + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetNonce ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *NonceStr + ) +{ + EFI_STATUS Status; + UINTN StrNonceLength; + UINT8 Nonce[NONCE_LENGTH]; + CHAR16 *UniCodeNonceStr; + + StrNonceLength = STR_NONCE_LENGTH; + + UniCodeNonceStr = AllocateZeroPool ((STR_NONCE_LENGTH + 1) * sizeof (CHAR16)); + if (UniCodeNonceStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mAtInstance.AtProtocol.GetNonce (&mAtInstance.AtProtocol, Nonce); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: GetSuspendAuthentication::GetNonce failed, Status = %r\n", Status)); + return Status; + } + + Base32Encode (NonceStr, &StrNonceLength, Nonce, NONCE_LENGTH); + Uint8ToUnicode ((CHAR8 *) NonceStr, UniCodeNonceStr); + + FreePool (UniCodeNonceStr); + + return Status; +} + +/** + This function gets recovery config. + + @param[in] This The address of protocol + @param[out] RecoveryConfig Pointer to structure + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmGetRecoveryConfig ( + IN EFI_AT_PROTOCOL *This, + OUT AT_BIOS_RECOVERY_CONFIG *RecoveryConfig + ) +{ + EFI_STATUS Status; + UINT32 StringId; + UINT32 StringLength; + + StringLength = 0; + + StringId = AT_CUSTOM_RECOVERY_ID_CONFIGURATIONS; + Status = mAtInstance.AtProtocol.GetRecoveryString (&mAtInstance.AtProtocol, &StringId, (UINT8 *) RecoveryConfig, &StringLength); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: GetRecoveryString failed, Status = %r\n", Status)); + /// + /// Let it continue even if the error + /// + } else { + DEBUG ((EFI_D_ERROR, "ATAM: GetRecoveryString StringLength = %d\n", StringLength)); + DEBUG ((EFI_D_ERROR, "ATAM: GetRecoveryString *IsvString = %d\n", *RecoveryConfig)); + DEBUG ((EFI_D_ERROR, "ATAM: GetRecoveryString StringId = %d\n", StringId)); + } + + return Status; +} + +/** + This routine receives the data (passphrase or SRTK) from UI and verifies it if the password (either passphrase or SRTK) is acceptable. + + @param[in] This The address of protocol + @param[in] PasswordEntered Pointer to string + @param[in] PassType Password type + @param[out] IsAuthenticated Pointer to result of verification + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmVerifyPassword ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PasswordEntered, + IN UINT32 PassType, + OUT UINT8 *IsAuthenticated + ) +{ + EFI_STATUS Status; + UINT8 *Hash; + UINT8 *PasswordHex; + UINT8 AtState; + UINT16 AtAmPref; + UINT8 IsAuthTmp = 0; + + Status = EFI_SUCCESS; + + PasswordHex = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + Hash = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + if (Hash == NULL || PasswordHex == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (PassType == AT_CREDENTIAL_TYPE_USER_PASSPHRASE) { + + Status = mAtInstance.AtProtocol.ComputeHash (&mAtInstance.AtProtocol, PasswordEntered, Hash); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ComputeHash failed, Status = %r\n", Status)); + } + + Status = mAtInstance.AtProtocol.AuthenticateCredential (&mAtInstance.AtProtocol, Hash, &PassType, &IsAuthTmp); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AuthenticateCredential, Status = %r\n", Status)); + } + + } else if (PassType == AT_CREDENTIAL_TYPE_SRTK) { + /// + /// User selected Base32 based Server based recovery, for BASE32 the length is always 32 + /// + if (AsciiStrLen((CHAR8 *) PasswordEntered) == 32) { + DEBUG ((EFI_D_ERROR, "ATAM: Password entered is SRTK BASE32 PASSWORD\n")); + /// + /// Decoded value is 20 byte hex + /// + Base32Decode (PasswordEntered, PasswordHex); + } else if (AsciiStrLen((CHAR8 *) PasswordEntered) > 40) { + /// + /// User selected Basee10 based Server based recovery, for BASE10 the length is always more than 40 + /// + DEBUG ((EFI_D_ERROR, "ATAM: Password entered is SRTK BASE10 PASSWORD\n")); + /// + /// Decoded value is 20 byte hex + /// + DecimalToHexString ((CHAR8 *) PasswordEntered, PasswordHex, MAX_HEX_BYTES - 1); + } + + Status = mAtInstance.AtProtocol.AuthenticateCredential (&mAtInstance.AtProtocol, PasswordHex, &PassType, &IsAuthTmp); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AuthenticateCredential, Status = %r\n", Status)); + } + } else { + DEBUG ((EFI_D_ERROR, "ATAM: Unknown Pass type \n")); + } + + /// + /// Calling ValidatePreferredAM to reset the PbafailedCount + /// + if (gAtStateGlobalVar.flags.AuthenticateModule == AT_AM_SELECTION_PBAM && IsAuthTmp == 1) { + AtState = AT_STATE_ACTIVE; + AtAmPref = AT_AM_SELECTION_PBAM; + Status = AtAmValidatePreferredAM (&AtState, &AtAmPref); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmValidatePreferredAM failed, Status = %r\n", Status)); + } + } + + *IsAuthenticated = IsAuthTmp; + + ZeroMem (Hash, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + ZeroMem (PasswordHex, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + FreePool (Hash); + FreePool (PasswordHex); + + return Status; +} + +/** + This routine receives the SSTK from UI and verifies it if the password is acceptable. This requests FW to enter or exit Suspend mode based on user input. + + @param[in] This The address of protocol + @param[in] TransitionState 1- enter suspend state, 0 - exit suspend state + @param[in] Token Pointer to token + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmSetSuspendState ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ) +{ + EFI_STATUS Status; + UINT8 TokenHex[ATAM_SETUP_PASSWORD_LENGTH]; + + DEBUG ((EFI_D_ERROR, "ATAM: SetSuspendState: Transition state = %x\n", TransitionState)); + + if(AsciiStrLen((CHAR8 *)Token) == 32) { + DEBUG ((EFI_D_ERROR, "ATAM: Suspend Password entered is in Base32\n")); + Base32Decode(Token, TokenHex); + } else if(AsciiStrLen((CHAR8 *)Token) > 40) { + DEBUG ((EFI_D_ERROR, "ATAM: Password entered is in Base10\n")); + DecimalToHexString((CHAR8 *) Token,TokenHex, MAX_HEX_BYTES - 1); + } else { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((EFI_D_ERROR, "ATAM: SrtkPass = %x\n", TokenHex)); + + Status = mAtInstance.AtProtocol.SetSuspendState (&mAtInstance.AtProtocol, TransitionState, TokenHex); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: SetSuspendState failed, Status = %r\n", Status)); + } else { + DEBUG ((EFI_D_ERROR, "ATAM: Successfully set suspended state\n")); + } + + return Status; +} + +/** + This routine gets AT state. + + @param[in] This The address of protocol + @param[out] AtStateInfo State of AT + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +AtAmGetAtStateInfo ( + IN EFI_AT_PROTOCOL *This, + OUT AT_STATE_INFO *AtStateInfo + ) +{ + + AtStateInfo->State = gAtStateGlobalVar.State; + AtStateInfo->LastTheftTrigger = gAtStateGlobalVar.LastTheftTrigger; + AtStateInfo->flags.LockState = gAtStateGlobalVar.flags.LockState; + AtStateInfo->flags.AuthenticateModule = gAtStateGlobalVar.flags.AuthenticateModule; + AtStateInfo->flags.S3Authentication = gAtStateGlobalVar.flags.S3Authentication; + AtStateInfo->flags.FlashVariableSecurity = gAtStateGlobalVar.flags.FlashVariableSecurity; + AtStateInfo->flags.FlashWearOut = gAtStateGlobalVar.flags.FlashWearOut; + if (gAtAmPrefUpdatedToATAM == TRUE) { + AtStateInfo->flags.AuthenticateModule = AT_AM_SELECTION_ATAM; + } + + return EFI_SUCCESS; +} + +/** + Validate preffered AM. + + @param[in] AtState State of AT + @param[in] AtAmPref Preferred AT authentication method + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmValidatePreferredAM ( + IN UINT8 *AtState, + IN UINT16 *AtAmPref + ) +{ + EFI_STATUS Status; + UINTN VarSize; + UINT8 PbaFailedCount; + UINT32 Attributes; + AT_BIOS_RECOVERY_CONFIG RecoveryConfig; + + VarSize = sizeof (UINT8); + + if (*AtAmPref == AT_AM_SELECTION_ATAM) { + return EFI_SUCCESS; + } + + if (*AtState == AT_STATE_ACTIVE) { + + Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; + Status = gRT->GetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + &Attributes, + &VarSize, + &PbaFailedCount + ); + if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "ATAM: ValidatePreferredAM failed, Status = %r\n", Status)); + return Status; + } + + if (Status == EFI_NOT_FOUND || PbaFailedCount > 0) { + + DEBUG ((EFI_D_INFO, "ATAM: ValidatePreferredAM In State Active PbaFailedCount not yet defined\n")); + /// + /// This will be the case 1st time after enrollment when PbaFailedCount i.e PREFERRED_AM is not defined + /// Define this variable here + /// + PbaFailedCount = 0; + Status = gRT->SetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT8), + &PbaFailedCount + ); + } + } + /// + /// Now get NVRAM Varible that store the PBA_Preferred_Failed count .. i.e. STOLEN_STATE which + /// which is incremented every boot + /// + if (*AtState == AT_STATE_STOLEN && *AtAmPref == AT_AM_SELECTION_PBAM) { + + AtAmGetRecoveryConfig (NULL, &RecoveryConfig); + + VarSize = sizeof (UINT8); + Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; + Status = gRT->GetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + &Attributes, + &VarSize, + &PbaFailedCount + ); + if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "ATAM: ValidatePreferredAM failed, Status = %r\n", Status)); + return Status; + } + + if (Status == EFI_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "ATAM: ValidatePreferredAM In State Stolen PbaFailedCount not yet defined\n")); + + /// + /// This will be the case 1st time after enrollment when PbaFailedCount i.e PREFERRED_AM is not defined and + /// AT somehow got into stolen mode + /// Define this variable here + /// + PbaFailedCount = 0; + Status = gRT->SetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT8), + &PbaFailedCount + ); + } else if (PbaFailedCount > 0 && PbaFailedCount >= (UINT8) RecoveryConfig.PbaOverRideThreshold) { + /// + /// Set the PREFERRED_AM to BIOS AM here + /// + *AtAmPref = AT_AM_SELECTION_ATAM; + gAtAmPrefUpdatedToATAM = TRUE; + DEBUG ((EFI_D_ERROR, "ATAM: ValidatePreferredAM PbaFailedCount = %d\n", PbaFailedCount)); + } + /// + /// Increment the PbaFailedCount count here + /// + PbaFailedCount = PbaFailedCount + 1; + Status = gRT->SetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT8), + &PbaFailedCount + ); + + DEBUG((EFI_D_INFO, "ATAM: ValidatePreferredAM PbaFailedCount incremented here:%d\n", PbaFailedCount)); + DEBUG((EFI_D_INFO, "ATAM: ValidatePreferredAM gBiosRecoveryGlobalVar.PbaOverRideThreshold:%d\n", + RecoveryConfig.PbaOverRideThreshold)); + + } + + return EFI_SUCCESS; +} + +/** + This routine checks if the PbaOverrideThreshold is exceeded. + + @param[out] PbaFailedExceeded TRUE when the PbaOverrideThreshold is exceeded + @param[out] PbaFailedAttempts Number of failed attempts + @param[out] PbaFailedThreshold Pba failed count treshold + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetPbaCounter ( + OUT UINT8* PbaFailedExceeded, + OUT UINT16* PbaFailedAttempts, + OUT UINT16* PbaFailedThreshold + ) +{ + EFI_STATUS Status; + UINTN VarSize; + UINT32 Attributes; + UINT8 PbaCount; + AT_BIOS_RECOVERY_CONFIG RecoveryConfig; + + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetPbaCounter\n")); + + *PbaFailedExceeded = FALSE; + VarSize = sizeof (UINT8); + + AtAmGetRecoveryConfig (NULL, &RecoveryConfig); + + Status = gRT->GetVariable ( + L"PBA_FAILED_COUNT", + &gEfiPBAVariableGuid, + &Attributes, + &VarSize, + &PbaCount + ); + + DEBUG ((EFI_D_ERROR, "ATAM: PbaCount = %d\n", PbaCount)); + DEBUG ((EFI_D_ERROR, "ATAM: PbaOverRideThreshold = %d\n", RecoveryConfig.PbaOverRideThreshold)); + + *PbaFailedAttempts = PbaCount; + *PbaFailedThreshold = RecoveryConfig.PbaOverRideThreshold; + + if (PbaCount >= (UINT8) RecoveryConfig.PbaOverRideThreshold) { + *PbaFailedExceeded = TRUE; + } + + return Status; +} diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAm.dxs b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.dxs new file mode 100644 index 0000000..5aac1dc --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.dxs @@ -0,0 +1,41 @@ +/** @file + Dependency expression file for ATAM Invocation Driver. + +@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 + +**/ + + +#include "AutoGen.h" +#include "DxeDepex.h" + +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (LegacyBios) +#include EFI_PROTOCOL_DEFINITION (BootScriptSave) +#include EFI_PROTOCOL_DEFINITION (At) +#include EFI_PROTOCOL_DEFINITION (Heci) +#include EFI_PROTOCOL_DEPENDENCY (MeBiosPayloadData) +#include EFI_PROTOCOL_DEFINITION (AtPlatformPolicy) +#endif + +DEPENDENCY_START + DXE_PLATFORM_AT_POLICY_GUID AND + EFI_HECI_PROTOCOL_GUID AND + ME_BIOS_PAYLOAD_DATA_PROTOCOL_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAm.h b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.h new file mode 100644 index 0000000..ece69d8 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.h @@ -0,0 +1,239 @@ +/** @file + Header file for hangling AT and provide interface for creating UI. + +@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 _ATAM_H_ +#define _ATAM_H_ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AtHi.h" +#include "MeLib.h" +#include "AtAmHelper.h" +#include "AtPolicyLib.h" +#include "At.h" +#endif + +// +// Used during initialization +// +#include EFI_PROTOCOL_CONSUMER (FirmwareVolume) +#include EFI_PROTOCOL_CONSUMER (HECI) +#include EFI_PROTOCOL_CONSUMER (At) +#include EFI_PROTOCOL_CONSUMER (AtPlatformPolicy) + +// +// Driver Produced Protocols +// +#include EFI_PROTOCOL_PRODUCER (AtAm) + +#define ATAM_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('A', 'T', 'A', 'M') + +#define MAX_HEX_BYTES 20 +#define ATAM_ENTER_SUSPEND_STATE 1 +#define ATAM_EXIT_SUSPEND_STATE 0 + +#define PBA_FAILED_COUNT_VARIABLE_GUID \ + { \ + 0x7c66ffdc, 0x423c, 0xe5d4, 0x25, 0x1b, 0x55, 0xad, 0xba, 0x95, 0x26, 0x98 \ + } + +#pragma pack(1) + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_ATAM_PROTOCOL AtAmProtocol; +} ATAM_INSTANCE; + +#define ATAM_INSTANCE_FROM_ATAM_PROTOCOL(a) CR (a, ATAM_INSTANCE, AtAm, ATAM_PRIVATE_DATA_SIGNATURE) + +#pragma pack() + +#define NONCE_LENGTH 16 +#define STR_NONCE_LENGTH 33 +#define ATAM_SETUP_PASSWORD_LENGTH 49 +#define ATAM_TIMER_STRING_LENGTH 10 +#define ISV_PLATFORM_ID_LENGTH 16 +#define SERVER_SHORTCODE_LENGTH 16 +#define DEFAULT_LANGUAGE_STRING 4 +#define RECOVERY_STRING_LENGTH 256 +#define MX_SMS_MESSAGES 99 + +typedef enum _AT_AM_SELECTION +{ + AT_AM_SELECTION_ATAM = 0, + AT_AM_SELECTION_PBAM, + AT_AM_SELECTION_MAX +} AT_AM_SELECTION; + +/** + This function gets the ISV Strings stored by AT Server that BIOS will display. + + @param[in] This The address of protocol + @param[out] IsvString Isv string pointer + @param[out] IsvId Intel(R) Anti-Theft service provider Id + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmGetIsvId ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *IsvString, + OUT UINT32 *IsvId + ) +; + +/** + This function returns time left to enter password. + + @param[in] This The address of protocol + @param[out] TimeLeft Time + @param[out] TimeInterval Time interval + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetTimer ( + IN EFI_AT_PROTOCOL *This, + OUT UINT32 *TimeLeft, + OUT UINT32 *TimeInterval + ) +; + +/** + This function gets 16 bytes nonce from firmware and also converts it to string according to format "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XX". + + @param[in] This The address of protocol + @param[out] NonceStr Pointer to Nonce string + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetNonce ( + IN EFI_AT_PROTOCOL *This, + OUT UINT8 *NonceStr + ) +; + +/** + This function gets recovery config. + + @param[in] This The address of protocol + @param[out] RecoveryConfig Pointer to structure + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmGetRecoveryConfig ( + IN EFI_AT_PROTOCOL *This, + OUT AT_BIOS_RECOVERY_CONFIG *RecoveryConfig + ) +; + +/** + This routine receives the data (passphrase or SRTK) from UI and verifies it if the password (either passphrase or SRTK) is acceptable. + + @param[in] This The address of protocol + @param[in] PasswordEntered Pointer to string + @param[in] PassType Password type + @param[out] IsAuthenticated Pointer to result of verification + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmVerifyPassword ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PasswordEntered, + IN UINT32 PassType, + OUT UINT8 *IsAuthenticated + ) +; + +/** + This routine receives the SSTK from UI and verifies it if the password is acceptable. This requests FW to enter or exit Suspend mode based on user input. + + @param[in] This The address of protocol + @param[in] TransitionState 1- enter suspend state, 0 - exit suspend state + @param[in] Token Pointer to token + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AtAmSetSuspendState ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ) +; + +/** + This routine gets AT state. + + @param[in] This The address of protocol + @param[out] AtStateInfo State of AT + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetAtStateInfo ( + IN EFI_AT_PROTOCOL *This, + OUT AT_STATE_INFO *AtStateInfo + ) +; + +/** + Validate preffered AM. + + @param[in] AtState State of AT + @param[in] AtAmPref Preferred AT authentication + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmValidatePreferredAM ( + IN UINT8 *AtState, + IN UINT16 *AtAmPref + ) +; + +/** + This routine checks if the PbaOverrideThreshold is exceeded. + + @param[out] PbaFailedExceeded TRUE when the PbaOverrideThreshold is exceeded + @param[out] PbaFailedAttempts Number of failed attempts + @param[out] PbaFailedThreshold Pba failed count treshold + + @retval EFI_SUCCESS The function completed + successfully. +**/ +EFI_STATUS +AtAmGetPbaCounter ( + OUT UINT8* PbaFailedExceeded, + OUT UINT16* PbaFailedAttempts, + OUT UINT16* PbaFailedThreshold + ) +; + +#endif // _ATAM_H_ diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAm.inf b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.inf new file mode 100644 index 0000000..8322e18 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAm.inf @@ -0,0 +1,95 @@ +## @file +# @todo ADD DESCRIPTION +# +#@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 +# + + +[defines] +BASE_NAME = AtAm +FILE_GUID = C810485E-D0EC-4e98-AAB5-120C7E554428 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + AtAm.c + AtAm.h + At.c + At.h + AtHi.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + . + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/At + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/At/AtAm/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AtLibrary + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AtLibrary/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Library + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + +[libraries.common] + AtDxeLib + MeProtocolLib + MeLib + MeGuidLib + EdkIIGlueBaseLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiLib + EdkIIGlueDxeMemoryAllocationLib + EdkIIGlueBasePrintLib + EdkProtocolLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=AtAm.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=AtAmEntryPoint + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__\ + -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.cif b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.cif new file mode 100644 index 0000000..e482950 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.cif @@ -0,0 +1,18 @@ +<component> + name = "AtAmDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\At\AtAm\Dxe\" + RefName = "AtAmDxe" +[files] +"At.c" +"At.h" +"AtAm.c" +"AtAm.h" +"AtAm.dxs" +"AtAm.inf" +"AtAmDxe.mak" +"AtAmDxe.sdl" +"AtHi.h" +[parts] +"ATAMProtocols" +<endComponent> diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.mak b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.mak new file mode 100644 index 0000000..b129b70 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.mak @@ -0,0 +1,81 @@ +# MAK file for the ModulePart:AtAmDxe + +all : AtAmDxe + +AtAmDxe : $(BUILD_DIR)\AtAmDxe.mak AtAmDxeBin + +$(BUILD_DIR)\AtAmDxe.mak : $(AtAmDxe_DIR)\$(@B).cif $(AtAmDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AtAmDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + + +AtAmDxe_INCLUDES=\ + $(AT_INCLUDES)\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(EdkIIGlueInclude)\ + $(IndustryStandard_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + + +AtAmDxe_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=AtAmEntryPoint"\ + /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_BASE_PCI_LIB_PCI_EXPRESS__ \ + /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \ + /D __EDKII_GLUE_UEFI_LIB__\ + /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \ + + +AtAmDxe_LIB_LINKS =\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EdkIIGlueBasePrintLib_LIB) \ + $(EdkIIGlueUefiLib_LIB)\ + $(TdtProtocolLib_LIB)\ + $(ProtocolLib_LIB)\ + $(EFISCRIPTLIB)\ + $(AmtLibDxe_LIB)\ + $(MeLibDxe_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(AmtGuidLib_LIB)\ + $(EFIGUIDLIB)\ + $(EDKPROTOCOLLIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EFIDRIVERLIB)\ + $(MeChipsetDxeLib_LIB)\ + $(AtDxeLib_LIB)\ + $(PchPlatformDxeLib_LIB) + + + +# MAK file for the eModule:AtAmDxe + +AtAmDxeBin : $(AtAmDxe_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\AtAmDxe.mak all\ + "MY_INCLUDES=$(AtAmDxe_INCLUDES)"\ + "MY_DEFINES=$(AtAmDxe_DEFINES)"\ + GUID=C810485E-D0EC-4e98-AAB5-120C7E554428\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(AtAmDxe_DIR)\AtAm.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ + + diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.sdl b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.sdl new file mode 100644 index 0000000..513a1a6 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtAmDxe.sdl @@ -0,0 +1,33 @@ +TOKEN + Name = "AtAmDxe_SUPPORT" + Value = "1" + Help = "Main switch to enable TdtDxe support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "AT_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes TdtDxe.mak to Project" + File = "AtAmDxe.mak" +End + +PATH + Name = "AtAmDxe_DIR" + Help = "Tdt file source directory" +End + +PATH + Name = "AtAmDxe_SOURCE" + Help = "iAMT Driver files source directory" +End + +ELINK + Name = "$(BUILD_DIR)\AtAmDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + + diff --git a/ReferenceCode/ME/At/AtAm/Dxe/AtHi.h b/ReferenceCode/ME/At/AtAm/Dxe/AtHi.h new file mode 100644 index 0000000..ee03cf8 --- /dev/null +++ b/ReferenceCode/ME/At/AtAm/Dxe/AtHi.h @@ -0,0 +1,1275 @@ +/** @file + Definition of AT Host Interface (ATHI) Protocol messages between the + AT Service and HOST Applications. + +@copyright + Copyright (c) 2007 - 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_HI_H +#define _AT_HI_H + +#include "MeLib.h" + +#define AT_COMMAND 0 +#define AT_RESPONSE 1 + +#define AT_ME_RULE_ID 0xd0000 +#define AT_ME_RULE_GROUP 0x03 +#define AT_ME_RULE_COMMAND 0x02 + +#pragma pack(1) +/// +/// ATHI Protocol Identifier +/// +/// AT Host Interface protocol GUID +/// +#define ATHI_PROTOCOL_GUID \ + { \ + 0x3C4852D6, 0xD47B, 0x4f46, 0xB0, 0x5E, 0xB5, 0xED, 0xC1, 0xAA, 0x43, 0x0A \ + } + +#define ATHI_PROTOCOL_FIXED_GUID \ + { \ + 0xfa8f55e8, 0xab22, 0x42dd, 0xb9, 0x16, 0x7d, 0xce, 0x39, 0x00, 0x25, 0x74 \ + } + +/// +/// AT Host Interface protocol version (for ME FW internal use) +/// +#define ATHI_PROTOCOL_VERSION_ME 1 + +/// +/// AT Host Interface protocol major version +/// +#define ATHI_PROTOCOL_VERSION_MAJOR 5 + +/// +/// AT Host Interface protocol minor version +/// +#define ATHI_PROTOCOL_VERSION_MINOR 0 + +/// +/// ATHI Framing Structures +/// Defines the ATHI header and creates a type name. +/// +/// Refer to AtHiHeader.dot "ATHI Header" +/// +typedef struct _ATHI_HEADER { + /// + /// The version number for the ATHI protocol. + /// + struct { + /// + /// The major version number. The major version number shall advance if + /// and only if backwards compatibility is broken by a change to the + /// protocol. If ME firmware doesn't specifically support the version + /// number supplied in the header, an error shall be returned. + /// + UINT8 Major; + + /// + /// The minor version number. All minor versions under a given major + /// version shall be backwards compatible with prevision minor versions + /// under that major version. If the version number supplied in the + /// header is higher than the minor version number supported by ME + /// firmware, an error shall be returned. + + UINT8 Minor; + } Version; + + /// + /// Specifies the command or response in the message. + /// + struct { + /// + /// The operation with which the command is associated. + /// + UINT16 Code : 7; + + /// + /// Command/Response indicator: + /// 0 The message contains a command. + /// 1 The message contains a response. + /// + UINT16 IsResponse : 1; + + /// + /// The functional category of the command + /// + /// See _ATHI_CMD_GROUP + /// + UINT16 Category : 8; + } Command; + + /// + /// The length in bytes of the message. The length applies to the message + /// body (excludes the header and signature fields). + /// + UINT32 Length; +} ATHI_HEADER; + +/// +/// Maximum blob data size. +/// +#define AT_BLOB_LENGTH_MAX 256 + +/// +/// Structure that defines the format of the Blob to be stored and retrieved +/// for the ISV software. +/// +typedef struct _AT_BLOB { + /// + /// The length of the data to be securely stored + /// + UINT32 Length; + + /// + /// The data to be securely stored + /// + UINT8 Value[AT_BLOB_LENGTH_MAX]; +} AT_BLOB; + +#define AT_NONCE_LENGTH 16 ///< Maximum nonce length. + +/// +/// Type definition for a nonce. To prevent replay of commands, a nonce +/// shall be added to each command message. A nonce is a value that is used +/// once. Ideally, each nonce value should not be used more than once during +/// the lifetime of the AT laptop computer. However, a nonce generation function +/// that guarantees a very low probability of nonce values being repeated shall +/// suffice. +/// + +typedef UINT8 AT_NONCE[AT_NONCE_LENGTH]; + +/// +/// Command Completion Codes. Each response message contains a completion code +/// that indicates whether the command completed successfully, and the nature +/// of the failure if it did not. +/// +typedef enum _ATHI_COMPLETION_CODE +{ + /// + /// The command completed successfully. + /// + ATHI_COMPCODE_SUCCESS = 0, + + /// + /// The command failed due to an internal error. + /// + ATHI_COMPCODE_INTERNAL_FAILURE, + + /// + /// The command is not recognized, or is recognized but not supported. + /// + ATHI_COMPCODE_INVALID_OPERATION, + + /// + /// A parameter value does not satisfy the requirements of the command. + /// + ATHI_COMPCODE_INVALID_PARAM = 6, + + /// + /// The value of the length field in the message header is outside the + /// supported range for the command. + /// + ATHI_COMPCODE_INVALID_MSG_LEN, + + /// + /// The command failed, but no information about the nature of the failure is available. + /// + ATHI_COMPCODE_GENERAL_FAILURE, + + /// + /// Maximum value for a completion code. + /// + ATHI_COMPCODE_MAXIMUM +} ATHI_COMPLETION_CODE; + +/// +/// Useful definitions for basic commands (commands without a body) +/// + +/// +/// Type name for an unsigned command message that has no body (header only). +/// +typedef ATHI_HEADER ATHI_BASIC_CMD; + +/// +/// Definition and type name for a basic response. The basic response has a +/// header and a minimal body (just the Completion Code). +/// +typedef struct _ATHI_BASIC_RSP { + ATHI_HEADER Header; ///< Message header + + ATHI_COMPLETION_CODE CompletionCode; ///< Completion code +} ATHI_BASIC_RSP; + +/// +/// AT Command Groups +/// + +/// Related ATHI commands are grouped into several categories. Each command +/// code contains the code of its category. See #ATHI_HEADER. +/// +typedef enum _ATHI_CMD_GROUP +{ + ATHI_CMD_GROUP_RESERVED = 0, ///< Reserved + + /// + /// Commands related to the ME's theft protection capabilities. + /// + /// See _ATHI_THEFT_DETECT_GRP_CMD + /// + ATHI_CMD_GROUP_THEFT_DETECTION, + + /// + /// Commands related to non-volatile data storage services provided to + /// the FDE/FLE software present on the AT laptop computer. + /// + /// See _ATHI_DATA_STORE_GRP_CMD + /// + ATHI_CMD_GROUP_DATA_STORAGE, + + /// + /// Commands related to securely recovering the AT laptop computer for + /// AT disablement actions. + /// + /// See _ATHI_RECOVERY_GRP_CMD + /// + ATHI_CMD_GROUP_RECOVERY, + + /// + /// Commands related to ATHI infrastructure. + /// + /// See _ATHI_GENERAL_GRP_CMD + /// + ATHI_CMD_GROUP_GENERAL, + + /// + /// Event notifications serve to inform the ME AT Service when an + /// event occurs in the PBA or AT server. + /// + /// See _ATHI_NOTIFICATION_GRP_CMD + /// + ATHI_CMD_GROUP_NOTIFICATIONS, + + /// + /// 3G NIC commands allow BIOS to initialize and request Radio + /// status from FW + /// + /// See _ATHI_3G_NIC_GRP_CMD + /// + ATHI_CMD_GROUP_3G_NIC, + + /// + /// Boundary check. + /// + ATHI_CMD_GROUP_MAX +} ATHI_CMD_GROUP; + +/// +/// ATHI THEFT DETECTION Group Commands +/// + +/// Theft detection commands control and configure the theft protection +/// capabilities of the ME AT Service. +/// +typedef enum _ATHI_THEFT_DETECT_GRP_CMD +{ + /// + /// Returns the AT state of the monitored system. + /// + /// See ATHI_GET_STATE_CMD + /// + ATHI_THEFT_DETECT_GRP_GET_STATE_CMD, + + /// + /// Returns the state of the specified timer. + /// + /// See ATHI_GET_TIMER_INFO_CMD + /// + ATHI_THEFT_DETECT_GRP_GET_TIMER_INFO_CMD, + + /// + /// Resets the specified timer to its configured reset interval. + /// + /// See ATHI_RESET_TIMER_CMD + /// + ATHI_THEFT_DETECT_GRP_RST_TIMER_CMD, + + /// + /// Configures the actions that the ME AT Service shall take if the + /// specified event occurs. + /// + /// See ATHI_SET_POLICY_CMD + /// + ATHI_THEFT_DETECT_GRP_SET_POLICY_CMD, + + /// + /// Returns the actions that the ME AT Service shall take if the + /// specified event occurs. + /// + /// See ATHI_GET_POLICY_CMD + /// + ATHI_THEFT_DETECT_GRP_GET_POLICY_CMD, + + /// + /// Sets the reset interval for the specified timer. The timer counts down + /// and expires if it reaches 0. + /// + /// See ATHI_SET_TIMER_INTERVAL_CMD + /// + ATHI_THEFT_DETECT_GRP_SET_TIMER_INTERVAL_CMD, + + /// + /// Asserts that the AT laptop is stolen. The ME AT Service shall proceed + /// immediately to the Stolen state, executing all actions in the + /// AssertStolenPolicy. + /// + /// See ATHI_ASSERT_STOLEN_CMD + /// + ATHI_THEFT_DETECT_GRP_ASSERT_STOLEN_CMD, + + /// + /// Same as the AssertStolen command but not signed. + /// + /// See ATHI_ASSERT_STOLEN_CMD + /// + ATHI_THEFT_DETECT_GRP_UNSIGNED_ASSERT_STOLEN_CMD, + + /// + /// Returns the AT current state in unsigned mode. + /// + /// See GET_STATE_UNSIGNED + /// + ATHI_THEFT_DETECT_GRP_GET_STATE_UNSIGNED, + + /// + /// Boundary check. + /// + ATHI_THEFT_DETECT_GRP_MAX +} ATHI_THEFT_DETECT_GRP_CMD; + +/// +/// This flag indicates that AT is in the STOLEN state and the policies are set +/// to "do nothing". The mask must be applied to the AT state rule. +/// +/// NOTE: This flag is only cleared when the FW receives an AssertStolen +/// message. +/// +#define AT_PSEUDO_STOLEN_STATE_MASK 0x00000080 + +/// +/// Enumeration of AT theft triggers IDs +/// +typedef enum _AT_THEFT_TRIGGER +{ + /// + /// None. + /// + AT_THEFT_TRIGGER_NA = 0, + + /// + /// Theft trigger identifier for disable timer expiration + /// + AT_THEFT_TRIGGER_DISABLE_TIMER_EXPIRATION, + + /// + /// Theft trigger identifier for command driven disablement. + /// + AT_THEFT_TRIGGER_ASSERT_STOLEN, + + /// + /// Theft trigger identifier for PBA logon failure exceeded threshold. + /// + AT_THEFT_TRIGGER_THRESHOLD_EXCEEDED, + + /// + /// Theft trigger identifier for platform attack detection. + /// + AT_THEFT_TRIGGER_ATTACK_DETECTED, + + /// + /// Bounday check. + /// + AT_THEFT_TRIGGER_MAX +} AT_THEFT_TRIGGER; + +/// +/// Enumeration of AT timer types. +/// +typedef enum _AT_TIMER_ID +{ + /// + /// Reserved. + /// + AT_TID_RSVD = 0, + + /// + /// The disable timer is a variation on the watchdog timer. It is periodically + /// reset by ISV software to indicate that the system is behaving as expected. + /// If it is not reset before it expires, the ME AT Service shall execute the + /// protective actions configured in its disable timer policy. + /// The first line of defense when the system begins to exhibit behavior that + /// indicates it has been stolen is the ISV software, which may invoke the + /// ATHI SetPolicy function to protect the platform. + /// The disable timer is designed to protect the system if the ISV software + /// is disabled. In this case, the ISV software will be unable to reset the + /// disable timer before it expires, and the ME AT Service will take the + /// configured protective actions. + /// + AT_TID_DISABLE_TIMER, + + /// + /// The unlock timer used when the AT laptop computer is locked. The ME AT Service + /// sets the recovery timer when it sees that the AT state is Stolen during + /// the host boot flow. If the user doesn't successfully complete the + /// platform_enable_flow recovery flow before the unlock timer expires, + /// the ME AT Service shall power down the platform immediately. + /// The variable UnlockTimerInterval shall be configurable within a range + /// that is long enough to facilitate a bona fide recovery attempt, but short + /// enough to prevent exploitation of the platform by a thief that does not + /// have the recovery credential. + /// + AT_TID_UNLOCK_TIMER, + + /// + /// The grace timer allows the user of a AT laptop computer time to take + /// actions to cause a ResetTimer command to be issued by the AT service. + /// The grace period shall be applied if and only if the ME AT service + /// determines that the Disable Timer logically expired while the AT + /// laptop computer was in Sx (sleeping). + /// + AT_TID_GRACE_TIMER, + + /// + /// The PBA Logon Timer shall be used to count down the allotted time for + /// PBA Logon. The ME AT Service shall start a PBA Logon Timer upon + /// transition from S4/S5 to S0. If the ME AT Service receives a property + /// authenticated PBA Logon notification message before the PBA Logon Timer + /// expires, it shall stop the timer and allow operation to continue normally. + /// If instead the PBA Logon Timer expires before the ME AT Service has + /// received a properly authenticated PBA Logon notification message, the + /// ME AT Service shall power down the system immediately, but shall not + /// transition to the Stolen state. + /// + AT_TID_PBA_LOGON_TIMER, + + /// + /// The activity timer is used to extend the period of the Disable Timer in + /// the event that a ATHI client has recently invoked a ATHI command when + /// the Disable Timer expires. The intent is to allow the client to complete + /// a command flow that may include a ResetTimer command. + /// The AT activity timer shall be reset each time a ATHI command is completed. + /// The interval of the AT activity timer shall be 30 seconds. This interval + /// shall not be externally configurable. + /// + AT_TID_ACTIVITY_TIMER, + + /// + /// Bounday check. + /// + AT_TID_MAX +} AT_TIMER_ID; + +/// +/// A timer with an interval of -1 means that the timer is disabled. Applies to +/// AT_TIMER_CONFIG and AT_TIMER_INFO. +/// +#define AT_TIMER_DISABLED 0xFFFFFFFF + +/// +/// Maximum timer value besides the disabled timer value. This value is due to +/// the maximum timer value allowed by the FW resources. +/// +#define AT_TIMER_MAX (AT_TIMER_DISABLED / 1024) + +/// +/// Remaining grace timer in which the user is not assumed not to be able to +/// complete a TimerResetCmd due to OS context loading from S3 -> S0. +/// +/// Value is 30 seconds. +/// +#define AT_LOW_GRACE_THRESHOLD 30 + +/// +/// Minumium DISABLE timer value (in seconds) +/// +#define AT_TMR_DISABLE_MIN 60 + +/// +/// Minumium DISABLE timer value (in seconds) +/// +#define AT_TMR_DISABLE_MAX AT_TIMER_DISABLED + +/// +// Minumium UNLOCK timer value (in seconds) +/// +#define AT_TMR_UNLOCK_MIN 60 + +/// +/// Minumium UNLOCK timer value (in seconds) +/// +#define AT_TMR_UNLOCK_MAX AT_TIMER_MAX + +/// +/// Minumium GRACE timer value (in seconds) +/// +#define AT_TMR_GRACE_MIN 60 + +/// +/// Minumium GRACE timer value (in seconds) +/// +#define AT_TMR_GRACE_MAX AT_TIMER_MAX + +/// +// Minumium PBALOGON timer value (in seconds) +/// +#define AT_TMR_PBALOGON_MIN 60 + +/// +/// Minumium PBALOGON timer value (in seconds) +/// +#define AT_TMR_PBALOGON_MAX AT_TIMER_DISABLED + +/// +/// Structure that contains the configuration and state information for +/// a specified timer. +/// +typedef struct _AT_TIMER_INFO { + /// + /// Identifies the timer that shall be configured. See #AT_TIMER_ID. + /// + UINT8 Id; + + /// + /// Padding for now + /// + UINT8 Reserved[3]; + + /// + /// The interval configured in the timer, in seconds. + /// + UINT32 Interval; + + /// + /// The number of ticks remaining in the current timer countdown. + /// + UINT32 TimeLeft; +} AT_TIMER_INFO; + +/// +/// Structure defining the PBAM Configuration. +/// +typedef struct _AT_POLICY_PBA_CONFIG { + UINT8 RunAfterPost : 1; + UINT8 IsInstalled : 1; + UINT8 Reserved : 6; +} AT_POLICY_PBA_CONFIG; + +/// +/// Optional union defining the PBAM Configuration. +/// +typedef union _AT_POLICY_PBA_CONFIG_U { + UINT8 Value; + AT_POLICY_PBA_CONFIG Bits; +} AT_POLICY_PBA_CONFIG_U; + +/// +/// Enumeration of the platform lock state +/// +typedef enum _AT_PLATFORM_LOCKSTATE +{ + AT_PLATFORM_LOCKSTATE_NOTLOCKED = 0, + AT_PLATFORM_LOCKSTATE_LOCKED, + AT_PLATFORM_LOCKSTATE_MAX +} AT_PLATFORM_LOCKSTATE; + +// +// Command definition structures +// + +/// +/// The GetATState command. Returns the AT state of the laptop computer. +/// +/// Sender: AT AM | PBA +/// Signing Key: None | None +/// +/// Refer to AtHiGetStateCmd.dot "GetState command" +/// +/// See ATHI_GET_STATE_RSP +/// +typedef ATHI_BASIC_CMD ATHI_GET_STATE_CMD; + +/// +// The GetATState response. +/// +/// Refer to AtHiGetStateRsp.dot "GetState response" +/// +/// +typedef struct _ATHI_GET_STATE_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + AT_STATE_INFO StateInfo; +} ATHI_GET_STATE_RSP; + +/// +/// The GetTimerInfo command. Returns configuration and state information about +/// the specified timer. +/// +/// Sender: PBA +/// Signing Key: PBASK +/// +/// Refer to AtHiGetTimerInfoCmd.dot "GetTimerInfo command" +/// +/// See ATHI_GET_TIMER_INFO_RSP +/// +typedef struct _ATHI_GET_TIMER_INFO_CMD { + ATHI_HEADER Header; + UINT8 TimerId; +} ATHI_GET_TIMER_INFO_CMD; + +/// +/// ATHI_GET_TIMER_INFO response. +/// +/// Refer to AtHiGetTimerInfoRsp.dot "GetTimerInfo response" +/// +typedef struct _ATHI_GET_TIMER_INFO_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + AT_TIMER_INFO TimerInfo; +} ATHI_GET_TIMER_INFO_RSP; + +/// +/// ATHI RECOVERY Group Commands +/// +typedef enum _ATHI_RECOVERY_GRP_CMD +{ + /// + /// SetCredential stores the recovery credential in non-volatile storage, + /// where it is used for validation purposes when the credential is presented + /// by a user during recovery flow. + /// + /// See #ATHI_SET_CREDENTIAL_CMD + /// + ATHI_RECOVERY_GRP_SET_CREDENTIAL_CMD, + /// + /// AuthenticateRecoveryCredential presents the a credential to the ME AT + /// Service for validation during the recovery flow. + /// + /// See ATHI_AUTHENTICATE_CREDENTIAL_CMD + /// + ATHI_RECOVERY_GRP_AUTH_CREDENTIAL_CMD, + /// + /// The ComputeHash command computes a specified hash of input data. Maximum + /// size of the digest value shall be 384 bits (48 bytes). This command may + /// be used to preprocess authentication tokens if the specified hash + /// algorithm is not supported by the requester. + /// + /// See ATHI_COMPUTE_HASH_CMD + /// + ATHI_RECOVERY_GRP_COMPUTE_HASH_CMD, + /// + /// The DeAssertStolen command is used to recovery the platfrom from stolen state + /// by PBAM or AT server + /// See ATHI_DEASSERT_STOLEN_CMD + /// + ATHI_RECOVERY_GRP_DEASSERT_STOLEN_CMD, + /// + /// The GetIsvId command exports the identity of the service provider (ISV) + /// that activated the AT service + /// See ATHI_GET_ISVID_CMD + /// + ATHI_RECOVERY_GRP_GET_ISVID_CMD, + /// + /// Bounday check. + /// + ATHI_RECOVERY_GRP_MAX +} ATHI_RECOVERY_GRP_CMD; + +/// +/// This enumeration defines the credential types. +/// +typedef enum _AT_CREDENTIAL_TYPE +{ + /// + // Reserved. + /// + AT_CREDENTIAL_TYPE_RSVD = 0, + + /// + // User defined recovery passphrase + /// + AT_CREDENTIAL_TYPE_USER_PASSPHRASE, + + /// + /// Server generated random token + /// + AT_CREDENTIAL_TYPE_SRTK, + + /// + /// Server suspend token + /// + AT_CREDENTIAL_TYPE_SSTK, + + /// + /// Base key + /// + AT_CREDENTIAL_TYPE_BK, + + /// + /// Boundary check. + /// + AT_CREDENTIAL_TYPE_MAX +} AT_CREDENTIAL_TYPE; + +/// +// This enumeration defines the salt IDs. +/// +typedef enum _AT_HASH_ALGO_ID +{ + /// + /// Reserved. + /// + AT_HASH_ALGO_ID_RSVD = 0, + + /// + /// SHA-1 algorithm (160-bit output) + /// + AT_HASH_ALGO_ID_SHA1, + + /// + /// Boundary check + /// + AT_HASH_ALGO_ID_MAX +} AT_HASH_ALGO_ID; + +/// +/// Defines the maximum length of a user passpharse recovery hash (will be 32 in 2009). +/// +#define AT_USR_PASS_HASH_LENGTH_MAX 20 + +/// +/// Defines the maximum length of a SRTK recovery token +/// +#define AT_SRTK_LENGTH_MAX 32 + +/// +/// Maximium credential length. +/// +#define AT_CREDENTIAL_VALUE_LENGTH_MAX AT_SRTK_LENGTH_MAX + +#define AT_PASSWORD_LENGTH 64 + +/// +/// Structure that defines a credential for storage, validation, and export operations. +/// +typedef struct _AT_CREDENTIAL { + /// + /// The credential type + /// + AT_CREDENTIAL_TYPE Type; + + /// + /// The credential length + /// + UINT32 Length; + + /// + /// The credential value + /// + UINT8 Value[1]; /// Need a pointer but cannot make a zero length array +} AT_CREDENTIAL; + +/// +/// The AuthenticateCredential command. Sets the value of the specified +/// credential in the ME AT Service. +/// +/// Sender: AT AM +/// Signing Key: None +/// +/// Refer to AtHiAuthenticateCredentialCmd.dot "AuthenticateCredential command" +/// +/// See ATHI_AUTHENTICATE_CREDENTIAL_RSP +/// +typedef struct _ATHI_AUTHENTICATE_CREDENTIAL_CMD { + ATHI_HEADER Header; + AT_CREDENTIAL Credential; +} ATHI_AUTHENTICATE_CREDENTIAL_CMD; + +/// +/// The AuthenticateCredential response. +/// +/// Refer to AtHiAuthenticateCredentialRsp.dot "AuthenticateCredential response" +/// +typedef struct _ATHI_AUTHENTICATE_CREDENTIAL_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + UINT8 Authenticated; +} ATHI_AUTHENTICATE_CREDENTIAL_RSP; + +/// +/// Definition for the maximum hash output size. +/// +#define AT_MAX_HASH_OUTPUT_SIZE 48 + +/// +/// The ComputeHash command. Computes a specified hash of input data. Maximum +/// size of the digest value shall be 384 bits (48 bytes). +/// +/// Sender: AT AM +/// Signing Key: None +/// +/// Refer to AtHiComputeHashCmd.dot "ComputeHash command" +/// +/// See ATHI_COMPUTE_HASH_RSP +/// +typedef struct _ATHI_COMPUTE_HASH_CMD { + ATHI_HEADER Header; + + /// + /// see AT_HASH_ALGO_ID for values + /// + UINT8 Algorithm; + UINT8 InputLength; + UINT8 InputBuffer[AT_MAX_HASH_OUTPUT_SIZE]; +} ATHI_COMPUTE_HASH_CMD; + +/// +/// The ComputeHash response. +/// +/// Refer to AtHiComputeHashRsp.dot "ComputeHash response" +/// +/// +typedef struct _ATHI_COMPUTE_HASH_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + + /// + /// see AT_HASH_ALGO_ID for values + /// + UINT8 OutputLength; + UINT8 OutputBuffer[AT_MAX_HASH_OUTPUT_SIZE]; +} ATHI_COMPUTE_HASH_RSP; + +/// +/// The DeassertStolen command. Recover the laptop from stolen state. The ME AT +/// Service shall proceed immediately to the NotStolen state. +/// +/// Sender: ISV SW +/// Signing Key: PBASK, TSSK +/// +/// Refer to AtHiDeassertStolenCmd.dot "DeassertStolen command" +/// +/// See ATHI_DEASSERT_STOLEN_RSP +/// +typedef ATHI_BASIC_CMD ATHI_DEASSERT_STOLEN_CMD; + +typedef ATHI_BASIC_RSP ATHI_DEASSERT_STOLEN_RSP; + +/// +/// The GetIsvId command exports the identity of the service provider (ISV) that +/// activated the AT service. This allows for system recovery in cases where the user +/// may not be sure who to contact when he/she is unable to recover the system locally. +/// Note that this command is allowed only while the system in the STOLEN state +/// +/// Sender: AT AM +/// Signing Key: None +/// +/// See ATHI_GET_ISVID_RSP +/// +typedef ATHI_BASIC_CMD ATHI_GET_ISVID_CMD; + +typedef struct _ATHI_GET_ISVID_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + UINT32 IsvId; +} ATHI_GET_ISVID_RSP; + +/// +/// ATHI General Group Commands +/// +typedef enum _ATHI_GENERAL_GRP_CMD +{ + /// + /// GetNonce returns a nonce generated by the ME AT Service. The purpose of + /// this nonce is to prevent replay of AT command messages. + /// + /// See ATHI_GET_NONCE_CMD + /// + ATHI_GENERAL_GRP_GET_NONCE_CMD, + + /// + /// GetATCapabilities requests that the ME AT Service return the + /// capabilities it has implemented. + /// + /// See ATHI_GET_AT_CAPABILITIES_CMD + /// + ATHI_GENERAL_GRP_GET_AT_CAPABILITIES_CMD, + + /// + /// The SetPublicKey command saves the specified public key of an RSA + /// key-pair for use by the ME AT Service. + /// + /// See ATHI_GET_PUBLIC_KEY_CMD + /// + ATHI_GENERAL_GRP_SET_PUBLIC_KEY_CMD, + + /// + /// The GetPublicKey command returns the specified public key of an RSA + /// key-pair owned by the ME AT Service. + /// + /// See ATHI_GET_PUBLIC_KEY_CMD + /// + ATHI_GENERAL_GRP_GET_PUBLIC_KEY_CMD, + + /// + /// The GetEventHistory command retrieves entries from the AT Event History + /// in the ME. + /// + /// See ATHI_GET_EVENT_HISTORY_CMD + /// + ATHI_GENERAL_GRP_GET_EVENT_HISTORY_CMD, + + /// + /// The ClearEventHistory command deletes all entries from the AT Event + /// History in the ME. + /// + /// See ATHI_CLEAR_EVENT_HISTORY_CMD + /// + ATHI_GENERAL_GRP_CLEAR_EVENT_HISTORY_CMD, + + /// + /// The SetSysTime command synchronizes the time between the FW with the + /// AT server. + /// + /// See ATHI_SET_SYS_TIME_CMD + /// + ATHI_GENERAL_GRP_SET_SYS_TIME_CMD, + + /// + /// The Set Supend Mode command requests FW transition + /// into or out of Suspend Mode. + /// + + ATHI_GENERAL_GRP_SET_SUSPEND_CMD = 8, + + /// + /// Bounday check. + /// + ATHI_GENERAL_GRP_MAX +} ATHI_GENERAL_GRP_CMD; + +/// +/// ATHI 3G WWAN Commands +/// +typedef enum _ATHI_3G_NIC_GRP_CMD +{ /// + /// 3G NIC Init Command tells FW to intialize the NIC radio + /// + ATHI_3G_NIC_GRP_INIT_CMD = 3, + + /// + /// The 3G NIC Query Command asks FW about the status of the NIC radio + /// + ATHI_3G_NIC_GRP_QUERY_CMD, + + /// + /// Bounday check. + /// + ATHI_3G_NIC_GRP_MAX +} ATHI_3G_NIC_GRP_CMD; + +/// +/// The GetNonce command. Requests that the ME AT Service generate and return +/// a nonce to be used in a subsequent ATHI command. The nonce prevents +/// replay of a command. +/// +/// Sender: ISV SW +/// Signing Key: Any +/// +/// Refer to AtHiGetNonceCmd.dot "GetNonce command" +/// +/// See ATHI_GET_NONCE_RSP +/// +typedef ATHI_BASIC_CMD ATHI_GET_NONCE_CMD; + +/// +/// The GetNonce response. +/// +/// Refer to AtHiGetNonceRsp.dot "GetNonce response" +/// +typedef struct _ATHI_GET_NONCE_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + AT_NONCE Nonce; +} ATHI_GET_NONCE_RSP; + +/// +/// ATHI NOTIFICATION Group Commands +/// +typedef enum _ATHI_NOTIFICATION_GRP_CMD +{ + /// + /// A PBA sends a PBALogon notification message to notify the ME AT service + /// of a successful user logon. + /// + /// See ATHI_PBA_LOGON + /// + ATHI_NOTIFICATION_GRP_PBA_LOGON, + + /// + /// Bounday check. + /// + ATHI_NOTIFICATION_GRP_MAX +} ATHI_NOTIFICATION_GRP_CMD; + +/// +/// PBALogon notification. Notifies the ME AT service of a successful user logon. +/// +/// Sender: PBA +/// Signing Key: PBASK +/// +/// Refer to AtHiPbaLogonNotify.dot "PBALogon notification" +/// +/// See ATHI_GET_NONCE_RSP +/// +typedef ATHI_BASIC_CMD ATHI_PBA_LOGON_NOTIFY; + +/// +/// The GetNonce response. +/// +/// Refer to AtHiPbaLogonAck.dot "PBALogon ack" +/// +typedef ATHI_BASIC_RSP ATHI_PBA_LOGON_ACK; + +/// +/// ATHI DATA STORAGE Group Commands +/// +typedef enum _ATHI_DATA_STORE_GRP_CMD +{ + /// + /// SetBlob stores data in the ME AT FDE/FLE ISV non-volatile storage area. + /// + /// See #ATHI_SET_BLOB_CMD. + /// + ATHI_DATA_STORE_GRP_SET_BLOB_CMD, + + /// + /// GetBlob returns the data stored in the ME AT FDE/FLE ISV non-volatile + /// storage area. + /// + /// See ATHI_GET_BLOB_CMD. + /// + ATHI_DATA_STORE_GRP_GET_BLOB_CMD, + + /// + /// Stores a vendor string the ME's non-volatile storage area. + /// + /// See ATHI_SET_VENDOR_STRING_CMD + /// + ATHI_DATA_STORE_GRP_SET_VENDOR_STRING_CMD, + + /// + /// Retrieves the vendor string from the ME's non-volatile storage area. + /// + /// See ATHI_GET_VENDOR_STRING_CMD + /// + ATHI_DATA_STORE_GRP_GET_VENDOR_STRING_CMD, + + /// + /// Bounday check. + /// + ATHI_DATA_STORE_GRP_MAX +} ATHI_DATA_STORE_GRP_CMD; + +/// +/// This enumeration defines the vendor string identifiers. +/// +typedef enum _AT_VENDOR_STRING_ID +{ + /// + /// Reserved. + /// + AT_VENDOR_STRING_ID_RSVD = 0, + + /// + /// User defined recovery passphrase + /// + AT_VENDOR_STRING_ID_RECOVERY_HELP, + /// + /// AT_VENDOR_STRING_ID_RECOVERY_HELP, + /// + + /// + /// Server generated random token + /// + AT_CUSTOM_RECOVERY_ID_CONFIGURATIONS, + + /// + /// Boundary check. + /// + AT_VENDOR_STRING_ID_MAX +} AT_VENDOR_STRING_ID; + +/// +/// Maximum blob data size. +/// +#define AT_VENDOR_STRING_LENGTH_MAX 256 + +/// +/// The SetVendorString command. Stores a vendor string the ME's +/// non-volatile storage area. +/// +/// Sender: ISV SW +/// Signing Key: TSSK +/// +/// See ATHI_SET_VENDOR_STRING_RSP +/// +typedef struct _ATHI_SET_VENDOR_STRING_CMD { + ATHI_HEADER Header; + UINT8 Id; + UINT8 Reserved[3]; + AT_BLOB String; +} ATHI_SET_VENDOR_STRING_CMD; + +/// +/// The SetVendorString response. +/// +typedef ATHI_BASIC_RSP ATHI_SET_VENDOR_STRING_RSP; + +/// +/// The GetVendorString command. Retrieves the vendor string data from the ME's +/// non-volatile storage area. +/// +/// Sender: ISV SW +/// Signing Key: None +/// +/// See ATHI_GET_VENDOR_STRING_RSP +/// +typedef struct _ATHI_GET_VENDOR_STRING_CMD { + ATHI_HEADER Header; + UINT8 Id; +} ATHI_GET_VENDOR_STRING_CMD; + +/// +/// The GetVendorString response. +/// +/// Sender: ISV SW +/// Signing Key: None +/// +/// +typedef struct _ATHI_GET_VENDOR_STRING_RSP { + ATHI_HEADER Header; + ATHI_COMPLETION_CODE CompletionCode; + AT_BLOB String; +} ATHI_GET_VENDOR_STRING_RSP; + +/// +/// The SendAssertStolen Request +/// +/// Sender: ISV SW +/// Signing Key: None +/// +/// +typedef struct _ATHI_ASSERT_STOLEN_CMD { + ATHI_HEADER Header; + UINT32 DelayTime; +} ATHI_ASSERT_STOLEN_CMD; + +/// +/// The SendAssertStolen response. +/// +typedef ATHI_BASIC_RSP ATHI_ASSERT_STOLEN_RSP; + +/// +/// The Set Supend State Request Message +/// +/// Sender: BIOS +/// Signing Key: SSTK One Time Token +/// +/// +typedef struct _ATHI_SET_SUSPEND_STATE_CMD { + ATHI_HEADER Header; + UINT32 TransitionState; /// 0=Exit, 1=Enter + AT_CREDENTIAL Credential; +} ATHI_SET_SUSPEND_STATE_CMD; + +/// +/// The Set Supend State Response Message +/// +/// Sender: FW +/// Signing Key: None +/// +/// +typedef struct _ATHI_SET_SUSPEND_STATE_RSP { + ATHI_HEADER Header; + UINT32 CompletionCode; +} ATHI_SET_SUSPEND_STATE_RSP; + +/// +/// The Initialize WWAN Recovery Request Message +/// +/// Sender: BIOS +/// Signing Key: None +/// +/// +typedef struct _ATHI_INIT_WWAN_RECOV_CMD { + ATHI_HEADER Header; +} ATHI_INIT_WWAN_RECOV_CMD; + +/// +/// The Initialize WWAN Recovery Response Message +/// +/// Sender: FW +/// Signing Key: None +/// +/// +typedef struct _ATHI_INIT_WWAN_RECOV_RSP { + ATHI_HEADER Header; + UINT32 CompletionCode; +} ATHI_INIT_WWAN_RECOV_RSP; + +/// +/// The Initialize WWAN Status Request Message +/// +/// Sender: BIOS +/// Signing Key: None +/// +/// +typedef struct _ATHI_WWAN_STATUS_CMD { + ATHI_HEADER Header; +} ATHI_WWAN_STATUS_CMD; + +/// +/// The Initialize WWAN Status Response Message +/// +/// Sender: FW +/// Signing Key: None +/// +/// +typedef struct _ATHI_WWAN_STATUS_RSP { + ATHI_HEADER Header; + UINT32 CompletionCode; + UINT8 RadioStatus; + UINT8 NetworkStatus; +} ATHI_WWAN_STATUS_RSP; + +#pragma pack() + +#endif // _AT_HI_H diff --git a/ReferenceCode/ME/BiosExtension/BiosExtension.cif b/ReferenceCode/ME/BiosExtension/BiosExtension.cif new file mode 100644 index 0000000..a41f8ee --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/BiosExtension.cif @@ -0,0 +1,9 @@ +<component> + name = "BiosExtension" + category = ModulePart + LocalRoot = "ReferenceCode\ME\BiosExtension\" + RefName = "BiosExtension" +[parts] +"BiosExtensionLoader" +"EfiMebx" +<endComponent> diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c new file mode 100644 index 0000000..ce16459 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c @@ -0,0 +1,1273 @@ +/** @file + Loads the AMT Bios Extensions and calls the module prior to boot. + Setup options control whether the user is allowed to change the provisioning of AMT + or not for boot speed optimization. + + Configuration and invokation of the AMT Bios Extensions is done as per + the AMT Bios Writers Guide. + +@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 +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "BiosExtensionLoader.h" +#include "MeLib.h" +#include "MeChipset.h" +#include "PchPlatformLib.h" +#include "AmtPolicyLib.h" +#endif + +extern DXE_AMT_POLICY_PROTOCOL *mDxePlatformAmtPolicy; +BOOLEAN mFirstBoot; + +ME_BIOS_EXTENSION_SETUP mMeBiosExtensionSetup = {0}; + +UINT32 mMebxSetupVariableAttributes; +UINTN mMebxSetupVariableDataSize; +AMT_READY_TO_BOOT_PROTOCOL mAmtReadyToBoot = { AmtReadyToBoot }; +UINT8 mFwImageType; +UINT8 mFwPlatformBrand; +BOOLEAN mFwMediaTableReqAvail = FALSE; +BOOLEAN mFwMediaTablePush = FALSE; +BOOLEAN mMebxLaunched = FALSE; +EFI_HANDLE mImageHandle; + +/** + Signal a event for Amt ready to boot. + + @param[in] None + + @retval EFI_SUCCESS Mebx launched or no controller +**/ +EFI_STATUS +EFIAPI +AmtReadyToBoot ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeStatus; + + /// + /// only launch MEBx once during POST + /// + if (mMebxLaunched) { + return EFI_SUCCESS; + } + + mMebxLaunched = TRUE; + + /// + /// Launch MEBx, do not assert on error as this may be valid case + /// + Status = MebxNotifyEvent (); + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (!EFI_ERROR (Status)) { + /// + /// Check ME Status + /// + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + + /// + /// Send 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) { + if (AmtWatchDog ()) { + /// + /// Stop BIOS ASF Watch Dog before ready to boot + /// + AsfStopWatchDog (); + /// + /// Start OS ASF Watch Dog + /// + AsfStartWatchDog (ASF_START_OS_WDT); + } + /// + /// End of watch dog setup option + /// + } + } + // + // End of EFI_ERROR of locate HECI driver + // + return EFI_SUCCESS; +} + +/** + Create the FRU table to send to AMT FW + + @param[in] AssetTableData Buffer of all Asset tables to send to FW + @param[in] AmtData Structure holds BIOS pointers for Asset tables + + @retval EFI_SUCCESS FRU table calculated +**/ +EFI_STATUS +CalulateFruTable ( + TABLE_PUSH_DATA *AssetTableData, + AMT_DATA *AmtData + ) +{ + + PCI_DEV_INFO PciDevInfoPtr; + HWAI_FRU_TABLE *FruHeader; + HWAI_PCI_FRU *PciFru; + UINT32 TableAddress; + UINT16 i; + + i = 0; + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_FRU_DEVICE].Offset = 0; + + FruHeader = (HWAI_FRU_TABLE *) &AssetTableData->TableData[0]; + PciFru = (HWAI_PCI_FRU *) &FruHeader->Data[0]; + + CopyMem (&PciDevInfoPtr, (VOID *) (UINTN) AmtData->PciDevAssertInfoPtr, sizeof (PCI_DEV_INFO)); + + if (AmtData->SupportedTablesFlags & MEBX_STF_PCI_DEV_TABLE) { + FruHeader->StructureCount = PciDevInfoPtr.PciDevCount; + } else { + FruHeader->StructureCount = 0; + } + + TableAddress = (UINT32) AmtData->PciDevAssertInfoPtr + sizeof (PCI_DEV_INFO); + + if (FruHeader->StructureCount) { + FruHeader->TableByteCount = FruHeader->StructureCount * sizeof (HWAI_PCI_FRU); + for (i = 0; i < FruHeader->StructureCount; i++) { + PciFru->SmbiosType = 0; + PciFru->Length = sizeof (HWAI_PCI_FRU); + PciFru->SmbiosHandle = 0; + PciFru->FruType = HWAI_FRU_TYPE_PCI; + CopyMem (&PciFru->FruData, (VOID *) (UINTN) TableAddress, sizeof (HWAI_PCI_DATA)); + ++PciFru; + TableAddress += sizeof (HWAI_PCI_DATA); + } + } else { + FruHeader->TableByteCount = 0; + } + + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_FRU_DEVICE].Length = FruHeader->TableByteCount + + sizeof (FruHeader->StructureCount) + sizeof (FruHeader->TableByteCount); + + return EFI_SUCCESS; + +} + +/** + Create the Media table to send to AMT FW + + @param[in] AssetTableData Buffer of all Asset tables to send to FW + @param[in] TableOffset Offset into AssetTableData that Media table will be located + @param[in] AmtDataPtr Structure holds BIOS pointers for Asset tables + + @retval EFI_SUCCESS Media table created +**/ +EFI_STATUS +CalulateMediaTable ( + TABLE_PUSH_DATA *AssetTableData, + UINT16 TableOffset, + AMT_DATA *AmtDataPtr + ) +{ + + HWAI_MEDIA_TABLE *MediaHeaderPtr; + HWAI_MEDIA_ENTRY *MediaEntryPtr; + MEDIA_DEV_INFO MediaDevStruct; + UINT32 TableAddress; + UINT16 i; + + i = 0; + + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE].Offset = TableOffset; + + MediaHeaderPtr = (HWAI_MEDIA_TABLE *) &AssetTableData->TableData[TableOffset]; + MediaEntryPtr = (HWAI_MEDIA_ENTRY *) &MediaHeaderPtr->Data[0]; + + CopyMem (&MediaDevStruct, (VOID *) (UINTN) AmtDataPtr->MediaDevAssetInfoPtr, sizeof (MEDIA_DEV_INFO)); + TableAddress = (UINT32) AmtDataPtr->MediaDevAssetInfoPtr + sizeof (MEDIA_DEV_INFO); + + if (!(AmtDataPtr->SupportedTablesFlags & MEBX_STF_MEDIA_DEV_TABLE)) { + MediaHeaderPtr->TableByteCount = 0; + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE].Length = 0; + return EFI_SUCCESS; + } + + MediaHeaderPtr->StructureCount = MediaDevStruct.MediaDevCount; + MediaHeaderPtr->TableByteCount = (MediaHeaderPtr->StructureCount * sizeof (HWAI_MEDIA_ENTRY)); + for (i = 0; i < MediaHeaderPtr->StructureCount; i++) { + MediaEntryPtr->Length = sizeof (HWAI_MEDIA_ENTRY); + MediaEntryPtr->SmbiosHandle = 0; + MediaEntryPtr->SmbiosType = 0; + + CopyMem (&MediaEntryPtr->MediaData, (VOID *) (UINTN) TableAddress, sizeof (HWAI_MEDIA_DATA)); + ++MediaEntryPtr; + TableAddress += sizeof (HWAI_MEDIA_DATA); + } + + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE].Length = MediaHeaderPtr->TableByteCount + + sizeof (MediaHeaderPtr->StructureCount) + sizeof (MediaHeaderPtr->TableByteCount); + + return EFI_SUCCESS; + +} + +/** + Create the SMBIOS table to send to AMT FW + + @param[in] AssetTableData Buffer of all Asset tables to send to FW + @param[in] TableOffset Offset into AssetTableData that the SMBIOS table will be located + @param[in] PtrSmbiosTable Pointer to BIOS SMBIOS tables + + @retval EFI_ABORTED PtrSmbiosTable data is invalid. + @retval EFI_SUCCESS Smbios table created. +**/ +EFI_STATUS +CalulateSmbiosTable ( + TABLE_PUSH_DATA *AssetTableData, + UINT16 TableOffset, + UINT32 PtrSmbiosTable + ) +{ + + SMBIOS_ENTRY_POINT SmbEntryStruct; + SMBIOS_HEADER *SmbiosHeaderPtr; + SMBIOS_TABLE_TYPE_ONE *Type1Ptr; + SMBIOS_TABLE_TYPE_THREE *Type3Ptr; + SMBIOS_TABLE_TYPE_FOUR *Type4Ptr; + SMBIOS_TABLE_TYPE_TWENTY_THREE *Type23Ptr; + UINT32 TableAddress; + UINT16 OrignalTableOffset; + UINT16 StringCounter; + UINT8 DataByte; + BOOLEAN EndOfTable; + BOOLEAN EndOfEntry; + BOOLEAN PreviousNull; + BOOLEAN KeepEntry; + + OrignalTableOffset = 0; + StringCounter = 1; + DataByte = 0; + EndOfTable = FALSE; + EndOfEntry = FALSE; + PreviousNull = FALSE; + KeepEntry = FALSE; + + OrignalTableOffset = TableOffset; + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_SMBIOS].Offset = OrignalTableOffset; + + CopyMem (&SmbEntryStruct, (VOID *) (UINTN) PtrSmbiosTable, sizeof (SMBIOS_ENTRY_POINT)); + + if (SmbEntryStruct.Signature != SMB_SIG) { + DEBUG ((EFI_D_ERROR, "CalulateSmbiosTable Error: SmbEntryStruct.Signature != SMB_SIG\n")); + return EFI_ABORTED; + } + + if (SmbEntryStruct.TableLength == 0) { + DEBUG ((EFI_D_ERROR, "CalulateSmbiosTable Error: TableSize == 0\n")); + return EFI_ABORTED; + } + + if (SmbEntryStruct.TableLength > (MAX_ASSET_TABLE_ALLOCATED_SIZE - TableOffset)) { + DEBUG ( + (EFI_D_ERROR, + "SMBIOS Tables Are Larger Than 0x%x\n", + (MAX_ASSET_TABLE_ALLOCATED_SIZE - TableOffset)) + ); + return EFI_ABORTED; + } + + TableAddress = SmbEntryStruct.TableAddress; + + while (!EndOfTable) { + + CopyMem (&AssetTableData->TableData[TableOffset], (VOID *) (UINTN) TableAddress, sizeof (SMBIOS_HEADER)); + + SmbiosHeaderPtr = (SMBIOS_HEADER *) &AssetTableData->TableData[TableOffset]; + + switch (SmbiosHeaderPtr->Type) { + case 13: + case 15: + case 25: + case 32: + KeepEntry = FALSE; + /// + /// Not needed by AMT + /// + break; + + case 127: + KeepEntry = TRUE; + EndOfTable = TRUE; + break; + + default: + KeepEntry = TRUE; + + } + + if (KeepEntry) { + TableOffset += sizeof (SMBIOS_HEADER); + TableAddress += sizeof (SMBIOS_HEADER); + + CopyMem ( + &AssetTableData->TableData[TableOffset], + (VOID *) (UINTN) TableAddress, + (SmbiosHeaderPtr->Length - sizeof (SMBIOS_HEADER)) + ); + + /// + /// Make any need modifications to entrys with changing fields + /// + switch (SmbiosHeaderPtr->Type) { + case 1: + Type1Ptr = (SMBIOS_TABLE_TYPE_ONE *) SmbiosHeaderPtr; + Type1Ptr->WakeUp = 0; + break; + + case 3: + Type3Ptr = (SMBIOS_TABLE_TYPE_THREE *) SmbiosHeaderPtr; + Type3Ptr->BootState = 0; + Type3Ptr->PowerSupplyState = 0; + Type3Ptr->ThermalState = 0; + Type3Ptr->SecurityStatus = 0; + break; + + case 4: + Type4Ptr = (SMBIOS_TABLE_TYPE_FOUR *) SmbiosHeaderPtr; + Type4Ptr->MaxSpeed = Type4Ptr->MaxSpeed - (Type4Ptr->MaxSpeed % 100); + Type4Ptr->CurrentSpeed = Type4Ptr->CurrentSpeed - (Type4Ptr->CurrentSpeed % 100); + break; + + case 23: + Type23Ptr = (SMBIOS_TABLE_TYPE_TWENTY_THREE *) SmbiosHeaderPtr; + Type23Ptr->ResetCount = 0; + break; + + default: + break; + } + /// + /// update both table pointer and scratch offset to be beyond this entry + /// + TableOffset += (SmbiosHeaderPtr->Length - sizeof (SMBIOS_HEADER)); + TableAddress += (SmbiosHeaderPtr->Length - sizeof (SMBIOS_HEADER)); + + } else { + /// + /// skip this entry + /// Move table address to beyond this entry, do not change scratch table offset + /// + TableAddress += SmbiosHeaderPtr->Length; + } + /// + /// Copy any remaining unformatted data til end of type structure + /// that is marked by double NULL bytes. + /// + EndOfEntry = FALSE; + PreviousNull = FALSE; + do { + /// + /// Read byte from bios data + /// + CopyMem (&DataByte, (VOID *) (UINTN) TableAddress++, 1); + if (DataByte == 0x00) { + if (SmbiosHeaderPtr->Type == 0) { + StringCounter++; + + } + + if (PreviousNull) { + /// + /// this null marks end of entry + /// + EndOfEntry = TRUE; + } else { + /// + /// flag we have seen first null + /// + PreviousNull = TRUE; + } + } else { + /// + /// clear null that terminated string + /// + PreviousNull = FALSE; + + } + + if (KeepEntry) { + AssetTableData->TableData[TableOffset++] = DataByte; + + } + + } while (!EndOfEntry); + + } + /// + /// while !EndOfTable + /// + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_SMBIOS].Length = TableOffset - OrignalTableOffset; + + return EFI_SUCCESS; + +} + +/** + Create the ASF table to send to AMT FW + + @param[in] AssetTableData Buffer of all Asset tables to send to FW + @param[in] TableOffset Offset into AssetTableData that the ASF table will be located + @param[in] PtrAcpiRsdt Pointer to BIOS ASF constructed tables + + @retval EFI_ABORTED AssetTableData data is invalid. + @retval EFI_SUCCESS ASF table created. +**/ +EFI_STATUS +CalulateAsfTable ( + TABLE_PUSH_DATA *AssetTableData, + UINT16 TableOffset, + UINT32 PtrAcpiRsdt + ) +{ + + ACPI_HEADER *AcpiHeaderPtr; + UINT32 TableAddress; + UINT32 ListAddress; + UINT16 ArrayLength; + + TableAddress = 0; + + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_ASF].Offset = TableOffset; + + CopyMem ((UINT8 *) &AssetTableData->TableData[TableOffset], (VOID *) (UINTN) PtrAcpiRsdt, sizeof (ACPI_HEADER)); + + AcpiHeaderPtr = (ACPI_HEADER *) &AssetTableData->TableData[TableOffset]; + + if (AcpiHeaderPtr->Signature != RSDT_SIG) { + DEBUG ((EFI_D_ERROR, "ASF ACPI Signature Does Not Match\n")); + return EFI_ABORTED; + } + + ArrayLength = (((UINT16) AcpiHeaderPtr->Length) - sizeof (ACPI_HEADER)) / sizeof (UINT32); + ListAddress = PtrAcpiRsdt + sizeof (ACPI_HEADER); + + while (ArrayLength) { + /// + /// copy header at this new table address into scratch area + /// + CopyMem (&TableAddress, (VOID *) (UINTN) ListAddress, sizeof (UINT32)); + CopyMem (&AssetTableData->TableData[TableOffset], (VOID *) (UINTN) TableAddress, sizeof (ACPI_HEADER)); + + if (AcpiHeaderPtr->Signature == ASF_SIG) { + break; + + } + + ArrayLength--; + ListAddress += sizeof (UINT32); + } + + if (!ArrayLength) { + /// + /// We hit end of table + /// + DEBUG ((EFI_D_ERROR, "Did Not Find ASF Signature \n")); + return EFI_ABORTED; + } + + CopyMem (&AssetTableData->TableData[TableOffset], (VOID *) (UINTN) TableAddress, AcpiHeaderPtr->Length); + + AssetTableData->Tables[HWAI_TABLE_TYPE_INDEX_ASF].Length = (UINT16) AcpiHeaderPtr->Length; + + return EFI_SUCCESS; + +} + +/** + Constructs each of the lower level asset tables + + @param[in] AssetTablesData Buffer of all Asset tables to send to FW + @param[in] TablesSize Size of all tables combined + @param[in] AmtData Structure that holds all the BIOS constructed tables + + @retval EFI_SUCCESS Tables crated. + @retval EFI_ABORTED AssetTableData data is invalid. +**/ +EFI_STATUS +CalculateTableData ( + TABLE_PUSH_DATA*AssetTablesData, + UINT16 *TablesSize, + AMT_DATA *AmtData + ) +{ + + EFI_STATUS Status; + UINT16 TableOffset; + + Status = EFI_SUCCESS; + TableOffset = 0; + + Status = CalulateFruTable (AssetTablesData, AmtData); + if (EFI_ERROR (Status)) { + return Status; + + } + + TableOffset = AssetTablesData->Tables[HWAI_TABLE_TYPE_INDEX_FRU_DEVICE].Length; + Status = CalulateMediaTable (AssetTablesData, TableOffset, AmtData); + if (EFI_ERROR (Status)) { + return Status; + + } + + TableOffset = TableOffset + AssetTablesData->Tables[HWAI_TABLE_TYPE_INDEX_MEDIA_DEVICE].Length; + Status = CalulateSmbiosTable (AssetTablesData, TableOffset, AmtData->PtrSmbiosTable); + if (EFI_ERROR (Status)) { + return Status; + + } + + TableOffset = TableOffset + AssetTablesData->Tables[HWAI_TABLE_TYPE_INDEX_SMBIOS].Length; + Status = CalulateAsfTable (AssetTablesData, TableOffset, AmtData->PtrAcpiRsdt); + if (EFI_ERROR (Status)) { + return Status; + + } + + TableOffset = TableOffset + AssetTablesData->Tables[HWAI_TABLE_TYPE_INDEX_ASF].Length; + + *TablesSize = TableOffset; + + return EFI_SUCCESS; + +} + +/** + Constructs all asset tables and send them to FW + + @param[in] AmtData Structure that holds all the BIOS constructed tables + + @retval EFI_ABORTED Unable to allocate necessary AssetTableData data structure. +**/ +EFI_STATUS +SendAssetTables2Firmware ( + AMT_DATA *AmtData + ) +{ + + EFI_HECI_PROTOCOL *Heci; + TABLE_PUSH_DATA *AssetTablesData; + EFI_STATUS Status; + UINT16 TableOffset; + UINT32 MeMode; + UINT32 MeStatus; + + Status = EFI_SUCCESS; + TableOffset = 0; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (EFI_ERROR (Status)) { + return Status; + } + + AssetTablesData = AllocateZeroPool (sizeof (TABLE_PUSH_DATA) + MAX_ASSET_TABLE_ALLOCATED_SIZE); + + if (AssetTablesData == NULL) { + DEBUG ((EFI_D_ERROR, "SendAssetTables2Firmware Error: Could not allocate Memory\n")); + return EFI_ABORTED; + } + + Status = CalculateTableData (AssetTablesData, &TableOffset, AmtData); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SendAssetTables2Firmware: Error calculating Asset tables - No Data Pushed\n")); + return Status; + } + + Status = Heci->GetMeMode (&MeMode); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SendAssetTables2Firmware: Could not read FW Mode\n")); + return Status; + } + + Status = Heci->GetMeStatus (&MeStatus); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SendAssetTables2Firmware: Could not read FW Status")); + return Status; + } + + if ((MeMode == ME_MODE_NORMAL) && (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY)) { + Status = HeciAssetUpdateFwMsg (mImageHandle, AssetTablesData, TableOffset); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SendAssetTables2Firmware Error: AssetUpdateFwMsg() returned Status %x\n", Status)); + } + } + + FreePool (AssetTablesData); + + return Status; +} + +/** + This routine is run at boot time. + 1) Initialize AMT library. + 2) Check if MEBx is required to be launched by user. + 3) Build and send asset tables to ME FW. + 4) Check USB provision. + 5) Hide unused AMT devices in prior to boot. + + @param[in] None. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structure. + @retval EFI_NOT_FOUND 1.5M FW SKU detected - there is no MEBx on 1.5 FW SKU +**/ +EFI_STATUS +MebxNotifyEvent ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 *CoreImage; + UINT8 *CallBackImage; + MEBX_BPF *MebxBiosParams; + AMT_DATA AmtData; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Acpi3RsdPtr; + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Acpi2RsdPtr; + EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Acpi1RsdPtr; + EFI_ACTIVE_MANAGEMENT_PROTOCOL *Amt; + VOID *TempPointer; + USB_KEY_PROVISIONING *UsbKeyProvisioningData; + EFI_HANDLE Handle; + UINT8 InvokeMebx; + UINT8 Data8; + EFI_BOOT_MODE BootMode; + BOOLEAN WarmReset; + BOOLEAN SendTables; + + DEBUG ((EFI_D_ERROR, "Entering BiosExtensionLoader Driver\n")); + + MebxBiosParams = NULL; + CoreImage = NULL; + CallBackImage = NULL; + Amt = NULL; + Handle = NULL; + InvokeMebx = 0; + Data8 = 0; + + /// + /// Verify FW SKU - dispatch correct images 5MB FW SKU only + /// + if (mFwImageType == FW_IMAGE_TYPE_1_5MB) { + /// + /// 1.5M FW SKU detected - there is no MEBx on 1.5 FW SKU + /// + Status = EFI_NOT_FOUND; + goto Done; + } + + /// + /// Initialize MEBX Setup Variable + /// + mMebxSetupVariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE; + mMebxSetupVariableDataSize = sizeof (ME_BIOS_EXTENSION_SETUP); + + Status = gST->RuntimeServices->GetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + &mMebxSetupVariableAttributes, + &mMebxSetupVariableDataSize, + &mMeBiosExtensionSetup + ); + + if (EFI_ERROR (Status) || mMeBiosExtensionSetup.InterfaceVersion == 0) { + DEBUG ((EFI_D_ERROR, "MeBiosExtensionSetup variable does not exist: create with default values\n")); + /// + /// create the variable when not exist + /// + mFirstBoot = TRUE; + + mMeBiosExtensionSetup.InterfaceVersion = MEBX_SETUP_VERSION; + mMeBiosExtensionSetup.Flags = 0; + mMeBiosExtensionSetup.PlatformMngSel = MEBX_SETUP_PLATFORM_MNT_DEFAULT; + mMeBiosExtensionSetup.AmtSolIder = MEBX_SETUP_SOL_IDER_DEFAULT; + mMeBiosExtensionSetup.RemoteAssistanceTriggerAvailablilty = 0; + mMeBiosExtensionSetup.KvmEnable = 0; + mMeBiosExtensionSetup.MebxDefaultSolIder = TRUE; + + Status = gST->RuntimeServices->SetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + mMebxSetupVariableAttributes, + mMebxSetupVariableDataSize, + &mMeBiosExtensionSetup + ); + ASSERT_EFI_ERROR (Status); + } else { + mFirstBoot = FALSE; + } + +#ifdef EFI_DEBUG + DEBUG ((EFI_D_ERROR, "mMeBiosExtensionSetup before calling MEBx:\n")); + DxeMebxSetupVariableDebugDump (&mMeBiosExtensionSetup); +#endif + +#ifdef EFI_DEBUG + /// + /// Dump the AMT platform policy + /// + // + // The global mDxePlatformAmtPolicy is initialized by the driver + // entry point. + // + DxeAmtPolicyDebugDump (); +#endif + + /// + /// Allocate memory for BPF + /// + MebxBiosParams = AllocatePool (sizeof (MEBX_BPF)); + ASSERT (MebxBiosParams != NULL); + if (MebxBiosParams == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (MebxBiosParams, sizeof (MEBX_BPF)); + + /// + /// Init AMT Library, still launch MEBx even if AMT Library Init fail + /// + Status = AmtLibInit (); + + ZeroMem ((VOID *) &AmtData, sizeof (AMT_DATA)); + + /// + /// Check if MEBx hotkey has been pressed in BIOS + /// + if (AmtHotkeyPressed ()) { + MebxBiosParams->OemFlags |= MEBX_USER_ENTERED_RESPONSE; + } + /// + /// Check if MEBx selection screen enabled + /// + if (AmtSelectionScreen ()) { + MebxBiosParams->OemFlags |= MEBX_RA_SELECTION_MENU; + } + /// + /// Check if UnConfigureMe request + /// + if (AmtUnConfigureMe ()) { + MebxBiosParams->OemFlags |= MEBX_UNCONFIGURE; + } + /// + /// Check if 'Hide UnConfigureMe Confirmation Prompt' request + /// + if (AmtHideUnConfigureMeConfPrompt ()) { + MebxBiosParams->OemFlags |= MEBX_HIDE_UNCONFIGURE_CONF_PROMPT; + } + /// + /// Check if want to show MEBx debug message + /// + if (AmtMebxDebugMsg ()) { + MebxBiosParams->OemFlags |= MEBX_DEBUG_MSG; + } + + MebxBiosParams->BpfVersion = MEBX_VERSION; + MebxBiosParams->CpuReplacementTimeout = mDxePlatformAmtPolicy->AmtConfig.CpuReplacementTimeout; + MebxBiosParams->MeBiosSyncDataPtr = (UINT32) (UINTN) &mMeBiosExtensionSetup; + MebxBiosParams->MebxDebugFlags.Port80 = 1; + + /// + /// pass OEM MEBx resolution settings through BPF + /// + MebxBiosParams->OemResolutionSettings.MebxGraphicsMode = mDxePlatformAmtPolicy->AmtConfig.MebxGraphicsMode; + MebxBiosParams->OemResolutionSettings.MebxNonUiTextMode = mDxePlatformAmtPolicy->AmtConfig.MebxNonUiTextMode; + MebxBiosParams->OemResolutionSettings.MebxUiTextMode = mDxePlatformAmtPolicy->AmtConfig.MebxUiTextMode; + + AmtData.PciDevAssertInfoPtr = (UINT32) (UINTN) &mAmtPciFru; + AmtData.MediaDevAssetInfoPtr = (UINT32) (UINTN) &mAmtMediaFru; + AmtData.VersionInfo = AMT_DATA_VERSION; + + /// + /// Setup CIRA data + /// + if (AmtCiraRequestTrigger ()) { + MebxBiosParams->ActiveRemoteAssistanceProcess = 1; + MebxBiosParams->CiraTimeout = AmtCiraRequestTimeout (); + } + /// + /// Now set the PCI devices + /// + Status = BuildPciFru (); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (mAmtPciFru.PciDevicesHeader.DevCount != 0) { + AmtData.SupportedTablesFlags |= MEBX_STF_PCI_DEV_TABLE; + } + + /// + /// HW asset tables need to be sent when: + /// - FW asked for it, or + /// - FW is alive (brand!=0) and platform isn't booting from a warm reset unless it's first boot + /// + Data8 = PciRead8 (PCI_LIB_ADDRESS (ME_BUS, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_GEN_PMCON_2)); + WarmReset = (BOOLEAN) !!(Data8 & B_PCH_LPC_GEN_PMCON_MEM_SR); + + SendTables = (mFwMediaTableReqAvail && mFwMediaTablePush) || (mFwPlatformBrand != NO_BRAND && (!WarmReset || mFirstBoot)); + + /// + /// ME BWG HWT_PushBIOSTables + /// Built Media List for 8.1 firmware onwards only if Firmware request it or full BIOS boot path (Note 2, 4) + /// Always built media list with older firmware (indicated by missing mFwMediaTableReqAvail) + /// Above all, don't waste time building media list if tables are not going to be sent. + /// + BootMode = GetBootModeHob(); + + if (SendTables && + ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION && BootMode != BOOT_ON_S4_RESUME) || + !mFwMediaTableReqAvail || (mFwMediaTableReqAvail && mFwMediaTablePush))) { + // + // Build Media List + // + BuildMediaList (); + AmtData.SupportedTablesFlags |= MEBX_STF_MEDIA_DEV_TABLE; + } else { + DEBUG ((EFI_D_INFO, "No Media Asset Table is sent\n")); + } + + mUsbProvsionDone = FALSE; + /// + /// If user selected for USB provisioning, then only use the provisioning file. + /// + if (USBProvisionSupport ()) { + /// + /// Check USB Key Provision + /// + UsbKeyProvisioning (); + } + /// + /// fill in the USB provisioning data... + /// + if (mUsbProvsionDone == TRUE) { + UsbKeyProvisioningData = (USB_KEY_PROVISIONING *) (UINTN) AllocatePool (mUsbProvDataSize + sizeof (USB_KEY_PROVISIONING)); + ASSERT (UsbKeyProvisioningData != NULL); + UsbKeyProvisioningData->USBKeyLocationInfo = (mUsbKeyPort << 16) | + (mUsbKeyBus << 8) | + (mUsbKeyDevice << 3) | + mUsbKeyFunction; + MebxBiosParams->UsbKeyDataStructurePtr = (UINT32) (UINTN) UsbKeyProvisioningData; + CopyMem ( + (VOID *) ((UINTN) MebxBiosParams->UsbKeyDataStructurePtr + sizeof (USB_KEY_PROVISIONING)), + mUsbProvData, + mUsbProvDataSize + ); + UsbConsumedDataRecordRemove (); + } + /// + /// Get SMBIOS table pointer. + /// + EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &TempPointer); + AmtData.PtrSmbiosTable = (UINT32) (UINTN) TempPointer; + + /// + /// Find the AcpiSupport protocol returns RSDP (or RSD PTR) address. + /// + Status = EfiGetSystemConfigurationTable (&gEfiAcpi30TableGuid, (VOID *) &Acpi3RsdPtr); + + if (EFI_ERROR (Status) || (Acpi3RsdPtr == NULL)) { + Status = EfiGetSystemConfigurationTable (&gEfiAcpi20TableGuid, (VOID *) &Acpi2RsdPtr); + + if (EFI_ERROR (Status) || (Acpi2RsdPtr == NULL)) { + Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID *) &Acpi1RsdPtr); + if (EFI_ERROR (Status) || (Acpi1RsdPtr == NULL)) { + DEBUG ((EFI_D_ERROR, "Error getting ACPI Table -> %r\n", Status)); + goto Done; + } else { + AmtData.PtrAcpiRsdt = Acpi1RsdPtr->RsdtAddress; + } + } else { + AmtData.PtrAcpiRsdt = Acpi2RsdPtr->RsdtAddress; + } + } else { + AmtData.PtrAcpiRsdt = Acpi3RsdPtr->RsdtAddress; + } + + /// + /// ME BWG HWT_PushBIOSTables + /// Send Tables to Firmware as long as not on warm reset and AMT not permanently disabled (brand = 0) + /// 8.1 firmware onwards, still send table to firmware as long as not on warm reset and AMT not permanently disable (note 2, 3) + /// 8.1 firmware onwards, warm reset with MediaPush set will send asset table to firmware (Note 1) + /// + if (SendTables) { + Status = SendAssetTables2Firmware (&AmtData); + DEBUG ((EFI_D_INFO, "Send Asset Tables to AMT FW - Status = 0x%x %r\n", Status)); + } + + /// + /// Check if firmware INVOKE_MEBX bit is set + /// + Data8 = 0; + Data8 = PciRead8 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_ME_GS_SHDW)); + InvokeMebx = (Data8 & INVOKE_MEBX_BIT) >> 3; + DEBUG ((EFI_D_ERROR, "InvokeMebx = 0x%x %r\n", InvokeMebx, Status)); + + /// + /// Check for BIOS invoke reason + /// + if (!InvokeMebx) { + CheckForBiosInvokeReason (&InvokeMebx, MebxBiosParams); + + } + + if (InvokeMebx) { + PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8000); + Status = AdjustAndExecuteMebxImage (MebxBiosParams); + PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc(), 0x8001); + } + +Done: + /// + /// Free up used RAM for MEBx as done now. + /// + if (MebxBiosParams != NULL) { + FreePool (MebxBiosParams); + } + /// + /// Hide the unused ME device. This will handle both cases MEBx running or not + /// + AmtDeviceConfigure (&mMeBiosExtensionSetup); + + return Status; +} + +/** + Check the status of Amt devices + + @param[in] MeBiosExtensionSetupData MEBx setting data +**/ +VOID +AmtDeviceConfigure ( + IN ME_BIOS_EXTENSION_SETUP *MeBiosExtensionSetupData + ) +{ + if (mFirstBoot || (MeBiosExtensionSetupData->AmtSolIder & SOL_ENABLE) == 0) { + SolDisable (); + } + + if (mFirstBoot || (MeBiosExtensionSetupData->AmtSolIder & IDER_ENABLE) == 0) { + IderDisable (); + } +} + +/** + Detect EFI MEBx support; Loading and execute. + + @param[in] MebxBiosParamsBuffer MebxBiosParams Flat pointer +**/ +EFI_STATUS +AdjustAndExecuteMebxImage ( + IN VOID *MebxBiosParamsBuffer + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + MEBX_BPF *MebxBiosParams; + EFI_MEBX_PROTOCOL *MebxProtocol; + DATA32_UNION MebxExitCode; + + MebxBiosParams = (MEBX_BPF *) MebxBiosParamsBuffer; + + MebxExitCode.Data32 = 0; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + DEBUG ((EFI_D_ERROR, "Calling MEBx\n")); + + /// + /// Stop ASF Watch Dog before entering MEBx Setup + /// + AsfStopWatchDog (); + + /// + /// Locate MEBX protocol + /// + Status = gBS->LocateProtocol (&gEfiMebxProtocolGuid, NULL, (VOID **) &MebxProtocol); + if (!EFI_ERROR (Status)) { +#ifdef EFI_DEBUG + /// + /// Dump MebxBiosParams before launching MEBx + /// + DxeMebxBiosParamsDebugDump (MebxBiosParams); +#endif + MebxProtocol->CoreMebxEntry ((UINT32) (UINTN) MebxBiosParams, (UINT32 *) &MebxExitCode); + } + /// + /// + /// Re-Start ASF Watch Dog after exiting MEBx Setup + /// + AsfStartWatchDog (ASF_START_BIOS_WDT); + + DEBUG ((EFI_D_ERROR, "MEBx return BIOS_CMD_DATA:%x, BIOS_CMD:%x)\n", MebxExitCode.Data8[1], MebxExitCode.Data8[0])); + DEBUG ((EFI_D_ERROR, "MEBx return MEBX_STATUS_CODE:%x)\n", MebxExitCode.Data16[1])); + + /// + /// Restore data record when needed + /// + if (mUsbProvsionDone == TRUE) { + CopyMem ( + mUsbProvDataBackup, + (VOID *) ((UINTN) MebxBiosParams->UsbKeyDataStructurePtr + sizeof (USB_KEY_PROVISIONING)), + mUsbProvDataSize + ); + UsbConsumedDataRecordRestore (); + } + /// + /// BIOS Sync-up DATA + /// + if (mMeBiosExtensionSetup.Flags == 1 || mMeBiosExtensionSetup.MebxDefaultSolIder == TRUE) { + mMeBiosExtensionSetup.Flags = 0; + mMeBiosExtensionSetup.MebxDefaultSolIder = FALSE; + /// + /// Update the variable to sync with MEBX Setup + /// + Status = gST->RuntimeServices->SetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + mMebxSetupVariableAttributes, + mMebxSetupVariableDataSize, + &mMeBiosExtensionSetup + ); + ASSERT_EFI_ERROR (Status); + } + + switch (MebxExitCode.Data8[0] & MEBX_RET_CODE_MASK) { + /// + /// mask off reserved bits 3-7 from mebx exit status code + /// + case MEBX_RET_ACTION_CONTINUE_TO_BOOT: + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_MEBX_OPROM_DONE + ); + break; + + case MEBX_RET_ACTION_RESET: + REPORT_STATUS_CODE ( + EFI_ERROR_CODE, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_MEBX_RESET_ACTION + ); + if (!(MebxExitCode.Data8[1] & MEBX_RET_ACTION_GLOBAL_RESET)) { + DEBUG ((EFI_D_ERROR, "MEBx requires Global Reset.\n")); + HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET); + } else { + DEBUG ((EFI_D_ERROR, "MEBx requires Host Reset.\n")); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } + + DEBUG ((EFI_D_ERROR, "No reset occurs after we get a reset cmd from MEBx.\n")); + EFI_DEADLOOP (); + break; + + default: + REPORT_STATUS_CODE ( + EFI_ERROR_CODE, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_MEBX_OTHER_UNSPECD + ); + Status = EFI_NOT_STARTED; + break; + } + +#ifdef EFI_DEBUG + Status = gST->RuntimeServices->GetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + &mMebxSetupVariableAttributes, + &mMebxSetupVariableDataSize, + &mMeBiosExtensionSetup + ); + DEBUG ((EFI_D_ERROR, "mMeBiosExtensionSetup after calling MEBx:\n")); + DxeMebxSetupVariableDebugDump (&mMeBiosExtensionSetup); +#endif + /// + /// Send PET Alert Message + /// + /// BIOS Specific Code + /// + /// Indicate OS BOOT handoff so that PET/ASF Push msg can be sent out to indicate + /// all done now booting os. + /// + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_UNSPECIFIED | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT + ); + + return Status; +} + +/** + The driver entry point - MEBx Driver main body. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The driver installed without error. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. +**/ +EFI_STATUS +MebxDriverEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeMode; + EFI_HANDLE Handle; + DXE_MBP_DATA_PROTOCOL *MbpData; + + mImageHandle = ImageHandle; + mFwImageType = FW_IMAGE_TYPE_5MB; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Heci->GetMeMode (&MeMode); + if (MeMode != ME_MODE_NORMAL) { + return EFI_UNSUPPORTED; + } + + /// + /// Init AMT Policy Library + /// + Status = AmtPolicyLibInit (); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + /// + /// Install an Amt ready to boot protocol. + /// + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gAmtReadyToBootProtocolGuid, + &mAmtReadyToBoot, + NULL + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + /// + /// Get the MBP Data. + /// + Status = gBS->LocateProtocol (&gMeBiosPayloadDataProtocolGuid, NULL, (VOID **) &MbpData); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "MEBx: No MBP Data Protocol available\n")); + return Status; + } else { + /// + /// Pass FW SKU Type + /// + mFwImageType = (UINT8) MbpData->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType; + mFwPlatformBrand = (UINT8) MbpData->MeBiosPayload.FwPlatType.RuleData.Fields.PlatformBrand; + /// + /// Save for Later use when MBPdata is deallocated + /// + mFwMediaTableReqAvail = MbpData->MeBiosPayload.HwaRequest.Available; + mFwMediaTablePush = (BOOLEAN)MbpData->MeBiosPayload.HwaRequest.Data.Fields.MediaTablePush; + } + } + + return Status; +} + +/** + Detect BIOS invoke reasons. + + @param[in] InvokeMebx Pointer to the Invoke MEBx flag + @param[in] MebxBiosParamsBuffer MebxBiosParams Flat pointer +**/ +VOID +CheckForBiosInvokeReason ( + IN UINT8 *InvokeMebx, + IN MEBX_BPF *MebxBiosParams + ) +{ + /// + /// Check for BIOS invoke reason + /// + if (MebxBiosParams->OemFlags & MEBX_USER_ENTERED_RESPONSE) { + DEBUG ((EFI_D_ERROR, "InvokeMebx Reason = MEBX_USER_ENTERED_RESPONSE %r\n")); + *InvokeMebx = 1; + } + + if (MebxBiosParams->OemFlags & MEBX_UNCONFIGURE) { + DEBUG ((EFI_D_ERROR, "InvokeMebx Reason = MEBX_UNCONFIGURE %r\n")); + *InvokeMebx = 1; + } + + if (MebxBiosParams->UsbKeyDataStructurePtr) { + DEBUG ((EFI_D_ERROR, "InvokeMebx Reason = UsbKeyDataStructurePtr %r\n")); + *InvokeMebx = 1; + } + + if (MebxBiosParams->ActiveRemoteAssistanceProcess) { + DEBUG ((EFI_D_ERROR, "InvokeMebx Reason = ActiveRemoteAssistanceProcess %r\n")); + *InvokeMebx = 1; + } + + if (AmtForcMebxSyncUp ()) { + DEBUG ((EFI_D_ERROR, "InvokeMebx Reason = forcing ME-BIOS sync-up %r\n")); + MebxBiosParams->OemFlags = 0; + *InvokeMebx = 1; + } + + return ; +} diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.cif b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.cif new file mode 100644 index 0000000..2984166 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.cif @@ -0,0 +1,18 @@ +<component> + name = "BiosExtensionLoader" + category = ModulePart + LocalRoot = "ReferenceCode\ME\BiosExtension\Efi\BiosExtensionLoader\Dxe\" + RefName = "BiosExtensionLoader" +[files] +"BiosExtensionLoader.sdl" +"BiosExtensionLoader.mak" +"BiosExtensionLoader.c" +"BiosExtensionLoader.dxs" +"BiosExtensionLoader.h" +"Inventory.c" +"Inventory.h" +"UsbProvision.c" +"UsbProvision.h" +"BiosExtensionLoader.inf" +"MebxBiosParamsDebugDumpDxe.c" +<endComponent> diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.dxs b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.dxs new file mode 100644 index 0000000..d33438c --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.dxs @@ -0,0 +1,52 @@ +/** @file + Dependency expression file for BIOS Extension Invocation Driver. + +@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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (Heci) +#if (PI_SPECIFICATION_VERSION < 0x00010000) +#include EFI_PROTOCOL_DEFINITION (FirmwareVolume) +#else +#include EFI_PROTOCOL_DEFINITION (FirmwareVolume2) +#endif +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) +#endif + +DEPENDENCY_START + EFI_HECI_PROTOCOL_GUID AND +#if (PI_SPECIFICATION_VERSION < 0x00010000) + EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND +#else + EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID AND +#endif + DXE_PLATFORM_AMT_POLICY_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.h b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.h new file mode 100644 index 0000000..c366d0b --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.h @@ -0,0 +1,440 @@ +/** @file + Include for AMT Bios Extentions Loader + +@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 +**/ +#ifndef _AMT_PTBX_H_ +#define _AMT_PTBX_H_ + +#include "Acpi1_0.h" +#include "Acpi2_0.h" +#include "Acpi3_0.h" +#include "MeAccess.h" +#include "Inventory.h" +#include "AmtLib.h" +#include "UsbProvision.h" +#include "Pci22.h" +#include "AmtPlatformPolicy.h" + +#include EFI_PROTOCOL_CONSUMER (FirmwareVolume) +#include EFI_PROTOCOL_CONSUMER (AcpiSupport) +#include EFI_PROTOCOL_CONSUMER (DiskInfo) +#include EFI_PROTOCOL_CONSUMER (BlockIO) +#include EFI_PROTOCOL_CONSUMER (DevicePath) +#include EFI_PROTOCOL_CONSUMER (IdeControllerInit) +#include EFI_PROTOCOL_CONSUMER (AlertStandardFormat) +#include EFI_PROTOCOL_CONSUMER (ActiveManagement) +#include EFI_PROTOCOL_CONSUMER (Heci) +#include EFI_PROTOCOL_CONSUMER (Smbus) +#include EFI_PROTOCOL_CONSUMER (SimpleFileSystem) +#include EFI_PROTOCOL_CONSUMER (Wdt) +#include EFI_PROTOCOL_CONSUMER (MebxProtocol) + +#include EFI_GUID_DEFINITION (Smbios) +#include EFI_GUID_DEFINITION (AcpiTableStorage) +#include EFI_GUID_DEFINITION (Acpi) +#include EFI_GUID_DEFINITION (Hob) +#include EFI_GUID_DEFINITION (MeBiosExtensionSetup) +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) +#include EFI_PROTOCOL_DEFINITION (MeplatformPolicy) +#include EFI_PROTOCOL_DEFINITION (AmtReadyToBoot) + +#define MEBX_RET_ACTION_CONTINUE_TO_BOOT 0x01 +#define MEBX_RET_ACTION_RESET 0x04 +#define MEBX_RET_CODE_MASK 0x07 + +#define MEBX_RET_ACTION_GLOBAL_RESET 0x01 + +#define FW_IMAGE_TYPE_1_5MB 3 +#define FW_IMAGE_TYPE_5MB 4 + +#define MEBX_USER_ENTERED_RESPONSE 0x0002 +#define MEBX_RA_SELECTION_MENU 0x0004 +#define MEBX_HIDE_UNCONFIGURE_CONF_PROMPT 0x0040 +#define MEBX_DEBUG_MSG 0x4000 +#define MEBX_UNCONFIGURE 0x8000 + +#define MEBX_STF_PCI_DEV_TABLE 0x0001 +#define MEBX_STF_MEDIA_DEV_TABLE 0x0002 + +#define MEBX_MEDIA_IN_ATA 0x0000 +#define MEBX_MEDIA_IN_ATAPI 0x0001 +#define MEBX_MEDIA_IN_SATA 0x0002 + +#define MEBX_MEDIA_DT_HDD 0x0000 +#define MEBX_MEDIA_DT_CDROM 0x0001 +#define MEBX_MEDIA_DT_DVD 0x0002 +#define MEBX_MEDIA_DT_FDD 0x0003 +#define MEBX_MEDIA_DT_MO 0x0004 + +// +// MEBX Software Class DXE Subclass Progress Code definitions. +// +#define EFI_SW_DXE_MEBX_OPROM_DONE (EFI_OEM_SPECIFIC | 0x00000000) +#define EFI_SW_DXE_MEBX_OTHER_UNSPECD (EFI_OEM_SPECIFIC | 0x00000009) +#define EFI_SW_DXE_MEBX_RESET_ACTION (EFI_OEM_SPECIFIC | 0x0000000a) + +#pragma pack(1) + +#define DEVICES_LIST_VERSION 0x0001 +#define AMT_DATA_VERSION 0x0101 +#define MEBX_SETUP_VERSION 0x9000 +#define MEBX_VERSION 0x9000 ///< for MEBx 9.0.0 or later +#define MEBX_SETUP_PLATFORM_MNT_DEFAULT MNT_OFF +#define MEBX_SETUP_SOL_IDER_DEFAULT 0 +#define PCI_DEVICE_MAX_NUM 256 +#define MEDIA_DEVICE_MAX_NUM 32 + +#define SMB_SIG 0x5F4D535F +#define RSDT_SIG 0x54445352 ///< RSDT (in reverse) +#define ASF_SIG 0x21465341 ///< ASF! (in reverse) +#define ONEMIN 60000000 +#define FIVEMIN 300000000 +#define TENMIN 600000000 + +#define INVOKE_MEBX_BIT 0x08 + +typedef enum _HWAI_FRU_TYPE_ +{ + HWAI_FRU_TYPE_NONE= 0, + HWAI_FRU_TYPE_PCI +} HWAI_FRU_TYPE; + +typedef struct { + UINT16 VersionInfo; + UINT8 DevCount; + UINT8 Reserved1[5]; +} AMT_FRU_DEVICES_HEADER; + +typedef struct { + UINT16 Vid; + UINT16 Did; + UINT16 Rid; + UINT16 SubSysVid; + UINT16 SubSysDid; + UINT32 ClassCode; + UINT16 BusDevFcn; +} MEBX_FRU_PCI_DEVICES; + +typedef struct { + AMT_FRU_DEVICES_HEADER PciDevicesHeader; + MEBX_FRU_PCI_DEVICES PciDevInfo[PCI_DEVICE_MAX_NUM]; +} AMT_PCI_FRU; + +typedef struct _PCI_DEV_INFO { + UINT16 VersionInfo; + UINT8 PciDevCount; + UINT8 Reserved[5]; +} PCI_DEV_INFO; + +typedef struct _HWAI_PCI_FRU_DATA_ { + UINT16 VendorID; + UINT16 DeviceID; + UINT16 RevID; + UINT16 SubsystemVendorID; + UINT16 SubsystemDeviceID; + UINT32 ClassCode; + UINT16 BusDevFunc; +} HWAI_PCI_DATA; + +typedef struct _HWAI_PCI_FRU_ENTRY { + UINT8 SmbiosType; + UINT8 Length; + UINT16 SmbiosHandle; + UINT32 FruType; + HWAI_PCI_DATA FruData; +} HWAI_PCI_FRU; + +typedef struct _HWAI_FRU_TABLE_HEADER { + UINT16 TableByteCount; + UINT16 StructureCount; + HWAI_PCI_FRU Data[1]; +} HWAI_FRU_TABLE; + +typedef struct _HWAI_MEDIA_DATA_ { + UINT16 Length; + UINT8 Interface; + UINT8 DevType; + UINT8 Manufacturer[40]; + UINT8 SerialNumber[20]; + UINT8 Version[8]; + UINT8 ModelNumber[40]; + UINT32 MaxMediaSizeLow; + UINT32 MaxMediaSizeHigh; + UINT16 Capabilities[3]; +} HWAI_MEDIA_DATA; + +typedef struct _HWAI_MEDIA_ENTRY { + UINT8 SmbiosType; + UINT8 Length; + UINT16 SmbiosHandle; + HWAI_MEDIA_DATA MediaData; +} HWAI_MEDIA_ENTRY; + +typedef struct _HWAI_MEDIA_DEVICE_TABLE_HEADER { + UINT16 TableByteCount; + UINT16 StructureCount; + HWAI_MEDIA_ENTRY Data[1]; +} HWAI_MEDIA_TABLE; + +typedef struct _MEDIA_DEV_INFO { + UINT16 VersionInfo; + UINT8 MediaDevCount; + UINT8 Reserved[5]; +} MEDIA_DEV_INFO; + +typedef struct { + UINT16 StructSize; + UINT8 Interface; + UINT8 DevType; + UINT8 Rsvd[40]; + UINT8 SerialNo[20]; + UINT8 VersionNo[8]; + UINT8 ModelNo[40]; + UINT64 MaxMediaSize; + UINT16 SupportedCmdSets[3]; +} MEBX_FRU_MEDIA_DEVICES; + +typedef struct { + AMT_FRU_DEVICES_HEADER MediaDevicesHeader; + MEBX_FRU_MEDIA_DEVICES MediaDevInfo[MEDIA_DEVICE_MAX_NUM]; +} AMT_MEDIA_FRU; + +typedef struct _COMMON_HEADER_ { + UINT8 Type; + UINT8 Length; + UINT16 Handle; +} SMBIOS_HEADER; + +typedef struct _SMBIOS_MAIN_ { + UINT32 Signature; + UINT8 EpChecksum; + UINT8 EpLength; + UINT8 MajorVersion; + UINT8 MinorVersion; + UINT16 MaxStruct_Size; + UINT8 EpRevision; + UINT8 RevInfo[5]; + UINT8 DmiSignature[5]; ///< _DMI_ + UINT8 IntChecksum; + UINT16 TableLength; + UINT32 TableAddress; + UINT16 StructureCnt; + UINT8 SmbBcdRevision; +} SMBIOS_ENTRY_POINT; + +typedef struct _SMBIOS_TABLE_TYPE_ONE { + SMBIOS_HEADER Header; + UINT8 ManufacturerStr; + UINT8 ProductNameStr; + UINT8 VersionStr; + UINT8 SerialNumberStr; + UINT8 Uuid[16]; + UINT8 WakeUp; +} SMBIOS_TABLE_TYPE_ONE; + +typedef struct _SMBIOS_TABLE_TYPE_THREE { + SMBIOS_HEADER Header; + UINT8 ManufacturerStr; + UINT8 Type; + UINT8 VersionStr; + UINT8 SerialNumberStr; + UINT8 AssetTagStr; + UINT8 BootState; + UINT8 PowerSupplyState; + UINT8 ThermalState; + UINT8 SecurityStatus; + UINT32 VendorInfo; +} SMBIOS_TABLE_TYPE_THREE; + +typedef struct _SMBIOS_TABLE_TYPE_FOUR { + SMBIOS_HEADER Header; + UINT8 SocketStr; + UINT8 Type; + UINT8 Family; + UINT8 Manufacturer; + UINT8 ProcId[8]; + UINT8 VersionStr; + UINT8 Voltage; + UINT16 ExternalClock; + UINT16 MaxSpeed; + UINT16 CurrentSpeed; + UINT8 Status; + UINT8 Upgrade; + UINT16 L1CacheHandle; + UINT16 L2CacheHandle; + UINT16 L3CacheHandle; +} SMBIOS_TABLE_TYPE_FOUR; + +typedef struct _SMBIOS_TABLE_TYPE_TWENTY_THREE { + SMBIOS_HEADER Header; + UINT8 Capabilities; + UINT16 ResetCount; + UINT16 ResetLimit; + UINT16 TimerInterval; + UINT16 Timeout; +} SMBIOS_TABLE_TYPE_TWENTY_THREE; + +typedef struct _ACPI_DESCRIPTOR_HEADER_ { + UINT32 Signature; + UINT32 Length; + UINT8 Revision; + UINT8 Checksum; + UINT8 OemId[6]; + UINT8 OemTableId[8]; + UINT32 OemRevision; + UINT8 CreatorId[4]; + UINT32 CreatorRev; +} ACPI_HEADER; + +typedef struct _MEBX_DEBUG_FLAGS_ { + UINT16 Port80 : 1; ///< Port 80h + UINT16 Rsvd : 15; ///< Reserved +} MEBX_DEBUG_FLAGS; + +typedef struct _MEBX_OEM_RESOLUTION_SETTINGS_ { + UINT16 MebxNonUiTextMode : 4; + UINT16 MebxUiTextMode : 4; + UINT16 MebxGraphicsMode : 4; + UINT16 Rsvd : 4; +} MEBX_OEM_RESOLUTION_SETTINGS; + +typedef struct { + UINT16 BpfVersion; + UINT8 CpuReplacementTimeout; + UINT8 Reserved[7]; + UINT8 ActiveRemoteAssistanceProcess; + UINT8 CiraTimeout; + UINT16 OemFlags; + MEBX_DEBUG_FLAGS MebxDebugFlags; + UINT32 MeBiosSyncDataPtr; + UINT32 UsbKeyDataStructurePtr; + MEBX_OEM_RESOLUTION_SETTINGS OemResolutionSettings; + UINT8 Reserved3[0x2E]; +} MEBX_BPF; + +typedef struct { + UINT16 VersionInfo; + UINT8 Reserved[2]; + UINT32 PtrSmbiosTable; + UINT32 PtrAcpiRsdt; + UINT16 SupportedTablesFlags; + UINT32 PciDevAssertInfoPtr; + UINT32 MediaDevAssetInfoPtr; +} AMT_DATA; + +typedef union { + UINT32 Data32; + UINT16 Data16[2]; + UINT8 Data8[4]; +} DATA32_UNION; + +#pragma pack() + +/** + Signal a event for Amt ready to boot. + + @param[in] None + + @retval EFI_SUCCESS Mebx launched or no controller +**/ +EFI_STATUS +EFIAPI +AmtReadyToBoot ( + VOID + ) +; + +/** + This routine is run at boot time. + 1) Initialize AMT library. + 2) Check if MEBx is required to be launched by user. + 3) Build and send asset tables to ME FW. + 4) Check USB provision. + 5) Hide unused AMT devices in prior to boot. + + @param[in] None. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structure. + @retval EFI_NOT_FOUND 1.5M FW SKU detected - there is no MEBx on 1.5 FW SKU +**/ +EFI_STATUS +MebxNotifyEvent ( + VOID + ) +; + +/** + Check the status of Amt devices + + @param[in] MeBiosExtensionSetupData MEBx setting data +**/ +VOID +AmtDeviceConfigure ( + IN ME_BIOS_EXTENSION_SETUP *MeBiosExtensionSetupData + ) +; + +/** + Detect EFI MEBx support; Loading and execute. + + @param[in] MebxBiosParamsBuffer MebxBiosParams Flat pointer +**/ +EFI_STATUS +AdjustAndExecuteMebxImage ( + IN VOID *MebxBiosParamsBuffer + ) +; + +/** + Detect BIOS invoke reasons. + + @param[in] InvokeMebx Pointer to the Invoke MEBx flag + @param[in] MebxBiosParamsBuffer MebxBiosParams Flat pointer +**/ +VOID +CheckForBiosInvokeReason ( + IN UINT8 *InvokeMebx, + IN MEBX_BPF *MebxBiosParams + ) +; + +/** + Dump MEBx BIOS Params + + @param[in] MebxBiosParams - MEBx BIOS params +**/ +VOID +DxeMebxBiosParamsDebugDump ( + IN MEBX_BPF *MebxBiosParams + ) +; + +extern AMT_MEDIA_FRU mAmtMediaFru; +extern AMT_PCI_FRU mAmtPciFru; + +// +// USB Provisioning +// +extern VOID *mUsbProvData; +extern VOID *mUsbProvDataBackup; +extern UINTN mUsbProvDataSize; +extern BOOLEAN mUsbProvsionDone; +extern UINT8 mUsbKeyBus, mUsbKeyPort, mUsbKeyDevice, mUsbKeyFunction; + +#endif // _AMT_PTBX_H_ diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.inf b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.inf new file mode 100644 index 0000000..689cfe8 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.inf @@ -0,0 +1,116 @@ +## @file +# @todo ADD DESCRIPTION +# +#@copyright +# Copyright (c) 2005 - 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 = BiosExtensionLoader +FILE_GUID = 32C1C9F8-D53F-41c8-94D0-F6739F231011 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + BiosExtensionLoader.h + BiosExtensionLoader.c + Inventory.c + Inventory.h + UsbProvision.h + UsbProvision.c + MebxBiosParamsDebugDumpDxe.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Protocol/AmtPlatformPolicy + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/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/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 + MeGuidLib + AmtLib + MeLib + MeChipsetLib + $(PROJECT_PCH_FAMILY)ProtocolLib + EdkProtocolLib + EfiGuidLib + EdkGuidLib + EdkFrameworkGuidLib + EdkFrameworkProtocolLib + EfiProtocolLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueBaseLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiDevicePathLib + EdkIIGlueUefiLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + EdkIIGlueDxeHobLib + PchPlatformLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = BiosExtensionLoader.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=MebxDriverEntry + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + -D __EDKII_GLUE_DXE_HOB_LIB__ diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.mak b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.mak new file mode 100644 index 0000000..5285798 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.mak @@ -0,0 +1,80 @@ +# MAK file for the ModulePart:BiosExtensionLoader + +all : BiosExtensionLoader + +BiosExtensionLoader : $(BUILD_DIR)\BiosExtensionLoader.mak BiosExtensionLoaderBin + +$(BUILD_DIR)\BiosExtensionLoader.mak : $(BiosExtensionLoader_DIR)\$(@B).cif $(BiosExtensionLoader_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BiosExtensionLoader_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BiosExtensionLoader_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + /I$(MeProtocolLib_DIR)\AmtPlatformPolicy\ + $(IndustryStandard_INCLUDES)\ + $(NB_INCLUDES) \ + $(INTEL_PCH_INCLUDES)\ + /I$(INTEL_COUGAR_POINT_DIR)\ + /I$(PROJECT_DIR)\Core\EM\Terminal + +BiosExtensionLoader_DEFINES=$(MY_DEFINES)\ +!IF "$(TCG_SUPPORT)"=="1" + /D TCG_SUPPORT\ +!ENDIF + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=MebxDriverEntry"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_BASE_LIB__ \ + /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_DEVICE_PATH_LIB__ \ + /D __EDKII_GLUE_UEFI_LIB__\ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \ + /D __EDKII_GLUE_DXE_HOB_LIB__ + +BiosExtensionLoader_LIB_LINKS =\ + $(AmtLibDxe_LIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(MeGuidLib_LIB)\ + $(EFIGUIDLIB)\ + $(EDKPROTOCOLLIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiDevicePathLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueDxeHobLib_LIB)\ + $(AmtProtocolLib_LIB)\ + $(EFIDRIVERLIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(PchPlatformDxeLib_LIB) + +BiosExtensionLoaderBin : $(BiosExtensionLoader_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BiosExtensionLoader.mak all\ + "MY_INCLUDES=$(BiosExtensionLoader_INCLUDES)"\ + "MY_DEFINES=$(BiosExtensionLoader_DEFINES)"\ + GUID=97cc7188-79c9-449f-b969-065b64bf9c69 \ + ENTRY_POINT=_ModuleEntryPoint \ + EDKIIModule=DXEDRIVER\ + TYPE=BS_DRIVER \ + DEPEX1=$(BiosExtensionLoader_DIR)\BiosExtensionLoader.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ + diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.sdl b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.sdl new file mode 100644 index 0000000..9a9d9de --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.sdl @@ -0,0 +1,32 @@ +TOKEN + Name = "BiosExtensionLoader_SUPPORT" + Value = "1" + Help = "Main switch to enable BiosExtensionLoader support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "iAMT_SUPPORT" "=" "1" +End + +PATH + Name = "BiosExtensionLoader_DIR" + Help = "iAMT BiosExtensionLoader file source directory" +End + +MODULE + Help = "Includes BiosExtensionLoader.mak to Project" + File = "BiosExtensionLoader.mak" +End + +ELINK + Name = "$(BUILD_DIR)\BiosExtensionLoader.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(BiosExtensionLoader_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.c b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.c new file mode 100644 index 0000000..b025e97 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.c @@ -0,0 +1,828 @@ +/** @file + Performs PCI and Media device inventory for AMT. + +@copyright + Copyright (c) 2005 - 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 "BiosExtensionLoader.h" +#include "Inventory.h" +#endif + +AMT_MEDIA_FRU mAmtMediaFru; +AMT_PCI_FRU mAmtPciFru; + +/** + Transfer each other while being front and back. + + @param[in] Data The address of data + @param[in] Size Size of data + + @retval None +**/ +VOID +SwapEntries ( + IN CHAR8 *Data, + IN UINT8 Size + ) +{ + UINT16 Index; + CHAR8 Temp8; + + Index = 0; + while (Data[Index] != 0 && Data[Index + 1] != 0) { + Temp8 = Data[Index]; + Data[Index] = Data[Index + 1]; + Data[Index + 1] = Temp8; + Index += 2; + if (Index >= Size) { + break; + } + } + + return ; +} + +/** + This function get the next bus range of given address space descriptors. + It also moves the pointer backward a node, to get prepared to be called + again. + + @param[in] Descriptors points to current position of a serial of address space + descriptors + @param[in] MinBus The lower range of bus number + @param[in] MaxBus The upper range of bus number + @param[in] IsEnd Meet end of the serial of descriptors + + @retval EFI_SUCCESS The command completed successfully +**/ +EFI_STATUS +PciGetNextBusRange ( + IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, + OUT UINT16 *MinBus, + OUT UINT16 *MaxBus, + OUT BOOLEAN *IsEnd + ) +{ + *IsEnd = FALSE; + + /// + /// When *Descriptors is NULL, Configuration() is not implemented, so assume + /// range is 0~PCI_MAX_BUS + /// + if ((*Descriptors) == NULL) { + *MinBus = 0; + *MaxBus = PCI_MAX_BUS; + return EFI_SUCCESS; + } + /// + /// *Descriptors points to one or more address space descriptors, which + /// ends with a end tagged descriptor. Examine each of the descriptors, + /// if a bus typed one is found and its bus range covers bus, this handle + /// is the handle we are looking for. + /// + if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) { + *IsEnd = TRUE; + } + + while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { + if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { + *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; + *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; + } + + (*Descriptors)++; + } + + return EFI_SUCCESS; +} + +/** + This function gets the protocol interface from the given handle, and + obtains its address space descriptors. + + @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle + @param[in] IoDev Handle used to access configuration space of PCI device + @param[in] Descriptors Points to the address space descriptors + + @retval EFI_SUCCESS The command completed successfully +**/ +EFI_STATUS +PciGetProtocolAndResource ( + IN EFI_HANDLE Handle, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, + OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors + ) +{ + EFI_STATUS Status; + + /// + /// Get inferface from protocol + /// + Status = gBS->HandleProtocol ( + Handle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) IoDev + ); + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Call Configuration() to get address space descriptors + /// + Status = (*IoDev)->Configuration (*IoDev, (VOID **) Descriptors); + if (Status == EFI_UNSUPPORTED) { + *Descriptors = NULL; + return EFI_SUCCESS; + + } else { + return Status; + } +} +/// +/// This is where we list any chipset PCI device that is NOT a FRU. +/// Platform specific PCI devices are listed elsewhere. +/// +UINT64 mPciDeviceFilterOutTable[] = { + EFI_PCI_ADDRESS(00, 00, 00, 00), ///< MCH + EFI_PCI_ADDRESS(00, 01, 00, 00), ///< PCIe PEG + EFI_PCI_ADDRESS(00, 02, 00, 00), ///< IGD + EFI_PCI_ADDRESS(00, 03, 00, 00), ///< Intel High Definition Audio Controller (inside processor) + EFI_PCI_ADDRESS(00, 30, 00, 00), ///< DMI to PCI Express Bridge + EFI_PCI_ADDRESS(00, 31, 00, 00), ///< LPC Controller + EFI_PCI_ADDRESS(00, 31, 02, 00), ///< Serial ATA Controller #1 + EFI_PCI_ADDRESS(00, 31, 03, 00), ///< SMBus Controller + EFI_PCI_ADDRESS(00, 31, 05, 00), ///< Serial ATA Controller #2 + EFI_PCI_ADDRESS(00, 31, 06, 00), ///< Thermal Subsystem + EFI_PCI_ADDRESS(00, 29, 00, 00), ///< USB EHCI Controller #1 + EFI_PCI_ADDRESS(00, 29, 01, 00), ///< USB UHCI Controller #1 + EFI_PCI_ADDRESS(00, 29, 02, 00), ///< USB UHCI Controller #2 + EFI_PCI_ADDRESS(00, 29, 03, 00), ///< USB UHCI Controller #3 + EFI_PCI_ADDRESS(00, 29, 04, 00), ///< USB UHCI Controller #4 + EFI_PCI_ADDRESS(00, 29, 07, 00), ///< USBr #1 + EFI_PCI_ADDRESS(00, 28, 00, 00), ///< PCI Express Port #1 + EFI_PCI_ADDRESS(00, 28, 01, 00), ///< PCI Express Port #2 + EFI_PCI_ADDRESS(00, 28, 02, 00), ///< PCI Express Port #3 + EFI_PCI_ADDRESS(00, 28, 03, 00), ///< PCI Express Port #4 + EFI_PCI_ADDRESS(00, 28, 04, 00), ///< PCI Express Port #5 + EFI_PCI_ADDRESS(00, 28, 05, 00), ///< PCI Express Port #6 + EFI_PCI_ADDRESS(00, 28, 06, 00), ///< PCI Express Port #7 + EFI_PCI_ADDRESS(00, 28, 07, 00), ///< PCI Express Port #8 + EFI_PCI_ADDRESS(00, 27, 00, 00), ///< Intel High Definition Audio Controller (inside chipset) + EFI_PCI_ADDRESS(00, 26, 00, 00), ///< USB EHCI Controller #2 + EFI_PCI_ADDRESS(00, 26, 01, 00), ///< USB UHCI Controller #5 + EFI_PCI_ADDRESS(00, 26, 02, 00), ///< USB UHCI Controller #6 + EFI_PCI_ADDRESS(00, 26, 03, 00), ///< USB UHCI Controller #7 + EFI_PCI_ADDRESS(00, 26, 07, 00), ///< USBr #2 + EFI_PCI_ADDRESS(00, 25, 00, 00), ///< GbE Controller + EFI_PCI_ADDRESS(00, 24, 00, 00), ///< Dual Channel NAND Controller + EFI_PCI_ADDRESS(00, 23, 00, 00), ///< Virtualization Engine + EFI_PCI_ADDRESS(00, 22, 00, 00), ///< HECI #1 + EFI_PCI_ADDRESS(00, 22, 01, 00), ///< HECI #2 + EFI_PCI_ADDRESS(00, 22, 02, 00), ///< IDER + EFI_PCI_ADDRESS(00, 22, 03, 00), ///< KT + EFI_PCI_ADDRESS(00, 21, 00, 00), ///< Virtualized SATA Controller + EFI_PCI_ADDRESS(00, 20, 00, 00), ///< xHCI Controller + EFI_MAX_ADDRESS, +}; +#define MAX_FILTER_OUT_DEVICE_NUMBER 0x100 + +/** + AMT only need to know removable PCI device information. + + @param[in] None + + @retval EFI_SUCCESS mAmtPciFru will be update. + @retval EFI_OUT_OF_RESOURCES System on-board device list is larger than + MAX_FILTER_OUT_DEVICE_NUMBER supported. +**/ +EFI_STATUS +BuildPciFru ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Index; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + UINT16 MinBus; + UINT16 MaxBus; + BOOLEAN IsEnd; + UINT16 Bus; + UINT16 Device; + UINT16 Func; + UINT64 Address; + PCI_COMMON_HEADER PciHeader; + PCI_CONFIG_SPACE ConfigSpace; + BOOLEAN ValidDevice; + UINT8 CurrentFruDev; + UINTN FilterOutIndex; + UINT64 *PciDeviceFilterOutTable; + UINT64 *PlatformPciDeviceFilterOutTable; + + CurrentFruDev = 0; + ValidDevice = FALSE; + + /// + /// Get PCI Device Filter Out table about on-board device list from AMT Platform Policy + /// Only need to report removeable device to AMT + /// + PlatformPciDeviceFilterOutTable = (UINT64 *) (UINTN) AmtPciDeviceFilterOutTable (); + + /// + /// System on-board device list + /// + if (sizeof (mPciDeviceFilterOutTable) / sizeof (UINT64) > MAX_FILTER_OUT_DEVICE_NUMBER) { + return EFI_OUT_OF_RESOURCES; + } + + PciDeviceFilterOutTable = mPciDeviceFilterOutTable; + + /// + /// Get all instances of PciRootBridgeIo + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// For each handle, which decides a segment and a bus number range, + /// enumerate all devices on it. + /// + for (Index = 0; Index < NumberOfHandles; Index++) { + Status = PciGetProtocolAndResource ( + HandleBuffer[Index], + &IoDev, + &Descriptors + ); + if (EFI_ERROR (Status)) { + FreePool (HandleBuffer); + return Status; + } + /// + /// No document say it's impossible for a RootBridgeIo protocol handle + /// to have more than one address space descriptors, so find out every + /// bus range and for each of them do device enumeration. + /// + while (TRUE) { + Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd); + + if (EFI_ERROR (Status)) { + FreePool (HandleBuffer); + return Status; + } + + if (IsEnd) { + break; + } + + for (Bus = MinBus; Bus <= MaxBus; Bus++) { + /// + /// For each devices, enumerate all functions it contains + /// + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + /// + /// For each function, read its configuration space and print summary + /// + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); + /// + /// Read the vendor information + /// + IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint16, + Address, + 1, + &PciHeader.VendorId + ); + + /// + /// If VendorId = 0xffff, there does not exist a device at this + /// location. For each device, if there is any function on it, + /// there must be 1 function at Function 0. So if Func = 0, there + /// will be no more functions in the same device, so we can break + /// loop to deal with the next device. + /// + if (PciHeader.VendorId == 0xffff && Func == 0) { + break; + } + + if (PciHeader.VendorId != 0xffff) { + IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint32, + Address, + sizeof (PciHeader) / sizeof (UINT32), + &PciHeader + ); + + ValidDevice = TRUE; + + /// + /// Check if any onboard system devices which need to be filter-out and do not report to AMT + /// + if (ValidDevice == TRUE) { + for (FilterOutIndex = 0; FilterOutIndex < (sizeof (mPciDeviceFilterOutTable) / sizeof (UINT64)); FilterOutIndex++) { + if (PciDeviceFilterOutTable[FilterOutIndex] == Address) { + /// + /// Match found so ignore it. + /// + ValidDevice = FALSE; + } + + if (PciDeviceFilterOutTable[FilterOutIndex] == Address || + PciDeviceFilterOutTable[FilterOutIndex] == EFI_MAX_ADDRESS + ) { + /// + /// Match or end of list. + /// + break; + } + } + } + /// + /// Check if any Platform specific onboard devices which need to be filter-out and do not report to AMT + /// + if (ValidDevice == TRUE) { + if (PlatformPciDeviceFilterOutTable != NULL) { + for (FilterOutIndex = 0; FilterOutIndex < MAX_FILTER_OUT_DEVICE_NUMBER; FilterOutIndex++) { + if (PlatformPciDeviceFilterOutTable[FilterOutIndex] == Address) { + /// + /// Match found so ignore it. + /// + ValidDevice = FALSE; + } + + if (PlatformPciDeviceFilterOutTable[FilterOutIndex] == Address || + PlatformPciDeviceFilterOutTable[FilterOutIndex] == EFI_MAX_ADDRESS + ) { + /// + /// Match or end of list. + /// + break; + } + } + } + } + /// + /// Filter-out bridge + /// + if (ValidDevice == TRUE) { + switch (PciHeader.ClassCode[2]) { + case PCI_CLASS_BRIDGE: + ValidDevice = FALSE; + break; + } + } + + if (ValidDevice == TRUE) { + mAmtPciFru.PciDevInfo[CurrentFruDev].Vid = PciHeader.VendorId; + mAmtPciFru.PciDevInfo[CurrentFruDev].Did = PciHeader.DeviceId; + mAmtPciFru.PciDevInfo[CurrentFruDev].Rid = PciHeader.RevisionId; + mAmtPciFru.PciDevInfo[CurrentFruDev].ClassCode = ((UINT32) PciHeader.ClassCode[0]) | ((UINT32) PciHeader.ClassCode[1] << 0x8) | ((UINT32) PciHeader.ClassCode[2] << 0x10); + + Status = IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint8, + Address, + sizeof (ConfigSpace), + &ConfigSpace + ); + + mAmtPciFru.PciDevInfo[CurrentFruDev].SubSysVid = ConfigSpace.NonCommon.Device.SubVendorId; + mAmtPciFru.PciDevInfo[CurrentFruDev].SubSysDid = ConfigSpace.NonCommon.Device.SubSystemId; + mAmtPciFru.PciDevInfo[CurrentFruDev].BusDevFcn = (UINT16) (Bus << 0x08 | Device << 0x03 | Func); + + if (CurrentFruDev >= PCI_DEVICE_MAX_NUM - 1) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + CurrentFruDev++; + } + /// + /// If this is not a multi-function device, we can leave the loop + /// to deal with the next device. + /// + if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) { + break; + } + } + } + } + } + /// + /// If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED, + /// we assume the bus range is 0~PCI_MAX_BUS. After enumerated all + /// devices on all bus, we can leave loop. + /// + if (Descriptors == NULL) { + break; + } + } + } + + mAmtPciFru.PciDevicesHeader.VersionInfo = DEVICES_LIST_VERSION; + mAmtPciFru.PciDevicesHeader.DevCount = CurrentFruDev; + +Done: + FreePool (HandleBuffer); + + return Status; +} + +/** + Collect all media devices. + + @param[in] None + + @retval None +**/ +VOID +EFIAPI +BuildMediaList ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN IderHandleCount; + EFI_HANDLE *IderHandleBuffer; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; + PCI_DEVICE_PATH *PciDevicePath; + PCI_DEVICE_PATH *IderPciDevicePath; + ACPI_HID_DEVICE_PATH *AcpiHidDevicePath; + UINTN Index; + EFI_DISK_INFO_PROTOCOL *DiskInfo; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + UINT32 IdeChannel; + UINT32 IdeDevice; + EFI_IDENTIFY_DATA *IdentifyDriveInfo; + UINT8 Index1; + UINT32 BufferSize; + UINT64 DriveSize; + UINT8 MediaDeviceCount; + + MediaDeviceCount = 0; + PciDevicePath = NULL; + Status = EFI_SUCCESS; + IderHandleCount = 0; + IderPciDevicePath = NULL; + + /// + /// Look for IDER PCI Device Path + /// + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiIderControllerDriverProtocolGuid, + NULL, + &IderHandleCount, + &IderHandleBuffer + ); + + if (IderHandleCount != 0) { + Status = gBS->HandleProtocol ( + IderHandleBuffer[0], + &gEfiDevicePathProtocolGuid, + (VOID *) &DevicePath + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return ; + } + /// + /// First traverse the device path and look for IDER PCI Device Path + /// + DevicePathNode = DevicePath; + while (!IsDevicePathEnd (DevicePathNode)) { + if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) && + (DevicePathSubType (DevicePathNode) == HW_PCI_DP) + ) { + IderPciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode; + break; + } + + DevicePathNode = NextDevicePathNode (DevicePathNode); + } + + FreePool (IderHandleBuffer); + if (IderPciDevicePath == NULL) { + DEBUG ((EFI_D_ERROR, " No Ider Pci device \n")); + return; + } + + } + /// + /// Locate all media devices connected. + /// We look for the Block I/O protocol to be attached to the device. + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status) || HandleCount == 0) { + return ; + } + + DEBUG ((EFI_D_ERROR, "HandleCount=%X\n", HandleCount)); + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + (VOID *) &DevicePath + ); + ASSERT_EFI_ERROR (Status); + + /// + /// We want to remove any Block I/O instances that refer to Logical partitions. + /// A Block I/O instance is added to the raw device and any partition discovered on + /// the media. This prevents duplications in our table. + /// + if (BlkIo->Media->LogicalPartition) { + continue; + } + /// + /// First traverse the device path and look for our PCI Device Path Type + /// + DevicePathNode = DevicePath; + PciDevicePath = NULL; + while (!IsDevicePathEnd (DevicePathNode)) { + if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) && + (DevicePathSubType (DevicePathNode) == HW_PCI_DP) + ) { + PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode; + break; + } + + DevicePathNode = NextDevicePathNode (DevicePathNode); + } + + if (PciDevicePath == NULL) { + continue; + } + /// + /// Skip IDE-R + /// + if (IderPciDevicePath != NULL) { + if (PciDevicePath->Function == IderPciDevicePath->Function && PciDevicePath->Device == IderPciDevicePath->Device) { + continue; + } + } + + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].StructSize = sizeof (MEBX_FRU_MEDIA_DEVICES); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Rsvd[0] = 0; + + /// + /// Next take a look at the Function field of the current device path node to determine if it is + /// a floppy, or ATA/ATAPI device. + /// + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiDiskInfoProtocolGuid, + (VOID **) &DiskInfo + ); + if (EFI_ERROR (Status)) { + /// + /// No DiskInfo available, check message field + /// Currently USB does not have a DiskInfo available + /// + DevicePathNode = NextDevicePathNode (DevicePathNode); + while (!IsDevicePathEnd (DevicePathNode)) { + if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH)) { + switch (DevicePathSubType (DevicePathNode)) { + case MSG_USB_DP: + /// + /// USB Mass Storage Device + /// + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_ATA; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_HDD; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo[0] = 0; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo[0] = 0; + AsciiStrCpy ((CHAR8 *) mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo, "USB"); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = MultU64x32 ( + BlkIo->Media->LastBlock + 1, + BlkIo->Media->BlockSize + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = 0; + break; + + case MSG_ATAPI_DP: + /// + /// Should be SATA if no DiskInfo Protocol available + /// + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_SATA; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_HDD; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo[0] = 0; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo[0] = 0; + AsciiStrCpy ((CHAR8 *) mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo, "Native SATA"); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = MultU64x32 ( + BlkIo->Media->LastBlock + 1, + BlkIo->Media->BlockSize + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = 0; + break; + + default: + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_ATA; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_MO; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo[0] = 0; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo[0] = 0; + AsciiStrCpy ((CHAR8 *) mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo, "Unknown"); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = MultU64x32 ( + BlkIo->Media->LastBlock + 1, + BlkIo->Media->BlockSize + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = 0; + break; + } + // + // End of Switch + // + } else if ((DevicePathType (DevicePathNode) == ACPI_DEVICE_PATH)) { + AcpiHidDevicePath = (ACPI_HID_DEVICE_PATH *) DevicePathNode; + if (EISA_ID_TO_NUM (AcpiHidDevicePath->HID) == 0x0604) { + /// + /// Floppy + /// + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_ATA; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_FDD; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo[0] = 0; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo[0] = 0; + AsciiStrCpy ((CHAR8 *) mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo, "Floppy"); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = MultU64x32 ( + BlkIo->Media->LastBlock + 1, + BlkIo->Media->BlockSize + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = 0; + } + } + + DevicePathNode = NextDevicePathNode (DevicePathNode); + } + } else { + Status = DiskInfo->WhichIde ( + DiskInfo, + &IdeChannel, + &IdeDevice + ); + if (Status == EFI_UNSUPPORTED) { + continue; + } + + BufferSize = sizeof (EFI_IDENTIFY_DATA); + IdentifyDriveInfo = AllocatePool (BufferSize); + ASSERT (IdentifyDriveInfo != NULL); + if (IdentifyDriveInfo == NULL) { + return ; + } + + Status = DiskInfo->Identify ( + DiskInfo, + IdentifyDriveInfo, + &BufferSize + ); + ASSERT_EFI_ERROR (Status); + + if (PciDevicePath->Function == 1) { + /// + /// PATA Device + /// + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_ATA; + } else if (PciDevicePath->Function == 2) { + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_SATA; + } + /// + /// Reverse the bytes for proper ordering of characters + /// + SwapEntries ((CHAR8 *) &IdentifyDriveInfo->AtaData.ModelName, sizeof (IdentifyDriveInfo->AtaData.ModelName)); + SwapEntries ((CHAR8 *) &IdentifyDriveInfo->AtaData.SerialNo, sizeof (IdentifyDriveInfo->AtaData.SerialNo)); + + CopyMem ( + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo, + IdentifyDriveInfo->AtaData.ModelName, + sizeof (mAmtMediaFru.MediaDevInfo[MediaDeviceCount].ModelNo) + ); + + /// + /// For HardDisk append the size. Otherwise display atapi + /// + if ((IdentifyDriveInfo->AtaData.config & 0x8000) == 00) { + /// + /// 48 bit address feature set is supported, get maximum capacity + /// + if ((IdentifyDriveInfo->AtaData.command_set_supported_83 & 0x0400) == 0) { + DriveSize = + ( + (IdentifyDriveInfo->AtaData.user_addressable_sectors_hi << 16) + + IdentifyDriveInfo->AtaData.user_addressable_sectors_lo + ); + } else { + DriveSize = IdentifyDriveInfo->AtapiData.max_user_lba_for_48bit_addr[0]; + for (Index1 = 1; Index1 < 4; Index1++) { + /// + /// Lower byte goes first: word[100] is the lowest word, word[103] is highest + /// + DriveSize |= LShiftU64 ( + IdentifyDriveInfo->AtapiData.max_user_lba_for_48bit_addr[Index1], + 16 * Index1 + ); + } + } + + DriveSize = MultU64x32 (DriveSize, 512); + CopyMem ( + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo, + IdentifyDriveInfo->AtaData.SerialNo, + sizeof (mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo) + ); + CopyMem ( + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo, + IdentifyDriveInfo->AtaData.FirmwareVer, + sizeof (mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo) + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = IdentifyDriveInfo->AtaData.command_set_supported_82; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[1] = IdentifyDriveInfo->AtaData.command_set_supported_83; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[2] = IdentifyDriveInfo->AtaData.command_set_feature_extn; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = DriveSize; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_HDD; + } else { + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface = MEBX_MEDIA_IN_ATAPI; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize = MultU64x32 ( + BlkIo->Media->LastBlock + 1, + BlkIo->Media->BlockSize + ); + CopyMem ( + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo, + IdentifyDriveInfo->AtapiData.SerialNo, + sizeof (mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SerialNo) + ); + CopyMem ( + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo, + IdentifyDriveInfo->AtapiData.FirmwareVer, + sizeof (mAmtMediaFru.MediaDevInfo[MediaDeviceCount].VersionNo) + ); + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[0] = IdentifyDriveInfo->AtapiData.cmd_set_support_82; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[1] = IdentifyDriveInfo->AtapiData.cmd_set_support_83; + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets[2] = IdentifyDriveInfo->AtapiData.cmd_feature_support; + if (BlkIo->Media->RemovableMedia) { + mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType = MEBX_MEDIA_DT_DVD; + } + } + } + + DEBUG ((EFI_D_ERROR, "%x DevType=%x, \n", MediaDeviceCount, mAmtMediaFru.MediaDevInfo[MediaDeviceCount].DevType)); + DEBUG ((EFI_D_ERROR, "Interface=%x, \n", mAmtMediaFru.MediaDevInfo[MediaDeviceCount].Interface)); + DEBUG ((EFI_D_ERROR, "MaxMediaSize=%x, \n", mAmtMediaFru.MediaDevInfo[MediaDeviceCount].MaxMediaSize)); + DEBUG ((EFI_D_ERROR, "SupportedCmdSets=%x, \n", mAmtMediaFru.MediaDevInfo[MediaDeviceCount].SupportedCmdSets)); + + MediaDeviceCount++; + if (MediaDeviceCount >= MEDIA_DEVICE_MAX_NUM) { + break; + } + } // end of handlebuffer blockio + mAmtMediaFru.MediaDevicesHeader.VersionInfo = DEVICES_LIST_VERSION; + mAmtMediaFru.MediaDevicesHeader.DevCount = MediaDeviceCount; + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } +} diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.h b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.h new file mode 100644 index 0000000..77ccd13 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.h @@ -0,0 +1,159 @@ +/** @file + Include for AMT Bios Extentions Loader Inventory Functions + +@copyright + Copyright (c) 2005 - 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 _INVENTORY_H_ +#define _INVENTORY_H_ + +#include EFI_PROTOCOL_CONSUMER (DiskInfo) +#include EFI_PROTOCOL_CONSUMER (IderControllerDriver) + +/// +/// Common part of the PCI configuration space header for devices, P2P bridges, +/// and cardbus bridges +/// +typedef struct { + UINT16 VendorId; + UINT16 DeviceId; + + UINT16 Command; + UINT16 Status; + + UINT8 RevisionId; + UINT8 ClassCode[3]; + + UINT8 CacheLineSize; + UINT8 PrimaryLatencyTimer; + UINT8 HeaderType; + UINT8 BIST; + +} PCI_COMMON_HEADER; + +/// +/// PCI configuration space header for devices(after the common part) +/// +typedef struct { + UINT32 Bar[6]; ///< Base Address Registers + UINT32 CardBusCISPtr; ///< CardBus CIS Pointer + UINT16 SubVendorId; ///< Subsystem Vendor ID + UINT16 SubSystemId; ///< Subsystem ID + UINT32 ROMBar; ///< Expansion ROM Base Address + UINT8 CapabilitiesPtr; ///< Capabilities Pointer + UINT8 Reserved[3]; + + UINT32 Reserved1; + + UINT8 InterruptLine; ///< Interrupt Line + UINT8 InterruptPin; ///< Interrupt Pin + UINT8 MinGnt; ///< Min_Gnt + UINT8 MaxLat; ///< Max_Lat +} PCI_DEVICE_HEADER; + +/// +/// PCI configuration space header for pci-to-pci bridges(after the common part) +/// +typedef struct { + UINT32 Bar[2]; ///< Base Address Registers + UINT8 PrimaryBus; ///< Primary Bus Number + UINT8 SecondaryBus; ///< Secondary Bus Number + UINT8 SubordinateBus; ///< Subordinate Bus Number + UINT8 SecondaryLatencyTimer; ///< Secondary Latency Timer + UINT8 IoBase; ///< I/O Base + UINT8 IoLimit; ///< I/O Limit + UINT16 SecondaryStatus; ///< Secondary Status + UINT16 MemoryBase; ///< Memory Base + UINT16 MemoryLimit; ///< Memory Limit + UINT16 PrefetchableMemBase; ///< Pre-fetchable Memory Base + UINT16 PrefetchableMemLimit; ///< Pre-fetchable Memory Limit + UINT32 PrefetchableBaseUpper; ///< Pre-fetchable Base Upper 32 bits + UINT32 PrefetchableLimitUpper; ///< Pre-fetchable Limit Upper 32 bits + UINT16 IoBaseUpper; ///< I/O Base Upper 16 bits + UINT16 IoLimitUpper; ///< I/O Limit Upper 16 bits + UINT8 CapabilitiesPtr; ///< Capabilities Pointer + UINT8 Reserved[3]; + + UINT32 ROMBar; ///< Expansion ROM Base Address + UINT8 InterruptLine; ///< Interrupt Line + UINT8 InterruptPin; ///< Interrupt Pin + UINT16 BridgeControl; ///< Bridge Control +} PCI_BRIDGE_HEADER; + +/// +/// PCI configuration space header for cardbus bridges(after the common part) +/// +typedef struct { + UINT32 CardBusSocketReg; ///< Cardus Socket/ExCA Base Address Register + UINT16 Reserved; + UINT16 SecondaryStatus; ///< Secondary Status + UINT8 PciBusNumber; ///< PCI Bus Number + UINT8 CardBusBusNumber; ///< CardBus Bus Number + UINT8 SubordinateBusNumber; ///< Subordinate Bus Number + UINT8 CardBusLatencyTimer; ///< CardBus Latency Timer + UINT32 MemoryBase0; ///< Memory Base Register 0 + UINT32 MemoryLimit0; ///< Memory Limit Register 0 + UINT32 MemoryBase1; + UINT32 MemoryLimit1; + UINT32 IoBase0; + UINT32 IoLimit0; ///< I/O Base Register 0 + UINT32 IoBase1; ///< I/O Limit Register 0 + UINT32 IoLimit1; + UINT8 InterruptLine; ///< Interrupt Line + UINT8 InterruptPin; ///< Interrupt Pin + UINT16 BridgeControl; ///< Bridge Control +} PCI_CARDBUS_HEADER; + +typedef struct { + PCI_COMMON_HEADER Common; + union { + PCI_DEVICE_HEADER Device; + PCI_BRIDGE_HEADER Bridge; + PCI_CARDBUS_HEADER CardBus; + } NonCommon; + UINT32 Data[48]; +} PCI_CONFIG_SPACE; + +/** + AMT only need to know removable PCI device information. + + @param[in] None + + @retval EFI_SUCCESS mAmtPciFru will be update. + @retval EFI_OUT_OF_RESOURCES System on-board device list is larger than + MAX_FILTER_OUT_DEVICE_NUMBER supported. +**/ +EFI_STATUS +BuildPciFru ( + VOID + ) +; + +/** + Collect all media devices. + + @param[in] None + + @retval None +**/ +VOID +EFIAPI +BuildMediaList ( + VOID + ) +; +#endif // _INVENTORY_H_ diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/MebxBiosParamsDebugDumpDxe.c b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/MebxBiosParamsDebugDumpDxe.c new file mode 100644 index 0000000..dda4561 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/MebxBiosParamsDebugDumpDxe.c @@ -0,0 +1,55 @@ +/** @file + Dump whole MEBX_BPF 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 "BiosExtensionLoader.h" +#endif + +/** + Dump MEBx BIOS Params + + @param[in] MebxBiosParams MEBx BIOS params + + @retval None +**/ +VOID +DxeMebxBiosParamsDebugDump ( + IN MEBX_BPF *MebxBiosParams + ) +{ + DEBUG ((EFI_D_INFO, "\n------------------------ MebxBiosParams Dump Begin -----------------\n")); + DEBUG ((EFI_D_INFO, " BpfVersion : 0x%x\n", MebxBiosParams->BpfVersion)); + DEBUG ((EFI_D_INFO, " CpuReplacementTimeout : 0x%x\n", MebxBiosParams->CpuReplacementTimeout)); + DEBUG ((EFI_D_INFO, " ActiveRemoteAssistanceProcess : 0x%x\n", MebxBiosParams->ActiveRemoteAssistanceProcess)); + DEBUG ((EFI_D_INFO, " CiraTimeout : 0x%x\n", MebxBiosParams->CiraTimeout)); + DEBUG ((EFI_D_INFO, " OemFlags : 0x%x\n", MebxBiosParams->OemFlags)); + DEBUG ((EFI_D_INFO, "MebxDebugFlags ---\n")); + DEBUG ((EFI_D_INFO, " Port80 : 0x%x\n", MebxBiosParams->MebxDebugFlags.Port80)); + DEBUG ((EFI_D_INFO, " MeBiosSyncDataPtr : 0x%x\n", MebxBiosParams->MeBiosSyncDataPtr)); + DEBUG ((EFI_D_INFO, " UsbKeyDataStructurePtr : 0x%x\n", MebxBiosParams->UsbKeyDataStructurePtr)); + DEBUG ((EFI_D_INFO, "OemResolutionSettings ---\n")); + DEBUG ((EFI_D_INFO, " MebxNonUiTextMode : 0x%x\n", MebxBiosParams->OemResolutionSettings.MebxNonUiTextMode)); + DEBUG ((EFI_D_INFO, " MebxUiTextMode : 0x%x\n", MebxBiosParams->OemResolutionSettings.MebxUiTextMode)); + DEBUG ((EFI_D_INFO, " MebxUiTextMode : 0x%x\n", MebxBiosParams->OemResolutionSettings.MebxGraphicsMode)); + DEBUG ((EFI_D_INFO, "\n------------------------ MebxBiosParams Dump End -------------------\n")); +} + diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.c b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.c new file mode 100644 index 0000000..50dbffc --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.c @@ -0,0 +1,753 @@ +/** @file + Performs USB Key Provisioning for AMT. + +@copyright + Copyright (c) 2005 - 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 "UsbProvision.h" +#endif + +VOID *mUsbProvData; +VOID *mUsbProvDataBackup; +UINTN mUsbProvDataSize; +BOOLEAN mUsbProvsionDone; +UINT8 mUsbKeyBus, mUsbKeyPort, mUsbKeyDevice, mUsbKeyFunction; +EFI_GUID mFileTypeUuid = FILE_TYPE_UUID; +EFI_GUID mFileTypeUuid2x = FILE_TYPE_UUID_2X; +EFI_GUID mFileTypeUuid3 = FILE_TYPE_UUID_3; +EFI_GUID mFileTypeUuid4 = FILE_TYPE_UUID_4; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mUsbProvisionFileVolume; +VOID *mUsbProvisionFileBuffer; +UINTN mUsbCurrentRecordOffset; +BOOLEAN mVersion2OrAbove; + +/** + Helper function called as part of the code needed + to allocate the proper sized buffer for various + EFI interfaces. + + @param[in] Status Current status + @param[in] Buffer Current allocated buffer, or NULL + @param[in] BufferSize Current buffer size needed + + @retval TRUE if the buffer was reallocated and the caller should try the + API again. +**/ +BOOLEAN +GrowBuffer ( + IN OUT EFI_STATUS *Status, + IN OUT VOID **Buffer, + IN UINTN BufferSize + ) +{ + BOOLEAN TryAgain; + + /// + /// If this is an initial request, buffer will be null with a new buffer size + /// + if (!*Buffer && BufferSize) { + *Status = EFI_BUFFER_TOO_SMALL; + } + /// + /// If the status code is "buffer too small", resize the buffer + /// + TryAgain = FALSE; + if (*Status == EFI_BUFFER_TOO_SMALL) { + + if (*Buffer) { + FreePool (*Buffer); + } + + *Buffer = AllocatePool (BufferSize); + + if (*Buffer) { + TryAgain = TRUE; + } else { + *Status = EFI_OUT_OF_RESOURCES; + } + } + /// + /// If there's an error, free the buffer + /// + if (!TryAgain && EFI_ERROR (*Status) && *Buffer) { + FreePool (*Buffer); + *Buffer = NULL; + } + + return TryAgain; +} + +/** + Function gets the file information from an open file descriptor, and stores it + in a buffer allocated from pool. + + @param[in] FHand A file handle + + @retval EFI_FILE_INFO A pointer to a buffer with file information or NULL is returned +**/ +EFI_FILE_INFO * +LibFileInfo ( + IN EFI_FILE_HANDLE FHand + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *Buffer; + UINTN BufferSize; + + /// + /// Initialize for GrowBuffer loop + /// + Buffer = NULL; + BufferSize = SIZE_OF_EFI_FILE_INFO + 200; + + /// + /// Call the real function + /// + while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { + Status = FHand->GetInfo ( + FHand, + &gEfiFileInfoGuid, + &BufferSize, + Buffer + ); + } + + return Buffer; +} + +/** + Search device which it is match the device path. + + @param[in] DevicePath The list of Device patch + @param[in] DevicePathHeader Path hoping to be found. + + @retval DevicePath Can be matched +**/ +EFI_DEVICE_PATH_PROTOCOL * +GetDevicePathTypeMatch ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath, + EFI_DEVICE_PATH_PROTOCOL *DevicePathHeader + ) +{ + while (!IsDevicePathEnd (DevicePath)) { + if (DevicePath->Type == DevicePathHeader->Type && DevicePath->SubType == DevicePathHeader->SubType) { + return DevicePath; + } else { + DevicePath = NextDevicePathNode (DevicePath); + } + } + + return NULL; +} + +/** + Get USB device path from the list of devices + + @param[in] DevicePath The list of Device patch + + @retval DevicePath Can be matched +**/ +USB_DEVICE_PATH * +GetUsbDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL UsbDevicePath = { MESSAGING_DEVICE_PATH, MSG_USB_DP }; + return (USB_DEVICE_PATH *) GetDevicePathTypeMatch (DevicePath, &UsbDevicePath); +} + +/** + Get Media device path from the list of devices + + @param[in] DevicePath The list of Device patch + + @retval DevicePath Can be matched +**/ +HARDDRIVE_DEVICE_PATH * +GetMediaDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL MediaDevicePath = { MESSAGING_DEVICE_PATH, MEDIA_HARDDRIVE_DP }; + return (HARDDRIVE_DEVICE_PATH *) GetDevicePathTypeMatch (DevicePath, &MediaDevicePath); +} + +/** + Get PCI device path from the list of devices + + @param[in] DevicePath The list of Device patch + + @retval DevicePath Can be matched +**/ +PCI_DEVICE_PATH * +GetPciDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL PciDevicePath = { HARDWARE_DEVICE_PATH, HW_PCI_DP }; + return (PCI_DEVICE_PATH *) GetDevicePathTypeMatch (DevicePath, &PciDevicePath); +} + +#pragma optimize("", off) + +/** + Read provisioning file and checking if header is valid. + + @param[in] FileHandle File handle will be checking. + + @retval None +**/ +VOID +DoProvision ( + EFI_FILE_HANDLE FileHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *FileInfo; + UINTN FileInfoSize; + FILE_HEADER_RECORD *FileHeaderRecord; + DATA_RECORD_HEADER *DataRecordHeader; + UINT16 DataRecordEntryCount; + UINTN FileHeaderSize; + UINTN DataRecordSize; + DATA_RECORD_ENTRY *DataRecordEntry; + UINTN ConsumedDataRecordSize; + UINTN UsbProvisionFileSize; +#ifdef EFI_DEBUG + UINT16 Padding; +#endif + + FileInfoSize = 0; + FileInfo = NULL; + FileHeaderRecord = NULL; + DataRecordEntryCount = 0; + DataRecordSize = 0; + DataRecordHeader = NULL; + + FileInfo = LibFileInfo (FileHandle); + if (FileInfo == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + mUsbProvisionFileBuffer = AllocatePool ((UINTN) FileInfo->FileSize); + if (mUsbProvisionFileBuffer != NULL) { + UsbProvisionFileSize = (UINTN) FileInfo->FileSize; + + Status = FileHandle->Read (FileHandle, &UsbProvisionFileSize, mUsbProvisionFileBuffer); + if (EFI_ERROR (Status)) { + goto Done; + } + } else { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + /// + /// Check if Valid File header record + /// + FileHeaderRecord = (FILE_HEADER_RECORD *) mUsbProvisionFileBuffer; + if (CompareGuid ((EFI_GUID *) &(FileHeaderRecord->FileTypeUUID), &mFileTypeUuid) == TRUE) { + if (FileHeaderRecord->MajorVersion == MAJOR_VERSION) { + if (FileHeaderRecord->MinorVersion != MINOR_VERSION) { + return ; + } + } else { + return ; + } + } else if (CompareGuid ((EFI_GUID *) &(FileHeaderRecord->FileTypeUUID), &mFileTypeUuid2x) == TRUE) { + if (FileHeaderRecord->MajorVersion == MAJOR_VERSION_20) { + if ((FileHeaderRecord->MinorVersion != MINOR_VERSION_20) && (FileHeaderRecord->MinorVersion != MINOR_VERSION_21)) { + return ; + } + } else { + return ; + } + } else if (CompareGuid ((EFI_GUID *) &(FileHeaderRecord->FileTypeUUID), &mFileTypeUuid3) == TRUE) { + if (FileHeaderRecord->MajorVersion == MAJOR_VERSION_30) { + if (FileHeaderRecord->MinorVersion != MINOR_VERSION_30) { + return ; + } + } else { + return ; + } + } else if (CompareGuid ((EFI_GUID *) &(FileHeaderRecord->FileTypeUUID), &mFileTypeUuid4) == TRUE) { + if (FileHeaderRecord->MajorVersion == MAJOR_VERSION_40) { + if (FileHeaderRecord->MinorVersion != MINOR_VERSION_40) { + return ; + } + } else { + return ; + } + + } else { + return ; + } + + if (FileHeaderRecord->MajorVersion >= MAJOR_VERSION_20) { + mVersion2OrAbove = TRUE; + } else { + mVersion2OrAbove = FALSE; + } + /// + /// Check if all records are consumed. + /// + if (FileHeaderRecord->DataRecordsConsumed == FileHeaderRecord->DataRecordCount) { + return ; + } + /// + /// Calculate Data Record size + /// + DataRecordSize = (FileHeaderRecord->DataRecordChunkCount) * CHUNK_SIZE; + + /// + /// Calculate Consumed Data Record size + /// + ConsumedDataRecordSize = (FileHeaderRecord->DataRecordsConsumed) * DataRecordSize; + + /// + /// Calculate File Header Size + /// + FileHeaderSize = (FileHeaderRecord->RecordChunkCount) * CHUNK_SIZE; + + /// + /// Calculate Current Data Record Header Offset + /// + mUsbCurrentRecordOffset = FileHeaderSize + ConsumedDataRecordSize; + + /// + /// Get current Data Record Header pointer + /// + DataRecordHeader = (DATA_RECORD_HEADER *) ((UINTN) mUsbProvisionFileBuffer + mUsbCurrentRecordOffset); + + /// + /// Check if this is a data record + /// + if (DataRecordHeader->RecordTypeIdentifier == DATA_RECORD_TYPE_DATA_RECORD) { + /// + /// Check the if valid flag is set + /// + if ((DataRecordHeader->RecordFlags) & DATA_RECORD_FLAG_VALID) { + /// + /// Found a valid Data Record + /// + mUsbProvsionDone = TRUE; + + /// + /// fetch the first entry + /// + DataRecordEntry = (DATA_RECORD_ENTRY *) ((UINTN) DataRecordHeader + DataRecordHeader->RecordHeaderByteCount); + +#ifdef EFI_DEBUG + DataRecordEntryCount = 0; + do { + switch (DataRecordEntry->ModuleIdentifier) { + case MODULE_IDENTIFIER_INVALID: + goto Done; + break; + + case MODULE_IDENTIFIER_ME_KERNEL: + DEBUG ((EFI_D_ERROR, "MODULE_IDENTIFIER_ME_KERNEL\n")); + switch (DataRecordEntry->VariableIdentifier) { + case VARIABLE_IDENTIFIER_ME_KERNEL_INVALID: + goto Done; + + case VARIABLE_IDENTIFIER_ME_KERNEL_CURRENT_MEBX_PASSWORD: + DataRecordEntryCount++; + DEBUG ((EFI_D_ERROR, "VARIABLE_IDENTIFIER_ME_KERNEL_CURRENT_MEBX_PASSWORD\n")); + break; + + case VARIABLE_IDENTIFIER_ME_KERNEL_NEW_MEBX_PASSWORD: + DataRecordEntryCount++; + DEBUG ((EFI_D_ERROR, "VARIABLE_IDENTIFIER_ME_KERNEL_NEW_MEBX_PASSWORD\n")); + break; + } // end of switch VariableIdentifier + break; + + case MODULE_IDENTIFIER_INTEL_AMT_CM: + DEBUG ((EFI_D_ERROR, "MODULE_IDENTIFIER_ME_KERNEL\n")); + switch (DataRecordEntry->VariableIdentifier) { + case VARIABLE_IDENTIFIER_INTEL_AMT_CM_INVALID: + goto Done; + + case VARIABLE_IDENTIFIER_INTEL_AMT_CM_PID: + DataRecordEntryCount++; + DEBUG ((EFI_D_ERROR, "VARIABLE_IDENTIFIER_INTEL_AMT_CM_PID\n")); + break; + + case VARIABLE_IDENTIFIER_INTEL_AMT_CM_PPS: + DataRecordEntryCount++; + DEBUG ((EFI_D_ERROR, "VARIABLE_IDENTIFIER_INTEL_AMT_CM_PPS\n")); + break; + } // end of switch VariableIdentifier + break; + } // End of switch ModuleIdentifier + /// + /// Move to the next entry + /// + /// + /// Calculate the padding required + /// + Padding = (4 - (DataRecordEntry->VariableLenght % 4)) % 4; + + DataRecordEntry = (DATA_RECORD_ENTRY *) ((UINTN) DataRecordEntry + 8 + DataRecordEntry->VariableLenght + Padding); + } while ((UINTN) DataRecordEntry < ((UINTN) DataRecordHeader + DataRecordSize)); +#endif // end of EFI_DEBUG + } // end of if RecordFlags + } // end of if RecordTypeIdentifier + +Done: + if (mUsbProvsionDone) { + DEBUG ((EFI_D_ERROR, "Found Total %x Entries\n", DataRecordEntryCount)); + DEBUG ((EFI_D_ERROR, "Found Consumed %x Entries\n", FileHeaderRecord->DataRecordsConsumed)); + mUsbProvData = (VOID *) DataRecordHeader; + mUsbProvDataSize = DataRecordSize; + DEBUG ((EFI_D_ERROR, "Total Size is %x\n", mUsbProvDataSize)); + mUsbProvDataBackup = AllocateZeroPool ((UINTN) DataRecordSize); + } + + return ; +} + +#pragma optimize("", on) + +/** + Remove Consumed Data Record in USB Key Provisioning Data File + + @param[in] None. + + @retval None +**/ +VOID +UsbConsumedDataRecordRemove ( + VOID + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE UsbRootFileHandle; + EFI_FILE_HANDLE UsbProvisionFileHandle; + FILE_HEADER_RECORD *FileHeaderRecord; + UINTN FileSize; + DATA_RECORD_HEADER *DataRecordHeader; + + if (mUsbProvsionDone) { + DataRecordHeader = (DATA_RECORD_HEADER *) mUsbProvData; + FileHeaderRecord = (FILE_HEADER_RECORD *) mUsbProvisionFileBuffer; + + /// + /// If version 2 or above and DONT_CONSUME_RECORDS is set, don't remove the record + /// + if (mVersion2OrAbove && ((FileHeaderRecord->FileFlags) & FILE_FLAGS_DONT_CONSUME_RECORDS)) { + return ; + } + /// + /// check if file is present in the root dir + /// + Status = mUsbProvisionFileVolume->OpenVolume (mUsbProvisionFileVolume, &UsbRootFileHandle); + ASSERT_EFI_ERROR (Status); + + Status = UsbRootFileHandle->Open ( + UsbRootFileHandle, + &UsbProvisionFileHandle, + USB_PROVISIONING_DATA_FILE_NAME, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, + 0 + ); + if (!EFI_ERROR (Status)) { + (FileHeaderRecord->DataRecordsConsumed)++; + /// + /// Zero-out data record body and set valid flag to invalid + /// + ZeroMem ( + (VOID *) ((UINTN) mUsbProvData + DataRecordHeader->RecordHeaderByteCount), + mUsbProvDataSize - DataRecordHeader->RecordHeaderByteCount + ); + DataRecordHeader->RecordFlags &= ~DATA_RECORD_FLAG_VALID; + + UsbProvisionFileHandle->SetPosition ( + UsbProvisionFileHandle, + (UINT64) USB_DATA_RECORD_CONSUMED_OFFSET + ); + + FileSize = sizeof (FileHeaderRecord->DataRecordsConsumed); + UsbProvisionFileHandle->Write ( + UsbProvisionFileHandle, + &FileSize, + &FileHeaderRecord->DataRecordsConsumed + ); + + UsbProvisionFileHandle->SetPosition ( + UsbProvisionFileHandle, + (UINT64) mUsbCurrentRecordOffset + ); + FileSize = mUsbProvDataSize; + UsbProvisionFileHandle->Write ( + UsbProvisionFileHandle, + &FileSize, + mUsbProvData + ); + UsbProvisionFileHandle->Close (UsbProvisionFileHandle); + } + + UsbRootFileHandle->Close (UsbRootFileHandle); + } + + return ; +} + +/** + Restore Consumed Data Record in USB Key Provisioning Data File + + @param[in] None. + + @retval None +**/ +VOID +UsbConsumedDataRecordRestore ( + VOID + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE UsbRootFileHandle; + EFI_FILE_HANDLE UsbProvisionFileHandle; + FILE_HEADER_RECORD *FileHeaderRecord; + UINTN FileSize; + DATA_RECORD_HEADER *DataRecordHeader; + + if (mUsbProvsionDone) { + DataRecordHeader = (DATA_RECORD_HEADER *) mUsbProvDataBackup; + FileHeaderRecord = (FILE_HEADER_RECORD *) mUsbProvisionFileBuffer; + + /// + /// If version 2 or above and DONT_CONSUME_RECORDS is set, don't need to restore the record + /// If DataRecordHeader->RecordFlags, DATA_RECORD_FLAG_VALID is not set, don't need to restore the record + /// + if ((mVersion2OrAbove && ((FileHeaderRecord->FileFlags) & FILE_FLAGS_DONT_CONSUME_RECORDS)) || + (((DataRecordHeader->RecordFlags) & DATA_RECORD_FLAG_VALID) == 0) + ) { + FreePool (mUsbProvisionFileBuffer); + FreePool (mUsbProvDataBackup); + return ; + } + /// + /// check if file is present in the root dir + /// + Status = mUsbProvisionFileVolume->OpenVolume (mUsbProvisionFileVolume, &UsbRootFileHandle); + ASSERT_EFI_ERROR (Status); + + Status = UsbRootFileHandle->Open ( + UsbRootFileHandle, + &UsbProvisionFileHandle, + USB_PROVISIONING_DATA_FILE_NAME, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, + 0 + ); + if (!EFI_ERROR (Status)) { + /// + /// Restore DataRecordsConsumed number + /// + (FileHeaderRecord->DataRecordsConsumed)--; + UsbProvisionFileHandle->SetPosition ( + UsbProvisionFileHandle, + (UINT64) USB_DATA_RECORD_CONSUMED_OFFSET + ); + + FileSize = sizeof (FileHeaderRecord->DataRecordsConsumed); + UsbProvisionFileHandle->Write ( + UsbProvisionFileHandle, + &FileSize, + &FileHeaderRecord->DataRecordsConsumed + ); + + UsbProvisionFileHandle->SetPosition ( + UsbProvisionFileHandle, + (UINT64) mUsbCurrentRecordOffset + ); + FileSize = mUsbProvDataSize; + UsbProvisionFileHandle->Write ( + UsbProvisionFileHandle, + &FileSize, + mUsbProvDataBackup + ); + UsbProvisionFileHandle->Close (UsbProvisionFileHandle); + } + + UsbRootFileHandle->Close (UsbRootFileHandle); + FreePool (mUsbProvisionFileBuffer); + FreePool (mUsbProvDataBackup); + } + + return ; +} + +/** + Check USB Key Provisioning Data + + @param[in] None. + + @retval None +**/ +VOID +UsbKeyProvisioning ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NumberFileSystemHandles; + EFI_HANDLE *FileSystemHandles; + UINTN Index; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + USB_DEVICE_PATH *UsbDevicePath; + PCI_DEVICE_PATH *PciDevicePath; + PCI_DEVICE_PATH *ParentPciDevicePath; + PCI_DEVICE_PATH *NextPciDevicePath; + EFI_DEVICE_PATH_PROTOCOL *NextDevicePath; + EFI_FILE_HANDLE UsbRootFileHandle; + EFI_FILE_HANDLE UsbProvisionFileHandle; + UINT8 UsbBusNumber; + UINT64 PciAddress; + + /// + /// This flag will be set only when some meaningfull data is read from USB key + /// + mUsbProvsionDone = FALSE; + + /// + /// Parse Fixed Disk Devices. + /// + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NumberFileSystemHandles, + &FileSystemHandles + ); + + for (Index = 0; Index < NumberFileSystemHandles; Index++) { + DevicePath = DevicePathFromHandle (FileSystemHandles[Index]); + if (DevicePath == NULL) { + continue; + } + + UsbDevicePath = GetUsbDevicePath (DevicePath); + if (UsbDevicePath == NULL) { + continue; + } + + Status = gBS->HandleProtocol ( + FileSystemHandles[Index], + &gEfiSimpleFileSystemProtocolGuid, + (VOID **) &mUsbProvisionFileVolume + ); + ASSERT_EFI_ERROR (Status); + + /// + /// check if file is present in the root dir + /// + Status = mUsbProvisionFileVolume->OpenVolume (mUsbProvisionFileVolume, &UsbRootFileHandle); + ASSERT_EFI_ERROR (Status); + + Status = UsbRootFileHandle->Open ( + UsbRootFileHandle, + &UsbProvisionFileHandle, + USB_PROVISIONING_DATA_FILE_NAME, + EFI_FILE_MODE_READ, + 0 + ); + + if (!EFI_ERROR (Status)) { + /// + /// USB Key Provisioning Data File is exist. + /// + /// + /// Locate PCI IO protocol for PCI registers read + /// + Status = gBS->LocateProtocol ( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + (VOID **) &PciRootBridgeIo + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Get bus number by analysis Device Path and PCI Register - PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET + /// + PciDevicePath = GetPciDevicePath (DevicePath); + if (PciDevicePath == NULL) { + break; + } + + ParentPciDevicePath = NULL; + UsbBusNumber = 0; + while (TRUE) { + NextDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) PciDevicePath; + NextDevicePath = NextDevicePathNode (NextDevicePath); + NextPciDevicePath = GetPciDevicePath (NextDevicePath); + if (NextPciDevicePath == NULL) { + break; + } + /// + /// If found next PCI Device Path, current Device Path is a P2P bridge + /// + ParentPciDevicePath = PciDevicePath; + PciDevicePath = NextPciDevicePath; + /// + /// Read Bus number + /// + PciAddress = EFI_PCI_ADDRESS ( + UsbBusNumber, + ParentPciDevicePath->Device, + ParentPciDevicePath->Function, + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET + ); + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint8, + PciAddress, + 1, + &UsbBusNumber + ); + ASSERT_EFI_ERROR (Status); + } + /// + /// Need a way to get this information + /// + mUsbKeyPort = UsbDevicePath->InterfaceNumber; + mUsbKeyBus = UsbBusNumber; + mUsbKeyDevice = PciDevicePath->Device; + mUsbKeyFunction = PciDevicePath->Function; + DoProvision (UsbProvisionFileHandle); + UsbProvisionFileHandle->Close (UsbProvisionFileHandle); + } + + UsbRootFileHandle->Close (UsbRootFileHandle); + /// + /// Break if found a valid provisioning file + /// + if (mUsbProvsionDone == TRUE) { + break; + } + } // End of For NumberFileSystem Loop + + if (NumberFileSystemHandles != 0) { + FreePool (FileSystemHandles); + } +} diff --git a/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.h b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.h new file mode 100644 index 0000000..74f8c08 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/UsbProvision.h @@ -0,0 +1,249 @@ +/** @file + Include for USB Key Provisioning for AMT. + +@copyright + Copyright (c) 2005 - 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 _USB_PROVISION_H_ +#define _USB_PROVISION_H_ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#include "Pci22.h" + +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) +#include EFI_PROTOCOL_CONSUMER (DiskInfo) +#include EFI_PROTOCOL_CONSUMER (SimpleFileSystem) +#include EFI_PROTOCOL_CONSUMER (FileInfo) +#include EFI_PROTOCOL_CONSUMER (BlockIo) + +#pragma pack(1) + +typedef struct { + EFI_GUID FileTypeUUID; + UINT16 RecordChunkCount; + UINT16 RecordHeaderByteCount; + UINT32 RecordNumber; + UINT8 MajorVersion; + UINT8 MinorVersion; + UINT16 FileFlags; + UINT32 DataRecordCount; + UINT32 DataRecordsConsumed; + UINT16 DataRecordChunkCount; + UINT16 Reserved2; + UINT16 ModuleList[(127 - 9) * 2]; +} FILE_HEADER_RECORD; + +/// +/// File Flags definition (V2 and above) +/// +#define FILE_FLAGS_DONT_CONSUME_RECORDS 0x01 + +// +// FileTypeUUID +// +#define FILE_TYPE_UUID \ + { \ + 0x71FB16B5, 0xCB87, 0x4AF9, 0xB4, 0x41, 0xCA, 0x7B, 0x38, 0x35, 0x78, 0xF9 \ + } + +#define FILE_TYPE_UUID_2X \ + { \ + 0x5881B296, 0x6BCF, 0x4C72, 0x8B, 0x91, 0xA1, 0x5E, 0x51, 0x2E, 0x99, 0xC4 \ + } + +#define FILE_TYPE_UUID_3 \ + { \ + 0xC6F6F7A7, 0xC489, 0x47F6, 0x93, 0xED, 0xE2, 0xE5, 0x02, 0x0D, 0xA5, 0x1D \ + } + +#define FILE_TYPE_UUID_4 \ + { \ + 0x5234A9AA, 0x29E1, 0x44A9, 0x8D, 0x4D, 0x08, 0x1C, 0x07, 0xB9, 0x63, 0x53 \ + } + +// +// MajorVersion +// +#define MAJOR_VERSION 0x01 ///< Check this value +#define MINOR_VERSION 0x00 ///< Check this value +#define MAJOR_VERSION_20 0x02 +#define MINOR_VERSION_20 0x00 +#define MAJOR_VERSION_21 0x02 +#define MINOR_VERSION_21 0x01 +#define MAJOR_VERSION_30 0x03 +#define MINOR_VERSION_30 0x00 +#define MAJOR_VERSION_40 0x04 +#define MINOR_VERSION_40 0x00 + +#define VERSION_10 0x0001 +#define VERSION_20 0x0002 +#define VERSION_21 0x0102 +#define VERSION_30 0x0003 + +typedef struct { + UINT32 RecordTypeIdentifier; + UINT32 RecordFlags; + UINT32 Reserved1[2]; + UINT16 RecordChunkCount; + UINT16 RecordHeaderByteCount; + UINT32 RecordNumber; +} DATA_RECORD_HEADER; + +// +// RecordTypeIdentifier +// +#define DATA_RECORD_TYPE_INVALID 0 +#define DATA_RECORD_TYPE_DATA_RECORD 1 + +/// +/// RecordFlags +/// +#define DATA_RECORD_FLAG_VALID 1 + +typedef struct { + UINT16 ModuleIdentifier; + UINT16 VariableIdentifier; + UINT16 VariableLenght; + UINT16 Reserved1; + VOID *VariableValue; +} DATA_RECORD_ENTRY; + +// +// ModuleIdentifier +// +#define MODULE_IDENTIFIER_INVALID 0 +#define MODULE_IDENTIFIER_ME_KERNEL 1 +#define MODULE_IDENTIFIER_INTEL_AMT_CM 2 + +// +// VariableIdentifier +// MODULE_IDENTIFIER_ME_KERNEL +// +#define VARIABLE_IDENTIFIER_ME_KERNEL_INVALID 0 +#define VARIABLE_IDENTIFIER_ME_KERNEL_CURRENT_MEBX_PASSWORD 1 +#define VARIABLE_IDENTIFIER_ME_KERNEL_NEW_MEBX_PASSWORD 2 + +// +// MODULE_IDENTIFIER_INTEL_AMT_CM +// +#define VARIABLE_IDENTIFIER_INTEL_AMT_CM_INVALID 0 +#define VARIABLE_IDENTIFIER_INTEL_AMT_CM_PID 1 +#define VARIABLE_IDENTIFIER_INTEL_AMT_CM_PPS 2 + +typedef struct { + UINT32 USBKeyLocationInfo; + UINT32 Reserved1[3]; +} USB_KEY_PROVISIONING; + +// +// DISK Definition +// +/// +/// PART_RECORD +/// +typedef struct _PART_RECORD { + UINT8 BootIndicator; + UINT8 StartHead; + UINT8 StartSector; + UINT8 StartCylinder; + UINT8 PartitionType; + UINT8 EndHead; + UINT8 EndSector; + UINT8 EndCylinder; + UINT32 StartLba; + UINT32 SizeInLba; +} PART_RECORD; + +/// +/// MBR Partition table +/// +typedef struct _MBR { + UINT8 CodeArea[440]; + UINT32 OptionalDiskSig; + UINT16 Reserved; + PART_RECORD PartRecord[4]; + UINT16 Sig; +} MASTER_BOOT_RECORD; + +typedef struct _BPB_RECORD { + UINT8 BS_JmpBoot[3]; + UINT8 BS_OEMName[8]; + UINT16 BPB_BytePerSec; + UINT8 BPB_SecPerClus; + UINT16 BPB_RsvdSecCnt; + UINT8 BPB_NumFATs; + UINT16 BPB_RootEntCnt; + UINT16 BPB_TotSec16; + UINT8 BPB_Media; + UINT16 BPB_FATSz16; + UINT16 BPB_SecPerTrk; + UINT16 BPB_NumHeads; + UINT32 BPB_Hiddsec; + UINT32 BPB_TotSec32; +} BPB_RECORD; + +#pragma pack() + +#define CHUNK_SIZE 512 + +#define USB_PROVISIONING_DATA_FILE_NAME L"\\setup.bin" + +#define USB_DATA_RECORD_CONSUMED_OFFSET EFI_FIELD_OFFSET (FILE_HEADER_RECORD, DataRecordsConsumed) + +/** + Remove Consumed Data Record in USB Key Provisioning Data File + + @param[in] None. + + @retval None +**/ +VOID +UsbConsumedDataRecordRemove ( + VOID + ) +; + +/** + Restore Consumed Data Record in USB Key Provisioning Data File + + @param[in] None. + + @retval None +**/ +VOID +UsbConsumedDataRecordRestore ( + VOID + ) +; + +/** + Check USB Key Provisioning Data + + @param[in] None. + + @retval None +**/ +VOID +UsbKeyProvisioning ( + VOID + ) +; + +#endif // _USB_PROVISION_H_ diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/EfiMEBx.cif b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/EfiMEBx.cif new file mode 100644 index 0000000..b0c0203 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/EfiMEBx.cif @@ -0,0 +1,9 @@ +<component> + name = "EfiMEBx" + category = ModulePart + LocalRoot = "ReferenceCode\ME\BiosExtension\Efi\EfiMEBx\" + RefName = "EfiMEBx" +[parts] +"Mebx" +"MebxSetupBrowser" +<endComponent> diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/MEBx.cif b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/MEBx.cif new file mode 100644 index 0000000..b9b87b3 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/MEBx.cif @@ -0,0 +1,12 @@ +<component> + name = "MEBx" + category = ModulePart + LocalRoot = "ReferenceCode\ME\BiosExtension\Efi\EfiMEBx\Mebx" + RefName = "MEBx" +[files] +"Mebx.dxs" +"Mebx.inf" +"Mebx.mak" +"Mebx.sdl" +"Mebx.efi" +<endComponent> diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.dxs b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.dxs new file mode 100644 index 0000000..a42e841 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.dxs @@ -0,0 +1,29 @@ +/** + +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. + + +Module Name: + + Mebx.dxs + +Abstract: + + Dependency expression file for EFI MEBx Setup Browser + +**/ + +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEPENDENCY (AmtPlatformPolicy) + + +DEPENDENCY_START + DXE_PLATFORM_AMT_POLICY_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.efi b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.efi Binary files differnew file mode 100644 index 0000000..78bc805 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.efi diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.inf b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.inf new file mode 100644 index 0000000..ff0daa0 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.inf @@ -0,0 +1,38 @@ +## @file +# Component description file for LegacyBios Extension Above 1M Driver. +# +#@copyright +# Copyright (c) 2011 - 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 +# + +[defines] +BASE_NAME = Mebx +FILE_GUID = 9cfd802c-09a1-43d6-8217-aa49c1f90d2c +COMPONENT_TYPE = BS_DRIVER +BUILD_TYPE = BS_DRIVER_EFI + +[sources.common] + +[includes.common] + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + +[nmake.common] + DPX_SOURCE = Mebx.dxs diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.mak b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.mak new file mode 100644 index 0000000..741abc5 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.mak @@ -0,0 +1,91 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (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/BiosExtension/EfiMEBx/MEBx/Mebx.mak 2 4/23/12 10:51p Klzhan $ +# +# $Revision: 2 $ +# +# $Date: 4/23/12 10:51p $ +# +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/BiosExtension/EfiMEBx/MEBx/Mebx.mak $ +# +# 2 4/23/12 10:51p Klzhan +# 1. Update MEBX binary +# 2. Add Elink for OEM to locate MEBX path. +# +# 1 2/08/12 12:59a Klzhan +# Initial Check in +# +# 3 9/26/11 5:35a Klzhan +# [TAG] EIP70516 +# [Category] Spec Update +# [Severity] Important +# [Description] Update ME 8.0 RC 0.8 +# +# 2 3/25/11 3:23a Klzhan +# Improvement : Remove un-use lines,and update Include path. +# +# 1 3/24/11 2:09a Klzhan +# [TAG] EIP56501 +# [Category] Improvement +# [Description] Support EFI MEBX. +# +# +#********************************************************************** +# +#<AMI_FHDR_START> +#---------------------------------------------------------------------------- +# +# Name: MEBX.mak +# +# Description: EFI MEBX +# +#---------------------------------------------------------------------------- +#<AMI_FHDR_END> +all : $(BUILD_DIR)\Mebx.ffs + +Mebx_INCLUDES=\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(EDK_INCLUDES) + + +$(BUILD_DIR)\Mebx.ffs : $(EFIMebx_FILE_PATH) $(Mebx_DIR)\$(@B).mak Core\FFS.mak + $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \ + CPFLAGS="$(GLOBAL_DEFINES) /D TIANO_RELEASE_VERSION=0x00080006 $(EXTRA_DEFINES) $(Mebx_INCLUDES)" \ + BUILD_DIR=$(BUILD_DIR) SOURCE_DIR=$(Mebx_DIR) \ + GUID=9cfd802c-09a1-43d6-8217-aa49c1f90d2c\ + NAME=$(@B)\ + TYPE=EFI_FV_FILETYPE_DRIVER \ + DEPEX1=$(Mebx_DIR)\Mebx.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + PEFILE=$(EFIMebx_FILE_PATH) FFSFILE=$@ COMPRESS=1 \ + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#*************************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.sdl b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.sdl new file mode 100644 index 0000000..7664926 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/Mebx/Mebx.sdl @@ -0,0 +1,34 @@ +TOKEN + Name = "EFIMebx_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable IccOverClocking support in Project" + Token = "iAMT_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes Mebx.mak to Project" + File = "Mebx.mak" +End + +PATH + Name = "Mebx_DIR" +End + +ELINK + Name = "$(BUILD_DIR)\Mebx.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +TOKEN + Name = "EFIMebx_FILE_PATH" + Value = "$(Mebx_DIR)\Mebx.efi" + TokenType = Expression + TargetMAK = Yes + Help = "Mebx File name and path" +End diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.cif b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.cif new file mode 100644 index 0000000..aaaa1fa --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.cif @@ -0,0 +1,12 @@ +<component> + name = MebxSetupBrowser + category = ModulePart + LocalRoot = "ReferenceCode\ME\BiosExtension\Efi\EfiMEBx\MebxSetupBrowser\" + RefName = "MebxSetupBrowser" +[files] +"MebxSetupBrowser.dxs" +"MebxSetupBrowser.inf" +"MebxSetupBrowser.mak" +"MebxSetupBrowser.efi" +"MebxSetupBrowser.sdl" +<endComponent> diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.dxs b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.dxs new file mode 100644 index 0000000..2e2e12c --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.dxs @@ -0,0 +1,33 @@ +/** + +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. + + +Module Name: + + MebxSetupBrowser.dxs + +Abstract: + + Dependency expression file for EFI MEBx Setup Browser + +**/ + +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEPENDENCY (AmtPlatformPolicy) +#include EFI_PROTOCOL_DEFINITION (SimpleTextIn) +#include EFI_PROTOCOL_DEFINITION (SimpleTextOut) + + +DEPENDENCY_START + DXE_PLATFORM_AMT_POLICY_GUID AND + EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID AND + EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.efi b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.efi Binary files differnew file mode 100644 index 0000000..d212aef --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.efi diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.inf b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.inf new file mode 100644 index 0000000..7bfd8d0 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.inf @@ -0,0 +1,38 @@ +## @file +# Component description file for LegacyBios Extension Above 1M Driver. +# +#@copyright +# Copyright (c) 2011 - 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 +# + +[defines] +BASE_NAME = MebxSetupBrowser +FILE_GUID = b62efbbb-3923-4cb9-a6e8-db818e828a80 +COMPONENT_TYPE = BS_DRIVER +BUILD_TYPE = BS_DRIVER_EFI + +[sources.common] + +[includes.common] + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + +[nmake.common] + DPX_SOURCE = MebxSetupBrowser.dxs diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.mak b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.mak new file mode 100644 index 0000000..cf65f06 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.mak @@ -0,0 +1,92 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (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/BiosExtension/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.mak 2 4/23/12 10:58p Klzhan $ +# +# $Revision: 2 $ +# +# $Date: 4/23/12 10:58p $ +# +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/BiosExtension/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.mak $ +# +# 2 4/23/12 10:58p Klzhan +# 1. Update MEBX binary +# 2. Add Elink for MEBX binary path. +# +# 1 2/08/12 1:00a Klzhan +# Initial Check in +# +# 2 3/25/11 2:50a Klzhan +# Improvement : Remove un-use line. +# +# 1 3/24/11 2:19a Klzhan +# [TAG] EIP56501 +# [Category] Improvement +# [Description] Support EFI MEBX. +# +# +#********************************************************************** +# +#<AMI_FHDR_START> +#---------------------------------------------------------------------------- +# +# Name: MebxSetupBrowser.mak +# +# Description: Mebx Setup Screen +# +#---------------------------------------------------------------------------- +#<AMI_FHDR_END> +all : $(BUILD_DIR)\MebxSetupBrowser.ffs + +MebxSetupBrowser_INCLUDES=\ + $(EDK_SOURCE_INCLUDES)\ + $(ME_INCLUDES)\ + -I$(EDK_SOURCE)\Foundation\Efi\ + -I$(EDK_SOURCE)\Foundation\Include\ + -I$(EDK_SOURCE)\Foundation\Efi\Include\ + -I$(EDK_SOURCE)\Foundation\Framework\Include\ +!IF "$(x64_BUILD)" == "1" + -I$(EDK_SOURCE)\Foundation\Include\x64 +!ELSE + -I$(EDK_SOURCE)\Foundation\Include\ia32 +!ENDIF + +$(BUILD_DIR)\MebxSetupBrowser.ffs : $(EFIMebxSetup_FILE_PATH) $(MebxSetupBrowser_DIR)\$(@B).mak Core\FFS.mak + $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \ + CPFLAGS="$(GLOBAL_DEFINES) /D TIANO_RELEASE_VERSION=0x00080006 $(EXTRA_DEFINES) $(MebxSetupBrowser_INCLUDES)" \ + BUILD_DIR=$(BUILD_DIR) SOURCE_DIR=$(MebxSetupBrowser_DIR) \ + GUID=b62efbbb-3923-4cb9-a6e8-db818e828a80\ + NAME=$(@B)\ + TYPE=EFI_FV_FILETYPE_DRIVER \ + DEPEX1=$(MebxSetupBrowser_DIR)\MebxSetupBrowser.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + PEFILE=$(EFIMebxSetup_FILE_PATH) FFSFILE=$@ COMPRESS=1 \ + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#*************************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.sdl b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.sdl new file mode 100644 index 0000000..b8eec64 --- /dev/null +++ b/ReferenceCode/ME/BiosExtension/Efi/EfiMEBx/MebxSetupBrowser/MebxSetupBrowser.sdl @@ -0,0 +1,34 @@ +TOKEN + Name = "MebxSetupBrowser_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable IccOverClocking support in Project" + Token = "iAMT_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes MebxSetupBrowser.mak to Project" + File = "MebxSetupBrowser.mak" +End + +PATH + Name = "MebxSetupBrowser_DIR" +End + +ELINK + Name = "$(BUILD_DIR)\MebxSetupBrowser.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +TOKEN + Name = "EFIMebxSetup_FILE_PATH" + Value = "$(MebxSetupBrowser_DIR)\MebxSetupBrowser.efi" + TokenType = Expression + TargetMAK = Yes + Help = "Mebx Setup Browser File name and path" +End diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c new file mode 100644 index 0000000..4dfc8b0 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c @@ -0,0 +1,261 @@ +/** @file + MeFwDowngrade driver + +@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 "EdkIIGlueDxe.h" +#include "MeLib.h" +#include "MeAccess.h" +#include "AmtLib.h" +#include "HeciRegs.h" + +#include EFI_GUID_DEFINITION (MePlatformReadyToBoot) +#endif + +#define ERROR_HANDLING_DELAY 7000000 ///< show warning msg and stay for 7 seconds. +#define FW_MSG_DELAY 1000 ///< show warning msg and stay for 1 milisecond. +#define FW_MSG_DELAY_TIMEOUT 10 + +UINT8 HeciHmrfpoLockResult, HeciHmrfpoEnableResult; + +VOID +EFIAPI +MeFwDowngradeMsgEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/** + Tell User that we failed to lock/unlock the flash - Do this after we have graphics initialized + + @param[in] Event The event that triggered this notification function + @param[in] Context Pointer to the notification functions context + + @retval None +**/ +{ + if (HeciHmrfpoLockResult != HMRFPO_LOCK_SUCCESS) { + MeReportError (MSG_HMRFPO_LOCK_FAILURE); + } + + if (HeciHmrfpoEnableResult != HMRFPO_ENABLE_SUCCESS) { + MeReportError (MSG_HMRFPO_UNLOCK_FAILURE); + } + + gBS->CloseEvent (Event); + return; +} + +VOID +EFIAPI +MeHmrfpoDisableEvent ( + EFI_EVENT Event, + VOID *Context + ) +/** + Send the HMRFPO_DISABLE MEI message. + + @param[in] Event The event that triggered this notification function + @param[in] Context Pointer to the notification functions context + + @retval None +**/ +{ + UINT32 FWstatus; + UINT8 WriteValue; + UINT8 StallCount; + + FWstatus = 0; + WriteValue = 0; + StallCount = 0; + + DEBUG ((EFI_D_ERROR, "(B3) Me FW Downgrade - Send the HMRFPO_DISABLE MEI message\n")); + + WriteValue = HeciPciRead8 (R_GEN_STS + 3); + WriteValue = WriteValue & BRNGUP_HMRFPO_DISABLE_CMD_MASK; + WriteValue = WriteValue | BRNGUP_HMRFPO_DISABLE_CMD; + DEBUG ((EFI_D_ERROR, "Me FW Downgrade Writing %x to register %x of PCI space\n", WriteValue, (R_GEN_STS + 3))); + /// + /// Set the highest Byte of General Status Register (Bits 28-31) + /// + HeciPciWrite8 (R_GEN_STS + 3, WriteValue); + FWstatus = HeciPciRead32 (R_FWSTATE); + while + ( + ((FWstatus & BRNGUP_HMRFPO_DISABLE_OVR_MASK) != BRNGUP_HMRFPO_DISABLE_OVR_RSP) && + (StallCount < FW_MSG_DELAY_TIMEOUT) + ) { + DEBUG ((EFI_D_ERROR, "Me FW Downgrade - ME HMRFPO Disable Status = 0x%x\n", FWstatus)); + FWstatus = HeciPciRead32 (R_FWSTATE); + gBS->Stall (FW_MSG_DELAY); + StallCount = StallCount + 1; + } + + if ((FWstatus & BRNGUP_HMRFPO_DISABLE_OVR_MASK) == BRNGUP_HMRFPO_DISABLE_OVR_RSP) { + DEBUG ((EFI_D_ERROR, "Me FW Downgrade Disable Msg Received Successfully\n")); + } else { + DEBUG ((EFI_D_ERROR, "Me FW Downgrade Disable Msg ACK not Received\n")); + + } + /// + /// Hide ME devices so we don't get a yellow bang in OS with disabled devices + /// + DisableAllMEDevices (); + + gBS->CloseEvent (Event); + + return; +} + +/** + Entry point for the MeFwDowngrade driver + + @param[in] ImageHandle Standard entry point parameter. + @param[in] SystemTable Standard entry point parameter. + + @exception EFI_UNSUPPORTED ME policy library initization failure. + @retval Status code returned by CreateEventEx. +**/ +EFI_STATUS +MeFwDowngradeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT MeFwDowngradeEvent; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeMode; + UINT32 MeStatus; + UINT64 Nonce; + UINT32 FactoryDefaultBase; + UINT32 FactoryDefaultLimit; + HECI_FWS_REGISTER MeFirmwareStatus; + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + ASSERT_EFI_ERROR (Status); + + Status = Heci->GetMeMode (&MeMode); + ASSERT_EFI_ERROR (Status); + + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + + /// + /// (B1) Whcih mode ? + /// + if (MeMode == ME_MODE_NORMAL) { + /// + /// (A2) Intel Me image re-flash is requested? + /// + if (MeFwDowngradeSupported ()) { + /// + /// (A4)(A5) The BIOS sends the HMRFPO ENABLE MEI message and wiat for response. + /// + HeciHmrfpoEnableResult = HMRFPO_ENABLE_UNKNOWN_FAILURE; + Status = HeciHmrfpoEnable (0, &HeciHmrfpoEnableResult); + if (Status == EFI_SUCCESS && HeciHmrfpoEnableResult == HMRFPO_ENABLE_SUCCESS) { + /// + /// (A6) The BIOS sends the GLOBAL RESET MEI message + /// + DEBUG ((EFI_D_ERROR, "Me FW Downgrade !!- Step A6\n")); + + HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET); + EFI_DEADLOOP (); + } + /// + /// (A8) Error Handling, HeciHmrfpoEnable include error handling. + /// + DEBUG ( + ( + EFI_D_ERROR, "Me FW Downgrade Error !!- Step A8, the Status is %r, The result is %x\n", Status, + HeciHmrfpoEnableResult + ) + ); + IoWrite8 (0x80, 0xA8); + } else { + /// + /// (A7) The BIOS sends the HMRFPO Lock MEI message and continues the normal boot + /// + HeciHmrfpoLockResult = HMRFPO_LOCK_SUCCESS; + /// + /// The ME firmware will ignore the HMRFPO LOCK command if ME is in ME manufacturing mode + /// + if ((MeFirmwareStatus.r.ManufacturingMode == 0) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + + DEBUG ( + ( + EFI_D_ERROR, + "(A7) Me FW Downgrade - The BIOS sends the HMRFPO Lock MEI message and continues the normal boot\n" + ) + ); + + FactoryDefaultBase = 0; + FactoryDefaultLimit = 0; + Status = HeciHmrfpoLock (&Nonce, &FactoryDefaultBase, &FactoryDefaultLimit, &HeciHmrfpoLockResult); + if (Status != EFI_SUCCESS) { + HeciHmrfpoLockResult = HMRFPO_LOCK_FAILURE; + } + } + } + + Status = gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_NOTIFY, + MeFwDowngradeMsgEvent, + (VOID *) &ImageHandle, + &gMePlatformReadyToBootGuid, + &MeFwDowngradeEvent + ); + + } + /// + /// (B3) Create an event that will call the HMRFPO_DISABLE + /// + if ((MeFirmwareStatus.r.MeOperationMode == ME_OPERATION_MODE_SECOVR_HECI_MSG) && + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) { + Status = gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_NOTIFY, + MeHmrfpoDisableEvent, + (VOID *) &ImageHandle, + &gMePlatformReadyToBootGuid, + &MeFwDowngradeEvent + ); + } + + return Status; +} diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.cif b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.cif new file mode 100644 index 0000000..0d62ae2 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.cif @@ -0,0 +1,12 @@ +<component> + name = "MeFwDowngrade" + category = ModulePart + LocalRoot = "ReferenceCode\ME\FwUpdate\MeFwDowngrade\Dxe\" + RefName = "MeFwDowngrade" +[files] +"MeFwDowngrade.sdl" +"MeFwDowngrade.mak" +"MeFwDowngrade.c" +"MeFwDowngrade.dxs" +"MeFwDowngrade.inf" +<endComponent> diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.dxs b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.dxs new file mode 100644 index 0000000..9352025 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.dxs @@ -0,0 +1,45 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 2011 - 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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (Heci) +#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy) +#include EFI_PROTOCOL_DEFINITION (Spi) +#endif + +DEPENDENCY_START + EFI_HECI_PROTOCOL_GUID AND + DXE_PLATFORM_ME_POLICY_GUID AND + EFI_SPI_PROTOCOL_GUID +DEPENDENCY_END + diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.inf b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.inf new file mode 100644 index 0000000..1c86bc5 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.inf @@ -0,0 +1,85 @@ +## @file +# Component description file for MeFwDowngrade DXE driver +# +#@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 = MeFwDowngrade +FILE_GUID = 5820EEB4-C135-4854-9D2A-AA9EFC4475E9 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + MeFwDowngrade.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(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) + $(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] + MeLib + MeChipsetLib + AmtLib + MeGuidLib + EfiScriptLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=MeFwDowngrade.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=MeFwDowngradeEntryPoint + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -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__ \ + -D __EDKII_GLUE_UEFI_LIB__ diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.mak b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.mak new file mode 100644 index 0000000..e7d8134 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.mak @@ -0,0 +1,56 @@ +# MAK file for the ModulePart:MeFwDowngrade +all : MeFwDowngrade + +MeFwDowngrade : $(BUILD_DIR)\MeFwDowngrade.mak MeFwDowngradeBin + +$(BUILD_DIR)\MeFwDowngrade.mak : $(MeFwDowngrade_DIR)\$(@B).cif $(MeFwDowngrade_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeFwDowngrade_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeFwDowngrade_INCLUDES= \ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + +MeFwDowngrade_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(AmtLibDxe_LIB)\ + $(MeGuidLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EFIGUIDLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EFIDRIVERLIB)\ + $(PchPlatformDxeLib_LIB) + +MeFwDowngrade_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=MeFwDowngradeEntryPoint"\ + /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_LIB__\ + +MeFwDowngradeBin : $(MeFwDowngrade_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeFwDowngrade.mak all\ + "MY_INCLUDES=$(MeFwDowngrade_INCLUDES)"\ + "MY_DEFINES=$(MeFwDowngrade_DEFINES)"\ + GUID=5820EEB4-C135-4854-9D2A-AA9EFC4475E9 \ + ENTRY_POINT=_ModuleEntryPoint \ + EDKIIModule=DXEDRIVER\ + TYPE=BS_DRIVER \ + DEPEX1=$(MeFwDowngrade_DIR)\MeFwDowngrade.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.sdl b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.sdl new file mode 100644 index 0000000..80c4125 --- /dev/null +++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.sdl @@ -0,0 +1,35 @@ +TOKEN + Name = "MeFwDowngrade_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeFwDowngrade support in Project" +End + +MODULE + Help = "Includes MeFwDowngrade.mak to Project" + File = "MeFwDowngrade.mak" +End + +ELINK + Name = "$(BUILD_DIR)\MeFwDowngrade.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +PATH + Name = "MeFwDowngrade_DIR" + Help = "ME Driver files source directory" +End + +TOKEN + Name = "Always_MeFwDowngrade" + Value = "0" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Help = "MeFwDowngrade Setup item will not switch automatically when this item is TRUE" +End diff --git a/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.c b/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.c new file mode 100644 index 0000000..ed9ab5e --- /dev/null +++ b/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.c @@ -0,0 +1,33 @@ +/** @file + AmtForcePushPetPolicy Guid data declarations. + +@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 "EdkIIGlueDxe.h" +#include EFI_GUID_DEFINITION (AmtForcePushPetPolicy) +#endif + +EFI_GUID gAmtForcePushPetPolicyGuid = AMT_FORCE_PUSH_PET_POLICY_GUID; + +EFI_GUID_STRING(&gAmtForcePushPetPolicyGuid, "AmtForcePushPetPolicy GUID", "AmtForcePushPetPolicy GUID") diff --git a/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.h b/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.h new file mode 100644 index 0000000..872045f --- /dev/null +++ b/ReferenceCode/ME/Guid/AmtForcePushPetPolicy/AmtForcePushPetPolicy.h @@ -0,0 +1,36 @@ +/** @file + AmtForcePushPetPolicy Guid definitions + +@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 _EFI_AMT_FORCE_PUSH_PET_POLICY_GUID_H_ +#define _EFI_AMT_FORCE_PUSH_PET_POLICY_GUID_H_ + +#define AMT_FORCE_PUSH_PET_POLICY_GUID \ + { \ + 0xacc8e1e4, 0x9f9f, 0x4e40, 0xa5, 0x7e, 0xf9, 0x9e, 0x52, 0xf3, 0x4c, 0xa5 \ + } + +typedef struct { + EFI_HOB_GUID_TYPE EfiHobGuidType; + INT32 MessageType[1]; +} AMT_FORCE_PUSH_PET_POLICY_HOB; + +extern EFI_GUID gAmtForcePushPetPolicyGuid; + +#endif diff --git a/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.c b/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.c new file mode 100644 index 0000000..ad71b6e --- /dev/null +++ b/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.c @@ -0,0 +1,35 @@ +/** @file + Console Lock Guid data declarations. + +@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 "EdkIIGlueDxe.h" +#include EFI_GUID_DEFINITION (ConsoleLock) +#endif + +EFI_GUID gEfiConsoleLockGuid = EFI_CONSOLE_LOCK_GUID; + +EFI_GUID_STRING(&gEfiConsoleLockGuid, "EFI", "Efi Console Lock GUID") + +CHAR16 gEfiConsoleLockName[] = EFI_CONSOLE_LOCK_VARIABLE_NAME; diff --git a/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.h b/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.h new file mode 100644 index 0000000..9e7acf9 --- /dev/null +++ b/ReferenceCode/ME/Guid/ConsoleLock/ConsoleLock.h @@ -0,0 +1,39 @@ +/** @file + Console Lock Guid definitions + +@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 _EFI_CONSOLE_LOCK_GUID_H_ +#define _EFI_CONSOLE_LOCK_GUID_H_ + +#define EFI_CONSOLE_LOCK_GUID \ + { \ + 0x368cda0d, 0xcf31, 0x4b9b, 0x8c, 0xf6, 0xe7, 0xd1, 0xbf, 0xff, 0x15, 0x7e \ + } + +#define EFI_CONSOLE_LOCK_VARIABLE_NAME (L"ConsoleLock") +#define EFI_CONSOLE_LOCK_FORMAT_VARIABLE_NAME ("ConsoleLock") + +extern CHAR16 gEfiConsoleLockName[]; + +extern EFI_GUID gEfiConsoleLockGuid; + +#define LOCK_CONSOLE 1 +#define NO_LOCK_CONSOLE 0 + +#endif diff --git a/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.c b/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.c new file mode 100644 index 0000000..d3d76c5 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.c @@ -0,0 +1,35 @@ +/** @file + ME BIOS Extension 16 Setup Options Guid data declarations. + +@copyright + Copyright (c) 2005 - 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_GUID_DEFINITION (MeBiosExtensionSetup) +#endif + +EFI_GUID gEfiMeBiosExtensionSetupGuid = EFI_ME_BIOS_EXTENSION_SETUP_GUID; + +EFI_GUID_STRING(&gEfiMeBiosExtensionSetupGuid, "EFI", "Efi Me Bios Extension 16 Setup Options GUID") + +CHAR16 gEfiMeBiosExtensionSetupName[] = EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME; diff --git a/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.h b/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.h new file mode 100644 index 0000000..24e5c75 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeBiosExtensionSetup/MeBiosExtensionSetup.h @@ -0,0 +1,95 @@ +/** @file + Me Bios Extension 16 Setup Options Guid definitions + +@copyright + Copyright (c) 2005 - 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 _EFI_ME_BIOS_EXTENSION_SETUP_GUID_H_ +#define _EFI_ME_BIOS_EXTENSION_SETUP_GUID_H_ + +/// +/// A NV-RAM variable for storing Intel MEBX setup option settings is created if this variable is not +/// present. Those settings are used by BIOS during POST to bypass portions of the code if the +/// Intel ME features are not available +/// +#define EFI_ME_BIOS_EXTENSION_SETUP_GUID \ + { \ + 0x1bad711c, 0xd451, 0x4241, 0xb1, 0xf3, 0x85, 0x37, 0x81, 0x2e, 0xc, 0x70 \ + } + +#define EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME (L"MeBiosExtensionSetup") +#define EFI_ME_BIOS_EXTENSION_SETUP_FORMAT_VARIABLE_NAME ("MeBiosExtensionSetup") + +extern CHAR16 gEfiMeBiosExtensionSetupName[]; + +extern EFI_GUID gEfiMeBiosExtensionSetupGuid; + +#pragma pack(1) + +/// +/// A NV-RAM variable for storing Intel MEBX setup option settings is created if this variable is not +/// present. Those settings are used by BIOS during POST to bypass portions of the code if the +/// Intel ME features are not available. The information is obtained from Intel MEBx BIOS sync data +/// structure +/// +typedef struct { + /// + /// Sync Data Structure Version, a non-zero version indicates the variable is being initialized or valid + /// + UINT16 InterfaceVersion; + UINT16 Reserved; + /// + /// Bit 0 - UPDATED - this structure has been updated by MEBX + /// + UINT32 Flags; + /// + /// Platform Manageability Selection + /// 00h - Off + /// 01h - On + /// + UINT8 PlatformMngSel; + UINT8 Reserved4; + UINT8 AmtSolIder; + UINT8 Reserved1[2]; + /// + /// CIRA Feature + /// 00h - DISABLED + /// 01h - ENABLED + /// + UINT8 RemoteAssistanceTriggerAvailablilty; + /// + /// KVM state (0 - DISABLED, 1 - ENABLED) + /// + UINT8 KvmEnable; + /// + /// 0 - On every later boot after BIOS 1st boot + /// 1 - Mebx will not require a reboot for synchronizing SOL/IDER state, used when BIOS 1st boot only. + /// + UINT8 MebxDefaultSolIder; + UINT8 Reserved2[10]; +} ME_BIOS_EXTENSION_SETUP; + +#define MNT_OFF 0x00 +#define MNT_ON 0x01 +#define LAN_ENABLE 0x01 +#define SOL_ENABLE 0x01 +#define IDER_ENABLE 0x02 +#define KVM_ENABLE 0x01 + +#pragma pack() + +#endif diff --git a/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.c b/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.c new file mode 100644 index 0000000..bb07932 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.c @@ -0,0 +1,27 @@ +/** @file + The GUID definition for MeDataHob + +@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 +**/ + +#include "Tiano.h" +#include "MeDataHob.h" + +EFI_GUID gMeDataHobGuid = ME_DATA_HOB_GUID; + +EFI_GUID_STRING(&gMeDataHobGuid, "ME Data HOB", "GUID for ME Data HOB"); diff --git a/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.h b/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.h new file mode 100644 index 0000000..69c1c5f --- /dev/null +++ b/ReferenceCode/ME/Guid/MeDataHob/MeDataHob.h @@ -0,0 +1,55 @@ +/** @file + The GUID definition for MeDataHob + +@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 _ME_DATA_HOB_H_ +#define _ME_DATA_HOB_H_ + +#define ME_DATA_HOB_GUID \ + { 0x1e94f097, 0x5acd, 0x4089, 0xb2, 0xe3, 0xb9, 0xa5, 0xc8, 0x79, 0xa7, 0x0c } + +extern EFI_GUID gMeDataHobGuid; + +#ifndef _PEI_HOB_H_ +#ifndef __HOB__H__ +#ifndef __PI_HOB_H__ +typedef struct _EFI_HOB_GENERIC_HEADER { + UINT16 HobType; + UINT16 HobLength; + UINT32 Reserved; +} EFI_HOB_GENERIC_HEADER; + +typedef struct _EFI_HOB_GUID_TYPE { + EFI_HOB_GENERIC_HEADER Header; + EFI_GUID Name; + // + // Guid specific data goes here + // +} EFI_HOB_GUID_TYPE; +#endif +#endif +#endif + +typedef struct { + EFI_HOB_GUID_TYPE EfiHobGuidType; + UINT64 FtpmBufferAddress; +} ME_DATA_HOB; + +#endif diff --git a/ReferenceCode/ME/Guid/MeGuidLib.cif b/ReferenceCode/ME/Guid/MeGuidLib.cif new file mode 100644 index 0000000..79c935b --- /dev/null +++ b/ReferenceCode/ME/Guid/MeGuidLib.cif @@ -0,0 +1,22 @@ +<component> + name = "MeGuidLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Guid\" + RefName = "MeGuidLib" +[files] +"MeGuidLib.sdl" +"MeGuidLib.mak" +"MeGuidLib.inf" +"AmtForcePushPetPolicy\AmtForcePushPetPolicy.h" +"AmtForcePushPetPolicy\AmtForcePushPetPolicy.c" +"ConsoleLock\ConsoleLock.h" +"ConsoleLock\ConsoleLock.c" +"MeBiosExtensionSetup\MeBiosExtensionSetup.c" +"MeBiosExtensionSetup\MeBiosExtensionSetup.h" +"MePlatformReadyToBoot\MePlatformReadyToBoot.c" +"MePlatformReadyToBoot\MePlatformReadyToBoot.h" +"MeDataHob\MeDataHob.c" +"MeDataHob\MeDataHob.h" +"MeSsdtTableStorage\MeSsdtTableStorage.c" +"MeSsdtTableStorage\MeSsdtTableStorage.h" +<endComponent> diff --git a/ReferenceCode/ME/Guid/MeGuidLib.inf b/ReferenceCode/ME/Guid/MeGuidLib.inf new file mode 100644 index 0000000..d0809c5 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeGuidLib.inf @@ -0,0 +1,55 @@ +## @file +# Component description file for MeGuidLib +# +#@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 = MeGuidLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + AmtForcePushPetPolicy/AmtForcePushPetPolicy.h + AmtForcePushPetPolicy/AmtForcePushPetPolicy.c + ConsoleLock/ConsoleLock.h + ConsoleLock/ConsoleLock.c + MeBiosExtensionSetup/MeBiosExtensionSetup.h + MeBiosExtensionSetup/MeBiosExtensionSetup.c + MePlatformReadyToBoot/MePlatformReadyToBoot.h + MePlatformReadyToBoot/MePlatformReadyToBoot.c + MeDataHob/MeDataHob.c + MeDataHob/MeDataHob.h + MeSsdtTableStorage/MeSsdtTableStorage.h + MeSsdtTableStorage/MeSsdtTableStorage.c +[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/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[nmake.common] +C_STD_INCLUDE= diff --git a/ReferenceCode/ME/Guid/MeGuidLib.mak b/ReferenceCode/ME/Guid/MeGuidLib.mak new file mode 100644 index 0000000..3d88d99 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeGuidLib.mak @@ -0,0 +1,49 @@ +# /*++ +# 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. +# --*/ +all : MeGuidLib + +$(MeGuidLib_LIB) : MeGuidLib + +MeGuidLib : $(BUILD_DIR)\MeGuidLib.mak MeGuidLibBin + +$(BUILD_DIR)\MeGuidLib.mak : $(MeGuidLib_DIR)\$(@B).cif $(MeGuidLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeGuidLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + + +MeGuidLib_INCLUDES=\ + $(ME_INCLUDES)\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + +MeGuidLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeGuidLib.mak all\ + "MY_INCLUDES=$(MeGuidLib_INCLUDES)" \ + TYPE=LIBRARY +!IF "$(x64_BUILD)"=="1" + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ + /f $(BUILD_DIR)\MeGuidLib.mak all\ + "MY_INCLUDES=$(MeGuidLib_INCLUDES)" \ + TYPE=PEI_LIBRARY +!ENDIF +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2006, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/Guid/MeGuidLib.sdl b/ReferenceCode/ME/Guid/MeGuidLib.sdl new file mode 100644 index 0000000..cf56f0e --- /dev/null +++ b/ReferenceCode/ME/Guid/MeGuidLib.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "MeGuidLib_SUPPORT" + Value = "1" + Help = "Main switch to enable MeGuidLib support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "MeGuidLib_DIR" +End + +MODULE + Help = "Includes MeGuidLib.mak to Project" + File = "MeGuidLib.mak" +End + +TOKEN + Name = "MeGuidLib_LIB" + Value = "$$(LIB_BUILD_DIR)\MeGuidLib.lib" + TokenType = Expression + TargetMAK = Yes +End diff --git a/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.c b/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.c new file mode 100644 index 0000000..574f715 --- /dev/null +++ b/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.c @@ -0,0 +1,33 @@ +/** @file + EFI PlatformReadyToBoot Guid data declarations. + +@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 "EdkIIGlueDxe.h" +#include EFI_GUID_DEFINITION (MePlatformReadyToBoot) +#endif + +EFI_GUID gMePlatformReadyToBootGuid = EFI_EVENT_ME_PLATFORM_READY_TO_BOOT; + +EFI_GUID_STRING(&gMePlatformReadyToBootGuid, "MePlatformReadyToBoot GUID", "MePlatformReadyToBoot GUID") diff --git a/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.h b/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.h new file mode 100644 index 0000000..e1bd9ac --- /dev/null +++ b/ReferenceCode/ME/Guid/MePlatformReadyToBoot/MePlatformReadyToBoot.h @@ -0,0 +1,31 @@ +/** @file + MePlatformReadyToBoot Guid definitions + +@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 _EFI_ME_PLATFORM_READY_TO_BOOT_GUID_H_ +#define _EFI_ME_PLATFORM_READY_TO_BOOT_GUID_H_ + +#define EFI_EVENT_ME_PLATFORM_READY_TO_BOOT \ + { \ + 0x3fdf171, 0x1d67, 0x4ace, 0xa9, 0x4, 0x3e, 0x36, 0xd3, 0x38, 0xfa, 0x74 \ + } + +extern EFI_GUID gMePlatformReadyToBootGuid; + +#endif diff --git a/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.c b/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.c new file mode 100644 index 0000000..82816a1 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.c @@ -0,0 +1,27 @@ +/** @file + The GUID definition for ME ACPI table storage file name + +@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 +**/ +#include "Tiano.h" +#include "MeSsdtTableStorage.h" + +EFI_GUID gMeSsdtAcpiTableStorageGuid = ME_SSDT_ACPI_TABLE_STORAGE_GUID; + +EFI_GUID_STRING + (&gMeSsdtAcpiTableStorageGuid, "ME SSDT ACPI Table Storage File Name", "ME SSDT ACPI Table Storage file name GUID"); diff --git a/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.h b/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.h new file mode 100644 index 0000000..74b72c9 --- /dev/null +++ b/ReferenceCode/ME/Guid/MeSsdtTableStorage/MeSsdtTableStorage.h @@ -0,0 +1,31 @@ +/** @file + GUID definition for the ME SSDT ACPI table storage file name + +@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 _ME_SSDT_TABLE_STORAGE_H_ +#define _ME_SSDT_TABLE_STORAGE_H_ + +#define ME_SSDT_ACPI_TABLE_STORAGE_GUID \ + { \ + 0x9A8F82D5, 0x39B1, 0x48DA, 0x92, 0xDC, 0xA2, 0x2D, 0xA8, 0x83, 0x4D, 0xF6 \ + } + +extern EFI_GUID gMeSsdtAcpiTableStorageGuid; + +#endif diff --git a/ReferenceCode/ME/Heci/Dxe/HeciDxe.cif b/ReferenceCode/ME/Heci/Dxe/HeciDxe.cif new file mode 100644 index 0000000..bd3469d --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/HeciDxe.cif @@ -0,0 +1,18 @@ +<component> + name = "HeciDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Heci\Dxe\" + RefName = "HeciDxe" +[files] +"HeciDxe.sdl" +"HeciDxe.mak" +"Hecicore.c" +"Hecicore.h" +"Hecidrv.c" +"Hecidrv.h" +"Hecidrv.dxs" +"HeciHpet.c" +"HeciHpet.h" +"Hecidrv.inf" +"MeFvi.c" +<endComponent> diff --git a/ReferenceCode/ME/Heci/Dxe/HeciDxe.mak b/ReferenceCode/ME/Heci/Dxe/HeciDxe.mak new file mode 100644 index 0000000..e343b51 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/HeciDxe.mak @@ -0,0 +1,65 @@ +# MAK file for the ModulePart:HeciDxe +all : HeciDxe + +HeciDxe : $(BUILD_DIR)\HeciDxe.mak HeciDxeBin + +$(BUILD_DIR)\HeciDxe.mak : $(HeciDxe_DIR)\$(@B).cif $(HeciDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(HeciDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +HeciDxe_INCLUDES= \ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + +HeciDxe_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(MeProtocolLib_LIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(MeGuidLib_LIB)\ + $(EFISCRIPTLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EFIGUIDLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EdkIIGlueBasePrintLib_LIB)\ + $(EFIDRIVERLIB)\ + $(RcFviDxeLib_LIB)\ + $(PchPlatformDxeLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + +HeciDxe_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeHECI"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /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_LIB__\ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ +# /D iFFS_FLAG \ + +HeciDxeBin : $(HeciDxe_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\HeciDxe.mak all\ + "MY_INCLUDES=$(HeciDxe_INCLUDES)"\ + "MY_DEFINES=$(HeciDxe_DEFINES)"\ + GUID=55E76644-78A5-4a82-A900-7126A5798892 \ + ENTRY_POINT=_ModuleEntryPoint \ + EDKIIModule=DXEDRIVER\ + TYPE=BS_DRIVER \ + DEPEX1=$(HeciDxe_DIR)\Hecidrv.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ diff --git a/ReferenceCode/ME/Heci/Dxe/HeciDxe.sdl b/ReferenceCode/ME/Heci/Dxe/HeciDxe.sdl new file mode 100644 index 0000000..f547413 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/HeciDxe.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "HeciDxe_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable HeciDxe support in Project" +End +MODULE + Help = "Includes HeciDxe.mak to Project" + File = "HeciDxe.mak" +End + +ELINK + Name = "$(BUILD_DIR)\HeciDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +PATH + Name = "HeciDxe_DIR" + Help = "iAMT Hec Driver files source directory" +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Heci/Dxe/HeciHpet.c b/ReferenceCode/ME/Heci/Dxe/HeciHpet.c new file mode 100644 index 0000000..318757c --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/HeciHpet.c @@ -0,0 +1,168 @@ +/** @file + Definitions for HECI driver + +@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 +**/ +#include "HeciDrv.h" +#include "HeciHpet.h" +#include "HeciRegs.h" +#include "HeciCore.h" + +// +// Extern for shared HECI data and protocols +// +extern HECI_INSTANCE *mHeciContext; +VOLATILE UINT32 mSaveHpetConfigReg; + +/** + Store the value of High Performance Timer + + @param[in] None + + @retval None +**/ +VOID +SaveHpet ( + VOID + ) +{ + mSaveHpetConfigReg = MmioRead32 (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); +} + +/** + Restore the value of High Performance Timer + + @param[in] None + + @retval None +**/ +VOID +RestoreHpet ( + VOID + ) +{ + MmioWrite32 (PCH_RCRB_BASE + R_PCH_RCRB_HPTC, mSaveHpetConfigReg); +} + +/** + Used for calculating timeouts + + @param[out] Start Snapshot of the HPET timer + @param[out] End Calculated time when timeout period will be done + @param[in] Time Timeout period in microseconds + + @retval None +**/ +VOID +StartTimer ( + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +{ + UINT32 Ticks; + + /// + /// Make sure that HPET is enabled and running + /// + EnableHpet (); + + /// + /// Read current timer value into start time from HPET + /// + *Start = mHeciContext->HpetTimer[HPET_MAIN_COUNTER_LOW]; + + /// + /// Convert microseconds into 70ns timer ticks + /// + Ticks = Time * HPET_TICKS_PER_MICRO; + + /// + /// Compute end time + /// + *End = *Start + Ticks; + + return ; +} + +/** + Used to determine if a timeout has occured. + + @param[in] Start Snapshot of the HPET timer when the timeout period started. + @param[in] End Calculated time when timeout period will be done. + + @retval EFI_TIMEOUT Timeout occured. + @retval EFI_SUCCESS Not yet timed out +**/ +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End + ) +{ + UINT32 Current; + + /// + /// Read HPET and assign the value as the current time. + /// + Current = mHeciContext->HpetTimer[HPET_MAIN_COUNTER_LOW]; + + /// + /// Test basic case (no overflow) + /// + if ((Start < End) && (End <= Current)) { + return EFI_TIMEOUT; + } + /// + /// Test basic start/end conditions with overflowed timer + /// + if ((Start < End) && (Current < Start)) { + return EFI_TIMEOUT; + } + /// + /// Test for overflowed start/end condition + /// + if ((Start > End) && ((Current < Start) && (Current > End))) { + return EFI_TIMEOUT; + } + /// + /// Catch corner case of broken arguments + /// + if (Start == End) { + return EFI_TIMEOUT; + } + /// + /// Else, we have not yet timed out + /// + return EFI_SUCCESS; +} + +/** + Delay for at least the request number of microseconds + + @param[in] delayTime Number of microseconds to delay. + + @retval None +**/ +VOID +IoDelay ( + IN UINT32 delayTime + ) +{ + gBS->Stall (delayTime); +} diff --git a/ReferenceCode/ME/Heci/Dxe/HeciHpet.h b/ReferenceCode/ME/Heci/Dxe/HeciHpet.h new file mode 100644 index 0000000..8743b3a --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/HeciHpet.h @@ -0,0 +1,115 @@ +/** @file + Definitions for HECI driver + +@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 _HECI_HPET_H +#define _HECI_HPET_H + +#include "EdkIIGlueDxe.h" +#include "MeAccess.h" +#include "HeciRegs.h" +#include "Pci22.h" + +/** + Store the value of High Performance Timer + + @param[in] None + + @retval None +**/ +VOID +SaveHpet ( + VOID + ) +; + +/** + Restore the value of High Performance Timer + + @param[in] None + + @retval None +**/ + +VOID +RestoreHpet ( + VOID + ) +; + +/** + Used for calculating timeouts + + @param[out] Start Snapshot of the HPET timer + @param[out] End Calculated time when timeout period will be done + @param[in] Time Timeout period in microseconds + + @retval None +**/ +VOID +StartTimer ( + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +; + +/** + Used to determine if a timeout has occured. + + @param[in] Start Snapshot of the HPET timer when the timeout period started. + @param[in] End Calculated time when timeout period will be done. + + @retval EFI_TIMEOUT Timeout occured. + @retval EFI_SUCCESS Not yet timed out +**/ +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End + ) +; + +/** + Enable Hpet function. + + @param[in] None. + + @retval None +**/ +VOID +EnableHpet ( + VOID + ) +; + +/** + Delay for at least the request number of microseconds + + @param[in] delayTime Number of microseconds to delay. + + @retval None +**/ +VOID +IoDelay ( + IN UINT32 delayTime + ) +; + +#endif // _HECI_HPET_H diff --git a/ReferenceCode/ME/Heci/Dxe/Hecicore.c b/ReferenceCode/ME/Heci/Dxe/Hecicore.c new file mode 100644 index 0000000..176fbed --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecicore.c @@ -0,0 +1,1461 @@ +/** @file + Heci driver core. For Dxe Phase, determines the HECI device and initializes it. + +@copyright + Copyright (c) 2007 - 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 + +**/ +#include "HeciDrv.h" +#include "HeciHpet.h" +#include "HeciCore.h" +#include "HeciRegs.h" +#include "MeState.h" + +// +// Globals used in Heci driver +// +UINT16 HECICtlrBDF; +static UINT64 HeciMBAR = 0; + +// +// Extern for shared HECI data and protocols +// +extern HECI_INSTANCE *mHeciContext; + +/** + The routing of MmIo Read Dword + + @param[in] a The address of Mmio + + @retval Return the valut of MmIo Read +**/ +UINT32 +MmIoReadDword ( + IN UINT64 a + ) +{ + volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + + HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a; + return HeciRegHCsrPtr->ul; +} + +/** + The routing of MmIo Write Dword + + @param[in] a The address of Mmio + @param[in] b Value revised + + @retval None +**/ +VOID +MmIoWriteDword ( + IN UINT64 a, + IN UINT32 b + ) +{ + volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + + HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a; + + HeciRegHCsrPtr->ul = b; +} + +// +// Macro definition for function used in Heci driver +// +#define MMIOREADDWORD(a) MmIoReadDword (a) +#define MMIOWRITEDWORD(a, b) MmIoWriteDword (a, b) + +#ifdef EFI_DEBUG + +/** + For serial debugger used, it will show the buffer message line by line to serial console. + + @param[in] Message the address point of buffer message + @param[in] Length message length + + @retval None +**/ +VOID +ShowBuffer ( + IN UINT8 *Message, + IN UINT32 Length + ) +{ + UINT32 Index; + UINT32 Offset; + CHAR16 Buffer[51]; // To construct a line needs 51 chars. + + Index = 0; + Offset = 0; + ZeroMem (Buffer, sizeof (Buffer)); + + while (Length-- > 0) { + // + // Get the corresponding offset value from the index of buffer message. + // + Offset = ((Index & 0x0F) > 7) ? (((Index & 0x0F) * 3) + 2) : ((Index & 0x0F) * 3); + + // + // Print "- " at the half of a line increases the readability of debug message. + // + if ((Index & 0x0F) == 0x08) { + UnicodeSPrint (&Buffer[24], 3 * sizeof (CHAR16), L"- "); + } + + // + // Collect the data of buffer message. + // + UnicodeSPrint (&Buffer[Offset], 4 * sizeof (CHAR16), L"%02x ", Message[Index]); + + // + // A line contains 16 bytes of buffer message. If a line is complete, it will be shown through DEBUG macro. + // + if (Offset == 47) { + DEBUG ((EFI_D_ERROR, "%02x: %s\n", (Index & 0xF0), Buffer)); + } + + Index++; + } + + // + // If a line isn't complete, show the remaining data. + // + if (Offset != 47) { + DEBUG ((EFI_D_ERROR, "%02x: %s\n", (Index & 0xF0), Buffer)); + } + return ; +} + +#endif // End Of EFI_DEBUG + +// +// Heci driver function definitions +// + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] None. + + @retval EFI_SUCCESS HECI device is present and initialized. + @retval EFI_DEVICE_ERROR No HECI controller. + @exception EFI_UNSUPPORTED HECI MSG is unsupported because ME MODE is in ME ALT Disabled & + SECOVR JMPR + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +InitializeHeciPrivate ( + VOID + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + EFI_STATUS Status; + HECI_FWS_REGISTER MeFirmwareStatus; + + Status = EFI_SUCCESS; + + SaveHpet (); + do { + /// + /// Store HECI vendor and device information away + /// + mHeciContext->DeviceInfo = HeciPciRead16 (PCI_DEVICE_ID_OFFSET); + + /// + /// Check for HECI-1 PCI device availability + /// + if (mHeciContext->DeviceInfo == 0xFFFF) { + Status = EFI_DEVICE_ERROR; + break; + } + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + /// + /// Check for ME FPT Bad + /// + if (MeFirmwareStatus.r.FptBad) { + Status = EFI_DEVICE_ERROR; + break; + } + /// + /// Check for ME error status + /// + if (MeFirmwareStatus.r.ErrorCode) { + Status = EFI_NOT_READY; + if (MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_UNKNOWN || MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_IMAGE_FAILURE) { + /// + /// ME failed to start so no HECI + /// + Status = EFI_DEVICE_ERROR; + break; + } + } + /// + /// HECI MSG is unsupported if ME MODE is in ME ALT Disabled & SECOVR JMPR + /// + if ((MeFirmwareStatus.r.MeOperationMode == ME_OPERATION_MODE_SECOVR_JMPR) || + (MeFirmwareStatus.r.MeOperationMode == ME_OPERATION_MODE_DEBUG) + ) { + Status = EFI_UNSUPPORTED; + break; + } + /// + /// Store HECI revision ID + /// + mHeciContext->RevisionInfo = HeciPciRead8 (PCI_REVISION_ID_OFFSET); + + /// + /// Check if Base register is 64 bits wide. + /// + if (HeciPciRead32 (R_HECIMBAR) & 0x4) { + mHeciContext->HeciMBAR = (((UINT64) HeciPciRead32 (R_HECIMBAR + 4) << 32) | + (UINT64) HeciPciRead32 (R_HECIMBAR)) & 0xFFFFFFF0; + } else { + mHeciContext->HeciMBAR = (UINT64) HeciPciRead32 (R_HECIMBAR) & 0xFFFFFFF0; + } + /// + /// Get HECI_MBAR and see if it is programmed + /// to a useable value + /// + HeciMBAR = mHeciContext->HeciMBAR; + + /// + /// Load temporary address for HECI_MBAR if one is not assigned + /// + if (mHeciContext->HeciMBAR == 0) { + DEBUG ((EFI_D_ERROR, "Heci MMIO Bar not programmed in DXE phase\n")); + } + /// + /// Enable HECI BME and MSE + /// + HeciPciOr8 ( + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + + /// + /// Set HECI interrupt delivery mode. + /// HECI-1 using legacy/MSI interrupt + /// + HeciPciAnd8 (R_HIDM, 0xFC); + + /// + /// Need to do following on ME init: + /// + /// 1) wait for ME_CSR_HA reg ME_RDY bit set + /// + if (WaitForMEReady () != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + break; + } + /// + /// 2) setup H_CSR reg as follows: + /// a) Make sure H_RST is clear + /// b) Set H_RDY + /// c) Set H_IG + /// + HeciRegHCsrPtr = (VOID *) (UINTN) (mHeciContext->HeciMBAR + H_CSR); + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + if (HeciRegHCsrPtr->r.H_RDY == 0) { + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsrPtr->ul = HeciRegHCsr.ul; + } + } while (Status != EFI_SUCCESS && Status != EFI_NOT_READY); + + RestoreHpet (); + + return Status; +} + +/** + Waits for the ME to report that it is ready for communication over the HECI + interface. + + @param[in] None. + + @retval EFI_SUCCESS ME is ready + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +WaitForMEReady ( + VOID + ) +{ + UINT32 TimerStart; + UINT32 TimerEnd; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + /// + /// Wait for ME ready + /// + /// + /// Check for ME ready status + /// + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Perform IO delay + /// + IoDelay (HECI_WAIT_DELAY); + + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + /// + /// ME ready!!! + /// + return EFI_SUCCESS; +} + +/** + Checks if HECI reset has occured. + + @param[in] None. + + @retval TRUE HECI reset occurred + @retval FALSE No HECI reset occurred +**/ +BOOLEAN +CheckForHeciReset ( + VOID + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + /// + /// Init Host & ME CSR + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + + if ((HeciRegMeCsrHa.r.ME_RDY_HRA == 0) || (HeciRegHCsr.r.H_RDY == 0)) { + return TRUE; + } + + return FALSE; +} + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] None. + + @retval EFI_SUCCESS HECI device is present and initialized + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +EFIAPI +HeciInitialize ( + VOID + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + HeciMBAR = CheckAndFixHeciForAccess (); + + /// + /// Need to do following on ME init: + /// + /// 1) wait for ME_CSR_HA reg ME_RDY bit set + /// + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// 2) setup H_CSR reg as follows: + /// a) Make sure H_RST is clear + /// b) Set H_RDY + /// c) Set H_IG + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + if (HeciRegHCsr.r.H_RDY == 0) { + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + } + + return EFI_SUCCESS; +} + +/** + Heci Re-initializes it for Host + + @param[in] None. + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_STATUS Status code returned by ResetHeciInterface +**/ +EFI_STATUS +EFIAPI +HeciReInitialize ( + VOID + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + /// + /// Need to do following on ME init: + /// + /// 1) wait for HOST_CSR_HA reg H_RDY bit set + /// + /// if (WaitForHostReady() != EFI_SUCCESS) { + /// + if (MeResetWait (HECI_INIT_TIMEOUT) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + if (HeciRegHCsr.r.H_RDY == 0) { + Status = ResetHeciInterface (); + + } + + return Status; +} + +/** + Heci Re-initializes it for Me + + @param[in] None. + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Re-initialization done +**/ +EFI_STATUS +EFIAPI +HeciReInitialize2 ( + VOID + ) +{ + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + EFI_STATUS Status; + UINT32 TimerStart; + UINT32 TimerEnd; + + Status = EFI_SUCCESS; + /// + /// Need to do following on ME init: + /// + /// 1) wait for HOST_CSR_HA reg H_RDY bit set + /// + /// if (WaitForHostReady() != EFI_SUCCESS) { + /// + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (HeciRegMeCsrHa.r.ME_RDY_HRA == 1) { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + IoDelay (HECI_WAIT_DELAY); + + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + return Status; +} + +/** + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[out] MessageHeader Pointer to a buffer for the message header. + @param[in] MessageData Pointer to a buffer to recieve the message in. + @param[in][out] Length On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR The circular buffer is overflowed. + @retval EFI_NO_RESPONSE The circular buffer is empty + @retval EFI_TIMEOUT Failed to receive a full message + @retval EFI_BUFFER_TOO_SMALL Message packet is larger than caller's buffer +**/ +EFI_STATUS +HECIPacketRead ( + IN UINT32 Blocking, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +{ + BOOLEAN GotMessage; + UINT32 TimerStart; + UINT32 TimerEnd; + UINT32 TimerStart1; + UINT32 TimerEnd1; + UINT32 i; + UINT32 LengthInDwords; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + + GotMessage = FALSE; + /// + /// Initialize memory mapped register pointers + /// + /// VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr = (VOID*)(mHeciContext->HeciMBAR + H_CSR); + /// VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr = (VOID*)(mHeciContext->HeciMBAR + ME_CSR_HA); + /// VOLATILE UINT32 *HeciRegMeCbrwPtr = (VOID*)(mHeciContext->HeciMBAR + ME_CB_RW); + /// + /// clear Interrupt Status bit + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IS = 1; + + /// + /// test for circular buffer overflow + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (OverflowCB ( + HeciRegMeCsrHa.r.ME_CBRP_HRA, + HeciRegMeCsrHa.r.ME_CBWP_HRA, + HeciRegMeCsrHa.r.ME_CBD_HRA + ) != EFI_SUCCESS) { + /// + /// if we get here, the circular buffer is overflowed + /// + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// If NON_BLOCKING, exit if the circular buffer is empty + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA);; + if ((FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) == 0) && (Blocking == NON_BLOCKING)) { + *Length = 0; + return EFI_NO_RESPONSE; + } + /// + /// Start timeout counter + /// + StartTimer (&TimerStart, &TimerEnd, HECI_READ_TIMEOUT); + + /// + /// loop until we get a message packet + /// + while (!GotMessage) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message. + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + /// + /// Read one message from HECI buffer and advance read pointer. Make sure + /// that we do not pass the write pointer. + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA);; + if (FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) > 0) { + /// + /// Eat the HECI Message header + /// + MessageHeader->Data = MMIOREADDWORD (HeciMBAR + ME_CB_RW); + + /// + /// Compute required message length in DWORDS + /// + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + /// + /// Just return success if Length is 0 + /// + if (MessageHeader->Fields.Length == 0) { + /// + /// Set Interrupt Generate bit and return + /// + MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + *Length = 0; + return EFI_SUCCESS; + } + /// + /// Make sure that the message does not overflow the circular buffer. + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if ((MessageHeader->Fields.Length + sizeof (HECI_MESSAGE_HEADER)) > (HeciRegMeCsrHa.r.ME_CBD_HRA * 4)) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// Make sure that the callers buffer can hold the correct number of DWORDS + /// + if ((MessageHeader->Fields.Length) <= *Length) { + /// + /// Start timeout counter for inner loop + /// + StartTimer (&TimerStart1, &TimerEnd1, HECI_READ_TIMEOUT); + + /// + /// Wait here until entire message is present in circular buffer + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (LengthInDwords > FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA)) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message + /// + if (Timeout (TimerStart1, TimerEnd1) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + /// + /// Wait before we read the register again + /// + IoDelay (HECI_WAIT_DELAY); + + /// + /// Read the register again + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + /// + /// copy rest of message + /// + for (i = 0; i < LengthInDwords; i++) { + MessageData[i] = MMIOREADDWORD (HeciMBAR + ME_CB_RW); + } + /// + /// Update status and length + /// + GotMessage = TRUE; + *Length = MessageHeader->Fields.Length; + + } else { + /// + /// Message packet is larger than caller's buffer + /// + *Length = 0; + return EFI_BUFFER_TOO_SMALL; + } + } + /// + /// Wait before we try to get a message again + /// + IoDelay (HECI_WAIT_DELAY); + } + /// + /// Read ME_CSR_HA. If the ME_RDY bit is 0, then an ME reset occurred during the + /// transaction and the message should be discarded as bad data may have been retrieved + /// from the host's circular buffer + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// Set Interrupt Generate bit + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + return EFI_SUCCESS; +} + +/** + Reads a message from the ME across HECI. + + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in][out] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR Failed to initialize HECI or zero-length message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +EFI_STATUS +EFIAPI +HeciReceive ( + IN UINT32 Blocking, + IN OUT UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +{ + HECI_MESSAGE_HEADER PacketHeader; + UINT32 CurrentLength; + UINT32 MessageComplete; + EFI_STATUS ReadError; + EFI_STATUS Status; + UINT32 PacketBuffer; + UINT32 timer_start; + UINT32 timer_end; + BOOLEAN QuitFlag; + + CurrentLength = 0; + MessageComplete = 0; + Status = EFI_SUCCESS; + QuitFlag = FALSE; + + SaveHpet (); + + do { + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + HeciMBAR = CheckAndFixHeciForAccess (); + + /// + /// Make sure we do not have a HECI reset + /// + if (CheckForHeciReset ()) { + /// + /// if HECI reset than try to re-init HECI + /// + Status = HeciInitialize (); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + break; + } + } + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady () != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + break; + } + /// + /// Set up timer for BIOS timeout. + /// + StartTimer (&timer_start, &timer_end, HECI_READ_TIMEOUT); + while ((CurrentLength < *Length) && (MessageComplete == 0)) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message + /// + if (Timeout (timer_start, timer_end) != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + QuitFlag = TRUE; + break; + } + + PacketBuffer = *Length - CurrentLength; + ReadError = HECIPacketRead ( + Blocking, + &PacketHeader, + (UINT32 *) &MessageBody[CurrentLength / 4], + &PacketBuffer + ); + + /// + /// Check for error condition on read + /// + if (EFI_ERROR (ReadError)) { + *Length = 0; + Status = ReadError; + QuitFlag = TRUE; + break; + } + /// + /// Get completion status from the packet header + /// + MessageComplete = PacketHeader.Fields.MessageComplete; + + /// + /// Check for zero length messages + /// + if (PacketBuffer == 0) { + /// + /// If we are not in the middle of a message, and we see Message Complete, + /// this is a valid zero-length message. + /// + if ((CurrentLength == 0) && (MessageComplete == 1)) { + *Length = 0; + Status = EFI_SUCCESS; + QuitFlag = TRUE; + break; + } else { + /// + /// We should not expect a zero-length message packet except as described above. + /// + *Length = 0; + Status = EFI_DEVICE_ERROR; + QuitFlag = TRUE; + break; + } + } + /// + /// Track the length of what we have read so far + /// + CurrentLength += PacketBuffer; + + } + + if (QuitFlag == TRUE) { + break; + } + /// + /// If we get here the message should be complete, if it is not + /// the caller's buffer was not large enough. + /// + if (MessageComplete == 0) { + *Length = 0; + Status = EFI_BUFFER_TOO_SMALL; + break; + } + + *Length = CurrentLength; + + DEBUG ((EFI_D_ERROR, "HECI ReadMsg:\n")); +#ifdef EFI_DEBUG + DEBUG_CODE ( + ShowBuffer ((UINT8 *) MessageBody, *Length); + ); +#endif + } while (EFI_ERROR (Status)); + + RestoreHpet (); + + return Status; +} + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +EFIAPI +HeciSend ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +{ + UINT32 CBLength; + UINT32 SendLength; + UINT32 CurrentLength; + HECI_MESSAGE_HEADER MessageHeader; + EFI_STATUS WriteStatus; + EFI_STATUS Status; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + UINT32 MeMode; + + CurrentLength = 0; + Status = EFI_SUCCESS; + + SaveHpet (); + + HeciGetMeMode (&MeMode); + do { + if (MeMode == ME_MODE_SECOVER) { + Status = EFI_UNSUPPORTED; + break; + } + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + HeciMBAR = CheckAndFixHeciForAccess (); + + /// + /// Make sure we do not have a HECI reset + /// + if (CheckForHeciReset ()) { + /// + /// if HECI reset than try to re-init HECI + /// + Status = HeciInitialize (); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + break; + } + } + + DEBUG ((EFI_D_ERROR, "HECI SendMsg:\n")); +#ifdef EFI_DEBUG + DEBUG_CODE ( + ShowBuffer ((UINT8 *) Message, Length); + ); +#endif + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady () != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + break; + } + /// + /// Set up memory mapped registers + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + + /// + /// Grab Circular Buffer length + /// + CBLength = HeciRegHCsr.r.H_CBD; + + /// + /// Prepare message header + /// + MessageHeader.Data = 0; + MessageHeader.Fields.MeAddress = MeAddress; + MessageHeader.Fields.HostAddress = HostAddress; + + /// + /// Break message up into CB-sized packets and loop until completely sent + /// + while (Length > CurrentLength) { + /// + /// Set the Message Complete bit if this is our last packet in the message. + /// Needs to be 'less than' to account for the header OR Needs to be exactly equal to CB depth. + /// + if (((((Length - CurrentLength) + 3) / 4) < CBLength) || + ((((((Length - CurrentLength) + 3) / 4) == CBLength) && ((((Length - CurrentLength) + 3) % 4) == 0))) + ) { + MessageHeader.Fields.MessageComplete = 1; + } + /// + /// Calculate length for Message Header + /// header length == smaller of circular buffer or remaining message (both account for the size of the header) + /// + SendLength = ((CBLength <= (((Length - CurrentLength) + 3) / 4)) ? ((CBLength - 1) * 4) : (Length - CurrentLength)); + MessageHeader.Fields.Length = SendLength; + + DEBUG ((EFI_D_ERROR, "HECI Header: %08x\n", MessageHeader.Data)); + + /// + /// send the current packet (CurrentLength can be treated as the index into the message buffer) + /// + WriteStatus = HeciPacketWrite (&MessageHeader, (UINT32 *) ((UINTN) Message + CurrentLength)); + if (EFI_ERROR (WriteStatus)) { + Status = WriteStatus; + break; + } + /// + /// Update the length information + /// + CurrentLength += SendLength; + } + + if (EFI_ERROR (Status)) { + break; + } + } while (EFI_ERROR (Status)); + + RestoreHpet (); + + return Status; + +} + +/** + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + @param[in] MessageHeader Pointer to the message header. + @param[in] MessageData Pointer to the actual message data. + + @retval EFI_SUCCESS One message packet sent + @retval EFI_DEVICE_ERROR ME is not ready + @retval EFI_TIMEOUT HECI is not ready for communication +**/ +EFI_STATUS +HeciPacketWrite ( + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +{ + UINT32 timer_start; + UINT32 timer_end; + UINT32 i; + UINT32 LengthInDwords; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Start timeout counter + /// + StartTimer (&timer_start, &timer_end, HECI_SEND_TIMEOUT); + + /// + /// Compute message length in DWORDS + /// + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + /// + /// Wait until there is sufficient room in the circular buffer + /// Must have room for message and message header + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + while ((LengthInDwords + 1) > (HeciRegHCsr.r.H_CBD - FilledSlots (HeciRegHCsr.r.H_CBRP, HeciRegHCsr.r.H_CBWP))) { + /// + /// If 1 second timeout has expired, return fail as the circular buffer never emptied + /// + if (Timeout (timer_start, timer_end) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Wait before we read the register again + /// + IoDelay (HECI_WAIT_DELAY); + + /// + /// Read Host CSR for next iteration + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } + /// + /// Write Message Header + /// + MMIOWRITEDWORD (HeciMBAR + H_CB_WW, MessageHeader->Data); + + /// + /// Write Message Body + /// + for (i = 0; i < LengthInDwords; i++) { + MMIOWRITEDWORD (HeciMBAR + H_CB_WW, MessageData[i]); + } + /// + /// Set Interrupt Generate bit + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + /// + /// Test if ME Ready bit is set to 1, if set to 0 a fatal error occured during + /// the transmission of this message. + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in][out] Message Pointer to the message buffer. + @param[in] Length Length of the message in bytes. + @param[in][out] RecLength Length of the message response in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @retval EFI_TIMEOUT HECI does not return the bufferbefore timeout + @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +EFIAPI +HeciSendwACK ( + IN OUT UINT32 *Message, + IN UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +{ + EFI_STATUS Status; + UINT16 RetryCount; + UINT32 TempRecLength; + UINT32 MeMode; + + HeciGetMeMode (&MeMode); + if (MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + /// + /// Send the message + /// + Status = HeciSend (Message, Length, HostAddress, MeAddress); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Wait for ACK message + /// + TempRecLength = *RecLength; + for (RetryCount = 0; RetryCount < HECI_MAX_RETRY; RetryCount++) { + /// + /// Read Message + /// + Status = HeciReceive (BLOCKING, Message, &TempRecLength); + if (!EFI_ERROR (Status)) { + break; + } + /// + /// Reload receive length as it has been modified by the read function + /// + TempRecLength = *RecLength; + } + /// + /// Return read length and status + /// + *RecLength = TempRecLength; + return Status; +} + +/** + Me reset and waiting for ready + + @param[in] Delay The biggest waiting time + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Me is ready +**/ +EFI_STATUS +EFIAPI +MeResetWait ( + IN UINT32 Delay + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + UINT32 TimerStart; + UINT32 TimerEnd; + + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + HeciMBAR = CheckAndFixHeciForAccess (); + + /// + /// Wait for the HOST Ready bit to be cleared to signal a reset + /// + StartTimer (&TimerStart, &TimerEnd, Delay); + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + while (HeciRegHCsr.r.H_RDY == 1) { + /// + /// If timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } + + return EFI_SUCCESS; +} + +/** + Function forces a reinit of the heci interface by following the reset heci interface via host algorithm + in HPS 0.90 doc 4-17-06 njy + + @param[in] none + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Interface reset +**/ +EFI_STATUS +EFIAPI +ResetHeciInterface ( + VOID + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + UINT32 TimerStart; + UINT32 TimerEnd; + + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + HeciMBAR = CheckAndFixHeciForAccess (); + + /// + /// Enable Reset + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_RST = 1; + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + /// + /// Make sure that the reset started + /// + /// HeciRegHCsr.ul = MMIOREADDWORD(HeciMBAR + H_CSR); + /// + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Read the ME CSR + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } while (HeciRegHCsr.r.H_RDY == 1); + + /// + /// Wait for ME to perform reset + /// + /// HeciRegMeCsrHa.ul = MMIOREADDWORD(HeciMBAR + ME_CSR_HA); + /// + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Read the ME CSR + /// + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } while (HeciRegMeCsrHa.r.ME_RDY_HRA == 0); + + /// + /// Make sure IS has been signaled on the HOST side + /// + /// HeciRegHCsr.ul = MMIOREADDWORD(HeciMBAR + H_CSR); + /// + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Read the ME CSR + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } while (HeciRegHCsr.r.H_IS == 0); + + /// + /// Enable host side interface + /// + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);; + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsr.r.H_RDY = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + return EFI_SUCCESS; +} + +/** + 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 Number of filled slots. +**/ +UINT8 +FilledSlots ( + 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; +} + +/** + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + @param[in] ReadPointer Value read from host/me read pointer + @param[in] WritePointer Value read from host/me write pointer + @param[in] BufferDepth Value read from buffer depth register + + @retval EFI_DEVICE_ERROR The circular buffer has overflowed + @retval EFI_SUCCESS The circular buffer does not overflowed +**/ +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +{ + UINT8 FilledSlots; + + /// + /// Calculation documented in HECI HPS 0.68 section 4.2.1 + /// + FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer)); + + /// + /// test for overflow + /// + if (FilledSlots > ((UINT8) BufferDepth)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Get an abstract Intel ME State from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions + + @param[out] MeStatus Pointer for status report + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + OUT UINT32 *MeStatus + ) +{ + HECI_FWS_REGISTER MeFirmwareStatus; + + if (MeStatus == NULL) { + return EFI_INVALID_PARAMETER; + } + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + if (MeFirmwareStatus.r.CurrentState == ME_STATE_NORMAL && MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_NO_ERROR) { + *MeStatus = ME_READY; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_RECOVERY) { + *MeStatus = ME_IN_RECOVERY_MODE; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_INIT) { + *MeStatus = ME_INITIALIZING; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_DISABLE_WAIT) { + *MeStatus = ME_DISABLE_WAIT; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_TRANSITION) { + *MeStatus = ME_TRANSITION; + } else { + *MeStatus = ME_NOT_READY; + } + + if (MeFirmwareStatus.r.FwUpdateInprogress) { + *MeStatus |= ME_FW_UPDATES_IN_PROGRESS; + } + + if (MeFirmwareStatus.r.FwInitComplete == ME_FIRMWARE_COMPLETED) { + *MeStatus |= ME_FW_INIT_COMPLETE; + } + + if (MeFirmwareStatus.r.MeBootOptionsPresent == ME_BOOT_OPTIONS_PRESENT) { + *MeStatus |= ME_FW_BOOT_OPTIONS_PRESENT; + } + + DEBUG ((EFI_D_ERROR, "HECI MeStatus %X\n", MeFirmwareStatus.ul)); + + return EFI_SUCCESS; +} + +/** + Return ME Mode + + @param[out] MeMode Pointer for ME Mode report + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeMode ( + OUT UINT32 *MeMode + ) +{ + HECI_FWS_REGISTER MeFirmwareStatus; + + if (MeMode == NULL) { + return EFI_INVALID_PARAMETER; + } + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + switch (MeFirmwareStatus.r.MeOperationMode) { + case ME_OPERATION_MODE_NORMAL: + *MeMode = ME_MODE_NORMAL; + break; + + case ME_OPERATION_MODE_DEBUG: + *MeMode = ME_MODE_DEBUG; + break; + + case ME_OPERATION_MODE_SOFT_TEMP_DISABLE: + *MeMode = ME_MODE_TEMP_DISABLED; + break; + + case ME_OPERATION_MODE_SECOVR_JMPR: + case ME_OPERATION_MODE_SECOVR_HECI_MSG: + *MeMode = ME_MODE_SECOVER; + break; + + default: + *MeMode = ME_MODE_FAILED; + } + DEBUG ((EFI_D_ERROR, "HECI MeMode %X\n", MeFirmwareStatus.r.MeOperationMode)); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/Heci/Dxe/Hecicore.h b/ReferenceCode/ME/Heci/Dxe/Hecicore.h new file mode 100644 index 0000000..4e60526 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecicore.h @@ -0,0 +1,342 @@ +/** @file + Definitions for HECI driver + +@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 _HECI_CORE_H +#define _HECI_CORE_H + +#include "CoreBiosMsg.h" + +// +// HECI bus function version +// +#define HBM_MINOR_VERSION 0 +#define HBM_MAJOR_VERSION 1 + +// +// Prototypes +// + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] None. + + @retval EFI_SUCCESS HECI device is present and initialized. + @retval EFI_DEVICE_ERROR No HECI controller. + @exception EFI_UNSUPPORTED HECI MSG is unsupported because ME MODE is in ME ALT Disabled & + SECOVR JMPR + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +InitializeHeciPrivate ( + VOID + ) +; +/** + Waits for the ME to report that it is ready for communication over the HECI + interface. + + @param[in] None. + + @retval EFI_SUCCESS ME is ready + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +WaitForMEReady ( + VOID + ) +; + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] None. + + @retval EFI_SUCCESS HECI device is present and initialized + @retval EFI_TIMEOUT ME is not ready +**/ +EFI_STATUS +EFIAPI +HeciInitialize ( + VOID + ) +; + +/** + Heci Re-initializes it for Host + + @param[in] None. + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_STATUS Status code returned by ResetHeciInterface +**/ +EFI_STATUS +EFIAPI +HeciReInitialize ( + VOID + ) +; + +/** + Heci Re-initializes it for Me + + @param[in] None. + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Re-initialization done +**/ +EFI_STATUS +EFIAPI +HeciReInitialize2 ( + VOID + ) +; + +/** + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[out] MessageHeader Pointer to a buffer for the message header. + @param[in] MessageData Pointer to a buffer to recieve the message in. + @param[in][out] Length On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR The circular buffer is overflowed. + @retval EFI_NO_RESPONSE The circular buffer is empty + @retval EFI_TIMEOUT Failed to receive a full message + @retval EFI_BUFFER_TOO_SMALL Message packet is larger than caller's buffer +**/ +EFI_STATUS +HECIPacketRead ( + IN UINT32 Blocking, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +; + +/** + Reads a message from the ME across HECI. + + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in][out] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR Failed to initialize HECI or zero-length message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +EFI_STATUS +EFIAPI +HeciReceive ( + IN UINT32 Blocking, + IN OUT UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +; + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +EFIAPI +HeciSend ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +; +/** + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + @param[in] MessageHeader Pointer to the message header. + @param[in] MessageData Pointer to the actual message data. + + @retval EFI_SUCCESS One message packet sent + @retval EFI_DEVICE_ERROR ME is not ready + @retval EFI_TIMEOUT HECI is not ready for communication +**/ +EFI_STATUS +HeciPacketWrite ( + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +; + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in][out] Message Pointer to the message buffer. + @param[in] Length Length of the message in bytes. + @param[in][out] RecLength Length of the message response in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @retval EFI_TIMEOUT HECI does not return the bufferbefore timeout + @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +EFIAPI +HeciSendwACK ( + IN OUT UINT32 *Message, + IN UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +; + +/** + Me reset and waiting for ready + + @param[in] Delay The biggest waiting time + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Me is ready +**/ +EFI_STATUS +EFIAPI +MeResetWait ( + IN UINT32 Delay + ) +; + +/** + Function forces a reinit of the heci interface by following the reset heci interface via host algorithm + in HPS 0.90 doc 4-17-06 njy + + @param[in] none + + @retval EFI_TIMEOUT ME is not ready + @retval EFI_SUCCESS Interface reset +**/ +EFI_STATUS +EFIAPI +ResetHeciInterface ( + VOID + ) +; + +/** + 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 Number of filled slots. +**/ +UINT8 +FilledSlots ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer + ) +; + +/** + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + @param[in] ReadPointer Value read from host/me read pointer + @param[in] WritePointer Value read from host/me write pointer + @param[in] BufferDepth Value read from buffer depth register + + @retval EFI_DEVICE_ERROR The circular buffer has overflowed + @retval EFI_SUCCESS The circular buffer does not overflowed +**/ +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +; + +/** + Get an abstract Intel ME State from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions + + @param[out] MeStatus Pointer for status report + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + OUT UINT32 *MeStatus + ) +; + +/** + Return ME Mode + + @param[out] MeMode Pointer for ME Mode report + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeMode ( + OUT UINT32 *MeMode + ) +; + +/** + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + + @param[in] None. + + @retval UINT64 HeciMar address +**/ +UINT64 +CheckAndFixHeciForAccess ( + VOID + ) +; +#endif // _HECI_CORE_H diff --git a/ReferenceCode/ME/Heci/Dxe/Hecidrv.c b/ReferenceCode/ME/Heci/Dxe/Hecidrv.c new file mode 100644 index 0000000..b34ea6f --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecidrv.c @@ -0,0 +1,1540 @@ +/** @file + HECI driver + +@copyright + Copyright (c) 2007 - 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 "HeciDrv.h" +#include "HeciHpet.h" +#include "HeciCore.h" +#include "MeLib.h" +#include "EfiScriptLib.h" +#include "PchPlatformLib.h" + +#include EFI_GUID_DEFINITION (MePlatformReadyToBoot) +#include EFI_GUID_DEFINITION (MeBiosExtensionSetup) +#include EFI_PROTOCOL_DEFINITION (MeplatformPolicy) +#include EFI_PROTOCOL_DEFINITION (AmtReadyToBoot) +#include EFI_PROTOCOL_CONSUMER (ExitPmAuth) + +extern DXE_ME_POLICY_PROTOCOL *mDxePlatformMePolicy; + +#ifdef TCG_SUPPORT_FLAG +#include "Acpi1_0.h" +#include "Acpi2_0.h" +#include "Acpi3_0.h" +#include EFI_PROTOCOL_DEFINITION (TcgService) +#include "TpmPc.h" +#endif // TCG_SUPPORT_FLAG +#endif // EDK_RELEASE_VERSION +#define ONE_SECOND_TIMEOUT 1000000 +#define FWU_TIMEOUT 90 + +// +// Global driver data +// +HECI_INSTANCE *mHeciContext; +EFI_HANDLE mHeciDrv; +EFI_EVENT mExitBootServicesEvent; +EFI_EVENT mLegacyBootEvent; +DXE_MBP_DATA_PROTOCOL mMbpData; + +/** + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + + @param[in] None. + + @retval UINT64 HeciMar address +**/ +UINT64 +CheckAndFixHeciForAccess ( + VOID + ) +{ + /// + /// Read HECI_MBAR in case it has changed + /// + /// + /// Check if Base register is 64 bits wide. + /// + if (HeciPciRead32 (R_HECIMBAR) & 0x4) { + mHeciContext->HeciMBAR = (((UINT64) HeciPciRead32 (R_HECIMBAR + 4) << 32) | + (UINT64) HeciPciRead32 (R_HECIMBAR)) & 0xFFFFFFF0; + } else { + mHeciContext->HeciMBAR = (UINT64) HeciPciRead32 (R_HECIMBAR) & 0xFFFFFFF0; + } + /// + /// Check if HECI_MBAR is disabled + /// + if ((HeciPciRead8 (PCI_COMMAND_OFFSET) & (EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER)) != + (EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) + ) { + /// + /// If cmd reg in pci cfg space is not turned on turn it on. + /// + HeciPciOr8 ( + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + } + + return mHeciContext->HeciMBAR; +} + +/** + Enable Hpet function. + + @param[in] None. + + @retval None +**/ +VOID +EnableHpet ( + VOID + ) +{ + VOLATILE UINT32 *HpetConfigReg; + + HpetConfigReg = NULL; + /// + /// Get the High Precision Event Timer base address and enable the memory range + /// + HpetConfigReg = (UINT32 *) (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); + switch (*HpetConfigReg & B_PCH_RCRB_HPTC_AS) { + case 0: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_0); + break; + + case 1: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_1); + break; + + case 2: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_2); + break; + + case 3: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_3); + break; + + default: + mHeciContext->HpetTimer = NULL; + break; + } + /// + /// Read this back to force the write-back. + /// + *HpetConfigReg = *HpetConfigReg | B_PCH_RCRB_HPTC_AE; + + /// + /// Start the timer so it is up and running + /// + mHeciContext->HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START; + mHeciContext->HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START; + + return ; +} + +#ifdef TCG_SUPPORT_FLAG + +/** + Perform measurement for HER register. + + @param[in] HerValue The value of HECI Extend Register. + @param[in] Index HerValue Size. + + @retval EFI_SUCCESS Measurement performed +**/ +EFI_STATUS +MeasureHer ( + IN UINT32 *HerValue, + IN UINT8 Index + ) +{ + EFI_STATUS Status; + EFI_TCG_PROTOCOL *TcgProtocol; + EFI_TCG_PCR_EVENT TcgEvent; + UINT32 EventNumber; + EFI_PHYSICAL_ADDRESS EventLogLastEntry; + + Status = gBS->LocateProtocol ( + &gEfiTcgProtocolGuid, + NULL, + (VOID **) &TcgProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// This below data will be stored in Tcg eventlog + /// + TcgEvent.Event.PostCode.PostCodeAddress = *HerValue; + TcgEvent.Event.PostCode.PostCodeLength = sizeof (UINT32); + + /// + /// Fill the TcgEvent Header + /// + TcgEvent.Header.PCRIndex = PCRi_CRTM_AND_POST_BIOS; + TcgEvent.Header.EventType = EV_S_CRTM_CONTENTS; + + TcgEvent.Header.EventDataSize = (Index * sizeof (UINT32)); + + Status = TcgProtocol->HashLogExtendEvent ( + TcgProtocol, + (EFI_PHYSICAL_ADDRESS) HerValue, + TcgEvent.Header.EventDataSize, + TPM_ALG_SHA, + (TCG_PCR_EVENT *) &TcgEvent, + &EventNumber, + &EventLogLastEntry + ); + return Status; +} + +/** + Me Measurement. + + @param[in] None. + + @retval EFI_NOT_READY Not ready for measurement. + @retval EFI_SUCCESS Measurement done +**/ +EFI_STATUS +MeMeasurement ( + VOID + ) +{ + EFI_STATUS Status; + DATA32_UNION Data32[7]; + UINT8 HerMax; + UINT8 HerIndex; + UINT8 Index; + + Index = 0; + /// + /// Measure HER + /// + HerMax = R_ME_HER5; + Data32[Index].Data32 = PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_ME_HERS)); + + if ((Data32[Index].Data32 & B_ME_EXTEND_REG_VALID) == B_ME_EXTEND_REG_VALID) { + if ((Data32[Index].Data8[0] & B_ME_EXTEND_REG_ALGORITHM) == V_ME_SHA_256) { + HerMax = R_ME_HER8; + } + + for (HerIndex = R_ME_HER1, Index = 0; HerIndex <= HerMax; HerIndex += 4, Index++) { + Data32[Index].Data32 = PciRead32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, HerIndex)); + } + + Status = MeasureHer (&Data32->Data32, Index); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ME Measurement feature failed, Status is %r \n", Status)); + } + } else { + Status = EFI_NOT_READY; + } + + return Status; +} + +/** + Signal a event for last checking. + + @param[in] Event The event that triggered this notification function + @param[in] Context Pointer to the notification functions context + + @retval EFI_SUCCESS Event excuted and closed. +**/ +EFI_STATUS +MeMeasurementEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + MeMeasurement (); + + gBS->CloseEvent (Event); + + return EFI_SUCCESS; +} +#endif + +/** + Show warning message to user. + + @param[in] None. + + @retval EFI_SUCCESS Warning reported +**/ +EFI_STATUS +MeWarningMessage ( + VOID + ) +{ + HECI_FWS_REGISTER MeFirmwareStatus; + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + /// + /// Check for ME FPT Bad & FT BUP LD FLR + /// + if (MeFirmwareStatus.r.FptBad != 0 || MeFirmwareStatus.r.FtBupLdFlr != 0) { + MeReportError (MSG_ME_FW_UPDATE_FAILED); + } + + return EFI_SUCCESS; +} + +/** + Store the current value of DEVEN for S3 resume path + + @param[in] None + + @retval None +**/ +VOID +DeviceStatusSave ( + VOID + ) +{ + UINT32 Data; + + /// + /// Read RCBA register for saving + /// + Data = Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FD2); + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_FD2), + 1, + &Data + ); + Data = Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FDSW); + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_FDSW), + 1, + &Data + ); +} + +/** + ME BWG 1.0 5.3.1.1: IDER Workaround, perform this only when IDER device is present. + + @param[in] None + + @retval None +**/ +VOID +PerformIderWorkaround ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 BaseAddress; + UINT64 BaseAddress2; + UINT64 Index; + BOOLEAN WorkaroundFlag; + + WorkaroundFlag = TRUE; + + Status = gDS->AllocateIoSpace ( + EfiGcdAllocateAnySearchBottomUp, + EfiGcdIoTypeIo, + 4, + 0x10, + &BaseAddress, + mHeciDrv, + NULL + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Program BAR4 + /// + PciWrite32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x20), (UINT32) BaseAddress); + + /// + /// Enable IDER IOE + /// + PciOr8 ( + PCI_LIB_ADDRESS (ME_BUS, + ME_DEVICE_NUMBER, + IDER_FUNCTION_NUMBER, + PCI_COMMAND_OFFSET), + EFI_PCI_COMMAND_IO_SPACE + ); + + /// + /// Perform the workaround if offset 3 bit 0 is not set + /// + if ((IoRead8 ((UINTN) BaseAddress + 3) & 0x01) == 00) { + Status = gDS->AllocateIoSpace ( + EfiGcdAllocateAnySearchBottomUp, + EfiGcdIoTypeIo, + 4, + 0x10, + &BaseAddress2, + mHeciDrv, + NULL + ); + ASSERT_EFI_ERROR (Status); + PciWrite32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x10), (UINT32) BaseAddress2); + /// + /// check all ports to make sure all are 0x7f before running the workaround + /// + for (Index = 0; Index <= 7; Index++) { + if (IoRead8 ((UINTN) BaseAddress2 + (UINTN) Index) != 0x7f) { + WorkaroundFlag = FALSE; + break; + } + } + /// + /// Disable IDER IOE and clear BAR0 and BAR4 + /// + PciAnd8 ( + PCI_LIB_ADDRESS (ME_BUS, + ME_DEVICE_NUMBER, + IDER_FUNCTION_NUMBER, + PCI_COMMAND_OFFSET), + (UINT8)~EFI_PCI_COMMAND_IO_SPACE + ); + PciWrite32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x10), 0); + PciWrite32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x20), 0); + + if (WorkaroundFlag) { + IderDisable (); + } + + gDS->FreeIoSpace (BaseAddress2, (UINT64) 0x10); + } else { + PciAnd8 ( + PCI_LIB_ADDRESS (ME_BUS, + ME_DEVICE_NUMBER, + IDER_FUNCTION_NUMBER, + PCI_COMMAND_OFFSET), + (UINT8)~EFI_PCI_COMMAND_IO_SPACE + ); + PciWrite32 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x20), 0); + } + + gDS->FreeIoSpace (BaseAddress, (UINT64) 0x10); + return ; +} + +/** + Disable ME Devices when needed + + @param[in] None + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +MeDeviceConfigure ( + VOID + ) +{ + UINT32 MeMode; + UINT16 VendorID; + UINT16 DeviceID; + + HeciGetMeMode (&MeMode); + if (MeMode == ME_MODE_NORMAL) { + if (mHeciContext->MeFwImageType != INTEL_ME_5MB_FW) { + /// + /// We will disable all AMT relevant devices in 1.5M SKU + /// + IderDisable (); + SolDisable (); + Usbr1Disable (); + Usbr2Disable (); + } else { + /// + /// ME BWG 1.0 5.3.1.1: IDER Workaround, perform this only when IDER device is present. + /// + VendorID = PciRead16 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x00)); + DeviceID = PciRead16 (PCI_LIB_ADDRESS (ME_BUS, ME_DEVICE_NUMBER, IDER_FUNCTION_NUMBER, 0x02)); + if ((VendorID == V_ME_IDER_VENDOR_ID) && IS_PCH_LPT_IDER_DEVICE_ID(DeviceID) + ) { + PerformIderWorkaround (); + } + } + } + + return EFI_SUCCESS; +} + +/** + Send ME the BIOS end of Post message. + + @param[in] None. + + @retval EFI_SUCCESS Always return EFI_SUCCESS except for policy initization failure. + @exception EFI_UNSUPPORTED Policy initization failure. +**/ +EFI_STATUS +MeEndOfPostEvent ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeStatus; + UINT8 EopSendRetries; + UINT32 HECI_BASE_ADDRESS; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr; + + // + // Init ME Policy Library, continue to send EOP message even if can't find Me Platform Policy + // + if (mDxePlatformMePolicy == NULL) { + MePolicyLibInit (); + } + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (!EFI_ERROR (Status)) { + /// + /// Send EOP message when ME is ready. Do not care about if ME FW INIT is completed. + /// + Status = Heci->GetMeStatus (&MeStatus); + ASSERT_EFI_ERROR (Status); + + if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) { + + if (MeEndOfPostEnabled ()) { + DEBUG ((EFI_D_INFO, "Sending EOP...\n")); + + // + // Initialize pointers to control registers + // + 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); + + for (EopSendRetries = 0; EopSendRetries <= MAX_EOP_SEND_RETRIES; EopSendRetries++) { + + Status = HeciSendEndOfPostMessage (mHeciDrv); + if (Status == EFI_SUCCESS) { + break; + } + + MeReportError (MSG_EOP_ERROR); + + // + // 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; + + // + // Wait for ME_RDY + // + if (WaitForMEReady () != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + break; + } + + // + // Clear H_RST, set H_RDY & H_IG bits + // + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsrPtr->ul = HeciRegHCsr.ul; + } + + if (EFI_ERROR(Status)) { + // + // Send HECI_BUS_DISABLE + // + for (EopSendRetries = 0; EopSendRetries <= MAX_EOP_SEND_RETRIES; EopSendRetries++) { + Status = HeciDisableHeciBusMsg(); + if (!EFI_ERROR(Status)) { + break; + } + } + + // + // Disable HECI function + // + HeciDisable(); + Heci2Disable(); + } + + } + } else if (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_DISABLE_WAIT) { + MeReportError (MSG_PLAT_DISABLE_WAIT); + } + + } + + return Status; +} + +/** + 1. Cf9Gr Lock Config + - PCH BIOS Spec Rev 0.9 Section 18.4 Additional Power Management Programming + Step 2 + Set "Power Management Initialization Register (PMIR) Field 1", D31:F0:ACh[31] = 1b + for production machine according to "RS - PCH Intel Management Engine + (Intel(r) ME) BIOS Writer's Guide". + 2. Function Disable SUS Well Lock + - PCH EDS 10.1.76 request that FDSW must be set when Intel Active Management Technology + is Enabled + + @param[in] None + + @retval Status. +**/ +EFI_STATUS +LockConfig ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeMode; + HECI_FWS_REGISTER MeFirmwareStatus; + UINTN Address; + UINT32 Data; + + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (!EFI_ERROR (Status)) { + /// + /// Check ME Status + /// + Status = Heci->GetMeMode (&MeMode); + ASSERT_EFI_ERROR (Status); + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + /// + /// PCH BIOS Spec Rev 0.9 Section 18.4 Additional Power Management Programming + /// Step 2 + /// Set "Power Management Initialization Register (PMIR) Field 1", D31:F0:ACh[31] = 1b + /// for production machine according to "RS - PCH Intel Management Engine + /// (Intel(r) ME) BIOS Writer's Guide". + /// + /// PCH ME BWG section 4.5.1 + /// The IntelR FPT tool /GRST option uses CF9GR bit to trigger global reset. + /// Based on above reason, the BIOS should not lock down CF9GR bit during Manufacturing and + /// Re-manufacturing environment. + /// + Data = 0; + if ((((MeMode == ME_MODE_NORMAL) || (MeMode == ME_MODE_TEMP_DISABLED)) && !(MeFirmwareStatus.r.ManufacturingMode))) { + /// + /// PCH ME BWG section 4.4.1 + /// BIOS must also ensure that CF9GR is cleared and locked (via bit31 of the same register) before + /// handing control to the OS in order to prevent the host from issuing global resets and reseting + /// Intel Management Engine. + /// + Data |= B_PCH_LPC_PMIR_CF9LOCK; + } + + Address = PCI_LIB_ADDRESS ( + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_PMIR + ); + PciAndThenOr32 ( + Address, + (UINT32) (~(B_PCH_LPC_PMIR_CF9LOCK | B_PCH_LPC_PMIR_CF9GR)), + (UINT32) Data + ); + + /// + /// Function Disable SUS Well lockdown + /// + if (MeMode == ME_MODE_NORMAL) { + if (mHeciContext->MeFwImageType == INTEL_ME_5MB_FW) { + DEBUG ((EFI_D_ERROR, "Function Disable SUS Well lockdown!\n")); + FunctionDisableWellLockdown (); + } + } + } + + return Status; +} + +/** + Halt Boot for up to 90 seconds if Bit 11 of FW Status Register (FW_UPD_IN_PROGRESS) is set + + @param[in] None + + @retval None +**/ +VOID +CheckFwUpdInProgress ( + VOID + ) +{ + HECI_FWS_REGISTER FwStatus; + UINT8 StallCount; + EFI_STATUS Status; + + StallCount = 0; + Status = mHeciContext->HeciCtlr.GetMeStatus (&FwStatus.ul); + if (!EFI_ERROR (Status)) { + if (FwStatus.ul & ME_FW_UPDATES_IN_PROGRESS) { + MeReportError (MSG_ME_FW_UPDATE_WAIT); + } + + while ((FwStatus.ul & ME_FW_UPDATES_IN_PROGRESS) && (StallCount < FWU_TIMEOUT)) { + gBS->Stall (ONE_SECOND_TIMEOUT); + StallCount = StallCount + 1; + Status = mHeciContext->HeciCtlr.GetMeStatus (&FwStatus.ul); + } + } + + return ; +} + +/** + Signal a event for Me ready to boot. + + @param[in] Event The event that triggered this notification function + @param[in] Context Pointer to the notification functions context + + @retval None +**/ +VOID +EFIAPI +MeReadyToBootEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_EVENT MePlatformReadyToBootEvent; + EFI_HANDLE *Handles; + UINTN Index; + UINTN Count; + AMT_READY_TO_BOOT_PROTOCOL *AmtReadyToBoot; + UINT32 MeMode; + UINT32 MeStatus; +#ifdef TCG_SUPPORT_FLAG + EFI_EVENT LegacyBootEvent; + EFI_EVENT ExitBootServicesEvent; + + Status = MeMeasurement (); + if (Status == EFI_NOT_READY) { + /// + /// Create a Legacy Boot event. + /// + Status = EfiCreateEventLegacyBootEx ( + EFI_TPL_CALLBACK, + MeMeasurementEvent, + NULL, + &LegacyBootEvent + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Create a ExitBootService event. + /// + Status = gBS->CreateEvent ( + EVENT_SIGNAL_EXIT_BOOT_SERVICES, + EFI_TPL_CALLBACK, + MeMeasurementEvent, + NULL, + &ExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + } + +#endif //TCG_SUPPORT_FLAG + /// + /// PCH BIOS Spec Rev 0.8.0, Section 22.8.3.1 ASPM on DMI and the PCI Express Root Ports + /// Step g + /// Issue "WRITE_ICC_REGISTER" MEI message to program ICC register offset 0x4 with 0x000999999 + /// This is always needed for PCIE with hotplug on and off and PCIE RP enabled and disabled. + /// + if(GetPchSeries() == PchLp) { + Status = HeciWriteIccRegDword(0x0004, 0x00999999, ICC_RESPONSE_MODE_SKIP); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Heci writes to TMCSRCCLK failed. Status = %X\n", Status)); + } + } + + /// + /// We will trigger all events in order + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gAmtReadyToBootProtocolGuid, + NULL, + &Count, + &Handles + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < Count; Index++) { + Status = gBS->HandleProtocol (Handles[Index], &gAmtReadyToBootProtocolGuid, (VOID **) &AmtReadyToBoot); + ASSERT_EFI_ERROR (Status); + AmtReadyToBoot->Signal (); + } + } + + Status = gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_CALLBACK, + MeEmptyEvent, + NULL, + &gMePlatformReadyToBootGuid, + &MePlatformReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + gBS->SignalEvent (MePlatformReadyToBootEvent); + gBS->CloseEvent (MePlatformReadyToBootEvent); + } + + HeciGetMeMode (&MeMode); + HeciGetMeStatus (&MeStatus); + if ((MeMode == ME_MODE_NORMAL) && + ((ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY)) + ) { + + CheckFwUpdInProgress (); + + Status = MeWarningMessage (); + ASSERT_EFI_ERROR (Status); + + Status = MeEndOfPostEvent (); + ASSERT_EFI_ERROR (Status); + } + + /// + /// Set EndOfPostDone regardless whether the EOP msg was sent + /// + if (MeEndOfPostEnabled ()) { + mDxePlatformMePolicy->MeConfig.EndOfPostDone = 1; + } + + /// + /// PMIR Configuration & FDSW Lockdown + /// + Status = LockConfig (); + ASSERT_EFI_ERROR (Status); + + /// + /// Disable Heci2 if policy dictates + /// + Heci2Disable (); + + /// + /// If ME Mode is running in ME Temp Disable state, disable Heci1, HECI2, Ider and Sol + /// + HeciGetMeMode (&MeMode); + if (MeMode == ME_MODE_TEMP_DISABLED) { + DisableAllMEDevices (); + } + + gBS->CloseEvent (Event); + + return; +} + +/** + Signal a event to save Me relevant registers and this event must be run before ExitPmAuth. + + @param[in] Event The event that triggered this notification function + @param[in] ParentImageHandle Pointer to the notification functions context + + @retval None +**/ +VOID +EFIAPI +MeScriptSaveEvent ( + IN EFI_EVENT Event, + IN VOID *ParentImageHandle + ) +{ + EFI_STATUS Status; + VOID *ProtocolPointer; + EFI_HECI_PROTOCOL *Heci; + UINT32 MeMode; + HECI_FWS_REGISTER MeFirmwareStatus; + UINTN Address; + UINT32 Data; + UINT32 MebxSetupVariableAttributes; + UINTN MebxSetupVariableDataSize; + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetup; + const UINT8 Str5MBFw[sizeof (MEFW_5M_STRING)] = MEFW_5M_STRING; + EFI_MEBX_PROTOCOL *MebxProtocol; + + INITIALIZE_SCRIPT (ParentImageHandle, gST); + + /// + /// Check whether this is real ExitPmAuth notification, or just a SignalEvent + /// + Status = gBS->LocateProtocol (&gExitPmAuthProtocolGuid, NULL, &ProtocolPointer); + if (EFI_ERROR (Status)) { + return; + } + /// + /// PMIR Configuration Save + /// + Status = gBS->LocateProtocol ( + &gEfiHeciProtocolGuid, + NULL, + (VOID **) &Heci + ); + if (EFI_ERROR (Status)) { + return; + } + /// + /// Check ME Status + /// + Status = Heci->GetMeMode (&MeMode); + ASSERT_EFI_ERROR (Status); + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + /// + /// Init ME Policy Library + /// + Status = MePolicyLibInit (); + if (EFI_ERROR (Status)) { + return; + } + +#ifdef EFI_DEBUG + // + // Dump the ME platform policy + // + DxeMePolicyDebugDump (); +#endif + + /// + /// Report ME components version information to FVI + /// + InitFviDataHubCbContext ( + mDxePlatformMePolicy->MeMiscConfig.FviSmbiosType, + (UINT8) mMeFviElements, + &mMeFviVersionData + ); + + mMeFviElementsData[EnumMeFw].Element.Version.MajorVersion = (UINT8) mMbpData.MeBiosPayload.FwVersionName.MajorVersion; + mMeFviElementsData[EnumMeFw].Element.Version.MinorVersion = (UINT8) mMbpData.MeBiosPayload.FwVersionName.MinorVersion; + mMeFviElementsData[EnumMeFw].Element.Version.Revision = (UINT8) mMbpData.MeBiosPayload.FwVersionName.HotfixVersion; + mMeFviElementsData[EnumMeFw].Element.Version.BuildNum = (UINT16) mMbpData.MeBiosPayload.FwVersionName.BuildVersion; + if (mMbpData.MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType == INTEL_ME_5MB_FW) { + CopyMem (mMeFviElementsData[EnumMeFw].Element.VerString, Str5MBFw, sizeof (MEFW_5M_STRING)); + } + Status = gBS->LocateProtocol (&gEfiMebxProtocolGuid, NULL, (VOID **) &MebxProtocol); + if (!EFI_ERROR (Status)) { + mMeFviElementsData[EnumMebx].Element.Version.MajorVersion = (UINT8) MebxProtocol->MebxVersion.Major; + mMeFviElementsData[EnumMebx].Element.Version.MinorVersion = (UINT8) MebxProtocol->MebxVersion.Minor; + mMeFviElementsData[EnumMebx].Element.Version.Revision = (UINT8) MebxProtocol->MebxVersion.Hotfix; + mMeFviElementsData[EnumMebx].Element.Version.BuildNum = (UINT16) MebxProtocol->MebxVersion.Build; + } + + CreateRcFviDatahub (&mMeFviVersionData); + + /// + /// PCH BIOS Spec Rev 0.9 Section 18.4 Additional Power Management Programming + /// Step 2 + /// Set "Power Management Initialization Register (PMIR) Field 1", D31:F0:ACh[31] = 1b + /// for production machine according to "RS - PCH Intel Management Engine + /// (Intel(r) ME) BIOS Writer's Guide". + /// + /// PCH ME BWG section 4.5.1 + /// The IntelR FPT tool /GRST option uses CF9GR bit to trigger global reset. + /// Based on above reason, the BIOS should not lock down CF9GR bit during Manufacturing and + /// Re-manufacturing environment. + /// + Address = PCI_LIB_ADDRESS ( + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_PMIR + ); + Data = PciRead32 (Address); + Data &= (UINT32) (~(B_PCH_LPC_PMIR_CF9LOCK | B_PCH_LPC_PMIR_CF9GR)); + + if ((((MeMode == ME_MODE_NORMAL) || (MeMode == ME_MODE_TEMP_DISABLED)) && !(MeFirmwareStatus.r.ManufacturingMode))) { + /// + /// PCH ME BWG section 4.4.1 + /// BIOS must also ensure that CF9GR is cleared and locked (via bit31 of the same register) before + /// handing control to the OS in order to prevent the host from issuing global resets and reseting + /// Intel Management Engine. + /// + Data |= (UINT32) (B_PCH_LPC_PMIR_CF9LOCK); + } +#ifdef SUS_WELL_RESTORE + /// + /// PMIR is a resume well register and has no script save for it. + /// System may go through S3 resume path from G3 if RapidStart is enabled, + /// that means all resume well registers will be reset to defaults. + /// Save boot script for PMIR register if RapidStart is enabled. + /// + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) MmPciAddress (0x0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_PMIR), + 1, + &Data + ); +#endif + /// + /// + /// Read RCBA register for saving + /// + Data = Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FD2); + /// + /// Disable Heci2 if policy dictates + /// + Data |= (BIT0 << HECI2); + + /// + /// If ME Mode is running in ME Temp Disable state, disable Heci1, HECI2, Ider and Sol + /// + if ((MeMode == ME_MODE_TEMP_DISABLED) || (MeMode == ME_MODE_SECOVER)) { + Data |= ((BIT0 << HECI1) + (BIT0 << HECI2) + (BIT0 << IDER) + (BIT0 << SOL)); + } + + if (MeMode == ME_MODE_NORMAL) { + if (mHeciContext->MeFwImageType == INTEL_ME_1_5MB_FW) { + /// + /// We will disable HECI2, Ider and Sol in 1.5M SKU + /// + Data |= ((BIT0 << HECI2) + (BIT0 << IDER) + (BIT0 << SOL)); + } else if (mHeciContext->MeFwImageType == INTEL_ME_5MB_FW) { + MebxSetupVariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE; + MebxSetupVariableDataSize = sizeof (ME_BIOS_EXTENSION_SETUP); + + Status = gST->RuntimeServices->GetVariable ( + gEfiMeBiosExtensionSetupName, + &gEfiMeBiosExtensionSetupGuid, + &MebxSetupVariableAttributes, + &MebxSetupVariableDataSize, + &MeBiosExtensionSetup + ); + if (!EFI_ERROR (Status)) { + if ((MeBiosExtensionSetup.AmtSolIder & SOL_ENABLE) == 0) { + Data |= (BIT0 << SOL); + } + + if ((MeBiosExtensionSetup.AmtSolIder & IDER_ENABLE) == 0) { + Data |= (BIT0 << IDER); + } + } + } + } + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_FD2), + 1, + &Data + ); + /// + /// Function Disable SUS Well lockdown + /// + Data = Mmio16 (PCH_RCRB_BASE, R_PCH_RCRB_FDSW); + + if (MeMode == ME_MODE_NORMAL) { + if (mHeciContext->MeFwImageType == INTEL_ME_5MB_FW) { + Data |= B_PCH_RCRB_FDSW_FDSWL; + } + } + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_FDSW), + 1, + &Data + ); + + gBS->CloseEvent (Event); + return; +} + +/** + Send Get Firmware SKU Request to ME + + @param[out] FwCapsSku Return FwCapsSku mask for Get Firmware Capability SKU + + @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 +MbpGetFwCapsSkuThroughHeci ( + OUT MEFWCAPS_SKU *FwCapsSku + ) +{ + EFI_STATUS Status; + GEN_GET_FW_CAPS_SKU_BUFFER MsgGenGetFwCapsSku; + UINT32 Length; + UINT32 RespLength; + + MsgGenGetFwCapsSku.Request.MKHIHeader.Data = 0; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.IsResponse = 0; + MsgGenGetFwCapsSku.Request.Data.RuleId = 0; + Length = sizeof (GEN_GET_FW_CAPSKU); + RespLength = sizeof(GEN_GET_FW_CAPS_SKU_ACK); + + /// + /// Send Get FW SKU Request to ME + /// + Status = HeciSendwACK ( + (UINT32 *) &MsgGenGetFwCapsSku, + Length, + &RespLength, + BIOS_FIXED_HOST_ADDR, + HECI_CORE_MESSAGE_ADDR + ); + + if (!EFI_ERROR(Status) && + ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) && + ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.IsResponse) == 1) && + (MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Result == 0) + ) { + *FwCapsSku = MsgGenGetFwCapsSku.Response.Data.FWCapSku; + return EFI_SUCCESS; + } + + return Status; +} + +/** + Send Get Platform Type Request to ME + + @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 +MbpGetPlatformTypeThroughHeci ( + OUT PLATFORM_TYPE_RULE_DATA *RuleData + ) +{ + EFI_STATUS Status; + GEN_GET_PLATFORM_TYPE_BUFFER MsgGenGetPlatformType; + UINT32 Length; + UINT32 RespLength; + + MsgGenGetPlatformType.Request.MKHIHeader.Data = 0; + MsgGenGetPlatformType.Request.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID; + MsgGenGetPlatformType.Request.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD; + MsgGenGetPlatformType.Request.MKHIHeader.Fields.IsResponse = 0; + MsgGenGetPlatformType.Request.Data.RuleId = 0x1D; + Length = sizeof (GEN_GET_PLATFORM_TYPE); + RespLength = sizeof(GEN_GET_PLATFORM_TYPE_ACK); + + /// + /// Send Get FW SKU Request to ME + /// + Status = HeciSendwACK ( + (UINT32 *) &MsgGenGetPlatformType, + Length, + &RespLength, + BIOS_FIXED_HOST_ADDR, + HECI_CORE_MESSAGE_ADDR + ); + + if (!EFI_ERROR(Status) && + ((MsgGenGetPlatformType.Response.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) && + ((MsgGenGetPlatformType.Response.MKHIHeader.Fields.IsResponse) == 1) && + (MsgGenGetPlatformType.Response.MKHIHeader.Fields.Result == 0) + ) { + *RuleData = MsgGenGetPlatformType.Response.Data.RuleData; + return EFI_SUCCESS; + } + + return Status; +} + +/** + Send Get Firmware Features State Request to ME + + @param[out] FwFeaturesState Return FwFeaturesState mask for Get Firmware Features State + + @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 +MbpGetFwFeaturesStateThroughHeci ( + OUT MEFWCAPS_SKU *FwFeaturesState + ) +{ + EFI_STATUS Status; + GEN_GET_FW_CAPS_SKU_BUFFER MsgGenGetFwCapsSku; + UINT32 Length; + UINT32 RespLength; + + MsgGenGetFwCapsSku.Request.MKHIHeader.Data = 0; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.GroupId = MKHI_FWCAPS_GROUP_ID; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.Command = FWCAPS_GET_RULE_CMD; + MsgGenGetFwCapsSku.Request.MKHIHeader.Fields.IsResponse = 0; + MsgGenGetFwCapsSku.Request.Data.RuleId = 0x20; + Length = sizeof (GEN_GET_FW_CAPSKU); + RespLength = sizeof(GEN_GET_FW_CAPS_SKU_ACK); + + /// + /// Send Get FW SKU Request to ME + /// + Status = HeciSendwACK ( + (UINT32 *) &MsgGenGetFwCapsSku, + Length, + &RespLength, + BIOS_FIXED_HOST_ADDR, + HECI_CORE_MESSAGE_ADDR + ); + + if (!EFI_ERROR(Status) && + ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Command) == FWCAPS_GET_RULE_CMD) && + ((MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.IsResponse) == 1) && + (MsgGenGetFwCapsSku.Response.MKHIHeader.Fields.Result == 0) + ) { + *FwFeaturesState = MsgGenGetFwCapsSku.Response.Data.FWCapSku; + return EFI_SUCCESS; + } + + return Status; +} + +/** + Install MbpData protocol. + + @param[in] None + + @retval None +**/ +VOID +InstallMbpDataProtocol ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 MeMode; + UINT32 MeStatus; + MEFWCAPS_SKU FwCapsSku; + PLATFORM_TYPE_RULE_DATA RuleData; + + ZeroMem (&mMbpData, sizeof (DXE_MBP_DATA_PROTOCOL)); + + HeciGetMeMode (&MeMode); + + mMbpData.Revision = DXE_MBP_DATA_PROTOCOL_REVISION_2; + + PERF_START_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc (), 0x8010); + Status = PrepareMeBiosPayload (&mMbpData.MeBiosPayload); + PERF_END_EX (NULL, EVENT_REC_TOK, NULL, AsmReadTsc (), 0x8011); + + if (!EFI_ERROR (Status)) { + HeciGetMeStatus (&MeStatus); + HeciGetMeMode (&MeMode); + + if (mMbpData.MeBiosPayload.FwCapsSku.Available == 0) { + if ((MeMode == ME_MODE_NORMAL) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + Status = MbpGetFwCapsSkuThroughHeci (&FwCapsSku); + if (!EFI_ERROR (Status)) { + mMbpData.MeBiosPayload.FwCapsSku.FwCapabilities.Data = FwCapsSku.Data; + mMbpData.MeBiosPayload.FwCapsSku.Available = TRUE; + } + } + } + + if (mMbpData.MeBiosPayload.FwPlatType.Available == 0) { + if ((MeMode == ME_MODE_NORMAL) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + Status = MbpGetPlatformTypeThroughHeci (&RuleData); + if (!EFI_ERROR (Status)) { + mMbpData.MeBiosPayload.FwPlatType.RuleData.Data = RuleData.Data; + mMbpData.MeBiosPayload.FwPlatType.Available = TRUE; + } + } + } + + if (mMbpData.MeBiosPayload.FwVersionName.MajorVersion == 10) { + // + // For ME 10 get the FW features state mask + // + if (mMbpData.MeBiosPayload.FwFeaturesState.Available == 0) { + if ((MeMode == ME_MODE_NORMAL) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + Status = MbpGetFwFeaturesStateThroughHeci ((MEFWCAPS_SKU*)&RuleData.Data); + if (!EFI_ERROR (Status)) { + mMbpData.MeBiosPayload.FwFeaturesState.FwFeatures.Data = RuleData.Data; + mMbpData.MeBiosPayload.FwFeaturesState.Available = TRUE; + } + } + } + } + +#ifdef EFI_DEBUG + // + // Dump the Mbp data + // + DxeMbpDebugDump (&mMbpData); +#endif + + /// + /// Install the MBP protocol + /// + mMbpData.Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &mMbpData.Handle, + &gMeBiosPayloadDataProtocolGuid, + &mMbpData, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "MBP data protocol install failed, Status is %r \n", Status)); + } + } +} + +/** + HECI driver entry point used to initialize support for the HECI device. + + @param[in] ImageHandle Standard entry point parameter. + @param[in] SystemTable Standard entry point parameter. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +InitializeHECI ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + VOID *Registration; + BOOLEAN HeciInitializeError; + UINT32 MeStatus; + UINT32 MeMode; + MEFWCAPS_SKU FwCapsSku; + PLATFORM_TYPE_RULE_DATA RuleData; + DXE_MBP_DATA_PROTOCOL *MbpData; + + INITIALIZE_SCRIPT (ImageHandle, SystemTable); + + mHeciDrv = ImageHandle; + HeciInitializeError = FALSE; + mHeciContext = AllocateZeroPool (sizeof (HECI_INSTANCE)); + /// + /// Initialize HECI protocol pointers + /// + if (mHeciContext != NULL) { + mHeciContext->HeciCtlr.ResetHeci = ResetHeciInterface; + mHeciContext->HeciCtlr.SendwACK = HeciSendwACK; + mHeciContext->HeciCtlr.ReadMsg = HeciReceive; + mHeciContext->HeciCtlr.SendMsg = HeciSend; + mHeciContext->HeciCtlr.InitHeci = HeciInitialize; + mHeciContext->HeciCtlr.ReInitHeci = HeciReInitialize; + mHeciContext->HeciCtlr.MeResetWait = MeResetWait; + mHeciContext->HeciCtlr.GetMeStatus = HeciGetMeStatus; + mHeciContext->HeciCtlr.GetMeMode = HeciGetMeMode; + } + /// + /// Initialize the HECI device + /// + Status = InitializeHeciPrivate (); + if ((EFI_ERROR (Status)) || (mHeciContext == NULL)) { + HeciInitializeError = TRUE; + } + /// + /// Install the MBP information + /// + InstallMbpDataProtocol (); + + if (HeciInitializeError) { + /// + /// Don't install on ERR + /// + if (Status != EFI_NOT_READY) { + DEBUG ((EFI_D_ERROR, "HECI not initialized - Removing devices from PCI space!\n")); + DisableAllMEDevices (); + /// + /// Store the current value of DEVEN for S3 resume path + /// + } + DeviceStatusSave (); + return EFI_SUCCESS; + } + /// + /// Install the HECI interface + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &mHeciContext->Handle, + &gEfiHeciProtocolGuid, + &mHeciContext->HeciCtlr, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + HeciGetMeStatus (&MeStatus); + HeciGetMeMode (&MeMode); + + Status = gBS->LocateProtocol ( + &gMeBiosPayloadDataProtocolGuid, + NULL, + (VOID **) &MbpData + ); + if (!EFI_ERROR (Status)) { + if (MbpData->MeBiosPayload.FwCapsSku.Available == 0) { + if ((MeMode == ME_MODE_NORMAL) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + Status = HeciGetFwCapsSku (&FwCapsSku); + if (!EFI_ERROR (Status)) { + MbpData->MeBiosPayload.FwCapsSku.FwCapabilities.Data = FwCapsSku.Data; + } + } + } + + if (MbpData->MeBiosPayload.FwPlatType.Available == 0) { + if ((MeMode == ME_MODE_NORMAL) && + ( + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) || + (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY) + ) + ) { + Status = HeciGetPlatformType (&RuleData); + if (!EFI_ERROR (Status)) { + MbpData->MeBiosPayload.FwPlatType.RuleData.Data = RuleData.Data; + } + } + } + /// + /// Dxe Mbp data is gone after ExitPmAuth, so we keep MeFwImageType for the inspection after ExitPmAuth + /// + mHeciContext->MeFwImageType = (UINT8) MbpData->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType; + } + + + /// + /// Hide Me relevant Devices + /// + Status = MeDeviceConfigure (); + ASSERT_EFI_ERROR (Status); + + /// + /// Initialize the Me Reference Code Information + /// + mHeciContext->MeRcInfo.Revision = ME_RC_INFO_PROTOCOL_REVISION_1; + mHeciContext->MeRcInfo.RCVersion = ME_RC_VERSION; + + /// + /// Install the Me Reference Code Information + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &mHeciContext->Handle, + &gEfiMeRcInfoProtocolGuid, + &mHeciContext->MeRcInfo, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + /// + /// Create an ExitPmAuth protocol call back event. + /// + EfiCreateProtocolNotifyEvent ( + &gExitPmAuthProtocolGuid, + EFI_TPL_CALLBACK, + MeScriptSaveEvent, + NULL, + &Registration + ); + + /// + /// Create a Ready to Boot event. + /// + Status = EfiCreateEventReadyToBootEx ( + EFI_TPL_CALLBACK, + MeReadyToBootEvent, + (VOID *) &ImageHandle, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/ReferenceCode/ME/Heci/Dxe/Hecidrv.dxs b/ReferenceCode/ME/Heci/Dxe/Hecidrv.dxs new file mode 100644 index 0000000..647c8e0 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecidrv.dxs @@ -0,0 +1,43 @@ +/** @file + Dependency expression source file. + +@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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (CpuIo) +#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo) +#endif + +DEPENDENCY_START + EFI_CPU_IO_PROTOCOL_GUID AND + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID +DEPENDENCY_END + diff --git a/ReferenceCode/ME/Heci/Dxe/Hecidrv.h b/ReferenceCode/ME/Heci/Dxe/Hecidrv.h new file mode 100644 index 0000000..d3cea85 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecidrv.h @@ -0,0 +1,70 @@ +/** @file + Definitions for HECI driver + +@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 _HECI_DRV_H +#define _HECI_DRV_H + +#include "EdkIIGlueDxe.h" +#include "MeAccess.h" +#include "HeciRegs.h" +#include "Pci22.h" +#include "RcFviDxeLib.h" + +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) + +#define HECI_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('H', 'e', 'c', 'i') +#define HECI_ROUND_UP_BUFFER_LENGTH(Length) ((UINT32) ((((Length) + 3) / 4) * 4)) + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_PRODUCER (Heci) +#include EFI_PROTOCOL_PRODUCER (MeRcInfo) + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_CONSUMER (MebxProtocol) + +extern FVI_ELEMENT_AND_FUNCTION mMeFviElementsData[]; +extern FVI_DATA_HUB_CALLBACK_CONTEXT mMeFviVersionData; +extern UINTN mMeFviElements; + +typedef union { + UINT32 Data32; + UINT16 Data16[2]; + UINT8 Data8[4]; +} DATA32_UNION; + +/// +/// HECI private data structure +/// +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + UINT64 HeciMBAR; + UINT16 DeviceInfo; + UINT32 RevisionInfo; + EFI_HECI_PROTOCOL HeciCtlr; + VOLATILE UINT32 *HpetTimer; + EFI_ME_RC_INFO_PROTOCOL MeRcInfo; + UINT8 MeFwImageType; +} HECI_INSTANCE; +#endif diff --git a/ReferenceCode/ME/Heci/Dxe/Hecidrv.inf b/ReferenceCode/ME/Heci/Dxe/Hecidrv.inf new file mode 100644 index 0000000..d82403e --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/Hecidrv.inf @@ -0,0 +1,99 @@ +## @file +# Component description file for Heci DXE driver +# +#@copyright +# Copyright (c) 2007 - 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 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 = Hecidrv +FILE_GUID = 55E76644-78A5-4a82-A900-7126A5798892 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + HeciDrv.c + Hecidrv.h + HeciCore.c + HeciCore.h + HeciHpet.c + HeciHpet.h + MeFvi.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(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 + $(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] + MeGuidLib + MeProtocolLib + MeLib + MeChipsetLib + IntelPchProtocolLib + $(PROJECT_PCH_FAMILY)ProtocolLib + RcFviDxeLib + EfiScriptLib + EfiProtocolLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + EdkIIGlueDxeServicesTableLib + EdkIIGlueBasePrintLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=Hecidrv.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeHECI + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -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_LIB__ \ + -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ +# Uncomment the following line if RapidStart is supported +# C_FLAGS = $(C_FLAGS) -DRAPID_START_FLAG diff --git a/ReferenceCode/ME/Heci/Dxe/MeFvi.c b/ReferenceCode/ME/Heci/Dxe/MeFvi.c new file mode 100644 index 0000000..f41b616 --- /dev/null +++ b/ReferenceCode/ME/Heci/Dxe/MeFvi.c @@ -0,0 +1,49 @@ +/** @file + ME Firmware Version Info implementation. + +@copyright + Copyright (c) 2011 - 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 +**/ +#include "Hecidrv.h" + +FVI_ELEMENT_AND_FUNCTION mMeFviElementsData[] = { + { + DEFAULT_FVI_ELEMENT_DATA(ME), + NULL + }, + { + DEFAULT_FVI_ELEMENT_DATA(MEBX), + NULL + }, + { + { + 1, + 3, + MEFW_VERSION, + MEFW_FVI_STRING, + MEFW_1_5M_STRING, + }, + NULL + } +}; + +FVI_DATA_HUB_CALLBACK_CONTEXT mMeFviVersionData = { + MISC_SUBCLASS_FVI_HEADER_ENTRY(ME), + mMeFviElementsData, +}; + +UINTN mMeFviElements = sizeof (mMeFviElementsData) / sizeof (FVI_ELEMENT_AND_FUNCTION); diff --git a/ReferenceCode/ME/Heci/Include/HeciInclude.cif b/ReferenceCode/ME/Heci/Include/HeciInclude.cif new file mode 100644 index 0000000..4379006 --- /dev/null +++ b/ReferenceCode/ME/Heci/Include/HeciInclude.cif @@ -0,0 +1,9 @@ +<component> + name = "HeciInclude" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Heci\Include\" + RefName = "HeciInclude" +[files] +"HeciInclude.sdl" +"HeciRegs.h" +<endComponent> diff --git a/ReferenceCode/ME/Heci/Include/HeciInclude.sdl b/ReferenceCode/ME/Heci/Include/HeciInclude.sdl new file mode 100644 index 0000000..9f9d6a7 --- /dev/null +++ b/ReferenceCode/ME/Heci/Include/HeciInclude.sdl @@ -0,0 +1,9 @@ +PATH + Name = "HeciInclude_DIR" +End + +ELINK + Name = "/I$(HeciInclude_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Heci/Include/HeciRegs.h b/ReferenceCode/ME/Heci/Include/HeciRegs.h new file mode 100644 index 0000000..5bc0a09 --- /dev/null +++ b/ReferenceCode/ME/Heci/Include/HeciRegs.h @@ -0,0 +1,275 @@ +/** @file + Register Definitions for HECI + +@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 _HECI_REGS_H +#define _HECI_REGS_H + +#define HECI_BUS ME_BUS +#define HECI_DEV ME_DEVICE_NUMBER +#define HECI_FUN HECI_FUNCTION_NUMBER +#define HECI_PCI_ADDR (HECI_BUS << 24) | (HECI_DEV << 16) | (HECI_FUN << 8) +#define REVID_MSK 0x000000FF + +#define BRNGUP_HMRFPO_DISABLE_CMD_MASK 0x0F +#define BRNGUP_HMRFPO_DISABLE_CMD 0x30 +#define BRNGUP_HMRFPO_DISABLE_OVR_MASK 0xF0000000 +#define BRNGUP_HMRFPO_DISABLE_OVR_RSP 0x30000000 + +// +// HECI PCI register definition +// +#define R_VENDORID 0x00 +#define R_DEVICEID 0x02 +#define R_COMMAND 0x04 +#define B_BME 0x04 +#define B_MSE 0x02 +#define R_REVID 0x08 +#define R_HECIMBAR 0x10 +#define R_FWSTATE 0x40 +#define R_GEN_STS 0x4C +#define R_HIDM 0xA0 + +// +// HECIMBAR register definition +// +#define H_CB_WW 0x00 +#define H_CSR 0x04 +#define ME_CB_RW 0x08 +#define ME_CSR_HA 0x0C + +/// +/// PCH related registers address +/// +#define PCH_ACPI_TIMER_MAX_VALUE 0x1000000 ///< The timer is 24 bit overflow +// +// HPET Information +// +#define HPET_ADDRESS_0 0xFED00000 +#define HPET_ADDRESS_1 0xFED01000 +#define HPET_ADDRESS_2 0xFED02000 +#define HPET_ADDRESS_3 0xFED03000 +// +// HPET Registers will be used as DWORD index +// +#define HPET_CAPS_REG_LOW 0x00 / 4 +#define HPET_CAPS_REG_HIGH 0x04 / 4 +#define HPET_GEN_CONFIG_LOW 0x10 / 4 +#define HPET_GEN_CONFIG_HIGH 0x14 / 4 +#define HPET_INT_STATUS_LOW 0x20 / 4 +#define HPET_INT_STATUS_HIGH 0x24 / 4 +#define HPET_MAIN_COUNTER_LOW 0xF0 / 4 +#define HPET_MAIN_COUNTER_HIGH 0xF4 / 4 + +#define HPET_START 0x01 +#define HPET_TICKS_PER_MICRO 14 ///< 70ns tick so 14.2 ticks per microsecond ish +// +// PEI Timeout values +// +#define PEI_HECI_WAIT_DELAY 50000 ///< 50ms timeout for IO delay +#define PEI_HECI_INIT_TIMEOUT 10000000 ///< 10 sec timeout in microseconds +#define PEI_HECI_READ_TIMEOUT 10000000 ///< 10sec timeout in microseconds +#define PEI_HECI_SEND_TIMEOUT 10000000 ///< 10sec timeout in microseconds +// +// DXE Timeout values based on HPET +// +#define HECI_WAIT_DELAY 1000 ///< 1ms timeout for IO delay +#define HECI_INIT_TIMEOUT 15000000 ///< 15sec timeout in microseconds +#define HECI_READ_TIMEOUT 5000000 ///< 5sec timeout in microseconds +#define HECI_SEND_TIMEOUT 5000000 ///< 5sec timeout in microseconds +#define HECI_MAX_RETRY 3 ///< Value based off HECI HPS +#define HECI_MSG_DELAY 2000000 ///< show warning msg and stay for 2 seconds. +#define HECI_MBP_RDY_TIMEOUT 50000 ///< 50ms timeout +#define HECI_MBP_CLR_TIMEOUT 1000000 ///< 1s timeout +#define HECI_MBP_READ_MAX_RETRIES 2 ///< MBP read will be retried twice +#pragma pack(1) +// +// REGISTER EQUATES +// + +/// +/// ME_CSR_HA - ME Control Status Host Access +/// +typedef union { + UINT32 ul; + struct { + UINT32 ME_IE_HRA : 1; ///< 0 - ME Interrupt Enable (Host Read Access) + UINT32 ME_IS_HRA : 1; ///< 1 - ME Interrupt Status (Host Read Access) + UINT32 ME_IG_HRA : 1; ///< 2 - ME Interrupt Generate (Host Read Access) + UINT32 ME_RDY_HRA : 1; ///< 3 - ME Ready (Host Read Access) + UINT32 ME_RST_HRA : 1; ///< 4 - ME Reset (Host Read Access) + UINT32 Reserved : 3; ///< 7:5 + UINT32 ME_CBRP_HRA : 8; ///< 15:8 - ME CB Read Pointer (Host Read Access) + UINT32 ME_CBWP_HRA : 8; ///< 23:16 - ME CB Write Pointer (Host Read Access) + UINT32 ME_CBD_HRA : 8; ///< 31:24 - ME Circular Buffer Depth (Host Read Access) + } r; +} HECI_ME_CONTROL_REGISTER; + +/// +/// H_CSR - Host Control Status +/// +typedef union { + UINT32 ul; + struct { + UINT32 H_IE : 1; ///< 0 - Host Interrupt Enable ME + UINT32 H_IS : 1; ///< 1 - Host Interrupt Status ME + UINT32 H_IG : 1; ///< 2 - Host Interrupt Generate + UINT32 H_RDY : 1; ///< 3 - Host Ready + UINT32 H_RST : 1; ///< 4 - Host Reset + UINT32 Reserved : 3; ///< 7:5 + UINT32 H_CBRP : 8; ///< 15:8 - Host CB Read Pointer + UINT32 H_CBWP : 8; ///< 23:16 - Host CB Write Pointer + UINT32 H_CBD : 8; ///< 31:24 - Host Circular Buffer Depth + } r; +} HECI_HOST_CONTROL_REGISTER; + +/// +/// FWS +/// +typedef union { + UINT32 ul; + struct { + UINT32 CurrentState : 4; ///< 0:3 - Current State + UINT32 ManufacturingMode : 1; ///< 4 Manufacturing Mode + UINT32 FptBad : 1; ///< 5 FPT(Flash Partition Table ) Bad + UINT32 MeOperationState : 3; ///< 6:8 - ME Operation State + UINT32 FwInitComplete : 1; ///< 9 + UINT32 FtBupLdFlr : 1; ///< 10 - This bit is set when firmware is not able to load BRINGUP from the fault tolerant (FT) code. + UINT32 FwUpdateInprogress : 1; ///< 11 + UINT32 ErrorCode : 4; ///< 12:15 - Error Code + UINT32 MeOperationMode : 4; ///< 16:19 - Management Engine Current Operation Mode + UINT32 Reserved2 : 4; ///< 20:23 + UINT32 MeBootOptionsPresent : 1; ///< 24 - If this bit is set, an Boot Options is present + UINT32 AckData : 3; ///< 25:27 Ack Data + UINT32 BiosMessageAck : 4; ///< 28:31 BIOS Message Ack + } r; +} HECI_FWS_REGISTER; + +/// +/// MISC_SHDW +/// +typedef union { + UINT32 ul; + struct { + UINT32 MUSZ : 6; ///< 0:5 - ME UMA Size + UINT32 Reserved : 8; ///< 6:13 - Reserved + UINT32 Reserved2 : 2; ///< 14:15 - Reserved + UINT32 MUSZV : 1; ///< 16:16 - ME UMA Size Valid + UINT32 Reserved3 : 8; ///< 17:24 - Reserved + UINT32 Reserved4 : 6; ///< 25:30 - Reserved + UINT32 MSVLD : 1; ///< 31:31 - Miscellaneous Shadow Valid + } r; +} HECI_MISC_SHDW_REGISTER; + +/// +/// GS_SHDW +/// +typedef union { + UINT32 ul; + struct { + UINT32 BistInProg : 1; ///< 0 - BIST in progress + UINT32 IccProgSts : 2; ///< 1:2 - ICC Prog STS + UINT32 InvokeMEBx : 1; ///< 3 - Invoke MEBX + UINT32 CpuReplacedSts : 1; ///< 4 - CPU Replaced STS + UINT32 MbpRdy : 1; ///< 5 - MBP RDY + UINT32 MfsFailure : 1; ///< 6 - MFS Failure + UINT32 WarmRstReqForDF : 1; ///< 7 - Warm Reset Required for Dynamic Fusing + UINT32 CpuReplacedValid : 1; ///< 8 - CPU Replaced Valid + UINT32 Reserved : 2; ///< 9:10 - Reserved + UINT32 FwUpdIpu : 1; ///< 11 - FW UPD IPU Needed + UINT32 Reserved2 : 1; ///< 12 - Reserved + UINT32 MbpCleared : 1; ///< 13 - MBP Cleared + UINT32 Reserved3 : 2; ///< 14:15 - Reserved + UINT32 ExtStatCode1 : 8; ///< 16:23 - EXT Status Code 1 + UINT32 ExtStatCode2 : 4; ///< 24:27 - EXT Status Code 2 + UINT32 InfPhaseCode : 4; ///< 31:28 - Infra. Phase code + } r; +} HECI_GS_SHDW_REGISTER; + +/// +/// HECI_GS2 +/// +typedef union { + UINT32 ul; + struct { + UINT32 MbpGiveUp : 1; ///< 0 - MBP Give Up + UINT32 Reserved :31; ///< 1-31 - Reserved + } r; +} HECI_GS2_REGISTER; + +// +// ME Current State Values +// +#define ME_STATE_RESET 0x00 +#define ME_STATE_INIT 0x01 +#define ME_STATE_RECOVERY 0x02 +#define ME_STATE_NORMAL 0x05 +#define ME_STATE_DISABLE_WAIT 0x06 +#define ME_STATE_TRANSITION 0x07 +#define ME_STATE_INVALID_CPU 0x08 + +// +// DRAM Initiailization Response Codes. +// +#define CBM_DIR_NON_PCR 0x01 +#define CBM_DIR_PCR 0x02 +#define CBM_DIR_GLOBAL_RESET 0x06 +#define CBM_DIR_CONTINUE_POST 0x07 +// +// ME Firmware FwInitComplete +// +#define ME_FIRMWARE_COMPLETED 0x01 +#define ME_FIRMWARE_INCOMPLETED 0x00 + +// +// ME Boot Options Present +// +#define ME_BOOT_OPTIONS_PRESENT 0x01 +#define ME_BOOT_OPTIONS_NOT_PRESENT 0x00 + +// +// ME Operation State Values +// +#define ME_OPERATION_STATE_PREBOOT 0x00 +#define ME_OPERATION_STATE_M0_UMA 0x01 +#define ME_OPERATION_STATE_M3 0x04 +#define ME_OPERATION_STATE_M0 0x05 +#define ME_OPERATION_STATE_BRINGUP 0x06 +#define ME_OPERATION_STATE_M0_ERROR 0x07 + +// +// ME Error Code Values +// +#define ME_ERROR_CODE_NO_ERROR 0x00 +#define ME_ERROR_CODE_UNKNOWN 0x01 +#define ME_ERROR_CODE_IMAGE_FAILURE 0x03 +#define ME_ERROR_CODE_DEBUG_FAILURE 0x04 + +// +// Management Engine Current Operation Mode +// +#define ME_OPERATION_MODE_NORMAL 0x00 + +#define ME_OPERATION_MODE_DEBUG 0x02 +#define ME_OPERATION_MODE_SOFT_TEMP_DISABLE 0x03 +#define ME_OPERATION_MODE_SECOVR_JMPR 0x04 +#define ME_OPERATION_MODE_SECOVR_HECI_MSG 0x05 +#pragma pack() + +#endif // HECI_REGS_H diff --git a/ReferenceCode/ME/Heci/MeHeci.cif b/ReferenceCode/ME/Heci/MeHeci.cif new file mode 100644 index 0000000..73fdc6d --- /dev/null +++ b/ReferenceCode/ME/Heci/MeHeci.cif @@ -0,0 +1,13 @@ +<component> + name = "MeHeci" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Heci\" + RefName = "MeHeci" +[files] +"MeHeci.sdl" +[parts] +"HeciDxe" +"HeciPei" +"HeciInclude" +"HeciSmm" +<endComponent> diff --git a/ReferenceCode/ME/Heci/MeHeci.sdl b/ReferenceCode/ME/Heci/MeHeci.sdl new file mode 100644 index 0000000..8755bf8 --- /dev/null +++ b/ReferenceCode/ME/Heci/MeHeci.sdl @@ -0,0 +1,19 @@ +TOKEN + Name = "MeHeci_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable MeHeci support in Project" +End + +PATH + Name = "MeHeci_DIR" + Help = "Me Heci Driver files source directory" +End +ELINK + Name = "/I$(MeHeci_DIR)\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Heci/Pei/HeciCore.c b/ReferenceCode/ME/Heci/Pei/HeciCore.c new file mode 100644 index 0000000..e248118 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciCore.c @@ -0,0 +1,1247 @@ +/** @file + Heci driver core. For PEI Phase, determines the HECI device and initializes it. + +@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 + +**/ +#include "HeciInit.h" +/** + Delay for at least the request number of microseconds + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] Microseconds Number of microseconds to delay. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +Stall ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINTN Microseconds + ) +{ + UINTN Ticks; + UINTN Counts; + UINT32 CurrentTick; + UINT32 OriginalTick; + UINT32 RemainingTick; + UINT32 AcpiPm1TimerBar; + + if (Microseconds == 0) { + return EFI_SUCCESS; + } + + AcpiPm1TimerBar = ( + PciRead32 (PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ACPI_BASE)) & B_PCH_LPC_ACPI_BASE_BAR + ) + + R_PCH_ACPI_PM1_TMR; + + OriginalTick = IoRead32 ((UINTN) (UINT64) AcpiPm1TimerBar); + OriginalTick &= (PCH_ACPI_TIMER_MAX_VALUE - 1); + CurrentTick = OriginalTick; + + /// + /// The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks + /// + Ticks = Microseconds * 358 / 100 + OriginalTick + 1; + + /// + /// The loops needed for timer overflow + /// + Counts = Ticks / PCH_ACPI_TIMER_MAX_VALUE; + + /// + /// Remaining clocks within one loop + /// + RemainingTick = Ticks % PCH_ACPI_TIMER_MAX_VALUE; + + /// + /// Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra + /// one I/O operation, and may generate SMI + /// + while (Counts != 0) { + CurrentTick = IoRead32 ((UINTN) (UINT64) AcpiPm1TimerBar); + CurrentTick &= (PCH_ACPI_TIMER_MAX_VALUE - 1); + if (CurrentTick <= OriginalTick) { + Counts--; + } + + OriginalTick = CurrentTick; + } + + while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) { + OriginalTick = CurrentTick; + CurrentTick = IoRead32 ((UINTN) (UINT64) AcpiPm1TimerBar); + CurrentTick &= (PCH_ACPI_TIMER_MAX_VALUE - 1); + } + + return EFI_SUCCESS; +} + +/** + Enable Hpet function. + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval UINT32 Return the High Precision Event Timer base address +**/ +VOLATILE +UINT32 * +EnableHpet ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + VOLATILE UINT32 *HpetConfigReg; + VOLATILE UINT32 *HpetTimer; + UINT32 Temp32; + HpetConfigReg = NULL; + /// + /// Get the High Precision Event Timer base address and enable the memory range + /// + HpetConfigReg = (UINT32 *) (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); + switch (*HpetConfigReg & B_PCH_RCRB_HPTC_AS) { + case 0: + HpetTimer = (VOID *) (HPET_ADDRESS_0); + break; + + case 1: + HpetTimer = (VOID *) (HPET_ADDRESS_1); + break; + + case 2: + HpetTimer = (VOID *) (HPET_ADDRESS_2); + break; + + case 3: + HpetTimer = (VOID *) (HPET_ADDRESS_3); + break; + + default: + HpetTimer = NULL; + break; + } + + *HpetConfigReg = *HpetConfigReg | B_PCH_RCRB_HPTC_AE; + /// + /// Read back from RCBA area. + /// + Temp32 = *HpetConfigReg; + + /// + /// Start the timer so it is up and running + /// + HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START; + + return HpetTimer; +} + +/** + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI + @param[in][out] HeciMemBar HECI Memory BAR + + @retval None +**/ +VOID +CheckAndFixHeciForAccess ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *HeciMemBar + ) +{ + UINT32 Buffer; + + /// + /// Check if HECI_MBAR has changed + /// + Buffer = HeciPciRead32 (R_HECIMBAR) & 0xFFFFFFF0; + if (*HeciMemBar != Buffer) { + /// + /// If it did change update the mHeciContext variable so we use the proper address for acceses + /// + *HeciMemBar = Buffer; + } + /// + /// Enable HECI BME and MSE + /// + HeciPciOr8 ( + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + return ; +} + +#ifdef EFI_DEBUG + +/** + For EFI debug used, will show the message of buffer to terminal. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] Message The address of message. + @param[in] Length The length of message. +**/ +VOID +ShowBuffer ( + IN EFI_PEI_SERVICES **PeiServices, + 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 + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI + @param[in][out] HeciMemBar HECI Memory BAR + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_DEVICE_ERROR No HECI device + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @exception EFI_UNSUPPORTED HECI MSG is unsupported +**/ +EFI_STATUS +EFIAPI +InitializeHeci ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *HeciMemBar + ) +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr; + UINT32 HeciMBar; + UINT32 MeMode; + + HeciRegHCsrPtr = NULL; + HeciRegMeCsrHaPtr = NULL; + + /// + /// Check for HECI-1 PCI device availability + /// + if (HeciPciRead16 (PCI_DEVICE_ID_OFFSET) == 0xFFFF) { + return EFI_DEVICE_ERROR; + } + /// + /// Check for ME error status + /// + if ((HeciPciRead32 (R_FWSTATE) & 0xF000) != 0) { + /// + /// ME failed to start so no HECI + /// + return EFI_DEVICE_ERROR; + } + /// + /// HECI MSG is unsupported if ME MODE is in Security Override + /// + HeciGetMeMode (PeiServices, &MeMode); + if (MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + /// + /// Get HECI_MBAR and see if it is programmed + /// to a useable value + /// + HeciMBar = HeciPciRead32 (R_HECIMBAR) & 0xFFFFFFF0; + + /// + /// Load temporary address for HECI_MBAR if one is not assigned + /// + if (HeciMBar == 0) { + DEBUG ((EFI_D_ERROR, "Heci MMIO Bar not programmed in PEI phase\n")); + } + + *HeciMemBar = HeciMBar; + + /// + /// Enable HECI BME and MSE + /// + HeciPciOr8 ( + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + + /// + /// Set HECI interrupt delivery mode. + /// HECI-1 using legacy/MSI interrupt + /// + HeciPciAnd8 (R_HIDM, 0xFC); + + /// + /// 2) setup H_CSR reg as follows: + /// a) Make sure H_RST is clear + /// b) Set H_RDY + /// c) Set H_IG + /// + HeciRegHCsrPtr = (VOID *) (HeciMBar + H_CSR); + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + if (HeciRegHCsrPtr->r.H_RDY == 0) { + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsrPtr->ul = HeciRegHCsr.ul; + } + + return EFI_SUCCESS; +} + +/** + Waits for the ME to report that it is ready for communication over the HECI + interface. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_TIMEOUT If 5 second timeout has expired, return fail. +**/ +EFI_STATUS +WaitForMEReady ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 HeciMemBar + ) +{ + UINT32 TimerStart; + UINT32 TimerEnd; + VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr; + VOLATILE UINT32 *HpetTimer; + + HeciRegMeCsrHaPtr = (VOID *) (HeciMemBar + ME_CSR_HA); + /// + /// Wait for ME ready + /// + /// + /// Check for ME ready status + /// + HpetTimer = StartTimer (PeiServices, &TimerStart, &TimerEnd, PEI_HECI_INIT_TIMEOUT); + while (HeciRegMeCsrHaPtr->r.ME_RDY_HRA == 0) { + /// + /// If 5 second timeout has expired, return fail + /// + if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Perform IO delay + /// + Stall (PeiServices, PEI_HECI_WAIT_DELAY); + } + /// + /// ME ready!!! + /// + return EFI_SUCCESS; +} + +/** + Read the HECI Message from Intel ME with size in Length into + buffer Message. Set Blocking to BLOCKING and code will wait + until one message packet is received. When set to + NON_BLOCKING, if the circular buffer is empty at the time, the + code not wait for the message packet read. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @exception EFI_UNSUPPORTED Current ME mode doesn't support this function + @retval EFI_SUCCESS One message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_DEVICE_ERROR Zero-length message packet read + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +EFI_STATUS +EFIAPI +HeciReadMsg ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 Blocking, + IN UINT32 HeciMemBar, + IN UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +{ + HECI_MESSAGE_HEADER PacketHeader; + UINT32 CurrentLength; + UINT32 MessageComplete; + EFI_STATUS ReadError; + UINT32 PacketBuffer; + UINT32 timer_start; + UINT32 timer_end; + VOLATILE UINT32 *HpetTimer; + UINT32 MeMode; + + CurrentLength = 0; + MessageComplete = 0; + + HeciGetMeMode (PeiServices, &MeMode); + if (MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + /// CheckAndFixHeciForAccess (PeiServices, This); + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady (PeiServices, This, HeciMemBar) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Set up timer for BIOS timeout. + /// + HpetTimer = StartTimer (PeiServices, &timer_start, &timer_end, PEI_HECI_READ_TIMEOUT); + while ((CurrentLength < *Length) && (MessageComplete == 0)) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message + /// + if (Timeout (timer_start, timer_end, HpetTimer) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + PacketBuffer = *Length - CurrentLength; + ReadError = HeciPacketRead ( + PeiServices, + Blocking, + HeciMemBar, + &PacketHeader, + (UINT32 *) &MessageBody[CurrentLength / 4], + &PacketBuffer + ); + + /// + /// Check for error condition on read + /// + if (EFI_ERROR (ReadError)) { + *Length = 0; + return ReadError; + } + /// + /// Get completion status from the packet header + /// + MessageComplete = PacketHeader.Fields.MessageComplete; + + /// + /// Check for zero length messages + /// + if (PacketBuffer == 0) { + /// + /// If we are not in the middle of a message, and we see Message Complete, + /// this is a valid zero-length message. + /// + if ((CurrentLength == 0) && (MessageComplete == 1)) { + *Length = 0; + return EFI_SUCCESS; + } else { + /// + /// We should not expect a zero-length message packet except as described above. + /// + *Length = 0; + return EFI_DEVICE_ERROR; + } + } + /// + /// Track the length of what we have read so far + /// + CurrentLength += PacketBuffer; + + } + /// + /// If we get here the message should be complete, if it is not + /// the caller's buffer was not large enough. + /// + if (MessageComplete == 0) { + *Length = 0; + return EFI_BUFFER_TOO_SMALL; + } + + *Length = CurrentLength; + + DEBUG ((EFI_D_ERROR, "HECI ReadMsg:\n")); +#ifdef EFI_DEBUG + DEBUG_CODE ( + ShowBuffer (PeiServices, (UINT8 *) MessageBody, *Length); + ); +#endif // End Of EFI_DEBUG + return EFI_SUCCESS; +} + +/** + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[out] MessageHeader Pointer to a buffer for the message header. + @param[out] MessageData Pointer to a buffer to recieve the message in. + @param[in][out] Length On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR The circular buffer is overflowed. + @retval EFI_NO_RESPONSE The circular buffer is empty + @retval EFI_TIMEOUT Failed to receive a full message + @retval EFI_BUFFER_TOO_SMALL Message packet is larger than caller's buffer +**/ +EFI_STATUS +HeciPacketRead ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 Blocking, + IN UINT32 HeciMemBar, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +{ + BOOLEAN GotMessage; + UINT32 TimerStart; + UINT32 TimerEnd; + UINT32 TimerStart1; + UINT32 TimerEnd1; + UINT32 i; + UINT32 LengthInDwords; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + VOLATILE UINT32 *HpetTimer; + /// + /// Initialize memory mapped register pointers + /// + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr; + VOLATILE UINT32 *HeciRegMeCbrwPtr; + + HeciRegHCsrPtr = (VOID *) (HeciMemBar + H_CSR); + HeciRegMeCsrHaPtr = (VOID *) (HeciMemBar + ME_CSR_HA); + HeciRegMeCbrwPtr = (VOID *) (HeciMemBar + ME_CB_RW); + + GotMessage = FALSE; + + /// + /// clear Interrupt Status bit + /// + HeciRegHCsrPtr->r.H_IS = 1; + + /// + /// test for circular buffer overflow + /// + HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul; + if (OverflowCB ( + HeciRegMeCsrHa.r.ME_CBRP_HRA, + HeciRegMeCsrHa.r.ME_CBWP_HRA, + HeciRegMeCsrHa.r.ME_CBD_HRA + ) != EFI_SUCCESS) { + /// + /// if we get here, the circular buffer is overflowed + /// + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// If NON_BLOCKING, exit if the circular buffer is empty + /// + HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul; + if ((FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) == 0) && (Blocking == NON_BLOCKING)) { + *Length = 0; + return EFI_NO_RESPONSE; + } + /// + /// Start timeout counter + /// + HpetTimer = StartTimer (PeiServices, &TimerStart, &TimerEnd, PEI_HECI_READ_TIMEOUT); + + /// + /// loop until we get a message packet + /// + while (!GotMessage) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message. + /// + if (Timeout (TimerStart, TimerEnd, HpetTimer) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + /// + /// Read one message from HECI buffer and advance read pointer. Make sure + /// that we do not pass the write pointer. + /// + HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul; + if (FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) > 0) { + /// + /// Eat the HECI Message header + /// + MessageHeader->Data = *HeciRegMeCbrwPtr; + + /// + /// Compute required message length in DWORDS + /// + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + /// + /// Just return success if Length is 0 + /// + if (MessageHeader->Fields.Length == 0) { + /// + /// Set Interrupt Generate bit and return + /// + HeciRegHCsrPtr->r.H_IG = 1; + *Length = 0; + return EFI_SUCCESS; + } + /// + /// Make sure that the message does not overflow the circular buffer. + /// + if ((MessageHeader->Fields.Length + sizeof (HECI_MESSAGE_HEADER)) > (HeciRegMeCsrHaPtr->r.ME_CBD_HRA * 4)) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// Make sure that the callers buffer can hold the correct number of DWORDS + /// + if ((MessageHeader->Fields.Length) <= *Length) { + /// + /// Start timeout counter for inner loop + /// + HpetTimer = StartTimer (PeiServices, &TimerStart1, &TimerEnd1, PEI_HECI_READ_TIMEOUT); + + /// + /// Wait here until entire message is present in circular buffer + /// + HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul; + while (LengthInDwords > FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA)) { + /// + /// If 1 second timeout has expired, return fail as we have not yet received a full message + /// + if (Timeout (TimerStart1, TimerEnd1, HpetTimer) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + /// + /// Wait before we read the register again + /// + Stall (PeiServices, PEI_HECI_WAIT_DELAY); + + /// + /// Read the register again + /// + HeciRegMeCsrHa.ul = HeciRegMeCsrHaPtr->ul; + } + /// + /// copy rest of message + /// + for (i = 0; i < LengthInDwords; i++) { + MessageData[i] = *HeciRegMeCbrwPtr; + } + /// + /// Update status and length + /// + GotMessage = TRUE; + *Length = MessageHeader->Fields.Length; + + } else { + /// + /// Message packet is larger than caller's buffer + /// + *Length = 0; + return EFI_BUFFER_TOO_SMALL; + } + } + /// + /// Wait before we try to get a message again + /// + Stall (PeiServices, PEI_HECI_WAIT_DELAY); + } + /// + /// Read ME_CSR_HA. If the ME_RDY bit is 0, then an ME reset occurred during the + /// transaction and the message should be discarded as bad data may have been retrieved + /// from the host's circular buffer + /// + if (HeciRegMeCsrHaPtr->r.ME_RDY_HRA == 0) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + /// + /// Set Interrupt Generate bit + /// + HeciRegHCsrPtr->r.H_IG = 1; + + return EFI_SUCCESS; +} + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HEC +**/ +EFI_STATUS +HeciSendMsg ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 *Message, + IN UINT32 HeciMemBar, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +{ + UINT32 CBLength; + UINT32 SendLength; + UINT32 CurrentLength; + HECI_MESSAGE_HEADER MessageHeader; + EFI_STATUS WriteStatus; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + UINT32 MeMode; + + CurrentLength = 0; + HeciRegHCsrPtr = NULL; + + HeciGetMeMode (PeiServices, &MeMode); + if (MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + + DEBUG ((EFI_D_ERROR, "HECI SendMsg:\n")); +#ifdef EFI_DEBUG + DEBUG_CODE ( + ShowBuffer (PeiServices, (UINT8 *) Message, Length); + ); +#endif // End Of EFI_DEBUG + /// + /// Make sure that HECI device BAR is correct and device is enabled. + /// + /// CheckAndFixHeciForAccess (PeiServices, This); + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady (PeiServices, This, HeciMemBar) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Set up memory mapped registers + /// + HeciRegHCsrPtr = (VOID *) (HeciMemBar + H_CSR); + + /// + /// Grab Circular Buffer length + /// + CBLength = HeciRegHCsrPtr->r.H_CBD; + + /// + /// Prepare message header + /// + MessageHeader.Data = 0; + MessageHeader.Fields.MeAddress = MeAddress; + MessageHeader.Fields.HostAddress = HostAddress; + + /// + /// Break message up into CB-sized packets and loop until completely sent + /// + while (Length > CurrentLength) { + /// + /// Set the Message Complete bit if this is our last packet in the message. + /// Needs to be 'less than' to account for the header. + /// + if ((((Length - CurrentLength) + 3) / 4) < CBLength) { + MessageHeader.Fields.MessageComplete = 1; + } + /// + /// Calculate length for Message Header + /// header length == smaller of circular buffer or remaining message (both account for the size of the header) + /// + SendLength = ((CBLength < (((Length - CurrentLength) + 3) / 4)) ? ((CBLength - 1) * 4) : (Length - CurrentLength)); + MessageHeader.Fields.Length = SendLength; + + DEBUG ((EFI_D_ERROR, "HECI Header: %08x\n", MessageHeader.Data)); + /// + /// send the current packet (CurrentLength can be treated as the index into the message buffer) + /// + WriteStatus = HeciPacketWrite ( + PeiServices, + This, + HeciMemBar, + &MessageHeader, + (UINT32 *) ((UINT32) Message + CurrentLength) + ); + if (EFI_ERROR (WriteStatus)) { + return WriteStatus; + } + /// + /// Update the length information + /// + CurrentLength += SendLength; + } + + return EFI_SUCCESS; +} + +/** + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] MessageHeader Pointer to the message header. + @param[in] MessageData Pointer to the actual message data. + + @retval EFI_SUCCESS One message packet sent + @retval EFI_DEVICE_ERROR ME is not ready + @retval EFI_TIMEOUT HECI is not ready for communication +**/ +EFI_STATUS +HeciPacketWrite ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 HeciMemBar, + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +{ + UINT32 timer_start; + UINT32 timer_end; + UINT32 i; + UINT32 LengthInDwords; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + VOLATILE UINT32 *HpetTimer; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr; + VOLATILE UINT32 *HeciRegHCbwwPtr; + + HeciRegHCsrPtr = (VOID *) (HeciMemBar + H_CSR); + HeciRegMeCsrHaPtr = (VOID *) (HeciMemBar + ME_CSR_HA); + HeciRegHCbwwPtr = (VOID *) (HeciMemBar + H_CB_WW); + /// + /// Make sure that HECI is ready for communication. + /// + if (WaitForMEReady (PeiServices, This, HeciMemBar) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Start timeout counter + /// + HpetTimer = StartTimer (PeiServices, &timer_start, &timer_end, PEI_HECI_SEND_TIMEOUT); + + /// + /// Compute message length in DWORDS + /// + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + /// + /// Wait until there is sufficient room in the circular buffer + /// Must have room for message and message header + /// + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + while ((LengthInDwords + 1) > (HeciRegHCsr.r.H_CBD - FilledSlots (HeciRegHCsr.r.H_CBRP, HeciRegHCsr.r.H_CBWP))) { + /// + /// If 1 second timeout has expired, return fail as the circular buffer never emptied + /// + if (Timeout (timer_start, timer_end, HpetTimer) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + /// + /// Wait before we read the register again + /// + Stall (PeiServices, PEI_HECI_WAIT_DELAY); + + /// + /// Read Host CSR for next iteration + /// + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + } + /// + /// Write Message Header + /// + *HeciRegHCbwwPtr = MessageHeader->Data; + + /// + /// Write Message Body + /// + for (i = 0; i < LengthInDwords; i++) { + *HeciRegHCbwwPtr = MessageData[i]; + } + /// + /// Set Interrupt Generate bit + /// + HeciRegHCsrPtr->r.H_IG = 1; + + /// + /// Test if ME Ready bit is set to 1, if set to 0 a fatal error occured during + /// the transmission of this message. + /// + if (HeciRegMeCsrHaPtr->r.ME_RDY_HRA == 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in][out] Message Pointer to the message buffer. + @param[in] HeciMemBar HECI Memory BAR. + @param[in][out] Length Length of the message in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @retval EFI_TIMEOUT HECI does not return the bufferbefore timeout + @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +HeciSendwAck ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *Message, + IN UINT32 HeciMemBar, + IN OUT UINT32 *Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +{ + EFI_STATUS Status; + UINT32 MeMode; + + HeciGetMeMode (PeiServices, &MeMode); + if (MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + /// + /// Send the message + /// + Status = HeciSendMsg (PeiServices, This, Message, HeciMemBar, *Length, HostAddress, MeAddress); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Wait for ACK message + /// + return HeciReadMsg (PeiServices, This, BLOCKING, HeciMemBar, Message, Length); +} + +/** + 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 +FilledSlots ( + 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; +} + +/** + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + @param[in] ReadPointer Value read from host/me read pointer + @param[in] WritePointer Value read from host/me write pointer + @param[in] BufferDepth Value read from buffer depth register + + @retval EFI_DEVICE_ERROR The circular buffer has overflowed + @retval EFI_SUCCESS The circular buffer does not overflowed +**/ +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +{ + UINT8 FilledSlots; + + /// + /// Calculation documented in HECI HPS 0.68 section 4.2.1 + /// + FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer)); + + /// + /// test for overflow + /// + if (FilledSlots > ((UINT8) BufferDepth)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Used for calculating timeouts + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] Start Snapshot of the HPET timer + @param[in] End Calculated time when timeout period will be done + @param[in] Time Timeout period in microseconds + + @retval None +**/ +VOLATILE +UINT32 * +StartTimer ( + IN EFI_PEI_SERVICES **PeiServices, + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +{ + UINT32 Ticks; + VOLATILE UINT32 *HpetTimer; + /// + /// Make sure that HPET is enabled and running + /// + HpetTimer = EnableHpet (PeiServices); + + /// + /// Read current timer value into start time from HPET + /// + *Start = HpetTimer[HPET_MAIN_COUNTER_LOW]; + + /// + /// Convert microseconds into 70ns timer ticks + /// + Ticks = Time * HPET_TICKS_PER_MICRO; + + /// + /// Compute end time + /// + *End = *Start + Ticks; + + return HpetTimer; +} + +/** + Used to determine if a timeout has occured. + + @param[in] Start Snapshot of the HPET timer when the timeout period started. + @param[in] End Calculated time when timeout period will be done. + @param[in] HpetTimer The value of High Precision Event Timer + + @retval EFI_TIMEOUT Timeout occured. + @retval EFI_SUCCESS Not yet timed out +**/ +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End, + IN VOLATILE UINT32 *HpetTimer + ) +{ + UINT32 Current; + + /// + /// Read HPET and assign the value as the current time. + /// + Current = HpetTimer[HPET_MAIN_COUNTER_LOW]; + + /// + /// If no timeout, current timer always is +1 to Start timer + /// + /// if(This->HeciTimeout == 0){ + /// Current = Start + 1; + /// } + /// + /// Test basic case (no overflow) + /// + if ((Start < End) && (End <= Current)) { + return EFI_TIMEOUT; + } + /// + /// Test basic start/end conditions with overflowed timer + /// + if ((Start < End) && (Current < Start)) { + return EFI_TIMEOUT; + } + /// + /// Test for overflowed start/end condition + /// + if ((Start > End) && ((Current < Start) && (Current > End))) { + return EFI_TIMEOUT; + } + /// + /// Catch corner case of broken arguments + /// + if (Start == End) { + return EFI_TIMEOUT; + } + /// + /// Else, we have not yet timed out + /// + return EFI_SUCCESS; +} + +/** + Get an abstract Intel ME Status from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MeStatus Pointer for status report, + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *MeStatus + ) +{ + HECI_FWS_REGISTER MeFirmwareStatus; + + if (MeStatus == NULL) { + return EFI_INVALID_PARAMETER; + } + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + if (MeFirmwareStatus.r.CurrentState == ME_STATE_NORMAL && MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_NO_ERROR) { + *MeStatus = ME_READY; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_RECOVERY) { + *MeStatus = ME_IN_RECOVERY_MODE; + } else { + *MeStatus = ME_NOT_READY; + } + + if (MeFirmwareStatus.r.FwInitComplete == ME_FIRMWARE_COMPLETED) { + *MeStatus |= ME_FW_INIT_COMPLETE; + } + + DEBUG ((EFI_D_ERROR, "HECI MeStatus %X\n", MeFirmwareStatus.ul)); + + return EFI_SUCCESS; +} + +/** + Get an abstract ME operation mode from firmware status + register. This is used to control BIOS flow for different + Intel ME functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MeMode Pointer for ME Mode report, + see MeState.h - Abstract ME Mode definitions. + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *MeMode + ) +{ + HECI_FWS_REGISTER MeFirmwareStatus; + + if (MeMode == NULL) { + return EFI_INVALID_PARAMETER; + } + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + switch (MeFirmwareStatus.r.MeOperationMode) { + case ME_OPERATION_MODE_NORMAL: + *MeMode = ME_MODE_NORMAL; + break; + + case ME_OPERATION_MODE_DEBUG: + *MeMode = ME_MODE_DEBUG; + break; + + case ME_OPERATION_MODE_SOFT_TEMP_DISABLE: + *MeMode = ME_MODE_TEMP_DISABLED; + break; + + case ME_OPERATION_MODE_SECOVR_JMPR: + case ME_OPERATION_MODE_SECOVR_HECI_MSG: + *MeMode = ME_MODE_SECOVER; + break; + + default: + *MeMode = ME_MODE_FAILED; + } + DEBUG ((EFI_D_ERROR, "HECI MeMode %X\n", MeFirmwareStatus.r.MeOperationMode)); + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/Heci/Pei/HeciInit.c b/ReferenceCode/ME/Heci/Pei/HeciInit.c new file mode 100644 index 0000000..0375bd7 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciInit.c @@ -0,0 +1,182 @@ +/** @file + Framework PEIM to HECI. + +@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 +**/ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +// +// Statements that include other files +// +#include "HeciInit.h" +#endif +// +// Function Declarations +// +static PEI_HECI_PPI mHeciPpi = { + HeciSendwAck, + HeciReadMsg, + HeciSendMsg, + InitializeHeci, + HeciGetMeStatus, + HeciGetMeMode +}; + +static EFI_PEI_PPI_DESCRIPTOR mInstallHeciPpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiHeciPpiGuid, + &mHeciPpi +}; + +// +// Function Implementations +// + +/** + Internal function performing Heci platform PPIs init needed in PEI phase + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_DEVICE_ERROR ME FPT is bad +**/ +EFI_STATUS +EFIAPI +PeiInstallHeciPpi ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + /// + /// Check for ME FPT Bad + /// + if ((HeciPciRead32 (R_FWSTATE) & 0x0020) != 0) { + + return EFI_DEVICE_ERROR; + } + /// + /// Initialize Heci platform PPIs + /// Do not use EdkIIGlueLib here because PeiService pointer used in GlueLib + /// is not updated after memory installed. + /// + Status = (**PeiServices).InstallPpi (PeiServices, &mInstallHeciPpi); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_ERROR, "Install Heci Ppi Complete.\n")); + return Status; +} + +/** + Internal function performing PM register initialization for Me + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +MePmInit ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINT16 PmBase; + UINT16 Pm1Cnt; + + /// + /// Before system memory initialization, BIOS should check the WAK_STS bit in PM1_STS[15] (PCH register PMBASE+00h) + /// to determine if Intel Management Engine has reset the system while the host was in a sleep state. If WAK_STS is + /// not set, BIOS should ensure a non-sleep exit path is taken. One way to accomplish this is by overwriting + /// PM1_CNT[12:10] (PCH register PMBASE+04h) to 111b to force an S5 exit path by the BIOS. + /// + PmBase = PciRead16 ( + PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + 0, + R_PCH_LPC_ACPI_BASE) + ) & B_PCH_LPC_ACPI_BASE_BAR; + + ASSERT (PmBase != 0); + + if (PmBase != 0) { + if ((IoRead16 (PmBase + R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_WAK) == 0) { + Pm1Cnt = IoRead16 (PmBase + R_PCH_ACPI_PM1_CNT) | V_PCH_ACPI_PM1_CNT_S5; + IoWrite16 (PmBase + R_PCH_ACPI_PM1_CNT, Pm1Cnt); + DEBUG ((EFI_D_ERROR, "Force an S5 exit path.\n")); + } + } + + return EFI_SUCCESS; +} + +/** + Internal function performing Me initialization. + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Heci initialization completed successfully. + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +EFIAPI +MeInit ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + Status = MePmInit (PeiServices); + return Status; +} + +/** + Initialize ME after reset + + @param[in] FfsHeader Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Heci initialization completed successfully. + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PeimHeciInit ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + /// + /// Performing Me initialization + /// + Status = MeInit (PeiServices); + ASSERT_EFI_ERROR (Status); + + Status = PeiInstallHeciPpi (PeiServices); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "(ICC) Failed to PeiInstallHeciPpi! Status = %r\n", Status)); + } else { + DEBUG ((EFI_D_INFO, "HeciInit Complete.\n")); + } + + return Status; +} diff --git a/ReferenceCode/ME/Heci/Pei/HeciInit.dxs b/ReferenceCode/ME/Heci/Pei/HeciInit.dxs new file mode 100644 index 0000000..2db83cd --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciInit.dxs @@ -0,0 +1,45 @@ +/** @file + Dependency expression file for Heci Init PEIM. + +@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 + +**/ + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "PeimDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" + +#endif + + +DEPENDENCY_START + + TRUE +DEPENDENCY_END + + + + diff --git a/ReferenceCode/ME/Heci/Pei/HeciInit.h b/ReferenceCode/ME/Heci/Pei/HeciInit.h new file mode 100644 index 0000000..a8dab69 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciInit.h @@ -0,0 +1,390 @@ +/** @file + Framework PEIM to provide Heci. + +@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 _HECI_INIT_H_ +#define _HECI_INIT_H_ + +#include "EdkIIGluePeim.h" +#include "MeAccess.h" +#include "HeciRegs.h" +#include "MeState.h" +#include "CoreBiosMsg.h" +#include "Pci22.h" + +// +// Driver Consumed PPI Prototypes +// +#include EFI_PPI_DEPENDENCY (CpuIo) +#include EFI_PPI_DEPENDENCY (PciCfg) +#include EFI_PPI_DEPENDENCY (Heci) +#include EFI_PPI_DEPENDENCY (MemoryDiscovered) + +// +// Prototypes +// + +/** + Enable Hpet function. + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval UINT32 Return the High Precision Event Timer base address +**/ +VOLATILE +UINT32 * +EnableHpet ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI + @param[in][out] HeciMemBar HECI Memory BAR + + @retval None +**/ +VOID +CheckAndFixHeciForAccess ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *HeciMemBar + ) +; + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI + @param[in][out] HeciMemBar HECI Memory BAR + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_DEVICE_ERROR No HECI device + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @exception EFI_UNSUPPORTED HECI MSG is unsupported +**/ +EFI_STATUS +EFIAPI +InitializeHeci ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *HeciMemBar + ) +; + +/** + Waits for the ME to report that it is ready for communication over the HECI + interface. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_TIMEOUT If 5 second timeout has expired, return fail. +**/ +EFI_STATUS +WaitForMEReady ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 HeciMemBar + ) +; + +/** + Read the HECI Message from Intel ME with size in Length into + buffer Message. Set Blocking to BLOCKING and code will wait + until one message packet is received. When set to + NON_BLOCKING, if the circular buffer is empty at the time, the + code not wait for the message packet read. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @exception EFI_UNSUPPORTED Current ME mode doesn't support this function + @retval EFI_SUCCESS One message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_DEVICE_ERROR Zero-length message packet read + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +EFI_STATUS +EFIAPI +HeciReadMsg ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 Blocking, + IN UINT32 HeciMemBar, + IN UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +; + +/** + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[out] MessageHeader Pointer to a buffer for the message header. + @param[out] MessageData Pointer to a buffer to recieve the message in. + @param[in][out] Length On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR The circular buffer is overflowed. + @retval EFI_NO_RESPONSE The circular buffer is empty + @retval EFI_TIMEOUT Failed to receive a full message + @retval EFI_BUFFER_TOO_SMALL Message packet is larger than caller's buffer +**/ +EFI_STATUS +HeciPacketRead ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 Blocking, + IN UINT32 HeciMemBar, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +; + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HEC +**/ +EFI_STATUS +HeciSendMsg ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 *Message, + IN UINT32 HeciMemBar, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +; + +/** + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] MessageHeader Pointer to the message header. + @param[in] MessageData Pointer to the actual message data. + + @retval EFI_SUCCESS One message packet sent + @retval EFI_DEVICE_ERROR ME is not ready + @retval EFI_TIMEOUT HECI is not ready for communication +**/ +EFI_STATUS +HeciPacketWrite ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 HeciMemBar, + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +; + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in][out] Message Pointer to the message buffer. + @param[in] HeciMemBar HECI Memory BAR. + @param[in][out] Length Length of the message in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @retval EFI_TIMEOUT HECI does not return the bufferbefore timeout + @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +EFI_STATUS +HeciSendwAck ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *Message, + IN UINT32 HeciMemBar, + IN OUT UINT32 *Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +; + +/** + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + @param[in] ReadPointer Value read from host/me read pointer + @param[in] WritePointer Value read from host/me write pointer + @param[in] BufferDepth Value read from buffer depth register + + @retval EFI_DEVICE_ERROR The circular buffer has overflowed + @retval EFI_SUCCESS The circular buffer does not overflowed +**/ +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +; + +/** + Used for calculating timeouts + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] Start Snapshot of the HPET timer + @param[in] End Calculated time when timeout period will be done + @param[in] Time Timeout period in microseconds + + @retval None +**/ +VOLATILE +UINT32 * +StartTimer ( + IN EFI_PEI_SERVICES **PeiServices, + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +; + +/** + Used to determine if a timeout has occured. + + @param[in] Start Snapshot of the HPET timer when the timeout period started. + @param[in] End Calculated time when timeout period will be done. + @param[in] HpetTimer The value of High Precision Event Timer + + @retval EFI_TIMEOUT Timeout occured. + @retval EFI_SUCCESS Not yet timed out +**/ +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End, + IN VOLATILE UINT32 *HpetTimer + ) +; + +/** + Get an abstract Intel ME Status from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MeStatus Pointer for status report, + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *MeStatus + ) +; + +/** + Get an abstract ME operation mode from firmware status + register. This is used to control BIOS flow for different + Intel ME functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MeMode Pointer for ME Mode report, + see MeState.h - Abstract ME Mode definitions. + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +EFI_STATUS +EFIAPI +HeciGetMeMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *MeMode + ) +; + +/** + Initialize ME after reset + + @param[in] FfsHeader Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Heci initialization completed successfully. + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PeimHeciInit ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + 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 +FilledSlots ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer + ) +; +#endif // _HECI_INIT_H_ diff --git a/ReferenceCode/ME/Heci/Pei/HeciInit.inf b/ReferenceCode/ME/Heci/Pei/HeciInit.inf new file mode 100644 index 0000000..2181282 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciInit.inf @@ -0,0 +1,82 @@ +## @file +# Component description file for HeciInit module +# +#@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 = HeciInit +FILE_GUID = 4862aff3-667c-5458-b274-a1c62df8ba80 +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + HeciInit.c + HeciInit.h + HeciCore.c + ../Include/HeciRegs.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(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/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + + + +[libraries.common] + EdkFrameworkPpiLib + MeLibPpi + EdkIIGlueBaseIoLibIntrinsic + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + EdkPpiLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = HeciInit.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeimHeciInit + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ diff --git a/ReferenceCode/ME/Heci/Pei/HeciPei.cif b/ReferenceCode/ME/Heci/Pei/HeciPei.cif new file mode 100644 index 0000000..c009607 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciPei.cif @@ -0,0 +1,14 @@ +<component> + name = "HeciPei" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Heci\Pei\" + RefName = "HeciPei" +[files] +"HeciPei.sdl" +"HeciPei.mak" +"HeciCore.c" +"HeciInit.c" +"HeciInit.dxs" +"HeciInit.h" +"HeciInit.inf" +<endComponent> diff --git a/ReferenceCode/ME/Heci/Pei/HeciPei.mak b/ReferenceCode/ME/Heci/Pei/HeciPei.mak new file mode 100644 index 0000000..990bcf1 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciPei.mak @@ -0,0 +1,48 @@ +# MAK file for the ModulePart:HeciPei + +all: HeciPei + +$(BUILD_DIR)\HeciPei.mak : $(HeciPei_DIR)\HeciPei.cif $(BUILD_RULES) + $(CIF2MAK) $(HeciPei_DIR)\HeciPei.cif $(CIF2MAK_DEFAULTS) + +HeciPei: $(BUILD_DIR)\HeciPei.mak HeciPeiBin + +HeciPei_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + + +HeciPei_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PeimHeciInit"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__\ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + +HeciPei_LIBS =\ + $(EDKPROTOCOLLIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + + +HeciPeiBin : $(EDKFRAMEWORKPPILIB) $(MeLibPpi_LIB) $(HeciPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\HeciPei.mak all\ + NAME=HeciPei\ + MAKEFILE=$(BUILD_DIR)\HeciPei.mak \ + GUID=9cf30325-dc5c-4556-a8b0-74215c5f7fc4\ + "MY_INCLUDES=$(HeciPei_INCLUDES)" \ + "MY_DEFINES=$(HeciPei_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(HeciPei_DIR)\HeciInit.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 diff --git a/ReferenceCode/ME/Heci/Pei/HeciPei.sdl b/ReferenceCode/ME/Heci/Pei/HeciPei.sdl new file mode 100644 index 0000000..e193446 --- /dev/null +++ b/ReferenceCode/ME/Heci/Pei/HeciPei.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = HeciPei_SUPPORT + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable HeciPei support in Project" +End +MODULE + Help = "Includes HeciPei.mak to Project" + File = "HeciPei.mak" +End + +PATH + Name = "HeciPei_DIR" + Help = "Me Heci Pei file source directory" +End + +ELINK + Name = "$(BUILD_DIR)\HeciPei.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Heci/Smm/HeciHpet.c b/ReferenceCode/ME/Heci/Smm/HeciHpet.c new file mode 100644 index 0000000..2f75571 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciHpet.c @@ -0,0 +1,282 @@ +/*++ + 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) 2006 - 2010 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. + +Module Name: + + HeciHpet.c + +Abstract: + + Definitions for HECI driver + +--*/ +#include "HeciHpet.h" +#include "HeciRegs.h" +#include "HeciCore.h" + +// +// Extern for shared HECI data and protocols +// +extern HECI_INSTANCE_SMM *mHeciContext; +VOLATILE UINT32 mSaveHpetConfigReg; + +VOID +SaveHpet ( + VOID + ) +/*++ + +Routine Description: + + Store the value of High Performance Timer + +Arguments: + + None + +Returns: + + None + +--*/ +{ + mSaveHpetConfigReg = MmioRead32 (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); +} + +VOID +RestoreHpet ( + VOID + ) +/*++ + +Routine Description: + + Restore the value of High Performance Timer + +Arguments: + + None + +Returns: + + None + +--*/ +{ + MmioWrite32 (PCH_RCRB_BASE + R_PCH_RCRB_HPTC, mSaveHpetConfigReg); +} + +VOID +StartTimer ( + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +/*++ + + Routine Description: + + Used for calculating timeouts + + Arguments: + + Start - Snapshot of the HPET timer + End - Calculated time when timeout period will be done + Time - Timeout period in microseconds + + Returns: + + VOID + +--*/ +{ + UINT32 Ticks; + + // + // Make sure that HPET is enabled and running + // + EnableHpet (); + + // + // Read current timer value into start time from HPET + // + *Start = mHeciContext->HpetTimer[HPET_MAIN_COUNTER_LOW]; + + // + // Convert microseconds into 70ns timer ticks + // + Ticks = Time * HPET_TICKS_PER_MICRO; + + // + // Compute end time + // + *End = *Start + Ticks; + + return ; +} + +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End + ) +/*++ + + Routine Description: + Used to determine if a timeout has occured. + + Arguments: + Start - Snapshot of the HPET timer when the timeout period started. + End - Calculated time when timeout period will be done. + + Returns: + EFI_STATUS + +--*/ +{ + UINT32 Current; + + // + // Read HPET and assign the value as the current time. + // + Current = mHeciContext->HpetTimer[HPET_MAIN_COUNTER_LOW]; + + // + // Test basic case (no overflow) + // + if ((Start < End) && (End <= Current)) { + return EFI_TIMEOUT; + } + // + // Test basic start/end conditions with overflowed timer + // + if ((Start < End) && (Current < Start)) { + return EFI_TIMEOUT; + } + // + // Test for overflowed start/end condition + // + if ((Start > End) && ((Current < Start) && (Current > End))) { + return EFI_TIMEOUT; + } + // + // Catch corner case of broken arguments + // + if (Start == End) { + return EFI_TIMEOUT; + } + // + // Else, we have not yet timed out + // + return EFI_SUCCESS; +} + +VOID +IoDelay ( + UINT32 delayTime + ) +/*++ + +Routine Description: + + Delay for at least the request number of microseconds + +Arguments: + + delayTime - Number of microseconds to delay. + +Returns: + + None. + +--*/ +{ + SmmStall (delayTime); +} + +VOID +SmmStall ( + IN UINTN Microseconds + ) +/*++ + +Routine Description: + + Delay for at least the request number of microseconds. + Timer used is DMA refresh timer, which has 15us granularity. + You can call with any number of microseconds, but this + implementation cannot support 1us granularity. + +Arguments: + + Microseconds - Number of microseconds to delay. + +Returns: + + None + +--*/ +{ + UINT8 Data; + UINT8 InitialState; + UINTN CycleIterations; + + CycleIterations = 0; + Data = 0; + InitialState = 0; + + // + // The time-source is 15 us granular, so calibrate the timing loop + // based on this baseline + // Error is possible 15us. + // + CycleIterations = (Microseconds / 15) + 1; + + // + // Use the DMA Refresh timer in port 0x61. Cheap but effective. + // The only issue is that the granularity is 15us, and we want to + // guarantee "at least" one full transition to avoid races. + // + // + // _____________/----------\__________/-------- + // + // |<--15us-->| + // + // --------------------------------------------------> Time (us) + // + while (CycleIterations--) { + Data = IoRead8 (0x61); + InitialState = Data; + + // + // Capture first transition (strictly less than one period) + // + while (InitialState == Data) { + Data = IoRead8 (0x61); + } + + InitialState = Data; + // + // Capture next transition (guarantee at least one full pulse) + // + while (InitialState == Data) { + Data = IoRead8 (0x61); + } + } +} diff --git a/ReferenceCode/ME/Heci/Smm/HeciHpet.h b/ReferenceCode/ME/Heci/Smm/HeciHpet.h new file mode 100644 index 0000000..8624445 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciHpet.h @@ -0,0 +1,197 @@ +/*++ + 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) 2006 - 2010 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. + +Module Name: + + HeciHpet.h + +Abstract: + + Definitions for HECI driver + +--*/ +#ifndef _HECI_HPET_H +#define _HECI_HPET_H + +#include "EdkIIGlueDxe.h" +#include "MeAccess.h" +#include "HeciRegs.h" +#include "Pci22.h" + +#define HECI_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('H', 'e', 'c', 'i') +#define HECI_ROUND_UP_BUFFER_LENGTH(Length) ((UINT32) ((((Length) + 3) / 4) * 4)) + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_PRODUCER (HeciSmm) + +VOID +SaveHpet ( + VOID + ) +/*++ + +Routine Description: + + Store the value of High Performance Timer + +Arguments: + + None + +Returns: + + None + +--*/ +; + +VOID +RestoreHpet ( + VOID + ) +/*++ + +Routine Description: + + Restore the value of High Performance Timer + +Arguments: + + None + +Returns: + + None + +--*/ +; + +VOID +StartTimer ( + OUT UINT32 *Start, + OUT UINT32 *End, + IN UINT32 Time + ) +/*++ + + Routine Description: + + Used for calculating timeouts + + Arguments: + + Start - Snapshot of the HPET timer + End - Calculated time when timeout period will be done + Time - Timeout period in microseconds + + Returns: + + VOID + +--*/ +; + +EFI_STATUS +Timeout ( + IN UINT32 Start, + IN UINT32 End + ) +/*++ + + Routine Description: + Used to determine if a timeout has occured. + + Arguments: + Start - Snapshot of the HPET timer when the timeout period started. + End - Calculated time when timeout period will be done. + + Returns: + EFI_STATUS + +--*/ +; + +VOID +EnableHpet ( + VOID + ) +/*++ + +Routine Description: + + Enable Hpet function. + +Arguments: + + None. + +Returns: + + None. + +--*/ +; + +VOID +IoDelay ( + UINT32 delayTime + ) +/*++ + +Routine Description: + + Delay for at least the request number of microseconds + +Arguments: + + delayTime - Number of microseconds to delay. + +Returns: + + None. + +--*/ +; + +VOID +SmmStall ( + IN UINTN Microseconds + ) +/*++ + +Routine Description: + + Delay for at least the request number of microseconds. + Timer used is DMA refresh timer, which has 15us granularity. + You can call with any number of microseconds, but this + implementation cannot support 1us granularity. + +Arguments: + + Microseconds - Number of microseconds to delay. + +Returns: + + None + +--*/ +; +#endif // _HECI_HPET_H diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.c b/ReferenceCode/ME/Heci/Smm/HeciSmm.c new file mode 100644 index 0000000..df1f165 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.c @@ -0,0 +1,228 @@ +/*++ + 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) 2008 - 2010 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. + +Module Name: + + HeciSmm.c + +Abstract: + + SMM HECI driver + +--*/ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "HeciHpet.h" +#include "HeciCore.h" +#endif // EDK_RELEASE_VERSION +// +// Global driver data +// +EFI_SMM_BASE_PROTOCOL *mSmmBase; +HECI_INSTANCE_SMM *mHeciContext; + +UINT32 +CheckAndFixHeciForAccess ( + VOID + ) +/*++ + +Routine Description: + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + +Arguments: + None. + +Returns: + VOID + +--*/ +{ + UINTN HeciPciAddressBase; + + HeciPciAddressBase = mHeciContext->PciAddressBase; + + // + // Read HECI_MBAR in case it has changed + // + mHeciContext->HeciMBAR = PciRead32 (HeciPciAddressBase + R_HECIMBAR) & 0xFFFFFFF0; + + // + // Check if HECI_MBAR is disabled + // + if (( + PciRead8 (HeciPciAddressBase + PCI_COMMAND_OFFSET) & (EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) + ) != (EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) + ) { + // + // If cmd reg in pci cfg space is not turned on turn it on. + // + PciOr8 ( + HeciPciAddressBase + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + } + + return mHeciContext->HeciMBAR; +} + +VOID +EnableHpet ( + VOID + ) +/*++ + +Routine Description: + + Enable Hpet function. + +Arguments: + + None. + +Returns: + + None. + +--*/ +{ + VOLATILE UINT32 *HpetConfigReg; + + HpetConfigReg = NULL; + // + // Get the High Precision Event Timer base address and enable the memory range + // + HpetConfigReg = (UINT32 *) (UINTN) (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); + switch (*HpetConfigReg & B_PCH_RCRB_HPTC_AS) { + case 0: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_0); + break; + + case 1: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_1); + break; + + case 2: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_2); + break; + + case 3: + mHeciContext->HpetTimer = (VOID *) (UINTN) (HPET_ADDRESS_3); + break; + + default: + mHeciContext->HpetTimer = NULL; + break; + } + // + // Read this back to force the write-back. + // + *HpetConfigReg = *HpetConfigReg | B_PCH_RCRB_HPTC_AE; + + // + // Start the timer so it is up and running + // + mHeciContext->HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START; + mHeciContext->HpetTimer[HPET_GEN_CONFIG_LOW] = HPET_START; + + return ; +} + +EFI_STATUS +InitializeHECI ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + HECI driver entry point used to initialize support for the HECI device. + +Arguments: + ImageHandle - Standard entry point parameter. + SystemTable - Standard entry point parameter. + +Returns: + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &mSmmBase); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Create database record and add to database + // + Status = mSmmBase->SmmAllocatePool ( + mSmmBase, + EfiRuntimeServicesData, + sizeof (HECI_INSTANCE_SMM), + &mHeciContext + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + mHeciContext->Handle = ImageHandle; + + // + // Initialize HECI protocol pointers + // + mHeciContext->HeciCtlr.ResetHeci = ResetHeciInterface; + mHeciContext->HeciCtlr.SendwACK = HeciSendwACK; + mHeciContext->HeciCtlr.ReadMsg = HeciReceive; + mHeciContext->HeciCtlr.SendMsg = HeciSend; + mHeciContext->HeciCtlr.InitHeci = HeciInitialize; + mHeciContext->HeciCtlr.ReInitHeci = HeciReInitialize; + mHeciContext->HeciCtlr.MeResetWait = MeResetWait; + mHeciContext->HeciCtlr.GetMeStatus = HeciGetMeStatus; + mHeciContext->HeciCtlr.GetMeMode = HeciGetMeMode; + // + // Initialize the HECI device + // + Status = InitializeHeciPrivate (); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + // + // Install the HECI interface + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mHeciContext->Handle, + &gSmmHeciProtocolGuid, + &mHeciContext->HeciCtlr, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.cif b/ReferenceCode/ME/Heci/Smm/HeciSmm.cif new file mode 100644 index 0000000..3ddcf24 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.cif @@ -0,0 +1,16 @@ +<component> + name = "HeciSmm" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Heci\Smm\" + RefName = "HeciSmm" +[files] +"HeciSmm.sdl" +"HeciSmm.mak" +"Hecicore.c" +"Hecicore.h" +"HeciSmm.c" +"HeciSmm.dxs" +"HeciHpet.c" +"HeciHpet.h" +"HeciSmm.inf" +<endComponent> diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.dxs b/ReferenceCode/ME/Heci/Smm/HeciSmm.dxs new file mode 100644 index 0000000..9c3676a --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.dxs @@ -0,0 +1,51 @@ +/*++ + 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 +--*/ +/*++ + +Copyright (c) 2010 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. + +Module Name: + + HeciSmm.dxs + +Abstract: + + Dependency expression source file. + +--*/ + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (SmmBase) +#include EFI_PROTOCOL_DEFINITION (CpuIo) +#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo) +#endif + +DEPENDENCY_START + EFI_CPU_IO_PROTOCOL_GUID AND + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID AND + EFI_SMM_BASE_PROTOCOL_GUID +DEPENDENCY_END + diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.inf b/ReferenceCode/ME/Heci/Smm/HeciSmm.inf new file mode 100644 index 0000000..600e1f2 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.inf @@ -0,0 +1,102 @@ +#/*++ +# 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 +#--*/ +#/*++ +# +# Copyright (c) 2007 - 2010 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. +# +# Module Name: +# +# HeciSmm.inf +# +# Abstract: +# +# Component description file for Heci SMM driver +# +#--*/ + +[defines] +BASE_NAME = HeciSmm +FILE_GUID = 921CD783-3E22-4579-A71F-00D74197FCC8 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + HeciSmm.c + Hecicore.c + HeciCore.h + HeciHpet.c + HeciHpet.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueSmmDriverEntryPoint.c + +[includes.common] + $(EDK_SOURCE)\Foundation + $(EDK_SOURCE)\Foundation\Framework + $(EDK_SOURCE)\Foundation\Efi + $(EDK_SOURCE)\Foundation\Include + $(EDK_SOURCE)\Foundation\Efi\Include + $(EDK_SOURCE)\Foundation\Framework\Include + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Include\IndustryStandard + $(EDK_SOURCE)\Foundation\Cpu\Pentium\Include + $(EFI_SOURCE)\$(PROJECT_ME_ROOT) + $(EFI_SOURCE)\$(PROJECT_ME_ROOT)\Library\MeKernel\Dxe + $(EFI_SOURCE)\$(PROJECT_ME_ROOT)\Library\MeKernel\Include + $(EFI_SOURCE)\$(PROJECT_ME_ROOT)\Heci\Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + $(EFI_SOURCE) + $(EFI_SOURCE)\Framework + $(EDK_SOURCE)\Foundation + $(EDK_SOURCE)\Foundation\Framework + $(EDK_SOURCE)\Foundation\Include\IndustryStandard + $(EDK_SOURCE)\Foundation\Core\Dxe + $(EDK_SOURCE)\Foundation\Include\Pei + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\Include + +[libraries.common] + MeProtocolLib + MeLib + MeChipsetLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueDxeMemoryAllocationLib + EdkIIGlueDxeServicesTableLib + EdkIIGluePeiDxeDebugLibReportStatusCode + EdkIIGlueSmmRuntimeDxeReportStatusCodeLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiDevicePathLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=HeciSmm.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) /D__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeHECI + C_FLAGS = $(C_FLAGS) /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \ + /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ + /D __EDKII_GLUE_PEI_DXE_DEBUG_LIB_REPORT_STATUS_CODE__\ + /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.mak b/ReferenceCode/ME/Heci/Smm/HeciSmm.mak new file mode 100644 index 0000000..31006bc --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.mak @@ -0,0 +1,64 @@ +# MAK file for the ModulePart:HeciSmm +all : HeciSmm + +HeciSmm : $(BUILD_DIR)\HeciSmm.mak HeciSmmBin + +$(BUILD_DIR)\HeciSmm.mak : $(HeciSmm_DIR)\$(@B).cif $(HeciSmm_DIR)\$(@B).mak $(CP_BUILD_RULES) + $(CIF2MAK) $(HeciSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +HeciSmm_INCLUDES= \ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + /I$(INTEL_COUGAR_POINT_INCLUDE_DIR) + + +HeciSmm_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(MeProtocolLib_LIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(MeGuidLib_LIB)\ + $(EFISCRIPTLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EFIGUIDLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EFIDRIVERLIB)\ + $(RcFviDxeLib_LIB)\ + $(PchPlatformDxeLib_LIB) + +HeciSmm_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeHECI"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /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_LIB__\ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ + +HeciSmmBin : $(HeciSmm_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\HeciSmm.mak all\ + MAKEFILE=$(BUILD_DIR)\HeciSmm.mak\ + "MY_INCLUDES=$(HeciSmm_INCLUDES)"\ + "MY_DEFINES=$(HeciSmm_DEFINES)"\ + GUID=921CD783-3E22-4579-A71F-00D74197FCC8\ + DEPEX1=$(HeciSmm_DIR)\HeciSmm.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=RT_DRIVER\ + EDKIIModule=SMMDRIVER\ + COMPRESS=1 diff --git a/ReferenceCode/ME/Heci/Smm/HeciSmm.sdl b/ReferenceCode/ME/Heci/Smm/HeciSmm.sdl new file mode 100644 index 0000000..3165eee --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/HeciSmm.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "HeciSmm_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable HeciSmm Suppport in Project" +End + +MODULE + Help = "Includes HeciSmm.mak to Project" + File = "HeciSmm.mak" +End + +ELINK + Name = "$(BUILD_DIR)\HeciSmm.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +PATH + Name = "HeciSmm_DIR" + Help = "iAMT Hec SMM Driver files source directory" +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Heci/Smm/Hecicore.c b/ReferenceCode/ME/Heci/Smm/Hecicore.c new file mode 100644 index 0000000..612f2f6 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/Hecicore.c @@ -0,0 +1,1585 @@ +/*++ + 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) 2008 - 2010 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. + +Module Name: + + Hecicore.c + +Abstract: + + Heci driver core. For Dxe Phase, determines the HECI device and initializes it. + +--*/ +#include "HeciHpet.h" +#include "HeciCore.h" +#include "HeciRegs.h" +#include "MeState.h" + +// +// ////////////////////////////////////////////////////////////////////////////////// +// Globals used in Heci driver +//////////////////////////////////////////////////////////////////////////////////// +// +UINT16 HECICtlrBDF; +static UINT32 HeciMBAR = 0; + +// +// ////////////////////////////////////////////////////////////////////////////////// +// Macro definition for function used in Heci driver +//////////////////////////////////////////////////////////////////////////////////// +// +#define R_PCH_RCRB_FUNC_DIS2 0x3428 + +UINT32 +MmIoReadDword ( + UINTN a + ) +/*++ + +Routine Description: + + The routing of MmIo Read Dword + +Arguments: + + a - The address of Mmio + +Returns: + + Return the valut of MmIo Read + +--*/ +{ + volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + + HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a; + return HeciRegHCsrPtr->ul; +} + +VOID +MmIoWriteDword ( + UINTN a, + UINT32 b + ) +/*++ + +Routine Description: + + The routing of MmIo Write Dword + +Arguments: + + a - The address of Mmio + b - Value revised + +Returns: + + None + +--*/ +{ + volatile HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + + HeciRegHCsrPtr = (HECI_HOST_CONTROL_REGISTER *) a; + + HeciRegHCsrPtr->ul = b; +} + +#define MMIOREADDWORD(a) MmIoReadDword (a) +#define MMIOWRITEDWORD(a, b) MmIoWriteDword (a, b) + +// +// Extern for shared HECI data and protocols +// +extern HECI_INSTANCE_SMM *mHeciContext; + +// +// ////////////////////////////////////////////////////////////////////////////////// +// Forward declaration +//////////////////////////////////////////////////////////////////////////////////// +// +UINT8 +FilledSlots ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer + ); + +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ); + +EFI_STATUS +WaitForMEReady ( + VOID + ); + +// +// Heci driver function definitions +// +EFI_STATUS +InitializeHeciPrivate ( + VOID + ) +/*++ + + Routine Description: + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr; + UINT32 MeMode; + EFI_STATUS Status; + UINTN HeciPciAddressBase; + + Status = EFI_SUCCESS; + + SaveHpet (); + + do { + // + // Check for ME FPT Bad + // + if ((HeciPciRead32 (R_FWSTATE) & 0x0020) != 0) { + Status = EFI_DEVICE_ERROR; + break; + } + // + // Check for ME error status + // + if ((HeciPciRead32 (R_FWSTATE) & 0xF000) != 0) { + // + // ME failed to start so no HECI + // + Status = EFI_DEVICE_ERROR; + break; + } + // + // Check ME Operation Mode to decice which HECI to use in SMM mode + // + Status = HeciGetMeMode (&MeMode); + ASSERT_EFI_ERROR (Status); + + // + // HECI MSG is unsupported if ME MODE is in Security Override + // + mHeciContext->MeMode = MeMode; + if (mHeciContext->MeMode == ME_MODE_DEBUG) { + Status = EFI_UNSUPPORTED; + break; + } + + HeciPciAddressBase = PCI_LIB_ADDRESS ( + ME_BUS, + ME_DEVICE_NUMBER, + HECI_FUNCTION_NUMBER, + 0 + ); + mHeciContext->HeciDevSaveEnable = Heci2DevSaveEnable; + mHeciContext->PciAddressBase = HeciPciAddressBase; + + // + // Store HECI vendor and device information away + // + mHeciContext->DeviceInfo = PciRead16 (HeciPciAddressBase + PCI_DEVICE_ID_OFFSET); + + // + // Check for HECI-2 PCI device availability + // + if (mHeciContext->DeviceInfo == 0xFFFF) { + Status = EFI_DEVICE_ERROR; + break; + } + // + // Store HECI revision ID + // + mHeciContext->RevisionInfo = PciRead8 (HeciPciAddressBase + PCI_REVISION_ID_OFFSET); + + // + // Get HECI_MBAR and see if it is programmed + // to a useable value + // + mHeciContext->HeciMBAR = PciRead32 (HeciPciAddressBase + R_HECIMBAR) & 0xFFFFFFF0; + HeciMBAR = mHeciContext->HeciMBAR; + + // + // Load temporary address for HECI_MBAR if one is not assigned + // + if (mHeciContext->HeciMBAR == 0) { + // + // mHeciContext->HeciMBAR = mHeciContext->DefaultHeciBar; + // PciWrite32 (HeciPciAddressBase + R_HECIMBAR, mHeciContext->HeciMBAR); + // HeciMBAR = mHeciContext->HeciMBAR; + // + DEBUG ((EFI_D_ERROR, "Heci MMIO Bar not programmed in SMM phase\n")); + } + // + // Enable HECI BME and MSE + // + PciOr8 ( + HeciPciAddressBase + PCI_COMMAND_OFFSET, + EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER + ); + + // + // Set HECI interrupt delivery mode. + // HECI-2 using legacy/MSI interrupt + // + PciAnd8 (HeciPciAddressBase + R_HIDM, 0xFC); + + // + // Need to do following on ME init: + // + // 1) wait for ME_CSR_HA reg ME_RDY bit set + // + if (WaitForMEReady () != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + break; + } + // + // 2) setup H_CSR reg as follows: + // a) Make sure H_RST is clear + // b) Set H_RDY + // c) Set H_IG + // + HeciRegHCsrPtr = (VOID *) (UINTN) (mHeciContext->HeciMBAR + H_CSR); + HeciRegHCsr.ul = HeciRegHCsrPtr->ul; + if (HeciRegHCsrPtr->r.H_RDY == 0) { + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsrPtr->ul = HeciRegHCsr.ul; + } + + } while (EFI_ERROR (Status)); + + RestoreHpet (); + + return Status; +} + +EFI_STATUS +WaitForMEReady ( + VOID + ) +/*++ + + Routine Description: + Waits for the ME to report that it is ready for communication over the HECI + interface. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +{ + UINT32 TimerStart; + UINT32 TimerEnd; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + // + // Wait for ME ready + // + // + // Check for ME ready status + // + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + // + // If 5 second timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Perform IO delay + // + IoDelay (HECI_WAIT_DELAY); + + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + // + // ME ready!!! + // + return EFI_SUCCESS; +} + +BOOLEAN +CheckForHeciReset ( + VOID + ) +/*++ + + Routine Description: + Checks if HECI reset has occured. + + Arguments: + None. + + Returns: + TRUE - HECI reset occurred + FALSE - No HECI reset occurred + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + // + // Init Host & ME CSR + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + + if ((HeciRegMeCsrHa.r.ME_RDY_HRA == 0) || (HeciRegHCsr.r.H_RDY == 0)) { + return TRUE; + } + + return FALSE; +} + +EFI_STATUS +HeciInitialize ( + VOID + ) +/*++ + + Routine Description: + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + + // + // Make sure that HECI device BAR is correct and device is enabled. + // + HeciMBAR = CheckAndFixHeciForAccess (); + + // + // Need to do following on ME init: + // + // 1) wait for ME_CSR_HA reg ME_RDY bit set + // + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // 2) setup H_CSR reg as follows: + // a) Make sure H_RST is clear + // b) Set H_RDY + // c) Set H_IG + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + if (HeciRegHCsr.r.H_RDY == 0) { + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_RDY = 1; + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +HeciReInitialize ( + VOID + ) +/*++ + + Routine Description: + Heci Re-initializes it for Host + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + // + // Need to do following on ME init: + // + // 1) wait for HOST_CSR_HA reg H_RDY bit set + // + // if (WaitForHostReady() != EFI_SUCCESS) { + // + if (MeResetWait (HECI_INIT_TIMEOUT) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + if (HeciRegHCsr.r.H_RDY == 0) { + Status = ResetHeciInterface (); + + } + + return Status; +} + +EFI_STATUS +EFIAPI +HeciReInitialize2 ( + VOID + ) +/*++ + + Routine Description: + Heci Re-initializes it for Me + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +{ + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + EFI_STATUS Status; + UINT32 TimerStart; + UINT32 TimerEnd; + Status = EFI_SUCCESS; + // + // Need to do following on ME init: + // + // 1) wait for HOST_CSR_HA reg H_RDY bit set + // + // if (WaitForHostReady() != EFI_SUCCESS) { + // + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (HeciRegMeCsrHa.r.ME_RDY_HRA == 1) { + // + // If 5 second timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + IoDelay (HECI_WAIT_DELAY); + + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + return Status; +} + +EFI_STATUS +HECIPacketRead ( + IN UINT32 Blocking, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +/*++ + + Routine Description: + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + + Arguments: + Blocking - Used to determine if the read is BLOCKING or NON_BLOCKING. + MessageHeader - Pointer to a buffer for the message header. + MessageData - Pointer to a buffer to recieve the message in. + Length - On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + Returns: + EFI_STATUS + +--*/ +{ + BOOLEAN GotMessage; + UINT32 TimerStart; + UINT32 TimerEnd; + UINT32 TimerStart1; + UINT32 TimerEnd1; + UINT32 i; + UINT32 LengthInDwords; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + + GotMessage = FALSE; + // + // Initialize memory mapped register pointers + // + // VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr = (VOID*)(mHeciContext->HeciMBAR + H_CSR); + // VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr = (VOID*)(mHeciContext->HeciMBAR + ME_CSR_HA); + // VOLATILE UINT32 *HeciRegMeCbrwPtr = (VOID*)(mHeciContext->HeciMBAR + ME_CB_RW); + // + // clear Interrupt Status bit + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IS = 1; + + // + // test for circular buffer overflow + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (OverflowCB ( + HeciRegMeCsrHa.r.ME_CBRP_HRA, + HeciRegMeCsrHa.r.ME_CBWP_HRA, + HeciRegMeCsrHa.r.ME_CBD_HRA + ) != EFI_SUCCESS) { + // + // if we get here, the circular buffer is overflowed + // + *Length = 0; + return EFI_DEVICE_ERROR; + } + // + // If NON_BLOCKING, exit if the circular buffer is empty + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA);; + if ((FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) == 0) && (Blocking == NON_BLOCKING)) { + *Length = 0; + return EFI_NO_RESPONSE; + } + // + // Start timeout counter + // + StartTimer (&TimerStart, &TimerEnd, HECI_READ_TIMEOUT); + + // + // loop until we get a message packet + // + while (!GotMessage) { + // + // If 1 second timeout has expired, return fail as we have not yet received a full message. + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + // + // Read one message from HECI buffer and advance read pointer. Make sure + // that we do not pass the write pointer. + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA);; + if (FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA) > 0) { + // + // Eat the HECI Message header + // + MessageHeader->Data = MMIOREADDWORD (HeciMBAR + ME_CB_RW); + + // + // Compute required message length in DWORDS + // + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + // + // Just return success if Length is 0 + // + if (MessageHeader->Fields.Length == 0) { + // + // Set Interrupt Generate bit and return + // + MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + *Length = 0; + return EFI_SUCCESS; + } + // + // Make sure that the message does not overflow the circular buffer. + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if ((MessageHeader->Fields.Length + sizeof (HECI_MESSAGE_HEADER)) > (HeciRegMeCsrHa.r.ME_CBD_HRA * 4)) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + // + // Make sure that the callers buffer can hold the correct number of DWORDS + // + if ((MessageHeader->Fields.Length) <= *Length) { + // + // Start timeout counter for inner loop + // + StartTimer (&TimerStart1, &TimerEnd1, HECI_READ_TIMEOUT); + + // + // Wait here until entire message is present in circular buffer + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + while (LengthInDwords > FilledSlots (HeciRegMeCsrHa.r.ME_CBRP_HRA, HeciRegMeCsrHa.r.ME_CBWP_HRA)) { + // + // If 1 second timeout has expired, return fail as we have not yet received a full message + // + if (Timeout (TimerStart1, TimerEnd1) != EFI_SUCCESS) { + *Length = 0; + return EFI_TIMEOUT; + } + // + // Wait before we read the register again + // + IoDelay (HECI_WAIT_DELAY); + + // + // Read the register again + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } + // + // copy rest of message + // + for (i = 0; i < LengthInDwords; i++) { + MessageData[i] = MMIOREADDWORD (HeciMBAR + ME_CB_RW); + } + // + // Update status and length + // + GotMessage = TRUE; + *Length = MessageHeader->Fields.Length; + + } else { + // + // Message packet is larger than caller's buffer + // + *Length = 0; + return EFI_BUFFER_TOO_SMALL; + } + } + // + // Wait before we try to get a message again + // + IoDelay (HECI_WAIT_DELAY); + } + // + // Read ME_CSR_HA. If the ME_RDY bit is 0, then an ME reset occurred during the + // transaction and the message should be discarded as bad data may have been retrieved + // from the host's circular buffer + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + *Length = 0; + return EFI_DEVICE_ERROR; + } + // + // Set Interrupt Generate bit + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +HeciReceive ( + IN UINT32 Blocking, + IN OUT UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +/*++ + + Routine Description: + Reads a message from the ME across HECI. + + Arguments: + Blocking - Used to determine if the read is BLOCKING or NON_BLOCKING. + MessageBody - Pointer to a buffer used to receive a message. + Length - Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + Returns: + EFI_STATUS + +--*/ +{ + HECI_MESSAGE_HEADER PacketHeader; + UINT32 CurrentLength; + UINT32 MessageComplete; + EFI_STATUS Status; + UINT32 PacketBuffer; + UINT32 timer_start; + UINT32 timer_end; + UINT32 MeDeviceState; + BOOLEAN QuitFlag; + + Status = EFI_SUCCESS; + CurrentLength = 0; + MessageComplete = 0; + QuitFlag = FALSE; + + SaveHpet (); + + do { + if (mHeciContext->MeMode == ME_MODE_SECOVER) { + Status = EFI_UNSUPPORTED; + break; + } + // + // Enable HECI and Save the Device State + // + mHeciContext->HeciDevSaveEnable (&MeDeviceState); + + // + // Make sure that HECI device BAR is correct and device is enabled. + // + HeciMBAR = CheckAndFixHeciForAccess (); + + // + // Make sure we do not have a HECI reset + // + if (CheckForHeciReset ()) { + // + // if HECI reset than try to re-init HECI + // + Status = HeciInitialize (); + + if (EFI_ERROR (Status)) { + HeciDevRestore (MeDeviceState); + Status = EFI_DEVICE_ERROR; + break; + } + } + // + // Make sure that HECI is ready for communication. + // + if (WaitForMEReady () != EFI_SUCCESS) { + HeciDevRestore (MeDeviceState); + Status = EFI_TIMEOUT; + break; + } + // + // Set up timer for BIOS timeout. + // + StartTimer (&timer_start, &timer_end, HECI_READ_TIMEOUT); + while ((CurrentLength < *Length) && (MessageComplete == 0)) { + // + // If 1 second timeout has expired, return fail as we have not yet received a full message + // + if (Timeout (timer_start, timer_end) != EFI_SUCCESS) { + Status = EFI_TIMEOUT; + QuitFlag = TRUE; + break; + } + + PacketBuffer = *Length - CurrentLength; + Status = HECIPacketRead ( + Blocking, + &PacketHeader, + (UINT32 *) &MessageBody[CurrentLength / 4], + &PacketBuffer + ); + + // + // Check for error condition on read + // + if (EFI_ERROR (Status)) { + *Length = 0; + QuitFlag = TRUE; + break; + } + // + // Get completion status from the packet header + // + MessageComplete = PacketHeader.Fields.MessageComplete; + + // + // Check for zero length messages + // + if (PacketBuffer == 0) { + // + // If we are not in the middle of a message, and we see Message Complete, + // this is a valid zero-length message. + // + if ((CurrentLength == 0) && (MessageComplete == 1)) { + *Length = 0; + QuitFlag = TRUE; + break; + } else { + // + // We should not expect a zero-length message packet except as described above. + // + *Length = 0; + Status = EFI_DEVICE_ERROR; + QuitFlag = TRUE; + break; + } + } + // + // Track the length of what we have read so far + // + CurrentLength += PacketBuffer; + + } + + if (QuitFlag == TRUE) { + break; + } + // + // If we get here the message should be complete, if it is not + // the caller's buffer was not large enough. + // + if (MessageComplete == 0) { + *Length = 0; + Status = EFI_BUFFER_TOO_SMALL; + } + + if (*Length != 0) { + *Length = CurrentLength; + } + // + // Restore HECI Device State + // + HeciDevRestore (MeDeviceState); + + } while (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)); + RestoreHpet (); + + return Status; +} + +EFI_STATUS +EFIAPI +HeciSend ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +/*++ + + Routine Description: + Function sends one messsage (of any length) through the HECI circular buffer. + + Arguments: + Message - Pointer to the message data to be sent. + Length - Length of the message in bytes. + HostAddress - The address of the host processor. + MeAddress - Address of the ME subsystem the message is being sent to. + + Returns: + EFI_STATUS + +--*/ +{ + UINT32 CBLength; + UINT32 SendLength; + UINT32 CurrentLength; + HECI_MESSAGE_HEADER MessageHeader; + EFI_STATUS Status; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + UINT32 MeDeviceState; + + Status = EFI_SUCCESS; + CurrentLength = 0; + + SaveHpet (); + + do { + if (mHeciContext->MeMode == ME_MODE_SECOVER) { + Status = EFI_UNSUPPORTED; + break; + } + // + // Enable HECI and Save the Device State + // + mHeciContext->HeciDevSaveEnable (&MeDeviceState); + + // + // Make sure that HECI device BAR is correct and device is enabled. + // + HeciMBAR = CheckAndFixHeciForAccess (); + + // + // Make sure we do not have a HECI reset + // + if (CheckForHeciReset ()) { + // + // if HECI reset than try to re-init HECI + // + Status = HeciInitialize (); + + if (EFI_ERROR (Status)) { + HeciDevRestore (MeDeviceState); + Status = EFI_DEVICE_ERROR; + break; + } + } + // + // Make sure that HECI is ready for communication. + // + if (WaitForMEReady () != EFI_SUCCESS) { + HeciDevRestore (MeDeviceState); + Status = EFI_TIMEOUT; + break; + } + // + // Set up memory mapped registers + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + + // + // Grab Circular Buffer length + // + CBLength = HeciRegHCsr.r.H_CBD; + + // + // Prepare message header + // + MessageHeader.Data = 0; + MessageHeader.Fields.MeAddress = MeAddress; + MessageHeader.Fields.HostAddress = HostAddress; + + // + // Break message up into CB-sized packets and loop until completely sent + // + while (Length > CurrentLength) { + // + // Set the Message Complete bit if this is our last packet in the message. + // Needs to be 'less than' to account for the header. + // + if ((((Length - CurrentLength) + 3) / 4) < CBLength) { + MessageHeader.Fields.MessageComplete = 1; + } + // + // Calculate length for Message Header + // header length == smaller of circular buffer or remaining message (both account for the size of the header) + // + SendLength = ((CBLength < (((Length - CurrentLength) + 3) / 4)) ? ((CBLength - 1) * 4) : (Length - CurrentLength)); + MessageHeader.Fields.Length = SendLength; + + // + // send the current packet (CurrentLength can be treated as the index into the message buffer) + // + Status = HeciPacketWrite (&MessageHeader, (UINT32 *) ((UINTN) Message + CurrentLength)); + if (EFI_ERROR (Status)) { + break; + } + // + // Update the length information + // + CurrentLength += SendLength; + } + + if (EFI_ERROR (Status)) { + break; + } + // + // Restore HECI Device State + // + HeciDevRestore (MeDeviceState); + + } while (EFI_ERROR (Status)); + + RestoreHpet (); + + return Status; +} + +EFI_STATUS +HeciPacketWrite ( + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +/*++ + + Routine Description: + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + Arguments: + MessageHeader - Pointer to the message header. + MessageData - Pointer to the actual message data. + + Returns: + EFI_STATUS + +--*/ +{ + UINT32 timer_start; + UINT32 timer_end; + UINT32 i; + UINT32 LengthInDwords; + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + + // + // VOLATILE HECI_HOST_CONTROL_REGISTER *HeciRegHCsrPtr = (VOID*)(mHeciContext->HeciMBAR + H_CSR); + // VOLATILE HECI_ME_CONTROL_REGISTER *HeciRegMeCsrHaPtr = (VOID*)(mHeciContext->HeciMBAR + ME_CSR_HA); + // VOLATILE UINT32 *HeciRegHCbwwPtr = (VOID*)(mHeciContext->HeciMBAR + H_CB_WW); + // + // Make sure that HECI is ready for communication. + // + if (WaitForMEReady () != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Start timeout counter + // + StartTimer (&timer_start, &timer_end, HECI_SEND_TIMEOUT); + + // + // Compute message length in DWORDS + // + LengthInDwords = ((MessageHeader->Fields.Length + 3) / 4); + + // + // Wait until there is sufficient room in the circular buffer + // Must have room for message and message header + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + while ((LengthInDwords + 1) > (HeciRegHCsr.r.H_CBD - FilledSlots (HeciRegHCsr.r.H_CBRP, HeciRegHCsr.r.H_CBWP))) { + // + // If 1 second timeout has expired, return fail as the circular buffer never emptied + // + if (Timeout (timer_start, timer_end) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Wait before we read the register again + // + IoDelay (HECI_WAIT_DELAY); + + // + // Read Host CSR for next iteration + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } + // + // Write Message Header + // + MMIOWRITEDWORD (HeciMBAR + H_CB_WW, MessageHeader->Data); + + // + // Write Message Body + // + for (i = 0; i < LengthInDwords; i++) { + MMIOWRITEDWORD (HeciMBAR + H_CB_WW, MessageData[i]); + } + // + // Set Interrupt Generate bit + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + // + // Test if ME Ready bit is set to 1, if set to 0 a fatal error occured during + // the transmission of this message. + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + if (HeciRegMeCsrHa.r.ME_RDY_HRA == 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +HeciSendwACK ( + IN OUT UINT32 *Message, + IN UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +/*++ + + Routine Description: + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + Arguments: + Message - Pointer to the message buffer. + SendLength - Length of the message in bytes. + RecLength - Length of the message response in bytes. + HostAddress - Address of the sending entity. + MeAddress - Address of the ME entity that should receive the message. + + Returns: + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + UINT16 RetryCount; + UINT32 TempRecLength; + + if (mHeciContext->MeMode == ME_MODE_SECOVER) { + return EFI_UNSUPPORTED; + } + // + // Send the message + // + Status = HeciSend (Message, Length, HostAddress, MeAddress); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Wait for ACK message + // + TempRecLength = *RecLength; + for (RetryCount = 0; RetryCount < HECI_MAX_RETRY; RetryCount++) { + // + // Read Message + // + Status = HeciReceive (BLOCKING, Message, &TempRecLength); + if (!EFI_ERROR (Status)) { + break; + } + // + // Reload receive length as it has been modified by the read function + // + TempRecLength = *RecLength; + } + // + // Return read length and status + // + *RecLength = TempRecLength; + return Status; +} + +EFI_STATUS +EFIAPI +MeResetWait ( + IN UINT32 Delay + ) +/*++ + +Routine Description: + + Me reset and waiting for ready + +Arguments: + + Delay - The biggest waiting time + +Returns: + + EFI_TIMEOUT - Time out + EFI_SUCCESS - Me ready + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + UINT32 TimerStart; + UINT32 TimerEnd; + + // + // Make sure that HECI device BAR is correct and device is enabled. + // + HeciMBAR = CheckAndFixHeciForAccess (); + + // + // Wait for the HOST Ready bit to be cleared to signal a reset + // + StartTimer (&TimerStart, &TimerEnd, Delay); + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + while (HeciRegHCsr.r.H_RDY == 1) { + // + // If timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +ResetHeciInterface ( + VOID + ) +/*++ + + Routine Description: + Function forces a reinit of the heci interface by following the reset heci interface via host algorithm + in HPS 0.90 doc 4-17-06 njy + + Arguments: + none + + Returns: + EFI_STATUS + +--*/ +{ + HECI_HOST_CONTROL_REGISTER HeciRegHCsr; + HECI_ME_CONTROL_REGISTER HeciRegMeCsrHa; + UINT32 TimerStart; + UINT32 TimerEnd; + + // + // Make sure that HECI device BAR is correct and device is enabled. + // + HeciMBAR = CheckAndFixHeciForAccess (); + + // + // Enable Reset + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + HeciRegHCsr.r.H_RST = 1; + HeciRegHCsr.r.H_IG = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + // + // Make sure that the reset started + // + // HeciRegHCsr.ul = MMIOREADDWORD(HeciMBAR + H_CSR); + // + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + // + // If 5 second timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Read the ME CSR + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } while (HeciRegHCsr.r.H_RDY == 1); + + // + // Wait for ME to perform reset + // + // HeciRegMeCsrHa.ul = MMIOREADDWORD(HeciMBAR + ME_CSR_HA); + // + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + // + // If 5 second timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Read the ME CSR + // + HeciRegMeCsrHa.ul = MMIOREADDWORD (HeciMBAR + ME_CSR_HA); + } while (HeciRegMeCsrHa.r.ME_RDY_HRA == 0); + + // + // Make sure IS has been signaled on the HOST side + // + // HeciRegHCsr.ul = MMIOREADDWORD(HeciMBAR + H_CSR); + // + StartTimer (&TimerStart, &TimerEnd, HECI_INIT_TIMEOUT); + do { + // + // If 5 second timeout has expired, return fail + // + if (Timeout (TimerStart, TimerEnd) != EFI_SUCCESS) { + return EFI_TIMEOUT; + } + // + // Read the ME CSR + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR); + } while (HeciRegHCsr.r.H_IS == 0); + + // + // Enable host side interface + // + HeciRegHCsr.ul = MMIOREADDWORD (HeciMBAR + H_CSR);; + HeciRegHCsr.r.H_RST = 0; + HeciRegHCsr.r.H_IG = 1; + HeciRegHCsr.r.H_RDY = 1; + MMIOWRITEDWORD (HeciMBAR + H_CSR, HeciRegHCsr.ul); + + return EFI_SUCCESS; +} + +UINT8 +FilledSlots ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer + ) +/*++ + + Routine Description: + Calculate if the circular buffer has overflowed. + Corresponds to HECI HPS (part of) section 4.2.1 + + Arguments: + ReadPointer - Location of the read pointer. + WritePointer - Location of the write pointer. + + Returns: + Number of filled slots. + +--*/ +{ + UINT8 FilledSlots; + + // + // Calculation documented in HECI HPS 0.68 section 4.2.1 + // + FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer)); + + return FilledSlots; +} + +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +/*++ + + Routine Description: + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + Arguments: + ReadPointer - Value read from host/me read pointer + WritePointer - Value read from host/me write pointer + BufferDepth - Value read from buffer depth register + + Returns: + EFI_STATUS + +--*/ +{ + UINT8 FilledSlots; + + // + // Calculation documented in HECI HPS 0.68 section 4.2.1 + // + FilledSlots = (((INT8) WritePointer) - ((INT8) ReadPointer)); + + // + // test for overflow + // + if (FilledSlots > ((UINT8) BufferDepth)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + IN UINT32 *MeStatus + ) +/*++ + + Routine Description: + Return ME Status + + Arguments: + MeStatus pointer for status report + + Returns: + EFI_STATUS + +--*/ +{ + HECI_FWS_REGISTER MeFirmwareStatus; + UINT32 MeDeviceState; + + if (MeStatus == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Save HECI1 Device State and Enable it + // + Heci1DevSaveEnable (&MeDeviceState); + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + + if (MeFirmwareStatus.r.CurrentState == ME_STATE_NORMAL && MeFirmwareStatus.r.ErrorCode == ME_ERROR_CODE_NO_ERROR) { + *MeStatus = ME_READY; + } else if (MeFirmwareStatus.r.CurrentState == ME_STATE_RECOVERY) { + *MeStatus = ME_IN_RECOVERY_MODE; + } else { + *MeStatus = ME_NOT_READY; + } + + if (MeFirmwareStatus.r.FwInitComplete == ME_FIRMWARE_COMPLETED) { + *MeStatus |= ME_FW_INIT_COMPLETE; + } + // + // Save HECI Device State and Enable it + // + HeciDevRestore (MeDeviceState); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +HeciGetMeMode ( + IN UINT32 *MeMode + ) +/*++ + + Routine Description: + Return ME Mode + + Arguments: + MeMode pointer for ME Mode report + + Returns: + EFI_STATUS + +--*/ +{ + HECI_FWS_REGISTER MeFirmwareStatus; + UINT32 MeDeviceState; + + if (MeMode == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Save HECI1 Device State and Enable it + // + Heci1DevSaveEnable (&MeDeviceState); + + MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE); + switch (MeFirmwareStatus.r.MeOperationMode) { + case ME_OPERATION_MODE_NORMAL: + *MeMode = ME_MODE_NORMAL; + break; + + case ME_OPERATION_MODE_DEBUG: + *MeMode = ME_MODE_DEBUG; + break; + + case ME_OPERATION_MODE_SOFT_TEMP_DISABLE: + *MeMode = ME_MODE_TEMP_DISABLED; + break; + + case ME_OPERATION_MODE_SECOVR_JMPR: + case ME_OPERATION_MODE_SECOVR_HECI_MSG: + *MeMode = ME_MODE_SECOVER; + break; + + default: + *MeMode = ME_MODE_FAILED; + } + // + // Save HECI Device State and Enable it + // + HeciDevRestore (MeDeviceState); + + return EFI_SUCCESS; +} + +EFI_STATUS +Heci1DevSaveEnable ( + IN OUT UINT32 *DevState + ) +/*++ + + Routine Description: + Save HECI1 State and Enable it + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +{ + *DevState = MMIOREADDWORD (PCH_RCRB_BASE + R_PCH_RCRB_FUNC_DIS2); + HeciEnable (); + return EFI_SUCCESS; +} + +EFI_STATUS +Heci2DevSaveEnable ( + IN OUT UINT32 *DevState + ) +/*++ + + Routine Description: + Save HECI2 State and Enable it + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +{ + *DevState = MMIOREADDWORD (PCH_RCRB_BASE + R_PCH_RCRB_FUNC_DIS2); + Heci2Enable (); + return EFI_SUCCESS; +} + +EFI_STATUS +HeciDevRestore ( + IN UINT32 DevState + ) +/*++ + + Routine Description: + Restore HECI1&HECI2 State + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +{ + MMIOWRITEDWORD (PCH_RCRB_BASE + R_PCH_RCRB_FUNC_DIS2, DevState); + MMIOREADDWORD (PCH_RCRB_BASE + R_PCH_RCRB_FUNC_DIS2); + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/Heci/Smm/Hecicore.h b/ReferenceCode/ME/Heci/Smm/Hecicore.h new file mode 100644 index 0000000..5f05c10 --- /dev/null +++ b/ReferenceCode/ME/Heci/Smm/Hecicore.h @@ -0,0 +1,512 @@ +/*++ + 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) 2006 - 2010 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. + +Module Name: + + HeciCore.h + +Abstract: + + Definitions for HECI driver + +--*/ +#ifndef _HECI_CORE_H +#define _HECI_CORE_H + +#include "CpuIa32.h" +#include "CoreBiosMsg.h" + +// +// HECI bus function version +// +#define HBM_MINOR_VERSION 0 +#define HBM_MAJOR_VERSION 1 + +// +// HECI save/restore Function +// +typedef +EFI_STATUS +(EFIAPI *HECI_DEV_SAVE_ENABLE) ( + IN OUT UINT32 *DevState + ); + +// +// HECI private data structure +// +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + UINT32 HeciMBAR; + UINT16 DeviceInfo; + UINT32 RevisionInfo; + SMM_HECI_PROTOCOL HeciCtlr; + VOLATILE UINT32 *HpetTimer; + UINTN PciAddressBase; + UINT32 DefaultHeciBar; + HECI_DEV_SAVE_ENABLE HeciDevSaveEnable; + UINT32 MeMode; +} HECI_INSTANCE_SMM; + +// +// Prototypes +// +EFI_STATUS +EFIAPI +HeciInitialize ( + VOID + ) +/*++ + + Routine Description: + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciReInitialize ( + VOID + ) +/*++ + + Routine Description: + Heci Re-initializes it for Host + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciReInitialize2 ( + VOID + ) +/*++ + + Routine Description: + Heci Re-initializes it for Me + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciReceive ( + IN UINT32 Blocking, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +/*++ + + Routine Description: + Reads a message from the ME across HECI. + + Arguments: + Blocking - Used to determine if the read is BLOCKING or NON_BLOCKING. + MessageData - Pointer to a buffer used to receive a message. + Length - Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciSend ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +/*++ + + Routine Description: + Function sends one messsage (of any length) through the HECI circular buffer. + + Arguments: + Message - Pointer to the message data to be sent. + Length - Length of the message in bytes. + HostAddress - The address of the host processor. + MeAddress - Address of the ME subsystem the message is being sent to. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciSendwACK ( + IN OUT UINT32 *Message, + IN UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ) +/*++ + + Routine Description: + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + Arguments: + Message - Pointer to the message buffer. + SendLength - Length of the message in bytes. + RecLength - Length of the message response in bytes. + HostAddress - Address of the sending entity. + MeAddress - Address of the ME entity that should receive the message. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +MeResetWait ( + IN UINT32 Delay + ) +/*++ + +Routine Description: + + Me reset and waiting for ready + +Arguments: + + Delay - The biggest waiting time + +Returns: + + EFI_TIMEOUT - Time out + EFI_SUCCESS - Me ready + +--*/ +; + +EFI_STATUS +EFIAPI +ResetHeciInterface ( + VOID + ) +/*++ + + Routine Description: + Function forces a reinit of the heci interface by following the reset heci interface via host algorithm + in HPS 0.90 doc 4-17-06 njy + + Arguments: + none + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciGetMeStatus ( + IN UINT32 *MeStatus + ) +/*++ + + Routine Description: + Return ME Status + + Arguments: + MeStatus pointer for status report + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +EFIAPI +HeciGetMeMode ( + IN UINT32 *MeMode + ) +/*++ + + Routine Description: + Return ME Mode + + Arguments: + MeMode pointer for ME Mode report + + Returns: + EFI_STATUS + +--*/ +; + +// +// Local/Private functions not part of EFIAPI for HECI +// +EFI_STATUS +InitializeHECI ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + HECI driver entry point used to initialize support for the HECI device. + +Arguments: + ImageHandle - Standard entry point parameter. + SystemTable - Standard entry point parameter. + +Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +InitializeHeciPrivate ( + VOID + ) +/*++ + + Routine Description: + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +; + +UINT32 +CheckAndFixHeciForAccess ( + VOID + ) +/*++ + +Routine Description: + This function provides a standard way to verify the HECI cmd and MBAR regs + in its PCI cfg space are setup properly and that the local mHeciContext + variable matches this info. + +Arguments: + None. + +Returns: + VOID + +--*/ +; + +EFI_STATUS +WaitForMEReady ( + VOID + ) +/*++ + + Routine Description: + Waits for the ME to report that it is ready for communication over the HECI + interface. + + Arguments: + None. + + Returns: + EFI_STATUS + +--*/ +; + +UINT8 +FilledSlots ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer + ) +/*++ + + Routine Description: + Calculate if the circular buffer has overflowed. + Corresponds to HECI HPS (part of) section 4.2.1 + + Arguments: + ReadPointer - Location of the read pointer. + WritePointer - Location of the write pointer. + + Returns: + Number of filled slots. + +--*/ +; + +EFI_STATUS +OverflowCB ( + IN UINT32 ReadPointer, + IN UINT32 WritePointer, + IN UINT32 BufferDepth + ) +/*++ + + Routine Description: + Calculate if the circular buffer has overflowed + Corresponds to HECI HPS (part of) section 4.2.1 + + Arguments: + ReadPointer - Value read from host/me read pointer + WritePointer - Value read from host/me write pointer + BufferDepth - Value read from buffer depth register + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +HeciPacketRead ( + IN UINT32 Blocking, + OUT HECI_MESSAGE_HEADER *MessageHeader, + OUT UINT32 *MessageData, + IN OUT UINT32 *Length + ) +/*++ + + Routine Description: + Function to pull one messsage packet off the HECI circular buffer. + Corresponds to HECI HPS (part of) section 4.2.4 + + + Arguments: + Blocking - Used to determine if the read is BLOCKING or NON_BLOCKING. + MessageHeader - Pointer to a buffer for the message header. + MessageData - Pointer to a buffer to recieve the message in. + Length - On input is the size of the callers buffer in bytes. On + output this is the size of the packet in bytes. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +HeciPacketWrite ( + IN HECI_MESSAGE_HEADER *MessageHeader, + IN UINT32 *MessageData + ) +/*++ + + Routine Description: + Function sends one messsage packet through the HECI circular buffer + Corresponds to HECI HPS (part of) section 4.2.3 + + Arguments: + MessageHeader - Pointer to the message header. + MessageData - Pointer to the actual message data. + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +Heci1DevSaveEnable ( + IN OUT UINT32 *DevState + ) +/*++ + + Routine Description: + Save HECI1 State and Enable it + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +Heci2DevSaveEnable ( + IN OUT UINT32 *DevState + ) +/*++ + + Routine Description: + Save HECI2 State and Enable it + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +; + +EFI_STATUS +HeciDevRestore ( + IN UINT32 DevState + ) +/*++ + + Routine Description: + Restore HECI1 State + + Arguments: + DevState - Device State Save Buffer + + Returns: + EFI_STATUS + +--*/ +; +#endif // _HECI_CORE_H diff --git a/ReferenceCode/ME/Include/IntelMeSsdtAcpiTables.dsc b/ReferenceCode/ME/Include/IntelMeSsdtAcpiTables.dsc new file mode 100644 index 0000000..f6428ea --- /dev/null +++ b/ReferenceCode/ME/Include/IntelMeSsdtAcpiTables.dsc @@ -0,0 +1,67 @@ +## @file +# Build description file for building the ME SSDT ACPI tables +# +#@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 +# + +[=============================================================================] +# +# Instructions for building the ME SSDT ACPI table storage file +# +[=============================================================================] +[Build.Ia32.ME_SSDT_ACPITABLE,Build.x64.ME_SSDT_ACPITABLE] +# +# Check if we have any source to work with. +# +!IFNDEF SECTIONS +!IFNDEF ASL_FILES +!ERROR No ASL source files to build were defined in the INF file +!ENDIF +!ENDIF + +# +# Define some macros to simplify changes +# +TARGET_FFS_FILE = $(BIN_DIR)\$(FILE_GUID)-$(BASE_NAME).ffs + +$(DEST_DIR)\MeSsdt.sec : $(ASL_SOURCE_FILES) $(ASL_FILES) + $(ASL) $(ASL_FLAGS) $(DEST_DIR)\MeSsdt.asl + -copy $(DEST_DIR)\MeSsdt.aml $(DEST_DIR)\MeSsdt.acpi + $(GENSECTION) -I $(DEST_DIR)\MeSsdt.acpi -O $(DEST_DIR)\MeSsdt.sec -S EFI_SECTION_RAW + +# +# Build FFS file +# +$(TARGET_FFS_FILE) : $(SECTIONS) $(DEST_DIR)\MeSsdt.sec + $(GENFFSFILE) -B $(DEST_DIR) -P1 $(DEST_DIR)\$(BASE_NAME).pkg -V + +all : $(TARGET_FFS_FILE) + +[=============================================================================] +[Package.ME_SSDT_ACPITABLE.Default] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress (Dummy) { + $(DEST_DIR)\MeSsdt.sec + } +} diff --git a/ReferenceCode/ME/Include/MeDxe.dsc b/ReferenceCode/ME/Include/MeDxe.dsc new file mode 100644 index 0000000..3c3791d --- /dev/null +++ b/ReferenceCode/ME/Include/MeDxe.dsc @@ -0,0 +1,41 @@ +## @file +# Build description file DXE Drivers for building the Me +# +#@copyright +# Copyright (c) 1999 - 2014 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 +# + +$(PROJECT_ME_ROOT)\Heci\Dxe\Hecidrv.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\AlertStandardFormat\Heci\Dxe\AlertStandardFormatDxe.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\AmtBootOptions\Dxe\ActiveManagement.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\BiosExtension\Efi\BiosExtensionLoader\Dxe\BiosExtensionLoader.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\ider\Dxe\IdeRController.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\sol\Dxe\PciSerial.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\FwUpdate\MeFwDowngrade\Dxe\MeFwDowngrade.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\At\AtAm\Dxe\AtAm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +# +# Disable the following driver if PTT is not supported +# +$(PROJECT_ME_ROOT)\Ptt\Smm\PttHciSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\Acpitables\MeSsdt\MeSsdt_Edk.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints + +# +# Uncomment the following line if the Mebx and MebxSetupBrowser are included by this build description +# +# $(PROJECT_ME_ROOT)\BiosExtension\Efi\Mebx\Mebx.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +# $(PROJECT_ME_ROOT)\BiosExtension\Efi\MebxSetupBrowser\MebxSetupBrowser.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints + diff --git a/ReferenceCode/ME/Include/MeDxeLib.dsc b/ReferenceCode/ME/Include/MeDxeLib.dsc new file mode 100644 index 0000000..efab364 --- /dev/null +++ b/ReferenceCode/ME/Include/MeDxeLib.dsc @@ -0,0 +1,31 @@ +## @file +# Build description file for building the Me Libries for DXE +# +#@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 +# + +$(PROJECT_ME_ROOT)\Guid\MeGuidLib.inf +$(PROJECT_ME_ROOT)\Protocol\MeProtocolLib.inf +$(PROJECT_ME_ROOT)\Library\MeKernel\Common\MeChipsetLib\MeChipsetLib.inf +$(PROJECT_ME_ROOT)\Library\MeKernel\Dxe\MeLib.inf +$(PROJECT_ME_ROOT)\Library\AMT\Dxe\AmtLib.inf +$(PROJECT_ME_ROOT)\Library\AtLibrary\Dxe\AtDxeLib.inf +# +# Disable the following library if PTT is not supported +# +$(PROJECT_ME_ROOT)\Library\Ptt\Dxe\PttHciDeviceDxeLib.inf diff --git a/ReferenceCode/ME/Include/MeInclude.cif b/ReferenceCode/ME/Include/MeInclude.cif new file mode 100644 index 0000000..b45f94f --- /dev/null +++ b/ReferenceCode/ME/Include/MeInclude.cif @@ -0,0 +1,13 @@ +<component> + name = "MeInclude" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Include\" + RefName = "MeInclude" +[files] +"MeInclude.sdl" +"MePeiLib.dsc" +"MeDxe.dsc" +"MeDxeLib.dsc" +"MePei.dsc" +"IntelMeSsdtAcpiTables.dsc" +<endComponent> diff --git a/ReferenceCode/ME/Include/MeInclude.sdl b/ReferenceCode/ME/Include/MeInclude.sdl new file mode 100644 index 0000000..ccba82a --- /dev/null +++ b/ReferenceCode/ME/Include/MeInclude.sdl @@ -0,0 +1,9 @@ +PATH + Name = "MeInclude_DIR" +End + +ELINK + Name = "/I$(MeInclude_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/Include/MePei.dsc b/ReferenceCode/ME/Include/MePei.dsc new file mode 100644 index 0000000..5110525 --- /dev/null +++ b/ReferenceCode/ME/Include/MePei.dsc @@ -0,0 +1,25 @@ +## @file +# Build description file PEI Drivers for building +# +#@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 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 +# + +$(PROJECT_ME_ROOT)\PchMeUma\PchMeUma.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\Heci\Pei\HeciInit.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\StartWatchDog\Pei\StartWatchDog.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints +$(PROJECT_ME_ROOT)\ActiveManagement\AlertStandardFormat\Heci\Pei\AlertStandardFormatPei.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints diff --git a/ReferenceCode/ME/Include/MePeiLib.dsc b/ReferenceCode/ME/Include/MePeiLib.dsc new file mode 100644 index 0000000..e5fc450 --- /dev/null +++ b/ReferenceCode/ME/Include/MePeiLib.dsc @@ -0,0 +1,30 @@ +## @file +# Build description file for building the Libraries for PEIM +# +#@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 +# + +$(PROJECT_ME_ROOT)\Guid\MeGuidLib.inf +$(PROJECT_ME_ROOT)\Ppi\MeLibPpi.inf +$(PROJECT_ME_ROOT)\Library\MeKernel\Pei\MeLibPei.inf +$(PROJECT_ME_ROOT)\Library\AMT\Pei\AmtLibPei.inf +# +# Disable the following library if PTT is not supported +# +$(PROJECT_ME_ROOT)\Library\Ptt\Pei\PttHciDevicePeiLib.inf + 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 diff --git a/ReferenceCode/ME/ME.cif b/ReferenceCode/ME/ME.cif new file mode 100644 index 0000000..9684de1 --- /dev/null +++ b/ReferenceCode/ME/ME.cif @@ -0,0 +1,25 @@ +<component> + name = "ME" + category = eModule + LocalRoot = "ReferenceCode\ME" + RefName = "ME" +[files] +"ME.sdl" +[parts] +"MeHeci" +"MeGuidLib" +"MeInclude" +"MeProtocolLib" +"MeLibPpi" +"MeSampleCode" +"MeLibrary" +"MeFwDowngrade" +"BiosExtension" +"ActiveManagement" +"PchMeUma" +"AntiTheft" +"MeWrapper" +"AmtWrapper" +"PttSmm" +"MeAcpiTableSsdt" +<endComponent> diff --git a/ReferenceCode/ME/ME.sdl b/ReferenceCode/ME/ME.sdl new file mode 100644 index 0000000..adf574e --- /dev/null +++ b/ReferenceCode/ME/ME.sdl @@ -0,0 +1,50 @@ +TOKEN + Name = "iME_SUPPORT" + Value = "1" + Help = "Main switch to enable iAMT support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +TOKEN + Name = "IntelPTT_SUPPORT" + Value = "1" + Help = "Main switch to enable Intel PTT support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes +End + +#TOKEN +# Name = "INTEL_ME_RELEASE_VERSION" +# Value = "0.80" +# Help = "Follow Intel Release Reference Code version" +# TokenType = Integer +#End + +PATH + Name = "ME_DIR" + Help = "ME Driver files source directory" +End + +ELINK + Name = "/I$(ME_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(ME_DIR)\SampleCode\Include" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "ME_INCLUDES" + InvokeOrder = ReplaceParent +End + diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.c b/ReferenceCode/ME/PchMeUma/PchMeUma.c new file mode 100644 index 0000000..dd8b51b --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.c @@ -0,0 +1,765 @@ +/** @file + Framework PEIM to PchMeUma + +@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 + +**/ + +// +// Statements that include other files +// +#include "EdkIIGluePeim.h" +#include "MeAccess.h" +#include "HeciRegs.h" +#include "Pci22.h" +#include "PchMeUma.h" +#include "PchPlatformLib.h" +#include "PttHciDeviceLib.h" +#include "PttHciRegs.h" +#include EFI_PPI_DEFINITION (PchMeUma) +#ifdef PTT_FLAG +#include EFI_PPI_DEFINITION (MePlatformPolicyPei) +#endif +#include EFI_PPI_DEFINITION (Stall) +#include EFI_PPI_CONSUMER (Wdt) + +// +// Function Declarations +// +static PCH_ME_UMA_PPI mPchMeUmaPpi = { + MeSendUmaSize, + CpuReplacementCheck, + MeConfigDidReg, + HandleMeBiosAction +}; + +static EFI_PEI_PPI_DESCRIPTOR mPchMeUmaPpiList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPchMeUmaPpiGuid, + &mPchMeUmaPpi + } +}; + +/** + This procedure will read and return the amount of ME UMA requested + by ME ROM from the HECI device. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + + @retval UINT32 Return ME UMA Size + @retval EFI_SUCCESS Do not check for ME UMA +**/ +UINT32 +MeSendUmaSize ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +{ + UINT32 Timeout; + HECI_MISC_SHDW_REGISTER MeMiscShdw; + HECI_FWS_REGISTER MeHfs; + EFI_STATUS Status; + PEI_STALL_PPI *StallPpi; + + MeMiscShdw.ul = HeciPciRead32 (R_ME_MISC_SHDW); + MeHfs.ul = HeciPciRead32 (R_ME_HFS); + Timeout = 0x0; + + if (MeHfs.r.MeOperationMode == ME_OPERATION_MODE_DEBUG) { + DEBUG ((EFI_D_INFO, "ME debug mode, do not check for ME UMA. \n")); + return EFI_SUCCESS; + } + + if (MeHfs.r.ErrorCode != 0) { + DEBUG ((EFI_D_INFO, "ME error, do not check for ME UMA. \n")); + return EFI_SUCCESS; + } + /// + /// Poll on MUSZV until it indicates a valid size is present or 5s timeout expires. + /// + Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi); + ASSERT_PEI_ERROR (PeiServices, Status); + + PERF_START_EX (FfsHeader, L"MUSZV", NULL, AsmReadTsc (), 0x4000); + while ((MeMiscShdw.r.MUSZV == 0) && (Timeout < MUSZV_TIMEOUT_MULTIPLIER)) { + StallPpi->Stall (PeiServices, StallPpi, STALL_1_MILLISECOND); + MeMiscShdw.ul = HeciPciRead32 (R_ME_MISC_SHDW); + Timeout++; + } + + if (Timeout >= MUSZV_TIMEOUT_MULTIPLIER) { + DEBUG ((EFI_D_INFO, "Timeout occurred waiting for MUSZV. \n")); + return EFI_SUCCESS; + } + PERF_END_EX (FfsHeader, L"MUSZV", NULL, AsmReadTsc (), 0x4001); + + /// + /// Return MeUmaSize value + /// + DEBUG ((EFI_D_INFO, "ME UMA Size Requested: %x\n", MeMiscShdw.r.MUSZ)); + + return MeMiscShdw.r.MUSZ; +} + +/** + Init and Install ME Hob + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS +**/ +EFI_STATUS +InstallMeHob ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + ME_DATA_HOB *MeDataHob; + + /// + /// Create HOB for ME Data + /// + Status = (**PeiServices).CreateHob ( + PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + sizeof (ME_DATA_HOB), + &MeDataHob + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Initialize default HOB data + /// + MeDataHob->EfiHobGuidType.Name = gMeDataHobGuid; + ZeroMem (&(MeDataHob->FtpmBufferAddress), sizeof (UINT64)); + + DEBUG ((EFI_D_INFO, "ME Data HOB installed\n")); + + return EFI_SUCCESS; +} + +#ifdef PTT_FLAG +/** + Internal function performing Heci platform ME Debug Dump in PEI phase + + @param[in] PeiMePolicyPpi Policy Ppi + + @retval None +**/ +VOID +DumpMePlatformPolicyPei ( + IN PEI_ME_PLATFORM_POLICY_PPI *PeiMePolicyPpi + ) +{ + DEBUG ((EFI_D_INFO, "\n------------------------ MePlatformPolicyPpi Dump Begin -----------------\n")); + DEBUG ((EFI_D_INFO, " Revision : 0x%x\n", PeiMePolicyPpi->Revision)); + DEBUG ((EFI_D_INFO, " FTpmSwitch : 0x%x\n", PeiMePolicyPpi->FTpmSwitch)); + DEBUG ((EFI_D_INFO, "\n------------------------ MePlatformPolicyPpi Dump End -------------------\n")); +} +#endif + +/** + This procedure will determine whether or not the CPU was replaced + during system power loss or via dynamic fusing. + Calling this procedure could result in a warm reset (if ME FW is requesting one). + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Not used. + @param[out] ForceFullTraining When set = 0x1, MRC will be forced to perform a full + memory training cycle. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +CpuReplacementCheck ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + OUT UINT8 *ForceFullTraining + ) +{ + HECI_GS_SHDW_REGISTER MeFwsts2; + EFI_STATUS Status; + UINT32 Timeout; + PEI_STALL_PPI *StallPpi; + Status = EFI_SUCCESS; + Timeout = 0x0; + + /// + /// Read ME FWS2 + /// + MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW); + DEBUG ((EFI_D_INFO, "MeFwsts2 = %x.\n", MeFwsts2.r)); + + /// + /// Locate Stall Ppi + /// + Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi); + ASSERT_PEI_ERROR (PeiServices, Status); + + PERF_START_EX (FfsHeader, L"CPURLOP", NULL, AsmReadTsc (), 0x4010); + /// + /// Poll 50 ms on CPU Replaced Valid bit + /// + while ((((MeFwsts2.r.CpuReplacedValid == 0) && Timeout < CPURV_TIMEOUT_MULTIPLIER)) + ) { + StallPpi->Stall (PeiServices, StallPpi, STALL_1_MILLISECOND); + MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW); + Timeout++; + } + PERF_END_EX (FfsHeader, L"CPURLOP", NULL, AsmReadTsc (), 0x4011); + + DEBUG ((EFI_D_INFO, "CpuReplacedValid = %x, ", MeFwsts2.r.CpuReplacedValid)); + DEBUG ((EFI_D_INFO, "CpuReplacedStatus = %x, ", MeFwsts2.r.CpuReplacedSts)); + DEBUG ((EFI_D_INFO, "WarmRstReqForDF = %x.\n", MeFwsts2.r.WarmRstReqForDF)); + + if (Timeout >= CPURV_TIMEOUT_MULTIPLIER || MeFwsts2.r.CpuReplacedValid == 0x0) { + DEBUG ((EFI_D_ERROR, "Timeout occurred, the CPU Replacement Valid Bit is not set.\n")); + *ForceFullTraining = 0x1; + } else { + if (MeFwsts2.r.CpuReplacedValid == 0x1) { + if (MeFwsts2.r.WarmRstReqForDF == 0x1) { + /// + /// Clear DISB and Issue a Non-Power Cycle Reset + /// + Status = ClearDisb (); + Status = PerformReset (PeiServices, CBM_DIR_NON_PCR); + } + + if ((MeFwsts2.r.CpuReplacedSts == 0x1 && MeFwsts2.r.WarmRstReqForDF == 0x0)) { + *ForceFullTraining = 0x1; + } + } + } + + return Status; +} + +/** + This procedure will configure the ME Host General Status register, + indicating that DRAM Initialization is complete and ME FW may + begin using the allocated ME UMA space. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + @param[in] MrcBootMode MRC BootMode + @param[in] InitStat H_GS[27:24] Status + @param[in] FtpmStolenBase The base of FTPM + @retval EFI_SUCCESS +**/ +EFI_STATUS +MeConfigDidReg ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 InitStat, + IN UINT32 FtpmStolenBase, + IN UINT32 MeUmaSize + ) +{ + UINT32 MeUmaBase; + UINT32 MeUmaBaseExt; + UINT32 MeHgs; + UINT32 Timeout; + HECI_FWS_REGISTER MeHfs; + EFI_STATUS Status; + PEI_STALL_PPI *StallPpi; +#ifdef PTT_FLAG + PEI_ME_PLATFORM_POLICY_PPI *PeiMePolicyPpi; + EFI_GUID gPeiMePlatformPolicyPpiGuid = PEI_ME_PLATFORM_POLICY_PPI_GUID; + ME_DATA_HOB *MeDataHob; + EFI_GUID gMeDataHobGuid = ME_DATA_HOB_GUID; + UINT32 RegRead; + UINT32 WaitTime; +#endif //PTT_FLAG + +#ifdef PTT_FLAG + /// + /// Get platform policy settings through the MePlatformPolicy PPI + /// + Status = (**PeiServices).LocatePpi ( + PeiServices, + &gPeiMePlatformPolicyPpiGuid, + 0, + NULL, + (VOID **) &PeiMePolicyPpi + ); + ASSERT_PEI_ERROR (PeiServices, Status); + + DumpMePlatformPolicyPei (PeiMePolicyPpi); +#endif //PTT_FLAG + + + Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi); + ASSERT_PEI_ERROR (PeiServices, Status); + + MeHgs = 0x0; + Timeout = 0x0; + MeHfs.ul = HeciPciRead32 (R_ME_HFS); + + DEBUG ((EFI_D_INFO, "ME status: 0x%08x\n", MeHfs.ul)); + + if (MeHfs.r.MeOperationMode == ME_OPERATION_MODE_DEBUG) { + DEBUG ((EFI_D_INFO, "ME debug mode, do not check for ME UMA. \n")); + return EFI_SUCCESS; + } + + if (MeHfs.r.ErrorCode != 0) { + DEBUG ((EFI_D_INFO, "ME error, do not check for ME UMA. \n")); + return EFI_SUCCESS; + } + + DEBUG ((EFI_D_INFO, "Entered ME DRAM Init Done procedure.\n")); + +#ifdef PTT_FLAG + if ((GetPchSeries() == PchLp) && + (MmioRead32 (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)& BIT0) && + (PeiMePolicyPpi->FTpmSwitch == 0) && + (InitStat != 0x1)) { + /// + /// Install ME HOBs + /// + InstallMeHob (PeiServices); + + MeDataHob = NULL; + MeDataHob = GetFirstGuidHob (&gMeDataHobGuid); + + if (MeDataHob != NULL) { + MeDataHob->FtpmBufferAddress = FtpmStolenBase; + DEBUG ((EFI_D_INFO, " Ftpm Allocated Buffer Address: %x\n", MeDataHob->FtpmBufferAddress )); + + /// + /// Poll Ready Bit + /// + RegRead = 0; + for (WaitTime = 0; WaitTime < PTT_HCI_TIMEOUT_B * 3; WaitTime += PTT_HCI_POLLING_PERIOD){ + RegRead = MmioRead32 (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS); + DEBUG ((EFI_D_INFO, " Ftpm Waiting on Ready Bit, HCI_STS Register = %x\n", RegRead)); + if((BIT1 & RegRead) != 0){ + MmioWrite64 ((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB),(UINTN) MeDataHob->FtpmBufferAddress ); + /// + /// Issue command to start. + /// + MmioWrite32 ((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START, V_PTT_HCI_BUFFER_ADDRESS_RDY); + if( MeUmaSize == 32 ) + { + /// + /// Trigger interrupt command processing only for 5MB sku + /// + MmioWrite32 ((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD, 0); + } + break; + } + StallPpi->Stall (PeiServices, StallPpi, PTT_HCI_POLLING_PERIOD); + } + + /// + /// Poll state, wait for Ftpm to finish processing + /// + for (WaitTime = 0; WaitTime < PTT_HCI_TIMEOUT_B; WaitTime += PTT_HCI_POLLING_PERIOD){ + RegRead = MmioRead32 (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START); + if (RegRead == 0){ + break; + } + StallPpi->Stall (PeiServices, StallPpi, PTT_HCI_POLLING_PERIOD); + } + } else { + DEBUG ((EFI_D_INFO, "ME DataHob error, MeDataHob not found\n")); + } + } +#endif + + /// + /// Read MESEGBASE value + /// + MeUmaBase = PciRead32 (PCI_LIB_ADDRESS (0, 0, 0, R_MESEG_BASE)); + MeUmaBaseExt = PciRead32 (PCI_LIB_ADDRESS (0, 0, 0, R_MESEG_BASE + 0x04)); + DEBUG ((EFI_D_INFO, " MeUmaBase read: %x\n", MeUmaBase)); + + /// + /// Write DRAM Init Done (DID) data to the ME H_GS[23:0]. + /// H_GS[23:16] = extended UMA base address (reserved) + /// H_GS[15:0] = 1M aligned UMA base address + /// ME FW will 0 extend these values to determine MeUmaBase + /// + MeUmaBase = ((MeUmaBaseExt << 28) + (MeUmaBase >> 4)) >> 16; + MeHgs = MeUmaBase; + + /// + /// Set H_GS[31:28] = 0x1 indicating DRAM Init Done + /// + MeHgs |= B_ME_DID_TYPE_MASK; + + /// + /// RapidStart + /// + if (InitStat & 0x80) { + MeHgs |= B_ME_DID_RAPID_START_BIT; + } + + InitStat &= 0x7F; + + /// + /// Set H_GS[27:24] = Status + /// 0x0 = Success + /// 0x1 = No Memory in channels + /// 0x2 = Memory Init Error + /// 0x3 = Memory not preserved across reset + /// 0x4-0xF = Reserved + /// + MeHgs |= (InitStat << 24); + + PERF_START_EX (FfsHeader, L"DID", NULL, AsmReadTsc (), 0x4020); + HeciPciAndThenOr32 (R_ME_H_GS, 0, MeHgs); + DEBUG ((EFI_D_INFO, " ME H_GS written: %x\n", MeHgs)); + + /// + /// ME FW typically responds with the DID ACK w/in 1ms + /// Adding short delay to avoid wasting time in the timeout loop + /// + StallPpi->Stall (PeiServices, StallPpi, STALL_1_MILLISECOND + STALL_100_MICROSECONDS); + + /// + /// Read the ME H_FS Register to look for DID ACK. + /// + MeHfs.ul = HeciPciRead32 (R_ME_HFS); + DEBUG ((EFI_D_INFO, " HFS read before DID ACK: %x\n", MeHfs.r)); + + /// + /// ~5 second Timeout for DID ACK + /// + while (((MeHfs.r.BiosMessageAck == 0) && Timeout < DID_TIMEOUT_MULTIPLIER) + ) { + StallPpi->Stall (PeiServices, StallPpi, STALL_1_MILLISECOND); + MeHfs.ul = HeciPciRead32 (R_ME_HFS); + Timeout++; + } + + if ((Timeout >= DID_TIMEOUT_MULTIPLIER) + ) { + DEBUG ((EFI_D_ERROR, "Timeout occurred waiting for DID ACK.\n")); + } else { + DEBUG ((EFI_D_INFO, "ME DRAM Init Done ACK received.\n")); + DEBUG ((EFI_D_INFO, "HFS read after DID ACK: %x\n", MeHfs.r)); + } + PERF_END_EX (FfsHeader, L"DID", NULL, AsmReadTsc (), 0x4021); + + DEBUG ((EFI_D_ERROR, "BiosAction = %x\n", MeHfs.r.AckData)); + + return HandleMeBiosAction (PeiServices, MrcBootMode, (UINT8) MeHfs.r.AckData); +} + +/** + This procedure will enforce the BIOS Action that was requested by ME FW + as part of the DRAM Init Done message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MrcBootMode MRC BootMode + @param[in] BiosAction Me requests BIOS to act + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +HandleMeBiosAction ( + IN EFI_PEI_SERVICES **PeiServices, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 BiosAction + ) +{ + EFI_STATUS Status; + HECI_GS_SHDW_REGISTER MeFwsts2; + /// + /// Read ME FWS2 + /// + MeFwsts2.ul = HeciPciRead32 (R_ME_GS_SHDW); + DEBUG ((EFI_D_INFO, "MeFwsts2 = %x.\n", MeFwsts2.r)); + + switch (BiosAction) { + case 0: + /// + /// Case: DID ACK was not received + /// + DEBUG ((EFI_D_ERROR, "DID Ack was not received, no BIOS Action to process.\n")); + break; + + case CBM_DIR_NON_PCR: + /// + /// Case: Perform Non-Power Cycle Reset + /// + DEBUG ((EFI_D_ERROR, "ME FW has requested a Non-PCR.\n")); + Status = PerformReset (PeiServices, CBM_DIR_NON_PCR); + break; + + case CBM_DIR_PCR: + /// + /// Case: Perform Power Cycle Reset + /// + DEBUG ((EFI_D_ERROR, "ME FW has requested a PCR.\n")); + Status = PerformReset (PeiServices, CBM_DIR_PCR); + break; + + case 3: + /// + /// Case: Go To S3 + /// + DEBUG ((EFI_D_INFO, "ME FW DID ACK has requested entry to S3. Not defined, continuing to POST.\n")); + break; + + case 4: + /// + /// Case: Go To S4 + /// + DEBUG ((EFI_D_INFO, "ME FW DID ACK has requested entry to S4. Not defined, continuing to POST.\n")); + break; + + case 5: + /// + /// Case: Go To S5 + /// + DEBUG ((EFI_D_INFO, "ME FW DID ACK has requested entry to S5. Not defined, continuing to POST.\n")); + break; + + case CBM_DIR_GLOBAL_RESET: + /// + /// Case: Perform Global Reset + /// + DEBUG ((EFI_D_ERROR, "ME FW has requested a Global Reset.\n")); + Status = PerformReset (PeiServices, CBM_DIR_GLOBAL_RESET); + break; + + case CBM_DIR_CONTINUE_POST: + /// + /// Case: Continue to POST + /// + DEBUG ((EFI_D_INFO, "ME FW DID Ack requested to continue to POST.\n")); + break; + } + + return EFI_SUCCESS; +} + +/** + This procedure will issue a Non-Power Cycle, Power Cycle, or Global Rest. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] ResetType Type of reset to be issued. + + @retval EFI_SUCCESS The function completed successfully. + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PerformReset ( + IN EFI_PEI_SERVICES **PeiServices, + UINT8 ResetType + ) +{ + EFI_STATUS Status; + UINT32 ETR3; + UINT32 GpioBase; + UINT8 Reset; + WDT_PPI *Wdt; + PCH_SERIES PchSeries; + + ETR3 = 0; + Reset = 0; + GpioBase = 0; + Wdt = NULL; + PchSeries = GetPchSeries(); + + /// + /// Locate WDT PPI for access to Wdt->AllowKnownReset() + /// + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gWdtPpiGuid, + 0, + NULL, + (VOID **) &Wdt + ); + ASSERT_PEI_ERROR (PeiServices, Status); + + /// + /// Clear CF9GR of PCH (B0/D31/f0 offset 0x0AC[20] = 1b) to indicate Host reset + /// Make sure CWORWRE (CF9 Without Resume Well Reset Enable) is cleared + /// + ETR3 = PciRead32 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMIR)); + ETR3 = ETR3 &~BIT20; + ETR3 = ETR3 &~BIT18; + PciWrite32 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMIR), ETR3); + + Reset = IoRead8 (R_PCH_RST_CNT); + Reset &= 0xF1; + + /// + /// If global reset required + /// + if (ResetType == CBM_DIR_GLOBAL_RESET) { + /// + /// Get GPIO Base Address + /// + GpioBase = PciRead32 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GPIO_BASE)) &~BIT0; + } + + switch (ResetType) { + case CBM_DIR_NON_PCR: + /// + /// Case: Non Power Cycle Reset requested + /// + DEBUG ((EFI_D_ERROR, "ME FW DID ACK has requested a Non Power Cycle Reset.\n")); + Reset |= 0x06; + break; + + case CBM_DIR_PCR: + /// + /// Case: Power Cycle Reset requested + /// + Wdt->ReloadAndStart (2); + DEBUG ((EFI_D_INFO, "ME FW DID ACK has requested a Power Cycle Reset.\n")); + Reset |= 0x0E; + break; + + case CBM_DIR_GLOBAL_RESET: + /// + /// Case: Global Reset + /// + DEBUG ((EFI_D_ERROR, "ME FW DID Ack requested a global reset.\n")); + + /// + /// Drive GPIO[30] (SPDNA#) low prior to 0xCF9 write + /// + if (PchSeries == PchH) { + /// 1. Set GPIOBASE + offset 00h[30] = 1b (for non-Deep Sx enabled platforms) + /// 2. Set GPIOBASE + offset 04h[30] = 0b (for non-Deep Sx enabled platforms) + /// 3. Set GPIOBASE + offset 0Ch[30] = 0b (for non-Deep Sx enabled platforms) + /// 4. Set GPIOBASE + offset 60h[30] = 1b (for non-Deep Sx enabled platforms) + /// NOTE: For Deep Sx enabled platforms steps 1,2 and 3 should be skipped and pin should be left in native mode + /// 5. Set CF9GR bit, D31:F0:ACh[20], issue a Global Reset through a 0xCF9 write of either 06h or 0Eh commands. + /// Global Reset MEI Message + /// 1. BIOS makes sure GPIO30 is left in native mode (default mode) before sending a Global Reset MEI message. + /// + IoOr32 ((UINTN) (GpioBase + R_PCH_GPIO_USE_SEL), (UINT32) (BIT30)); + IoAnd32 ((UINTN) (GpioBase + R_PCH_GPIO_IO_SEL), (UINT32) (~BIT30)); + IoAnd32 ((UINTN) (GpioBase + R_PCH_GPIO_LVL), (UINT32) (~BIT30)); + } + + if (PchSeries == PchLp) { + /// 1. Set GPIOBASE + offset 1F0h[0] = 1b (for non-Deep Sx enabled platforms) + /// 2. Set GPIOBASE + offset 1F0h[2] = 0b (for non-Deep Sx enabled platforms) + /// 3. Set GPIOBASE + offset 1F0h[31] = 0b (for non-Deep Sx enabled platforms) + /// 4. Set GPIOBASE + offset 60h[30] = 1h (for non-Deep Sx enabled platforms) + /// NOTE: For Deep Sx enabled platforms steps 1,2 and 3 should be skipped and pin should be left in native mode + /// 5. Set CF9GR bit, D31:F0:ACh[20], issue a Global Reset through a 0xCF9 write of either 06h or 0Eh commands. + /// Global Reset MEI Message + /// 1. BIOS makes sure GPIO30 is left in native mode (default mode) before sending a Global Reset MEI message. + /// + IoOr32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (B_PCH_GPIO_OWN0_GPIO_USE_SEL)); + IoAnd32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (~B_PCH_GPIO_OWN0_GPIO_IO_SEL)); + IoAnd32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (~B_PCH_GPIO_OWN0_GPO_LVL)); + } + + IoOr32 ((UINTN) (GpioBase + R_PCH_GP_RST_SEL), (UINT32) (BIT30)); + + PciOr32 ( + PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_PMIR), + (UINT32) (B_PCH_LPC_PMIR_CF9GR) + ); + + /// + /// Issue global reset CF9 = 0x0E + /// + DEBUG ((EFI_D_ERROR, "Issuing global reset.\n")); + Reset |= 0x0E; + break; + } + /// + /// Write PCH RST CNT, Issue Reset + /// + Wdt->AllowKnownReset (); + + IoWrite8 (R_PCH_RST_CNT, Reset); + + return EFI_SUCCESS; +} + +/** + This procedure will clear the DISB. + + @param[in] None + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +ClearDisb ( + VOID + ) +{ + UINT16 Data16; + + Data16 = PciRead16 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GEN_PMCON_2)); + Data16 = Data16 &~B_PCH_LPC_GEN_PMCON_DRAM_INIT; + PciWrite16 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GEN_PMCON_2), Data16); + + return EFI_SUCCESS; +} + +/** + This procedure will clear the DISB. + + @param[in] None + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +SetDISB ( + VOID + ) +{ + UINT16 Data16; + + Data16 = PciRead16 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GEN_PMCON_2)); + Data16 = Data16 & B_PCH_LPC_GEN_PMCON_DRAM_INIT; + PciWrite16 (PCI_LIB_ADDRESS (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GEN_PMCON_2), Data16); + + return EFI_SUCCESS; +} + +/** + This function is the entry point for this PEI. + + @param[in] FfsHeader Pointer to the FFS file header + @param[in] PeiServices Pointer to the PEI services table + + @retval Return Status based on errors that occurred while waiting for time to expire. +**/ +EFI_STATUS +EFIAPI +PchMeUmaEntry ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + Status = EFI_SUCCESS; + Status = (*PeiServices)->InstallPpi (PeiServices, mPchMeUmaPpiList); + + return Status; +} diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.cif b/ReferenceCode/ME/PchMeUma/PchMeUma.cif new file mode 100644 index 0000000..4a3d2b0 --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.cif @@ -0,0 +1,13 @@ +<component> + name = "PchMeUma" + category = ModulePart + LocalRoot = "ReferenceCode\ME\PchMeUma\" + RefName = "PchMeUma" +[files] +"PchMeUma.sdl" +"PchMeUma.mak" +"PchMeUma.c" +"PchMeUma.h" +"PchMeUma.dxs" +"PchMeUma.inf" +<endComponent>
\ No newline at end of file diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.dxs b/ReferenceCode/ME/PchMeUma/PchMeUma.dxs new file mode 100644 index 0000000..0d942cb --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.dxs @@ -0,0 +1,50 @@ +/** @file + Dependency expression file for PchMeUma Init PEIM. + +@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 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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "PeimDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" + +#endif + +#include EFI_PPI_DEPENDENCY (Wdt) +#include EFI_PPI_DEPENDENCY (Stall) +#include EFI_PPI_DEFINITION (MePlatformPolicyPei) + +DEPENDENCY_START + WDT_PPI_GUID AND + PEI_STALL_PPI_GUID AND + PEI_ME_PLATFORM_POLICY_PPI_GUID +DEPENDENCY_END + + + + diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.h b/ReferenceCode/ME/PchMeUma/PchMeUma.h new file mode 100644 index 0000000..6530b23 --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.h @@ -0,0 +1,178 @@ +/** @file + Header file for Framework PEIM to PchMeUma + +@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 _PCH_ME_UMA_H_ +#define _PCH_ME_UMA_H_ + +#include EFI_PPI_DEFINITION (PchMeUma) +#include EFI_GUID_DEFINITION (MeDataHob) + +/// +/// LPT PCI Register Definition(s) +/// +#define R_MESEG_BASE 0x70 + +// +// ME FW communication timeout value definitions +// +#define DID_TIMEOUT_MULTIPLIER 0x1388 +#define MUSZV_TIMEOUT_MULTIPLIER 0x1388 +#define CPURV_TIMEOUT_MULTIPLIER 0x32 +#define STALL_1_MILLISECOND 1000 +#define STALL_100_MICROSECONDS 100 + +// +// Function Prototype(s) +// + +/** + This procedure will read and return the amount of ME UMA requested + by ME ROM from the HECI device. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + + @retval UINT32 Return ME UMA Size + @retval EFI_SUCCESS Do not check for ME UMA +**/ +UINT32 +MeSendUmaSize ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +; + +/** + Init and Install ME Hob + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS +**/ +EFI_STATUS +InstallMeHob ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +/** + This procedure will determine whether or not the CPU was replaced + during system power loss or via dynamic fusing. + Calling this procedure could result in a warm reset (if ME FW is requesting one). + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Not used. + @param[out] ForceFullTraining When set = 0x1, MRC will be forced to perform a full + memory training cycle. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +CpuReplacementCheck ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + OUT UINT8 *ForceFullTraining + ) +; + +/** + This procedure will configure the ME Host General Status register, + indicating that DRAM Initialization is complete and ME FW may + begin using the allocated ME UMA space. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + @param[in] MrcBootMode MRC BootMode + @param[in] InitStat H_GS[27:24] Status + @param[in] FtpmStolenBase The base of FTPM + + @retval EFI_SUCCESS +**/ +EFI_STATUS +MeConfigDidReg ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 InitStat, + IN UINT32 FtpmStolenBase, + IN UINT32 MeUmaSize + ) +; + +/** + This procedure will enforce the BIOS Action that was requested by ME FW + as part of the DRAM Init Done message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MrcBootMode MRC BootMode + @param[in] BiosAction Me requests BIOS to act + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +HandleMeBiosAction ( + IN EFI_PEI_SERVICES **PeiServices, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 BiosAction + ) +; + +/** + This procedure will issue a Non-Power Cycle, Power Cycle, or Global Rest. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] ResetType Type of reset to be issued. + + @retval EFI_SUCCESS The function completed successfully. + @retval All other error conditions encountered result in an ASSERT. +**/ +EFI_STATUS +PerformReset ( + IN EFI_PEI_SERVICES **PeiServices, + UINT8 ResetType + ) +; + +/** + This procedure will clear the DISB. + + @param[in] None + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +ClearDisb ( + VOID + ) +; + +/** + This procedure will clear the DISB. + + @param[in] None + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +SetDISB ( + VOID + ) +; +#endif diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.inf b/ReferenceCode/ME/PchMeUma/PchMeUma.inf new file mode 100644 index 0000000..5aae62d --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.inf @@ -0,0 +1,88 @@ +## @file +# Component description file for PchMeUma module +# +#@copyright +# Copyright (c) 2011 - 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 = PchMeUma +FILE_GUID = b6a2aff3-767c-5658-c37a-d1c82ef76543 +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + PchMeUma.c + PchMeUma.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Guid/MeDataHob + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/Ptt/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/Include/Pei + $(EDK_SOURCE)/Foundation/library/Pei/Include + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + + +[libraries.common] + EdkFrameworkPpiLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBasePciExpressLib + PeiLib + $(PROJECT_PCH_FAMILY)PpiLib + MeLibPpi + EdkIIGluePeiFirmwarePerformanceLib + PchPlatformLib + MeGuidLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = PchMeUma.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchMeUmaEntry + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.mak b/ReferenceCode/ME/PchMeUma/PchMeUma.mak new file mode 100644 index 0000000..426692e --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.mak @@ -0,0 +1,62 @@ +# MAK file for the ModulePart:PchMeUma + +all: PchMeUma + +$(BUILD_DIR)\PchMeUma.mak : $(PchMeUma_DIR)\PchMeUma.cif $(BUILD_RULES) + $(CIF2MAK) $(PchMeUma_DIR)\PchMeUma.cif $(CIF2MAK_DEFAULTS) + +PchMeUma: $(BUILD_DIR)\PchMeUma.mak PchMeUmaBin + +PchMeUma_Pei_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + $(ME_INCLUDES)\ + /I$(MePttLibrary_DIR)\Pei + + +PchMeUma_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PchMeUmaEntry"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__\ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ +!IF "$(IntelPTT_SUPPORT)"=="1" + /D PTT_FLAG +!ENDIF + +PchMeUma_LIBS =\ + $(EDKPROTOCOLLIB)\ + $(EDKFRAMEWORKPPILIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(IntelPchPpiLib_LIB)\ + $(EFIDRIVERLIB)\ + $(PEILIB)\ + $(MeLibPpi_LIB)\ + $(PchPlatformPeiLib_LIB)\ + $(MeGuidLib_LIB)\ + $(EdkIIGluePeiHobLib_LIB)\ + $(EFIGUIDLIB)\ + $(EFIPROTOCOLLIB) +## $(EdkIIGluePeiFirmwarePerformanceLib_LIB) + +PchMeUmaBin : $(PchMeUma_LIBS) $(HeciPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PchMeUma.mak all\ + NAME=PchMeUma\ + MAKEFILE=$(BUILD_DIR)\PchMeUma.mak \ + GUID=8C376010-2400-4d7d-B47B-9D851DF3C9D1\ + "MY_INCLUDES=$(PchMeUma_Pei_INCLUDES)" \ + "MY_DEFINES=$(PchMeUma_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(PchMeUma_DIR)\PchMeUma.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 diff --git a/ReferenceCode/ME/PchMeUma/PchMeUma.sdl b/ReferenceCode/ME/PchMeUma/PchMeUma.sdl new file mode 100644 index 0000000..fc09086 --- /dev/null +++ b/ReferenceCode/ME/PchMeUma/PchMeUma.sdl @@ -0,0 +1,41 @@ +TOKEN + Name = PchMeUma_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PchMeUma support in Project" +End +MODULE + Help = "Includes PchMeUma.mak to Project" + File = "PchMeUma.mak" +End + +PATH + Name = "PchMeUma_DIR" + Help = "PCH ME UMA file source directory" +End + +ELINK + Name = "PchMeUma_INCLUDES" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "/I$(PchMeUma_DIR)" + Parent = "PchMeUma_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\PchMeUma.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(ME_DIR)" + Parent = "PchMeUma_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.c b/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.c new file mode 100644 index 0000000..86e3155 --- /dev/null +++ b/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.c @@ -0,0 +1,31 @@ +/** @file + AMT Platform Policy for AMT PEIMs + +@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 +**/ + +// +// 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 EFI_PPI_DEFINITION (AmtPlatformPolicyPei) +#endif + +EFI_GUID gPeiAmtPlatformPolicyPpiGuid = PEI_AMT_PLATFORM_POLICY_PPI_GUID; + +EFI_GUID_STRING(&gPeiAmtPlatformPolicyPpiGuid, "PeiAmtPlatformPolicyPpi", "PEI Amt Platform Policy PPI"); diff --git a/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.h b/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.h new file mode 100644 index 0000000..d41d187 --- /dev/null +++ b/ReferenceCode/ME/Ppi/AmtPlatformPolicyPei/AmtPlatformPolicyPei.h @@ -0,0 +1,77 @@ +/** @file + AMT Platform Policy for AMT PEIMs + +@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 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 +**/ +#ifndef _PEI_AMT_PLATFORM_POLICY_PPI_H_ +#define _PEI_AMT_PLATFORM_POLICY_PPI_H_ + +// +// Include other definitions +// +/// +/// Intel AMT Platform Policy PPI GUID +/// This PPI provides an interface to get the current Intel AMT SKU information +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_GUID \ + { \ + 0xb4a1208e, 0x4d9a, 0x4ea2, 0x9d, 0x6b, 0xe4, 0x1a, 0x61, 0xe6, 0xc5, 0xac \ + } + +// +// Extern the GUID for PPI users. +// +extern EFI_GUID gPeiAmtPlatformPolicyPpiGuid; + +/// +/// Revision +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_REVISION_1 1 +/// +/// Add AsfEnabled, and ManageabilityMode +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_REVISION_2 2 +/// +/// Added FWProgress +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_REVISION_3 3 +/// +/// Cleanup +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_REVISION_4 4 +/// +/// Cleanup +/// +#define PEI_AMT_PLATFORM_POLICY_PPI_REVISION_5 5 + +/// +/// Intel AMT Platform Policy PPI +/// The Intel AMT Platform Policy PPI returns the Intel ME feature set in PEI phase +/// +typedef struct _PEI_AMT_PLATFORM_POLICY_PPI { + UINT8 Revision; ///< Policy structure revision number + UINT8 iAmtEnabled : 1; ///< Intel AMT features enabled/disable + UINT8 WatchDog : 1; ///< Asf Watch Dog timer message enabled/disable + UINT8 Reserved : 1; + UINT8 AsfEnabled : 1; ///< Asf features enable/disable + UINT8 ManageabilityMode : 1; ///< Manageability Mode, 0: Off, 1:On + UINT8 Reserved1 : 1; + UINT16 WatchDogTimerOs; ///< Watch Dog timeout value for OS + UINT16 WatchDogTimerBios; ///< Watch Dog timeout value for BIOS + UINT8 FWProgress; ///< Progress Event option enable/disable +} PEI_AMT_PLATFORM_POLICY_PPI; + +#endif diff --git a/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.c b/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.c new file mode 100644 index 0000000..c1f850e --- /dev/null +++ b/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.c @@ -0,0 +1,30 @@ +/** @file + AMT Status Code support at PEI phase + +@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 +**/ +#include "Tiano.h" +#include "Pei.h" + +#include EFI_PPI_DEFINITION (AmtStatusCode) + +EFI_GUID gPeiAmtStatusCodePpiGuid = PEI_AMT_STATUS_CODE_PPI_GUID; +EFI_GUID gAmtPetQueueHobGuid = AMT_PET_QUEUE_HOB_GUID; +EFI_GUID gAmtForcePushPetHobGuid = AMT_FORCE_PUSH_PET_HOB_GUID; + +EFI_GUID_STRING(&gPeiAmtStatusCodePpiGuid, "PEI AMT Status Code PPI", "PEI AMT Status Code PPI"); +EFI_GUID_STRING(&gAmtPetQueueHobGuid, "PEI AMT PET Queue Hob", "PEI AMT PET Queue Hob"); +EFI_GUID_STRING(&gAmtForcePushPetHobGuid, "PEI AMT Force Push PET Hob", "PEI AMT Force Push PET Hob"); diff --git a/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.h b/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.h new file mode 100644 index 0000000..733a57f --- /dev/null +++ b/ReferenceCode/ME/Ppi/AmtStatusCode/AmtStatusCode.h @@ -0,0 +1,120 @@ +/** @file + Header file for AMT Status Code support at PEI phase + +@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 +**/ +#ifndef _PEI_AMT_STATUS_CODE_PPI_H_ +#define _PEI_AMT_STATUS_CODE_PPI_H_ + +/// +/// Intel AMT PEI Status Code PPI GUID +/// This driver produces interface to let PEI Status Code generic driver report status to +/// Intel AMT, so that Intel AMT PET message can be sent out in PEI phase. +/// +#define PEI_AMT_STATUS_CODE_PPI_GUID \ + { \ + 0x881807d2, 0x98d1, 0x4ec9, 0xaf, 0xa0, 0x77, 0x46, 0xc4, 0x2f, 0x24, 0x49 \ + } + +extern EFI_GUID gPeiAmtStatusCodePpiGuid; + +EFI_FORWARD_DECLARATION (PEI_AMT_STATUS_CODE_PPI); + +/** + Provides an interface that a software module can call to report an ASF PEI status code. + The extension to report status code to Intel AMT, so that Intel AMT PET message will + be sent out in PEI. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This This interface. + @param[in] Type 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. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_AMT_STATUS_CODE_PPI_REPORT_STATUS_CODE) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_AMT_STATUS_CODE_PPI *This, + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ) +; + +/// +/// Intel AMT PEI Status Code PPI +/// The PEI platform status code driver should be responsible to use this interface to report +/// status code to Intel AMT. For example, memory init, memory init done, chassis intrusion. +/// So that Intel AMT driver will send corresponding PET message out. +/// +struct _PEI_AMT_STATUS_CODE_PPI { + /// + /// The extension to report status code to Intel AMT, so that Intel AMT PET message will + /// be sent out in PEI. + /// + PEI_AMT_STATUS_CODE_PPI_REPORT_STATUS_CODE ReportStatusCode; +}; + +/// +/// Queue Hob. +/// This hob is used by PEI Status Code generic driver before Intel AMT PEI status code driver +/// starts. +/// 1) If AMT driver is not ready yet, StatusCode driver can save information +/// to QueueHob. +/// 2) If after AMT driver start, but ME is not ready, the AMT +/// driver can also save information to QueueHob. +/// Later, when ME is ready, AMT driver will send all the +/// message in the QueueHob. +/// +typedef struct { + EFI_HOB_GUID_TYPE EfiHobGuidType; ///< The GUID type hob header + EFI_STATUS_CODE_VALUE Value; ///< Status code value + EFI_STATUS_CODE_TYPE Type; ///< Status code type +} AMT_PET_QUEUE_HOB; + +#define AMT_PET_QUEUE_HOB_GUID \ + { \ + 0xca0801d3, 0xafb1, 0x4dec, 0x9b, 0x65, 0x93, 0x65, 0xec, 0xc7, 0x93, 0x6b \ + } + +extern EFI_GUID gAmtPetQueueHobGuid; + +#define AMT_FORCE_PUSH_PET_HOB_GUID \ + { \ + 0x4efa0db6, 0x26dc, 0x4bb1, 0xa7, 0x6f, 0x14, 0xbc, 0x63, 0x0c, 0x7b, 0x3c \ + } + +typedef struct { + EFI_HOB_GUID_TYPE EfiHobGuidType; + INT32 MessageType; +} AMT_FORCE_PUSH_PET_HOB; + +extern EFI_GUID gAmtForcePushPetHobGuid; + +#endif diff --git a/ReferenceCode/ME/Ppi/Heci/Heci.c b/ReferenceCode/ME/Ppi/Heci/Heci.c new file mode 100644 index 0000000..9b600a7 --- /dev/null +++ b/ReferenceCode/ME/Ppi/Heci/Heci.c @@ -0,0 +1,31 @@ +/** @file + PEI Heci PPI + +@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 +**/ + +// +// 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 EFI_PPI_DEFINITION (Heci) +#endif + +EFI_GUID gPeiHeciPpiGuid = PEI_HECI_PPI_GUID; + +EFI_GUID_STRING(&gPeiHeciPpiGuid, "PEI Heci PPI", "PEI Heci PPI"); diff --git a/ReferenceCode/ME/Ppi/Heci/Heci.h b/ReferenceCode/ME/Ppi/Heci/Heci.h new file mode 100644 index 0000000..2f026b3 --- /dev/null +++ b/ReferenceCode/ME/Ppi/Heci/Heci.h @@ -0,0 +1,201 @@ +/** @file + PEI Heci PPI + +@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 + +**/ +#ifndef _PEI_HECI_PPI_H_ +#define _PEI_HECI_PPI_H_ + +#include "MeState.h" + +/// +/// HECI PPI GUID +/// This PPI provides an interface to communicate with Intel ME in PEI phase +/// +#define PEI_HECI_PPI_GUID \ + { \ + 0xEE0EA811, 0xFBD9, 0x4777, 0xB9, 0x5A, 0xBA, 0x4F, 0x71, 0x10, 0x1F, 0x74 \ + } + +extern EFI_GUID gPeiHeciPpiGuid; + +EFI_FORWARD_DECLARATION (PEI_HECI_PPI); + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in][out] Message Pointer to the message buffer. + @param[in] HeciMemBar HECI Memory BAR. + @param[in][out] Length Length of the message in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @retval EFI_SUCCESS Command succeeded + @retval EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @retval EFI_TIMEOUT HECI does not return the bufferbefore timeout + @retval EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_HECI_SENDWACK) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *Message, + IN UINT32 HeciMemBar, + IN OUT UINT32 *Length, + IN UINT8 HostAddress, + IN UINT8 MeAddress + ); + +/** + Read the HECI Message from Intel ME with size in Length into + buffer Message. Set Blocking to BLOCKING and code will wait + until one message packet is received. When set to + NON_BLOCKING, if the circular buffer is empty at the time, the + code not wait for the message packet read. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @exception EFI_UNSUPPORTED Current ME mode doesn't support this function + @retval EFI_SUCCESS One message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_DEVICE_ERROR Zero-length message packet read + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_HECI_READ_MESSAGE) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 Blocking, + IN UINT32 HeciMemBar, + IN UINT32 *MessageBody, + IN OUT UINT32 *Length + ); + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI. + @param[in] HeciMemBar HECI Memory BAR. + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HEC +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_HECI_SEND_MESSAGE) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN UINT32 *Message, + IN UINT32 HeciMemBar, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MEAddress + ); + +/** + Determines if the HECI device is present and, if present, initializes it for + use by the BIOS. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The address of HECI PPI + @param[in][out] HeciMemBar HECI Memory BAR + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_DEVICE_ERROR No HECI device + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @exception EFI_UNSUPPORTED HECI MSG is unsupported +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_INITIALIZE_HECI) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_HECI_PPI *This, + IN OUT UINT32 *HeciMemBar + ); + +/** + Get an abstract Intel ME Status from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MeStatus Pointer for status report, + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_HECI_GET_ME_STATUS) ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *Status + ); + +/** + Get an abstract ME operation mode from firmware status + register. This is used to control BIOS flow for different + Intel ME functions. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[out] MeMode Pointer for ME Mode report, + see MeState.h - Abstract ME Mode definitions. + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +typedef +EFI_STATUS +(EFIAPI *PEI_HECI_GET_ME_MODE) ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 *MeMode + ); + +/// +/// HECI PPI +/// The interface functions are for sending/receiving HECI messages between host and Intel ME subsystem +/// in PEI phase +/// +struct _PEI_HECI_PPI { + PEI_HECI_SENDWACK SendwAck; ///< Send HECI message and wait for respond + PEI_HECI_READ_MESSAGE ReadMsg; ///< Read message from HECI + PEI_HECI_SEND_MESSAGE SendMsg; ///< Send message to HECI + PEI_INITIALIZE_HECI InitializeHeci; ///< Init HECI + PEI_HECI_GET_ME_STATUS GetMeStatus; ///< Get Intel ME Status register + PEI_HECI_GET_ME_MODE GetMeMode; ///< Get Intel ME mode +}; + +#endif diff --git a/ReferenceCode/ME/Ppi/MeLibPpi.cif b/ReferenceCode/ME/Ppi/MeLibPpi.cif new file mode 100644 index 0000000..da1b41c --- /dev/null +++ b/ReferenceCode/ME/Ppi/MeLibPpi.cif @@ -0,0 +1,22 @@ +<component> + name = "MeLibPpi" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Ppi\" + RefName = "MeLibPpi" +[files] +"MeLibPpi.sdl" +"MeLibPpi.mak" +"MeLibPpi.inf" +"AmtStatusCode\AmtStatusCode.h" +"AmtStatusCode\AmtStatusCode.c" +"Heci\Heci.h" +"Heci\Heci.c" +"AmtPlatformPolicyPei\AmtPlatformPolicyPei.c" +"AmtPlatformPolicyPei\AmtPlatformPolicyPei.h" +"MePlatformPolicyPei\MePlatformPolicyPei.h" +"MePlatformPolicyPei\MePlatformPolicyPei.c" +"PlatformMeHook\PlatformMeHook.h" +"PlatformMeHook\PlatformMeHook.c" +"PchMeUma\PchMeUma.c" +"PchMeUma\PchMeUma.h" +<endComponent> diff --git a/ReferenceCode/ME/Ppi/MeLibPpi.inf b/ReferenceCode/ME/Ppi/MeLibPpi.inf new file mode 100644 index 0000000..7a4973e --- /dev/null +++ b/ReferenceCode/ME/Ppi/MeLibPpi.inf @@ -0,0 +1,59 @@ +## @file +# Component description file for Me PPI library. +# +#@copyright +# Copyright (c) 2005 - 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 = MeLibPpi +COMPONENT_TYPE = LIBRARY + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[sources.common] + AmtStatusCode/AmtStatusCode.c + AmtStatusCode/AmtStatusCode.h + Heci/Heci.c + Heci/Heci.h + AmtPlatformPolicyPei/AmtPlatformPolicyPei.c + AmtPlatformPolicyPei/AmtPlatformPolicyPei.h + MePlatformPolicyPei/MePlatformPolicyPei.c + MePlatformPolicyPei/MePlatformPolicyPei.h + PlatformMeHook/PlatformMeHook.c + PlatformMeHook/PlatformMeHook.h + PchMeUma/PchMeUma.c + PchMeUma/PchMeUma.h + +[nmake.common] +C_STD_INCLUDE= + diff --git a/ReferenceCode/ME/Ppi/MeLibPpi.mak b/ReferenceCode/ME/Ppi/MeLibPpi.mak new file mode 100644 index 0000000..139f0d1 --- /dev/null +++ b/ReferenceCode/ME/Ppi/MeLibPpi.mak @@ -0,0 +1,43 @@ +# /*++ +# 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:MeLibPpi +all : MeLibPpi + +$(MeLibPpi_LIB) : MeLibPpi + +MeLibPpi : $(BUILD_DIR)\MeLibPpi.mak MeLibPpiBin + +$(BUILD_DIR)\MeLibPpi.mak : $(MeLibPpi_DIR)\$(@B).cif $(MeLibPpi_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeLibPpi_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeLibPpi_INCLUDES = \ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES) + +MeLibPpiBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeLibPpi.mak all\ + "MY_INCLUDES=$(MeLibPpi_INCLUDES)" \ + 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/Ppi/MeLibPpi.sdl b/ReferenceCode/ME/Ppi/MeLibPpi.sdl new file mode 100644 index 0000000..cedbd4b --- /dev/null +++ b/ReferenceCode/ME/Ppi/MeLibPpi.sdl @@ -0,0 +1,34 @@ +TOKEN + Name = "MeLibPpi_SUPPORT" + Value = "1" + Help = "Main switch to enable MeLibPpi support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "MeLibPpi_DIR" +End + +MODULE + Help = "Includes MeLibPpi.mak to Project" + File = "MeLibPpi.mak" +End + +ELINK + Name = "MeLibPpi_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeLibPpi.lib" + Parent = "MeLibPpi_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(MeLibPpi_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.c b/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.c new file mode 100644 index 0000000..e371be3 --- /dev/null +++ b/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.c @@ -0,0 +1,31 @@ +/** @file + ME Platform Policy for ME PEIMs + +@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 +**/ + +// +// 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 EFI_PPI_DEFINITION (MePlatformPolicyPei) +#endif + +EFI_GUID gPeiMePlatformPolicyPpiGuid = PEI_ME_PLATFORM_POLICY_PPI_GUID; + +EFI_GUID_STRING(&gPeiMePlatformPolicyPpiGuid, "PeiMePlatformPolicyPpi", "PEI Me Platform Policy PPI"); diff --git a/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.h b/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.h new file mode 100644 index 0000000..034b955 --- /dev/null +++ b/ReferenceCode/ME/Ppi/MePlatformPolicyPei/MePlatformPolicyPei.h @@ -0,0 +1,58 @@ +/** @file + ME Platform Policy for ME PEIMs + +@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 +**/ +#ifndef _PEI_ME_PLATFORM_POLICY_PPI_H_ +#define _PEI_ME_PLATFORM_POLICY_PPI_H_ + +// +// Include other definitions +// +/// +/// ME policy provided by platform for PEI phase +/// The Platform Policy PPI returns the Intel ME feature set in PEI phase +/// +#define PEI_ME_PLATFORM_POLICY_PPI_GUID \ + { \ + 0x7ae3ceb7, 0x2ee2, 0x48fa, 0xaa, 0x49, 0x35, 0x10, 0xbc, 0x83, 0xca, 0xbf \ + } + +// +// Extern the GUID for PPI users. +// +extern EFI_GUID gPeiMePlatformPolicyPpiGuid; + +// +// Revision +// +#define PEI_ME_PLATFORM_POLICY_PPI_REVISION_1 1 +#define PEI_ME_PLATFORM_POLICY_PPI_REVISION_2 2 + +/// +/// +/// ME policy provided by platform for PEI phase +/// The Platform Policy PPI returns the Intel ME feature set in PEI phase +/// +typedef struct _PEI_ME_PLATFORM_POLICY_PPI { + UINT8 Revision; ///< Revision for the protocol structure + UINT8 Reserved1 : 1; ///< Reserved for Intel internal use + UINT8 Reserved2 : 1; ///< Reserved for Intel internal use + UINT8 Reserved : 6; ///< Reserved for Intel internal use + UINT8 FTpmSwitch; +} PEI_ME_PLATFORM_POLICY_PPI; + +#endif diff --git a/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.c b/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.c new file mode 100644 index 0000000..a7478d1 --- /dev/null +++ b/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.c @@ -0,0 +1,42 @@ +/** @file + This file defines the Pch Me UMA function + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the PPI header file +// +#include EFI_PPI_DEFINITION (PchMeUma) +#endif +// +// PPI GUID definition +// +EFI_GUID gPchMeUmaPpiGuid = PCH_ME_UMA_PPI_GUID; + +// +// PPI description +// +EFI_GUID_STRING(&gPchMeUmaPpiGuid, "PchMeUma PPI", "Intel(R) PCH ME UMA PPI"); diff --git a/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.h b/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.h new file mode 100644 index 0000000..ef9b0a3 --- /dev/null +++ b/ReferenceCode/ME/Ppi/PchMeUma/PchMeUma.h @@ -0,0 +1,159 @@ +/** @file + Interface definition details for PCH Me UMA. + +@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 +**/ +#ifndef _PCH_ME_UMA_PPI_H_ +#define _PCH_ME_UMA_PPI_H_ + +/// +/// ME UMA PPI +/// The interface functions are for configure/receiving Me FW in PEI phase. +/// +#define PCH_ME_UMA_PPI_GUID \ + { \ + 0x8c376010, 0x2400, 0x4d7d, 0xb4, 0x7b, 0x9d, 0x85, 0x1d, 0xf3, 0xc9, 0xd1 \ + } + +extern EFI_GUID gPchMeUmaPpiGuid; + +// +// Revision +// +#define PCH_ME_UMA_PPI_REVISION 1 + +/// +/// define the MRC recommended boot modes. +/// +typedef enum { + s3Boot, ///< In current implementation, bmS3 == bmWarm + warmBoot, + coldBoot, + fastBoot, +} MRC_BOOT_MODE_T; + +/** + This procedure will read and return the amount of ME UMA requested + by ME ROM from the HECI device. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + + @retval UINT32 Return ME UMA Size + @retval EFI_SUCCESS Do not check for ME UMA +**/ +typedef +UINT32 +(EFIAPI *ME_SEND_UMA_SIZE) ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +; + +/** + This procedure will determine whether or not the CPU was replaced + during system power loss or via dynamic fusing. + Calling this procedure could result in a warm reset (if ME FW is requesting one). + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Not used. + @param[out] ForceFullTraining When set = 0x1, MRC will be forced to perform a full + memory training cycle. + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *CPU_REPLACEMENT_CHECK) ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + OUT UINT8 *ForceFullTraining + ) +; + +/** + This procedure will configure the ME Host General Status register, + indicating that DRAM Initialization is complete and ME FW may + begin using the allocated ME UMA space. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] FfsHeader Pointer to the FFS file header + @param[in] MrcBootMode MRC BootMode + @param[in] InitStat H_GS[27:24] Status + @param[in] FtpmStolenBase The base of FTPM + + @retval EFI_SUCCESS +**/ +typedef +EFI_STATUS +(EFIAPI *ME_CONFIG_DID_REG) ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 InitStat, + IN UINT32 FtpmStolenBase, + IN UINT32 MeUmaSize + + ) +; + +/** + This procedure will enforce the BIOS Action that was requested by ME FW + as part of the DRAM Init Done message. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] MrcBootMode MRC BootMode + @param[in] BiosAction Me requests BIOS to act + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +typedef +EFI_STATUS +(EFIAPI *HANDLE_ME_BIOS_ACTION) ( + IN EFI_PEI_SERVICES **PeiServices, + IN MRC_BOOT_MODE_T MrcBootMode, + IN UINT8 BiosAction + ) +; + +/// +/// ME UMA PPI +/// This PPI provides an interface to get the ME UMA size and performs the DID handshake with ME +/// +typedef struct PCH_ME_UMA_PPI { + /// + /// This procedure will read and return the amount of ME UMA requested by ME ROM from the + /// HECI device + /// + ME_SEND_UMA_SIZE MeSendUmaSize; + /// + /// This procedure will determine whether or not the CPU was replaced during system power loss + /// or via dynamic fusing + /// + CPU_REPLACEMENT_CHECK CpuReplacementCheck; + /// + /// This procedure will configure the ME Host General Status register, indicating that DRAM + /// Initialization is complete and ME FW may begin using the allocated ME UMA space + /// + ME_CONFIG_DID_REG MeConfigDidReg; + /// + /// This procedure will enforce the BIOS Action that was requested by ME FW as part of the + /// DRAM Init Done message + /// + HANDLE_ME_BIOS_ACTION HandleMeBiosAction; +} PCH_ME_UMA_PPI; + +#endif diff --git a/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.c b/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.c new file mode 100644 index 0000000..96dc6c9 --- /dev/null +++ b/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.c @@ -0,0 +1,42 @@ +/** @file + This file defines the Platform ME Hook function + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the PPI header file +// +#include EFI_PPI_DEFINITION (PlatformMeHook) +#endif +// +// PPI GUID definition +// +EFI_GUID gPlatformMeHookPpiGuid = PLATFORM_ME_HOOK_PPI_GUID; + +// +// PPI description +// +EFI_GUID_STRING(&gPlatformMeHookPpiGuid, "PlatformMeHook PPI", "Intel(R) PEIM Phase ME Platform Hook PPI"); diff --git a/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.h b/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.h new file mode 100644 index 0000000..92c0292 --- /dev/null +++ b/ReferenceCode/ME/Ppi/PlatformMeHook/PlatformMeHook.h @@ -0,0 +1,70 @@ +/** @file + Interface definition details for platform hook support to ME module. + +@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 +**/ +#ifndef _PLATFORM_ME_HOOK_PPI_H_ +#define _PLATFORM_ME_HOOK_PPI_H_ + +/// +/// ME Hook provided by platform for PEI phase +/// This ppi provides an interface to hook reference code by OEM. +/// +#define PLATFORM_ME_HOOK_PPI_GUID \ + { \ + 0xe806424f, 0xd425, 0x4b1a, 0xbc, 0x26, 0x5f, 0x69, 0x03, 0x89, 0xa1, 0x5a \ + } + +extern EFI_GUID gPlatformMeHookPpiGuid; + +EFI_FORWARD_DECLARATION (PLATFORM_ME_HOOK_PPI); + +// +// Revision +// +#define PLATFORM_ME_HOOK_PPI_REVISION 1 + +/** + Platform hook before BIOS sends Global Reset Heci Message to ME + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to this PLATFORM_ME_HOOK_PPI + + @retval EFI Status Code +**/ +typedef +EFI_STATUS +(EFIAPI *PLATFORM_ME_HOOK_PRE_GLOBAL_RESET) ( + IN EFI_PEI_SERVICES **PeiServices, + IN PLATFORM_ME_HOOK_PPI *This + ); + +/// +/// ME Hook provided by platform for PEI phase +/// This ppi provides an interface to hook reference code by OEM. +/// +struct _PLATFORM_ME_HOOK_PPI { + /// + /// Revision for the ppi structure + /// + UINT8 Revision; + /// + /// Function pointer for the hook called before BIOS sends Global Reset Heci Message to ME + // + PLATFORM_ME_HOOK_PRE_GLOBAL_RESET PreGlobalReset; +}; + +#endif diff --git a/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.c b/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.c new file mode 100644 index 0000000..521426b --- /dev/null +++ b/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.c @@ -0,0 +1,46 @@ +/** @file + Defines and prototypes for the ActiveManagement driver. + This driver implements the ActiveManagement protocol for iAMT. + It provides some functions to get Boot Options from ASF. + +@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 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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (ActiveManagement) +#endif +// +// Protocol GUID definition +// +EFI_GUID gEfiActiveManagementProtocolGuid = EFI_ACTIVE_MANAGEMENT_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING( + &gEfiActiveManagementProtocolGuid, "Active Management Protocol", "The active management protocol provides services." + ); diff --git a/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.h b/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.h new file mode 100644 index 0000000..17a5045 --- /dev/null +++ b/ReferenceCode/ME/Protocol/ActiveManagement/ActiveManagement.h @@ -0,0 +1,140 @@ +/** @file + Active Management Technology Protocol to return the state of ASF Boot Options + related to Active Management Technology. + +@copyright + Copyright (c) 2005 - 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 +**/ +#ifndef _EFI_ACTIVE_MANAGEMENT_PROTOCOL_H_ +#define _EFI_ACTIVE_MANAGEMENT_PROTOCOL_H_ + +#include EFI_PROTOCOL_DEFINITION (AlertStandardFormat) + +/// +/// Intel Active Management Technology Protocol +/// This protocol provides interface to get ASF boot options status +/// +#define EFI_ACTIVE_MANAGEMENT_PROTOCOL_GUID \ + { \ + 0x8555fd40, 0x140b, 0x4f3c, 0x90, 0x5e, 0x3b, 0xf3, 0x78, 0xa0, 0x99, 0xfa \ + } + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiActiveManagementProtocolGuid; + +// +// Forward reference for ANSI C compatibility +// +EFI_FORWARD_DECLARATION (EFI_ACTIVE_MANAGEMENT_PROTOCOL); + +// +// Protocol definitions +// + +/** + Return current state of Boot Options + @param[in] This Pointer to the EFI_ACTIVE_MANAGEMENT_PROTOCOL instance. + @param[in] CurrentState TRUE when the boot options is enabled + + @retval EFI_SUCCESS Command succeed. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE) ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT BOOLEAN *CurrentState + ) +; + +/** + This will return IDE Redirection boot device to boot + + @param[in] 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 + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ACTIVE_MANAGEMENT_IDER_BOOT_DEVICE_SELECTED) ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT UINT8 *IdeBootDevice + ) +; + +/** + Return current ASF Boot Options + + @param[in] This Pointer to the EFI_ACTIVE_MANAGEMENT_PROTOCOL instance. + @param[in] AsfBootOptions ASF Boot Options + + @retval EFI_SUCCESS Command succeed. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ACTIVE_MANAGEMENT_ASF_BOOT_OPTIONS_GET) ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +; + +/** + This will return verbosity request option + + @param[in] CurrentState Return the state of verbosity option + + @retval EFI_SUCCESS The function completed successfully. + @retval CurrentState 00 - No BootOption available + 01 - Non-Verbosity request + 02 - Verbosity request +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ACTIVE_MANAGEMENT_VERBOSITY_REQUESTED) ( + IN EFI_ACTIVE_MANAGEMENT_PROTOCOL *This, + IN OUT UINT8 *CurrentState + ) +; + +/// +/// Intel Active Management Technology Protocol +/// It provides abstract level function of ASF boot options defined in ASF 2.0 specification for +/// other modules to get ASF boot options status. +/// +struct _EFI_ACTIVE_MANAGEMENT_PROTOCOL { + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetIderState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetEnforceSecureBootState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetSolState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetRemoteFlashState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetBiosSetupState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetBiosPauseState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetConsoleLockState; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetKvmState; + EFI_ACTIVE_MANAGEMENT_IDER_BOOT_DEVICE_SELECTED GetIderBootDeviceSelectd; + EFI_ACTIVE_MANAGEMENT_ASF_BOOT_OPTIONS_GET GetAsfBootOptions; + EFI_ACTIVE_MANAGEMENT_BOOT_OPTIONS_STATE GetProgressMsgRequest; +}; + +#endif diff --git a/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.c b/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.c new file mode 100644 index 0000000..256fed5 --- /dev/null +++ b/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.c @@ -0,0 +1,32 @@ +/** @file + Definition of Alert Standard Format (ASF) 2.0 + +@copyright + Copyright (c) 2005 - 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 +**/ + +// +// 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_DEFINITION (AlertStandardFormat) +#endif + +EFI_GUID gEfiAlertStandardFormatProtocolGuid = EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GUID; + +EFI_GUID_STRING + (&gEfiAlertStandardFormatProtocolGuid, "Alert Standard Format Protocol", "Alert Standard Format Protocol"); diff --git a/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.h b/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.h new file mode 100644 index 0000000..3d4bf3b --- /dev/null +++ b/ReferenceCode/ME/Protocol/AlertStandardFormat/AlertStandardFormat.h @@ -0,0 +1,185 @@ +/** @file + Definition of Alert Standard Format (ASF) 2.0 + +@copyright + Copyright (c) 2005 - 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 +**/ +#ifndef __ALERT_STANDARD_FORMAT_PROTOCOL_H__ +#define __ALERT_STANDARD_FORMAT_PROTOCOL_H__ + +/// +/// Alert Standard Format Protocol +/// This protocol provides interfaces to get ASF Boot Options and send ASF messages +/// +#define EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GUID \ + { \ + 0xcc93a70b, 0xec27, 0x49c5, 0x8b, 0x34, 0x13, 0x93, 0x1e, 0xfe, 0xd6, 0xe2 \ + } + +typedef struct _EFI_ALERT_STANDARD_FORMAT_PROTOCOL EFI_ALERT_STANDARD_FORMAT_PROTOCOL; + +#pragma pack(1) +typedef struct { + UINT8 SubCommand; + UINT8 Version; + UINT32 IanaId; + UINT8 SpecialCommand; + UINT16 SpecialCommandParam; + UINT16 BootOptions; + UINT16 OemParameters; +} EFI_ASF_BOOT_OPTIONS; + +typedef struct { + UINT8 SubCommand; + UINT8 Version; + UINT8 EventSensorType; + UINT8 EventType; + UINT8 EventOffset; + UINT8 EventSourceType; + UINT8 EventSeverity; + UINT8 SensorDevice; + UINT8 SensorNumber; + UINT8 Entity; + UINT8 EntityInstance; + UINT8 Data0; + UINT8 Data1; +} EFI_ASF_MESSAGE; + +typedef struct { + UINT8 SubCommand; + UINT8 Version; +} EFI_ASF_CLEAR_BOOT_OPTIONS; +#pragma pack() +// +// Special Command Attributes +// +#define NOP 0x00 +#define FORCE_PXE 0x01 +#define FORCE_HARDDRIVE 0x02 +#define FORCE_SAFEMODE 0x03 +#define FORCE_DIAGNOSTICS 0x04 +#define FORCE_CDDVD 0x05 + +// +// Boot Options Mask +// +#define LOCK_POWER_BUTTON 0x0002 ///< 0000 0000 0000 0010 - bit 1 +#define LOCK_RESET_BUTTON 0x0004 ///< 0000 0000 0000 0200 - bit 2 +#define LOCK_KEYBOARD 0x0020 ///< 0000 0000 0010 0000 - bit 5 +#define LOCK_SLEEP_BUTTON 0x0040 ///< 0000 0000 0100 0000 - bit 6 +#define USER_PASSWORD_BYPASS 0x0800 ///< 0000 1000 0000 0000 - bit 3 +#define FORCE_PROGRESS_EVENTS 0x1000 ///< 0001 0000 0000 0000 - bit 4 +#define FIRMWARE_VERBOSITY_DEFAULT 0x0000 ///< 0000 0000 0000 0000 - bit 6:5 +#define FIRMWARE_VERBOSITY_QUIET 0x2000 ///< 0010 0000 0000 0000 - bit 6:5 +#define FIRMWARE_VERBOSITY_VERBOSE 0x4000 ///< 0100 0000 0000 0000 - bit 6:5 +#define FIRMWARE_VERBOSITY_BLANK 0x6000 ///< 0110 0000 0000 0000 - bit 6:5 +#define CONFIG_DATA_RESET 0x8000 ///< 1000 0000 0000 0000 - bit 7 +#define ASF_BOOT_OPTIONS_PRESENT 0x16 +#define ASF_BOOT_OPTIONS_NOT_PRESENT 0x17 + +#define USE_KVM 0x0020 ///< 0000 0000 0010 0000 - bit 5 +/// +/// ASF Internet Assigned Numbers Authority Manufacturer ID +/// (The firmware sends 0XBE110000 for decimal value 4542) +/// +#define INDUSTRY_IANA_SWAP32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) +#define ASF_INDUSTRY_IANA 0x000011BE +#define ASF_INDUSTRY_CONVERTED_IANA INDUSTRY_IANA_SWAP32 (ASF_INDUSTRY_IANA) ///< 0XBE110000, received from ME FW + +/** + Return the SMBus address used by the ASF driver. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @retval EFI_SUCCESS Address returned + @retval EFI_INVALID_PARAMETER Invalid SMBus address +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GET_SMBUSADDR) ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + OUT UINTN *SmbusDeviceAddress + ) +; + +/** + Set the SMBus address used by the ASF driver. 0 is an invalid address. + Not applicable in Intel ME/HECI system, need to return EFI_UNSUPPORTED. + + @param[in] SmbusAddr SMBus address of the controller + + @retval EFI_SUCCESS Address set + @retval EFI_INVALID_PARAMETER Invalid SMBus address +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ALERT_STANDARD_FORMAT_PROTOCOL_SET_SMBUSADDR) ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN UINTN SmbusDeviceAddress + ) +; + +/** + Return the ASF Boot Options obtained from the controller. If the + Boot Options parameter is NULL and no boot options have been retrieved, + Query the ASF controller for its boot options. + Get ASF Boot Options through HECI. + + @param[in] AsfBootOptions Pointer to ASF boot options to copy current ASF Boot options + + @retval EFI_SUCCESS Boot options copied + @retval EFI_NOT_READY No boot options +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GET_BOOT_OPTIONS) ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN OUT EFI_ASF_BOOT_OPTIONS **AsfBootOptions + ) +; + +/** + Send ASF Message. + Send ASF Message through HECI. + + @param[in] AsfMessage Pointer to ASF message + + @retval EFI_SUCCESS Boot options copied + @retval EFI_INVALID_PARAMETER Invalid pointer + @retval EFI_NOT_READY No controller +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ALERT_STANDARD_FORMAT_PROTOCOL_SEND_ASF_MESSAGE) ( + IN EFI_ALERT_STANDARD_FORMAT_PROTOCOL *This, + IN EFI_ASF_MESSAGE *AsfMessage + ) +; + +/// +/// Alert Standard Format Protocol +/// This protocol provides interfaces to get ASF Boot Options and send ASF messages +/// HECI protocol is consumed and used to send ASF messages and receive ASF Boot Options +/// +struct _EFI_ALERT_STANDARD_FORMAT_PROTOCOL { + EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GET_SMBUSADDR GetSmbusAddr; + EFI_ALERT_STANDARD_FORMAT_PROTOCOL_SET_SMBUSADDR SetSmbusAddr; + EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GET_BOOT_OPTIONS GetBootOptions; + EFI_ALERT_STANDARD_FORMAT_PROTOCOL_SEND_ASF_MESSAGE SendAsfMessage; +}; + +extern EFI_GUID gEfiAlertStandardFormatProtocolGuid; + +#endif diff --git a/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.c b/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.c new file mode 100644 index 0000000..f947dfc --- /dev/null +++ b/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.c @@ -0,0 +1,44 @@ +/** @file + This file defines the EFI AMT policy Protocol which implements the + Intel(R) Active Management Technology + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (AmtPlatformPolicy) +#endif +// +// Protocol GUID definition +// +EFI_GUID gDxePlatformAmtPolicyGuid = DXE_PLATFORM_AMT_POLICY_GUID; + +// +// Protocol description +// +EFI_GUID_STRING + (&gDxePlatformAmtPolicyGuid, "AmtPlatformPolicy Protocol", "Intel(R) DXE Phase AMT Platform Policy Protocol"); diff --git a/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.h b/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.h new file mode 100644 index 0000000..bfc98ff --- /dev/null +++ b/ReferenceCode/ME/Protocol/AmtPlatformPolicy/AmtPlatformPolicy.h @@ -0,0 +1,111 @@ +/** @file + Interface definition details between AMT and platform drivers during DXE 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 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 +**/ +#ifndef _AMT_PLATFORM_POLICY_H_ +#define _AMT_PLATFORM_POLICY_H_ + +/// +/// AMT policy provided by platform for DXE phase +/// This protocol provides the information about Intel AMT platform configuration settings. +/// +#define DXE_PLATFORM_AMT_POLICY_GUID \ + { \ + 0x6725e645, 0x4a7f, 0x9969, 0x82, 0xec, 0xd1, 0x87, 0x21, 0xde, 0x5a, 0x57 \ + } + +/// +/// Protocol revision number +/// Any backwards compatible changes to this protocol will result in an update in the revision number +/// Major changes will require publication of a new protocol +/// +#define DXE_PLATFORM_AMT_POLICY_PROTOCOL_REVISION_1 1 ///< Initial Revision + +extern EFI_GUID gDxePlatformAmtPolicyGuid; +#pragma pack(1) +typedef struct { + // + // Byte 0, bit definition for functionality enable/disable + // + UINT8 AsfEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 iAmtEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 iAmtbxPasswordWrite : 1; ///< 0: Disabled; 1: Enabled + UINT8 WatchDog : 1; ///< 0: Disabled; 1: Enabled + UINT8 CiraRequest : 1; ///< 0: No CIRA request; 1: Trigger CIRA request + UINT8 ManageabilityMode : 1; ///< 0: Disabled; 1:AMT + UINT8 UnConfigureMe : 1; ///< 0: No; 1: Un-configure ME without password + UINT8 MebxDebugMsg : 1; ///< 0: Disabled; 1: Enabled + // + // Byte 1, bit definition for functionality enable/disable + // + UINT8 ForcMebxSyncUp : 1; ///< 0: No; 1: Force MEBX execution + UINT8 UsbrEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 UsbLockingEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 HideUnConfigureMeConfirm : 1; ///< 0: Don't hide; 1: Hide Un-configure ME Confirmation Prompt + UINT8 USBProvision : 1; ///< 0: Disabled; 1: Enabled + UINT8 FWProgress : 1; ///< 0: Disabled; 1: Enabled + UINT8 iAmtbxHotkeyPressed : 1; ///< 0: Disabled; 1: Enabled + UINT8 iAmtbxSelectionScreen : 1; ///< 0: Disabled; 1: Enabled + // + // Byte 2, bit definition for functionality enable/disable + // + UINT8 AtEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 Byte2Reserved : 7; + UINT16 WatchDogTimerOs; ///< Byte 3-4 OS WatchDog Timer + UINT16 WatchDogTimerBios; ///< Byte 5-6 BIOS WatchDog Timer + /// + /// Byte 7 CIRA Timeout: Client Initiated Remote Access Timeout + /// OEM defined timeout for MPS connection to be established. + /// 0: 60 seconds by default, 0xFF: Wait until the connection succeeds. + /// 1~0xFE: Values in seconds + /// + UINT8 CiraTimeout; + + /// + /// Byte 8 CPU Replacement Timeout + /// 0: 10 seconds; 1: 30 seconds; 2~5: Reserved; 6: No delay; 7: Unlimited delay + /// + UINT8 CpuReplacementTimeout; + // + // Byte 9-10 OemResolutionSettings + // + UINT16 MebxNonUiTextMode : 4; ///< 0: Auto; 1: 80x25; 2: 100x31 + UINT16 MebxUiTextMode : 4; ///< 0: Auto; 1: 80x25; 2: 100x31 + UINT16 MebxGraphicsMode : 4; ///< 0: Auto; 1: 640x480; 2: 800x600; 3: 1024x768 + UINT16 OemResolutionSettingsRsvd : 4; + // + // Byte 11-14 Pointer to a list which contain on-board devices bus/device/fun number + // + UINT32 PciDeviceFilterOutTable; + // + // Byte 15-23 Reserved and make AMT_CONFIG as 32 bit alignment + // + UINT8 ByteReserved[9]; +} AMT_CONFIG; + +#pragma pack() +/// +/// AMT DXE Platform Policy +/// This protocol is initialized by platform Policy driver. Other modules can locate this protocol +/// to retrieve Intel AMT related setup options setting +/// +typedef struct _DXE_AMT_POLICY_PROTOCOL { + UINT8 Revision; ///< Revision for the protocol structure + AMT_CONFIG AmtConfig; ///< AMT policy for platform code to pass to Reference Code +} DXE_AMT_POLICY_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.c b/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.c new file mode 100644 index 0000000..d23795c --- /dev/null +++ b/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.c @@ -0,0 +1,31 @@ +/** @file + AmtReadyToBoot Protocol definitions + +@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 +**/ + +// +// 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_DEFINITION (AmtReadyToBoot) +#endif + +EFI_GUID gAmtReadyToBootProtocolGuid = AMT_READY_TO_BOOT_PROTOCOL_GUID; + +EFI_GUID_STRING(&gAmtReadyToBootProtocolGuid, "AMT ReadyToBoot Protocol", "AMT ReadyToBoot Protocol") diff --git a/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.h b/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.h new file mode 100644 index 0000000..93e784f --- /dev/null +++ b/ReferenceCode/ME/Protocol/AmtReadyToBoot/AmtReadyToBoot.h @@ -0,0 +1,56 @@ +/** @file + AmtReadyToBoot Protocol definitions + +@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 +**/ +#ifndef _AMT_READY_TO_BOOT_PROTOCOL_H_ +#define _AMT_READY_TO_BOOT_PROTOCOL_H_ + +/// +/// AMT Readt to Boot Protocol +/// This protocol performs all Management Engine task +/// +#define AMT_READY_TO_BOOT_PROTOCOL_GUID \ + { \ + 0x40b09b5a, 0xf0ef, 0x4627, 0x93, 0xd5, 0x27, 0xf0, 0x4b, 0x75, 0x4d, 0x5 \ + } + +EFI_FORWARD_DECLARATION (AMT_READY_TO_BOOT_PROTOCOL); + +/** + Signal an event for Amt ready to boot. + + @param[in] None + + @retval EFI_SUCCESS Mebx launched or no controller +**/ +typedef +EFI_STATUS +(EFIAPI *AMT_READY_TO_BOOT_PROTOCOL_SIGNAL) ( + VOID + ); + +/// +/// AMT Readt to Boot Protocol +/// The interface functions are for Performing all Management Engine task +/// +struct _AMT_READY_TO_BOOT_PROTOCOL { + AMT_READY_TO_BOOT_PROTOCOL_SIGNAL Signal; ///< Performs all Management Engine task +}; + +extern EFI_GUID gAmtReadyToBootProtocolGuid; + +#endif diff --git a/ReferenceCode/ME/Protocol/At/At.c b/ReferenceCode/ME/Protocol/At/At.c new file mode 100644 index 0000000..60a4c2c --- /dev/null +++ b/ReferenceCode/ME/Protocol/At/At.c @@ -0,0 +1,39 @@ +/** @file + Defines and prototypes for the At driver. + This driver implements the At protocol. + +@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 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 +**/ + +// +// Statements that include other files +// +#include "EdkIIGlueDxe.h" + +// +// Include the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (At) + +// +// Protocol GUID definition +// +EFI_GUID gEfiAtProtocolGuid = EFI_AT_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING(&gEfiAtProtocolGuid, "AT Protocol", "Intel (R) AT Protocol Services."); diff --git a/ReferenceCode/ME/Protocol/At/At.h b/ReferenceCode/ME/Protocol/At/At.h new file mode 100644 index 0000000..39a8dbd --- /dev/null +++ b/ReferenceCode/ME/Protocol/At/At.h @@ -0,0 +1,247 @@ +/** @file + Defines and prototypes for the AT driver. + This driver implements the AT protocol. + +@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 + +**/ +#ifndef _DXE_AT_PROTOCOL_H_ +#define _DXE_AT_PROTOCOL_H_ +#include "MkhiMsgs.h" +/// +/// Define the protocol GUID +/// +#define EFI_AT_PROTOCOL_GUID \ + { \ + 0x2df8cdbe, 0x79ce, 0x48a0, 0x8c, 0x59, 0x50, 0xf7, 0x1d, 0xe1, 0xad, 0xd1 \ + } + +/// +/// Protocol revision number +/// Any backwards compatible changes to this protocol will result in an update in the revision number +/// Major changes will require publication of a new protocol +/// +#define AT_PROTOCOL_REVISION 1 + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiAtProtocolGuid; + +// +// Forward reference for ANSI C compatibility +// +EFI_FORWARD_DECLARATION (EFI_AT_PROTOCOL); + +// +// Protocol definitions +// + +/** + This function sends a request to ME AT Services to validate AT + recovery credentials. The user input is captured in UTF-16 + format and then passed to this funtion. This function converts + the User recovery password into a HASH by using Salt & Nonce + and then send the password HASH to ME AT Services for + validation. ME AT Service compares the Password HASH and + returns either pass or fail. + + @param[in] This The address of protocol + @param[in] PassPhrase Passphrase that needs to be authenticated sent to ME + @param[in] PassType Password type user or server generated + @param[in][out] IsAuthenticated The return of the password match 1 for success and 0 for fail + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures + @retval EFI_SUCCESS The function completed successfully +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_AUTHETICATE_CREDENTIAL) ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN UINT32 *PassType, + IN OUT UINT8 *IsAuthenticated + ); + +/** + This API compute the SHA1 hash of the user enterted password + + @param[in] This The address of protocol + @param[in] PassPhrase The passphrase for which SHA1 hash to be computed + @param[in][out] Hash The return value of the SHA1 hash + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_COMPUTE_HASH) ( + IN EFI_AT_PROTOCOL *This, + IN UINT8 *PassPhrase, + IN OUT UINT8 *Hash + ); + +/** + This gets the ME nonce + @param[in] This The address of protocol + @param[in][out] Nonce The return value of the 16 Byte nonce received from ME + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_NONCE) ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *Nonce + ); + +/** + This API get the AT Unlock Timer values + + @param[in] This The address of protocol + @param[in] Interval The return value of the Unlock Time Interval that was set by AT Server + @param[in] TimeLeft The Timeleft in the Unlock Timer + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_TIMER_INFO) ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT32 *Interval, + IN OUT UINT32 *TimeLeft + ); + +/** + This retrives the ISV String stored by AT Server that BIOS will display during Platform lock state + + @param[in] This The address of protocol + @param[in] StringId The String buffer ID to retrive the ISV String + @param[out] IsvString 256 Bytes of ISV string array, the + @param[out] IsvStringLength The String length + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_RECOVERY_STRING) ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 *StringId, + IN OUT UINT8 *IsvString, + IN OUT UINT32 *IsvStringLength + ); + +/** + This receives the ISV ID from ME and display the ID, when the platform is in stolen state + + @param[in] This The address of protocol + @param[out] IsvId The pointer to 4 byte ISV ID + + @retval EFI_SUCCESS The function completed successfully. +**/typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_ISV_ID) ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT32 *IsvId + ); + +/** + This instructs FW that a WWAN recovery is desired and thus the Radio needs to be initialized. + + This command in not supported. + + @param[in] This The address of protocol +**/typedef +EFI_STATUS +(EFIAPI *EFI_AT_SET_SUSPEND_STATE) ( + IN EFI_AT_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_AT_INIT_WWAN_RECOV) ( + IN EFI_AT_PROTOCOL *This + ); + +/** + This queries FW of the NIC Radio Status + + This command in not supported. + + @param[in] This The address of protocol + @param[in] RadioStatus Radio status + @param[in] NetworkStatus Network status +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_WWAN_NIC_STATUS) ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *RadioStatus, + IN OUT UINT8 *NetworkStatus + ); + +/** + This send an AssertStolen Message to ME when OEM has set the AllowAssertStolen bit to be accepted by BIOS. + + @param[in] This The address of protocol + @param[out] CompletionCode The return ME Firmware return code for this request + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_SEND_ASSERT_STOLEN) ( + IN EFI_AT_PROTOCOL *This, + IN OUT UINT8 *CompletionCode + ); + +/** + This queries FW of the AT Status in Unsigned mode + + @param[in] This The address of protocol + @param[out] StateUnsigned Structure retrieved from ME describing current AT state + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_AT_GET_STATE_UNSIGNED) ( + IN EFI_AT_PROTOCOL *This, + IN OUT AT_STATE_INFO *StateUnsigned + ); + +/// +/// Protocol definition +/// +struct _EFI_AT_PROTOCOL { + UINT8 Revision; + EFI_AT_AUTHETICATE_CREDENTIAL AuthenticateCredential; + EFI_AT_COMPUTE_HASH ComputeHash; + EFI_AT_GET_NONCE GetNonce; + EFI_AT_GET_TIMER_INFO GetTimerInfo; + EFI_AT_GET_RECOVERY_STRING GetRecoveryString; + EFI_AT_GET_ISV_ID GetIsvId; + EFI_AT_SEND_ASSERT_STOLEN SendAssertStolen; + EFI_AT_SET_SUSPEND_STATE SetSuspendState; + EFI_AT_INIT_WWAN_RECOV InitWWAN; + EFI_AT_GET_WWAN_NIC_STATUS GetWWANNicStatus; + EFI_AT_GET_STATE_UNSIGNED GetStateUnsigned; +}; + +#endif diff --git a/ReferenceCode/ME/Protocol/AtAm/ATAM.c b/ReferenceCode/ME/Protocol/AtAm/ATAM.c new file mode 100644 index 0000000..04d86ee --- /dev/null +++ b/ReferenceCode/ME/Protocol/AtAm/ATAM.c @@ -0,0 +1,40 @@ +/** @file + Defines AtAm protocol. + +@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 +**/ + +// +// Statements that include other files +// +#include "EdkIIGlueDxe.h" + +// +// Include the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (AtAm) + +// +// Protocol GUID definition +// +EFI_GUID gEfiAtAmProtocolGuid = EFI_ATAM_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING(&gEfiAtAmProtocolGuid, "AtAm Protocol", "Intel (R) AtAm Protocol Services."); diff --git a/ReferenceCode/ME/Protocol/AtAm/ATAM.h b/ReferenceCode/ME/Protocol/AtAm/ATAM.h new file mode 100644 index 0000000..5d75f33 --- /dev/null +++ b/ReferenceCode/ME/Protocol/AtAm/ATAM.h @@ -0,0 +1,249 @@ +/** @file + Header file for ATAM + +@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 _DXE_ATAM_PROTOCOL_H_ +#define _DXE_ATAM_PROTOCOL_H_ + +#include "MkhiMsgs.h" + +/// +/// Define the protocol GUID +/// +#define EFI_ATAM_PROTOCOL_GUID \ + { \ + 0x8aebaa5a, 0x556f, 0x404b, 0x96, 0x05, 0x38, 0xe0, 0xde, 0x29, 0x76, 0x2f \ + } + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiAtProtocolGuid; + +#define ATAM_PROTOCOL_REVISION 3 + +// +// Forward reference for ANSI C compatibility +// + +#define ISV_PLATFORM_ID_LENGTH 16 +#define SERVER_SHORTCODE_LENGTH 16 +#define DEFAULT_LANGUAGE_STRING 4 + +// +// Forward reference for ANSI C compatibility +// +EFI_FORWARD_DECLARATION (EFI_ATAM_PROTOCOL); + +#pragma pack(1) +typedef struct { + + UINT8 BiosLanguageSupport[DEFAULT_LANGUAGE_STRING]; + UINT8 Reserved[2]; + + /// + /// Defines the number which will be used by BIOS before making BIOS AM as a + /// default recovery mechanism + /// + UINT16 PbaOverRideThreshold; + + /// + /// The value used by BIOS to try sending GPS location when AT stolen + /// + UINT8 BiosLocationBeconing; + + /// + /// This will be used for Notebook transfer authorization request + /// + UINT8 PlatformAuthReq; + + /// + /// This will be used for Notebook transfer authorization acknowledgement + /// + UINT8 PlatformAuthAck; + + /// + /// This will be used for AT Server short code + /// + UINT8 ServerShortCode[SERVER_SHORTCODE_LENGTH]; + + /// + /// This allow ISV to set unique platform ID and will be used for displayed on need basis + /// + UINT16 IsvPlatformId[ISV_PLATFORM_ID_LENGTH]; + +} AT_BIOS_RECOVERY_CONFIG; +#pragma pack() + +/// +/// Protocol definitions +/// + +/** + This function gets the ISV Strings stored by AT Server that BIOS will display. + + @param[in] This The address of protocol + @param[out] IsvString Isv string pointer + @param[out] IsvId Intel(R) Anti-Theft service provider Id + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_ISV_ID) ( + IN EFI_ATAM_PROTOCOL *This, + OUT UINT8 *IsvString, + OUT UINT32 *IsvId + ); + +/** + This function gets recovery config. + + @param[in] This The address of protocol + @param[out] RecoveryConfig Pointer to structure + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_RECOVERY_CONFIG) ( + IN EFI_ATAM_PROTOCOL *This, + OUT AT_BIOS_RECOVERY_CONFIG *RecoveryConfig + ); + +/** + This function returns time left to enter password. + + @param[in] This The address of protocol + @param[out] TimeLeft Time + @param[out] TimeInterval Time interval + + @retval EFI_SUCCESS The function completed + successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_TIMER) ( + IN EFI_ATAM_PROTOCOL *This, + OUT UINT32 *TimeLeft, + OUT UINT32 *TimeInterval + ); + +/** + This function gets 16 bytes nonce from firmware and also converts it to string according to format "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XX". + + @param[in] This The address of protocol + @param[out] NonceStr Pointer to Nonce string + + @retval EFI_SUCCESS The function completed + successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_NONCE) ( + IN EFI_ATAM_PROTOCOL *This, + OUT UINT8 *NonceStr + ); + +/** + This routine receives the data (passphrase or SRTK) from UI and verifies it if the password (either passphrase or SRTK) is acceptable. + + @param[in] This The address of protocol + @param[in] PasswordEntered Pointer to string + @param[in] PassType Password type + @param[out] IsAuthenticated Pointer to result of verification + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_VERIFY_PASSWORD) ( + IN EFI_ATAM_PROTOCOL *This, + IN UINT8 *PasswordEntered, + IN UINT32 PassType, + OUT UINT8 *IsAuthenticated + ); + +/** + This routine receives the SRTK from UI and verifies it if the password is acceptable. This requests FW to enter or exit Suspend mode based on user input. + + @param[in] This The address of protocol + @param[in] TransitionState 1- enter suspend state, 0 - exit suspend state + @param[in] Token Pointer to token + + @retval EFI_SUCCESS The function completed successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_SET_SUSPEND_STATE) ( + IN EFI_ATAM_PROTOCOL *This, + IN UINT32 TransitionState, + IN UINT8 *Token + ); + +/** + This routine gets AT state. + + @param[in] This The address of protocol + @param[out] AtStateInfo State of AT + + @retval EFI_SUCCESS The function completed + successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_AT_STATE_INFO) ( + IN EFI_ATAM_PROTOCOL *This, + OUT AT_STATE_INFO *AtStateInfo + ); + +/** + This routine gets PBA failed count value. + + @param[out] PbaFailedExceeded TRUE when the PbaOverrideThreshold is exceeded + @param[out] PbaFailedAttempts Number of failed attempts + @param[out] PbaFailedThreshold Pba failed count treshold + + @retval EFI_SUCCESS The function completed + successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ATAM_GET_PBA_COUNTER) ( + OUT UINT8* PbaFailedExceeded, + OUT UINT16* PbaFailedAttempts, + OUT UINT16* PbaFailedThreshold + ); + +/// +/// Protocol definition +/// +struct _EFI_ATAM_PROTOCOL { + UINT8 Revision; + EFI_ATAM_GET_ISV_ID AtAmGetIsvId; + EFI_ATAM_GET_RECOVERY_CONFIG AtAmGetRecoveryConfig; + EFI_ATAM_GET_TIMER AtAmGetTimer; + EFI_ATAM_GET_NONCE AtAmGetNonce; + EFI_ATAM_VERIFY_PASSWORD AtAmVerifyPassword; + EFI_ATAM_SET_SUSPEND_STATE AtAmSetSuspendState; + EFI_ATAM_GET_AT_STATE_INFO AtAmGetAtStateInfo; + EFI_ATAM_GET_PBA_COUNTER AtAmGetPbaCounter; +}; + +#endif diff --git a/ReferenceCode/ME/Protocol/AtAm/AtAm.cif b/ReferenceCode/ME/Protocol/AtAm/AtAm.cif new file mode 100644 index 0000000..bd47708 --- /dev/null +++ b/ReferenceCode/ME/Protocol/AtAm/AtAm.cif @@ -0,0 +1,9 @@ +<component> + name = "ATAM Protocol" + category = ModulePart + LocalRoot = "ReferenceCode\Me\Protocol\AtAm" + RefName = "ATAMProtocols" +[files] +"ATAM.h" +"ATAM.c" +<endComponent> diff --git a/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.c b/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.c new file mode 100644 index 0000000..98e0c9d --- /dev/null +++ b/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.c @@ -0,0 +1,43 @@ +/** @file + This driver implements the AT Platform Policy protocol. + +@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 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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (AtPlatformPolicy) +#endif +// +// Protocol GUID definition +// +EFI_GUID gDxePlatformAtPolicyGuid = DXE_PLATFORM_AT_POLICY_GUID; + +// +// Protocol description +// +EFI_GUID_STRING + (&gDxePlatformAtPolicyGuid, "AtPlatformPolicy Protocol", "Intel(R) DXE Phase At Platform Policy Protocol"); diff --git a/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.h b/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.h new file mode 100644 index 0000000..9cf00d7 --- /dev/null +++ b/ReferenceCode/ME/Protocol/AtPlatformPolicy/AtPlatformPolicy.h @@ -0,0 +1,57 @@ +/** @file + This driver implements the AT Platform Policy protocol. + +@copyright + Copyright (c) 2004 - 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 _DXE_AT_PLATFORM_POLICY_H_ +#define _DXE_AT_PLATFORM_POLICY_H_ + +/// +/// AT policy provided by platform for DXE phase +/// +#define DXE_PLATFORM_AT_POLICY_GUID \ + { \ + 0x3f4ea4d4, 0xb465, 0x4f3f, 0x9c, 0x92, 0xb3, 0x40, 0xab, 0x58, 0x96, 0xb5 \ + } + +/// +/// Protocol revision number +/// Any backwards compatible changes to this protocol will result in an update in the revision number +/// Major changes will require publication of a new protocol +/// +#define DXE_PLATFORM_AT_POLICY_PROTOCOL_REVISION_1 1 +#define DXE_PLATFORM_AT_POLICY_PROTOCOL_REVISION_2 2 + +extern EFI_GUID gDxePlatformAtPolicyGuid; +#pragma pack(1) +typedef struct { + UINT8 AtAmBypass; ///< Byte 0, bit definition for functionality enable/disable + UINT8 AtEnterSuspendState; + UINT8 AtSupported; + UINT8 AtPba; + UINT8 ByteReserved[28]; ///< Bytes 4-31 Reserved and make AT_CONFIG as 32 bit alignment +} AT_CONFIG; +#pragma pack() +/// +/// AMT DXE Platform Policy +/// +typedef struct _DXE_AT_POLICY_PROTOCOL { + UINT8 Revision; + AT_CONFIG At; +} DXE_AT_POLICY_PROTOCOL; +#endif diff --git a/ReferenceCode/ME/Protocol/Heci/Heci.c b/ReferenceCode/ME/Protocol/Heci/Heci.c new file mode 100644 index 0000000..64ac0f4 --- /dev/null +++ b/ReferenceCode/ME/Protocol/Heci/Heci.c @@ -0,0 +1,31 @@ +/** @file + EFI Heci Protocol + +@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 +**/ + +// +// 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_DEFINITION (Heci) +#endif + +EFI_GUID gEfiHeciProtocolGuid = HECI_PROTOCOL_GUID; + +EFI_GUID_STRING(&gEfiHeciProtocolGuid, "HECI Protocol", "EFI 2.0 HECI Protocol"); diff --git a/ReferenceCode/ME/Protocol/Heci/Heci.h b/ReferenceCode/ME/Protocol/Heci/Heci.h new file mode 100644 index 0000000..fcb14a1 --- /dev/null +++ b/ReferenceCode/ME/Protocol/Heci/Heci.h @@ -0,0 +1,243 @@ +/** @file + EFI HECI Protocol + +@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 + +**/ +#ifndef _EFI_HECI_H +#define _EFI_HECI_H + +#include "MeState.h" + +/// +/// HECI protocol provided for DXE phase +/// This protocol provides an interface to communicate with Intel ME subsystem via HECI +/// +#define HECI_PROTOCOL_GUID \ + { \ + 0xcfb33810, 0x6e87, 0x4284, 0xb2, 0x3, 0xa6, 0x6a, 0xbe, 0x7, 0xf6, 0xe8 \ + } + +#define EFI_HECI_PROTOCOL_GUID HECI_PROTOCOL_GUID + +EFI_FORWARD_DECLARATION (EFI_HECI_PROTOCOL); + +/** + Function sends one messsage through the HECI circular buffer and waits + for the corresponding ACK message. + + @param[in][out] Message Pointer to the message buffer. + @param[in] SendLength Length of the message in bytes. + @param[in][out] RecLength Length of the message response in bytes. + @param[in] HostAddress Address of the sending entity. + @param[in] MeAddress Address of the ME entity that should receive the message. + + @exception EFI_SUCCESS Command succeeded + @exception EFI_DEVICE_ERROR HECI Device error, command aborts abnormally + @exception EFI_TIMEOUT HECI does not return the buffer before timeout + @exception EFI_BUFFER_TOO_SMALL Message Buffer is too small for the Acknowledge + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_SENDWACK) ( + IN OUT UINT32 *Message, + IN OUT UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MEAddress + ) +; + +/** + Read the HECI Message from Intel ME with size in Length into + buffer MessageBody. Set Blocking to BLOCKING and code will + wait until one message packet is received. When set to + NON_BLOCKING, if the circular buffer is empty at the time, the + code will not wait for the message packet. + + @param[in] Blocking Used to determine if the read is BLOCKING or NON_BLOCKING. + @param[in][out] MessageBody Pointer to a buffer used to receive a message. + @param[in][out] Length Pointer to the length of the buffer on input and the length + of the message on return. (in bytes) + + @retval EFI_SUCCESS One message packet read. + @retval EFI_DEVICE_ERROR Failed to initialize HECI or zero-length message packet read + @retval EFI_TIMEOUT HECI is not ready for communication + @retval EFI_BUFFER_TOO_SMALL The caller's buffer was not large enough +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_READ_MESSAGE) ( + IN UINT32 Blocking, + IN UINT32 *MessageBody, + IN OUT UINT32 *Length + ) +; + +/** + Function sends one messsage (of any length) through the HECI circular buffer. + + @param[in] Message Pointer to the message data to be sent. + @param[in] Length Length of the message in bytes. + @param[in] HostAddress The address of the host processor. + @param[in] MeAddress Address of the ME subsystem the message is being sent to. + + @retval EFI_SUCCESS One message packet sent. + @retval EFI_DEVICE_ERROR Failed to initialize HECI + @retval EFI_TIMEOUT HECI is not ready for communication + @exception EFI_UNSUPPORTED Current ME mode doesn't support send message through HECI +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_SEND_MESSAGE) ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MEAddress + ) +; + +/** + Reset the HECI Controller with algorithm defined in the RS - + Intel(R) Management Engine - Host Embedded Controller + Interface Hardware Programming Specification (HPS) + @param[in] none + + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @retval EFI_SUCCESS Interface reset +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_RESET) ( + VOID + ) +; + +/** + Initialize the HECI Controller with algorithm defined in the + RS - Intel(R) Management Engine - Host Embedded Controller + Interface Hardware Programming Specification (HPS). + Determines if the HECI device is present and, if present, + initializes it for use by the BIOS. + + @param[in] None. + + @retval EFI_SUCCESS HECI device is present and initialized + @retval EFI_TIMEOUT HECI does not return the buffer before timeout +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_INIT) ( + VOID + ) +; + +/** + Re-initialize the HECI Controller with algorithm defined in the RS - Intel(R) Management Engine + - Host Embedded Controller Interface Hardware Programming Specification (HPS). + Heci Re-initializes it for Host + + @param[in] None. + + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @retval EFI_STATUS Status code returned by ResetHeciInterface +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_REINIT) ( + VOID + ) +; + +/** + Reset Intel ME and timeout if Ready is not set after Delay timeout + + @param[in] Delay Timeout value in microseconds + + @retval EFI_TIMEOUT HECI does not return the buffer before timeout + @retval EFI_SUCCESS Me is ready +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_RESET_WAIT) ( + IN UINT32 Delay + ) +; + +/** + Get an abstract Intel ME State from Firmware Status Register. + This is used to control BIOS flow for different Intel ME + functions. + The ME status information is obtained by sending HECI messages + to Intel ME and is used both by the platform code and + reference code. This will optimize boot time because system + BIOS only sends each HECI message once. It is recommended to + send the HECI messages to Intel ME only when ME mode is normal + (Except for HMRFPO Disable Message) and ME State is NORMAL or + RECOVERY (Suitable for AT and Kernel Messaging only). + + @param[out] MeStatus Pointer for abstract status report, + see MeState.h - Abstract ME status definitions. + + @retval EFI_SUCCESS MeStatus copied + @retval EFI_INVALID_PARAMETER Pointer of MeStatus is invalid +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_GET_ME_STATUS) ( + OUT UINT32 *Status + ) +; + +/** + Get an abstract ME operation mode from firmware status + register. This is used to control BIOS flow for different + Intel ME functions. + + @param[out] MeMode Pointer for ME Mode report, + see MeState.h - Abstract ME Mode definitions. + + @retval EFI_SUCCESS MeMode copied + @retval EFI_INVALID_PARAMETER Pointer of MeMode is invalid +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_GET_ME_MODE) ( + OUT UINT32 *Mode + ) +; + +/// +/// HECI protocol provided for DXE phase +/// The interface functions are for sending/receiving HECI messages between host and Intel ME subsystem. +/// There is also support to control HECI Initialization and get Intel ME status. +/// +struct _EFI_HECI_PROTOCOL { + EFI_HECI_SENDWACK SendwACK; ///< Send HECI message and wait for respond + EFI_HECI_READ_MESSAGE ReadMsg; ///< Receive HECI message + EFI_HECI_SEND_MESSAGE SendMsg; ///< Send HECI message + EFI_HECI_RESET ResetHeci; ///< Reset HECI device + EFI_HECI_INIT InitHeci; ///< Initialize HECI device + EFI_HECI_RESET_WAIT MeResetWait; ///< Intel ME Reset Wait Timer + EFI_HECI_REINIT ReInitHeci; ///< Re-initialize HECI + EFI_HECI_GET_ME_STATUS GetMeStatus; ///< Get Intel ME Status register + EFI_HECI_GET_ME_MODE GetMeMode; ///< Get Intel ME mode +}; + +extern EFI_GUID gEfiHeciProtocolGuid; + +#endif // _EFI_HECI_H diff --git a/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.c b/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.c new file mode 100644 index 0000000..cd28c0e --- /dev/null +++ b/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.c @@ -0,0 +1,40 @@ +/*++ + 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 +--*/ +/*++ + +Copyright (c) 1999 - 2010 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. + +Module Name: + + HeciSmm.c + +Abstract: + + SMM Heci Protocol +Revision History + +--*/ + +// +// 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_DEFINITION (HeciSmm) +#endif + +EFI_GUID gSmmHeciProtocolGuid = SMM_HECI_PROTOCOL_GUID; + +EFI_GUID_STRING(&gSmmHeciProtocolGuid, "SMM HECI Protocol", "EFI 2.0 SMM HECI Protocol"); diff --git a/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.h b/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.h new file mode 100644 index 0000000..667a1fb --- /dev/null +++ b/ReferenceCode/ME/Protocol/HeciSmm/HeciSmm.h @@ -0,0 +1,122 @@ +/*++ + 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 +--*/ +/*++ + +Copyright (c) 2010 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. + +Module Name: + + HeciSmm.h + +Abstract: + + SMM HECI Protocol + +--*/ +#ifndef _SMM_HECI_H +#define _SMM_HECI_H + +#include "MeState.h" + +#define SMM_HECI_PROTOCOL_GUID \ + { \ + 0xFC9A50C1, 0x8B3D, 0x40D0, 0x99, 0x12, 0x6E, 0x26, 0xD7, 0x89, 0x6C, 0xBA \ + } +//- 0x826824b6, 0xcc9b, 0x4d62, 0x8e, 0x7a, 0xf, 0xfb, 0xf6, 0x1, 0x3c, 0xbe +#define AMI_HECI_SMM_GUID \ + { \ + 0xFC9A50C1, 0x8B3D, 0x40D0, 0x99, 0x12, 0x6E, 0x26, 0xD7, 0x89, 0x6C, 0xBA \ + } + + +EFI_FORWARD_DECLARATION (SMM_HECI_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_SENDWACK) ( + IN OUT UINT32 *Message, + IN OUT UINT32 Length, + IN OUT UINT32 *RecLength, + IN UINT8 HostAddress, + IN UINT8 MEAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_READ_MESSAGE) ( + IN UINT32 Blocking, + IN UINT32 *MessageBody, + IN OUT UINT32 *Length + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_SEND_MESSAGE) ( + IN UINT32 *Message, + IN UINT32 Length, + IN UINT8 HostAddress, + IN UINT8 MEAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_RESET) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_INIT) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_REINIT) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_RESET_WAIT) ( + IN UINT32 Delay + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_GET_ME_STATUS) ( + IN UINT32 *Status + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HECI_GET_ME_MODE) ( + IN UINT32 *Mode + ); + +typedef struct _SMM_HECI_PROTOCOL { + EFI_HECI_SENDWACK SendwACK; + EFI_HECI_READ_MESSAGE ReadMsg; + EFI_HECI_SEND_MESSAGE SendMsg; + EFI_HECI_RESET ResetHeci; + EFI_HECI_INIT InitHeci; + EFI_HECI_RESET_WAIT MeResetWait; + EFI_HECI_REINIT ReInitHeci; + EFI_HECI_GET_ME_STATUS GetMeStatus; + EFI_HECI_GET_ME_MODE GetMeMode; +} SMM_HECI_PROTOCOL; + +extern EFI_GUID gSmmHeciProtocolGuid; + +#endif // _SMM_HECI_H diff --git a/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.c b/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.c new file mode 100644 index 0000000..f68b7f4 --- /dev/null +++ b/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.c @@ -0,0 +1,31 @@ +/** @file + Protocol used for IDE-R Controller Driver. + +@copyright + Copyright (c) 2005 - 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 +**/ + +// +// 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_DEFINITION (IderControllerDriver) +#endif + +EFI_GUID gEfiIderControllerDriverProtocolGuid = EFI_IDER_CONTROLLER_DRIVER_PROTOCOL_GUID; + +EFI_GUID_STRING(&gEfiIderControllerDriverProtocolGuid, "IDE-R Controller Driver", "EFI IDE-R Controller Driver GUID") diff --git a/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.h b/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.h new file mode 100644 index 0000000..05ccf4e --- /dev/null +++ b/ReferenceCode/ME/Protocol/IderControllerDriver/IderControllerDriver.h @@ -0,0 +1,34 @@ +/** @file + IDE-R Controller Driver Protocol definitions. + We can specify normal IDE contorller driver and IDE-R controller by checking this GUID + +@copyright + Copyright (c) 2005 - 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 +**/ +#ifndef _EFI_IDER_CONTROLLER_DRIVER_PROTOCOL_H_ +#define _EFI_IDER_CONTROLLER_DRIVER_PROTOCOL_H_ + +/// +/// IDER Controller Driver Protocol +/// This protocol is used in Platform BDS phase to identify IDE-R boot devices. +/// +#define EFI_IDER_CONTROLLER_DRIVER_PROTOCOL_GUID \ + { \ + 0x956a2ed0, 0xa6cf, 0x409a, 0xb8, 0xf5, 0x35, 0xf1, 0x4c, 0x3e, 0x3c, 0x2 \ + } + +extern EFI_GUID gEfiIderControllerDriverProtocolGuid; + +#endif diff --git a/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.c b/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.c new file mode 100644 index 0000000..c52ff21 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.c @@ -0,0 +1,43 @@ +/** @file + This file defines the Me Bios Payload Data Protocol which implements the + Intel(R) Management Engine + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (MeBiosPayloadData) +#endif +// +// Protocol GUID definition +// +EFI_GUID gMeBiosPayloadDataProtocolGuid = ME_BIOS_PAYLOAD_DATA_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING(&gMeBiosPayloadDataProtocolGuid, "MeBiosPayloadData Protocol", "Intel(R) DXE Phase MBP Protocol"); diff --git a/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.h b/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.h new file mode 100644 index 0000000..4a90ebb --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeBiosPayloadData/MeBiosPayloadData.h @@ -0,0 +1,138 @@ +/** @file + Interface definition details for MBP during DXE 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 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 +**/ +#ifndef _MBP_DATA_PROTOCOL_H_ +#define _MBP_DATA_PROTOCOL_H_ +#include "CoreBiosMsg.h" + +/// +/// MBP Protocol for DXE phase +/// +#define ME_BIOS_PAYLOAD_DATA_PROTOCOL_GUID \ + { \ + 0x71a19494, 0x2ab6, 0x4e96, 0x85, 0x81, 0xcf, 0x34, 0x25, 0x42, 0x73, 0xfe \ + } + +/// +/// Revision 1: Original version +/// +#define DXE_MBP_DATA_PROTOCOL_REVISION_1 1 +#define DXE_MBP_DATA_PROTOCOL_REVISION_2 2 +extern EFI_GUID gMeBiosPayloadDataProtocolGuid; + +#pragma pack(push, 1) +typedef struct _MBP_FW_VERSION_NAME { + UINT32 MajorVersion : 16; + UINT32 MinorVersion : 16; + UINT32 HotfixVersion : 16; + UINT32 BuildVersion : 16; +} MBP_FW_VERSION_NAME; + +typedef struct _MBP_ICC_PROFILE { + UINT8 NumIccProfiles; + UINT8 IccProfileSoftStrap; + UINT8 IccProfileIndex; + UINT8 Reserved; + ICC_LOCK_REGS_INFO IccLockRegInfo; +} MBP_ICC_PROFILE; + +typedef struct _MBP_FW_CAPS_SKU { + MEFWCAPS_SKU FwCapabilities; + BOOLEAN Available; +} MBP_FW_CAPS_SKU; + +typedef struct _MBP_FW_FEATURES_STATE { + MEFWCAPS_SKU FwFeatures; + BOOLEAN Available; +} MBP_FW_FEATURES_STATE; + +typedef struct _MBP_ROM_BIST_DATA { + UINT16 DeviceId; + UINT16 FuseTestFlags; + UINT32 UMCHID[4]; +} MBP_ROM_BIST_DATA; + +typedef struct _MBP_PLATFORM_KEY { + UINT32 Key[8]; +} MBP_PLATFORM_KEY; + +typedef struct _MBP_PLAT_TYPE { + PLATFORM_TYPE_RULE_DATA RuleData; + BOOLEAN Available; +} MBP_PLAT_TYPE; + +typedef union _HWA_DATA { + UINT32 Raw; + struct { + UINT32 MediaTablePush : 1; + UINT32 Reserved : 31; + } Fields; +} HWA_DATA; + +typedef struct _MBP_HWA_REQ { + HWA_DATA Data; + BOOLEAN Available; +} MBP_HWA_REQ; + +typedef struct _MBP_PERF_DATA { + UINT32 PwrbtnMrst; + UINT32 MrstPltrst; + UINT32 PltrstCpurst; +} MBP_PERF_DATA; + +typedef struct _PLAT_BOOT_PERF_DATA { + MBP_PERF_DATA MbpPerfData; + BOOLEAN Available; +} PLAT_BOOT_PERF_DATA; + +typedef struct _MBP_NFC_DATA { + UINT32 DeviceType :2; + UINT32 Reserved : 29; + UINT32 Hide :1; +} MBP_NFC_DATA; + +typedef struct _MBP_NFC_SUPPORT { + MBP_NFC_DATA NfcData; + BOOLEAN Available; +} MBP_NFC_SUPPORT; + +typedef struct { + MBP_FW_VERSION_NAME FwVersionName; + MBP_FW_CAPS_SKU FwCapsSku; + MBP_FW_FEATURES_STATE FwFeaturesState; + MBP_ROM_BIST_DATA RomBistData; + MBP_PLATFORM_KEY PlatformKey; + MBP_PLAT_TYPE FwPlatType; + MBP_ICC_PROFILE IccProfile; + AT_STATE_INFO AtState; + UINT32 MFSIntegrity; + MBP_HWA_REQ HwaRequest; + PLAT_BOOT_PERF_DATA PlatBootPerfData; + MBP_NFC_SUPPORT NfcSupport; +} ME_BIOS_PAYLOAD; +#pragma pack(pop) +/// +/// MBP DXE Protocol +/// +typedef struct _DXE_MBP_DATA_PROTOCOL { + EFI_HANDLE Handle; + UINT8 Revision; + ME_BIOS_PAYLOAD MeBiosPayload; +} DXE_MBP_DATA_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.c b/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.c new file mode 100644 index 0000000..351c98e --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.c @@ -0,0 +1,31 @@ +/** @file + ME FW Global NVS Area description protocol implementation. + +@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 Mobile Silicon Support Module" and is + licensed for Intel Mobile 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 +**/ +#include "EdkIIGlueDxe.h" + +#include "MeGlobalNvsArea.h" + +EFI_GUID gMeGlobalNvsAreaProtocolGuid = ME_GLOBAL_NVS_AREA_PROTOCOL_GUID; + +EFI_GUID_STRING + ( + &gMeGlobalNvsAreaProtocolGuid, "ME Global NVS Area Protocol", + "Protocol describing MEFW ACPI NVS memory region used by ACPI subsystem." + ); diff --git a/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.h b/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.h new file mode 100644 index 0000000..ce037a1 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeGlobalNvsArea/MeGlobalNvsArea.h @@ -0,0 +1,72 @@ +/** @file + Definition of the MEFW global NVS area protocol. This protocol + publishes the address and format of a global ACPI NVS buffer used as a communications + buffer between SMM/DXE/PEI code and ASL code. + @todo The format is derived from the ACPI reference code, version 0.95. + + Note: Data structures defined in this protocol are not naturally aligned. + +@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 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 +**/ +#ifndef _ME_GLOBAL_NVS_AREA_H_ +#define _ME_GLOBAL_NVS_AREA_H_ + +/// +/// Includes +/// +/// +/// Forward reference for pure ANSI compatability +/// +EFI_FORWARD_DECLARATION (ME_GLOBAL_NVS_AREA_PROTOCOL); + +/// +/// ME Global NVS Area Protocol GUID +/// +#define ME_GLOBAL_NVS_AREA_PROTOCOL_GUID \ + { \ + 0x3bffecfd, 0xd75f, 0x4975, 0xb8, 0x88, 0x39, 0x02, 0xbd, 0x69, 0x00, 0x2b \ + } + +/// +/// Extern the GUID for protocol users. +/// +extern EFI_GUID gMeGlobalNvsAreaProtocolGuid; + +/// +/// Global NVS Area definition +/// +#pragma pack(1) +typedef struct { + UINT32 MeNvsRevision; ///< 000 Me NVS Protocol Revision + /// + /// PTT Solution + /// + UINT8 FTpmSwitch; /// (004) fTPM Solution Method Selection + /// + /// PTT Allocated Buffer Address + /// + UINT64 PTTAddress; /// (005) PTT Allocated Buffer Address + +} ME_GLOBAL_NVS_AREA; +#pragma pack() +/// +/// ME Global NVS Area Protocol +/// +typedef struct _ME_GLOBAL_NVS_AREA_PROTOCOL { + ME_GLOBAL_NVS_AREA *Area; +} ME_GLOBAL_NVS_AREA_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.c b/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.c new file mode 100644 index 0000000..8679604 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.c @@ -0,0 +1,44 @@ +/** @file + This file defines the EFI ME policy Protocol which implements the + Intel(R) Management Engine + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy) +#endif +// +// Protocol GUID definition +// +EFI_GUID gDxePlatformMePolicyGuid = DXE_PLATFORM_ME_POLICY_GUID; + +// +// Protocol description +// +EFI_GUID_STRING + (&gDxePlatformMePolicyGuid, "MePlatformPolicy Protocol", "Intel(R) DXE Phase ME Platform Policy Protocol"); diff --git a/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.h b/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.h new file mode 100644 index 0000000..ee3ef25 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MePlatformPolicy/MePlatformPolicy.h @@ -0,0 +1,134 @@ +/** @file + Interface definition details between ME and platform drivers during DXE phase. + +@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 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 +**/ +#ifndef _ME_PLATFORM_POLICY_H_ +#define _ME_PLATFORM_POLICY_H_ + +/// +/// ME policy provided by platform for DXE phase +/// This protocol provides an interface to get Intel ME Configuration information +/// +#define DXE_PLATFORM_ME_POLICY_GUID \ + { \ + 0x69bf9e8a, 0x4ad6, 0x9a28, 0x87, 0xf3, 0x09, 0xa0, 0x71, 0x29, 0x2a, 0x00 \ + } + +/// +/// Initial Revision +/// +#define DXE_PLATFORM_ME_POLICY_PROTOCOL_REVISION_1 1 +/// +/// Remove MbpSecurity +/// +#define DXE_PLATFORM_ME_POLICY_PROTOCOL_REVISION_2 2 +extern EFI_GUID gDxePlatformMePolicyGuid; + +#pragma pack(1) + +typedef struct { + // + // Byte 0, bit definition for functionality enable/disable + // + UINT8 MeFwDownGrade : 1; ///< 0: Disabled; 1: Enabled + UINT8 MeLocalFwUpdEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 Byte0ReservedBit2 : 1; + UINT8 EndOfPostEnabled : 1; ///< 0: Disabled; 1: Enabled + UINT8 EndOfPostDone : 1; ///< 0: Not yet; 1: Done + UINT8 MdesCapability : 1; ///< 0: Disabled; 1: Enabled + UINT8 SvtForPchCap: 1; ///< 0: Disabled; 1: Enabled + UINT8 MdesForBiosState : 1; ///< 0: Disabled; 1: Enabled + UINT8 ByteReserved[15]; ///< Byte 1-15 Reserved for other bit definitions in future +} ME_CONFIG; + +/// +/// ME ERROR Message ID +/// +typedef enum { + MSG_EOP_ERROR = 0, + MSG_ME_FW_UPDATE_FAILED, + MSG_ASF_BOOT_DISK_MISSING, + MSG_KVM_TIMES_UP, + MSG_KVM_REJECTED, + MSG_HMRFPO_LOCK_FAILURE, + MSG_HMRFPO_UNLOCK_FAILURE, + MSG_ME_FW_UPDATE_WAIT, + MSG_ILLEGAL_CPU_PLUGGED_IN, + MSG_KVM_WAIT, + MSG_PLAT_DISABLE_WAIT, + MAX_ERROR_ENUM +} ME_ERROR_MSG_ID; + +/** + Show Me Error message. This is to display localized message in + the console. This is used to display message strings in local + language. To display the message, the routine will check the + message ID and ConOut the message strings. For example, the + End of Post error displayed in English will be: + gST->ConOut->OutputString (gST->ConOut, L"Error sending End Of + Post message to ME\n"); It is recommended to clear the screen + before displaying the error message and keep the message on + the screen for several seconds. + A sample is provided, see ShowMeReportError () to retrieve + details. + + @param[in] MsgId Me error message ID for displaying on screen message + + @retval None +**/ +typedef +VOID +(EFIAPI *ME_REPORT_ERROR) ( + IN ME_ERROR_MSG_ID MsgId + ); + +typedef struct { + /// + /// This member determines the SMBIOS OEM type (0x80 to 0xFF) defined in SMBIOS + /// Type 14 - Group Associations structure - item type. FVI structure uses it as + /// SMBIOS OEM type to provide MEBx, ME FW and reference code version information + /// + UINT8 FviSmbiosType; +} ME_MISC_CONFIG; + +#pragma pack() +/// +/// ME DXE Platform Policy +/// This protocol provides information of the current Intel ME feature selection. Information is +/// passed from the platform code to the Intel ME Reference code using this structure. There are +/// 2 types of information, BIOS setup option and ME status information. +/// +typedef struct _DXE_ME_POLICY_PROTOCOL { + /// + /// Revision for the protocol structure + /// + UINT8 Revision; + /// + /// Intel ME feature selection enable/disable and firmware configuration information + /// + ME_CONFIG MeConfig; + /// + /// Support Localization for displaying on screen message + /// + ME_REPORT_ERROR MeReportError; + /// + /// Miscellaneous items + /// + ME_MISC_CONFIG MeMiscConfig; +} DXE_ME_POLICY_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/Protocol/MeProtocolLib.cif b/ReferenceCode/ME/Protocol/MeProtocolLib.cif new file mode 100644 index 0000000..b256f15 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeProtocolLib.cif @@ -0,0 +1,40 @@ +<component> + name = "MeProtocolLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Protocol\" + RefName = "MeProtocolLib" +[files] +"MeProtocolLib.sdl" +"MeProtocolLib.mak" +"MeProtocolLib.inf" +"ActiveManagement\ActiveManagement.c" +"ActiveManagement\ActiveManagement.h" +"AlertStandardFormat\AlertStandardFormat.c" +"AlertStandardFormat\AlertStandardFormat.h" +"AmtPlatformPolicy\AmtPlatformPolicy.c" +"AmtPlatformPolicy\AmtPlatformPolicy.h" +"AmtReadyToBoot\AmtReadyToBoot.c" +"AmtReadyToBoot\AmtReadyToBoot.h" +"At\At.c" +"At\At.h" +"AtPlatformPolicy\AtPlatformPolicy.c" +"AtPlatformPolicy\AtPlatformPolicy.h" +"Heci\Heci.c" +"Heci\Heci.h" +"IderControllerDriver\IderControllerDriver.c" +"IderControllerDriver\IderControllerDriver.h" +"MeBiosPayloadData\MeBiosPayloadData.c" +"MeBiosPayloadData\MeBiosPayloadData.h" +"MebxProtocol\MebxProtocol.c" +"MebxProtocol\MebxProtocol.h" +"MePlatformPolicy\MePlatformPolicy.c" +"MePlatformPolicy\MePlatformPolicy.h" +"MeRcInfo\MeRcInfo.c" +"MeRcInfo\MeRcInfo.h" +"PlatformMeHook\PlatformMeHook.c" +"PlatformMeHook\PlatformMeHook.h" +"HeciSmm\HeciSmm.c" +"HeciSmm\HeciSmm.h" +"MeGlobalNvsArea\MeGlobalNvsArea.c" +"MeGlobalNvsArea\MeGlobalNvsArea.h" +<endComponent> diff --git a/ReferenceCode/ME/Protocol/MeProtocolLib.inf b/ReferenceCode/ME/Protocol/MeProtocolLib.inf new file mode 100644 index 0000000..f6b6590 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeProtocolLib.inf @@ -0,0 +1,73 @@ +## @file +# Component description file for the Me protocol library +# +#@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 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 = MeProtocolLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + ActiveManagement/ActiveManagement.h + ActiveManagement/ActiveManagement.c + AlertStandardFormat/AlertStandardFormat.h + AlertStandardFormat/AlertStandardFormat.c + AmtPlatformPolicy/AmtPlatformPolicy.h + AmtPlatformPolicy/AmtPlatformPolicy.c + Heci/Heci.h + Heci/Heci.c + IderControllerDriver/IderControllerDriver.h + IderControllerDriver/IderControllerDriver.c + MePlatformPolicy/MePlatformPolicy.h + MePlatformPolicy/MePlatformPolicy.c + PlatformMeHook/PlatformMeHook.h + PlatformMeHook/PlatformMeHook.c + MeRcInfo/MeRcInfo.h + MeRcInfo/MeRcInfo.c + MebxProtocol/MebxProtocol.c + MebxProtocol/MebxProtocol.h + AmtReadyToBoot/AmtReadyToBoot.h + AmtReadyToBoot/AmtReadyToBoot.c + MeBiosPayloadData/MeBiosPayloadData.h + MeBiosPayloadData/MeBiosPayloadData.c + AtPlatformPolicy/AtPlatformPolicy.h + AtPlatformPolicy/AtPlatformPolicy.c + At/At.c + At/At.h + MeGlobalNvsArea/MeGlobalNvsArea.h + MeGlobalNvsArea/MeGlobalNvsArea.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/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 + +[nmake.common] +C_STD_INCLUDE= diff --git a/ReferenceCode/ME/Protocol/MeProtocolLib.mak b/ReferenceCode/ME/Protocol/MeProtocolLib.mak new file mode 100644 index 0000000..c8ebec3 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeProtocolLib.mak @@ -0,0 +1,43 @@ +# /*++ +# 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:MeProtocolLib +all : MeProtocolLib + +$(MeProtocolLib_LIB): MeProtocolLib + +MeProtocolLib : $(BUILD_DIR)\MeProtocolLib.mak MeProtocolLibBin + +$(BUILD_DIR)\MeProtocolLib.mak : $(MeProtocolLib_DIR)\$(@B).cif $(MeProtocolLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeProtocolLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeProtocolLib_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES) \ + $(ME_INCLUDES) + +MeProtocolLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeProtocolLib.mak all\ + "MY_INCLUDES=$(MeProtocolLib_INCLUDES)" \ + TYPE=LIBRARY \ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2006, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/Protocol/MeProtocolLib.sdl b/ReferenceCode/ME/Protocol/MeProtocolLib.sdl new file mode 100644 index 0000000..ca3d3c3 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeProtocolLib.sdl @@ -0,0 +1,28 @@ +TOKEN + Name = "MeProtocolLib_SUPPORT" + Value = "1" + Help = "Main switch to enable MeProtocolLib support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "MeProtocolLib_DIR" +End + +MODULE + Help = "Includes MeProtocolLib.mak to Project" + File = "MeProtocolLib.mak" +End + +ELINK + Name = "MeProtocolLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeProtocolLib.lib" + Parent = "MeProtocolLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.c b/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.c new file mode 100644 index 0000000..0dedc85 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.c @@ -0,0 +1,43 @@ +/** @file + +@brief + This file defines the Me Info Protocol. + +@copyright + Copyright (c) 2011 - 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 +**/ + +// +// Statements that include other files +// +// +// 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 + +#include "MeRcInfo.h" + +// +// Protocol GUID definition +// +EFI_GUID gEfiMeRcInfoProtocolGuid = EFI_ME_RC_INFO_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING(&gEfiMeRcInfoProtocolGuid, "ME RC Info Protocol", "ME Reference Code Information Protocol"); diff --git a/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.h b/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.h new file mode 100644 index 0000000..1862f0d --- /dev/null +++ b/ReferenceCode/ME/Protocol/MeRcInfo/MeRcInfo.h @@ -0,0 +1,88 @@ +/** @file + This file defines the ME RC Info Protocol. + +@copyright + Copyright (c) 2011 - 2014 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 +**/ +#ifndef _ME_RC_INFO_H_ +#define _ME_RC_INFO_H_ + +/// +/// ME RC INFO protocol GUID +/// This protocol provides the version information for Me RC. +/// +#define EFI_ME_RC_INFO_PROTOCOL_GUID \ + { \ + 0x11fbfdfb, 0x10d2, 0x43e6, 0xb5, 0xb1, 0xb4, 0x38, 0x6e, 0xdc, 0xcb, 0x9a \ + } + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiMeRcInfoProtocolGuid; + +/// +/// Revision 1: Original version +/// +#define ME_RC_INFO_PROTOCOL_REVISION_1 1 + +/** + Me Reference Code formats 0xAABBCCDD + DD - Build Number + CC - Reference Code Revision + BB - Reference Code Minor Version + AA - Reference Code Major Version + Example: Me Reference Code 0.7.1 should be 00 07 01 00 (0x00070100) +**/ +#define ME_RC_VERSION 0x01090000 +#define ME_FVI_STRING "Reference Code - ME 9.0" +#define ME_FVI_SMBIOS_TYPE 0xDD ///< Default value +#define ME_FVI_SMBIOS_INSTANCE 0x03 +#define MEBX_RC_VERSION 0xFFFFFFFF +#define MEBX_FVI_STRING "MEBx version" + +#define MEFW_VERSION \ + { \ + 0xFF, 0xFF, 0xFF, 0xFFFF \ + } +#define MEFW_FVI_STRING "ME Firmware Version" +#define MEFW_1_5M_STRING "1.5MB SKU" +#define MEFW_5M_STRING "5MB SKU " + +enum { + EnumMeRc = 0, ///< ME Reference Code Version + EnumMebx, ///< MEBx Version + EnumMeFw ///< ME FW Version +} ME_FVI_INDEX; + +/// +/// ME RC INFO protocol +/// This protocol provides the version information for Me RC. +/// +typedef struct _EFI_ME_RC_INFO_PROTOCOL { + /// + /// Revision for the protocol structure + /// + UINT8 Revision; + /** + Me Reference Code formats 0xAABBCCDD + DD - Build Number + CC - Reference Code Revision + BB - Reference Code Minor Version + AA - Reference Code Major Version + **/ + UINT32 RCVersion; +} EFI_ME_RC_INFO_PROTOCOL; +#endif diff --git a/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.c b/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.c new file mode 100644 index 0000000..1d81195 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.c @@ -0,0 +1,31 @@ +/** @file + EFI MEBx Protocol + +@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 +**/ + +// +// 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_DEFINITION (MebxProtocol) +#endif + +EFI_GUID gEfiMebxProtocolGuid = INTEL_MEBX_PROTOCOL_GUID; + +EFI_GUID_STRING(&gEfiMebxProtocolGuid, "EFI MEBx Protocol", "EFI 2.1 MEBx Protocol"); diff --git a/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.h b/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.h new file mode 100644 index 0000000..3ad33e8 --- /dev/null +++ b/ReferenceCode/ME/Protocol/MebxProtocol/MebxProtocol.h @@ -0,0 +1,72 @@ +/** @file + EFI MEBx Protocol + +@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 +**/ +#ifndef _MEBX_PROTOCOL_H +#define _MEBX_PROTOCOL_H + +#define MEBX_CALLBACK_INFO_SIGNATURE EFI_SIGNATURE_32 ('m', 'e', 'b', 'x') + +#define MEBX_CALLBACK_INFO_FROM_THIS(a) CR (a, MEBX_CALLBACK_INFO, DriverCallback, MEBX_CALLBACK_INFO_SIGNATURE) + +#ifndef INTEL_MEBX_PROTOCOL_GUID +#define INTEL_MEBX_PROTOCOL_GUID \ + { \ + 0x01ab1829, 0xcecd, 0x4cfa, 0xa1, 0x8c, 0xea, 0x75, 0xd6, 0x6f, 0x3e, 0x74 \ + } +#endif + +typedef +EFI_STATUS +(EFIAPI *EFI_MEBX_API_ENTRY_POINT) ( + IN UINT32 BiosParams, + OUT UINT32 *MebxReturnValue + ); + +typedef struct _MEBX_VER { + UINT16 Major; + UINT16 Minor; + UINT16 Hotfix; + UINT16 Build; +} MEBX_VER; + +typedef enum { + MEBX_GRAPHICS_AUTO = 0, + MEBX_GRAPHICS_640X480, + MEBX_GRAPHICS_800X600, + MEBX_GRAPHICS_1024X768 +} MEBX_GRAPHICS_MODE; + +typedef enum { + MEBX_TEXT_AUTO = 0, + MEBX_TEXT_80X25, + MEBX_TEXT_100X31 +} MEBX_TEXT_MODE; + +typedef struct _EFI_MEBX_PROTOCOL { + MEBX_VER MebxVersion; + EFI_MEBX_API_ENTRY_POINT CoreMebxEntry; +} EFI_MEBX_PROTOCOL; + +typedef struct _MEBX_INSTANCE { + EFI_HANDLE Handle; + EFI_MEBX_PROTOCOL MebxProtocol; +} MEBX_INSTANCE; + +extern EFI_GUID gEfiMebxProtocolGuid; + +#endif diff --git a/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.c b/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.c new file mode 100644 index 0000000..c34ce99 --- /dev/null +++ b/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.c @@ -0,0 +1,43 @@ +/** @file + This file defines the Platform ME Hook function + +@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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (PlatformMeHook) +#endif +// +// Protocol GUID definition +// +EFI_GUID gPlatformMeHookProtocolGuid = PLATFORM_ME_HOOK_PROTOCOL_GUID; + +// +// Protocol description +// +EFI_GUID_STRING + (&gPlatformMeHookProtocolGuid, "PlatformMeHook Protocol", "Intel(R) DXE Phase ME Platform Hook Protocol"); diff --git a/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.h b/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.h new file mode 100644 index 0000000..eef2c47 --- /dev/null +++ b/ReferenceCode/ME/Protocol/PlatformMeHook/PlatformMeHook.h @@ -0,0 +1,64 @@ +/** @file + Interface definition details for platform hook support to ME module during DXE phase. + +@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 +**/ +#ifndef _PLATFORM_ME_HOOK_H_ +#define _PLATFORM_ME_HOOK_H_ + +/// +/// ME Hook provided by platform for DXE phase +/// This protocol provides an interface to hook reference code by OEM. +/// +#define PLATFORM_ME_HOOK_PROTOCOL_GUID \ + { \ + 0xbc52476e, 0xf67e, 0x4301, 0xb2, 0x62, 0x36, 0x9c, 0x48, 0x78, 0xaa, 0xc2 \ + } + +#define PLATFORM_ME_HOOK_PROTOCOL_REVISION 1 + +/** + Platform hook before BIOS sends Global Reset Heci Message to ME + + @param[in] None + + @retval EFI Status Code +**/ +typedef +EFI_STATUS +(EFIAPI *PLATFORM_ME_HOOK_PRE_GLOBAL_RESET) ( + VOID + ) +; + +/// +/// Platform Intel ME Hook Protocol +/// This protocol provides an interface to hook reference code by OEM. +/// +typedef struct _PLATFORM_ME_HOOK_PROTOCOL { + /// + /// Revision for the protocol structure + /// + UINT8 Revision; + /// + /// Function pointer for the hook called before BIOS sends Global Reset Heci Message to ME + /// + PLATFORM_ME_HOOK_PRE_GLOBAL_RESET PreGlobalReset; +} PLATFORM_ME_HOOK_PROTOCOL; + +extern EFI_GUID gPlatformMeHookProtocolGuid; + +#endif diff --git a/ReferenceCode/ME/Ptt/Smm/Ftpm.asl b/ReferenceCode/ME/Ptt/Smm/Ftpm.asl new file mode 100644 index 0000000..234bb42 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/Ftpm.asl @@ -0,0 +1,447 @@ +/**************************************************************************; +;* *; +;* Intel Confidential *; +;* *; +;* Intel Corporation - ACPI Reference Code for the Haswell *; +;* Family of Customer Reference Boards. *; +;* *; +;* *; +;* 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 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 +--*/ +/** @file + The TPM2 definition block in ACPI table for TrEE physical presence + and MemoryClear. +**/ + +DefinitionBlock ( + "Tpm.aml", + "SSDT", + 1, + "Intel_", + "Tpm2Tabl", + 0x1000 + ) +{ + External(PTTS) // PTT Solution Method Selection + External(PTTB) // PTT Buffer Address + + Scope (\_SB) + { + Device (TPM) + { + // + // Define _HID, "PNP0C31" is defined in + // "Secure Startup-FVE and TPM Admin BIOS and Platform Requirements" + // + Name (_HID, "MSFT0101") + + // + // Readable name of this device, don't know if this way is correct yet + // + Name (_STR, Unicode ("TPM 2.0 Device")) + + // + // Return the resource consumed by TPM device + // + Name (CRS, ResourceTemplate () { + Memory32Fixed (ReadOnly, 0xFED70000, 0x1000,PCRS) + }) + + + Method(_CRS,0) + { + CreateDWordField (CRS, \_SB.TPM.PCRS._BAS, CBAS) + Store (PTTB, CBAS) + Return(CRS) + } + + // + // Operational region for Smi port access + // + OperationRegion (SMIP, SystemIO, 0xB2, 1) + Field (SMIP, ByteAcc, NoLock, Preserve) + { + IOB2, 8 + } + + OperationRegion (FHCI, SystemMemory, 0xFED70000, 0x1000) + Field (FHCI, AnyAcc, NoLock, Preserve) + { + Offset(0x04), + HERR, 32, + Offset (0x40), + HCMD, 32, + Offset(0x44), + HSTS, 32, + } + // + // Operational region for TPM support, TPM Physical Presence and TPM Memory Clear + // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code. + // + OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0) + Field (TNVS, AnyAcc, NoLock, Preserve) + { + PPIN, 8, // Software SMI for Physical Presence Interface + PPIP, 32, // Used for save physical presence paramter + PPRP, 32, // Physical Presence request operation response + PPRQ, 32, // Physical Presence request operation + LPPR, 32, // Last Physical Presence request operation + FRET, 32, // Physical Presence function return code + MCIN, 8, // Software SMI for Memory Clear Interface + MCIP, 32, // Used for save the Mor paramter + MORD, 32, // Memory Overwrite Request Data + MRET, 32 // Memory Overwrite function return code + } + + Method (PTS, 1, Serialized) + { + // + // Detect Sx state for MOR, only S4, S5 need to handle + // + If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3))) + { + // + // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect. + // + If (LNot (And (MORD, 0x10))) + { + // + // Triggle the SMI through ACPI _PTS method. + // + Store (0x02, MCIP) + + // + // Triggle the SMI interrupt + // + Store (MCIN, IOB2) + } + } + Return (0) + } + + Method (_STA, 0) + { + Return (0x0f) + } + + // + // TCG Hardware Information + // + Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger(Arg1)) + { + Case (0) + { + // + // Standard query + // + Return (Buffer () {0x03}) + } + Case (1) + { + // + // Return failure if no TPM present + // + Name(TPMV, Package () {0x01, Package () {0x1, 0x20}}) + if (LEqual (_STA (), 0x00)) + { + Return (Package () {0x00}) + } + + // + // Return TPM version + // + Return (TPMV) + } + Default {BreakPoint} + } + Return (Buffer () {0}) + } + + Name(TPM2, Package (0x02){ + Zero, + Zero + }) + + Name(TPM3, Package (0x03){ + Zero, + Zero, + Zero + }) + + // + // TCG Physical Presence Interface + // + Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger(Arg1)) + { + Case (0) + { + // + // Standard query, supports function 1-8 + // + Return (Buffer () {0xFF, 0x01}) + } + Case (1) + { + // + // a) Get Physical Presence Interface Version + // + Return ("1.2") + } + Case (2) + { + // + // b) Submit TPM Operation Request to Pre-OS Environment + // + + Store (DerefOf (Index (Arg2, 0x00)), PPRQ) + Store (0x02, PPIP) + + // + // Triggle the SMI interrupt + // + Store (PPIN, IOB2) + Return (FRET) + + + } + Case (3) + { + // + // c) Get Pending TPM Operation Requested By the OS + // + + Store (PPRQ, Index (TPM2, 0x01)) + Return (TPM2) + } + Case (4) + { + // + // d) Get Platform-Specific Action to Transition to Pre-OS Environment + // + Return (2) + } + Case (5) + { + // + // e) Return TPM Operation Response to OS Environment + // + Store (0x05, PPIP) + + // + // Triggle the SMI interrupt + // + Store (PPIN, IOB2) + + Store (LPPR, Index (TPM3, 0x01)) + Store (PPRP, Index (TPM3, 0x02)) + + Return (TPM3) + } + Case (6) + { + + // + // f) Submit preferred user language (Not implemented) + // + + Return (3) + + } + Case (7) + { + // + // g) Submit TPM Operation Request to Pre-OS Environment 2 + // + Store (7, PPIP) + Store (DerefOf (Index (Arg2, 0x00)), PPRQ) + + // + // Triggle the SMI interrupt + // + Store (PPIN, IOB2) + Return (FRET) + } + Case (8) + { + // + // e) Get User Confirmation Status for Operation + // + Store (8, PPIP) + Store (DerefOf (Index (Arg2, 0x00)), PPRQ) + + // + // Triggle the SMI interrupt + // + Store (PPIN, IOB2) + + Return (FRET) + } + + Default {BreakPoint} + } + Return (1) + } + + Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger (Arg1)) + { + Case (0) + { + // + // Standard query, supports function 1-1 + // + Return (Buffer () {0x03}) + } + Case (1) + { + // + // Save the Operation Value of the Request to MORD (reserved memory) + // + Store (DerefOf (Index (Arg2, 0x00)), MORD) + + // + // Triggle the SMI through ACPI _DSM method. + // + Store (0x01, MCIP) + + // + // Triggle the SMI interrupt + // + Store (MCIN, IOB2) + Return (MRET) + } + Default {BreakPoint} + } + Return (1) + } + + Method (TSMI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + + // + // Operational region for TPM access + // + OperationRegion (TPMR, SystemMemory, PTTB, 0x1000) + Field (TPMR, AnyAcc, NoLock, Preserve) + { + Offset(0x04), + FERR, 32, + Offset(0x0c), + STRT, 32, + } + + // + // Switch by function index + // + Switch (ToInteger (Arg1)) + { + Case (0) + { + // + // Standard query, supports function 1-1 + // + Return (Buffer () {0x03}) + } + Case (1) + { + If(LEqual(PTTS, 0)) // GPDMA + { + If(LEqual(Or(And(HSTS,0x00000002),And(HSTS,0x00000001)),0x00000003)) + { + // + // Trigger the FTPM_CMD interrupt + // + Store (0x00000001, HCMD) + } + Else + { + //Set Error Bit + Store(0x00000001,FERR) + //Clear Start Bit + Store(0x00000000,STRT) + } + } + If(LEqual(PTTS, 1)) // MSFT QFE + { + // + // Trigger the FTPM_CMD interrupt + // + Store (0x00000000, HCMD) + } + Return (0) + } + Default {BreakPoint} + } + Return (1) + } + + Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) + { + + // + // TCG Hardware Information + // + If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8"))) + { + Return (HINF (Arg1, Arg2, Arg3)) + } + + // + // TCG Physical Presence Interface + // + If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653"))) + { + Return (TPPI (Arg1, Arg2, Arg3)) + } + + // + // TCG Memory Clear Interface + // + If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d"))) + { + Return (TMCI (Arg1, Arg2, Arg3)) + } + + // + // TPM2 ACPI Start Method + // + If(LEqual(Arg0, ToUUID ("6bbf6cab-5463-4714-b7cd-f0203c0368d4"))) + { + Return (TSMI (Arg1, Arg2, Arg3)) + } + + Return (Buffer () {0}) + } + } + } +} diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.c b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.c new file mode 100644 index 0000000..570a554 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.c @@ -0,0 +1,847 @@ +/** @file + It updates TPM2 items in ACPI table and registers SMI2 callback + functions for TrEE physical presence, ClearMemory, and sample + for dTPM StartMethod. + + Caution: This module requires additional review when modified. + This driver will have external input - variable and ACPINvs data in SMM mode. + This external input must be validated carefully to avoid security issue. + + PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check. + +@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 + +**/ + +#include "PttHciSmm.h" +#include "MeAccess.h" +#include "HeciRegs.h" + +EFI_GUID gTpm2AcpiTableStorageGuid = TPM2_ACPI_TABLE_STORAGE_GUID; +EFI_GUID gEfiTrEEPhysicalPresenceGuid = EFI_TREE_PHYSICAL_PRESENCE_DATA_GUID; +EFI_GUID gEfiMemoryOverwriteControlDataGuid = MEMORY_ONLY_RESET_CONTROL_GUID; +EFI_GUID gEfiSmmVariableProtocolGuid = EFI_SMM_VARIABLE_PROTOCOL_GUID; +EFI_GUID gMeGlobalNvsAreaProtocolGuid = ME_GLOBAL_NVS_AREA_PROTOCOL_GUID; +EFI_GUID gMeSsdtAcpiTableStorageGuid = ME_SSDT_ACPI_TABLE_STORAGE_GUID; + +EFI_TPM2_ACPI_TABLE mTpm2AcpiTemplate = { + { + EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE, + sizeof (mTpm2AcpiTemplate), + EFI_TPM2_ACPI_TABLE_REVISION, + // + // Compiler initializes the remaining bytes to 0 + // These fields should be filled in in production + // + }, + 0, // Flags + (EFI_PHYSICAL_ADDRESS)(UINTN)0xFFFFFFFF, // Control Area + EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI, +}; + +EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; +TCG_NVS *mTcgNvs; +EFI_TPM2_ACPI_CONTROL_AREA mControlArea; // Smm copy, because we need cache Command & Response address +ME_GLOBAL_NVS_AREA_PROTOCOL mMeGlobalNvsAreaProtocol; +//<AMI_OVERRIDE> >>> +#define EFI_SMM_RUNTIME_SERVICES_TABLE_GUID \ + { 0x395c33fe, 0x287f, 0x413e, { 0xa0, 0x55, 0x80, 0x88, 0xc0, 0xe1, 0xd4, 0x3e } } + +EFI_RUNTIME_SERVICES *mRuntimeServices; + +EFI_STATUS +GetSmmRtTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GUID SmmRtServTableGuid = EFI_SMM_RUNTIME_SERVICES_TABLE_GUID; + EFI_SMM_BASE_PROTOCOL *SmmBase = NULL; + EFI_SMM_SYSTEM_TABLE *Smst = NULL; + EFI_CONFIGURATION_TABLE *Table = NULL; + UINTN Count = 0; + + Status = gBS->LocateProtocol( + &gEfiSmmBaseProtocolGuid, + NULL, + &SmmBase ); + if( EFI_ERROR(Status) ) return Status; + + Status = SmmBase->GetSmstLocation( SmmBase, &Smst ); + if( EFI_ERROR(Status) ) return Status; + + Table = Smst->SmmConfigurationTable; + Count = Smst->NumberOfTableEntries; + + mRuntimeServices = NULL; + for( ; Count ; --Count, ++Table ) + { + if( CompareGuid( &Table->VendorGuid, &SmmRtServTableGuid ) ) + { + mRuntimeServices = (EFI_RUNTIME_SERVICES*)Table->VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} +//<AMI_OVERRIDE> <<< + +/** + Software SMI callback for TPM physical presence which is called from ACPI method. + + Caution: This function may receive untrusted input. + Variable and ACPINvs are external input, so this function will validate + its data structure to be valid value. + + @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @param[in] Context Points to an optional handler context which was specified when the + handler was registered. + + @retval EFI_SUCCESS The interrupt was handled successfully. +**/ +EFI_STATUS +EFIAPI +PhysicalPresenceCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_TREE_PHYSICAL_PRESENCE PpData; + UINT8 Flags; + BOOLEAN RequestConfirmed; + + // + // Get the Physical Presence variable + // + DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE); +//<AMI_OVERRIDE> >>> + Status = mRuntimeServices->GetVariable ( + TREE_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTrEEPhysicalPresenceGuid, + NULL, + &DataSize, + &PpData + ); +//<AMI_OVERRIDE> <<< + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + DEBUG ((EFI_D_INFO, "[TPM2] PP callback, Parameter = %x\n", mTcgNvs->PhysicalPresence.Parameter)); + if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) { + mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest; + mTcgNvs->PhysicalPresence.Response = PpData.PPResponse; + } else if ((mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) + || (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) { + if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) { + PpData.PPRequest = (UINT8) mTcgNvs->PhysicalPresence.Request; + DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE); +//<AMI_OVERRIDE> >>> + Status = mRuntimeServices->SetVariable ( + TREE_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTrEEPhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &PpData + ); +//<AMI_OVERRIDE> <<< + } + + if (EFI_ERROR (Status)) { + mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE; + return EFI_SUCCESS; + } + mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS; + } else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) { + Flags = PpData.Flags; + RequestConfirmed = FALSE; + + switch (mTcgNvs->PhysicalPresence.Request) { + + case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR: + case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2: + case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3: + case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4: + if ((Flags & TREE_FLAG_NO_PPI_CLEAR) != 0) { + RequestConfirmed = TRUE; + } + break; + + case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: + RequestConfirmed = TRUE; + break; + + case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: + break; + + default: + if (mTcgNvs->PhysicalPresence.Request <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) { + RequestConfirmed = TRUE; + } + break; + } + + if (RequestConfirmed) { + mTcgNvs->PhysicalPresence.ReturnCode = PP_REQUEST_ALLOWED_AND_PPUSER_NOT_REQUIRED; + } else { + mTcgNvs->PhysicalPresence.ReturnCode = PP_REQUEST_ALLOWED_AND_PPUSER_REQUIRED; + } + } + + return EFI_SUCCESS; +} + +/** + Software SMI callback for MemoryClear which is called from ACPI method. + + Caution: This function may receive untrusted input. + Variable and ACPINvs are external input, so this function will validate + its data structure to be valid value. + + @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @param[in] Context Points to an optional handler context which was specified when the + handler was registered. + + @retval EFI_SUCCESS The interrupt was handled successfully. +**/ +EFI_STATUS +EFIAPI +MemoryClearCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +{ + EFI_STATUS Status; + UINTN DataSize; + UINT8 MorControl; + + mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS; + if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) { + MorControl = (UINT8) mTcgNvs->MemoryClear.Request; + } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) { + DataSize = sizeof (UINT8); +//<AMI_OVERRIDE> >>> + Status = mRuntimeServices->GetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + NULL, + &DataSize, + &MorControl + ); +//<AMI_OVERRIDE> <<< + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) { + return EFI_SUCCESS; + } + MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK; + } + + DataSize = sizeof (UINT8); +//<AMI_OVERRIDE> >>> + Status = mRuntimeServices->SetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &MorControl + ); +//<AMI_OVERRIDE> <<< + if (EFI_ERROR (Status)) { + mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; + } + + return EFI_SUCCESS; +} + +/** + Find the operation region in TCG ACPI table by given Name and Size, + and initialize it if the region is found. + + @param[in, out] Table The TPM item in ACPI table. + @param[in] Name The name string to find in TPM table. + @param[in] Size The size of the region to find. + + @return The allocated address for the found region. +**/ +VOID * +AssignOpRegion ( + EFI_ACPI_DESCRIPTION_HEADER *Table, + UINT32 Name, + UINT16 Size + ) +{ + EFI_STATUS Status; + AML_OP_REGION_32_8 *OpRegion; + EFI_PHYSICAL_ADDRESS MemoryAddress; + + MemoryAddress = 0xFFFFFFFF; + + // + // Patch some pointers for the ASL code before loading the SSDT. + // + for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1); + OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length); + OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) { + if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) && + (OpRegion->NameString == Name) && + (OpRegion->DWordPrefix == AML_DWORD_PREFIX) && + (OpRegion->BytePrefix == AML_BYTE_PREFIX)) { + + Status = (gBS->AllocatePages)(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress); + ASSERT_EFI_ERROR (Status); + ZeroMem ((VOID *)(UINTN)MemoryAddress, Size); + OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress; + OpRegion->RegionLen = (UINT8) Size; + break; + } + } + + return (VOID *) (UINTN) MemoryAddress; +} + +VOID * +GetTpm2AcpiTableFromFv ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + INTN Instance; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; + + /// + /// Locate protocol. + /// There is little chance we can't find an FV protocol + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + FwVol = NULL; + /// + /// Looking for FV with ACPI storage file + /// + for (Index = 0; Index < NumberOfHandles; Index++) { + /// + /// Get the protocol on this handle + /// This should not fail because of LocateHandleBuffer + /// + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeProtocolGuid, + &FwVol + ); + ASSERT_EFI_ERROR (Status); + + /// + /// See if it has the ACPI storage file + /// + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &gTpm2AcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + /// + /// If we found it, then we are done + /// + if (Status == EFI_SUCCESS) { + break; + } else { + FwVol = NULL; + } + } + + if ((Index == NumberOfHandles) || (FwVol == NULL)) { + return NULL; + } + + Instance = 0; + CurrentTable = NULL; + + while (Status == EFI_SUCCESS) { + Status = FwVol->ReadSection ( + FwVol, + &gTpm2AcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + /// + /// Check the Signature ID to modify the table + /// + if ((((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature == EFI_SIGNATURE_32 ('S', 'S', 'D', 'T')) && + (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == EFI_SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'))) { + // + // Find it. + // + break; + } + /// + /// Increment the instance + /// + Instance++; + CurrentTable = NULL; + } + } + + /// + /// Our exit status is determined by the success of the previous operations + /// If the protocol was found, Instance already points to it. + /// + /// + /// Free any allocated buffers + /// + (gBS->FreePool) (HandleBuffer); + + return CurrentTable; +} + +/** + Initialize and publish TPM items in ACPI table. + + @retval EFI_SUCCESS The TCG ACPI table is published successfully. + @retval Others The TCG ACPI table is not published. +**/ +EFI_STATUS +PublishAcpiTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + UINTN TableKey; + EFI_ACPI_DESCRIPTION_HEADER *Table; + UINTN TableSize; + + Table = GetTpm2AcpiTableFromFv (); + ASSERT (Table != NULL); + + if (Table == NULL) { + return EFI_NOT_FOUND; + } + + TableSize = Table->Length; + + ASSERT (Table->OemTableId == EFI_SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l')); + mTcgNvs = AssignOpRegion (Table, EFI_SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); + ASSERT (mTcgNvs != NULL); + + // + // Publish the TPM ACPI table + // + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + ASSERT_EFI_ERROR (Status); + + TableKey = 0; + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + Table, + TableSize, + &TableKey + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +EFI_STATUS +PublishFtpmAcpiTable ( + VOID + ) +/** + Publish TPM2 ACPI table + + @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. + @retval Others The TPM2 ACPI table is not published. +**/ +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + UINTN TableKey; + EFI_TPM2_ACPI_CONTROL_AREA *ControlArea; + ME_DATA_HOB *MeDataHob; + EFI_GUID gMeDataHobGuid = ME_DATA_HOB_GUID; + + /// + /// Construct ACPI table + /// + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + ASSERT_EFI_ERROR (Status); + + MeDataHob = NULL; + MeDataHob = GetFirstGuidHob (&gMeDataHobGuid); + if (MeDataHob != NULL) { + (UINTN)mTpm2AcpiTemplate.AddressOfControlArea = MeDataHob->FtpmBufferAddress; + } else { + (UINTN) mTpm2AcpiTemplate.AddressOfControlArea = 0xFED70000; + } + + ControlArea = (EFI_TPM2_ACPI_CONTROL_AREA *)(UINTN)mTpm2AcpiTemplate.AddressOfControlArea; + ZeroMem (ControlArea, sizeof(*ControlArea)); + ControlArea->CommandSize = 0xF80; + ControlArea->ResponseSize = 0xF80; + ControlArea->Command = (UINTN)mTpm2AcpiTemplate.AddressOfControlArea + 0x80; + ControlArea->Response = (UINTN)mTpm2AcpiTemplate.AddressOfControlArea + 0x80; + CopyMem (&mControlArea, ControlArea, sizeof(mControlArea)); + + DEBUG ((EFI_D_INFO, "Ftpm Windows Buffer Control Area Address = %x\n", mTpm2AcpiTemplate.AddressOfControlArea)); + DEBUG ((EFI_D_INFO, "Ftpm Windows Command/Response Buffer Address = %x\n", ControlArea->Command)); + + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + &mTpm2AcpiTemplate, + sizeof(mTpm2AcpiTemplate), + &TableKey + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +BOOLEAN +IsFtpmEnabled ( + VOID + ) +{ + UINT32 IsPttEnabled; + UINT32 IsPttReady; + UINT32 MeFwSts4; + + IsPttEnabled = ( B_PTT_HCI_STS_ENABLED & MmioRead32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)) ); + /// + /// Read ME FWSTS4 to check if TPM_DISCONNECT_ALL BIT[12] is set + /// + MeFwSts4 = HeciPciRead32(R_ME_HFS_4); + + /// + /// Read Ready Bit to identify if PTT is ready for accepting OS Commands + /// + IsPttReady = (B_PTT_HCI_STS_READY & MmioRead32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS))); + + if ( (IsPttEnabled == 0) || (MeFwSts4 & BIT12) || (IsPttReady == 0) ) { + return FALSE; + } + + return TRUE; +} + +EFI_STATUS +InitializeMeSsdtAcpiTables ( +IN EFI_HANDLE ImageHandle + ) +/** +@brief + Initialize MEFW SSDT ACPI tables + + @retval EFI_SUCCESS ACPI tables are initialized successfully + @retval EFI_NOT_FOUND ACPI tables not found +**/ +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN i; + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; + INTN Instance; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINTN AcpiTableKey; + UINT8 *CurrPtr; + UINT8 *EndPtr; + UINT32 *Signature; + EFI_ACPI_DESCRIPTION_HEADER *MeAcpiTable; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + Status = (gBS->AllocatePool) (EfiReservedMemoryType, sizeof (ME_GLOBAL_NVS_AREA), (VOID **) &mMeGlobalNvsAreaProtocol.Area); + ASSERT_EFI_ERROR (Status); + ZeroMem ((VOID *) mMeGlobalNvsAreaProtocol.Area, sizeof (ME_GLOBAL_NVS_AREA)); + + FwVol = NULL; + MeAcpiTable = NULL; + + /// + /// Locate ACPI Table protocol + /// + DEBUG ((EFI_D_INFO, "Init ME SSDT table\n")); + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, &AcpiTable); + if (Status != EFI_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Fail to locate EfiAcpiTableProtocol.\n")); + return EFI_NOT_FOUND; + } + + /// + /// Locate protocol. + /// There is little chance we can't find an FV protocol + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + /// + /// Looking for FV with ACPI storage file + /// + for (i = 0; i < NumberOfHandles; i++) { + /// + /// Get the protocol on this handle + /// This should not fail because of LocateHandleBuffer + /// + Status = gBS->HandleProtocol ( + HandleBuffer[i], + &gEfiFirmwareVolumeProtocolGuid, + &FwVol + ); + ASSERT_EFI_ERROR (Status); + + /// + /// See if it has the ACPI storage file + /// + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &gMeSsdtAcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + /// + /// If we found it, then we are done + /// + if (Status == EFI_SUCCESS) { + break; + } + } + /// + /// Free any allocated buffers + /// + FreePool (HandleBuffer); + + /// + /// Sanity check that we found our data file + /// + ASSERT (FwVol != NULL); + if (FwVol == NULL) { + DEBUG ((EFI_D_INFO, "ME Global NVS table not found\n")); + return EFI_NOT_FOUND; + } + /// + /// Our exit status is determined by the success of the previous operations + /// If the protocol was found, Instance already points to it. + /// Read tables from the storage file. + /// + Instance = 0; + CurrentTable = NULL; + while (Status == EFI_SUCCESS) { + Status = FwVol->ReadSection ( + FwVol, + &gMeSsdtAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + /// + /// Check the table ID to modify the table + /// + if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == EFI_SIGNATURE_64 ('M', 'e', 'S', 's', 'd', 't', ' ', 0)) { + MeAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable; + /// + /// Locate the SSDT package + /// + CurrPtr = (UINT8 *) MeAcpiTable; + EndPtr = CurrPtr + MeAcpiTable->Length; + + for (; CurrPtr <= EndPtr; CurrPtr++) { + Signature = (UINT32 *) (CurrPtr + 3); + if (*Signature == EFI_SIGNATURE_32 ('M', 'E', 'N', 'V')) { + ASSERT_EFI_ERROR (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) == 0xFFFF0000); + ASSERT_EFI_ERROR (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55); + /// + /// ME Global NVS Area address + /// + + *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN) mMeGlobalNvsAreaProtocol.Area; + /// + /// ME Global NVS Area size + /// + *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) = + sizeof (ME_GLOBAL_NVS_AREA); + + AcpiTableKey = 0; + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + MeAcpiTable, + MeAcpiTable->Length, + &AcpiTableKey + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gMeGlobalNvsAreaProtocolGuid, + &mMeGlobalNvsAreaProtocol, + NULL + ); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; + } + } + } + /// + /// Increment the instance + /// + Instance++; + CurrentTable = NULL; + } + } + + return Status; +} +/** + The driver's entry point. + + It install callbacks for TPM physical presence and MemoryClear, and locate + SMM variable to be used in the callback function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Others Some error occurs when executing this entry point. +**/ +EFI_STATUS +EFIAPI +InitializeFtpmSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch; + EFI_SMM_SW_DISPATCH_CONTEXT SwContext; + EFI_HANDLE SwHandle; + ME_GLOBAL_NVS_AREA_PROTOCOL *MeGlobalNvsAreaProtocol; + ME_GLOBAL_NVS_AREA *MeGlobalNvsArea; + + if (!IsFtpmEnabled ()) { + DEBUG ((EFI_D_ERROR, "InitializeFtpmSmm - FTPM not enabled\n")); + return EFI_SUCCESS; + } + +if (GetCpuFamily() == EnumCpuHswUlt) { + Status = PublishAcpiTable (); + ASSERT_EFI_ERROR (Status); + + // + // Get the Sw dispatch protocol and register SMI callback functions. + // + Status = gBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, (VOID**)&SwDispatch); + ASSERT_EFI_ERROR (Status); + SwContext.SwSmiInputValue = EFI_TPM2_PP_SW_SMI; + Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; + + SwContext.SwSmiInputValue = EFI_TPM2_MOR_SW_SMI; + Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; + +//<AMI_OVERRIDE> >>> + /// + /// Locate SmmVariableProtocol. + /// + //Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable); + //ASSERT_EFI_ERROR (Status); + + //We don't install SmmVariableProtocol in gBS, use gRT's variable + //service directly. + Status = GetSmmRtTable(); + ASSERT_EFI_ERROR (Status); +//<AMI_OVERRIDE> <<< + + Status = InitializeMeSsdtAcpiTables(ImageHandle); + ASSERT_EFI_ERROR (Status); + + /// + /// Publish TPM2 ACPI table + /// + Status = PublishFtpmAcpiTable(); + ASSERT_EFI_ERROR (Status); + + /// + /// Locate Global NVS and update PTT Buffer Address + /// + Status = gBS->LocateProtocol (&gMeGlobalNvsAreaProtocolGuid, NULL, (VOID **) &MeGlobalNvsAreaProtocol); + ASSERT_EFI_ERROR (Status); + + MeGlobalNvsArea = MeGlobalNvsAreaProtocol->Area; + MeGlobalNvsArea->PTTAddress = mTpm2AcpiTemplate.AddressOfControlArea; +} + + return EFI_SUCCESS; +} + diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.cif b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.cif new file mode 100644 index 0000000..d8a8e0d --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.cif @@ -0,0 +1,13 @@ +<component> + name = "PttHciSmm" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Ptt\Smm\" + RefName = "PttHciSmm" +[files] +"PttHciSmm.sdl" +"PttHciSmm.mak" +"PttHciSmm.c" +"PttHciSmm.h" +"PttHciSmm.dxs" +"PttHciSmm.inf" +<endComponent> diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.dxs b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.dxs new file mode 100644 index 0000000..01b31c8 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.dxs @@ -0,0 +1,48 @@ +/** @file + Dependency expression source file. + +@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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#endif + +#include EFI_PROTOCOL_DEFINITION (AcpiTable) +#include EFI_PROTOCOL_DEFINITION (SmmSwDispatch) +//#include EFI_PROTOCOL_DEFINITION (SmmVariable) //<AMI_OVERRIDE> + +//<AMI_OVERRIDE> >>> +DEPENDENCY_START + EFI_ACPI_TABLE_PROTOCOL_GUID AND + EFI_SMM_SW_DISPATCH_PROTOCOL_GUID +DEPENDENCY_END +//<AMI_OVERRIDE> <<<
\ No newline at end of file diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.h b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.h new file mode 100644 index 0000000..3771d00 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.h @@ -0,0 +1,158 @@ +/** @file + The header file for Ftpm SMM driver. + +@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 __FTPM_SMM_H__ +#define __FTPM_SMM_H__ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" + +#include EFI_PROTOCOL_DEPENDENCY (SmmBase) +#include EFI_PROTOCOL_DEPENDENCY (SmmSwDispatch) +#include EFI_PROTOCOL_DEPENDENCY (AcpiTable) +#include EFI_PROTOCOL_DEPENDENCY (FirmwareVolume) +#include EFI_PROTOCOL_DEPENDENCY (MeGlobalNvsArea) +#include EFI_GUID_DEFINITION (MeSsdtTableStorage) + +#include "Acpi.h" + +// +// Below definition is generic, but NOT in GreenH +// +#include EFI_PROTOCOL_DEPENDENCY (SmmVariable) + +#include "IndustryStandard\AcpiAml.h" +#ifndef EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE +#define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE EFI_SIGNATURE_32('T', 'P', 'M', '2') +#endif + +#include "IndustryStandard\Tpm2Acpi.h" +#include EFI_GUID_DEFINITION (TrEEPhysicalPresenceData) +#include EFI_GUID_DEFINITION (MemoryOverwriteControl) + +// +// Below definition is chipset specific +// +#include EFI_GUID_DEFINITION (MeDataHob) +#include "CpuRegs.h" +#include "CpuPlatformLib.h" +#include "PttHciRegs.h" +#endif + +// +// Below definition is driver specific +// +#include "Tpm2AcpiTableStorage.h" + +#pragma pack(1) +typedef struct { + UINT8 SoftwareSmi; + UINT32 Parameter; + UINT32 Response; + UINT32 Request; + UINT32 LastRequest; + UINT32 ReturnCode; +} PHYSICAL_PRESENCE_NVS; + +typedef struct { + UINT8 SoftwareSmi; + UINT32 Parameter; + UINT32 Request; + UINT32 ReturnCode; +} MEMORY_CLEAR_NVS; + +typedef struct { + UINT8 SoftwareSmi; + UINT32 ReturnCode; +} START_METHOD_NVS; + +typedef struct { + PHYSICAL_PRESENCE_NVS PhysicalPresence; + MEMORY_CLEAR_NVS MemoryClear; + START_METHOD_NVS StartMethod; +} TCG_NVS; + +typedef struct { + UINT8 OpRegionOp; + UINT32 NameString; + UINT8 RegionSpace; + UINT8 DWordPrefix; + UINT32 RegionOffset; + UINT8 BytePrefix; + UINT8 RegionLen; +} AML_OP_REGION_32_8; +#pragma pack() + +// +// The definition for TCG physical presence ACPI function +// +#define ACPI_FUNCTION_GET_PHYSICAL_PRESENCE_INTERFACE_VERSION 1 +#define ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS 2 +#define ACPI_FUNCTION_GET_PENDING_REQUEST_BY_OS 3 +#define ACPI_FUNCTION_GET_PLATFORM_ACTION_TO_TRANSITION_TO_BIOS 4 +#define ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS 5 +#define ACPI_FUNCTION_SUBMIT_PREFERRED_USER_LANGUAGE 6 +#define ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2 7 +#define ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST 8 + +// +// The return code for Get User Confirmation Status for Operation +// +#define PP_REQUEST_NOT_IMPLEMENTED 0 +#define PP_REQUEST_BIOS_ONLY 1 +#define PP_REQUEST_BLOCKED 2 +#define PP_REQUEST_ALLOWED_AND_PPUSER_REQUIRED 3 +#define PP_REQUEST_ALLOWED_AND_PPUSER_NOT_REQUIRED 4 + +// +// The return code for Sumbit TPM Request to Pre-OS Environment +// and Sumbit TPM Request to Pre-OS Environment 2 +// +#define PP_SUBMIT_REQUEST_SUCCESS 0 +#define PP_SUBMIT_REQUEST_NOT_IMPLEMENTED 1 +#define PP_SUBMIT_REQUEST_GENERAL_FAILURE 2 +#define PP_SUBMIT_REQUEST_BLOCKED_BY_BIOS_SETTINGS 3 + +// +// The definition for TCG MOR +// +#define ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE 1 +#define ACPI_FUNCTION_PTS_CLEAR_MOR_BIT 2 + +// +// The return code for Memory Clear Interface Functions +// +#define MOR_REQUEST_SUCCESS 0 +#define MOR_REQUEST_GENERAL_FAILURE 1 + +// +// Below definition should be in platorm scope +// +// TBD: Use policy to input these data... +#ifndef EFI_TPM2_PP_SW_SMI +#define EFI_TPM2_PP_SW_SMI 0x9E +#endif +#ifndef EFI_TPM2_MOR_SW_SMI +#define EFI_TPM2_MOR_SW_SMI 0x9F +#endif + +#endif // __FTPM_SMM_H__ diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.inf b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.inf new file mode 100644 index 0000000..87e30f1 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.inf @@ -0,0 +1,106 @@ +## @file +# This driver implements TPM2 definition block in ACPI table and +# +#@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 +# + +[defines] + BASE_NAME = PttHciSmm + FILE_GUID = 8029a5b5-4088-48d2-96e0-f7052bc0a842 + COMPONENT_TYPE = RT_DRIVER + +[sources.common] + PttHciSmm.c + PttHciSmm.h +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueSmmDriverEntryPoint.c + +[includes.common] + # + # Edk II Glue Library, some hearder are included by R9 header so have to include + # + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Library + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Common + + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Framework/Guid + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT) + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/Ptt/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 + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueSmmRuntimeDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueDxeHobLib + CpuPlatformLib + EdkFrameworkProtocolLib + EdkProtocolLib + EdkIIGlueSmmFirmwarePerformanceLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = PttHciSmm.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) /D__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeFtpmSmm + C_FLAGS = $(C_FLAGS) /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_SMM_RUNTIME_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_DXE_HOB_LIB__ \ + /D PTT_FLAG diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.mak b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.mak new file mode 100644 index 0000000..1c6485a --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.mak @@ -0,0 +1,69 @@ +# MAK file for the ModulePart:PTTHciSmm +all : PttHciSmm + +PttHciSmm : $(BUILD_DIR)\PttHciSmm.mak PttHciSmmBin + +$(BUILD_DIR)\PttHciSmm.mak : $(PttHciSmm_DIR)\PttHciSmm.cif $(PttHciSmm_DIR)\PttHciSmm.mak $(CP_BUILD_RULES) + $(CIF2MAK) $(PttHciSmm_DIR)\PttHciSmm.cif $(CIF2MAK_DEFAULTS) + +PTTHciSmm_INCLUDES= \ + $(ACPI_PLATFORM_INCLUDES)\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + /I$(INTEL_COUGAR_POINT_INCLUDE_DIR)\ + /IReferenceCode\ME\SampleCode\ + $(PROJECT_CPU_INCLUDES) + +PTTHciSmm_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(MeProtocolLib_LIB)\ + $(MeLibDxe_LIB)\ + $(MeChipsetDxeLib_LIB)\ + $(MeGuidLib_LIB)\ + $(EFISCRIPTLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EFIGUIDLIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EFIDRIVERLIB)\ + $(RcFviDxeLib_LIB)\ + $(PchPlatformDxeLib_LIB)\ + $(CpuPlatformLib_LIB)\ + $(EdkIIGlueDxeHobLib_LIB)\ + $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\ + +PTTHciSmm_DEFINES=$(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeFtpmSmm"\ + /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_SMM_RUNTIME_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_DXE_HOB_LIB__ \ + /D PTT_FLAG + +PTTHciSmmBin : $(PTTHciSmm_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PttHciSmm.mak all\ + MAKEFILE=$(BUILD_DIR)\PttHciSmm.mak\ + "MY_INCLUDES=$(PTTHciSmm_INCLUDES)"\ + "MY_DEFINES=$(PTTHciSmm_DEFINES)"\ + GUID=8029a5b5-4088-48d2-96e0-f7052bc0a842\ + DEPEX1=$(PttHciSmm_DIR)\PTTHciSmm.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=RT_DRIVER\ + EDKIIModule=SMMDRIVER\ + COMPRESS=1
\ No newline at end of file diff --git a/ReferenceCode/ME/Ptt/Smm/PttHciSmm.sdl b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.sdl new file mode 100644 index 0000000..1853239 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttHciSmm.sdl @@ -0,0 +1,32 @@ +TOKEN + Name = "PTTHciSmm_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PTTHciSmm Suppport in Project" + Token = "IntelPTT_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes HeciSmm.mak to Project" + File = "PttHciSmm.mak" +End + +ELINK + Name = "$(BUILD_DIR)\PttHciSmm.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +PATH + Name = "PttHciSmm_DIR" + Help = "PTT Hci SMM Driver files source directory" +End + +ELINK + Name = "/D PTT_FLAG" + Parent = "GLOBAL_DEFINES" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/Ptt/Smm/PttSmm.cif b/ReferenceCode/ME/Ptt/Smm/PttSmm.cif new file mode 100644 index 0000000..d2c5c29 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttSmm.cif @@ -0,0 +1,9 @@ +<component> + name = "PttSmm" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Ptt\Smm\" + RefName = "PttSmm" +[parts] +"PttHciSmm" +"PttSmmAcpi" +<endComponent> diff --git a/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.cif b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.cif new file mode 100644 index 0000000..50eb85c --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.cif @@ -0,0 +1,12 @@ +<component> + name = "PttSmmAcpi" + category = ModulePart + LocalRoot = "ReferenceCode\ME\Ptt\Smm\" + RefName = "PttSmmAcpi" +[files] +"Ftpm.asl" +"Tpm2AcpiTables.inf" +"Tpm2AcpiTableStorage.h" +"PttSmmAcpi.mak" +"PttSmmAcpi.sdl" +<endComponent> diff --git a/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.mak b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.mak new file mode 100644 index 0000000..24e7414 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.mak @@ -0,0 +1,44 @@ +#----------------------------------------------------------------------- +# ASL compiler definition +#----------------------------------------------------------------------- +MASL = $(SILENT)asl.exe # Microsoft ASL compiler +!IF "$(ACPIPLATFORM_ASL_COMPILER)"=="" +!ERROR It is an invalid path, please check your ASL compiler path. +!ENDIF + +IASL = $(ACPIPLATFORM_ASL_COMPILER) +#----------------------------------------------------------------------- +ASL_COMPILER = IASL # Default ASL compiler. Can be 'IASL' for Intel ASL and 'MASL' for Microsoft ASL compiler. +# Note. Msft. ASL compiler of version 1.0.14NT correctly process ACPI 2.0 extended ASL objects. +#----------------------------------------------------------------------- +EDK : PTTASL + +PTTASL: $(BUILD_DIR)\PTTACPI.ffs + +$(BUILD_DIR)\TPM.aml: $(INTEL_PTT_ASL_FILE) +!if "$(ASL_COMPILER)" == "MASL" + $(MASL) /Fo=$@ $** +!elseif "$(ASL_COMPILER)" == "IASL" + $(IASL) -p $(BUILD_DIR)\TPM.aml $(INTEL_PTT_ASL_FILE) +!endif + +$(BUILD_DIR)\TPM.sec: $(BUILD_DIR)\TPM.aml + $(GENSECTION) -I $** -O $@ -S EFI_SECTION_RAW + +$(BUILD_DIR)\PTTACPI.ffs: $(BUILD_DIR)\TPM.sec $(PttHciSmm_DIR)\PttSmmAcpi.mak + $(GENFFSFILE) -B $(BUILD_DIR) -V -o $@ -P1 <<$(BUILD_DIR)\PTTACPI.pkg +PACKAGE.INF +[.] +BASE_NAME = PTTACPI +FFS_FILEGUID = 7D279373-EECC-4d4f-AE2F-CEC4B706B06A +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress (dummy) { + $(PROJECT_DIR)\$(BUILD_DIR)\TPM.sec + } +} +<<KEEP +#-----------------------------------------------------------------------
\ No newline at end of file diff --git a/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.sdl b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.sdl new file mode 100644 index 0000000..b039d27 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/PttSmmAcpi.sdl @@ -0,0 +1,33 @@ +TOKEN + Name = "PTTSmmAcpi_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PTTHciSmm Suppport in Project" + Token = "IntelPTT_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes HeciSmm.mak to Project" + File = "PttSmmAcpi.mak" +End + +PATH + Name = "PttHciSmm_DIR" + Help = "PTT Hci SMM Driver files source directory" +End + +ELINK + Name = "$(BUILD_DIR)\PTTACPI.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +TOKEN + Name = "INTEL_PTT_ASL_FILE" + Value = "$(PttHciSmm_DIR)\Ftpm.asl" + TokenType = Expression + TargetMAK = Yes +End diff --git a/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTableStorage.h b/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTableStorage.h new file mode 100644 index 0000000..42a7e18 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTableStorage.h @@ -0,0 +1,31 @@ +/** @file + GUID definition for the TPM2 ACPI table storage file name + +@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 _TPM2_ACPI_TABLE_STORAGE_H_ +#define _TPM2_ACPI_TABLE_STORAGE_H_ + +#define TPM2_ACPI_TABLE_STORAGE_GUID \ + { \ + 0x7d279373, 0xeecc, 0x4d4f, 0xae, 0x2f, 0xce, 0xc4, 0xb7, 0x6, 0xb0, 0x6a \ + } + +extern EFI_GUID gTpm2AcpiTableStorageGuid; + +#endif diff --git a/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTables.inf b/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTables.inf new file mode 100644 index 0000000..e6e03a4 --- /dev/null +++ b/ReferenceCode/ME/Ptt/Smm/Tpm2AcpiTables.inf @@ -0,0 +1,38 @@ +## @file +# Component description file for the ACPI tables +# +#@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 +# + +[defines] +BASE_NAME = Tpm2AcpiTables +FILE_GUID = 7D279373-EECC-4d4f-AE2F-CEC4B706B06A +COMPONENT_TYPE = ACPITABLE +FFS_EXT = .ffs + +[sources.common] + Ftpm.ASL + +[libraries.common] + +[includes.common] + . + $(EFI_SOURCE) + $(EFI_SOURCE)\Include + +[nmake.common] diff --git a/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.c b/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.c new file mode 100644 index 0000000..c5324aa --- /dev/null +++ b/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.c @@ -0,0 +1,1517 @@ +/** @file + Support routines for ASF boot options in the BDS + +@copyright + Copyright (c) 2005-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 + +**/ + +#include "AsfSupport.h" + +#pragma pack(push,1) + +typedef struct { + UINT32 Attributes; + UINT16 FilePathListLength; +} EFI_LOAD_OPTION; + +#pragma pack(pop) + +// +// Global variables +// +EFI_ASF_BOOT_OPTIONS *mAsfBootOptions; +EFI_GUID gAsfRestoreBootSettingsGuid = RESTORE_SECURE_BOOT_GUID; + +/** + Retrieve the ASF boot options previously recorded by the ASF driver. + + @param[in] None. + + @retval EFI_SUCCESS Initialized Boot Options global variable and AMT protocol +**/ +EFI_STATUS +BdsAsfInitialization ( + IN VOID + ) +{ + EFI_STATUS Status; + EFI_ALERT_STANDARD_FORMAT_PROTOCOL *Asf; + + mAsfBootOptions = NULL; + + // + // Amt Library Init + // + Status = AmtLibInit (); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Info : Error init AmtLibInit -> %r\n", Status)); + return Status; + } + // + // Get Protocol for ASF + // + Status = gBS->LocateProtocol ( + &gEfiAlertStandardFormatProtocolGuid, + NULL, + &Asf + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Info : Error getting ASF protocol -> %r\n", Status)); + return Status; + } + + Status = Asf->GetBootOptions (Asf, &mAsfBootOptions); + if (EFI_ERROR(Status)) { + DEBUG ((EFI_D_ERROR, "Info : Error getting ASF BootOptions -> %r\n", Status)); + return Status; + } + + Status = ManageSecureBootState(); + + return Status; +} + +/** + Get current Secure Boot state (enabled/disabled) + + @param[in] None. + + @retval UINT8 Secure Boot State +**/ +UINT8 +GetSecureBootState( + IN VOID + ) +{ + // + // This function is BIOS implementation specific + // and should be implemented in platform code + // + + return SECURE_BOOT_DISABLED; +} + +/** + Set current Secure Boot state (enabled/disabled) + + @param[in] SecureBootState Secure Boot State + + @retval EFI_SUCCESS Secure Boot State successfully changed +**/ +EFI_STATUS +SetSecureBootState( + IN UINT8 SecureBootState + ) +{ + // + // This function is BIOS implementation specific + // and should be implemented in platform code + // + + return EFI_SUCCESS; +} + +/** + This routine makes necessary Secure Boot & CSM state changes for IDEr boot + + @param[in] None. + + @retval EFI_SUCCESS Changes applied succesfully +**/ +EFI_STATUS +ManageSecureBootState( + IN VOID + ) +{ + EFI_STATUS Status; + BOOLEAN EnforceSecureBoot; + UINT8 SecureBootState; + UINT8 RestoreBootSettings; + UINT8 IderBoot; + UINTN VarSize; + + VarSize = sizeof(UINT8); + + // + // Get boot parameters (IDER boot?, EnforceSecureBoot flag set?, secure boot enabled?) + // + EnforceSecureBoot = ActiveManagementEnforceSecureBoot(); + IderBoot = ActiveManagementEnableIdeR(); + SecureBootState = GetSecureBootState(); + + // + // Check whether we need to restore SecureBootEnable value changed in previous IDER boot + // + Status = gRT->GetVariable( + L"RestoreBootSettings", + &gAsfRestoreBootSettingsGuid, + NULL, + &VarSize, + &RestoreBootSettings + ); + + if (Status == EFI_SUCCESS && RestoreBootSettings != RESTORE_SECURE_BOOT_NONE) { + if (RestoreBootSettings == RESTORE_SECURE_BOOT_ENABLED && SecureBootState == SECURE_BOOT_DISABLED && + !(IderBoot && !EnforceSecureBoot)) { + + SecureBootState = SECURE_BOOT_ENABLED; + + Status = SetSecureBootState(SecureBootState); + ASSERT_EFI_ERROR (Status); + + // + // Delete RestoreBootSettings variable + // + Status = gRT->SetVariable( + L"RestoreBootSettings", + &gAsfRestoreBootSettingsGuid, + 0, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "Secure Boot settings restored after IDER boot - Cold Reset!\n")); + gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + EFI_DEADLOOP(); + } + } + + Status = EFI_SUCCESS; + + if (IderBoot) { + if (SecureBootState == SECURE_BOOT_ENABLED && !EnforceSecureBoot) { + // + // Secure boot needs to be disabled if we're doing IDER and EnforceSecureBoot not set + // + SecureBootState = SECURE_BOOT_DISABLED; + RestoreBootSettings = RESTORE_SECURE_BOOT_ENABLED; + + Status = SetSecureBootState(SecureBootState); + ASSERT_EFI_ERROR (Status); + + // + // Set variable to restore previous secure boot state + // + Status = gRT->SetVariable( + L"RestoreBootSettings", + &gAsfRestoreBootSettingsGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(UINT8), + &RestoreBootSettings + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "Secure Boot disabled for IDER boot - Cold Reset!\n")); + gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + EFI_DEADLOOP(); + } + } + + return Status; +} + +/** + This function will create a BootOption from the give device path and + description string. + + @param[in] DevicePath The device path which the option represent + @param[in] Description The description of the boot option + + @retval BDS_COMMON_OPTION - Pointer to created boot option +**/ +BDS_COMMON_OPTION * +BdsCreateBootOption ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Description + ) +{ + BDS_COMMON_OPTION *Option; + + Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION)); + if (Option == NULL) { + return NULL; + } + + Option->Signature = BDS_LOAD_OPTION_SIGNATURE; + Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); + CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); + + Option->Attribute = LOAD_OPTION_ACTIVE; + Option->Description = AllocateZeroPool (EfiStrSize (Description)); + CopyMem (Option->Description, Description, EfiStrSize (Description)); + + return Option; +} + +/** + This function will create a SHELL BootOption to boot. + + @param[in] None. + + @retval EFI_DEVICE_PATH_PROTOCOL Shell Device path for booting. +**/ +EFI_DEVICE_PATH_PROTOCOL * +BdsCreateShellDevicePath ( + VOID + ) +{ + UINTN FvHandleCount; + EFI_HANDLE *FvHandleBuffer; + UINTN Index; + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_PROTOCOL *Fv; + EFI_FV_FILETYPE Type; + UINTN Size; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode; + + DevicePath = NULL; + Status = EFI_SUCCESS; + + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + + for (Index = 0; Index < FvHandleCount; Index++) { + gBS->HandleProtocol ( + FvHandleBuffer[Index], + &gEfiFirmwareVolumeProtocolGuid, + (VOID **) &Fv + ); + + Status = Fv->ReadFile ( + Fv, + &gEfiShellFileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + // + // Skip if no shell file in the FV + // + continue; + } else { + // + // Found the shell + // + break; + } + } + + if (EFI_ERROR (Status)) { + // + // No shell present + // + if (FvHandleCount) { + FreePool (FvHandleBuffer); + } + return NULL; + } + // + // Build the shell boot option + // + DevicePath = DevicePathFromHandle (FvHandleBuffer[Index]); + + // + // Build the shell device path + // + ShellNode.Header.Type = MEDIA_DEVICE_PATH; + ShellNode.Header.SubType = MEDIA_FV_FILEPATH_DP; + SetDevicePathNodeLength (&ShellNode.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)); + CopyMem (&ShellNode.NameGuid, &gEfiShellFileGuid, sizeof (EFI_GUID)); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode); + + if (FvHandleCount) { + FreePool (FvHandleBuffer); + } + + return DevicePath; +} + +/** + This function will create a PXE BootOption to boot. + + @param[in] DeviceIndex PXE handle index + + @retval EFI_DEVICE_PATH_PROTOCOL PXE Device path for booting. +**/ +EFI_DEVICE_PATH_PROTOCOL * +BdsCreatePxeDevicePath ( + IN UINT16 DeviceIndex + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN NumberLoadFileHandles; + EFI_HANDLE *LoadFileHandles; + VOID *ProtocolInstance; + + DevicePath = NULL; + Status = EFI_SUCCESS; + + // + // We want everything connected up for PXE + // + BdsLibConnectAllDriversToAllControllers (); + + // + // Parse Network Boot Device + // + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleNetworkProtocolGuid, + NULL, + &NumberLoadFileHandles, + &LoadFileHandles + ); + for (Index = 0; Index < NumberLoadFileHandles; Index++) { + Status = gBS->HandleProtocol ( + LoadFileHandles[Index], + &gEfiLoadFileProtocolGuid, + (VOID **) &ProtocolInstance + ); + if (EFI_ERROR (Status)) { + // + // try next handle + // + continue; + } else { + if (Index == DeviceIndex) { + // + // Found a PXE handle + // + break; + } else { + Status = EFI_UNSUPPORTED; + } + } + } + + if (EFI_ERROR (Status)) { + // + // No PXE present + // + if (NumberLoadFileHandles) { + FreePool (LoadFileHandles); + } + return NULL; + } + // + // Build the PXE device path + // + DevicePath = DevicePathFromHandle (LoadFileHandles[Index]); + + if (NumberLoadFileHandles) { + FreePool (LoadFileHandles); + } + + return DevicePath; +} + +BOOLEAN +ComparePathNode( + IN EFI_DEVICE_PATH_PROTOCOL *PathNode1, + IN EFI_DEVICE_PATH_PROTOCOL *PathNode2 +) +{ + BOOLEAN st = FALSE; + UINTN Size1, Size2; + UINT8 *p1, *p2; + + if ((PathNode1 == NULL) || (PathNode2 == NULL)) { + return FALSE; + } + + if (PathNode1 == PathNode2) { + st = TRUE; + } else { + Size1 = DevicePathNodeLength(PathNode1); + Size2 = DevicePathNodeLength(PathNode2); + p1 = (UINT8 *)PathNode1; + p2 = (UINT8 *)PathNode2; + if ((Size1 == Size2) + && (DevicePathType(PathNode1) == DevicePathType(PathNode2)) + && (CompareMem(p1+1, p2+1, Size1-1) == 0)) { + st = TRUE; + } + } + + return st; +} + +/** + Compare two device paths node by node up to MEDIA_DEVICE_PATH node + + @param[in] BootOptionDP Device path acquired from BootXXXX EFI variable + @param[in] FileSysDP Device path acquired through EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Handles buffer + + @retval TRUE Both device paths point to the same device + @retval FALSE Device paths point to different devices +**/ +BOOLEAN +CompareDevicePaths( + IN EFI_DEVICE_PATH_PROTOCOL *BootOptionDP, + IN EFI_DEVICE_PATH_PROTOCOL *FileSysDP +) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPathNodeA; + EFI_DEVICE_PATH_PROTOCOL *DevPathNodeB; + + if (BootOptionDP == NULL || FileSysDP == NULL) { + return FALSE; + } + + DevPathNodeA = BdsLibUnpackDevicePath(BootOptionDP); + if (DevPathNodeA == NULL) { + return FALSE; + } + + DevPathNodeB = BdsLibUnpackDevicePath(FileSysDP); + if (DevPathNodeB == NULL) { + return FALSE; + } + + while (!IsDevicePathEnd(DevPathNodeB)) { + if (DevicePathType(DevPathNodeB) == MEDIA_DEVICE_PATH) { + // + // If we have reached MEDIA_DEVICE_PATH node and all previous + // nodes matched - we can be sure path points to the same device + // + return TRUE; + } + + if (!ComparePathNode(DevPathNodeA, DevPathNodeB)) { + break; + } + + DevPathNodeA = NextDevicePathNode(DevPathNodeA); + DevPathNodeB = NextDevicePathNode(DevPathNodeB); + } + + return FALSE; +} + +/** + Get EFI device path through EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Handles buffer. Acquired path must + point to the same device as argument DevicePath passed to the function. + + @param[in] DevicePath Device path acquired from BootXXXX EFI variable + + @retval EFI_DEVICE_PATH_PROTOCOL Device path for booting +**/ +EFI_DEVICE_PATH_PROTOCOL * +GetFullBootDevicePath( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath +) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DPath; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + UINTN HandleNum; + EFI_HANDLE *HandleBuf; + UINTN Index; + + DevPath = NULL; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &HandleNum, + &HandleBuf + ); + if ((EFI_ERROR (Status)) || (HandleBuf == NULL)) { + return NULL; + } + + for (Index = 0; Index < HandleNum; Index++) { + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiDevicePathProtocolGuid, + &DPath + ); + + if (CompareDevicePaths(DevicePath, DPath)) { + DevPath = DuplicateDevicePath(DPath); + break; + } + } + + return DevPath; +} + +/*++ + Translate ASF request type to BBS or EFI device path type + + @param[in] DeviceType - ASF request type + @param[in] Efi - Set to TRUE if DeviceType is to be translated + to EFI device path type; FALSE if BBS type + @retval UINTN Translated device type +--*/ +UINTN +GetBootDeviceType ( + IN UINTN DeviceType, + IN BOOLEAN Efi + ) +{ + UINTN Type = 0; + + switch (DeviceType) { + case FORCE_PXE: + if (Efi) { + Type = MEDIA_FILEPATH_DP; + } else { + Type = BBS_EMBED_NETWORK; + } + break; + case FORCE_HARDDRIVE: + case FORCE_SAFEMODE: + if (Efi) { + Type = MEDIA_HARDDRIVE_DP; + } else { + Type = BBS_TYPE_HARDDRIVE; + } + break; + case FORCE_DIAGNOSTICS: + if (Efi) { + Type = MEDIA_FILEPATH_DP; + } + break; + case FORCE_CDDVD: + if (Efi) { + Type = MEDIA_CDROM_DP; + } else { + Type = BBS_TYPE_CDROM; + } + break; + default: + break; + } + + return Type; +} + +/** + Update the BBS table with our required boot device + + @param[in] DeviceIndex Boot device whose device index + @param[in] DevType Boot device whose device type + @param[in] BbsCount Number of BBS_TABLE structures + @param[in] BbsTable BBS entry + @param[in] IderBoot set to TRUE if this is IDER boot + + @retval EFI_SUCCESS BBS table successfully updated +**/ +EFI_STATUS +RefreshBbsTableForBoot ( + IN UINT16 DeviceIndex, + IN UINT16 DevType, + IN BOOLEAN IderBoot + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT16 TempIndex; + BOOLEAN IderBootDevice; + BOOLEAN RegularBootDevice; + HDD_INFO *LocalHddInfo; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + BBS_TABLE *BbsTable; + UINT16 HddCount; + UINT16 BbsCount; + + TempIndex = (IderBoot) ? 0 : ((DeviceIndex <= 1) ? DeviceIndex : 1); + + // + // Make sure the Legacy Boot Protocol is available + // + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios); + if (LegacyBios == NULL) { + return EFI_ABORTED; + } + + // + // Get BBS table instance + // + Status = LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &BbsTable + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + Status = EFI_NOT_FOUND; + + // + // For debug + // + PrintBbsTable (BbsTable); + + // + // Find the first present boot device whose device type + // matches the DevType, we use it to boot first. This is different + // from the other Bbs table refresh since we are looking for the device type + // index instead of the first device to match the device type. + // + // And set other present boot devices' priority to BBS_UNPRIORITIZED_ENTRY + // their priority will be set by LegacyBiosPlatform protocol by default + // + for (Index = 0; Index < BbsCount; Index++) { + if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { + continue; + } + + BbsTable[Index].BootPriority = BBS_DO_NOT_BOOT_FROM; + IderBootDevice = IderBoot && IS_IDER(BbsTable[Index].Bus, BbsTable[Index].Device, BbsTable[Index].Function) && + BbsTable[Index].DeviceType == DevType; + RegularBootDevice = !IderBoot && (BbsTable[Index].DeviceType == DevType || + (DevType == BBS_EMBED_NETWORK && IS_PXE(BbsTable[Index].DeviceType, BbsTable[Index].Class)) || + (DevType == BBS_TYPE_CDROM && IS_CDROM(BbsTable[Index].DeviceType, BbsTable[Index].Class))); + + if ((IderBootDevice || RegularBootDevice) && Status != EFI_SUCCESS) { + if (IderBoot || (TempIndex++ == DeviceIndex)) { + BbsTable[Index].BootPriority = 0; + Status = EFI_SUCCESS; + continue; + } + } + } + + // + // For debug + // + PrintBbsTable (BbsTable); + + return Status; +} + +EFI_DEVICE_PATH_PROTOCOL * +BdsCreateBootDevicePath ( + IN UINT16 DeviceType, + IN UINT16 DeviceIndex, + IN BOOLEAN IdeRBoot, + IN BOOLEAN EfiBoot + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; + UINTN OptionOrderSize; + UINT16 *OptionOrder; + EFI_LOAD_OPTION *Option; + CHAR16 OptionName[sizeof ("Driver####")]; + UINT16 OptionNumber; + UINTN OptionIndex; + UINTN OptionCount; + UINTN Index; + UINTN OptionSize; + UINTN TempIndex; + EFI_DEVICE_PATH_PROTOCOL *DevPathNode; + EFI_DEVICE_PATH_PROTOCOL *DevPathNodeBackup; + ATAPI_DEVICE_PATH *AtaPath; + BOOLEAN AtaDeviceMatch; + PCI_DEVICE_PATH *PciPath; + BOOLEAN PciDeviceMatch; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINTN EfiDeviceType; + UINTN LegacyDeviceType; + BOOLEAN TypeMatched; + + PrimarySecondary = ((mAsfBootOptions->SpecialCommandParam >> IDER_BOOT_DEVICE_SHIFT) & IDER_PRIMARY_SECONDARY_MASK) + >> IDER_PRIMARY_SECONDARY_SHIFT; + SlaveMaster = (mAsfBootOptions->SpecialCommandParam >> IDER_BOOT_DEVICE_SHIFT) & IDER_MASTER_SLAVE_MASK; + DevicePath = NULL; + FullDevicePath = NULL; + TempIndex = 1; + AtaDeviceMatch = FALSE; + PciDeviceMatch = FALSE; + EfiDeviceType = GetBootDeviceType(DeviceType, TRUE); + LegacyDeviceType = GetBootDeviceType(DeviceType, FALSE); + TypeMatched = FALSE; + + if (IdeRBoot && !EfiBoot) { + LegacyDeviceType = (SlaveMaster == 1) ? BBS_CDROM : BBS_HARDDISK; + } + + // + // Read the BootOrder variable. + // + OptionOrder = BdsLibGetVariableAndSize (L"BootOrder", &gEfiGlobalVariableGuid, &OptionOrderSize); + if (OptionOrder == NULL) { + return NULL; + } + + OptionCount = OptionOrderSize/sizeof(UINT16); + OptionIndex = 0; + + for (Index = 0; Index < OptionCount; Index++) { + + OptionNumber = OptionOrder[Index]; + UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionNumber); + Option = BdsLibGetVariableAndSize (OptionName, &gEfiGlobalVariableGuid, &OptionSize); + if (Option == NULL) { + continue; + } + + // + // Extract device path from the boot order entry + // + TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) + ( //skip the header + (UINT8*)(Option+1) + //skip the string + +(EfiStrLen((CHAR16*)(Option+1))+1)*sizeof(CHAR16) + ); + + if (DevicePathType(TempDevicePath) == BBS_DEVICE_PATH && DevicePathSubType(TempDevicePath) == BBS_BBS_DP) { + FullDevicePath = DuplicateDevicePath(TempDevicePath); + } else { + // + // If this is EFI boot option, we need to get full device path from EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + // to determine type of device and provide LoadImage with proper path to bootloader image later on + // + FullDevicePath = GetFullBootDevicePath(TempDevicePath); + if (FullDevicePath == NULL) { + continue; + } + } + + TempDevicePath = FullDevicePath; + DevPathNode = BdsLibUnpackDevicePath(TempDevicePath); + if (DevPathNode == NULL) { + continue; + } + + DevPathNodeBackup = DevPathNode; + + // + // Check if this is our requested boot device + // + while (!IsDevicePathEnd(DevPathNode)) { + if (IdeRBoot && EfiBoot) { + // + // IDER EFI boot, check for PCI/ATA device match + // + if ((DevicePathType(DevPathNode) == HARDWARE_DEVICE_PATH) && + (DevicePathSubType(DevPathNode) == HW_PCI_DP)) { + PciPath = (PCI_DEVICE_PATH*) DevPathNode; + + if ((PciPath->Device == IDER_DEVICE_NUMBER) + && (PciPath->Function == IDER_FUNCTION_NUMBER)) { + PciDeviceMatch = TRUE; + } + } else if ((DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) && + (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)) { + AtaPath = (ATAPI_DEVICE_PATH*) DevPathNode; + + if ((AtaPath->PrimarySecondary == PrimarySecondary) + && (AtaPath->SlaveMaster == SlaveMaster)) { + AtaDeviceMatch = TRUE; + } + } + + if (PciDeviceMatch && AtaDeviceMatch) { + TypeMatched = TRUE; + } + } else { + if (DevicePathType(DevPathNode) == BBS_DEVICE_PATH && DevicePathSubType(DevPathNode) == BBS_BBS_DP) { + // + // Legacy boot option + // + if (((BBS_BBS_DEVICE_PATH *)DevPathNode)->DeviceType == LegacyDeviceType) { + TypeMatched = TRUE; + } + } else { + // + // EFI boot option + // + if (DevicePathType(DevPathNode) == MEDIA_DEVICE_PATH && DevicePathSubType(DevPathNode) == EfiDeviceType) { + TypeMatched = TRUE; + } + } + } + + if (TypeMatched) { + // + // Type matched, check for device index + // + if (!IdeRBoot && TempIndex < DeviceIndex) { + TempIndex++; + TypeMatched = FALSE; + break; + } + + DevicePath = DuplicateDevicePath(TempDevicePath); + // + // Refresh BBS table if legacy option + // + if (DevicePathType(DevicePath) == BBS_DEVICE_PATH && DevicePathSubType(DevicePath) == BBS_BBS_DP) { + RefreshBbsTableForBoot(DeviceIndex, (UINT16)LegacyDeviceType, IdeRBoot); + } + break; + } + + DevPathNode = NextDevicePathNode(DevPathNode); + } + + if (FullDevicePath != NULL) { + FreePool(FullDevicePath); + FullDevicePath = NULL; + } + + FreePool(DevPathNodeBackup); + FreePool(Option); + + if (DevicePath != NULL) { + // + // Set Boot Current and leave + // + gRT->SetVariable ( + L"BootCurrent", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (UINT16), + &OptionNumber + ); + break; + } + } + + FreePool(OptionOrder); + + return DevicePath; +} + +/** + Boot the legacy system with the boot option + + @param[in] Option The legacy boot option which have BBS device path + + @retval EFI_UNSUPPORTED - There is no legacybios protocol, do not support legacy boot. + @retval EFI_STATUS - Return the status of LegacyBios->LegacyBoot (). +**/ +EFI_STATUS +AsfDoLegacyBoot ( + IN BDS_COMMON_OPTION *Option + ) +{ + EFI_STATUS Status; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios); + if (EFI_ERROR (Status)) { + // + // If no LegacyBios protocol we do not support legacy boot + // + return EFI_UNSUPPORTED; + } + // + // Write boot to OS performance data to a file + // + WRITE_BOOT_TO_OS_PERFORMANCE_DATA; + + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Legacy Boot: %S\n", Option->Description)); + return LegacyBios->LegacyBoot ( + LegacyBios, + (BBS_BBS_DEVICE_PATH *) Option->DevicePath, + Option->LoadOptionsSize, + Option->LoadOptions + ); +} + +/** + Process the boot option follow the EFI 1.1 specification and + special treat the legacy boot option with BBS_DEVICE_PATH. + + @param[in] Option The boot option need to be processed + @param[in] DevicePath The device path which describe where to load + the boot image or the legcy BBS device path + to boot the legacy OS + @param[in] ExitDataSize Returned directly from gBS->StartImage () + @param[in] ExitData Returned directly from gBS->StartImage () + + @retval EFI_SUCCESS - Status from gBS->StartImage (), + or BdsBootByDiskSignatureAndPartition () + @retval EFI_NOT_FOUND - If the Device Path is not found in the system +**/ +EFI_STATUS +AsfBootViaBootOption ( + IN BDS_COMMON_OPTION * Option, + IN EFI_DEVICE_PATH_PROTOCOL * DevicePath, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_HANDLE ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + EFI_EVENT ReadyToBootEvent; + EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save; + UINTN DataSize; + EFI_INPUT_KEY Key; + UINTN EventIndex; +#ifdef EFI_DEBUG + UINT8 SecureBootState; +#endif + + *ExitDataSize = 0; + *ExitData = NULL; + DataSize = sizeof(UINT16); + + // + // Notes: put EFI64 ROM Shadow Solution + // + EFI64_SHADOW_ALL_LEGACY_ROM (); + + // + // Notes: this code can be remove after the s3 script table + // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or + // EFI_EVENT_SIGNAL_LEGACY_BOOT + // + Status = gBS->LocateProtocol (&gEfiAcpiS3SaveGuid, NULL, &AcpiS3Save); + if (!EFI_ERROR (Status)) { + AcpiS3Save->S3Save (AcpiS3Save, NULL); + } + // + // If it's Device Path that starts with a hard drive path, + // this routine will do the booting. + // + Status = BdsBootByDiskSignatureAndPartition ( + Option, + (HARDDRIVE_DEVICE_PATH *) DevicePath, + Option->LoadOptionsSize, + Option->LoadOptions, + ExitDataSize, + ExitData + ); + if (!EFI_ERROR (Status)) { + // + // If we found a disk signature and partition device path return success + // + return EFI_SUCCESS; + } + + // + // Set Option's BootCurrent field + // + gRT->GetVariable ( + L"BootCurrent", + &gEfiGlobalVariableGuid, + 0, + &DataSize, + &Option->BootCurrent + ); + + DEBUG ((EFI_D_INFO, "AsfBootViaBootOption: BootCurrent = %d, DevicePath = %s\n", Option->BootCurrent, DevicePathToStr(DevicePath))); + + // + // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event + // + Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent); + if (!EFI_ERROR (Status)) { + gBS->SignalEvent (ReadyToBootEvent); + gBS->CloseEvent (ReadyToBootEvent); + } + + if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) && + (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP) + ) { + // + // Check to see if we should legacy BOOT. If yes then do the legacy boot + // + return AsfDoLegacyBoot (Option); + } + + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description)); + + // + // If this is RCO/IDER EFI Boot, don't allow returning to regular boot + // and booting other devices + // + while (1) { + Status = gBS->LoadImage ( + TRUE, + mBdsImageHandle, + DevicePath, + NULL, + 0, + &ImageHandle + ); + + // + // If we didn't find an image, we may need to load the default + // boot behavior for the device. + // + if (EFI_ERROR (Status)) { + // + // Find a Simple File System protocol on the device path. If the remaining + // device path is set to end then no Files are being specified, so try + // the removable media file name. + // + TempDevicePath = DevicePath; + Status = gBS->LocateDevicePath ( + &gEfiSimpleFileSystemProtocolGuid, + &TempDevicePath, + &Handle + ); + if (!EFI_ERROR (Status) && IsDevicePathEnd (TempDevicePath)) { + FilePath = FileDevicePath (Handle, DEFAULT_REMOVABLE_FILE_NAME); + if (FilePath) { + Status = gBS->LoadImage ( + TRUE, + mBdsImageHandle, + FilePath, + NULL, + 0, + &ImageHandle + ); + } else { + Status = EFI_NOT_FOUND; + } + } else { + Status = EFI_NOT_FOUND; + } + } + + if (!EFI_ERROR (Status)) { + // + // Provide the image with it's load options + // + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, &ImageInfo); + ASSERT_EFI_ERROR (Status); + + if (Option->LoadOptionsSize != 0) { + ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; + ImageInfo->LoadOptions = Option->LoadOptions; + } + +#ifdef EFI_DEBUG + // + // Get SecureBoot state + // + SecureBootState = GetSecureBootState(); + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "SecureBootEnable value prior to image execution %d\n", SecureBootState)); +#endif + // + // Before calling the image, enable the Watchdog Timer for + // the 5 Minute period + // + gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); + + Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData); + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Image Return Status = %r\n", Status)); + + // + // Clear the Watchdog Timer after the image returns + // + gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); + } + + // + // Display message to user before attempting another RCO/IDER boot + // + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->OutputString ( + gST->ConOut, + L"EFI RCO/IDER boot failed. Press ENTER to try again\r\n" + ); + Key.ScanCode = 0; + Key.UnicodeChar = 0; + while (!(Key.ScanCode == 0 && Key.UnicodeChar == L'\r')) { + gBS->WaitForEvent (1, &(gST->ConIn->WaitForKey), &EventIndex); + gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + } + } + + // + // Clear Boot Current + // + gRT->SetVariable ( + L"BootCurrent", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, + &Option->BootCurrent + ); + + return Status; +} + +/** + Found out ASF boot options. + + @param[in] EfiBoot Set to TRUE if this is EFI boot + + @retval EFI_DEVICE_PATH_PROTOCOL Device path for booting. +**/ +EFI_DEVICE_PATH_PROTOCOL * +BdsAsfBoot ( + IN BOOLEAN EfiBoot + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = NULL; + + // + // First we check ASF boot options Special Command + // + switch (mAsfBootOptions->SpecialCommand) { + // + // No additional special command is included; the Special Command Parameter has no + // meaning. + // + case NOP: + break; + + // + // The Special Command Parameter can be used to specify a PXE + // parameter. When the parameter value is 0, the system default PXE device is booted. All + // other values for the PXE parameter are reserved for future definition by this specification. + // + case FORCE_PXE: + if (mAsfBootOptions->SpecialCommandParam != 0) { + // + // ASF spec says 0 currently only option + // + break; + } + + if (EfiBoot == TRUE) { + DevicePath = BdsCreatePxeDevicePath (mAsfBootOptions->SpecialCommandParam); + } else { + DevicePath = BdsCreateBootDevicePath (FORCE_PXE, mAsfBootOptions->SpecialCommandParam, FALSE, EfiBoot); + } + break; + + // + // The Special Command Parameter identifies the boot-media index for + // the managed client. When the parameter value is 0, the default hard-drive is booted, when the + // parameter value is 1, the primary hard-drive is booted; when the value is 2, the secondary + // hard-drive is booted and so on. + // + case FORCE_HARDDRIVE: + // + // The Special Command Parameter identifies the boot-media + // index for the managed client. When the parameter value is 0, the default hard-drive is + // booted, when the parameter value is 1, the primary hard-drive is booted; when the value is 2, + // the secondary hard-drive is booted and so on. + // + case FORCE_SAFEMODE: + DevicePath = BdsCreateBootDevicePath(FORCE_HARDDRIVE, mAsfBootOptions->SpecialCommandParam, FALSE, EfiBoot); + break; + + // + // The Special Command Parameter can be used to specify a + // diagnostic parameter. When the parameter value is 0, the default diagnostic media is booted. + // All other values for the diagnostic parameter are reserved for future definition by this + // specification. + // + case FORCE_DIAGNOSTICS: + if (mAsfBootOptions->SpecialCommandParam != 0) { + // + // ASF spec says 0 currently only option + // + break; + } + + DevicePath = BdsCreateShellDevicePath (); + + // + // We want everything connected up for shell + // + BdsLibConnectAllDriversToAllControllers (); + break; + + // + // The Special Command Parameter identifies the boot-media index for + // the managed client. When the parameter value is 0, the default CD/DVD is booted, when the + // parameter value is 1, the primary CD/DVD is booted; when the value is 2, the secondary + // CD/DVD is booted and so on. + // + case FORCE_CDDVD: + DevicePath = BdsCreateBootDevicePath (FORCE_CDDVD, mAsfBootOptions->SpecialCommandParam, FALSE, EfiBoot); + break; + + default: + break;; + } + + return DevicePath; +} + +/** + Check IdeR boot device and Asf boot device + + @param[in] EfiBoot Set to TRUE if this is EFI boot + + @retval EFI_DEVICE_PATH_PROTOCOL Device path for booting. +**/ +EFI_DEVICE_PATH_PROTOCOL * +BdsForcedBoot ( + IN BOOLEAN EfiBoot + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = NULL; + + // + // OEM command values; the interpretation of the Special Command and associated Special + // Command Parameters is defined by the entity associated with the Enterprise ID. + // + if (ActiveManagementEnableIdeR ()) { + // + // Check if any media exist in Ider device + // + if (BdsCheckIderMedia ()) { + DevicePath = BdsCreateBootDevicePath ( + FORCE_CDDVD, + 0, + TRUE, + EfiBoot + ); + } + } else if (mAsfBootOptions->IanaId != ASF_INDUSTRY_CONVERTED_IANA) { + DevicePath = BdsAsfBoot (EfiBoot); + } + + return DevicePath; +} + +/** + Process ASF boot options and if available, attempt the boot + + @param[in] None. + + @retval EFI_SUCCESS The command completed successfully +**/ +EFI_STATUS +BdsBootViaAsf ( + IN VOID + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + BDS_COMMON_OPTION *BootOption; + UINTN ExitDataSize; + CHAR16 *ExitData; + BOOLEAN EfiBoot; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + + Status = EFI_SUCCESS; + DevicePath = NULL; + EfiBoot = FALSE; + + // + // Check if this is legacy or efi boot + // + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios); + if (LegacyBios == NULL) { + EfiBoot = TRUE; + } + + // + // Check if ASF Boot Options is present. + // + if (mAsfBootOptions->SubCommand != ASF_BOOT_OPTIONS_PRESENT) { + return EFI_NOT_FOUND; + } + + DevicePath = BdsForcedBoot (EfiBoot); + // + // If device path was set, the we have a boot option to use + // + if (DevicePath == NULL) { + return EFI_UNSUPPORTED; + } + + BootOption = BdsCreateBootOption (DevicePath, L"ASF Boot"); + if (BootOption == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = AsfBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); + + FreePool (BootOption); + FreePool (DevicePath); + + return Status; +} + +/** + This will return if Media in IDE-R is present. + + @param[in] None. + + @retval TRUE Media is present. + @retval FALSE Media is not present. +**/ +BOOLEAN +BdsCheckIderMedia ( + IN VOID + ) +{ + UINTN HandleNum; + EFI_HANDLE *HandleBuf; + EFI_HANDLE Handle; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DPath; + UINTN Index; + UINTN EventIndex; + EFI_INPUT_KEY Key; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_DISK_INFO_PROTOCOL *DiskInfo; + EFI_BLOCK_IO_MEDIA *BlkMedia; + VOID *Buffer; + UINT8 IdeBootDevice; + UINT32 IdeChannel; + UINT32 IdeDevice; + + IdeBootDevice = ActiveManagementIderBootDeviceGet (); + + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Ide Channel Device Index = %d\n", IdeBootDevice)); + + // + // Make sure the Legacy Boot Protocol is available + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &HandleNum, + &HandleBuf + ); + if ((EFI_ERROR (Status)) || (HandleBuf == NULL)) { + goto Exit; + } + + for (Index = 0; Index < HandleNum; Index++) { + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiDevicePathProtocolGuid, + &DPath + ); + if (EFI_ERROR (Status)) { + continue; + } + + Status = gBS->LocateDevicePath ( + &gEfiIderControllerDriverProtocolGuid, + &DPath, + &Handle + ); + if (EFI_ERROR (Status)) { + continue; + } + + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiBlockIoProtocolGuid, + &BlkIo + ); + + if (EFI_ERROR(Status)) { + continue; + } + + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiDiskInfoProtocolGuid, + &DiskInfo + ); + + if (EFI_ERROR(Status)) { + continue; + } + + DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice); + + if (IdeBootDevice != (UINT8) (IdeChannel * 2 + IdeDevice)) { + continue; + } + + if (BlkIo->Media->MediaPresent) { + if (HandleBuf != NULL) { + FreePool (HandleBuf); + } + return TRUE; + } + + while (TRUE) { + BlkMedia = BlkIo->Media; + Buffer = AllocatePool (BlkMedia->BlockSize); + if (Buffer) { + BlkIo->ReadBlocks ( + BlkIo, + BlkMedia->MediaId, + 0, + BlkMedia->BlockSize, + Buffer + ); + FreePool (Buffer); + } + + if (BlkMedia->MediaPresent) { + if (HandleBuf != NULL) { + FreePool (HandleBuf); + } + return TRUE; + } + + gST->ConOut->OutputString ( + gST->ConOut, + L"Boot disk missing, please insert boot disk and press ENTER\r\n" + ); + Key.ScanCode = 0; + Key.UnicodeChar = 0; + gBS->RestoreTPL (EFI_TPL_APPLICATION); + while (!(Key.ScanCode == 0 && Key.UnicodeChar == L'\r')) { + Status = gBS->WaitForEvent (1, &(gST->ConIn->WaitForKey), &EventIndex); + gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + } + + gBS->RaiseTPL (EFI_TPL_DRIVER); + } + + break; + } + +Exit: + if (HandleBuf != NULL) { + FreePool (HandleBuf); + } + return FALSE; +} diff --git a/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.h b/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.h new file mode 100644 index 0000000..dad873d --- /dev/null +++ b/ReferenceCode/ME/SampleCode/AsfSupport/AsfSupport.h @@ -0,0 +1,162 @@ +/** @file + ASF BDS Support include file + +@copyright + Copyright (c) 2005-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 +**/ +#ifndef _ASF_SUPPORT_H_ +#define _ASF_SUPPORT_H_ + +#include "EdkIIGlueDxe.h" +#include "BdsLib.h" +#include "Pci22.h" +#include "Amt.h" +#include "AmtLib.h" +#include "MeAccess.h" + +#include EFI_PROTOCOL_DEFINITION (LegacyBios) +#include EFI_PROTOCOL_DEFINITION (SimpleNetwork) +#include EFI_PROTOCOL_DEFINITION (FirmwareVolume) +#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo) + +#include EFI_PROTOCOL_CONSUMER (AlertStandardformat) +#include EFI_PROTOCOL_CONSUMER (DiskInfo) + +#include EFI_PROTOCOL_DEFINITION (IderControllerDriver) + +#define IDER_PRIMARY_SECONDARY_MASK 0x02 +#define IDER_MASTER_SLAVE_MASK 0x01 +#define IDER_PRIMARY_SECONDARY_SHIFT 1 + +#define IS_IDER(BUS, DEVICE,FUNCTION) \ + (BUS == ME_BUS && DEVICE == ME_DEVICE_NUMBER && FUNCTION == IDER_FUNCTION_NUMBER) +#define IS_PXE(TYPE, CLASS) \ + (TYPE == BBS_TYPE_BEV && CLASS == PCI_CLASS_NETWORK) +#define IS_CDROM(TYPE, CLASS) \ + (TYPE == BBS_TYPE_BEV && CLASS == PCI_CLASS_MASS_STORAGE) + +#define SECURE_BOOT_ENABLED 1 +#define SECURE_BOOT_DISABLED 0 + +#define RESTORE_SECURE_BOOT_NONE 0 +#define RESTORE_SECURE_BOOT_ENABLED 1 + +#define RESTORE_SECURE_BOOT_GUID \ + { \ + 0x118b3c6f, 0x98d6, 0x4d05, 0x96, 0xb2, 0x90, 0xe4, 0xcb, 0xb7, 0x40, 0x34 \ + } + +typedef union { + UINT32 Data32; + UINT16 Data16[2]; +} DATA32_UNION; + +/** + Retrieve the ASF boot options previously recorded by the ASF driver. + + @param[in] None. + + @retval EFI_SUCCESS Initialized Boot Options global variable and AMT protocol +**/ +EFI_STATUS +BdsAsfInitialization ( + IN VOID + ) +; + +/** + This routine makes necessary Secure Boot & CSM state changes for IDEr boot + + @param[in] None. + + @retval EFI_SUCCESS Changes applied succesfully +**/ +EFI_STATUS +ManageSecureBootState( + IN VOID + ) +; + +/** + This function will create a BootOption from the give device path and + description string. + + @param[in] DevicePath The device path which the option represent + @param[in] Description The description of the boot option + + @retval BDS_COMMON_OPTION - Pointer to created boot option +**/ +BDS_COMMON_OPTION * +BdsCreateBootOption ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Description + ) +; + +/** + Dump all devices of BBS. + + @param[in] LocalBbsTable BBS table entry. +**/ +VOID +PrintBbsTable ( + IN BBS_TABLE *LocalBbsTable + ) +; + +/** + This will return if Media in IDE-R is present. + + @param[in] None. + + @retval TRUE Media is present. + @retval FALSE Media is not present. +**/ +BOOLEAN +BdsCheckIderMedia ( + IN VOID + ) +; + +/** + This function will create a SHELL BootOption to boot. + + @param[in] None. + + @retval EFI_DEVICE_PATH_PROTOCOL Shell Device path for booting. +**/ +EFI_DEVICE_PATH_PROTOCOL * +BdsCreateShellDevicePath ( + VOID + ) +; + +/** + This function will create a BootOption from the give device path and + description string. + + @param[in] DevicePath The device path which the option represent + @param[in] Description The description of the boot option + + @retval BDS_COMMON_OPTION - Pointer to created boot option +**/ +BDS_COMMON_OPTION * +BdsCreateBootOption ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Description + ) +; + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/Acpi1_0.h b/ReferenceCode/ME/SampleCode/Include/Acpi1_0.h new file mode 100644 index 0000000..71c6624 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/Acpi1_0.h @@ -0,0 +1,297 @@ +/** @file + ACPI 1.0b definitions from the ACPI Specification, revision 1.0b + +@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 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. +**/ +#ifndef _ACPI_1_0_H_ +#define _ACPI_1_0_H_ + +// +// Statements that include other files +// +#include "Tiano.h" +#include "Acpi.h" + +// +// Ensure proper structure formats +// +#pragma pack(1) +/// +/// ACPI 1.0b table structures +/// +/// +/// Root System Description Pointer Structure +/// +typedef struct { + UINT64 Signature; + UINT8 Checksum; + UINT8 OemId[6]; + UINT8 Reserved; + UINT32 RsdtAddress; +} EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER; + +/// +/// Root System Description Table +/// No definition needed as it is a common description table header followed by a +/// variable number of UINT32 table pointers. +/// +/// +/// RSDT Revision (as defined in ACPI 1.0b spec.) +/// +#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Fixed ACPI Description Table Structure (FADT) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 FirmwareCtrl; + UINT32 Dsdt; + UINT8 IntModel; + UINT8 Reserved1; + UINT16 SciInt; + UINT32 SmiCmd; + UINT8 AcpiEnable; + UINT8 AcpiDisable; + UINT8 S4BiosReq; + UINT8 Reserved2; + UINT32 Pm1aEvtBlk; + UINT32 Pm1bEvtBlk; + UINT32 Pm1aCntBlk; + UINT32 Pm1bCntBlk; + UINT32 Pm2CntBlk; + UINT32 PmTmrBlk; + UINT32 Gpe0Blk; + UINT32 Gpe1Blk; + UINT8 Pm1EvtLen; + UINT8 Pm1CntLen; + UINT8 Pm2CntLen; + UINT8 PmTmLen; + UINT8 Gpe0BlkLen; + UINT8 Gpe1BlkLen; + UINT8 Gpe1Base; + UINT8 Reserved3; + UINT16 PLvl2Lat; + UINT16 PLvl3Lat; + UINT16 FlushSize; + UINT16 FlushStride; + UINT8 DutyOffset; + UINT8 DutyWidth; + UINT8 DayAlrm; + UINT8 MonAlrm; + UINT8 Century; + UINT8 Reserved4; + UINT8 Reserved5; + UINT8 Reserved6; + UINT32 Flags; +} EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE; + +/// +/// FADT Version (as defined in ACPI 1.0b spec.) +/// +#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x01 + +// +// Fixed ACPI Description Table Fixed Feature Flags +// All other bits are reserved and must be set to 0. +// +#define EFI_ACPI_1_0_WBINVD (1 << 0) +#define EFI_ACPI_1_0_WBINVD_FLUSH (1 << 1) +#define EFI_ACPI_1_0_PROC_C1 (1 << 2) +#define EFI_ACPI_1_0_P_LVL2_UP (1 << 3) +#define EFI_ACPI_1_0_PWR_BUTTON (1 << 4) +#define EFI_ACPI_1_0_SLP_BUTTON (1 << 5) +#define EFI_ACPI_1_0_FIX_RTC (1 << 6) +#define EFI_ACPI_1_0_RTC_S4 (1 << 7) +#define EFI_ACPI_1_0_TMR_VAL_EXT (1 << 8) +#define EFI_ACPI_1_0_DCK_CAP (1 << 9) + +/// +/// Firmware ACPI Control Structure +/// +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT32 HardwareSignature; + UINT32 FirmwareWakingVector; + UINT32 GlobalLock; + UINT32 Flags; + UINT8 Reserved[40]; +} EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; + +/// +/// Firmware Control Structure Feature Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_1_0_S4BIOS_F (1 << 0) + +/// +/// Multiple APIC Description Table header definition. The rest of the table +/// must be defined in a platform specific manner. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 LocalApicAddress; + UINT32 Flags; +} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; + +/// +/// MADT Revision (as defined in ACPI 1.0b spec.) +/// +#define EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Multiple APIC Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_1_0_PCAT_COMPAT (1 << 0) + +// +// Multiple APIC Description Table APIC structure types +// All other values between 0x09 an 0xFF are reserved and +// will be ignored by OSPM. +// +#define EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC 0x00 +#define EFI_ACPI_1_0_IO_APIC 0x01 +#define EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE 0x02 +#define EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 +#define EFI_ACPI_1_0_LOCAL_APIC_NMI 0x04 + +/// +/// APIC Structure Definitions +/// +/// +/// Processor Local APIC Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT8 ApicId; + UINT32 Flags; +} EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE; + +/// +/// Local APIC Flags. All other bits are reserved and must be 0. +/// +#define EFI_ACPI_1_0_LOCAL_APIC_ENABLED (1 << 0) + +/// +/// IO APIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 IoApicId; + UINT8 Reserved; + UINT32 IoApicAddress; + UINT32 SystemVectorBase; +} EFI_ACPI_1_0_IO_APIC_STRUCTURE; + +/// +/// Interrupt Source Override Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 Bus; + UINT8 Source; + UINT32 GlobalSystemInterruptVector; + UINT16 Flags; +} EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; + +/// +/// Non-Maskable Interrupt Source Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT32 GlobalSystemInterruptVector; +} EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; + +/// +/// Local APIC NMI Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT16 Flags; + UINT8 LocalApicInti; +} EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE; + +/// +/// Smart Battery Description Table (SBST) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 WarningEnergyLevel; + UINT32 LowEnergyLevel; + UINT32 CriticalEnergyLevel; +} EFI_ACPI_1_0_SMART_BATTERY_DESCRIPTION_TABLE; + +/// +/// Known table signatures +/// +/// +/// "RSD PTR " Root System Description Pointer +/// +#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352 + +/// +/// "APIC" Multiple APIC Description Table +/// +#define EFI_ACPI_1_0_APIC_SIGNATURE 0x43495041 + +/// +/// "DSDT" Differentiated System Description Table +/// +#define EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344 + +/// +/// "FACS" Firmware ACPI Control Structure +/// +#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146 + +/// +/// "FACP" Fixed ACPI Description Table +/// +#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146 + +/// +/// "PSDT" Persistent System Description Table +/// +#define EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350 + +/// +/// "RSDT" Root System Description Table +/// +#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352 + +/// +/// "SBST" Smart Battery Specification Table +/// +#define EFI_ACPI_1_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253 + +/// +/// "SSDT" Secondary System Description Table +/// +#define EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353 + +#pragma pack() + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/Acpi2_0.h b/ReferenceCode/ME/SampleCode/Include/Acpi2_0.h new file mode 100644 index 0000000..38ffbac --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/Acpi2_0.h @@ -0,0 +1,533 @@ +/** @file + ACPI 2.0 definitions from the ACPI Specification, revision 2.0 + +@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 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. +**/ +#ifndef _ACPI_2_0_H_ +#define _ACPI_2_0_H_ + +// +// Statements that include other files +// +#include "Tiano.h" +#include "Acpi.h" + +// +// Ensure proper structure formats +// +#pragma pack(1) +/// +/// ACPI Specification Revision +/// +#define EFI_ACPI_2_0_REVISION 0x02 + +// +// BUGBUG: OEM values need to be moved somewhere else, probably read from data hub +// and produced by a platform specific driver. +// +/// +/// ACPI OEM ID +/// +#define EFI_ACPI_2_0_OEM_ID "INTEL " +#define EFI_ACPI_2_0_OEM_TABLE_ID 0x5034303738543245 /// "E2T8704P" +/// +/// ACPI OEM Revision +/// +#define EFI_ACPI_2_0_OEM_REVISION 0x00000002 + +/// +/// ACPI table creator ID +/// +#define EFI_ACPI_2_0_CREATOR_ID 0x5446534D /// TBD "MSFT" +/// +/// ACPI table creator revision +/// +#define EFI_ACPI_2_0_CREATOR_REVISION 0x01000013 /// TBD +/// +/// ACPI 2.0 Generic Address Space definition +/// +typedef struct { + UINT8 AddressSpaceId; + UINT8 RegisterBitWidth; + UINT8 RegisterBitOffset; + UINT8 Reserved; + UINT64 Address; +} EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE; + +/// +/// Generic Address Space Address IDs +/// +#define EFI_ACPI_2_0_SYSTEM_MEMORY 0 +#define EFI_ACPI_2_0_SYSTEM_IO 1 +#define EFI_ACPI_2_0_PCI_CONFIGURATION_SPACE 2 +#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER 3 +#define EFI_ACPI_2_0_SMBUS 4 +#define EFI_ACPI_2_0_FUNCTIONAL_FIXED_HARDWARE 0x7F + +/// +/// ACPI 2.0 table structures +/// +/// +/// Root System Description Pointer Structure +/// +typedef struct { + UINT64 Signature; + UINT8 Checksum; + UINT8 OemId[6]; + UINT8 Revision; + UINT32 RsdtAddress; + UINT32 Length; + UINT64 XsdtAddress; + UINT8 ExtendedChecksum; + UINT8 Reserved[3]; +} EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER; + +/// +/// RSD_PTR Revision (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 + +/// +/// Common table header, this prefaces all ACPI tables, including FACS, but +/// excluding the RSD PTR structure +/// +typedef struct { + UINT32 Signature; + UINT32 Length; +} EFI_ACPI_2_0_COMMON_HEADER; + +/// +/// Root System Description Table +/// No definition needed as it is a common description table header followed by a +/// variable number of UINT32 table pointers. +/// +/// +/// RSDT Revision (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Extended System Description Table +/// No definition needed as it is a common description table header followed by a +/// variable number of UINT64 table pointers. +/// +/// +/// XSDT Revision (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Fixed ACPI Description Table Structure (FADT) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 FirmwareCtrl; + UINT32 Dsdt; + UINT8 Reserved0; + UINT8 PreferredPmProfile; + UINT16 SciInt; + UINT32 SmiCmd; + UINT8 AcpiEnable; + UINT8 AcpiDisable; + UINT8 S4BiosReq; + UINT8 PstateCnt; + UINT32 Pm1aEvtBlk; + UINT32 Pm1bEvtBlk; + UINT32 Pm1aCntBlk; + UINT32 Pm1bCntBlk; + UINT32 Pm2CntBlk; + UINT32 PmTmrBlk; + UINT32 Gpe0Blk; + UINT32 Gpe1Blk; + UINT8 Pm1EvtLen; + UINT8 Pm1CntLen; + UINT8 Pm2CntLen; + UINT8 PmTmrLen; + UINT8 Gpe0BlkLen; + UINT8 Gpe1BlkLen; + UINT8 Gpe1Base; + UINT8 CstCnt; + UINT16 PLvl2Lat; + UINT16 PLvl3Lat; + UINT16 FlushSize; + UINT16 FlushStride; + UINT8 DutyOffset; + UINT8 DutyWidth; + UINT8 DayAlrm; + UINT8 MonAlrm; + UINT8 Century; + UINT16 IaPcBootArch; + UINT8 Reserved1; + UINT32 Flags; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResetReg; + UINT8 ResetValue; + UINT8 Reserved2[3]; + UINT64 XFirmwareCtrl; + UINT64 XDsdt; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; +} EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE; + +/// +/// FADT Version (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x03 + +/// +/// Fixed ACPI Description Table Boot Architecture Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_2_0_LEGACY_DEVICES (1 << 0) +#define EFI_ACPI_2_0_8042 (1 << 1) + +/// +/// Fixed ACPI Description Table Fixed Feature Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_2_0_WBINVD (1 << 0) +#define EFI_ACPI_2_0_WBINVD_FLUSH (1 << 1) +#define EFI_ACPI_2_0_PROC_C1 (1 << 2) +#define EFI_ACPI_2_0_P_LVL2_UP (1 << 3) +#define EFI_ACPI_2_0_PWR_BUTTON (1 << 4) +#define EFI_ACPI_2_0_SLP_BUTTON (1 << 5) +#define EFI_ACPI_2_0_FIX_RTC (1 << 6) +#define EFI_ACPI_2_0_RTC_S4 (1 << 7) +#define EFI_ACPI_2_0_TMR_VAL_EXT (1 << 8) +#define EFI_ACPI_2_0_DCK_CAP (1 << 9) +#define EFI_ACPI_2_0_RESET_REG_SUP (1 << 10) +#define EFI_ACPI_2_0_SEALED_CASE (1 << 11) +#define EFI_ACPI_2_0_HEADLESS (1 << 12) +#define EFI_ACPI_2_0_CPU_SW_SLP (1 << 13) + +/// +/// Firmware ACPI Control Structure +/// +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT32 HardwareSignature; + UINT32 FirmwareWakingVector; + UINT32 GlobalLock; + UINT32 Flags; + UINT64 XFirmwareWakingVector; + UINT8 Version; + UINT8 Reserved[31]; +} EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; + +/// +/// FACS Version (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01 + +/// +/// Firmware Control Structure Feature Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_2_0_S4BIOS_F (1 << 0) + +/// +/// Multiple APIC Description Table header definition. The rest of the table +/// must be defined in a platform specific manner. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 LocalApicAddress; + UINT32 Flags; +} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; + +/// +/// MADT Revision (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Multiple APIC Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_2_0_PCAT_COMPAT (1 << 0) + +// +// Multiple APIC Description Table APIC structure types +// All other values between 0x09 an 0xFF are reserved and +// will be ignored by OSPM. +// +#define EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC 0x00 +#define EFI_ACPI_2_0_IO_APIC 0x01 +#define EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE 0x02 +#define EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 +#define EFI_ACPI_2_0_LOCAL_APIC_NMI 0x04 +#define EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 +#define EFI_ACPI_2_0_IO_SAPIC 0x06 +#define EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC 0x07 +#define EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES 0x08 + +/// +/// APIC Structure Definitions +/// +/// +/// Processor Local APIC Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT8 ApicId; + UINT32 Flags; +} EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE; + +/// +/// Local APIC Flags. All other bits are reserved and must be 0. +/// +#define EFI_ACPI_2_0_LOCAL_APIC_ENABLED (1 << 0) + +/// +/// IO APIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 IoApicId; + UINT8 Reserved; + UINT32 IoApicAddress; + UINT32 GlobalSystemInterruptBase; +} EFI_ACPI_2_0_IO_APIC_STRUCTURE; + +/// +/// Interrupt Source Override Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 Bus; + UINT8 Source; + UINT32 GlobalSystemInterrupt; + UINT16 Flags; +} EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; + +/// +/// Non-Maskable Interrupt Source Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT32 GlobalSystemInterrupt; +} EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; + +/// +/// Local APIC NMI Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT16 Flags; + UINT8 LocalApicLint; +} EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE; + +/// +/// Local APIC Address Override Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Reserved; + UINT64 LocalApicAddress; +} EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; + +/// +/// IO SAPIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 IoApicId; + UINT8 Reserved; + UINT32 GlobalSystemInterruptBase; + UINT64 IoSapicAddress; +} EFI_ACPI_2_0_IO_SAPIC_STRUCTURE; + +/// +/// Local SAPIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT8 LocalSapicId; + UINT8 LocalSapicEid; + UINT8 Reserved[3]; + UINT32 Flags; +} EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; + +/// +/// Platform Interrupt Sources Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT8 InterruptType; + UINT8 ProcessorId; + UINT8 ProcessorEid; + UINT8 IoSapicVector; + UINT32 GlobalSystemInterrupt; + UINT32 Reserved; +} EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; + +/// +/// Smart Battery Description Table (SBST) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 WarningEnergyLevel; + UINT32 LowEnergyLevel; + UINT32 CriticalEnergyLevel; +} EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE; + +/// +/// SBST Version (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Embedded Controller Boot Resources Table (ECDT) +/// The table is followed by a null terminated ASCII string that contains +/// a fully qualified reference to the name space object. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcControl; + EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcData; + UINT32 Uid; + UINT8 GpeBit; +} EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; + +/// +/// ECDT Version (as defined in ACPI 2.0 spec.) +/// +#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 + +/// +/// Known table signatures +/// +/// +/// "RSD PTR " Root System Description Pointer +/// +#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352 + +/// +/// "SPIC" Multiple SAPIC Description Table +/// +/// BUGBUG: Don't know where this came from except SR870BN4 uses it. +/// #define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495053 +/// +#define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041 + +/// +/// "BOOT" MS Simple Boot Spec +/// +#define EFI_ACPI_2_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE 0x544F4F42 + +/// +/// "DBGP" MS Bebug Port Spec +/// +#define EFI_ACPI_2_0_DEBUG_PORT_TABLE_SIGNATURE 0x50474244 + +/// +/// "DSDT" Differentiated System Description Table +/// +#define EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344 + +/// +/// "ECDT" Embedded Controller Boot Resources Table +/// +#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE 0x54444345 + +/// +/// "ETDT" Event Timer Description Table +/// +#define EFI_ACPI_2_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE 0x54445445 + +/// +/// "FACS" Firmware ACPI Control Structure +/// +#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146 + +/// +/// "FACP" Fixed ACPI Description Table +/// +#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146 + +/// +/// "APIC" Multiple APIC Description Table +/// +#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041 + +/// +/// "PSDT" Persistent System Description Table +/// +#define EFI_ACPI_2_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350 + +/// +/// "RSDT" Root System Description Table +/// +#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352 + +/// +/// "SBST" Smart Battery Specification Table +/// +#define EFI_ACPI_2_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253 + +/// +/// "SLIT" System Locality Information Table +/// +#define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE 0x54494C53 + +/// +/// "SPCR" Serial Port Concole Redirection Table +/// +#define EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE 0x52435053 + +/// +/// "SRAT" Static Resource Affinity Table +/// +#define EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE 0x54415253 + +/// +/// "SSDT" Secondary System Description Table +/// +#define EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353 + +/// +/// "SPMI" Server Platform Management Interface Table +/// +#define EFI_ACPI_2_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_SIGNATURE 0x494D5053 + +/// +/// "XSDT" Extended System Description Table +/// +#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445358 + +#pragma pack() + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/Acpi3_0.h b/ReferenceCode/ME/SampleCode/Include/Acpi3_0.h new file mode 100644 index 0000000..3fc3cb6 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/Acpi3_0.h @@ -0,0 +1,682 @@ +/** @file + ACPI 3.0 definitions from the ACPI Specification Revision 3.0 September 2, 2004 + +@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 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. +**/ +#ifndef _ACPI_3_0_H_ +#define _ACPI_3_0_H_ + +// +// Statements that include other files +// +#include "Tiano.h" +#include "Acpi.h" + +// +// Ensure proper structure formats +// +#pragma pack(1) +/// +/// ACPI Specification Revision +/// +#define EFI_ACPI_3_0_REVISION 0x03 /// BUGBUG: Not in spec yet. +// +// BUGBUG: OEM values need to be moved somewhere else, probably read from data hub +// and produced by a platform specific driver. +// + +/// +/// ACPI 3.0 Generic Address Space definition +/// +typedef struct { + UINT8 AddressSpaceId; + UINT8 RegisterBitWidth; + UINT8 RegisterBitOffset; + UINT8 AccessSize; + UINT64 Address; +} EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE; + +/// +/// Generic Address Space Address IDs +/// +#define EFI_ACPI_3_0_SYSTEM_MEMORY 0 +#define EFI_ACPI_3_0_SYSTEM_IO 1 +#define EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE 2 +#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER 3 +#define EFI_ACPI_3_0_SMBUS 4 +#define EFI_ACPI_3_0_FUNCTIONAL_FIXED_HARDWARE 0x7F + +/// +/// Generic Address Space Access Sizes +/// +#define EFI_ACPI_3_0_UNDEFINED 0 +#define EFI_ACPI_3_0_BYTE 1 +#define EFI_ACPI_3_0_WORD 2 +#define EFI_ACPI_3_0_DWORD 3 +#define EFI_ACPI_3_0_QWORD 4 + +/// +/// ACPI 3.0 table structures +/// +/// +/// Root System Description Pointer Structure +/// +typedef struct { + UINT64 Signature; + UINT8 Checksum; + UINT8 OemId[6]; + UINT8 Revision; + UINT32 RsdtAddress; + UINT32 Length; + UINT64 XsdtAddress; + UINT8 ExtendedChecksum; + UINT8 Reserved[3]; +} EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER; + +/// +/// RSD_PTR Revision (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 /// ACPISpec30 (Revision 3.0 September 2, 2004) says current value is 2 +/// +/// Common table header, this prefaces all ACPI tables, including FACS, but +/// excluding the RSD PTR structure +/// +typedef struct { + UINT32 Signature; + UINT32 Length; +} EFI_ACPI_3_0_COMMON_HEADER; + +/// +/// Root System Description Table +/// No definition needed as it is a common description table header followed by a +/// variable number of UINT32 table pointers. +/// +/// +/// RSDT Revision (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Extended System Description Table +/// No definition needed as it is a common description table header followed by a +/// variable number of UINT64 table pointers. +/// +/// +/// XSDT Revision (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Fixed ACPI Description Table Structure (FADT) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 FirmwareCtrl; + UINT32 Dsdt; + UINT8 Reserved0; + UINT8 PreferredPmProfile; + UINT16 SciInt; + UINT32 SmiCmd; + UINT8 AcpiEnable; + UINT8 AcpiDisable; + UINT8 S4BiosReq; + UINT8 PstateCnt; + UINT32 Pm1aEvtBlk; + UINT32 Pm1bEvtBlk; + UINT32 Pm1aCntBlk; + UINT32 Pm1bCntBlk; + UINT32 Pm2CntBlk; + UINT32 PmTmrBlk; + UINT32 Gpe0Blk; + UINT32 Gpe1Blk; + UINT8 Pm1EvtLen; + UINT8 Pm1CntLen; + UINT8 Pm2CntLen; + UINT8 PmTmrLen; + UINT8 Gpe0BlkLen; + UINT8 Gpe1BlkLen; + UINT8 Gpe1Base; + UINT8 CstCnt; + UINT16 PLvl2Lat; + UINT16 PLvl3Lat; + UINT16 FlushSize; + UINT16 FlushStride; + UINT8 DutyOffset; + UINT8 DutyWidth; + UINT8 DayAlrm; + UINT8 MonAlrm; + UINT8 Century; + UINT16 IaPcBootArch; + UINT8 Reserved1; + UINT32 Flags; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ResetReg; + UINT8 ResetValue; + UINT8 Reserved2[3]; + UINT64 XFirmwareCtrl; + UINT64 XDsdt; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; +} EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE; + +/// +/// FADT Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x04 + +// +// Fixed ACPI Description Table Preferred Power Management Profile +// +#define EFI_ACPI_3_0_PM_PROFILE_UNSPECIFIED 0 +#define EFI_ACPI_3_0_PM_PROFILE_DESKTOP 1 +#define EFI_ACPI_3_0_PM_PROFILE_MOBILE 2 +#define EFI_ACPI_3_0_PM_PROFILE_WORKSTATION 3 +#define EFI_ACPI_3_0_PM_PROFILE_ENTERPRISE_SERVER 4 +#define EFI_ACPI_3_0_PM_PROFILE_SOHO_SERVER 5 +#define EFI_ACPI_3_0_PM_PROFILE_APPLIANCE_PC 6 +#define EFI_ACPI_3_0_PM_PROFILE_PERFORMANCE_SERVER 7 + +// +// Fixed ACPI Description Table Boot Architecture Flags +// All other bits are reserved and must be set to 0. +// +#define EFI_ACPI_3_0_LEGACY_DEVICES (1 << 0) +#define EFI_ACPI_3_0_8042 (1 << 1) +#define EFI_ACPI_3_0_VGA_NOT_PRESENT (1 << 2) + +// +// Fixed ACPI Description Table Fixed Feature Flags +// All other bits are reserved and must be set to 0. +// +#define EFI_ACPI_3_0_WBINVD (1 << 0) +#define EFI_ACPI_3_0_WBINVD_FLUSH (1 << 1) +#define EFI_ACPI_3_0_PROC_C1 (1 << 2) +#define EFI_ACPI_3_0_P_LVL2_UP (1 << 3) +#define EFI_ACPI_3_0_PWR_BUTTON (1 << 4) +#define EFI_ACPI_3_0_SLP_BUTTON (1 << 5) +#define EFI_ACPI_3_0_FIX_RTC (1 << 6) +#define EFI_ACPI_3_0_RTC_S4 (1 << 7) +#define EFI_ACPI_3_0_TMR_VAL_EXT (1 << 8) +#define EFI_ACPI_3_0_DCK_CAP (1 << 9) +#define EFI_ACPI_3_0_RESET_REG_SUP (1 << 10) +#define EFI_ACPI_3_0_SEALED_CASE (1 << 11) +#define EFI_ACPI_3_0_HEADLESS (1 << 12) +#define EFI_ACPI_3_0_CPU_SW_SLP (1 << 13) +#define EFI_ACPI_3_0_PCI_EXP_WAK (1 << 14) +#define EFI_ACPI_3_0_USE_PLATFORM_CLOCK (1 << 15) +#define EFI_ACPI_3_0_S4_RTC_STS_VALID (1 << 16) +#define EFI_ACPI_3_0_REMOTE_POWER_ON_CAPABLE (1 << 17) +#define EFI_ACPI_3_0_FORCE_APIC_CLUSTER_MODEL (1 << 18) +#define EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE (1 << 19) + +/// +/// Firmware ACPI Control Structure +/// +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT32 HardwareSignature; + UINT32 FirmwareWakingVector; + UINT32 GlobalLock; + UINT32 Flags; + UINT64 XFirmwareWakingVector; + UINT8 Version; + UINT8 Reserved[31]; +} EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; + +/// +/// FACS Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01 + +/// +/// Firmware Control Structure Feature Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_3_0_S4BIOS_F (1 << 0) + +// +// Differentiated System Description Table, +// Secondary System Description Table +// and Persistent System Description Table, +// no definition needed as they are common description table header followed by a +// definition block. +// +#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 +#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 + +/// +/// Multiple APIC Description Table header definition. The rest of the table +/// must be defined in a platform specific manner. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 LocalApicAddress; + UINT32 Flags; +} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; + +/// +/// MADT Revision (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x02 + +/// +/// Multiple APIC Flags +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_3_0_PCAT_COMPAT (1 << 0) + +// +// Multiple APIC Description Table APIC structure types +// All other values between 0x09 an 0xFF are reserved and +// will be ignored by OSPM. +// +#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC 0x00 +#define EFI_ACPI_3_0_IO_APIC 0x01 +#define EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE 0x02 +#define EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 +#define EFI_ACPI_3_0_LOCAL_APIC_NMI 0x04 +#define EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 +#define EFI_ACPI_3_0_IO_SAPIC 0x06 +#define EFI_ACPI_3_0_LOCAL_SAPIC 0x07 +#define EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES 0x08 + +/// +/// APIC Structure Definitions +/// +/// +/// Processor Local APIC Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT8 ApicId; + UINT32 Flags; +} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE; + +/// +/// Local APIC Flags. All other bits are reserved and must be 0. +/// +#define EFI_ACPI_3_0_LOCAL_APIC_ENABLED (1 << 0) + +/// +/// IO APIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 IoApicId; + UINT8 Reserved; + UINT32 IoApicAddress; + UINT32 GlobalSystemInterruptBase; +} EFI_ACPI_3_0_IO_APIC_STRUCTURE; + +/// +/// Interrupt Source Override Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 Bus; + UINT8 Source; + UINT32 GlobalSystemInterrupt; + UINT16 Flags; +} EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; + +/// +/// Platform Interrupt Sources Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT8 InterruptType; + UINT8 ProcessorId; + UINT8 ProcessorEid; + UINT8 IoSapicVector; + UINT32 GlobalSystemInterrupt; + UINT32 PlatformInterruptSourceFlags; + UINT8 CpeiProcessorOverride; + UINT8 Reserved[31]; +} EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE; + +/// +/// MPS INTI flags. +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_3_0_POLARITY (3 << 0) +#define EFI_ACPI_3_0_TRIGGER_MODE (3 << 2) + +/// +/// Non-Maskable Interrupt Source Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT32 GlobalSystemInterrupt; +} EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; + +/// +/// Local APIC NMI Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT16 Flags; + UINT8 LocalApicLint; +} EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE; + +/// +/// Local APIC Address Override Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Reserved; + UINT64 LocalApicAddress; +} EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; + +/// +/// IO SAPIC Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 IoApicId; + UINT8 Reserved; + UINT32 GlobalSystemInterruptBase; + UINT64 IoSapicAddress; +} EFI_ACPI_3_0_IO_SAPIC_STRUCTURE; + +/// +/// Local SAPIC Structure +/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 AcpiProcessorId; + UINT8 LocalSapicId; + UINT8 LocalSapicEid; + UINT8 Reserved[3]; + UINT32 Flags; + UINT32 ACPIProcessorUIDValue; +} EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; + +/// +/// Platform Interrupt Sources Structure +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT16 Flags; + UINT8 InterruptType; + UINT8 ProcessorId; + UINT8 ProcessorEid; + UINT8 IoSapicVector; + UINT32 GlobalSystemInterrupt; + UINT32 PlatformInterruptSourceFlags; +} EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; + +/// +/// Platform Interrupt Source Flags. +/// All other bits are reserved and must be set to 0. +/// +#define EFI_ACPI_3_0_CPEI_PROCESSOR_OVERRIDE (1 << 0) + +/// +/// Smart Battery Description Table (SBST) +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 WarningEnergyLevel; + UINT32 LowEnergyLevel; + UINT32 CriticalEnergyLevel; +} EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE; + +/// +/// SBST Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 + +/// +/// Embedded Controller Boot Resources Table (ECDT) +/// The table is followed by a null terminated ASCII string that contains +/// a fully qualified reference to the name space object. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcControl; + EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcData; + UINT32 Uid; + UINT8 GpeBit; +} EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; + +/// +/// ECDT Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 + +/// +/// System Resource Affinity Table (SRAT. The rest of the table +/// must be defined in a platform specific manner. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 Reserved1; /// Must be set to 1 + UINT64 Reserved2; +} EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; + +/// +/// SRAT Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x02 + +/// +/// SRAT structure types. +/// All other values between 0x02 an 0xFF are reserved and +/// will be ignored by OSPM. +/// +#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 +#define EFI_ACPI_3_0_MEMORY_AFFINITY 0x01 + +/// +/// Processor Local APIC/SAPIC Affinity Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 ProximityDomain7To0; + UINT8 ApicId; + UINT32 Flags; + UINT8 LocalSapicEid; + UINT8 ProximityDomain31To8[3]; + UINT8 Reserved[4]; +} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; + +/// +/// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. +/// +#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) + +/// +/// Memory Affinity Structure Definition +/// +typedef struct { + UINT8 Type; + UINT8 Length; + UINT32 ProximityDomain; + UINT16 Reserved1; + UINT32 AddressBaseLow; + UINT32 AddressBaseHigh; + UINT32 LengthLow; + UINT32 LengthHigh; + UINT32 Reserved2; + UINT32 Flags; + UINT64 Reserved3; +} EFI_ACPI_3_0_MEMORY_AFFINITY_STRUCTURE; + +/// +/// Memory Flags. All other bits are reserved and must be 0. +/// +#define EFI_ACPI_3_0_MEMORY_ENABLED (1 << 0) +#define EFI_ACPI_3_0_MEMORY_HOT_PLUGGABLE (1 << 1) +#define EFI_ACPI_3_0_MEMORY_NONVOLATILE (1 << 2) + +/// +/// System Locality Distance Information Table (SLIT). +/// The rest of the table is a matrix. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT64 NumberOfSystemLocalities; +} EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; + +/// +/// SLIT Version (as defined in ACPI 3.0 spec.) +/// +#define EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 + +/// +/// Known table signatures +/// +/// +/// "RSD PTR " Root System Description Pointer +/// +#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352 + +/// +/// "APIC" Multiple APIC Description Table +/// +#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041 + +/// +/// "DSDT" Differentiated System Description Table +/// +#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344 + +/// +/// "ECDT" Embedded Controller Boot Resources Table +/// +#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE 0x54444345 + +/// +/// "FACP" Fixed ACPI Description Table +/// +#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146 + +/// +/// "FACS" Firmware ACPI Control Structure +/// +#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146 + +/// +/// "PSDT" Persistent System Description Table +/// +#define EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350 + +/// +/// "RSDT" Root System Description Table +/// +#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352 + +/// +/// "SBST" Smart Battery Specification Table +/// +#define EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253 + +/// +/// "SLIT" System Locality Information Table +/// +#define EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE 0x54494C53 + +/// +/// "SRAT" System Resource Affinity Table +/// +#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE 0x54415253 + +/// +/// "SSDT" Secondary System Description Table +/// +#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353 + +/// +/// "XSDT" Extended System Description Table +/// +#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445358 + +/// +/// "BOOT" MS Simple Boot Spec +/// +#define EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE 0x544F4F42 + +/// +/// "CPEP" Corrected Platform Error Polling Table +/// See +/// +#define EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE 0x50455043 + +/// +/// "DBGP" MS Debug Port Spec +/// +#define EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE 0x50474244 + +/// +/// "ETDT" Event Timer Description Table +/// +#define EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE 0x54445445 + +/// +/// "HPET" IA-PC High Precision Event Timer Table +/// +#define EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE 0x54455048 + +/// +/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table +/// +#define EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE 0x4746434D + +/// +/// "SPCR" Serial Port Concole Redirection Table +/// +#define EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE 0x52435053 + +/// +/// "SPMI" Server Platform Management Interface Table +/// +#define EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE 0x494D5053 + +/// +/// "TCPA" Trusted Computing Platform Alliance Capabilities Table +/// +#define EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE 0x41504354 + +/// +/// "WDRT" Watchdog Resource Table +/// +#define EFI_ACPI_3_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE 0x41504354 0x54524457 + +#pragma pack() + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/AlertStandardFormatTable.h b/ReferenceCode/ME/SampleCode/Include/AlertStandardFormatTable.h new file mode 100644 index 0000000..672a764 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/AlertStandardFormatTable.h @@ -0,0 +1,119 @@ +/** @file + ACPI Alert Standard Format Description Table ASF! as described + in the ASF2.0 Specification + +@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 +**/ +#ifndef _ALERT_STANDARD_FORMAT_TABLE_H +#define _ALERT_STANDARD_FORMAT_TABLE_H + +#include "Acpi2_0.h" + +// +// Ensure proper structure formats +// +#pragma pack(1) +/// +/// Information Record header that appears at the beginning of each record +/// +typedef struct { + UINT8 Type; + UINT8 Reserved; + UINT16 RecordLength; +} EFI_ACPI_ASF_RECORD_HEADER; + +/// +/// This structure contains information that identifies the system's type +/// and configuration +/// +typedef struct { + EFI_ACPI_ASF_RECORD_HEADER RecordHeader; + UINT8 MinWatchDogResetValue; + UINT8 MinPollingInterval; + UINT16 SystemID; + UINT32 IANAManufactureID; + UINT8 FeatureFlags; + UINT8 Reserved[3]; +} EFI_ACPI_ASF_INFO; + +/// +/// Alert sensors definition +/// +#define ASF_ALRT_SENSOR_ARRAY_LENGTH 36 + +typedef struct { + EFI_ACPI_ASF_RECORD_HEADER RecordHeader; + UINT8 AssertionEventBitMask; + UINT8 DeassertionEventBitMask; + UINT8 NumberOfAlerts; + UINT8 ArrayElementLength; + UINT8 DeviceArray[ASF_ALRT_SENSOR_ARRAY_LENGTH]; +} EFI_ACPI_ASF_ALRT; + +/// +/// Alert Remote Control System Actions +/// +#define ASF_RCTL_DEVICES_ARRAY_LENGTH 16 +typedef struct { + EFI_ACPI_ASF_RECORD_HEADER RecordHeader; + UINT8 NumberOfControls; + UINT8 ArrayElementLength; + UINT16 RctlReserved; + UINT8 ControlArray[ASF_RCTL_DEVICES_ARRAY_LENGTH]; +} EFI_ACPI_ASF_RCTL; + +/// +/// Remote Control Capabilities +/// +typedef struct { + EFI_ACPI_ASF_RECORD_HEADER RecordHeader; + UINT8 RemoteControlCapabilities[7]; + UINT8 RMCPCompletionCode; + UINT32 RMCPIANA; + UINT8 RMCPSpecialCommand; + UINT8 RMCPSpecialCommandParameter[2]; + UINT8 RMCPBootOptions[2]; + UINT8 RMCPOEMParameters[2]; +} EFI_ACPI_ASF_RMCP; + +/// +/// SMBus Devices with fixed addresses +/// +#define ASF_ADDR_DEVICE_ARRAY_LENGTH 11 +typedef struct { + EFI_ACPI_ASF_RECORD_HEADER RecordHeader; + UINT8 SEEPROMAddress; + UINT8 NumberOfDevices; + UINT8 FixedSmbusAddresses[ASF_ADDR_DEVICE_ARRAY_LENGTH]; +} EFI_ACPI_ASF_ADDR; + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + EFI_ACPI_ASF_INFO AsfInfo; + EFI_ACPI_ASF_ALRT AsfAlert; + EFI_ACPI_ASF_RCTL AsfRctl; + EFI_ACPI_ASF_RMCP AsfRmcp; + EFI_ACPI_ASF_ADDR AsfAddr; +} EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE; + +/// +/// "ASF!" ASF Description Table Signature +/// +#define EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE 0x21465341 + +#pragma pack() + +#endif // _ALERT_STANDARD_FORMAT_TABLE_H diff --git a/ReferenceCode/ME/SampleCode/Include/AslUpdateLib.h b/ReferenceCode/ME/SampleCode/Include/AslUpdateLib.h new file mode 100644 index 0000000..dcee41d --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/AslUpdateLib.h @@ -0,0 +1,167 @@ +/** @file + ASL dynamic update library definitions. + This library provides dymanic update to various ASL structures. + There may be different libraries for different environments (PEI, BS, RT, SMM). + Make sure you meet the requirements for the library (protocol dependencies, use + restrictions, etc). + +@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 +**/ +#ifndef _ASL_UPDATE_LIB_H_ +#define _ASL_UPDATE_LIB_H_ + +// +// Include files +// +#include "Acpi.h" +#include "Acpi3_0.h" + +#include EFI_PROTOCOL_DEPENDENCY (AcpiSupport) +#include EFI_PROTOCOL_DEPENDENCY (AcpiTable) + +// +// AML parsing definitions +// +#define AML_NAME_OP 0x08 +#define AML_SCOPE_OP 0x10 +#define AML_PACKAGE_OP 0x12 +#define AML_METHOD_OP 0x14 +#define AML_OPREGION_OP 0x80 +#define AML_DEVICE_OP 0x82 +#define AML_PROCESSOR_OP 0x83 + +// +// Magic number definition for values to be updated +// +#define UINT16_BIT_MAGIC_NUMBER 0xFFFF +#define UINT32_BIT_MAGIC_NUMBER 0xFFFFFFFF + +/// +/// ASL PSS package structure layout +/// +#pragma pack(1) +typedef struct { + UINT8 NameOp; ///< 12h ;First opcode is a NameOp. + UINT8 PackageLead; ///< 20h ;First opcode is a NameOp. + UINT8 NumEntries; ///< 06h ;First opcode is a NameOp. + UINT8 DwordPrefix1; ///< 0Ch + UINT32 CoreFrequency; ///< 00h + UINT8 DwordPrefix2; ///< 0Ch + UINT32 Power; ///< 00h + UINT8 DwordPrefix3; ///< 0Ch + UINT32 TransLatency; ///< 00h + UINT8 DwordPrefix4; ///< 0Ch + UINT32 BMLatency; ///< 00h + UINT8 DwordPrefix5; ///< 0Ch + UINT32 Control; ///< 00h + UINT8 DwordPrefix6; ///< 0Ch + UINT32 Status; ///< 00h +} PSS_PACKAGE_LAYOUT; +#pragma pack() + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ) +; + +/** + This procedure will update two kinds of asl code. + 1: Operating Region base address and length. + 2: Resource Consumption structures in device LDRC. + + @param[in] AslSignature The signature of Operation Region that we want to update. + @param[in] BaseAddress Base address of IO trap. + @param[in] Length Length of IO address. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +UpdateAslCode ( + IN UINT32 AslSignature, + IN UINT16 BaseAddress, + IN UINT8 Length + ) +; + +/** + This function uses the ACPI support protocol to locate an ACPI table. + It is really only useful for finding tables that only have a single instance, + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc. + + @param[in] Signature Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version The version of the table desired + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableBySignature ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +; + +/** + This function uses the ACPI support protocol to locate an ACPI SSDT table. + + @param[in] TableId Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] TableIdSize Length of the TableId to match. Table ID are 8 bytes long, this function + will consider it a match if the first TableIdSize bytes match + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version See AcpiSupport protocol, GetAcpiTable function for use + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableByOemTableId ( + IN UINT8 *TableId, + IN UINT8 TableIdSize, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +; + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + @param[in] ChecksumOffset Offset to place the checksum result in + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AcpiChecksum ( + IN VOID *Buffer, + IN UINTN Size, + IN UINTN ChecksumOffset + ) +; +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/Guid/MemoryOverwriteControl/MemoryOverwriteControl.h b/ReferenceCode/ME/SampleCode/Include/Guid/MemoryOverwriteControl/MemoryOverwriteControl.h new file mode 100644 index 0000000..a792842 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/Guid/MemoryOverwriteControl/MemoryOverwriteControl.h @@ -0,0 +1,81 @@ +/** @file + GUID used for MemoryOverwriteRequestControl UEFI variable defined in + TCG Platform Reset Attack Mitigation Specification 1.00. + See http://trustedcomputinggroup.org for the latest specification + + The purpose of the MemoryOverwriteRequestControl UEFI variable is to give users (e.g., OS, loader) the ability to + indicate to the platform that secrets are present in memory and that the platform firmware must clear memory upon + a restart. The OS loader should not create the variable. Rather, the firmware is required to create it. + +@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 +**/ + +#ifndef _MEMORY_OVERWRITE_CONTROL_DATA_GUID_H_ +#define _MEMORY_OVERWRITE_CONTROL_DATA_GUID_H_ + +#define MEMORY_ONLY_RESET_CONTROL_GUID \ + { \ + 0xe20939be, 0x32d4, 0x41be, {0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29} \ + } + +/// +/// Variable name is "MemoryOverwriteRequestControl" and it is a 1 byte unsigned value. +/// The attributes should be: +/// EFI_VARIABLE_NON_VOLATILE | +/// EFI_VARIABLE_BOOTSERVICE_ACCESS | +/// EFI_VARIABLE_RUNTIME_ACCESS +/// +#define MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME L"MemoryOverwriteRequestControl" + +/// +/// 0 = Firmware MUST clear the MOR bi +/// 1 = Firmware MUST set the MOR bit +/// +#define MOR_CLEAR_MEMORY_BIT_MASK 0x01 + +/// +/// 0 = Firmware MAY autodetect a clean shutdown of the Static RTM OS. +/// 1 = Firmware MUST NOT autodetect a clean shutdown of the Static RTM OS. +/// +#define MOR_DISABLEAUTODETECT_BIT_MASK 0x10 + +/// +/// MOR field bit offset +/// +#define MOR_CLEAR_MEMORY_BIT_OFFSET 0 +#define MOR_DISABLEAUTODETECT_BIT_OFFSET 4 + +/** + Return the ClearMemory bit value 0 or 1. + + @param mor 1 byte value that contains ClearMemory and DisableAutoDetect bit. + + @return ClearMemory bit value +**/ +#define MOR_CLEAR_MEMORY_VALUE(mor) (((UINT8)(mor) & MOR_CLEAR_MEMORY_BIT_MASK) >> MOR_CLEAR_MEMORY_BIT_OFFSET) + +/** + Return the DisableAutoDetect bit value 0 or 1. + + @param mor 1 byte value that contains ClearMemory and DisableAutoDetect bit. + + @return DisableAutoDetect bit value +**/ +#define MOR_DISABLE_AUTO_DETECT_VALUE(mor) (((UINT8)(mor) & MOR_DISABLEAUTODETECT_BIT_MASK) >> MOR_DISABLEAUTODETECT_BIT_OFFSET) + +extern EFI_GUID gEfiMemoryOverwriteControlDataGuid; + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/Guid/TrEEPhysicalPresenceData/TrEEPhysicalPresenceData.h b/ReferenceCode/ME/SampleCode/Include/Guid/TrEEPhysicalPresenceData/TrEEPhysicalPresenceData.h new file mode 100644 index 0000000..215e8f9 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/Guid/TrEEPhysicalPresenceData/TrEEPhysicalPresenceData.h @@ -0,0 +1,62 @@ +/** @file + Define the variable data structures used for TrEE physical presence. + The TPM2 request from firmware or OS is saved to variable. And it is + cleared after it is processed in the next boot cycle. The TPM2 response + is saved to variable. + +@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 +**/ + +#ifndef __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__ +#define __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__ + +#define EFI_TREE_PHYSICAL_PRESENCE_DATA_GUID \ + { \ + 0xf24643c2, 0xc622, 0x494e, { 0x8a, 0xd, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b }\ + } + +#define TREE_PHYSICAL_PRESENCE_VARIABLE L"TrEEPhysicalPresence" + +typedef struct { + UINT8 PPRequest; ///< Physical Presence request command. + UINT8 LastPPRequest; + UINT32 PPResponse; + UINT8 Flags; +} EFI_TREE_PHYSICAL_PRESENCE; + +// +// The definition bit of the flags +// +#define TREE_FLAG_NO_PPI_CLEAR 0x2 +#define TREE_FLAG_RESET_TRACK 0x8 + +// +// The definition of physical presence operation actions +// +#define TREE_PHYSICAL_PRESENCE_NO_ACTION 0 +#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR 5 +#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2 14 +#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE 17 +#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE 18 +#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3 21 +#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4 22 + +#define TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX 20 + +extern EFI_GUID gEfiTrEEPhysicalPresenceGuid; + +#endif + diff --git a/ReferenceCode/ME/SampleCode/Include/IndustryStandard/AcpiAml.h b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/AcpiAml.h new file mode 100644 index 0000000..192a869 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/AcpiAml.h @@ -0,0 +1,180 @@ +/** @file + This file contains AML code definition in the latest ACPI spec. + +@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 +**/ + +#ifndef _ACPI_AML_H_ +#define _ACPI_AML_H_ + +// +// ACPI AML definition +// + +// +// Primary OpCode +// +#define AML_ZERO_OP 0x00 +#define AML_ONE_OP 0x01 +#define AML_ALIAS_OP 0x06 +#define AML_NAME_OP 0x08 +#define AML_BYTE_PREFIX 0x0a +#define AML_WORD_PREFIX 0x0b +#define AML_DWORD_PREFIX 0x0c +#define AML_STRING_PREFIX 0x0d +#define AML_QWORD_PREFIX 0x0e +#define AML_SCOPE_OP 0x10 +#define AML_BUFFER_OP 0x11 +#define AML_PACKAGE_OP 0x12 +#define AML_VAR_PACKAGE_OP 0x13 +#define AML_METHOD_OP 0x14 +#define AML_DUAL_NAME_PREFIX 0x2e +#define AML_MULTI_NAME_PREFIX 0x2f +#define AML_NAME_CHAR_A 0x41 +#define AML_NAME_CHAR_B 0x42 +#define AML_NAME_CHAR_C 0x43 +#define AML_NAME_CHAR_D 0x44 +#define AML_NAME_CHAR_E 0x45 +#define AML_NAME_CHAR_F 0x46 +#define AML_NAME_CHAR_G 0x47 +#define AML_NAME_CHAR_H 0x48 +#define AML_NAME_CHAR_I 0x49 +#define AML_NAME_CHAR_J 0x4a +#define AML_NAME_CHAR_K 0x4b +#define AML_NAME_CHAR_L 0x4c +#define AML_NAME_CHAR_M 0x4d +#define AML_NAME_CHAR_N 0x4e +#define AML_NAME_CHAR_O 0x4f +#define AML_NAME_CHAR_P 0x50 +#define AML_NAME_CHAR_Q 0x51 +#define AML_NAME_CHAR_R 0x52 +#define AML_NAME_CHAR_S 0x53 +#define AML_NAME_CHAR_T 0x54 +#define AML_NAME_CHAR_U 0x55 +#define AML_NAME_CHAR_V 0x56 +#define AML_NAME_CHAR_W 0x57 +#define AML_NAME_CHAR_X 0x58 +#define AML_NAME_CHAR_Y 0x59 +#define AML_NAME_CHAR_Z 0x5a +#define AML_ROOT_CHAR 0x5c +#define AML_PARENT_PREFIX_CHAR 0x5e +#define AML_NAME_CHAR__ 0x5f +#define AML_LOCAL0 0x60 +#define AML_LOCAL1 0x61 +#define AML_LOCAL2 0x62 +#define AML_LOCAL3 0x63 +#define AML_LOCAL4 0x64 +#define AML_LOCAL5 0x65 +#define AML_LOCAL6 0x66 +#define AML_LOCAL7 0x67 +#define AML_ARG0 0x68 +#define AML_ARG1 0x69 +#define AML_ARG2 0x6a +#define AML_ARG3 0x6b +#define AML_ARG4 0x6c +#define AML_ARG5 0x6d +#define AML_ARG6 0x6e +#define AML_STORE_OP 0x70 +#define AML_REF_OF_OP 0x71 +#define AML_ADD_OP 0x72 +#define AML_CONCAT_OP 0x73 +#define AML_SUBTRACT_OP 0x74 +#define AML_INCREMENT_OP 0x75 +#define AML_DECREMENT_OP 0x76 +#define AML_MULTIPLY_OP 0x77 +#define AML_DIVIDE_OP 0x78 +#define AML_SHIFT_LEFT_OP 0x79 +#define AML_SHIFT_RIGHT_OP 0x7a +#define AML_AND_OP 0x7b +#define AML_NAND_OP 0x7c +#define AML_OR_OP 0x7d +#define AML_NOR_OP 0x7e +#define AML_XOR_OP 0x7f +#define AML_NOT_OP 0x80 +#define AML_FIND_SET_LEFT_BIT_OP 0x81 +#define AML_FIND_SET_RIGHT_BIT_OP 0x82 +#define AML_DEREF_OF_OP 0x83 +#define AML_CONCAT_RES_OP 0x84 +#define AML_MOD_OP 0x85 +#define AML_NOTIFY_OP 0x86 +#define AML_SIZE_OF_OP 0x87 +#define AML_INDEX_OP 0x88 +#define AML_MATCH_OP 0x89 +#define AML_CREATE_DWORD_FIELD_OP 0x8a +#define AML_CREATE_WORD_FIELD_OP 0x8b +#define AML_CREATE_BYTE_FIELD_OP 0x8c +#define AML_CREATE_BIT_FIELD_OP 0x8d +#define AML_OBJECT_TYPE_OP 0x8e +#define AML_CREATE_QWORD_FIELD_OP 0x8f +#define AML_LAND_OP 0x90 +#define AML_LOR_OP 0x91 +#define AML_LNOT_OP 0x92 +#define AML_LEQUAL_OP 0x93 +#define AML_LGREATER_OP 0x94 +#define AML_LLESS_OP 0x95 +#define AML_TO_BUFFER_OP 0x96 +#define AML_TO_DEC_STRING_OP 0x97 +#define AML_TO_HEX_STRING_OP 0x98 +#define AML_TO_INTEGER_OP 0x99 +#define AML_TO_STRING_OP 0x9c +#define AML_COPY_OBJECT_OP 0x9d +#define AML_MID_OP 0x9e +#define AML_CONTINUE_OP 0x9f +#define AML_IF_OP 0xa0 +#define AML_ELSE_OP 0xa1 +#define AML_WHILE_OP 0xa2 +#define AML_NOOP_OP 0xa3 +#define AML_RETURN_OP 0xa4 +#define AML_BREAK_OP 0xa5 +#define AML_BREAK_POINT_OP 0xcc +#define AML_ONES_OP 0xff + +// +// Extended OpCode +// +#define AML_EXT_OP 0x5b + +#define AML_EXT_MUTEX_OP 0x01 +#define AML_EXT_EVENT_OP 0x02 +#define AML_EXT_COND_REF_OF_OP 0x12 +#define AML_EXT_CREATE_FIELD_OP 0x13 +#define AML_EXT_LOAD_TABLE_OP 0x1f +#define AML_EXT_LOAD_OP 0x20 +#define AML_EXT_STALL_OP 0x21 +#define AML_EXT_SLEEP_OP 0x22 +#define AML_EXT_ACQUIRE_OP 0x23 +#define AML_EXT_SIGNAL_OP 0x24 +#define AML_EXT_WAIT_OP 0x25 +#define AML_EXT_RESET_OP 0x26 +#define AML_EXT_RELEASE_OP 0x27 +#define AML_EXT_FROM_BCD_OP 0x28 +#define AML_EXT_TO_BCD_OP 0x29 +#define AML_EXT_UNLOAD_OP 0x2a +#define AML_EXT_REVISION_OP 0x30 +#define AML_EXT_DEBUG_OP 0x31 +#define AML_EXT_FATAL_OP 0x32 +#define AML_EXT_TIMER_OP 0x33 +#define AML_EXT_REGION_OP 0x80 +#define AML_EXT_FIELD_OP 0x81 +#define AML_EXT_DEVICE_OP 0x82 +#define AML_EXT_PROCESSOR_OP 0x83 +#define AML_EXT_POWER_RES_OP 0x84 +#define AML_EXT_THERMAL_ZONE_OP 0x85 +#define AML_EXT_INDEX_FIELD_OP 0x86 +#define AML_EXT_BANK_FIELD_OP 0x87 +#define AML_EXT_DATA_REGION_OP 0x88 + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20.h b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20.h new file mode 100644 index 0000000..95cd283 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20.h @@ -0,0 +1,1872 @@ +/** @file + + Definitions for Tpm 2.0 + +@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 +**/ + +#ifndef _TPM20_H +#define _TPM20_H + +/// +/// The start of TPM return codes +/// +#define TPM_BASE 0 +#include <IndustryStandard/Tpm12.h> + +#pragma pack (push, 1) + +typedef UINT8 BYTE; +typedef UINT8 BOOL; + +typedef struct { + UINT16 size; + BYTE buffer[1]; +} TPM2B; + +#include <IndustryStandard/Tpm20Implementation.h> + +#define MAX_CAP_DATA (MAX_CAP_BUFFER-sizeof(TPM_CAP)-sizeof(UINT32)) +#define MAX_CAP_ALGS (MAX_CAP_DATA/sizeof(TPMS_ALG_PROPERTY)) +#define MAX_CAP_HANDLES (MAX_CAP_DATA/sizeof(TPM_HANDLE)) +#define MAX_CAP_CC (MAX_CAP_DATA/sizeof(TPM_CC)) +#define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY)) +#define MAX_PCR_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PCR_SELECT)) +#define MAX_ECC_CURVES (MAX_CAP_DATA/sizeof(TPM_ECC_CURVE)) + +// Table 2 -- BaseTypes BaseTypes <I/O> + +// Table 3 -- DocumentationClarity Types <I/O> +typedef UINT32 TPM_ALGORITHM_ID; +typedef UINT32 TPM_MODIFIER_INDICATOR; +typedef UINT32 TPM_SESSION_OFFSET; +typedef UINT16 TPM_KEY_SIZE; +typedef UINT16 TPM_KEY_BITS; +typedef UINT64 TPM_SYSTEM_ADDRESS; +typedef UINT32 TPM_SPEC; + +#define TPM_SPEC_FAMILY (TPM_SPEC)(0x322E3000) +#define TPM_SPEC_LEVEL (TPM_SPEC)(00) +#define TPM_SPEC_VERSION (TPM_SPEC)(88) +#define TPM_SPEC_YEAR (TPM_SPEC)(2012) +#define TPM_SPEC_DAY_OF_YEAR (TPM_SPEC)(65) + +// Table 5 -- TPM_GENERATED Constants <O,S> +typedef UINT32 TPM_GENERATED; + +#define TPM_GENERATED_VALUE (TPM_GENERATED)(0xff544347) + +// Table 10 -- TPM_CC Constants <I/O,S> +typedef UINT32 TPM_CC; + +#define TPM_CC_FIRST (TPM_CC)(0x0000011F) +#define TPM_CC_PP_FIRST (TPM_CC)(0x0000011F) +#define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F) +#define CC_NV_UndefineSpaceSpecial YES +#define TPM_CC_EvictControl (TPM_CC)(0x00000120) +#define CC_EvictControl YES +#define TPM_CC_HierarchyControl (TPM_CC)(0x00000121) +#define CC_HierarchyControl YES +#define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122) +#define CC_NV_UndefineSpace YES +#define TPM_CC_ChangeEPS (TPM_CC)(0x00000124) +#define CC_ChangeEPS YES +#define TPM_CC_ChangePPS (TPM_CC)(0x00000125) +#define CC_ChangePPS YES +#define TPM_CC_Clear (TPM_CC)(0x00000126) +#define CC_Clear YES +#define TPM_CC_ClearControl (TPM_CC)(0x00000127) +#define CC_ClearControl YES +#define TPM_CC_ClockSet (TPM_CC)(0x00000128) +#define CC_ClockSet YES +#define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129) +#define CC_HierarchyChangeAuth YES +#define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A) +#define CC_NV_DefineSpace YES +#define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B) +#define CC_PCR_Allocate YES +#define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C) +#define CC_PCR_SetAuthPolicy YES +#define TPM_CC_PP_Commands (TPM_CC)(0x0000012D) +#define CC_PP_Commands YES +#define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E) +#define CC_SetPrimaryPolicy YES +#define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F) +#define CC_FieldUpgradeStart NO +#define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130) +#define CC_ClockRateAdjust YES +#define TPM_CC_CreatePrimary (TPM_CC)(0x00000131) +#define CC_CreatePrimary YES +#define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132) +#define CC_NV_GlobalWriteLock YES +#define TPM_CC_PP_LAST (TPM_CC)(0x00000132) +#define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133) +#define CC_GetCommandAuditDigest YES +#define TPM_CC_NV_Increment (TPM_CC)(0x00000134) +#define CC_NV_Increment YES +#define TPM_CC_NV_SetBits (TPM_CC)(0x00000135) +#define CC_NV_SetBits YES +#define TPM_CC_NV_Extend (TPM_CC)(0x00000136) +#define CC_NV_Extend YES +#define TPM_CC_NV_Write (TPM_CC)(0x00000137) +#define CC_NV_Write YES +#define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138) +#define CC_NV_WriteLock YES +#define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139) +#define CC_DictionaryAttackLockReset YES +#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A) +#define CC_DictionaryAttackParameters YES +#define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B) +#define CC_NV_ChangeAuth YES +#define TPM_CC_PCR_Event (TPM_CC)(0x0000013C) +#define CC_PCR_Event YES +#define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D) +#define CC_PCR_Reset YES +#define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E) +#define CC_SequenceComplete YES +#define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F) +#define CC_SetAlgorithmSet YES +#define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140) +#define CC_SetCommandCodeAuditStatus YES +#define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141) +#define CC_FieldUpgradeData NO +#define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142) +#define CC_IncrementalSelfTest YES +#define TPM_CC_SelfTest (TPM_CC)(0x00000143) +#define CC_SelfTest YES +#define TPM_CC_Startup (TPM_CC)(0x00000144) +#define CC_Startup YES +#define TPM_CC_Shutdown (TPM_CC)(0x00000145) +#define CC_Shutdown YES +#define TPM_CC_StirRandom (TPM_CC)(0x00000146) +#define CC_StirRandom YES +#define TPM_CC_ActivateCredential (TPM_CC)(0x00000147) +#define CC_ActivateCredential YES +#define TPM_CC_Certify (TPM_CC)(0x00000148) +#define CC_Certify YES +#define TPM_CC_PolicyNV (TPM_CC)(0x00000149) +#define CC_PolicyNV YES +#define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A) +#define CC_CertifyCreation YES +#define TPM_CC_Duplicate (TPM_CC)(0x0000014B) +#define CC_Duplicate YES +#define TPM_CC_GetTime (TPM_CC)(0x0000014C) +#define CC_GetTime YES +#define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D) +#define CC_GetSessionAuditDigest YES +#define TPM_CC_NV_Read (TPM_CC)(0x0000014E) +#define CC_NV_Read YES +#define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F) +#define CC_NV_ReadLock YES +#define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150) +#define CC_ObjectChangeAuth YES +#define TPM_CC_PolicySecret (TPM_CC)(0x00000151) +#define CC_PolicySecret YES +#define TPM_CC_Rewrap (TPM_CC)(0x00000152) +#define CC_Rewrap YES +#define TPM_CC_Create (TPM_CC)(0x00000153) +#define CC_Create YES +#define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154) +#define CC_ECDH_ZGen YES +#define TPM_CC_HMAC (TPM_CC)(0x00000155) +#define CC_HMAC YES +#define TPM_CC_Import (TPM_CC)(0x00000156) +#define CC_Import YES +#define TPM_CC_Load (TPM_CC)(0x00000157) +#define CC_Load YES +#define TPM_CC_Quote (TPM_CC)(0x00000158) +#define CC_Quote YES +#define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159) +#define CC_RSA_Decrypt YES +#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B) +#define CC_HMAC_Start YES +#define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C) +#define CC_SequenceUpdate YES +#define TPM_CC_Sign (TPM_CC)(0x0000015D) +#define CC_Sign YES +#define TPM_CC_Unseal (TPM_CC)(0x0000015E) +#define CC_Unseal YES +#define TPM_CC_PolicySigned (TPM_CC)(0x00000160) +#define CC_PolicySigned YES +#define TPM_CC_ContextLoad (TPM_CC)(0x00000161) +#define CC_ContextLoad YES +#define TPM_CC_ContextSave (TPM_CC)(0x00000162) +#define CC_ContextSave YES +#define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163) +#define CC_ECDH_KeyGen YES +#define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164) +#define CC_EncryptDecrypt YES +#define TPM_CC_FlushContext (TPM_CC)(0x00000165) +#define CC_FlushContext YES +#define TPM_CC_LoadExternal (TPM_CC)(0x00000167) +#define CC_LoadExternal YES +#define TPM_CC_MakeCredential (TPM_CC)(0x00000168) +#define CC_MakeCredential YES +#define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169) +#define CC_NV_ReadPublic YES +#define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A) +#define CC_PolicyAuthorize YES +#define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B) +#define CC_PolicyAuthValue YES +#define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C) +#define CC_PolicyCommandCode YES +#define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D) +#define CC_PolicyCounterTimer YES +#define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E) +#define CC_PolicyCpHash YES +#define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F) +#define CC_PolicyLocality YES +#define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170) +#define CC_PolicyNameHash YES +#define TPM_CC_PolicyOR (TPM_CC)(0x00000171) +#define CC_PolicyOR YES +#define TPM_CC_PolicyTicket (TPM_CC)(0x00000172) +#define CC_PolicyTicket YES +#define TPM_CC_ReadPublic (TPM_CC)(0x00000173) +#define CC_ReadPublic YES +#define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174) +#define CC_RSA_Encrypt YES +#define TPM_CC_StartAuthSession (TPM_CC)(0x00000176) +#define CC_StartAuthSession YES +#define TPM_CC_VerifySignature (TPM_CC)(0x00000177) +#define CC_VerifySignature YES +#define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178) +#define CC_ECC_Parameters YES +#define TPM_CC_FirmwareRead (TPM_CC)(0x00000179) +#define CC_FirmwareRead NO +#define TPM_CC_GetCapability (TPM_CC)(0x0000017A) +#define CC_GetCapability YES +#define TPM_CC_GetRandom (TPM_CC)(0x0000017B) +#define CC_GetRandom YES +#define TPM_CC_GetTestResult (TPM_CC)(0x0000017C) +#define CC_GetTestResult YES +#define TPM_CC_Hash (TPM_CC)(0x0000017D) +#define CC_Hash YES +#define TPM_CC_PCR_Read (TPM_CC)(0x0000017E) +#define CC_PCR_Read YES +#define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F) +#define CC_PolicyPCR YES +#define TPM_CC_PolicyRestart (TPM_CC)(0x00000180) +#define CC_PolicyRestart YES +#define TPM_CC_ReadClock (TPM_CC)(0x00000181) +#define CC_ReadClock YES +#define TPM_CC_PCR_Extend (TPM_CC)(0x00000182) +#define CC_PCR_Extend YES +#define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183) +#define CC_PCR_SetAuthValue YES +#define TPM_CC_NV_Certify (TPM_CC)(0x00000184) +#define CC_NV_Certify YES +#define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185) +#define CC_EventSequenceComplete YES +#define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186) +#define CC_HashSequenceStart YES +#define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187) +#define CC_PolicyPhysicalPresence YES +#define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188) +#define CC_PolicyDuplicationSelect YES +#define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189) +#define CC_PolicyGetDigest YES +#define TPM_CC_TestParms (TPM_CC)(0x0000018A) +#define CC_TestParms YES +#define TPM_CC_Commit (TPM_CC)(0x0000018B) +#define CC_Commit YES +#define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C) +#define CC_PolicyPassword YES +#define TPM_CC_LAST (TPM_CC)(0x0000018C) + +// Table 14 -- TPM_RC Constants <O,S> +typedef UINT32 TPM_RC; + +#define TPM_RC_SUCCESS (TPM_RC)(0x000) +#define TPM_RC_BAD_TAG (TPM_RC)(0x030) +#define RC_VER1 (TPM_RC)(0x100) +#define TPM_RC_INITIALIZE (TPM_RC)(RC_VER1 + 0x000) +#define TPM_RC_FAILURE (TPM_RC)(RC_VER1 + 0x001) +#define TPM_RC_SEQUENCE (TPM_RC)(RC_VER1 + 0x003) +#define TPM_RC_PRIVATE (TPM_RC)(RC_VER1 + 0x00B) +#define TPM_RC_HMAC (TPM_RC)(RC_VER1 + 0x019) +#define TPM_RC_DISABLED (TPM_RC)(RC_VER1 + 0x020) +#define TPM_RC_EXCLUSIVE (TPM_RC)(RC_VER1 + 0x021) +#define TPM_RC_ECC_CURVE (TPM_RC)(RC_VER1 + 0x023) +#define TPM_RC_AUTH_TYPE (TPM_RC)(RC_VER1 + 0x024) +#define TPM_RC_AUTH_MISSING (TPM_RC)(RC_VER1 + 0x025) +#define TPM_RC_POLICY (TPM_RC)(RC_VER1 + 0x026) +#define TPM_RC_PCR (TPM_RC)(RC_VER1 + 0x027) +#define TPM_RC_PCR_CHANGED (TPM_RC)(RC_VER1 + 0x028) +#define TPM_RC_ECC_POINT (TPM_RC)(RC_VER1 + 0x02C) +#define TPM_RC_UPGRADE (TPM_RC)(RC_VER1 + 0x02D) +#define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1 + 0x02E) +#define TPM_RC_AUTH_UNAVAILABLE (TPM_RC)(RC_VER1 + 0x02F) +#define TPM_RC_REBOOT (TPM_RC)(RC_VER1 + 0x030) +#define TPM_RC_UNBALANCED (TPM_RC)(RC_VER1 + 0x031) +#define TPM_RC_COMMAND_SIZE (TPM_RC)(RC_VER1 + 0x042) +#define TPM_RC_COMMAND_CODE (TPM_RC)(RC_VER1 + 0x043) +#define TPM_RC_AUTHSIZE (TPM_RC)(RC_VER1 + 0x044) +#define TPM_RC_AUTH_CONTEXT (TPM_RC)(RC_VER1 + 0x045) +#define TPM_RC_NV_RANGE (TPM_RC)(RC_VER1 + 0x046) +#define TPM_RC_NV_SIZE (TPM_RC)(RC_VER1 + 0x047) +#define TPM_RC_NV_LOCKED (TPM_RC)(RC_VER1 + 0x048) +#define TPM_RC_NV_AUTHORIZATION (TPM_RC)(RC_VER1 + 0x049) +#define TPM_RC_NV_UNINITIALIZED (TPM_RC)(RC_VER1 + 0x04A) +#define TPM_RC_NV_SPACE (TPM_RC)(RC_VER1 + 0x04B) +#define TPM_RC_NV_DEFINED (TPM_RC)(RC_VER1 + 0x04C) +#define TPM_RC_BAD_CONTEXT (TPM_RC)(RC_VER1 + 0x050) +#define TPM_RC_CPHASH (TPM_RC)(RC_VER1 + 0x051) +#define TPM_RC_PARENT (TPM_RC)(RC_VER1 + 0x052) +#define TPM_RC_NEEDS_TEST (TPM_RC)(RC_VER1 + 0x053) +#define TPM_RC_NO_RESULT (TPM_RC)(RC_VER1 + 0x054) +#define TPM_RC_SENSITIVE (TPM_RC)(RC_VER1 + 0x055) +#define RC_MAX_FM0 (TPM_RC)(RC_VER1 + 0x07F) +#define RC_FMT1 (TPM_RC)(0x080) +#define TPM_RC_ASYMMETRIC (TPM_RC)(RC_FMT1 + 0x001) +#define TPM_RC_ATTRIBUTES (TPM_RC)(RC_FMT1 + 0x002) +#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003) +#define TPM_RC_VALUE (TPM_RC)(RC_FMT1 + 0x004) +#define TPM_RC_HIERARCHY (TPM_RC)(RC_FMT1 + 0x005) +#define TPM_RC_KEY_SIZE (TPM_RC)(RC_FMT1 + 0x007) +#define TPM_RC_MGF (TPM_RC)(RC_FMT1 + 0x008) +#define TPM_RC_MODE (TPM_RC)(RC_FMT1 + 0x009) +#define TPM_RC_TYPE (TPM_RC)(RC_FMT1 + 0x00A) +#define TPM_RC_HANDLE (TPM_RC)(RC_FMT1 + 0x00B) +#define TPM_RC_KDF (TPM_RC)(RC_FMT1 + 0x00C) +#define TPM_RC_RANGE (TPM_RC)(RC_FMT1 + 0x00D) +#define TPM_RC_AUTH_FAIL (TPM_RC)(RC_FMT1 + 0x00E) +#define TPM_RC_NONCE (TPM_RC)(RC_FMT1 + 0x00F) +#define TPM_RC_PP (TPM_RC)(RC_FMT1 + 0x010) +#define TPM_RC_SCHEME (TPM_RC)(RC_FMT1 + 0x012) +#define TPM_RC_SIZE (TPM_RC)(RC_FMT1 + 0x015) +#define TPM_RC_SYMMETRIC (TPM_RC)(RC_FMT1 + 0x016) +#define TPM_RC_TAG (TPM_RC)(RC_FMT1 + 0x017) +#define TPM_RC_SELECTOR (TPM_RC)(RC_FMT1 + 0x018) +#define TPM_RC_INSUFFICIENT (TPM_RC)(RC_FMT1 + 0x01A) +#define TPM_RC_SIGNATURE (TPM_RC)(RC_FMT1 + 0x01B) +#define TPM_RC_KEY (TPM_RC)(RC_FMT1 + 0x01C) +#define TPM_RC_POLICY_FAIL (TPM_RC)(RC_FMT1 + 0x01D) +#define TPM_RC_INTEGRITY (TPM_RC)(RC_FMT1 + 0x01F) +#define TPM_RC_TICKET (TPM_RC)(RC_FMT1 + 0x020) +#define TPM_RC_RESERVED_BITS (TPM_RC)(RC_FMT1 + 0x021) +#define TPM_RC_BAD_AUTH (TPM_RC)(RC_FMT1 + 0x022) +#define TPM_RC_EXPIRED (TPM_RC)(RC_FMT1 + 0x023) +#define TPM_RC_POLICY_CC (TPM_RC)(RC_FMT1 + 0x024 ) +#define TPM_RC_BINDING (TPM_RC)(RC_FMT1 + 0x025) +#define TPM_RC_CURVE (TPM_RC)(RC_FMT1 + 0x026) +#define RC_WARN (TPM_RC)(0x900) +#define TPM_RC_CONTEXT_GAP (TPM_RC)(RC_WARN + 0x001) +#define TPM_RC_OBJECT_MEMORY (TPM_RC)(RC_WARN + 0x002) +#define TPM_RC_SESSION_MEMORY (TPM_RC)(RC_WARN + 0x003) +#define TPM_RC_MEMORY (TPM_RC)(RC_WARN + 0x004) +#define TPM_RC_SESSION_HANDLES (TPM_RC)(RC_WARN + 0x005) +#define TPM_RC_OBJECT_HANDLES (TPM_RC)(RC_WARN + 0x006) +#define TPM_RC_LOCALITY (TPM_RC)(RC_WARN + 0x007) +#define TPM_RC_YIELDED (TPM_RC)(RC_WARN + 0x008) +#define TPM_RC_CANCELLED (TPM_RC)(RC_WARN + 0x009) +#define TPM_RC_TESTING (TPM_RC)(RC_WARN + 0x00A) +#define TPM_RC_REFERENCE_H0 (TPM_RC)(RC_WARN + 0x010) +#define TPM_RC_REFERENCE_H1 (TPM_RC)(RC_WARN + 0x011) +#define TPM_RC_REFERENCE_H2 (TPM_RC)(RC_WARN + 0x012) +#define TPM_RC_REFERENCE_H3 (TPM_RC)(RC_WARN + 0x013) +#define TPM_RC_REFERENCE_H4 (TPM_RC)(RC_WARN + 0x014) +#define TPM_RC_REFERENCE_H5 (TPM_RC)(RC_WARN + 0x015) +#define TPM_RC_REFERENCE_H6 (TPM_RC)(RC_WARN + 0x016) +#define TPM_RC_REFERENCE_S0 (TPM_RC)(RC_WARN + 0x018) +#define TPM_RC_REFERENCE_S1 (TPM_RC)(RC_WARN + 0x019) +#define TPM_RC_REFERENCE_S2 (TPM_RC)(RC_WARN + 0x01A) +#define TPM_RC_REFERENCE_S3 (TPM_RC)(RC_WARN + 0x01B) +#define TPM_RC_REFERENCE_S4 (TPM_RC)(RC_WARN + 0x01C) +#define TPM_RC_REFERENCE_S5 (TPM_RC)(RC_WARN + 0x01D) +#define TPM_RC_REFERENCE_S6 (TPM_RC)(RC_WARN + 0x01E) +#define TPM_RC_NV_RATE (TPM_RC)(RC_WARN + 0x020) +#define TPM_RC_LOCKOUT (TPM_RC)(RC_WARN + 0x021) +#define TPM_RC_RETRY (TPM_RC)(RC_WARN + 0x022) +#define TPM_RC_NV_UNAVAILABLE (TPM_RC)(RC_WARN + 0x023) +#define TPM_RC_NOT_USED (TPM_RC)(RC_WARN + 0x7F) +#define TPM_RC_H (TPM_RC)(0x000) +#define TPM_RC_P (TPM_RC)(0x040) +#define TPM_RC_S (TPM_RC)(0x800) +#define TPM_RC_1 (TPM_RC)(0x100) +#define TPM_RC_2 (TPM_RC)(0x200) +#define TPM_RC_3 (TPM_RC)(0x300) +#define TPM_RC_4 (TPM_RC)(0x400) +#define TPM_RC_5 (TPM_RC)(0x500) +#define TPM_RC_6 (TPM_RC)(0x600) +#define TPM_RC_7 (TPM_RC)(0x700) +#define TPM_RC_8 (TPM_RC)(0x800) +#define TPM_RC_9 (TPM_RC)(0x900) +#define TPM_RC_A (TPM_RC)(0xA00) +#define TPM_RC_B (TPM_RC)(0xB00) +#define TPM_RC_C (TPM_RC)(0xC00) +#define TPM_RC_D (TPM_RC)(0xD00) +#define TPM_RC_E (TPM_RC)(0xE00) +#define TPM_RC_F (TPM_RC)(0xF00) +#define TPM_RC_N_MASK (TPM_RC)(0xF00) + +// Table 15 -- TPM_CLOCK_ADJUST Constants <I> +typedef INT8 TPM_CLOCK_ADJUST; + +#define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3) +#define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2) +#define TPM_CLOCK_FINE_SLOWER (TPM_CLOCK_ADJUST)(-1) +#define TPM_CLOCK_NO_CHANGE (TPM_CLOCK_ADJUST)(0) +#define TPM_CLOCK_FINE_FASTER (TPM_CLOCK_ADJUST)(1) +#define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2) +#define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3) + +// Table 16 -- TPM_EO Constants <I/O> +typedef UINT16 TPM_EO; + +#define TPM_EO_EQ (TPM_EO)(0x0000) +#define TPM_EO_NEQ (TPM_EO)(0x0001) +#define TPM_EO_SIGNED_GT (TPM_EO)(0x0002) +#define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003) +#define TPM_EO_SIGNED_LT (TPM_EO)(0x0004) +#define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005) +#define TPM_EO_SIGNED_GE (TPM_EO)(0x0006) +#define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007) +#define TPM_EO_SIGNED_LE (TPM_EO)(0x0008) +#define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009) +#define TPM_EO_BITSET (TPM_EO)(0x000A) +#define TPM_EO_BITCLEAR (TPM_EO)(0x000B) + +// Table 17 -- TPM_ST Constants <I/O,S> +typedef UINT16 TPM_ST; + +#define TPM_ST_RSP_COMMAND (TPM_ST)(0x00C4) +#define TPM_ST_NULL (TPM_ST)(0X8000) +#define TPM_ST_NO_SESSIONS (TPM_ST)(0x8001) +#define TPM_ST_SESSIONS (TPM_ST)(0x8002) +#define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015) +#define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016) +#define TPM_ST_ATTEST_CERTIFY (TPM_ST)(0x8017) +#define TPM_ST_ATTEST_QUOTE (TPM_ST)(0x8018) +#define TPM_ST_ATTEST_TIME (TPM_ST)(0x8019) +#define TPM_ST_ATTEST_CREATION (TPM_ST)(0x801A) +#define TPM_ST_ATTEST_NV (TPM_ST)(0x801B) +#define TPM_ST_CREATION (TPM_ST)(0x8021) +#define TPM_ST_VERIFIED (TPM_ST)(0x8022) +#define TPM_ST_AUTH_SECRET (TPM_ST)(0x8023) +#define TPM_ST_HASHCHECK (TPM_ST)(0x8024) +#define TPM_ST_AUTH_SIGNED (TPM_ST)(0x8025) +#define TPM_ST_FU_MANIFEST (TPM_ST)(0x8029) + +// Table 18 -- TPM_SU Constants <I> +typedef UINT16 TPM_SU; + +#define TPM_SU_CLEAR (TPM_SU)(0x0000) +#define TPM_SU_STATE (TPM_SU)(0x0001) + +// Table 19 -- TPM_SE Constants <I> +typedef UINT8 TPM_SE; + +#define TPM_SE_HMAC (TPM_SE)(0x00) +#define TPM_SE_POLICY (TPM_SE)(0x01) +#define TPM_SE_TRIAL (TPM_SE)(0x03) + +// Table 20 -- TPM_CAP Constants <I/O,S> +typedef UINT32 TPM_CAP; + +#define TPM_CAP_FIRST (TPM_CAP)(0x00000000) +#define TPM_CAP_ALGS (TPM_CAP)(0x00000000) +#define TPM_CAP_HANDLES (TPM_CAP)(0x00000001) +#define TPM_CAP_COMMANDS (TPM_CAP)(0x00000002) +#define TPM_CAP_PP_COMMANDS (TPM_CAP)(0x00000003) +#define TPM_CAP_AUDIT_COMMANDS (TPM_CAP)(0x00000004) +#define TPM_CAP_PCRS (TPM_CAP)(0x00000005) +#define TPM_CAP_TPM_PROPERTIES (TPM_CAP)(0x00000006) +#define TPM_CAP_PCR_PROPERTIES (TPM_CAP)(0x00000007) +#define TPM_CAP_ECC_CURVES (TPM_CAP)(0x00000008) +#define TPM_CAP_LAST (TPM_CAP)(0x00000008) +#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100) + +// Table 21 -- TPM_PT Constants <I/O,S> +typedef UINT32 TPM_PT; + +#define TPM_PT_NONE (TPM_PT)(0x00000000) +#define PT_GROUP (TPM_PT)(0x00000100) +#define PT_FIXED (TPM_PT)(PT_GROUP * 1) +#define TPM_PT_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 0) +#define TPM_PT_LEVEL (TPM_PT)(PT_FIXED + 1) +#define TPM_PT_REVISION (TPM_PT)(PT_FIXED + 2) +#define TPM_PT_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 3) +#define TPM_PT_YEAR (TPM_PT)(PT_FIXED + 4) +#define TPM_PT_MANUFACTURER (TPM_PT)(PT_FIXED + 5) +#define TPM_PT_VENDOR_STRING_1 (TPM_PT)(PT_FIXED + 6) +#define TPM_PT_VENDOR_STRING_2 (TPM_PT)(PT_FIXED + 7) +#define TPM_PT_VENDOR_STRING_3 (TPM_PT)(PT_FIXED + 8) +#define TPM_PT_VENDOR_STRING_4 (TPM_PT)(PT_FIXED + 9) +#define TPM_PT_VENDOR_TPM_TYPE (TPM_PT)(PT_FIXED + 10) +#define TPM_PT_FIRMWARE_VERSION_1 (TPM_PT)(PT_FIXED + 11) +#define TPM_PT_FIRMWARE_VERSION_2 (TPM_PT)(PT_FIXED + 12) +#define TPM_PT_INPUT_BUFFER (TPM_PT)(PT_FIXED + 13) +#define TPM_PT_HR_TRANSIENT_MIN (TPM_PT)(PT_FIXED + 14) +#define TPM_PT_HR_PERSISTENT_MIN (TPM_PT)(PT_FIXED + 15) +#define TPM_PT_HR_LOADED_MIN (TPM_PT)(PT_FIXED + 16) +#define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED + 17) +#define TPM_PT_PCR_COUNT (TPM_PT)(PT_FIXED + 18) +#define TPM_PT_PCR_SELECT_MIN (TPM_PT)(PT_FIXED + 19) +#define TPM_PT_CONTEXT_GAP_MAX (TPM_PT)(PT_FIXED + 20) +#define TPM_PT_NV_COUNTERS_MAX (TPM_PT)(PT_FIXED + 22) +#define TPM_PT_NV_INDEX_MAX (TPM_PT)(PT_FIXED + 23) +#define TPM_PT_MEMORY (TPM_PT)(PT_FIXED + 24) +#define TPM_PT_CLOCK_UPDATE (TPM_PT)(PT_FIXED + 25) +#define TPM_PT_CONTEXT_HASH (TPM_PT)(PT_FIXED + 26) +#define TPM_PT_CONTEXT_SYM (TPM_PT)(PT_FIXED + 27) +#define TPM_PT_CONTEXT_SYM_SIZE (TPM_PT)(PT_FIXED + 28) +#define TPM_PT_ORDERLY_COUNT (TPM_PT)(PT_FIXED + 29) +#define TPM_PT_MAX_COMMAND_SIZE (TPM_PT)(PT_FIXED + 30) +#define TPM_PT_MAX_RESPONSE_SIZE (TPM_PT)(PT_FIXED + 31) +#define TPM_PT_MAX_DIGEST (TPM_PT)(PT_FIXED + 32) +#define TPM_PT_MAX_OBJECT_CONTEXT (TPM_PT)(PT_FIXED + 33) +#define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED + 34) +#define TPM_PT_PS_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 35) +#define TPM_PT_PS_LEVEL (TPM_PT)(PT_FIXED + 36) +#define TPM_PT_PS_REVISION (TPM_PT)(PT_FIXED + 37) +#define TPM_PT_PS_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 38) +#define TPM_PT_PS_YEAR (TPM_PT)(PT_FIXED + 39) +#define TPM_PT_SPLIT_MAX (TPM_PT)(PT_FIXED + 40) +#define TPM_PT_TOTAL_COMMANDS (TPM_PT)(PT_FIXED + 41) +#define TPM_PT_LIBRARY_COMMANDS (TPM_PT)(PT_FIXED + 42) +#define TPM_PT_VENDOR_COMMANDS (TPM_PT)(PT_FIXED + 43) +#define PT_VAR (TPM_PT)(PT_GROUP * 2) +#define TPM_PT_PERMANENT (TPM_PT)(PT_VAR + 0) +#define TPM_PT_STARTUP_CLEAR (TPM_PT)(PT_VAR + 1) +#define TPM_PT_HR_NV_INDEX (TPM_PT)(PT_VAR + 2) +#define TPM_PT_HR_LOADED (TPM_PT)(PT_VAR + 3) +#define TPM_PT_HR_LOADED_AVAIL (TPM_PT)(PT_VAR + 4) +#define TPM_PT_HR_ACTIVE (TPM_PT)(PT_VAR + 5) +#define TPM_PT_HR_ACTIVE_AVAIL (TPM_PT)(PT_VAR + 6) +#define TPM_PT_HR_TRANSIENT_AVAIL (TPM_PT)(PT_VAR + 7) +#define TPM_PT_HR_PERSISTENT (TPM_PT)(PT_VAR + 8) +#define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR + 9) +#define TPM_PT_NV_COUNTERS (TPM_PT)(PT_VAR + 10) +#define TPM_PT_NV_COUNTERS_AVAIL (TPM_PT)(PT_VAR + 11) +#define TPM_PT_ALGORITHM_SET (TPM_PT)(PT_VAR + 12) +#define TPM_PT_LOADED_CURVES (TPM_PT)(PT_VAR + 13) +#define TPM_PT_LOCKOUT_COUNTER (TPM_PT)(PT_VAR + 14) +#define TPM_PT_MAX_AUTH_FAIL (TPM_PT)(PT_VAR + 15) +#define TPM_PT_LOCKOUT_INTERVAL (TPM_PT)(PT_VAR + 16) +#define TPM_PT_LOCKOUT_RECOVERY (TPM_PT)(PT_VAR + 17) +#define TPM_PT_NV_WRITE_RECOVERY (TPM_PT)(PT_VAR + 18) +#define TPM_PT_AUDIT_COUNTER_0 (TPM_PT)(PT_VAR + 19) +#define TPM_PT_AUDIT_COUNTER_1 (TPM_PT)(PT_VAR + 20) + +// Table 22 -- TPM_PT_PCR Constants <I/O,S> +typedef UINT32 TPM_PT_PCR; + +#define TPM_PT_PCR_FIRST (TPM_PT_PCR)(0x00000000) +#define TPM_PT_PCR_SAVE (TPM_PT_PCR)(0x00000000) +#define TPM_PT_PCR_EXTEND_L0 (TPM_PT_PCR)(0x00000001) +#define TPM_PT_PCR_RESET_L0 (TPM_PT_PCR)(0x00000002) +#define TPM_PT_PCR_EXTEND_L1 (TPM_PT_PCR)(0x00000003) +#define TPM_PT_PCR_RESET_L1 (TPM_PT_PCR)(0x00000004) +#define TPM_PT_PCR_EXTEND_L2 (TPM_PT_PCR)(0x00000005) +#define TPM_PT_PCR_RESET_L2 (TPM_PT_PCR)(0x00000006) +#define TPM_PT_PCR_EXTEND_L3 (TPM_PT_PCR)(0x00000007) +#define TPM_PT_PCR_RESET_L3 (TPM_PT_PCR)(0x00000008) +#define TPM_PT_PCR_EXTEND_L4 (TPM_PT_PCR)(0x00000009) +#define TPM_PT_PCR_RESET_L4 (TPM_PT_PCR)(0x0000000A) +#define TPM_PT_PCR_DRTM_RESET (TPM_PT_PCR)(0x0000000B) +#define TPM_PT_PCR_POLICY (TPM_PT_PCR)(0x0000000C) +#define TPM_PT_PCR_AUTH (TPM_PT_PCR)(0x0000000D) +#define TPM_PT_PCR_LAST (TPM_PT_PCR)(0x0000000D) + +// Table 23 -- TPM_PS Constants <O,S> +typedef UINT32 TPM_PS; + +#define TPM_PS_MAIN (TPM_PS)(0x00000000) +#define TPM_PS_PC (TPM_PS)(0x00000001) +#define TPM_PS_PDA (TPM_PS)(0x00000002) +#define TPM_PS_CELL_PHONE (TPM_PS)(0x00000003) +#define TPM_PS_SERVER (TPM_PS)(0x00000004) +#define TPM_PS_PERIPHERAL (TPM_PS)(0x00000005) +#define TPM_PS_TSS (TPM_PS)(0x00000006) +#define TPM_PS_STORAGE (TPM_PS)(0x00000007) +#define TPM_PS_AUTHENTICATION (TPM_PS)(0x00000008) +#define TPM_PS_EMBEDDED (TPM_PS)(0x00000009) +#define TPM_PS_HARDCOPY (TPM_PS)(0x0000000A) +#define TPM_PS_INFRASTRUCTURE (TPM_PS)(0x0000000B) +#define TPM_PS_VIRTUALIZATION (TPM_PS)(0x0000000C) +#define TPM_PS_TNC (TPM_PS)(0x0000000D) +#define TPM_PS_MULTI_TENANT (TPM_PS)(0x0000000E) +#define TPM_PS_TC (TPM_PS)(0x0000000F) + +// Table 24 -- Handles Types <I/O> +typedef UINT32 TPM_HANDLE; +typedef UINT8 TPM_HT; + +#define TPM_HT_PCR (TPM_HT)(0x00) +#define TPM_HT_NV_INDEX (TPM_HT)(0x01) +#define TPM_HT_HMAC_SESSION (TPM_HT)(0x02) +#define TPM_HT_LOADED_SESSION (TPM_HT)(0x02) +#define TPM_HT_POLICY_SESSION (TPM_HT)(0x03) +#define TPM_HT_ACTIVE_SESSION (TPM_HT)(0x03) +#define TPM_HT_PERMANENT (TPM_HT)(0x40) +#define TPM_HT_TRANSIENT (TPM_HT)(0x80) +#define TPM_HT_PERSISTENT (TPM_HT)(0x81) + +// Table 26 -- TPM_RH Constants <I,S> +typedef UINT32 TPM_RH; + +#define TPM_RH_FIRST (TPM_RH)(0x40000000) +#define TPM_RH_SRK (TPM_RH)(0x40000000) +#define TPM_RH_OWNER (TPM_RH)(0x40000001) +#define TPM_RH_REVOKE (TPM_RH)(0x40000002) +#define TPM_RH_TRANSPORT (TPM_RH)(0x40000003) +#define TPM_RH_OPERATOR (TPM_RH)(0x40000004) +#define TPM_RH_ADMIN (TPM_RH)(0x40000005) +#define TPM_RH_EK (TPM_RH)(0x40000006) +#define TPM_RH_NULL (TPM_RH)(0x40000007) +#define TPM_RH_UNASSIGNED (TPM_RH)(0x40000008) +#define TPM_RH_PW (TPM_RH)(0x40000009) +#define TPM_RS_PW (TPM_RH)(0x40000009) +#define TPM_RH_LOCKOUT (TPM_RH)(0x4000000A) +#define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B) +#define TPM_RH_PLATFORM (TPM_RH)(0x4000000C) +#define TPM_RH_LAST (TPM_RH)(0x4000000C) +#define TPM_RH_PCR0 (TPM_RH)(0x00000000) + +// Table 27 -- TPM_HC Constants <I,S> +typedef TPM_HANDLE TPM_HC; + +#define HR_HANDLE_MASK (TPM_HC)(0x00FFFFFF) +#define HR_RANGE_MASK (TPM_HC)(0xFF000000) +#define HR_SHIFT (TPM_HC)(24) +#define HR_PCR (TPM_HC)((TPM_HC)TPM_HT_PCR << HR_SHIFT) +#define HR_HMAC_SESSION (TPM_HC)((TPM_HC)TPM_HT_HMAC_SESSION << HR_SHIFT) +#define HR_POLICY_SESSION (TPM_HC)((TPM_HC)TPM_HT_POLICY_SESSION << HR_SHIFT) +#define HR_TRANSIENT (TPM_HC)((TPM_HC)TPM_HT_TRANSIENT << HR_SHIFT) +#define HR_PERSISTENT (TPM_HC)((TPM_HC)TPM_HT_PERSISTENT << HR_SHIFT) +#define HR_NV_INDEX (TPM_HC)((TPM_HC)TPM_HT_NV_INDEX << HR_SHIFT) +#define HR_PERMANENT (TPM_HC)((TPM_HC)TPM_HT_PERMANENT << HR_SHIFT) +#define PCR_FIRST (TPM_HC)(TPM_RH_PCR0) +#define PCR_LAST (TPM_HC)(PCR_FIRST + IMPLEMENTATION_PCR-1) +#define HMAC_SESSION_FIRST (TPM_HC)(HR_HMAC_SESSION + 0) +#define HMAC_SESSION_LAST (TPM_HC)(HMAC_SESSION_FIRST+MAX_ACTIVE_SESSIONS-1) +#define LOADED_SESSION_FIRST (TPM_HC)(HMAC_SESSION_FIRST) +#define LOADED_SESSION_LAST (TPM_HC)(HMAC_SESSION_LAST) +#define POLICY_SESSION_FIRST (TPM_HC)(HR_POLICY_SESSION + 0) +#define POLICY_SESSION_LAST (TPM_HC)(POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS-1) +#define TRANSIENT_FIRST (TPM_HC)(HR_TRANSIENT + 0) +#define ACTIVE_SESSION_FIRST (TPM_HC)(POLICY_SESSION_FIRST) +#define ACTIVE_SESSION_LAST (TPM_HC)(POLICY_SESSION_LAST) +#define TRANSIENT_LAST (TPM_HC)(TRANSIENT_FIRST+MAX_LOADED_OBJECTS-1) +#define PERSISTENT_FIRST (TPM_HC)(HR_PERSISTENT + 0) +#define PERSISTENT_LAST (TPM_HC)(PERSISTENT_FIRST + 0x00FFFFFF) +#define PLATFORM_PERSISTENT (TPM_HC)(PERSISTENT_FIRST + 0x00800000) +#define NV_INDEX_FIRST (TPM_HC)(HR_NV_INDEX + 0) +#define NV_INDEX_LAST (TPM_HC)(NV_INDEX_FIRST + 0x00FFFFFF) +#define PERMANENT_FIRST (TPM_HC)(TPM_RH_FIRST) +#define PERMANENT_LAST (TPM_HC)(TPM_RH_LAST) + +// Table 28 -- TPMA_ALGORITHM Bits <I/O> +typedef struct { + unsigned int asymmetric : 1; + unsigned int symmetric : 1; + unsigned int hash : 1; + unsigned int object : 1; + unsigned int reserved5 : 4; + unsigned int signing : 1; + unsigned int encrypting : 1; + unsigned int method : 1; + unsigned int reserved9 : 21; +} TPMA_ALGORITHM ; + +// Table 29 -- TPMA_OBJECT Bits <I/O> +typedef struct { + unsigned int reserved1 : 1; + unsigned int fixedTPM : 1; + unsigned int stClear : 1; + unsigned int reserved4 : 1; + unsigned int fixedParent : 1; + unsigned int sensitiveDataOrigin : 1; + unsigned int userWithAuth : 1; + unsigned int adminWithPolicy : 1; + unsigned int Pad9 : 1; //Inserted extra pad + unsigned int reserved9 : 1; + unsigned int noDA : 1; + unsigned int reserved11 : 5; + unsigned int restricted : 1; + unsigned int decrypt : 1; + unsigned int sign : 1; + unsigned int Pad15 : 9; //Inserted extra pad + unsigned int softwareUse : 4; +} TPMA_OBJECT ; + +// Table 30 -- TPMA_SESSION Bits <I/O> +typedef struct { + unsigned int continueSession : 1; + unsigned int auditExclusive : 1; + unsigned int auditReset : 1; + unsigned int reserved4 : 2; + unsigned int decrypt : 1; + unsigned int encrypt : 1; + unsigned int audit : 1; +} TPMA_SESSION ; + +// Table 31 -- TPMA_LOCALITY Bits <I/O> +// +// BUGBUG: Use low case here to resolve conflict +// +typedef struct { + unsigned int locZero : 1; + unsigned int locOne : 1; + unsigned int locTwo : 1; + unsigned int locThree : 1; + unsigned int locFour : 1; + unsigned int reserved6 : 3; +} TPMA_LOCALITY ; + +// Table 32 -- TPMA_PERMANENT Bits <O,S> +typedef struct { + unsigned int ownerAuthSet : 1; + unsigned int endorsementAuthSet : 1; + unsigned int lockoutAuthSet : 1; + unsigned int reserved4 : 5; + unsigned int disableClear : 1; + unsigned int inLockout : 1; + unsigned int tpmGeneratedEPS : 1; + unsigned int reserved8 : 21; +} TPMA_PERMANENT ; + +// Table 33 -- TPMA_STARTUP_CLEAR Bits <O,S> +typedef struct { + unsigned int phEnable : 1; + unsigned int shEnable : 1; + unsigned int ehEnable : 1; + unsigned int reserved4 : 28; + unsigned int orderly : 1; +} TPMA_STARTUP_CLEAR ; + +// Table 34 -- TPMA_MEMORY Bits <O,S> +typedef struct { + unsigned int sharedRAM : 1; + unsigned int sharedNV : 1; + unsigned int objectCopiedToRam : 1; + unsigned int reserved4 : 29; +} TPMA_MEMORY ; + +// Table 35 -- TPMA_CC Bits <O,S> +typedef struct { + unsigned int commandIndex : 16; + unsigned int reserved2 : 6; + unsigned int nv : 1; + unsigned int extensive : 1; + unsigned int flushed : 1; + unsigned int cHandles : 3; + unsigned int rHandle : 1; + unsigned int V : 1; + unsigned int reserved9 : 2; +} TPMA_CC ; + +// Table 36 -- TPMI_YES_NO Type <I/O> +typedef BYTE TPMI_YES_NO; + +// Table 37 -- TPMI_DH_OBJECT Type <I/O> +typedef TPM_HANDLE TPMI_DH_OBJECT; + +// Table 38 -- TPMI_DH_PERSISTENT Type <I/O> +typedef TPM_HANDLE TPMI_DH_PERSISTENT; + +// Table 39 -- TPMI_DH_ENTITY Type <I> +typedef TPM_HANDLE TPMI_DH_ENTITY; + +// Table 40 -- TPMI_DH_PCR Type <I> +typedef TPM_HANDLE TPMI_DH_PCR; + +// Table 41 -- TPMI_SH_AUTH_SESSION Type <I/O> +typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; + +// Table 42 -- TPMI_SH_HMAC Type <I/O> +typedef TPM_HANDLE TPMI_SH_HMAC; + +// Table 43 -- TPMI_SH_POLICY Type <I/O> +typedef TPM_HANDLE TPMI_SH_POLICY; + +// Table 44 -- TPMI_DH_CONTEXT Type <I/O> +typedef TPM_HANDLE TPMI_DH_CONTEXT; + +// Table 45 -- TPMI_RH_HIERARCHY Type <I/O> +typedef TPM_HANDLE TPMI_RH_HIERARCHY; + +// Table 46 -- TPMI_RH_HIERARCHY_AUTH Type <I> +typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH; + +// Table 47 -- TPMI_RH_PLATFORM Type <I> +typedef TPM_HANDLE TPMI_RH_PLATFORM; + +// Table 48 -- TPMI_RH_OWNER Type <I> +typedef TPM_HANDLE TPMI_RH_OWNER; + +// Table 49 -- TPMI_RH_ENDORSEMENT Type <I> +typedef TPM_HANDLE TPMI_RH_ENDORSEMENT; + +// Table 50 -- TPMI_RH_PROVISION Type <I> +typedef TPM_HANDLE TPMI_RH_PROVISION; + +// Table 51 -- TPMI_RH_CLEAR Type <I> +typedef TPM_HANDLE TPMI_RH_CLEAR; + +// Table 52 -- TPMI_RH_NV_AUTH Type <I> +typedef TPM_HANDLE TPMI_RH_NV_AUTH; + +// Table 53 -- TPMI_RH_LOCKOUT Type <I> +typedef TPM_HANDLE TPMI_RH_LOCKOUT; + +// Table 54 -- TPMI_RH_NV_INDEX Type <I/O> +typedef TPM_HANDLE TPMI_RH_NV_INDEX; + +// Table 55 -- TPMI_ALG_HASH Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_HASH; + +// Table 56 -- TPMI_ALG_ASYM Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_ASYM; + +// Table 57 -- TPMI_ALG_SYM Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_SYM; + +// Table 58 -- TPMI_ALG_SYM_OBJECT Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT; + +// Table 59 -- TPMI_ALG_SYM_MODE Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_SYM_MODE; + +// Table 60 -- TPMI_ALG_KDF Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_KDF; + +// Table 61 -- TPMI_ALG_SIG_SCHEME Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; + +// Table 62 -- TPMI_ST_COMMAND_TAG Type <I/O> +typedef TPM_ST TPMI_ST_COMMAND_TAG; + +// Table 63 -- TPMS_ALGORITHM_DESCRIPTION Structure <O,S> +typedef struct { + TPM_ALG_ID alg; + TPMA_ALGORITHM attributes; +} TPMS_ALGORITHM_DESCRIPTION; + +// Table 64 -- TPMU_HA Union <I/O,S> +typedef union { + BYTE sha1[SHA1_DIGEST_SIZE]; + BYTE sha256[SHA256_DIGEST_SIZE]; + BYTE sm3_256[SM3_256_DIGEST_SIZE]; + BYTE sha384[SHA384_DIGEST_SIZE]; + BYTE sha512[SHA512_DIGEST_SIZE]; + BYTE whirlpool[WHIRLPOOL512_DIGEST_SIZE]; +} TPMU_HA ; + +// Table 65 -- TPMT_HA Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; + TPMU_HA digest; +} TPMT_HA; + +// Table 66 -- TPM2B_DIGEST Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(TPMU_HA)]; +} DIGEST_2B; + +typedef union { + DIGEST_2B t; + TPM2B b; +} TPM2B_DIGEST; + +// Table 67 -- TPM2B_DATA Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(TPMT_HA)]; +} DATA_2B; + +typedef union { + DATA_2B t; + TPM2B b; +} TPM2B_DATA; + +// Table 68 -- TPM2B_NONCE Types <I/O> +typedef TPM2B_DIGEST TPM2B_NONCE; + +// Table 69 -- TPM2B_AUTH Types <I/O> +typedef TPM2B_DIGEST TPM2B_AUTH; + +// Table 70 -- TPM2B_OPERAND Types <I/O> +typedef TPM2B_DIGEST TPM2B_OPERAND; + +// Table 71 -- TPM2B_EVENT Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[1024]; +} EVENT_2B; + +typedef union { + EVENT_2B t; + TPM2B b; +} TPM2B_EVENT; + +// Table 72 -- TPM2B_MAX_BUFFER Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_DIGEST_BUFFER]; +} MAX_BUFFER_2B; + +typedef union { + MAX_BUFFER_2B t; + TPM2B b; +} TPM2B_MAX_BUFFER; + +// Table 73 -- TPM2B_TIMEOUT Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(UINT64)]; +} TIMEOUT_2B; + +typedef union { + TIMEOUT_2B t; + TPM2B b; +} TPM2B_TIMEOUT; + +// Table 74 -- TPM2B_IV Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_SYM_BLOCK_SIZE]; +} IV_2B; + +typedef union { + IV_2B t; + TPM2B b; +} TPM2B_IV; +typedef union { + TPMT_HA digest; + TPM_HANDLE handle; + +} TPMU_NAME ; + +// Table 76 -- TPM2B_NAME Structure <I/O> +typedef struct { + UINT16 size; + BYTE name[sizeof(TPMU_NAME)]; +} NAME_2B; + +typedef union { + NAME_2B t; + TPM2B b; +} TPM2B_NAME; + +// Table 77 -- TPMS_PCR_SELECT Structure <I/O> +typedef struct { + UINT8 sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MAX]; +} TPMS_PCR_SELECT; + +// Table 78 -- TPMS_PCR_SELECTION Structure <I/O> +typedef struct { + TPMI_ALG_HASH hash; + UINT8 sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MAX]; +} TPMS_PCR_SELECTION; + +// Table 82 -- TPMT_TK_CREATION Structure <I/O> +typedef struct { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_CREATION; + +// Table 83 -- TPMT_TK_VERIFIED Structure <I/O> +typedef struct { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_VERIFIED; + +// Table 84 -- TPMT_TK_AUTH Structure <I/O> +typedef struct { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_AUTH; + +// Table 85 -- TPMT_TK_HASHCHECK Structure <I/O> +typedef struct { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_HASHCHECK; + +// Table 86 -- TPMS_ALG_PROPERTY Structure <O,S> +typedef struct { + TPM_ALG_ID alg; + TPMA_ALGORITHM algProperties; +} TPMS_ALG_PROPERTY; + +// Table 87 -- TPMS_TAGGED_PROPERTY Structure <O,S> +typedef struct { + TPM_PT property; + UINT32 value; +} TPMS_TAGGED_PROPERTY; + +// Table 88 -- TPMS_TAGGED_PCR_SELECT Structure <O,S> +typedef struct { + TPM_PT tag; + UINT8 sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MAX]; +} TPMS_TAGGED_PCR_SELECT; + +// Table 89 -- TPML_CC Structure <I/O> +typedef struct { + UINT32 count; + TPM_CC commandCodes[MAX_CAP_CC]; +} TPML_CC; + +// Table 90 -- TPML_CCA Structure <O,S> +typedef struct { + UINT32 count; + TPMA_CC commandAttributes[MAX_CAP_CC]; +} TPML_CCA; + +// Table 91 -- TPML_ALG Structure <I/O> +typedef struct { + UINT32 count; + TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE]; +} TPML_ALG; + +// Table 92 -- TPML_HANDLE Structure <O,S> +typedef struct { + UINT32 count; + TPM_HANDLE handle[MAX_CAP_HANDLES]; +} TPML_HANDLE; + +// Table 93 -- TPML_DIGEST Structure <I/O> +typedef struct { + UINT32 count; + TPM2B_DIGEST digests[8]; +} TPML_DIGEST; + +// Table 94 -- TPML_DIGEST_VALUES Structure <I/O> +typedef struct { + UINT32 count; + TPMT_HA digests[HASH_COUNT]; +} TPML_DIGEST_VALUES; + +// Table 95 -- TPM2B_DIGEST_VALUES Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(TPML_DIGEST_VALUES)]; +} DIGEST_VALUES_2B; + +typedef union { + DIGEST_VALUES_2B t; + TPM2B b; +} TPM2B_DIGEST_VALUES; + +// Table 96 -- TPML_PCR_SELECTION Structure <I/O> +typedef struct { + UINT32 count; + TPMS_PCR_SELECTION pcrSelections[HASH_COUNT]; +} TPML_PCR_SELECTION; + +// Table 97 -- TPML_ALG_PROPERTY Structure <O,S> +typedef struct { + UINT32 count; + TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS]; +} TPML_ALG_PROPERTY; + +// Table 98 -- TPML_TAGGED_TPM_PROPERTY Structure <O,S> +typedef struct { + UINT32 count; + TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES]; +} TPML_TAGGED_TPM_PROPERTY; + +// Table 99 -- TPML_TAGGED_PCR_PROPERTY Structure <O,S> +typedef struct { + UINT32 count; + TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES]; +} TPML_TAGGED_PCR_PROPERTY; + +// Table 100 -- TPML_ECC_CURVE Structure <O,S> +typedef struct { + UINT32 count; + TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES]; +} TPML_ECC_CURVE; + +// Table 101 -- TPMU_CAPABILITIES Union <O,S> +typedef union { + TPML_ALG_PROPERTY algorithms; + TPML_HANDLE handles; + TPML_CCA command; + TPML_CC ppCommands; + TPML_CC auditCommands; + TPML_PCR_SELECTION assignedPCR; + TPML_TAGGED_TPM_PROPERTY tpmProperties; + TPML_TAGGED_PCR_PROPERTY pcrProperties; + TPML_ECC_CURVE eccCurves; + +} TPMU_CAPABILITIES ; + +// Table 102 -- TPMS_CAPABILITY_DATA Structure <O,S> +typedef struct { + TPM_CAP capability; + TPMU_CAPABILITIES data; +} TPMS_CAPABILITY_DATA; + +// Table 103 -- TPMS_CLOCK_INFO Structure <I/O> +typedef struct { + UINT64 clock; + UINT32 resetCount; + UINT32 restartCount; + TPMI_YES_NO safe; +} TPMS_CLOCK_INFO; + +// Table 104 -- TPMS_TIME_INFO Structure <I/O> +typedef struct { + UINT64 time; + TPMS_CLOCK_INFO clockInfo; +} TPMS_TIME_INFO; + +// Table 105 -- TPMS_TIME_ATTEST_INFO Structure <O,S> +typedef struct { + TPMS_TIME_INFO time; + UINT64 firmwareVersion; +} TPMS_TIME_ATTEST_INFO; + +// Table 106 -- TPMS_CERTIFY_INFO Structure <O,S> +typedef struct { + TPM2B_NAME name; + TPM2B_NAME qualifiedName; +} TPMS_CERTIFY_INFO; + +// Table 107 -- TPMS_QUOTE_INFO Structure <O,S> +typedef struct { + TPML_PCR_SELECTION pcrSelect; + TPM2B_DIGEST pcrDigest; +} TPMS_QUOTE_INFO; + +// Table 108 -- TPMS_COMMAND_AUDIT_INFO Structure <O,S> +typedef struct { + UINT64 auditCounter; + TPM_ALG_ID digestAlg; + TPM2B_DIGEST auditDigest; + TPM2B_DIGEST commandDigest; +} TPMS_COMMAND_AUDIT_INFO; + +// Table 109 -- TPMS_SESSION_AUDIT_INFO Structure <O,S> +typedef struct { + TPMI_YES_NO exclusiveSession; + TPM2B_DIGEST sessionDigest; +} TPMS_SESSION_AUDIT_INFO; + +// Table 110 -- TPMS_CREATION_INFO Structure <O,S> +typedef struct { + TPM2B_NAME objectName; + TPM2B_DIGEST creationHash; +} TPMS_CREATION_INFO; + +// Table 111 -- TPMS_NV_CERTIFY_INFO Structure <O,S> +typedef struct { + TPM2B_MAX_BUFFER nvContents; +} TPMS_NV_CERTIFY_INFO; + +// Table 112 -- TPMI_ST_ATTEST Type <O,S> +typedef TPM_ST TPMI_ST_ATTEST; + +// Table 113 -- TPMU_ATTEST Union <O,S> +typedef union { + TPMS_CERTIFY_INFO certify; + TPMS_CREATION_INFO creation; + TPMS_QUOTE_INFO quote; + TPMS_COMMAND_AUDIT_INFO commandAudit; + TPMS_SESSION_AUDIT_INFO sessionAudit; + TPMS_TIME_ATTEST_INFO time; + TPMS_NV_CERTIFY_INFO nv; + +} TPMU_ATTEST ; + +// Table 114 -- TPMS_ATTEST Structure <O,S> +typedef struct { + TPM_GENERATED magic; + TPMI_ST_ATTEST type; + TPM2B_NAME qualifiedSigner; + TPM2B_DATA extraData; + TPMS_CLOCK_INFO clockInfo; + UINT64 firmwareVersion; + TPMU_ATTEST attested; +} TPMS_ATTEST; + +// Table 115 -- TPM2B_ATTEST Structure <O,S> +typedef struct { + UINT16 size; + BYTE attestationData[sizeof(TPMS_ATTEST)]; +} ATTEST_2B; + +typedef union { + ATTEST_2B t; + TPM2B b; +} TPM2B_ATTEST; + +// Table 116 -- TPMS_AUTH_SESSION_COMMAND Structure <I> +typedef struct { + TPMI_SH_AUTH_SESSION sessionHandle; + TPM2B_NONCE nonce; + TPMA_SESSION sessionAttributes; + TPM2B_AUTH auth; +} TPMS_AUTH_SESSION_COMMAND; + +// Table 117 -- TPMS_AUTH_SESSION_RESPONSE Structure <O,S> +typedef struct { + TPM2B_NONCE nonce; + TPMA_SESSION sessionAttributes; + TPM2B_AUTH auth; +} TPMS_AUTH_SESSION_RESPONSE; +typedef struct { + TPM2B_AUTH sessionKey; + TPM2B_AUTH authValue; + TPM2B_DIGEST pHash; + TPM2B_NONCE nonceNewer; + TPM2B_NONCE nonceOlder; + TPMA_SESSION sessionFlags; +} TPMS_AUTH_COMPUTE_NOT_BOUND; +typedef struct { + TPM2B_DIGEST sessionKey; + TPM2B_DIGEST pHash; + TPM2B_NONCE nonceNewer; + TPM2B_NONCE nonceOlder; + TPMA_SESSION sessionFlags; +} TPMS_AUTH_COMPUTE_BOUND; + +// Table 120 -- TPMI_AES_KEY_BITS Type <I/O> +typedef TPM_KEY_BITS TPMI_AES_KEY_BITS; + +// Table 121 -- TPMI_SMS4_KEY_BITS Type <I/O> +typedef TPM_KEY_BITS TPMI_SMS4_KEY_BITS; + +// Table 122 -- TPMU_SYM_KEY_BITS Union <I/O> +typedef union { + TPMI_AES_KEY_BITS aes; + TPMI_SMS4_KEY_BITS sms4; + TPM_KEY_BITS sym; + TPMI_ALG_HASH xor; + +} TPMU_SYM_KEY_BITS ; + +// Table 123 -- TPMU_SYM_MODE Union <I/O> +typedef union { + TPMI_ALG_SYM_MODE aes; + TPMI_ALG_SYM_MODE sms4; + TPMI_ALG_SYM_MODE sym; + +} TPMU_SYM_MODE ; + +// Table 125 -- TPMT_SYM_DEF Structure <I/O> +typedef struct { + TPMI_ALG_SYM algorithm; + TPMU_SYM_KEY_BITS keyBits; + TPMU_SYM_MODE mode; +} TPMT_SYM_DEF; + +// Table 126 -- TPMT_SYM_DEF_OBJECT Structure <I/O> +typedef struct { + TPMI_ALG_SYM_OBJECT algorithm; + TPMU_SYM_KEY_BITS keyBits; + TPMU_SYM_MODE mode; +} TPMT_SYM_DEF_OBJECT; + +// Table 127 -- TPM2B_SYM_KEY Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_SYM_KEY_BYTES]; +} SYM_KEY_2B; + +typedef union { + SYM_KEY_2B t; + TPM2B b; +} TPM2B_SYM_KEY; + +// Table 128 -- TPMS_SYMCIPHER_PARMS Structure <I/O> +typedef struct { + TPMT_SYM_DEF_OBJECT sym; +} TPMS_SYMCIPHER_PARMS; + +// Table 129 -- TPM2B_SENSITIVE_DATA Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_SYM_DATA]; +} SENSITIVE_DATA_2B; + +typedef union { + SENSITIVE_DATA_2B t; + TPM2B b; +} TPM2B_SENSITIVE_DATA; + +// Table 130 -- TPMS_SENSITIVE_CREATE Structure <I> +typedef struct { + TPM2B_AUTH userAuth; + TPM2B_SENSITIVE_DATA data; +} TPMS_SENSITIVE_CREATE; + +// Table 131 -- TPM2B_SENSITIVE_CREATE Structure <I,S> +typedef struct { + UINT16 size; + TPMS_SENSITIVE_CREATE sensitive; +} SENSITIVE_CREATE_2B; + +typedef union { + SENSITIVE_CREATE_2B t; + TPM2B b; +} TPM2B_SENSITIVE_CREATE; + +// Table 132 -- TPMS_SCHEME_SIGHASH Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_SIGHASH; + +// Table 133 -- TPMI_ALG_KEYEDHASH_SCHEME Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME; + +// Table 134 -- HMAC_SIG_SCHEME Types <I/O> +typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_HMAC; + +// Table 135 -- TPMS_SCHEME_XOR Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; + TPMI_ALG_KDF kdf; +} TPMS_SCHEME_XOR; + +// Table 136 -- TPMU_SCHEME_KEYEDHASH Union <I/O,S> +typedef union { + TPMS_SCHEME_HMAC hmac; + TPMS_SCHEME_XOR xor; + +} TPMU_SCHEME_KEYEDHASH ; + +// Table 137 -- TPMT_KEYEDHASH_SCHEME Structure <I/O> +typedef struct { + TPMI_ALG_KEYEDHASH_SCHEME scheme; + TPMU_SCHEME_KEYEDHASH details; +} TPMT_KEYEDHASH_SCHEME; + +// Table 138 -- RSA_SIG_SCHEMES Types <I/O> +typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSASSA; +typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSAPSS; + +// Table 139 -- ECC_SIG_SCHEMES Types <I/O> +typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECDSA; + +// Table 140 -- TPMS_SCHEME_ECDAA Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_ECDAA; + +// Table 141 -- TPMS_SCHEME_ECSCHNORR Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; + UINT16 count; +} TPMS_SCHEME_ECSCHNORR; + +// Table 142 -- TPMU_SIG_SCHEME Union <I/O,S> +typedef union { + TPMS_SCHEME_RSASSA rsassa; + TPMS_SCHEME_RSAPSS rsapss; + TPMS_SCHEME_ECDSA ecdsa; + TPMS_SCHEME_ECDAA ecdaa; + TPMS_SCHEME_ECSCHNORR ecSchnorr; + TPMS_SCHEME_HMAC hmac; + TPMS_SCHEME_SIGHASH any; + +} TPMU_SIG_SCHEME ; + +// Table 143 -- TPMT_SIG_SCHEME Structure <I/O> +typedef struct { + TPMI_ALG_SIG_SCHEME scheme; + TPMU_SIG_SCHEME details; +} TPMT_SIG_SCHEME; + +// Table 144 -- TPMS_SCHEME_OAEP Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_OAEP; + +// Table 145 -- TPMS_SCHEME_ECDH Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_ECDH; + +// Table 146 -- TPMS_SCHEME_MGF1 Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_MGF1; + +// Table 147 -- TPMS_SCHEME_KDF1_SP800_56a Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_KDF1_SP800_56a; + +// Table 148 -- TPMS_SCHEME_KDF2 Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_KDF2; + +// Table 149 -- TPMS_SCHEME_KDF1_SP800_108 Structure <I/O> +typedef struct { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_KDF1_SP800_108; + +// Table 150 -- TPMU_KDF_SCHEME Union <I/O,S> +typedef union { + TPMS_SCHEME_MGF1 mgf1; + TPMS_SCHEME_KDF1_SP800_56a kdf1_SP800_56a; + TPMS_SCHEME_KDF2 kdf2; + TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108; +} TPMU_KDF_SCHEME ; + +// Table 151 -- TPMT_KDF_SCHEME Structure <I/O> +typedef struct { + TPMI_ALG_KDF scheme; + TPMU_KDF_SCHEME details; +} TPMT_KDF_SCHEME; +typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; + +// Table 153 -- TPMU_ASYM_SCHEME Union <I/O> +typedef union { + TPMS_SCHEME_RSASSA rsassa; + TPMS_SCHEME_RSAPSS rsapss; + TPMS_SCHEME_OAEP oaep; + TPMS_SCHEME_ECDSA ecdsa; + TPMS_SCHEME_ECDAA ecdaa; + TPMS_SCHEME_ECSCHNORR ecSchnorr; + TPMS_SCHEME_SIGHASH anySig; + +} TPMU_ASYM_SCHEME ; + +typedef struct { + TPMI_ALG_ASYM_SCHEME scheme; + TPMU_ASYM_SCHEME details; +} TPMT_ASYM_SCHEME; + +// Table 155 -- TPMI_ALG_RSA_SCHEME Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; + +// Table 156 -- TPMT_RSA_SCHEME Structure <I/O> +typedef struct { + TPMI_ALG_RSA_SCHEME scheme; + TPMU_ASYM_SCHEME details; +} TPMT_RSA_SCHEME; + +// Table 157 -- TPMI_ALG_RSA_DECRYPT Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT; + +// Table 158 -- TPMT_RSA_DECRYPT Structure <I/O> +typedef struct { + TPMI_ALG_RSA_DECRYPT scheme; + TPMU_ASYM_SCHEME details; +} TPMT_RSA_DECRYPT; + +// Table 159 -- TPM2B_PUBLIC_KEY_RSA Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_RSA_KEY_BYTES]; +} PUBLIC_KEY_RSA_2B; + +typedef union { + PUBLIC_KEY_RSA_2B t; + TPM2B b; +} TPM2B_PUBLIC_KEY_RSA; + +// Table 160 -- TPMI_RSA_KEY_BITS Type <I/O> +typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS; + +// Table 161 -- TPM2B_PRIVATE_KEY_RSA Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_RSA_KEY_BYTES/2]; +} PRIVATE_KEY_RSA_2B; + +typedef union { + PRIVATE_KEY_RSA_2B t; + TPM2B b; +} TPM2B_PRIVATE_KEY_RSA; + +// Table 162 -- TPM2B_ECC_PARAMETER Structure <I/O> +typedef struct { + UINT16 size; + BYTE value[MAX_ECC_KEY_BYTES]; +} ECC_PARAMETER_2B; + +typedef union { + ECC_PARAMETER_2B t; + TPM2B b; +} TPM2B_ECC_PARAMETER; + +// Table 163 -- TPMS_ECC_POINT Structure <I/O> +typedef struct { + TPM2B_ECC_PARAMETER pointX; + TPM2B_ECC_PARAMETER pointY; +} TPMS_ECC_POINT; + +// Table 164 -- TPM2B_ECC_POINT Structure <I/O> +typedef struct { + UINT16 size; + TPMS_ECC_POINT point; +} ECC_POINT_2B; + +typedef union { + ECC_POINT_2B t; + TPM2B b; +} TPM2B_ECC_POINT; + +// Table 165 -- TPMI_ALG_ECC_SCHEME Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; + +// Table 166 -- TPMI_ECC_CURVE Type <I/O> +typedef TPM_ECC_CURVE TPMI_ECC_CURVE; + +// Table 167 -- TPMT_ECC_SCHEME Structure <I/O> +typedef struct { + TPMI_ALG_ECC_SCHEME scheme; + TPMU_SIG_SCHEME details; +} TPMT_ECC_SCHEME; + +// Table 168 -- TPMS_ALGORITHM_DETAIL_ECC Structure <O,S> +typedef struct { + TPM_ECC_CURVE curveID; + UINT16 keySize; + TPMT_KDF_SCHEME kdf; + TPMT_ECC_SCHEME sign; + TPM2B_ECC_PARAMETER p; + TPM2B_ECC_PARAMETER a; + TPM2B_ECC_PARAMETER b; + TPM2B_ECC_PARAMETER gX; + TPM2B_ECC_PARAMETER gY; + TPM2B_ECC_PARAMETER n; + TPM2B_ECC_PARAMETER h; +} TPMS_ALGORITHM_DETAIL_ECC; + +// Table 169 -- TPMS_SIGNATURE_RSASSA Structure <I/O> +typedef struct { + TPMI_ALG_HASH hash; + TPM2B_PUBLIC_KEY_RSA sig; +} TPMS_SIGNATURE_RSASSA; + +// Table 170 -- TPMS_SIGNATURE_RSAPSS Structure <I/O> +typedef struct { + TPMI_ALG_HASH hash; + TPM2B_PUBLIC_KEY_RSA sig; +} TPMS_SIGNATURE_RSAPSS; + +// Table 171 -- TPMS_SIGNATURE_ECDSA Structure <I/O> +typedef struct { + TPMI_ALG_HASH hash; + TPM2B_ECC_PARAMETER signatureR; + TPM2B_ECC_PARAMETER signatureS; +} TPMS_SIGNATURE_ECDSA; + +// Table 172 -- TPMU_SIGNATURE Union <I/O,S> +typedef union { + TPMS_SIGNATURE_RSASSA rsassa; + TPMS_SIGNATURE_RSAPSS rsapss; + TPMS_SIGNATURE_ECDSA ecdsa; + TPMT_HA hmac; +} TPMU_SIGNATURE ; + +// Table 173 -- TPMT_SIGNATURE Structure <I/O> +typedef struct { + TPMI_ALG_SIG_SCHEME sigAlg; + TPMU_SIGNATURE signature; +} TPMT_SIGNATURE; +typedef union { + BYTE ecc[sizeof(TPMS_ECC_POINT)]; + BYTE rsa[MAX_RSA_KEY_BYTES]; + BYTE symmetric[sizeof(TPM2B_DIGEST)]; + BYTE keyedHash[sizeof(TPM2B_DIGEST)]; +} TPMU_ENCRYPTED_SECRET ; + +// Table 175 -- TPM2B_ENCRYPTED_SECRET Structure <I/O> +typedef struct { + UINT16 size; + BYTE secret[sizeof(TPMU_ENCRYPTED_SECRET)]; +} ENCRYPTED_SECRET_2B; + +typedef union { + ENCRYPTED_SECRET_2B t; + TPM2B b; +} TPM2B_ENCRYPTED_SECRET; + +// Table 176 -- TPMI_ALG_PUBLIC Type <I/O> +typedef TPM_ALG_ID TPMI_ALG_PUBLIC; + +// Table 177 -- TPMU_PUBLIC_ID Union <I/O,S> +typedef union { + TPM2B_DIGEST keyedHash; + TPM2B_DIGEST sym; + TPM2B_PUBLIC_KEY_RSA rsa; + TPMS_ECC_POINT ecc; + +} TPMU_PUBLIC_ID ; + +// Table 178 -- TPMS_KEYEDHASH_PARMS Structure <I/O> +typedef struct { + TPMT_KEYEDHASH_SCHEME scheme; +} TPMS_KEYEDHASH_PARMS; +typedef struct { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_ASYM_SCHEME scheme; +} TPMS_ASYM_PARMS; + +// Table 180 -- TPMS_RSA_PARMS Structure <I/O> +typedef struct { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_RSA_SCHEME scheme; + TPMI_RSA_KEY_BITS keyBits; + UINT32 exponent; +} TPMS_RSA_PARMS; + +// Table 181 -- TPMS_ECC_PARMS Structure <I/O> +typedef struct { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_ECC_SCHEME scheme; + TPMI_ECC_CURVE curveID; + TPMT_KDF_SCHEME kdf; +} TPMS_ECC_PARMS; + +// Table 182 -- TPMU_PUBLIC_PARMS Union <I/O,S> +typedef union { + TPMS_KEYEDHASH_PARMS keyedHashDetail; + TPMT_SYM_DEF_OBJECT symDetail; + TPMS_RSA_PARMS rsaDetail; + TPMS_ECC_PARMS eccDetail; + TPMS_ASYM_PARMS asymDetail; + +} TPMU_PUBLIC_PARMS ; + +// Table 183 -- TPMT_PUBLIC_PARMS Structure <I/O> +typedef struct { + TPMI_ALG_PUBLIC type; + TPMU_PUBLIC_PARMS parameters; +} TPMT_PUBLIC_PARMS; + +// Table 184 -- TPMT_PUBLIC Structure <I/O> +typedef struct { + TPMI_ALG_PUBLIC type; + TPMI_ALG_HASH nameAlg; + TPMA_OBJECT objectAttributes; + TPM2B_DIGEST authPolicy; + TPMU_PUBLIC_PARMS parameters; + TPMU_PUBLIC_ID unique; +} TPMT_PUBLIC; + +// Table 185 -- TPM2B_PUBLIC Structure <I/O> +typedef struct { + UINT16 size; + TPMT_PUBLIC publicArea; +} PUBLIC_2B; + +typedef union { + PUBLIC_2B t; + TPM2B b; +} TPM2B_PUBLIC; + +// Table 186 -- TPMU_SENSITIVE_COMPOSITE Union <I/O,S> +typedef union { + TPM2B_PRIVATE_KEY_RSA rsa; + TPM2B_ECC_PARAMETER ecc; + TPM2B_SENSITIVE_DATA bits; + TPM2B_SYM_KEY sym; + TPM2B_SENSITIVE_DATA any; + +} TPMU_SENSITIVE_COMPOSITE ; + +// Table 187 -- TPMT_SENSITIVE Structure <I/O> +typedef struct { + TPMI_ALG_PUBLIC sensitiveType; + TPM2B_AUTH authValue; + TPM2B_DIGEST seedValue; + TPMU_SENSITIVE_COMPOSITE sensitive; +} TPMT_SENSITIVE; + +// Table 188 -- TPM2B_SENSITIVE Structure <I/O> +typedef struct { + UINT16 size; + TPMT_SENSITIVE sensitiveArea; +} SENSITIVE_2B; + +typedef union { + SENSITIVE_2B t; + TPM2B b; +} TPM2B_SENSITIVE; +typedef struct { + TPM2B_DIGEST integrityOuter; + TPM2B_DIGEST integrityInner; + TPMT_SENSITIVE sensitive; +} _PRIVATE; + +// Table 190 -- TPM2B_PRIVATE Structure <I/O,S> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(_PRIVATE)]; +} PRIVATE_2B; + +typedef union { + PRIVATE_2B t; + TPM2B b; +} TPM2B_PRIVATE; +typedef struct { + TPM2B_DIGEST integrityHMAC; + TPM2B_DIGEST encIdentity; +} _ID_OBJECT; + +// Table 192 -- TPM2B_ID_OBJECT Structure <I/O> +typedef struct { + UINT16 size; + BYTE credential[sizeof(_ID_OBJECT)]; +} ID_OBJECT_2B; + +typedef union { + ID_OBJECT_2B t; + TPM2B b; +} TPM2B_ID_OBJECT; +// +// BUGBUG: Comment here to resolve conflict +// +//typedef struct { +// unsigned int index : 22; +// unsigned int space : 2; +// unsigned int RH_NV : 8; +//} TPM_NV_INDEX ; + +// Table 195 -- TPMA_NV Bits <I/O> +typedef struct { + unsigned int TPMA_NV_PPWRITE : 1; + unsigned int TPMA_NV_OWNERWRITE : 1; + unsigned int TPMA_NV_AUTHWRITE : 1; + unsigned int TPMA_NV_POLICYWRITE : 1; + unsigned int TPMA_NV_COUNTER : 1; + unsigned int TPMA_NV_BITS : 1; + unsigned int TPMA_NV_EXTEND : 1; + unsigned int reserved8 : 3; + unsigned int TPMA_NV_POLICY_DELETE : 1; + unsigned int TPMA_NV_WRITELOCKED : 1; + unsigned int TPMA_NV_WRITEALL : 1; + unsigned int TPMA_NV_WRITEDEFINE : 1; + unsigned int TPMA_NV_WRITE_STCLEAR : 1; + unsigned int TPMA_NV_GLOBALLOCK : 1; + unsigned int TPMA_NV_PPREAD : 1; + unsigned int TPMA_NV_OWNERREAD : 1; + unsigned int TPMA_NV_AUTHREAD : 1; + unsigned int TPMA_NV_POLICYREAD : 1; + unsigned int reserved19 : 5; + unsigned int TPMA_NV_NO_DA : 1; + unsigned int TPMA_NV_ORDERLY : 1; + unsigned int TPMA_NV_CLEAR_STCLEAR : 1; + unsigned int TPMA_NV_READLOCKED : 1; + unsigned int TPMA_NV_WRITTEN : 1; + unsigned int TPMA_NV_PLATFORMCREATE : 1; + unsigned int TPMA_NV_READ_STCLEAR : 1; +} TPMA_NV ; + +// Table 196 -- TPMS_NV_PUBLIC Structure <I/O> +typedef struct { + TPMI_RH_NV_INDEX nvIndex; + TPMI_ALG_HASH nameAlg; + TPMA_NV attributes; + TPM2B_DIGEST authPolicy; + UINT16 dataSize; +} TPMS_NV_PUBLIC; + +// Table 197 -- TPM2B_NV_PUBLIC Structure <I/O> +typedef struct { + UINT16 size; + TPMS_NV_PUBLIC nvPublic; +} NV_PUBLIC_2B; + +typedef union { + NV_PUBLIC_2B t; + TPM2B b; +} TPM2B_NV_PUBLIC; + +// Table 198 -- TPM2B_CONTEXT_SENSITIVE Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[MAX_CONTEXT_SIZE]; +} CONTEXT_SENSITIVE_2B; + +typedef union { + CONTEXT_SENSITIVE_2B t; + TPM2B b; +} TPM2B_CONTEXT_SENSITIVE; + +// Table 199 -- TPMS_CONTEXT_DATA Structure <I/O,S> +typedef struct { + TPM2B_DIGEST integrity; + TPM2B_CONTEXT_SENSITIVE encrypted; +} TPMS_CONTEXT_DATA; + +// Table 200 -- TPM2B_CONTEXT_DATA Structure <I/O> +typedef struct { + UINT16 size; + BYTE buffer[sizeof(TPMS_CONTEXT_DATA)]; +} CONTEXT_DATA_2B; + +typedef union { + CONTEXT_DATA_2B t; + TPM2B b; +} TPM2B_CONTEXT_DATA; + +// Table 201 -- TPMS_CONTEXT Structure <I/O> +typedef struct { + UINT64 sequence; + TPMI_DH_CONTEXT savedHandle; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_CONTEXT_DATA contextBlob; +} TPMS_CONTEXT; + +// Table 203 -- TPMS_CREATION_DATA Structure <O,S> +typedef struct { + TPML_PCR_SELECTION pcrSelect; + TPM2B_DIGEST pcrDigest; + TPMA_LOCALITY locality; + TPM_ALG_ID parentNameAlg; + TPM2B_NAME parentName; + TPM2B_NAME parentQualifiedName; + TPM2B_DATA outsideInfo; +} TPMS_CREATION_DATA; + +// Table 204 -- TPM2B_CREATION_DATA Structure <O,S> +typedef struct { + UINT16 size; + TPMS_CREATION_DATA creationData; +} CREATION_DATA_2B; + +typedef union { + CREATION_DATA_2B t; + TPM2B b; +} TPM2B_CREATION_DATA; + +// +// Command Header +// +typedef struct { + TPM_ST tag; + UINT32 paramSize; + TPM_CC commandCode; +} TPM2_COMMAND_HEADER; + +typedef struct { + TPM_ST tag; + UINT32 paramSize; + TPM_RC responseCode; +} TPM2_RESPONSE_HEADER; + +#pragma pack (pop) + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20Implementation.h b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20Implementation.h new file mode 100644 index 0000000..d21eb53 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm20Implementation.h @@ -0,0 +1,259 @@ +/** @file + + Definitions for Tpm 2.0 implementation + +@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 +**/ + +#ifndef _IMPLEMENTATION_H +#define _IMPLEMENTATION_H + +// Table 205 -- Hash Algorithm Digest and Block Size Values +#define SHA1_DIGEST_SIZE 20 +#define SHA1_BLOCK_SIZE 64 +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 +#define SM3_256_DIGEST_SIZE 32 +#define SM3_256_BLOCK_SIZE 64 +#define SHA384_DIGEST_SIZE 48 +#define SHA384_BLOCK_SIZE 128 +#define SHA512_DIGEST_SIZE 64 +#define SHA512_BLOCK_SIZE 128 +#define WHIRLPOOL512_DIGEST_SIZE 64 +#define WHIRLPOOL512_BLOCK_SIZE 64 + +// Table 206 -- DER Values +#define SHA1_DER_SIZE 15 +#define SHA1_DER {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14} +#define SHA256_DER_SIZE 19 +#define SHA256_DER {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20} +#define SHA384_DER_SIZE 19 +#define SHA384_DER {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30} +#define SHA512_DER_SIZE 19 +#define SHA512_DER {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40} + +// Table 207 -- Architectural Limits Values +#define MAX_SESSION_NUMBER 3 + +// Table 208 -- Minimum and Maximum Values +#ifndef UINT8_MAX +#define UINT8_MAX 255 +#endif +#define BYTE_MAX 255 +#define INT8_MIN -128 +#define INT8_MAX 127 +#define UINT16_MAX 65535 +#define INT16_MIN -32768 +#define INT16_MAX 32767 +#define UINT32_MAX 4294967295 +#define INT32_MIN -2147483648 +#define INT32_MAX 2147483647 +#define UINT64_MAX 18446744073709551615 // 1.84467440737096e+019 +#define INT64_MIN -9223372036854775808 // 1 +#define INT64_MAX 9223372036854775807 // 9.22337203685478e+018 + +// Table 209 -- Logic Values +#define YES 1 +#define NO 0 +// +// BUGBUG: Comment to to resolve duplicated definition +// +//#define TRUE 1 +//#define FALSE 0 +#define SET 1 +#define CLEAR 0 + +// Table 210 -- Processor Values +#define BIG_ENDIAN NO // 0 +#define LITTLE_ENDIAN YES // 1 +#define NO_AUTO_ALIGN NO // 0 + +/* Table 211 -- Implemented Algorithms +#define RSA YES // 1 +#define DES YES // 1 +#define _3DES YES // 1 +#define SHA1 YES // 1 +#define HMAC YES // 1 +#define AES YES // 1 +#define MGF1 YES // 1 +#define XOR YES // 1 +#define KEYEDHASH YES // 1 +#define SHA256 YES // 1 +#define SHA384 YES // 1 +#define SHA512 YES // 1 +#define WHIRLPOOL512 YES // 1 +#define SM3_256 YES // 1 +#define SMS4 YES // 1 +#define RSASSA RSA // 1 +#define RSAES RSA // 1 +#define RSAPSS RSA // 1 +#define OAEP RSA // 1 +#define ECC YES // 1 +#define ECDH YES // 1 +#define ECDSA ECC // 1 +#define ECDAA ECC // 1 +#define ECSCHNORR ECC // 1 +#define SYMCIPHER YES // 1 +#define KDF1_SP800_56a ECC // 1 +#define KDF2 YES // 1 +#define KDF1_SP800_108 YES // 1 +#define SP800_56a_C1_1 ECC // 1 +#define CTR YES // 1 +#define OFB YES // 1 +#define CBC YES // 1 +#define CFB YES // 1 +#define ECB YES // 1 + +*/ + +// Table 212 -- Implemented Algorithm Constants +#define RSA_KEY_SIZES_BITS {1024,2048} +#define MAX_RSA_KEY_BITS 2048 +#define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS+7)/8) // 256 +#define ECC_CURVES {TPM_ECC_NIST_P256,TPM_ECC_BN_P256} +#define ECC_KEY_SIZES_BITS {256} +#define MAX_ECC_KEY_BITS 256 +#define MAX_ECC_KEY_BYTES ((MAX_ECC_KEY_BITS+7)/8) // 32 +#define AES_KEY_SIZES_BITS {128} +#define MAX_AES_KEY_BITS 128 +#define MAX_AES_KEY_BYTES ((MAX_AES_KEY_BITS+7)/8) // 16 +#define MAX_SYM_KEY_BITS 128 +#define MAX_SYM_KEY_BYTES ((MAX_SYM_KEY_BITS+7)/8) // 16 +#define MAX_SYM_BLOCK_SIZE 16 + +// Table 213 -- Implementation Values +#define FIELD_UPGRADE_IMPLEMENTED NO // 0 +typedef UINT16 BSIZE; +#define IMPLEMENTATION_PCR 24 +#define PLATFORM_PCR 24 +#define DRTM_PCR 17 +#define NUM_LOCALITIES 5 +#define MAX_HANDLE_NUM 3 +#define MAX_ACTIVE_SESSIONS 64 +typedef UINT16 CONTEXT_SLOT; +typedef UINT64 CONTEXT_COUNTER; +#define MAX_LOADED_SESSIONS 3 +#define MAX_SESSION_NUM 3 +#define MAX_LOADED_OBJECTS 3 +#define MIN_EVICT_OBJECTS 2 +#define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8) // 3 +#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8) // 3 +#define NUM_POLICY_PCR_GROUP 1 +#define NUM_AUTHVALUE_PCR_GROUP 1 +#define MAX_CONTEXT_SIZE 4000 +#define MAX_DIGEST_BUFFER 1024 +#define MAX_NV_INDEX_SIZE 1024 +#define MAX_CAP_BUFFER 1024 +#define NV_MEMORY_SIZE 16384 +#define NUM_STATIC_PCR 16 +#define MAX_ALG_LIST_SIZE 64 +#define TIMER_PRESCALE 100000 +#define PRIMARY_SEED_SIZE 32 +#define CONTEXT_ENCRYPT_ALG TPM_ALG_AES +#define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS // 128 +#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8) // 16 +#define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256 +#define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE // 32 +#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE // 32 +#define NV_CLOCK_UPDATE_INTERVAL 12 +#define NUM_POLICY_PCR 1 +#define MAX_COMMAND_SIZE 4096 +#define MAX_RESPONSE_SIZE 4096 +#define ORDERLY_BITS 8 +#define MAX_ORDERLY_COUNT ((1<<ORDERLY_BITS)-1) // 255 +#define ALG_ID_FIRST TPM_ALG_FIRST +#define ALG_ID_LAST TPM_ALG_LAST +#define MAX_SYM_DATA 128 +#define MAX_HASH_STATE_SIZE 512 +#define MAX_RNG_ENTROPY_SIZE 64 +#define RAM_INDEX_SPACE 512 +#define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001 + +/// + +/*(auto) + + Automatically Generated by DoImplemented.pl + + Date: Mar 5, 2012 + Time: 11:14:55 PM + +*/ + +// Table 6 -- TPM_ALG_ID Constants <I/O,S> +typedef UINT16 TPM_ALG_ID; +// +// BUGBUG: Comment some algo which has same name as TPM1.2 (value is same, so not runtime issue) +// +#define TPM_ALG_ERROR (TPM_ALG_ID)(0x0000) // a: ; D: +#define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001) // a: ; D: +//#define TPM_ALG_RSA (TPM_ALG_ID)(0x0001) // a: A O; D: +//#define TPM_ALG_DES (TPM_ALG_ID)(0x0002) // a: S; D: +#define TPM_ALG__3DES (TPM_ALG_ID)(0x0003) // a: S; D: +//#define TPM_ALG_SHA (TPM_ALG_ID)(0x0004) // a: H; D: +#define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004) // a: H; D: +//#define TPM_ALG_HMAC (TPM_ALG_ID)(0x0005) // a: H X; D: +#define TPM_ALG_AES (TPM_ALG_ID)(0x0006) // a: S; D: +//#define TPM_ALG_MGF1 (TPM_ALG_ID)(0x0007) // a: H M; D: +#define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(0x0008) // a: H E X O; D: +//#define TPM_ALG_XOR (TPM_ALG_ID)(0x000A) // a: H S; D: +#define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B) // a: H; D: +#define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C) // a: H; D: +#define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D) // a: H; D: +#define TPM_ALG_WHIRLPOOL512 (TPM_ALG_ID)(0x000E) // a: H; D: +#define TPM_ALG_NULL (TPM_ALG_ID)(0x0010) // a: ; D: +#define TPM_ALG_SM3_256 (TPM_ALG_ID)(0x0012) // a: H; D: +#define TPM_ALG_SMS4 (TPM_ALG_ID)(0x0013) // a: S; D: +#define TPM_ALG_RSASSA (TPM_ALG_ID)(0x0014) // a: X; D: RSA +#define TPM_ALG_RSAES (TPM_ALG_ID)(0x0015) // a: E; D: RSA +#define TPM_ALG_RSAPSS (TPM_ALG_ID)(0x0016) // a: X; D: RSA +#define TPM_ALG_OAEP (TPM_ALG_ID)(0x0017) // a: E; D: RSA +#define TPM_ALG_ECDSA (TPM_ALG_ID)(0x0018) // a: X; D: ECC +#define TPM_ALG_ECDH (TPM_ALG_ID)(0x0019) // a: M; D: ECC +#define TPM_ALG_ECDAA (TPM_ALG_ID)(0x001A) // a: A X; D: ECC +#define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(0x001C) // a: A X; D: ECC +#define TPM_ALG_KDF1_SP800_56a (TPM_ALG_ID)(0x0020) // a: H M; D: ECC +#define TPM_ALG_KDF2 (TPM_ALG_ID)(0x0021) // a: H M; D: +#define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022) // a: H M; D: +#define TPM_ALG_ECC (TPM_ALG_ID)(0x0023) // a: A O; D: +#define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(0x0025) // a: O; D: +#define TPM_ALG_CTR (TPM_ALG_ID)(0x0040) // a: S E; D: +#define TPM_ALG_OFB (TPM_ALG_ID)(0x0041) // a: S E; D: +#define TPM_ALG_CBC (TPM_ALG_ID)(0x0042) // a: S E; D: +#define TPM_ALG_CFB (TPM_ALG_ID)(0x0043) // a: S E; D: +#define TPM_ALG_ECB (TPM_ALG_ID)(0x0044) // a: S E; D: +#define TPM_ALG_LAST (TPM_ALG_ID)(0x0044) // a: ; D: + +// Table 7 -- TPM_ECC_CURVE Constants <I/O,S> +typedef UINT16 TPM_ECC_CURVE; + +#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000) +#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001) +#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002) +#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003) +#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004) +#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005) +#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010) +#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011) + +//#define MAX_DIGEST_SIZE 32 +//#define MAX_HASH_BLOCK_SIZE 64 +// +// BUGBUG: Always set 6 here, because we want to support all hash algo in BIOS. +// +#define HASH_COUNT 6 + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2Acpi.h b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2Acpi.h new file mode 100644 index 0000000..3c86567 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2Acpi.h @@ -0,0 +1,53 @@ +/** @file + TPM2 ACPI table definition. + +@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 +**/ + +#ifndef _TPM2_ACPI_H_ +#define _TPM2_ACPI_H_ + +#include <IndustryStandard/Acpi.h> + +#pragma pack (1) + +#define EFI_TPM2_ACPI_TABLE_REVISION 3 + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 Flags; + UINT64 AddressOfControlArea; + UINT32 StartMethod; +//UINT8 PlatformSpecificParameters[]; +} EFI_TPM2_ACPI_TABLE; + +#define EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI 2 + +typedef struct { + UINT32 Reserved; + UINT32 Error; + UINT32 Cancel; + UINT32 Start; + UINT64 InterruptControl; + UINT32 CommandSize; + UINT64 Command; + UINT32 ResponseSize; + UINT64 Response; +} EFI_TPM2_ACPI_CONTROL_AREA; + +#pragma pack () + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2DeviceLib.h b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2DeviceLib.h new file mode 100644 index 0000000..803fb6c --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/IndustryStandard/Tpm2DeviceLib.h @@ -0,0 +1,112 @@ +/** @file + This library abstract how to access TPM2 hardware device. + +@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 +**/ + +#ifndef _TPM2_DEVICE_LIB_H_ +#define _TPM2_DEVICE_LIB_H_ + +/** + This service enables the sending of commands to the TPM2. + + @param[in] InputParameterBlockSize Size of the TPM2 input parameter block. + @param[in] InputParameterBlock Pointer to the TPM2 input parameter block. + @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block. + @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block. + + @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +Tpm2SubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ); + +/** + This service requests use TPM2. + + @retval EFI_SUCCESS Get the control of TPM2 chip. + @retval EFI_NOT_FOUND TPM2 not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2RequestUseTpm ( + VOID + ); + +/** + This service enables the sending of commands to the TPM2. + + @param[in] InputParameterBlockSize Size of the TPM2 input parameter block. + @param[in] InputParameterBlock Pointer to the TPM2 input parameter block. + @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block. + @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block. + + @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +typedef +EFI_STATUS +(EFIAPI *TPM2_SUBMIT_COMMAND) ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ); + +/** + This service requests use TPM2. + + @retval EFI_SUCCESS Get the control of TPM2 chip. + @retval EFI_NOT_FOUND TPM2 not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +typedef +EFI_STATUS +(EFIAPI *TPM2_REQUEST_USE_TPM) ( + VOID + ); + +typedef struct { + EFI_GUID ProviderGuid; + TPM2_SUBMIT_COMMAND Tpm2SubmitCommand; + TPM2_REQUEST_USE_TPM Tpm2RequestUseTpm; +} TPM2_DEVICE_INTERFACE; + +/** + This service register TPM2 device. + + @Param Tpm2Device TPM2 device + + @retval EFI_SUCCESS This TPM2 device is registered successfully. + @retval EFI_UNSUPPORTED System does not support register this TPM2 device. + @retval EFI_ALREADY_STARTED System already register this TPM2 device. +**/ +EFI_STATUS +EFIAPI +Tpm2RegisterTpm2DeviceLib ( + IN TPM2_DEVICE_INTERFACE *Tpm2Device + ); + +#endif diff --git a/ReferenceCode/ME/SampleCode/Include/MeDxeLibSampleCode.dsc b/ReferenceCode/ME/SampleCode/Include/MeDxeLibSampleCode.dsc new file mode 100644 index 0000000..334e205 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Include/MeDxeLibSampleCode.dsc @@ -0,0 +1,26 @@ +## @file +# Build description file Sample Code for building the Me +# +#@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 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 +# + +# +# ME Sample Code Libraries +# +$(PROJECT_ME_ROOT)\SampleCode\Library\AslUpdate\Dxe\AslUpdateLib.inf +$(PROJECT_ME_ROOT)\SampleCode\Protocol\MeSampleCodeProtocolLib.inf
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf new file mode 100644 index 0000000..8b5396f --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf @@ -0,0 +1,66 @@ +## @file +# Provides services to update ASL tables. +# +#@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 = AslUpdateLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DxeAslUpdateLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/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/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + +[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/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c new file mode 100644 index 0000000..79a7c86 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c @@ -0,0 +1,333 @@ +/** @file + Boot service DXE ASL update library implementation. + These functions in this file can be called during DXE and cannot be called during runtime + or in SMM which should use a RT or SMM library. + This library uses the ACPI Support protocol. + +@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 + +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AslUpdateLib.h" +#endif +static EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL; +static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL; + +// +// Function implemenations +// + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Locate ACPI tables + /// + Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, (VOID **) &mAcpiSupport); + ASSERT_EFI_ERROR (Status); + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable); + return EFI_SUCCESS; +} + +/** + This procedure will update two kinds of asl code. + 1: Operating Region base address and length. + 2: Resource Consumption structures in device LDRC. + + @param[in] AslSignature The signature of Operation Region that we want to update. + @param[in] BaseAddress Base address of IO trap. + @param[in] Length Length of IO address. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +UpdateAslCode ( + IN UINT32 AslSignature, + IN UINT16 BaseAddress, + IN UINT8 Length + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_TABLE_VERSION Version; + UINT8 *CurrPtr; + UINT8 *Operation; + UINT32 *Signature; + UINT8 *DsdtPointer; + INTN Index; + UINTN Handle; + UINT16 AslLength; + + /// + /// Locate table with matching ID + /// + Index = 0; + AslLength = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) &Table, &Version, &Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (Table->Signature != EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE); + + /// + /// Fix up the following ASL Code in DSDT: + /// (1) OperationRegion's IO Base Address and Length. + /// (2) Resource Consumption in LPC Device. + /// + CurrPtr = (UINT8 *) Table; + + /// + /// Loop through the ASL looking for values that we must fix up. + /// + for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) DsdtPointer; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == AslSignature) { + /// + /// Conditional match. For Region Objects, the Operator will always be the + /// byte immediately before the specific name. Therefore, subtract 1 to check + /// the Operator. + /// + Operation = DsdtPointer - 1; + + /// + /// If we have an operation region, update the base address and length + /// + if (*Operation == AML_OPREGION_OP) { + /// + /// Fixup the Base Address in OperationRegion. + /// + *(UINT16 *) (DsdtPointer + 6) = BaseAddress; + + /// + /// Fixup the Length in OperationRegion. + /// + *(DsdtPointer + 9) = Length; + } + + } else if ((*Signature) == EFI_SIGNATURE_32 ('L', 'D', 'R', 'C')) { + /// + /// Make sure it's device of LDRC and read the length + /// + if (*(DsdtPointer - 2) == AML_DEVICE_OP) { + AslLength = *(DsdtPointer - 1); + } else if (*(DsdtPointer - 3) == AML_DEVICE_OP) { + AslLength = *(UINT16 *) (DsdtPointer - 2); + AslLength = (AslLength & 0x0F) + ((AslLength & 0x0FF00) >> 4); + } + /// + /// Conditional match. Search _CSR in Device (LDRC). + /// + for (Operation = DsdtPointer; Operation <= DsdtPointer + AslLength; Operation++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) Operation; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == EFI_SIGNATURE_32 ('_', 'C', 'R', 'S')) { + /// + /// Now look for an empty resource entry, fix the base address and length fields + /// + for (Index = 0; *(UINT16 *) (Operation + 9 + 8 * Index) != 0x0079; Index++) { + if (*(UINT16 *) (Operation + 11 + 8 * Index) == UINT16_BIT_MAGIC_NUMBER) { + /// + /// Fixup the Base Address and Length. + /// + *(UINT16 *) (Operation + 11 + 8 * Index) = BaseAddress; + *(UINT16 *) (Operation + 13 + 8 * Index) = BaseAddress; + *(Operation + 16 + 8 * Index) = Length; + break; + } + } + } + } + + DsdtPointer = DsdtPointer + AslLength; + } + } + /// + /// Update the modified ACPI table + /// + Status = mAcpiTable->InstallAcpiTable ( + mAcpiTable, + Table, + Table->Length, + &Handle + ); + FreePool (Table); + + return EFI_SUCCESS; +} + +/** + This function uses the ACPI support protocol to locate an ACPI table. + It is really only useful for finding tables that only have a single instance, + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc. + + @param[in] Signature Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version The version of the table desired + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableBySignature ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + EFI_ACPI_TABLE_VERSION DesiredVersion; + + DesiredVersion = *Version; + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while ((*Table)->Signature != Signature || !(*Version & DesiredVersion)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function uses the ACPI support protocol to locate an ACPI SSDT table. + + @param[in] TableId Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] TableIdSize Length of the TableId to match. Table ID are 8 bytes long, this function + will consider it a match if the first TableIdSize bytes match + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version See AcpiSupport protocol, GetAcpiTable function for use + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableByOemTableId ( + IN UINT8 *TableId, + IN UINT8 TableIdSize, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (CompareMem (&(*Table)->OemTableId, TableId, TableIdSize)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + @param[in] ChecksumOffset Offset to place the checksum result in + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AcpiChecksum ( + IN VOID *Buffer, + IN UINTN Size, + IN UINTN ChecksumOffset + ) +{ + UINT8 Sum; + UINT8 *Ptr; + + Sum = 0; + // + // Initialize pointer + // + Ptr = Buffer; + + // + // Set checksum to 0 first + // + Ptr[ChecksumOffset] = 0; + + // + // Add all content of buffer + // + while (Size--) { + Sum = (UINT8) (Sum + (*Ptr++)); + } + // + // Set checksum + // + Ptr = Buffer; + Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif new file mode 100644 index 0000000..81b5bf0 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif @@ -0,0 +1,11 @@ +<component> + name = "MeAslUpdateLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\SampleCode\Library\AslUpdate\Dxe" + RefName = "MeAslUpdateLib" +[files] +"MeAslUpdateLib.sdl" +"MeAslUpdateLib.mak" +"DxeAslUpdateLib.c" +"AslUpdateLib.inf" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak new file mode 100644 index 0000000..7417a00 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak @@ -0,0 +1,32 @@ +# MAK file for the ModulePart:AslUpdateLib +all : MeAslUpdateLib + +$(BUILD_DIR)\MeAslUpdateLib.lib : MeAslUpdateLib + +MeAslUpdateLib : $(BUILD_DIR)\MeAslUpdateLib.mak MeAslUpdateLibBin + +$(BUILD_DIR)\MeAslUpdateLib.mak : $(MeAslUpdateLib_DIR)\$(@B).cif $(MeAslUpdateLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeAslUpdateLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeAslUpdateLib_INCLUDES=\ + $(EDK_INCLUDES)\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +MeAslUpdateLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +MeAslUpdateLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +MeAslUpdateLibBin : $(MeAslUpdateLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeAslUpdateLib.mak all \ + "MY_INCLUDES=$(MeAslUpdateLib_INCLUDES)"\ + "MY_DEFINES=$(MeAslUpdateLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl new file mode 100644 index 0000000..aae94fb --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = MeAslUpdateLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AslUpdateLib support in Project" +End + +MODULE + Help = "Includes MeAslUpdateLib.mak to Project" + File = "MeAslUpdateLib.mak" +End + +PATH + Name = "MeAslUpdateLib_DIR" +End + +ELINK + Name = "MeAslUpdateLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeAslUpdateLib.lib" + Parent = "MeAslUpdateLib_LIB" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.c b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.c new file mode 100644 index 0000000..3b78726 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.c @@ -0,0 +1,122 @@ +/** @file + Provides an interface to call function to send HECI message. + +@copyright + Copyright (c) 2011 - 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 +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#endif +#include "MdesStatusCodeDxe.h" +#include "MeLib.h" +#include "MePlatformPolicy\MePlatformPolicy.h" + + +EFI_GUID gMdesStatusCodeProtocolGuid = MDES_STATUS_CODE_PROTOCOL_GUID; + +/** + This function is called in case of status code appears. + Provides an interface to call function to send HECI message. + + @param[in] Type 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. + + @retval EFI_STATUS HECI sent with success. +**/ +EFI_STATUS +EFIAPI +MdesReportStatusCodeHandler ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ) +{ + EFI_STATUS Status; + + Status = HeciSendMdesStatusCode (Type, Value, Instance, CallerId, Data); + + return Status; +} + +MDES_STATUS_CODE_PROTOCOL MdesStatusCodeProtocolInstance = {MdesReportStatusCodeHandler}; + + +/** + Installs MdesStatusCodeProtocolInstance protocol. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_STATUS Driver instaled with siccess. +**/ +EFI_STATUS +EFIAPI +MdesStatusCodeDrvEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + MDES_BIOS_FLAGS Flags; + UINT32 BiosEventFilters; + DXE_ME_POLICY_PROTOCOL *MePlatformPolicy; + + /// + /// Get the ME platform policy. + /// + Status = gBS->LocateProtocol (&gDxePlatformMePolicyGuid, NULL, (VOID **) &MePlatformPolicy); + if (EFI_ERROR (Status)) { + return Status; + } + + if(MePlatformPolicy->MeConfig.MdesForBiosState == TRUE) { + /// + /// Check if Mdes is enabled in FW + /// + Status = HeciGetMdesConfig(&Flags, &BiosEventFilters); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + if (1) { + /// + /// Install Mdes protocol to be consumed by platform library for ReportStatusCode core driver. + /// + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gMdesStatusCodeProtocolGuid, + EFI_NATIVE_INTERFACE, + &MdesStatusCodeProtocolInstance + ); + } + { + PLATFORM_DEBUG_CAP Data; + UINT8 Result; + + Data.Data = 3; + Status = HeciPlatformDebugCapabilityMsg(Data, &Result); + } + } + return Status; +} diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.cif b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.cif new file mode 100644 index 0000000..2647905 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.cif @@ -0,0 +1,13 @@ +<component> + name = "MdesStatusCodeDxe" + category = ModulePart + LocalRoot = "ReferenceCode\ME\SampleCode\MdesStatusCode\Dxe" + RefName = "MdesStatusCodeDxe" +[files] +"MdesStatusCodeDxe.sdl" +"MdesStatusCodeDxe.mak" +"MdesStatusCodeDxe.c" +"MdesStatusCodeDxe.dxs" +"MdesStatusCodeDxe.h" +"MdesStatusCodeDxe.inf" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.dxs b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.dxs new file mode 100644 index 0000000..ab85bb6 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.dxs @@ -0,0 +1,39 @@ +/** + +Copyright (c) 2011 - 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. + +Module Name: + + +Abstract: + + +**/ +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (Heci) +#include EFI_PROTOCOL_DEFINITION (MePlatformPolicy) +#endif + +DEPENDENCY_START + EFI_HECI_PROTOCOL_GUID AND + DXE_PLATFORM_ME_POLICY_GUID +DEPENDENCY_END diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.h b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.h new file mode 100644 index 0000000..74bfc0a --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.h @@ -0,0 +1,59 @@ +/** @file + Header file to provides an interface to call function to send HECI message. + +@copyright + Copyright (c) 2011 - 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 + +--*/ +#ifndef _MDES_STATUS_CODE_DXE_H_ +#define _MDES_STATUS_CODE_DXE_H_ + +#define MDES_STATUS_CODE_PROTOCOL_GUID \ + { \ + 0xe5d0875a, 0xf647, 0x4e16, 0xbe, 0x4d, 0x95, 0x02, 0x40, 0x29, 0xcc, 0x44 \ + } + +/** + This function is called in case of status code appears. + Provides an interface to call function to send HECI message. + + @param[in] Type 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. + + @retval EFI_STATUS HECI sent with success. +**/ +typedef +EFI_STATUS +(EFIAPI *SEND_STATUS_CODE) ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ); + +typedef struct _MDES_STATUS_CODE_PROTOCOL { + SEND_STATUS_CODE SendMdesStatusCode; +} MDES_STATUS_CODE_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.inf b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.inf new file mode 100644 index 0000000..1a77fa5 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.inf @@ -0,0 +1,82 @@ +## @file +# Component description file for the MdesStatusCodeDrv DXE driver. +# +#@copyright +# Copyright (c) 2011 - 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 = MdesStatusCodeDxe +FILE_GUID = df5cd25a-8e55-46ba-8cda-bc7db7bf9c64 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + MdesStatusCodeDxe.c + MdesStatusCodeDxe.h +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Protocol/MePlatformPolicy + $(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 + MeLib + MeGuidLib + MeChipsetLib + EdkProtocolLib + EdkFrameworkProtocolLib + EdkIIGlueBaseLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueDxeServicesTableLib + EdkIIGlueEdkDxeRuntimeDriverLib + EdkIIGlueBasePciLibPciExpress + +[nmake.common] + IMAGE_ENTRY_POINT= _ModuleEntryPoint + DPX_SOURCE=MdesStatusCodeDxe.dxs + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=MdesStatusCodeDrvEntryPoint \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.mak b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.mak new file mode 100644 index 0000000..6e49bcc --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.mak @@ -0,0 +1,142 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (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/MeSampleCode/MdesStatusCodeDxe/MdesStatusCodeDxe.mak 1 4/06/12 8:57a Klzhan $ +# +# $Revision: 1 $ +# +# $Date: 4/06/12 8:57a $ +# +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/MeSampleCode/MdesStatusCodeDxe/MdesStatusCodeDxe.mak $ +# +# 1 4/06/12 8:57a Klzhan +# +# 4 3/27/12 5:17a Klzhan +# Correct TYPE of this modulepart. +# +# 3 10/19/11 9:19a Calvinchen +# [TAG] EIP65695 +# [Category] Bug Fix +# [Severity] Normal +# [Symptom] Support HECI protocol in SMM for ME 8.0 +# [Solution] Removed "EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB" from Make +# file. +# +# 2 9/27/11 5:03a Klzhan +# Fix build error +# +# 1 9/27/11 4:46a Klzhan +# +# +# +#********************************************************************** +# +#<AMI_FHDR_START> +#---------------------------------------------------------------------------- +# +# Name: MdesStatusCodeDrv.mak +# +# Description: Mdes Status Code driver +# +#---------------------------------------------------------------------------- +#<AMI_FHDR_END> +all : MdesStatusCodeDrv + +MdesStatusCodeDrv : $(BUILD_DIR)\MdesStatusCodeDxe.mak MdesStatusCodeDrvBin + +$(BUILD_DIR)\MdesStatusCodeDxe.mak : $(MdesStatusCodeDrv_DIR)\$(@B).cif $(MdesStatusCodeDrv_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MdesStatusCodeDrv_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + + +MdesStatusCodeDrv_INCLUDES=\ + $(EDK_INCLUDES)\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(EdkIIGlueInclude)\ + $(IndustryStandard_INCLUDES)\ + -I$(MeProtocolLib_DIR)\ + -I$(INTEL_COUGAR_POINT_INCLUDE_DIR) + +MdesStatusCodeDrv_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=MdesStatusCodeDrvEntryPoint"\ + /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_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ + + +MdesStatusCodeDrv_LIB_LINKS =\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EdkIIGlueBasePrintLib_LIB) \ + $(EdkIIGlueUefiLib_LIB)\ + $(TdtProtocolLib_LIB)\ + $(ProtocolLib_LIB)\ + $(EFISCRIPTLIB)\ + $(AmtLibDxe_LIB)\ + $(MeLibDxe_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(AmtGuidLib_LIB)\ + $(EFIGUIDLIB)\ + $(EDKPROTOCOLLIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGluePeiDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EFIDRIVERLIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(MeProtocolLib_LIB) +# MAK file for the eModule:TdtDxe + +MdesStatusCodeDrvBin : $(MdesStatusCodeDrv_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MdesStatusCodeDxe.mak all\ + "MY_INCLUDES=$(MdesStatusCodeDrv_INCLUDES)"\ + "MY_DEFINES=$(MdesStatusCodeDrv_DEFINES)"\ + GUID=df5cd25a-8e55-46ba-8cda-bc7db7bf9c64 \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(MdesStatusCodeDrv_DIR)\MdesStatusCodeDxe.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#*************************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.sdl b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.sdl new file mode 100644 index 0000000..f61edd3 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MdesStatusCode/Dxe/MdesStatusCodeDxe.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "MDES_STATUSCODE_DRV_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable IccOverClocking support in Project" +End + +MODULE + Help = "Includes MebxSetupBrowser.mak to Project" + File = "MdesStatusCodeDxe.mak" +End + +PATH + Name = "MdesStatusCodeDrv_DIR" +End + +ELINK + Name = "$(BUILD_DIR)\MdesStatusCodeDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/MeSampleCode.cif b/ReferenceCode/ME/SampleCode/MeSampleCode.cif new file mode 100644 index 0000000..3b8484e --- /dev/null +++ b/ReferenceCode/ME/SampleCode/MeSampleCode.cif @@ -0,0 +1,28 @@ +<component> + name = "MeSampleCode" + category = ModulePart + LocalRoot = "ReferenceCode\ME\SampleCode\" + RefName = "MeSampleCode" +[files] +"Include\MeDxeLibSampleCode.dsc" +"Include\Acpi1_0.h" +"Include\Acpi2_0.h" +"Include\Acpi3_0.h" +"Include\AlertStandardFormatTable.h" +"Include\AslUpdateLib.h" +"AsfSupport\AsfSupport.h" +"AsfSupport\AsfSupport.c" +"Protocol\SmmVariable\SmmVariable.h" +"Include\Guid\MemoryOverwriteControl\MemoryOverwriteControl.h" +"Include\Guid\TrEEPhysicalPresenceData\TrEEPhysicalPresenceData.h" +"Include\IndustryStandard\AcpiAml.h" +"Include\IndustryStandard\Tpm20.h" +"Include\IndustryStandard\Tpm20Implementation.h" +"Include\IndustryStandard\Tpm2Acpi.h" +"Include\IndustryStandard\Tpm2DeviceLib.h" +[parts] +"MeAslUpdateLib" +"PlatformReset" +"MePlatformGetResetTypeProtocolLib" +"MdesStatusCodeDxe" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.c b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.c new file mode 100644 index 0000000..55cdf11 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.c @@ -0,0 +1,168 @@ +/** @file + Provide the ResetSystem AP + +@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 +**/ +#include "PlatformReset.h" +#include "MeLib.h" +PCH_RESET_PROTOCOL *mPchReset; + +/** + Reset the system + + @param[in] ResetType Warm or cold + @param[in] ResetStatus Possible cause of reset + @param[in] DataSize Size of ResetData in bytes + @param[in] ResetData Optional Unicode string + + @retval Does not return if the reset takes place. +**/ +VOID +EFIAPI +PlatformResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ) +{ + EFI_STATUS Status; + ME_PLATFORM_GET_RESET_TYPE_PROTOCOL *MePlatformGetResetType; + PCH_RESET_TYPE OverridePchResetType; + PCH_RESET_TYPE PchResetType; + UINTN NumberMePlatformGetResetHandles; + EFI_HANDLE *MePlatformGetResetHandles; + UINTN Index; + + PchResetType = ResetType; + OverridePchResetType = ResetType; + + if (!EfiAtRuntime ()) { + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gMePlatformGetResetTypeGuid, + NULL, + &NumberMePlatformGetResetHandles, + &MePlatformGetResetHandles + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < NumberMePlatformGetResetHandles; Index++) { + Status = gBS->HandleProtocol ( + MePlatformGetResetHandles[Index], + &gMePlatformGetResetTypeGuid, + (VOID **) &MePlatformGetResetType + ); + if (!EFI_ERROR (Status)) { + PchResetType = MePlatformGetResetType->GetResetType (ResetType); + DEBUG ((EFI_D_INFO, "Returned Pch ResetType is: %x\n", PchResetType)); + if (PchResetType >= MaxRestReq) { + DEBUG ((EFI_D_ERROR, "Platform Reset failed, invalid parameter\n")); + ASSERT (FALSE); + } + if (OverridePchResetType < PchResetType) { + DEBUG ((EFI_D_INFO, "Previous Pch ResetType is: %x\n", OverridePchResetType)); + OverridePchResetType = PchResetType; + } + DEBUG ((EFI_D_INFO, "Current Pch ResetType is: %x\n", OverridePchResetType)); + } + } + } + PchResetType = OverridePchResetType; + if ((PchResetType == GlobalReset) || (PchResetType == GlobalResetWithEc)) { + /// + /// Let ME do global reset if Me Fw is available + /// + Status = HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET); + if (!EFI_ERROR (Status)) { + /// + /// ME Global Reset should fail after EOP is sent. + /// Go to use PCH Reset + /// + gBS->Stall (1000000); + } + } + } + + mPchReset->Reset (mPchReset, PchResetType); + + ASSERT (FALSE); +} + +/** + Entry point of Platform Reset driver. + + @param[in] ImageHandle Standard entry point parameter + @param[in] SystemTable Standard entry point parameter + + @retval EFI_SUCCESS Reset RT protocol installed + @retval All other error conditions encountered result in an ASSERT +**/ +EFI_STATUS +InitializePlatformReset ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gPchResetProtocolGuid, NULL, (VOID **) &mPchReset); + ASSERT_EFI_ERROR (Status); + + /// + /// Make sure the Reset Architectural Protocol is not already installed in the system + /// + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid); + + /// + /// Hook the runtime service table + /// + SystemTable->RuntimeServices->ResetSystem = PlatformResetSystem; + + /// + /// Now install the Reset RT AP on a new handle + /// + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiResetArchProtocolGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Fixup internal data pointers so that the services can be called in virtual mode. + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event handler. + + @retval None +**/ +EFI_RUNTIMESERVICE +VOID +PchResetVirtualddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &mPchReset); +} diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.cif b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.cif new file mode 100644 index 0000000..6403a09 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.cif @@ -0,0 +1,12 @@ +<component> + name = "PlatformReset" + category = ModulePart + LocalRoot = "ReferenceCode\ME\SampleCode\PlatformReset\RuntimeDxe" + RefName = "PlatformReset" +[files] +"PlatformReset.sdl" +"PlatformReset.mak" +"PlatformReset.h" +"PlatformReset.c" +"PlatformReset.dxs" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.dxs b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.dxs new file mode 100644 index 0000000..62919fa --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.dxs @@ -0,0 +1,41 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 2011 - 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 + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include EFI_PROTOCOL_DEFINITION (PchReset) +#endif + +DEPENDENCY_START + PCH_RESET_PROTOCOL_GUID +DEPENDENCY_END + diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.h b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.h new file mode 100644 index 0000000..9847b5e --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.h @@ -0,0 +1,29 @@ +/** @file + Definitions for PlatformReset driver + +@copyright + Copyright (c) 2011 - 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 _PLATFORM_RESET_H_ +#define _PLATFORM_RESET_H_ + +#include "EdkIIGlueDxe.h" +#include EFI_PROTOCOL_CONSUMER (PchReset) +#include EFI_PROTOCOL_CONSUMER (MePlatformGetResetType) +#include EFI_ARCH_PROTOCOL_DEFINITION (Reset) + +#endif // _PLATFORM_RESET_H_ diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.mak b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.mak new file mode 100644 index 0000000..7ad1b51 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.mak @@ -0,0 +1,67 @@ +#--------------------------------------------------------------------------- +# Create PlatformReset Driver +#--------------------------------------------------------------------------- + +All : PlatformReset + +PlatformReset : $(BUILD_DIR)\PlatformReset.mak PlatformResetBin + +$(BUILD_DIR)\PlatformReset.mak : $(PlatformReset_DIR)\$(@B).cif $(PlatformReset_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PlatformReset_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PlatformReset_INCLUDES=\ + $(ME_INCLUDES) \ + /I$(ME_DIR)\SampleCode \ + $(INTEL_PCH_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + +PlatformReset_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePlatformReset"\ + /D"__EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=PchResetVirtualddressChangeEvent"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ + /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +PlatformReset_LIBS=\ + $(MeLibDxe_LIB)\ + $(MeSampleCodeProtocolLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EDKPROTOCOLLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(IntelMpgProtocolLib_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(MePlatformGetResetTypeProtocolLib_LIB) +# $(EFIDRIVERLIB)\ +# $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\ +# $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + + +PlatformResetBin : $(PlatformReset_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PlatformReset.mak all \ + GUID=9A9A912B-5F53-4586-8820-704485A29D21\ + "MY_INCLUDES=$(PlatformReset_INCLUDES)"\ + "MY_DEFINES=$(PlatformReset_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint\ + TYPE=RT_DRIVER\ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(PlatformReset_DIR)\PlatformReset.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\ + COMPRESS=1 + + diff --git a/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.sdl b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.sdl new file mode 100644 index 0000000..97fc45e --- /dev/null +++ b/ReferenceCode/ME/SampleCode/PlatformReset/RuntimeDxe/PlatformReset.sdl @@ -0,0 +1,26 @@ +TOKEN + Name = "PlatformReset_SUPPORT" + Value = "1" + Help = "Main switch to enable PlatformReset support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +PATH + Name = "PlatformReset_DIR" +End + +MODULE + Help = "Includes PlatformReset.mak to Project" + File = "PlatformReset.mak" +End + +ELINK + Name = "$(BUILD_DIR)\PlatformReset.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.c b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.c new file mode 100644 index 0000000..43b748a --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.c @@ -0,0 +1,42 @@ +/** @file + This file defines the EFI ME Platform Get Reset Type Protocol + +@copyright + Copyright (c) 2011 - 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 +**/ + +// +// Statements that include other files +// +// +// 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 the protocol header file +// +#include EFI_PROTOCOL_DEFINITION (MePlatformGetResetType) +#endif +// +// Protocol GUID definition +// +EFI_GUID gMePlatformGetResetTypeGuid = ME_PLATFORM_GET_RESET_TYPE_GUID; + +// +// Protocol description +// +EFI_GUID_STRING(&gMePlatformGetResetTypeGuid, "MePlatformGetResetType Protocol", "Intel(R) ME Platform Reset Protocol"); diff --git a/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.h b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.h new file mode 100644 index 0000000..5134b55 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetType.h @@ -0,0 +1,57 @@ +/** @file + Interface definition Me Platform Get Reset Type. + +@copyright + Copyright (c) 2011 - 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 +**/ +#ifndef _ME_PLATFORM_GET_RESET_TYPE_H_ +#define _ME_PLATFORM_GET_RESET_TYPE_H_ + +#define ME_PLATFORM_GET_RESET_TYPE_GUID \ + { \ + 0xb8cdced7, 0xbdc4, 0x4464, 0x9a, 0x1a, 0xff, 0x3f, 0xbd, 0xf7, 0x48, 0x69 \ + } + +#define ME_PLATFORM_GET_RESET_TYPE_PROTOCOL_REVISION 1 +extern EFI_GUID gMePlatformGetResetTypeGuid; + +/// +/// ME_SPEICAL_RESET_TYPES must be aligned with PCH_EXTENDED_RESET_TYPES +/// +typedef enum { + PowerCycleResetReq = 3, + GlobalResetReq, + GlobalResetWithEcReq, + MaxRestReq +} ME_SPEICAL_RESET_TYPES; + +/** + Get Platform requested reset type + + @param[in] Type UEFI defined reset type + + @retval ME_SPEICAL_RESET_TYPES ME reset type aligned with PCH_EXTENDED_RESET_TYPES +**/ +typedef +ME_SPEICAL_RESET_TYPES +(EFIAPI *GET_RESET_TYPE) ( + IN EFI_RESET_TYPE Type + ); + +typedef struct _ME_PLATFORM_GET_RESET_TYPE_PROTOCOL { + GET_RESET_TYPE GetResetType; +} ME_PLATFORM_GET_RESET_TYPE_PROTOCOL; + +#endif diff --git a/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.cif b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.cif new file mode 100644 index 0000000..2e4412e --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.cif @@ -0,0 +1,11 @@ +<component> + name = "MePlatformGetResetTypeProtocolLib" + category = ModulePart + LocalRoot = "\ReferenceCode\ME\SampleCode\Protocol\MePlatformGetResetType\" + RefName = "MePlatformGetResetTypeProtocolLib" +[files] +"MePlatformGetResetTypeProtocolLib.sdl" +"MePlatformGetResetTypeProtocolLib.mak" +"MePlatformGetResetType.h" +"MePlatformGetResetType.c" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.mak b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.mak new file mode 100644 index 0000000..504290e --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.mak @@ -0,0 +1,67 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/ME/MeSampleCode/MePlatformGetResetTypeProtocolLib/MePlatformGetResetTypeProtocolLib.mak 1 2/08/12 12:55a Klzhan $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 12:55a $ +#********************************************************************** +# Revision History +# ---------------- +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: AmtWrapperProtocolLib.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +all : MePlatformGetResetTypeProtocolLib + +$(BUILD_DIR)\MePlatformGetResetTypeProtocolLib.lib : MePlatformGetResetTypeProtocolLib + +MePlatformGetResetTypeProtocolLib : $(BUILD_DIR)\MePlatformGetResetTypeProtocolLib.mak MePlatformGetResetTypeProtocolLibBin + +$(BUILD_DIR)\MePlatformGetResetTypeProtocolLib.mak : $(MePlatformGetResetTypeProtocolLib_DIR)\$(@B).cif $(MePlatformGetResetTypeProtocolLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MePlatformGetResetTypeProtocolLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MePlatformGetResetTypeProtocolLib_INCLUDES=\ + $(EDK_INCLUDES) \ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES) \ + $(MISCFRAMEWORK_INCLUDES) \ + -I ReferenceCode\ME\SampleCode + +MePlatformGetResetTypeProtocolLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\ + /f $(BUILD_DIR)\MePlatformGetResetTypeProtocolLib.mak all\ + "MY_INCLUDES=$(MePlatformGetResetTypeProtocolLib_INCLUDES)" \ + TYPE=LIBRARY \ + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.sdl b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.sdl new file mode 100644 index 0000000..1c0cc7d --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/MePlatformGetResetType/MePlatformGetResetTypeProtocolLib.sdl @@ -0,0 +1,34 @@ +TOKEN + Name = "MePlatformGetResetTypeProtocolLib_SUPPORT" + Value = "1" + Help = "Main switch to enable AmtWrapperProtocolLib support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "MePlatformGetResetTypeProtocolLib_DIR" +End + +ELINK + Name = "/I$(MePlatformGetResetTypeProtocolLib_DIR)" + Parent = "ME_INCLUDES" + InvokeOrder = AfterParent +End + +MODULE + Help = "Includes AmtWrapperProtocolLib.mak to Project" + File = "MePlatformGetResetTypeProtocolLib.mak" +End + +ELINK + Name = "MePlatformGetResetTypeProtocolLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MePlatformGetResetTypeProtocolLib.lib" + Parent = "MePlatformGetResetTypeProtocolLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/ME/SampleCode/Protocol/SmmVariable/SmmVariable.h b/ReferenceCode/ME/SampleCode/Protocol/SmmVariable/SmmVariable.h new file mode 100644 index 0000000..06c7762 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Protocol/SmmVariable/SmmVariable.h @@ -0,0 +1,52 @@ +/*++ @file + SMM Variable Protocol + +@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 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. +--*/ + +#ifndef _SMM_VARIABLE_H_ +#define _SMM_VARIABLE_H_ + +// +// SmmVariable Protocol GUID value +// +// Note: The GUID value is the same as the protocol produced in EDKII. +#define EFI_SMM_VARIABLE_PROTOCOL_GUID \ + { \ + 0xed32d533, 0x99e6, 0x4209, 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 \ + } + +EFI_FORWARD_DECLARATION (EFI_SMM_VARIABLE_PROTOCOL); + +typedef struct _EFI_SMM_VARIABLE_PROTOCOL EFI_SMM_VARIABLE_PROTOCOL; + +/// +/// EFI SMM Variable Protocol is intended for use as a means +/// to store data in the EFI SMM environment. +/// +struct _EFI_SMM_VARIABLE_PROTOCOL { + EFI_GET_VARIABLE SmmGetVariable; + EFI_GET_NEXT_VARIABLE_NAME SmmGetNextVariableName; + EFI_SET_VARIABLE SmmSetVariable; + EFI_QUERY_VARIABLE_INFO SmmQueryVariableInfo; +}; + +/// +/// SmmVariable Protocol GUID variable. +/// +extern EFI_GUID gEfiSmmVariableProtocolGuid; + +#endif |