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