2 The functions for Boot Maintainence Main menu.
4 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "BootMaintenanceManager.h"
11 #define FRONT_PAGE_KEY_OFFSET 0x4000
13 // Boot video resolution and text mode.
15 UINT32 mBmmBootHorizontalResolution
= 0;
16 UINT32 mBmmBootVerticalResolution
= 0;
17 UINT32 mBmmBootTextModeColumn
= 0;
18 UINT32 mBmmBootTextModeRow
= 0;
20 // BIOS setup video resolution and text mode.
22 UINT32 mBmmSetupTextModeColumn
= 0;
23 UINT32 mBmmSetupTextModeRow
= 0;
24 UINT32 mBmmSetupHorizontalResolution
= 0;
25 UINT32 mBmmSetupVerticalResolution
= 0;
27 BOOLEAN mBmmModeInitialized
= FALSE
;
29 EFI_DEVICE_PATH_PROTOCOL EndDevicePath
[] = {
32 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
34 END_DEVICE_PATH_LENGTH
,
40 HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath
= {
46 (UINT8
)(sizeof (VENDOR_DEVICE_PATH
)),
47 (UINT8
)((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
51 // {165A028F-0BB2-4b5f-8747-77592E3F6499}
53 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 }
58 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
60 (UINT8
)(END_DEVICE_PATH_LENGTH
),
61 (UINT8
)((END_DEVICE_PATH_LENGTH
) >> 8)
66 EFI_GUID mBootMaintGuid
= BOOT_MAINT_FORMSET_GUID
;
68 CHAR16 mBootMaintStorageName
[] = L
"BmmData";
69 BMM_CALLBACK_DATA gBootMaintenancePrivate
= {
70 BMM_CALLBACK_DATA_SIGNATURE
,
74 BootMaintExtractConfig
,
80 BMM_CALLBACK_DATA
*mBmmCallbackInfo
= &gBootMaintenancePrivate
;
81 BOOLEAN mAllMenuInit
= FALSE
;
82 BOOLEAN mFirstEnterBMMForm
= FALSE
;
87 @param CallbackData The BMM context data.
92 IN BMM_CALLBACK_DATA
*CallbackData
96 Free up all Menu Option list.
106 Update the menus in the BMM page.
115 This function will change video resolution and text mode
116 according to defined setup mode or defined boot mode
118 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
120 @retval EFI_SUCCESS Mode is changed successfully.
121 @retval Others Mode failed to be changed.
129 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
130 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
132 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
136 UINT32 NewHorizontalResolution
;
137 UINT32 NewVerticalResolution
;
141 EFI_HANDLE
*HandleBuffer
;
151 // Get current video resolution and text mode
153 Status
= gBS
->HandleProtocol (
154 gST
->ConsoleOutHandle
,
155 &gEfiGraphicsOutputProtocolGuid
,
156 (VOID
**)&GraphicsOutput
158 if (EFI_ERROR (Status
)) {
159 GraphicsOutput
= NULL
;
162 Status
= gBS
->HandleProtocol (
163 gST
->ConsoleOutHandle
,
164 &gEfiSimpleTextOutProtocolGuid
,
165 (VOID
**)&SimpleTextOut
167 if (EFI_ERROR (Status
)) {
168 SimpleTextOut
= NULL
;
171 if ((GraphicsOutput
== NULL
) || (SimpleTextOut
== NULL
)) {
172 return EFI_UNSUPPORTED
;
177 // The required resolution and text mode is setup mode.
179 NewHorizontalResolution
= mBmmSetupHorizontalResolution
;
180 NewVerticalResolution
= mBmmSetupVerticalResolution
;
181 NewColumns
= mBmmSetupTextModeColumn
;
182 NewRows
= mBmmSetupTextModeRow
;
185 // The required resolution and text mode is boot mode.
187 NewHorizontalResolution
= mBmmBootHorizontalResolution
;
188 NewVerticalResolution
= mBmmBootVerticalResolution
;
189 NewColumns
= mBmmBootTextModeColumn
;
190 NewRows
= mBmmBootTextModeRow
;
193 if (GraphicsOutput
!= NULL
) {
194 MaxGopMode
= GraphicsOutput
->Mode
->MaxMode
;
197 if (SimpleTextOut
!= NULL
) {
198 MaxTextMode
= SimpleTextOut
->Mode
->MaxMode
;
202 // 1. If current video resolution is same with required video resolution,
203 // video resolution need not be changed.
204 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
205 // 1.2. If current text mode is different from required text mode, text mode need be changed.
206 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
208 for (ModeNumber
= 0; ModeNumber
< MaxGopMode
; ModeNumber
++) {
209 Status
= GraphicsOutput
->QueryMode (
215 if (!EFI_ERROR (Status
)) {
216 if ((Info
->HorizontalResolution
== NewHorizontalResolution
) &&
217 (Info
->VerticalResolution
== NewVerticalResolution
))
219 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== NewHorizontalResolution
) &&
220 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== NewVerticalResolution
))
223 // Current resolution is same with required resolution, check if text mode need be set
225 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, SimpleTextOut
->Mode
->Mode
, &CurrentColumn
, &CurrentRow
);
226 ASSERT_EFI_ERROR (Status
);
227 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
229 // If current text mode is same with required text mode. Do nothing
235 // If current text mode is different from required text mode. Set new video mode
237 for (Index
= 0; Index
< MaxTextMode
; Index
++) {
238 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, Index
, &CurrentColumn
, &CurrentRow
);
239 if (!EFI_ERROR (Status
)) {
240 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
242 // Required text mode is supported, set it.
244 Status
= SimpleTextOut
->SetMode (SimpleTextOut
, Index
);
245 ASSERT_EFI_ERROR (Status
);
247 // Update text mode PCD.
249 Status
= PcdSet32S (PcdConOutColumn
, mBmmSetupTextModeColumn
);
250 ASSERT_EFI_ERROR (Status
);
251 Status
= PcdSet32S (PcdConOutRow
, mBmmSetupTextModeRow
);
252 ASSERT_EFI_ERROR (Status
);
259 if (Index
== MaxTextMode
) {
261 // If required text mode is not supported, return error.
264 return EFI_UNSUPPORTED
;
269 // If current video resolution is not same with the new one, set new video resolution.
270 // In this case, the driver which produces simple text out need be restarted.
272 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
273 if (!EFI_ERROR (Status
)) {
284 if (ModeNumber
== MaxGopMode
) {
286 // If the resolution is not supported, return error.
288 return EFI_UNSUPPORTED
;
292 // Set PCD to Inform GraphicsConsole to change video resolution.
293 // Set PCD to Inform Consplitter to change text mode.
295 Status
= PcdSet32S (PcdVideoHorizontalResolution
, NewHorizontalResolution
);
296 ASSERT_EFI_ERROR (Status
);
297 Status
= PcdSet32S (PcdVideoVerticalResolution
, NewVerticalResolution
);
298 ASSERT_EFI_ERROR (Status
);
299 Status
= PcdSet32S (PcdConOutColumn
, NewColumns
);
300 ASSERT_EFI_ERROR (Status
);
301 Status
= PcdSet32S (PcdConOutRow
, NewRows
);
302 ASSERT_EFI_ERROR (Status
);
305 // Video mode is changed, so restart graphics console driver and higher level driver.
306 // Reconnect graphics console driver and higher level driver.
307 // Locate all the handles with GOP protocol and reconnect it.
309 Status
= gBS
->LocateHandleBuffer (
311 &gEfiSimpleTextOutProtocolGuid
,
316 if (!EFI_ERROR (Status
)) {
317 for (Index
= 0; Index
< HandleCount
; Index
++) {
318 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
321 for (Index
= 0; Index
< HandleCount
; Index
++) {
322 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
325 if (HandleBuffer
!= NULL
) {
326 FreePool (HandleBuffer
);
334 This function converts an input device structure to a Unicode string.
336 @param DevPath A pointer to the device path structure.
338 @return A new allocated Unicode string that represents the device path.
343 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
348 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
350 if (DevPath
== NULL
) {
354 Status
= gBS
->LocateProtocol (
355 &gEfiDevicePathToTextProtocolGuid
,
357 (VOID
**)&DevPathToText
359 ASSERT_EFI_ERROR (Status
);
360 ToText
= DevPathToText
->ConvertDevicePathToText (
365 ASSERT (ToText
!= NULL
);
370 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
371 The caller is responsible for freeing the allocated buffer using FreePool().
373 @param DevicePath Device path.
375 @return A new allocated string that represents the file name.
379 ExtractFileNameFromDevicePath (
380 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
389 ASSERT (DevicePath
!= NULL
);
391 String
= UiDevicePathToStr (DevicePath
);
392 MatchString
= String
;
396 while (MatchString
!= NULL
) {
397 LastMatch
= MatchString
+ 1;
398 MatchString
= StrStr (LastMatch
, L
"\\");
401 Length
= StrLen (LastMatch
);
402 FileName
= AllocateCopyPool ((Length
+ 1) * sizeof (CHAR16
), LastMatch
);
403 if (FileName
!= NULL
) {
404 *(FileName
+ Length
) = 0;
413 Extract device path for given HII handle and class guid.
415 @param Handle The HII handle.
417 @retval NULL Fail to get the device path string.
418 @return PathString Get the device path string.
422 BmmExtractDevicePathFromHiiHandle (
423 IN EFI_HII_HANDLE Handle
427 EFI_HANDLE DriverHandle
;
429 ASSERT (Handle
!= NULL
);
431 if (Handle
== NULL
) {
435 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
436 if (EFI_ERROR (Status
)) {
441 // Get device path string.
443 return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle
), FALSE
, FALSE
);
447 Converts the unicode character of the string from uppercase to lowercase.
448 This is a internal function.
450 @param ConfigString String to be converted
455 IN EFI_STRING ConfigString
461 ASSERT (ConfigString
!= NULL
);
464 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
466 for (String
= ConfigString
, Lower
= FALSE
; *String
!= L
'\0'; String
++) {
467 if (*String
== L
'=') {
469 } else if (*String
== L
'&') {
471 } else if (Lower
&& (*String
>= L
'A') && (*String
<= L
'F')) {
472 *String
= (CHAR16
)(*String
- L
'A' + L
'a');
478 Update the progress string through the offset value.
480 @param Offset The offset value
481 @param Configuration Point to the configuration string.
487 IN EFI_STRING Configuration
491 EFI_STRING StringPtr
;
492 EFI_STRING ReturnString
;
498 // &OFFSET=XXXX followed by a Null-terminator.
499 // Length = StrLen (L"&OFFSET=") + 4 + 1
501 Length
= StrLen (L
"&OFFSET=") + 4 + 1;
503 StringPtr
= AllocateZeroPool (Length
* sizeof (CHAR16
));
505 if (StringPtr
== NULL
) {
511 (8 + 4 + 1) * sizeof (CHAR16
),
516 ReturnString
= StrStr (Configuration
, StringPtr
);
518 if (ReturnString
== NULL
) {
520 // If doesn't find the string in Configuration, convert the string to lower case then search again.
522 HiiToLower (StringPtr
);
523 ReturnString
= StrStr (Configuration
, StringPtr
);
526 FreePool (StringPtr
);
532 Update the terminal content in TerminalMenu.
534 @param BmmData The BMM fake NV data.
538 UpdateTerminalContent (
539 IN BMM_FAKE_NV_DATA
*BmmData
543 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
544 BM_MENU_ENTRY
*NewMenuEntry
;
546 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
547 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
548 ASSERT (NewMenuEntry
!= NULL
);
549 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
550 NewTerminalContext
->BaudRateIndex
= BmmData
->COMBaudRate
[Index
];
551 ASSERT (BmmData
->COMBaudRate
[Index
] < (ARRAY_SIZE (BaudRateList
)));
552 NewTerminalContext
->BaudRate
= BaudRateList
[BmmData
->COMBaudRate
[Index
]].Value
;
553 NewTerminalContext
->DataBitsIndex
= BmmData
->COMDataRate
[Index
];
554 ASSERT (BmmData
->COMDataRate
[Index
] < (ARRAY_SIZE (DataBitsList
)));
555 NewTerminalContext
->DataBits
= (UINT8
)DataBitsList
[BmmData
->COMDataRate
[Index
]].Value
;
556 NewTerminalContext
->StopBitsIndex
= BmmData
->COMStopBits
[Index
];
557 ASSERT (BmmData
->COMStopBits
[Index
] < (ARRAY_SIZE (StopBitsList
)));
558 NewTerminalContext
->StopBits
= (UINT8
)StopBitsList
[BmmData
->COMStopBits
[Index
]].Value
;
559 NewTerminalContext
->ParityIndex
= BmmData
->COMParity
[Index
];
560 ASSERT (BmmData
->COMParity
[Index
] < (ARRAY_SIZE (ParityList
)));
561 NewTerminalContext
->Parity
= (UINT8
)ParityList
[BmmData
->COMParity
[Index
]].Value
;
562 NewTerminalContext
->TerminalType
= BmmData
->COMTerminalType
[Index
];
563 NewTerminalContext
->FlowControl
= BmmData
->COMFlowControl
[Index
];
564 ChangeTerminalDevicePath (
565 NewTerminalContext
->DevicePath
,
572 Update the console content in ConsoleMenu.
574 @param ConsoleName The name for the console device type.
575 @param BmmData The BMM fake NV data.
579 UpdateConsoleContent (
580 IN CHAR16
*ConsoleName
,
581 IN BMM_FAKE_NV_DATA
*BmmData
585 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
586 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
587 BM_MENU_ENTRY
*NewMenuEntry
;
589 if (StrCmp (ConsoleName
, L
"ConIn") == 0) {
590 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
591 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
592 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
593 ASSERT (Index
< MAX_MENU_NUMBER
);
594 NewConsoleContext
->IsActive
= BmmData
->ConsoleInCheck
[Index
];
597 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
598 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
599 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
600 ASSERT (Index
+ ConsoleInpMenu
.MenuNumber
< MAX_MENU_NUMBER
);
601 NewTerminalContext
->IsConIn
= BmmData
->ConsoleInCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
605 if (StrCmp (ConsoleName
, L
"ConOut") == 0) {
606 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
607 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
608 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
609 ASSERT (Index
< MAX_MENU_NUMBER
);
610 NewConsoleContext
->IsActive
= BmmData
->ConsoleOutCheck
[Index
];
613 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
614 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
615 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
616 ASSERT (Index
+ ConsoleOutMenu
.MenuNumber
< MAX_MENU_NUMBER
);
617 NewTerminalContext
->IsConOut
= BmmData
->ConsoleOutCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
621 if (StrCmp (ConsoleName
, L
"ErrOut") == 0) {
622 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
623 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
624 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
625 ASSERT (Index
< MAX_MENU_NUMBER
);
626 NewConsoleContext
->IsActive
= BmmData
->ConsoleErrCheck
[Index
];
629 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
630 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
631 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
632 ASSERT (Index
+ ConsoleErrMenu
.MenuNumber
< MAX_MENU_NUMBER
);
633 NewTerminalContext
->IsStdErr
= BmmData
->ConsoleErrCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
639 This function allows a caller to extract the current configuration for one
640 or more named elements from the target driver.
642 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
643 @param Request A null-terminated Unicode string in <ConfigRequest> format.
644 @param Progress On return, points to a character in the Request string.
645 Points to the string's null terminator if request was successful.
646 Points to the most recent '&' before the first failing name/value
647 pair (or the beginning of the string if the failure is in the
648 first name/value pair) if the request was not successful.
649 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
650 has all values filled in for the names in the Request string.
651 String to be allocated by the called function.
653 @retval EFI_SUCCESS The Results is filled with the requested values.
654 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
655 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
656 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
661 BootMaintExtractConfig (
662 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
663 IN CONST EFI_STRING Request
,
664 OUT EFI_STRING
*Progress
,
665 OUT EFI_STRING
*Results
670 BMM_CALLBACK_DATA
*Private
;
671 EFI_STRING ConfigRequestHdr
;
672 EFI_STRING ConfigRequest
;
673 BOOLEAN AllocatedRequest
;
676 if ((Progress
== NULL
) || (Results
== NULL
)) {
677 return EFI_INVALID_PARAMETER
;
681 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &mBootMaintGuid
, mBootMaintStorageName
)) {
682 return EFI_NOT_FOUND
;
685 ConfigRequestHdr
= NULL
;
686 ConfigRequest
= NULL
;
687 AllocatedRequest
= FALSE
;
690 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
692 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
694 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
695 ConfigRequest
= Request
;
696 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
698 // Request has no request element, construct full request string.
699 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
700 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
702 ConfigRequestHdr
= HiiConstructConfigHdr (&mBootMaintGuid
, mBootMaintStorageName
, Private
->BmmDriverHandle
);
703 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
704 ConfigRequest
= AllocateZeroPool (Size
);
705 ASSERT (ConfigRequest
!= NULL
);
706 AllocatedRequest
= TRUE
;
707 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
708 FreePool (ConfigRequestHdr
);
711 Status
= gHiiConfigRouting
->BlockToConfig (
714 (UINT8
*)&Private
->BmmFakeNvData
,
720 // Free the allocated config request string.
722 if (AllocatedRequest
) {
723 FreePool (ConfigRequest
);
724 ConfigRequest
= NULL
;
728 // Set Progress string to the original request string.
730 if (Request
== NULL
) {
732 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
733 *Progress
= Request
+ StrLen (Request
);
740 This function applies changes in a driver's configuration.
741 Input is a Configuration, which has the routing data for this
742 driver followed by name / value configuration pairs. The driver
743 must apply those pairs to its configurable storage. If the
744 driver's configuration is stored in a linear block of data
745 and the driver's name / value pairs are in <BlockConfig>
746 format, it may use the ConfigToBlock helper function (above) to
747 simplify the job. Currently not implemented.
749 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
750 @param[in] Configuration A null-terminated Unicode string in
751 <ConfigString> format.
752 @param[out] Progress A pointer to a string filled in with the
753 offset of the most recent '&' before the
754 first failing name / value pair (or the
755 beginn ing of the string if the failure
756 is in the first name / value pair) or
757 the terminating NULL if all was
760 @retval EFI_SUCCESS The results have been distributed or are
761 awaiting distribution.
762 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
763 parts of the results that must be
764 stored awaiting possible future
766 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
767 Results parameter would result
768 in this type of error.
769 @retval EFI_NOT_FOUND Target for the specified routing data
774 BootMaintRouteConfig (
775 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
776 IN CONST EFI_STRING Configuration
,
777 OUT EFI_STRING
*Progress
782 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
783 BMM_FAKE_NV_DATA
*NewBmmData
;
784 BMM_FAKE_NV_DATA
*OldBmmData
;
785 BM_MENU_ENTRY
*NewMenuEntry
;
786 BM_LOAD_CONTEXT
*NewLoadContext
;
788 BOOLEAN TerminalAttChange
;
789 BMM_CALLBACK_DATA
*Private
;
792 if (Progress
== NULL
) {
793 return EFI_INVALID_PARAMETER
;
796 *Progress
= Configuration
;
798 if (Configuration
== NULL
) {
799 return EFI_INVALID_PARAMETER
;
803 // Check routing data in <ConfigHdr>.
804 // Note: there is no name for Name/Value storage, only GUID will be checked
806 if (!HiiIsConfigHdrMatch (Configuration
, &mBootMaintGuid
, mBootMaintStorageName
)) {
807 return EFI_NOT_FOUND
;
810 Status
= gBS
->LocateProtocol (
811 &gEfiHiiConfigRoutingProtocolGuid
,
813 (VOID
**)&ConfigRouting
815 if (EFI_ERROR (Status
)) {
819 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
821 // Get Buffer Storage data from EFI variable
823 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
824 OldBmmData
= &Private
->BmmOldFakeNVData
;
825 NewBmmData
= &Private
->BmmFakeNvData
;
828 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
830 Status
= ConfigRouting
->ConfigToBlock (
837 ASSERT_EFI_ERROR (Status
);
839 // Compare new and old BMM configuration data and only do action for modified item to
840 // avoid setting unnecessary non-volatile variable
844 // Check data which located in BMM main page and save the settings if need
846 if (CompareMem (&NewBmmData
->BootNext
, &OldBmmData
->BootNext
, sizeof (NewBmmData
->BootNext
)) != 0) {
847 Status
= Var_UpdateBootNext (Private
);
848 if (EFI_ERROR (Status
)) {
849 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootNext
);
855 // Check data which located in Boot Options Menu and save the settings if need
857 if (CompareMem (NewBmmData
->BootOptionDel
, OldBmmData
->BootOptionDel
, sizeof (NewBmmData
->BootOptionDel
)) != 0) {
859 ((Index
< BootOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->BootOptionDel
) / sizeof (NewBmmData
->BootOptionDel
[0]))));
862 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
863 NewLoadContext
= (BM_LOAD_CONTEXT
*)NewMenuEntry
->VariableContext
;
864 NewLoadContext
->Deleted
= NewBmmData
->BootOptionDel
[Index
];
865 NewBmmData
->BootOptionDel
[Index
] = FALSE
;
866 NewBmmData
->BootOptionDelMark
[Index
] = FALSE
;
869 Status
= Var_DelBootOption ();
870 if (EFI_ERROR (Status
)) {
871 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionDel
);
876 if (CompareMem (NewBmmData
->BootOptionOrder
, OldBmmData
->BootOptionOrder
, sizeof (NewBmmData
->BootOptionOrder
)) != 0) {
877 Status
= Var_UpdateBootOrder (Private
);
878 if (EFI_ERROR (Status
)) {
879 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionOrder
);
884 if (CompareMem (&NewBmmData
->BootTimeOut
, &OldBmmData
->BootTimeOut
, sizeof (NewBmmData
->BootTimeOut
)) != 0) {
885 Status
= gRT
->SetVariable (
887 &gEfiGlobalVariableGuid
,
888 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
890 &(NewBmmData
->BootTimeOut
)
892 if (EFI_ERROR (Status
)) {
893 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootTimeOut
);
897 Private
->BmmOldFakeNVData
.BootTimeOut
= NewBmmData
->BootTimeOut
;
901 // Check data which located in Driver Options Menu and save the settings if need
903 if (CompareMem (NewBmmData
->DriverOptionDel
, OldBmmData
->DriverOptionDel
, sizeof (NewBmmData
->DriverOptionDel
)) != 0) {
905 ((Index
< DriverOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->DriverOptionDel
) / sizeof (NewBmmData
->DriverOptionDel
[0]))));
908 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
909 NewLoadContext
= (BM_LOAD_CONTEXT
*)NewMenuEntry
->VariableContext
;
910 NewLoadContext
->Deleted
= NewBmmData
->DriverOptionDel
[Index
];
911 NewBmmData
->DriverOptionDel
[Index
] = FALSE
;
912 NewBmmData
->DriverOptionDelMark
[Index
] = FALSE
;
915 Status
= Var_DelDriverOption ();
916 if (EFI_ERROR (Status
)) {
917 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionDel
);
922 if (CompareMem (NewBmmData
->DriverOptionOrder
, OldBmmData
->DriverOptionOrder
, sizeof (NewBmmData
->DriverOptionOrder
)) != 0) {
923 Status
= Var_UpdateDriverOrder (Private
);
924 if (EFI_ERROR (Status
)) {
925 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionOrder
);
930 if (CompareMem (&NewBmmData
->ConsoleOutMode
, &OldBmmData
->ConsoleOutMode
, sizeof (NewBmmData
->ConsoleOutMode
)) != 0) {
931 Status
= Var_UpdateConMode (Private
);
932 if (EFI_ERROR (Status
)) {
933 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleOutMode
);
938 TerminalAttChange
= FALSE
;
939 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
941 // only need update modified items
943 if ((CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) == 0) &&
944 (CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) == 0) &&
945 (CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) == 0) &&
946 (CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) == 0) &&
947 (CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) == 0) &&
948 (CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) == 0))
953 TerminalAttChange
= TRUE
;
956 if (TerminalAttChange
) {
957 if (CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) != 0) {
958 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMBaudRate
);
959 } else if (CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) != 0) {
960 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMDataRate
);
961 } else if (CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) != 0) {
962 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMStopBits
);
963 } else if (CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) != 0) {
964 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMParity
);
965 } else if (CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) != 0) {
966 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMTerminalType
);
967 } else if (CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) != 0) {
968 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMFlowControl
);
971 Status
= Var_UpdateConsoleInpOption ();
972 if (EFI_ERROR (Status
)) {
976 Status
= Var_UpdateConsoleOutOption ();
977 if (EFI_ERROR (Status
)) {
981 Status
= Var_UpdateErrorOutOption ();
982 if (EFI_ERROR (Status
)) {
988 // Check data which located in Console Options Menu and save the settings if need
990 if (CompareMem (NewBmmData
->ConsoleInCheck
, OldBmmData
->ConsoleInCheck
, sizeof (NewBmmData
->ConsoleInCheck
)) != 0) {
991 Status
= Var_UpdateConsoleInpOption ();
992 if (EFI_ERROR (Status
)) {
993 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleInCheck
);
998 if (CompareMem (NewBmmData
->ConsoleOutCheck
, OldBmmData
->ConsoleOutCheck
, sizeof (NewBmmData
->ConsoleOutCheck
)) != 0) {
999 Status
= Var_UpdateConsoleOutOption ();
1000 if (EFI_ERROR (Status
)) {
1001 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleOutCheck
);
1006 if (CompareMem (NewBmmData
->ConsoleErrCheck
, OldBmmData
->ConsoleErrCheck
, sizeof (NewBmmData
->ConsoleErrCheck
)) != 0) {
1007 Status
= Var_UpdateErrorOutOption ();
1008 if (EFI_ERROR (Status
)) {
1009 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleErrCheck
);
1014 if ((CompareMem (NewBmmData
->BootDescriptionData
, OldBmmData
->BootDescriptionData
, sizeof (NewBmmData
->BootDescriptionData
)) != 0) ||
1015 (CompareMem (NewBmmData
->BootOptionalData
, OldBmmData
->BootOptionalData
, sizeof (NewBmmData
->BootOptionalData
)) != 0))
1017 Status
= Var_UpdateBootOption (Private
);
1018 NewBmmData
->BootOptionChanged
= FALSE
;
1019 if (EFI_ERROR (Status
)) {
1020 if (CompareMem (NewBmmData
->BootDescriptionData
, OldBmmData
->BootDescriptionData
, sizeof (NewBmmData
->BootDescriptionData
)) != 0) {
1021 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootDescriptionData
);
1023 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionalData
);
1029 BOpt_GetBootOptions (Private
);
1032 if ((CompareMem (NewBmmData
->DriverDescriptionData
, OldBmmData
->DriverDescriptionData
, sizeof (NewBmmData
->DriverDescriptionData
)) != 0) ||
1033 (CompareMem (NewBmmData
->DriverOptionalData
, OldBmmData
->DriverOptionalData
, sizeof (NewBmmData
->DriverOptionalData
)) != 0))
1035 Status
= Var_UpdateDriverOption (
1037 Private
->BmmHiiHandle
,
1038 NewBmmData
->DriverDescriptionData
,
1039 NewBmmData
->DriverOptionalData
,
1040 NewBmmData
->ForceReconnect
1042 NewBmmData
->DriverOptionChanged
= FALSE
;
1043 NewBmmData
->ForceReconnect
= TRUE
;
1044 if (EFI_ERROR (Status
)) {
1045 if (CompareMem (NewBmmData
->DriverDescriptionData
, OldBmmData
->DriverDescriptionData
, sizeof (NewBmmData
->DriverDescriptionData
)) != 0) {
1046 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverDescriptionData
);
1048 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionalData
);
1054 BOpt_GetDriverOptions (Private
);
1058 // After user do the save action, need to update OldBmmData.
1060 CopyMem (OldBmmData
, NewBmmData
, sizeof (BMM_FAKE_NV_DATA
));
1066 // Fail to save the data, update the progress string.
1068 *Progress
= UpdateProgress (Offset
, Configuration
);
1069 if (Status
== EFI_OUT_OF_RESOURCES
) {
1072 return EFI_NOT_FOUND
;
1077 This function processes the results of changes in configuration.
1080 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1081 @param Action Specifies the type of action taken by the browser.
1082 @param QuestionId A unique value which is sent to the original exporting driver
1083 so that it can identify the type of data to expect.
1084 @param Type The type of value for the question.
1085 @param Value A pointer to the data being sent to the original exporting driver.
1086 @param ActionRequest On return, points to the action requested by the callback function.
1088 @retval EFI_SUCCESS The callback successfully handled the action.
1089 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
1090 @retval EFI_DEVICE_ERROR The variable could not be saved.
1091 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
1092 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
1097 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1098 IN EFI_BROWSER_ACTION Action
,
1099 IN EFI_QUESTION_ID QuestionId
,
1101 IN EFI_IFR_TYPE_VALUE
*Value
,
1102 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1105 BMM_CALLBACK_DATA
*Private
;
1106 BM_MENU_ENTRY
*NewMenuEntry
;
1107 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1108 BMM_FAKE_NV_DATA
*OldFakeNVMap
;
1110 EFI_DEVICE_PATH_PROTOCOL
*File
;
1112 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
)) {
1114 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
1116 return EFI_UNSUPPORTED
;
1119 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
1121 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
1122 if (QuestionId
== KEY_VALUE_TRIGGER_FORM_OPEN_ACTION
) {
1123 if (!mFirstEnterBMMForm
) {
1125 // BMMUiLib depends on LegacyUi library to show legacy menus.
1126 // If we want to show Legacy menus correctly in BMM page,
1127 // we must do it after the LegacyUi library has already been initialized.
1128 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
1129 // So we do the tasks which are related to legacy menus here.
1130 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
1131 // 2. Re-scan the BootOption menus (including the legacy boot option).
1134 EfiBootManagerRefreshAllBootOption ();
1135 BOpt_GetBootOptions (Private
);
1136 mFirstEnterBMMForm
= TRUE
;
1142 // Retrieve uncommitted data from Form Browser
1144 CurrentFakeNVMap
= &Private
->BmmFakeNvData
;
1145 OldFakeNVMap
= &Private
->BmmOldFakeNVData
;
1146 HiiGetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*)CurrentFakeNVMap
);
1148 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1149 if (Value
== NULL
) {
1150 return EFI_INVALID_PARAMETER
;
1153 UpdatePageId (Private
, QuestionId
);
1155 if (QuestionId
< FILE_OPTION_OFFSET
) {
1156 if (QuestionId
< CONFIG_OPTION_OFFSET
) {
1157 switch (QuestionId
) {
1158 case FORM_BOOT_ADD_ID
:
1159 // Leave BMM and enter FileExplorer.
1160 ChooseFile (NULL
, L
".efi", CreateBootOptionFromFile
, &File
);
1163 case FORM_DRV_ADD_FILE_ID
:
1164 // Leave BMM and enter FileExplorer.
1165 ChooseFile (NULL
, L
".efi", CreateDriverOptionFromFile
, &File
);
1168 case FORM_DRV_ADD_HANDLE_ID
:
1169 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
1170 UpdateDrvAddHandlePage (Private
);
1173 case FORM_BOOT_DEL_ID
:
1174 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
1175 UpdateBootDelPage (Private
);
1178 case FORM_BOOT_CHG_ID
:
1179 case FORM_DRV_CHG_ID
:
1180 UpdatePageBody (QuestionId
, Private
);
1183 case FORM_DRV_DEL_ID
:
1184 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
1185 UpdateDrvDelPage (Private
);
1188 case FORM_CON_IN_ID
:
1189 case FORM_CON_OUT_ID
:
1190 case FORM_CON_ERR_ID
:
1191 UpdatePageBody (QuestionId
, Private
);
1194 case FORM_CON_MODE_ID
:
1195 CleanUpPage (FORM_CON_MODE_ID
, Private
);
1196 UpdateConModePage (Private
);
1199 case FORM_CON_COM_ID
:
1200 CleanUpPage (FORM_CON_COM_ID
, Private
);
1201 UpdateConCOMPage (Private
);
1207 } else if ((QuestionId
>= TERMINAL_OPTION_OFFSET
) && (QuestionId
< CONSOLE_OPTION_OFFSET
)) {
1208 Index
= (UINT16
)(QuestionId
- TERMINAL_OPTION_OFFSET
);
1209 Private
->CurrentTerminal
= Index
;
1211 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
1212 UpdateTerminalPage (Private
);
1213 } else if (QuestionId
>= HANDLE_OPTION_OFFSET
) {
1214 Index
= (UINT16
)(QuestionId
- HANDLE_OPTION_OFFSET
);
1216 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index
);
1217 ASSERT (NewMenuEntry
!= NULL
);
1218 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
1220 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
1222 Private
->MenuEntry
= NewMenuEntry
;
1223 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
1225 UpdateDriverAddHandleDescPage (Private
);
1229 if (QuestionId
== KEY_VALUE_BOOT_FROM_FILE
) {
1230 // Leave BMM and enter FileExplorer.
1231 ChooseFile (NULL
, L
".efi", BootFromFile
, &File
);
1233 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1234 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1235 return EFI_INVALID_PARAMETER
;
1238 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_BOOT
) {
1239 CleanUselessBeforeSubmit (Private
);
1240 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1241 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1242 } else if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_DRIVER
) {
1243 CleanUselessBeforeSubmit (Private
);
1244 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1245 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1246 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER
) {
1248 // Discard changes and exit formset
1250 ZeroMem (CurrentFakeNVMap
->DriverOptionalData
, sizeof (CurrentFakeNVMap
->DriverOptionalData
));
1251 ZeroMem (CurrentFakeNVMap
->BootDescriptionData
, sizeof (CurrentFakeNVMap
->BootDescriptionData
));
1252 ZeroMem (OldFakeNVMap
->DriverOptionalData
, sizeof (OldFakeNVMap
->DriverOptionalData
));
1253 ZeroMem (OldFakeNVMap
->DriverDescriptionData
, sizeof (OldFakeNVMap
->DriverDescriptionData
));
1254 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1255 CurrentFakeNVMap
->ForceReconnect
= TRUE
;
1256 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1257 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_BOOT
) {
1259 // Discard changes and exit formset
1261 ZeroMem (CurrentFakeNVMap
->BootOptionalData
, sizeof (CurrentFakeNVMap
->BootOptionalData
));
1262 ZeroMem (CurrentFakeNVMap
->BootDescriptionData
, sizeof (CurrentFakeNVMap
->BootDescriptionData
));
1263 ZeroMem (OldFakeNVMap
->BootOptionalData
, sizeof (OldFakeNVMap
->BootOptionalData
));
1264 ZeroMem (OldFakeNVMap
->BootDescriptionData
, sizeof (OldFakeNVMap
->BootDescriptionData
));
1265 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1266 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1267 } else if ((QuestionId
== KEY_VALUE_BOOT_DESCRIPTION
) || (QuestionId
== KEY_VALUE_BOOT_OPTION
)) {
1268 CurrentFakeNVMap
->BootOptionChanged
= TRUE
;
1269 } else if ((QuestionId
== KEY_VALUE_DRIVER_DESCRIPTION
) || (QuestionId
== KEY_VALUE_DRIVER_OPTION
)) {
1270 CurrentFakeNVMap
->DriverOptionChanged
= TRUE
;
1273 if ((QuestionId
>= BOOT_OPTION_DEL_QUESTION_ID
) && (QuestionId
< BOOT_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1276 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
1278 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = TRUE
;
1281 // Means user remove the old check status.
1283 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = FALSE
;
1285 } else if ((QuestionId
>= DRIVER_OPTION_DEL_QUESTION_ID
) && (QuestionId
< DRIVER_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1287 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = TRUE
;
1289 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = FALSE
;
1292 switch (QuestionId
) {
1293 case KEY_VALUE_SAVE_AND_EXIT
:
1294 case KEY_VALUE_NO_SAVE_AND_EXIT
:
1295 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT
) {
1296 CleanUselessBeforeSubmit (Private
);
1297 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1298 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
1299 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
1300 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1306 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1307 return EFI_UNSUPPORTED
;
1315 // Update the content in Terminal menu and Console menu here.
1317 if ((QuestionId
== COM_BAUD_RATE_QUESTION_ID
+ Private
->CurrentTerminal
) || (QuestionId
== COM_DATA_RATE_QUESTION_ID
+ Private
->CurrentTerminal
) ||
1318 (QuestionId
== COM_PARITY_QUESTION_ID
+ Private
->CurrentTerminal
) || (QuestionId
== COM_STOP_BITS_QUESTION_ID
+ Private
->CurrentTerminal
) ||
1319 (QuestionId
== COM_TERMINAL_QUESTION_ID
+ Private
->CurrentTerminal
) || (QuestionId
== COM_FLOWCONTROL_QUESTION_ID
+ Private
->CurrentTerminal
)
1322 UpdateTerminalContent (CurrentFakeNVMap
);
1325 if ((QuestionId
>= CON_IN_DEVICE_QUESTION_ID
) && (QuestionId
< CON_IN_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1326 UpdateConsoleContent (L
"ConIn", CurrentFakeNVMap
);
1327 } else if ((QuestionId
>= CON_OUT_DEVICE_QUESTION_ID
) && (QuestionId
< CON_OUT_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1328 UpdateConsoleContent (L
"ConOut", CurrentFakeNVMap
);
1329 } else if ((QuestionId
>= CON_ERR_DEVICE_QUESTION_ID
) && (QuestionId
< CON_ERR_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1330 UpdateConsoleContent (L
"ErrOut", CurrentFakeNVMap
);
1335 // Pass changed uncommitted data back to Form Browser
1337 HiiSetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*)CurrentFakeNVMap
, NULL
);
1343 Discard all changes done to the BMM pages such as Boot Order change,
1344 Driver order change.
1346 @param Private The BMM context data.
1347 @param CurrentFakeNVMap The current Fack NV Map.
1351 DiscardChangeHandler (
1352 IN BMM_CALLBACK_DATA
*Private
,
1353 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
1358 switch (Private
->BmmPreviousPageId
) {
1359 case FORM_BOOT_CHG_ID
:
1360 CopyMem (CurrentFakeNVMap
->BootOptionOrder
, Private
->BmmOldFakeNVData
.BootOptionOrder
, sizeof (CurrentFakeNVMap
->BootOptionOrder
));
1363 case FORM_DRV_CHG_ID
:
1364 CopyMem (CurrentFakeNVMap
->DriverOptionOrder
, Private
->BmmOldFakeNVData
.DriverOptionOrder
, sizeof (CurrentFakeNVMap
->DriverOptionOrder
));
1367 case FORM_BOOT_DEL_ID
:
1368 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->BootOptionDel
) / sizeof (CurrentFakeNVMap
->BootOptionDel
[0])));
1369 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1370 CurrentFakeNVMap
->BootOptionDel
[Index
] = FALSE
;
1375 case FORM_DRV_DEL_ID
:
1376 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->DriverOptionDel
) / sizeof (CurrentFakeNVMap
->DriverOptionDel
[0])));
1377 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1378 CurrentFakeNVMap
->DriverOptionDel
[Index
] = FALSE
;
1383 case FORM_BOOT_NEXT_ID
:
1384 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
1387 case FORM_TIME_OUT_ID
:
1388 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
1391 case FORM_DRV_ADD_HANDLE_DESC_ID
:
1392 case FORM_DRV_ADD_FILE_ID
:
1393 case FORM_DRV_ADD_HANDLE_ID
:
1394 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
1395 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
1404 This function is to clean some useless data before submit changes.
1406 @param Private The BMM context data.
1410 CleanUselessBeforeSubmit (
1411 IN BMM_CALLBACK_DATA
*Private
1416 if (Private
->BmmPreviousPageId
!= FORM_BOOT_DEL_ID
) {
1417 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1418 if (Private
->BmmFakeNvData
.BootOptionDel
[Index
] && !Private
->BmmFakeNvData
.BootOptionDelMark
[Index
]) {
1419 Private
->BmmFakeNvData
.BootOptionDel
[Index
] = FALSE
;
1420 Private
->BmmOldFakeNVData
.BootOptionDel
[Index
] = FALSE
;
1425 if (Private
->BmmPreviousPageId
!= FORM_DRV_DEL_ID
) {
1426 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1427 if (Private
->BmmFakeNvData
.DriverOptionDel
[Index
] && !Private
->BmmFakeNvData
.DriverOptionDelMark
[Index
]) {
1428 Private
->BmmFakeNvData
.DriverOptionDel
[Index
] = FALSE
;
1429 Private
->BmmOldFakeNVData
.DriverOptionDel
[Index
] = FALSE
;
1437 Update the menus in the BMM page.
1445 VOID
*StartOpCodeHandle
;
1446 VOID
*EndOpCodeHandle
;
1447 EFI_IFR_GUID_LABEL
*StartGuidLabel
;
1448 EFI_IFR_GUID_LABEL
*EndGuidLabel
;
1451 // Allocate space for creation of UpdateData Buffer
1453 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1454 ASSERT (StartOpCodeHandle
!= NULL
);
1456 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1457 ASSERT (EndOpCodeHandle
!= NULL
);
1459 // Create Hii Extend Label OpCode as the start opcode
1461 StartGuidLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1462 StartGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1463 StartGuidLabel
->Number
= LABEL_FORM_MAIN_START
;
1465 // Create Hii Extend Label OpCode as the end opcode
1467 EndGuidLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1468 EndGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1469 EndGuidLabel
->Number
= LABEL_FORM_MAIN_END
;
1472 // Updata Front Page form
1474 UiCustomizeBMMPage (
1475 mBmmCallbackInfo
->BmmHiiHandle
,
1480 mBmmCallbackInfo
->BmmHiiHandle
,
1487 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1488 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1492 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
1493 BmmOldFakeNVData member in BMM context data.
1495 @param CallbackData The BMM context data.
1499 InitializeBmmConfig (
1500 IN BMM_CALLBACK_DATA
*CallbackData
1503 BM_MENU_ENTRY
*NewMenuEntry
;
1504 BM_LOAD_CONTEXT
*NewLoadContext
;
1507 ASSERT (CallbackData
!= NULL
);
1510 // Initialize data which located in BMM main page
1512 CallbackData
->BmmFakeNvData
.BootNext
= NONE_BOOTNEXT_VALUE
;
1513 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1514 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
1515 NewLoadContext
= (BM_LOAD_CONTEXT
*)NewMenuEntry
->VariableContext
;
1517 if (NewLoadContext
->IsBootNext
) {
1518 CallbackData
->BmmFakeNvData
.BootNext
= Index
;
1523 CallbackData
->BmmFakeNvData
.BootTimeOut
= PcdGet16 (PcdPlatformBootTimeOut
);
1526 // Initialize data which located in Boot Options Menu
1528 GetBootOrder (CallbackData
);
1531 // Initialize data which located in Driver Options Menu
1533 GetDriverOrder (CallbackData
);
1536 // Initialize data which located in Console Options Menu
1538 GetConsoleOutMode (CallbackData
);
1539 GetConsoleInCheck (CallbackData
);
1540 GetConsoleOutCheck (CallbackData
);
1541 GetConsoleErrCheck (CallbackData
);
1542 GetTerminalAttribute (CallbackData
);
1544 CallbackData
->BmmFakeNvData
.ForceReconnect
= TRUE
;
1547 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
1549 CopyMem (&CallbackData
->BmmOldFakeNVData
, &CallbackData
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
1553 Initialized all Menu Option List.
1555 @param CallbackData The BMM context data.
1560 IN BMM_CALLBACK_DATA
*CallbackData
1563 InitializeListHead (&BootOptionMenu
.Head
);
1564 InitializeListHead (&DriverOptionMenu
.Head
);
1565 BOpt_GetBootOptions (CallbackData
);
1566 BOpt_GetDriverOptions (CallbackData
);
1567 BOpt_FindDrivers ();
1568 InitializeListHead (&ConsoleInpMenu
.Head
);
1569 InitializeListHead (&ConsoleOutMenu
.Head
);
1570 InitializeListHead (&ConsoleErrMenu
.Head
);
1571 InitializeListHead (&TerminalMenu
.Head
);
1574 mAllMenuInit
= TRUE
;
1578 Free up all Menu Option list.
1586 if (!mAllMenuInit
) {
1590 BOpt_FreeMenu (&BootOptionMenu
);
1591 BOpt_FreeMenu (&DriverOptionMenu
);
1592 BOpt_FreeMenu (&DriverMenu
);
1594 mAllMenuInit
= FALSE
;
1598 Initial the boot mode related parameters.
1602 BmmInitialBootModeInfo (
1607 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1608 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1609 UINTN BootTextColumn
;
1612 if (mBmmModeInitialized
) {
1617 // After the console is ready, get current video resolution
1618 // and text mode before launching setup at first time.
1620 Status
= gBS
->HandleProtocol (
1621 gST
->ConsoleOutHandle
,
1622 &gEfiGraphicsOutputProtocolGuid
,
1623 (VOID
**)&GraphicsOutput
1625 if (EFI_ERROR (Status
)) {
1626 GraphicsOutput
= NULL
;
1629 Status
= gBS
->HandleProtocol (
1630 gST
->ConsoleOutHandle
,
1631 &gEfiSimpleTextOutProtocolGuid
,
1632 (VOID
**)&SimpleTextOut
1634 if (EFI_ERROR (Status
)) {
1635 SimpleTextOut
= NULL
;
1638 if (GraphicsOutput
!= NULL
) {
1640 // Get current video resolution and text mode.
1642 mBmmBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1643 mBmmBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1646 if (SimpleTextOut
!= NULL
) {
1647 Status
= SimpleTextOut
->QueryMode (
1649 SimpleTextOut
->Mode
->Mode
,
1653 mBmmBootTextModeColumn
= (UINT32
)BootTextColumn
;
1654 mBmmBootTextModeRow
= (UINT32
)BootTextRow
;
1658 // Get user defined text mode for setup.
1660 mBmmSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1661 mBmmSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1662 mBmmSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1663 mBmmSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1665 mBmmModeInitialized
= TRUE
;
1670 Install Boot Maintenance Manager Menu driver.
1672 @param ImageHandle The image handle.
1673 @param SystemTable The system table.
1675 @retval EFI_SUCEESS Install Boot manager menu success.
1676 @retval Other Return error status.
1681 BootMaintenanceManagerUiLibConstructor (
1682 IN EFI_HANDLE ImageHandle
,
1683 IN EFI_SYSTEM_TABLE
*SystemTable
1690 Status
= EFI_SUCCESS
;
1693 // Install Device Path Protocol and Config Access protocol to driver handle
1695 Status
= gBS
->InstallMultipleProtocolInterfaces (
1696 &mBmmCallbackInfo
->BmmDriverHandle
,
1697 &gEfiDevicePathProtocolGuid
,
1698 &mBmmHiiVendorDevicePath
,
1699 &gEfiHiiConfigAccessProtocolGuid
,
1700 &mBmmCallbackInfo
->BmmConfigAccess
,
1703 ASSERT_EFI_ERROR (Status
);
1706 // Post our Boot Maint VFR binary to the HII database.
1708 mBmmCallbackInfo
->BmmHiiHandle
= HiiAddPackages (
1710 mBmmCallbackInfo
->BmmDriverHandle
,
1711 BootMaintenanceManagerBin
,
1712 BootMaintenanceManagerUiLibStrings
,
1715 ASSERT (mBmmCallbackInfo
->BmmHiiHandle
!= NULL
);
1718 // Locate Formbrowser2 protocol
1720 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**)&mBmmCallbackInfo
->FormBrowser2
);
1721 ASSERT_EFI_ERROR (Status
);
1724 // Create LoadOption in BmmCallbackInfo for Driver Callback
1726 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
1727 ASSERT (Ptr
!= NULL
);
1730 // Initialize Bmm callback data.
1732 mBmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*)Ptr
;
1733 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
1735 mBmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*)Ptr
;
1736 Ptr
+= sizeof (BM_FILE_CONTEXT
);
1738 mBmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*)Ptr
;
1739 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
1741 mBmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*)Ptr
;
1743 mBmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
1744 mBmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
1746 InitAllMenu (mBmmCallbackInfo
);
1748 CreateUpdateData ();
1750 // Update boot maintenance manager page
1752 InitializeBmmConfig (mBmmCallbackInfo
);
1754 BmmInitialBootModeInfo ();
1760 Unloads the application and its installed protocol.
1762 @param ImageHandle Handle that identifies the image to be unloaded.
1763 @param SystemTable The system table.
1765 @retval EFI_SUCCESS The image has been unloaded.
1770 BootMaintenanceManagerUiLibDestructor (
1771 IN EFI_HANDLE ImageHandle
,
1772 IN EFI_SYSTEM_TABLE
*SystemTable
1776 if (mStartOpCodeHandle
!= NULL
) {
1777 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
1780 if (mEndOpCodeHandle
!= NULL
) {
1781 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1787 // Remove our IFR data from HII database
1789 HiiRemovePackages (mBmmCallbackInfo
->BmmHiiHandle
);
1791 gBS
->UninstallMultipleProtocolInterfaces (
1792 mBmmCallbackInfo
->BmmDriverHandle
,
1793 &gEfiDevicePathProtocolGuid
,
1794 &mBmmHiiVendorDevicePath
,
1795 &gEfiHiiConfigAccessProtocolGuid
,
1796 &mBmmCallbackInfo
->BmmConfigAccess
,
1800 FreePool (mBmmCallbackInfo
->LoadContext
);
1801 mBmmCallbackInfo
->BmmDriverHandle
= NULL
;