2 Variable operation that will be used by bootmaint
4 Copyright (c) 2004 - 2015, 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
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.
15 #include "BootMaint.h"
18 Delete Boot Option that represent a Deleted state in BootOptionMenu.
19 After deleting this boot option, call Var_ChangeBootOrder to
20 make sure BootOrder is in valid state.
22 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
23 BM_LOAD_CONTEXT marked for deletion is deleted.
24 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.
25 @return Others If failed to update the "BootOrder" variable after deletion.
33 BM_MENU_ENTRY
*NewMenuEntry
;
34 BM_LOAD_CONTEXT
*NewLoadContext
;
35 UINT16 BootString
[10];
42 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
43 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
44 if (NULL
== NewMenuEntry
) {
48 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
49 if (!NewLoadContext
->Deleted
) {
57 NewMenuEntry
->OptionNumber
60 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
63 // If current Load Option is the same as BootNext,
64 // must delete BootNext in order to make sure
65 // there will be no panic on next boot
67 if (NewLoadContext
->IsBootNext
) {
68 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
71 RemoveEntryList (&NewMenuEntry
->Link
);
72 BOpt_DestroyMenuEntry (NewMenuEntry
);
76 BootOptionMenu
.MenuNumber
-= Index2
;
78 Status
= Var_ChangeBootOrder ();
83 After any operation on Boot####, there will be a discrepancy in BootOrder.
84 Since some are missing but in BootOrder, while some are present but are
85 not reflected by BootOrder. Then a function rebuild BootOrder from
86 scratch by content from BootOptionMenu is needed.
91 @retval EFI_SUCCESS The boot order is updated successfully.
92 @return EFI_STATUS other than EFI_SUCCESS if failed to
93 Set the "BootOrder" EFI Variable.
103 BM_MENU_ENTRY
*NewMenuEntry
;
104 UINT16
*BootOrderList
;
105 UINT16
*BootOrderListPtr
;
106 UINTN BootOrderListSize
;
109 BootOrderList
= NULL
;
110 BootOrderListSize
= 0;
113 // First check whether BootOrder is present in current configuration
115 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrderList
, &BootOrderListSize
);
118 // If exists, delete it to hold new BootOrder
120 if (BootOrderList
!= NULL
) {
121 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
122 FreePool (BootOrderList
);
123 BootOrderList
= NULL
;
126 // Maybe here should be some check method to ensure that
127 // no new added boot options will be added
128 // but the setup engine now will give only one callback
129 // that is to say, user are granted only one chance to
130 // decide whether the boot option will be added or not
131 // there should be no indictor to show whether this
132 // is a "new" boot option
134 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
136 if (BootOrderListSize
> 0) {
137 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
138 ASSERT (BootOrderList
!= NULL
);
139 BootOrderListPtr
= BootOrderList
;
142 // Get all current used Boot#### from BootOptionMenu.
143 // OptionNumber in each BM_LOAD_OPTION is really its
146 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
147 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
148 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
152 BootOrderList
= BootOrderListPtr
;
155 // After building the BootOrderList, write it back
157 Status
= gRT
->SetVariable (
159 &gEfiGlobalVariableGuid
,
161 BootOrderListSize
* sizeof (UINT16
),
164 if (EFI_ERROR (Status
)) {
172 Delete Load Option that represent a Deleted state in BootOptionMenu.
173 After deleting this Driver option, call Var_ChangeDriverOrder to
174 make sure DriverOrder is in valid state.
176 @retval EFI_SUCCESS Load Option is successfully updated.
177 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.
178 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
183 Var_DelDriverOption (
187 BM_MENU_ENTRY
*NewMenuEntry
;
188 BM_LOAD_CONTEXT
*NewLoadContext
;
189 UINT16 DriverString
[12];
194 Status
= EFI_SUCCESS
;
196 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
197 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
198 if (NULL
== NewMenuEntry
) {
199 return EFI_NOT_FOUND
;
202 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
203 if (!NewLoadContext
->Deleted
) {
209 sizeof (DriverString
),
211 NewMenuEntry
->OptionNumber
214 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
217 RemoveEntryList (&NewMenuEntry
->Link
);
218 BOpt_DestroyMenuEntry (NewMenuEntry
);
222 DriverOptionMenu
.MenuNumber
-= Index2
;
224 Status
= Var_ChangeDriverOrder ();
229 After any operation on Driver####, there will be a discrepancy in
230 DriverOrder. Since some are missing but in DriverOrder, while some
231 are present but are not reflected by DriverOrder. Then a function
232 rebuild DriverOrder from scratch by content from DriverOptionMenu is
235 @retval EFI_SUCCESS The driver order is updated successfully.
236 @return Other status than EFI_SUCCESS if failed to set the "DriverOrder" EFI Variable.
240 Var_ChangeDriverOrder (
245 BM_MENU_ENTRY
*NewMenuEntry
;
246 UINT16
*DriverOrderList
;
247 UINT16
*DriverOrderListPtr
;
248 UINTN DriverOrderListSize
;
251 DriverOrderList
= NULL
;
252 DriverOrderListSize
= 0;
255 // First check whether DriverOrder is present in current configuration
257 GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
259 // If exists, delete it to hold new DriverOrder
261 if (DriverOrderList
!= NULL
) {
262 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
263 FreePool (DriverOrderList
);
264 DriverOrderList
= NULL
;
267 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
269 if (DriverOrderListSize
> 0) {
270 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
271 ASSERT (DriverOrderList
!= NULL
);
272 DriverOrderListPtr
= DriverOrderList
;
275 // Get all current used Driver#### from DriverOptionMenu.
276 // OptionNumber in each BM_LOAD_OPTION is really its
279 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
280 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
281 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
285 DriverOrderList
= DriverOrderListPtr
;
288 // After building the DriverOrderList, write it back
290 Status
= gRT
->SetVariable (
292 &gEfiGlobalVariableGuid
,
294 DriverOrderListSize
* sizeof (UINT16
),
297 if (EFI_ERROR (Status
)) {
305 Update the device path of "ConOut", "ConIn" and "ErrOut"
306 based on the new BaudRate, Data Bits, parity and Stop Bits
311 Var_UpdateAllConsoleOption (
315 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
316 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
317 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
320 OutDevicePath
= GetEfiGlobalVariable (L
"ConOut");
321 InpDevicePath
= GetEfiGlobalVariable (L
"ConIn");
322 ErrDevicePath
= GetEfiGlobalVariable (L
"ErrOut");
323 if (OutDevicePath
!= NULL
) {
324 ChangeVariableDevicePath (OutDevicePath
);
325 Status
= gRT
->SetVariable (
327 &gEfiGlobalVariableGuid
,
329 GetDevicePathSize (OutDevicePath
),
332 ASSERT (!EFI_ERROR (Status
));
335 if (InpDevicePath
!= NULL
) {
336 ChangeVariableDevicePath (InpDevicePath
);
337 Status
= gRT
->SetVariable (
339 &gEfiGlobalVariableGuid
,
341 GetDevicePathSize (InpDevicePath
),
344 ASSERT (!EFI_ERROR (Status
));
347 if (ErrDevicePath
!= NULL
) {
348 ChangeVariableDevicePath (ErrDevicePath
);
349 Status
= gRT
->SetVariable (
351 &gEfiGlobalVariableGuid
,
353 GetDevicePathSize (ErrDevicePath
),
356 ASSERT (!EFI_ERROR (Status
));
361 This function delete and build multi-instance device path for
362 specified type of console device.
364 This function clear the EFI variable defined by ConsoleName and
365 gEfiGlobalVariableGuid. It then build the multi-instance device
366 path by appending the device path of the Console (In/Out/Err) instance
367 in ConsoleMenu. Then it scan all corresponding console device by
368 scanning Terminal (built from device supporting Serial I/O instances)
369 devices in TerminalMenu. At last, it save a EFI variable specifed
370 by ConsoleName and gEfiGlobalVariableGuid.
372 @param ConsoleName The name for the console device type. They are
373 usually "ConIn", "ConOut" and "ErrOut".
374 @param ConsoleMenu The console memu which is a list of console devices.
375 @param UpdatePageId The flag specifying which type of console device
378 @retval EFI_SUCCESS The function complete successfully.
379 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
383 Var_UpdateConsoleOption (
384 IN UINT16
*ConsoleName
,
385 IN BM_MENU_OPTION
*ConsoleMenu
,
386 IN UINT16 UpdatePageId
389 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
390 BM_MENU_ENTRY
*NewMenuEntry
;
391 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
392 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
394 VENDOR_DEVICE_PATH Vendor
;
395 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
398 ConDevicePath
= GetEfiGlobalVariable (ConsoleName
);
399 if (ConDevicePath
!= NULL
) {
400 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
401 FreePool (ConDevicePath
);
402 ConDevicePath
= NULL
;
406 // First add all console input device from console input menu
408 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
409 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
411 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
412 if (NewConsoleContext
->IsActive
) {
413 ConDevicePath
= AppendDevicePathInstance (
415 NewConsoleContext
->DevicePath
420 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
421 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
423 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
424 if (((NewTerminalContext
->IsConIn
!= 0) && (UpdatePageId
== FORM_CON_IN_ID
)) ||
425 ((NewTerminalContext
->IsConOut
!= 0) && (UpdatePageId
== FORM_CON_OUT_ID
)) ||
426 ((NewTerminalContext
->IsStdErr
!= 0) && (UpdatePageId
== FORM_CON_ERR_ID
))
428 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
429 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
431 ASSERT (NewTerminalContext
->TerminalType
< (sizeof (TerminalTypeGuid
) / sizeof (TerminalTypeGuid
[0])));
434 &TerminalTypeGuid
[NewTerminalContext
->TerminalType
],
437 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
438 TerminalDevicePath
= AppendDevicePathNode (
439 NewTerminalContext
->DevicePath
,
440 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
442 ASSERT (TerminalDevicePath
!= NULL
);
443 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
444 ConDevicePath
= AppendDevicePathInstance (
451 if (ConDevicePath
!= NULL
) {
452 Status
= gRT
->SetVariable (
454 &gEfiGlobalVariableGuid
,
456 GetDevicePathSize (ConDevicePath
),
459 if (EFI_ERROR (Status
)) {
469 This function delete and build multi-instance device path ConIn
472 @retval EFI_SUCCESS The function complete successfully.
473 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
476 Var_UpdateConsoleInpOption (
480 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
484 This function delete and build multi-instance device path ConOut
487 @retval EFI_SUCCESS The function complete successfully.
488 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
491 Var_UpdateConsoleOutOption (
495 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
499 This function delete and build multi-instance device path ErrOut
502 @retval EFI_SUCCESS The function complete successfully.
503 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
506 Var_UpdateErrorOutOption (
510 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
514 This function create a currently loaded Drive Option from
515 the BMM. It then appends this Driver Option to the end of
516 the "DriverOrder" list. It append this Driver Opotion to the end
519 @param CallbackData The BMM context data.
520 @param HiiHandle The HII handle associated with the BMM formset.
521 @param DescriptionData The description of this driver option.
522 @param OptionalData The optional load option.
523 @param ForceReconnect If to force reconnect.
525 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
526 @retval EFI_SUCCESS If function completes successfully.
527 @return Others Errors Return errors from call to gRT->GetVariable.
531 Var_UpdateDriverOption (
532 IN BMM_CALLBACK_DATA
*CallbackData
,
533 IN EFI_HII_HANDLE HiiHandle
,
534 IN UINT16
*DescriptionData
,
535 IN UINT16
*OptionalData
,
536 IN UINT8 ForceReconnect
540 UINT16
*DriverOrderList
;
541 UINT16
*NewDriverOrderList
;
542 UINT16 DriverString
[12];
543 UINTN DriverOrderListSize
;
547 BM_MENU_ENTRY
*NewMenuEntry
;
548 BM_LOAD_CONTEXT
*NewLoadContext
;
549 BOOLEAN OptionalDataExist
;
552 OptionalDataExist
= FALSE
;
554 Index
= BOpt_GetDriverOptionNumber ();
557 sizeof (DriverString
),
562 if (*DescriptionData
== 0x0000) {
563 StrCpyS (DescriptionData
, MAX_MENU_NUMBER
, DriverString
);
566 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
567 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
569 if (*OptionalData
!= 0x0000) {
570 OptionalDataExist
= TRUE
;
571 BufferSize
+= StrSize (OptionalData
);
574 Buffer
= AllocateZeroPool (BufferSize
);
575 if (NULL
== Buffer
) {
576 return EFI_OUT_OF_RESOURCES
;
579 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
580 if (NULL
== NewMenuEntry
) {
582 return EFI_OUT_OF_RESOURCES
;
585 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
586 NewLoadContext
->Deleted
= FALSE
;
587 NewLoadContext
->LoadOptionSize
= BufferSize
;
588 Ptr
= (UINT8
*) Buffer
;
589 NewLoadContext
->LoadOption
= Ptr
;
590 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
591 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
592 NewLoadContext
->IsActive
= TRUE
;
593 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
595 Ptr
+= sizeof (UINT32
);
596 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
597 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
599 Ptr
+= sizeof (UINT16
);
603 StrSize (DescriptionData
)
606 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
607 ASSERT (NewLoadContext
->Description
!= NULL
);
608 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
610 NewLoadContext
->Description
,
612 StrSize (DescriptionData
)
615 Ptr
+= StrSize (DescriptionData
);
618 CallbackData
->LoadContext
->FilePathList
,
619 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
622 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
623 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
626 NewLoadContext
->FilePathList
,
628 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
631 NewMenuEntry
->HelpString
= UiDevicePathToStr (NewLoadContext
->FilePathList
);
632 NewMenuEntry
->OptionNumber
= Index
;
633 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
635 DriverOptionStrDepository
637 NewMenuEntry
->DisplayStringToken
= HiiSetString (HiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
639 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
641 DriverOptionHelpStrDepository
643 NewMenuEntry
->HelpStringToken
= HiiSetString (HiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
645 if (OptionalDataExist
) {
646 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
651 StrSize (OptionalData
)
655 Status
= gRT
->SetVariable (
657 &gEfiGlobalVariableGuid
,
662 ASSERT_EFI_ERROR (Status
);
663 Status
= GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
664 if (EFI_ERROR (Status
) || DriverOrderList
== NULL
){
667 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
668 ASSERT (NewDriverOrderList
!= NULL
);
669 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
670 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
671 if (DriverOrderList
!= NULL
) {
672 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
675 Status
= gRT
->SetVariable (
677 &gEfiGlobalVariableGuid
,
679 DriverOrderListSize
+ sizeof (UINT16
),
682 ASSERT_EFI_ERROR (Status
);
683 if (DriverOrderList
!= NULL
) {
684 FreePool (DriverOrderList
);
686 DriverOrderList
= NULL
;
687 FreePool (NewDriverOrderList
);
688 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
689 DriverOptionMenu
.MenuNumber
++;
691 *DescriptionData
= 0x0000;
692 *OptionalData
= 0x0000;
697 This function create a currently loaded Boot Option from
698 the BMM. It then appends this Boot Option to the end of
699 the "BootOrder" list. It also append this Boot Opotion to the end
702 @param CallbackData The BMM context data.
703 @param NvRamMap The file explorer formset internal state.
705 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
706 @retval EFI_SUCCESS If function completes successfully.
707 @return Others Errors Return errors from call to gRT->GetVariable.
711 Var_UpdateBootOption (
712 IN BMM_CALLBACK_DATA
*CallbackData
,
713 IN FILE_EXPLORER_NV_DATA
*NvRamMap
716 UINT16
*BootOrderList
;
717 UINT16
*NewBootOrderList
;
718 UINTN BootOrderListSize
;
719 UINT16 BootString
[10];
724 BM_MENU_ENTRY
*NewMenuEntry
;
725 BM_LOAD_CONTEXT
*NewLoadContext
;
726 BOOLEAN OptionalDataExist
;
729 OptionalDataExist
= FALSE
;
731 Index
= BOpt_GetBootOptionNumber () ;
732 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
734 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
735 StrCpyS (NvRamMap
->DescriptionData
, sizeof (NvRamMap
->DescriptionData
) / sizeof (NvRamMap
->DescriptionData
[0]), BootString
);
738 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
739 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
741 if (NvRamMap
->OptionalData
[0] != 0x0000) {
742 OptionalDataExist
= TRUE
;
743 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
746 Buffer
= AllocateZeroPool (BufferSize
);
747 if (NULL
== Buffer
) {
748 return EFI_OUT_OF_RESOURCES
;
751 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
752 if (NULL
== NewMenuEntry
) {
753 return EFI_OUT_OF_RESOURCES
;
756 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
757 NewLoadContext
->Deleted
= FALSE
;
758 NewLoadContext
->LoadOptionSize
= BufferSize
;
759 Ptr
= (UINT8
*) Buffer
;
760 NewLoadContext
->LoadOption
= Ptr
;
761 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
762 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
763 NewLoadContext
->IsActive
= TRUE
;
764 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
766 Ptr
+= sizeof (UINT32
);
767 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
768 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
769 Ptr
+= sizeof (UINT16
);
773 NvRamMap
->DescriptionData
,
774 StrSize (NvRamMap
->DescriptionData
)
777 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
778 ASSERT (NewLoadContext
->Description
!= NULL
);
780 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
782 NewLoadContext
->Description
,
784 StrSize (NvRamMap
->DescriptionData
)
787 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
790 CallbackData
->LoadContext
->FilePathList
,
791 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
794 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
795 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
798 NewLoadContext
->FilePathList
,
800 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
803 NewMenuEntry
->HelpString
= UiDevicePathToStr (NewLoadContext
->FilePathList
);
804 NewMenuEntry
->OptionNumber
= Index
;
805 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
807 BootOptionStrDepository
809 NewMenuEntry
->DisplayStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
811 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
813 BootOptionHelpStrDepository
815 NewMenuEntry
->HelpStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
817 if (OptionalDataExist
) {
818 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
820 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
823 Status
= gRT
->SetVariable (
825 &gEfiGlobalVariableGuid
,
830 ASSERT_EFI_ERROR (Status
);
832 Status
= GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrderList
, &BootOrderListSize
);
833 if (EFI_ERROR (Status
) || BootOrderList
== NULL
){
836 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
837 ASSERT (NewBootOrderList
!= NULL
);
838 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
839 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
841 if (BootOrderList
!= NULL
) {
842 FreePool (BootOrderList
);
845 Status
= gRT
->SetVariable (
847 &gEfiGlobalVariableGuid
,
849 BootOrderListSize
+ sizeof (UINT16
),
852 ASSERT_EFI_ERROR (Status
);
854 FreePool (NewBootOrderList
);
855 NewBootOrderList
= NULL
;
856 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
857 BootOptionMenu
.MenuNumber
++;
859 NvRamMap
->DescriptionData
[0] = 0x0000;
860 NvRamMap
->OptionalData
[0] = 0x0000;
865 This function update the "BootNext" EFI Variable. If there is
866 no "BootNext" specified in BMM, this EFI Variable is deleted.
867 It also update the BMM context data specified the "BootNext"
870 @param CallbackData The BMM context data.
872 @retval EFI_SUCCESS The function complete successfully.
873 @return The EFI variable can be saved. See gRT->SetVariable
874 for detail return information.
879 IN BMM_CALLBACK_DATA
*CallbackData
882 BM_MENU_ENTRY
*NewMenuEntry
;
883 BM_LOAD_CONTEXT
*NewLoadContext
;
884 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
888 Status
= EFI_SUCCESS
;
889 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
890 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
891 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
892 ASSERT (NULL
!= NewMenuEntry
);
894 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
895 NewLoadContext
->IsBootNext
= FALSE
;
898 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
899 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
903 NewMenuEntry
= BOpt_GetMenuEntry (
905 CurrentFakeNVMap
->BootNext
907 ASSERT (NewMenuEntry
!= NULL
);
909 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
910 Status
= gRT
->SetVariable (
912 &gEfiGlobalVariableGuid
,
915 &NewMenuEntry
->OptionNumber
917 NewLoadContext
->IsBootNext
= TRUE
;
918 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
923 This function update the "BootOrder" EFI Variable based on
924 BMM Formset's NV map. It then refresh BootOptionMenu
925 with the new "BootOrder" list.
927 @param CallbackData The BMM context data.
929 @retval EFI_SUCCESS The function complete successfully.
930 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
931 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
935 Var_UpdateBootOrder (
936 IN BMM_CALLBACK_DATA
*CallbackData
947 // First check whether BootOrder is present in current configuration
949 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrder
, &BootOrderSize
);
950 if (BootOrder
== NULL
) {
951 return EFI_OUT_OF_RESOURCES
;
954 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
[0])));
957 // OptionOrder is subset of BootOrder
959 for (OrderIndex
= 0; (OrderIndex
< BootOptionMenu
.MenuNumber
) && (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] != 0); OrderIndex
++) {
960 for (Index
= OrderIndex
; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
961 if ((BootOrder
[Index
] == (UINT16
) (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] - 1)) && (OrderIndex
!= Index
)) {
962 OptionNumber
= BootOrder
[Index
];
963 CopyMem (&BootOrder
[OrderIndex
+ 1], &BootOrder
[OrderIndex
], (Index
- OrderIndex
) * sizeof (UINT16
));
964 BootOrder
[OrderIndex
] = OptionNumber
;
969 Status
= gRT
->SetVariable (
971 &gEfiGlobalVariableGuid
,
976 FreePool (BootOrder
);
978 BOpt_FreeMenu (&BootOptionMenu
);
979 BOpt_GetBootOptions (CallbackData
);
986 This function update the "DriverOrder" EFI Variable based on
987 BMM Formset's NV map. It then refresh DriverOptionMenu
988 with the new "DriverOrder" list.
990 @param CallbackData The BMM context data.
992 @retval EFI_SUCCESS The function complete successfully.
993 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
994 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
998 Var_UpdateDriverOrder (
999 IN BMM_CALLBACK_DATA
*CallbackData
1004 UINT16
*DriverOrderList
;
1005 UINT16
*NewDriverOrderList
;
1006 UINTN DriverOrderListSize
;
1008 DriverOrderList
= NULL
;
1009 DriverOrderListSize
= 0;
1012 // First check whether DriverOrder is present in current configuration
1014 GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
1015 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1017 if (NewDriverOrderList
== NULL
) {
1018 return EFI_OUT_OF_RESOURCES
;
1021 // If exists, delete it to hold new DriverOrder
1023 if (DriverOrderList
!= NULL
) {
1024 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1025 FreePool (DriverOrderList
);
1028 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[0])));
1029 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1030 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[Index
] - 1);
1033 Status
= gRT
->SetVariable (
1035 &gEfiGlobalVariableGuid
,
1037 DriverOrderListSize
,
1040 if (EFI_ERROR (Status
)) {
1044 BOpt_FreeMenu (&DriverOptionMenu
);
1045 BOpt_GetDriverOptions (CallbackData
);
1050 Update the Text Mode of Console.
1052 @param CallbackData The context data for BMM.
1054 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1055 @return Other value if the Text Mode of Console is not updated.
1060 IN BMM_CALLBACK_DATA
*CallbackData
1065 CONSOLE_OUT_MODE ModeInfo
;
1067 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1069 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1070 if (!EFI_ERROR(Status
)) {
1071 PcdSet32 (PcdSetupConOutColumn
, (UINT32
) ModeInfo
.Column
);
1072 PcdSet32 (PcdSetupConOutRow
, (UINT32
) ModeInfo
.Row
);