3 Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available
6 under the terms and conditions of the BSD License which accompanies this
7 distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
11 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "NonDiscoverablePciDeviceIo.h"
17 #include <Protocol/DriverBinding.h>
19 #define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)
21 STATIC UINTN mUniqueIdCounter
= 0;
22 EFI_CPU_ARCH_PROTOCOL
*mCpu
;
25 // We only support the following device types
28 CONST EFI_GUID
* CONST
29 SupportedNonDiscoverableDevices
[] = {
30 &gEdkiiNonDiscoverableAhciDeviceGuid
,
31 &gEdkiiNonDiscoverableEhciDeviceGuid
,
32 &gEdkiiNonDiscoverableNvmeDeviceGuid
,
33 &gEdkiiNonDiscoverableOhciDeviceGuid
,
34 &gEdkiiNonDiscoverableSdhciDeviceGuid
,
35 &gEdkiiNonDiscoverableUfsDeviceGuid
,
36 &gEdkiiNonDiscoverableUhciDeviceGuid
,
37 &gEdkiiNonDiscoverableXhciDeviceGuid
,
41 // Probe, start and stop functions of this driver, called by the DXE core for
44 // The following specifications document these interfaces:
45 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
46 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
48 // The implementation follows:
49 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
50 // - 5.1.3.4 OpenProtocol() and CloseProtocol()
51 // - UEFI Spec 2.3.1 + Errata C
52 // - 6.3 Protocol Handler Services
56 Supported function of Driver Binding protocol for this driver.
57 Test to see if this driver supports ControllerHandle.
59 @param This Protocol instance pointer.
60 @param DeviceHandle Handle of device to test.
61 @param RemainingDevicePath A pointer to the device path.
62 it should be ignored by device driver.
64 @retval EFI_SUCCESS This driver supports this device.
65 @retval other This driver does not support this device.
71 NonDiscoverablePciDeviceSupported (
72 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
73 IN EFI_HANDLE DeviceHandle
,
74 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
77 NON_DISCOVERABLE_DEVICE
*Device
;
79 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
82 Status
= gBS
->OpenProtocol (DeviceHandle
,
83 &gEdkiiNonDiscoverableDeviceProtocolGuid
, (VOID
**)&Device
,
84 This
->DriverBindingHandle
, DeviceHandle
,
85 EFI_OPEN_PROTOCOL_BY_DRIVER
);
86 if (EFI_ERROR (Status
)) {
90 Status
= EFI_UNSUPPORTED
;
91 for (Idx
= 0; Idx
< ARRAY_SIZE (SupportedNonDiscoverableDevices
); Idx
++) {
92 if (CompareGuid (Device
->Type
, SupportedNonDiscoverableDevices
[Idx
])) {
98 if (EFI_ERROR (Status
)) {
103 // We only support MMIO devices, so iterate over the resources to ensure
104 // that they only describe things that we can handle
106 for (Desc
= Device
->Resources
; Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
107 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
108 if (Desc
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
||
109 Desc
->ResType
!= ACPI_ADDRESS_SPACE_TYPE_MEM
) {
110 Status
= EFI_UNSUPPORTED
;
116 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
117 This
->DriverBindingHandle
, DeviceHandle
);
123 This routine is called right after the .Supported() called and
124 Start this driver on ControllerHandle.
126 @param This Protocol instance pointer.
127 @param DeviceHandle Handle of device to bind driver to.
128 @param RemainingDevicePath A pointer to the device path.
129 it should be ignored by device driver.
131 @retval EFI_SUCCESS This driver is added to this device.
132 @retval other Some error occurs when binding this driver to this device.
138 NonDiscoverablePciDeviceStart (
139 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
140 IN EFI_HANDLE DeviceHandle
,
141 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
144 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
147 ASSERT (mUniqueIdCounter
< MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
);
148 if (mUniqueIdCounter
>= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID
) {
149 return EFI_OUT_OF_RESOURCES
;
152 Dev
= AllocateZeroPool (sizeof *Dev
);
154 return EFI_OUT_OF_RESOURCES
;
157 Status
= gBS
->OpenProtocol (DeviceHandle
,
158 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
159 (VOID
**)&Dev
->Device
, This
->DriverBindingHandle
,
160 DeviceHandle
, EFI_OPEN_PROTOCOL_BY_DRIVER
);
161 if (EFI_ERROR (Status
)) {
165 InitializePciIoProtocol (Dev
);
168 // Setup complete, attempt to export the driver instance's
169 // EFI_PCI_IO_PROTOCOL interface.
171 Dev
->Signature
= NON_DISCOVERABLE_PCI_DEVICE_SIG
;
172 Status
= gBS
->InstallProtocolInterface (&DeviceHandle
, &gEfiPciIoProtocolGuid
,
173 EFI_NATIVE_INTERFACE
, &Dev
->PciIo
);
174 if (EFI_ERROR (Status
)) {
178 Dev
->UniqueId
= mUniqueIdCounter
++;
183 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
184 This
->DriverBindingHandle
, DeviceHandle
);
193 Stop this driver on ControllerHandle.
195 @param This Protocol instance pointer.
196 @param DeviceHandle Handle of device to stop driver on.
197 @param NumberOfChildren Not used.
198 @param ChildHandleBuffer Not used.
200 @retval EFI_SUCCESS This driver is removed from this device.
201 @retval other Some error occurs when removing this driver from this device.
207 NonDiscoverablePciDeviceStop (
208 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
209 IN EFI_HANDLE DeviceHandle
,
210 IN UINTN NumberOfChildren
,
211 IN EFI_HANDLE
*ChildHandleBuffer
215 EFI_PCI_IO_PROTOCOL
*PciIo
;
216 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
218 Status
= gBS
->OpenProtocol (DeviceHandle
, &gEfiPciIoProtocolGuid
,
219 (VOID
**)&PciIo
, This
->DriverBindingHandle
, DeviceHandle
,
220 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
221 if (EFI_ERROR (Status
)) {
225 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo
);
228 // Handle Stop() requests for in-use driver instances gracefully.
230 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
231 &gEfiPciIoProtocolGuid
, &Dev
->PciIo
);
232 if (EFI_ERROR (Status
)) {
236 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
237 This
->DriverBindingHandle
, DeviceHandle
);
246 // The static object that groups the Supported() (ie. probe), Start() and
247 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
248 // C, 10.1 EFI Driver Binding Protocol.
250 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
251 &NonDiscoverablePciDeviceSupported
,
252 &NonDiscoverablePciDeviceStart
,
253 &NonDiscoverablePciDeviceStop
,
254 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
260 Entry point of this driver.
262 @param ImageHandle Image handle this driver.
263 @param SystemTable Pointer to the System Table.
265 @retval EFI_SUCCESS The entry point is executed successfully.
266 @retval other Some error occurred when executing this entry point.
271 NonDiscoverablePciDeviceDxeEntryPoint (
272 IN EFI_HANDLE ImageHandle
,
273 IN EFI_SYSTEM_TABLE
*SystemTable
278 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&mCpu
);
279 ASSERT_EFI_ERROR(Status
);
281 return EfiLibInstallDriverBindingComponentName2 (