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
22 #include "Generic/Bds.h"
23 #include "BootMaint.h"
27 // Form binary for Boot Maintenance
31 extern BOOLEAN gConnectAllHappened
;
33 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
37 IN BMM_CALLBACK_DATA
*CallbackData
46 CreateMenuStringToken (
47 IN BMM_CALLBACK_DATA
*CallbackData
,
48 IN EFI_HII_HANDLE HiiHandle
,
49 IN BM_MENU_OPTION
*MenuOption
54 Create string tokens for a menu from its help strings and display strings
58 HiiHandle - Hii Handle of the package to be updated.
60 MenuOption - The Menu whose string tokens need to be created
64 EFI_SUCCESS - string tokens created successfully
66 others - contain some errors
70 BM_MENU_ENTRY
*NewMenuEntry
;
73 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
74 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
75 CallbackData
->Hii
->NewString (
79 &NewMenuEntry
->DisplayStringToken
,
80 NewMenuEntry
->DisplayString
83 if (NULL
== NewMenuEntry
->HelpString
) {
84 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
86 CallbackData
->Hii
->NewString (
90 &NewMenuEntry
->HelpStringToken
,
91 NewMenuEntry
->HelpString
102 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
104 IN EFI_IFR_DATA_ARRAY
*Data
,
105 OUT EFI_HII_CALLBACK_PACKET
**Packet
110 Callback Function for boot maintenance utility user interface interaction.
114 This - File explorer callback protocol pointer.
115 KeyValue - Key value to identify the type of data to expect.
116 Data - A pointer to the data being sent to the original exporting driver.
117 Packet - A pointer to a packet of information which a driver passes back to the browser.
121 EFI_SUCCESS - Callback ended successfully.
122 Others - Contain some errors.
126 BMM_CALLBACK_DATA
*Private
;
127 BM_MENU_ENTRY
*NewMenuEntry
;
128 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
152 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
153 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
154 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
155 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
156 Location
= (UINT8
*) &UpdateData
->Data
;
158 UpdatePageId (Private
, KeyValue
);
161 // need to be subtituded.
163 // Update Select FD/HD/CD/NET/BEV Order Form
165 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
166 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
167 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
168 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
169 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
170 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
171 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
172 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
175 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
177 FormId
= Private
->BmmPreviousPageId
;
178 if (FormId
== FORM_BOOT_SETUP_ID
) {
179 FormId
= Private
->BmmCurrentPageId
;
183 case FORM_SET_FD_ORDER_ID
:
184 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
185 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
186 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
189 case FORM_SET_HD_ORDER_ID
:
190 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
191 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
192 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
195 case FORM_SET_CD_ORDER_ID
:
196 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
197 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
198 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
201 case FORM_SET_NET_ORDER_ID
:
202 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
203 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
204 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
207 case FORM_SET_BEV_ORDER_ID
:
208 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
209 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
210 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
217 // First, find the different position
218 // if there is change, it should be only one
220 for (Index
= 0; Index
< Number
; Index
++) {
221 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
222 OldValue
= OldLegacyDev
[Index
];
223 NewValue
= NewLegacyDev
[Index
];
228 if (Index
!= Number
) {
230 // there is change, now process
232 if (0xFF == NewValue
) {
234 // This item will be disable
235 // Just move the items behind this forward to overlap it
238 Bit
= 7 - (OldValue
% 8);
239 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
240 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
241 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
244 NewLegacyDev
[Index2
] = 0xFF;
246 for (Index2
= 0; Index2
< Number
; Index2
++) {
247 if (Index2
== Index
) {
251 if (OldLegacyDev
[Index2
] == NewValue
) {
253 // If NewValue is in OldLegacyDev array
254 // remember its old position
256 NewValuePos
= Index2
;
261 if (Index2
!= Number
) {
263 // We will change current item to an existing item
264 // (It's hard to describe here, please read code, it's like a cycle-moving)
266 for (Index2
= NewValuePos
; Index2
!= Index
;) {
267 if (NewValuePos
< Index
) {
268 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
271 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
277 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
278 // so we should modify DisMap to reflect the change
281 Bit
= 7 - (NewValue
% 8);
282 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
283 if (0xFF != OldValue
) {
285 // Because NewValue is a item that was disabled before
286 // so after changing the OldValue should be disabled
287 // actually we are doing a swap of enable-disable states of two items
290 Bit
= 7 - (OldValue
% 8);
291 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
296 // To prevent DISABLE appears in the middle of the list
297 // we should perform a re-ordering
300 while (Index
< Number
) {
301 if (0xFF != NewLegacyDev
[Index
]) {
308 while (Index2
< Number
) {
309 if (0xFF != NewLegacyDev
[Index2
]) {
316 if (Index2
< Number
) {
317 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
318 NewLegacyDev
[Index2
] = 0xFF;
332 if (KeyValue
< FILE_OPTION_OFFSET
) {
333 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
335 case KEY_VALUE_BOOT_FROM_FILE
:
336 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
339 // Exit Bmm main formset to send File Explorer formset.
341 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
345 case FORM_BOOT_ADD_ID
:
346 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
349 // Exit Bmm main formset to send File Explorer formset.
351 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
354 case FORM_DRV_ADD_FILE_ID
:
355 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
358 // Exit Bmm main formset to send File Explorer formset.
360 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
364 case FORM_DRV_ADD_HANDLE_ID
:
365 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
366 UpdateDrvAddHandlePage (Private
);
369 case FORM_BOOT_DEL_ID
:
370 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
371 UpdateBootDelPage (Private
);
374 case FORM_BOOT_CHG_ID
:
375 case FORM_DRV_CHG_ID
:
376 UpdatePageBody (KeyValue
, Private
);
379 case FORM_DRV_DEL_ID
:
380 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
381 UpdateDrvDelPage (Private
);
384 case FORM_BOOT_NEXT_ID
:
385 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
386 UpdateBootNextPage (Private
);
389 case FORM_TIME_OUT_ID
:
390 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
391 UpdateTimeOutPage (Private
);
395 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
396 return EFI_UNSUPPORTED
;
399 case FORM_CON_OUT_ID
:
400 case FORM_CON_ERR_ID
:
401 UpdatePageBody (KeyValue
, Private
);
404 case FORM_CON_COM_ID
:
405 CleanUpPage (FORM_CON_COM_ID
, Private
);
406 UpdateConCOMPage (Private
);
409 case FORM_SET_FD_ORDER_ID
:
410 case FORM_SET_HD_ORDER_ID
:
411 case FORM_SET_CD_ORDER_ID
:
412 case FORM_SET_NET_ORDER_ID
:
413 case FORM_SET_BEV_ORDER_ID
:
414 CleanUpPage (KeyValue
, Private
);
415 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
418 case KEY_VALUE_SAVE_AND_EXIT
:
419 case KEY_VALUE_NO_SAVE_AND_EXIT
:
421 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
422 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
423 if (EFI_ERROR (Status
)) {
426 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
427 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
430 // Tell browser not to ask for confirmation of changes,
431 // since we have already applied or discarded.
433 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
439 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
440 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
441 Private
->CurrentTerminal
= Index2
;
443 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
444 UpdateTerminalPage (Private
);
446 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
447 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
449 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
450 ASSERT (NewMenuEntry
!= NULL
);
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 ASSERT (NewMenuEntry
!= NULL
);
560 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
562 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
563 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
564 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
565 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
566 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
567 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
568 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
569 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
570 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
572 ChangeTerminalDevicePath (
573 NewTerminalContext
->DevicePath
,
577 Var_UpdateConsoleInpOption ();
578 Var_UpdateConsoleOutOption ();
579 Var_UpdateErrorOutOption ();
583 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
584 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
585 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
586 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
589 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
590 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
591 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
592 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
595 Var_UpdateConsoleInpOption ();
598 case FORM_CON_OUT_ID
:
599 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
600 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
601 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
602 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
605 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
606 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
607 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
608 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
611 Var_UpdateConsoleOutOption ();
614 case FORM_CON_ERR_ID
:
615 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
616 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
617 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
618 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
621 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
622 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
623 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
624 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
627 Var_UpdateErrorOutOption ();
630 case FORM_DRV_ADD_HANDLE_DESC_ID
:
631 Status
= Var_UpdateDriverOption (
633 Private
->BmmHiiHandle
,
634 CurrentFakeNVMap
->DriverAddHandleDesc
,
635 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
636 CurrentFakeNVMap
->DriverAddForceReconnect
638 if (EFI_ERROR (Status
)) {
642 BOpt_GetDriverOptions (Private
);
643 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
655 DiscardChangeHandler (
656 IN BMM_CALLBACK_DATA
*Private
,
657 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
662 switch (Private
->BmmPreviousPageId
) {
663 case FORM_BOOT_CHG_ID
:
664 case FORM_DRV_CHG_ID
:
665 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
668 case FORM_BOOT_DEL_ID
:
669 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
670 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
674 case FORM_DRV_DEL_ID
:
675 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
676 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
680 case FORM_BOOT_NEXT_ID
:
681 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
684 case FORM_TIME_OUT_ID
:
685 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
688 case FORM_DRV_ADD_HANDLE_DESC_ID
:
689 case FORM_DRV_ADD_FILE_ID
:
690 case FORM_DRV_ADD_HANDLE_ID
:
691 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
692 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
703 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
704 IN CHAR16
*VariableName
,
705 IN EFI_GUID
*VendorGuid
,
706 OUT UINT32 Attributes OPTIONAL
,
707 IN OUT UINTN DataSize
,
709 OUT BOOLEAN
*ResetRequired
713 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
725 Initialize the Boot Maintenance Utitliy
729 ImageHandle - caller provided handle
731 SystemTable - caller provided system tables
735 EFI_SUCCESS - utility ended successfully
737 others - contain some errors
741 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
742 EFI_HII_PACKAGES
*PackageList
;
743 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
744 EFI_HII_PROTOCOL
*Hii
;
745 EFI_HII_HANDLE HiiHandle
;
751 Status
= EFI_SUCCESS
;
754 // Initialize EfiUtilityLib and EfiDriverLib
755 // Since many functions in UtilityLib must be used and
756 // SetupBrowser use DriverLib
759 // There should be only one EFI_HII_PROTOCOL Image
761 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
762 if (EFI_ERROR (Status
)) {
766 // Create CallbackData structures for Driver Callback
768 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
769 if (!BmmCallbackInfo
) {
770 return EFI_OUT_OF_RESOURCES
;
773 // Create LoadOption in BmmCallbackInfo for Driver Callback
775 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
777 SafeFreePool (BmmCallbackInfo
);
778 return EFI_OUT_OF_RESOURCES
;
781 // Initialize Bmm callback data.
783 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
784 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
786 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
787 Ptr
+= sizeof (BM_FILE_CONTEXT
);
789 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
790 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
792 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
794 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
796 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
798 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
799 BmmCallbackInfo
->Hii
= Hii
;
800 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
801 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
802 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
803 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
804 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
805 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
806 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
807 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
808 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
809 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
812 // Install bmm callback protocol interface
815 Status
= gBS
->InstallProtocolInterface (
817 &gEfiFormCallbackProtocolGuid
,
818 EFI_NATIVE_INTERFACE
,
819 &BmmCallbackInfo
->BmmDriverCallback
822 if (EFI_ERROR (Status
)) {
826 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
829 // Install file explorer callback protocol interface
832 Status
= gBS
->InstallProtocolInterface (
834 &gEfiFormCallbackProtocolGuid
,
835 EFI_NATIVE_INTERFACE
,
836 &BmmCallbackInfo
->FeDriverCallback
839 if (EFI_ERROR (Status
)) {
843 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
846 // Post our VFR to the HII database.
848 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, bmBin
);
849 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
850 FreePool (PackageList
);
852 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
854 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, FEBin
);
855 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
856 FreePool (PackageList
);
858 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
861 // Allocate space for creation of Buffer
863 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
865 SafeFreePool (BmmCallbackInfo
->LoadContext
);
866 SafeFreePool (BmmCallbackInfo
);
867 return EFI_OUT_OF_RESOURCES
;
870 // Initialize UpdateData structure
872 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
874 Location
= (UINT8
*) &UpdateData
->Data
;
876 InitializeStringDepository ();
878 InitAllMenu (BmmCallbackInfo
);
880 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
881 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
882 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
883 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
884 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
885 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
886 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
888 UpdateBootDelPage (BmmCallbackInfo
);
889 UpdateDrvDelPage (BmmCallbackInfo
);
891 if (TerminalMenu
.MenuNumber
> 0) {
892 BmmCallbackInfo
->CurrentTerminal
= 0;
893 UpdateTerminalPage (BmmCallbackInfo
);
896 Location
= (UINT8
*) &UpdateData
->Data
;
897 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
898 if (!EFI_ERROR (Status
)) {
900 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
901 // in BootOption form: legacy FD/HD/CD/NET/BEV
903 UpdateData
->DataCount
= 5;
905 FORM_SET_FD_ORDER_ID
,
906 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
907 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
908 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
909 FORM_SET_FD_ORDER_ID
,
913 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
916 FORM_SET_HD_ORDER_ID
,
917 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
918 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
919 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
920 FORM_SET_HD_ORDER_ID
,
924 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
927 FORM_SET_CD_ORDER_ID
,
928 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
929 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
930 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
931 FORM_SET_CD_ORDER_ID
,
935 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
938 FORM_SET_NET_ORDER_ID
,
939 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
940 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
941 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
942 FORM_SET_NET_ORDER_ID
,
946 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
949 FORM_SET_BEV_ORDER_ID
,
950 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
951 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
952 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
953 FORM_SET_BEV_ORDER_ID
,
959 BmmCallbackInfo
->BmmHiiHandle
,
960 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
966 // Dispatch BMM main formset and File Explorer formset.
968 FormSetDispatcher (BmmCallbackInfo
);
970 Hii
->ResetStrings (Hii
, HiiHandle
);
972 CleanUpStringDepository ();
974 if (EFI_ERROR (Status
)) {
980 SafeFreePool (BmmCallbackInfo
->LoadContext
);
981 BmmCallbackInfo
->LoadContext
= NULL
;
982 SafeFreePool (BmmCallbackInfo
);
983 BmmCallbackInfo
= NULL
;
984 SafeFreePool (UpdateData
);
992 IN BMM_CALLBACK_DATA
*CallbackData
995 InitializeListHead (&BootOptionMenu
.Head
);
996 InitializeListHead (&DriverOptionMenu
.Head
);
997 BOpt_GetBootOptions (CallbackData
);
998 BOpt_GetDriverOptions (CallbackData
);
999 BOpt_GetLegacyOptions ();
1000 InitializeListHead (&FsOptionMenu
.Head
);
1001 BOpt_FindDrivers ();
1002 InitializeListHead (&DirectoryMenu
.Head
);
1003 InitializeListHead (&ConsoleInpMenu
.Head
);
1004 InitializeListHead (&ConsoleOutMenu
.Head
);
1005 InitializeListHead (&ConsoleErrMenu
.Head
);
1006 InitializeListHead (&TerminalMenu
.Head
);
1016 BOpt_FreeMenu (&DirectoryMenu
);
1017 BOpt_FreeMenu (&FsOptionMenu
);
1018 BOpt_FreeMenu (&BootOptionMenu
);
1019 BOpt_FreeMenu (&DriverOptionMenu
);
1020 BOpt_FreeMenu (&DriverMenu
);
1021 BOpt_FreeLegacyOptions ();
1026 InitializeStringDepository (
1030 Routine Description:
1031 Intialize all the string depositories.
1040 STRING_DEPOSITORY
*StringDepository
;
1041 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1042 FileOptionStrDepository
= StringDepository
++;
1043 ConsoleOptionStrDepository
= StringDepository
++;
1044 BootOptionStrDepository
= StringDepository
++;
1045 BootOptionHelpStrDepository
= StringDepository
++;
1046 DriverOptionStrDepository
= StringDepository
++;
1047 DriverOptionHelpStrDepository
= StringDepository
++;
1048 TerminalStrDepository
= StringDepository
;
1052 GetStringTokenFromDepository (
1053 IN BMM_CALLBACK_DATA
*CallbackData
,
1054 IN STRING_DEPOSITORY
*StringDepository
1057 Routine Description:
1058 Fetch a usable string node from the string depository and return the string token.
1061 StringDepository - Pointer of the string depository.
1064 STRING_REF - String token.
1067 STRING_LIST_NODE
*CurrentListNode
;
1068 STRING_LIST_NODE
*NextListNode
;
1070 CurrentListNode
= StringDepository
->CurrentNode
;
1072 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1074 // Fetch one reclaimed node from the list.
1076 NextListNode
= StringDepository
->CurrentNode
->Next
;
1079 // If there is no usable node in the list, update the list.
1081 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1083 CallbackData
->Hii
->NewString (
1086 CallbackData
->BmmHiiHandle
,
1087 &(NextListNode
->StringToken
),
1091 ASSERT (NextListNode
->StringToken
!= 0);
1093 StringDepository
->TotalNodeNumber
++;
1095 if (NULL
== CurrentListNode
) {
1096 StringDepository
->ListHead
= NextListNode
;
1098 CurrentListNode
->Next
= NextListNode
;
1102 StringDepository
->CurrentNode
= NextListNode
;
1104 return StringDepository
->CurrentNode
->StringToken
;
1108 ReclaimStringDepository (
1112 Routine Description:
1113 Reclaim string depositories by moving the current node pointer to list head..
1122 UINTN DepositoryIndex
;
1123 STRING_DEPOSITORY
*StringDepository
;
1125 StringDepository
= FileOptionStrDepository
;
1126 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1127 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1133 CleanUpStringDepository (
1137 Routine Description:
1138 Release resource for all the string depositories.
1148 UINTN DepositoryIndex
;
1149 STRING_LIST_NODE
*CurrentListNode
;
1150 STRING_LIST_NODE
*NextListNode
;
1151 STRING_DEPOSITORY
*StringDepository
;
1154 // Release string list nodes.
1156 StringDepository
= FileOptionStrDepository
;
1157 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1158 CurrentListNode
= StringDepository
->ListHead
;
1159 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1160 NextListNode
= CurrentListNode
->Next
;
1161 SafeFreePool (CurrentListNode
);
1162 CurrentListNode
= NextListNode
;
1168 // Release string depository.
1170 SafeFreePool (FileOptionStrDepository
);
1179 Routine Description:
1180 Start boot maintenance manager
1189 LIST_ENTRY BdsBootOptionList
;
1191 InitializeListHead (&BdsBootOptionList
);
1194 // Connect all prior to entering the platform setup menu.
1196 if (!gConnectAllHappened
) {
1197 BdsLibConnectAllDriversToAllControllers ();
1198 gConnectAllHappened
= TRUE
;
1201 // Have chance to enumerate boot device
1203 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1208 Status
= InitializeBM ();
1215 IN BMM_CALLBACK_DATA
*CallbackData
1219 Routine Description:
1220 Dispatch BMM formset and FileExplorer formset.
1228 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1232 BM_MENU_ENTRY
*NewMenuEntry
;
1233 BM_FILE_CONTEXT
*NewFileContext
;
1234 BOOLEAN BootMaintMenuResetRequired
;
1238 NewMenuEntry
= NULL
;
1239 NewFileContext
= NULL
;
1242 // There should only be one Form Configuration protocol
1244 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1245 if (EFI_ERROR (Status
)) {
1250 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1252 BootMaintMenuResetRequired
= FALSE
;
1253 Status
= FormConfig
->SendForm (
1256 &(CallbackData
->BmmHiiHandle
),
1260 (UINT8
*) CallbackData
->BmmFakeNvData
,
1262 &BootMaintMenuResetRequired
1265 if (BootMaintMenuResetRequired
) {
1266 EnableResetRequired ();
1269 ReclaimStringDepository ();
1272 // When this Formset returns, check if we are going to explore files.
1274 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1275 UpdateFileExplorer (CallbackData
, 0);
1277 BootMaintMenuResetRequired
= FALSE
;
1278 Status
= FormConfig
->SendForm (
1281 &(CallbackData
->FeHiiHandle
),
1287 &BootMaintMenuResetRequired
1290 if (BootMaintMenuResetRequired
) {
1291 EnableResetRequired ();
1294 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1295 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1296 ReclaimStringDepository ();
1306 CreateCallbackPacket (
1307 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1311 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1312 ASSERT (*Packet
!= NULL
);
1314 (*Packet
)->DataArray
.EntryCount
= 1;
1315 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1316 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;