]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.c
MdeModulePkg/Pci: Fixed Asserts in SCT PCIIO Protocol Test.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / NonDiscoverablePciDeviceDxe / NonDiscoverablePciDeviceDxe.c
CommitLineData
a42e6d44
AB
1/** @file\r
2\r
3 Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>\r
4\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a42e6d44
AB
6\r
7**/\r
8\r
9#include "NonDiscoverablePciDeviceIo.h"\r
10\r
11#include <Protocol/DriverBinding.h>\r
12\r
1a3bee20
AB
13#define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)\r
14\r
15STATIC UINTN mUniqueIdCounter = 0;\r
16296a12
AB
16EFI_CPU_ARCH_PROTOCOL *mCpu;\r
17\r
a42e6d44
AB
18//\r
19// We only support the following device types\r
20//\r
21STATIC\r
22CONST EFI_GUID * CONST\r
5f16ecdb 23SupportedNonDiscoverableDevices[] = {\r
a42e6d44
AB
24 &gEdkiiNonDiscoverableAhciDeviceGuid,\r
25 &gEdkiiNonDiscoverableEhciDeviceGuid,\r
26 &gEdkiiNonDiscoverableNvmeDeviceGuid,\r
27 &gEdkiiNonDiscoverableOhciDeviceGuid,\r
28 &gEdkiiNonDiscoverableSdhciDeviceGuid,\r
29 &gEdkiiNonDiscoverableUfsDeviceGuid,\r
30 &gEdkiiNonDiscoverableUhciDeviceGuid,\r
31 &gEdkiiNonDiscoverableXhciDeviceGuid,\r
32};\r
33\r
34//\r
35// Probe, start and stop functions of this driver, called by the DXE core for\r
36// specific devices.\r
37//\r
38// The following specifications document these interfaces:\r
39// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol\r
40// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol\r
41//\r
42// The implementation follows:\r
43// - Driver Writer's Guide for UEFI 2.3.1 v1.01\r
44// - 5.1.3.4 OpenProtocol() and CloseProtocol()\r
45// - UEFI Spec 2.3.1 + Errata C\r
46// - 6.3 Protocol Handler Services\r
47//\r
48\r
43b7cd61
DB
49/**\r
50 Supported function of Driver Binding protocol for this driver.\r
51 Test to see if this driver supports ControllerHandle.\r
52\r
53 @param This Protocol instance pointer.\r
54 @param DeviceHandle Handle of device to test.\r
55 @param RemainingDevicePath A pointer to the device path.\r
56 it should be ignored by device driver.\r
57\r
58 @retval EFI_SUCCESS This driver supports this device.\r
59 @retval other This driver does not support this device.\r
60\r
61**/\r
a42e6d44
AB
62STATIC\r
63EFI_STATUS\r
64EFIAPI\r
65NonDiscoverablePciDeviceSupported (\r
66 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
67 IN EFI_HANDLE DeviceHandle,\r
68 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
69 )\r
70{\r
71 NON_DISCOVERABLE_DEVICE *Device;\r
72 EFI_STATUS Status;\r
73 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
74 INTN Idx;\r
75\r
76 Status = gBS->OpenProtocol (DeviceHandle,\r
77 &gEdkiiNonDiscoverableDeviceProtocolGuid, (VOID **)&Device,\r
78 This->DriverBindingHandle, DeviceHandle,\r
79 EFI_OPEN_PROTOCOL_BY_DRIVER);\r
80 if (EFI_ERROR (Status)) {\r
81 return Status;\r
82 }\r
83\r
a42e6d44 84 Status = EFI_UNSUPPORTED;\r
a42e6d44
AB
85 for (Idx = 0; Idx < ARRAY_SIZE (SupportedNonDiscoverableDevices); Idx++) {\r
86 if (CompareGuid (Device->Type, SupportedNonDiscoverableDevices [Idx])) {\r
87 Status = EFI_SUCCESS;\r
88 break;\r
89 }\r
90 }\r
91\r
92 if (EFI_ERROR (Status)) {\r
93 goto CloseProtocol;\r
94 }\r
95\r
96 //\r
97 // We only support MMIO devices, so iterate over the resources to ensure\r
98 // that they only describe things that we can handle\r
99 //\r
100 for (Desc = Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR;\r
101 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) {\r
102 if (Desc->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR ||\r
103 Desc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
104 Status = EFI_UNSUPPORTED;\r
105 break;\r
106 }\r
107 }\r
108\r
109CloseProtocol:\r
110 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
111 This->DriverBindingHandle, DeviceHandle);\r
112\r
113 return Status;\r
114}\r
115\r
43b7cd61
DB
116/**\r
117 This routine is called right after the .Supported() called and\r
118 Start this driver on ControllerHandle.\r
119\r
120 @param This Protocol instance pointer.\r
121 @param DeviceHandle Handle of device to bind driver to.\r
122 @param RemainingDevicePath A pointer to the device path.\r
123 it should be ignored by device driver.\r
124\r
125 @retval EFI_SUCCESS This driver is added to this device.\r
126 @retval other Some error occurs when binding this driver to this device.\r
127\r
128**/\r
a42e6d44
AB
129STATIC\r
130EFI_STATUS\r
131EFIAPI\r
132NonDiscoverablePciDeviceStart (\r
133 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
134 IN EFI_HANDLE DeviceHandle,\r
135 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
136 )\r
137{\r
138 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
139 EFI_STATUS Status;\r
140\r
1a3bee20
AB
141 ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);\r
142 if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {\r
143 return EFI_OUT_OF_RESOURCES;\r
144 }\r
145\r
a42e6d44
AB
146 Dev = AllocateZeroPool (sizeof *Dev);\r
147 if (Dev == NULL) {\r
148 return EFI_OUT_OF_RESOURCES;\r
149 }\r
150\r
151 Status = gBS->OpenProtocol (DeviceHandle,\r
152 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
153 (VOID **)&Dev->Device, This->DriverBindingHandle,\r
154 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);\r
155 if (EFI_ERROR (Status)) {\r
156 goto FreeDev;\r
157 }\r
158\r
159 InitializePciIoProtocol (Dev);\r
160\r
161 //\r
162 // Setup complete, attempt to export the driver instance's\r
163 // EFI_PCI_IO_PROTOCOL interface.\r
164 //\r
165 Dev->Signature = NON_DISCOVERABLE_PCI_DEVICE_SIG;\r
166 Status = gBS->InstallProtocolInterface (&DeviceHandle, &gEfiPciIoProtocolGuid,\r
167 EFI_NATIVE_INTERFACE, &Dev->PciIo);\r
168 if (EFI_ERROR (Status)) {\r
169 goto CloseProtocol;\r
170 }\r
1a3bee20
AB
171\r
172 Dev->UniqueId = mUniqueIdCounter++;\r
a42e6d44
AB
173\r
174 return EFI_SUCCESS;\r
175\r
176CloseProtocol:\r
177 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
178 This->DriverBindingHandle, DeviceHandle);\r
179\r
180FreeDev:\r
181 FreePool (Dev);\r
182\r
183 return Status;\r
184}\r
185\r
43b7cd61
DB
186/**\r
187 Stop this driver on ControllerHandle.\r
188\r
189 @param This Protocol instance pointer.\r
190 @param DeviceHandle Handle of device to stop driver on.\r
191 @param NumberOfChildren Not used.\r
192 @param ChildHandleBuffer Not used.\r
a42e6d44 193\r
43b7cd61
DB
194 @retval EFI_SUCCESS This driver is removed from this device.\r
195 @retval other Some error occurs when removing this driver from this device.\r
196\r
197**/\r
a42e6d44
AB
198STATIC\r
199EFI_STATUS\r
200EFIAPI\r
201NonDiscoverablePciDeviceStop (\r
202 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
203 IN EFI_HANDLE DeviceHandle,\r
204 IN UINTN NumberOfChildren,\r
205 IN EFI_HANDLE *ChildHandleBuffer\r
206 )\r
207{\r
208 EFI_STATUS Status;\r
209 EFI_PCI_IO_PROTOCOL *PciIo;\r
210 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
211\r
212 Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
213 (VOID **)&PciIo, This->DriverBindingHandle, DeviceHandle,\r
214 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
215 if (EFI_ERROR (Status)) {\r
216 return Status;\r
217 }\r
218\r
219 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo);\r
220\r
221 //\r
222 // Handle Stop() requests for in-use driver instances gracefully.\r
223 //\r
224 Status = gBS->UninstallProtocolInterface (DeviceHandle,\r
225 &gEfiPciIoProtocolGuid, &Dev->PciIo);\r
226 if (EFI_ERROR (Status)) {\r
227 return Status;\r
228 }\r
229\r
230 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
231 This->DriverBindingHandle, DeviceHandle);\r
232\r
233 FreePool (Dev);\r
234\r
235 return EFI_SUCCESS;\r
236}\r
237\r
238\r
239//\r
240// The static object that groups the Supported() (ie. probe), Start() and\r
241// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
242// C, 10.1 EFI Driver Binding Protocol.\r
243//\r
244STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
245 &NonDiscoverablePciDeviceSupported,\r
246 &NonDiscoverablePciDeviceStart,\r
247 &NonDiscoverablePciDeviceStop,\r
248 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
249 NULL,\r
250 NULL\r
251};\r
252\r
43b7cd61
DB
253/**\r
254 Entry point of this driver.\r
255\r
256 @param ImageHandle Image handle this driver.\r
257 @param SystemTable Pointer to the System Table.\r
258\r
259 @retval EFI_SUCCESS The entry point is executed successfully.\r
260 @retval other Some error occurred when executing this entry point.\r
261\r
262**/\r
a42e6d44
AB
263EFI_STATUS\r
264EFIAPI\r
265NonDiscoverablePciDeviceDxeEntryPoint (\r
266 IN EFI_HANDLE ImageHandle,\r
267 IN EFI_SYSTEM_TABLE *SystemTable\r
268 )\r
269{\r
16296a12
AB
270 EFI_STATUS Status;\r
271\r
272 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);\r
273 ASSERT_EFI_ERROR(Status);\r
274\r
a42e6d44
AB
275 return EfiLibInstallDriverBindingComponentName2 (\r
276 ImageHandle,\r
277 SystemTable,\r
278 &gDriverBinding,\r
279 ImageHandle,\r
280 &gComponentName,\r
281 &gComponentName2\r
282 );\r
283}\r