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"
29 #include "BdsStrDefs.h"
33 // Form binary for Boot Maintenance
37 extern EFI_GUID gBdsStringPackGuid
;
38 extern BOOLEAN gConnectAllHappened
;
40 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
44 IN BMM_CALLBACK_DATA
*CallbackData
53 CreateMenuStringToken (
54 IN BMM_CALLBACK_DATA
*CallbackData
,
55 IN EFI_HII_HANDLE HiiHandle
,
56 IN BM_MENU_OPTION
*MenuOption
61 Create string tokens for a menu from its help strings and display strings
65 HiiHandle - Hii Handle of the package to be updated.
67 MenuOption - The Menu whose string tokens need to be created
71 EFI_SUCCESS - string tokens created successfully
73 others - contain some errors
77 BM_MENU_ENTRY
*NewMenuEntry
;
80 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
81 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
82 CallbackData
->Hii
->NewString (
86 &NewMenuEntry
->DisplayStringToken
,
87 NewMenuEntry
->DisplayString
90 if (NULL
== NewMenuEntry
->HelpString
) {
91 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
93 CallbackData
->Hii
->NewString (
97 &NewMenuEntry
->HelpStringToken
,
98 NewMenuEntry
->HelpString
109 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
111 IN EFI_IFR_DATA_ARRAY
*Data
,
112 OUT EFI_HII_CALLBACK_PACKET
**Packet
117 Callback Function for boot maintenance utility user interface interaction.
121 This - File explorer callback protocol pointer.
122 KeyValue - Key value to identify the type of data to expect.
123 Data - A pointer to the data being sent to the original exporting driver.
124 Packet - A pointer to a packet of information which a driver passes back to the browser.
128 EFI_SUCCESS - Callback ended successfully.
129 Others - Contain some errors.
133 BMM_CALLBACK_DATA
*Private
;
134 BM_MENU_ENTRY
*NewMenuEntry
;
135 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
159 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
160 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
161 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
162 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
163 Location
= (UINT8
*) &UpdateData
->Data
;
165 UpdatePageId (Private
, KeyValue
);
168 // need to be subtituded.
170 // Update Select FD/HD/CD/NET/BEV Order Form
172 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
173 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
174 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
175 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
176 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
177 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
178 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
179 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
182 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
184 FormId
= Private
->BmmPreviousPageId
;
185 if (FormId
== FORM_BOOT_SETUP_ID
) {
186 FormId
= Private
->BmmCurrentPageId
;
190 case FORM_SET_FD_ORDER_ID
:
191 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
192 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
193 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
196 case FORM_SET_HD_ORDER_ID
:
197 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
198 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
199 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
202 case FORM_SET_CD_ORDER_ID
:
203 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
204 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
205 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
208 case FORM_SET_NET_ORDER_ID
:
209 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
210 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
211 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
214 case FORM_SET_BEV_ORDER_ID
:
215 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
216 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
217 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
224 // First, find the different position
225 // if there is change, it should be only one
227 for (Index
= 0; Index
< Number
; Index
++) {
228 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
229 OldValue
= OldLegacyDev
[Index
];
230 NewValue
= NewLegacyDev
[Index
];
235 if (Index
!= Number
) {
237 // there is change, now process
239 if (0xFF == NewValue
) {
241 // This item will be disable
242 // Just move the items behind this forward to overlap it
245 Bit
= 7 - (OldValue
% 8);
246 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
247 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
248 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
251 NewLegacyDev
[Index2
] = 0xFF;
253 for (Index2
= 0; Index2
< Number
; Index2
++) {
254 if (Index2
== Index
) {
258 if (OldLegacyDev
[Index2
] == NewValue
) {
260 // If NewValue is in OldLegacyDev array
261 // remember its old position
263 NewValuePos
= Index2
;
268 if (Index2
!= Number
) {
270 // We will change current item to an existing item
271 // (It's hard to describe here, please read code, it's like a cycle-moving)
273 for (Index2
= NewValuePos
; Index2
!= Index
;) {
274 if (NewValuePos
< Index
) {
275 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
278 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
284 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
285 // so we should modify DisMap to reflect the change
288 Bit
= 7 - (NewValue
% 8);
289 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
290 if (0xFF != OldValue
) {
292 // Because NewValue is a item that was disabled before
293 // so after changing the OldValue should be disabled
294 // actually we are doing a swap of enable-disable states of two items
297 Bit
= 7 - (OldValue
% 8);
298 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
303 // To prevent DISABLE appears in the middle of the list
304 // we should perform a re-ordering
307 while (Index
< Number
) {
308 if (0xFF != NewLegacyDev
[Index
]) {
315 while (Index2
< Number
) {
316 if (0xFF != NewLegacyDev
[Index2
]) {
323 if (Index2
< Number
) {
324 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
325 NewLegacyDev
[Index2
] = 0xFF;
339 if (KeyValue
< FILE_OPTION_OFFSET
) {
340 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
342 case KEY_VALUE_BOOT_FROM_FILE
:
343 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
346 // Exit Bmm main formset to send File Explorer formset.
348 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
352 case FORM_BOOT_ADD_ID
:
353 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
356 // Exit Bmm main formset to send File Explorer formset.
358 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
361 case FORM_DRV_ADD_FILE_ID
:
362 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
365 // Exit Bmm main formset to send File Explorer formset.
367 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
371 case FORM_DRV_ADD_HANDLE_ID
:
372 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
373 UpdateDrvAddHandlePage (Private
);
376 case FORM_BOOT_DEL_ID
:
377 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
378 UpdateBootDelPage (Private
);
381 case FORM_BOOT_CHG_ID
:
382 case FORM_DRV_CHG_ID
:
383 UpdatePageBody (KeyValue
, Private
);
386 case FORM_DRV_DEL_ID
:
387 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
388 UpdateDrvDelPage (Private
);
391 case FORM_BOOT_NEXT_ID
:
392 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
393 UpdateBootNextPage (Private
);
396 case FORM_TIME_OUT_ID
:
397 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
398 UpdateTimeOutPage (Private
);
402 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
403 return EFI_UNSUPPORTED
;
406 case FORM_CON_OUT_ID
:
407 case FORM_CON_ERR_ID
:
408 UpdatePageBody (KeyValue
, Private
);
411 case FORM_CON_COM_ID
:
412 CleanUpPage (FORM_CON_COM_ID
, Private
);
413 UpdateConCOMPage (Private
);
416 case FORM_SET_FD_ORDER_ID
:
417 case FORM_SET_HD_ORDER_ID
:
418 case FORM_SET_CD_ORDER_ID
:
419 case FORM_SET_NET_ORDER_ID
:
420 case FORM_SET_BEV_ORDER_ID
:
421 CleanUpPage (KeyValue
, Private
);
422 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
425 case KEY_VALUE_SAVE_AND_EXIT
:
426 case KEY_VALUE_NO_SAVE_AND_EXIT
:
428 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
429 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
430 if (EFI_ERROR (Status
)) {
433 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
434 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
437 // Tell browser not to ask for confirmation of changes,
438 // since we have already applied or discarded.
440 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
446 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
447 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
448 Private
->CurrentTerminal
= Index2
;
450 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
451 UpdateTerminalPage (Private
);
453 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
454 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
456 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
457 ASSERT (NewMenuEntry
!= NULL
);
458 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
460 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
462 Private
->MenuEntry
= NewMenuEntry
;
463 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
465 UpdateDriverAddHandleDescPage (Private
);
474 IN BMM_CALLBACK_DATA
*Private
,
475 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
482 Function handling request to apply changes for BMM pages.
486 Private - Pointer to callback data buffer.
487 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
488 FormId - ID of the form which has sent the request to apply change.
492 EFI_SUCCESS - Change successfully applied.
493 Other - Error occurs while trying to apply changes.
497 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
498 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
499 BM_LOAD_CONTEXT
*NewLoadContext
;
500 BM_MENU_ENTRY
*NewMenuEntry
;
504 Status
= EFI_SUCCESS
;
507 case FORM_SET_FD_ORDER_ID
:
508 case FORM_SET_HD_ORDER_ID
:
509 case FORM_SET_CD_ORDER_ID
:
510 case FORM_SET_NET_ORDER_ID
:
511 case FORM_SET_BEV_ORDER_ID
:
512 Var_UpdateBBSOption (Private
);
515 case FORM_BOOT_DEL_ID
:
516 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
517 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
518 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
519 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
522 Var_DelBootOption ();
525 case FORM_DRV_DEL_ID
:
526 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
527 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
528 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
529 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
532 Var_DelDriverOption ();
535 case FORM_BOOT_CHG_ID
:
536 Status
= Var_UpdateBootOrder (Private
);
539 case FORM_DRV_CHG_ID
:
540 Status
= Var_UpdateDriverOrder (Private
);
543 case FORM_TIME_OUT_ID
:
544 Status
= gRT
->SetVariable (
546 &gEfiGlobalVariableGuid
,
549 &(CurrentFakeNVMap
->BootTimeOut
)
551 if (EFI_ERROR (Status
)) {
555 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
558 case FORM_BOOT_NEXT_ID
:
559 Status
= Var_UpdateBootNext (Private
);
562 case FORM_CON_COM_ID
:
563 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
565 ASSERT (NewMenuEntry
!= NULL
);
567 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
569 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
570 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
571 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
572 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
573 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
574 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
575 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
576 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
577 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
579 ChangeTerminalDevicePath (
580 NewTerminalContext
->DevicePath
,
584 Var_UpdateConsoleInpOption ();
585 Var_UpdateConsoleOutOption ();
586 Var_UpdateErrorOutOption ();
590 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
591 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
592 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
593 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
596 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
597 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
598 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
599 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
602 Var_UpdateConsoleInpOption ();
605 case FORM_CON_OUT_ID
:
606 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
607 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
608 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
609 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
612 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
613 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
614 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
615 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
618 Var_UpdateConsoleOutOption ();
621 case FORM_CON_ERR_ID
:
622 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
623 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
624 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
625 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
628 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
629 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
630 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
631 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
634 Var_UpdateErrorOutOption ();
637 case FORM_DRV_ADD_HANDLE_DESC_ID
:
638 Status
= Var_UpdateDriverOption (
640 Private
->BmmHiiHandle
,
641 CurrentFakeNVMap
->DriverAddHandleDesc
,
642 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
643 CurrentFakeNVMap
->DriverAddForceReconnect
645 if (EFI_ERROR (Status
)) {
649 BOpt_GetDriverOptions (Private
);
650 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
662 DiscardChangeHandler (
663 IN BMM_CALLBACK_DATA
*Private
,
664 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
669 switch (Private
->BmmPreviousPageId
) {
670 case FORM_BOOT_CHG_ID
:
671 case FORM_DRV_CHG_ID
:
672 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
675 case FORM_BOOT_DEL_ID
:
676 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
677 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
681 case FORM_DRV_DEL_ID
:
682 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
683 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
687 case FORM_BOOT_NEXT_ID
:
688 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
691 case FORM_TIME_OUT_ID
:
692 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
695 case FORM_DRV_ADD_HANDLE_DESC_ID
:
696 case FORM_DRV_ADD_FILE_ID
:
697 case FORM_DRV_ADD_HANDLE_ID
:
698 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
699 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
710 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
711 IN CHAR16
*VariableName
,
712 IN EFI_GUID
*VendorGuid
,
713 OUT UINT32 Attributes OPTIONAL
,
714 IN OUT UINTN DataSize
,
716 OUT BOOLEAN
*ResetRequired
720 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
732 Initialize the Boot Maintenance Utitliy
736 ImageHandle - caller provided handle
738 SystemTable - caller provided system tables
742 EFI_SUCCESS - utility ended successfully
744 others - contain some errors
748 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
749 EFI_HII_PACKAGES
*PackageList
;
750 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
751 EFI_HII_PROTOCOL
*Hii
;
752 EFI_HII_HANDLE HiiHandle
;
758 Status
= EFI_SUCCESS
;
761 // Initialize EfiUtilityLib and EfiDriverLib
762 // Since many functions in UtilityLib must be used and
763 // SetupBrowser use DriverLib
766 // There should be only one EFI_HII_PROTOCOL Image
768 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
769 if (EFI_ERROR (Status
)) {
773 // Create CallbackData structures for Driver Callback
775 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
776 if (!BmmCallbackInfo
) {
777 return EFI_OUT_OF_RESOURCES
;
780 // Create LoadOption in BmmCallbackInfo for Driver Callback
782 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
784 SafeFreePool (BmmCallbackInfo
);
785 return EFI_OUT_OF_RESOURCES
;
788 // Initialize Bmm callback data.
790 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
791 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
793 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
794 Ptr
+= sizeof (BM_FILE_CONTEXT
);
796 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
797 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
799 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
801 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
803 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
805 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
806 BmmCallbackInfo
->Hii
= Hii
;
807 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
808 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
809 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
810 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
811 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
812 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
813 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
814 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
815 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
816 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
819 // Install bmm callback protocol interface
822 Status
= gBS
->InstallProtocolInterface (
824 &gEfiFormCallbackProtocolGuid
,
825 EFI_NATIVE_INTERFACE
,
826 &BmmCallbackInfo
->BmmDriverCallback
829 if (EFI_ERROR (Status
)) {
833 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
836 // Install file explorer callback protocol interface
839 Status
= gBS
->InstallProtocolInterface (
841 &gEfiFormCallbackProtocolGuid
,
842 EFI_NATIVE_INTERFACE
,
843 &BmmCallbackInfo
->FeDriverCallback
846 if (EFI_ERROR (Status
)) {
850 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
853 // Post our VFR to the HII database.
855 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, bmBin
);
856 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
857 FreePool (PackageList
);
859 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
861 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FEBin
);
862 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
863 FreePool (PackageList
);
865 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
868 // Allocate space for creation of Buffer
870 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
872 SafeFreePool (BmmCallbackInfo
->LoadContext
);
873 SafeFreePool (BmmCallbackInfo
);
874 return EFI_OUT_OF_RESOURCES
;
877 // Initialize UpdateData structure
879 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
881 Location
= (UINT8
*) &UpdateData
->Data
;
883 InitializeStringDepository ();
885 InitAllMenu (BmmCallbackInfo
);
887 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
888 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
889 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
890 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
891 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
892 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
893 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
895 UpdateBootDelPage (BmmCallbackInfo
);
896 UpdateDrvDelPage (BmmCallbackInfo
);
898 if (TerminalMenu
.MenuNumber
> 0) {
899 BmmCallbackInfo
->CurrentTerminal
= 0;
900 UpdateTerminalPage (BmmCallbackInfo
);
903 Location
= (UINT8
*) &UpdateData
->Data
;
904 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
905 if (!EFI_ERROR (Status
)) {
907 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
908 // in BootOption form: legacy FD/HD/CD/NET/BEV
910 UpdateData
->DataCount
= 5;
912 FORM_SET_FD_ORDER_ID
,
913 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
914 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
915 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
916 FORM_SET_FD_ORDER_ID
,
920 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
923 FORM_SET_HD_ORDER_ID
,
924 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
925 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
926 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
927 FORM_SET_HD_ORDER_ID
,
931 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
934 FORM_SET_CD_ORDER_ID
,
935 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
936 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
937 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
938 FORM_SET_CD_ORDER_ID
,
942 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
945 FORM_SET_NET_ORDER_ID
,
946 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
947 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
948 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
949 FORM_SET_NET_ORDER_ID
,
953 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
956 FORM_SET_BEV_ORDER_ID
,
957 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
958 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
959 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
960 FORM_SET_BEV_ORDER_ID
,
966 BmmCallbackInfo
->BmmHiiHandle
,
967 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
973 // Dispatch BMM main formset and File Explorer formset.
975 FormSetDispatcher (BmmCallbackInfo
);
977 Hii
->ResetStrings (Hii
, HiiHandle
);
979 CleanUpStringDepository ();
981 if (EFI_ERROR (Status
)) {
987 SafeFreePool (BmmCallbackInfo
->LoadContext
);
988 BmmCallbackInfo
->LoadContext
= NULL
;
989 SafeFreePool (BmmCallbackInfo
);
990 BmmCallbackInfo
= NULL
;
991 SafeFreePool (UpdateData
);
999 IN BMM_CALLBACK_DATA
*CallbackData
1002 InitializeListHead (&BootOptionMenu
.Head
);
1003 InitializeListHead (&DriverOptionMenu
.Head
);
1004 BOpt_GetBootOptions (CallbackData
);
1005 BOpt_GetDriverOptions (CallbackData
);
1006 BOpt_GetLegacyOptions ();
1007 InitializeListHead (&FsOptionMenu
.Head
);
1008 BOpt_FindDrivers ();
1009 InitializeListHead (&DirectoryMenu
.Head
);
1010 InitializeListHead (&ConsoleInpMenu
.Head
);
1011 InitializeListHead (&ConsoleOutMenu
.Head
);
1012 InitializeListHead (&ConsoleErrMenu
.Head
);
1013 InitializeListHead (&TerminalMenu
.Head
);
1023 BOpt_FreeMenu (&DirectoryMenu
);
1024 BOpt_FreeMenu (&FsOptionMenu
);
1025 BOpt_FreeMenu (&BootOptionMenu
);
1026 BOpt_FreeMenu (&DriverOptionMenu
);
1027 BOpt_FreeMenu (&DriverMenu
);
1028 BOpt_FreeLegacyOptions ();
1033 InitializeStringDepository (
1037 Routine Description:
1038 Intialize all the string depositories.
1047 STRING_DEPOSITORY
*StringDepository
;
1048 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1049 FileOptionStrDepository
= StringDepository
++;
1050 ConsoleOptionStrDepository
= StringDepository
++;
1051 BootOptionStrDepository
= StringDepository
++;
1052 BootOptionHelpStrDepository
= StringDepository
++;
1053 DriverOptionStrDepository
= StringDepository
++;
1054 DriverOptionHelpStrDepository
= StringDepository
++;
1055 TerminalStrDepository
= StringDepository
;
1059 GetStringTokenFromDepository (
1060 IN BMM_CALLBACK_DATA
*CallbackData
,
1061 IN STRING_DEPOSITORY
*StringDepository
1064 Routine Description:
1065 Fetch a usable string node from the string depository and return the string token.
1068 StringDepository - Pointer of the string depository.
1071 STRING_REF - String token.
1074 STRING_LIST_NODE
*CurrentListNode
;
1075 STRING_LIST_NODE
*NextListNode
;
1077 CurrentListNode
= StringDepository
->CurrentNode
;
1079 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1081 // Fetch one reclaimed node from the list.
1083 NextListNode
= StringDepository
->CurrentNode
->Next
;
1086 // If there is no usable node in the list, update the list.
1088 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1090 CallbackData
->Hii
->NewString (
1093 CallbackData
->BmmHiiHandle
,
1094 &(NextListNode
->StringToken
),
1098 ASSERT (NextListNode
->StringToken
!= 0);
1100 StringDepository
->TotalNodeNumber
++;
1102 if (NULL
== CurrentListNode
) {
1103 StringDepository
->ListHead
= NextListNode
;
1105 CurrentListNode
->Next
= NextListNode
;
1109 StringDepository
->CurrentNode
= NextListNode
;
1111 return StringDepository
->CurrentNode
->StringToken
;
1115 ReclaimStringDepository (
1119 Routine Description:
1120 Reclaim string depositories by moving the current node pointer to list head..
1129 UINTN DepositoryIndex
;
1130 STRING_DEPOSITORY
*StringDepository
;
1132 StringDepository
= FileOptionStrDepository
;
1133 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1134 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1140 CleanUpStringDepository (
1144 Routine Description:
1145 Release resource for all the string depositories.
1155 UINTN DepositoryIndex
;
1156 STRING_LIST_NODE
*CurrentListNode
;
1157 STRING_LIST_NODE
*NextListNode
;
1158 STRING_DEPOSITORY
*StringDepository
;
1161 // Release string list nodes.
1163 StringDepository
= FileOptionStrDepository
;
1164 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1165 CurrentListNode
= StringDepository
->ListHead
;
1166 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1167 NextListNode
= CurrentListNode
->Next
;
1168 SafeFreePool (CurrentListNode
);
1169 CurrentListNode
= NextListNode
;
1175 // Release string depository.
1177 SafeFreePool (FileOptionStrDepository
);
1186 Routine Description:
1187 Start boot maintenance manager
1196 LIST_ENTRY BdsBootOptionList
;
1198 InitializeListHead (&BdsBootOptionList
);
1201 // Connect all prior to entering the platform setup menu.
1203 if (!gConnectAllHappened
) {
1204 BdsLibConnectAllDriversToAllControllers ();
1205 gConnectAllHappened
= TRUE
;
1208 // Have chance to enumerate boot device
1210 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1215 Status
= InitializeBM ();
1222 IN BMM_CALLBACK_DATA
*CallbackData
1226 Routine Description:
1227 Dispatch BMM formset and FileExplorer formset.
1235 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1239 BM_MENU_ENTRY
*NewMenuEntry
;
1240 BM_FILE_CONTEXT
*NewFileContext
;
1241 BOOLEAN BootMaintMenuResetRequired
;
1245 NewMenuEntry
= NULL
;
1246 NewFileContext
= NULL
;
1249 // There should only be one Form Configuration protocol
1251 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1252 if (EFI_ERROR (Status
)) {
1257 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1259 BootMaintMenuResetRequired
= FALSE
;
1260 Status
= FormConfig
->SendForm (
1263 &(CallbackData
->BmmHiiHandle
),
1267 (UINT8
*) CallbackData
->BmmFakeNvData
,
1269 &BootMaintMenuResetRequired
1272 if (BootMaintMenuResetRequired
) {
1273 EnableResetRequired ();
1276 ReclaimStringDepository ();
1279 // When this Formset returns, check if we are going to explore files.
1281 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1282 UpdateFileExplorer (CallbackData
, 0);
1284 BootMaintMenuResetRequired
= FALSE
;
1285 Status
= FormConfig
->SendForm (
1288 &(CallbackData
->FeHiiHandle
),
1294 &BootMaintMenuResetRequired
1297 if (BootMaintMenuResetRequired
) {
1298 EnableResetRequired ();
1301 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1302 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1303 ReclaimStringDepository ();
1313 CreateCallbackPacket (
1314 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1318 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1319 ASSERT (*Packet
!= NULL
);
1321 (*Packet
)->DataArray
.EntryCount
= 1;
1322 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1323 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;