]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
Nt32Pkg: Fix VS2010/VS2012 build failure
[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
e9fec732
DB
277 OptionNumber = 0;\r
278\r
0b6dc68d
ED
279 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
280\r
281 for (Index = 0; Index < BootOptionCount; Index++) {\r
282 if (IsBootManagerMenuAppFilePath (BootOptions[Index].FilePath)) {\r
283 OptionNumber = BootOptions[Index].OptionNumber;\r
284 break;\r
285 }\r
286 }\r
287\r
288 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
289\r
290 if (Index >= BootOptionCount) {\r
291 //\r
292 // If not found the BootManagerMenuApp, create it.\r
293 //\r
294 OptionNumber = (UINT16) RegisterBootManagerMenuAppBootOption (&mBootMenuFile, L"UEFI BootManagerMenuApp", (UINTN) -1, FALSE);\r
295 }\r
296\r
297 return OptionNumber;\r
298}\r
299\r
123e9f62
RN
300/**\r
301 Do the platform specific action after the console is connected.\r
302\r
303 Such as:\r
304 Dynamically switch output mode;\r
305 Signal console ready platform customized event;\r
306 Run diagnostics like memory testing;\r
307 Connect certain devices;\r
308 Dispatch aditional option roms.\r
309**/\r
310VOID\r
311EFIAPI\r
312PlatformBootManagerAfterConsole (\r
313 VOID\r
314 )\r
315{\r
703da8b4
RN
316 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
317 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;\r
e2e9b3b4
LG
318 EFI_INPUT_KEY Enter;\r
319 EFI_INPUT_KEY F2;\r
0b6dc68d 320 EFI_INPUT_KEY F7;\r
e2e9b3b4 321 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
0b6dc68d 322 UINTN OptionNumber;\r
703da8b4
RN
323\r
324 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;\r
325 White.Blue = White.Green = White.Red = White.Reserved = 0xFF;\r
326\r
99eda885
ED
327 EfiBootManagerConnectAll ();\r
328 EfiBootManagerRefreshAllBootOption ();\r
703da8b4 329\r
e2e9b3b4
LG
330 //\r
331 // Register ENTER as CONTINUE key\r
332 //\r
333 Enter.ScanCode = SCAN_NULL;\r
334 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
335 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
336 //\r
337 // Map F2 to Boot Manager Menu\r
338 //\r
339 F2.ScanCode = SCAN_F2;\r
340 F2.UnicodeChar = CHAR_NULL;\r
341 EfiBootManagerGetBootManagerMenu (&BootOption);\r
342 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
343\r
0b6dc68d
ED
344 //\r
345 // 3. Boot Device List menu\r
346 //\r
347 F7.ScanCode = SCAN_F7;\r
348 F7.UnicodeChar = CHAR_NULL;\r
349 OptionNumber = GetBootManagerMenuAppOption ();\r
350 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)OptionNumber, 0, &F7, NULL);\r
351\r
3d8fab57
LG
352 //\r
353 // Make Shell as the first boot option\r
354 //\r
355 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, (SORT_COMPARE) CompareBootOption);\r
356\r
703da8b4 357 PlatformBootManagerDiagnostics (QUICK, TRUE);\r
0b6dc68d
ED
358\r
359 PrintXY (10, 10, &White, &Black, L"F2 to enter Setup. ");\r
360 PrintXY (10, 30, &White, &Black, L"F7 to enter Boot Manager Menu.");\r
361 PrintXY (10, 50, &White, &Black, L"Enter to boot directly.");\r
123e9f62
RN
362}\r
363\r
364/**\r
365 This function is called each second during the boot manager waits the timeout.\r
366\r
367 @param TimeoutRemain The remaining timeout.\r
368**/\r
369VOID\r
370EFIAPI\r
371PlatformBootManagerWaitCallback (\r
372 UINT16 TimeoutRemain\r
373 )\r
374{\r
ef3216eb
LE
375 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
376 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
377 UINT16 Timeout;\r
703da8b4
RN
378\r
379 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
380\r
ef3216eb
LE
381 Black.Raw = 0x00000000;\r
382 White.Raw = 0x00FFFFFF;\r
703da8b4 383\r
859e75c4 384 BootLogoUpdateProgress (\r
ef3216eb
LE
385 White.Pixel,\r
386 Black.Pixel,\r
703da8b4 387 L"Start boot option",\r
ef3216eb 388 White.Pixel,\r
703da8b4
RN
389 (Timeout - TimeoutRemain) * 100 / Timeout,\r
390 0\r
391 );\r
123e9f62 392}\r