]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c
ArmPkg/PlatformBootManagerLib: print firmware version to console
[mirror_edk2.git] / ArmPkg / Library / PlatformBootManagerLib / PlatformBm.c
CommitLineData
c976f9cb
AB
1/** @file\r
2 Implementation for PlatformBootManagerLib library class interfaces.\r
3\r
4 Copyright (C) 2015-2016, Red Hat, Inc.\r
5 Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>\r
6 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
7 Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
8\r
9 This program and the accompanying materials are licensed and made available\r
10 under the terms and conditions of the BSD License which accompanies this\r
11 distribution. The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
15 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18\r
19#include <IndustryStandard/Pci22.h>\r
a43d75e1 20#include <Library/BootLogoLib.h>\r
4bbcc285 21#include <Library/CapsuleLib.h>\r
c976f9cb 22#include <Library/DevicePathLib.h>\r
4bbcc285 23#include <Library/HobLib.h>\r
c976f9cb
AB
24#include <Library/PcdLib.h>\r
25#include <Library/UefiBootManagerLib.h>\r
26#include <Library/UefiLib.h>\r
27#include <Protocol/DevicePath.h>\r
13ca0abb 28#include <Protocol/EsrtManagement.h>\r
c976f9cb
AB
29#include <Protocol/GraphicsOutput.h>\r
30#include <Protocol/LoadedImage.h>\r
31#include <Protocol/PciIo.h>\r
32#include <Protocol/PciRootBridgeIo.h>\r
33#include <Guid/EventGroup.h>\r
34#include <Guid/TtyTerm.h>\r
35\r
36#include "PlatformBm.h"\r
37\r
38#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }\r
39\r
c976f9cb
AB
40#pragma pack (1)\r
41typedef struct {\r
42 VENDOR_DEVICE_PATH SerialDxe;\r
43 UART_DEVICE_PATH Uart;\r
44 VENDOR_DEFINED_DEVICE_PATH TermType;\r
45 EFI_DEVICE_PATH_PROTOCOL End;\r
46} PLATFORM_SERIAL_CONSOLE;\r
47#pragma pack ()\r
48\r
49#define SERIAL_DXE_FILE_GUID { \\r
50 0xD3987D4B, 0x971A, 0x435F, \\r
51 { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \\r
52 }\r
53\r
54STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {\r
55 //\r
56 // VENDOR_DEVICE_PATH SerialDxe\r
57 //\r
58 {\r
59 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },\r
60 SERIAL_DXE_FILE_GUID\r
61 },\r
62\r
63 //\r
64 // UART_DEVICE_PATH Uart\r
65 //\r
66 {\r
67 { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) },\r
68 0, // Reserved\r
69 FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
70 FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
71 FixedPcdGet8 (PcdUartDefaultParity), // Parity\r
72 FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\r
73 },\r
74\r
75 //\r
76 // VENDOR_DEFINED_DEVICE_PATH TermType\r
77 //\r
78 {\r
79 {\r
80 MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,\r
81 DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)\r
82 }\r
83 //\r
84 // Guid to be filled in dynamically\r
85 //\r
86 },\r
87\r
88 //\r
89 // EFI_DEVICE_PATH_PROTOCOL End\r
90 //\r
91 {\r
92 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
93 DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)\r
94 }\r
95};\r
96\r
97\r
98#pragma pack (1)\r
99typedef struct {\r
100 USB_CLASS_DEVICE_PATH Keyboard;\r
101 EFI_DEVICE_PATH_PROTOCOL End;\r
102} PLATFORM_USB_KEYBOARD;\r
103#pragma pack ()\r
104\r
105STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {\r
106 //\r
107 // USB_CLASS_DEVICE_PATH Keyboard\r
108 //\r
109 {\r
110 {\r
111 MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,\r
112 DP_NODE_LEN (USB_CLASS_DEVICE_PATH)\r
113 },\r
114 0xFFFF, // VendorId: any\r
115 0xFFFF, // ProductId: any\r
116 3, // DeviceClass: HID\r
117 1, // DeviceSubClass: boot\r
118 1 // DeviceProtocol: keyboard\r
119 },\r
120\r
121 //\r
122 // EFI_DEVICE_PATH_PROTOCOL End\r
123 //\r
124 {\r
125 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
126 DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)\r
127 }\r
128};\r
129\r
130\r
131/**\r
132 Check if the handle satisfies a particular condition.\r
133\r
134 @param[in] Handle The handle to check.\r
135 @param[in] ReportText A caller-allocated string passed in for reporting\r
136 purposes. It must never be NULL.\r
137\r
138 @retval TRUE The condition is satisfied.\r
139 @retval FALSE Otherwise. This includes the case when the condition could not\r
140 be fully evaluated due to an error.\r
141**/\r
142typedef\r
143BOOLEAN\r
144(EFIAPI *FILTER_FUNCTION) (\r
145 IN EFI_HANDLE Handle,\r
146 IN CONST CHAR16 *ReportText\r
147 );\r
148\r
149\r
150/**\r
151 Process a handle.\r
152\r
153 @param[in] Handle The handle to process.\r
154 @param[in] ReportText A caller-allocated string passed in for reporting\r
155 purposes. It must never be NULL.\r
156**/\r
157typedef\r
158VOID\r
159(EFIAPI *CALLBACK_FUNCTION) (\r
160 IN EFI_HANDLE Handle,\r
161 IN CONST CHAR16 *ReportText\r
162 );\r
163\r
164/**\r
165 Locate all handles that carry the specified protocol, filter them with a\r
166 callback function, and pass each handle that passes the filter to another\r
167 callback.\r
168\r
169 @param[in] ProtocolGuid The protocol to look for.\r
170\r
171 @param[in] Filter The filter function to pass each handle to. If this\r
172 parameter is NULL, then all handles are processed.\r
173\r
174 @param[in] Process The callback function to pass each handle to that\r
175 clears the filter.\r
176**/\r
177STATIC\r
178VOID\r
179FilterAndProcess (\r
180 IN EFI_GUID *ProtocolGuid,\r
181 IN FILTER_FUNCTION Filter OPTIONAL,\r
182 IN CALLBACK_FUNCTION Process\r
183 )\r
184{\r
185 EFI_STATUS Status;\r
186 EFI_HANDLE *Handles;\r
187 UINTN NoHandles;\r
188 UINTN Idx;\r
189\r
190 Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid,\r
191 NULL /* SearchKey */, &NoHandles, &Handles);\r
192 if (EFI_ERROR (Status)) {\r
193 //\r
194 // This is not an error, just an informative condition.\r
195 //\r
196 DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid,\r
197 Status));\r
198 return;\r
199 }\r
200\r
201 ASSERT (NoHandles > 0);\r
202 for (Idx = 0; Idx < NoHandles; ++Idx) {\r
203 CHAR16 *DevicePathText;\r
204 STATIC CHAR16 Fallback[] = L"<device path unavailable>";\r
205\r
206 //\r
207 // The ConvertDevicePathToText() function handles NULL input transparently.\r
208 //\r
209 DevicePathText = ConvertDevicePathToText (\r
210 DevicePathFromHandle (Handles[Idx]),\r
211 FALSE, // DisplayOnly\r
212 FALSE // AllowShortcuts\r
213 );\r
214 if (DevicePathText == NULL) {\r
215 DevicePathText = Fallback;\r
216 }\r
217\r
218 if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) {\r
219 Process (Handles[Idx], DevicePathText);\r
220 }\r
221\r
222 if (DevicePathText != Fallback) {\r
223 FreePool (DevicePathText);\r
224 }\r
225 }\r
226 gBS->FreePool (Handles);\r
227}\r
228\r
229\r
230/**\r
231 This FILTER_FUNCTION checks if a handle corresponds to a PCI display device.\r
232**/\r
233STATIC\r
234BOOLEAN\r
235EFIAPI\r
236IsPciDisplay (\r
237 IN EFI_HANDLE Handle,\r
238 IN CONST CHAR16 *ReportText\r
239 )\r
240{\r
241 EFI_STATUS Status;\r
242 EFI_PCI_IO_PROTOCOL *PciIo;\r
243 PCI_TYPE00 Pci;\r
244\r
245 Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid,\r
246 (VOID**)&PciIo);\r
247 if (EFI_ERROR (Status)) {\r
248 //\r
249 // This is not an error worth reporting.\r
250 //\r
251 return FALSE;\r
252 }\r
253\r
254 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */,\r
255 sizeof Pci / sizeof (UINT32), &Pci);\r
256 if (EFI_ERROR (Status)) {\r
257 DEBUG ((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));\r
258 return FALSE;\r
259 }\r
260\r
261 return IS_PCI_DISPLAY (&Pci);\r
262}\r
263\r
264\r
265/**\r
266 This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking\r
267 the matching driver to produce all first-level child handles.\r
268**/\r
269STATIC\r
270VOID\r
271EFIAPI\r
272Connect (\r
273 IN EFI_HANDLE Handle,\r
274 IN CONST CHAR16 *ReportText\r
275 )\r
276{\r
277 EFI_STATUS Status;\r
278\r
279 Status = gBS->ConnectController (\r
280 Handle, // ControllerHandle\r
281 NULL, // DriverImageHandle\r
282 NULL, // RemainingDevicePath -- produce all children\r
283 FALSE // Recursive\r
284 );\r
285 DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n",\r
286 __FUNCTION__, ReportText, Status));\r
287}\r
288\r
289\r
290/**\r
291 This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the\r
292 handle, and adds it to ConOut and ErrOut.\r
293**/\r
294STATIC\r
295VOID\r
296EFIAPI\r
297AddOutput (\r
298 IN EFI_HANDLE Handle,\r
299 IN CONST CHAR16 *ReportText\r
300 )\r
301{\r
302 EFI_STATUS Status;\r
303 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
304\r
305 DevicePath = DevicePathFromHandle (Handle);\r
306 if (DevicePath == NULL) {\r
307 DEBUG ((EFI_D_ERROR, "%a: %s: handle %p: device path not found\n",\r
308 __FUNCTION__, ReportText, Handle));\r
309 return;\r
310 }\r
311\r
312 Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
313 if (EFI_ERROR (Status)) {\r
314 DEBUG ((EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__,\r
315 ReportText, Status));\r
316 return;\r
317 }\r
318\r
319 Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
320 if (EFI_ERROR (Status)) {\r
321 DEBUG ((EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__,\r
322 ReportText, Status));\r
323 return;\r
324 }\r
325\r
326 DEBUG ((EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__,\r
327 ReportText));\r
328}\r
329\r
330STATIC\r
331VOID\r
332PlatformRegisterFvBootOption (\r
07548e17 333 CONST EFI_GUID *FileGuid,\r
c976f9cb
AB
334 CHAR16 *Description,\r
335 UINT32 Attributes\r
336 )\r
337{\r
338 EFI_STATUS Status;\r
339 INTN OptionIndex;\r
340 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
341 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
342 UINTN BootOptionCount;\r
343 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
344 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
345 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
346\r
347 Status = gBS->HandleProtocol (\r
348 gImageHandle,\r
349 &gEfiLoadedImageProtocolGuid,\r
350 (VOID **) &LoadedImage\r
351 );\r
352 ASSERT_EFI_ERROR (Status);\r
353\r
354 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
355 DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);\r
356 ASSERT (DevicePath != NULL);\r
357 DevicePath = AppendDevicePathNode (\r
358 DevicePath,\r
359 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
360 );\r
361 ASSERT (DevicePath != NULL);\r
362\r
363 Status = EfiBootManagerInitializeLoadOption (\r
364 &NewOption,\r
365 LoadOptionNumberUnassigned,\r
366 LoadOptionTypeBoot,\r
367 Attributes,\r
368 Description,\r
369 DevicePath,\r
370 NULL,\r
371 0\r
372 );\r
373 ASSERT_EFI_ERROR (Status);\r
374 FreePool (DevicePath);\r
375\r
376 BootOptions = EfiBootManagerGetLoadOptions (\r
377 &BootOptionCount, LoadOptionTypeBoot\r
378 );\r
379\r
380 OptionIndex = EfiBootManagerFindLoadOption (\r
381 &NewOption, BootOptions, BootOptionCount\r
382 );\r
383\r
384 if (OptionIndex == -1) {\r
385 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);\r
386 ASSERT_EFI_ERROR (Status);\r
387 }\r
388 EfiBootManagerFreeLoadOption (&NewOption);\r
389 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
390}\r
391\r
392\r
393STATIC\r
394VOID\r
395PlatformRegisterOptionsAndKeys (\r
396 VOID\r
397 )\r
398{\r
399 EFI_STATUS Status;\r
400 EFI_INPUT_KEY Enter;\r
401 EFI_INPUT_KEY F2;\r
402 EFI_INPUT_KEY Esc;\r
403 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
404\r
405 //\r
406 // Register ENTER as CONTINUE key\r
407 //\r
408 Enter.ScanCode = SCAN_NULL;\r
409 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
410 Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
411 ASSERT_EFI_ERROR (Status);\r
412\r
413 //\r
414 // Map F2 and ESC to Boot Manager Menu\r
415 //\r
416 F2.ScanCode = SCAN_F2;\r
417 F2.UnicodeChar = CHAR_NULL;\r
418 Esc.ScanCode = SCAN_ESC;\r
419 Esc.UnicodeChar = CHAR_NULL;\r
420 Status = EfiBootManagerGetBootManagerMenu (&BootOption);\r
421 ASSERT_EFI_ERROR (Status);\r
422 Status = EfiBootManagerAddKeyOptionVariable (\r
423 NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL\r
424 );\r
425 ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
426 Status = EfiBootManagerAddKeyOptionVariable (\r
427 NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL\r
428 );\r
429 ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
430}\r
431\r
432\r
433//\r
434// BDS Platform Functions\r
435//\r
436/**\r
437 Do the platform init, can be customized by OEM/IBV\r
438 Possible things that can be done in PlatformBootManagerBeforeConsole:\r
439 > Update console variable: 1. include hot-plug devices;\r
440 > 2. Clear ConIn and add SOL for AMT\r
441 > Register new Driver#### or Boot####\r
442 > Register new Key####: e.g.: F12\r
443 > Signal ReadyToLock event\r
444 > Authentication action: 1. connect Auth devices;\r
445 > 2. Identify auto logon user.\r
446**/\r
447VOID\r
448EFIAPI\r
449PlatformBootManagerBeforeConsole (\r
450 VOID\r
451 )\r
452{\r
13ca0abb
AB
453 EFI_STATUS Status;\r
454 ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;\r
4bbcc285
AB
455\r
456 if (GetBootModeHob() == BOOT_ON_FLASH_UPDATE) {\r
457 DEBUG ((DEBUG_INFO, "ProcessCapsules Before EndOfDxe ......\n"));\r
458 Status = ProcessCapsules ();\r
459 DEBUG ((DEBUG_INFO, "ProcessCapsules returned %r\n", Status));\r
13ca0abb 460 } else {\r
aed68ed6
AB
461 Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL,\r
462 (VOID **)&EsrtManagement);\r
463 if (!EFI_ERROR (Status)) {\r
13ca0abb
AB
464 EsrtManagement->SyncEsrtFmp ();\r
465 }\r
466 }\r
467\r
c976f9cb
AB
468 //\r
469 // Signal EndOfDxe PI Event\r
470 //\r
471 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
472\r
473 //\r
474 // Locate the PCI root bridges and make the PCI bus driver connect each,\r
475 // non-recursively. This will produce a number of child handles with PciIo on\r
476 // them.\r
477 //\r
478 FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect);\r
479\r
480 //\r
481 // Find all display class PCI devices (using the handles from the previous\r
482 // step), and connect them non-recursively. This should produce a number of\r
483 // child handles with GOPs on them.\r
484 //\r
485 FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect);\r
486\r
487 //\r
488 // Now add the device path of all handles with GOP on them to ConOut and\r
489 // ErrOut.\r
490 //\r
491 FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);\r
492\r
493 //\r
494 // Add the hardcoded short-form USB keyboard device path to ConIn.\r
495 //\r
496 EfiBootManagerUpdateConsoleVariable (ConIn,\r
497 (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);\r
498\r
499 //\r
500 // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.\r
501 //\r
502 ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);\r
503 CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);\r
504\r
505 EfiBootManagerUpdateConsoleVariable (ConIn,\r
506 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
507 EfiBootManagerUpdateConsoleVariable (ConOut,\r
508 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
509 EfiBootManagerUpdateConsoleVariable (ErrOut,\r
510 (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);\r
511\r
512 //\r
513 // Register platform-specific boot options and keyboard shortcuts.\r
514 //\r
515 PlatformRegisterOptionsAndKeys ();\r
516}\r
517\r
6c4194c9
AB
518#define VERSION_STRING_PREFIX L"Tianocore/EDK2 firmware version "\r
519\r
c976f9cb
AB
520/**\r
521 Do the platform specific action after the console is ready\r
522 Possible things that can be done in PlatformBootManagerAfterConsole:\r
523 > Console post action:\r
524 > Dynamically switch output mode from 100x31 to 80x25 for certain senarino\r
525 > Signal console ready platform customized event\r
526 > Run diagnostics like memory testing\r
527 > Connect certain devices\r
528 > Dispatch aditional option roms\r
529 > Special boot: e.g.: USB boot, enter UI\r
530**/\r
531VOID\r
532EFIAPI\r
533PlatformBootManagerAfterConsole (\r
534 VOID\r
535 )\r
536{\r
13ca0abb
AB
537 ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;\r
538 EFI_STATUS Status;\r
6c4194c9
AB
539 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
540 UINTN FirmwareVerLength;\r
541 UINTN PosX;\r
542 UINTN PosY;\r
543\r
544 FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString));\r
c976f9cb
AB
545\r
546 //\r
547 // Show the splash screen.\r
548 //\r
a43d75e1
AB
549 Status = BootLogoEnableLogo ();\r
550 if (EFI_ERROR (Status)) {\r
6c4194c9
AB
551 if (FirmwareVerLength > 0) {\r
552 Print (VERSION_STRING_PREFIX L"%s",\r
553 PcdGetPtr (PcdFirmwareVersionString));\r
554 }\r
a43d75e1 555 Print (L"Press ESCAPE for boot options ");\r
6c4194c9
AB
556 } else if (FirmwareVerLength > 0) {\r
557 Status = gBS->HandleProtocol (gST->ConsoleOutHandle,\r
558 &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);\r
559 if (!EFI_ERROR (Status)) {\r
560 PosX = (GraphicsOutput->Mode->Info->HorizontalResolution -\r
561 (StrLen (VERSION_STRING_PREFIX) + FirmwareVerLength) *\r
562 EFI_GLYPH_WIDTH) / 2;\r
563 PosY = 0;\r
564\r
565 PrintXY (PosX, PosY, NULL, NULL, VERSION_STRING_PREFIX L"%s",\r
566 PcdGetPtr (PcdFirmwareVersionString));\r
567 }\r
a43d75e1 568 }\r
6c4194c9 569\r
c976f9cb
AB
570 //\r
571 // Connect the rest of the devices.\r
572 //\r
573 EfiBootManagerConnectAll ();\r
574\r
13ca0abb
AB
575 Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL,\r
576 (VOID **)&EsrtManagement);\r
577 if (!EFI_ERROR (Status)) {\r
578 EsrtManagement->SyncEsrtFmp ();\r
579 }\r
580\r
4bbcc285
AB
581 if (GetBootModeHob() == BOOT_ON_FLASH_UPDATE) {\r
582 DEBUG((DEBUG_INFO, "ProcessCapsules After EndOfDxe ......\n"));\r
583 Status = ProcessCapsules ();\r
584 DEBUG((DEBUG_INFO, "ProcessCapsules returned %r\n", Status));\r
585 }\r
586\r
c976f9cb
AB
587 //\r
588 // Enumerate all possible boot options.\r
589 //\r
590 EfiBootManagerRefreshAllBootOption ();\r
591\r
592 //\r
593 // Register UEFI Shell\r
594 //\r
595 PlatformRegisterFvBootOption (\r
07548e17 596 &gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE\r
c976f9cb
AB
597 );\r
598}\r
599\r
600/**\r
601 This function is called each second during the boot manager waits the\r
602 timeout.\r
603\r
604 @param TimeoutRemain The remaining timeout.\r
605**/\r
606VOID\r
607EFIAPI\r
608PlatformBootManagerWaitCallback (\r
609 UINT16 TimeoutRemain\r
610 )\r
611{\r
a43d75e1
AB
612 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
613 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
614 UINT16 Timeout;\r
615 EFI_STATUS Status;\r
616\r
617 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
618\r
619 Black.Raw = 0x00000000;\r
620 White.Raw = 0x00FFFFFF;\r
621\r
622 Status = BootLogoUpdateProgress (\r
623 White.Pixel,\r
624 Black.Pixel,\r
625 L"Press ESCAPE for boot options",\r
626 White.Pixel,\r
627 (Timeout - TimeoutRemain) * 100 / Timeout,\r
628 0\r
629 );\r
630 if (EFI_ERROR (Status)) {\r
631 Print (L".");\r
632 }\r
c976f9cb 633}\r