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
22 #include "Generic/Bds.h"
23 #include "BootMaint.h"
24 #include "BdsStrDefs.h"
28 // Form binary for Boot Maintenance
32 extern EFI_GUID gBdsStringPackGuid
;
33 extern BOOLEAN gConnectAllHappened
;
35 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
39 IN BMM_CALLBACK_DATA
*CallbackData
48 CreateMenuStringToken (
49 IN BMM_CALLBACK_DATA
*CallbackData
,
50 IN EFI_HII_HANDLE HiiHandle
,
51 IN BM_MENU_OPTION
*MenuOption
56 Create string tokens for a menu from its help strings and display strings
60 HiiHandle - Hii Handle of the package to be updated.
62 MenuOption - The Menu whose string tokens need to be created
66 EFI_SUCCESS - string tokens created successfully
68 others - contain some errors
72 BM_MENU_ENTRY
*NewMenuEntry
;
75 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
76 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
77 CallbackData
->Hii
->NewString (
81 &NewMenuEntry
->DisplayStringToken
,
82 NewMenuEntry
->DisplayString
85 if (NULL
== NewMenuEntry
->HelpString
) {
86 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
88 CallbackData
->Hii
->NewString (
92 &NewMenuEntry
->HelpStringToken
,
93 NewMenuEntry
->HelpString
104 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
106 IN EFI_IFR_DATA_ARRAY
*Data
,
107 OUT EFI_HII_CALLBACK_PACKET
**Packet
112 Callback Function for boot maintenance utility user interface interaction.
116 This - File explorer callback protocol pointer.
117 KeyValue - Key value to identify the type of data to expect.
118 Data - A pointer to the data being sent to the original exporting driver.
119 Packet - A pointer to a packet of information which a driver passes back to the browser.
123 EFI_SUCCESS - Callback ended successfully.
124 Others - Contain some errors.
128 BMM_CALLBACK_DATA
*Private
;
129 BM_MENU_ENTRY
*NewMenuEntry
;
130 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
154 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
155 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
156 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
157 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
158 Location
= (UINT8
*) &UpdateData
->Data
;
160 UpdatePageId (Private
, KeyValue
);
163 // need to be subtituded.
165 // Update Select FD/HD/CD/NET/BEV Order Form
167 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
168 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
169 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
170 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
171 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
172 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
173 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
174 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
177 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
179 FormId
= Private
->BmmPreviousPageId
;
180 if (FormId
== FORM_BOOT_SETUP_ID
) {
181 FormId
= Private
->BmmCurrentPageId
;
185 case FORM_SET_FD_ORDER_ID
:
186 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
187 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
188 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
191 case FORM_SET_HD_ORDER_ID
:
192 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
193 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
194 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
197 case FORM_SET_CD_ORDER_ID
:
198 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
199 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
200 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
203 case FORM_SET_NET_ORDER_ID
:
204 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
205 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
206 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
209 case FORM_SET_BEV_ORDER_ID
:
210 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
211 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
212 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
219 // First, find the different position
220 // if there is change, it should be only one
222 for (Index
= 0; Index
< Number
; Index
++) {
223 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
224 OldValue
= OldLegacyDev
[Index
];
225 NewValue
= NewLegacyDev
[Index
];
230 if (Index
!= Number
) {
232 // there is change, now process
234 if (0xFF == NewValue
) {
236 // This item will be disable
237 // Just move the items behind this forward to overlap it
240 Bit
= 7 - (OldValue
% 8);
241 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
242 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
243 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
246 NewLegacyDev
[Index2
] = 0xFF;
248 for (Index2
= 0; Index2
< Number
; Index2
++) {
249 if (Index2
== Index
) {
253 if (OldLegacyDev
[Index2
] == NewValue
) {
255 // If NewValue is in OldLegacyDev array
256 // remember its old position
258 NewValuePos
= Index2
;
263 if (Index2
!= Number
) {
265 // We will change current item to an existing item
266 // (It's hard to describe here, please read code, it's like a cycle-moving)
268 for (Index2
= NewValuePos
; Index2
!= Index
;) {
269 if (NewValuePos
< Index
) {
270 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
273 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
279 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
280 // so we should modify DisMap to reflect the change
283 Bit
= 7 - (NewValue
% 8);
284 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
285 if (0xFF != OldValue
) {
287 // Because NewValue is a item that was disabled before
288 // so after changing the OldValue should be disabled
289 // actually we are doing a swap of enable-disable states of two items
292 Bit
= 7 - (OldValue
% 8);
293 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
298 // To prevent DISABLE appears in the middle of the list
299 // we should perform a re-ordering
302 while (Index
< Number
) {
303 if (0xFF != NewLegacyDev
[Index
]) {
310 while (Index2
< Number
) {
311 if (0xFF != NewLegacyDev
[Index2
]) {
318 if (Index2
< Number
) {
319 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
320 NewLegacyDev
[Index2
] = 0xFF;
334 if (KeyValue
< FILE_OPTION_OFFSET
) {
335 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
337 case KEY_VALUE_BOOT_FROM_FILE
:
338 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
341 // Exit Bmm main formset to send File Explorer formset.
343 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
347 case FORM_BOOT_ADD_ID
:
348 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
351 // Exit Bmm main formset to send File Explorer formset.
353 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
356 case FORM_DRV_ADD_FILE_ID
:
357 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
360 // Exit Bmm main formset to send File Explorer formset.
362 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
366 case FORM_DRV_ADD_HANDLE_ID
:
367 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
368 UpdateDrvAddHandlePage (Private
);
371 case FORM_BOOT_DEL_ID
:
372 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
373 UpdateBootDelPage (Private
);
376 case FORM_BOOT_CHG_ID
:
377 case FORM_DRV_CHG_ID
:
378 UpdatePageBody (KeyValue
, Private
);
381 case FORM_DRV_DEL_ID
:
382 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
383 UpdateDrvDelPage (Private
);
386 case FORM_BOOT_NEXT_ID
:
387 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
388 UpdateBootNextPage (Private
);
391 case FORM_TIME_OUT_ID
:
392 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
393 UpdateTimeOutPage (Private
);
397 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
398 return EFI_UNSUPPORTED
;
401 case FORM_CON_OUT_ID
:
402 case FORM_CON_ERR_ID
:
403 UpdatePageBody (KeyValue
, Private
);
406 case FORM_CON_COM_ID
:
407 CleanUpPage (FORM_CON_COM_ID
, Private
);
408 UpdateConCOMPage (Private
);
411 case FORM_SET_FD_ORDER_ID
:
412 case FORM_SET_HD_ORDER_ID
:
413 case FORM_SET_CD_ORDER_ID
:
414 case FORM_SET_NET_ORDER_ID
:
415 case FORM_SET_BEV_ORDER_ID
:
416 CleanUpPage (KeyValue
, Private
);
417 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
420 case KEY_VALUE_SAVE_AND_EXIT
:
421 case KEY_VALUE_NO_SAVE_AND_EXIT
:
423 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
424 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
425 if (EFI_ERROR (Status
)) {
428 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
429 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
432 // Tell browser not to ask for confirmation of changes,
433 // since we have already applied or discarded.
435 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
441 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
442 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
443 Private
->CurrentTerminal
= Index2
;
445 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
446 UpdateTerminalPage (Private
);
448 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
449 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
451 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
452 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
454 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
456 Private
->MenuEntry
= NewMenuEntry
;
457 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
459 UpdateDriverAddHandleDescPage (Private
);
468 IN BMM_CALLBACK_DATA
*Private
,
469 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
476 Function handling request to apply changes for BMM pages.
480 Private - Pointer to callback data buffer.
481 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
482 FormId - ID of the form which has sent the request to apply change.
486 EFI_SUCCESS - Change successfully applied.
487 Other - Error occurs while trying to apply changes.
491 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
492 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
493 BM_LOAD_CONTEXT
*NewLoadContext
;
494 BM_MENU_ENTRY
*NewMenuEntry
;
498 Status
= EFI_SUCCESS
;
501 case FORM_SET_FD_ORDER_ID
:
502 case FORM_SET_HD_ORDER_ID
:
503 case FORM_SET_CD_ORDER_ID
:
504 case FORM_SET_NET_ORDER_ID
:
505 case FORM_SET_BEV_ORDER_ID
:
506 Var_UpdateBBSOption (Private
);
509 case FORM_BOOT_DEL_ID
:
510 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
511 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
512 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
513 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
516 Var_DelBootOption ();
519 case FORM_DRV_DEL_ID
:
520 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
521 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
522 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
523 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
526 Var_DelDriverOption ();
529 case FORM_BOOT_CHG_ID
:
530 Status
= Var_UpdateBootOrder (Private
);
533 case FORM_DRV_CHG_ID
:
534 Status
= Var_UpdateDriverOrder (Private
);
537 case FORM_TIME_OUT_ID
:
538 Status
= gRT
->SetVariable (
540 &gEfiGlobalVariableGuid
,
543 &(CurrentFakeNVMap
->BootTimeOut
)
545 if (EFI_ERROR (Status
)) {
549 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
552 case FORM_BOOT_NEXT_ID
:
553 Status
= Var_UpdateBootNext (Private
);
556 case FORM_CON_COM_ID
:
557 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
559 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
561 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
562 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
563 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
564 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
565 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
566 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
567 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
568 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
569 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
571 ChangeTerminalDevicePath (
572 NewTerminalContext
->DevicePath
,
576 Var_UpdateConsoleInpOption ();
577 Var_UpdateConsoleOutOption ();
578 Var_UpdateErrorOutOption ();
582 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
583 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
584 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
585 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
588 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
589 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
590 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
591 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
594 Var_UpdateConsoleInpOption ();
597 case FORM_CON_OUT_ID
:
598 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
599 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
600 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
601 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
604 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
605 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
606 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
607 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
610 Var_UpdateConsoleOutOption ();
613 case FORM_CON_ERR_ID
:
614 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
615 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
616 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
617 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
620 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
621 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
622 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
623 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
626 Var_UpdateErrorOutOption ();
629 case FORM_DRV_ADD_HANDLE_DESC_ID
:
630 Status
= Var_UpdateDriverOption (
632 Private
->BmmHiiHandle
,
633 CurrentFakeNVMap
->DriverAddHandleDesc
,
634 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
635 CurrentFakeNVMap
->DriverAddForceReconnect
637 if (EFI_ERROR (Status
)) {
641 BOpt_GetDriverOptions (Private
);
642 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
654 DiscardChangeHandler (
655 IN BMM_CALLBACK_DATA
*Private
,
656 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
661 switch (Private
->BmmPreviousPageId
) {
662 case FORM_BOOT_CHG_ID
:
663 case FORM_DRV_CHG_ID
:
664 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
667 case FORM_BOOT_DEL_ID
:
668 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
669 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
673 case FORM_DRV_DEL_ID
:
674 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
675 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
679 case FORM_BOOT_NEXT_ID
:
680 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
683 case FORM_TIME_OUT_ID
:
684 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
687 case FORM_DRV_ADD_HANDLE_DESC_ID
:
688 case FORM_DRV_ADD_FILE_ID
:
689 case FORM_DRV_ADD_HANDLE_ID
:
690 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
691 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
702 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
703 IN CHAR16
*VariableName
,
704 IN EFI_GUID
*VendorGuid
,
705 OUT UINT32 Attributes OPTIONAL
,
706 IN OUT UINTN DataSize
,
708 OUT BOOLEAN
*ResetRequired
712 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
724 Initialize the Boot Maintenance Utitliy
728 ImageHandle - caller provided handle
730 SystemTable - caller provided system tables
734 EFI_SUCCESS - utility ended successfully
736 others - contain some errors
740 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
741 EFI_HII_PACKAGES
*PackageList
;
742 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
743 EFI_HII_PROTOCOL
*Hii
;
744 EFI_HII_HANDLE HiiHandle
;
750 Status
= EFI_SUCCESS
;
753 // Initialize EfiUtilityLib and EfiDriverLib
754 // Since many functions in UtilityLib must be used and
755 // SetupBrowser use DriverLib
758 // There should be only one EFI_HII_PROTOCOL Image
760 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
761 if (EFI_ERROR (Status
)) {
765 // Create CallbackData structures for Driver Callback
767 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
768 if (!BmmCallbackInfo
) {
769 return EFI_OUT_OF_RESOURCES
;
772 // Create LoadOption in BmmCallbackInfo for Driver Callback
774 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
776 SafeFreePool (BmmCallbackInfo
);
777 return EFI_OUT_OF_RESOURCES
;
780 // Initialize Bmm callback data.
782 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
783 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
785 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
786 Ptr
+= sizeof (BM_FILE_CONTEXT
);
788 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
789 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
791 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
793 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
795 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
797 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
798 BmmCallbackInfo
->Hii
= Hii
;
799 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
800 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
801 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
802 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
803 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
804 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
805 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
806 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
807 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
808 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
811 // Install bmm callback protocol interface
814 Status
= gBS
->InstallProtocolInterface (
816 &gEfiFormCallbackProtocolGuid
,
817 EFI_NATIVE_INTERFACE
,
818 &BmmCallbackInfo
->BmmDriverCallback
821 if (EFI_ERROR (Status
)) {
825 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
828 // Install file explorer callback protocol interface
831 Status
= gBS
->InstallProtocolInterface (
833 &gEfiFormCallbackProtocolGuid
,
834 EFI_NATIVE_INTERFACE
,
835 &BmmCallbackInfo
->FeDriverCallback
838 if (EFI_ERROR (Status
)) {
842 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
845 // Post our VFR to the HII database.
847 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, BmBin
);
848 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
849 gBS
->FreePool (PackageList
);
851 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
853 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FEBin
);
854 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
855 gBS
->FreePool (PackageList
);
857 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
860 // Allocate space for creation of Buffer
862 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
864 SafeFreePool (BmmCallbackInfo
->LoadContext
);
865 SafeFreePool (BmmCallbackInfo
);
866 return EFI_OUT_OF_RESOURCES
;
869 // Initialize UpdateData structure
871 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
873 Location
= (UINT8
*) &UpdateData
->Data
;
875 InitializeStringDepository ();
877 InitAllMenu (BmmCallbackInfo
);
879 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
880 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
881 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
882 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
883 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
884 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
885 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
887 UpdateBootDelPage (BmmCallbackInfo
);
888 UpdateDrvDelPage (BmmCallbackInfo
);
890 if (TerminalMenu
.MenuNumber
> 0) {
891 BmmCallbackInfo
->CurrentTerminal
= 0;
892 UpdateTerminalPage (BmmCallbackInfo
);
895 Location
= (UINT8
*) &UpdateData
->Data
;
896 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
897 if (!EFI_ERROR (Status
)) {
899 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
900 // in BootOption form: legacy FD/HD/CD/NET/BEV
902 UpdateData
->DataCount
= 5;
904 FORM_SET_FD_ORDER_ID
,
905 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
906 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
907 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
908 FORM_SET_FD_ORDER_ID
,
912 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
915 FORM_SET_HD_ORDER_ID
,
916 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
917 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
918 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
919 FORM_SET_HD_ORDER_ID
,
923 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
926 FORM_SET_CD_ORDER_ID
,
927 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
928 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
929 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
930 FORM_SET_CD_ORDER_ID
,
934 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
937 FORM_SET_NET_ORDER_ID
,
938 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
939 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
940 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
941 FORM_SET_NET_ORDER_ID
,
945 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
948 FORM_SET_BEV_ORDER_ID
,
949 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
950 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
951 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
952 FORM_SET_BEV_ORDER_ID
,
958 BmmCallbackInfo
->BmmHiiHandle
,
959 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
965 // Dispatch BMM main formset and File Explorer formset.
967 FormSetDispatcher (BmmCallbackInfo
);
969 Hii
->ResetStrings (Hii
, HiiHandle
);
971 CleanUpStringDepository ();
973 if (EFI_ERROR (Status
)) {
979 SafeFreePool (BmmCallbackInfo
->LoadContext
);
980 BmmCallbackInfo
->LoadContext
= NULL
;
981 SafeFreePool (BmmCallbackInfo
);
982 BmmCallbackInfo
= NULL
;
983 SafeFreePool (UpdateData
);
991 IN BMM_CALLBACK_DATA
*CallbackData
994 InitializeListHead (&BootOptionMenu
.Head
);
995 InitializeListHead (&DriverOptionMenu
.Head
);
996 BOpt_GetBootOptions (CallbackData
);
997 BOpt_GetDriverOptions (CallbackData
);
998 BOpt_GetLegacyOptions ();
999 InitializeListHead (&FsOptionMenu
.Head
);
1000 BOpt_FindDrivers ();
1001 InitializeListHead (&DirectoryMenu
.Head
);
1002 InitializeListHead (&ConsoleInpMenu
.Head
);
1003 InitializeListHead (&ConsoleOutMenu
.Head
);
1004 InitializeListHead (&ConsoleErrMenu
.Head
);
1005 InitializeListHead (&TerminalMenu
.Head
);
1015 BOpt_FreeMenu (&DirectoryMenu
);
1016 BOpt_FreeMenu (&FsOptionMenu
);
1017 BOpt_FreeMenu (&BootOptionMenu
);
1018 BOpt_FreeMenu (&DriverOptionMenu
);
1019 BOpt_FreeMenu (&DriverMenu
);
1020 BOpt_FreeLegacyOptions ();
1025 InitializeStringDepository (
1029 Routine Description:
1030 Intialize all the string depositories.
1039 STRING_DEPOSITORY
*StringDepository
;
1040 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1041 FileOptionStrDepository
= StringDepository
++;
1042 ConsoleOptionStrDepository
= StringDepository
++;
1043 BootOptionStrDepository
= StringDepository
++;
1044 BootOptionHelpStrDepository
= StringDepository
++;
1045 DriverOptionStrDepository
= StringDepository
++;
1046 DriverOptionHelpStrDepository
= StringDepository
++;
1047 TerminalStrDepository
= StringDepository
;
1051 GetStringTokenFromDepository (
1052 IN BMM_CALLBACK_DATA
*CallbackData
,
1053 IN STRING_DEPOSITORY
*StringDepository
1056 Routine Description:
1057 Fetch a usable string node from the string depository and return the string token.
1060 StringDepository - Pointer of the string depository.
1063 STRING_REF - String token.
1066 STRING_LIST_NODE
*CurrentListNode
;
1067 STRING_LIST_NODE
*NextListNode
;
1069 CurrentListNode
= StringDepository
->CurrentNode
;
1071 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1073 // Fetch one reclaimed node from the list.
1075 NextListNode
= StringDepository
->CurrentNode
->Next
;
1078 // If there is no usable node in the list, update the list.
1080 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1082 CallbackData
->Hii
->NewString (
1085 CallbackData
->BmmHiiHandle
,
1086 &(NextListNode
->StringToken
),
1090 ASSERT (NextListNode
->StringToken
!= 0);
1092 StringDepository
->TotalNodeNumber
++;
1094 if (NULL
== CurrentListNode
) {
1095 StringDepository
->ListHead
= NextListNode
;
1097 CurrentListNode
->Next
= NextListNode
;
1101 StringDepository
->CurrentNode
= NextListNode
;
1103 return StringDepository
->CurrentNode
->StringToken
;
1107 ReclaimStringDepository (
1111 Routine Description:
1112 Reclaim string depositories by moving the current node pointer to list head..
1121 UINTN DepositoryIndex
;
1122 STRING_DEPOSITORY
*StringDepository
;
1124 StringDepository
= FileOptionStrDepository
;
1125 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1126 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1132 CleanUpStringDepository (
1136 Routine Description:
1137 Release resource for all the string depositories.
1147 UINTN DepositoryIndex
;
1148 STRING_LIST_NODE
*CurrentListNode
;
1149 STRING_LIST_NODE
*NextListNode
;
1150 STRING_DEPOSITORY
*StringDepository
;
1153 // Release string list nodes.
1155 StringDepository
= FileOptionStrDepository
;
1156 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1157 CurrentListNode
= StringDepository
->ListHead
;
1158 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1159 NextListNode
= CurrentListNode
->Next
;
1160 SafeFreePool (CurrentListNode
);
1161 CurrentListNode
= NextListNode
;
1167 // Release string depository.
1169 SafeFreePool (FileOptionStrDepository
);
1178 Routine Description:
1179 Start boot maintenance manager
1188 LIST_ENTRY BdsBootOptionList
;
1190 InitializeListHead (&BdsBootOptionList
);
1193 // Connect all prior to entering the platform setup menu.
1195 if (!gConnectAllHappened
) {
1196 BdsLibConnectAllDriversToAllControllers ();
1197 gConnectAllHappened
= TRUE
;
1200 // Have chance to enumerate boot device
1202 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1207 Status
= InitializeBM ();
1214 IN BMM_CALLBACK_DATA
*CallbackData
1218 Routine Description:
1219 Dispatch BMM formset and FileExplorer formset.
1227 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1231 BM_MENU_ENTRY
*NewMenuEntry
;
1232 BM_FILE_CONTEXT
*NewFileContext
;
1233 BOOLEAN BootMaintMenuResetRequired
;
1237 NewMenuEntry
= NULL
;
1238 NewFileContext
= NULL
;
1241 // There should only be one Form Configuration protocol
1243 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1244 if (EFI_ERROR (Status
)) {
1249 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1251 BootMaintMenuResetRequired
= FALSE
;
1252 Status
= FormConfig
->SendForm (
1255 &(CallbackData
->BmmHiiHandle
),
1259 (UINT8
*) CallbackData
->BmmFakeNvData
,
1261 &BootMaintMenuResetRequired
1264 if (BootMaintMenuResetRequired
) {
1265 EnableResetRequired ();
1268 ReclaimStringDepository ();
1271 // When this Formset returns, check if we are going to explore files.
1273 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1274 UpdateFileExplorer (CallbackData
, 0);
1276 BootMaintMenuResetRequired
= FALSE
;
1277 Status
= FormConfig
->SendForm (
1280 &(CallbackData
->FeHiiHandle
),
1286 &BootMaintMenuResetRequired
1289 if (BootMaintMenuResetRequired
) {
1290 EnableResetRequired ();
1293 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1294 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1295 ReclaimStringDepository ();
1305 CreateCallbackPacket (
1306 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1310 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1311 ASSERT (*Packet
!= NULL
);
1313 (*Packet
)->DataArray
.EntryCount
= 1;
1314 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1315 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;