Skip to content

Commit c2df5b4

Browse files
Andrei Warkentinandreiw
authored andcommitted
Application: add PciInfo tool.
This might seem a strange tool to have in FdtBusPkg, but it is very useful in diagnosing PciHostBridgeFdtDxe, as it shows BARs and both bus- and CPU-side addresses. Signed-off-by: Andrei Warkentin <[email protected]>
1 parent 7b7eb2e commit c2df5b4

File tree

4 files changed

+322
-2
lines changed

4 files changed

+322
-2
lines changed

Application/PciInfo/PciInfo.c

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/** @file
2+
3+
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
4+
Copyright (C) 2016 Andrei Evgenievich Warkentin
5+
6+
SPDX-License-Identifier: BSD-2-Clause-Patent
7+
8+
**/
9+
10+
#include <Uefi.h>
11+
#include <Library/UefiLib.h>
12+
#include <Library/MemoryAllocationLib.h>
13+
#include <Library/UefiBootServicesTableLib.h>
14+
#include <Library/UefiApplicationEntryPoint.h>
15+
#include <Library/DevicePathLib.h>
16+
#include <Library/FbpAppUtilsLib.h>
17+
#include <Protocol/PciIo.h>
18+
#include <IndustryStandard/Pci.h>
19+
#include <IndustryStandard/Acpi.h>
20+
21+
STATIC BOOLEAN mVerbose;
22+
23+
STATIC
24+
EFI_STATUS
25+
Usage (
26+
IN CHAR16 *Name
27+
)
28+
{
29+
Print (L"Usage: %s [-v] [seg bus dev func]\n", Name);
30+
return EFI_INVALID_PARAMETER;
31+
}
32+
33+
STATIC
34+
EFI_STATUS
35+
Dump (
36+
IN UINTN Seg,
37+
IN UINTN Bus,
38+
IN UINTN Dev,
39+
IN UINTN Func,
40+
IN EFI_PCI_IO_PROTOCOL *PciIo
41+
)
42+
{
43+
UINTN Index;
44+
EFI_STATUS Status;
45+
PCI_DEVICE_INDEPENDENT_REGION Hdr;
46+
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
47+
48+
Hdr.DeviceId = Hdr.VendorId = 0xffff;
49+
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, sizeof (Hdr) / sizeof (UINT16), &Hdr);
50+
if (!mVerbose) {
51+
Print (
52+
L"%04x:%02x:%02x.%02x: Vendor: %04x Device: %04x\n",
53+
Seg,
54+
Bus,
55+
Dev,
56+
Func,
57+
Hdr.VendorId,
58+
Hdr.DeviceId
59+
);
60+
return EFI_SUCCESS;
61+
}
62+
63+
Print (
64+
L"%04x:%02x:%02x.%02x info:\n",
65+
Seg,
66+
Bus,
67+
Dev,
68+
Func
69+
);
70+
71+
Print (L"-------------------------\n");
72+
73+
Print (L"Vendor: %04x Device: %04x\n", Hdr.VendorId, Hdr.DeviceId);
74+
75+
for (Index = 0; Index < PCI_MAX_BAR; Index++) {
76+
BarDesc = NULL;
77+
Status = PciIo->GetBarAttributes (
78+
PciIo,
79+
Index,
80+
NULL,
81+
(VOID **)&BarDesc
82+
);
83+
if (Status == EFI_UNSUPPORTED) {
84+
break;
85+
}
86+
87+
Print (L"BAR%u: ", Index);
88+
89+
if (EFI_ERROR (Status)) {
90+
Print (L"error fetching (%r)\n", Status);
91+
continue;
92+
}
93+
94+
if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
95+
Print (L"MEM%u ", BarDesc->AddrSpaceGranularity);
96+
} else if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {
97+
Print (L"IO ");
98+
} else {
99+
Print (L"bad type 0x%x\n", BarDesc->ResType);
100+
continue;
101+
}
102+
103+
Print (
104+
L"CPU 0x%016lx -> PCI 0x%016lx (0x%x)\n",
105+
BarDesc->AddrRangeMin,
106+
BarDesc->AddrRangeMin + BarDesc->AddrTranslationOffset,
107+
BarDesc->AddrLen
108+
);
109+
110+
FreePool (BarDesc);
111+
}
112+
113+
Print (L"\n");
114+
115+
return EFI_SUCCESS;
116+
}
117+
118+
EFI_STATUS
119+
EFIAPI
120+
EntryPoint (
121+
IN EFI_HANDLE ImageHandle,
122+
IN EFI_SYSTEM_TABLE *SystemTable
123+
)
124+
{
125+
UINTN Argc;
126+
CHAR16 **Argv;
127+
UINTN WantSeg;
128+
UINTN WantBus;
129+
UINTN WantDev;
130+
UINTN WantFunc;
131+
UINTN PciIndex;
132+
UINTN PciCount;
133+
EFI_STATUS Status;
134+
EFI_HANDLE *PciHandles;
135+
EFI_PCI_IO_PROTOCOL *PciIo;
136+
GET_OPT_CONTEXT GetOptContext;
137+
BOOLEAN AllDevs;
138+
139+
Status = GetShellArgcArgv (ImageHandle, &Argc, &Argv);
140+
if (Status != EFI_SUCCESS) {
141+
Print (
142+
L"This program requires Microsoft Windows.\n"
143+
"Just kidding...only the UEFI Shell!\n"
144+
);
145+
return EFI_ABORTED;
146+
}
147+
148+
INIT_GET_OPT_CONTEXT (&GetOptContext);
149+
while ((Status = GetOpt (
150+
Argc,
151+
Argv,
152+
L"",
153+
&GetOptContext
154+
)) == EFI_SUCCESS)
155+
{
156+
switch (GetOptContext.Opt) {
157+
case L'v':
158+
mVerbose = TRUE;
159+
break;
160+
default:
161+
Print (L"Unknown option '%c'\n", GetOptContext.Opt);
162+
return Usage (Argv[0]);
163+
}
164+
}
165+
166+
if ((Argc - GetOptContext.OptIndex) == 0) {
167+
WantSeg = (UINTN)-1;
168+
WantBus = (UINTN)-1;
169+
WantDev = (UINTN)-1;
170+
WantFunc = (UINTN)-1;
171+
AllDevs = TRUE;
172+
} else if ((Argc - GetOptContext.OptIndex) == 4) {
173+
WantSeg = StrHexToUintn (Argv[GetOptContext.OptIndex]);
174+
WantBus = StrHexToUintn (Argv[GetOptContext.OptIndex + 1]);
175+
WantDev = StrHexToUintn (Argv[GetOptContext.OptIndex + 2]);
176+
WantFunc = StrHexToUintn (Argv[GetOptContext.OptIndex + 3]);
177+
AllDevs = FALSE;
178+
mVerbose = TRUE;
179+
} else {
180+
return Usage (Argv[0]);
181+
}
182+
183+
PciCount = 0;
184+
PciHandles = NULL;
185+
Status = gBS->LocateHandleBuffer (
186+
ByProtocol,
187+
&gEfiPciIoProtocolGuid,
188+
NULL,
189+
&PciCount,
190+
&PciHandles
191+
);
192+
if (Status != EFI_SUCCESS) {
193+
Print (L"No PCI devices found\n");
194+
return EFI_SUCCESS;
195+
}
196+
197+
for (PciIndex = 0; PciIndex < PciCount; PciIndex++) {
198+
UINTN Seg;
199+
UINTN Bus;
200+
UINTN Dev;
201+
UINTN Func;
202+
203+
Status = gBS->HandleProtocol (
204+
PciHandles[PciIndex],
205+
&gEfiPciIoProtocolGuid,
206+
(VOID *)&PciIo
207+
);
208+
209+
if (Status != EFI_SUCCESS) {
210+
Print (L"Couldn't get EFI_PCI_IO_PROTOCOL: %r\n", Status);
211+
continue;
212+
}
213+
214+
Status = PciIo->GetLocation (PciIo, &Seg, &Bus, &Dev, &Func);
215+
if (Status != EFI_SUCCESS) {
216+
Print (L"GetLocation failed: %r\n", Status);
217+
continue;
218+
}
219+
220+
if (!AllDevs) {
221+
if ((WantSeg != Seg) ||
222+
(WantBus != Bus) ||
223+
(WantDev != Dev) ||
224+
(WantFunc != Func))
225+
{
226+
continue;
227+
}
228+
}
229+
230+
Status = Dump (
231+
Seg,
232+
Bus,
233+
Dev,
234+
Func,
235+
PciIo
236+
);
237+
if (!AllDevs) {
238+
break;
239+
}
240+
}
241+
242+
if (!AllDevs) {
243+
if (PciIndex == PciCount) {
244+
Print (
245+
L"%04x:%02x:%02x.%02x not found\n",
246+
WantSeg,
247+
WantBus,
248+
WantDev,
249+
WantFunc
250+
);
251+
Status = EFI_NOT_FOUND;
252+
}
253+
}
254+
255+
gBS->FreePool (PciHandles);
256+
return Status;
257+
}

