MdeModulePkg/NonDiscoverablePciDeviceDxe: expose unique B/D/F identifiers

Currently, the implementation of EFI_PCI_IO_PROTOCOL::GetLocation()
in NonDiscoverablePciDeviceDxe returns the same set of dummy values
for each instance of the NON_DISCOVERABLE_DEVICE protocol that it
attaches itself to. However, this turns out to be causing problems
in cases where software (such as the ARM Compliance Test Suite [ACS])
attempts to use these values to uniquely identify controllers, since
the collisions create ambiguity in this regard.

So let's modify GetLocation() to return an arbitrary bus/device tuple
on segment 0xff instead. This is guaranteed not to clash with other
non-discoverable PCI devices, and highly unlikely to clash with real
PCIe devices.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Ard Biesheuvel 2018-10-10 10:34:50 +02:00
parent 2730470f9d
commit 1a3bee2082
3 changed files with 23 additions and 3 deletions

View File

@ -16,6 +16,9 @@
#include <Protocol/DriverBinding.h>
#define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)
STATIC UINTN mUniqueIdCounter = 0;
EFI_CPU_ARCH_PROTOCOL *mCpu;
//
@ -141,6 +144,11 @@ NonDiscoverablePciDeviceStart (
NON_DISCOVERABLE_PCI_DEVICE *Dev;
EFI_STATUS Status;
ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);
if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {
return EFI_OUT_OF_RESOURCES;
}
Dev = AllocateZeroPool (sizeof *Dev);
if (Dev == NULL) {
return EFI_OUT_OF_RESOURCES;
@ -167,6 +175,8 @@ NonDiscoverablePciDeviceStart (
goto CloseProtocol;
}
Dev->UniqueId = mUniqueIdCounter++;
return EFI_SUCCESS;
CloseProtocol:

View File

@ -1181,6 +1181,8 @@ PciIoGetLocation (
OUT UINTN *FunctionNumber
)
{
NON_DISCOVERABLE_PCI_DEVICE *Dev;
if (SegmentNumber == NULL ||
BusNumber == NULL ||
DeviceNumber == NULL ||
@ -1188,9 +1190,11 @@ PciIoGetLocation (
return EFI_INVALID_PARAMETER;
}
*SegmentNumber = 0;
*BusNumber = 0xff;
*DeviceNumber = 0;
Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This);
*SegmentNumber = 0xff;
*BusNumber = Dev->UniqueId >> 5;
*DeviceNumber = Dev->UniqueId & 0x1f;
*FunctionNumber = 0;
return EFI_SUCCESS;

View File

@ -100,6 +100,12 @@ typedef struct {
// on behalf of this device
//
LIST_ENTRY UncachedAllocationList;
//
// Unique ID for this device instance: needed so that we can report unique
// segment/bus/device number for each device instance. Note that this number
// may change when disconnecting/reconnecting the driver.
//
UINTN UniqueId;
} NON_DISCOVERABLE_PCI_DEVICE;
/**