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 not be saved. See gRT->SetVariable for detail return information.
391 Var_UpdateConsoleOption (
392 IN UINT16
*ConsoleName
,
393 IN BM_MENU_OPTION
*ConsoleMenu
,
394 IN UINT16 UpdatePageId
397 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
398 BM_MENU_ENTRY
*NewMenuEntry
;
399 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
400 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
402 VENDOR_DEVICE_PATH Vendor
;
403 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
406 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
407 if (ConDevicePath
!= NULL
) {
408 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
409 FreePool (ConDevicePath
);
410 ConDevicePath
= NULL
;
414 // First add all console input device from console input menu
416 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
417 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
419 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
420 if (NewConsoleContext
->IsActive
) {
421 ConDevicePath
= AppendDevicePathInstance (
423 NewConsoleContext
->DevicePath
428 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
429 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
431 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
432 if (((NewTerminalContext
->IsConIn
!= 0) && (UpdatePageId
== FORM_CON_IN_ID
)) ||
433 ((NewTerminalContext
->IsConOut
!= 0) && (UpdatePageId
== FORM_CON_OUT_ID
)) ||
434 ((NewTerminalContext
->IsStdErr
!= 0) && (UpdatePageId
== FORM_CON_ERR_ID
))
436 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
437 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
440 &TerminalTypeGuid
[NewTerminalContext
->TerminalType
],
443 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
444 TerminalDevicePath
= AppendDevicePathNode (
445 NewTerminalContext
->DevicePath
,
446 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
448 ASSERT (TerminalDevicePath
!= NULL
);
449 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
450 ConDevicePath
= AppendDevicePathInstance (
457 if (ConDevicePath
!= NULL
) {
458 Status
= gRT
->SetVariable (
460 &gEfiGlobalVariableGuid
,
462 GetDevicePathSize (ConDevicePath
),
465 if (EFI_ERROR (Status
)) {
475 This function delete and build multi-instance device path ConIn
478 @retval EFI_SUCCESS The function complete successfully.
479 @return The EFI variable can be saved. See gRT->SetVariable
480 for detail return information.
483 Var_UpdateConsoleInpOption (
487 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
491 This function delete and build multi-instance device path ConOut
494 @retval EFI_SUCCESS The function complete successfully.
495 @return The EFI variable can be saved. See gRT->SetVariable
496 for detail return information.
499 Var_UpdateConsoleOutOption (
503 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
507 This function delete and build multi-instance device path ErrOut
510 @retval EFI_SUCCESS The function complete successfully.
511 @return The EFI variable can be saved. See gRT->SetVariable
512 for detail return information.
515 Var_UpdateErrorOutOption (
519 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
523 This function create a currently loaded Drive Option from
524 the BMM. It then appends this Driver Option to the end of
525 the "DriverOrder" list. It append this Driver Opotion to the end
528 @param CallbackData The BMM context data.
529 @param HiiHandle The HII handle associated with the BMM formset.
530 @param DescriptionData The description of this driver option.
531 @param OptionalData The optional load option.
532 @param ForceReconnect If to force reconnect.
534 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
535 @retval EFI_SUCCESS If function completes successfully.
539 Var_UpdateDriverOption (
540 IN BMM_CALLBACK_DATA
*CallbackData
,
541 IN EFI_HII_HANDLE HiiHandle
,
542 IN UINT16
*DescriptionData
,
543 IN UINT16
*OptionalData
,
544 IN UINT8 ForceReconnect
548 UINT16
*DriverOrderList
;
549 UINT16
*NewDriverOrderList
;
550 UINT16 DriverString
[12];
551 UINTN DriverOrderListSize
;
555 BM_MENU_ENTRY
*NewMenuEntry
;
556 BM_LOAD_CONTEXT
*NewLoadContext
;
557 BOOLEAN OptionalDataExist
;
560 OptionalDataExist
= FALSE
;
562 Index
= BOpt_GetDriverOptionNumber ();
565 sizeof (DriverString
),
570 if (*DescriptionData
== 0x0000) {
571 StrCpy (DescriptionData
, DriverString
);
574 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
575 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
577 if (*OptionalData
!= 0x0000) {
578 OptionalDataExist
= TRUE
;
579 BufferSize
+= StrSize (OptionalData
);
582 Buffer
= AllocateZeroPool (BufferSize
);
583 if (NULL
== Buffer
) {
584 return EFI_OUT_OF_RESOURCES
;
587 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
588 if (NULL
== NewMenuEntry
) {
589 return EFI_OUT_OF_RESOURCES
;
592 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
593 NewLoadContext
->Deleted
= FALSE
;
594 NewLoadContext
->LoadOptionSize
= BufferSize
;
595 Ptr
= (UINT8
*) Buffer
;
596 NewLoadContext
->LoadOption
= Ptr
;
597 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
598 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
599 NewLoadContext
->IsActive
= TRUE
;
600 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
602 Ptr
+= sizeof (UINT32
);
603 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
604 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
606 Ptr
+= sizeof (UINT16
);
610 StrSize (DescriptionData
)
613 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
614 ASSERT (NewLoadContext
->Description
!= NULL
);
615 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
617 NewLoadContext
->Description
,
619 StrSize (DescriptionData
)
622 Ptr
+= StrSize (DescriptionData
);
625 CallbackData
->LoadContext
->FilePathList
,
626 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
629 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
630 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
633 NewLoadContext
->FilePathList
,
635 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
638 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
639 NewMenuEntry
->OptionNumber
= Index
;
640 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
642 DriverOptionStrDepository
644 HiiLibNewString (HiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
646 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
648 DriverOptionHelpStrDepository
650 HiiLibNewString (HiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
652 if (OptionalDataExist
) {
653 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
658 StrSize (OptionalData
)
662 Status
= gRT
->SetVariable (
664 &gEfiGlobalVariableGuid
,
669 ASSERT_EFI_ERROR (Status
);
670 DriverOrderList
= BdsLibGetVariableAndSize (
672 &gEfiGlobalVariableGuid
,
675 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
676 ASSERT (NewDriverOrderList
!= NULL
);
677 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
678 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
679 if (DriverOrderList
!= NULL
) {
680 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
683 Status
= gRT
->SetVariable (
685 &gEfiGlobalVariableGuid
,
687 DriverOrderListSize
+ sizeof (UINT16
),
690 ASSERT_EFI_ERROR (Status
);
691 if (DriverOrderList
!= NULL
) {
692 FreePool (DriverOrderList
);
694 DriverOrderList
= NULL
;
695 FreePool (NewDriverOrderList
);
696 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
697 DriverOptionMenu
.MenuNumber
++;
699 *DescriptionData
= 0x0000;
700 *OptionalData
= 0x0000;
705 This function create a currently loaded Boot Option from
706 the BMM. It then appends this Boot Option to the end of
707 the "BootOrder" list. It also append this Boot Opotion to the end
710 @param CallbackData The BMM context data.
711 @param NvRamMap The file explorer formset internal state.
713 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
714 @retval EFI_SUCCESS If function completes successfully.
718 Var_UpdateBootOption (
719 IN BMM_CALLBACK_DATA
*CallbackData
,
720 IN FILE_EXPLORER_NV_DATA
*NvRamMap
723 UINT16
*BootOrderList
;
724 UINT16
*NewBootOrderList
;
725 UINTN BootOrderListSize
;
726 UINT16 BootString
[10];
731 BM_MENU_ENTRY
*NewMenuEntry
;
732 BM_LOAD_CONTEXT
*NewLoadContext
;
733 BOOLEAN OptionalDataExist
;
736 OptionalDataExist
= FALSE
;
738 Index
= BOpt_GetBootOptionNumber () ;
739 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
741 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
742 StrCpy (NvRamMap
->DescriptionData
, BootString
);
745 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
746 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
748 if (NvRamMap
->OptionalData
[0] != 0x0000) {
749 OptionalDataExist
= TRUE
;
750 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
753 Buffer
= AllocateZeroPool (BufferSize
);
754 if (NULL
== Buffer
) {
755 return EFI_OUT_OF_RESOURCES
;
758 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
759 if (NULL
== NewMenuEntry
) {
760 return EFI_OUT_OF_RESOURCES
;
763 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
764 NewLoadContext
->Deleted
= FALSE
;
765 NewLoadContext
->LoadOptionSize
= BufferSize
;
766 Ptr
= (UINT8
*) Buffer
;
767 NewLoadContext
->LoadOption
= Ptr
;
768 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
769 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
770 NewLoadContext
->IsActive
= TRUE
;
771 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
773 Ptr
+= sizeof (UINT32
);
774 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
775 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
776 Ptr
+= sizeof (UINT16
);
780 NvRamMap
->DescriptionData
,
781 StrSize (NvRamMap
->DescriptionData
)
784 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
785 ASSERT (NewLoadContext
->Description
!= NULL
);
787 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
789 NewLoadContext
->Description
,
791 StrSize (NvRamMap
->DescriptionData
)
794 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
797 CallbackData
->LoadContext
->FilePathList
,
798 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
801 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
802 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
805 NewLoadContext
->FilePathList
,
807 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
810 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
811 NewMenuEntry
->OptionNumber
= Index
;
812 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
814 BootOptionStrDepository
816 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
818 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
820 BootOptionHelpStrDepository
822 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
824 if (OptionalDataExist
) {
825 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
827 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
830 Status
= gRT
->SetVariable (
832 &gEfiGlobalVariableGuid
,
837 ASSERT_EFI_ERROR (Status
);
839 BootOrderList
= BdsLibGetVariableAndSize (
841 &gEfiGlobalVariableGuid
,
845 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
846 ASSERT (NewBootOrderList
!= NULL
);
847 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
848 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
850 if (BootOrderList
!= NULL
) {
851 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
852 FreePool (BootOrderList
);
855 Status
= gRT
->SetVariable (
857 &gEfiGlobalVariableGuid
,
859 BootOrderListSize
+ sizeof (UINT16
),
862 ASSERT_EFI_ERROR (Status
);
864 FreePool (NewBootOrderList
);
865 NewBootOrderList
= NULL
;
866 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
867 BootOptionMenu
.MenuNumber
++;
869 NvRamMap
->DescriptionData
[0] = 0x0000;
870 NvRamMap
->OptionalData
[0] = 0x0000;
875 This function update the "BootNext" EFI Variable. If there is
876 no "BootNex" specified in BMM, this EFI Variable is deleted.
877 It also update the BMM context data specified the "BootNext"
880 @param CallbackData The BMM context data.
882 @retval EFI_SUCCESS The function complete successfully.
883 @return The EFI variable can be saved. See gRT->SetVariable
884 for detail return information.
889 IN BMM_CALLBACK_DATA
*CallbackData
892 BM_MENU_ENTRY
*NewMenuEntry
;
893 BM_LOAD_CONTEXT
*NewLoadContext
;
894 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
898 Status
= EFI_SUCCESS
;
899 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
900 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
901 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
902 ASSERT (NULL
!= NewMenuEntry
);
904 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
905 NewLoadContext
->IsBootNext
= FALSE
;
908 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
909 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
913 NewMenuEntry
= BOpt_GetMenuEntry (
915 CurrentFakeNVMap
->BootNext
917 ASSERT (NewMenuEntry
!= NULL
);
919 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
920 Status
= gRT
->SetVariable (
922 &gEfiGlobalVariableGuid
,
925 &NewMenuEntry
->OptionNumber
927 NewLoadContext
->IsBootNext
= TRUE
;
928 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
933 This function update the "BootOrder" EFI Variable based on
934 BMM Formset's NV map. It then refresh BootOptionMenu
935 with the new "BootOrder" list.
937 @param CallbackData The BMM context data.
939 @retval EFI_SUCCESS The function complete successfully.
940 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
941 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
945 Var_UpdateBootOrder (
946 IN BMM_CALLBACK_DATA
*CallbackData
951 UINT16
*BootOrderList
;
952 UINT16
*NewBootOrderList
;
953 UINTN BootOrderListSize
;
955 BootOrderList
= NULL
;
956 BootOrderListSize
= 0;
959 // First check whether BootOrder is present in current configuration
961 BootOrderList
= BdsLibGetVariableAndSize (
963 &gEfiGlobalVariableGuid
,
967 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
968 if (NewBootOrderList
== NULL
) {
969 return EFI_OUT_OF_RESOURCES
;
973 // If exists, delete it to hold new BootOrder
975 if (BootOrderList
!= NULL
) {
976 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
977 FreePool (BootOrderList
);
980 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
981 NewBootOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
984 Status
= gRT
->SetVariable (
986 &gEfiGlobalVariableGuid
,
991 FreePool (NewBootOrderList
);
992 if (EFI_ERROR (Status
)) {
996 BOpt_FreeMenu (&BootOptionMenu
);
997 BOpt_GetBootOptions (CallbackData
);
1004 This function update the "DriverOrder" EFI Variable based on
1005 BMM Formset's NV map. It then refresh DriverOptionMenu
1006 with the new "DriverOrder" list.
1008 @param CallbackData The BMM context data.
1010 @retval EFI_SUCCESS The function complete successfully.
1011 @retval EFI_SUCCESS Not enough memory to complete the function.
1012 @return The EFI variable can be saved. See gRT->SetVariable
1013 for detail return information.
1017 Var_UpdateDriverOrder (
1018 IN BMM_CALLBACK_DATA
*CallbackData
1023 UINT16
*DriverOrderList
;
1024 UINT16
*NewDriverOrderList
;
1025 UINTN DriverOrderListSize
;
1027 DriverOrderList
= NULL
;
1028 DriverOrderListSize
= 0;
1031 // First check whether DriverOrder is present in current configuration
1033 DriverOrderList
= BdsLibGetVariableAndSize (
1035 &gEfiGlobalVariableGuid
,
1036 &DriverOrderListSize
1039 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
1041 if (NewDriverOrderList
== NULL
) {
1042 return EFI_OUT_OF_RESOURCES
;
1045 // If exists, delete it to hold new DriverOrder
1047 if (DriverOrderList
!= NULL
) {
1048 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1049 FreePool (DriverOrderList
);
1052 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
1053 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
1056 Status
= gRT
->SetVariable (
1058 &gEfiGlobalVariableGuid
,
1060 DriverOrderListSize
,
1063 if (EFI_ERROR (Status
)) {
1067 BOpt_FreeMenu (&DriverOptionMenu
);
1068 BOpt_GetDriverOptions (CallbackData
);
1073 Update the legacy BBS boot option. L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable
1074 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
1077 @param CallbackData The context data for BMM.
1079 @return EFI_SUCCESS The function completed successfully.
1080 @retval EFI_NOT_FOUND If L"LegacyDevOrder" and EfiLegacyDevOrderGuid EFI Variable can be found.
1084 Var_UpdateBBSOption (
1085 IN BMM_CALLBACK_DATA
*CallbackData
1090 VOID
*BootOptionVar
;
1091 CHAR16 VarName
[100];
1095 CHAR16 DescString
[100];
1096 CHAR8 DescAsciiString
[100];
1097 UINTN NewOptionSize
;
1098 UINT8
*NewOptionPtr
;
1101 BM_MENU_OPTION
*OptionMenu
;
1102 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1106 BM_MENU_ENTRY
*NewMenuEntry
;
1107 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1115 LegacyDeviceContext
= NULL
;
1119 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1120 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1121 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1122 CallbackData
->BbsType
= BBS_FLOPPY
;
1124 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1125 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1126 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1127 CallbackData
->BbsType
= BBS_HARDDISK
;
1129 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1130 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1131 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1132 CallbackData
->BbsType
= BBS_CDROM
;
1134 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1135 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1136 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1137 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1139 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1140 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1141 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1147 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1148 Status
= EFI_SUCCESS
;
1151 // Find the first device's context
1152 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1153 // because we just use it to fill the desc string, and user can not see the string in UI
1155 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1156 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1157 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1158 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1159 DEBUG ((DEBUG_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1164 // Update the Variable "LegacyDevOrder"
1166 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1167 VAR_LEGACY_DEV_ORDER
,
1168 &EfiLegacyDevOrderGuid
,
1172 if (NULL
== VarData
) {
1173 return EFI_NOT_FOUND
;
1176 OriginalPtr
= VarData
;
1177 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1179 while (VarData
< VarData
+ VarSize
) {
1180 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1184 VarData
+= sizeof (BBS_TYPE
);
1185 VarData
+= *(UINT16
*) VarData
;
1186 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1189 if (VarData
>= VarData
+ VarSize
) {
1190 FreePool (OriginalPtr
);
1191 return EFI_NOT_FOUND
;
1194 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1195 if (NULL
== NewOrder
) {
1197 return EFI_OUT_OF_RESOURCES
;
1200 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1201 if (0xFF == LegacyDev
[Index
]) {
1205 NewOrder
[Index
] = LegacyDev
[Index
];
1208 // Only the enable/disable state of each boot device with same device type can be changed,
1209 // so we can count on the index information in DevOrder.
1210 // DisMap bit array is the only reliable source to check a device's en/dis state,
1211 // so we use DisMap to set en/dis state of each item in NewOrder array
1213 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1214 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1217 Bit
= 7 - (Tmp
% 8);
1218 if ((DisMap
[Pos
] & (1 << Bit
)) != 0) {
1219 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1225 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1227 DevOrder
->Length
- sizeof (UINT16
)
1229 FreePool (NewOrder
);
1231 Status
= gRT
->SetVariable (
1232 VAR_LEGACY_DEV_ORDER
,
1233 &EfiLegacyDevOrderGuid
,
1239 FreePool (OriginalPtr
);
1242 // Update Optional Data of Boot####
1244 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1246 if (NULL
!= BootOptionVar
) {
1249 LegacyDeviceContext
->Description
,
1250 StrSize (LegacyDeviceContext
->Description
)
1253 UnicodeStrToAsciiStr((CONST CHAR16
*)&DescString
, (CHAR8
*)&DescAsciiString
);
1255 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) +
1256 sizeof (BBS_BBS_DEVICE_PATH
);
1257 NewOptionSize
+= AsciiStrLen (DescAsciiString
) +
1258 END_DEVICE_PATH_LENGTH
+ sizeof (BBS_TABLE
) + sizeof (UINT16
);
1260 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1262 Ptr
= BootOptionVar
;
1264 Attribute
= (UINT32
*) Ptr
;
1265 *Attribute
|= LOAD_OPTION_ACTIVE
;
1266 if (0xFF == LegacyDev
[0]) {
1268 // Disable this legacy boot option
1270 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1273 Ptr
+= sizeof (UINT32
);
1275 Ptr
+= sizeof (UINT16
);
1276 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1278 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1279 if (NULL
== NewOptionPtr
) {
1280 return EFI_OUT_OF_RESOURCES
;
1283 TempPtr
= NewOptionPtr
;
1294 TempPtr
+= sizeof (UINT32
);
1297 // BBS device path Length
1299 *((UINT16
*) TempPtr
) = (UINT16
) (sizeof (BBS_BBS_DEVICE_PATH
) +
1300 AsciiStrLen (DescAsciiString
) +
1301 END_DEVICE_PATH_LENGTH
);
1303 TempPtr
+= sizeof (UINT16
);
1306 // Description string
1311 StrSize (DescString
)
1314 TempPtr
+= StrSize (DescString
);
1322 sizeof (BBS_BBS_DEVICE_PATH
)
1326 ((BBS_BBS_DEVICE_PATH
*) TempPtr
)->String
,
1328 AsciiStrSize (DescAsciiString
)
1331 SetDevicePathNodeLength (
1332 (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
,
1333 sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
)
1336 TempPtr
+= sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
);
1344 END_DEVICE_PATH_LENGTH
1346 TempPtr
+= END_DEVICE_PATH_LENGTH
;
1349 // Now TempPtr point to optional data, i.e. Bbs Table
1353 LegacyDeviceContext
->BbsTable
,
1358 // Now TempPtr point to BBS index
1360 TempPtr
+= sizeof (BBS_TABLE
);
1361 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1363 Status
= gRT
->SetVariable (
1365 &gEfiGlobalVariableGuid
,
1371 FreePool (NewOptionPtr
);
1372 FreePool (BootOptionVar
);
1375 BOpt_GetBootOptions (CallbackData
);
1380 Update the Text Mode of Console.
1382 @param CallbackData The context data for BMM.
1384 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1385 @return Other value if the Text Mode of Console is not updated.
1390 IN BMM_CALLBACK_DATA
*CallbackData
1395 CONSOLE_OUT_MODE ModeInfo
;
1397 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1399 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1400 if (EFI_ERROR(Status
)) {
1401 ModeInfo
.Column
= 80;
1405 Status
= gRT
->SetVariable (
1407 &gEfiGenericPlatformVariableGuid
,
1408 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1409 sizeof (CONSOLE_OUT_MODE
),