summaryrefslogtreecommitdiff
path: root/ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c')
-rw-r--r--ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/BiosExtensionLoader.c1273
1 files changed, 1273 insertions, 0 deletions
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 ;
+}