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.
22 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
23 BM_LOAD_CONTEXT marked for deletion is deleted
24 @return Others If failed to update the "BootOrder" variable after deletion.
32 BM_MENU_ENTRY
*NewMenuEntry
;
33 BM_LOAD_CONTEXT
*NewLoadContext
;
34 UINT16 BootString
[10];
41 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
42 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
43 if (NULL
== NewMenuEntry
) {
47 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
48 if (!NewLoadContext
->Deleted
) {
56 NewMenuEntry
->OptionNumber
59 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
62 // If current Load Option is the same as BootNext,
63 // must delete BootNext in order to make sure
64 // there will be no panic on next boot
66 if (NewLoadContext
->IsBootNext
) {
67 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
70 RemoveEntryList (&NewMenuEntry
->Link
);
71 BOpt_DestroyMenuEntry (NewMenuEntry
);
75 BootOptionMenu
.MenuNumber
-= Index2
;
77 Status
= Var_ChangeBootOrder ();
82 After any operation on Boot####, there will be a discrepancy in BootOrder.
83 Since some are missing but in BootOrder, while some are present but are
84 not reflected by BootOrder. Then a function rebuild BootOrder from
85 scratch by content from BootOptionMenu is needed.
90 @retval EFI_SUCCESS The boot order is updated successfully.
91 @return EFI_STATUS other than EFI_SUCCESS if failed to
92 Set the "BootOrder" EFI Variable.
102 BM_MENU_ENTRY
*NewMenuEntry
;
103 UINT16
*BootOrderList
;
104 UINT16
*BootOrderListPtr
;
105 UINTN BootOrderListSize
;
108 BootOrderList
= NULL
;
109 BootOrderListSize
= 0;
112 // First check whether BootOrder is present in current configuration
114 BootOrderList
= BdsLibGetVariableAndSize (
116 &gEfiGlobalVariableGuid
,
121 // If exists, delete it to hold new BootOrder
123 if (BootOrderList
!= NULL
) {
124 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
125 FreePool (BootOrderList
);
126 BootOrderList
= NULL
;
129 // Maybe here should be some check method to ensure that
130 // no new added boot options will be added
131 // but the setup engine now will give only one callback
132 // that is to say, user are granted only one chance to
133 // decide whether the boot option will be added or not
134 // there should be no indictor to show whether this
135 // is a "new" boot option
137 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
139 if (BootOrderListSize
> 0) {
140 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
141 ASSERT (BootOrderList
!= NULL
);
142 BootOrderListPtr
= BootOrderList
;
145 // Get all current used Boot#### from BootOptionMenu.
146 // OptionNumber in each BM_LOAD_OPTION is really its
149 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
150 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
151 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
155 BootOrderList
= BootOrderListPtr
;
158 // After building the BootOrderList, write it back
160 Status
= gRT
->SetVariable (
162 &gEfiGlobalVariableGuid
,
164 BootOrderListSize
* sizeof (UINT16
),
167 if (EFI_ERROR (Status
)) {
175 Delete Load Option that represent a Deleted state in BootOptionMenu.
176 After deleting this Driver option, call Var_ChangeDriverOrder to
177 make sure DriverOrder is in valid state.
179 @retval EFI_SUCCESS Load Option is successfully updated.
180 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
185 Var_DelDriverOption (
189 BM_MENU_ENTRY
*NewMenuEntry
;
190 BM_LOAD_CONTEXT
*NewLoadContext
;
191 UINT16 DriverString
[12];
196 Status
= EFI_SUCCESS
;
198 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
199 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
200 if (NULL
== NewMenuEntry
) {
201 return EFI_NOT_FOUND
;
204 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
205 if (!NewLoadContext
->Deleted
) {
211 sizeof (DriverString
),
213 NewMenuEntry
->OptionNumber
216 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
219 RemoveEntryList (&NewMenuEntry
->Link
);
220 BOpt_DestroyMenuEntry (NewMenuEntry
);
224 DriverOptionMenu
.MenuNumber
-= Index2
;
226 Status
= Var_ChangeDriverOrder ();
231 After any operation on Driver####, there will be a discrepancy in
232 DriverOrder. Since some are missing but in DriverOrder, while some
233 are present but are not reflected by DriverOrder. Then a function
234 rebuild DriverOrder from scratch by content from DriverOptionMenu is
237 @retval EFI_SUCCESS The driver order is updated successfully.
238 @return EFI_STATUS other than EFI_SUCCESS if failed to
239 Set the "DriverOrder" EFI Variable.
243 Var_ChangeDriverOrder (
248 BM_MENU_ENTRY
*NewMenuEntry
;
249 UINT16
*DriverOrderList
;
250 UINT16
*DriverOrderListPtr
;
251 UINTN DriverOrderListSize
;
254 DriverOrderList
= NULL
;
255 DriverOrderListSize
= 0;
258 // First check whether DriverOrder is present in current configuration
260 DriverOrderList
= BdsLibGetVariableAndSize (
262 &gEfiGlobalVariableGuid
,
267 // If exists, delete it to hold new DriverOrder
269 if (DriverOrderList
!= NULL
) {
270 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
271 FreePool (DriverOrderList
);
272 DriverOrderList
= NULL
;
275 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
277 if (DriverOrderListSize
> 0) {
278 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
279 ASSERT (DriverOrderList
!= NULL
);
280 DriverOrderListPtr
= DriverOrderList
;
283 // Get all current used Driver#### from DriverOptionMenu.
284 // OptionNumber in each BM_LOAD_OPTION is really its
287 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
288 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
289 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
293 DriverOrderList
= DriverOrderListPtr
;
296 // After building the DriverOrderList, write it back
298 Status
= gRT
->SetVariable (
300 &gEfiGlobalVariableGuid
,
302 DriverOrderListSize
* sizeof (UINT16
),
305 if (EFI_ERROR (Status
)) {
313 Update the device path of "ConOut", "ConIn" and "ErrOut"
314 based on the new BaudRate, Data Bits, parity and Stop Bits
319 Var_UpdateAllConsoleOption (
323 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
324 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
325 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
328 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
329 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
330 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
331 if (OutDevicePath
!= NULL
) {
332 ChangeVariableDevicePath (OutDevicePath
);
333 Status
= gRT
->SetVariable (
335 &gEfiGlobalVariableGuid
,
337 GetDevicePathSize (OutDevicePath
),
340 ASSERT (!EFI_ERROR (Status
));
343 if (InpDevicePath
!= NULL
) {
344 ChangeVariableDevicePath (InpDevicePath
);
345 Status
= gRT
->SetVariable (
347 &gEfiGlobalVariableGuid
,
349 GetDevicePathSize (InpDevicePath
),
352 ASSERT (!EFI_ERROR (Status
));
355 if (ErrDevicePath
!= NULL
) {
356 ChangeVariableDevicePath (ErrDevicePath
);
357 Status
= gRT
->SetVariable (
359 &gEfiGlobalVariableGuid
,
361 GetDevicePathSize (ErrDevicePath
),
364 ASSERT (!EFI_ERROR (Status
));
369 This function delete and build multi-instance device path for
370 specified type of console device.
372 This function clear the EFI variable defined by ConsoleName and
373 gEfiGlobalVariableGuid. It then build the multi-instance device
374 path by appending the device path of the Console (In/Out/Err) instance
375 in ConsoleMenu. Then it scan all corresponding console device by
376 scanning Terminal (built from device supporting Serial I/O instances)
377 devices in TerminalMenu. At last, it save a EFI variable specifed
378 by ConsoleName and gEfiGlobalVariableGuid.
380 @param ConsoleName The name for the console device type. They are
381 usually "ConIn", "ConOut" and "ErrOut".
382 @param ConsoleMenu The console memu which is a list of console devices.
383 @param UpdatePageId The flag specifying which type of console device
386 @retval EFI_SUCCESS The function complete successfully.
387 @return The EFI variable can be saved. See gRT->SetVariable
388 for detail return information.
392 Var_UpdateConsoleOption (
393 IN UINT16
*ConsoleName
,
394 IN BM_MENU_OPTION
*ConsoleMenu
,
395 IN UINT16 UpdatePageId
398 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
399 BM_MENU_ENTRY
*NewMenuEntry
;
400 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
401 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
403 VENDOR_DEVICE_PATH Vendor
;
404 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
407 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
408 if (ConDevicePath
!= NULL
) {
409 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
410 FreePool (ConDevicePath
);
411 ConDevicePath
= NULL
;
415 // First add all console input device from console input menu
417 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
418 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
420 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
421 if (NewConsoleContext
->IsActive
) {
422 ConDevicePath
= AppendDevicePathInstance (
424 NewConsoleContext
->DevicePath
429 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
430 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
432 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
433 if (((NewTerminalContext
->IsConIn
!= 0) && (UpdatePageId
== FORM_CON_IN_ID
)) ||
434 ((NewTerminalContext
->IsConOut
!= 0) && (UpdatePageId
== FORM_CON_OUT_ID
)) ||
435 ((NewTerminalContext
->IsStdErr
!= 0) && (UpdatePageId
== FORM_CON_ERR_ID
))
437 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
438 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
441 &TerminalTypeGuid
[NewTerminalContext
->TerminalType
],
444 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
445 TerminalDevicePath
= AppendDevicePathNode (
446 NewTerminalContext
->DevicePath
,
447 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
449 ASSERT (TerminalDevicePath
!= NULL
);
450 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
451 ConDevicePath
= AppendDevicePathInstance (
458 if (ConDevicePath
!= NULL
) {
459 Status
= gRT
->SetVariable (
461 &gEfiGlobalVariableGuid
,
463 GetDevicePathSize (ConDevicePath
),
466 if (EFI_ERROR (Status
)) {
476 This function delete and build multi-instance device path ConIn
479 @retval EFI_SUCCESS The function complete successfully.
480 @return The EFI variable can be saved. See gRT->SetVariable
481 for detail return information.
484 Var_UpdateConsoleInpOption (
488 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
492 This function delete and build multi-instance device path ConOut
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_UpdateConsoleOutOption (
504 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
508 This function delete and build multi-instance device path ErrOut
511 @retval EFI_SUCCESS The function complete successfully.
512 @return The EFI variable can be saved. See gRT->SetVariable
513 for detail return information.
516 Var_UpdateErrorOutOption (
520 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
524 This function create a currently loaded Drive Option from
525 the BMM. It then appends this Driver Option to the end of
526 the "DriverOrder" list. It append this Driver Opotion to the end
529 @param CallbackData The BMM context data.
530 @param HiiHandle The HII handle associated with the BMM formset.
531 @param DescriptionData The description of this driver option.
532 @param OptionalData The optional load option.
533 @param ForceReconnect If to force reconnect.
535 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
536 @retval EFI_SUCCESS If function completes successfully.
540 Var_UpdateDriverOption (
541 IN BMM_CALLBACK_DATA
*CallbackData
,
542 IN EFI_HII_HANDLE HiiHandle
,
543 IN UINT16
*DescriptionData
,
544 IN UINT16
*OptionalData
,
545 IN UINT8 ForceReconnect
549 UINT16
*DriverOrderList
;
550 UINT16
*NewDriverOrderList
;
551 UINT16 DriverString
[12];
552 UINTN DriverOrderListSize
;
556 BM_MENU_ENTRY
*NewMenuEntry
;
557 BM_LOAD_CONTEXT
*NewLoadContext
;
558 BOOLEAN OptionalDataExist
;
561 OptionalDataExist
= FALSE
;
563 Index
= BOpt_GetDriverOptionNumber ();
566 sizeof (DriverString
),
571 if (*DescriptionData
== 0x0000) {
572 StrCpy (DescriptionData
, DriverString
);
575 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
576 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
578 if (*OptionalData
!= 0x0000) {
579 OptionalDataExist
= TRUE
;
580 BufferSize
+= StrSize (OptionalData
);
583 Buffer
= AllocateZeroPool (BufferSize
);
584 if (NULL
== Buffer
) {
585 return EFI_OUT_OF_RESOURCES
;
588 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
589 if (NULL
== NewMenuEntry
) {
590 return EFI_OUT_OF_RESOURCES
;
593 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
594 NewLoadContext
->Deleted
= FALSE
;
595 NewLoadContext
->LoadOptionSize
= BufferSize
;
596 Ptr
= (UINT8
*) Buffer
;
597 NewLoadContext
->LoadOption
= Ptr
;
598 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
599 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
600 NewLoadContext
->IsActive
= TRUE
;
601 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
603 Ptr
+= sizeof (UINT32
);
604 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
605 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
607 Ptr
+= sizeof (UINT16
);
611 StrSize (DescriptionData
)
614 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
615 ASSERT (NewLoadContext
->Description
!= NULL
);
616 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
618 NewLoadContext
->Description
,
620 StrSize (DescriptionData
)
623 Ptr
+= StrSize (DescriptionData
);
626 CallbackData
->LoadContext
->FilePathList
,
627 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
630 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
631 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
634 NewLoadContext
->FilePathList
,
636 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
639 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
640 NewMenuEntry
->OptionNumber
= Index
;
641 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
643 DriverOptionStrDepository
645 HiiLibNewString (HiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
647 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
649 DriverOptionHelpStrDepository
651 HiiLibNewString (HiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
653 if (OptionalDataExist
) {
654 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
659 StrSize (OptionalData
)
663 Status
= gRT
->SetVariable (
665 &gEfiGlobalVariableGuid
,
670 ASSERT_EFI_ERROR (Status
);
671 DriverOrderList
= BdsLibGetVariableAndSize (
673 &gEfiGlobalVariableGuid
,
676 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
677 ASSERT (NewDriverOrderList
!= NULL
);
678 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
679 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
680 if (DriverOrderList
!= NULL
) {
681 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
684 Status
= gRT
->SetVariable (
686 &gEfiGlobalVariableGuid
,
688 DriverOrderListSize
+ sizeof (UINT16
),
691 ASSERT_EFI_ERROR (Status
);
692 if (DriverOrderList
!= NULL
) {
693 FreePool (DriverOrderList
);
695 DriverOrderList
= NULL
;
696 FreePool (NewDriverOrderList
);
697 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
698 DriverOptionMenu
.MenuNumber
++;
700 *DescriptionData
= 0x0000;
701 *OptionalData
= 0x0000;
706 This function create a currently loaded Boot Option from
707 the BMM. It then appends this Boot Option to the end of
708 the "BootOrder" list. It also append this Boot Opotion to the end
711 @param CallbackData The BMM context data.
712 @param NvRamMap The file explorer formset internal state.
714 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
715 @retval EFI_SUCCESS If function completes successfully.
719 Var_UpdateBootOption (
720 IN BMM_CALLBACK_DATA
*CallbackData
,
721 IN FILE_EXPLORER_NV_DATA
*NvRamMap
724 UINT16
*BootOrderList
;
725 UINT16
*NewBootOrderList
;
726 UINTN BootOrderListSize
;
727 UINT16 BootString
[10];
732 BM_MENU_ENTRY
*NewMenuEntry
;
733 BM_LOAD_CONTEXT
*NewLoadContext
;
734 BOOLEAN OptionalDataExist
;
737 OptionalDataExist
= FALSE
;
739 Index
= BOpt_GetBootOptionNumber () ;
740 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
742 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
743 StrCpy (NvRamMap
->DescriptionData
, BootString
);
746 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
747 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
749 if (NvRamMap
->OptionalData
[0] != 0x0000) {
750 OptionalDataExist
= TRUE
;
751 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
754 Buffer
= AllocateZeroPool (BufferSize
);
755 if (NULL
== Buffer
) {
756 return EFI_OUT_OF_RESOURCES
;
759 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
760 if (NULL
== NewMenuEntry
) {
761 return EFI_OUT_OF_RESOURCES
;
764 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
765 NewLoadContext
->Deleted
= FALSE
;
766 NewLoadContext
->LoadOptionSize
= BufferSize
;
767 Ptr
= (UINT8
*) Buffer
;
768 NewLoadContext
->LoadOption
= Ptr
;
769 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
770 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
771 NewLoadContext
->IsActive
= TRUE
;
772 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
774 Ptr
+= sizeof (UINT32
);
775 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
776 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
777 Ptr
+= sizeof (UINT16
);
781 NvRamMap
->DescriptionData
,
782 StrSize (NvRamMap
->DescriptionData
)
785 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
786 ASSERT (NewLoadContext
->Description
!= NULL
);
788 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
790 NewLoadContext
->Description
,
792 StrSize (NvRamMap
->DescriptionData
)
795 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
798 CallbackData
->LoadContext
->FilePathList
,
799 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
802 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
803 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
806 NewLoadContext
->FilePathList
,
808 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
811 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
812 NewMenuEntry
->OptionNumber
= Index
;
813 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
815 BootOptionStrDepository
817 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
819 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
821 BootOptionHelpStrDepository
823 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
825 if (OptionalDataExist
) {
826 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
828 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
831 Status
= gRT
->SetVariable (
833 &gEfiGlobalVariableGuid
,
838 ASSERT_EFI_ERROR (Status
);
840 BootOrderList
= BdsLibGetVariableAndSize (
842 &gEfiGlobalVariableGuid
,
846 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
847 ASSERT (NewBootOrderList
!= NULL
);
848 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
849 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
851 if (BootOrderList
!= NULL
) {
852 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
853 FreePool (BootOrderList
);
856 Status
= gRT
->SetVariable (
858 &gEfiGlobalVariableGuid
,
860 BootOrderListSize
+ sizeof (UINT16
),
863 ASSERT_EFI_ERROR (Status
);
865 FreePool (NewBootOrderList
);
866 NewBootOrderList
= NULL
;
867 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
868 BootOptionMenu
.MenuNumber
++;
870 NvRamMap
->DescriptionData
[0] = 0x0000;
871 NvRamMap
->OptionalData
[0] = 0x0000;
876 This function update the "BootNext" EFI Variable. If there is
877 no "BootNex" specified in BMM, this EFI Variable is deleted.
878 It also update the BMM context data specified the "BootNext"
881 @param CallbackData The BMM context data.
883 @retval EFI_SUCCESS The function complete successfully.
884 @return The EFI variable can be saved. See gRT->SetVariable
885 for detail return information.
890 IN BMM_CALLBACK_DATA
*CallbackData
893 BM_MENU_ENTRY
*NewMenuEntry
;
894 BM_LOAD_CONTEXT
*NewLoadContext
;
895 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
899 Status
= EFI_SUCCESS
;
900 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
901 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
902 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
903 ASSERT (NULL
!= NewMenuEntry
);
905 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
906 NewLoadContext
->IsBootNext
= FALSE
;
909 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
910 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
914 NewMenuEntry
= BOpt_GetMenuEntry (
916 CurrentFakeNVMap
->BootNext
918 ASSERT (NewMenuEntry
!= NULL
);
920 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
921 Status
= gRT
->SetVariable (
923 &gEfiGlobalVariableGuid
,
926 &NewMenuEntry
->OptionNumber
928 NewLoadContext
->IsBootNext
= TRUE
;
929 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
934 This function update the "BootOrder" EFI Variable based on
935 BMM Formset's NV map. It then refresh BootOptionMenu
936 with the new "BootOrder" list.
938 @param CallbackData The BMM context data.
940 @retval EFI_SUCCESS The function complete successfully.
941 @retval EFI_SUCCESS Not enough memory to complete the function.
942 @return The EFI variable can be saved. See gRT->SetVariable
943 for detail return information.
947 Var_UpdateBootOrder (
948 IN BMM_CALLBACK_DATA
*CallbackData
953 UINT16
*BootOrderList
;
954 UINT16
*NewBootOrderList
;
955 UINTN BootOrderListSize
;
957 BootOrderList
= NULL
;
958 BootOrderListSize
= 0;
961 // First check whether BootOrder is present in current configuration
963 BootOrderList
= BdsLibGetVariableAndSize (
965 &gEfiGlobalVariableGuid
,
969 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
970 if (NewBootOrderList
== NULL
) {
971 return EFI_OUT_OF_RESOURCES
;
975 // If exists, delete it to hold new BootOrder
977 if (BootOrderList
!= NULL
) {
978 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
979 FreePool (BootOrderList
);
982 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
983 NewBootOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
986 Status
= gRT
->SetVariable (
988 &gEfiGlobalVariableGuid
,
993 FreePool (NewBootOrderList
);
994 if (EFI_ERROR (Status
)) {
998 BOpt_FreeMenu (&BootOptionMenu
);
999 BOpt_GetBootOptions (CallbackData
);
1006 This function update the "DriverOrder" EFI Variable based on
1007 BMM Formset's NV map. It then refresh DriverOptionMenu
1008 with the new "DriverOrder" list.
1010 @param CallbackData The BMM context data.
1012 @retval EFI_SUCCESS The function complete successfully.
1013 @retval EFI_SUCCESS Not enough memory to complete the function.
1014 @return The EFI variable can be saved. See gRT->SetVariable
1015 for detail return information.
1019 Var_UpdateDriverOrder (
1020 IN BMM_CALLBACK_DATA
*CallbackData
1025 UINT16
*DriverOrderList
;
1026 UINT16
*NewDriverOrderList
;
1027 UINTN DriverOrderListSize
;
1029 DriverOrderList
= NULL
;
1030 DriverOrderListSize
= 0;
1033 // First check whether DriverOrder is present in current configuration
1035 DriverOrderList
= BdsLibGetVariableAndSize (
1037 &gEfiGlobalVariableGuid
,
1038 &DriverOrderListSize
1041 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1043 if (NewDriverOrderList
== NULL
) {
1044 return EFI_OUT_OF_RESOURCES
;
1047 // If exists, delete it to hold new DriverOrder
1049 if (DriverOrderList
!= NULL
) {
1050 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1051 FreePool (DriverOrderList
);
1054 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
1055 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
1058 Status
= gRT
->SetVariable (
1060 &gEfiGlobalVariableGuid
,
1062 DriverOrderListSize
,
1065 if (EFI_ERROR (Status
)) {
1069 BOpt_FreeMenu (&DriverOptionMenu
);
1070 BOpt_GetDriverOptions (CallbackData
);
1075 Update the legacy BBS boot option. L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable
1076 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
1079 @param CallbackData The context data for BMM.
1081 @return EFI_SUCCESS The function completed successfully.
1082 @retval EFI_NOT_FOUND If L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable can be found.
1086 Var_UpdateBBSOption (
1087 IN BMM_CALLBACK_DATA
*CallbackData
1092 VOID
*BootOptionVar
;
1093 CHAR16 VarName
[100];
1097 CHAR16 DescString
[100];
1098 CHAR8 DescAsciiString
[100];
1099 UINTN NewOptionSize
;
1100 UINT8
*NewOptionPtr
;
1103 BM_MENU_OPTION
*OptionMenu
;
1104 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1108 BM_MENU_ENTRY
*NewMenuEntry
;
1109 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1117 LegacyDeviceContext
= NULL
;
1121 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1122 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1123 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1124 CallbackData
->BbsType
= BBS_FLOPPY
;
1126 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1127 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1128 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1129 CallbackData
->BbsType
= BBS_HARDDISK
;
1131 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1132 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1133 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1134 CallbackData
->BbsType
= BBS_CDROM
;
1136 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1137 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1138 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1139 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1141 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1142 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1143 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1149 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1150 Status
= EFI_SUCCESS
;
1153 // Find the first device's context
1154 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1155 // because we just use it to fill the desc string, and user can not see the string in UI
1157 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1158 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1159 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1160 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1161 DEBUG ((DEBUG_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1166 // Update the Variable "LegacyDevOrder"
1168 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1169 VAR_LEGACY_DEV_ORDER
,
1170 &EfiLegacyDevOrderGuid
,
1174 if (NULL
== VarData
) {
1175 return EFI_NOT_FOUND
;
1178 OriginalPtr
= VarData
;
1179 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1181 while (VarData
< VarData
+ VarSize
) {
1182 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1186 VarData
+= sizeof (BBS_TYPE
);
1187 VarData
+= *(UINT16
*) VarData
;
1188 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1191 if (VarData
>= VarData
+ VarSize
) {
1192 FreePool (OriginalPtr
);
1193 return EFI_NOT_FOUND
;
1196 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1197 if (NULL
== NewOrder
) {
1199 return EFI_OUT_OF_RESOURCES
;
1202 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1203 if (0xFF == LegacyDev
[Index
]) {
1207 NewOrder
[Index
] = LegacyDev
[Index
];
1210 // Only the enable/disable state of each boot device with same device type can be changed,
1211 // so we can count on the index information in DevOrder.
1212 // DisMap bit array is the only reliable source to check a device's en/dis state,
1213 // so we use DisMap to set en/dis state of each item in NewOrder array
1215 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1216 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1219 Bit
= 7 - (Tmp
% 8);
1220 if ((DisMap
[Pos
] & (1 << Bit
)) != 0) {
1221 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1227 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1229 DevOrder
->Length
- sizeof (UINT16
)
1231 FreePool (NewOrder
);
1233 Status
= gRT
->SetVariable (
1234 VAR_LEGACY_DEV_ORDER
,
1235 &EfiLegacyDevOrderGuid
,
1241 FreePool (OriginalPtr
);
1244 // Update Optional Data of Boot####
1246 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1248 if (NULL
!= BootOptionVar
) {
1251 LegacyDeviceContext
->Description
,
1252 StrSize (LegacyDeviceContext
->Description
)
1255 UnicodeStrToAsciiStr((CONST CHAR16
*)&DescString
, (CHAR8
*)&DescAsciiString
);
1257 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) +
1258 sizeof (BBS_BBS_DEVICE_PATH
);
1259 NewOptionSize
+= AsciiStrLen (DescAsciiString
) +
1260 EFI_END_DEVICE_PATH_LENGTH
+ sizeof (BBS_TABLE
) + sizeof (UINT16
);
1262 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1264 Ptr
= BootOptionVar
;
1266 Attribute
= (UINT32
*) Ptr
;
1267 *Attribute
|= LOAD_OPTION_ACTIVE
;
1268 if (0xFF == LegacyDev
[0]) {
1270 // Disable this legacy boot option
1272 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1275 Ptr
+= sizeof (UINT32
);
1277 Ptr
+= sizeof (UINT16
);
1278 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1280 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1281 if (NULL
== NewOptionPtr
) {
1282 return EFI_OUT_OF_RESOURCES
;
1285 TempPtr
= NewOptionPtr
;
1296 TempPtr
+= sizeof (UINT32
);
1299 // BBS device path Length
1301 *((UINT16
*) TempPtr
) = (UINT16
) (sizeof (BBS_BBS_DEVICE_PATH
) +
1302 AsciiStrLen (DescAsciiString
) +
1303 EFI_END_DEVICE_PATH_LENGTH
);
1305 TempPtr
+= sizeof (UINT16
);
1308 // Description string
1313 StrSize (DescString
)
1316 TempPtr
+= StrSize (DescString
);
1324 sizeof (BBS_BBS_DEVICE_PATH
)
1328 ((BBS_BBS_DEVICE_PATH
*) TempPtr
)->String
,
1330 AsciiStrSize (DescAsciiString
)
1333 SetDevicePathNodeLength (
1334 (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
,
1335 sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
)
1338 TempPtr
+= sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
);
1346 EFI_END_DEVICE_PATH_LENGTH
1348 TempPtr
+= EFI_END_DEVICE_PATH_LENGTH
;
1351 // Now TempPtr point to optional data, i.e. Bbs Table
1355 LegacyDeviceContext
->BbsTable
,
1360 // Now TempPtr point to BBS index
1362 TempPtr
+= sizeof (BBS_TABLE
);
1363 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1365 Status
= gRT
->SetVariable (
1367 &gEfiGlobalVariableGuid
,
1373 FreePool (NewOptionPtr
);
1374 FreePool (BootOptionVar
);
1377 BOpt_GetBootOptions (CallbackData
);
1382 Update the Text Mode of Console.
1384 @param CallbackData The context data for BMM.
1386 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1387 @return Other value if the Text Mode of Console is not updated.
1392 IN BMM_CALLBACK_DATA
*CallbackData
1397 CONSOLE_OUT_MODE ModeInfo
;
1399 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1401 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1402 if (EFI_ERROR(Status
)) {
1403 ModeInfo
.Column
= 80;
1407 Status
= gRT
->SetVariable (
1409 &gEfiGenericPlatformVariableGuid
,
1410 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1411 sizeof (CONSOLE_OUT_MODE
),