2 The functions for Boot Maintainence Main menu.
4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootMaintenanceManager.h"
17 #define FRONT_PAGE_KEY_OFFSET 0x4000
19 // Boot video resolution and text mode.
21 UINT32 mBmmBootHorizontalResolution
= 0;
22 UINT32 mBmmBootVerticalResolution
= 0;
23 UINT32 mBmmBootTextModeColumn
= 0;
24 UINT32 mBmmBootTextModeRow
= 0;
26 // BIOS setup video resolution and text mode.
28 UINT32 mBmmSetupTextModeColumn
= 0;
29 UINT32 mBmmSetupTextModeRow
= 0;
30 UINT32 mBmmSetupHorizontalResolution
= 0;
31 UINT32 mBmmSetupVerticalResolution
= 0;
33 BOOLEAN mBmmModeInitialized
= FALSE
;
35 EFI_DEVICE_PATH_PROTOCOL EndDevicePath
[] = {
38 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
40 END_DEVICE_PATH_LENGTH
,
46 HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath
= {
52 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
53 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
57 // {165A028F-0BB2-4b5f-8747-77592E3F6499}
59 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 } }
63 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
65 (UINT8
) (END_DEVICE_PATH_LENGTH
),
66 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
71 EFI_GUID mBootMaintGuid
= BOOT_MAINT_FORMSET_GUID
;
73 CHAR16 mBootMaintStorageName
[] = L
"BmmData";
74 BMM_CALLBACK_DATA gBootMaintenancePrivate
= {
75 BMM_CALLBACK_DATA_SIGNATURE
,
79 BootMaintExtractConfig
,
85 BMM_CALLBACK_DATA
*mBmmCallbackInfo
= &gBootMaintenancePrivate
;
86 BOOLEAN mAllMenuInit
= FALSE
;
87 BOOLEAN mFirstEnterBMMForm
= FALSE
;
92 @param CallbackData The BMM context data.
97 IN BMM_CALLBACK_DATA
*CallbackData
101 Free up all Menu Option list.
111 Update the menus in the BMM page.
120 This function will change video resolution and text mode
121 according to defined setup mode or defined boot mode
123 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
125 @retval EFI_SUCCESS Mode is changed successfully.
126 @retval Others Mode failed to be changed.
134 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
135 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
137 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
141 UINT32 NewHorizontalResolution
;
142 UINT32 NewVerticalResolution
;
146 EFI_HANDLE
*HandleBuffer
;
156 // Get current video resolution and text mode
158 Status
= gBS
->HandleProtocol (
159 gST
->ConsoleOutHandle
,
160 &gEfiGraphicsOutputProtocolGuid
,
161 (VOID
**)&GraphicsOutput
163 if (EFI_ERROR (Status
)) {
164 GraphicsOutput
= NULL
;
167 Status
= gBS
->HandleProtocol (
168 gST
->ConsoleOutHandle
,
169 &gEfiSimpleTextOutProtocolGuid
,
170 (VOID
**)&SimpleTextOut
172 if (EFI_ERROR (Status
)) {
173 SimpleTextOut
= NULL
;
176 if ((GraphicsOutput
== NULL
) || (SimpleTextOut
== NULL
)) {
177 return EFI_UNSUPPORTED
;
182 // The required resolution and text mode is setup mode.
184 NewHorizontalResolution
= mBmmSetupHorizontalResolution
;
185 NewVerticalResolution
= mBmmSetupVerticalResolution
;
186 NewColumns
= mBmmSetupTextModeColumn
;
187 NewRows
= mBmmSetupTextModeRow
;
190 // The required resolution and text mode is boot mode.
192 NewHorizontalResolution
= mBmmBootHorizontalResolution
;
193 NewVerticalResolution
= mBmmBootVerticalResolution
;
194 NewColumns
= mBmmBootTextModeColumn
;
195 NewRows
= mBmmBootTextModeRow
;
198 if (GraphicsOutput
!= NULL
) {
199 MaxGopMode
= GraphicsOutput
->Mode
->MaxMode
;
202 if (SimpleTextOut
!= NULL
) {
203 MaxTextMode
= SimpleTextOut
->Mode
->MaxMode
;
207 // 1. If current video resolution is same with required video resolution,
208 // video resolution need not be changed.
209 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
210 // 1.2. If current text mode is different from required text mode, text mode need be changed.
211 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
213 for (ModeNumber
= 0; ModeNumber
< MaxGopMode
; ModeNumber
++) {
214 Status
= GraphicsOutput
->QueryMode (
220 if (!EFI_ERROR (Status
)) {
221 if ((Info
->HorizontalResolution
== NewHorizontalResolution
) &&
222 (Info
->VerticalResolution
== NewVerticalResolution
)) {
223 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== NewHorizontalResolution
) &&
224 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== NewVerticalResolution
)) {
226 // Current resolution is same with required resolution, check if text mode need be set
228 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, SimpleTextOut
->Mode
->Mode
, &CurrentColumn
, &CurrentRow
);
229 ASSERT_EFI_ERROR (Status
);
230 if (CurrentColumn
== NewColumns
&& CurrentRow
== NewRows
) {
232 // If current text mode is same with required text mode. Do nothing
238 // If current text mode is different from required text mode. Set new video mode
240 for (Index
= 0; Index
< MaxTextMode
; Index
++) {
241 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, Index
, &CurrentColumn
, &CurrentRow
);
242 if (!EFI_ERROR(Status
)) {
243 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
245 // Required text mode is supported, set it.
247 Status
= SimpleTextOut
->SetMode (SimpleTextOut
, Index
);
248 ASSERT_EFI_ERROR (Status
);
250 // Update text mode PCD.
252 Status
= PcdSet32S (PcdConOutColumn
, mBmmSetupTextModeColumn
);
253 ASSERT_EFI_ERROR (Status
);
254 Status
= PcdSet32S (PcdConOutRow
, mBmmSetupTextModeRow
);
255 ASSERT_EFI_ERROR (Status
);
261 if (Index
== MaxTextMode
) {
263 // If required text mode is not supported, return error.
266 return EFI_UNSUPPORTED
;
271 // If current video resolution is not same with the new one, set new video resolution.
272 // In this case, the driver which produces simple text out need be restarted.
274 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
275 if (!EFI_ERROR (Status
)) {
285 if (ModeNumber
== MaxGopMode
) {
287 // If the resolution is not supported, return error.
289 return EFI_UNSUPPORTED
;
293 // Set PCD to Inform GraphicsConsole to change video resolution.
294 // Set PCD to Inform Consplitter to change text mode.
296 Status
= PcdSet32S (PcdVideoHorizontalResolution
, NewHorizontalResolution
);
297 ASSERT_EFI_ERROR (Status
);
298 Status
= PcdSet32S (PcdVideoVerticalResolution
, NewVerticalResolution
);
299 ASSERT_EFI_ERROR (Status
);
300 Status
= PcdSet32S (PcdConOutColumn
, NewColumns
);
301 ASSERT_EFI_ERROR (Status
);
302 Status
= PcdSet32S (PcdConOutRow
, NewRows
);
303 ASSERT_EFI_ERROR (Status
);
306 // Video mode is changed, so restart graphics console driver and higher level driver.
307 // Reconnect graphics console driver and higher level driver.
308 // Locate all the handles with GOP protocol and reconnect it.
310 Status
= gBS
->LocateHandleBuffer (
312 &gEfiSimpleTextOutProtocolGuid
,
317 if (!EFI_ERROR (Status
)) {
318 for (Index
= 0; Index
< HandleCount
; Index
++) {
319 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
321 for (Index
= 0; Index
< HandleCount
; Index
++) {
322 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
324 if (HandleBuffer
!= NULL
) {
325 FreePool (HandleBuffer
);
333 This function converts an input device structure to a Unicode string.
335 @param DevPath A pointer to the device path structure.
337 @return A new allocated Unicode string that represents the device path.
342 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
347 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
349 if (DevPath
== NULL
) {
353 Status
= gBS
->LocateProtocol (
354 &gEfiDevicePathToTextProtocolGuid
,
356 (VOID
**) &DevPathToText
358 ASSERT_EFI_ERROR (Status
);
359 ToText
= DevPathToText
->ConvertDevicePathToText (
364 ASSERT (ToText
!= NULL
);
369 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
370 The caller is responsible for freeing the allocated buffer using FreePool().
372 @param DevicePath Device path.
374 @return A new allocated string that represents the file name.
378 ExtractFileNameFromDevicePath (
379 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
388 ASSERT(DevicePath
!= NULL
);
390 String
= UiDevicePathToStr(DevicePath
);
391 MatchString
= String
;
395 while(MatchString
!= NULL
){
396 LastMatch
= MatchString
+ 1;
397 MatchString
= StrStr(LastMatch
,L
"\\");
400 Length
= StrLen(LastMatch
);
401 FileName
= AllocateCopyPool ((Length
+ 1) * sizeof(CHAR16
), LastMatch
);
402 if (FileName
!= NULL
) {
403 *(FileName
+ Length
) = 0;
412 Extract device path for given HII handle and class guid.
414 @param Handle The HII handle.
416 @retval NULL Fail to get the device path string.
417 @return PathString Get the device path string.
421 BmmExtractDevicePathFromHiiHandle (
422 IN EFI_HII_HANDLE Handle
426 EFI_HANDLE DriverHandle
;
428 ASSERT (Handle
!= NULL
);
430 if (Handle
== NULL
) {
434 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
435 if (EFI_ERROR (Status
)) {
440 // Get device path string.
442 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
];
596 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
597 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
598 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
599 ASSERT (Index
+ ConsoleInpMenu
.MenuNumber
< MAX_MENU_NUMBER
);
600 NewTerminalContext
->IsConIn
= BmmData
->ConsoleInCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
604 if (StrCmp (ConsoleName
, L
"ConOut") == 0) {
605 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++){
606 NewMenuEntry
= BOpt_GetMenuEntry(&ConsoleOutMenu
, Index
);
607 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
608 ASSERT (Index
< MAX_MENU_NUMBER
);
609 NewConsoleContext
->IsActive
= BmmData
->ConsoleOutCheck
[Index
];
611 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
612 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
613 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
614 ASSERT (Index
+ ConsoleOutMenu
.MenuNumber
< MAX_MENU_NUMBER
);
615 NewTerminalContext
->IsConOut
= BmmData
->ConsoleOutCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
618 if (StrCmp (ConsoleName
, L
"ErrOut") == 0) {
619 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++){
620 NewMenuEntry
= BOpt_GetMenuEntry(&ConsoleErrMenu
, Index
);
621 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
622 ASSERT (Index
< MAX_MENU_NUMBER
);
623 NewConsoleContext
->IsActive
= BmmData
->ConsoleErrCheck
[Index
];
625 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
626 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
627 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
628 ASSERT (Index
+ ConsoleErrMenu
.MenuNumber
< MAX_MENU_NUMBER
);
629 NewTerminalContext
->IsStdErr
= BmmData
->ConsoleErrCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
635 This function allows a caller to extract the current configuration for one
636 or more named elements from the target driver.
638 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
639 @param Request A null-terminated Unicode string in <ConfigRequest> format.
640 @param Progress On return, points to a character in the Request string.
641 Points to the string's null terminator if request was successful.
642 Points to the most recent '&' before the first failing name/value
643 pair (or the beginning of the string if the failure is in the
644 first name/value pair) if the request was not successful.
645 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
646 has all values filled in for the names in the Request string.
647 String to be allocated by the called function.
649 @retval EFI_SUCCESS The Results is filled with the requested values.
650 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
651 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
652 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
657 BootMaintExtractConfig (
658 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
659 IN CONST EFI_STRING Request
,
660 OUT EFI_STRING
*Progress
,
661 OUT EFI_STRING
*Results
666 BMM_CALLBACK_DATA
*Private
;
667 EFI_STRING ConfigRequestHdr
;
668 EFI_STRING ConfigRequest
;
669 BOOLEAN AllocatedRequest
;
672 if (Progress
== NULL
|| Results
== NULL
) {
673 return EFI_INVALID_PARAMETER
;
677 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &mBootMaintGuid
, mBootMaintStorageName
)) {
678 return EFI_NOT_FOUND
;
681 ConfigRequestHdr
= NULL
;
682 ConfigRequest
= NULL
;
683 AllocatedRequest
= FALSE
;
686 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
688 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
690 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
691 ConfigRequest
= Request
;
692 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
694 // Request has no request element, construct full request string.
695 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
696 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
698 ConfigRequestHdr
= HiiConstructConfigHdr (&mBootMaintGuid
, mBootMaintStorageName
, Private
->BmmDriverHandle
);
699 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
700 ConfigRequest
= AllocateZeroPool (Size
);
701 ASSERT (ConfigRequest
!= NULL
);
702 AllocatedRequest
= TRUE
;
703 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
704 FreePool (ConfigRequestHdr
);
707 Status
= gHiiConfigRouting
->BlockToConfig (
710 (UINT8
*) &Private
->BmmFakeNvData
,
716 // Free the allocated config request string.
718 if (AllocatedRequest
) {
719 FreePool (ConfigRequest
);
720 ConfigRequest
= NULL
;
723 // Set Progress string to the original request string.
725 if (Request
== NULL
) {
727 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
728 *Progress
= Request
+ StrLen (Request
);
735 This function applies changes in a driver's configuration.
736 Input is a Configuration, which has the routing data for this
737 driver followed by name / value configuration pairs. The driver
738 must apply those pairs to its configurable storage. If the
739 driver's configuration is stored in a linear block of data
740 and the driver's name / value pairs are in <BlockConfig>
741 format, it may use the ConfigToBlock helper function (above) to
742 simplify the job. Currently not implemented.
744 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
745 @param[in] Configuration A null-terminated Unicode string in
746 <ConfigString> format.
747 @param[out] Progress A pointer to a string filled in with the
748 offset of the most recent '&' before the
749 first failing name / value pair (or the
750 beginn ing of the string if the failure
751 is in the first name / value pair) or
752 the terminating NULL if all was
755 @retval EFI_SUCCESS The results have been distributed or are
756 awaiting distribution.
757 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
758 parts of the results that must be
759 stored awaiting possible future
761 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
762 Results parameter would result
763 in this type of error.
764 @retval EFI_NOT_FOUND Target for the specified routing data
769 BootMaintRouteConfig (
770 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
771 IN CONST EFI_STRING Configuration
,
772 OUT EFI_STRING
*Progress
777 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
778 BMM_FAKE_NV_DATA
*NewBmmData
;
779 BMM_FAKE_NV_DATA
*OldBmmData
;
780 BM_MENU_ENTRY
*NewMenuEntry
;
781 BM_LOAD_CONTEXT
*NewLoadContext
;
783 BOOLEAN TerminalAttChange
;
784 BMM_CALLBACK_DATA
*Private
;
787 if (Progress
== NULL
) {
788 return EFI_INVALID_PARAMETER
;
790 *Progress
= Configuration
;
792 if (Configuration
== NULL
) {
793 return EFI_INVALID_PARAMETER
;
797 // Check routing data in <ConfigHdr>.
798 // Note: there is no name for Name/Value storage, only GUID will be checked
800 if (!HiiIsConfigHdrMatch (Configuration
, &mBootMaintGuid
, mBootMaintStorageName
)) {
801 return EFI_NOT_FOUND
;
804 Status
= gBS
->LocateProtocol (
805 &gEfiHiiConfigRoutingProtocolGuid
,
807 (VOID
**)&ConfigRouting
809 if (EFI_ERROR (Status
)) {
813 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
815 // Get Buffer Storage data from EFI variable
817 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
818 OldBmmData
= &Private
->BmmOldFakeNVData
;
819 NewBmmData
= &Private
->BmmFakeNvData
;
822 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
824 Status
= ConfigRouting
->ConfigToBlock (
827 (UINT8
*) NewBmmData
,
831 ASSERT_EFI_ERROR (Status
);
833 // Compare new and old BMM configuration data and only do action for modified item to
834 // avoid setting unnecessary non-volatile variable
838 // Check data which located in BMM main page and save the settings if need
840 if (CompareMem (&NewBmmData
->BootNext
, &OldBmmData
->BootNext
, sizeof (NewBmmData
->BootNext
)) != 0) {
841 Status
= Var_UpdateBootNext (Private
);
842 if (EFI_ERROR (Status
)) {
843 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootNext
);
849 // Check data which located in Boot Options Menu and save the settings if need
851 if (CompareMem (NewBmmData
->BootOptionDel
, OldBmmData
->BootOptionDel
, sizeof (NewBmmData
->BootOptionDel
)) != 0) {
853 ((Index
< BootOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->BootOptionDel
) / sizeof (NewBmmData
->BootOptionDel
[0]))));
855 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
856 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
857 NewLoadContext
->Deleted
= NewBmmData
->BootOptionDel
[Index
];
858 NewBmmData
->BootOptionDel
[Index
] = FALSE
;
859 NewBmmData
->BootOptionDelMark
[Index
] = FALSE
;
862 Status
= Var_DelBootOption ();
863 if (EFI_ERROR (Status
)) {
864 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionDel
);
869 if (CompareMem (NewBmmData
->BootOptionOrder
, OldBmmData
->BootOptionOrder
, sizeof (NewBmmData
->BootOptionOrder
)) != 0) {
870 Status
= Var_UpdateBootOrder (Private
);
871 if (EFI_ERROR (Status
)) {
872 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionOrder
);
877 if (CompareMem (&NewBmmData
->BootTimeOut
, &OldBmmData
->BootTimeOut
, sizeof (NewBmmData
->BootTimeOut
)) != 0){
878 Status
= gRT
->SetVariable(
880 &gEfiGlobalVariableGuid
,
881 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
883 &(NewBmmData
->BootTimeOut
)
885 if (EFI_ERROR (Status
)) {
886 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootTimeOut
);
889 Private
->BmmOldFakeNVData
.BootTimeOut
= NewBmmData
->BootTimeOut
;
893 // Check data which located in Driver Options Menu and save the settings if need
895 if (CompareMem (NewBmmData
->DriverOptionDel
, OldBmmData
->DriverOptionDel
, sizeof (NewBmmData
->DriverOptionDel
)) != 0) {
897 ((Index
< DriverOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->DriverOptionDel
) / sizeof (NewBmmData
->DriverOptionDel
[0]))));
899 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
900 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
901 NewLoadContext
->Deleted
= NewBmmData
->DriverOptionDel
[Index
];
902 NewBmmData
->DriverOptionDel
[Index
] = FALSE
;
903 NewBmmData
->DriverOptionDelMark
[Index
] = FALSE
;
905 Status
= Var_DelDriverOption ();
906 if (EFI_ERROR (Status
)) {
907 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionDel
);
912 if (CompareMem (NewBmmData
->DriverOptionOrder
, OldBmmData
->DriverOptionOrder
, sizeof (NewBmmData
->DriverOptionOrder
)) != 0) {
913 Status
= Var_UpdateDriverOrder (Private
);
914 if (EFI_ERROR (Status
)) {
915 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionOrder
);
920 if (CompareMem (&NewBmmData
->ConsoleOutMode
, &OldBmmData
->ConsoleOutMode
, sizeof (NewBmmData
->ConsoleOutMode
)) != 0){
921 Status
= Var_UpdateConMode(Private
);
922 if (EFI_ERROR (Status
)) {
923 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleOutMode
);
928 TerminalAttChange
= FALSE
;
929 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
932 // only need update modified items
934 if (CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) == 0 &&
935 CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) == 0 &&
936 CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) == 0 &&
937 CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) == 0 &&
938 CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) == 0 &&
939 CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) == 0) {
943 TerminalAttChange
= TRUE
;
945 if (TerminalAttChange
) {
946 if (CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) != 0) {
947 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMBaudRate
);
948 } else if (CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) != 0) {
949 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMDataRate
);
950 } else if (CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) != 0) {
951 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMStopBits
);
952 } else if (CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) != 0) {
953 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMParity
);
954 } else if (CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) != 0) {
955 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMTerminalType
);
956 } else if (CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) != 0) {
957 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, COMFlowControl
);
959 Status
= Var_UpdateConsoleInpOption ();
960 if (EFI_ERROR (Status
)) {
963 Status
= Var_UpdateConsoleOutOption ();
964 if (EFI_ERROR (Status
)) {
967 Status
= Var_UpdateErrorOutOption ();
968 if (EFI_ERROR (Status
)) {
973 // Check data which located in Console Options Menu and save the settings if need
975 if (CompareMem (NewBmmData
->ConsoleInCheck
, OldBmmData
->ConsoleInCheck
, sizeof (NewBmmData
->ConsoleInCheck
)) != 0){
976 Status
= Var_UpdateConsoleInpOption();
977 if (EFI_ERROR (Status
)) {
978 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleInCheck
);
983 if (CompareMem (NewBmmData
->ConsoleOutCheck
, OldBmmData
->ConsoleOutCheck
, sizeof (NewBmmData
->ConsoleOutCheck
)) != 0){
984 Status
= Var_UpdateConsoleOutOption();
985 if (EFI_ERROR (Status
)) {
986 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleOutCheck
);
991 if (CompareMem (NewBmmData
->ConsoleErrCheck
, OldBmmData
->ConsoleErrCheck
, sizeof (NewBmmData
->ConsoleErrCheck
)) != 0){
992 Status
= Var_UpdateErrorOutOption();
993 if (EFI_ERROR (Status
)) {
994 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, ConsoleErrCheck
);
999 if (CompareMem (NewBmmData
->BootDescriptionData
, OldBmmData
->BootDescriptionData
, sizeof (NewBmmData
->BootDescriptionData
)) != 0 ||
1000 CompareMem (NewBmmData
->BootOptionalData
, OldBmmData
->BootOptionalData
, sizeof (NewBmmData
->BootOptionalData
)) != 0) {
1001 Status
= Var_UpdateBootOption (Private
);
1002 NewBmmData
->BootOptionChanged
= FALSE
;
1003 if (EFI_ERROR (Status
)) {
1004 if (CompareMem (NewBmmData
->BootDescriptionData
, OldBmmData
->BootDescriptionData
, sizeof (NewBmmData
->BootDescriptionData
)) != 0) {
1005 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootDescriptionData
);
1007 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, BootOptionalData
);
1011 BOpt_GetBootOptions (Private
);
1014 if (CompareMem (NewBmmData
->DriverDescriptionData
, OldBmmData
->DriverDescriptionData
, sizeof (NewBmmData
->DriverDescriptionData
)) != 0 ||
1015 CompareMem (NewBmmData
->DriverOptionalData
, OldBmmData
->DriverOptionalData
, sizeof (NewBmmData
->DriverOptionalData
)) != 0) {
1016 Status
= Var_UpdateDriverOption (
1018 Private
->BmmHiiHandle
,
1019 NewBmmData
->DriverDescriptionData
,
1020 NewBmmData
->DriverOptionalData
,
1021 NewBmmData
->ForceReconnect
1023 NewBmmData
->DriverOptionChanged
= FALSE
;
1024 NewBmmData
->ForceReconnect
= TRUE
;
1025 if (EFI_ERROR (Status
)) {
1026 if (CompareMem (NewBmmData
->DriverDescriptionData
, OldBmmData
->DriverDescriptionData
, sizeof (NewBmmData
->DriverDescriptionData
)) != 0) {
1027 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverDescriptionData
);
1029 Offset
= OFFSET_OF (BMM_FAKE_NV_DATA
, DriverOptionalData
);
1034 BOpt_GetDriverOptions (Private
);
1038 // After user do the save action, need to update OldBmmData.
1040 CopyMem (OldBmmData
, NewBmmData
, sizeof (BMM_FAKE_NV_DATA
));
1046 // Fail to save the data, update the progress string.
1048 *Progress
= UpdateProgress (Offset
, Configuration
);
1049 if (Status
== EFI_OUT_OF_RESOURCES
) {
1052 return EFI_NOT_FOUND
;
1057 This function processes the results of changes in configuration.
1060 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1061 @param Action Specifies the type of action taken by the browser.
1062 @param QuestionId A unique value which is sent to the original exporting driver
1063 so that it can identify the type of data to expect.
1064 @param Type The type of value for the question.
1065 @param Value A pointer to the data being sent to the original exporting driver.
1066 @param ActionRequest On return, points to the action requested by the callback function.
1068 @retval EFI_SUCCESS The callback successfully handled the action.
1069 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
1070 @retval EFI_DEVICE_ERROR The variable could not be saved.
1071 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
1072 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
1077 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1078 IN EFI_BROWSER_ACTION Action
,
1079 IN EFI_QUESTION_ID QuestionId
,
1081 IN EFI_IFR_TYPE_VALUE
*Value
,
1082 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1085 BMM_CALLBACK_DATA
*Private
;
1086 BM_MENU_ENTRY
*NewMenuEntry
;
1087 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1088 BMM_FAKE_NV_DATA
*OldFakeNVMap
;
1090 EFI_DEVICE_PATH_PROTOCOL
* File
;
1092 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
&& Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) {
1094 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
1096 return EFI_UNSUPPORTED
;
1099 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
1101 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
1102 if (QuestionId
== KEY_VALUE_TRIGGER_FORM_OPEN_ACTION
) {
1103 if (!mFirstEnterBMMForm
) {
1105 // BMMUiLib depends on LegacyUi library to show legacy menus.
1106 // If we want to show Legacy menus correctly in BMM page,
1107 // we must do it after the LegacyUi library has already been initialized.
1108 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
1109 // So we do the tasks which are related to legacy menus here.
1110 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
1111 // 2. Re-scan the BootOption menus (including the legacy boot option).
1114 BOpt_GetBootOptions (Private
);
1115 mFirstEnterBMMForm
= TRUE
;
1120 // Retrieve uncommitted data from Form Browser
1122 CurrentFakeNVMap
= &Private
->BmmFakeNvData
;
1123 OldFakeNVMap
= &Private
->BmmOldFakeNVData
;
1124 HiiGetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
);
1126 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1127 if (Value
== NULL
) {
1128 return EFI_INVALID_PARAMETER
;
1131 UpdatePageId (Private
, QuestionId
);
1133 if (QuestionId
< FILE_OPTION_OFFSET
) {
1134 if (QuestionId
< CONFIG_OPTION_OFFSET
) {
1135 switch (QuestionId
) {
1136 case FORM_BOOT_ADD_ID
:
1137 // Leave BMM and enter FileExplorer.
1138 ChooseFile (NULL
, L
".efi", CreateBootOptionFromFile
, &File
);
1141 case FORM_DRV_ADD_FILE_ID
:
1142 // Leave BMM and enter FileExplorer.
1143 ChooseFile (NULL
, L
".efi", CreateDriverOptionFromFile
, &File
);
1146 case FORM_DRV_ADD_HANDLE_ID
:
1147 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
1148 UpdateDrvAddHandlePage (Private
);
1151 case FORM_BOOT_DEL_ID
:
1152 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
1153 UpdateBootDelPage (Private
);
1156 case FORM_BOOT_CHG_ID
:
1157 case FORM_DRV_CHG_ID
:
1158 UpdatePageBody (QuestionId
, Private
);
1161 case FORM_DRV_DEL_ID
:
1162 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
1163 UpdateDrvDelPage (Private
);
1166 case FORM_CON_IN_ID
:
1167 case FORM_CON_OUT_ID
:
1168 case FORM_CON_ERR_ID
:
1169 UpdatePageBody (QuestionId
, Private
);
1172 case FORM_CON_MODE_ID
:
1173 CleanUpPage (FORM_CON_MODE_ID
, Private
);
1174 UpdateConModePage (Private
);
1177 case FORM_CON_COM_ID
:
1178 CleanUpPage (FORM_CON_COM_ID
, Private
);
1179 UpdateConCOMPage (Private
);
1185 } else if ((QuestionId
>= TERMINAL_OPTION_OFFSET
) && (QuestionId
< CONSOLE_OPTION_OFFSET
)) {
1186 Index
= (UINT16
) (QuestionId
- TERMINAL_OPTION_OFFSET
);
1187 Private
->CurrentTerminal
= Index
;
1189 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
1190 UpdateTerminalPage (Private
);
1192 } else if (QuestionId
>= HANDLE_OPTION_OFFSET
) {
1193 Index
= (UINT16
) (QuestionId
- HANDLE_OPTION_OFFSET
);
1195 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index
);
1196 ASSERT (NewMenuEntry
!= NULL
);
1197 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1199 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
1201 Private
->MenuEntry
= NewMenuEntry
;
1202 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
1204 UpdateDriverAddHandleDescPage (Private
);
1207 if (QuestionId
== KEY_VALUE_BOOT_FROM_FILE
){
1208 // Leave BMM and enter FileExplorer.
1209 ChooseFile (NULL
, L
".efi", BootFromFile
, &File
);
1211 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1212 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1213 return EFI_INVALID_PARAMETER
;
1216 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_BOOT
) {
1217 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1218 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1219 } else if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_DRIVER
) {
1220 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1221 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1222 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER
) {
1224 // Discard changes and exit formset
1226 ZeroMem (CurrentFakeNVMap
->DriverOptionalData
, sizeof (CurrentFakeNVMap
->DriverOptionalData
));
1227 ZeroMem (CurrentFakeNVMap
->BootDescriptionData
, sizeof (CurrentFakeNVMap
->BootDescriptionData
));
1228 ZeroMem (OldFakeNVMap
->DriverOptionalData
, sizeof (OldFakeNVMap
->DriverOptionalData
));
1229 ZeroMem (OldFakeNVMap
->DriverDescriptionData
, sizeof (OldFakeNVMap
->DriverDescriptionData
));
1230 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1231 CurrentFakeNVMap
->ForceReconnect
= TRUE
;
1232 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1233 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_BOOT
) {
1235 // Discard changes and exit formset
1237 ZeroMem (CurrentFakeNVMap
->BootOptionalData
, sizeof (CurrentFakeNVMap
->BootOptionalData
));
1238 ZeroMem (CurrentFakeNVMap
->BootDescriptionData
, sizeof (CurrentFakeNVMap
->BootDescriptionData
));
1239 ZeroMem (OldFakeNVMap
->BootOptionalData
, sizeof (OldFakeNVMap
->BootOptionalData
));
1240 ZeroMem (OldFakeNVMap
->BootDescriptionData
, sizeof (OldFakeNVMap
->BootDescriptionData
));
1241 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1242 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1243 } else if (QuestionId
== KEY_VALUE_BOOT_DESCRIPTION
|| QuestionId
== KEY_VALUE_BOOT_OPTION
) {
1244 CurrentFakeNVMap
->BootOptionChanged
= TRUE
;
1245 } else if (QuestionId
== KEY_VALUE_DRIVER_DESCRIPTION
|| QuestionId
== KEY_VALUE_DRIVER_OPTION
) {
1246 CurrentFakeNVMap
->DriverOptionChanged
= TRUE
;
1249 if ((QuestionId
>= BOOT_OPTION_DEL_QUESTION_ID
) && (QuestionId
< BOOT_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1252 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
1254 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = TRUE
;
1257 // Means user remove the old check status.
1259 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = FALSE
;
1261 } else if ((QuestionId
>= DRIVER_OPTION_DEL_QUESTION_ID
) && (QuestionId
< DRIVER_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1263 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = TRUE
;
1265 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = FALSE
;
1268 switch (QuestionId
) {
1269 case KEY_VALUE_SAVE_AND_EXIT
:
1270 case KEY_VALUE_NO_SAVE_AND_EXIT
:
1271 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT
) {
1272 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1273 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
1274 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
1275 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1281 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1282 return EFI_UNSUPPORTED
;
1289 // Update the content in Terminal menu and Console menu here.
1291 if (QuestionId
== COM_BAUD_RATE_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_DATA_RATE_QUESTION_ID
+ Private
->CurrentTerminal
||
1292 QuestionId
== COM_PARITY_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_STOP_BITS_QUESTION_ID
+ Private
->CurrentTerminal
||
1293 QuestionId
== COM_TERMINAL_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_FLOWCONTROL_QUESTION_ID
+ Private
->CurrentTerminal
1295 UpdateTerminalContent(CurrentFakeNVMap
);
1297 if ((QuestionId
>= CON_IN_DEVICE_QUESTION_ID
) && (QuestionId
< CON_IN_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1298 UpdateConsoleContent (L
"ConIn",CurrentFakeNVMap
);
1299 } else if ((QuestionId
>= CON_OUT_DEVICE_QUESTION_ID
) && (QuestionId
< CON_OUT_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1300 UpdateConsoleContent (L
"ConOut", CurrentFakeNVMap
);
1301 } else if ((QuestionId
>= CON_ERR_DEVICE_QUESTION_ID
) && (QuestionId
< CON_ERR_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1302 UpdateConsoleContent (L
"ConErr", CurrentFakeNVMap
);
1307 // Pass changed uncommitted data back to Form Browser
1309 HiiSetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
, NULL
);
1315 Discard all changes done to the BMM pages such as Boot Order change,
1316 Driver order change.
1318 @param Private The BMM context data.
1319 @param CurrentFakeNVMap The current Fack NV Map.
1323 DiscardChangeHandler (
1324 IN BMM_CALLBACK_DATA
*Private
,
1325 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
1330 switch (Private
->BmmPreviousPageId
) {
1331 case FORM_BOOT_CHG_ID
:
1332 CopyMem (CurrentFakeNVMap
->BootOptionOrder
, Private
->BmmOldFakeNVData
.BootOptionOrder
, sizeof (CurrentFakeNVMap
->BootOptionOrder
));
1335 case FORM_DRV_CHG_ID
:
1336 CopyMem (CurrentFakeNVMap
->DriverOptionOrder
, Private
->BmmOldFakeNVData
.DriverOptionOrder
, sizeof (CurrentFakeNVMap
->DriverOptionOrder
));
1339 case FORM_BOOT_DEL_ID
:
1340 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->BootOptionDel
) / sizeof (CurrentFakeNVMap
->BootOptionDel
[0])));
1341 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1342 CurrentFakeNVMap
->BootOptionDel
[Index
] = FALSE
;
1346 case FORM_DRV_DEL_ID
:
1347 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->DriverOptionDel
) / sizeof (CurrentFakeNVMap
->DriverOptionDel
[0])));
1348 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1349 CurrentFakeNVMap
->DriverOptionDel
[Index
] = FALSE
;
1353 case FORM_BOOT_NEXT_ID
:
1354 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
1357 case FORM_TIME_OUT_ID
:
1358 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
1361 case FORM_DRV_ADD_HANDLE_DESC_ID
:
1362 case FORM_DRV_ADD_FILE_ID
:
1363 case FORM_DRV_ADD_HANDLE_ID
:
1364 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
1365 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
1375 Update the menus in the BMM page.
1383 VOID
*StartOpCodeHandle
;
1384 VOID
*EndOpCodeHandle
;
1385 EFI_IFR_GUID_LABEL
*StartGuidLabel
;
1386 EFI_IFR_GUID_LABEL
*EndGuidLabel
;
1389 // Allocate space for creation of UpdateData Buffer
1391 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1392 ASSERT (StartOpCodeHandle
!= NULL
);
1394 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1395 ASSERT (EndOpCodeHandle
!= NULL
);
1397 // Create Hii Extend Label OpCode as the start opcode
1399 StartGuidLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1400 StartGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1401 StartGuidLabel
->Number
= LABEL_FORM_MAIN_START
;
1403 // Create Hii Extend Label OpCode as the end opcode
1405 EndGuidLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1406 EndGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1407 EndGuidLabel
->Number
= LABEL_FORM_MAIN_END
;
1410 //Updata Front Page form
1412 UiCustomizeBMMPage (
1413 mBmmCallbackInfo
->BmmHiiHandle
,
1418 mBmmCallbackInfo
->BmmHiiHandle
,
1425 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1426 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1430 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
1431 BmmOldFakeNVData member in BMM context data.
1433 @param CallbackData The BMM context data.
1437 InitializeBmmConfig (
1438 IN BMM_CALLBACK_DATA
*CallbackData
1441 BM_MENU_ENTRY
*NewMenuEntry
;
1442 BM_LOAD_CONTEXT
*NewLoadContext
;
1445 ASSERT (CallbackData
!= NULL
);
1448 // Initialize data which located in BMM main page
1450 CallbackData
->BmmFakeNvData
.BootNext
= NONE_BOOTNEXT_VALUE
;
1451 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1452 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
1453 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1455 if (NewLoadContext
->IsBootNext
) {
1456 CallbackData
->BmmFakeNvData
.BootNext
= Index
;
1461 CallbackData
->BmmFakeNvData
.BootTimeOut
= PcdGet16 (PcdPlatformBootTimeOut
);
1464 // Initialize data which located in Boot Options Menu
1466 GetBootOrder (CallbackData
);
1469 // Initialize data which located in Driver Options Menu
1471 GetDriverOrder (CallbackData
);
1474 // Initialize data which located in Console Options Menu
1476 GetConsoleOutMode (CallbackData
);
1477 GetConsoleInCheck (CallbackData
);
1478 GetConsoleOutCheck (CallbackData
);
1479 GetConsoleErrCheck (CallbackData
);
1480 GetTerminalAttribute (CallbackData
);
1482 CallbackData
->BmmFakeNvData
.ForceReconnect
= TRUE
;
1485 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
1487 CopyMem (&CallbackData
->BmmOldFakeNVData
, &CallbackData
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
1491 Initialized all Menu Option List.
1493 @param CallbackData The BMM context data.
1498 IN BMM_CALLBACK_DATA
*CallbackData
1501 InitializeListHead (&BootOptionMenu
.Head
);
1502 InitializeListHead (&DriverOptionMenu
.Head
);
1503 BOpt_GetBootOptions (CallbackData
);
1504 BOpt_GetDriverOptions (CallbackData
);
1505 BOpt_FindDrivers ();
1506 InitializeListHead (&ConsoleInpMenu
.Head
);
1507 InitializeListHead (&ConsoleOutMenu
.Head
);
1508 InitializeListHead (&ConsoleErrMenu
.Head
);
1509 InitializeListHead (&TerminalMenu
.Head
);
1512 mAllMenuInit
= TRUE
;
1516 Free up all Menu Option list.
1527 BOpt_FreeMenu (&BootOptionMenu
);
1528 BOpt_FreeMenu (&DriverOptionMenu
);
1529 BOpt_FreeMenu (&DriverMenu
);
1531 mAllMenuInit
= FALSE
;
1535 Initial the boot mode related parameters.
1539 BmmInitialBootModeInfo (
1544 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1545 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1546 UINTN BootTextColumn
;
1549 if (mBmmModeInitialized
) {
1554 // After the console is ready, get current video resolution
1555 // and text mode before launching setup at first time.
1557 Status
= gBS
->HandleProtocol (
1558 gST
->ConsoleOutHandle
,
1559 &gEfiGraphicsOutputProtocolGuid
,
1560 (VOID
**)&GraphicsOutput
1562 if (EFI_ERROR (Status
)) {
1563 GraphicsOutput
= NULL
;
1566 Status
= gBS
->HandleProtocol (
1567 gST
->ConsoleOutHandle
,
1568 &gEfiSimpleTextOutProtocolGuid
,
1569 (VOID
**)&SimpleTextOut
1571 if (EFI_ERROR (Status
)) {
1572 SimpleTextOut
= NULL
;
1575 if (GraphicsOutput
!= NULL
) {
1577 // Get current video resolution and text mode.
1579 mBmmBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1580 mBmmBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1583 if (SimpleTextOut
!= NULL
) {
1584 Status
= SimpleTextOut
->QueryMode (
1586 SimpleTextOut
->Mode
->Mode
,
1590 mBmmBootTextModeColumn
= (UINT32
)BootTextColumn
;
1591 mBmmBootTextModeRow
= (UINT32
)BootTextRow
;
1595 // Get user defined text mode for setup.
1597 mBmmSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1598 mBmmSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1599 mBmmSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1600 mBmmSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1602 mBmmModeInitialized
= TRUE
;
1607 Install Boot Maintenance Manager Menu driver.
1609 @param ImageHandle The image handle.
1610 @param SystemTable The system table.
1612 @retval EFI_SUCEESS Install Boot manager menu success.
1613 @retval Other Return error status.
1618 BootMaintenanceManagerUiLibConstructor (
1619 IN EFI_HANDLE ImageHandle
,
1620 IN EFI_SYSTEM_TABLE
*SystemTable
1627 Status
= EFI_SUCCESS
;
1630 // Install Device Path Protocol and Config Access protocol to driver handle
1632 Status
= gBS
->InstallMultipleProtocolInterfaces (
1633 &mBmmCallbackInfo
->BmmDriverHandle
,
1634 &gEfiDevicePathProtocolGuid
,
1635 &mBmmHiiVendorDevicePath
,
1636 &gEfiHiiConfigAccessProtocolGuid
,
1637 &mBmmCallbackInfo
->BmmConfigAccess
,
1640 ASSERT_EFI_ERROR (Status
);
1643 // Post our Boot Maint VFR binary to the HII database.
1645 mBmmCallbackInfo
->BmmHiiHandle
= HiiAddPackages (
1647 mBmmCallbackInfo
->BmmDriverHandle
,
1648 BootMaintenanceManagerBin
,
1649 BootMaintenanceManagerUiLibStrings
,
1652 ASSERT (mBmmCallbackInfo
->BmmHiiHandle
!= NULL
);
1655 // Locate Formbrowser2 protocol
1657 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &mBmmCallbackInfo
->FormBrowser2
);
1658 ASSERT_EFI_ERROR (Status
);
1660 EfiBootManagerRefreshAllBootOption ();
1663 // Create LoadOption in BmmCallbackInfo for Driver Callback
1665 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
1666 ASSERT (Ptr
!= NULL
);
1669 // Initialize Bmm callback data.
1671 mBmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
1672 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
1674 mBmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
1675 Ptr
+= sizeof (BM_FILE_CONTEXT
);
1677 mBmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
1678 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
1680 mBmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
1682 mBmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
1683 mBmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
1685 InitAllMenu (mBmmCallbackInfo
);
1689 // Update boot maintenance manager page
1691 InitializeBmmConfig(mBmmCallbackInfo
);
1693 BmmInitialBootModeInfo();
1699 Unloads the application and its installed protocol.
1701 @param ImageHandle Handle that identifies the image to be unloaded.
1702 @param SystemTable The system table.
1704 @retval EFI_SUCCESS The image has been unloaded.
1709 BootMaintenanceManagerUiLibDestructor (
1710 IN EFI_HANDLE ImageHandle
,
1711 IN EFI_SYSTEM_TABLE
*SystemTable
1715 if (mStartOpCodeHandle
!= NULL
) {
1716 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
1719 if (mEndOpCodeHandle
!= NULL
) {
1720 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1726 // Remove our IFR data from HII database
1728 HiiRemovePackages (mBmmCallbackInfo
->BmmHiiHandle
);
1730 gBS
->UninstallMultipleProtocolInterfaces (
1731 mBmmCallbackInfo
->BmmDriverHandle
,
1732 &gEfiDevicePathProtocolGuid
,
1733 &mBmmHiiVendorDevicePath
,
1734 &gEfiHiiConfigAccessProtocolGuid
,
1735 &mBmmCallbackInfo
->BmmConfigAccess
,
1739 FreePool (mBmmCallbackInfo
->LoadContext
);