3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2011, Apple Inc. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "PlatformBm.h"
11 EFI_GUID mBootMenuFile
= {
12 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }
16 Initialize the "Setup" variable.
25 EMU_SYSTEM_CONFIGURATION SystemConfigData
;
27 Size
= sizeof (SystemConfigData
);
28 Status
= gRT
->GetVariable (
30 &gEmuSystemConfigGuid
,
33 (VOID
*) &SystemConfigData
36 if (EFI_ERROR (Status
)) {
38 // SetupVariable is corrupt
40 SystemConfigData
.ConOutRow
= PcdGet32 (PcdConOutColumn
);
41 SystemConfigData
.ConOutColumn
= PcdGet32 (PcdConOutRow
);
43 Status
= gRT
->SetVariable (
45 &gEmuSystemConfigGuid
,
46 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
47 sizeof (SystemConfigData
),
48 (VOID
*) &SystemConfigData
50 if (EFI_ERROR (Status
)) {
51 DEBUG ((DEBUG_ERROR
, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status
));
63 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
64 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
66 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
68 Status
= gBS
->HandleProtocol (
70 &gEfiLoadedImageProtocolGuid
,
71 (VOID
**) &LoadedImage
73 ASSERT_EFI_ERROR (Status
);
74 return AppendDevicePathNode (
75 DevicePathFromHandle (LoadedImage
->DeviceHandle
),
76 (EFI_DEVICE_PATH_PROTOCOL
*) &FileNode
81 Create one boot option for BootManagerMenuApp.
83 @param FileGuid Input file guid for the BootManagerMenuApp.
84 @param Description Description of the BootManagerMenuApp boot option.
85 @param Position Position of the new load option to put in the ****Order variable.
86 @param IsBootCategory Whether this is a boot category.
89 @retval OptionNumber Return the option number info.
93 RegisterBootManagerMenuAppBootOption (
97 BOOLEAN IsBootCategory
101 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
102 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
105 DevicePath
= FvFilePath (FileGuid
);
106 Status
= EfiBootManagerInitializeLoadOption (
108 LoadOptionNumberUnassigned
,
110 IsBootCategory
? LOAD_OPTION_ACTIVE
: LOAD_OPTION_CATEGORY_APP
,
116 ASSERT_EFI_ERROR (Status
);
117 FreePool (DevicePath
);
119 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, Position
);
120 ASSERT_EFI_ERROR (Status
);
122 OptionNumber
= NewOption
.OptionNumber
;
124 EfiBootManagerFreeLoadOption (&NewOption
);
130 Check if it's a Device Path pointing to BootManagerMenuApp.
132 @param DevicePath Input device path.
134 @retval TRUE The device path is BootManagerMenuApp File Device Path.
135 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.
138 IsBootManagerMenuAppFilePath (
139 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
146 Status
= gBS
->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid
, &DevicePath
, &FvHandle
);
147 if (!EFI_ERROR (Status
)) {
148 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) DevicePath
);
149 if (NameGuid
!= NULL
) {
150 return CompareGuid (NameGuid
, &mBootMenuFile
);
158 Return the boot option number to the BootManagerMenuApp.
160 If not found it in the current boot option, create a new one.
162 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.
166 GetBootManagerMenuAppOption (
170 UINTN BootOptionCount
;
171 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
177 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
179 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
180 if (IsBootManagerMenuAppFilePath (BootOptions
[Index
].FilePath
)) {
181 OptionNumber
= BootOptions
[Index
].OptionNumber
;
186 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
188 if (Index
>= BootOptionCount
) {
190 // If not found the BootManagerMenuApp, create it.
192 OptionNumber
= (UINT16
) RegisterBootManagerMenuAppBootOption (&mBootMenuFile
, L
"UEFI BootManagerMenuApp", (UINTN
) -1, FALSE
);
199 Platform Bds init. Include the platform firmware vendor, revision
204 PlatformBootManagerBeforeConsole (
210 SetupVariableInit ();
212 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
215 while (gPlatformConsole
[Index
].DevicePath
!= NULL
) {
217 // Update the console variable with the connect type
219 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
220 EfiBootManagerUpdateConsoleVariable (ConIn
, gPlatformConsole
[Index
].DevicePath
, NULL
);
223 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
224 EfiBootManagerUpdateConsoleVariable (ConOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
227 if ((gPlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
228 EfiBootManagerUpdateConsoleVariable (ErrOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
236 Connect with predefined platform connect sequence,
237 the OEM/IBV can customize with their own connect sequence.
240 PlatformBdsConnectSequence (
245 // Just use the simple policy to connect all devices
247 EfiBootManagerConnectAll ();
251 Perform the platform diagnostic, such like test memory. OEM/IBV also
252 can customize this fuction to support specific platform diagnostic.
254 @param MemoryTestLevel The memory test intensive level
255 @param QuietBoot Indicate if need to enable the quiet boot
258 PlatformBdsDiagnostics (
259 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
266 // Here we can decide if we need to show
267 // the diagnostics screen
270 BootLogoEnableLogo ();
273 // Perform system diagnostic
275 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
276 if (EFI_ERROR (Status
)) {
277 BootLogoDisableLogo ();
284 // Perform system diagnostic
286 PlatformBootManagerMemoryTest (MemoryTestLevel
);
290 Register the static boot options.
293 PlatformBdsRegisterStaticBootOptions (
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black
;
298 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White
;
302 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
305 Black
.Blue
= Black
.Green
= Black
.Red
= Black
.Reserved
= 0;
306 White
.Blue
= White
.Green
= White
.Red
= White
.Reserved
= 0xFF;
309 // Register ENTER as CONTINUE key
311 Enter
.ScanCode
= SCAN_NULL
;
312 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
313 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
315 // Map F2 to Boot Manager Menu
317 F2
.ScanCode
= SCAN_F2
;
318 F2
.UnicodeChar
= CHAR_NULL
;
319 EfiBootManagerGetBootManagerMenu (&BootOption
);
320 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
) BootOption
.OptionNumber
, 0, &F2
, NULL
);
323 // 3. Boot Device List menu
325 F7
.ScanCode
= SCAN_F7
;
326 F7
.UnicodeChar
= CHAR_NULL
;
327 OptionNumber
= GetBootManagerMenuAppOption ();
328 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)OptionNumber
, 0, &F7
, NULL
);
330 PrintXY (10, 10, &White
, &Black
, L
"F2 to enter Setup. ");
331 PrintXY (10, 30, &White
, &Black
, L
"F7 to enter Boot Manager Menu.");
332 PrintXY (10, 50, &White
, &Black
, L
"Enter to boot directly.");
336 Returns the priority number.
342 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
346 // Make sure Shell is first
348 if (StrCmp (BootOption
->Description
, L
"UEFI Shell") == 0) {
357 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Left
,
358 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Right
361 return BootOptionPriority (Left
) - BootOptionPriority (Right
);
365 Do the platform specific action after the console is connected.
368 Dynamically switch output mode;
369 Signal console ready platform customized event;
370 Run diagnostics like memory testing;
371 Connect certain devices;
372 Dispatch aditional option roms.
376 PlatformBootManagerAfterConsole (
382 // Go the different platform policy with different boot mode
383 // Notes: this part code can be change with the table policy
385 switch (GetBootModeHob ()) {
387 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
388 case BOOT_WITH_MINIMAL_CONFIGURATION
:
389 PlatformBdsDiagnostics (IGNORE
, TRUE
);
392 // Perform some platform specific connect sequence
394 PlatformBdsConnectSequence ();
397 case BOOT_IN_RECOVERY_MODE
:
398 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
);
401 case BOOT_WITH_FULL_CONFIGURATION
:
402 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
403 case BOOT_WITH_DEFAULT_SETTINGS
:
405 PlatformBdsDiagnostics (IGNORE
, TRUE
);
406 PlatformBdsRegisterStaticBootOptions ();
407 PlatformBdsConnectSequence ();
408 EfiBootManagerRefreshAllBootOption ();
409 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot
, (SORT_COMPARE
)CompareBootOption
);
415 This function is called each second during the boot manager waits the timeout.
417 @param TimeoutRemain The remaining timeout.
421 PlatformBootManagerWaitCallback (
425 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black
;
426 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White
;
429 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
431 Black
.Raw
= 0x00000000;
432 White
.Raw
= 0x00FFFFFF;
434 BootLogoUpdateProgress (
437 L
"Start boot option",
439 (Timeout
- TimeoutRemain
) * 100 / Timeout
,
445 The function is called when no boot option could be launched,
446 including platform recovery options and options pointing to applications
447 built into firmware volumes.
449 If this function returns, BDS attempts to enter an infinite loop.
453 PlatformBootManagerUnableToBoot (