2 This file include all platform action which can be customized
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "PlatformBootManager.h"
13 EFI_GUID mBootMenuFile
= {
14 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }
18 Perform the platform diagnostic, such like test memory. OEM/IBV also
19 can customize this function to support specific platform diagnostic.
21 @param MemoryTestLevel The memory test intensive level
22 @param QuietBoot Indicate if need to enable the quiet boot
26 PlatformBootManagerDiagnostics (
27 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
34 // Here we can decide if we need to show
35 // the diagnostics screen
36 // Notes: this quiet boot code should be remove
37 // from the graphic lib
40 BootLogoEnableLogo ();
43 // Perform system diagnostic
45 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
46 if (EFI_ERROR (Status
)) {
47 BootLogoDisableLogo ();
54 // Perform system diagnostic
56 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
60 Do the platform specific action before the console is connected.
63 Update console variable;
64 Register new Driver#### or Boot####;
65 Signal ReadyToLock event.
69 PlatformBootManagerBeforeConsole (
75 WIN_NT_SYSTEM_CONFIGURATION
*Configuration
;
77 GetVariable2 (L
"Setup", &gEfiWinNtSystemConfigGuid
, (VOID
**) &Configuration
, NULL
);
78 if (Configuration
!= NULL
) {
80 // SetupVariable is corrupt
82 Configuration
->ConOutRow
= PcdGet32 (PcdConOutColumn
);
83 Configuration
->ConOutColumn
= PcdGet32 (PcdConOutRow
);
85 Status
= gRT
->SetVariable (
87 &gEfiWinNtSystemConfigGuid
,
88 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
89 sizeof (WIN_NT_SYSTEM_CONFIGURATION
),
92 if (EFI_ERROR (Status
)) {
93 DEBUG ((EFI_D_ERROR
, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status
));
95 FreePool (Configuration
);
99 // Update the ocnsole variables.
101 for (Index
= 0; gPlatformConsole
[Index
].DevicePath
!= NULL
; Index
++) {
102 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
103 EfiBootManagerUpdateConsoleVariable (ConIn
, gPlatformConsole
[Index
].DevicePath
, NULL
);
106 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
107 EfiBootManagerUpdateConsoleVariable (ConOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
110 if ((gPlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
111 EfiBootManagerUpdateConsoleVariable (ErrOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
116 // From PI spec vol2:
117 // Prior to invoking any UEFI drivers, applications, or connecting consoles,
118 // the platform should signal the event EFI_END_OF_DXE_EVENT_GUID
120 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
123 // Dispatch deferred images after EndOfDxe event.
125 EfiBootManagerDispatchDeferredImages ();
129 Returns the priority number.
135 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
139 // Make sure Shell is first
141 if (StrCmp (BootOption
->Description
, L
"UEFI Shell") == 0) {
150 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Left
,
151 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Right
154 return BootOptionPriority (Left
) - BootOptionPriority (Right
);
158 Generate device path include the input file guid info.
160 @param FileGuid Input file guid for the BootManagerMenuApp.
162 @retval DevicePath for BootManagerMenuApp.
171 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
172 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
174 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
176 Status
= gBS
->HandleProtocol (
178 &gEfiLoadedImageProtocolGuid
,
179 (VOID
**) &LoadedImage
181 ASSERT_EFI_ERROR (Status
);
183 return AppendDevicePathNode (
184 DevicePathFromHandle (LoadedImage
->DeviceHandle
),
185 (EFI_DEVICE_PATH_PROTOCOL
*) &FileNode
190 Create one boot option for BootManagerMenuApp.
192 @param FileGuid Input file guid for the BootManagerMenuApp.
193 @param Description Description of the BootManagerMenuApp boot option.
194 @param Position Position of the new load option to put in the ****Order variable.
195 @param IsBootCategory Whether this is a boot category.
198 @retval OptionNumber Return the option number info.
202 RegisterBootManagerMenuAppBootOption (
206 BOOLEAN IsBootCategory
210 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
211 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
214 DevicePath
= FvFilePath (FileGuid
);
215 Status
= EfiBootManagerInitializeLoadOption (
217 LoadOptionNumberUnassigned
,
219 IsBootCategory
? LOAD_OPTION_ACTIVE
: LOAD_OPTION_CATEGORY_APP
,
225 ASSERT_EFI_ERROR (Status
);
226 FreePool (DevicePath
);
228 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, Position
);
229 ASSERT_EFI_ERROR (Status
);
231 OptionNumber
= NewOption
.OptionNumber
;
233 EfiBootManagerFreeLoadOption (&NewOption
);
239 Check if it's a Device Path pointing to BootManagerMenuApp.
241 @param DevicePath Input device path.
243 @retval TRUE The device path is BootManagerMenuApp File Device Path.
244 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.
247 IsBootManagerMenuAppFilePath (
248 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
255 Status
= gBS
->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid
, &DevicePath
, &FvHandle
);
256 if (!EFI_ERROR (Status
)) {
257 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) DevicePath
);
258 if (NameGuid
!= NULL
) {
259 return CompareGuid (NameGuid
, &mBootMenuFile
);
267 Return the boot option number to the BootManagerMenuApp.
269 If not found it in the current boot option, create a new one.
271 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.
275 GetBootManagerMenuAppOption (
279 UINTN BootOptionCount
;
280 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
286 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
288 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
289 if (IsBootManagerMenuAppFilePath (BootOptions
[Index
].FilePath
)) {
290 OptionNumber
= BootOptions
[Index
].OptionNumber
;
295 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
297 if (Index
>= BootOptionCount
) {
299 // If not found the BootManagerMenuApp, create it.
301 OptionNumber
= (UINT16
) RegisterBootManagerMenuAppBootOption (&mBootMenuFile
, L
"UEFI BootManagerMenuApp", (UINTN
) -1, FALSE
);
308 Do the platform specific action after the console is connected.
311 Dynamically switch output mode;
312 Signal console ready platform customized event;
313 Run diagnostics like memory testing;
314 Connect certain devices;
315 Dispatch aditional option roms.
319 PlatformBootManagerAfterConsole (
323 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black
;
324 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White
;
328 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
331 Black
.Blue
= Black
.Green
= Black
.Red
= Black
.Reserved
= 0;
332 White
.Blue
= White
.Green
= White
.Red
= White
.Reserved
= 0xFF;
334 EfiBootManagerConnectAll ();
335 EfiBootManagerRefreshAllBootOption ();
338 // Register ENTER as CONTINUE key
340 Enter
.ScanCode
= SCAN_NULL
;
341 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
342 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
344 // Map F2 to Boot Manager Menu
346 F2
.ScanCode
= SCAN_F2
;
347 F2
.UnicodeChar
= CHAR_NULL
;
348 EfiBootManagerGetBootManagerMenu (&BootOption
);
349 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
) BootOption
.OptionNumber
, 0, &F2
, NULL
);
352 // 3. Boot Device List menu
354 F7
.ScanCode
= SCAN_F7
;
355 F7
.UnicodeChar
= CHAR_NULL
;
356 OptionNumber
= GetBootManagerMenuAppOption ();
357 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)OptionNumber
, 0, &F7
, NULL
);
360 // Make Shell as the first boot option
362 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot
, (SORT_COMPARE
) CompareBootOption
);
364 PlatformBootManagerDiagnostics (QUICK
, TRUE
);
366 PrintXY (10, 10, &White
, &Black
, L
"F2 to enter Setup. ");
367 PrintXY (10, 30, &White
, &Black
, L
"F7 to enter Boot Manager Menu.");
368 PrintXY (10, 50, &White
, &Black
, L
"Enter to boot directly.");
372 This function is called each second during the boot manager waits the timeout.
374 @param TimeoutRemain The remaining timeout.
378 PlatformBootManagerWaitCallback (
382 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black
;
383 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White
;
386 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
388 Black
.Raw
= 0x00000000;
389 White
.Raw
= 0x00FFFFFF;
391 BootLogoUpdateProgress (
394 L
"Start boot option",
396 (Timeout
- TimeoutRemain
) * 100 / Timeout
,
402 The function is called when no boot option could be launched,
403 including platform recovery options and options pointing to applications
404 built into firmware volumes.
406 If this function returns, BDS attempts to enter an infinite loop.
410 PlatformBootManagerUnableToBoot (