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 StrCpyS (DescriptionData
, MAX_MENU_NUMBER
, 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 if (DriverOrderList
!= NULL
){
666 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
668 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
669 if (DriverOrderList
!= NULL
) {
670 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
673 Status
= gRT
->SetVariable (
675 &gEfiGlobalVariableGuid
,
677 DriverOrderListSize
+ sizeof (UINT16
),
680 ASSERT_EFI_ERROR (Status
);
681 if (DriverOrderList
!= NULL
) {
682 FreePool (DriverOrderList
);
684 DriverOrderList
= NULL
;
685 FreePool (NewDriverOrderList
);
686 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
687 DriverOptionMenu
.MenuNumber
++;
689 *DescriptionData
= 0x0000;
690 *OptionalData
= 0x0000;
695 This function create a currently loaded Boot Option from
696 the BMM. It then appends this Boot Option to the end of
697 the "BootOrder" list. It also append this Boot Opotion to the end
700 @param CallbackData The BMM context data.
701 @param NvRamMap The file explorer formset internal state.
703 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
704 @retval EFI_SUCCESS If function completes successfully.
708 Var_UpdateBootOption (
709 IN BMM_CALLBACK_DATA
*CallbackData
,
710 IN FILE_EXPLORER_NV_DATA
*NvRamMap
713 UINT16
*BootOrderList
;
714 UINT16
*NewBootOrderList
;
715 UINTN BootOrderListSize
;
716 UINT16 BootString
[10];
721 BM_MENU_ENTRY
*NewMenuEntry
;
722 BM_LOAD_CONTEXT
*NewLoadContext
;
723 BOOLEAN OptionalDataExist
;
726 OptionalDataExist
= FALSE
;
728 Index
= BOpt_GetBootOptionNumber () ;
729 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
731 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
732 StrCpyS (NvRamMap
->DescriptionData
, sizeof (NvRamMap
->DescriptionData
) / sizeof (NvRamMap
->DescriptionData
[0]), BootString
);
735 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
736 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
738 if (NvRamMap
->OptionalData
[0] != 0x0000) {
739 OptionalDataExist
= TRUE
;
740 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
743 Buffer
= AllocateZeroPool (BufferSize
);
744 if (NULL
== Buffer
) {
745 return EFI_OUT_OF_RESOURCES
;
748 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
749 if (NULL
== NewMenuEntry
) {
750 return EFI_OUT_OF_RESOURCES
;
753 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
754 NewLoadContext
->Deleted
= FALSE
;
755 NewLoadContext
->LoadOptionSize
= BufferSize
;
756 Ptr
= (UINT8
*) Buffer
;
757 NewLoadContext
->LoadOption
= Ptr
;
758 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
759 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
760 NewLoadContext
->IsActive
= TRUE
;
761 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
763 Ptr
+= sizeof (UINT32
);
764 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
765 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
766 Ptr
+= sizeof (UINT16
);
770 NvRamMap
->DescriptionData
,
771 StrSize (NvRamMap
->DescriptionData
)
774 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
775 ASSERT (NewLoadContext
->Description
!= NULL
);
777 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
779 NewLoadContext
->Description
,
781 StrSize (NvRamMap
->DescriptionData
)
784 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
787 CallbackData
->LoadContext
->FilePathList
,
788 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
791 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
792 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
795 NewLoadContext
->FilePathList
,
797 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
800 NewMenuEntry
->HelpString
= UiDevicePathToStr (NewLoadContext
->FilePathList
);
801 NewMenuEntry
->OptionNumber
= Index
;
802 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
804 BootOptionStrDepository
806 NewMenuEntry
->DisplayStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
808 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
810 BootOptionHelpStrDepository
812 NewMenuEntry
->HelpStringToken
= HiiSetString (CallbackData
->FeHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
814 if (OptionalDataExist
) {
815 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
817 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
820 Status
= gRT
->SetVariable (
822 &gEfiGlobalVariableGuid
,
827 ASSERT_EFI_ERROR (Status
);
829 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrderList
, &BootOrderListSize
);
830 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
831 ASSERT (NewBootOrderList
!= NULL
);
832 if (BootOrderList
!= NULL
){
833 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
835 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
837 if (BootOrderList
!= NULL
) {
838 FreePool (BootOrderList
);
841 Status
= gRT
->SetVariable (
843 &gEfiGlobalVariableGuid
,
845 BootOrderListSize
+ sizeof (UINT16
),
848 ASSERT_EFI_ERROR (Status
);
850 FreePool (NewBootOrderList
);
851 NewBootOrderList
= NULL
;
852 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
853 BootOptionMenu
.MenuNumber
++;
855 NvRamMap
->DescriptionData
[0] = 0x0000;
856 NvRamMap
->OptionalData
[0] = 0x0000;
861 This function update the "BootNext" EFI Variable. If there is
862 no "BootNext" specified in BMM, this EFI Variable is deleted.
863 It also update the BMM context data specified the "BootNext"
866 @param CallbackData The BMM context data.
868 @retval EFI_SUCCESS The function complete successfully.
869 @return The EFI variable can be saved. See gRT->SetVariable
870 for detail return information.
875 IN BMM_CALLBACK_DATA
*CallbackData
878 BM_MENU_ENTRY
*NewMenuEntry
;
879 BM_LOAD_CONTEXT
*NewLoadContext
;
880 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
884 Status
= EFI_SUCCESS
;
885 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
886 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
887 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
888 ASSERT (NULL
!= NewMenuEntry
);
890 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
891 NewLoadContext
->IsBootNext
= FALSE
;
894 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
895 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
899 NewMenuEntry
= BOpt_GetMenuEntry (
901 CurrentFakeNVMap
->BootNext
903 ASSERT (NewMenuEntry
!= NULL
);
905 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
906 Status
= gRT
->SetVariable (
908 &gEfiGlobalVariableGuid
,
911 &NewMenuEntry
->OptionNumber
913 NewLoadContext
->IsBootNext
= TRUE
;
914 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
919 This function update the "BootOrder" EFI Variable based on
920 BMM Formset's NV map. It then refresh BootOptionMenu
921 with the new "BootOrder" list.
923 @param CallbackData The BMM context data.
925 @retval EFI_SUCCESS The function complete successfully.
926 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
927 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
931 Var_UpdateBootOrder (
932 IN BMM_CALLBACK_DATA
*CallbackData
943 // First check whether BootOrder is present in current configuration
945 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrder
, &BootOrderSize
);
946 if (BootOrder
== NULL
) {
947 return EFI_OUT_OF_RESOURCES
;
950 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.BootOptionOrder
[0])));
953 // OptionOrder is subset of BootOrder
955 for (OrderIndex
= 0; (OrderIndex
< BootOptionMenu
.MenuNumber
) && (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] != 0); OrderIndex
++) {
956 for (Index
= OrderIndex
; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
957 if ((BootOrder
[Index
] == (UINT16
) (CallbackData
->BmmFakeNvData
.BootOptionOrder
[OrderIndex
] - 1)) && (OrderIndex
!= Index
)) {
958 OptionNumber
= BootOrder
[Index
];
959 CopyMem (&BootOrder
[OrderIndex
+ 1], &BootOrder
[OrderIndex
], (Index
- OrderIndex
) * sizeof (UINT16
));
960 BootOrder
[OrderIndex
] = OptionNumber
;
965 Status
= gRT
->SetVariable (
967 &gEfiGlobalVariableGuid
,
972 FreePool (BootOrder
);
974 BOpt_FreeMenu (&BootOptionMenu
);
975 BOpt_GetBootOptions (CallbackData
);
982 This function update the "DriverOrder" EFI Variable based on
983 BMM Formset's NV map. It then refresh DriverOptionMenu
984 with the new "DriverOrder" list.
986 @param CallbackData The BMM context data.
988 @retval EFI_SUCCESS The function complete successfully.
989 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
990 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
994 Var_UpdateDriverOrder (
995 IN BMM_CALLBACK_DATA
*CallbackData
1000 UINT16
*DriverOrderList
;
1001 UINT16
*NewDriverOrderList
;
1002 UINTN DriverOrderListSize
;
1004 DriverOrderList
= NULL
;
1005 DriverOrderListSize
= 0;
1008 // First check whether DriverOrder is present in current configuration
1010 GetEfiGlobalVariable2 (L
"DriverOrder", (VOID
**) &DriverOrderList
, &DriverOrderListSize
);
1011 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1013 if (NewDriverOrderList
== NULL
) {
1014 return EFI_OUT_OF_RESOURCES
;
1017 // If exists, delete it to hold new DriverOrder
1019 if (DriverOrderList
!= NULL
) {
1020 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1021 FreePool (DriverOrderList
);
1024 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
) / sizeof (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[0])));
1025 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1026 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.DriverOptionOrder
[Index
] - 1);
1029 Status
= gRT
->SetVariable (
1031 &gEfiGlobalVariableGuid
,
1033 DriverOrderListSize
,
1036 if (EFI_ERROR (Status
)) {
1040 BOpt_FreeMenu (&DriverOptionMenu
);
1041 BOpt_GetDriverOptions (CallbackData
);
1046 Update the Text Mode of Console.
1048 @param CallbackData The context data for BMM.
1050 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1051 @return Other value if the Text Mode of Console is not updated.
1056 IN BMM_CALLBACK_DATA
*CallbackData
1061 CONSOLE_OUT_MODE ModeInfo
;
1063 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1065 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1066 if (!EFI_ERROR(Status
)) {
1067 PcdSet32 (PcdSetupConOutColumn
, (UINT32
) ModeInfo
.Column
);
1068 PcdSet32 (PcdSetupConOutRow
, (UINT32
) ModeInfo
.Row
);