]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - OvmfPkg/XenIoPciDxe/XenIoPciDxe.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / XenIoPciDxe / XenIoPciDxe.c
... / ...
CommitLineData
1/** @file\r
2\r
3 Driver for the virtual Xen PCI device\r
4\r
5 Copyright (C) 2012, Red Hat, Inc.\r
6 Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>\r
7 Copyright (C) 2013, ARM Ltd.\r
8 Copyright (C) 2015, Linaro Ltd.\r
9\r
10 SPDX-License-Identifier: BSD-2-Clause-Patent\r
11\r
12**/\r
13\r
14#include <IndustryStandard/Acpi.h>\r
15#include <IndustryStandard/Pci.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/UefiLib.h>\r
21\r
22#include <Protocol/PciIo.h>\r
23#include <Protocol/XenIo.h>\r
24\r
25#define PCI_VENDOR_ID_XEN 0x5853\r
26#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001\r
27\r
28/**\r
29\r
30 Device probe function for this driver.\r
31\r
32 The DXE core calls this function for any given device in order to see if the\r
33 driver can drive the device.\r
34\r
35 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
36 incorporating this driver (independently of\r
37 any device).\r
38\r
39 @param[in] DeviceHandle The device to probe.\r
40\r
41 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.\r
42\r
43\r
44 @retval EFI_SUCCESS The driver supports the device being probed.\r
45\r
46 @retval EFI_UNSUPPORTED The driver does not support the device being probed.\r
47\r
48 @return Error codes from the OpenProtocol() boot service or\r
49 the PciIo protocol.\r
50\r
51**/\r
52STATIC\r
53EFI_STATUS\r
54EFIAPI\r
55XenIoPciDeviceBindingSupported (\r
56 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
57 IN EFI_HANDLE DeviceHandle,\r
58 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
59 )\r
60{\r
61 EFI_STATUS Status;\r
62 EFI_PCI_IO_PROTOCOL *PciIo;\r
63 PCI_TYPE00 Pci;\r
64\r
65 //\r
66 // Attempt to open the device with the PciIo set of interfaces. On success,\r
67 // the protocol is "instantiated" for the PCI device. Covers duplicate open\r
68 // attempts (EFI_ALREADY_STARTED).\r
69 //\r
70 Status = gBS->OpenProtocol (\r
71 DeviceHandle, // candidate device\r
72 &gEfiPciIoProtocolGuid, // for generic PCI access\r
73 (VOID **)&PciIo, // handle to instantiate\r
74 This->DriverBindingHandle, // requestor driver identity\r
75 DeviceHandle, // ControllerHandle, according to\r
76 // the UEFI Driver Model\r
77 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to\r
78 // the device; to be released\r
79 );\r
80 if (EFI_ERROR (Status)) {\r
81 return Status;\r
82 }\r
83\r
84 //\r
85 // Read entire PCI configuration header for more extensive check ahead.\r
86 //\r
87 Status = PciIo->Pci.Read (\r
88 PciIo, // (protocol, device)\r
89 // handle\r
90 EfiPciIoWidthUint32, // access width & copy\r
91 // mode\r
92 0, // Offset\r
93 sizeof Pci / sizeof (UINT32), // Count\r
94 &Pci // target buffer\r
95 );\r
96\r
97 if (Status == EFI_SUCCESS) {\r
98 if ((Pci.Hdr.VendorId == PCI_VENDOR_ID_XEN) &&\r
99 (Pci.Hdr.DeviceId == PCI_DEVICE_ID_XEN_PLATFORM))\r
100 {\r
101 Status = EFI_SUCCESS;\r
102 } else {\r
103 Status = EFI_UNSUPPORTED;\r
104 }\r
105 }\r
106\r
107 //\r
108 // We needed PCI IO access only transitorily, to see whether we support the\r
109 // device or not.\r
110 //\r
111 gBS->CloseProtocol (\r
112 DeviceHandle,\r
113 &gEfiPciIoProtocolGuid,\r
114 This->DriverBindingHandle,\r
115 DeviceHandle\r
116 );\r
117\r
118 return Status;\r
119}\r
120\r
121/**\r
122\r
123 After we've pronounced support for a specific device in\r
124 DriverBindingSupported(), we start managing said device (passed in by the\r
125 Driver Execution Environment) with the following service.\r
126\r
127 See DriverBindingSupported() for specification references.\r
128\r
129 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
130 incorporating this driver (independently of\r
131 any device).\r
132\r
133 @param[in] DeviceHandle The supported device to drive.\r
134\r
135 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.\r
136\r
137\r
138 @retval EFI_SUCCESS The device was started.\r
139\r
140 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
141\r
142 @return Error codes from the OpenProtocol() boot\r
143 service, the PciIo protocol or the\r
144 InstallProtocolInterface() boot service.\r
145\r
146**/\r
147STATIC\r
148EFI_STATUS\r
149EFIAPI\r
150XenIoPciDeviceBindingStart (\r
151 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
152 IN EFI_HANDLE DeviceHandle,\r
153 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
154 )\r
155{\r
156 EFI_STATUS Status;\r
157 XENIO_PROTOCOL *XenIo;\r
158 EFI_PCI_IO_PROTOCOL *PciIo;\r
159 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;\r
160\r
161 XenIo = (XENIO_PROTOCOL *)AllocateZeroPool (sizeof *XenIo);\r
162 if (XenIo == NULL) {\r
163 return EFI_OUT_OF_RESOURCES;\r
164 }\r
165\r
166 Status = gBS->OpenProtocol (\r
167 DeviceHandle,\r
168 &gEfiPciIoProtocolGuid,\r
169 (VOID **)&PciIo,\r
170 This->DriverBindingHandle,\r
171 DeviceHandle,\r
172 EFI_OPEN_PROTOCOL_BY_DRIVER\r
173 );\r
174 if (EFI_ERROR (Status)) {\r
175 goto FreeXenIo;\r
176 }\r
177\r
178 //\r
179 // The BAR1 of this PCI device is used for shared memory and is supposed to\r
180 // look like MMIO. The address space of the BAR1 will be used to map the\r
181 // Grant Table.\r
182 //\r
183 Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID **)&BarDesc);\r
184 ASSERT_EFI_ERROR (Status);\r
185 ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM);\r
186\r
187 /* Get a Memory address for mapping the Grant Table. */\r
188 DEBUG ((DEBUG_INFO, "XenIoPci: BAR at %LX\n", BarDesc->AddrRangeMin));\r
189 XenIo->GrantTableAddress = BarDesc->AddrRangeMin;\r
190 FreePool (BarDesc);\r
191\r
192 Status = gBS->InstallProtocolInterface (\r
193 &DeviceHandle,\r
194 &gXenIoProtocolGuid,\r
195 EFI_NATIVE_INTERFACE,\r
196 XenIo\r
197 );\r
198\r
199 if (!EFI_ERROR (Status)) {\r
200 return EFI_SUCCESS;\r
201 }\r
202\r
203 gBS->CloseProtocol (\r
204 DeviceHandle,\r
205 &gEfiPciIoProtocolGuid,\r
206 This->DriverBindingHandle,\r
207 DeviceHandle\r
208 );\r
209\r
210FreeXenIo:\r
211 FreePool (XenIo);\r
212\r
213 return Status;\r
214}\r
215\r
216/**\r
217\r
218 Stop driving the XenIo PCI device\r
219\r
220 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
221 incorporating this driver (independently of any\r
222 device).\r
223\r
224 @param[in] DeviceHandle Stop driving this device.\r
225\r
226 @param[in] NumberOfChildren Since this function belongs to a device driver\r
227 only (as opposed to a bus driver), the caller\r
228 environment sets NumberOfChildren to zero, and\r
229 we ignore it.\r
230\r
231 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren).\r
232\r
233 @retval EFI_SUCCESS Driver instance has been stopped and the PCI\r
234 configuration attributes have been restored.\r
235\r
236 @return Error codes from the OpenProtocol() or\r
237 CloseProtocol(), UninstallProtocolInterface()\r
238 boot services.\r
239\r
240**/\r
241STATIC\r
242EFI_STATUS\r
243EFIAPI\r
244XenIoPciDeviceBindingStop (\r
245 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
246 IN EFI_HANDLE DeviceHandle,\r
247 IN UINTN NumberOfChildren,\r
248 IN EFI_HANDLE *ChildHandleBuffer\r
249 )\r
250{\r
251 EFI_STATUS Status;\r
252 XENIO_PROTOCOL *XenIo;\r
253\r
254 Status = gBS->OpenProtocol (\r
255 DeviceHandle, // candidate device\r
256 &gXenIoProtocolGuid, // retrieve the XenIo iface\r
257 (VOID **)&XenIo, // target pointer\r
258 This->DriverBindingHandle, // requestor driver identity\r
259 DeviceHandle, // requesting lookup for dev.\r
260 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added\r
261 );\r
262 if (EFI_ERROR (Status)) {\r
263 return Status;\r
264 }\r
265\r
266 //\r
267 // Handle Stop() requests for in-use driver instances gracefully.\r
268 //\r
269 Status = gBS->UninstallProtocolInterface (\r
270 DeviceHandle,\r
271 &gXenIoProtocolGuid,\r
272 XenIo\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
275 return Status;\r
276 }\r
277\r
278 Status = gBS->CloseProtocol (\r
279 DeviceHandle,\r
280 &gEfiPciIoProtocolGuid,\r
281 This->DriverBindingHandle,\r
282 DeviceHandle\r
283 );\r
284\r
285 FreePool (XenIo);\r
286\r
287 return Status;\r
288}\r
289\r
290//\r
291// The static object that groups the Supported() (ie. probe), Start() and\r
292// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
293// C, 10.1 EFI Driver Binding Protocol.\r
294//\r
295STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
296 &XenIoPciDeviceBindingSupported,\r
297 &XenIoPciDeviceBindingStart,\r
298 &XenIoPciDeviceBindingStop,\r
299 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
300 NULL, // ImageHandle, to be overwritten by\r
301 // EfiLibInstallDriverBindingComponentName2() in XenIoPciDeviceEntryPoint()\r
302 NULL // DriverBindingHandle, ditto\r
303};\r
304\r
305//\r
306// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and\r
307// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name\r
308// in English, for display on standard console devices. This is recommended for\r
309// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's\r
310// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.\r
311//\r
312STATIC\r
313EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {\r
314 { "eng;en", L"XenIo PCI Driver" },\r
315 { NULL, NULL }\r
316};\r
317\r
318STATIC\r
319EFI_COMPONENT_NAME_PROTOCOL gComponentName;\r
320\r
321EFI_STATUS\r
322EFIAPI\r
323XenIoPciGetDriverName (\r
324 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
325 IN CHAR8 *Language,\r
326 OUT CHAR16 **DriverName\r
327 )\r
328{\r
329 return LookupUnicodeString2 (\r
330 Language,\r
331 This->SupportedLanguages,\r
332 mDriverNameTable,\r
333 DriverName,\r
334 (BOOLEAN)(This == &gComponentName) // Iso639Language\r
335 );\r
336}\r
337\r
338EFI_STATUS\r
339EFIAPI\r
340XenIoPciGetDeviceName (\r
341 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
342 IN EFI_HANDLE DeviceHandle,\r
343 IN EFI_HANDLE ChildHandle,\r
344 IN CHAR8 *Language,\r
345 OUT CHAR16 **ControllerName\r
346 )\r
347{\r
348 return EFI_UNSUPPORTED;\r
349}\r
350\r
351STATIC\r
352EFI_COMPONENT_NAME_PROTOCOL gComponentName = {\r
353 &XenIoPciGetDriverName,\r
354 &XenIoPciGetDeviceName,\r
355 "eng" // SupportedLanguages, ISO 639-2 language codes\r
356};\r
357\r
358STATIC\r
359EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {\r
360 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&XenIoPciGetDriverName,\r
361 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&XenIoPciGetDeviceName,\r
362 "en" // SupportedLanguages, RFC 4646 language codes\r
363};\r
364\r
365//\r
366// Entry point of this driver.\r
367//\r
368EFI_STATUS\r
369EFIAPI\r
370XenIoPciDeviceEntryPoint (\r
371 IN EFI_HANDLE ImageHandle,\r
372 IN EFI_SYSTEM_TABLE *SystemTable\r
373 )\r
374{\r
375 return EfiLibInstallDriverBindingComponentName2 (\r
376 ImageHandle,\r
377 SystemTable,\r
378 &gDriverBinding,\r
379 ImageHandle,\r
380 &gComponentName,\r
381 &gComponentName2\r
382 );\r
383}\r