3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Boot Maintainence Main File
23 #include "BootMaint.h"
27 // Form binary for Boot Maintenance
31 extern EFI_GUID gBdsStringPackGuid
;
32 extern BOOLEAN gConnectAllHappened
;
34 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
38 IN BMM_CALLBACK_DATA
*CallbackData
47 CreateMenuStringToken (
48 IN BMM_CALLBACK_DATA
*CallbackData
,
49 IN EFI_HII_HANDLE HiiHandle
,
50 IN BM_MENU_OPTION
*MenuOption
55 Create string tokens for a menu from its help strings and display strings
59 HiiHandle - Hii Handle of the package to be updated.
61 MenuOption - The Menu whose string tokens need to be created
65 EFI_SUCCESS - string tokens created successfully
67 others - contain some errors
71 BM_MENU_ENTRY
*NewMenuEntry
;
74 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
75 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
76 CallbackData
->Hii
->NewString (
80 &NewMenuEntry
->DisplayStringToken
,
81 NewMenuEntry
->DisplayString
84 if (NULL
== NewMenuEntry
->HelpString
) {
85 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
87 CallbackData
->Hii
->NewString (
91 &NewMenuEntry
->HelpStringToken
,
92 NewMenuEntry
->HelpString
103 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
105 IN EFI_IFR_DATA_ARRAY
*Data
,
106 OUT EFI_HII_CALLBACK_PACKET
**Packet
111 Callback Function for boot maintenance utility user interface interaction.
115 This - File explorer callback protocol pointer.
116 KeyValue - Key value to identify the type of data to expect.
117 Data - A pointer to the data being sent to the original exporting driver.
118 Packet - A pointer to a packet of information which a driver passes back to the browser.
122 EFI_SUCCESS - Callback ended successfully.
123 Others - Contain some errors.
127 BMM_CALLBACK_DATA
*Private
;
128 BM_MENU_ENTRY
*NewMenuEntry
;
129 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
153 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
154 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
155 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
156 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
157 Location
= (UINT8
*) &UpdateData
->Data
;
159 UpdatePageId (Private
, KeyValue
);
162 // need to be subtituded.
164 // Update Select FD/HD/CD/NET/BEV Order Form
166 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
167 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
168 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
169 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
170 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
171 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
172 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
173 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
176 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
178 FormId
= Private
->BmmPreviousPageId
;
179 if (FormId
== FORM_BOOT_SETUP_ID
) {
180 FormId
= Private
->BmmCurrentPageId
;
184 case FORM_SET_FD_ORDER_ID
:
185 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
186 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
187 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
190 case FORM_SET_HD_ORDER_ID
:
191 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
192 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
193 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
196 case FORM_SET_CD_ORDER_ID
:
197 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
198 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
199 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
202 case FORM_SET_NET_ORDER_ID
:
203 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
204 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
205 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
208 case FORM_SET_BEV_ORDER_ID
:
209 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
210 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
211 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
218 // First, find the different position
219 // if there is change, it should be only one
221 for (Index
= 0; Index
< Number
; Index
++) {
222 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
223 OldValue
= OldLegacyDev
[Index
];
224 NewValue
= NewLegacyDev
[Index
];
229 if (Index
!= Number
) {
231 // there is change, now process
233 if (0xFF == NewValue
) {
235 // This item will be disable
236 // Just move the items behind this forward to overlap it
239 Bit
= 7 - (OldValue
% 8);
240 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
241 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
242 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
245 NewLegacyDev
[Index2
] = 0xFF;
247 for (Index2
= 0; Index2
< Number
; Index2
++) {
248 if (Index2
== Index
) {
252 if (OldLegacyDev
[Index2
] == NewValue
) {
254 // If NewValue is in OldLegacyDev array
255 // remember its old position
257 NewValuePos
= Index2
;
262 if (Index2
!= Number
) {
264 // We will change current item to an existing item
265 // (It's hard to describe here, please read code, it's like a cycle-moving)
267 for (Index2
= NewValuePos
; Index2
!= Index
;) {
268 if (NewValuePos
< Index
) {
269 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
272 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
278 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
279 // so we should modify DisMap to reflect the change
282 Bit
= 7 - (NewValue
% 8);
283 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
284 if (0xFF != OldValue
) {
286 // Because NewValue is a item that was disabled before
287 // so after changing the OldValue should be disabled
288 // actually we are doing a swap of enable-disable states of two items
291 Bit
= 7 - (OldValue
% 8);
292 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
297 // To prevent DISABLE appears in the middle of the list
298 // we should perform a re-ordering
301 while (Index
< Number
) {
302 if (0xFF != NewLegacyDev
[Index
]) {
309 while (Index2
< Number
) {
310 if (0xFF != NewLegacyDev
[Index2
]) {
317 if (Index2
< Number
) {
318 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
319 NewLegacyDev
[Index2
] = 0xFF;
333 if (KeyValue
< FILE_OPTION_OFFSET
) {
334 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
336 case KEY_VALUE_BOOT_FROM_FILE
:
337 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
340 // Exit Bmm main formset to send File Explorer formset.
342 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
346 case FORM_BOOT_ADD_ID
:
347 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
350 // Exit Bmm main formset to send File Explorer formset.
352 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
355 case FORM_DRV_ADD_FILE_ID
:
356 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
359 // Exit Bmm main formset to send File Explorer formset.
361 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
365 case FORM_DRV_ADD_HANDLE_ID
:
366 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
367 UpdateDrvAddHandlePage (Private
);
370 case FORM_BOOT_DEL_ID
:
371 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
372 UpdateBootDelPage (Private
);
375 case FORM_BOOT_CHG_ID
:
376 case FORM_DRV_CHG_ID
:
377 UpdatePageBody (KeyValue
, Private
);
380 case FORM_DRV_DEL_ID
:
381 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
382 UpdateDrvDelPage (Private
);
385 case FORM_BOOT_NEXT_ID
:
386 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
387 UpdateBootNextPage (Private
);
390 case FORM_TIME_OUT_ID
:
391 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
392 UpdateTimeOutPage (Private
);
396 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
397 return EFI_UNSUPPORTED
;
400 case FORM_CON_OUT_ID
:
401 case FORM_CON_ERR_ID
:
402 UpdatePageBody (KeyValue
, Private
);
405 case FORM_CON_COM_ID
:
406 CleanUpPage (FORM_CON_COM_ID
, Private
);
407 UpdateConCOMPage (Private
);
410 case FORM_SET_FD_ORDER_ID
:
411 case FORM_SET_HD_ORDER_ID
:
412 case FORM_SET_CD_ORDER_ID
:
413 case FORM_SET_NET_ORDER_ID
:
414 case FORM_SET_BEV_ORDER_ID
:
415 CleanUpPage (KeyValue
, Private
);
416 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
419 case KEY_VALUE_SAVE_AND_EXIT
:
420 case KEY_VALUE_NO_SAVE_AND_EXIT
:
422 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
423 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
424 if (EFI_ERROR (Status
)) {
427 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
428 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
431 // Tell browser not to ask for confirmation of changes,
432 // since we have already applied or discarded.
434 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
440 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
441 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
442 Private
->CurrentTerminal
= Index2
;
444 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
445 UpdateTerminalPage (Private
);
447 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
448 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
450 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
451 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
453 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
455 Private
->MenuEntry
= NewMenuEntry
;
456 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
458 UpdateDriverAddHandleDescPage (Private
);
467 IN BMM_CALLBACK_DATA
*Private
,
468 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
475 Function handling request to apply changes for BMM pages.
479 Private - Pointer to callback data buffer.
480 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
481 FormId - ID of the form which has sent the request to apply change.
485 EFI_SUCCESS - Change successfully applied.
486 Other - Error occurs while trying to apply changes.
490 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
491 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
492 BM_LOAD_CONTEXT
*NewLoadContext
;
493 BM_MENU_ENTRY
*NewMenuEntry
;
497 Status
= EFI_SUCCESS
;
500 case FORM_SET_FD_ORDER_ID
:
501 case FORM_SET_HD_ORDER_ID
:
502 case FORM_SET_CD_ORDER_ID
:
503 case FORM_SET_NET_ORDER_ID
:
504 case FORM_SET_BEV_ORDER_ID
:
505 Var_UpdateBBSOption (Private
);
508 case FORM_BOOT_DEL_ID
:
509 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
510 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
511 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
512 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
515 Var_DelBootOption ();
518 case FORM_DRV_DEL_ID
:
519 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
520 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
521 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
522 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
525 Var_DelDriverOption ();
528 case FORM_BOOT_CHG_ID
:
529 Status
= Var_UpdateBootOrder (Private
);
532 case FORM_DRV_CHG_ID
:
533 Status
= Var_UpdateDriverOrder (Private
);
536 case FORM_TIME_OUT_ID
:
537 Status
= gRT
->SetVariable (
539 &gEfiGlobalVariableGuid
,
542 &(CurrentFakeNVMap
->BootTimeOut
)
544 if (EFI_ERROR (Status
)) {
548 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
551 case FORM_BOOT_NEXT_ID
:
552 Status
= Var_UpdateBootNext (Private
);
555 case FORM_CON_COM_ID
:
556 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
558 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
560 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
561 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
562 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
563 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
564 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
565 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
566 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
567 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
568 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
570 ChangeTerminalDevicePath (
571 NewTerminalContext
->DevicePath
,
575 Var_UpdateConsoleInpOption ();
576 Var_UpdateConsoleOutOption ();
577 Var_UpdateErrorOutOption ();
581 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
582 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
583 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
584 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
587 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
588 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
589 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
590 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
593 Var_UpdateConsoleInpOption ();
596 case FORM_CON_OUT_ID
:
597 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
598 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
599 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
600 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
603 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
604 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
605 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
606 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
609 Var_UpdateConsoleOutOption ();
612 case FORM_CON_ERR_ID
:
613 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
614 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
615 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
616 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
619 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
620 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
621 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
622 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
625 Var_UpdateErrorOutOption ();
628 case FORM_DRV_ADD_HANDLE_DESC_ID
:
629 Status
= Var_UpdateDriverOption (
631 Private
->BmmHiiHandle
,
632 CurrentFakeNVMap
->DriverAddHandleDesc
,
633 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
634 CurrentFakeNVMap
->DriverAddForceReconnect
636 if (EFI_ERROR (Status
)) {
640 BOpt_GetDriverOptions (Private
);
641 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
653 DiscardChangeHandler (
654 IN BMM_CALLBACK_DATA
*Private
,
655 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
660 switch (Private
->BmmPreviousPageId
) {
661 case FORM_BOOT_CHG_ID
:
662 case FORM_DRV_CHG_ID
:
663 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
666 case FORM_BOOT_DEL_ID
:
667 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
668 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
672 case FORM_DRV_DEL_ID
:
673 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
674 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
678 case FORM_BOOT_NEXT_ID
:
679 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
682 case FORM_TIME_OUT_ID
:
683 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
686 case FORM_DRV_ADD_HANDLE_DESC_ID
:
687 case FORM_DRV_ADD_FILE_ID
:
688 case FORM_DRV_ADD_HANDLE_ID
:
689 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
690 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
701 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
702 IN CHAR16
*VariableName
,
703 IN EFI_GUID
*VendorGuid
,
704 OUT UINT32 Attributes OPTIONAL
,
705 IN OUT UINTN DataSize
,
707 OUT BOOLEAN
*ResetRequired
711 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
723 Initialize the Boot Maintenance Utitliy
727 ImageHandle - caller provided handle
729 SystemTable - caller provided system tables
733 EFI_SUCCESS - utility ended successfully
735 others - contain some errors
739 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
740 EFI_HII_PACKAGES
*PackageList
;
741 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
742 EFI_HII_PROTOCOL
*Hii
;
743 EFI_HII_HANDLE HiiHandle
;
749 Status
= EFI_SUCCESS
;
752 // Initialize EfiUtilityLib and EfiDriverLib
753 // Since many functions in UtilityLib must be used and
754 // SetupBrowser use DriverLib
757 // There should be only one EFI_HII_PROTOCOL Image
759 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, (VOID
**)&Hii
);
760 if (EFI_ERROR (Status
)) {
764 // Create CallbackData structures for Driver Callback
766 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
767 if (!BmmCallbackInfo
) {
768 return EFI_OUT_OF_RESOURCES
;
771 // Create LoadOption in BmmCallbackInfo for Driver Callback
773 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
775 SafeFreePool (BmmCallbackInfo
);
776 return EFI_OUT_OF_RESOURCES
;
779 // Initialize Bmm callback data.
781 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
782 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
784 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
785 Ptr
+= sizeof (BM_FILE_CONTEXT
);
787 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
788 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
790 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
792 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
794 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
796 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
797 BmmCallbackInfo
->Hii
= Hii
;
798 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
799 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
800 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
801 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
802 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
803 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
804 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
805 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
806 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
807 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
810 // Install bmm callback protocol interface
813 Status
= gBS
->InstallProtocolInterface (
815 &gEfiFormCallbackProtocolGuid
,
816 EFI_NATIVE_INTERFACE
,
817 &BmmCallbackInfo
->BmmDriverCallback
820 if (EFI_ERROR (Status
)) {
824 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
827 // Install file explorer callback protocol interface
830 Status
= gBS
->InstallProtocolInterface (
832 &gEfiFormCallbackProtocolGuid
,
833 EFI_NATIVE_INTERFACE
,
834 &BmmCallbackInfo
->FeDriverCallback
837 if (EFI_ERROR (Status
)) {
841 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
844 // Post our VFR to the HII database.
846 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, BmBin
);
847 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
848 gBS
->FreePool (PackageList
);
850 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
852 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FEBin
);
853 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
854 gBS
->FreePool (PackageList
);
856 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
859 // Allocate space for creation of Buffer
861 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
863 SafeFreePool (BmmCallbackInfo
->LoadContext
);
864 SafeFreePool (BmmCallbackInfo
);
865 return EFI_OUT_OF_RESOURCES
;
868 // Initialize UpdateData structure
870 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
872 Location
= (UINT8
*) &UpdateData
->Data
;
874 InitializeStringDepository ();
876 InitAllMenu (BmmCallbackInfo
);
878 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
879 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
880 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
881 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
882 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
883 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
884 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
886 UpdateBootDelPage (BmmCallbackInfo
);
887 UpdateDrvDelPage (BmmCallbackInfo
);
889 if (TerminalMenu
.MenuNumber
> 0) {
890 BmmCallbackInfo
->CurrentTerminal
= 0;
891 UpdateTerminalPage (BmmCallbackInfo
);
894 Location
= (UINT8
*) &UpdateData
->Data
;
895 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
896 if (!EFI_ERROR (Status
)) {
898 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
899 // in BootOption form: legacy FD/HD/CD/NET/BEV
901 UpdateData
->DataCount
= 5;
903 FORM_SET_FD_ORDER_ID
,
904 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
905 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
906 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
907 FORM_SET_FD_ORDER_ID
,
911 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
914 FORM_SET_HD_ORDER_ID
,
915 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
916 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
917 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
918 FORM_SET_HD_ORDER_ID
,
922 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
925 FORM_SET_CD_ORDER_ID
,
926 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
927 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
928 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
929 FORM_SET_CD_ORDER_ID
,
933 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
936 FORM_SET_NET_ORDER_ID
,
937 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
938 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
939 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
940 FORM_SET_NET_ORDER_ID
,
944 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
947 FORM_SET_BEV_ORDER_ID
,
948 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
949 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
950 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
951 FORM_SET_BEV_ORDER_ID
,
957 BmmCallbackInfo
->BmmHiiHandle
,
958 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
964 // Dispatch BMM main formset and File Explorer formset.
966 FormSetDispatcher (BmmCallbackInfo
);
968 Hii
->ResetStrings (Hii
, HiiHandle
);
970 CleanUpStringDepository ();
972 if (EFI_ERROR (Status
)) {
978 SafeFreePool (BmmCallbackInfo
->LoadContext
);
979 BmmCallbackInfo
->LoadContext
= NULL
;
980 SafeFreePool (BmmCallbackInfo
);
981 BmmCallbackInfo
= NULL
;
982 SafeFreePool (UpdateData
);
990 IN BMM_CALLBACK_DATA
*CallbackData
993 InitializeListHead (&BootOptionMenu
.Head
);
994 InitializeListHead (&DriverOptionMenu
.Head
);
995 BOpt_GetBootOptions (CallbackData
);
996 BOpt_GetDriverOptions (CallbackData
);
997 BOpt_GetLegacyOptions ();
998 InitializeListHead (&FsOptionMenu
.Head
);
1000 InitializeListHead (&DirectoryMenu
.Head
);
1001 InitializeListHead (&ConsoleInpMenu
.Head
);
1002 InitializeListHead (&ConsoleOutMenu
.Head
);
1003 InitializeListHead (&ConsoleErrMenu
.Head
);
1004 InitializeListHead (&TerminalMenu
.Head
);
1014 BOpt_FreeMenu (&DirectoryMenu
);
1015 BOpt_FreeMenu (&FsOptionMenu
);
1016 BOpt_FreeMenu (&BootOptionMenu
);
1017 BOpt_FreeMenu (&DriverOptionMenu
);
1018 BOpt_FreeMenu (&DriverMenu
);
1019 BOpt_FreeLegacyOptions ();
1024 InitializeStringDepository (
1028 Routine Description:
1029 Intialize all the string depositories.
1038 STRING_DEPOSITORY
*StringDepository
;
1039 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1040 FileOptionStrDepository
= StringDepository
++;
1041 ConsoleOptionStrDepository
= StringDepository
++;
1042 BootOptionStrDepository
= StringDepository
++;
1043 BootOptionHelpStrDepository
= StringDepository
++;
1044 DriverOptionStrDepository
= StringDepository
++;
1045 DriverOptionHelpStrDepository
= StringDepository
++;
1046 TerminalStrDepository
= StringDepository
;
1050 GetStringTokenFromDepository (
1051 IN BMM_CALLBACK_DATA
*CallbackData
,
1052 IN STRING_DEPOSITORY
*StringDepository
1055 Routine Description:
1056 Fetch a usable string node from the string depository and return the string token.
1059 StringDepository - Pointer of the string depository.
1062 STRING_REF - String token.
1065 STRING_LIST_NODE
*CurrentListNode
;
1066 STRING_LIST_NODE
*NextListNode
;
1068 CurrentListNode
= StringDepository
->CurrentNode
;
1070 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1072 // Fetch one reclaimed node from the list.
1074 NextListNode
= StringDepository
->CurrentNode
->Next
;
1077 // If there is no usable node in the list, update the list.
1079 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1081 CallbackData
->Hii
->NewString (
1084 CallbackData
->BmmHiiHandle
,
1085 &(NextListNode
->StringToken
),
1089 ASSERT (NextListNode
->StringToken
!= 0);
1091 StringDepository
->TotalNodeNumber
++;
1093 if (NULL
== CurrentListNode
) {
1094 StringDepository
->ListHead
= NextListNode
;
1096 CurrentListNode
->Next
= NextListNode
;
1100 StringDepository
->CurrentNode
= NextListNode
;
1102 return StringDepository
->CurrentNode
->StringToken
;
1106 ReclaimStringDepository (
1110 Routine Description:
1111 Reclaim string depositories by moving the current node pointer to list head..
1120 UINTN DepositoryIndex
;
1121 STRING_DEPOSITORY
*StringDepository
;
1123 StringDepository
= FileOptionStrDepository
;
1124 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1125 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1131 CleanUpStringDepository (
1135 Routine Description:
1136 Release resource for all the string depositories.
1146 UINTN DepositoryIndex
;
1147 STRING_LIST_NODE
*CurrentListNode
;
1148 STRING_LIST_NODE
*NextListNode
;
1149 STRING_DEPOSITORY
*StringDepository
;
1152 // Release string list nodes.
1154 StringDepository
= FileOptionStrDepository
;
1155 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1156 CurrentListNode
= StringDepository
->ListHead
;
1157 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1158 NextListNode
= CurrentListNode
->Next
;
1159 SafeFreePool (CurrentListNode
);
1160 CurrentListNode
= NextListNode
;
1166 // Release string depository.
1168 SafeFreePool (FileOptionStrDepository
);
1177 Routine Description:
1178 Start boot maintenance manager
1187 LIST_ENTRY BdsBootOptionList
;
1189 InitializeListHead (&BdsBootOptionList
);
1192 // Connect all prior to entering the platform setup menu.
1194 if (!gConnectAllHappened
) {
1195 BdsLibConnectAllDriversToAllControllers ();
1196 gConnectAllHappened
= TRUE
;
1199 // Have chance to enumerate boot device
1201 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1206 Status
= InitializeBM ();
1213 IN BMM_CALLBACK_DATA
*CallbackData
1217 Routine Description:
1218 Dispatch BMM formset and FileExplorer formset.
1226 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1230 BM_MENU_ENTRY
*NewMenuEntry
;
1231 BM_FILE_CONTEXT
*NewFileContext
;
1232 BOOLEAN BootMaintMenuResetRequired
;
1236 NewMenuEntry
= NULL
;
1237 NewFileContext
= NULL
;
1240 // There should only be one Form Configuration protocol
1242 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, (VOID
**) &FormConfig
);
1243 if (EFI_ERROR (Status
)) {
1248 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1250 BootMaintMenuResetRequired
= FALSE
;
1251 Status
= FormConfig
->SendForm (
1254 &(CallbackData
->BmmHiiHandle
),
1258 (UINT8
*) CallbackData
->BmmFakeNvData
,
1260 &BootMaintMenuResetRequired
1263 if (BootMaintMenuResetRequired
) {
1264 EnableResetRequired ();
1267 ReclaimStringDepository ();
1270 // When this Formset returns, check if we are going to explore files.
1272 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1273 UpdateFileExplorer (CallbackData
, 0);
1275 BootMaintMenuResetRequired
= FALSE
;
1276 Status
= FormConfig
->SendForm (
1279 &(CallbackData
->FeHiiHandle
),
1285 &BootMaintMenuResetRequired
1288 if (BootMaintMenuResetRequired
) {
1289 EnableResetRequired ();
1292 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1293 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1294 ReclaimStringDepository ();
1304 CreateCallbackPacket (
1305 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1309 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1310 ASSERT (*Packet
!= NULL
);
1312 (*Packet
)->DataArray
.EntryCount
= 1;
1313 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1314 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;