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.
530 Var_UpdateDriverOption (
531 IN BMM_CALLBACK_DATA
*CallbackData
,
532 IN EFI_HII_HANDLE HiiHandle
,
533 IN UINT16
*DescriptionData
,
534 IN UINT16
*OptionalData
,
535 IN UINT8 ForceReconnect
539 UINT16
*DriverOrderList
;
540 UINT16
*NewDriverOrderList
;
541 UINT16 DriverString
[12];
542 UINTN DriverOrderListSize
;
546 BM_MENU_ENTRY
*NewMenuEntry
;
547 BM_LOAD_CONTEXT
*NewLoadContext
;
548 BOOLEAN OptionalDataExist
;
551 OptionalDataExist
= FALSE
;
553 Index
= BOpt_GetDriverOptionNumber ();
556 sizeof (DriverString
),
561 if (*DescriptionData
== 0x0000) {
562 StrCpy (DescriptionData
, DriverString
);
565 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
566 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
568 if (*OptionalData
!= 0x0000) {
569 OptionalDataExist
= TRUE
;
570 BufferSize
+= StrSize (OptionalData
);
573 Buffer
= AllocateZeroPool (BufferSize
);
574 if (NULL
== Buffer
) {
575 return EFI_OUT_OF_RESOURCES
;
578 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
579 if (NULL
== NewMenuEntry
) {
581 return EFI_OUT_OF_RESOURCES
;
584 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
585 NewLoadContext
->Deleted
= FALSE
;
586 NewLoadContext
->LoadOptionSize
= BufferSize
;
587 Ptr
= (UINT8
*) Buffer
;
588 NewLoadContext
->LoadOption
= Ptr
;
589 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
590 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
591 NewLoadContext
->IsActive
= TRUE
;
592 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
594 Ptr
+= sizeof (UINT32
);
595 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
596 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
598 Ptr
+= sizeof (UINT16
);
602 StrSize (DescriptionData
)
605 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
606 ASSERT (NewLoadContext
->Description
!= NULL
);
607 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
609 NewLoadContext
->Description
,
611 StrSize (DescriptionData
)
614 Ptr
+= StrSize (DescriptionData
);
617 CallbackData
->LoadContext
->FilePathList
,
618 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
621 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
622 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
625 NewLoadContext
->FilePathList
,
627 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
630 NewMenuEntry
->HelpString
= UiDevicePathToStr (NewLoadContext
->FilePathList
);
631 NewMenuEntry
->OptionNumber
= Index
;
632 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
634 DriverOptionStrDepository
636 NewMenuEntry
->DisplayStringToken
= HiiSetString (HiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
638 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
640 DriverOptionHelpStrDepository
642 NewMenuEntry
->HelpStringToken
= HiiSetString (HiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
644 if (OptionalDataExist
) {
645 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
650 StrSize (OptionalData
)
654 Status
= gRT
->SetVariable (
656 &gEfiGlobalVariableGuid
,
661 ASSERT_EFI_ERROR (Status
);
662 GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
663 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
664 ASSERT (NewDriverOrderList
!= NULL
);
665 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
666 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
667 if (DriverOrderList
!= NULL
) {
668 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
671 Status
= gRT
->SetVariable (
673 &gEfiGlobalVariableGuid
,
675 DriverOrderListSize
+ sizeof (UINT16
),
678 ASSERT_EFI_ERROR (Status
);
679 if (DriverOrderList
!= NULL
) {
680 FreePool (DriverOrderList
);
682 DriverOrderList
= NULL
;
683 FreePool (NewDriverOrderList
);
684 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
685 DriverOptionMenu
.MenuNumber
++;
687 *DescriptionData
= 0x0000;
688 *OptionalData
= 0x0000;
693 This function create a currently loaded Boot Option from
694 the BMM. It then appends this Boot Option to the end of
695 the "BootOrder" list. It also append this Boot Opotion to the end
698 @param CallbackData The BMM context data.
699 @param NvRamMap The file explorer formset internal state.
701 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
702 @retval EFI_SUCCESS If function completes successfully.
706 Var_UpdateBootOption (
707 IN BMM_CALLBACK_DATA
*CallbackData
,
708 IN FILE_EXPLORER_NV_DATA
*NvRamMap
711 UINT16
*BootOrderList
;
712 UINT16
*NewBootOrderList
;
713 UINTN BootOrderListSize
;
714 UINT16 BootString
[10];
719 BM_MENU_ENTRY
*NewMenuEntry
;
720 BM_LOAD_CONTEXT
*NewLoadContext
;
721 BOOLEAN OptionalDataExist
;
724 OptionalDataExist
= FALSE
;
726 Index
= BOpt_GetBootOptionNumber () ;
727 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
729 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
730 StrCpy (NvRamMap
->DescriptionData
, BootString
);
733 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
734 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
736 if (NvRamMap
->OptionalData
[0] != 0x0000) {
737 OptionalDataExist
= TRUE
;
738 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
741 Buffer
= AllocateZeroPool (BufferSize
);
742 if (NULL
== Buffer
) {
743 return EFI_OUT_OF_RESOURCES
;
746 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
747 if (NULL
== NewMenuEntry
) {
748 return EFI_OUT_OF_RESOURCES
;
751 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
752 NewLoadContext
->Deleted
= FALSE
;
753 NewLoadContext
->LoadOptionSize
= BufferSize
;
754 Ptr
= (UINT8
*) Buffer
;
755 NewLoadContext
->LoadOption
= Ptr
;
756 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
757 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
758 NewLoadContext
->IsActive
= TRUE
;
759 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
761 Ptr
+= sizeof (UINT32
);
762 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
763 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
764 Ptr
+= sizeof (UINT16
);
768 NvRamMap
->DescriptionData
,
769 StrSize (NvRamMap
->DescriptionData
)
772 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
773 ASSERT (NewLoadContext
->Description
!= NULL
);
775 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
777 NewLoadContext
->Description
,
779 StrSize (NvRamMap
->DescriptionData
)
782 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
785 CallbackData
->LoadContext
->FilePathList
,
786 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
789 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
790 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
793 NewLoadContext
->FilePathList
,
795 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
798 NewMenuEntry
->HelpString
= UiDevicePathToStr (NewLoadContext
->FilePathList
);
799 NewMenuEntry
->OptionNumber
= Index
;
800 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
802 BootOptionStrDepository
804 NewMenuEntry
->DisplayStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
806 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
808 BootOptionHelpStrDepository
810 NewMenuEntry
->HelpStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
812 if (OptionalDataExist
) {
813 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
815 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
818 Status
= gRT
->SetVariable (
820 &gEfiGlobalVariableGuid
,
825 ASSERT_EFI_ERROR (Status
);
827 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrderList
, &BootOrderListSize
);
828 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
829 ASSERT (NewBootOrderList
!= NULL
);
830 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
831 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
833 if (BootOrderList
!= NULL
) {
834 FreePool (BootOrderList
);
837 Status
= gRT
->SetVariable (
839 &gEfiGlobalVariableGuid
,
841 BootOrderListSize
+ sizeof (UINT16
),
844 ASSERT_EFI_ERROR (Status
);
846 FreePool (NewBootOrderList
);
847 NewBootOrderList
= NULL
;
848 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
849 BootOptionMenu
.MenuNumber
++;
851 NvRamMap
->DescriptionData
[0] = 0x0000;
852 NvRamMap
->OptionalData
[0] = 0x0000;
857 This function update the "BootNext" EFI Variable. If there is
858 no "BootNext" specified in BMM, this EFI Variable is deleted.
859 It also update the BMM context data specified the "BootNext"
862 @param CallbackData The BMM context data.
864 @retval EFI_SUCCESS The function complete successfully.
865 @return The EFI variable can be saved. See gRT->SetVariable
866 for detail return information.
871 IN BMM_CALLBACK_DATA
*CallbackData
874 BM_MENU_ENTRY
*NewMenuEntry
;
875 BM_LOAD_CONTEXT
*NewLoadContext
;
876 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
880 Status
= EFI_SUCCESS
;
881 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
882 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
883 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
884 ASSERT (NULL
!= NewMenuEntry
);
886 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
887 NewLoadContext
->IsBootNext
= FALSE
;
890 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
891 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
895 NewMenuEntry
= BOpt_GetMenuEntry (
897 CurrentFakeNVMap
->BootNext
899 ASSERT (NewMenuEntry
!= NULL
);
901 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
902 Status
= gRT
->SetVariable (
904 &gEfiGlobalVariableGuid
,
907 &NewMenuEntry
->OptionNumber
909 NewLoadContext
->IsBootNext
= TRUE
;
910 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
915 This function update the "BootOrder" EFI Variable based on
916 BMM Formset's NV map. It then refresh BootOptionMenu
917 with the new "BootOrder" list.
919 @param CallbackData The BMM context data.
921 @retval EFI_SUCCESS The function complete successfully.
922 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
923 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
927 Var_UpdateBootOrder (
928 IN BMM_CALLBACK_DATA
*CallbackData
939 // First check whether BootOrder is present in current configuration
941 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrder
, &BootOrderSize
);
942 if (BootOrder
== NULL
) {
943 return EFI_OUT_OF_RESOURCES
;
946 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
[0])));
949 // OptionOrder is subset of BootOrder
951 for (OrderIndex
= 0; (OrderIndex
< BootOptionMenu
.MenuNumber
) && (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] != 0); OrderIndex
++) {
952 for (Index
= OrderIndex
; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
953 if ((BootOrder
[Index
] == (UINT16
) (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] - 1)) && (OrderIndex
!= Index
)) {
954 OptionNumber
= BootOrder
[Index
];
955 CopyMem (&BootOrder
[OrderIndex
+ 1], &BootOrder
[OrderIndex
], (Index
- OrderIndex
) * sizeof (UINT16
));
956 BootOrder
[OrderIndex
] = OptionNumber
;
961 Status
= gRT
->SetVariable (
963 &gEfiGlobalVariableGuid
,
968 FreePool (BootOrder
);
970 BOpt_FreeMenu (&BootOptionMenu
);
971 BOpt_GetBootOptions (CallbackData
);
978 This function update the "DriverOrder" EFI Variable based on
979 BMM Formset's NV map. It then refresh DriverOptionMenu
980 with the new "DriverOrder" list.
982 @param CallbackData The BMM context data.
984 @retval EFI_SUCCESS The function complete successfully.
985 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
986 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
990 Var_UpdateDriverOrder (
991 IN BMM_CALLBACK_DATA
*CallbackData
996 UINT16
*DriverOrderList
;
997 UINT16
*NewDriverOrderList
;
998 UINTN DriverOrderListSize
;
1000 DriverOrderList
= NULL
;
1001 DriverOrderListSize
= 0;
1004 // First check whether DriverOrder is present in current configuration
1006 GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
1007 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1009 if (NewDriverOrderList
== NULL
) {
1010 return EFI_OUT_OF_RESOURCES
;
1013 // If exists, delete it to hold new DriverOrder
1015 if (DriverOrderList
!= NULL
) {
1016 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1017 FreePool (DriverOrderList
);
1020 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[0])));
1021 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1022 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[Index
] - 1);
1025 Status
= gRT
->SetVariable (
1027 &gEfiGlobalVariableGuid
,
1029 DriverOrderListSize
,
1032 if (EFI_ERROR (Status
)) {
1036 BOpt_FreeMenu (&DriverOptionMenu
);
1037 BOpt_GetDriverOptions (CallbackData
);
1042 Update the Text Mode of Console.
1044 @param CallbackData The context data for BMM.
1046 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1047 @return Other value if the Text Mode of Console is not updated.
1052 IN BMM_CALLBACK_DATA
*CallbackData
1057 CONSOLE_OUT_MODE ModeInfo
;
1059 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1061 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1062 if (!EFI_ERROR(Status
)) {
1063 PcdSet32 (PcdSetupConOutColumn
, (UINT32
) ModeInfo
.Column
);
1064 PcdSet32 (PcdSetupConOutRow
, (UINT32
) ModeInfo
.Row
);