aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lesson_32/README.md144
-rw-r--r--Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.c376
-rw-r--r--Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.inf22
3 files changed, 542 insertions, 0 deletions
diff --git a/Lesson_32/README.md b/Lesson_32/README.md
new file mode 100644
index 0000000..7eea2b3
--- /dev/null
+++ b/Lesson_32/README.md
@@ -0,0 +1,144 @@
+https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/PciRootBridgeIo.h
+```
+typedef struct _EFI_PCI_IO_PROTOCOL {
+EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem;
+ EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo;
+ EFI_PCI_IO_PROTOCOL_ACCESS Mem;
+ EFI_PCI_IO_PROTOCOL_ACCESS Io;
+ EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci;
+ EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem;
+ EFI_PCI_IO_PROTOCOL_MAP Map;
+ EFI_PCI_IO_PROTOCOL_UNMAP Unmap;
+ EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
+ EFI_PCI_IO_PROTOCOL_FLUSH Flush;
+ EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation;
+ EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes;
+ EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes;
+ EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes;
+ UINT64 RomSize;
+ VOID *RomImage;
+} EFI_PCI_IO_PROTOCOL;
+```
+
+As you can see it is pretty simiilar to `EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL`. Here is a comparision of these two:
+```
+typedef struct _EFI_PCI_IO_PROTOCOL { typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL {
+ EFI_HANDLE ParentHandle;
+ EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem;
+ EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo;
+ EFI_PCI_IO_PROTOCOL_ACCESS Mem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem;
+ EFI_PCI_IO_PROTOCOL_ACCESS Io; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io;
+ EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci;
+ EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem;
+ EFI_PCI_IO_PROTOCOL_MAP Map; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map;
+ EFI_PCI_IO_PROTOCOL_UNMAP Unmap; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap;
+ EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
+ EFI_PCI_IO_PROTOCOL_FLUSH Flush; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush;
+ EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation;
+ EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes;
+ EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes;
+ EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes;
+ UINT64 RomSize;
+ VOID *RomImage;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration;
+ UINT32 SegmentNumber;
+} EFI_PCI_IO_PROTOCOL; } EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;
+```
+
+
+
+
+```
+RomSize The size, in bytes, of the ROM image.
+RomImage A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible
+ for allocating memory for the ROM image, and copying the contents of the ROM to memory.
+ The contents of this buffer are either from the PCI option ROM that can be accessed
+ through the ROM BAR of the PCI controller, or it is from a platformspecific location.
+ The Attributes() function can be used to determine from which of these two sources
+ the RomImage buffer was initialized
+```
+
+```
+GetLocation Retrieves this PCI controller’s current PCI bus number, device
+number, and function number
+```
+
+
+```
+EFI_PCI_IO_PROTOCOL.GetLocation()
+
+Summary:
+Retrieves this PCI controller’s current PCI bus number, device number, and function number.
+
+Prototype:
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION) (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *SegmentNumber,
+ OUT UINTN *BusNumber,
+ OUT UINTN *DeviceNumber,
+ OUT UINTN *FunctionNumber
+ );
+
+Parameters:
+This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+SegmentNumber The PCI controller’s current PCI segment number.
+BusNumber The PCI controller’s current PCI bus number.
+DeviceNumber The PCI controller’s current PCI device number.
+FunctionNumber The PCI controller’s current PCI function number.
+
+Description:
+The GetLocation() function retrieves a PCI controller’s current location on a PCI Host Bridge. This is
+specified by a PCI segment number, PCI bus number, PCI device number, and PCI function number. These
+values can be used with the PCI Root Bridge I/O Protocol to perform PCI configuration cycles on the PCI
+controller, or any of its peer PCI controller’s on the same PCI Host Bridge.
+```
+
+```
+FS0:\> DumpPCIroms.efi
+Number of PCI devices in the system: 5
+00:00.00 - Vendor:8086, Device:1237
+00:01.00 - Vendor:8086, Device:7000
+00:01.01 - Vendor:8086, Device:7010
+00:01.03 - Vendor:8086, Device:7113
+00:02.00 - Vendor:1234, Device:1111
+ Has OptionROM: address=6E91018, size=39424
+```
+
+```
+FS0:\> dmem 6E91018 30
+Memory Address 0000000006E91018 30 Bytes
+ 06E91018: 55 AA 4D E9 AE 55 B4 00-00 00 00 00 00 00 00 00 *U.M..U..........*
+ 06E91028: 00 00 00 00 00 00 00 00-3C 98 00 00 00 00 49 42 *........<.....IB*
+ 06E91038: 4D 00 2E 8B 16 C6 98 85-D2 74 01 EE C2 02 00 66 *M........t.....f*
+```
+
+https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/Pci22.h
+```
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
+
+...
+
+///
+/// Standard PCI Expansion ROM Header
+/// Section 13.4.2, Unified Extensible Firmware Interface Specification, Version 2.1
+///
+typedef struct {
+ UINT16 Signature; ///< 0xaa55
+ UINT8 Reserved[0x16];
+ UINT16 PcirOffset;
+} PCI_EXPANSION_ROM_HEADER;
+```
+
+
+
+```
+$ git clone git://git.ipxe.org/ipxe.git
+$ cd ipxe/src
+$ make bin-x86_64-efi/ipxe.efi # EFI app with all devices
+$ make bin-x86_64-efi/808610de.efirom # EFI ROM vendev: 8086:10de
+$ make bin/808610de.rom # Legacy ROM vendev: 8086:10de
+```
diff --git a/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.c b/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.c
new file mode 100644
index 0000000..9842a36
--- /dev/null
+++ b/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.c
@@ -0,0 +1,376 @@
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/PciIo.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/ShellLib.h>
+#include <Library/PrintLib.h>
+
+#include <IndustryStandard/PeImage.h>
+
+
+#define DESCRIPTOR_STR_MAX_SIZE 200
+#define BLOCK_READ_SIZE (1024*4)
+
+VOID ToLowerASCII(CHAR8* Str, UINTN Size)
+{
+ for (UINT8 i=0; i<Size; i++) {
+ if ((Str[i]>='A')&&(Str[i]<='Z')) {
+ Str[i]+=32;
+ }
+ }
+}
+
+EFI_STATUS FindPCIDevDescription(UINT16 VendorId,
+ UINT16 DeviceId,
+ CHAR16* VendorDesc,
+ CHAR16* DeviceDesc,
+ UINTN DescBufferSize)
+{
+ EFI_STATUS Status = ShellFileExists(L"pci.ids");
+ if (EFI_ERROR(Status))
+ {
+ Print(L"No file pci.ids: %r\n", Status);
+ return Status;
+ }
+
+ SHELL_FILE_HANDLE FileHandle;
+ Status = ShellOpenFileByName(L"pci.ids",
+ &FileHandle,
+ EFI_FILE_MODE_READ,
+ 0);
+ if (EFI_ERROR(Status))
+ {
+ Print(L"Can't open file pci.ids: %r\n", Status);
+ return Status;
+ }
+
+ UINT64 FileSize;
+ Status = ShellGetFileSize(FileHandle, &FileSize);
+ if (EFI_ERROR(Status))
+ {
+ Print(L"Can't get file size for file pci.ids: %r\n", Status);
+ goto end;
+ }
+
+ CHAR8 VendorStr[5];
+ CHAR8 DeviceStr[5];
+ AsciiValueToStringS(VendorStr,
+ 5,
+ RADIX_HEX | PREFIX_ZERO,
+ VendorId,
+ 4);
+ AsciiValueToStringS(DeviceStr,
+ 5,
+ RADIX_HEX | PREFIX_ZERO,
+ DeviceId,
+ 4);
+ ToLowerASCII(VendorStr, 4);
+ ToLowerASCII(DeviceStr, 4);
+
+ CHAR8 Buffer[BLOCK_READ_SIZE];
+ UINTN Size;
+ UINT64 FilePos = 0;
+ BOOLEAN Vendor_found = FALSE;
+ BOOLEAN Device_found = FALSE;
+ while (TRUE)
+ {
+ Size = BLOCK_READ_SIZE;
+ Status = ShellReadFile(FileHandle, &Size, Buffer);
+ if (EFI_ERROR(Status))
+ {
+ Print(L"Can't read file pci.ids: %r\n", Status);
+ goto end;
+ }
+ UINTN StrStart = 0;
+ UINTN StrEnd = 0;
+ for (UINTN i=0; i<Size; i++) {
+ if (Buffer[i]=='\n') {
+ StrEnd=i;
+ if (!Vendor_found){
+ // 0123456 7
+ //\nXXXX |<desc>|\n
+ if ((StrEnd - StrStart) > 7) {
+ if ((Buffer[StrStart+1]==VendorStr[0]) &&
+ (Buffer[StrStart+2]==VendorStr[1]) &&
+ (Buffer[StrStart+3]==VendorStr[2]) &&
+ (Buffer[StrStart+4]==VendorStr[3])) {
+ Buffer[StrEnd] = 0;
+ UnicodeSPrintAsciiFormat(VendorDesc, DescBufferSize, "%a", &Buffer[StrStart+1+4+2]);
+ Vendor_found = TRUE;
+ }
+ }
+ } else {
+ // 0 1234567 8
+ //\n\tXXXX |<desc>|\n
+ if ((StrEnd - StrStart) > 8) {
+ if ((Buffer[StrStart+1]=='\t') &&
+ (Buffer[StrStart+2]==DeviceStr[0]) &&
+ (Buffer[StrStart+3]==DeviceStr[1]) &&
+ (Buffer[StrStart+4]==DeviceStr[2]) &&
+ (Buffer[StrStart+5]==DeviceStr[3])) {
+ Buffer[StrEnd] = 0;
+ UnicodeSPrintAsciiFormat(DeviceDesc, DescBufferSize, "%a", &Buffer[StrStart+1+1+4+2]);
+ Device_found = TRUE;
+ break;
+ }
+ }
+ }
+ StrStart = StrEnd;
+ }
+ }
+
+ if (FilePos+Size >= FileSize) {
+ break;
+ }
+ FilePos += StrEnd;
+ Status = ShellSetFilePosition(FileHandle, FilePos);
+ if (EFI_ERROR(Status))
+ {
+ Print(L"Can't set file position pci.ids: %r\n", Status);
+ goto end;
+ }
+ }
+
+end:
+ if (!Vendor_found) {
+ UnicodeSPrint(VendorDesc, DescBufferSize, L"Undefined");
+ }
+ if (!Device_found) {
+ UnicodeSPrint(DeviceDesc, DescBufferSize, L"Undefined");
+ }
+ ShellCloseFile(&FileHandle);
+
+ return Status;
+}
+
+
+UINT64 PciConfigurationAddress(UINT8 Bus,
+ UINT8 Device,
+ UINT8 Function,
+ UINT32 Register)
+{
+ UINT64 Address = (((UINT64)Bus) << 24) + (((UINT64)Device) << 16) + (((UINT64)Function) << 8);
+ if (Register & 0xFFFFFF00) {
+ Address += (((UINT64)Register) << 32);
+ } else {
+ Address += (((UINT64)Register) << 0);
+ }
+ return Address;
+}
+
+
+EFI_STATUS PrintPCI(EFI_PCI_IO_PROTOCOL* PciIo)
+{
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+ EFI_STATUS Status = PciIo->GetLocation(PciIo,
+ &SegmentNumber,
+ &BusNumber,
+ &DeviceNumber,
+ &FunctionNumber);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error in getting PCI location: %r\n", Status);
+ return Status;
+ }
+
+ PCI_DEVICE_INDEPENDENT_REGION PCIConfHdr;
+ Status = PciIo->Pci.Read(PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof(PCI_DEVICE_INDEPENDENT_REGION),
+ &PCIConfHdr);
+
+ if (EFI_ERROR(Status)) {
+ Print(L"Error in reading PCI conf space: %r\n", Status);
+ return Status;
+ }
+
+ if (PciIo->RomSize) {
+
+ Print(L"%02x:%02x.%02x - Vendor:%04x, Device:%04x", BusNumber,
+ DeviceNumber,
+ FunctionNumber,
+ PCIConfHdr.VendorId,
+ PCIConfHdr.DeviceId);
+
+ CHAR16 VendorDesc[DESCRIPTOR_STR_MAX_SIZE];
+ CHAR16 DeviceDesc[DESCRIPTOR_STR_MAX_SIZE];
+ Status = FindPCIDevDescription(PCIConfHdr.VendorId,
+ PCIConfHdr.DeviceId,
+ VendorDesc,
+ DeviceDesc,
+ DESCRIPTOR_STR_MAX_SIZE);
+ if (!EFI_ERROR(Status)) {
+ Print(L": %s, %s\n", VendorDesc, DeviceDesc);
+ } else {
+ Print(L"\n");
+ }
+ Print(L"Has OptionROM at memory %p-%p\n", PciIo->RomImage, (UINT8*)PciIo->RomImage + PciIo->RomSize);
+ PCI_EXPANSION_ROM_HEADER* RomHeader = (PCI_EXPANSION_ROM_HEADER*) PciIo->RomImage;
+ UINTN RomImageIndex = 1;
+ while (TRUE)
+ {
+ if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+ Print(L"Error! OptionROM has a wrong signature\n");
+ return Status;
+ }
+ PCI_DATA_STRUCTURE* RomImage = (PCI_DATA_STRUCTURE*)((UINT8*)RomHeader + RomHeader->PcirOffset);
+ if ((((CHAR8)((RomImage->Signature >> 0) & 0xFF)) != 'P') &&
+ (((CHAR8)((RomImage->Signature >> 8) & 0xFF)) != 'C') &&
+ (((CHAR8)((RomImage->Signature >> 16) & 0xFF)) != 'I') &&
+ (((CHAR8)((RomImage->Signature >> 24) & 0xFF)) != 'R')) {
+ Print(L"Error! OptionROM image has wrong signature\n");
+ return Status;
+ }
+ Print(L"---Code Image %d---\n", RomImageIndex);
+ Print(L"Address: %p-%p\n", RomHeader, (UINT8*)RomHeader + (RomImage->ImageLength)*512);
+ Print(L"VendorId: %04x, DeviceId: %04x\n", RomImage->VendorId, RomImage->DeviceId);
+ Print(L"Type: ");
+ switch (RomImage->CodeType) {
+ case 0x00:
+ Print(L"IA-32, PC-AT compatible\n");
+ break;
+ case 0x01:
+ Print(L"Open Firmware standard for PCI\n");
+ break;
+ case 0x02:
+ Print(L"Hewlett-Packard PA RISC\n");
+ break;
+ case 0x03:
+ Print(L"EFI Image\n");
+ break;
+ default:
+ Print(L"Unknown\n");
+ break;
+ }
+ if (RomImage->CodeType == 0x03) {
+ EFI_PCI_EXPANSION_ROM_HEADER* EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER*) RomHeader;
+ if (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) {
+ Print(L"Subsystem: ");
+ switch (EfiRomHeader->EfiSubsystem) {
+ case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ Print(L"EFI Application\n");
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ Print(L"EFI Boot Service Driver\n");
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ Print(L"EFI Runtime Driver\n");
+ break;
+ case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+ Print(L"EFI SAL Runtime Driver\n");
+ break;
+ default:
+ Print(L"Unknown\n");
+ break;
+ }
+ Print(L"Machine type: ");
+ switch (EfiRomHeader->EfiMachineType) {
+ case IMAGE_FILE_MACHINE_I386:
+ Print(L"IA-32\n");
+ break;
+ case IMAGE_FILE_MACHINE_IA64:
+ Print(L"Itanium\n");
+ break;
+ case IMAGE_FILE_MACHINE_EBC:
+ Print(L"EFI Byte Code (EBC)\n");
+ break;
+ case IMAGE_FILE_MACHINE_X64:
+ Print(L"X64\n");
+ break;
+ case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
+ Print(L"ARM\n");
+ break;
+ case IMAGE_FILE_MACHINE_ARM64:
+ Print(L"ARM 64-bit\n");
+ break;
+ case IMAGE_FILE_MACHINE_RISCV32:
+ Print(L"RISCV32\n");
+ break;
+ case IMAGE_FILE_MACHINE_RISCV64:
+ Print(L"RISCV64\n");
+ break;
+ case IMAGE_FILE_MACHINE_RISCV128:
+ Print(L"RISCV128\n");
+ break;
+ default:
+ Print(L"Unknown\n");
+ break;
+ }
+ switch (EfiRomHeader->CompressionType) {
+ case EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED:
+ Print(L"Compressed following the UEFI Compression Algorithm\n");
+ break;
+ case 0:
+ Print(L"Uncompressed\n");
+ break;
+ default:
+ Print(L"Unknown compression type\n");
+ break;
+ }
+ } else {
+ Print(L"EFI signature is incorrect!\n");
+ }
+ }
+ if ((RomImage->Indicator) & 0x80) {
+ break;
+ }
+ RomHeader = (PCI_EXPANSION_ROM_HEADER*)((UINT8*) RomHeader + (RomImage->ImageLength)*512);
+ RomImageIndex++;
+ }
+ Print(L"------------------\n");
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ Status = gBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ Print(L"Can't locate EFI_PCI_IO_PROTOCOL: %r\n", Status);
+ return Status;
+ }
+
+ //Print(L"Number of PCI devices in the system: %d\n", HandleCount);
+ EFI_PCI_IO_PROTOCOL* PciIo;
+ for (UINTN Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->OpenProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR(Status)) {
+ Print(L"Can't open protocol: %r\n", Status);
+ return Status;
+ }
+ Status = PrintPCI(PciIo);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error in PCI printing\n");
+ }
+
+ }
+ FreePool(HandleBuffer);
+
+ return EFI_SUCCESS;
+}
diff --git a/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.inf b/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.inf
new file mode 100644
index 0000000..213a8e4
--- /dev/null
+++ b/Lesson_32/UefiLessonsPkg/DumpPCIroms/DumpPCIroms.inf
@@ -0,0 +1,22 @@
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = DumpPCIroms
+ FILE_GUID = 76f1798f-533f-49a2-b94c-96ab3dfebea0
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ DumpPCIroms.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ ShellLib
+
+[Protocols]
+ gEfiPciIoProtocolGuid