3 Copyright (c) 2006 - 2007, 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 common header file for this module.
25 #include "CommonHeader.h"
27 #include "Generic/Bds.h"
28 #include "BootMaint.h"
32 // Form binary for Boot Maintenance
36 extern EFI_GUID gBdsStringPackGuid
;
37 extern BOOLEAN gConnectAllHappened
;
39 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
43 IN BMM_CALLBACK_DATA
*CallbackData
52 CreateMenuStringToken (
53 IN BMM_CALLBACK_DATA
*CallbackData
,
54 IN EFI_HII_HANDLE HiiHandle
,
55 IN BM_MENU_OPTION
*MenuOption
60 Create string tokens for a menu from its help strings and display strings
64 HiiHandle - Hii Handle of the package to be updated.
66 MenuOption - The Menu whose string tokens need to be created
70 EFI_SUCCESS - string tokens created successfully
72 others - contain some errors
76 BM_MENU_ENTRY
*NewMenuEntry
;
79 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
80 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
81 CallbackData
->Hii
->NewString (
85 &NewMenuEntry
->DisplayStringToken
,
86 NewMenuEntry
->DisplayString
89 if (NULL
== NewMenuEntry
->HelpString
) {
90 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
92 CallbackData
->Hii
->NewString (
96 &NewMenuEntry
->HelpStringToken
,
97 NewMenuEntry
->HelpString
108 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
110 IN EFI_IFR_DATA_ARRAY
*Data
,
111 OUT EFI_HII_CALLBACK_PACKET
**Packet
116 Callback Function for boot maintenance utility user interface interaction.
120 This - File explorer callback protocol pointer.
121 KeyValue - Key value to identify the type of data to expect.
122 Data - A pointer to the data being sent to the original exporting driver.
123 Packet - A pointer to a packet of information which a driver passes back to the browser.
127 EFI_SUCCESS - Callback ended successfully.
128 Others - Contain some errors.
132 BMM_CALLBACK_DATA
*Private
;
133 BM_MENU_ENTRY
*NewMenuEntry
;
134 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
158 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
159 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
160 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
161 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
162 Location
= (UINT8
*) &UpdateData
->Data
;
164 UpdatePageId (Private
, KeyValue
);
167 // need to be subtituded.
169 // Update Select FD/HD/CD/NET/BEV Order Form
171 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
172 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
173 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
174 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
175 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
176 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
177 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
178 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
181 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
183 FormId
= Private
->BmmPreviousPageId
;
184 if (FormId
== FORM_BOOT_SETUP_ID
) {
185 FormId
= Private
->BmmCurrentPageId
;
189 case FORM_SET_FD_ORDER_ID
:
190 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
191 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
192 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
195 case FORM_SET_HD_ORDER_ID
:
196 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
197 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
198 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
201 case FORM_SET_CD_ORDER_ID
:
202 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
203 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
204 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
207 case FORM_SET_NET_ORDER_ID
:
208 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
209 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
210 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
213 case FORM_SET_BEV_ORDER_ID
:
214 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
215 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
216 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
223 // First, find the different position
224 // if there is change, it should be only one
226 for (Index
= 0; Index
< Number
; Index
++) {
227 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
228 OldValue
= OldLegacyDev
[Index
];
229 NewValue
= NewLegacyDev
[Index
];
234 if (Index
!= Number
) {
236 // there is change, now process
238 if (0xFF == NewValue
) {
240 // This item will be disable
241 // Just move the items behind this forward to overlap it
244 Bit
= 7 - (OldValue
% 8);
245 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
246 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
247 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
250 NewLegacyDev
[Index2
] = 0xFF;
252 for (Index2
= 0; Index2
< Number
; Index2
++) {
253 if (Index2
== Index
) {
257 if (OldLegacyDev
[Index2
] == NewValue
) {
259 // If NewValue is in OldLegacyDev array
260 // remember its old position
262 NewValuePos
= Index2
;
267 if (Index2
!= Number
) {
269 // We will change current item to an existing item
270 // (It's hard to describe here, please read code, it's like a cycle-moving)
272 for (Index2
= NewValuePos
; Index2
!= Index
;) {
273 if (NewValuePos
< Index
) {
274 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
277 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
283 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
284 // so we should modify DisMap to reflect the change
287 Bit
= 7 - (NewValue
% 8);
288 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
289 if (0xFF != OldValue
) {
291 // Because NewValue is a item that was disabled before
292 // so after changing the OldValue should be disabled
293 // actually we are doing a swap of enable-disable states of two items
296 Bit
= 7 - (OldValue
% 8);
297 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
302 // To prevent DISABLE appears in the middle of the list
303 // we should perform a re-ordering
306 while (Index
< Number
) {
307 if (0xFF != NewLegacyDev
[Index
]) {
314 while (Index2
< Number
) {
315 if (0xFF != NewLegacyDev
[Index2
]) {
322 if (Index2
< Number
) {
323 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
324 NewLegacyDev
[Index2
] = 0xFF;
338 if (KeyValue
< FILE_OPTION_OFFSET
) {
339 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
341 case KEY_VALUE_BOOT_FROM_FILE
:
342 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
345 // Exit Bmm main formset to send File Explorer formset.
347 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
351 case FORM_BOOT_ADD_ID
:
352 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
355 // Exit Bmm main formset to send File Explorer formset.
357 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
360 case FORM_DRV_ADD_FILE_ID
:
361 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
364 // Exit Bmm main formset to send File Explorer formset.
366 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
370 case FORM_DRV_ADD_HANDLE_ID
:
371 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
372 UpdateDrvAddHandlePage (Private
);
375 case FORM_BOOT_DEL_ID
:
376 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
377 UpdateBootDelPage (Private
);
380 case FORM_BOOT_CHG_ID
:
381 case FORM_DRV_CHG_ID
:
382 UpdatePageBody (KeyValue
, Private
);
385 case FORM_DRV_DEL_ID
:
386 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
387 UpdateDrvDelPage (Private
);
390 case FORM_BOOT_NEXT_ID
:
391 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
392 UpdateBootNextPage (Private
);
395 case FORM_TIME_OUT_ID
:
396 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
397 UpdateTimeOutPage (Private
);
401 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
402 return EFI_UNSUPPORTED
;
405 case FORM_CON_OUT_ID
:
406 case FORM_CON_ERR_ID
:
407 UpdatePageBody (KeyValue
, Private
);
410 case FORM_CON_COM_ID
:
411 CleanUpPage (FORM_CON_COM_ID
, Private
);
412 UpdateConCOMPage (Private
);
415 case FORM_SET_FD_ORDER_ID
:
416 case FORM_SET_HD_ORDER_ID
:
417 case FORM_SET_CD_ORDER_ID
:
418 case FORM_SET_NET_ORDER_ID
:
419 case FORM_SET_BEV_ORDER_ID
:
420 CleanUpPage (KeyValue
, Private
);
421 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
424 case KEY_VALUE_SAVE_AND_EXIT
:
425 case KEY_VALUE_NO_SAVE_AND_EXIT
:
427 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
428 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
429 if (EFI_ERROR (Status
)) {
432 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
433 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
436 // Tell browser not to ask for confirmation of changes,
437 // since we have already applied or discarded.
439 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
445 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
446 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
447 Private
->CurrentTerminal
= Index2
;
449 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
450 UpdateTerminalPage (Private
);
452 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
453 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
455 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
456 ASSERT (NewMenuEntry
!= NULL
);
457 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
459 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
461 Private
->MenuEntry
= NewMenuEntry
;
462 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
464 UpdateDriverAddHandleDescPage (Private
);
473 IN BMM_CALLBACK_DATA
*Private
,
474 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
481 Function handling request to apply changes for BMM pages.
485 Private - Pointer to callback data buffer.
486 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
487 FormId - ID of the form which has sent the request to apply change.
491 EFI_SUCCESS - Change successfully applied.
492 Other - Error occurs while trying to apply changes.
496 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
497 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
498 BM_LOAD_CONTEXT
*NewLoadContext
;
499 BM_MENU_ENTRY
*NewMenuEntry
;
503 Status
= EFI_SUCCESS
;
506 case FORM_SET_FD_ORDER_ID
:
507 case FORM_SET_HD_ORDER_ID
:
508 case FORM_SET_CD_ORDER_ID
:
509 case FORM_SET_NET_ORDER_ID
:
510 case FORM_SET_BEV_ORDER_ID
:
511 Var_UpdateBBSOption (Private
);
514 case FORM_BOOT_DEL_ID
:
515 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
516 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
517 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
518 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
521 Var_DelBootOption ();
524 case FORM_DRV_DEL_ID
:
525 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
526 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
527 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
528 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
531 Var_DelDriverOption ();
534 case FORM_BOOT_CHG_ID
:
535 Status
= Var_UpdateBootOrder (Private
);
538 case FORM_DRV_CHG_ID
:
539 Status
= Var_UpdateDriverOrder (Private
);
542 case FORM_TIME_OUT_ID
:
543 Status
= gRT
->SetVariable (
545 &gEfiGlobalVariableGuid
,
548 &(CurrentFakeNVMap
->BootTimeOut
)
550 if (EFI_ERROR (Status
)) {
554 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
557 case FORM_BOOT_NEXT_ID
:
558 Status
= Var_UpdateBootNext (Private
);
561 case FORM_CON_COM_ID
:
562 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
564 ASSERT (NewMenuEntry
!= NULL
);
566 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
568 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
569 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
570 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
571 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
572 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
573 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
574 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
575 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
576 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
578 ChangeTerminalDevicePath (
579 NewTerminalContext
->DevicePath
,
583 Var_UpdateConsoleInpOption ();
584 Var_UpdateConsoleOutOption ();
585 Var_UpdateErrorOutOption ();
589 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
590 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
591 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
592 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
595 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
596 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
597 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
598 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
601 Var_UpdateConsoleInpOption ();
604 case FORM_CON_OUT_ID
:
605 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
606 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
607 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
608 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
611 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
612 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
613 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
614 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
617 Var_UpdateConsoleOutOption ();
620 case FORM_CON_ERR_ID
:
621 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
622 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
623 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
624 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
627 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
628 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
629 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
630 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
633 Var_UpdateErrorOutOption ();
636 case FORM_DRV_ADD_HANDLE_DESC_ID
:
637 Status
= Var_UpdateDriverOption (
639 Private
->BmmHiiHandle
,
640 CurrentFakeNVMap
->DriverAddHandleDesc
,
641 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
642 CurrentFakeNVMap
->DriverAddForceReconnect
644 if (EFI_ERROR (Status
)) {
648 BOpt_GetDriverOptions (Private
);
649 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
661 DiscardChangeHandler (
662 IN BMM_CALLBACK_DATA
*Private
,
663 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
668 switch (Private
->BmmPreviousPageId
) {
669 case FORM_BOOT_CHG_ID
:
670 case FORM_DRV_CHG_ID
:
671 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
674 case FORM_BOOT_DEL_ID
:
675 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
676 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
680 case FORM_DRV_DEL_ID
:
681 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
682 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
686 case FORM_BOOT_NEXT_ID
:
687 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
690 case FORM_TIME_OUT_ID
:
691 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
694 case FORM_DRV_ADD_HANDLE_DESC_ID
:
695 case FORM_DRV_ADD_FILE_ID
:
696 case FORM_DRV_ADD_HANDLE_ID
:
697 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
698 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
709 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
710 IN CHAR16
*VariableName
,
711 IN EFI_GUID
*VendorGuid
,
712 OUT UINT32 Attributes OPTIONAL
,
713 IN OUT UINTN DataSize
,
715 OUT BOOLEAN
*ResetRequired
719 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
731 Initialize the Boot Maintenance Utitliy
735 ImageHandle - caller provided handle
737 SystemTable - caller provided system tables
741 EFI_SUCCESS - utility ended successfully
743 others - contain some errors
747 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
748 EFI_HII_PACKAGES
*PackageList
;
749 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
750 EFI_HII_PROTOCOL
*Hii
;
751 EFI_HII_HANDLE HiiHandle
;
757 Status
= EFI_SUCCESS
;
760 // Initialize EfiUtilityLib and EfiDriverLib
761 // Since many functions in UtilityLib must be used and
762 // SetupBrowser use DriverLib
765 // There should be only one EFI_HII_PROTOCOL Image
767 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
768 if (EFI_ERROR (Status
)) {
772 // Create CallbackData structures for Driver Callback
774 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
775 if (!BmmCallbackInfo
) {
776 return EFI_OUT_OF_RESOURCES
;
779 // Create LoadOption in BmmCallbackInfo for Driver Callback
781 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
783 SafeFreePool (BmmCallbackInfo
);
784 return EFI_OUT_OF_RESOURCES
;
787 // Initialize Bmm callback data.
789 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
790 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
792 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
793 Ptr
+= sizeof (BM_FILE_CONTEXT
);
795 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
796 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
798 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
800 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
802 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
804 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
805 BmmCallbackInfo
->Hii
= Hii
;
806 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
807 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
808 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
809 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
810 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
811 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
812 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
813 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
814 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
815 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
818 // Install bmm callback protocol interface
821 Status
= gBS
->InstallProtocolInterface (
823 &gEfiFormCallbackProtocolGuid
,
824 EFI_NATIVE_INTERFACE
,
825 &BmmCallbackInfo
->BmmDriverCallback
828 if (EFI_ERROR (Status
)) {
832 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
835 // Install file explorer callback protocol interface
838 Status
= gBS
->InstallProtocolInterface (
840 &gEfiFormCallbackProtocolGuid
,
841 EFI_NATIVE_INTERFACE
,
842 &BmmCallbackInfo
->FeDriverCallback
845 if (EFI_ERROR (Status
)) {
849 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
852 // Post our VFR to the HII database.
854 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, bmBin
);
855 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
856 FreePool (PackageList
);
858 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
860 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FEBin
);
861 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
862 FreePool (PackageList
);
864 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
867 // Allocate space for creation of Buffer
869 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
871 SafeFreePool (BmmCallbackInfo
->LoadContext
);
872 SafeFreePool (BmmCallbackInfo
);
873 return EFI_OUT_OF_RESOURCES
;
876 // Initialize UpdateData structure
878 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
880 Location
= (UINT8
*) &UpdateData
->Data
;
882 InitializeStringDepository ();
884 InitAllMenu (BmmCallbackInfo
);
886 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
887 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
888 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
889 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
890 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
891 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
892 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
894 UpdateBootDelPage (BmmCallbackInfo
);
895 UpdateDrvDelPage (BmmCallbackInfo
);
897 if (TerminalMenu
.MenuNumber
> 0) {
898 BmmCallbackInfo
->CurrentTerminal
= 0;
899 UpdateTerminalPage (BmmCallbackInfo
);
902 Location
= (UINT8
*) &UpdateData
->Data
;
903 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
904 if (!EFI_ERROR (Status
)) {
906 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
907 // in BootOption form: legacy FD/HD/CD/NET/BEV
909 UpdateData
->DataCount
= 5;
911 FORM_SET_FD_ORDER_ID
,
912 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
913 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
914 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
915 FORM_SET_FD_ORDER_ID
,
919 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
922 FORM_SET_HD_ORDER_ID
,
923 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
924 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
925 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
926 FORM_SET_HD_ORDER_ID
,
930 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
933 FORM_SET_CD_ORDER_ID
,
934 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
935 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
936 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
937 FORM_SET_CD_ORDER_ID
,
941 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
944 FORM_SET_NET_ORDER_ID
,
945 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
946 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
947 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
948 FORM_SET_NET_ORDER_ID
,
952 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
955 FORM_SET_BEV_ORDER_ID
,
956 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
957 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
958 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
959 FORM_SET_BEV_ORDER_ID
,
965 BmmCallbackInfo
->BmmHiiHandle
,
966 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
972 // Dispatch BMM main formset and File Explorer formset.
974 FormSetDispatcher (BmmCallbackInfo
);
976 Hii
->ResetStrings (Hii
, HiiHandle
);
978 CleanUpStringDepository ();
980 if (EFI_ERROR (Status
)) {
986 SafeFreePool (BmmCallbackInfo
->LoadContext
);
987 BmmCallbackInfo
->LoadContext
= NULL
;
988 SafeFreePool (BmmCallbackInfo
);
989 BmmCallbackInfo
= NULL
;
990 SafeFreePool (UpdateData
);
998 IN BMM_CALLBACK_DATA
*CallbackData
1001 InitializeListHead (&BootOptionMenu
.Head
);
1002 InitializeListHead (&DriverOptionMenu
.Head
);
1003 BOpt_GetBootOptions (CallbackData
);
1004 BOpt_GetDriverOptions (CallbackData
);
1005 BOpt_GetLegacyOptions ();
1006 InitializeListHead (&FsOptionMenu
.Head
);
1007 BOpt_FindDrivers ();
1008 InitializeListHead (&DirectoryMenu
.Head
);
1009 InitializeListHead (&ConsoleInpMenu
.Head
);
1010 InitializeListHead (&ConsoleOutMenu
.Head
);
1011 InitializeListHead (&ConsoleErrMenu
.Head
);
1012 InitializeListHead (&TerminalMenu
.Head
);
1022 BOpt_FreeMenu (&DirectoryMenu
);
1023 BOpt_FreeMenu (&FsOptionMenu
);
1024 BOpt_FreeMenu (&BootOptionMenu
);
1025 BOpt_FreeMenu (&DriverOptionMenu
);
1026 BOpt_FreeMenu (&DriverMenu
);
1027 BOpt_FreeLegacyOptions ();
1032 InitializeStringDepository (
1036 Routine Description:
1037 Intialize all the string depositories.
1046 STRING_DEPOSITORY
*StringDepository
;
1047 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1048 FileOptionStrDepository
= StringDepository
++;
1049 ConsoleOptionStrDepository
= StringDepository
++;
1050 BootOptionStrDepository
= StringDepository
++;
1051 BootOptionHelpStrDepository
= StringDepository
++;
1052 DriverOptionStrDepository
= StringDepository
++;
1053 DriverOptionHelpStrDepository
= StringDepository
++;
1054 TerminalStrDepository
= StringDepository
;
1058 GetStringTokenFromDepository (
1059 IN BMM_CALLBACK_DATA
*CallbackData
,
1060 IN STRING_DEPOSITORY
*StringDepository
1063 Routine Description:
1064 Fetch a usable string node from the string depository and return the string token.
1067 StringDepository - Pointer of the string depository.
1070 STRING_REF - String token.
1073 STRING_LIST_NODE
*CurrentListNode
;
1074 STRING_LIST_NODE
*NextListNode
;
1076 CurrentListNode
= StringDepository
->CurrentNode
;
1078 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1080 // Fetch one reclaimed node from the list.
1082 NextListNode
= StringDepository
->CurrentNode
->Next
;
1085 // If there is no usable node in the list, update the list.
1087 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1089 CallbackData
->Hii
->NewString (
1092 CallbackData
->BmmHiiHandle
,
1093 &(NextListNode
->StringToken
),
1097 ASSERT (NextListNode
->StringToken
!= 0);
1099 StringDepository
->TotalNodeNumber
++;
1101 if (NULL
== CurrentListNode
) {
1102 StringDepository
->ListHead
= NextListNode
;
1104 CurrentListNode
->Next
= NextListNode
;
1108 StringDepository
->CurrentNode
= NextListNode
;
1110 return StringDepository
->CurrentNode
->StringToken
;
1114 ReclaimStringDepository (
1118 Routine Description:
1119 Reclaim string depositories by moving the current node pointer to list head..
1128 UINTN DepositoryIndex
;
1129 STRING_DEPOSITORY
*StringDepository
;
1131 StringDepository
= FileOptionStrDepository
;
1132 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1133 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1139 CleanUpStringDepository (
1143 Routine Description:
1144 Release resource for all the string depositories.
1154 UINTN DepositoryIndex
;
1155 STRING_LIST_NODE
*CurrentListNode
;
1156 STRING_LIST_NODE
*NextListNode
;
1157 STRING_DEPOSITORY
*StringDepository
;
1160 // Release string list nodes.
1162 StringDepository
= FileOptionStrDepository
;
1163 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1164 CurrentListNode
= StringDepository
->ListHead
;
1165 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1166 NextListNode
= CurrentListNode
->Next
;
1167 SafeFreePool (CurrentListNode
);
1168 CurrentListNode
= NextListNode
;
1174 // Release string depository.
1176 SafeFreePool (FileOptionStrDepository
);
1185 Routine Description:
1186 Start boot maintenance manager
1195 LIST_ENTRY BdsBootOptionList
;
1197 InitializeListHead (&BdsBootOptionList
);
1200 // Connect all prior to entering the platform setup menu.
1202 if (!gConnectAllHappened
) {
1203 BdsLibConnectAllDriversToAllControllers ();
1204 gConnectAllHappened
= TRUE
;
1207 // Have chance to enumerate boot device
1209 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1214 Status
= InitializeBM ();
1221 IN BMM_CALLBACK_DATA
*CallbackData
1225 Routine Description:
1226 Dispatch BMM formset and FileExplorer formset.
1234 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1238 BM_MENU_ENTRY
*NewMenuEntry
;
1239 BM_FILE_CONTEXT
*NewFileContext
;
1240 BOOLEAN BootMaintMenuResetRequired
;
1244 NewMenuEntry
= NULL
;
1245 NewFileContext
= NULL
;
1248 // There should only be one Form Configuration protocol
1250 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1251 if (EFI_ERROR (Status
)) {
1256 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1258 BootMaintMenuResetRequired
= FALSE
;
1259 Status
= FormConfig
->SendForm (
1262 &(CallbackData
->BmmHiiHandle
),
1266 (UINT8
*) CallbackData
->BmmFakeNvData
,
1268 &BootMaintMenuResetRequired
1271 if (BootMaintMenuResetRequired
) {
1272 EnableResetRequired ();
1275 ReclaimStringDepository ();
1278 // When this Formset returns, check if we are going to explore files.
1280 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1281 UpdateFileExplorer (CallbackData
, 0);
1283 BootMaintMenuResetRequired
= FALSE
;
1284 Status
= FormConfig
->SendForm (
1287 &(CallbackData
->FeHiiHandle
),
1293 &BootMaintMenuResetRequired
1296 if (BootMaintMenuResetRequired
) {
1297 EnableResetRequired ();
1300 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1301 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1302 ReclaimStringDepository ();
1312 CreateCallbackPacket (
1313 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1317 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1318 ASSERT (*Packet
!= NULL
);
1320 (*Packet
)->DataArray
.EntryCount
= 1;
1321 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1322 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;