]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
QuarkPlatformPkg/PlatformBds: Dispatch deferred images after EndOfDxe
[mirror_edk2.git] / Nt32Pkg / Library / PlatformBootManagerLib / PlatformBootManager.c
CommitLineData
123e9f62
RN
1/** @file\r
2 This file include all platform action which can be customized\r
3 by IBV/OEM.\r
4\r
62936ada 5Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
cf814093 6(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
123e9f62
RN
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "PlatformBootManager.h"\r
18\r
0b6dc68d
ED
19EFI_GUID mBootMenuFile = {\r
20 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }\r
21};\r
22\r
8f227c2f 23/**\r
703da8b4
RN
24 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
25 can customize this function to support specific platform diagnostic.\r
8f227c2f 26\r
703da8b4
RN
27 @param MemoryTestLevel The memory test intensive level\r
28 @param QuietBoot Indicate if need to enable the quiet boot\r
8f227c2f
RN
29\r
30**/\r
703da8b4
RN
31VOID\r
32PlatformBootManagerDiagnostics (\r
33 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
34 IN BOOLEAN QuietBoot\r
8f227c2f
RN
35 )\r
36{\r
703da8b4
RN
37 EFI_STATUS Status;\r
38\r
39 //\r
40 // Here we can decide if we need to show\r
41 // the diagnostics screen\r
42 // Notes: this quiet boot code should be remove\r
43 // from the graphic lib\r
44 //\r
45 if (QuietBoot) {\r
67ce479a 46 BootLogoEnableLogo ();\r
8f227c2f 47\r
8f227c2f 48 //\r
703da8b4 49 // Perform system diagnostic\r
8f227c2f 50 //\r
703da8b4
RN
51 Status = PlatformBootManagerMemoryTest (MemoryTestLevel);\r
52 if (EFI_ERROR (Status)) {\r
859e75c4 53 BootLogoDisableLogo ();\r
8f227c2f 54 }\r
8f227c2f 55\r
703da8b4
RN
56 return;\r
57 }\r
8f227c2f 58\r
703da8b4
RN
59 //\r
60 // Perform system diagnostic\r
61 //\r
62 Status = PlatformBootManagerMemoryTest (MemoryTestLevel);\r
8f227c2f
RN
63}\r
64\r
123e9f62
RN
65/**\r
66 Do the platform specific action before the console is connected.\r
67\r
68 Such as:\r
69 Update console variable;\r
70 Register new Driver#### or Boot####;\r
71 Signal ReadyToLock event.\r
72**/\r
73VOID\r
74EFIAPI\r
75PlatformBootManagerBeforeConsole (\r
76 VOID\r
77 )\r
78{\r
79 UINTN Index;\r
80 EFI_STATUS Status;\r
81 WIN_NT_SYSTEM_CONFIGURATION *Configuration;\r
123e9f62
RN
82\r
83 GetVariable2 (L"Setup", &gEfiWinNtSystemConfigGuid, (VOID **) &Configuration, NULL);\r
84 if (Configuration != NULL) {\r
85 //\r
86 // SetupVariable is corrupt\r
87 //\r
88 Configuration->ConOutRow = PcdGet32 (PcdConOutColumn);\r
89 Configuration->ConOutColumn = PcdGet32 (PcdConOutRow);\r
90\r
91 Status = gRT->SetVariable (\r
92 L"Setup",\r
93 &gEfiWinNtSystemConfigGuid,\r
94 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
95 sizeof (WIN_NT_SYSTEM_CONFIGURATION),\r
96 Configuration\r
97 );\r
98 if (EFI_ERROR (Status)) {\r
99 DEBUG ((EFI_D_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status));\r
100 }\r
101 FreePool (Configuration);\r
102 }\r
103\r
104 //\r
105 // Update the ocnsole variables.\r
106 //\r
107 for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {\r
108 if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
109 EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);\r
110 }\r
111\r
112 if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
113 EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);\r
114 }\r
115\r
116 if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
117 EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);\r
118 }\r
119 }\r
cf814093
CS
120\r
121 //\r
122 // From PI spec vol2:\r
123 // Prior to invoking any UEFI drivers, applications, or connecting consoles, \r
124 // the platform should signal the event EFI_END_OF_DXE_EVENT_GUID\r
125 //\r
126 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
123e9f62
RN
127}\r
128\r
3d8fab57
LG
129/**\r
130 Returns the priority number.\r
131\r
132 @param BootOption\r
133**/\r
134UINTN\r
135BootOptionPriority (\r
136 CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption\r
137 )\r
138{\r
139 //\r
140 // Make sure Shell is first\r
141 //\r
142 if (StrCmp (BootOption->Description, L"UEFI Shell") == 0) {\r
143 return 0;\r
144 }\r
145 return 100;\r
146}\r
147\r
148INTN\r
149EFIAPI\r
150CompareBootOption (\r
151 CONST EFI_BOOT_MANAGER_LOAD_OPTION *Left,\r
152 CONST EFI_BOOT_MANAGER_LOAD_OPTION *Right\r
153 )\r
154{\r
155 return BootOptionPriority (Left) - BootOptionPriority (Right);\r
156}\r
157\r
0b6dc68d
ED
158/**\r
159 Generate device path include the input file guid info.\r
160\r
161 @param FileGuid Input file guid for the BootManagerMenuApp.\r
162\r
163 @retval DevicePath for BootManagerMenuApp.\r
164**/\r
165EFI_DEVICE_PATH *\r
166FvFilePath (\r
167 EFI_GUID *FileGuid\r
168 )\r
169{\r
170\r
171 EFI_STATUS Status;\r
172 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
173 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
174\r
175 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
176\r
177 Status = gBS->HandleProtocol (\r
178 gImageHandle,\r
179 &gEfiLoadedImageProtocolGuid,\r
180 (VOID **) &LoadedImage\r
181 );\r
182 ASSERT_EFI_ERROR (Status);\r
183\r
184 return AppendDevicePathNode (\r
185 DevicePathFromHandle (LoadedImage->DeviceHandle),\r
186 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
187 );\r
188}\r
189\r
190/**\r
191 Create one boot option for BootManagerMenuApp.\r
192\r
193 @param FileGuid Input file guid for the BootManagerMenuApp.\r
194 @param Description Description of the BootManagerMenuApp boot option.\r
195 @param Position Position of the new load option to put in the ****Order variable.\r
196 @param IsBootCategory Whether this is a boot category.\r
197\r
198\r
199 @retval OptionNumber Return the option number info.\r
200\r
201**/\r
202UINTN\r
203RegisterBootManagerMenuAppBootOption (\r
204 EFI_GUID *FileGuid,\r
205 CHAR16 *Description,\r
206 UINTN Position,\r
207 BOOLEAN IsBootCategory\r
208 )\r
209{\r
210 EFI_STATUS Status;\r
211 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
212 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
213 UINTN OptionNumber;\r
214\r
215 DevicePath = FvFilePath (FileGuid);\r
216 Status = EfiBootManagerInitializeLoadOption (\r
217 &NewOption,\r
218 LoadOptionNumberUnassigned,\r
219 LoadOptionTypeBoot,\r
220 IsBootCategory ? LOAD_OPTION_ACTIVE : LOAD_OPTION_CATEGORY_APP,\r
221 Description,\r
222 DevicePath,\r
223 NULL,\r
224 0\r
225 );\r
226 ASSERT_EFI_ERROR (Status);\r
227 FreePool (DevicePath);\r
228\r
229 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position);\r
230 ASSERT_EFI_ERROR (Status);\r
231\r
232 OptionNumber = NewOption.OptionNumber;\r
233\r
234 EfiBootManagerFreeLoadOption (&NewOption);\r
235\r
236 return OptionNumber;\r
237}\r
238\r
239/**\r
240 Check if it's a Device Path pointing to BootManagerMenuApp.\r
241\r
242 @param DevicePath Input device path.\r
243\r
244 @retval TRUE The device path is BootManagerMenuApp File Device Path.\r
245 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.\r
246**/\r
247BOOLEAN\r
248IsBootManagerMenuAppFilePath (\r
249 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
250)\r
251{\r
252 EFI_HANDLE FvHandle;\r
253 VOID *NameGuid;\r
254 EFI_STATUS Status;\r
255\r
256 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle);\r
257 if (!EFI_ERROR (Status)) {\r
258 NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);\r
259 if (NameGuid != NULL) {\r
260 return CompareGuid (NameGuid, &mBootMenuFile);\r
261 }\r
262 }\r
263\r
264 return FALSE;\r
265}\r
266\r
267/**\r
268 Return the boot option number to the BootManagerMenuApp.\r
269\r
270 If not found it in the current boot option, create a new one.\r
271\r
272 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.\r
273\r
274**/\r
275UINTN\r
276GetBootManagerMenuAppOption (\r
277 VOID\r
278 )\r
279{\r
280 UINTN BootOptionCount;\r
281 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
282 UINTN Index;\r
283 UINTN OptionNumber;\r
284\r
e9fec732
DB
285 OptionNumber = 0;\r
286\r
0b6dc68d
ED
287 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
288\r
289 for (Index = 0; Index < BootOptionCount; Index++) {\r
290 if (IsBootManagerMenuAppFilePath (BootOptions[Index].FilePath)) {\r
291 OptionNumber = BootOptions[Index].OptionNumber;\r
292 break;\r
293 }\r
294 }\r
295\r
296 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
297\r
298 if (Index >= BootOptionCount) {\r
299 //\r
300 // If not found the BootManagerMenuApp, create it.\r
301 //\r
302 OptionNumber = (UINT16) RegisterBootManagerMenuAppBootOption (&mBootMenuFile, L"UEFI BootManagerMenuApp", (UINTN) -1, FALSE);\r
303 }\r
304\r
305 return OptionNumber;\r
306}\r
307\r
123e9f62
RN
308/**\r
309 Do the platform specific action after the console is connected.\r
310\r
311 Such as:\r
312 Dynamically switch output mode;\r
313 Signal console ready platform customized event;\r
314 Run diagnostics like memory testing;\r
315 Connect certain devices;\r
316 Dispatch aditional option roms.\r
317**/\r
318VOID\r
319EFIAPI\r
320PlatformBootManagerAfterConsole (\r
321 VOID\r
322 )\r
323{\r
703da8b4
RN
324 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
325 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;\r
e2e9b3b4
LG
326 EFI_INPUT_KEY Enter;\r
327 EFI_INPUT_KEY F2;\r
0b6dc68d 328 EFI_INPUT_KEY F7;\r
e2e9b3b4 329 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
0b6dc68d 330 UINTN OptionNumber;\r
703da8b4
RN
331\r
332 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;\r
333 White.Blue = White.Green = White.Red = White.Reserved = 0xFF;\r
334\r
99eda885
ED
335 EfiBootManagerConnectAll ();\r
336 EfiBootManagerRefreshAllBootOption ();\r
703da8b4 337\r
e2e9b3b4
LG
338 //\r
339 // Register ENTER as CONTINUE key\r
340 //\r
341 Enter.ScanCode = SCAN_NULL;\r
342 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
343 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
344 //\r
345 // Map F2 to Boot Manager Menu\r
346 //\r
347 F2.ScanCode = SCAN_F2;\r
348 F2.UnicodeChar = CHAR_NULL;\r
349 EfiBootManagerGetBootManagerMenu (&BootOption);\r
350 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
351\r
0b6dc68d
ED
352 //\r
353 // 3. Boot Device List menu\r
354 //\r
355 F7.ScanCode = SCAN_F7;\r
356 F7.UnicodeChar = CHAR_NULL;\r
357 OptionNumber = GetBootManagerMenuAppOption ();\r
358 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)OptionNumber, 0, &F7, NULL);\r
359\r
3d8fab57
LG
360 //\r
361 // Make Shell as the first boot option\r
362 //\r
363 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, (SORT_COMPARE) CompareBootOption);\r
364\r
703da8b4 365 PlatformBootManagerDiagnostics (QUICK, TRUE);\r
0b6dc68d
ED
366\r
367 PrintXY (10, 10, &White, &Black, L"F2 to enter Setup. ");\r
368 PrintXY (10, 30, &White, &Black, L"F7 to enter Boot Manager Menu.");\r
369 PrintXY (10, 50, &White, &Black, L"Enter to boot directly.");\r
123e9f62
RN
370}\r
371\r
372/**\r
373 This function is called each second during the boot manager waits the timeout.\r
374\r
375 @param TimeoutRemain The remaining timeout.\r
376**/\r
377VOID\r
378EFIAPI\r
379PlatformBootManagerWaitCallback (\r
380 UINT16 TimeoutRemain\r
381 )\r
382{\r
ef3216eb
LE
383 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
384 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
385 UINT16 Timeout;\r
703da8b4
RN
386\r
387 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
388\r
ef3216eb
LE
389 Black.Raw = 0x00000000;\r
390 White.Raw = 0x00FFFFFF;\r
703da8b4 391\r
859e75c4 392 BootLogoUpdateProgress (\r
ef3216eb
LE
393 White.Pixel,\r
394 Black.Pixel,\r
703da8b4 395 L"Start boot option",\r
ef3216eb 396 White.Pixel,\r
703da8b4
RN
397 (Timeout - TimeoutRemain) * 100 / Timeout,\r
398 0\r
399 );\r
123e9f62 400}\r