TianoCore EDK2 master
Loading...
Searching...
No Matches
NonDiscoverablePciDeviceDxe.c
Go to the documentation of this file.
1
10
12
13#define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)
14
15STATIC UINTN mUniqueIdCounter = 0;
17
18//
19// We only support the following device types
20//
23SupportedNonDiscoverableDevices[] = {
24 &gEdkiiNonDiscoverableAhciDeviceGuid,
25 &gEdkiiNonDiscoverableEhciDeviceGuid,
26 &gEdkiiNonDiscoverableNvmeDeviceGuid,
27 &gEdkiiNonDiscoverableOhciDeviceGuid,
28 &gEdkiiNonDiscoverableSdhciDeviceGuid,
29 &gEdkiiNonDiscoverableUfsDeviceGuid,
30 &gEdkiiNonDiscoverableUhciDeviceGuid,
31 &gEdkiiNonDiscoverableXhciDeviceGuid,
32};
33
34//
35// Probe, start and stop functions of this driver, called by the DXE core for
36// specific devices.
37//
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
41//
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
47//
48
64EFIAPI
67 IN EFI_HANDLE DeviceHandle,
68 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
69 )
70{
72 EFI_STATUS Status;
74 INTN Idx;
75
76 Status = gBS->OpenProtocol (
77 DeviceHandle,
78 &gEdkiiNonDiscoverableDeviceProtocolGuid,
79 (VOID **)&Device,
80 This->DriverBindingHandle,
81 DeviceHandle,
82 EFI_OPEN_PROTOCOL_BY_DRIVER
83 );
84 if (EFI_ERROR (Status)) {
85 return Status;
86 }
87
88 Status = EFI_UNSUPPORTED;
89 for (Idx = 0; Idx < ARRAY_SIZE (SupportedNonDiscoverableDevices); Idx++) {
90 if (CompareGuid (Device->Type, SupportedNonDiscoverableDevices[Idx])) {
91 Status = EFI_SUCCESS;
92 break;
93 }
94 }
95
96 if (EFI_ERROR (Status)) {
97 goto CloseProtocol;
98 }
99
100 //
101 // We only support MMIO devices, so iterate over the resources to ensure
102 // that they only describe things that we can handle
103 //
104 for (Desc = Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR;
105 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3))
106 {
107 if ((Desc->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) ||
108 (Desc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM))
109 {
110 Status = EFI_UNSUPPORTED;
111 break;
112 }
113 }
114
115CloseProtocol:
116 gBS->CloseProtocol (
117 DeviceHandle,
118 &gEdkiiNonDiscoverableDeviceProtocolGuid,
119 This->DriverBindingHandle,
120 DeviceHandle
121 );
122
123 return Status;
124}
125
139STATIC
141EFIAPI
144 IN EFI_HANDLE DeviceHandle,
145 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
146 )
147{
149 EFI_STATUS Status;
150
151 ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);
152 if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {
153 return EFI_OUT_OF_RESOURCES;
154 }
155
156 Dev = AllocateZeroPool (sizeof *Dev);
157 if (Dev == NULL) {
158 return EFI_OUT_OF_RESOURCES;
159 }
160
161 Status = gBS->OpenProtocol (
162 DeviceHandle,
163 &gEdkiiNonDiscoverableDeviceProtocolGuid,
164 (VOID **)&Dev->Device,
165 This->DriverBindingHandle,
166 DeviceHandle,
167 EFI_OPEN_PROTOCOL_BY_DRIVER
168 );
169 if (EFI_ERROR (Status)) {
170 goto FreeDev;
171 }
172
174
175 //
176 // Setup complete, attempt to export the driver instance's
177 // EFI_PCI_IO_PROTOCOL interface.
178 //
179 Dev->Signature = NON_DISCOVERABLE_PCI_DEVICE_SIG;
180 Status = gBS->InstallProtocolInterface (
181 &DeviceHandle,
182 &gEfiPciIoProtocolGuid,
184 &Dev->PciIo
185 );
186 if (EFI_ERROR (Status)) {
187 goto CloseProtocol;
188 }
189
190 Dev->UniqueId = mUniqueIdCounter++;
191
192 return EFI_SUCCESS;
193
194CloseProtocol:
195 gBS->CloseProtocol (
196 DeviceHandle,
197 &gEdkiiNonDiscoverableDeviceProtocolGuid,
198 This->DriverBindingHandle,
199 DeviceHandle
200 );
201
202FreeDev:
203 FreePool (Dev);
204
205 return Status;
206}
207
220STATIC
222EFIAPI
225 IN EFI_HANDLE DeviceHandle,
226 IN UINTN NumberOfChildren,
227 IN EFI_HANDLE *ChildHandleBuffer
228 )
229{
230 EFI_STATUS Status;
231 EFI_PCI_IO_PROTOCOL *PciIo;
233
234 Status = gBS->OpenProtocol (
235 DeviceHandle,
236 &gEfiPciIoProtocolGuid,
237 (VOID **)&PciIo,
238 This->DriverBindingHandle,
239 DeviceHandle,
240 EFI_OPEN_PROTOCOL_GET_PROTOCOL
241 );
242 if (EFI_ERROR (Status)) {
243 return Status;
244 }
245
246 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo);
247
248 //
249 // Handle Stop() requests for in-use driver instances gracefully.
250 //
251 Status = gBS->UninstallProtocolInterface (
252 DeviceHandle,
253 &gEfiPciIoProtocolGuid,
254 &Dev->PciIo
255 );
256 if (EFI_ERROR (Status)) {
257 return Status;
258 }
259
260 gBS->CloseProtocol (
261 DeviceHandle,
262 &gEdkiiNonDiscoverableDeviceProtocolGuid,
263 This->DriverBindingHandle,
264 DeviceHandle
265 );
266
267 FreePool (Dev);
268
269 return EFI_SUCCESS;
270}
271
272//
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.
276//
277STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
281 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
282 NULL,
283 NULL
284};
285
297EFIAPI
299 IN EFI_HANDLE ImageHandle,
300 IN EFI_SYSTEM_TABLE *SystemTable
301 )
302{
303 EFI_STATUS Status;
304
305 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
306 ASSERT_EFI_ERROR (Status);
307
309 ImageHandle,
310 SystemTable,
311 &gDriverBinding,
312 ImageHandle,
313 &gComponentName,
314 &gComponentName2
315 );
316}
UINT64 UINTN
INT64 INTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
STATIC EFI_STATUS EFIAPI NonDiscoverablePciDeviceStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
STATIC EFI_STATUS EFIAPI NonDiscoverablePciDeviceStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS EFIAPI NonDiscoverablePciDeviceDxeEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS EFIAPI NonDiscoverablePciDeviceSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
VOID InitializePciIoProtocol(NON_DISCOVERABLE_PCI_DEVICE *Dev)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
Definition: Base.h:213