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