]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
MdeModulePkg/UfsPciHcDxe: Fix EBC build error
[mirror_edk2.git] / ArmPlatformPkg / ArmVirtualizationPkg / Library / PlatformIntelBdsLib / IntelBdsPlatform.c
CommitLineData
be8afe14 1/** @file\r
e4fbd18f 2 Implementation for PlatformBdsLib library class interfaces.\r
be8afe14 3\r
60dc18a1 4 Copyright (C) 2015, Red Hat, Inc.\r
e4fbd18f
LE
5 Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>\r
6 Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
be8afe14 7\r
e4fbd18f
LE
8 This program and the accompanying materials are licensed and made available\r
9 under the terms and conditions of the BSD License which accompanies this\r
10 distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
be8afe14 12\r
e4fbd18f
LE
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
14 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
be8afe14
LE
15\r
16**/\r
17\r
60dc18a1
LE
18#include <IndustryStandard/Pci22.h>\r
19#include <Library/DevicePathLib.h>\r
20#include <Library/PcdLib.h>\r
ba67a145 21#include <Library/PlatformBdsLib.h>\r
274b4a8d 22#include <Library/QemuBootOrderLib.h>\r
60dc18a1
LE
23#include <Protocol/DevicePath.h>\r
24#include <Protocol/GraphicsOutput.h>\r
25#include <Protocol/PciIo.h>\r
26#include <Protocol/PciRootBridgeIo.h>\r
274b4a8d 27\r
ba67a145
LE
28#include "IntelBdsPlatform.h"\r
29\r
60dc18a1
LE
30#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }\r
31\r
32\r
33#pragma pack (1)\r
34typedef struct {\r
35 VENDOR_DEVICE_PATH SerialDxe;\r
36 UART_DEVICE_PATH Uart;\r
37 VENDOR_DEFINED_DEVICE_PATH Vt100;\r
38 EFI_DEVICE_PATH_PROTOCOL End;\r
39} PLATFORM_SERIAL_CONSOLE;\r
40#pragma pack ()\r
41\r
42#define SERIAL_DXE_FILE_GUID { \\r
43 0xD3987D4B, 0x971A, 0x435F, \\r
44 { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \\r
45 }\r
46\r
47STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {\r
48 //\r
49 // VENDOR_DEVICE_PATH SerialDxe\r
50 //\r
51 {\r
52 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },\r
53 SERIAL_DXE_FILE_GUID\r
54 },\r
55\r
56 //\r
57 // UART_DEVICE_PATH Uart\r
58 //\r
59 {\r
60 { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) },\r
61 0, // Reserved\r
62 FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
63 FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
64 FixedPcdGet8 (PcdUartDefaultParity), // Parity\r
65 FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\r
66 },\r
67\r
68 //\r
69 // VENDOR_DEFINED_DEVICE_PATH Vt100\r
70 //\r
71 {\r
72 {\r
73 MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,\r
74 DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)\r
75 },\r
76 EFI_VT_100_GUID\r
77 },\r
78\r
79 //\r
80 // EFI_DEVICE_PATH_PROTOCOL End\r
81 //\r
82 {\r
83 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
84 DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)\r
85 }\r
86};\r
87\r
88\r
89#pragma pack (1)\r
90typedef struct {\r
91 USB_CLASS_DEVICE_PATH Keyboard;\r
92 EFI_DEVICE_PATH_PROTOCOL End;\r
93} PLATFORM_USB_KEYBOARD;\r
94#pragma pack ()\r
95\r
96STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {\r
97 //\r
98 // USB_CLASS_DEVICE_PATH Keyboard\r
99 //\r
100 {\r
101 {\r
102 MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,\r
103 DP_NODE_LEN (USB_CLASS_DEVICE_PATH)\r
104 },\r
105 0xFFFF, // VendorId: any\r
106 0xFFFF, // ProductId: any\r
107 3, // DeviceClass: HID\r
108 1, // DeviceSubClass: boot\r
109 1 // DeviceProtocol: keyboard\r
110 },\r
111\r
112 //\r
113 // EFI_DEVICE_PATH_PROTOCOL End\r
114 //\r
115 {\r
116 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
117 DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)\r
118 }\r
119};\r
120\r
121\r
be8afe14
LE
122//\r
123// BDS Platform Functions\r
124//\r
125/**\r
126 Platform Bds init. Include the platform firmware vendor, revision\r
127 and so crc check.\r
128\r
129**/\r
130VOID\r
131EFIAPI\r
132PlatformBdsInit (\r
133 VOID\r
134 )\r
135{\r
136}\r
137\r
60dc18a1
LE
138\r
139/**\r
140 Check if the handle satisfies a particular condition.\r
141\r
142 @param[in] Handle The handle to check.\r
143 @param[in] ReportText A caller-allocated string passed in for reporting\r
144 purposes. It must never be NULL.\r
145\r
146 @retval TRUE The condition is satisfied.\r
147 @retval FALSE Otherwise. This includes the case when the condition could not\r
148 be fully evaluated due to an error.\r
149**/\r
150typedef\r
151BOOLEAN\r
152(EFIAPI *FILTER_FUNCTION) (\r
153 IN EFI_HANDLE Handle,\r
154 IN CONST CHAR16 *ReportText\r
155 );\r
156\r
157\r
158/**\r
159 Process a handle.\r
160\r
161 @param[in] Handle The handle to process.\r
162 @param[in] ReportText A caller-allocated string passed in for reporting\r
163 purposes. It must never be NULL.\r
164**/\r
165typedef\r
166VOID\r
167(EFIAPI *CALLBACK_FUNCTION) (\r
168 IN EFI_HANDLE Handle,\r
169 IN CONST CHAR16 *ReportText\r
170 );\r
171\r
172/**\r
173 Locate all handles that carry the specified protocol, filter them with a\r
174 callback function, and pass each handle that passes the filter to another\r
175 callback.\r
176\r
177 @param[in] ProtocolGuid The protocol to look for.\r
178\r
179 @param[in] Filter The filter function to pass each handle to. If this\r
180 parameter is NULL, then all handles are processed.\r
181\r
182 @param[in] Process The callback function to pass each handle to that\r
183 clears the filter.\r
184**/\r
185STATIC\r
186VOID\r
187FilterAndProcess (\r
188 IN EFI_GUID *ProtocolGuid,\r
189 IN FILTER_FUNCTION Filter OPTIONAL,\r
190 IN CALLBACK_FUNCTION Process\r
191 )\r
192{\r
193 EFI_STATUS Status;\r
194 EFI_HANDLE *Handles;\r
195 UINTN NoHandles;\r
196 UINTN Idx;\r
197\r
198 Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid,\r
199 NULL /* SearchKey */, &NoHandles, &Handles);\r
200 if (EFI_ERROR (Status)) {\r
201 //\r
202 // This is not an error, just an informative condition.\r
203 //\r
204 DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid,\r
205 Status));\r
206 return;\r
207 }\r
208\r
209 ASSERT (NoHandles > 0);\r
210 for (Idx = 0; Idx < NoHandles; ++Idx) {\r
211 CHAR16 *DevicePathText;\r
212 STATIC CHAR16 Fallback[] = L"<device path unavailable>";\r
213\r
214 //\r
215 // The ConvertDevicePathToText() function handles NULL input transparently.\r
216 //\r
217 DevicePathText = ConvertDevicePathToText (\r
218 DevicePathFromHandle (Handles[Idx]),\r
219 FALSE, // DisplayOnly\r
220 FALSE // AllowShortcuts\r
221 );\r
222 if (DevicePathText == NULL) {\r
223 DevicePathText = Fallback;\r
224 }\r
225\r
226 if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) {\r
227 Process (Handles[Idx], DevicePathText);\r
228 }\r
229\r
230 if (DevicePathText != Fallback) {\r
231 FreePool (DevicePathText);\r
232 }\r
233 }\r
234 gBS->FreePool (Handles);\r
235}\r
236\r
237\r
238/**\r
239 This FILTER_FUNCTION checks if a handle corresponds to a PCI display device.\r
240**/\r
241STATIC\r
242BOOLEAN\r
243EFIAPI\r
244IsPciDisplay (\r
245 IN EFI_HANDLE Handle,\r
246 IN CONST CHAR16 *ReportText\r
247 )\r
248{\r
249 EFI_STATUS Status;\r
250 EFI_PCI_IO_PROTOCOL *PciIo;\r
251 PCI_TYPE00 Pci;\r
252\r
253 Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid,\r
254 (VOID**)&PciIo);\r
255 if (EFI_ERROR (Status)) {\r
256 //\r
257 // This is not an error worth reporting.\r
258 //\r
259 return FALSE;\r
260 }\r
261\r
262 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */,\r
263 sizeof Pci / sizeof (UINT32), &Pci);\r
264 if (EFI_ERROR (Status)) {\r
265 DEBUG ((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));\r
266 return FALSE;\r
267 }\r
268\r
269 return IS_PCI_DISPLAY (&Pci);\r
270}\r
271\r
272\r
273/**\r
274 This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking\r
275 the matching driver to produce all first-level child handles.\r
276**/\r
277STATIC\r
278VOID\r
279EFIAPI\r
280Connect (\r
281 IN EFI_HANDLE Handle,\r
282 IN CONST CHAR16 *ReportText\r
283 )\r
284{\r
285 EFI_STATUS Status;\r
286\r
287 Status = gBS->ConnectController (\r
288 Handle, // ControllerHandle\r
289 NULL, // DriverImageHandle\r
290 NULL, // RemainingDevicePath -- produce all children\r
291 FALSE // Recursive\r
292 );\r
293 DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n",\r
294 __FUNCTION__, ReportText, Status));\r
295}\r
296\r
297\r
298/**\r
299 This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the\r
300 handle, and adds it to ConOut and ErrOut.\r
301**/\r
302STATIC\r
303VOID\r
304EFIAPI\r
305AddOutput (\r
306 IN EFI_HANDLE Handle,\r
307 IN CONST CHAR16 *ReportText\r
308 )\r
309{\r
310 EFI_STATUS Status;\r
311 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
312\r
313 DevicePath = DevicePathFromHandle (Handle);\r
314 if (DevicePath == NULL) {\r
315 DEBUG ((EFI_D_ERROR, "%a: %s: handle %p: device path not found\n",\r
316 __FUNCTION__, ReportText, Handle));\r
317 return;\r
318 }\r
319\r
320 Status = BdsLibUpdateConsoleVariable (L"ConOut", DevicePath, NULL);\r
321 if (EFI_ERROR (Status)) {\r
322 DEBUG ((EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__,\r
323 ReportText, Status));\r
324 return;\r
325 }\r
326\r
327 Status = BdsLibUpdateConsoleVariable (L"ErrOut", DevicePath, NULL);\r
328 if (EFI_ERROR (Status)) {\r
329 DEBUG ((EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__,\r
330 ReportText, Status));\r
331 return;\r
332 }\r
333\r
334 DEBUG ((EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__,\r
335 ReportText));\r
336}\r
337\r
338\r
be8afe14
LE
339/**\r
340 The function will execute with as the platform policy, current policy\r
341 is driven by boot mode. IBV/OEM can customize this code for their specific\r
342 policy action.\r
343\r
344 @param DriverOptionList The header of the driver option link list\r
345 @param BootOptionList The header of the boot option link list\r
346 @param ProcessCapsules A pointer to ProcessCapsules()\r
347 @param BaseMemoryTest A pointer to BaseMemoryTest()\r
348\r
349**/\r
350VOID\r
351EFIAPI\r
352PlatformBdsPolicyBehavior (\r
353 IN LIST_ENTRY *DriverOptionList,\r
354 IN LIST_ENTRY *BootOptionList,\r
355 IN PROCESS_CAPSULES ProcessCapsules,\r
356 IN BASEM_MEMORY_TEST BaseMemoryTest\r
357 )\r
358{\r
60dc18a1
LE
359 //\r
360 // Locate the PCI root bridges and make the PCI bus driver connect each,\r
361 // non-recursively. This will produce a number of child handles with PciIo on\r
362 // them.\r
363 //\r
364 FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect);\r
365\r
366 //\r
367 // Find all display class PCI devices (using the handles from the previous\r
368 // step), and connect them non-recursively. This should produce a number of\r
369 // child handles with GOPs on them.\r
370 //\r
371 FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect);\r
372\r
373 //\r
374 // Now add the device path of all handles with GOP on them to ConOut and\r
375 // ErrOut.\r
376 //\r
377 FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);\r
378\r
379 //\r
380 // Add the hardcoded short-form USB keyboard device path to ConIn.\r
381 //\r
382 BdsLibUpdateConsoleVariable (L"ConIn",\r
383 (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);\r
384\r
385 //\r
386 // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.\r
387 //\r
388 BdsLibUpdateConsoleVariable (L"ConIn",\r
389 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
390 BdsLibUpdateConsoleVariable (L"ConOut",\r
391 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
392 BdsLibUpdateConsoleVariable (L"ErrOut",\r
393 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
394\r
395 //\r
396 // Connect the consoles based on the above variables.\r
397 //\r
398 BdsLibConnectAllDefaultConsoles ();\r
399\r
26a36374
LE
400 //\r
401 // Show the splash screen.\r
402 //\r
403 EnableQuietBoot (PcdGetPtr (PcdLogoFile));\r
404\r
60dc18a1
LE
405 //\r
406 // Connect the rest of the devices.\r
407 //\r
a78c4836
LE
408 BdsLibConnectAll ();\r
409\r
23d04b58 410 //\r
a78c4836
LE
411 // Process QEMU's -kernel command line option. Note that the kernel booted\r
412 // this way should receive ACPI tables, which is why we connect all devices\r
413 // first (see above) -- PCI enumeration blocks ACPI table installation, if\r
414 // there is a PCI host.\r
23d04b58
LE
415 //\r
416 TryRunningQemuKernel ();\r
417\r
1b610ac2 418 BdsLibEnumerateAllBootOption (BootOptionList);\r
274b4a8d
LE
419 SetBootOrderFromQemu (BootOptionList);\r
420 //\r
421 // The BootOrder variable may have changed, reload the in-memory list with\r
422 // it.\r
423 //\r
424 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
425\r
9aaf441c 426 PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);\r
be8afe14
LE
427}\r
428\r
429/**\r
430 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
431 return, so the UEFI 2.0 specification defines that you will default to an\r
432 interactive mode and stop processing the BootOrder list in this case. This\r
433 is also a platform implementation and can be customized by IBV/OEM.\r
434\r
435 @param Option Pointer to Boot Option that succeeded to boot.\r
436\r
437**/\r
438VOID\r
439EFIAPI\r
440PlatformBdsBootSuccess (\r
441 IN BDS_COMMON_OPTION *Option\r
442 )\r
443{\r
444}\r
445\r
446/**\r
447 Hook point after a boot attempt fails.\r
448\r
449 @param Option Pointer to Boot Option that failed to boot.\r
450 @param Status Status returned from failed boot.\r
451 @param ExitData Exit data returned from failed boot.\r
452 @param ExitDataSize Exit data size returned from failed boot.\r
453\r
454**/\r
455VOID\r
456EFIAPI\r
457PlatformBdsBootFail (\r
458 IN BDS_COMMON_OPTION *Option,\r
459 IN EFI_STATUS Status,\r
460 IN CHAR16 *ExitData,\r
461 IN UINTN ExitDataSize\r
462 )\r
463{\r
464}\r
465\r
466/**\r
467 This function locks platform flash that is not allowed to be updated during normal boot path.\r
468 The flash layout is platform specific.\r
469**/\r
470VOID\r
471EFIAPI\r
472PlatformBdsLockNonUpdatableFlash (\r
473 VOID\r
474 )\r
475{\r
476 return;\r
477}\r