]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / Variable.c
... / ...
CommitLineData
1/** @file\r
2Variable operation that will be used by bootmaint\r
3\r
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "BootMaintenanceManager.h"\r
10\r
11/**\r
12 Delete Boot Option that represent a Deleted state in BootOptionMenu.\r
13\r
14 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to\r
15 BM_LOAD_CONTEXT marked for deletion is deleted.\r
16 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.\r
17 @return Others If failed to update the "BootOrder" variable after deletion.\r
18\r
19**/\r
20EFI_STATUS\r
21Var_DelBootOption (\r
22 VOID\r
23 )\r
24{\r
25 BM_MENU_ENTRY *NewMenuEntry;\r
26 BM_LOAD_CONTEXT *NewLoadContext;\r
27 EFI_STATUS Status;\r
28 UINTN Index;\r
29 UINTN Index2;\r
30\r
31 Index2 = 0;\r
32 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
33 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));\r
34 if (NULL == NewMenuEntry) {\r
35 return EFI_NOT_FOUND;\r
36 }\r
37\r
38 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
39 if (!NewLoadContext->Deleted) {\r
40 continue;\r
41 }\r
42\r
43 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeBoot);\r
44 if (EFI_ERROR (Status)) {\r
45 return Status;\r
46 }\r
47\r
48 Index2++;\r
49 //\r
50 // If current Load Option is the same as BootNext,\r
51 // must delete BootNext in order to make sure\r
52 // there will be no panic on next boot\r
53 //\r
54 if (NewLoadContext->IsBootNext) {\r
55 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
56 }\r
57\r
58 RemoveEntryList (&NewMenuEntry->Link);\r
59 BOpt_DestroyMenuEntry (NewMenuEntry);\r
60 NewMenuEntry = NULL;\r
61 }\r
62\r
63 BootOptionMenu.MenuNumber -= Index2;\r
64\r
65 return EFI_SUCCESS;\r
66}\r
67\r
68/**\r
69 Delete Load Option that represent a Deleted state in DriverOptionMenu.\r
70\r
71 @retval EFI_SUCCESS Load Option is successfully updated.\r
72 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.\r
73 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI\r
74 Variable.\r
75\r
76**/\r
77EFI_STATUS\r
78Var_DelDriverOption (\r
79 VOID\r
80 )\r
81{\r
82 BM_MENU_ENTRY *NewMenuEntry;\r
83 BM_LOAD_CONTEXT *NewLoadContext;\r
84 EFI_STATUS Status;\r
85 UINTN Index;\r
86 UINTN Index2;\r
87\r
88 Index2 = 0;\r
89 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
90 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));\r
91 if (NULL == NewMenuEntry) {\r
92 return EFI_NOT_FOUND;\r
93 }\r
94\r
95 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
96 if (!NewLoadContext->Deleted) {\r
97 continue;\r
98 }\r
99\r
100 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeDriver);\r
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
104\r
105 Index2++;\r
106\r
107 RemoveEntryList (&NewMenuEntry->Link);\r
108 BOpt_DestroyMenuEntry (NewMenuEntry);\r
109 NewMenuEntry = NULL;\r
110 }\r
111\r
112 DriverOptionMenu.MenuNumber -= Index2;\r
113\r
114 return EFI_SUCCESS;\r
115}\r
116\r
117/**\r
118 This function delete and build multi-instance device path for\r
119 specified type of console device.\r
120\r
121 This function clear the EFI variable defined by ConsoleName and\r
122 gEfiGlobalVariableGuid. It then build the multi-instance device\r
123 path by appending the device path of the Console (In/Out/Err) instance\r
124 in ConsoleMenu. Then it scan all corresponding console device by\r
125 scanning Terminal (built from device supporting Serial I/O instances)\r
126 devices in TerminalMenu. At last, it save a EFI variable specifed\r
127 by ConsoleName and gEfiGlobalVariableGuid.\r
128\r
129 @param ConsoleName The name for the console device type. They are\r
130 usually "ConIn", "ConOut" and "ErrOut".\r
131 @param ConsoleMenu The console memu which is a list of console devices.\r
132 @param UpdatePageId The flag specifying which type of console device\r
133 to be processed.\r
134\r
135 @retval EFI_SUCCESS The function complete successfully.\r
136 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
137\r
138**/\r
139EFI_STATUS\r
140Var_UpdateConsoleOption (\r
141 IN UINT16 *ConsoleName,\r
142 IN BM_MENU_OPTION *ConsoleMenu,\r
143 IN UINT16 UpdatePageId\r
144 )\r
145{\r
146 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
147 BM_MENU_ENTRY *NewMenuEntry;\r
148 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
149 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
150 EFI_STATUS Status;\r
151 VENDOR_DEVICE_PATH Vendor;\r
152 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;\r
153 UINTN Index;\r
154\r
155 GetEfiGlobalVariable2 (ConsoleName, (VOID **)&ConDevicePath, NULL);\r
156 if (ConDevicePath != NULL) {\r
157 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);\r
158 FreePool (ConDevicePath);\r
159 ConDevicePath = NULL;\r
160 }\r
161\r
162 //\r
163 // First add all console input device from console input menu\r
164 //\r
165 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {\r
166 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);\r
167\r
168 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
169 if (NewConsoleContext->IsActive) {\r
170 ConDevicePath = AppendDevicePathInstance (\r
171 ConDevicePath,\r
172 NewConsoleContext->DevicePath\r
173 );\r
174 }\r
175 }\r
176\r
177 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
178 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
179\r
180 NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;\r
181 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||\r
182 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||\r
183 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))\r
184 )\r
185 {\r
186 Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
187 Vendor.Header.SubType = MSG_VENDOR_DP;\r
188\r
189 ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid)));\r
190 CopyMem (\r
191 &Vendor.Guid,\r
192 &TerminalTypeGuid[NewTerminalContext->TerminalType],\r
193 sizeof (EFI_GUID)\r
194 );\r
195 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
196 TerminalDevicePath = AppendDevicePathNode (\r
197 NewTerminalContext->DevicePath,\r
198 (EFI_DEVICE_PATH_PROTOCOL *)&Vendor\r
199 );\r
200 ASSERT (TerminalDevicePath != NULL);\r
201 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);\r
202 ConDevicePath = AppendDevicePathInstance (\r
203 ConDevicePath,\r
204 TerminalDevicePath\r
205 );\r
206 }\r
207 }\r
208\r
209 if (ConDevicePath != NULL) {\r
210 Status = gRT->SetVariable (\r
211 ConsoleName,\r
212 &gEfiGlobalVariableGuid,\r
213 VAR_FLAG,\r
214 GetDevicePathSize (ConDevicePath),\r
215 ConDevicePath\r
216 );\r
217 if (EFI_ERROR (Status)) {\r
218 return Status;\r
219 }\r
220 }\r
221\r
222 return EFI_SUCCESS;\r
223}\r
224\r
225/**\r
226 This function delete and build multi-instance device path ConIn\r
227 console device.\r
228\r
229 @retval EFI_SUCCESS The function complete successfully.\r
230 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
231**/\r
232EFI_STATUS\r
233Var_UpdateConsoleInpOption (\r
234 VOID\r
235 )\r
236{\r
237 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);\r
238}\r
239\r
240/**\r
241 This function delete and build multi-instance device path ConOut\r
242 console device.\r
243\r
244 @retval EFI_SUCCESS The function complete successfully.\r
245 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
246**/\r
247EFI_STATUS\r
248Var_UpdateConsoleOutOption (\r
249 VOID\r
250 )\r
251{\r
252 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);\r
253}\r
254\r
255/**\r
256 This function delete and build multi-instance device path ErrOut\r
257 console device.\r
258\r
259 @retval EFI_SUCCESS The function complete successfully.\r
260 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
261**/\r
262EFI_STATUS\r
263Var_UpdateErrorOutOption (\r
264 VOID\r
265 )\r
266{\r
267 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);\r
268}\r
269\r
270/**\r
271 This function create a currently loaded Drive Option from\r
272 the BMM. It then appends this Driver Option to the end of\r
273 the "DriverOrder" list. It append this Driver Opotion to the end\r
274 of DriverOptionMenu.\r
275\r
276 @param CallbackData The BMM context data.\r
277 @param HiiHandle The HII handle associated with the BMM formset.\r
278 @param DescriptionData The description of this driver option.\r
279 @param OptionalData The optional load option.\r
280 @param ForceReconnect If to force reconnect.\r
281\r
282 @retval other Contain some errors when excuting this function.See function\r
283 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
284 for detail return information.\r
285 @retval EFI_SUCCESS If function completes successfully.\r
286\r
287**/\r
288EFI_STATUS\r
289Var_UpdateDriverOption (\r
290 IN BMM_CALLBACK_DATA *CallbackData,\r
291 IN EFI_HII_HANDLE HiiHandle,\r
292 IN UINT16 *DescriptionData,\r
293 IN UINT16 *OptionalData,\r
294 IN UINT8 ForceReconnect\r
295 )\r
296{\r
297 UINT16 Index;\r
298 UINT16 DriverString[12];\r
299 BM_MENU_ENTRY *NewMenuEntry;\r
300 BM_LOAD_CONTEXT *NewLoadContext;\r
301 BOOLEAN OptionalDataExist;\r
302 EFI_STATUS Status;\r
303 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
304 UINT8 *OptionalDesData;\r
305 UINT32 OptionalDataSize;\r
306\r
307 OptionalDataExist = FALSE;\r
308 OptionalDesData = NULL;\r
309 OptionalDataSize = 0;\r
310\r
311 Index = BOpt_GetDriverOptionNumber ();\r
312 UnicodeSPrint (\r
313 DriverString,\r
314 sizeof (DriverString),\r
315 L"Driver%04x",\r
316 Index\r
317 );\r
318\r
319 if (*DescriptionData == 0x0000) {\r
320 StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString);\r
321 }\r
322\r
323 if (*OptionalData != 0x0000) {\r
324 OptionalDataExist = TRUE;\r
325 OptionalDesData = (UINT8 *)OptionalData;\r
326 OptionalDataSize = (UINT32)StrSize (OptionalData);\r
327 }\r
328\r
329 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
330 if (NULL == NewMenuEntry) {\r
331 return EFI_OUT_OF_RESOURCES;\r
332 }\r
333\r
334 Status = EfiBootManagerInitializeLoadOption (\r
335 &LoadOption,\r
336 Index,\r
337 LoadOptionTypeDriver,\r
338 LOAD_OPTION_ACTIVE | (ForceReconnect << 1),\r
339 DescriptionData,\r
340 CallbackData->LoadContext->FilePathList,\r
341 OptionalDesData,\r
342 OptionalDataSize\r
343 );\r
344 if (EFI_ERROR (Status)) {\r
345 return Status;\r
346 }\r
347\r
348 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1);\r
349 if (EFI_ERROR (Status)) {\r
350 EfiBootManagerFreeLoadOption (&LoadOption);\r
351 return Status;\r
352 }\r
353\r
354 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
355 NewLoadContext->Deleted = FALSE;\r
356 NewLoadContext->Attributes = LoadOption.Attributes;\r
357 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
358\r
359 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));\r
360 ASSERT (NewLoadContext->Description != NULL);\r
361 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
362 CopyMem (\r
363 NewLoadContext->Description,\r
364 LoadOption.Description,\r
365 StrSize (DescriptionData)\r
366 );\r
367\r
368 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
369 ASSERT (NewLoadContext->FilePathList != NULL);\r
370 CopyMem (\r
371 NewLoadContext->FilePathList,\r
372 LoadOption.FilePath,\r
373 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
374 );\r
375\r
376 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
377 NewMenuEntry->OptionNumber = Index;\r
378 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
379 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
380\r
381 if (OptionalDataExist) {\r
382 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
383 ASSERT (NewLoadContext->OptionalData != NULL);\r
384 CopyMem (\r
385 NewLoadContext->OptionalData,\r
386 LoadOption.OptionalData,\r
387 LoadOption.OptionalDataSize\r
388 );\r
389 }\r
390\r
391 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
392 DriverOptionMenu.MenuNumber++;\r
393\r
394 EfiBootManagerFreeLoadOption (&LoadOption);\r
395\r
396 return EFI_SUCCESS;\r
397}\r
398\r
399/**\r
400 This function create a currently loaded Boot Option from\r
401 the BMM. It then appends this Boot Option to the end of\r
402 the "BootOrder" list. It also append this Boot Opotion to the end\r
403 of BootOptionMenu.\r
404\r
405 @param CallbackData The BMM context data.\r
406\r
407 @retval other Contain some errors when excuting this function. See function\r
408 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
409 for detail return information.\r
410 @retval EFI_SUCCESS If function completes successfully.\r
411\r
412**/\r
413EFI_STATUS\r
414Var_UpdateBootOption (\r
415 IN BMM_CALLBACK_DATA *CallbackData\r
416 )\r
417{\r
418 UINT16 BootString[10];\r
419 UINT16 Index;\r
420 BM_MENU_ENTRY *NewMenuEntry;\r
421 BM_LOAD_CONTEXT *NewLoadContext;\r
422 BOOLEAN OptionalDataExist;\r
423 EFI_STATUS Status;\r
424 BMM_FAKE_NV_DATA *NvRamMap;\r
425 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
426 UINT8 *OptionalData;\r
427 UINT32 OptionalDataSize;\r
428\r
429 OptionalDataExist = FALSE;\r
430 NvRamMap = &CallbackData->BmmFakeNvData;\r
431 OptionalData = NULL;\r
432 OptionalDataSize = 0;\r
433\r
434 Index = BOpt_GetBootOptionNumber ();\r
435 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);\r
436\r
437 if (NvRamMap->BootDescriptionData[0] == 0x0000) {\r
438 StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString);\r
439 }\r
440\r
441 if (NvRamMap->BootOptionalData[0] != 0x0000) {\r
442 OptionalDataExist = TRUE;\r
443 OptionalData = (UINT8 *)NvRamMap->BootOptionalData;\r
444 OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData);\r
445 }\r
446\r
447 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
448 if (NULL == NewMenuEntry) {\r
449 return EFI_OUT_OF_RESOURCES;\r
450 }\r
451\r
452 Status = EfiBootManagerInitializeLoadOption (\r
453 &LoadOption,\r
454 Index,\r
455 LoadOptionTypeBoot,\r
456 LOAD_OPTION_ACTIVE,\r
457 NvRamMap->BootDescriptionData,\r
458 CallbackData->LoadContext->FilePathList,\r
459 OptionalData,\r
460 OptionalDataSize\r
461 );\r
462 if (EFI_ERROR (Status)) {\r
463 return Status;\r
464 }\r
465\r
466 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1);\r
467 if (EFI_ERROR (Status)) {\r
468 EfiBootManagerFreeLoadOption (&LoadOption);\r
469 return Status;\r
470 }\r
471\r
472 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
473 NewLoadContext->Deleted = FALSE;\r
474 NewLoadContext->Attributes = LoadOption.Attributes;\r
475 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
476\r
477 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));\r
478 ASSERT (NewLoadContext->Description != NULL);\r
479\r
480 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
481\r
482 CopyMem (\r
483 NewLoadContext->Description,\r
484 LoadOption.Description,\r
485 StrSize (NvRamMap->BootDescriptionData)\r
486 );\r
487\r
488 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
489 ASSERT (NewLoadContext->FilePathList != NULL);\r
490 CopyMem (\r
491 NewLoadContext->FilePathList,\r
492 LoadOption.FilePath,\r
493 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
494 );\r
495\r
496 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
497 NewMenuEntry->OptionNumber = Index;\r
498 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
499 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
500\r
501 if (OptionalDataExist) {\r
502 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
503 ASSERT (NewLoadContext->OptionalData != NULL);\r
504 CopyMem (\r
505 NewLoadContext->OptionalData,\r
506 LoadOption.OptionalData,\r
507 LoadOption.OptionalDataSize\r
508 );\r
509 }\r
510\r
511 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
512 BootOptionMenu.MenuNumber++;\r
513\r
514 EfiBootManagerFreeLoadOption (&LoadOption);\r
515\r
516 return EFI_SUCCESS;\r
517}\r
518\r
519/**\r
520 This function update the "BootNext" EFI Variable. If there is\r
521 no "BootNext" specified in BMM, this EFI Variable is deleted.\r
522 It also update the BMM context data specified the "BootNext"\r
523 vaule.\r
524\r
525 @param CallbackData The BMM context data.\r
526\r
527 @retval EFI_SUCCESS The function complete successfully.\r
528 @return The EFI variable can be saved. See gRT->SetVariable\r
529 for detail return information.\r
530\r
531**/\r
532EFI_STATUS\r
533Var_UpdateBootNext (\r
534 IN BMM_CALLBACK_DATA *CallbackData\r
535 )\r
536{\r
537 BM_MENU_ENTRY *NewMenuEntry;\r
538 BM_LOAD_CONTEXT *NewLoadContext;\r
539 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
540 UINT16 Index;\r
541 EFI_STATUS Status;\r
542\r
543 Status = EFI_SUCCESS;\r
544 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;\r
545 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
546 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
547 ASSERT (NULL != NewMenuEntry);\r
548\r
549 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
550 NewLoadContext->IsBootNext = FALSE;\r
551 }\r
552\r
553 if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) {\r
554 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
555 return EFI_SUCCESS;\r
556 }\r
557\r
558 NewMenuEntry = BOpt_GetMenuEntry (\r
559 &BootOptionMenu,\r
560 CurrentFakeNVMap->BootNext\r
561 );\r
562 ASSERT (NewMenuEntry != NULL);\r
563\r
564 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
565 Status = gRT->SetVariable (\r
566 L"BootNext",\r
567 &gEfiGlobalVariableGuid,\r
568 VAR_FLAG,\r
569 sizeof (UINT16),\r
570 &NewMenuEntry->OptionNumber\r
571 );\r
572 NewLoadContext->IsBootNext = TRUE;\r
573 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;\r
574 return Status;\r
575}\r
576\r
577/**\r
578 This function update the "BootOrder" EFI Variable based on\r
579 BMM Formset's NV map. It then refresh BootOptionMenu\r
580 with the new "BootOrder" list.\r
581\r
582 @param CallbackData The BMM context data.\r
583\r
584 @retval EFI_SUCCESS The function complete successfully.\r
585 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
586 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
587\r
588**/\r
589EFI_STATUS\r
590Var_UpdateBootOrder (\r
591 IN BMM_CALLBACK_DATA *CallbackData\r
592 )\r
593{\r
594 EFI_STATUS Status;\r
595 UINT16 Index;\r
596 UINT16 OrderIndex;\r
597 UINT16 *BootOrder;\r
598 UINTN BootOrderSize;\r
599 UINT16 OptionNumber;\r
600\r
601 //\r
602 // First check whether BootOrder is present in current configuration\r
603 //\r
604 GetEfiGlobalVariable2 (L"BootOrder", (VOID **)&BootOrder, &BootOrderSize);\r
605 if (BootOrder == NULL) {\r
606 return EFI_OUT_OF_RESOURCES;\r
607 }\r
608\r
609 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0])));\r
610\r
611 //\r
612 // OptionOrder is subset of BootOrder\r
613 //\r
614 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) {\r
615 for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
616 if ((BootOrder[Index] == (UINT16)(CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {\r
617 OptionNumber = BootOrder[Index];\r
618 CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));\r
619 BootOrder[OrderIndex] = OptionNumber;\r
620 }\r
621 }\r
622 }\r
623\r
624 Status = gRT->SetVariable (\r
625 L"BootOrder",\r
626 &gEfiGlobalVariableGuid,\r
627 VAR_FLAG,\r
628 BootOrderSize,\r
629 BootOrder\r
630 );\r
631 FreePool (BootOrder);\r
632\r
633 BOpt_FreeMenu (&BootOptionMenu);\r
634 BOpt_GetBootOptions (CallbackData);\r
635\r
636 return Status;\r
637}\r
638\r
639/**\r
640 This function update the "DriverOrder" EFI Variable based on\r
641 BMM Formset's NV map. It then refresh DriverOptionMenu\r
642 with the new "DriverOrder" list.\r
643\r
644 @param CallbackData The BMM context data.\r
645\r
646 @retval EFI_SUCCESS The function complete successfully.\r
647 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
648 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
649\r
650**/\r
651EFI_STATUS\r
652Var_UpdateDriverOrder (\r
653 IN BMM_CALLBACK_DATA *CallbackData\r
654 )\r
655{\r
656 EFI_STATUS Status;\r
657 UINT16 Index;\r
658 UINT16 *DriverOrderList;\r
659 UINT16 *NewDriverOrderList;\r
660 UINTN DriverOrderListSize;\r
661\r
662 DriverOrderList = NULL;\r
663 DriverOrderListSize = 0;\r
664\r
665 //\r
666 // First check whether DriverOrder is present in current configuration\r
667 //\r
668 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **)&DriverOrderList, &DriverOrderListSize);\r
669 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);\r
670\r
671 if (NewDriverOrderList == NULL) {\r
672 return EFI_OUT_OF_RESOURCES;\r
673 }\r
674\r
675 //\r
676 // If exists, delete it to hold new DriverOrder\r
677 //\r
678 if (DriverOrderList != NULL) {\r
679 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);\r
680 FreePool (DriverOrderList);\r
681 }\r
682\r
683 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0])));\r
684 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
685 NewDriverOrderList[Index] = (UINT16)(CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1);\r
686 }\r
687\r
688 Status = gRT->SetVariable (\r
689 L"DriverOrder",\r
690 &gEfiGlobalVariableGuid,\r
691 VAR_FLAG,\r
692 DriverOrderListSize,\r
693 NewDriverOrderList\r
694 );\r
695 if (EFI_ERROR (Status)) {\r
696 return Status;\r
697 }\r
698\r
699 BOpt_FreeMenu (&DriverOptionMenu);\r
700 BOpt_GetDriverOptions (CallbackData);\r
701 return EFI_SUCCESS;\r
702}\r
703\r
704/**\r
705 Update the Text Mode of Console.\r
706\r
707 @param CallbackData The context data for BMM.\r
708\r
709 @retval EFI_SUCCSS If the Text Mode of Console is updated.\r
710 @return Other value if the Text Mode of Console is not updated.\r
711\r
712**/\r
713EFI_STATUS\r
714Var_UpdateConMode (\r
715 IN BMM_CALLBACK_DATA *CallbackData\r
716 )\r
717{\r
718 EFI_STATUS Status;\r
719 UINTN Mode;\r
720 CONSOLE_OUT_MODE ModeInfo;\r
721\r
722 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;\r
723\r
724 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));\r
725 if (!EFI_ERROR (Status)) {\r
726 Status = PcdSet32S (PcdSetupConOutColumn, (UINT32)ModeInfo.Column);\r
727 if (!EFI_ERROR (Status)) {\r
728 Status = PcdSet32S (PcdSetupConOutRow, (UINT32)ModeInfo.Row);\r
729 }\r
730 }\r
731\r
732 return Status;\r
733}\r