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 EFI_CPU_ARCH_PROTOCOL
*mCpu
;
22 // We only support the following device types
25 CONST EFI_GUID
* CONST
26 SupportedNonDiscoverableDevices
[] = {
27 &gEdkiiNonDiscoverableAhciDeviceGuid
,
28 &gEdkiiNonDiscoverableEhciDeviceGuid
,
29 &gEdkiiNonDiscoverableNvmeDeviceGuid
,
30 &gEdkiiNonDiscoverableOhciDeviceGuid
,
31 &gEdkiiNonDiscoverableSdhciDeviceGuid
,
32 &gEdkiiNonDiscoverableUfsDeviceGuid
,
33 &gEdkiiNonDiscoverableUhciDeviceGuid
,
34 &gEdkiiNonDiscoverableXhciDeviceGuid
,
38 // Probe, start and stop functions of this driver, called by the DXE core for
41 // The following specifications document these interfaces:
42 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
43 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
45 // The implementation follows:
46 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
47 // - 5.1.3.4 OpenProtocol() and CloseProtocol()
48 // - UEFI Spec 2.3.1 + Errata C
49 // - 6.3 Protocol Handler Services
55 NonDiscoverablePciDeviceSupported (
56 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
57 IN EFI_HANDLE DeviceHandle
,
58 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
61 NON_DISCOVERABLE_DEVICE
*Device
;
63 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
66 Status
= gBS
->OpenProtocol (DeviceHandle
,
67 &gEdkiiNonDiscoverableDeviceProtocolGuid
, (VOID
**)&Device
,
68 This
->DriverBindingHandle
, DeviceHandle
,
69 EFI_OPEN_PROTOCOL_BY_DRIVER
);
70 if (EFI_ERROR (Status
)) {
74 Status
= EFI_UNSUPPORTED
;
75 for (Idx
= 0; Idx
< ARRAY_SIZE (SupportedNonDiscoverableDevices
); Idx
++) {
76 if (CompareGuid (Device
->Type
, SupportedNonDiscoverableDevices
[Idx
])) {
82 if (EFI_ERROR (Status
)) {
87 // We only support MMIO devices, so iterate over the resources to ensure
88 // that they only describe things that we can handle
90 for (Desc
= Device
->Resources
; Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
91 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
92 if (Desc
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
||
93 Desc
->ResType
!= ACPI_ADDRESS_SPACE_TYPE_MEM
) {
94 Status
= EFI_UNSUPPORTED
;
100 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
101 This
->DriverBindingHandle
, DeviceHandle
);
109 NonDiscoverablePciDeviceStart (
110 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
111 IN EFI_HANDLE DeviceHandle
,
112 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
115 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
118 Dev
= AllocateZeroPool (sizeof *Dev
);
120 return EFI_OUT_OF_RESOURCES
;
123 Status
= gBS
->OpenProtocol (DeviceHandle
,
124 &gEdkiiNonDiscoverableDeviceProtocolGuid
,
125 (VOID
**)&Dev
->Device
, This
->DriverBindingHandle
,
126 DeviceHandle
, EFI_OPEN_PROTOCOL_BY_DRIVER
);
127 if (EFI_ERROR (Status
)) {
131 InitializePciIoProtocol (Dev
);
134 // Setup complete, attempt to export the driver instance's
135 // EFI_PCI_IO_PROTOCOL interface.
137 Dev
->Signature
= NON_DISCOVERABLE_PCI_DEVICE_SIG
;
138 Status
= gBS
->InstallProtocolInterface (&DeviceHandle
, &gEfiPciIoProtocolGuid
,
139 EFI_NATIVE_INTERFACE
, &Dev
->PciIo
);
140 if (EFI_ERROR (Status
)) {
147 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
148 This
->DriverBindingHandle
, DeviceHandle
);
160 NonDiscoverablePciDeviceStop (
161 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
162 IN EFI_HANDLE DeviceHandle
,
163 IN UINTN NumberOfChildren
,
164 IN EFI_HANDLE
*ChildHandleBuffer
168 EFI_PCI_IO_PROTOCOL
*PciIo
;
169 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
171 Status
= gBS
->OpenProtocol (DeviceHandle
, &gEfiPciIoProtocolGuid
,
172 (VOID
**)&PciIo
, This
->DriverBindingHandle
, DeviceHandle
,
173 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
174 if (EFI_ERROR (Status
)) {
178 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo
);
181 // Handle Stop() requests for in-use driver instances gracefully.
183 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
184 &gEfiPciIoProtocolGuid
, &Dev
->PciIo
);
185 if (EFI_ERROR (Status
)) {
189 gBS
->CloseProtocol (DeviceHandle
, &gEdkiiNonDiscoverableDeviceProtocolGuid
,
190 This
->DriverBindingHandle
, DeviceHandle
);
199 // The static object that groups the Supported() (ie. probe), Start() and
200 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
201 // C, 10.1 EFI Driver Binding Protocol.
203 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
204 &NonDiscoverablePciDeviceSupported
,
205 &NonDiscoverablePciDeviceStart
,
206 &NonDiscoverablePciDeviceStop
,
207 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
213 // Entry point of this driver.
217 NonDiscoverablePciDeviceDxeEntryPoint (
218 IN EFI_HANDLE ImageHandle
,
219 IN EFI_SYSTEM_TABLE
*SystemTable
224 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&mCpu
);
225 ASSERT_EFI_ERROR(Status
);
227 return EfiLibInstallDriverBindingComponentName2 (