diff options
Diffstat (limited to 'ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.c')
-rw-r--r-- | ReferenceCode/ME/BiosExtension/Efi/BiosExtensionLoader/Dxe/Inventory.c | 828 |
1 files changed, 828 insertions, 0 deletions
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); + } +} |