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
));
62 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
63 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
65 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
67 Status
= gBS
->HandleProtocol (
69 &gEfiLoadedImageProtocolGuid
,
72 ASSERT_EFI_ERROR (Status
);
73 return AppendDevicePathNode (
74 DevicePathFromHandle (LoadedImage
->DeviceHandle
),
75 (EFI_DEVICE_PATH_PROTOCOL
*)&FileNode
80 Create one boot option for BootManagerMenuApp.
82 @param FileGuid Input file guid for the BootManagerMenuApp.
83 @param Description Description of the BootManagerMenuApp boot option.
84 @param Position Position of the new load option to put in the ****Order variable.
85 @param IsBootCategory Whether this is a boot category.
88 @retval OptionNumber Return the option number info.
92 RegisterBootManagerMenuAppBootOption (
96 BOOLEAN IsBootCategory
100 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
101 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
104 DevicePath
= FvFilePath (FileGuid
);
105 Status
= EfiBootManagerInitializeLoadOption (
107 LoadOptionNumberUnassigned
,
109 IsBootCategory
? LOAD_OPTION_ACTIVE
: LOAD_OPTION_CATEGORY_APP
,
115 ASSERT_EFI_ERROR (Status
);
116 FreePool (DevicePath
);
118 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, Position
);
119 ASSERT_EFI_ERROR (Status
);
121 OptionNumber
= NewOption
.OptionNumber
;
123 EfiBootManagerFreeLoadOption (&NewOption
);
129 Check if it's a Device Path pointing to BootManagerMenuApp.
131 @param DevicePath Input device path.
133 @retval TRUE The device path is BootManagerMenuApp File Device Path.
134 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.
137 IsBootManagerMenuAppFilePath (
138 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
145 Status
= gBS
->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid
, &DevicePath
, &FvHandle
);
146 if (!EFI_ERROR (Status
)) {
147 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)DevicePath
);
148 if (NameGuid
!= NULL
) {
149 return CompareGuid (NameGuid
, &mBootMenuFile
);
157 Return the boot option number to the BootManagerMenuApp.
159 If not found it in the current boot option, create a new one.
161 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.
165 GetBootManagerMenuAppOption (
169 UINTN BootOptionCount
;
170 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
176 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
178 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
179 if (IsBootManagerMenuAppFilePath (BootOptions
[Index
].FilePath
)) {
180 OptionNumber
= BootOptions
[Index
].OptionNumber
;
185 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
187 if (Index
>= BootOptionCount
) {
189 // If not found the BootManagerMenuApp, create it.
191 OptionNumber
= (UINT16
)RegisterBootManagerMenuAppBootOption (&mBootMenuFile
, L
"UEFI BootManagerMenuApp", (UINTN
)-1, FALSE
);
198 Platform Bds init. Include the platform firmware vendor, revision
203 PlatformBootManagerBeforeConsole (
209 SetupVariableInit ();
211 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
214 while (gPlatformConsole
[Index
].DevicePath
!= NULL
) {
216 // Update the console variable with the connect type
218 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
219 EfiBootManagerUpdateConsoleVariable (ConIn
, gPlatformConsole
[Index
].DevicePath
, NULL
);
222 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
223 EfiBootManagerUpdateConsoleVariable (ConOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
226 if ((gPlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
227 EfiBootManagerUpdateConsoleVariable (ErrOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
235 Connect with predefined platform connect sequence,
236 the OEM/IBV can customize with their own connect sequence.
239 PlatformBdsConnectSequence (
244 // Just use the simple policy to connect all devices
246 EfiBootManagerConnectAll ();
250 Perform the platform diagnostic, such like test memory. OEM/IBV also
251 can customize this fuction to support specific platform diagnostic.
253 @param MemoryTestLevel The memory test intensive level
254 @param QuietBoot Indicate if need to enable the quiet boot
257 PlatformBdsDiagnostics (
258 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
265 // Here we can decide if we need to show
266 // the diagnostics screen
269 BootLogoEnableLogo ();
272 // Perform system diagnostic
274 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
275 if (EFI_ERROR (Status
)) {
276 BootLogoDisableLogo ();
283 // Perform system diagnostic
285 PlatformBootManagerMemoryTest (MemoryTestLevel
);
289 Register the static boot options.
292 PlatformBdsRegisterStaticBootOptions (
296 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black
;
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White
;
301 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
304 Black
.Blue
= Black
.Green
= Black
.Red
= Black
.Reserved
= 0;
305 White
.Blue
= White
.Green
= White
.Red
= White
.Reserved
= 0xFF;
308 // Register ENTER as CONTINUE key
310 Enter
.ScanCode
= SCAN_NULL
;
311 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
312 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
314 // Map F2 to Boot Manager Menu
316 F2
.ScanCode
= SCAN_F2
;
317 F2
.UnicodeChar
= CHAR_NULL
;
318 EfiBootManagerGetBootManagerMenu (&BootOption
);
319 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)BootOption
.OptionNumber
, 0, &F2
, NULL
);
322 // 3. Boot Device List menu
324 F7
.ScanCode
= SCAN_F7
;
325 F7
.UnicodeChar
= CHAR_NULL
;
326 OptionNumber
= GetBootManagerMenuAppOption ();
327 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)OptionNumber
, 0, &F7
, NULL
);
329 PrintXY (10, 10, &White
, &Black
, L
"F2 to enter Setup. ");
330 PrintXY (10, 30, &White
, &Black
, L
"F7 to enter Boot Manager Menu.");
331 PrintXY (10, 50, &White
, &Black
, L
"Enter to boot directly.");
335 Returns the priority number.
341 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
345 // Make sure Shell is first
347 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 (
381 // Go the different platform policy with different boot mode
382 // Notes: this part code can be change with the table policy
384 switch (GetBootModeHob ()) {
385 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
386 case BOOT_WITH_MINIMAL_CONFIGURATION
:
387 PlatformBdsDiagnostics (IGNORE
, TRUE
);
390 // Perform some platform specific connect sequence
392 PlatformBdsConnectSequence ();
395 case BOOT_IN_RECOVERY_MODE
:
396 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
);
399 case BOOT_WITH_FULL_CONFIGURATION
:
400 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
401 case BOOT_WITH_DEFAULT_SETTINGS
:
403 PlatformBdsDiagnostics (IGNORE
, TRUE
);
404 PlatformBdsRegisterStaticBootOptions ();
405 PlatformBdsConnectSequence ();
406 EfiBootManagerRefreshAllBootOption ();
407 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot
, (SORT_COMPARE
)CompareBootOption
);
413 This function is called each second during the boot manager waits the timeout.
415 @param TimeoutRemain The remaining timeout.
419 PlatformBootManagerWaitCallback (
423 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black
;
424 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White
;
427 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
429 Black
.Raw
= 0x00000000;
430 White
.Raw
= 0x00FFFFFF;
432 BootLogoUpdateProgress (
435 L
"Start boot option",
437 (Timeout
- TimeoutRemain
) * 100 / Timeout
,
443 The function is called when no boot option could be launched,
444 including platform recovery options and options pointing to applications
445 built into firmware volumes.
447 If this function returns, BDS attempts to enter an infinite loop.
451 PlatformBootManagerUnableToBoot (