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 ASSERT (NewMenuEntry
!= NULL
);
453 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
455 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
457 Private
->MenuEntry
= NewMenuEntry
;
458 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
460 UpdateDriverAddHandleDescPage (Private
);
469 IN BMM_CALLBACK_DATA
*Private
,
470 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
477 Function handling request to apply changes for BMM pages.
481 Private - Pointer to callback data buffer.
482 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
483 FormId - ID of the form which has sent the request to apply change.
487 EFI_SUCCESS - Change successfully applied.
488 Other - Error occurs while trying to apply changes.
492 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
493 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
494 BM_LOAD_CONTEXT
*NewLoadContext
;
495 BM_MENU_ENTRY
*NewMenuEntry
;
499 Status
= EFI_SUCCESS
;
502 case FORM_SET_FD_ORDER_ID
:
503 case FORM_SET_HD_ORDER_ID
:
504 case FORM_SET_CD_ORDER_ID
:
505 case FORM_SET_NET_ORDER_ID
:
506 case FORM_SET_BEV_ORDER_ID
:
507 Var_UpdateBBSOption (Private
);
510 case FORM_BOOT_DEL_ID
:
511 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
512 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
513 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
514 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
517 Var_DelBootOption ();
520 case FORM_DRV_DEL_ID
:
521 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
522 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
523 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
524 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
527 Var_DelDriverOption ();
530 case FORM_BOOT_CHG_ID
:
531 Status
= Var_UpdateBootOrder (Private
);
534 case FORM_DRV_CHG_ID
:
535 Status
= Var_UpdateDriverOrder (Private
);
538 case FORM_TIME_OUT_ID
:
539 Status
= gRT
->SetVariable (
541 &gEfiGlobalVariableGuid
,
544 &(CurrentFakeNVMap
->BootTimeOut
)
546 if (EFI_ERROR (Status
)) {
550 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
553 case FORM_BOOT_NEXT_ID
:
554 Status
= Var_UpdateBootNext (Private
);
557 case FORM_CON_COM_ID
:
558 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
560 ASSERT (NewMenuEntry
!= NULL
);
562 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
564 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
565 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
566 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
567 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
568 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
569 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
570 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
571 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
572 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
574 ChangeTerminalDevicePath (
575 NewTerminalContext
->DevicePath
,
579 Var_UpdateConsoleInpOption ();
580 Var_UpdateConsoleOutOption ();
581 Var_UpdateErrorOutOption ();
585 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
586 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
587 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
588 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
591 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
592 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
593 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
594 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
597 Var_UpdateConsoleInpOption ();
600 case FORM_CON_OUT_ID
:
601 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
602 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
603 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
604 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
607 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
608 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
609 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
610 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
613 Var_UpdateConsoleOutOption ();
616 case FORM_CON_ERR_ID
:
617 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
618 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
619 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
620 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
623 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
624 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
625 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
626 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
629 Var_UpdateErrorOutOption ();
632 case FORM_DRV_ADD_HANDLE_DESC_ID
:
633 Status
= Var_UpdateDriverOption (
635 Private
->BmmHiiHandle
,
636 CurrentFakeNVMap
->DriverAddHandleDesc
,
637 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
638 CurrentFakeNVMap
->DriverAddForceReconnect
640 if (EFI_ERROR (Status
)) {
644 BOpt_GetDriverOptions (Private
);
645 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
657 DiscardChangeHandler (
658 IN BMM_CALLBACK_DATA
*Private
,
659 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
664 switch (Private
->BmmPreviousPageId
) {
665 case FORM_BOOT_CHG_ID
:
666 case FORM_DRV_CHG_ID
:
667 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
670 case FORM_BOOT_DEL_ID
:
671 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
672 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
676 case FORM_DRV_DEL_ID
:
677 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
678 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
682 case FORM_BOOT_NEXT_ID
:
683 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
686 case FORM_TIME_OUT_ID
:
687 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
690 case FORM_DRV_ADD_HANDLE_DESC_ID
:
691 case FORM_DRV_ADD_FILE_ID
:
692 case FORM_DRV_ADD_HANDLE_ID
:
693 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
694 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
705 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
706 IN CHAR16
*VariableName
,
707 IN EFI_GUID
*VendorGuid
,
708 OUT UINT32 Attributes OPTIONAL
,
709 IN OUT UINTN DataSize
,
711 OUT BOOLEAN
*ResetRequired
715 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
727 Initialize the Boot Maintenance Utitliy
731 ImageHandle - caller provided handle
733 SystemTable - caller provided system tables
737 EFI_SUCCESS - utility ended successfully
739 others - contain some errors
743 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
744 EFI_HII_PACKAGES
*PackageList
;
745 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
746 EFI_HII_PROTOCOL
*Hii
;
747 EFI_HII_HANDLE HiiHandle
;
753 Status
= EFI_SUCCESS
;
756 // Initialize EfiUtilityLib and EfiDriverLib
757 // Since many functions in UtilityLib must be used and
758 // SetupBrowser use DriverLib
761 // There should be only one EFI_HII_PROTOCOL Image
763 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
764 if (EFI_ERROR (Status
)) {
768 // Create CallbackData structures for Driver Callback
770 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
771 if (!BmmCallbackInfo
) {
772 return EFI_OUT_OF_RESOURCES
;
775 // Create LoadOption in BmmCallbackInfo for Driver Callback
777 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
779 SafeFreePool (BmmCallbackInfo
);
780 return EFI_OUT_OF_RESOURCES
;
783 // Initialize Bmm callback data.
785 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
786 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
788 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
789 Ptr
+= sizeof (BM_FILE_CONTEXT
);
791 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
792 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
794 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
796 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
798 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
800 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
801 BmmCallbackInfo
->Hii
= Hii
;
802 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
803 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
804 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
805 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
806 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
807 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
808 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
809 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
810 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
811 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
814 // Install bmm callback protocol interface
817 Status
= gBS
->InstallProtocolInterface (
819 &gEfiFormCallbackProtocolGuid
,
820 EFI_NATIVE_INTERFACE
,
821 &BmmCallbackInfo
->BmmDriverCallback
824 if (EFI_ERROR (Status
)) {
828 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
831 // Install file explorer callback protocol interface
834 Status
= gBS
->InstallProtocolInterface (
836 &gEfiFormCallbackProtocolGuid
,
837 EFI_NATIVE_INTERFACE
,
838 &BmmCallbackInfo
->FeDriverCallback
841 if (EFI_ERROR (Status
)) {
845 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
848 // Post our VFR to the HII database.
850 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, bmBin
);
851 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
852 gBS
->FreePool (PackageList
);
854 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
856 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FEBin
);
857 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
858 gBS
->FreePool (PackageList
);
860 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
863 // Allocate space for creation of Buffer
865 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
867 SafeFreePool (BmmCallbackInfo
->LoadContext
);
868 SafeFreePool (BmmCallbackInfo
);
869 return EFI_OUT_OF_RESOURCES
;
872 // Initialize UpdateData structure
874 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
876 Location
= (UINT8
*) &UpdateData
->Data
;
878 InitializeStringDepository ();
880 InitAllMenu (BmmCallbackInfo
);
882 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
883 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
884 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
885 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
886 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
887 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
888 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
890 UpdateBootDelPage (BmmCallbackInfo
);
891 UpdateDrvDelPage (BmmCallbackInfo
);
893 if (TerminalMenu
.MenuNumber
> 0) {
894 BmmCallbackInfo
->CurrentTerminal
= 0;
895 UpdateTerminalPage (BmmCallbackInfo
);
898 Location
= (UINT8
*) &UpdateData
->Data
;
899 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
900 if (!EFI_ERROR (Status
)) {
902 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
903 // in BootOption form: legacy FD/HD/CD/NET/BEV
905 UpdateData
->DataCount
= 5;
907 FORM_SET_FD_ORDER_ID
,
908 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
909 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
910 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
911 FORM_SET_FD_ORDER_ID
,
915 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
918 FORM_SET_HD_ORDER_ID
,
919 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
920 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
921 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
922 FORM_SET_HD_ORDER_ID
,
926 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
929 FORM_SET_CD_ORDER_ID
,
930 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
931 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
932 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
933 FORM_SET_CD_ORDER_ID
,
937 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
940 FORM_SET_NET_ORDER_ID
,
941 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
942 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
943 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
944 FORM_SET_NET_ORDER_ID
,
948 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
951 FORM_SET_BEV_ORDER_ID
,
952 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
953 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
954 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
955 FORM_SET_BEV_ORDER_ID
,
961 BmmCallbackInfo
->BmmHiiHandle
,
962 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
968 // Dispatch BMM main formset and File Explorer formset.
970 FormSetDispatcher (BmmCallbackInfo
);
972 Hii
->ResetStrings (Hii
, HiiHandle
);
974 CleanUpStringDepository ();
976 if (EFI_ERROR (Status
)) {
982 SafeFreePool (BmmCallbackInfo
->LoadContext
);
983 BmmCallbackInfo
->LoadContext
= NULL
;
984 SafeFreePool (BmmCallbackInfo
);
985 BmmCallbackInfo
= NULL
;
986 SafeFreePool (UpdateData
);
994 IN BMM_CALLBACK_DATA
*CallbackData
997 InitializeListHead (&BootOptionMenu
.Head
);
998 InitializeListHead (&DriverOptionMenu
.Head
);
999 BOpt_GetBootOptions (CallbackData
);
1000 BOpt_GetDriverOptions (CallbackData
);
1001 BOpt_GetLegacyOptions ();
1002 InitializeListHead (&FsOptionMenu
.Head
);
1003 BOpt_FindDrivers ();
1004 InitializeListHead (&DirectoryMenu
.Head
);
1005 InitializeListHead (&ConsoleInpMenu
.Head
);
1006 InitializeListHead (&ConsoleOutMenu
.Head
);
1007 InitializeListHead (&ConsoleErrMenu
.Head
);
1008 InitializeListHead (&TerminalMenu
.Head
);
1018 BOpt_FreeMenu (&DirectoryMenu
);
1019 BOpt_FreeMenu (&FsOptionMenu
);
1020 BOpt_FreeMenu (&BootOptionMenu
);
1021 BOpt_FreeMenu (&DriverOptionMenu
);
1022 BOpt_FreeMenu (&DriverMenu
);
1023 BOpt_FreeLegacyOptions ();
1028 InitializeStringDepository (
1032 Routine Description:
1033 Intialize all the string depositories.
1042 STRING_DEPOSITORY
*StringDepository
;
1043 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1044 FileOptionStrDepository
= StringDepository
++;
1045 ConsoleOptionStrDepository
= StringDepository
++;
1046 BootOptionStrDepository
= StringDepository
++;
1047 BootOptionHelpStrDepository
= StringDepository
++;
1048 DriverOptionStrDepository
= StringDepository
++;
1049 DriverOptionHelpStrDepository
= StringDepository
++;
1050 TerminalStrDepository
= StringDepository
;
1054 GetStringTokenFromDepository (
1055 IN BMM_CALLBACK_DATA
*CallbackData
,
1056 IN STRING_DEPOSITORY
*StringDepository
1059 Routine Description:
1060 Fetch a usable string node from the string depository and return the string token.
1063 StringDepository - Pointer of the string depository.
1066 STRING_REF - String token.
1069 STRING_LIST_NODE
*CurrentListNode
;
1070 STRING_LIST_NODE
*NextListNode
;
1072 CurrentListNode
= StringDepository
->CurrentNode
;
1074 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1076 // Fetch one reclaimed node from the list.
1078 NextListNode
= StringDepository
->CurrentNode
->Next
;
1081 // If there is no usable node in the list, update the list.
1083 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1085 CallbackData
->Hii
->NewString (
1088 CallbackData
->BmmHiiHandle
,
1089 &(NextListNode
->StringToken
),
1093 ASSERT (NextListNode
->StringToken
!= 0);
1095 StringDepository
->TotalNodeNumber
++;
1097 if (NULL
== CurrentListNode
) {
1098 StringDepository
->ListHead
= NextListNode
;
1100 CurrentListNode
->Next
= NextListNode
;
1104 StringDepository
->CurrentNode
= NextListNode
;
1106 return StringDepository
->CurrentNode
->StringToken
;
1110 ReclaimStringDepository (
1114 Routine Description:
1115 Reclaim string depositories by moving the current node pointer to list head..
1124 UINTN DepositoryIndex
;
1125 STRING_DEPOSITORY
*StringDepository
;
1127 StringDepository
= FileOptionStrDepository
;
1128 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1129 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1135 CleanUpStringDepository (
1139 Routine Description:
1140 Release resource for all the string depositories.
1150 UINTN DepositoryIndex
;
1151 STRING_LIST_NODE
*CurrentListNode
;
1152 STRING_LIST_NODE
*NextListNode
;
1153 STRING_DEPOSITORY
*StringDepository
;
1156 // Release string list nodes.
1158 StringDepository
= FileOptionStrDepository
;
1159 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1160 CurrentListNode
= StringDepository
->ListHead
;
1161 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1162 NextListNode
= CurrentListNode
->Next
;
1163 SafeFreePool (CurrentListNode
);
1164 CurrentListNode
= NextListNode
;
1170 // Release string depository.
1172 SafeFreePool (FileOptionStrDepository
);
1181 Routine Description:
1182 Start boot maintenance manager
1191 LIST_ENTRY BdsBootOptionList
;
1193 InitializeListHead (&BdsBootOptionList
);
1196 // Connect all prior to entering the platform setup menu.
1198 if (!gConnectAllHappened
) {
1199 BdsLibConnectAllDriversToAllControllers ();
1200 gConnectAllHappened
= TRUE
;
1203 // Have chance to enumerate boot device
1205 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1210 Status
= InitializeBM ();
1217 IN BMM_CALLBACK_DATA
*CallbackData
1221 Routine Description:
1222 Dispatch BMM formset and FileExplorer formset.
1230 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1234 BM_MENU_ENTRY
*NewMenuEntry
;
1235 BM_FILE_CONTEXT
*NewFileContext
;
1236 BOOLEAN BootMaintMenuResetRequired
;
1240 NewMenuEntry
= NULL
;
1241 NewFileContext
= NULL
;
1244 // There should only be one Form Configuration protocol
1246 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1247 if (EFI_ERROR (Status
)) {
1252 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1254 BootMaintMenuResetRequired
= FALSE
;
1255 Status
= FormConfig
->SendForm (
1258 &(CallbackData
->BmmHiiHandle
),
1262 (UINT8
*) CallbackData
->BmmFakeNvData
,
1264 &BootMaintMenuResetRequired
1267 if (BootMaintMenuResetRequired
) {
1268 EnableResetRequired ();
1271 ReclaimStringDepository ();
1274 // When this Formset returns, check if we are going to explore files.
1276 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1277 UpdateFileExplorer (CallbackData
, 0);
1279 BootMaintMenuResetRequired
= FALSE
;
1280 Status
= FormConfig
->SendForm (
1283 &(CallbackData
->FeHiiHandle
),
1289 &BootMaintMenuResetRequired
1292 if (BootMaintMenuResetRequired
) {
1293 EnableResetRequired ();
1296 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1297 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1298 ReclaimStringDepository ();
1308 CreateCallbackPacket (
1309 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1313 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1314 ASSERT (*Packet
!= NULL
);
1316 (*Packet
)->DataArray
.EntryCount
= 1;
1317 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1318 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;