Application/PciInfo/PciInfo.inf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## @file
2+
#
3+
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
4+
#
5+
# SPDX-License-Identifier: BSD-2-Clause-Patent
6+
#
7+
##
8+
9+
[Defines]
10+
INF_VERSION = 0x00010019
11+
BASE_NAME = PciInfo
12+
FILE_GUID = A57F1751-649A-4581-B2A0-56D17E1B148C
13+
MODULE_TYPE = UEFI_APPLICATION
14+
VERSION_STRING = 1.0
15+
ENTRY_POINT = EntryPoint
16+
17+
[Sources]
18+
PciInfo.c
19+
20+
[Packages]
21+
MdePkg/MdePkg.dec
22+
MdeModulePkg/MdeModulePkg.dec
23+
FdtBusPkg/FdtBusPkg.dec
24+
25+
[LibraryClasses]
26+
UefiLib
27+
FbpAppUtilsLib
28+
UefiApplicationEntryPoint
29+
UefiBootServicesTableLib
30+
31+
[Protocols]
32+
gEfiPciIoProtocolGuid

Docs/Developers.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,37 @@ Write 1 byte at offset 0:
265265
Shell> FS0:\DtReg soc/serial@10000000 0 41
266266
```
267267
268+
### PciInfo.efi
269+
270+
Tool for dumping BAR info for PCI devices.
271+
272+
This might seem a strange tool to have in FdtBusPkg, but it
273+
is very useful in diagnosing PciHostBridgeFdtDxe, as it
274+
shows BARs and both bus- and CPU-side addresses.
275+
276+
#### Usage
277+
278+
```
279+
Shell> FS0:\PciInfo [-v] [seg bus dev func]
280+
```
281+
282+
#### Parameter
283+
284+
* `-v`: verbose, dumping info for all PCI devices when a device is not specified.
285+
286+
#### Examples
287+
288+
Shows the BAR configuration (bus address, CPU address, region length).
289+
290+
```
291+
Shell> PciInfo 0000 00 02 00
292+
0000:00:02.00 info:
293+
-------------------------
294+
Vendor: 1AF4 Device: 1005
295+
BAR0: IO CPU 0x0000000003000020 -> PCI 0x0000000000000020 (0x20)
296+
BAR1: MEM32 CPU 0x0000000040045000 -> PCI 0x0000000040045000 (0x1000)
297+
```
298+
268299
## FAQ
269300
270301
### How do I load a standalone built driver?

FdtBusPkgApps.dsc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## @file
22
#
3-
# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
3+
# Copyright (c) 2023-2024, Intel Corporation. All rights reserved.<BR>
44
#
55
# SPDX-License-Identifier: BSD-2-Clause-Patent
66
#
@@ -93,4 +93,4 @@
9393
FdtBusPkg/Application/DtInfo/DtInfo.inf
9494
FdtBusPkg/Application/DtProp/DtProp.inf
9595
FdtBusPkg/Application/DtReg/DtReg.inf
96-
96+
FdtBusPkg/Application/PciInfo/PciInfo.inf

0 commit comments

Comments
 (0)