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