]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Library/PlatformBmLib/PlatformBm.c
EmulatorPkg: Change the cpu frequency to a non-zero value
[mirror_edk2.git] / EmulatorPkg / Library / PlatformBmLib / PlatformBm.c
CommitLineData
e0123894
RN
1/*++ @file\r
2\r
3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
4Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
e3ba31da 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
e0123894
RN
6\r
7**/\r
8\r
9#include "PlatformBm.h"\r
10\r
11EFI_GUID mBootMenuFile = {\r
12 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }\r
13};\r
14\r
15/**\r
16 Initialize the "Setup" variable.\r
17**/\r
18VOID\r
19SetupVariableInit (\r
20 VOID\r
21 )\r
22{\r
23 EFI_STATUS Status;\r
24 UINTN Size;\r
25 EMU_SYSTEM_CONFIGURATION SystemConfigData;\r
26\r
27 Size = sizeof (SystemConfigData);\r
28 Status = gRT->GetVariable (\r
29 L"Setup",\r
30 &gEmuSystemConfigGuid,\r
31 NULL,\r
32 &Size,\r
33 (VOID *) &SystemConfigData\r
34 );\r
35\r
36 if (EFI_ERROR (Status)) {\r
37 //\r
38 // SetupVariable is corrupt\r
39 //\r
40 SystemConfigData.ConOutRow = PcdGet32 (PcdConOutColumn);\r
41 SystemConfigData.ConOutColumn = PcdGet32 (PcdConOutRow);\r
42\r
43 Status = gRT->SetVariable (\r
44 L"Setup",\r
45 &gEmuSystemConfigGuid,\r
46 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
47 sizeof (SystemConfigData),\r
48 (VOID *) &SystemConfigData\r
49 );\r
50 if (EFI_ERROR (Status)) {\r
51 DEBUG ((DEBUG_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status));\r
52 }\r
53 }\r
54}\r
55\r
56EFI_DEVICE_PATH *\r
57FvFilePath (\r
58 EFI_GUID *FileGuid\r
59 )\r
60{\r
61\r
62 EFI_STATUS Status;\r
63 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
64 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
65\r
66 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
67\r
68 Status = gBS->HandleProtocol (\r
69 gImageHandle,\r
70 &gEfiLoadedImageProtocolGuid,\r
71 (VOID **) &LoadedImage\r
72 );\r
73 ASSERT_EFI_ERROR (Status);\r
74 return AppendDevicePathNode (\r
75 DevicePathFromHandle (LoadedImage->DeviceHandle),\r
76 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
77 );\r
78}\r
79\r
80/**\r
81 Create one boot option for BootManagerMenuApp.\r
82\r
83 @param FileGuid Input file guid for the BootManagerMenuApp.\r
84 @param Description Description of the BootManagerMenuApp boot option.\r
85 @param Position Position of the new load option to put in the ****Order variable.\r
86 @param IsBootCategory Whether this is a boot category.\r
87\r
88\r
89 @retval OptionNumber Return the option number info.\r
90\r
91**/\r
92UINTN\r
93RegisterBootManagerMenuAppBootOption (\r
94 EFI_GUID *FileGuid,\r
95 CHAR16 *Description,\r
96 UINTN Position,\r
97 BOOLEAN IsBootCategory\r
98 )\r
99{\r
100 EFI_STATUS Status;\r
101 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
102 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
103 UINTN OptionNumber;\r
104\r
105 DevicePath = FvFilePath (FileGuid);\r
106 Status = EfiBootManagerInitializeLoadOption (\r
107 &NewOption,\r
108 LoadOptionNumberUnassigned,\r
109 LoadOptionTypeBoot,\r
110 IsBootCategory ? LOAD_OPTION_ACTIVE : LOAD_OPTION_CATEGORY_APP,\r
111 Description,\r
112 DevicePath,\r
113 NULL,\r
114 0\r
115 );\r
116 ASSERT_EFI_ERROR (Status);\r
117 FreePool (DevicePath);\r
118\r
119 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position);\r
120 ASSERT_EFI_ERROR (Status);\r
121\r
122 OptionNumber = NewOption.OptionNumber;\r
123\r
124 EfiBootManagerFreeLoadOption (&NewOption);\r
125\r
126 return OptionNumber;\r
127}\r
128\r
129/**\r
130 Check if it's a Device Path pointing to BootManagerMenuApp.\r
131\r
132 @param DevicePath Input device path.\r
133\r
134 @retval TRUE The device path is BootManagerMenuApp File Device Path.\r
135 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.\r
136**/\r
137BOOLEAN\r
138IsBootManagerMenuAppFilePath (\r
139 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
140)\r
141{\r
142 EFI_HANDLE FvHandle;\r
143 VOID *NameGuid;\r
144 EFI_STATUS Status;\r
145\r
146 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle);\r
147 if (!EFI_ERROR (Status)) {\r
148 NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);\r
149 if (NameGuid != NULL) {\r
150 return CompareGuid (NameGuid, &mBootMenuFile);\r
151 }\r
152 }\r
153\r
154 return FALSE;\r
155}\r
156\r
157/**\r
158 Return the boot option number to the BootManagerMenuApp.\r
159\r
160 If not found it in the current boot option, create a new one.\r
161\r
162 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.\r
163\r
164**/\r
165UINTN\r
166GetBootManagerMenuAppOption (\r
167 VOID\r
168 )\r
169{\r
170 UINTN BootOptionCount;\r
171 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
172 UINTN Index;\r
173 UINTN OptionNumber;\r
174\r
175 OptionNumber = 0;\r
176\r
177 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
178\r
179 for (Index = 0; Index < BootOptionCount; Index++) {\r
180 if (IsBootManagerMenuAppFilePath (BootOptions[Index].FilePath)) {\r
181 OptionNumber = BootOptions[Index].OptionNumber;\r
182 break;\r
183 }\r
184 }\r
185\r
186 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
187\r
188 if (Index >= BootOptionCount) {\r
189 //\r
190 // If not found the BootManagerMenuApp, create it.\r
191 //\r
192 OptionNumber = (UINT16) RegisterBootManagerMenuAppBootOption (&mBootMenuFile, L"UEFI BootManagerMenuApp", (UINTN) -1, FALSE);\r
193 }\r
194\r
195 return OptionNumber;\r
196}\r
197\r
198/**\r
199 Platform Bds init. Include the platform firmware vendor, revision\r
200 and so crc check.\r
201**/\r
202VOID\r
203EFIAPI\r
204PlatformBootManagerBeforeConsole (\r
205 VOID\r
206 )\r
207{\r
208 UINTN Index;\r
209\r
210 SetupVariableInit ();\r
211\r
212 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
213\r
214 Index = 0;\r
215 while (gPlatformConsole[Index].DevicePath != NULL) {\r
216 //\r
217 // Update the console variable with the connect type\r
218 //\r
219 if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
220 EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);\r
221 }\r
222\r
223 if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
224 EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);\r
225 }\r
226\r
227 if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
228 EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);\r
229 }\r
230\r
231 Index++;\r
232 }\r
233}\r
234\r
235/**\r
236 Connect with predefined platform connect sequence,\r
237 the OEM/IBV can customize with their own connect sequence.\r
238**/\r
239VOID\r
240PlatformBdsConnectSequence (\r
241 VOID\r
242 )\r
243{\r
244 //\r
245 // Just use the simple policy to connect all devices\r
246 //\r
247 EfiBootManagerConnectAll ();\r
248}\r
249\r
250/**\r
251 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
252 can customize this fuction to support specific platform diagnostic.\r
253\r
254 @param MemoryTestLevel The memory test intensive level\r
255 @param QuietBoot Indicate if need to enable the quiet boot\r
256**/\r
257VOID\r
258PlatformBdsDiagnostics (\r
259 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
260 IN BOOLEAN QuietBoot\r
261 )\r
262{\r
263 EFI_STATUS Status;\r
264\r
265 //\r
266 // Here we can decide if we need to show\r
267 // the diagnostics screen\r
268 //\r
269 if (QuietBoot) {\r
270 BootLogoEnableLogo ();\r
271\r
272 //\r
273 // Perform system diagnostic\r
274 //\r
275 Status = PlatformBootManagerMemoryTest (MemoryTestLevel);\r
276 if (EFI_ERROR (Status)) {\r
277 BootLogoDisableLogo ();\r
278 }\r
279\r
280 return;\r
281 }\r
282\r
283 //\r
284 // Perform system diagnostic\r
285 //\r
286 PlatformBootManagerMemoryTest (MemoryTestLevel);\r
287}\r
288\r
289/**\r
290 Register the static boot options.\r
291**/\r
292VOID\r
293PlatformBdsRegisterStaticBootOptions (\r
294 VOID\r
295 )\r
296{\r
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
298 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;\r
299 EFI_INPUT_KEY Enter;\r
300 EFI_INPUT_KEY F2;\r
301 EFI_INPUT_KEY F7;\r
302 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
303 UINTN OptionNumber;\r
304\r
305 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;\r
306 White.Blue = White.Green = White.Red = White.Reserved = 0xFF;\r
307\r
308 //\r
309 // Register ENTER as CONTINUE key\r
310 //\r
311 Enter.ScanCode = SCAN_NULL;\r
312 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
313 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
314 //\r
315 // Map F2 to Boot Manager Menu\r
316 //\r
317 F2.ScanCode = SCAN_F2;\r
318 F2.UnicodeChar = CHAR_NULL;\r
319 EfiBootManagerGetBootManagerMenu (&BootOption);\r
320 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
321\r
322 //\r
323 // 3. Boot Device List menu\r
324 //\r
325 F7.ScanCode = SCAN_F7;\r
326 F7.UnicodeChar = CHAR_NULL;\r
327 OptionNumber = GetBootManagerMenuAppOption ();\r
328 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)OptionNumber, 0, &F7, NULL);\r
329\r
330 PrintXY (10, 10, &White, &Black, L"F2 to enter Setup. ");\r
331 PrintXY (10, 30, &White, &Black, L"F7 to enter Boot Manager Menu.");\r
332 PrintXY (10, 50, &White, &Black, L"Enter to boot directly.");\r
333}\r
334\r
335/**\r
336 Do the platform specific action after the console is connected.\r
337\r
338 Such as:\r
339 Dynamically switch output mode;\r
340 Signal console ready platform customized event;\r
341 Run diagnostics like memory testing;\r
342 Connect certain devices;\r
343 Dispatch aditional option roms.\r
344**/\r
345VOID\r
346EFIAPI\r
347PlatformBootManagerAfterConsole (\r
348 VOID\r
349 )\r
350{\r
351\r
352 //\r
353 // Go the different platform policy with different boot mode\r
354 // Notes: this part code can be change with the table policy\r
355 //\r
356 switch (GetBootModeHob ()) {\r
357\r
358 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
359 case BOOT_WITH_MINIMAL_CONFIGURATION:\r
360 PlatformBdsDiagnostics (IGNORE, TRUE);\r
361\r
362 //\r
363 // Perform some platform specific connect sequence\r
364 //\r
365 PlatformBdsConnectSequence ();\r
366 break;\r
367\r
368 case BOOT_IN_RECOVERY_MODE:\r
369 PlatformBdsDiagnostics (EXTENSIVE, FALSE);\r
370 break;\r
371\r
372 case BOOT_WITH_FULL_CONFIGURATION:\r
373 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:\r
374 case BOOT_WITH_DEFAULT_SETTINGS:\r
375 default:\r
376 PlatformBdsDiagnostics (IGNORE, TRUE);\r
377 PlatformBdsRegisterStaticBootOptions ();\r
378 PlatformBdsConnectSequence ();\r
379 EfiBootManagerRefreshAllBootOption ();\r
380 break;\r
381 }\r
382}\r
383\r
384/**\r
385 This function is called each second during the boot manager waits the timeout.\r
386\r
387 @param TimeoutRemain The remaining timeout.\r
388**/\r
389VOID\r
390EFIAPI\r
391PlatformBootManagerWaitCallback (\r
392 UINT16 TimeoutRemain\r
393 )\r
394{\r
395 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
396 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
397 UINT16 Timeout;\r
398\r
399 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
400\r
401 Black.Raw = 0x00000000;\r
402 White.Raw = 0x00FFFFFF;\r
403\r
404 BootLogoUpdateProgress (\r
405 White.Pixel,\r
406 Black.Pixel,\r
407 L"Start boot option",\r
408 White.Pixel,\r
409 (Timeout - TimeoutRemain) * 100 / Timeout,\r
410 0\r
411 );\r
412}\r
413\r
414/**\r
415 The function is called when no boot option could be launched,\r
416 including platform recovery options and options pointing to applications\r
417 built into firmware volumes.\r
418\r
419 If this function returns, BDS attempts to enter an infinite loop.\r
420**/\r
421VOID\r
422EFIAPI\r
423PlatformBootManagerUnableToBoot (\r
424 VOID\r
425 )\r
426{\r
427 return;\r
428}\r
429\r