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