3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Boot Maintainence Main File
23 // Include common header file for this module.
25 #include "CommonHeader.h"
27 #include "Generic/Bds.h"
28 #include "BootMaint.h"
32 // Form binary for Boot Maintenance
36 extern BOOLEAN gConnectAllHappened
;
38 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
42 IN BMM_CALLBACK_DATA
*CallbackData
51 CreateMenuStringToken (
52 IN BMM_CALLBACK_DATA
*CallbackData
,
53 IN EFI_HII_HANDLE HiiHandle
,
54 IN BM_MENU_OPTION
*MenuOption
59 Create string tokens for a menu from its help strings and display strings
63 HiiHandle - Hii Handle of the package to be updated.
65 MenuOption - The Menu whose string tokens need to be created
69 EFI_SUCCESS - string tokens created successfully
71 others - contain some errors
75 BM_MENU_ENTRY
*NewMenuEntry
;
78 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
79 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
80 CallbackData
->Hii
->NewString (
84 &NewMenuEntry
->DisplayStringToken
,
85 NewMenuEntry
->DisplayString
88 if (NULL
== NewMenuEntry
->HelpString
) {
89 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
91 CallbackData
->Hii
->NewString (
95 &NewMenuEntry
->HelpStringToken
,
96 NewMenuEntry
->HelpString
107 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
109 IN EFI_IFR_DATA_ARRAY
*Data
,
110 OUT EFI_HII_CALLBACK_PACKET
**Packet
115 Callback Function for boot maintenance utility user interface interaction.
119 This - File explorer callback protocol pointer.
120 KeyValue - Key value to identify the type of data to expect.
121 Data - A pointer to the data being sent to the original exporting driver.
122 Packet - A pointer to a packet of information which a driver passes back to the browser.
126 EFI_SUCCESS - Callback ended successfully.
127 Others - Contain some errors.
131 BMM_CALLBACK_DATA
*Private
;
132 BM_MENU_ENTRY
*NewMenuEntry
;
133 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
157 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
158 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Private
->BmmCallbackHandle
;
159 CurrentFakeNVMap
= (BMM_FAKE_NV_DATA
*) Data
->NvRamMap
;
160 Private
->BmmFakeNvData
= CurrentFakeNVMap
;
161 Location
= (UINT8
*) &UpdateData
->Data
;
163 UpdatePageId (Private
, KeyValue
);
166 // need to be subtituded.
168 // Update Select FD/HD/CD/NET/BEV Order Form
170 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
171 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
172 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
173 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
174 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
175 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
176 (KeyValue
>= LEGACY_FD_QUESTION_ID
) &&
177 (KeyValue
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
180 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
182 FormId
= Private
->BmmPreviousPageId
;
183 if (FormId
== FORM_BOOT_SETUP_ID
) {
184 FormId
= Private
->BmmCurrentPageId
;
188 case FORM_SET_FD_ORDER_ID
:
189 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
190 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
191 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
194 case FORM_SET_HD_ORDER_ID
:
195 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
196 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
197 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
200 case FORM_SET_CD_ORDER_ID
:
201 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
202 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
203 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
206 case FORM_SET_NET_ORDER_ID
:
207 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
208 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
209 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
212 case FORM_SET_BEV_ORDER_ID
:
213 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
214 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
215 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
222 // First, find the different position
223 // if there is change, it should be only one
225 for (Index
= 0; Index
< Number
; Index
++) {
226 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
227 OldValue
= OldLegacyDev
[Index
];
228 NewValue
= NewLegacyDev
[Index
];
233 if (Index
!= Number
) {
235 // there is change, now process
237 if (0xFF == NewValue
) {
239 // This item will be disable
240 // Just move the items behind this forward to overlap it
243 Bit
= 7 - (OldValue
% 8);
244 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
245 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
246 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
249 NewLegacyDev
[Index2
] = 0xFF;
251 for (Index2
= 0; Index2
< Number
; Index2
++) {
252 if (Index2
== Index
) {
256 if (OldLegacyDev
[Index2
] == NewValue
) {
258 // If NewValue is in OldLegacyDev array
259 // remember its old position
261 NewValuePos
= Index2
;
266 if (Index2
!= Number
) {
268 // We will change current item to an existing item
269 // (It's hard to describe here, please read code, it's like a cycle-moving)
271 for (Index2
= NewValuePos
; Index2
!= Index
;) {
272 if (NewValuePos
< Index
) {
273 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
276 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
282 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
283 // so we should modify DisMap to reflect the change
286 Bit
= 7 - (NewValue
% 8);
287 DisMap
[Pos
] &= ~ (UINT8
) (1 << Bit
);
288 if (0xFF != OldValue
) {
290 // Because NewValue is a item that was disabled before
291 // so after changing the OldValue should be disabled
292 // actually we are doing a swap of enable-disable states of two items
295 Bit
= 7 - (OldValue
% 8);
296 DisMap
[Pos
] |= (UINT8
) (1 << Bit
);
301 // To prevent DISABLE appears in the middle of the list
302 // we should perform a re-ordering
305 while (Index
< Number
) {
306 if (0xFF != NewLegacyDev
[Index
]) {
313 while (Index2
< Number
) {
314 if (0xFF != NewLegacyDev
[Index2
]) {
321 if (Index2
< Number
) {
322 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
323 NewLegacyDev
[Index2
] = 0xFF;
337 if (KeyValue
< FILE_OPTION_OFFSET
) {
338 if (KeyValue
< NORMAL_GOTO_OFFSET
) {
340 case KEY_VALUE_BOOT_FROM_FILE
:
341 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
344 // Exit Bmm main formset to send File Explorer formset.
346 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
350 case FORM_BOOT_ADD_ID
:
351 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
354 // Exit Bmm main formset to send File Explorer formset.
356 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
359 case FORM_DRV_ADD_FILE_ID
:
360 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
363 // Exit Bmm main formset to send File Explorer formset.
365 CreateCallbackPacket (Packet
, EXIT_REQUIRED
);
369 case FORM_DRV_ADD_HANDLE_ID
:
370 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
371 UpdateDrvAddHandlePage (Private
);
374 case FORM_BOOT_DEL_ID
:
375 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
376 UpdateBootDelPage (Private
);
379 case FORM_BOOT_CHG_ID
:
380 case FORM_DRV_CHG_ID
:
381 UpdatePageBody (KeyValue
, Private
);
384 case FORM_DRV_DEL_ID
:
385 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
386 UpdateDrvDelPage (Private
);
389 case FORM_BOOT_NEXT_ID
:
390 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
391 UpdateBootNextPage (Private
);
394 case FORM_TIME_OUT_ID
:
395 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
396 UpdateTimeOutPage (Private
);
400 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
401 return EFI_UNSUPPORTED
;
404 case FORM_CON_OUT_ID
:
405 case FORM_CON_ERR_ID
:
406 UpdatePageBody (KeyValue
, Private
);
409 case FORM_CON_COM_ID
:
410 CleanUpPage (FORM_CON_COM_ID
, Private
);
411 UpdateConCOMPage (Private
);
414 case FORM_SET_FD_ORDER_ID
:
415 case FORM_SET_HD_ORDER_ID
:
416 case FORM_SET_CD_ORDER_ID
:
417 case FORM_SET_NET_ORDER_ID
:
418 case FORM_SET_BEV_ORDER_ID
:
419 CleanUpPage (KeyValue
, Private
);
420 UpdateSetLegacyDeviceOrderPage (KeyValue
, Private
);
423 case KEY_VALUE_SAVE_AND_EXIT
:
424 case KEY_VALUE_NO_SAVE_AND_EXIT
:
426 if (KeyValue
== KEY_VALUE_SAVE_AND_EXIT
) {
427 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
428 if (EFI_ERROR (Status
)) {
431 } else if (KeyValue
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
432 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
435 // Tell browser not to ask for confirmation of changes,
436 // since we have already applied or discarded.
438 CreateCallbackPacket (Packet
, NV_NOT_CHANGED
);
444 } else if ((KeyValue
>= TERMINAL_OPTION_OFFSET
) && (KeyValue
< CONSOLE_OPTION_OFFSET
)) {
445 Index2
= (UINT16
) (KeyValue
- TERMINAL_OPTION_OFFSET
);
446 Private
->CurrentTerminal
= Index2
;
448 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
449 UpdateTerminalPage (Private
);
451 } else if (KeyValue
>= HANDLE_OPTION_OFFSET
) {
452 Index2
= (UINT16
) (KeyValue
- HANDLE_OPTION_OFFSET
);
454 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
455 ASSERT (NewMenuEntry
!= NULL
);
456 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
458 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
460 Private
->MenuEntry
= NewMenuEntry
;
461 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
463 UpdateDriverAddHandleDescPage (Private
);
472 IN BMM_CALLBACK_DATA
*Private
,
473 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
480 Function handling request to apply changes for BMM pages.
484 Private - Pointer to callback data buffer.
485 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
486 FormId - ID of the form which has sent the request to apply change.
490 EFI_SUCCESS - Change successfully applied.
491 Other - Error occurs while trying to apply changes.
495 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
496 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
497 BM_LOAD_CONTEXT
*NewLoadContext
;
498 BM_MENU_ENTRY
*NewMenuEntry
;
502 Status
= EFI_SUCCESS
;
505 case FORM_SET_FD_ORDER_ID
:
506 case FORM_SET_HD_ORDER_ID
:
507 case FORM_SET_CD_ORDER_ID
:
508 case FORM_SET_NET_ORDER_ID
:
509 case FORM_SET_BEV_ORDER_ID
:
510 Var_UpdateBBSOption (Private
);
513 case FORM_BOOT_DEL_ID
:
514 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
515 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
516 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
517 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
520 Var_DelBootOption ();
523 case FORM_DRV_DEL_ID
:
524 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
525 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
526 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
527 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
530 Var_DelDriverOption ();
533 case FORM_BOOT_CHG_ID
:
534 Status
= Var_UpdateBootOrder (Private
);
537 case FORM_DRV_CHG_ID
:
538 Status
= Var_UpdateDriverOrder (Private
);
541 case FORM_TIME_OUT_ID
:
542 Status
= gRT
->SetVariable (
544 &gEfiGlobalVariableGuid
,
547 &(CurrentFakeNVMap
->BootTimeOut
)
549 if (EFI_ERROR (Status
)) {
553 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
556 case FORM_BOOT_NEXT_ID
:
557 Status
= Var_UpdateBootNext (Private
);
560 case FORM_CON_COM_ID
:
561 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
563 ASSERT (NewMenuEntry
!= NULL
);
565 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
567 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
568 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
569 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
570 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
571 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
572 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
573 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
574 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
575 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
577 ChangeTerminalDevicePath (
578 NewTerminalContext
->DevicePath
,
582 Var_UpdateConsoleInpOption ();
583 Var_UpdateConsoleOutOption ();
584 Var_UpdateErrorOutOption ();
588 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
589 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
590 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
591 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
594 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
595 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
596 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
597 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
600 Var_UpdateConsoleInpOption ();
603 case FORM_CON_OUT_ID
:
604 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
605 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
606 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
607 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
610 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
611 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
612 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
613 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
616 Var_UpdateConsoleOutOption ();
619 case FORM_CON_ERR_ID
:
620 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
621 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
622 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
623 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
626 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
627 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
628 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
629 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
632 Var_UpdateErrorOutOption ();
635 case FORM_DRV_ADD_HANDLE_DESC_ID
:
636 Status
= Var_UpdateDriverOption (
638 Private
->BmmHiiHandle
,
639 CurrentFakeNVMap
->DriverAddHandleDesc
,
640 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
641 CurrentFakeNVMap
->DriverAddForceReconnect
643 if (EFI_ERROR (Status
)) {
647 BOpt_GetDriverOptions (Private
);
648 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
660 DiscardChangeHandler (
661 IN BMM_CALLBACK_DATA
*Private
,
662 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
667 switch (Private
->BmmPreviousPageId
) {
668 case FORM_BOOT_CHG_ID
:
669 case FORM_DRV_CHG_ID
:
670 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
673 case FORM_BOOT_DEL_ID
:
674 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
675 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
679 case FORM_DRV_DEL_ID
:
680 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
681 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
685 case FORM_BOOT_NEXT_ID
:
686 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
689 case FORM_TIME_OUT_ID
:
690 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
693 case FORM_DRV_ADD_HANDLE_DESC_ID
:
694 case FORM_DRV_ADD_FILE_ID
:
695 case FORM_DRV_ADD_HANDLE_ID
:
696 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
697 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
708 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
709 IN CHAR16
*VariableName
,
710 IN EFI_GUID
*VendorGuid
,
711 OUT UINT32 Attributes OPTIONAL
,
712 IN OUT UINTN DataSize
,
714 OUT BOOLEAN
*ResetRequired
718 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
730 Initialize the Boot Maintenance Utitliy
734 ImageHandle - caller provided handle
736 SystemTable - caller provided system tables
740 EFI_SUCCESS - utility ended successfully
742 others - contain some errors
746 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
747 EFI_HII_PACKAGES
*PackageList
;
748 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
749 EFI_HII_PROTOCOL
*Hii
;
750 EFI_HII_HANDLE HiiHandle
;
756 Status
= EFI_SUCCESS
;
759 // Initialize EfiUtilityLib and EfiDriverLib
760 // Since many functions in UtilityLib must be used and
761 // SetupBrowser use DriverLib
764 // There should be only one EFI_HII_PROTOCOL Image
766 Status
= EfiLibLocateProtocol (&gEfiHiiProtocolGuid
, &Hii
);
767 if (EFI_ERROR (Status
)) {
771 // Create CallbackData structures for Driver Callback
773 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
774 if (!BmmCallbackInfo
) {
775 return EFI_OUT_OF_RESOURCES
;
778 // Create LoadOption in BmmCallbackInfo for Driver Callback
780 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
782 SafeFreePool (BmmCallbackInfo
);
783 return EFI_OUT_OF_RESOURCES
;
786 // Initialize Bmm callback data.
788 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
789 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
791 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
792 Ptr
+= sizeof (BM_FILE_CONTEXT
);
794 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
795 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
797 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
799 BmmCallbackInfo
->BmmFakeNvData
= &BmmCallbackInfo
->BmmOldFakeNVData
;
801 ZeroMem (BmmCallbackInfo
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
803 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
804 BmmCallbackInfo
->Hii
= Hii
;
805 BmmCallbackInfo
->BmmDriverCallback
.NvRead
= NULL
;
806 BmmCallbackInfo
->BmmDriverCallback
.NvWrite
= NvWrite
;
807 BmmCallbackInfo
->BmmDriverCallback
.Callback
= DriverCallback
;
808 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
809 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
810 BmmCallbackInfo
->FeDriverCallback
.NvRead
= NULL
;
811 BmmCallbackInfo
->FeDriverCallback
.NvWrite
= NvWrite
;
812 BmmCallbackInfo
->FeDriverCallback
.Callback
= FileExplorerCallback
;
813 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
814 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
817 // Install bmm callback protocol interface
820 Status
= gBS
->InstallProtocolInterface (
822 &gEfiFormCallbackProtocolGuid
,
823 EFI_NATIVE_INTERFACE
,
824 &BmmCallbackInfo
->BmmDriverCallback
827 if (EFI_ERROR (Status
)) {
831 BmmCallbackInfo
->BmmCallbackHandle
= Handle
;
834 // Install file explorer callback protocol interface
837 Status
= gBS
->InstallProtocolInterface (
839 &gEfiFormCallbackProtocolGuid
,
840 EFI_NATIVE_INTERFACE
,
841 &BmmCallbackInfo
->FeDriverCallback
844 if (EFI_ERROR (Status
)) {
848 BmmCallbackInfo
->FeCallbackHandle
= Handle
;
851 // Post our VFR to the HII database.
853 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, bmBin
);
854 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
855 FreePool (PackageList
);
857 BmmCallbackInfo
->BmmHiiHandle
= HiiHandle
;
859 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, FEBin
);
860 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
861 FreePool (PackageList
);
863 BmmCallbackInfo
->FeHiiHandle
= HiiHandle
;
866 // Allocate space for creation of Buffer
868 UpdateData
= AllocateZeroPool (UPDATE_DATA_SIZE
);
870 SafeFreePool (BmmCallbackInfo
->LoadContext
);
871 SafeFreePool (BmmCallbackInfo
);
872 return EFI_OUT_OF_RESOURCES
;
875 // Initialize UpdateData structure
877 RefreshUpdateData (TRUE
, (EFI_PHYSICAL_ADDRESS
) (UINTN
) BmmCallbackInfo
->BmmCallbackHandle
, FALSE
, 0, 0);
879 Location
= (UINT8
*) &UpdateData
->Data
;
881 InitializeStringDepository ();
883 InitAllMenu (BmmCallbackInfo
);
885 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
886 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
887 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
888 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
889 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
890 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
891 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
893 UpdateBootDelPage (BmmCallbackInfo
);
894 UpdateDrvDelPage (BmmCallbackInfo
);
896 if (TerminalMenu
.MenuNumber
> 0) {
897 BmmCallbackInfo
->CurrentTerminal
= 0;
898 UpdateTerminalPage (BmmCallbackInfo
);
901 Location
= (UINT8
*) &UpdateData
->Data
;
902 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, &LegacyBios
);
903 if (!EFI_ERROR (Status
)) {
905 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
906 // in BootOption form: legacy FD/HD/CD/NET/BEV
908 UpdateData
->DataCount
= 5;
910 FORM_SET_FD_ORDER_ID
,
911 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
912 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
913 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
914 FORM_SET_FD_ORDER_ID
,
918 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
921 FORM_SET_HD_ORDER_ID
,
922 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
923 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
924 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
925 FORM_SET_HD_ORDER_ID
,
929 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
932 FORM_SET_CD_ORDER_ID
,
933 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
934 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
935 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
936 FORM_SET_CD_ORDER_ID
,
940 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
943 FORM_SET_NET_ORDER_ID
,
944 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
945 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
946 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
947 FORM_SET_NET_ORDER_ID
,
951 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
954 FORM_SET_BEV_ORDER_ID
,
955 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
956 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
957 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
,
958 FORM_SET_BEV_ORDER_ID
,
964 BmmCallbackInfo
->BmmHiiHandle
,
965 (EFI_FORM_LABEL
) FORM_BOOT_LEGACY_DEVICE_ID
,
971 // Dispatch BMM main formset and File Explorer formset.
973 FormSetDispatcher (BmmCallbackInfo
);
975 Hii
->ResetStrings (Hii
, HiiHandle
);
977 CleanUpStringDepository ();
979 if (EFI_ERROR (Status
)) {
985 SafeFreePool (BmmCallbackInfo
->LoadContext
);
986 BmmCallbackInfo
->LoadContext
= NULL
;
987 SafeFreePool (BmmCallbackInfo
);
988 BmmCallbackInfo
= NULL
;
989 SafeFreePool (UpdateData
);
997 IN BMM_CALLBACK_DATA
*CallbackData
1000 InitializeListHead (&BootOptionMenu
.Head
);
1001 InitializeListHead (&DriverOptionMenu
.Head
);
1002 BOpt_GetBootOptions (CallbackData
);
1003 BOpt_GetDriverOptions (CallbackData
);
1004 BOpt_GetLegacyOptions ();
1005 InitializeListHead (&FsOptionMenu
.Head
);
1006 BOpt_FindDrivers ();
1007 InitializeListHead (&DirectoryMenu
.Head
);
1008 InitializeListHead (&ConsoleInpMenu
.Head
);
1009 InitializeListHead (&ConsoleOutMenu
.Head
);
1010 InitializeListHead (&ConsoleErrMenu
.Head
);
1011 InitializeListHead (&TerminalMenu
.Head
);
1021 BOpt_FreeMenu (&DirectoryMenu
);
1022 BOpt_FreeMenu (&FsOptionMenu
);
1023 BOpt_FreeMenu (&BootOptionMenu
);
1024 BOpt_FreeMenu (&DriverOptionMenu
);
1025 BOpt_FreeMenu (&DriverMenu
);
1026 BOpt_FreeLegacyOptions ();
1031 InitializeStringDepository (
1035 Routine Description:
1036 Intialize all the string depositories.
1045 STRING_DEPOSITORY
*StringDepository
;
1046 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1047 FileOptionStrDepository
= StringDepository
++;
1048 ConsoleOptionStrDepository
= StringDepository
++;
1049 BootOptionStrDepository
= StringDepository
++;
1050 BootOptionHelpStrDepository
= StringDepository
++;
1051 DriverOptionStrDepository
= StringDepository
++;
1052 DriverOptionHelpStrDepository
= StringDepository
++;
1053 TerminalStrDepository
= StringDepository
;
1057 GetStringTokenFromDepository (
1058 IN BMM_CALLBACK_DATA
*CallbackData
,
1059 IN STRING_DEPOSITORY
*StringDepository
1062 Routine Description:
1063 Fetch a usable string node from the string depository and return the string token.
1066 StringDepository - Pointer of the string depository.
1069 STRING_REF - String token.
1072 STRING_LIST_NODE
*CurrentListNode
;
1073 STRING_LIST_NODE
*NextListNode
;
1075 CurrentListNode
= StringDepository
->CurrentNode
;
1077 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1079 // Fetch one reclaimed node from the list.
1081 NextListNode
= StringDepository
->CurrentNode
->Next
;
1084 // If there is no usable node in the list, update the list.
1086 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1088 CallbackData
->Hii
->NewString (
1091 CallbackData
->BmmHiiHandle
,
1092 &(NextListNode
->StringToken
),
1096 ASSERT (NextListNode
->StringToken
!= 0);
1098 StringDepository
->TotalNodeNumber
++;
1100 if (NULL
== CurrentListNode
) {
1101 StringDepository
->ListHead
= NextListNode
;
1103 CurrentListNode
->Next
= NextListNode
;
1107 StringDepository
->CurrentNode
= NextListNode
;
1109 return StringDepository
->CurrentNode
->StringToken
;
1113 ReclaimStringDepository (
1117 Routine Description:
1118 Reclaim string depositories by moving the current node pointer to list head..
1127 UINTN DepositoryIndex
;
1128 STRING_DEPOSITORY
*StringDepository
;
1130 StringDepository
= FileOptionStrDepository
;
1131 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1132 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1138 CleanUpStringDepository (
1142 Routine Description:
1143 Release resource for all the string depositories.
1153 UINTN DepositoryIndex
;
1154 STRING_LIST_NODE
*CurrentListNode
;
1155 STRING_LIST_NODE
*NextListNode
;
1156 STRING_DEPOSITORY
*StringDepository
;
1159 // Release string list nodes.
1161 StringDepository
= FileOptionStrDepository
;
1162 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1163 CurrentListNode
= StringDepository
->ListHead
;
1164 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1165 NextListNode
= CurrentListNode
->Next
;
1166 SafeFreePool (CurrentListNode
);
1167 CurrentListNode
= NextListNode
;
1173 // Release string depository.
1175 SafeFreePool (FileOptionStrDepository
);
1184 Routine Description:
1185 Start boot maintenance manager
1194 LIST_ENTRY BdsBootOptionList
;
1196 InitializeListHead (&BdsBootOptionList
);
1199 // Connect all prior to entering the platform setup menu.
1201 if (!gConnectAllHappened
) {
1202 BdsLibConnectAllDriversToAllControllers ();
1203 gConnectAllHappened
= TRUE
;
1206 // Have chance to enumerate boot device
1208 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1213 Status
= InitializeBM ();
1220 IN BMM_CALLBACK_DATA
*CallbackData
1224 Routine Description:
1225 Dispatch BMM formset and FileExplorer formset.
1233 EFI_FORM_BROWSER_PROTOCOL
*FormConfig
;
1237 BM_MENU_ENTRY
*NewMenuEntry
;
1238 BM_FILE_CONTEXT
*NewFileContext
;
1239 BOOLEAN BootMaintMenuResetRequired
;
1243 NewMenuEntry
= NULL
;
1244 NewFileContext
= NULL
;
1247 // There should only be one Form Configuration protocol
1249 Status
= EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid
, &FormConfig
);
1250 if (EFI_ERROR (Status
)) {
1255 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1257 BootMaintMenuResetRequired
= FALSE
;
1258 Status
= FormConfig
->SendForm (
1261 &(CallbackData
->BmmHiiHandle
),
1265 (UINT8
*) CallbackData
->BmmFakeNvData
,
1267 &BootMaintMenuResetRequired
1270 if (BootMaintMenuResetRequired
) {
1271 EnableResetRequired ();
1274 ReclaimStringDepository ();
1277 // When this Formset returns, check if we are going to explore files.
1279 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1280 UpdateFileExplorer (CallbackData
, 0);
1282 BootMaintMenuResetRequired
= FALSE
;
1283 Status
= FormConfig
->SendForm (
1286 &(CallbackData
->FeHiiHandle
),
1292 &BootMaintMenuResetRequired
1295 if (BootMaintMenuResetRequired
) {
1296 EnableResetRequired ();
1299 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1300 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1301 ReclaimStringDepository ();
1311 CreateCallbackPacket (
1312 OUT EFI_HII_CALLBACK_PACKET
**Packet
,
1316 *Packet
= (EFI_HII_CALLBACK_PACKET
*) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
1317 ASSERT (*Packet
!= NULL
);
1319 (*Packet
)->DataArray
.EntryCount
= 1;
1320 (*Packet
)->DataArray
.NvRamMap
= NULL
;
1321 ((EFI_IFR_DATA_ENTRY
*) (&((*Packet
)->DataArray
) + 1))->Flags
= Flags
;