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
22 CONST EFI_GUID
* CONST
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 (DeviceHandle
,
77 &gEdkiiNonDiscoverableDeviceProtocolGuid
, (VOID
**)&Device
,
78 This
->DriverBindingHandle
, DeviceHandle
,
79 EFI_OPEN_PROTOCOL_BY_DRIVER
);
80 if (EFI_ERROR (Status
)) {
84 Status
= EFI_UNSUPPORTED
;
85 for (Idx
= 0; Idx
< ARRAY_SIZE (SupportedNonDiscoverableDevices
); Idx
++) {
86 if (CompareGuid (Device
->Type
, SupportedNonDiscoverableDevices
[Idx
])) {
92 if (EFI_ERROR (Status
)) {
97 // We only support MMIO devices, so iterate over the resources to ensure
98 // that they only describe things that we can handle
100 for (Desc
= Device
->Resources
; Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
101 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
102 if (Desc
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
||
103 Desc
->ResType
!= ACPI_ADDRESS_SPACE_TYPE_MEM
) {
104 Status
= EFI_UNSUPPORTED
;
110 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
111 This
->DriverBindingHandle
, DeviceHandle
);
117 This routine is called right after the .Supported() called and
118 Start this driver on ControllerHandle.
120 @param This Protocol instance pointer.
121 @param DeviceHandle Handle of device to bind driver to.
122 @param RemainingDevicePath A pointer to the device path.
123 it should be ignored by device driver.
125 @retval EFI_SUCCESS This driver is added to this device.
126 @retval other Some error occurs when binding this driver to this device.
132 NonDiscoverablePciDeviceStart (
133 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
134 IN EFI_HANDLE DeviceHandle
,
135 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
138 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
141 ASSERT (mUniqueIdCounter
< MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
);
142 if (mUniqueIdCounter
>= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
) {
143 return EFI_OUT_OF_RESOURCES
;
146 Dev
= AllocateZeroPool (sizeof *Dev
);
148 return EFI_OUT_OF_RESOURCES
;
151 Status
= gBS
->OpenProtocol (DeviceHandle
,
152 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
153 (VOID
**)&Dev
->Device
, This
->DriverBindingHandle
,
154 DeviceHandle
, EFI_OPEN_PROTOCOL_BY_DRIVER
);
155 if (EFI_ERROR (Status
)) {
159 InitializePciIoProtocol (Dev
);
162 // Setup complete, attempt to export the driver instance's
163 // EFI_PCI_IO_PROTOCOL interface.
165 Dev
->Signature
= NON_DISCOVERABLE_PCI_DEVICE_SIG
;
166 Status
= gBS
->InstallProtocolInterface (&DeviceHandle
, &gEfiPciIoProtocolGuid
,
167 EFI_NATIVE_INTERFACE
, &Dev
->PciIo
);
168 if (EFI_ERROR (Status
)) {
172 Dev
->UniqueId
= mUniqueIdCounter
++;
177 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
178 This
->DriverBindingHandle
, DeviceHandle
);
187 Stop this driver on ControllerHandle.
189 @param This Protocol instance pointer.
190 @param DeviceHandle Handle of device to stop driver on.
191 @param NumberOfChildren Not used.
192 @param ChildHandleBuffer Not used.
194 @retval EFI_SUCCESS This driver is removed from this device.
195 @retval other Some error occurs when removing this driver from this device.
201 NonDiscoverablePciDeviceStop (
202 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
203 IN EFI_HANDLE DeviceHandle
,
204 IN UINTN NumberOfChildren
,
205 IN EFI_HANDLE
*ChildHandleBuffer
209 EFI_PCI_IO_PROTOCOL
*PciIo
;
210 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
212 Status
= gBS
->OpenProtocol (DeviceHandle
, &gEfiPciIoProtocolGuid
,
213 (VOID
**)&PciIo
, This
->DriverBindingHandle
, DeviceHandle
,
214 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
215 if (EFI_ERROR (Status
)) {
219 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo
);
222 // Handle Stop() requests for in-use driver instances gracefully.
224 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
225 &gEfiPciIoProtocolGuid
, &Dev
->PciIo
);
226 if (EFI_ERROR (Status
)) {
230 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
231 This
->DriverBindingHandle
, DeviceHandle
);
240 // The static object that groups the Supported() (ie. probe), Start() and
241 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
242 // C, 10.1 EFI Driver Binding Protocol.
244 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
245 &NonDiscoverablePciDeviceSupported
,
246 &NonDiscoverablePciDeviceStart
,
247 &NonDiscoverablePciDeviceStop
,
248 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
254 Entry point of this driver.
256 @param ImageHandle Image handle this driver.
257 @param SystemTable Pointer to the System Table.
259 @retval EFI_SUCCESS The entry point is executed successfully.
260 @retval other Some error occurred when executing this entry point.
265 NonDiscoverablePciDeviceDxeEntryPoint (
266 IN EFI_HANDLE ImageHandle
,
267 IN EFI_SYSTEM_TABLE
*SystemTable
272 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&mCpu
);
273 ASSERT_EFI_ERROR(Status
);
275 return EfiLibInstallDriverBindingComponentName2 (