Date
1 - 3 of 3
Questions about unusual PCI location when using EFI_PCI_IO_PROTOCOL in ARM system
gustavo.marcello@...
Hello,
I am learning about PCI and trying to write an application that lists PCI controllers in UEFI environment, using EFI_PCI_IO_PROTOCOL and EDK2. I want to list some information from Configuration Space Header and the Bus/Device/Function location for each instance.
The system that I am executing the application is an ARM, which has a Qualcomm
Snapdragon SoC. The code simply locates all handles for EFI_PCI_IO_PROTOCOL and reads some information from each one, as shown in this code snippet:
EFI_GUID gPciIo = EFI_PCI_IO_PROTOCOL_GUID;
EFI_PCI_IO_PROTOCOL *PciIo;
...
// Locate all handles with PciIo protocol
gBS->LocateHandleBuffer(ByProtocol, &gPciIo, NULL, &NoHandles, &Buffer);
// Scan all found handles
for (Index = 0, Count = 0; Index < NoHandles; Index++) {
// Get PciIo protocol for current handle
gBS->HandleProtocol (Buffer[Index], &gPciIo, (VOID**) &PciIo);
// Get some PCI information
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x00, 2, &VendorId);
...
// Check if VendorId is different from 0xFFFF
...
// Get location
PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
// Show PCI information
...
}
The information retrieved from EFI_PCI_IO_PROTOCOL seems to be OK, except the information from GetLocation that some USB controller handles are returning, as follows:
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x80
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x81
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x82
Function: 0x00
My questions are:
1 - I am not familiar with PCI, but, as far as I know, maximum device number is 32, since it comes from a 5 bits field, am I correct? If so, how can it be 0x80, 0x81 or 0x82, maybe a bug in EFI_PCI_IO_PROTOCOL code or am I missing something?
2 - Usually , the bus numbering use sequential numbers starting from 0 (afaik again), and since it's a simple small system with few PCI components (it does not have 255 buses), what does the number 0xFF for Bus indicates?
PS: "pci" command in UEFI Shell do not show these USB controllers but "devtree" command shows these USB contollers with the same Device/Funcion numbers.
Thanks so much!
I am learning about PCI and trying to write an application that lists PCI controllers in UEFI environment, using EFI_PCI_IO_PROTOCOL and EDK2. I want to list some information from Configuration Space Header and the Bus/Device/Function location for each instance.
The system that I am executing the application is an ARM, which has a Qualcomm
Snapdragon SoC. The code simply locates all handles for EFI_PCI_IO_PROTOCOL and reads some information from each one, as shown in this code snippet:
EFI_GUID gPciIo = EFI_PCI_IO_PROTOCOL_GUID;
EFI_PCI_IO_PROTOCOL *PciIo;
...
// Locate all handles with PciIo protocol
gBS->LocateHandleBuffer(ByProtocol, &gPciIo, NULL, &NoHandles, &Buffer);
// Scan all found handles
for (Index = 0, Count = 0; Index < NoHandles; Index++) {
// Get PciIo protocol for current handle
gBS->HandleProtocol (Buffer[Index], &gPciIo, (VOID**) &PciIo);
// Get some PCI information
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x00, 2, &VendorId);
...
// Check if VendorId is different from 0xFFFF
...
// Get location
PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
// Show PCI information
...
}
The information retrieved from EFI_PCI_IO_PROTOCOL seems to be OK, except the information from GetLocation that some USB controller handles are returning, as follows:
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x80
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x81
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x82
Function: 0x00
My questions are:
1 - I am not familiar with PCI, but, as far as I know, maximum device number is 32, since it comes from a 5 bits field, am I correct? If so, how can it be 0x80, 0x81 or 0x82, maybe a bug in EFI_PCI_IO_PROTOCOL code or am I missing something?
2 - Usually , the bus numbering use sequential numbers starting from 0 (afaik again), and since it's a simple small system with few PCI components (it does not have 255 buses), what does the number 0xFF for Bus indicates?
PS: "pci" command in UEFI Shell do not show these USB controllers but "devtree" command shows these USB contollers with the same Device/Funcion numbers.
Thanks so much!
Laszlo Ersek
On 02/16/21 14:41, gustavo.marcello via groups.io wrote:
"gEfiPciIoProtocolGuid" variable instead.
Also, for the offset, PCI_VENDOR_ID_OFFSET would be more idiomatic.
bridge driver. (I assume they use the PCI bus driver from edk2 without
any modifications.)
Or maybe the MMCONFIG range is misconfigured somehow; not sure.
(I'm reminded of ARI too, which I don't have any practical experience
with, however. ARI seems to permit up to 256 functions, combining the 5
bits from the device number with the 3 bits from the function number.
But a *device* number as high as 0x80 -- and not a function number that
high -- looks a bit fishy still. ARI seems to eliminate the device
number completely.)
a root port, or the downstream port of a switch), the bus number is not
assigned by the PCI bus driver. It's just a platform trait. I don't
think it's necessarily a bug.
Hope this helps; I could only make some guesses.
Laszlo
Hello,Style comment: you should remove "gPciIo", and use the auto-generated
I am learning about PCI and trying to write an application that lists PCI controllers in UEFI environment, using EFI_PCI_IO_PROTOCOL and EDK2. I want to list some information from Configuration Space Header and the Bus/Device/Function location for each instance.
The system that I am executing the application is an ARM, which has a Qualcomm
Snapdragon SoC. The code simply locates all handles for EFI_PCI_IO_PROTOCOL and reads some information from each one, as shown in this code snippet:
EFI_GUID gPciIo = EFI_PCI_IO_PROTOCOL_GUID;
EFI_PCI_IO_PROTOCOL *PciIo;
...
// Locate all handles with PciIo protocol
gBS->LocateHandleBuffer(ByProtocol, &gPciIo, NULL, &NoHandles, &Buffer);
"gEfiPciIoProtocolGuid" variable instead.
Why not read it with a single EfiPciIoWidthUint16 operation?
// Scan all found handles
for (Index = 0, Count = 0; Index < NoHandles; Index++) {
// Get PciIo protocol for current handle
gBS->HandleProtocol (Buffer[Index], &gPciIo, (VOID**) &PciIo);
// Get some PCI information
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x00, 2, &VendorId);
Also, for the offset, PCI_VENDOR_ID_OFFSET would be more idiomatic.
...Yes, I would hazard that this is a bug in your platform's PCI host
// Check if VendorId is different from 0xFFFF
...
// Get location
PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
// Show PCI information
...
}
The information retrieved from EFI_PCI_IO_PROTOCOL seems to be OK, except the information from GetLocation that some USB controller handles are returning, as follows:
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x80
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x81
Function: 0x00
Class: Serial Bus Controller
Subclass: USB Controller
Bus: 0xFF
Device: 0x82
Function: 0x00
My questions are:
1 - I am not familiar with PCI, but, as far as I know, maximum device number is 32, since it comes from a 5 bits field, am I correct? If so, how can it be 0x80, 0x81 or 0x82, maybe a bug in EFI_PCI_IO_PROTOCOL code or am I missing something?
bridge driver. (I assume they use the PCI bus driver from edk2 without
any modifications.)
Or maybe the MMCONFIG range is misconfigured somehow; not sure.
(I'm reminded of ARI too, which I don't have any practical experience
with, however. ARI seems to permit up to 256 functions, combining the 5
bits from the device number with the 3 bits from the function number.
But a *device* number as high as 0x80 -- and not a function number that
high -- looks a bit fishy still. ARI seems to eliminate the device
number completely.)
Assuming the bus number refers to a root bridge (and not a bridge behind
2 - Usually , the bus numbering use sequential numbers starting from 0 (afaik again), and since it's a simple small system with few PCI components (it does not have 255 buses), what does the number 0xFF for Bus indicates?
a root port, or the downstream port of a switch), the bus number is not
assigned by the PCI bus driver. It's just a platform trait. I don't
think it's necessarily a bug.
Hope this helps; I could only make some guesses.
Laszlo
PS: "pci" command in UEFI Shell do not show these USB controllers but "devtree" command shows these USB contollers with the same Device/Funcion numbers.
Thanks so much!
gustavo.marcello@...
Hi Laszlo Ersek,
Thanks for the style comments, I appreciate it, I will do these changes.
And, for the questions, I agree, for the first question, that seems to be a platform driver bug and, for the second one, it seems something related to the platform as you said. I will try to contact the manufacturer to clarify if it's correct.
Thanks so much for your reply, it was very helpful!
Thanks for the style comments, I appreciate it, I will do these changes.
And, for the questions, I agree, for the first question, that seems to be a platform driver bug and, for the second one, it seems something related to the platform as you said. I will try to contact the manufacturer to clarify if it's correct.
Thanks so much for your reply, it was very helpful!