diff options
Diffstat (limited to 'ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader')
12 files changed, 4055 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 ; +} 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_ |