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