The UEFI Shell has a built-in command called pci for enumerating PCI (Peripheral Component Interconnect) devices. Here is what is outputted for a Lenovo T450 using this command:
fs1:> pci Seg Bus Dev Func --- --- --- ---- 00 00 00 00 ==> Bridge Device - Host/PCI bridge Vendor 8086 Device 1604 Prog Interface 0 00 00 02 00 ==> Display Controller - VGA/8514 controller Vendor 8086 Device 1616 Prog Interface 0 00 00 03 00 ==> Multimedia Device - Mixed mode device Vendor 8086 Device 160C Prog Interface 0 00 00 14 00 ==> Serial Bus Controllers - USB Vendor 8086 Device 9CB1 Prog Interface 30 00 00 16 00 ==> Simple Communications Controllers - Other communication device Vendor 8086 Device 9CBA Prog Interface 0 00 00 19 00 ==> Network Controller - Ethernet controller Vendor 8086 Device 15A2 Prog Interface 0 00 00 1B 00 ==> Multimedia Device - Mixed mode device Vendor 8086 Device 9CA0 Prog Interface 0 00 00 1C 00 ==> Bridge Device - PCI/PCI bridge Vendor 8086 Device 9C9A Prog Interface 0 00 00 1C 01 ==> Bridge Device - PCI/PCI bridge Vendor 8086 Device 9C94 Prog Interface 0 00 00 1D 00 ==> Serial Bus Controllers - USB Vendor 8086 Device 9CA6 Prog Interface 20 00 00 1F 00 ==> Bridge Device - PCI/ISA bridge Vendor 8086 Device 9CC3 Prog Interface 0 00 00 1F 02 ==> Mass Storage Controller - Serial ATA controller Vendor 8086 Device 9C83 Prog Interface 1 00 00 1F 03 ==> Serial Bus Controllers - System Management Bus Vendor 8086 Device 9CA2 Prog Interface 0 00 00 1F 06 ==> Data Acquisition & Signal Processing Controllers - Other DAQ & SP controllers Vendor 8086 Device 9CA4 Prog Interface 0 00 02 00 00 ==> Device does not fit in any defined classes - Vendor 10EC Device 5227 Prog Interface 0 00 03 00 00 ==> Network Controller - Other network controller Vendor 8086 Device 095B Prog Interface 0
As you can see the command returns, amongst other information, the Vendor ID (VID) and the Device ID (DID) together with a simple generic description of the device.
On Linux distributions, the utility lspci is typically used to view PCI information. This utility uses the pci.ids text-based database to provide descriptions of vendors, devices, and subvendors. It is not a perfect list but it is relatively complete.
Here is an excerpt from pci.ids which details where to get the file and the layout of the file, together with a number of entries:
# # List of PCI ID's # # Version: 2016.01.02 # Date: 2016-01-02 03:15:02 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. # # New data are always welcome, especially if they are accurate. If you have # anything to contribute, please follow the instructions at the web site. # # This file can be distributed under either the GNU General Public License # (version 2 or higher) or the 3-clause BSD License. # # Vendors, devices and subsystems. Please keep sorted. # Syntax: # vendor vendor_name # device device_name < -- single tab # subvendor subdevice subsystem_name <-- two tabs 0001 SafeNet (wrong ID) 0010 Allied Telesis, Inc (Wrong ID) # This is a relabelled RTL-8139 8139 AT-2500TX V3 Ethernet 001c PEAK-System Technik GmbH 0001 PCAN-PCI CAN-Bus controller 001c 0004 2 Channel CAN Bus SJC1000 001c 0005 2 Channel CAN Bus SJC1000 (Optically Isolated) 003d Lockheed Martin-Marietta Corp # Real TJN ID is e159, but they got it wrong several times --mj 0059 Tiger Jet Network Inc. (Wrong ID) 0070 Hauppauge computer works Inc. 7801 WinTV HVR-1800 MCE 0071 Nebula Electronics Ltd. 0095 Silicon Image, Inc. (Wrong ID) 0680 Ultra ATA/133 IDE RAID CONTROLLER CARD # Wrong ID used in subsystem ID of the TELES.S0/PCI 2.x ISDN adapter 00a7 Teles AG (Wrong ID) 0100 Ncipher Corp Ltd 0123 General Dynamics # 018a is not LevelOne but there is a board misprogrammed 018a LevelOne 0106 FPC-0106TX misprogrammed [RTL81xx] # 021b is not Compaq but there is a board misprogrammed 021b Compaq Computer Corporation 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking] 0270 Hauppauge computer works Inc. (Wrong ID) # SpeedStream is Efficient Networks, Inc, a Siemens Company 02ac SpeedStream 1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx] 0303 Hewlett-Packard Company (Wrong ID) 0308 ZyXEL Communications Corporation (Wrong ID) 0315 SK-Electronics Co., Ltd. 0357 TTTech Computertechnik AG (Wrong ID) 000a TTP-Monitoring Card V2.0 0432 SCM Microsystems, Inc. 0001 Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet] 0675 Dynalink 1700 IS64PH ISDN Adapter 1702 IS64PH ISDN Adapter 1703 ISDN Adapter (PCI Bus, DV, W) 1704 ISDN Adapter (PCI Bus, D, C) 0721 Sapphire, Inc. 0777 Ubiquiti Networks, Inc. 0795 Wired Inc. 6663 Butane II (MPEG2 encoder board) 6666 MediaPress (MPEG2 encoder board) 07d1 D-Link System Inc 0925 VIA Technologies, Inc. (Wrong ID) 0a89 BREA Technologies Inc
I decided to try and produce a “better” PCI utility for the UEFI shell – a utility that would use pci.ids to retrieve and display a description for both the VID and the DID of each device found. This blog post details my experiment.
Before you read any further, if you are unfamiliar with the PCI configuration space, you might wish to read this Wikipedia article. A good reference source for Vendor IDs and Device IDs is pcidatabase.com. It is more complete than the data in pci.ids.
The 16-bit VID and DID registers together identify the device (such as a networking chip), and are commonly called the PCI IDs. The VID is allocated by the PCI-SIG. The DID is assigned by the vendor.
The Subsystem Vendor ID (SVID) and the Subsystem ID (SSID) are used to differentiate between the original equipment manufacturer and the implementation manufacturer. If implemented correctly, the VID/DID/SVID/SSID combination provides a 4 tuple that is unique.
A example is useful here. Suppose Kane Security Devices Limited manufactures a PCI-based security board which uses a Intel LAN on Motherboard (LOM). The company is a member of PCI-SIG and has an assigned DID of 0xEEAA (SVIDs come from the DID namespace). Their DID would go into the SVID register in our example. What goes into the Subvendor Device ID field? Well, it can be anything you like. Some people just start at 1 (0 evidently causes problems) and increment the number for each new design.
Here is the source code for my utility (which I called ShowPCIx):
// // Copyright (c) 2017 Finnbarr P. Murphy. All rights reserved. // // Show PCI devices using PCI.IDS text-based database // // License: UDK2015 license applies to code from UDK2015 source, // BSD 2 cluase license applies to all other code. // #include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellCEntryLib.h> #include <Library/ShellLib.h> #include <Library/ShellCommandLib.h> #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/PrintLib.h> #include <Protocol/EfiShell.h> #include <Protocol/PciEnumerationComplete.h> #include <Protocol/PciRootBridgeIo.h> #include <IndustryStandard/Pci.h> #define CALC_EFI_PCI_ADDRESS(Bus, Dev, Func, Reg) \ ((UINT64) ((((UINTN) Bus) << 24) + (((UINTN) Dev) << 16) + (((UINTN) Func) << 8) + ((UINTN) Reg))) // all typedefs from UDK2015 sources #pragma pack(1) 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; 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; typedef struct { UINT32 CardBusSocketReg; // Cardus Socket/ExCA Base Address Register UINT8 CapabilitiesPtr; // 14h in pci-cardbus bridge. UINT8 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 union { PCI_DEVICE_HEADER Device; PCI_CARDBUS_HEADER CardBus; } NON_COMMON_UNION; typedef struct { PCI_COMMON_HEADER Common; NON_COMMON_UNION NonCommon; UINT32 Data[48]; } PCI_CONFIG_SPACE; #pragma pack() #define UTILITY_VERSION L"0.8" #define LINE_MAX 1024 #define EFI_PCI_EMUMERATION_COMPLETE_GUID \ { 0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93}} CHAR16 * GetDeviceDesc( CHAR16 *Line) { CHAR16 *s = Line; static CHAR16 DeviceDesc[LINE_MAX]; CHAR16 *d = DeviceDesc; s++; while (*s++) { if (*s == L' ' || *s == L'\t') break; } while (*s++) { if (*s != L' ' && *s != L'\t') break; } while (*s) { *(d++) = *(s++); } *d = 0; return DeviceDesc; } CHAR16 * GetVendorDesc( CHAR16 *Line) { CHAR16 *s = Line; static CHAR16 VendorDesc[LINE_MAX]; CHAR16 *d = VendorDesc; while (*s++) { if (*s == L' ' || *s == L'\t') break; } while (*s++) { if (*s != L' ' && *s != L'\t') break; } while (*s) { *(d++) = *(s++); } *d = 0; return VendorDesc; } // // Copied from UDK2015 Source. // EFI_STATUS PciGetNextBusRange( EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, UINT16 *MinBus, UINT16 *MaxBus, BOOLEAN *IsEnd) { *IsEnd = FALSE; if ((*Descriptors) == NULL) { *MinBus = 0; *MaxBus = PCI_MAX_BUS; return EFI_SUCCESS; } 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); } (*Descriptors)++; } if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) { *IsEnd = TRUE; } return EFI_SUCCESS; } // // Copied from UDK2015 Source. // EFI_STATUS PciGetProtocolAndResource( EFI_HANDLE Handle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors) { EFI_STATUS Status; Status = gBS->HandleProtocol( Handle, &gEfiPciRootBridgeIoProtocolGuid, (VOID**)IoDev); if (EFI_ERROR (Status)) { return Status; } Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors); if (Status == EFI_UNSUPPORTED) { *Descriptors = NULL; return EFI_SUCCESS; } return Status; } VOID LowerCaseStr( CHAR16 *Str) { for (int i = 0; Str[i] != L'\0'; i++) { if (Str[i] >= L'A' && Str[i] <= L'Z') { Str[i] -= (CHAR16)(L'A' - L'a'); } } } BOOLEAN SearchPciData( SHELL_FILE_HANDLE FileHandle, CHAR16 *ReadLine, UINTN VendorID, UINTN DeviceID) { EFI_STATUS Status = EFI_SUCCESS; BOOLEAN Found = FALSE; BOOLEAN VendorFound = FALSE; BOOLEAN Ascii = TRUE; UINTN Size = LINE_MAX; CHAR16 Vendor[5]; CHAR16 Device[5]; UnicodeSPrint(Vendor, sizeof(Vendor), L"%04x", VendorID); LowerCaseStr(Vendor); UnicodeSPrint(Device, sizeof(Device), L"%04x", DeviceID); LowerCaseStr(Device); ShellSetFilePosition(FileHandle, 0); // read file line by line for (;!ShellFileHandleEof(FileHandle); Size = 1024) { Status = ShellFileHandleReadLine(FileHandle, ReadLine, &Size, TRUE, &Ascii); if (Status == EFI_BUFFER_TOO_SMALL) { Status = EFI_SUCCESS; } else if (EFI_ERROR(Status)) { break; } // Skip comment and empty lines if (ReadLine[0] == L'#' || ReadLine[0] == L' ' || ReadLine[0] == L'\n' || ReadLine[0] == L'\r') { continue; } if (StrnCmp(ReadLine, Vendor, 4) == 0) { Print(L" %s", GetVendorDesc(ReadLine)); VendorFound = TRUE; } else if (VendorFound && StrnCmp(&ReadLine[1], Device, 4) == 0) { Print(L", %s", GetDeviceDesc(ReadLine)); Found = TRUE; break; } else if (VendorFound && (StrnCmp(ReadLine, L"\t", 1) != 0) && (StrnCmp(ReadLine, L"\t\t", 2) != 0)) { break; } } return Found; } VOID Usage( CHAR16 *Str) { Print(L"Usage: %s [ -v | --verbose ]\n", Str); Print(L" %s [ -h | --help | -V | --version ]\n", Str); } INTN EFIAPI ShellAppMain(UINTN Argc, CHAR16 **Argv) { EFI_GUID gEfiPciEnumerationCompleteProtocolGuid = EFI_PCI_EMUMERATION_COMPLETE_GUID; EFI_STATUS Status = EFI_SUCCESS; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; SHELL_FILE_HANDLE InFileHandle = (SHELL_FILE_HANDLE)NULL; PCI_COMMON_HEADER PciHeader; PCI_CONFIG_SPACE ConfigSpace; PCI_DEVICE_HEADER *DeviceHeader; CHAR16 FileName[] = L"pci.ids"; CHAR16 *FullFileName = (CHAR16 *)NULL; CHAR16 *ReadLine = (CHAR16 *)NULL; VOID *Interface; EFI_HANDLE *HandleBuf; UINTN HandleBufSize; UINTN HandleCount; UINTN Size = LINE_MAX; UINT16 MinBus, MaxBus; UINT64 Address; BOOLEAN IsEnd; BOOLEAN Verbose = FALSE; for (int i = 1; i < Argc; i++) { if (!StrCmp(Argv[i], L"--version") || !StrCmp(Argv[i], L"-V")) { Print(L"Version: %s\n", UTILITY_VERSION); return Status; } else if (!StrCmp(Argv[i], L"--verbose") || !StrCmp(Argv[i], L"-v")) { Verbose = TRUE; } else if (!StrCmp(Argv[i], L"--help") || !StrCmp(Argv[i], L"-h") || !StrCmp(Argv[i], L"-?")) { Usage(Argv[0]); return Status; } else { Print(L"ERROR: Unknown option.\n"); Usage(Argv[0]); return Status; } } Status = gBS->LocateProtocol( &gEfiPciEnumerationCompleteProtocolGuid, NULL, &Interface); if (EFI_ERROR(Status)) { Print(L"ERROR: Could not find an enumerated PCI database\n"); return Status; } HandleBufSize = sizeof(EFI_HANDLE); HandleBuf = (EFI_HANDLE *) AllocateZeroPool( HandleBufSize); if (HandleBuf == NULL) { Print(L"ERROR: Out of memory resources\n"); goto Done; } Status = gBS->LocateHandle( ByProtocol, &gEfiPciRootBridgeIoProtocolGuid, NULL, &HandleBufSize, HandleBuf); if (Status == EFI_BUFFER_TOO_SMALL) { HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf); if (HandleBuf == NULL) { Print(L"ERROR: Out of memory resources\n"); goto Done; } Status = gBS->LocateHandle( ByProtocol, &gEfiPciRootBridgeIoProtocolGuid, NULL, &HandleBufSize, HandleBuf); } if (EFI_ERROR (Status)) { Print(L"ERROR: Failed to find any PCI handles\n"); goto Done; } if (Verbose) { FullFileName = ShellFindFilePath(FileName); if (FullFileName == NULL) { Print(L"ERROR: Could not find %s\n", FileName); Status = EFI_NOT_FOUND; goto Done; } // open the file Status = ShellOpenFileByName(FullFileName, &InFileHandle, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { Print(L"ERROR: Could not open %s\n", FileName); goto Done; } // allocate a buffer to read lines into ReadLine = AllocateZeroPool(Size); if (ReadLine == NULL) { Print(L"ERROR: Could not allocate memory\n"); Status = EFI_OUT_OF_RESOURCES; goto Done; } } HandleCount = HandleBufSize / sizeof (EFI_HANDLE); for (UINT16 Index = 0; Index < HandleCount; Index++) { Status = PciGetProtocolAndResource( HandleBuf[Index], &IoDev, &Descriptors); if (EFI_ERROR(Status)) { Print(L"ERROR: PciGetProtocolAndResource [%d]\n, Status"); goto Done; } while(1) { Status = PciGetNextBusRange( &Descriptors, &MinBus, &MaxBus, &IsEnd); if (EFI_ERROR(Status)) { Print(L"ERROR: Retrieving PCI bus range [%d]\n", Status); goto Done; } if (IsEnd) { break; } Print(L"\n"); Print(L"Bus Vendor Device Subvendor SVDevice\n"); Print(L"\n"); for (UINT16 Bus = MinBus; Bus <= MaxBus; Bus++) { for (UINT16 Device = 0; Device <= PCI_MAX_DEVICE; Device++) { for (UINT16 Func = 0; Func <= PCI_MAX_FUNC; Func++) { Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0); Status = IoDev->Pci.Read( IoDev, EfiPciWidthUint8, Address, sizeof(ConfigSpace), &ConfigSpace); DeviceHeader = (PCI_DEVICE_HEADER *) &(ConfigSpace.NonCommon.Device); Status = IoDev->Pci.Read( IoDev, EfiPciWidthUint16, Address, 1, &PciHeader.VendorId); if (PciHeader.VendorId == 0xffff && Func == 0) { break; } if (PciHeader.VendorId != 0xffff) { Status = IoDev->Pci.Read( IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader); Print(L" %02d %04x %04x %04x %04x", Bus, PciHeader.VendorId, PciHeader.DeviceId, DeviceHeader->SubVendorId, DeviceHeader->SubSystemId); if (Verbose) { SearchPciData( InFileHandle, ReadLine, PciHeader.VendorId, PciHeader.DeviceId); } Print(L"\n"); if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) { break; } } } } } if (Descriptors == NULL) { break; } } } Print(L"\n"); Done: if (HandleBuf != NULL) { FreePool(HandleBuf); } if (Verbose) { if (ReadLine != NULL) { FreePool(ReadLine); } if (FullFileName != NULL) { FreePool(FullFileName); } if (InFileHandle != NULL) { ShellCloseFile(&InFileHandle); } } return Status; }
As usual, it is assumed that you are familiar with the various UEFI specifications and UDK2015 if you are reading this blog post. The above source code is not production quality code and still needs some work to make it more robust. Currently it has no support for displaying SubVendor ID descriptions but the required code to do so can easily be added.
Note that 0xFFFF is the value that is returned on read accesses to PCI configuration space registers of non-existent devices. Hence the test for this value in the above code.
I could also have listed the PCI class code and description for each device but I do not think it adds much value to the output. There are standard classes for every sort of PCI device; for example the class code for a SCSI device is 0x0100.
Here is the UDK2015 build file that I used:
[Defines] INF_VERSION = 0x00010006 BASE_NAME = ShowPCIx FILE_GUID = 4ea87c51-7491-4dfd-0055-767013f3ce51 MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 0.1 ENTRY_POINT = ShellCEntryLib VALID_ARCHITECTURES = X64 [Sources] ShowPCIx.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] ShellCEntryLib ShellLib ShellCommandLib BaseLib BaseMemoryLib UefiLib [Protocols] gEfiPciRootBridgeIoProtocolGuid ## CONSUMES [BuildOptions] [Pcd]
Note that the code has only been built and tested on Intel X64 platforms so there may be architecture-related issues on other platforms.
Use the same laptop, here is the output from my utility:
fs1> ShowPCIx --help Usage: FS1:\ShowPCI.efi [ -v | --verbose ] FS1:\ShowPCI.efi [ -h | --help | -V | --version ] fs1> ShowPCIx Bus Vendor Device Subvendor SVDevice 00 8086 1604 17AA 5034 00 8086 1616 17AA 5034 00 8086 160C 17AA 5034 00 8086 9CB1 17AA 5034 00 8086 9CBA 17AA 5034 00 8086 15A2 17AA 2226 00 8086 9CA0 17AA 5034 00 8086 9C9A 0000 0000 00 8086 9C94 0000 0000 00 8086 9CA6 17AA 5034 00 8086 9CC3 17AA 5034 00 8086 9C83 17AA 5034 00 8086 9CA2 17AA 5034 00 8086 9CA4 17AA 5034 02 10EC 5227 17AA 5034 03 8086 095B 8086 5210 fs1> ShowPCIx --verbose Bus Vendor Device Subvendor SVDevice 00 8086 1604 17AA 5034 Intel Corporation, Broadwell-U Host Bridge -OPI 00 8086 1616 17AA 5034 Intel Corporation, Broadwell-U Integrated Graphics 00 8086 160C 17AA 5034 Intel Corporation, Broadwell-U Audio Controller 00 8086 9CB1 17AA 5034 Intel Corporation, Wildcat Point-LP USB xHCI Controller 00 8086 9CBA 17AA 5034 Intel Corporation, Wildcat Point-LP MEI Controller #1 00 8086 15A2 17AA 2226 Intel Corporation, Ethernet Connection (3) I218-LM 00 8086 9CA0 17AA 5034 Intel Corporation, Wildcat Point-LP High Definition Audio Controller 00 8086 9C9A 0000 0000 Intel Corporation, Wildcat Point-LP PCI Express Root Port #6 00 8086 9C94 0000 0000 Intel Corporation, Wildcat Point-LP PCI Express Root Port #3 00 8086 9CA6 17AA 5034 Intel Corporation, Wildcat Point-LP USB EHCI Controller 00 8086 9CC3 17AA 5034 Intel Corporation, Wildcat Point-LP LPC Controller 00 8086 9C83 17AA 5034 Intel Corporation, Wildcat Point-LP SATA Controller [AHCI Mode] 00 8086 9CA2 17AA 5034 Intel Corporation, Wildcat Point-LP SMBus Controller 00 8086 9CA4 17AA 5034 Intel Corporation, Wildcat Point-LP Thermal Management Controller 02 10EC 5227 17AA 5034 Realtek Semiconductor Co., Ltd., RTS5227 PCI Express Card Reader 03 8086 095B 8086 5210 Intel Corporation, Wireless 7265 fs1>
As you can see, the output is more useful due to the additional of VID and DID descriptions.
Hopefully the developers of the UEFI reference implementation will consider adding support for pci.ids, or a similar database, to a future version of the UEFI shell.
Enjoy!
I hope I can ask a question regarding your article on converting MBR to GPT. I have followed your steps and everything completes without error. When I reboot Fedora 16 I only get GRUB_ with a flashing underscore but no GRUB boot menu. I have hammered on this for a week and this is where I am. SDA1 is flagged bios boot, SDA2 has the Linux OS and SDA3 is storage.
The original install uses MBR and works fine with a 2TB limit. I am trying to move to GPT to expand the drive to 4TB.
I have captured all of the terminal process to text.
How can I recover the GRUB boot menu?