|
| 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 | +} |
0 commit comments