2 Variable operation that will be used by bootmaint
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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.
23 @param VOID EDES_TODO: Add parameter description
25 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
26 BM_LOAD_CONTEXT marked for deletion is deleted
27 @return Others If failed to update the "BootOrder" variable after deletion.
35 BM_MENU_ENTRY
*NewMenuEntry
;
36 BM_LOAD_CONTEXT
*NewLoadContext
;
37 UINT16 BootString
[10];
44 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
45 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
46 if (NULL
== NewMenuEntry
) {
50 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
51 if (!NewLoadContext
->Deleted
) {
59 NewMenuEntry
->OptionNumber
62 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
65 // If current Load Option is the same as BootNext,
66 // must delete BootNext in order to make sure
67 // there will be no panic on next boot
69 if (NewLoadContext
->IsBootNext
) {
70 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
73 RemoveEntryList (&NewMenuEntry
->Link
);
74 BOpt_DestroyMenuEntry (NewMenuEntry
);
78 BootOptionMenu
.MenuNumber
-= Index2
;
80 Status
= Var_ChangeBootOrder ();
85 After any operation on Boot####, there will be a discrepancy in BootOrder.
86 Since some are missing but in BootOrder, while some are present but are
87 not reflected by BootOrder. Then a function rebuild BootOrder from
88 scratch by content from BootOptionMenu is needed.
93 @retval EFI_SUCCESS The boot order is updated successfully.
94 @return EFI_STATUS other than EFI_SUCCESS if failed to
95 Set the "BootOrder" EFI Variable.
105 BM_MENU_ENTRY
*NewMenuEntry
;
106 UINT16
*BootOrderList
;
107 UINT16
*BootOrderListPtr
;
108 UINTN BootOrderListSize
;
111 BootOrderList
= NULL
;
112 BootOrderListSize
= 0;
115 // First check whether BootOrder is present in current configuration
117 BootOrderList
= BdsLibGetVariableAndSize (
119 &gEfiGlobalVariableGuid
,
124 // If exists, delete it to hold new BootOrder
126 if (BootOrderList
!= NULL
) {
127 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
128 SafeFreePool (BootOrderList
);
129 BootOrderList
= NULL
;
132 // Maybe here should be some check method to ensure that
133 // no new added boot options will be added
134 // but the setup engine now will give only one callback
135 // that is to say, user are granted only one chance to
136 // decide whether the boot option will be added or not
137 // there should be no indictor to show whether this
138 // is a "new" boot option
140 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
142 if (BootOrderListSize
> 0) {
143 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
144 ASSERT (BootOrderList
!= NULL
);
145 BootOrderListPtr
= BootOrderList
;
148 // Get all current used Boot#### from BootOptionMenu.
149 // OptionNumber in each BM_LOAD_OPTION is really its
152 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
153 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
154 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
158 BootOrderList
= BootOrderListPtr
;
161 // After building the BootOrderList, write it back
163 Status
= gRT
->SetVariable (
165 &gEfiGlobalVariableGuid
,
167 BootOrderListSize
* sizeof (UINT16
),
170 if (EFI_ERROR (Status
)) {
178 Delete Load Option that represent a Deleted state in BootOptionMenu.
179 After deleting this Driver option, call Var_ChangeDriverOrder to
180 make sure DriverOrder is in valid state.
185 @retval EFI_SUCCESS Load Option is successfully updated.
186 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
191 Var_DelDriverOption (
195 BM_MENU_ENTRY
*NewMenuEntry
;
196 BM_LOAD_CONTEXT
*NewLoadContext
;
197 UINT16 DriverString
[12];
202 Status
= EFI_SUCCESS
;
204 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
205 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
206 if (NULL
== NewMenuEntry
) {
207 return EFI_NOT_FOUND
;
210 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
211 if (!NewLoadContext
->Deleted
) {
217 sizeof (DriverString
),
219 NewMenuEntry
->OptionNumber
222 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
225 RemoveEntryList (&NewMenuEntry
->Link
);
226 BOpt_DestroyMenuEntry (NewMenuEntry
);
230 DriverOptionMenu
.MenuNumber
-= Index2
;
232 Status
= Var_ChangeDriverOrder ();
237 After any operation on Driver####, there will be a discrepancy in
238 DriverOrder. Since some are missing but in DriverOrder, while some
239 are present but are not reflected by DriverOrder. Then a function
240 rebuild DriverOrder from scratch by content from DriverOptionMenu is
246 @retval EFI_SUCCESS The driver order is updated successfully.
247 @return EFI_STATUS other than EFI_SUCCESS if failed to
248 Set the "DriverOrder" EFI Variable.
252 Var_ChangeDriverOrder (
257 BM_MENU_ENTRY
*NewMenuEntry
;
258 UINT16
*DriverOrderList
;
259 UINT16
*DriverOrderListPtr
;
260 UINTN DriverOrderListSize
;
263 DriverOrderList
= NULL
;
264 DriverOrderListSize
= 0;
267 // First check whether DriverOrder is present in current configuration
269 DriverOrderList
= BdsLibGetVariableAndSize (
271 &gEfiGlobalVariableGuid
,
276 // If exists, delete it to hold new DriverOrder
278 if (DriverOrderList
!= NULL
) {
279 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
280 SafeFreePool (DriverOrderList
);
281 DriverOrderList
= NULL
;
284 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
286 if (DriverOrderListSize
> 0) {
287 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
288 ASSERT (DriverOrderList
!= NULL
);
289 DriverOrderListPtr
= DriverOrderList
;
292 // Get all current used Driver#### from DriverOptionMenu.
293 // OptionNumber in each BM_LOAD_OPTION is really its
296 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
297 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
298 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
302 DriverOrderList
= DriverOrderListPtr
;
305 // After building the DriverOrderList, write it back
307 Status
= gRT
->SetVariable (
309 &gEfiGlobalVariableGuid
,
311 DriverOrderListSize
* sizeof (UINT16
),
314 if (EFI_ERROR (Status
)) {
322 Update the device path of "ConOut", "ConIn" and "ErrOut"
323 based on the new BaudRate, Data Bits, parity and Stop Bits
332 Var_UpdateAllConsoleOption (
336 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
337 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
338 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
341 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
342 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
343 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
344 if (OutDevicePath
!= NULL
) {
345 ChangeVariableDevicePath (OutDevicePath
);
346 Status
= gRT
->SetVariable (
348 &gEfiGlobalVariableGuid
,
350 GetDevicePathSize (OutDevicePath
),
353 ASSERT (!EFI_ERROR (Status
));
356 if (InpDevicePath
!= NULL
) {
357 ChangeVariableDevicePath (InpDevicePath
);
358 Status
= gRT
->SetVariable (
360 &gEfiGlobalVariableGuid
,
362 GetDevicePathSize (InpDevicePath
),
365 ASSERT (!EFI_ERROR (Status
));
368 if (ErrDevicePath
!= NULL
) {
369 ChangeVariableDevicePath (ErrDevicePath
);
370 Status
= gRT
->SetVariable (
372 &gEfiGlobalVariableGuid
,
374 GetDevicePathSize (ErrDevicePath
),
377 ASSERT (!EFI_ERROR (Status
));
382 This function delete and build multi-instance device path for
383 specified type of console device.
385 This function clear the EFI variable defined by ConsoleName and
386 gEfiGlobalVariableGuid. It then build the multi-instance device
387 path by appending the device path of the Console (In/Out/Err) instance
388 in ConsoleMenu. Then it scan all corresponding console device by
389 scanning Terminal (built from device supporting Serial I/O instances)
390 devices in TerminalMenu. At last, it save a EFI variable specifed
391 by ConsoleName and gEfiGlobalVariableGuid.
393 @param ConsoleName The name for the console device type. They are
394 usually "ConIn", "ConOut" and "ErrOut".
395 @param ConsoleMenu The console memu which is a list of console devices.
396 @param UpdatePageId The flag specifying which type of console device
399 @retval EFI_SUCCESS The function complete successfully.
400 @return The EFI variable can be saved. See gRT->SetVariable
401 for detail return information.
405 Var_UpdateConsoleOption (
406 IN UINT16
*ConsoleName
,
407 IN BM_MENU_OPTION
*ConsoleMenu
,
408 IN UINT16 UpdatePageId
411 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
412 BM_MENU_ENTRY
*NewMenuEntry
;
413 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
414 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
416 VENDOR_DEVICE_PATH Vendor
;
417 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
420 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
421 if (ConDevicePath
!= NULL
) {
422 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
423 SafeFreePool (ConDevicePath
);
424 ConDevicePath
= NULL
;
428 // First add all console input device from console input menu
430 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
431 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
433 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
434 if (NewConsoleContext
->IsActive
) {
435 ConDevicePath
= AppendDevicePathInstance (
437 NewConsoleContext
->DevicePath
442 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
443 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
445 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
446 if (((NewTerminalContext
->IsConIn
!= 0) && (UpdatePageId
== FORM_CON_IN_ID
)) ||
447 ((NewTerminalContext
->IsConOut
!= 0) && (UpdatePageId
== FORM_CON_OUT_ID
)) ||
448 ((NewTerminalContext
->IsStdErr
!= 0) && (UpdatePageId
== FORM_CON_ERR_ID
))
450 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
451 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
454 &TerminalTypeGuid
[NewTerminalContext
->TerminalType
],
457 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
458 TerminalDevicePath
= AppendDevicePathNode (
459 NewTerminalContext
->DevicePath
,
460 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
462 ASSERT (TerminalDevicePath
!= NULL
);
463 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
464 ConDevicePath
= AppendDevicePathInstance (
471 if (ConDevicePath
!= NULL
) {
472 Status
= gRT
->SetVariable (
474 &gEfiGlobalVariableGuid
,
476 GetDevicePathSize (ConDevicePath
),
479 if (EFI_ERROR (Status
)) {
489 This function delete and build multi-instance device path ConIn
495 @retval EFI_SUCCESS The function complete successfully.
496 @return The EFI variable can be saved. See gRT->SetVariable
497 for detail return information.
500 Var_UpdateConsoleInpOption (
504 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
508 This function delete and build multi-instance device path ConOut
514 @retval EFI_SUCCESS The function complete successfully.
515 @return The EFI variable can be saved. See gRT->SetVariable
516 for detail return information.
519 Var_UpdateConsoleOutOption (
523 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
527 This function delete and build multi-instance device path ErrOut
533 @retval EFI_SUCCESS The function complete successfully.
534 @return The EFI variable can be saved. See gRT->SetVariable
535 for detail return information.
538 Var_UpdateErrorOutOption (
542 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
546 This function create a currently loaded Drive Option from
547 the BMM. It then appends this Driver Option to the end of
548 the "DriverOrder" list. It append this Driver Opotion to the end
551 @param CallbackData The BMM context data.
552 @param HiiHandle The HII handle associated with the BMM formset.
553 @param DescriptionData The description of this driver option.
554 @param OptionalData The optional load option.
555 @param ForceReconnect EDES_TODO: Add parameter description
557 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
558 @retval EFI_SUCCESS If function completes successfully.
562 Var_UpdateDriverOption (
563 IN BMM_CALLBACK_DATA
*CallbackData
,
564 IN EFI_HII_HANDLE HiiHandle
,
565 IN UINT16
*DescriptionData
,
566 IN UINT16
*OptionalData
,
567 IN UINT8 ForceReconnect
571 UINT16
*DriverOrderList
;
572 UINT16
*NewDriverOrderList
;
573 UINT16 DriverString
[12];
574 UINTN DriverOrderListSize
;
578 BM_MENU_ENTRY
*NewMenuEntry
;
579 BM_LOAD_CONTEXT
*NewLoadContext
;
580 BOOLEAN OptionalDataExist
;
583 OptionalDataExist
= FALSE
;
585 Index
= BOpt_GetDriverOptionNumber ();
588 sizeof (DriverString
),
593 if (*DescriptionData
== 0x0000) {
594 StrCpy (DescriptionData
, DriverString
);
597 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
598 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
600 if (*OptionalData
!= 0x0000) {
601 OptionalDataExist
= TRUE
;
602 BufferSize
+= StrSize (OptionalData
);
605 Buffer
= AllocateZeroPool (BufferSize
);
606 if (NULL
== Buffer
) {
607 return EFI_OUT_OF_RESOURCES
;
610 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
611 if (NULL
== NewMenuEntry
) {
612 return EFI_OUT_OF_RESOURCES
;
615 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
616 NewLoadContext
->Deleted
= FALSE
;
617 NewLoadContext
->LoadOptionSize
= BufferSize
;
618 Ptr
= (UINT8
*) Buffer
;
619 NewLoadContext
->LoadOption
= Ptr
;
620 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
621 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
622 NewLoadContext
->IsActive
= TRUE
;
623 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
625 Ptr
+= sizeof (UINT32
);
626 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
627 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
629 Ptr
+= sizeof (UINT16
);
633 StrSize (DescriptionData
)
636 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
637 ASSERT (NewLoadContext
->Description
!= NULL
);
638 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
640 NewLoadContext
->Description
,
642 StrSize (DescriptionData
)
645 Ptr
+= StrSize (DescriptionData
);
648 CallbackData
->LoadContext
->FilePathList
,
649 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
652 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
653 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
656 NewLoadContext
->FilePathList
,
658 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
661 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
662 NewMenuEntry
->OptionNumber
= Index
;
663 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
665 DriverOptionStrDepository
667 HiiLibNewString (HiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
669 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
671 DriverOptionHelpStrDepository
673 HiiLibNewString (HiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
675 if (OptionalDataExist
) {
676 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
681 StrSize (OptionalData
)
685 Status
= gRT
->SetVariable (
687 &gEfiGlobalVariableGuid
,
692 ASSERT_EFI_ERROR (Status
);
693 DriverOrderList
= BdsLibGetVariableAndSize (
695 &gEfiGlobalVariableGuid
,
698 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
699 ASSERT (NewDriverOrderList
!= NULL
);
700 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
701 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
702 if (DriverOrderList
!= NULL
) {
703 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
706 Status
= gRT
->SetVariable (
708 &gEfiGlobalVariableGuid
,
710 DriverOrderListSize
+ sizeof (UINT16
),
713 ASSERT_EFI_ERROR (Status
);
714 SafeFreePool (DriverOrderList
);
715 DriverOrderList
= NULL
;
716 SafeFreePool (NewDriverOrderList
);
717 NewDriverOrderList
= NULL
;
718 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
719 DriverOptionMenu
.MenuNumber
++;
721 *DescriptionData
= 0x0000;
722 *OptionalData
= 0x0000;
727 This function create a currently loaded Boot Option from
728 the BMM. It then appends this Boot Option to the end of
729 the "BootOrder" list. It also append this Boot Opotion to the end
732 @param CallbackData The BMM context data.
733 @param NvRamMap The file explorer formset internal state.
735 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
736 @retval EFI_SUCCESS If function completes successfully.
741 Var_UpdateBootOption (
742 IN BMM_CALLBACK_DATA
*CallbackData
,
743 IN FILE_EXPLORER_NV_DATA
*NvRamMap
746 UINT16
*BootOrderList
;
747 UINT16
*NewBootOrderList
;
748 UINTN BootOrderListSize
;
749 UINT16 BootString
[10];
754 BM_MENU_ENTRY
*NewMenuEntry
;
755 BM_LOAD_CONTEXT
*NewLoadContext
;
756 BOOLEAN OptionalDataExist
;
759 OptionalDataExist
= FALSE
;
761 Index
= BOpt_GetBootOptionNumber () ;
762 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
764 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
765 StrCpy (NvRamMap
->DescriptionData
, BootString
);
768 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
769 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
771 if (NvRamMap
->OptionalData
[0] != 0x0000) {
772 OptionalDataExist
= TRUE
;
773 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
776 Buffer
= AllocateZeroPool (BufferSize
);
777 if (NULL
== Buffer
) {
778 return EFI_OUT_OF_RESOURCES
;
781 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
782 if (NULL
== NewMenuEntry
) {
783 return EFI_OUT_OF_RESOURCES
;
786 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
787 NewLoadContext
->Deleted
= FALSE
;
788 NewLoadContext
->LoadOptionSize
= BufferSize
;
789 Ptr
= (UINT8
*) Buffer
;
790 NewLoadContext
->LoadOption
= Ptr
;
791 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
792 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
793 NewLoadContext
->IsActive
= TRUE
;
794 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
796 Ptr
+= sizeof (UINT32
);
797 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
798 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
799 Ptr
+= sizeof (UINT16
);
803 NvRamMap
->DescriptionData
,
804 StrSize (NvRamMap
->DescriptionData
)
807 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
808 ASSERT (NewLoadContext
->Description
!= NULL
);
810 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
812 NewLoadContext
->Description
,
814 StrSize (NvRamMap
->DescriptionData
)
817 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
820 CallbackData
->LoadContext
->FilePathList
,
821 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
824 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
825 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
828 NewLoadContext
->FilePathList
,
830 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
833 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
834 NewMenuEntry
->OptionNumber
= Index
;
835 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
837 BootOptionStrDepository
839 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
841 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
843 BootOptionHelpStrDepository
845 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
847 if (OptionalDataExist
) {
848 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
850 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
853 Status
= gRT
->SetVariable (
855 &gEfiGlobalVariableGuid
,
860 ASSERT_EFI_ERROR (Status
);
862 BootOrderList
= BdsLibGetVariableAndSize (
864 &gEfiGlobalVariableGuid
,
868 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
869 ASSERT (NewBootOrderList
!= NULL
);
870 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
871 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
873 if (BootOrderList
!= NULL
) {
874 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
877 Status
= gRT
->SetVariable (
879 &gEfiGlobalVariableGuid
,
881 BootOrderListSize
+ sizeof (UINT16
),
884 ASSERT_EFI_ERROR (Status
);
886 SafeFreePool (BootOrderList
);
887 BootOrderList
= NULL
;
888 SafeFreePool (NewBootOrderList
);
889 NewBootOrderList
= NULL
;
890 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
891 BootOptionMenu
.MenuNumber
++;
893 NvRamMap
->DescriptionData
[0] = 0x0000;
894 NvRamMap
->OptionalData
[0] = 0x0000;
899 This function update the "BootNext" EFI Variable. If there is
900 no "BootNex" specified in BMM, this EFI Variable is deleted.
901 It also update the BMM context data specified the "BootNext"
904 @param CallbackData The BMM context data.
906 @retval EFI_SUCCESS The function complete successfully.
907 @return The EFI variable can be saved. See gRT->SetVariable
908 for detail return information.
913 IN BMM_CALLBACK_DATA
*CallbackData
916 BM_MENU_ENTRY
*NewMenuEntry
;
917 BM_LOAD_CONTEXT
*NewLoadContext
;
918 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
922 Status
= EFI_SUCCESS
;
923 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
924 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
925 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
926 ASSERT (NULL
!= NewMenuEntry
);
928 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
929 NewLoadContext
->IsBootNext
= FALSE
;
932 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
933 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
937 NewMenuEntry
= BOpt_GetMenuEntry (
939 CurrentFakeNVMap
->BootNext
941 ASSERT (NewMenuEntry
!= NULL
);
943 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
944 Status
= gRT
->SetVariable (
946 &gEfiGlobalVariableGuid
,
949 &NewMenuEntry
->OptionNumber
951 NewLoadContext
->IsBootNext
= TRUE
;
952 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
957 This function update the "BootOrder" EFI Variable based on
958 BMM Formset's NV map. It then refresh BootOptionMenu
959 with the new "BootOrder" list.
961 @param CallbackData The BMM context data.
963 @retval EFI_SUCCESS The function complete successfully.
964 @retval EFI_SUCCESS Not enough memory to complete the function.
965 @return The EFI variable can be saved. See gRT->SetVariable
966 for detail return information.
970 Var_UpdateBootOrder (
971 IN BMM_CALLBACK_DATA
*CallbackData
976 UINT16
*BootOrderList
;
977 UINT16
*NewBootOrderList
;
978 UINTN BootOrderListSize
;
980 BootOrderList
= NULL
;
981 BootOrderListSize
= 0;
984 // First check whether BootOrder is present in current configuration
986 BootOrderList
= BdsLibGetVariableAndSize (
988 &gEfiGlobalVariableGuid
,
992 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
993 if (NewBootOrderList
== NULL
) {
994 return EFI_OUT_OF_RESOURCES
;
998 // If exists, delete it to hold new BootOrder
1000 if (BootOrderList
!= NULL
) {
1001 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
1004 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1005 NewBootOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
1008 Status
= gRT
->SetVariable (
1010 &gEfiGlobalVariableGuid
,
1015 SafeFreePool (BootOrderList
);
1016 SafeFreePool (NewBootOrderList
);
1017 if (EFI_ERROR (Status
)) {
1021 BOpt_FreeMenu (&BootOptionMenu
);
1022 BOpt_GetBootOptions (CallbackData
);
1029 This function update the "DriverOrder" EFI Variable based on
1030 BMM Formset's NV map. It then refresh DriverOptionMenu
1031 with the new "DriverOrder" list.
1033 @param CallbackData The BMM context data.
1035 @retval EFI_SUCCESS The function complete successfully.
1036 @retval EFI_SUCCESS Not enough memory to complete the function.
1037 @return The EFI variable can be saved. See gRT->SetVariable
1038 for detail return information.
1042 Var_UpdateDriverOrder (
1043 IN BMM_CALLBACK_DATA
*CallbackData
1048 UINT16
*DriverOrderList
;
1049 UINT16
*NewDriverOrderList
;
1050 UINTN DriverOrderListSize
;
1052 DriverOrderList
= NULL
;
1053 DriverOrderListSize
= 0;
1056 // First check whether DriverOrder is present in current configuration
1058 DriverOrderList
= BdsLibGetVariableAndSize (
1060 &gEfiGlobalVariableGuid
,
1061 &DriverOrderListSize
1064 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1066 if (NewDriverOrderList
== NULL
) {
1067 return EFI_OUT_OF_RESOURCES
;
1070 // If exists, delete it to hold new DriverOrder
1072 if (DriverOrderList
!= NULL
) {
1073 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1076 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
1077 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
1080 Status
= gRT
->SetVariable (
1082 &gEfiGlobalVariableGuid
,
1084 DriverOrderListSize
,
1087 if (EFI_ERROR (Status
)) {
1091 SafeFreePool (DriverOrderList
);
1093 BOpt_FreeMenu (&DriverOptionMenu
);
1094 BOpt_GetDriverOptions (CallbackData
);
1099 Update the legacy BBS boot option. L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable
1100 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
1103 @param CallbackData The context data for BMM.
1105 @return EFI_SUCCESS The function completed successfully.
1106 @retval EFI_NOT_FOUND If L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable can be found.
1110 Var_UpdateBBSOption (
1111 IN BMM_CALLBACK_DATA
*CallbackData
1116 VOID
*BootOptionVar
;
1117 CHAR16 VarName
[100];
1121 CHAR16 DescString
[100];
1122 CHAR8 DescAsciiString
[100];
1123 UINTN NewOptionSize
;
1124 UINT8
*NewOptionPtr
;
1127 BM_MENU_OPTION
*OptionMenu
;
1128 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1132 BM_MENU_ENTRY
*NewMenuEntry
;
1133 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1141 LegacyDeviceContext
= NULL
;
1145 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1146 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1147 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1148 CallbackData
->BbsType
= BBS_FLOPPY
;
1150 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1151 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1152 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1153 CallbackData
->BbsType
= BBS_HARDDISK
;
1155 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1156 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1157 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1158 CallbackData
->BbsType
= BBS_CDROM
;
1160 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1161 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1162 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1163 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1165 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1166 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1167 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1173 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1174 Status
= EFI_SUCCESS
;
1177 // Find the first device's context
1178 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1179 // because we just use it to fill the desc string, and user can not see the string in UI
1181 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1182 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1183 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1184 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1185 DEBUG ((DEBUG_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1190 // Update the Variable "LegacyDevOrder"
1192 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1193 VAR_LEGACY_DEV_ORDER
,
1194 &EfiLegacyDevOrderGuid
,
1198 if (NULL
== VarData
) {
1199 return EFI_NOT_FOUND
;
1202 OriginalPtr
= VarData
;
1203 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1205 while (VarData
< VarData
+ VarSize
) {
1206 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1210 VarData
+= sizeof (BBS_TYPE
);
1211 VarData
+= *(UINT16
*) VarData
;
1212 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1215 if (VarData
>= VarData
+ VarSize
) {
1216 SafeFreePool (OriginalPtr
);
1217 return EFI_NOT_FOUND
;
1220 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1221 if (NULL
== NewOrder
) {
1222 SafeFreePool (VarData
);
1223 return EFI_OUT_OF_RESOURCES
;
1226 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1227 if (0xFF == LegacyDev
[Index
]) {
1231 NewOrder
[Index
] = LegacyDev
[Index
];
1234 // Only the enable/disable state of each boot device with same device type can be changed,
1235 // so we can count on the index information in DevOrder.
1236 // DisMap bit array is the only reliable source to check a device's en/dis state,
1237 // so we use DisMap to set en/dis state of each item in NewOrder array
1239 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1240 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1243 Bit
= 7 - (Tmp
% 8);
1244 if ((DisMap
[Pos
] & (1 << Bit
)) != 0) {
1245 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1251 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1253 DevOrder
->Length
- sizeof (UINT16
)
1255 SafeFreePool (NewOrder
);
1257 Status
= gRT
->SetVariable (
1258 VAR_LEGACY_DEV_ORDER
,
1259 &EfiLegacyDevOrderGuid
,
1265 SafeFreePool (OriginalPtr
);
1268 // Update Optional Data of Boot####
1270 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1272 if (NULL
!= BootOptionVar
) {
1275 LegacyDeviceContext
->Description
,
1276 StrSize (LegacyDeviceContext
->Description
)
1279 UnicodeToAscii (DescString
, StrSize (DescString
), DescAsciiString
);
1281 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) +
1282 sizeof (BBS_BBS_DEVICE_PATH
);
1283 NewOptionSize
+= AsciiStrLen (DescAsciiString
) +
1284 EFI_END_DEVICE_PATH_LENGTH
+ sizeof (BBS_TABLE
) + sizeof (UINT16
);
1286 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1288 Ptr
= BootOptionVar
;
1290 Attribute
= (UINT32
*) Ptr
;
1291 *Attribute
|= LOAD_OPTION_ACTIVE
;
1292 if (0xFF == LegacyDev
[0]) {
1294 // Disable this legacy boot option
1296 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1299 Ptr
+= sizeof (UINT32
);
1301 Ptr
+= sizeof (UINT16
);
1302 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1304 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1305 if (NULL
== NewOptionPtr
) {
1306 return EFI_OUT_OF_RESOURCES
;
1309 TempPtr
= NewOptionPtr
;
1320 TempPtr
+= sizeof (UINT32
);
1323 // BBS device path Length
1325 *((UINT16
*) TempPtr
) = (UINT16
) (sizeof (BBS_BBS_DEVICE_PATH
) +
1326 AsciiStrLen (DescAsciiString
) +
1327 EFI_END_DEVICE_PATH_LENGTH
);
1329 TempPtr
+= sizeof (UINT16
);
1332 // Description string
1337 StrSize (DescString
)
1340 TempPtr
+= StrSize (DescString
);
1348 sizeof (BBS_BBS_DEVICE_PATH
)
1352 ((BBS_BBS_DEVICE_PATH
*) TempPtr
)->String
,
1354 AsciiStrSize (DescAsciiString
)
1357 SetDevicePathNodeLength (
1358 (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
,
1359 sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
)
1362 TempPtr
+= sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
);
1370 EFI_END_DEVICE_PATH_LENGTH
1372 TempPtr
+= EFI_END_DEVICE_PATH_LENGTH
;
1375 // Now TempPtr point to optional data, i.e. Bbs Table
1379 LegacyDeviceContext
->BbsTable
,
1384 // Now TempPtr point to BBS index
1386 TempPtr
+= sizeof (BBS_TABLE
);
1387 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1389 Status
= gRT
->SetVariable (
1391 &gEfiGlobalVariableGuid
,
1397 SafeFreePool (NewOptionPtr
);
1398 SafeFreePool (BootOptionVar
);
1401 BOpt_GetBootOptions (CallbackData
);
1406 Update the Text Mode of Console.
1408 @param CallbackData The context data for BMM.
1410 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1411 @return Other value if the Text Mode of Console is not updated.
1416 IN BMM_CALLBACK_DATA
*CallbackData
1421 CONSOLE_OUT_MODE ModeInfo
;
1423 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1425 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1426 if (EFI_ERROR(Status
)) {
1427 ModeInfo
.Column
= 80;
1431 Status
= gRT
->SetVariable (
1433 &gEfiGenericPlatformVariableGuid
,
1434 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1435 sizeof (CONSOLE_OUT_MODE
),