3 Copyright (c) 2004 - 2008, 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 "BootMaint.h"
25 #include "FrontPage.h"
27 EFI_GUID EfiLegacyDevOrderGuid
= EFI_LEGACY_DEV_ORDER_VARIABLE_GUID
;
28 EFI_GUID mBootMaintGuid
= BOOT_MAINT_FORMSET_GUID
;
29 EFI_GUID mFileExplorerGuid
= FILE_EXPLORE_FORMSET_GUID
;
31 CHAR16 mBootMaintStorageName
[] = L
"BmData";
32 CHAR16 mFileExplorerStorageName
[] = L
"FeData";
36 IN BMM_CALLBACK_DATA
*CallbackData
45 CreateMenuStringToken (
46 IN BMM_CALLBACK_DATA
*CallbackData
,
47 IN EFI_HII_HANDLE HiiHandle
,
48 IN BM_MENU_OPTION
*MenuOption
53 Create string tokens for a menu from its help strings and display strings
56 HiiHandle - Hii Handle of the package to be updated.
57 MenuOption - The Menu whose string tokens need to be created
60 EFI_SUCCESS - string tokens created successfully
61 others - contain some errors
65 BM_MENU_ENTRY
*NewMenuEntry
;
68 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
69 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
73 &NewMenuEntry
->DisplayStringToken
,
74 NewMenuEntry
->DisplayString
77 if (NULL
== NewMenuEntry
->HelpString
) {
78 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
82 &NewMenuEntry
->HelpStringToken
,
83 NewMenuEntry
->HelpString
93 BootMaintExtractConfig (
94 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
95 IN CONST EFI_STRING Request
,
96 OUT EFI_STRING
*Progress
,
97 OUT EFI_STRING
*Results
102 This function allows a caller to extract the current configuration for one
103 or more named elements from the target driver.
106 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
107 Request - A null-terminated Unicode string in <ConfigRequest> format.
108 Progress - On return, points to a character in the Request string.
109 Points to the string's null terminator if request was successful.
110 Points to the most recent '&' before the first failing name/value
111 pair (or the beginning of the string if the failure is in the
112 first name/value pair) if the request was not successful.
113 Results - A null-terminated Unicode string in <ConfigAltResp> format which
114 has all values filled in for the names in the Request string.
115 String to be allocated by the called function.
118 EFI_SUCCESS - The Results is filled with the requested values.
119 EFI_OUT_OF_RESOURCES - Not enough memory to store the results.
120 EFI_INVALID_PARAMETER - Request is NULL, illegal syntax, or unknown name.
121 EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
127 BMM_CALLBACK_DATA
*Private
;
129 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
132 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
134 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
135 Status
= gHiiConfigRouting
->BlockToConfig (
138 (UINT8
*) &Private
->BmmFakeNvData
,
149 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
150 IN EFI_BROWSER_ACTION Action
,
151 IN EFI_QUESTION_ID QuestionId
,
153 IN EFI_IFR_TYPE_VALUE
*Value
,
154 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
159 This function processes the results of changes in configuration.
162 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
163 Action - Specifies the type of action taken by the browser.
164 QuestionId - A unique value which is sent to the original exporting driver
165 so that it can identify the type of data to expect.
166 Type - The type of value for the question.
167 Value - A pointer to the data being sent to the original exporting driver.
168 ActionRequest - On return, points to the action requested by the callback function.
171 EFI_SUCCESS - The callback successfully handled the action.
172 EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
173 EFI_DEVICE_ERROR - The variable could not be saved.
174 EFI_UNSUPPORTED - The specified Action is not supported by the callback.
178 BMM_CALLBACK_DATA
*Private
;
179 BM_MENU_ENTRY
*NewMenuEntry
;
180 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
196 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
197 return EFI_INVALID_PARAMETER
;
207 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
209 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
210 UpdatePageId (Private
, QuestionId
);
213 // Retrive uncommitted data from Form Browser
215 CurrentFakeNVMap
= &Private
->BmmFakeNvData
;
216 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
217 Status
= GetBrowserData (NULL
, NULL
, &BufferSize
, (UINT8
*) CurrentFakeNVMap
);
218 if (EFI_ERROR (Status
)) {
223 // need to be subtituded.
225 // Update Select FD/HD/CD/NET/BEV Order Form
227 if (FORM_SET_FD_ORDER_ID
== Private
->BmmPreviousPageId
||
228 FORM_SET_HD_ORDER_ID
== Private
->BmmPreviousPageId
||
229 FORM_SET_CD_ORDER_ID
== Private
->BmmPreviousPageId
||
230 FORM_SET_NET_ORDER_ID
== Private
->BmmPreviousPageId
||
231 FORM_SET_BEV_ORDER_ID
== Private
->BmmPreviousPageId
||
232 ((FORM_BOOT_SETUP_ID
== Private
->BmmPreviousPageId
) &&
233 (QuestionId
>= LEGACY_FD_QUESTION_ID
) &&
234 (QuestionId
< (LEGACY_BEV_QUESTION_ID
+ 100)) )
237 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
239 FormId
= Private
->BmmPreviousPageId
;
240 if (FormId
== FORM_BOOT_SETUP_ID
) {
241 FormId
= Private
->BmmCurrentPageId
;
245 case FORM_SET_FD_ORDER_ID
:
246 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
247 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
248 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
251 case FORM_SET_HD_ORDER_ID
:
252 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
253 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
254 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
257 case FORM_SET_CD_ORDER_ID
:
258 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
259 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
260 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
263 case FORM_SET_NET_ORDER_ID
:
264 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
265 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
266 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
269 case FORM_SET_BEV_ORDER_ID
:
270 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
271 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
272 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
279 // First, find the different position
280 // if there is change, it should be only one
282 for (Index
= 0; Index
< Number
; Index
++) {
283 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
284 OldValue
= OldLegacyDev
[Index
];
285 NewValue
= NewLegacyDev
[Index
];
290 if (Index
!= Number
) {
292 // there is change, now process
294 if (0xFF == NewValue
) {
296 // This item will be disable
297 // Just move the items behind this forward to overlap it
300 Bit
= 7 - (OldValue
% 8);
301 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
302 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
303 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
306 NewLegacyDev
[Index2
] = 0xFF;
308 for (Index2
= 0; Index2
< Number
; Index2
++) {
309 if (Index2
== Index
) {
313 if (OldLegacyDev
[Index2
] == NewValue
) {
315 // If NewValue is in OldLegacyDev array
316 // remember its old position
318 NewValuePos
= Index2
;
323 if (Index2
!= Number
) {
325 // We will change current item to an existing item
326 // (It's hard to describe here, please read code, it's like a cycle-moving)
328 for (Index2
= NewValuePos
; Index2
!= Index
;) {
329 if (NewValuePos
< Index
) {
330 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
333 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
339 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
340 // so we should modify DisMap to reflect the change
343 Bit
= 7 - (NewValue
% 8);
344 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] & (~ (UINT8
) (1 << Bit
)));
345 if (0xFF != OldValue
) {
347 // Because NewValue is a item that was disabled before
348 // so after changing the OldValue should be disabled
349 // actually we are doing a swap of enable-disable states of two items
352 Bit
= 7 - (OldValue
% 8);
353 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
358 // To prevent DISABLE appears in the middle of the list
359 // we should perform a re-ordering
362 while (Index
< Number
) {
363 if (0xFF != NewLegacyDev
[Index
]) {
370 while (Index2
< Number
) {
371 if (0xFF != NewLegacyDev
[Index2
]) {
378 if (Index2
< Number
) {
379 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
380 NewLegacyDev
[Index2
] = 0xFF;
394 if (QuestionId
< FILE_OPTION_OFFSET
) {
395 if (QuestionId
< CONFIG_OPTION_OFFSET
) {
396 switch (QuestionId
) {
397 case KEY_VALUE_BOOT_FROM_FILE
:
398 Private
->FeCurrentState
= BOOT_FROM_FILE_STATE
;
401 // Exit Bmm main formset to send File Explorer formset.
403 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
406 case FORM_BOOT_ADD_ID
:
407 Private
->FeCurrentState
= ADD_BOOT_OPTION_STATE
;
410 // Exit Bmm main formset to send File Explorer formset.
412 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
415 case FORM_DRV_ADD_FILE_ID
:
416 Private
->FeCurrentState
= ADD_DRIVER_OPTION_STATE
;
419 // Exit Bmm main formset to send File Explorer formset.
421 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
424 case FORM_DRV_ADD_HANDLE_ID
:
425 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
426 UpdateDrvAddHandlePage (Private
);
429 case FORM_BOOT_DEL_ID
:
430 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
431 UpdateBootDelPage (Private
);
434 case FORM_BOOT_CHG_ID
:
435 case FORM_DRV_CHG_ID
:
436 UpdatePageBody (QuestionId
, Private
);
439 case FORM_DRV_DEL_ID
:
440 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
441 UpdateDrvDelPage (Private
);
444 case FORM_BOOT_NEXT_ID
:
445 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
446 UpdateBootNextPage (Private
);
449 case FORM_TIME_OUT_ID
:
450 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
451 UpdateTimeOutPage (Private
);
455 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
456 return EFI_UNSUPPORTED
;
459 case FORM_CON_OUT_ID
:
460 case FORM_CON_ERR_ID
:
461 UpdatePageBody (QuestionId
, Private
);
464 case FORM_CON_MODE_ID
:
465 CleanUpPage (FORM_CON_MODE_ID
, Private
);
466 UpdateConModePage (Private
);
469 case FORM_CON_COM_ID
:
470 CleanUpPage (FORM_CON_COM_ID
, Private
);
471 UpdateConCOMPage (Private
);
474 case FORM_SET_FD_ORDER_ID
:
475 case FORM_SET_HD_ORDER_ID
:
476 case FORM_SET_CD_ORDER_ID
:
477 case FORM_SET_NET_ORDER_ID
:
478 case FORM_SET_BEV_ORDER_ID
:
479 CleanUpPage (QuestionId
, Private
);
480 UpdateSetLegacyDeviceOrderPage (QuestionId
, Private
);
483 case KEY_VALUE_SAVE_AND_EXIT
:
484 case KEY_VALUE_NO_SAVE_AND_EXIT
:
486 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT
) {
487 Status
= ApplyChangeHandler (Private
, CurrentFakeNVMap
, Private
->BmmPreviousPageId
);
488 if (EFI_ERROR (Status
)) {
491 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
492 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
496 // Tell browser not to ask for confirmation of changes,
497 // since we have already applied or discarded.
499 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
505 } else if ((QuestionId
>= TERMINAL_OPTION_OFFSET
) && (QuestionId
< CONSOLE_OPTION_OFFSET
)) {
506 Index2
= (UINT16
) (QuestionId
- TERMINAL_OPTION_OFFSET
);
507 Private
->CurrentTerminal
= Index2
;
509 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
510 UpdateTerminalPage (Private
);
512 } else if (QuestionId
>= HANDLE_OPTION_OFFSET
) {
513 Index2
= (UINT16
) (QuestionId
- HANDLE_OPTION_OFFSET
);
515 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
516 ASSERT (NewMenuEntry
!= NULL
);
517 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
519 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
521 Private
->MenuEntry
= NewMenuEntry
;
522 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
524 UpdateDriverAddHandleDescPage (Private
);
529 // Pass changed uncommitted data back to Form Browser
531 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
532 Status
= SetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) CurrentFakeNVMap
, NULL
);
539 IN BMM_CALLBACK_DATA
*Private
,
540 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
,
541 IN EFI_FORM_ID FormId
546 Function handling request to apply changes for BMM pages.
549 Private - Pointer to callback data buffer.
550 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
551 FormId - ID of the form which has sent the request to apply change.
554 EFI_SUCCESS - Change successfully applied.
555 Other - Error occurs while trying to apply changes.
559 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
560 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
561 BM_LOAD_CONTEXT
*NewLoadContext
;
562 BM_MENU_ENTRY
*NewMenuEntry
;
566 Status
= EFI_SUCCESS
;
569 case FORM_SET_FD_ORDER_ID
:
570 case FORM_SET_HD_ORDER_ID
:
571 case FORM_SET_CD_ORDER_ID
:
572 case FORM_SET_NET_ORDER_ID
:
573 case FORM_SET_BEV_ORDER_ID
:
574 Var_UpdateBBSOption (Private
);
577 case FORM_BOOT_DEL_ID
:
578 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
579 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
580 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
581 NewLoadContext
->Deleted
= CurrentFakeNVMap
->BootOptionDel
[Index
];
584 Var_DelBootOption ();
587 case FORM_DRV_DEL_ID
:
588 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
589 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
590 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
591 NewLoadContext
->Deleted
= CurrentFakeNVMap
->DriverOptionDel
[Index
];
594 Var_DelDriverOption ();
597 case FORM_BOOT_CHG_ID
:
598 Status
= Var_UpdateBootOrder (Private
);
601 case FORM_DRV_CHG_ID
:
602 Status
= Var_UpdateDriverOrder (Private
);
605 case FORM_TIME_OUT_ID
:
606 Status
= gRT
->SetVariable (
608 &gEfiGlobalVariableGuid
,
611 &(CurrentFakeNVMap
->BootTimeOut
)
613 if (EFI_ERROR (Status
)) {
617 Private
->BmmOldFakeNVData
.BootTimeOut
= CurrentFakeNVMap
->BootTimeOut
;
620 case FORM_BOOT_NEXT_ID
:
621 Status
= Var_UpdateBootNext (Private
);
624 case FORM_CON_MODE_ID
:
625 Status
= Var_UpdateConMode (Private
);
628 case FORM_CON_COM_SETUP_ID
:
629 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Private
->CurrentTerminal
);
631 ASSERT (NewMenuEntry
!= NULL
);
633 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
635 NewTerminalContext
->BaudRateIndex
= CurrentFakeNVMap
->COMBaudRate
;
636 NewTerminalContext
->BaudRate
= BaudRateList
[CurrentFakeNVMap
->COMBaudRate
].Value
;
637 NewTerminalContext
->DataBitsIndex
= CurrentFakeNVMap
->COMDataRate
;
638 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[CurrentFakeNVMap
->COMDataRate
].Value
;
639 NewTerminalContext
->StopBitsIndex
= CurrentFakeNVMap
->COMStopBits
;
640 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[CurrentFakeNVMap
->COMStopBits
].Value
;
641 NewTerminalContext
->ParityIndex
= CurrentFakeNVMap
->COMParity
;
642 NewTerminalContext
->Parity
= (UINT8
) ParityList
[CurrentFakeNVMap
->COMParity
].Value
;
643 NewTerminalContext
->TerminalType
= CurrentFakeNVMap
->COMTerminalType
;
645 ChangeTerminalDevicePath (
646 NewTerminalContext
->DevicePath
,
650 Var_UpdateConsoleInpOption ();
651 Var_UpdateConsoleOutOption ();
652 Var_UpdateErrorOutOption ();
656 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
657 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
658 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
659 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
662 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
663 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
664 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
665 NewTerminalContext
->IsConIn
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
668 Var_UpdateConsoleInpOption ();
671 case FORM_CON_OUT_ID
:
672 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
673 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
674 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
675 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
678 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
679 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
680 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
681 NewTerminalContext
->IsConOut
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
684 Var_UpdateConsoleOutOption ();
687 case FORM_CON_ERR_ID
:
688 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
689 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
690 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
691 NewConsoleContext
->IsActive
= CurrentFakeNVMap
->ConsoleCheck
[Index
];
694 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
695 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
696 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
697 NewTerminalContext
->IsStdErr
= CurrentFakeNVMap
->ConsoleCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
700 Var_UpdateErrorOutOption ();
703 case FORM_DRV_ADD_HANDLE_DESC_ID
:
704 Status
= Var_UpdateDriverOption (
706 Private
->BmmHiiHandle
,
707 CurrentFakeNVMap
->DriverAddHandleDesc
,
708 CurrentFakeNVMap
->DriverAddHandleOptionalData
,
709 CurrentFakeNVMap
->DriverAddForceReconnect
711 if (EFI_ERROR (Status
)) {
715 BOpt_GetDriverOptions (Private
);
716 CreateMenuStringToken (Private
, Private
->BmmHiiHandle
, &DriverOptionMenu
);
728 DiscardChangeHandler (
729 IN BMM_CALLBACK_DATA
*Private
,
730 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
735 switch (Private
->BmmPreviousPageId
) {
736 case FORM_BOOT_CHG_ID
:
737 case FORM_DRV_CHG_ID
:
738 CopyMem (CurrentFakeNVMap
->OptionOrder
, Private
->BmmOldFakeNVData
.OptionOrder
, 100);
741 case FORM_BOOT_DEL_ID
:
742 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
743 CurrentFakeNVMap
->BootOptionDel
[Index
] = 0x00;
747 case FORM_DRV_DEL_ID
:
748 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
749 CurrentFakeNVMap
->DriverOptionDel
[Index
] = 0x00;
753 case FORM_BOOT_NEXT_ID
:
754 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
757 case FORM_TIME_OUT_ID
:
758 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
761 case FORM_DRV_ADD_HANDLE_DESC_ID
:
762 case FORM_DRV_ADD_FILE_ID
:
763 case FORM_DRV_ADD_HANDLE_ID
:
764 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
765 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
780 Initialize the Boot Maintenance Utitliy
783 ImageHandle - caller provided handle
784 SystemTable - caller provided system tables
787 EFI_SUCCESS - utility ended successfully
788 others - contain some errors
792 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
793 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
794 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
798 Status
= EFI_SUCCESS
;
801 // Create CallbackData structures for Driver Callback
803 BmmCallbackInfo
= EfiAllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
804 if (BmmCallbackInfo
== NULL
) {
805 return EFI_OUT_OF_RESOURCES
;
809 // Create LoadOption in BmmCallbackInfo for Driver Callback
811 Ptr
= EfiAllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
813 SafeFreePool (BmmCallbackInfo
);
814 return EFI_OUT_OF_RESOURCES
;
818 // Initialize Bmm callback data.
820 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
821 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
823 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
824 Ptr
+= sizeof (BM_FILE_CONTEXT
);
826 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
827 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
829 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
831 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
832 BmmCallbackInfo
->BmmConfigAccess
.ExtractConfig
= BootMaintExtractConfig
;
833 BmmCallbackInfo
->BmmConfigAccess
.RouteConfig
= FakeRouteConfig
;
834 BmmCallbackInfo
->BmmConfigAccess
.Callback
= BootMaintCallback
;
835 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
836 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
837 BmmCallbackInfo
->FeConfigAccess
.ExtractConfig
= FakeExtractConfig
;
838 BmmCallbackInfo
->FeConfigAccess
.RouteConfig
= FakeRouteConfig
;
839 BmmCallbackInfo
->FeConfigAccess
.Callback
= FileExplorerCallback
;
840 BmmCallbackInfo
->FeCurrentState
= INACTIVE_STATE
;
841 BmmCallbackInfo
->FeDisplayContext
= UNKNOWN_CONTEXT
;
844 // Create driver handle used by HII database
846 Status
= HiiLibCreateHiiDriverHandle (&BmmCallbackInfo
->BmmDriverHandle
);
847 if (EFI_ERROR (Status
)) {
852 // Install Config Access protocol to driver handle
854 Status
= gBS
->InstallProtocolInterface (
855 &BmmCallbackInfo
->BmmDriverHandle
,
856 &gEfiHiiConfigAccessProtocolGuid
,
857 EFI_NATIVE_INTERFACE
,
858 &BmmCallbackInfo
->BmmConfigAccess
860 if (EFI_ERROR (Status
)) {
865 // Create driver handle used by HII database
867 Status
= HiiLibCreateHiiDriverHandle (&BmmCallbackInfo
->FeDriverHandle
);
868 if (EFI_ERROR (Status
)) {
873 // Install Config Access protocol to driver handle
875 Status
= gBS
->InstallProtocolInterface (
876 &BmmCallbackInfo
->FeDriverHandle
,
877 &gEfiHiiConfigAccessProtocolGuid
,
878 EFI_NATIVE_INTERFACE
,
879 &BmmCallbackInfo
->FeConfigAccess
881 if (EFI_ERROR (Status
)) {
886 // Post our Boot Maint VFR binnary to the HII database.
888 PackageList
= PreparePackageList (2, &mBootMaintGuid
, BmBin
, BdsStrings
);
889 ASSERT (PackageList
!= NULL
);
891 Status
= gHiiDatabase
->NewPackageList (
894 BmmCallbackInfo
->BmmDriverHandle
,
895 &BmmCallbackInfo
->BmmHiiHandle
897 FreePool (PackageList
);
900 // Post our File Explorer VFR binary to the HII database.
902 PackageList
= PreparePackageList (2, &mFileExplorerGuid
, FEBin
, BdsStrings
);
903 ASSERT (PackageList
!= NULL
);
905 Status
= gHiiDatabase
->NewPackageList (
908 BmmCallbackInfo
->FeDriverHandle
,
909 &BmmCallbackInfo
->FeHiiHandle
911 FreePool (PackageList
);
914 // Allocate space for creation of Buffer
916 gUpdateData
.BufferSize
= UPDATE_DATA_SIZE
;
917 gUpdateData
.Data
= EfiAllocateZeroPool (UPDATE_DATA_SIZE
);
918 if (gUpdateData
.Data
== NULL
) {
919 SafeFreePool (BmmCallbackInfo
->LoadContext
);
920 SafeFreePool (BmmCallbackInfo
);
921 return EFI_OUT_OF_RESOURCES
;
924 InitializeStringDepository ();
926 InitAllMenu (BmmCallbackInfo
);
928 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
929 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
930 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
931 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
932 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
933 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
934 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
936 UpdateBootDelPage (BmmCallbackInfo
);
937 UpdateDrvDelPage (BmmCallbackInfo
);
939 if (TerminalMenu
.MenuNumber
> 0) {
940 BmmCallbackInfo
->CurrentTerminal
= 0;
941 UpdateTerminalPage (BmmCallbackInfo
);
944 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
945 if (!EFI_ERROR (Status
)) {
946 RefreshUpdateData ();
949 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
950 // in BootOption form: legacy FD/HD/CD/NET/BEV
953 FORM_SET_FD_ORDER_ID
,
954 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
955 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
956 EFI_IFR_FLAG_CALLBACK
,
957 FORM_SET_FD_ORDER_ID
,
962 FORM_SET_HD_ORDER_ID
,
963 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
964 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
965 EFI_IFR_FLAG_CALLBACK
,
966 FORM_SET_HD_ORDER_ID
,
971 FORM_SET_CD_ORDER_ID
,
972 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
973 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
974 EFI_IFR_FLAG_CALLBACK
,
975 FORM_SET_CD_ORDER_ID
,
980 FORM_SET_NET_ORDER_ID
,
981 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
982 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
983 EFI_IFR_FLAG_CALLBACK
,
984 FORM_SET_NET_ORDER_ID
,
989 FORM_SET_BEV_ORDER_ID
,
990 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
991 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
992 EFI_IFR_FLAG_CALLBACK
,
993 FORM_SET_BEV_ORDER_ID
,
998 BmmCallbackInfo
->BmmHiiHandle
,
1001 FORM_BOOT_LEGACY_DEVICE_ID
,
1008 // Dispatch BMM main formset and File Explorer formset.
1010 FormSetDispatcher (BmmCallbackInfo
);
1013 // Remove our IFR data from HII database
1015 gHiiDatabase
->RemovePackageList (gHiiDatabase
, BmmCallbackInfo
->BmmHiiHandle
);
1016 gHiiDatabase
->RemovePackageList (gHiiDatabase
, BmmCallbackInfo
->FeHiiHandle
);
1018 CleanUpStringDepository ();
1022 SafeFreePool (BmmCallbackInfo
->LoadContext
);
1023 SafeFreePool (BmmCallbackInfo
);
1024 SafeFreePool (gUpdateData
.Data
);
1025 gUpdateData
.Data
= NULL
;
1032 IN BMM_CALLBACK_DATA
*CallbackData
1035 InitializeListHead (&BootOptionMenu
.Head
);
1036 InitializeListHead (&DriverOptionMenu
.Head
);
1037 BOpt_GetBootOptions (CallbackData
);
1038 BOpt_GetDriverOptions (CallbackData
);
1039 BOpt_GetLegacyOptions ();
1040 InitializeListHead (&FsOptionMenu
.Head
);
1041 BOpt_FindDrivers ();
1042 InitializeListHead (&DirectoryMenu
.Head
);
1043 InitializeListHead (&ConsoleInpMenu
.Head
);
1044 InitializeListHead (&ConsoleOutMenu
.Head
);
1045 InitializeListHead (&ConsoleErrMenu
.Head
);
1046 InitializeListHead (&TerminalMenu
.Head
);
1056 BOpt_FreeMenu (&DirectoryMenu
);
1057 BOpt_FreeMenu (&FsOptionMenu
);
1058 BOpt_FreeMenu (&BootOptionMenu
);
1059 BOpt_FreeMenu (&DriverOptionMenu
);
1060 BOpt_FreeMenu (&DriverMenu
);
1061 BOpt_FreeLegacyOptions ();
1066 InitializeStringDepository (
1071 Routine Description:
1072 Intialize all the string depositories.
1082 STRING_DEPOSITORY
*StringDepository
;
1083 StringDepository
= EfiAllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1084 FileOptionStrDepository
= StringDepository
++;
1085 ConsoleOptionStrDepository
= StringDepository
++;
1086 BootOptionStrDepository
= StringDepository
++;
1087 BootOptionHelpStrDepository
= StringDepository
++;
1088 DriverOptionStrDepository
= StringDepository
++;
1089 DriverOptionHelpStrDepository
= StringDepository
++;
1090 TerminalStrDepository
= StringDepository
;
1094 GetStringTokenFromDepository (
1095 IN BMM_CALLBACK_DATA
*CallbackData
,
1096 IN STRING_DEPOSITORY
*StringDepository
1100 Routine Description:
1101 Fetch a usable string node from the string depository and return the string token.
1104 StringDepository - Pointer of the string depository.
1107 EFI_STRING_ID - String token.
1111 STRING_LIST_NODE
*CurrentListNode
;
1112 STRING_LIST_NODE
*NextListNode
;
1114 CurrentListNode
= StringDepository
->CurrentNode
;
1116 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1118 // Fetch one reclaimed node from the list.
1120 NextListNode
= StringDepository
->CurrentNode
->Next
;
1123 // If there is no usable node in the list, update the list.
1125 NextListNode
= EfiAllocateZeroPool (sizeof (STRING_LIST_NODE
));
1127 IfrLibNewString (CallbackData
->BmmHiiHandle
, &(NextListNode
->StringToken
), L
" ");
1128 ASSERT (NextListNode
->StringToken
!= 0);
1130 StringDepository
->TotalNodeNumber
++;
1132 if (NULL
== CurrentListNode
) {
1133 StringDepository
->ListHead
= NextListNode
;
1135 CurrentListNode
->Next
= NextListNode
;
1139 StringDepository
->CurrentNode
= NextListNode
;
1141 return StringDepository
->CurrentNode
->StringToken
;
1145 ReclaimStringDepository (
1150 Routine Description:
1151 Reclaim string depositories by moving the current node pointer to list head..
1161 UINTN DepositoryIndex
;
1162 STRING_DEPOSITORY
*StringDepository
;
1164 StringDepository
= FileOptionStrDepository
;
1165 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1166 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1172 CleanUpStringDepository (
1177 Routine Description:
1178 Release resource for all the string depositories.
1189 UINTN DepositoryIndex
;
1190 STRING_LIST_NODE
*CurrentListNode
;
1191 STRING_LIST_NODE
*NextListNode
;
1192 STRING_DEPOSITORY
*StringDepository
;
1195 // Release string list nodes.
1197 StringDepository
= FileOptionStrDepository
;
1198 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1199 CurrentListNode
= StringDepository
->ListHead
;
1200 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1201 NextListNode
= CurrentListNode
->Next
;
1202 SafeFreePool (CurrentListNode
);
1203 CurrentListNode
= NextListNode
;
1209 // Release string depository.
1211 SafeFreePool (FileOptionStrDepository
);
1220 Routine Description:
1221 Start boot maintenance manager
1230 LIST_ENTRY BdsBootOptionList
;
1232 InitializeListHead (&BdsBootOptionList
);
1235 // Connect all prior to entering the platform setup menu.
1237 if (!gConnectAllHappened
) {
1238 BdsLibConnectAllDriversToAllControllers ();
1239 gConnectAllHappened
= TRUE
;
1242 // Have chance to enumerate boot device
1244 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1247 // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
1249 gBS
->RestoreTPL (TPL_APPLICATION
);
1254 Status
= InitializeBM ();
1257 // Raise the TPL level back to TPL_APPLICATION
1259 gBS
->RaiseTPL (TPL_APPLICATION
);
1266 IN BMM_CALLBACK_DATA
*CallbackData
1270 Routine Description:
1271 Dispatch BMM formset and FileExplorer formset.
1280 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1283 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1285 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1286 Status
= gFormBrowser2
->SendForm (
1288 &CallbackData
->BmmHiiHandle
,
1295 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1296 EnableResetRequired ();
1299 ReclaimStringDepository ();
1302 // When this Formset returns, check if we are going to explore files.
1304 if (INACTIVE_STATE
!= CallbackData
->FeCurrentState
) {
1305 UpdateFileExplorer (CallbackData
, 0);
1307 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1308 Status
= gFormBrowser2
->SendForm (
1310 &CallbackData
->FeHiiHandle
,
1317 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1318 EnableResetRequired ();
1321 CallbackData
->FeCurrentState
= INACTIVE_STATE
;
1322 CallbackData
->FeDisplayContext
= UNKNOWN_CONTEXT
;
1323 ReclaimStringDepository ();