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>
20 // We only support the following device types
23 CONST EFI_GUID
* CONST
24 SupportedNonDiscoverableDevices
[] = {
25 &gEdkiiNonDiscoverableAhciDeviceGuid
,
26 &gEdkiiNonDiscoverableEhciDeviceGuid
,
27 &gEdkiiNonDiscoverableNvmeDeviceGuid
,
28 &gEdkiiNonDiscoverableOhciDeviceGuid
,
29 &gEdkiiNonDiscoverableSdhciDeviceGuid
,
30 &gEdkiiNonDiscoverableUfsDeviceGuid
,
31 &gEdkiiNonDiscoverableUhciDeviceGuid
,
32 &gEdkiiNonDiscoverableXhciDeviceGuid
,
36 // Probe, start and stop functions of this driver, called by the DXE core for
39 // The following specifications document these interfaces:
40 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
41 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
43 // The implementation follows:
44 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
45 // - 5.1.3.4 OpenProtocol() and CloseProtocol()
46 // - UEFI Spec 2.3.1 + Errata C
47 // - 6.3 Protocol Handler Services
53 NonDiscoverablePciDeviceSupported (
54 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
55 IN EFI_HANDLE DeviceHandle
,
56 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
59 NON_DISCOVERABLE_DEVICE
*Device
;
61 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
64 Status
= gBS
->OpenProtocol (DeviceHandle
,
65 &gEdkiiNonDiscoverableDeviceProtocolGuid
, (VOID
**)&Device
,
66 This
->DriverBindingHandle
, DeviceHandle
,
67 EFI_OPEN_PROTOCOL_BY_DRIVER
);
68 if (EFI_ERROR (Status
)) {
73 // Restricted to DMA coherent for now
75 Status
= EFI_UNSUPPORTED
;
76 if (Device
->DmaType
!= NonDiscoverableDeviceDmaTypeCoherent
) {
80 for (Idx
= 0; Idx
< ARRAY_SIZE (SupportedNonDiscoverableDevices
); Idx
++) {
81 if (CompareGuid (Device
->Type
, SupportedNonDiscoverableDevices
[Idx
])) {
87 if (EFI_ERROR (Status
)) {
92 // We only support MMIO devices, so iterate over the resources to ensure
93 // that they only describe things that we can handle
95 for (Desc
= Device
->Resources
; Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
96 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
97 if (Desc
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
||
98 Desc
->ResType
!= ACPI_ADDRESS_SPACE_TYPE_MEM
) {
99 Status
= EFI_UNSUPPORTED
;
105 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
106 This
->DriverBindingHandle
, DeviceHandle
);
114 NonDiscoverablePciDeviceStart (
115 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
116 IN EFI_HANDLE DeviceHandle
,
117 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
120 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
123 Dev
= AllocateZeroPool (sizeof *Dev
);
125 return EFI_OUT_OF_RESOURCES
;
128 Status
= gBS
->OpenProtocol (DeviceHandle
,
129 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
130 (VOID
**)&Dev
->Device
, This
->DriverBindingHandle
,
131 DeviceHandle
, EFI_OPEN_PROTOCOL_BY_DRIVER
);
132 if (EFI_ERROR (Status
)) {
136 InitializePciIoProtocol (Dev
);
139 // Setup complete, attempt to export the driver instance's
140 // EFI_PCI_IO_PROTOCOL interface.
142 Dev
->Signature
= NON_DISCOVERABLE_PCI_DEVICE_SIG
;
143 Status
= gBS
->InstallProtocolInterface (&DeviceHandle
, &gEfiPciIoProtocolGuid
,
144 EFI_NATIVE_INTERFACE
, &Dev
->PciIo
);
145 if (EFI_ERROR (Status
)) {
152 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
153 This
->DriverBindingHandle
, DeviceHandle
);
165 NonDiscoverablePciDeviceStop (
166 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
167 IN EFI_HANDLE DeviceHandle
,
168 IN UINTN NumberOfChildren
,
169 IN EFI_HANDLE
*ChildHandleBuffer
173 EFI_PCI_IO_PROTOCOL
*PciIo
;
174 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
176 Status
= gBS
->OpenProtocol (DeviceHandle
, &gEfiPciIoProtocolGuid
,
177 (VOID
**)&PciIo
, This
->DriverBindingHandle
, DeviceHandle
,
178 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
179 if (EFI_ERROR (Status
)) {
183 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo
);
186 // Handle Stop() requests for in-use driver instances gracefully.
188 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
189 &gEfiPciIoProtocolGuid
, &Dev
->PciIo
);
190 if (EFI_ERROR (Status
)) {
194 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
195 This
->DriverBindingHandle
, DeviceHandle
);
204 // The static object that groups the Supported() (ie. probe), Start() and
205 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
206 // C, 10.1 EFI Driver Binding Protocol.
208 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
209 &NonDiscoverablePciDeviceSupported
,
210 &NonDiscoverablePciDeviceStart
,
211 &NonDiscoverablePciDeviceStop
,
212 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
218 // Entry point of this driver.
222 NonDiscoverablePciDeviceDxeEntryPoint (
223 IN EFI_HANDLE ImageHandle
,
224 IN EFI_SYSTEM_TABLE
*SystemTable
227 return EfiLibInstallDriverBindingComponentName2 (