3 Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "NonDiscoverablePciDeviceIo.h"
11 #include <Protocol/DriverBinding.h>
13 #define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)
15 STATIC UINTN mUniqueIdCounter
= 0;
16 EFI_CPU_ARCH_PROTOCOL
*mCpu
;
19 // We only support the following device types
23 SupportedNonDiscoverableDevices
[] = {
24 &gEdkiiNonDiscoverableAhciDeviceGuid
,
25 &gEdkiiNonDiscoverableEhciDeviceGuid
,
26 &gEdkiiNonDiscoverableNvmeDeviceGuid
,
27 &gEdkiiNonDiscoverableOhciDeviceGuid
,
28 &gEdkiiNonDiscoverableSdhciDeviceGuid
,
29 &gEdkiiNonDiscoverableUfsDeviceGuid
,
30 &gEdkiiNonDiscoverableUhciDeviceGuid
,
31 &gEdkiiNonDiscoverableXhciDeviceGuid
,
35 // Probe, start and stop functions of this driver, called by the DXE core for
38 // The following specifications document these interfaces:
39 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
40 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
42 // The implementation follows:
43 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
44 // - 5.1.3.4 OpenProtocol() and CloseProtocol()
45 // - UEFI Spec 2.3.1 + Errata C
46 // - 6.3 Protocol Handler Services
50 Supported function of Driver Binding protocol for this driver.
51 Test to see if this driver supports ControllerHandle.
53 @param This Protocol instance pointer.
54 @param DeviceHandle Handle of device to test.
55 @param RemainingDevicePath A pointer to the device path.
56 it should be ignored by device driver.
58 @retval EFI_SUCCESS This driver supports this device.
59 @retval other This driver does not support this device.
65 NonDiscoverablePciDeviceSupported (
66 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
67 IN EFI_HANDLE DeviceHandle
,
68 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
71 NON_DISCOVERABLE_DEVICE
*Device
;
73 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
76 Status
= gBS
->OpenProtocol (
78 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
80 This
->DriverBindingHandle
,
82 EFI_OPEN_PROTOCOL_BY_DRIVER
84 if (EFI_ERROR (Status
)) {
88 Status
= EFI_UNSUPPORTED
;
89 for (Idx
= 0; Idx
< ARRAY_SIZE (SupportedNonDiscoverableDevices
); Idx
++) {
90 if (CompareGuid (Device
->Type
, SupportedNonDiscoverableDevices
[Idx
])) {
96 if (EFI_ERROR (Status
)) {
101 // We only support MMIO devices, so iterate over the resources to ensure
102 // that they only describe things that we can handle
104 for (Desc
= Device
->Resources
; Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
105 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3))
107 if ((Desc
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) ||
108 (Desc
->ResType
!= ACPI_ADDRESS_SPACE_TYPE_MEM
))
110 Status
= EFI_UNSUPPORTED
;
118 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
119 This
->DriverBindingHandle
,
127 This routine is called right after the .Supported() called and
128 Start this driver on ControllerHandle.
130 @param This Protocol instance pointer.
131 @param DeviceHandle Handle of device to bind driver to.
132 @param RemainingDevicePath A pointer to the device path.
133 it should be ignored by device driver.
135 @retval EFI_SUCCESS This driver is added to this device.
136 @retval other Some error occurs when binding this driver to this device.
142 NonDiscoverablePciDeviceStart (
143 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
144 IN EFI_HANDLE DeviceHandle
,
145 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
148 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
151 ASSERT (mUniqueIdCounter
< MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
);
152 if (mUniqueIdCounter
>= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
) {
153 return EFI_OUT_OF_RESOURCES
;
156 Dev
= AllocateZeroPool (sizeof *Dev
);
158 return EFI_OUT_OF_RESOURCES
;
161 Status
= gBS
->OpenProtocol (
163 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
164 (VOID
**)&Dev
->Device
,
165 This
->DriverBindingHandle
,
167 EFI_OPEN_PROTOCOL_BY_DRIVER
169 if (EFI_ERROR (Status
)) {
173 InitializePciIoProtocol (Dev
);
176 // Setup complete, attempt to export the driver instance's
177 // EFI_PCI_IO_PROTOCOL interface.
179 Dev
->Signature
= NON_DISCOVERABLE_PCI_DEVICE_SIG
;
180 Status
= gBS
->InstallProtocolInterface (
182 &gEfiPciIoProtocolGuid
,
183 EFI_NATIVE_INTERFACE
,
186 if (EFI_ERROR (Status
)) {
190 Dev
->UniqueId
= mUniqueIdCounter
++;
197 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
198 This
->DriverBindingHandle
,
209 Stop this driver on ControllerHandle.
211 @param This Protocol instance pointer.
212 @param DeviceHandle Handle of device to stop driver on.
213 @param NumberOfChildren Not used.
214 @param ChildHandleBuffer Not used.
216 @retval EFI_SUCCESS This driver is removed from this device.
217 @retval other Some error occurs when removing this driver from this device.
223 NonDiscoverablePciDeviceStop (
224 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
225 IN EFI_HANDLE DeviceHandle
,
226 IN UINTN NumberOfChildren
,
227 IN EFI_HANDLE
*ChildHandleBuffer
231 EFI_PCI_IO_PROTOCOL
*PciIo
;
232 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
234 Status
= gBS
->OpenProtocol (
236 &gEfiPciIoProtocolGuid
,
238 This
->DriverBindingHandle
,
240 EFI_OPEN_PROTOCOL_GET_PROTOCOL
242 if (EFI_ERROR (Status
)) {
246 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo
);
249 // Handle Stop() requests for in-use driver instances gracefully.
251 Status
= gBS
->UninstallProtocolInterface (
253 &gEfiPciIoProtocolGuid
,
256 if (EFI_ERROR (Status
)) {
262 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
263 This
->DriverBindingHandle
,
273 // The static object that groups the Supported() (ie. probe), Start() and
274 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
275 // C, 10.1 EFI Driver Binding Protocol.
277 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
278 &NonDiscoverablePciDeviceSupported
,
279 &NonDiscoverablePciDeviceStart
,
280 &NonDiscoverablePciDeviceStop
,
281 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
287 Entry point of this driver.
289 @param ImageHandle Image handle this driver.
290 @param SystemTable Pointer to the System Table.
292 @retval EFI_SUCCESS The entry point is executed successfully.
293 @retval other Some error occurred when executing this entry point.
298 NonDiscoverablePciDeviceDxeEntryPoint (
299 IN EFI_HANDLE ImageHandle
,
300 IN EFI_SYSTEM_TABLE
*SystemTable
305 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&mCpu
);
306 ASSERT_EFI_ERROR (Status
);
308 return EfiLibInstallDriverBindingComponentName2 (