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>
\r
#include <Protocol/DriverBinding.h>\r
\r
+#define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)\r
+\r
+STATIC UINTN mUniqueIdCounter = 0;\r
EFI_CPU_ARCH_PROTOCOL *mCpu;\r
\r
//\r
NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
EFI_STATUS Status;\r
\r
+ ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);\r
+ if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
Dev = AllocateZeroPool (sizeof *Dev);\r
if (Dev == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
goto CloseProtocol;\r
}\r
\r
+ Dev->UniqueId = mUniqueIdCounter++;\r
+\r
return EFI_SUCCESS;\r
\r
CloseProtocol:\r
OUT UINTN *FunctionNumber\r
)\r
{\r
+ NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
+\r
if (SegmentNumber == NULL ||\r
BusNumber == NULL ||\r
DeviceNumber == NULL ||\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- *SegmentNumber = 0;\r
- *BusNumber = 0xff;\r
- *DeviceNumber = 0;\r
+ Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This);\r
+\r
+ *SegmentNumber = 0xff;\r
+ *BusNumber = Dev->UniqueId >> 5;\r
+ *DeviceNumber = Dev->UniqueId & 0x1f;\r
*FunctionNumber = 0;\r
\r
return EFI_SUCCESS;\r
// on behalf of this device\r
//\r
LIST_ENTRY UncachedAllocationList;\r
+ //\r
+ // Unique ID for this device instance: needed so that we can report unique\r
+ // segment/bus/device number for each device instance. Note that this number\r
+ // may change when disconnecting/reconnecting the driver.\r
+ //\r
+ UINTN UniqueId;\r
} NON_DISCOVERABLE_PCI_DEVICE;\r
\r
/**\r