]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
1436aea4 13#define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID (32 * 256)\r
1a3bee20 14\r
1436aea4
MK
15STATIC UINTN mUniqueIdCounter = 0;\r
16EFI_CPU_ARCH_PROTOCOL *mCpu;\r
16296a12 17\r
a42e6d44
AB
18//\r
19// We only support the following device types\r
20//\r
21STATIC\r
1436aea4 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
1436aea4
MK
66 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
67 IN EFI_HANDLE DeviceHandle,\r
68 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
a42e6d44
AB
69 )\r
70{\r
1436aea4
MK
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 (\r
77 DeviceHandle,\r
78 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
79 (VOID **)&Device,\r
80 This->DriverBindingHandle,\r
81 DeviceHandle,\r
82 EFI_OPEN_PROTOCOL_BY_DRIVER\r
83 );\r
a42e6d44
AB
84 if (EFI_ERROR (Status)) {\r
85 return Status;\r
86 }\r
87\r
a42e6d44 88 Status = EFI_UNSUPPORTED;\r
a42e6d44 89 for (Idx = 0; Idx < ARRAY_SIZE (SupportedNonDiscoverableDevices); Idx++) {\r
1436aea4 90 if (CompareGuid (Device->Type, SupportedNonDiscoverableDevices[Idx])) {\r
a42e6d44
AB
91 Status = EFI_SUCCESS;\r
92 break;\r
93 }\r
94 }\r
95\r
96 if (EFI_ERROR (Status)) {\r
97 goto CloseProtocol;\r
98 }\r
99\r
100 //\r
101 // We only support MMIO devices, so iterate over the resources to ensure\r
102 // that they only describe things that we can handle\r
103 //\r
104 for (Desc = Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR;\r
1436aea4
MK
105 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3))\r
106 {\r
107 if ((Desc->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) ||\r
108 (Desc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM))\r
109 {\r
a42e6d44
AB
110 Status = EFI_UNSUPPORTED;\r
111 break;\r
112 }\r
113 }\r
114\r
115CloseProtocol:\r
1436aea4
MK
116 gBS->CloseProtocol (\r
117 DeviceHandle,\r
118 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
119 This->DriverBindingHandle,\r
120 DeviceHandle\r
121 );\r
a42e6d44
AB
122\r
123 return Status;\r
124}\r
125\r
43b7cd61
DB
126/**\r
127 This routine is called right after the .Supported() called and\r
128 Start this driver on ControllerHandle.\r
129\r
130 @param This Protocol instance pointer.\r
131 @param DeviceHandle Handle of device to bind driver to.\r
132 @param RemainingDevicePath A pointer to the device path.\r
133 it should be ignored by device driver.\r
134\r
135 @retval EFI_SUCCESS This driver is added to this device.\r
136 @retval other Some error occurs when binding this driver to this device.\r
137\r
138**/\r
a42e6d44
AB
139STATIC\r
140EFI_STATUS\r
141EFIAPI\r
142NonDiscoverablePciDeviceStart (\r
1436aea4
MK
143 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
144 IN EFI_HANDLE DeviceHandle,\r
145 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
a42e6d44
AB
146 )\r
147{\r
1436aea4
MK
148 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
149 EFI_STATUS Status;\r
a42e6d44 150\r
1a3bee20
AB
151 ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);\r
152 if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {\r
153 return EFI_OUT_OF_RESOURCES;\r
154 }\r
155\r
a42e6d44
AB
156 Dev = AllocateZeroPool (sizeof *Dev);\r
157 if (Dev == NULL) {\r
158 return EFI_OUT_OF_RESOURCES;\r
159 }\r
160\r
1436aea4
MK
161 Status = gBS->OpenProtocol (\r
162 DeviceHandle,\r
a42e6d44 163 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
1436aea4
MK
164 (VOID **)&Dev->Device,\r
165 This->DriverBindingHandle,\r
166 DeviceHandle,\r
167 EFI_OPEN_PROTOCOL_BY_DRIVER\r
168 );\r
a42e6d44
AB
169 if (EFI_ERROR (Status)) {\r
170 goto FreeDev;\r
171 }\r
172\r
173 InitializePciIoProtocol (Dev);\r
174\r
175 //\r
176 // Setup complete, attempt to export the driver instance's\r
177 // EFI_PCI_IO_PROTOCOL interface.\r
178 //\r
179 Dev->Signature = NON_DISCOVERABLE_PCI_DEVICE_SIG;\r
1436aea4
MK
180 Status = gBS->InstallProtocolInterface (\r
181 &DeviceHandle,\r
182 &gEfiPciIoProtocolGuid,\r
183 EFI_NATIVE_INTERFACE,\r
184 &Dev->PciIo\r
185 );\r
a42e6d44
AB
186 if (EFI_ERROR (Status)) {\r
187 goto CloseProtocol;\r
188 }\r
1a3bee20
AB
189\r
190 Dev->UniqueId = mUniqueIdCounter++;\r
a42e6d44
AB
191\r
192 return EFI_SUCCESS;\r
193\r
194CloseProtocol:\r
1436aea4
MK
195 gBS->CloseProtocol (\r
196 DeviceHandle,\r
197 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
198 This->DriverBindingHandle,\r
199 DeviceHandle\r
200 );\r
a42e6d44
AB
201\r
202FreeDev:\r
203 FreePool (Dev);\r
204\r
205 return Status;\r
206}\r
207\r
43b7cd61
DB
208/**\r
209 Stop this driver on ControllerHandle.\r
210\r
211 @param This Protocol instance pointer.\r
212 @param DeviceHandle Handle of device to stop driver on.\r
213 @param NumberOfChildren Not used.\r
214 @param ChildHandleBuffer Not used.\r
a42e6d44 215\r
43b7cd61
DB
216 @retval EFI_SUCCESS This driver is removed from this device.\r
217 @retval other Some error occurs when removing this driver from this device.\r
218\r
219**/\r
a42e6d44
AB
220STATIC\r
221EFI_STATUS\r
222EFIAPI\r
223NonDiscoverablePciDeviceStop (\r
1436aea4
MK
224 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
225 IN EFI_HANDLE DeviceHandle,\r
226 IN UINTN NumberOfChildren,\r
227 IN EFI_HANDLE *ChildHandleBuffer\r
a42e6d44
AB
228 )\r
229{\r
1436aea4
MK
230 EFI_STATUS Status;\r
231 EFI_PCI_IO_PROTOCOL *PciIo;\r
232 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
233\r
234 Status = gBS->OpenProtocol (\r
235 DeviceHandle,\r
236 &gEfiPciIoProtocolGuid,\r
237 (VOID **)&PciIo,\r
238 This->DriverBindingHandle,\r
239 DeviceHandle,\r
240 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
241 );\r
a42e6d44
AB
242 if (EFI_ERROR (Status)) {\r
243 return Status;\r
244 }\r
245\r
246 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo);\r
247\r
248 //\r
249 // Handle Stop() requests for in-use driver instances gracefully.\r
250 //\r
1436aea4
MK
251 Status = gBS->UninstallProtocolInterface (\r
252 DeviceHandle,\r
253 &gEfiPciIoProtocolGuid,\r
254 &Dev->PciIo\r
255 );\r
a42e6d44
AB
256 if (EFI_ERROR (Status)) {\r
257 return Status;\r
258 }\r
259\r
1436aea4
MK
260 gBS->CloseProtocol (\r
261 DeviceHandle,\r
262 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
263 This->DriverBindingHandle,\r
264 DeviceHandle\r
265 );\r
a42e6d44
AB
266\r
267 FreePool (Dev);\r
268\r
269 return EFI_SUCCESS;\r
270}\r
271\r
a42e6d44
AB
272//\r
273// The static object that groups the Supported() (ie. probe), Start() and\r
274// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
275// C, 10.1 EFI Driver Binding Protocol.\r
276//\r
1436aea4 277STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
a42e6d44
AB
278 &NonDiscoverablePciDeviceSupported,\r
279 &NonDiscoverablePciDeviceStart,\r
280 &NonDiscoverablePciDeviceStop,\r
281 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
282 NULL,\r
283 NULL\r
284};\r
285\r
43b7cd61
DB
286/**\r
287 Entry point of this driver.\r
288\r
289 @param ImageHandle Image handle this driver.\r
290 @param SystemTable Pointer to the System Table.\r
291\r
292 @retval EFI_SUCCESS The entry point is executed successfully.\r
293 @retval other Some error occurred when executing this entry point.\r
294\r
295**/\r
a42e6d44
AB
296EFI_STATUS\r
297EFIAPI\r
298NonDiscoverablePciDeviceDxeEntryPoint (\r
1436aea4
MK
299 IN EFI_HANDLE ImageHandle,\r
300 IN EFI_SYSTEM_TABLE *SystemTable\r
a42e6d44
AB
301 )\r
302{\r
1436aea4 303 EFI_STATUS Status;\r
16296a12
AB
304\r
305 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);\r
1436aea4 306 ASSERT_EFI_ERROR (Status);\r
16296a12 307\r
a42e6d44
AB
308 return EfiLibInstallDriverBindingComponentName2 (\r
309 ImageHandle,\r
310 SystemTable,\r
311 &gDriverBinding,\r
312 ImageHandle,\r
313 &gComponentName,\r
314 &gComponentName2\r
315 );\r
316}\r