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 Update the terminal content in TerminalMenu.
449 @param BmmData The BMM fake NV data.
453 UpdateTerminalContent (
454 IN BMM_FAKE_NV_DATA
*BmmData
458 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
459 BM_MENU_ENTRY
*NewMenuEntry
;
461 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
462 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
463 ASSERT (NewMenuEntry
!= NULL
);
464 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
465 NewTerminalContext
->BaudRateIndex
= BmmData
->COMBaudRate
[Index
];
466 ASSERT (BmmData
->COMBaudRate
[Index
] < (sizeof (BaudRateList
) / sizeof (BaudRateList
[0])));
467 NewTerminalContext
->BaudRate
= BaudRateList
[BmmData
->COMBaudRate
[Index
]].Value
;
468 NewTerminalContext
->DataBitsIndex
= BmmData
->COMDataRate
[Index
];
469 ASSERT (BmmData
->COMDataRate
[Index
] < (sizeof (DataBitsList
) / sizeof (DataBitsList
[0])));
470 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[BmmData
->COMDataRate
[Index
]].Value
;
471 NewTerminalContext
->StopBitsIndex
= BmmData
->COMStopBits
[Index
];
472 ASSERT (BmmData
->COMStopBits
[Index
] < (sizeof (StopBitsList
) / sizeof (StopBitsList
[0])));
473 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[BmmData
->COMStopBits
[Index
]].Value
;
474 NewTerminalContext
->ParityIndex
= BmmData
->COMParity
[Index
];
475 ASSERT (BmmData
->COMParity
[Index
] < (sizeof (ParityList
) / sizeof (ParityList
[0])));
476 NewTerminalContext
->Parity
= (UINT8
) ParityList
[BmmData
->COMParity
[Index
]].Value
;
477 NewTerminalContext
->TerminalType
= BmmData
->COMTerminalType
[Index
];
478 NewTerminalContext
->FlowControl
= BmmData
->COMFlowControl
[Index
];
479 ChangeTerminalDevicePath (
480 NewTerminalContext
->DevicePath
,
487 Update the console content in ConsoleMenu.
489 @param BmmData The BMM fake NV data.
493 UpdateConsoleContent(
494 IN CHAR16
*ConsoleName
,
495 IN BMM_FAKE_NV_DATA
*BmmData
499 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
500 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
501 BM_MENU_ENTRY
*NewMenuEntry
;
503 if (StrCmp (ConsoleName
, L
"ConIn") == 0) {
504 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++){
505 NewMenuEntry
= BOpt_GetMenuEntry(&ConsoleInpMenu
, Index
);
506 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
507 ASSERT (Index
< MAX_MENU_NUMBER
);
508 NewConsoleContext
->IsActive
= BmmData
->ConsoleInCheck
[Index
];
510 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
511 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
512 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
513 ASSERT (Index
+ ConsoleInpMenu
.MenuNumber
< MAX_MENU_NUMBER
);
514 NewTerminalContext
->IsConIn
= BmmData
->ConsoleInCheck
[Index
+ ConsoleInpMenu
.MenuNumber
];
518 if (StrCmp (ConsoleName
, L
"ConOut") == 0) {
519 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++){
520 NewMenuEntry
= BOpt_GetMenuEntry(&ConsoleOutMenu
, Index
);
521 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
522 ASSERT (Index
< MAX_MENU_NUMBER
);
523 NewConsoleContext
->IsActive
= BmmData
->ConsoleOutCheck
[Index
];
525 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
526 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
527 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
528 ASSERT (Index
+ ConsoleOutMenu
.MenuNumber
< MAX_MENU_NUMBER
);
529 NewTerminalContext
->IsConOut
= BmmData
->ConsoleOutCheck
[Index
+ ConsoleOutMenu
.MenuNumber
];
532 if (StrCmp (ConsoleName
, L
"ErrOut") == 0) {
533 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++){
534 NewMenuEntry
= BOpt_GetMenuEntry(&ConsoleErrMenu
, Index
);
535 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
536 ASSERT (Index
< MAX_MENU_NUMBER
);
537 NewConsoleContext
->IsActive
= BmmData
->ConsoleErrCheck
[Index
];
539 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
540 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
541 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
542 ASSERT (Index
+ ConsoleErrMenu
.MenuNumber
< MAX_MENU_NUMBER
);
543 NewTerminalContext
->IsStdErr
= BmmData
->ConsoleErrCheck
[Index
+ ConsoleErrMenu
.MenuNumber
];
549 This function allows a caller to extract the current configuration for one
550 or more named elements from the target driver.
552 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
553 @param Request A null-terminated Unicode string in <ConfigRequest> format.
554 @param Progress On return, points to a character in the Request string.
555 Points to the string's null terminator if request was successful.
556 Points to the most recent '&' before the first failing name/value
557 pair (or the beginning of the string if the failure is in the
558 first name/value pair) if the request was not successful.
559 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
560 has all values filled in for the names in the Request string.
561 String to be allocated by the called function.
563 @retval EFI_SUCCESS The Results is filled with the requested values.
564 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
565 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
566 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
571 BootMaintExtractConfig (
572 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
573 IN CONST EFI_STRING Request
,
574 OUT EFI_STRING
*Progress
,
575 OUT EFI_STRING
*Results
580 BMM_CALLBACK_DATA
*Private
;
581 EFI_STRING ConfigRequestHdr
;
582 EFI_STRING ConfigRequest
;
583 BOOLEAN AllocatedRequest
;
586 if (Progress
== NULL
|| Results
== NULL
) {
587 return EFI_INVALID_PARAMETER
;
591 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &mBootMaintGuid
, mBootMaintStorageName
)) {
592 return EFI_NOT_FOUND
;
595 ConfigRequestHdr
= NULL
;
596 ConfigRequest
= NULL
;
597 AllocatedRequest
= FALSE
;
600 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
602 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
604 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
605 ConfigRequest
= Request
;
606 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
608 // Request has no request element, construct full request string.
609 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
610 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
612 ConfigRequestHdr
= HiiConstructConfigHdr (&mBootMaintGuid
, mBootMaintStorageName
, Private
->BmmDriverHandle
);
613 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
614 ConfigRequest
= AllocateZeroPool (Size
);
615 ASSERT (ConfigRequest
!= NULL
);
616 AllocatedRequest
= TRUE
;
617 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
618 FreePool (ConfigRequestHdr
);
621 Status
= gHiiConfigRouting
->BlockToConfig (
624 (UINT8
*) &Private
->BmmFakeNvData
,
630 // Free the allocated config request string.
632 if (AllocatedRequest
) {
633 FreePool (ConfigRequest
);
634 ConfigRequest
= NULL
;
637 // Set Progress string to the original request string.
639 if (Request
== NULL
) {
641 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
642 *Progress
= Request
+ StrLen (Request
);
649 This function applies changes in a driver's configuration.
650 Input is a Configuration, which has the routing data for this
651 driver followed by name / value configuration pairs. The driver
652 must apply those pairs to its configurable storage. If the
653 driver's configuration is stored in a linear block of data
654 and the driver's name / value pairs are in <BlockConfig>
655 format, it may use the ConfigToBlock helper function (above) to
656 simplify the job. Currently not implemented.
658 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
659 @param[in] Configuration A null-terminated Unicode string in
660 <ConfigString> format.
661 @param[out] Progress A pointer to a string filled in with the
662 offset of the most recent '&' before the
663 first failing name / value pair (or the
664 beginn ing of the string if the failure
665 is in the first name / value pair) or
666 the terminating NULL if all was
669 @retval EFI_SUCCESS The results have been distributed or are
670 awaiting distribution.
671 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
672 parts of the results that must be
673 stored awaiting possible future
675 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
676 Results parameter would result
677 in this type of error.
678 @retval EFI_NOT_FOUND Target for the specified routing data
683 BootMaintRouteConfig (
684 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
685 IN CONST EFI_STRING Configuration
,
686 OUT EFI_STRING
*Progress
691 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
692 BMM_FAKE_NV_DATA
*NewBmmData
;
693 BMM_FAKE_NV_DATA
*OldBmmData
;
694 BM_MENU_ENTRY
*NewMenuEntry
;
695 BM_LOAD_CONTEXT
*NewLoadContext
;
697 BOOLEAN TerminalAttChange
;
698 BMM_CALLBACK_DATA
*Private
;
700 if (Progress
== NULL
) {
701 return EFI_INVALID_PARAMETER
;
703 *Progress
= Configuration
;
705 if (Configuration
== NULL
) {
706 return EFI_INVALID_PARAMETER
;
710 // Check routing data in <ConfigHdr>.
711 // Note: there is no name for Name/Value storage, only GUID will be checked
713 if (!HiiIsConfigHdrMatch (Configuration
, &mBootMaintGuid
, mBootMaintStorageName
)) {
714 return EFI_NOT_FOUND
;
717 Status
= gBS
->LocateProtocol (
718 &gEfiHiiConfigRoutingProtocolGuid
,
720 (VOID
**)&ConfigRouting
722 if (EFI_ERROR (Status
)) {
726 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
728 // Get Buffer Storage data from EFI variable
730 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
731 OldBmmData
= &Private
->BmmOldFakeNVData
;
732 NewBmmData
= &Private
->BmmFakeNvData
;
734 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
736 Status
= ConfigRouting
->ConfigToBlock (
739 (UINT8
*) NewBmmData
,
743 ASSERT_EFI_ERROR (Status
);
745 // Compare new and old BMM configuration data and only do action for modified item to
746 // avoid setting unnecessary non-volatile variable
750 // Check data which located in BMM main page and save the settings if need
752 if (CompareMem (&NewBmmData
->BootNext
, &OldBmmData
->BootNext
, sizeof (NewBmmData
->BootNext
)) != 0) {
753 Status
= Var_UpdateBootNext (Private
);
757 // Check data which located in Boot Options Menu and save the settings if need
759 if (CompareMem (NewBmmData
->BootOptionDel
, OldBmmData
->BootOptionDel
, sizeof (NewBmmData
->BootOptionDel
)) != 0) {
761 ((Index
< BootOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->BootOptionDel
) / sizeof (NewBmmData
->BootOptionDel
[0]))));
763 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
764 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
765 NewLoadContext
->Deleted
= NewBmmData
->BootOptionDel
[Index
];
766 NewBmmData
->BootOptionDel
[Index
] = FALSE
;
767 NewBmmData
->BootOptionDelMark
[Index
] = FALSE
;
770 Var_DelBootOption ();
773 if (CompareMem (NewBmmData
->BootOptionOrder
, OldBmmData
->BootOptionOrder
, sizeof (NewBmmData
->BootOptionOrder
)) != 0) {
774 Status
= Var_UpdateBootOrder (Private
);
777 if (CompareMem (&NewBmmData
->BootTimeOut
, &OldBmmData
->BootTimeOut
, sizeof (NewBmmData
->BootTimeOut
)) != 0){
778 Status
= gRT
->SetVariable(
780 &gEfiGlobalVariableGuid
,
781 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
783 &(NewBmmData
->BootTimeOut
)
785 if (EFI_ERROR (Status
)) {
787 // If set variable fail, and don't have the appropriate error status for RouteConfig fuction to return,
788 // just return the EFI_NOT_FOUND.
790 if (Status
== EFI_OUT_OF_RESOURCES
) {
793 return EFI_NOT_FOUND
;
796 Private
->BmmOldFakeNVData
.BootTimeOut
= NewBmmData
->BootTimeOut
;
800 // Check data which located in Driver Options Menu and save the settings if need
802 if (CompareMem (NewBmmData
->DriverOptionDel
, OldBmmData
->DriverOptionDel
, sizeof (NewBmmData
->DriverOptionDel
)) != 0) {
804 ((Index
< DriverOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->DriverOptionDel
) / sizeof (NewBmmData
->DriverOptionDel
[0]))));
806 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
807 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
808 NewLoadContext
->Deleted
= NewBmmData
->DriverOptionDel
[Index
];
809 NewBmmData
->DriverOptionDel
[Index
] = FALSE
;
810 NewBmmData
->DriverOptionDelMark
[Index
] = FALSE
;
812 Var_DelDriverOption ();
815 if (CompareMem (NewBmmData
->DriverOptionOrder
, OldBmmData
->DriverOptionOrder
, sizeof (NewBmmData
->DriverOptionOrder
)) != 0) {
816 Status
= Var_UpdateDriverOrder (Private
);
819 if (CompareMem (&NewBmmData
->ConsoleOutMode
, &OldBmmData
->ConsoleOutMode
, sizeof (NewBmmData
->ConsoleOutMode
)) != 0){
820 Var_UpdateConMode(Private
);
823 TerminalAttChange
= FALSE
;
824 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
827 // only need update modified items
829 if (CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) == 0 &&
830 CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) == 0 &&
831 CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) == 0 &&
832 CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) == 0 &&
833 CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) == 0 &&
834 CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) == 0) {
838 TerminalAttChange
= TRUE
;
840 if (TerminalAttChange
) {
841 Var_UpdateConsoleInpOption ();
842 Var_UpdateConsoleOutOption ();
843 Var_UpdateErrorOutOption ();
846 // Check data which located in Console Options Menu and save the settings if need
848 if (CompareMem (NewBmmData
->ConsoleInCheck
, OldBmmData
->ConsoleInCheck
, sizeof (NewBmmData
->ConsoleInCheck
)) != 0){
849 Var_UpdateConsoleInpOption();
852 if (CompareMem (NewBmmData
->ConsoleOutCheck
, OldBmmData
->ConsoleOutCheck
, sizeof (NewBmmData
->ConsoleOutCheck
)) != 0){
853 Var_UpdateConsoleOutOption();
856 if (CompareMem (NewBmmData
->ConsoleErrCheck
, OldBmmData
->ConsoleErrCheck
, sizeof (NewBmmData
->ConsoleErrCheck
)) != 0){
857 Var_UpdateErrorOutOption();
860 if (CompareMem (NewBmmData
->BootDescriptionData
, OldBmmData
->BootDescriptionData
, sizeof (NewBmmData
->BootDescriptionData
)) != 0 ||
861 CompareMem (NewBmmData
->BootOptionalData
, OldBmmData
->BootOptionalData
, sizeof (NewBmmData
->BootOptionalData
)) != 0) {
862 Status
= Var_UpdateBootOption (Private
);
863 NewBmmData
->BootOptionChanged
= FALSE
;
864 if (EFI_ERROR (Status
)) {
867 BOpt_GetBootOptions (Private
);
870 if (CompareMem (NewBmmData
->DriverDescriptionData
, OldBmmData
->DriverDescriptionData
, sizeof (NewBmmData
->DriverDescriptionData
)) != 0 ||
871 CompareMem (NewBmmData
->DriverOptionalData
, OldBmmData
->DriverOptionalData
, sizeof (NewBmmData
->DriverOptionalData
)) != 0) {
872 Status
= Var_UpdateDriverOption (
874 Private
->BmmHiiHandle
,
875 NewBmmData
->DriverDescriptionData
,
876 NewBmmData
->DriverOptionalData
,
877 NewBmmData
->ForceReconnect
879 NewBmmData
->DriverOptionChanged
= FALSE
;
880 NewBmmData
->ForceReconnect
= TRUE
;
881 if (EFI_ERROR (Status
)) {
885 BOpt_GetDriverOptions (Private
);
889 // After user do the save action, need to update OldBmmData.
891 CopyMem (OldBmmData
, NewBmmData
, sizeof (BMM_FAKE_NV_DATA
));
897 This function processes the results of changes in configuration.
900 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
901 @param Action Specifies the type of action taken by the browser.
902 @param QuestionId A unique value which is sent to the original exporting driver
903 so that it can identify the type of data to expect.
904 @param Type The type of value for the question.
905 @param Value A pointer to the data being sent to the original exporting driver.
906 @param ActionRequest On return, points to the action requested by the callback function.
908 @retval EFI_SUCCESS The callback successfully handled the action.
909 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
910 @retval EFI_DEVICE_ERROR The variable could not be saved.
911 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
912 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
917 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
918 IN EFI_BROWSER_ACTION Action
,
919 IN EFI_QUESTION_ID QuestionId
,
921 IN EFI_IFR_TYPE_VALUE
*Value
,
922 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
925 BMM_CALLBACK_DATA
*Private
;
926 BM_MENU_ENTRY
*NewMenuEntry
;
927 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
929 EFI_DEVICE_PATH_PROTOCOL
* File
;
931 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
&& Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) {
933 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
935 return EFI_UNSUPPORTED
;
938 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
940 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
941 if (QuestionId
== KEY_VALUE_TRIGGER_FORM_OPEN_ACTION
) {
942 if (!mFirstEnterBMMForm
) {
944 // BMMUiLib depends on LegacyUi library to show legacy menus.
945 // If we want to show Legacy menus correctly in BMM page,
946 // we must do it after the LegacyUi library has already been initialized.
947 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
948 // So we do the tasks which are related to legacy menus here.
949 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
950 // 2. Re-scan the BootOption menus (including the legacy boot option).
953 BOpt_GetBootOptions (Private
);
954 mFirstEnterBMMForm
= TRUE
;
959 // Retrive uncommitted data from Form Browser
961 CurrentFakeNVMap
= &Private
->BmmFakeNvData
;
962 HiiGetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
);
964 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
966 return EFI_INVALID_PARAMETER
;
969 UpdatePageId (Private
, QuestionId
);
971 if (QuestionId
< FILE_OPTION_OFFSET
) {
972 if (QuestionId
< CONFIG_OPTION_OFFSET
) {
973 switch (QuestionId
) {
974 case FORM_BOOT_ADD_ID
:
975 // Leave BMM and enter FileExplorer.
976 ChooseFile (NULL
, L
".efi", CreateBootOptionFromFile
, &File
);
979 case FORM_DRV_ADD_FILE_ID
:
980 // Leave BMM and enter FileExplorer.
981 ChooseFile (NULL
, L
".efi", CreateDriverOptionFromFile
, &File
);
984 case FORM_DRV_ADD_HANDLE_ID
:
985 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
986 UpdateDrvAddHandlePage (Private
);
989 case FORM_BOOT_DEL_ID
:
990 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
991 UpdateBootDelPage (Private
);
994 case FORM_BOOT_CHG_ID
:
995 case FORM_DRV_CHG_ID
:
996 UpdatePageBody (QuestionId
, Private
);
999 case FORM_DRV_DEL_ID
:
1000 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
1001 UpdateDrvDelPage (Private
);
1004 case FORM_CON_IN_ID
:
1005 case FORM_CON_OUT_ID
:
1006 case FORM_CON_ERR_ID
:
1007 UpdatePageBody (QuestionId
, Private
);
1010 case FORM_CON_MODE_ID
:
1011 CleanUpPage (FORM_CON_MODE_ID
, Private
);
1012 UpdateConModePage (Private
);
1015 case FORM_CON_COM_ID
:
1016 CleanUpPage (FORM_CON_COM_ID
, Private
);
1017 UpdateConCOMPage (Private
);
1023 } else if ((QuestionId
>= TERMINAL_OPTION_OFFSET
) && (QuestionId
< CONSOLE_OPTION_OFFSET
)) {
1024 Index
= (UINT16
) (QuestionId
- TERMINAL_OPTION_OFFSET
);
1025 Private
->CurrentTerminal
= Index
;
1027 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
1028 UpdateTerminalPage (Private
);
1030 } else if (QuestionId
>= HANDLE_OPTION_OFFSET
) {
1031 Index
= (UINT16
) (QuestionId
- HANDLE_OPTION_OFFSET
);
1033 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index
);
1034 ASSERT (NewMenuEntry
!= NULL
);
1035 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1037 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
1039 Private
->MenuEntry
= NewMenuEntry
;
1040 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
1042 UpdateDriverAddHandleDescPage (Private
);
1045 if (QuestionId
== KEY_VALUE_BOOT_FROM_FILE
){
1046 // Leave BMM and enter FileExplorer.
1047 ChooseFile (NULL
, L
".efi", BootFromFile
, &File
);
1049 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1050 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1051 return EFI_INVALID_PARAMETER
;
1054 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_BOOT
) {
1055 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1056 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1057 } else if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_DRIVER
) {
1058 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1059 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1060 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER
) {
1062 // Discard changes and exit formset
1064 CurrentFakeNVMap
->DriverOptionalData
[0] = 0x0000;
1065 CurrentFakeNVMap
->DriverDescriptionData
[0] = 0x0000;
1066 CurrentFakeNVMap
->DriverOptionChanged
= FALSE
;
1067 CurrentFakeNVMap
->ForceReconnect
= TRUE
;
1068 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1069 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_BOOT
) {
1071 // Discard changes and exit formset
1073 CurrentFakeNVMap
->BootOptionalData
[0] = 0x0000;
1074 CurrentFakeNVMap
->BootDescriptionData
[0] = 0x0000;
1075 CurrentFakeNVMap
->BootOptionChanged
= FALSE
;
1076 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1077 } else if (QuestionId
== KEY_VALUE_BOOT_DESCRIPTION
|| QuestionId
== KEY_VALUE_BOOT_OPTION
) {
1078 CurrentFakeNVMap
->BootOptionChanged
= TRUE
;
1079 } else if (QuestionId
== KEY_VALUE_DRIVER_DESCRIPTION
|| QuestionId
== KEY_VALUE_DRIVER_OPTION
) {
1080 CurrentFakeNVMap
->DriverOptionChanged
= TRUE
;
1083 if ((QuestionId
>= BOOT_OPTION_DEL_QUESTION_ID
) && (QuestionId
< BOOT_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1086 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
1088 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = TRUE
;
1091 // Means user remove the old check status.
1093 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = FALSE
;
1095 } else if ((QuestionId
>= DRIVER_OPTION_DEL_QUESTION_ID
) && (QuestionId
< DRIVER_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1097 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = TRUE
;
1099 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = FALSE
;
1102 switch (QuestionId
) {
1103 case KEY_VALUE_SAVE_AND_EXIT
:
1104 case KEY_VALUE_NO_SAVE_AND_EXIT
:
1105 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT
) {
1106 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1107 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT
) {
1108 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
1109 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1115 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1116 return EFI_UNSUPPORTED
;
1123 // Update the content in Terminal menu and Console menu here.
1125 if (QuestionId
== COM_BAUD_RATE_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_DATA_RATE_QUESTION_ID
+ Private
->CurrentTerminal
||
1126 QuestionId
== COM_PARITY_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_STOP_BITS_QUESTION_ID
+ Private
->CurrentTerminal
||
1127 QuestionId
== COM_TERMINAL_QUESTION_ID
+ Private
->CurrentTerminal
|| QuestionId
== COM_FLOWCONTROL_QUESTION_ID
+ Private
->CurrentTerminal
1129 UpdateTerminalContent(CurrentFakeNVMap
);
1131 if ((QuestionId
>= CON_IN_DEVICE_QUESTION_ID
) && (QuestionId
< CON_IN_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1132 UpdateConsoleContent (L
"ConIn",CurrentFakeNVMap
);
1133 } else if ((QuestionId
>= CON_OUT_DEVICE_QUESTION_ID
) && (QuestionId
< CON_OUT_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1134 UpdateConsoleContent (L
"ConOut", CurrentFakeNVMap
);
1135 } else if ((QuestionId
>= CON_ERR_DEVICE_QUESTION_ID
) && (QuestionId
< CON_ERR_DEVICE_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1136 UpdateConsoleContent (L
"ConErr", CurrentFakeNVMap
);
1141 // Pass changed uncommitted data back to Form Browser
1143 HiiSetBrowserData (&mBootMaintGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
, NULL
);
1149 Discard all changes done to the BMM pages such as Boot Order change,
1150 Driver order change.
1152 @param Private The BMM context data.
1153 @param CurrentFakeNVMap The current Fack NV Map.
1157 DiscardChangeHandler (
1158 IN BMM_CALLBACK_DATA
*Private
,
1159 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
1164 switch (Private
->BmmPreviousPageId
) {
1165 case FORM_BOOT_CHG_ID
:
1166 CopyMem (CurrentFakeNVMap
->BootOptionOrder
, Private
->BmmOldFakeNVData
.BootOptionOrder
, sizeof (CurrentFakeNVMap
->BootOptionOrder
));
1169 case FORM_DRV_CHG_ID
:
1170 CopyMem (CurrentFakeNVMap
->DriverOptionOrder
, Private
->BmmOldFakeNVData
.DriverOptionOrder
, sizeof (CurrentFakeNVMap
->DriverOptionOrder
));
1173 case FORM_BOOT_DEL_ID
:
1174 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->BootOptionDel
) / sizeof (CurrentFakeNVMap
->BootOptionDel
[0])));
1175 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1176 CurrentFakeNVMap
->BootOptionDel
[Index
] = FALSE
;
1180 case FORM_DRV_DEL_ID
:
1181 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->DriverOptionDel
) / sizeof (CurrentFakeNVMap
->DriverOptionDel
[0])));
1182 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1183 CurrentFakeNVMap
->DriverOptionDel
[Index
] = FALSE
;
1187 case FORM_BOOT_NEXT_ID
:
1188 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
1191 case FORM_TIME_OUT_ID
:
1192 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
1195 case FORM_DRV_ADD_HANDLE_DESC_ID
:
1196 case FORM_DRV_ADD_FILE_ID
:
1197 case FORM_DRV_ADD_HANDLE_ID
:
1198 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
1199 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
1209 Update the menus in the BMM page.
1217 VOID
*StartOpCodeHandle
;
1218 VOID
*EndOpCodeHandle
;
1219 EFI_IFR_GUID_LABEL
*StartGuidLabel
;
1220 EFI_IFR_GUID_LABEL
*EndGuidLabel
;
1223 // Allocate space for creation of UpdateData Buffer
1225 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1226 ASSERT (StartOpCodeHandle
!= NULL
);
1228 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1229 ASSERT (EndOpCodeHandle
!= NULL
);
1231 // Create Hii Extend Label OpCode as the start opcode
1233 StartGuidLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1234 StartGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1235 StartGuidLabel
->Number
= LABEL_FORM_MAIN_START
;
1237 // Create Hii Extend Label OpCode as the end opcode
1239 EndGuidLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1240 EndGuidLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1241 EndGuidLabel
->Number
= LABEL_FORM_MAIN_END
;
1244 //Updata Front Page form
1246 UiCustomizeBMMPage (
1247 mBmmCallbackInfo
->BmmHiiHandle
,
1252 mBmmCallbackInfo
->BmmHiiHandle
,
1259 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1260 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1264 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
1265 BmmOldFakeNVData member in BMM context data.
1267 @param CallbackData The BMM context data.
1271 InitializeBmmConfig (
1272 IN BMM_CALLBACK_DATA
*CallbackData
1275 BM_MENU_ENTRY
*NewMenuEntry
;
1276 BM_LOAD_CONTEXT
*NewLoadContext
;
1279 ASSERT (CallbackData
!= NULL
);
1282 // Initialize data which located in BMM main page
1284 CallbackData
->BmmFakeNvData
.BootNext
= NONE_BOOTNEXT_VALUE
;
1285 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1286 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
1287 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1289 if (NewLoadContext
->IsBootNext
) {
1290 CallbackData
->BmmFakeNvData
.BootNext
= Index
;
1295 CallbackData
->BmmFakeNvData
.BootTimeOut
= PcdGet16 (PcdPlatformBootTimeOut
);
1298 // Initialize data which located in Boot Options Menu
1300 GetBootOrder (CallbackData
);
1303 // Initialize data which located in Driver Options Menu
1305 GetDriverOrder (CallbackData
);
1308 // Initialize data which located in Console Options Menu
1310 GetConsoleOutMode (CallbackData
);
1311 GetConsoleInCheck (CallbackData
);
1312 GetConsoleOutCheck (CallbackData
);
1313 GetConsoleErrCheck (CallbackData
);
1314 GetTerminalAttribute (CallbackData
);
1316 CallbackData
->BmmFakeNvData
.ForceReconnect
= TRUE
;
1319 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
1321 CopyMem (&CallbackData
->BmmOldFakeNVData
, &CallbackData
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
1325 Initialized all Menu Option List.
1327 @param CallbackData The BMM context data.
1332 IN BMM_CALLBACK_DATA
*CallbackData
1335 InitializeListHead (&BootOptionMenu
.Head
);
1336 InitializeListHead (&DriverOptionMenu
.Head
);
1337 BOpt_GetBootOptions (CallbackData
);
1338 BOpt_GetDriverOptions (CallbackData
);
1339 BOpt_FindDrivers ();
1340 InitializeListHead (&ConsoleInpMenu
.Head
);
1341 InitializeListHead (&ConsoleOutMenu
.Head
);
1342 InitializeListHead (&ConsoleErrMenu
.Head
);
1343 InitializeListHead (&TerminalMenu
.Head
);
1346 mAllMenuInit
= TRUE
;
1350 Free up all Menu Option list.
1361 BOpt_FreeMenu (&BootOptionMenu
);
1362 BOpt_FreeMenu (&DriverOptionMenu
);
1363 BOpt_FreeMenu (&DriverMenu
);
1365 mAllMenuInit
= FALSE
;
1369 Initial the boot mode related parameters.
1373 BmmInitialBootModeInfo (
1378 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1379 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1380 UINTN BootTextColumn
;
1383 if (mBmmModeInitialized
) {
1388 // After the console is ready, get current video resolution
1389 // and text mode before launching setup at first time.
1391 Status
= gBS
->HandleProtocol (
1392 gST
->ConsoleOutHandle
,
1393 &gEfiGraphicsOutputProtocolGuid
,
1394 (VOID
**)&GraphicsOutput
1396 if (EFI_ERROR (Status
)) {
1397 GraphicsOutput
= NULL
;
1400 Status
= gBS
->HandleProtocol (
1401 gST
->ConsoleOutHandle
,
1402 &gEfiSimpleTextOutProtocolGuid
,
1403 (VOID
**)&SimpleTextOut
1405 if (EFI_ERROR (Status
)) {
1406 SimpleTextOut
= NULL
;
1409 if (GraphicsOutput
!= NULL
) {
1411 // Get current video resolution and text mode.
1413 mBmmBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1414 mBmmBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1417 if (SimpleTextOut
!= NULL
) {
1418 Status
= SimpleTextOut
->QueryMode (
1420 SimpleTextOut
->Mode
->Mode
,
1424 mBmmBootTextModeColumn
= (UINT32
)BootTextColumn
;
1425 mBmmBootTextModeRow
= (UINT32
)BootTextRow
;
1429 // Get user defined text mode for setup.
1431 mBmmSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1432 mBmmSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1433 mBmmSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1434 mBmmSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1436 mBmmModeInitialized
= TRUE
;
1441 Install Boot Maintenance Manager Menu driver.
1443 @param ImageHandle The image handle.
1444 @param SystemTable The system table.
1446 @retval EFI_SUCEESS Install Boot manager menu success.
1447 @retval Other Return error status.
1452 BootMaintenanceManagerUiLibConstructor (
1453 IN EFI_HANDLE ImageHandle
,
1454 IN EFI_SYSTEM_TABLE
*SystemTable
1461 Status
= EFI_SUCCESS
;
1464 // Install Device Path Protocol and Config Access protocol to driver handle
1466 Status
= gBS
->InstallMultipleProtocolInterfaces (
1467 &mBmmCallbackInfo
->BmmDriverHandle
,
1468 &gEfiDevicePathProtocolGuid
,
1469 &mBmmHiiVendorDevicePath
,
1470 &gEfiHiiConfigAccessProtocolGuid
,
1471 &mBmmCallbackInfo
->BmmConfigAccess
,
1474 ASSERT_EFI_ERROR (Status
);
1477 // Post our Boot Maint VFR binary to the HII database.
1479 mBmmCallbackInfo
->BmmHiiHandle
= HiiAddPackages (
1481 mBmmCallbackInfo
->BmmDriverHandle
,
1482 BootMaintenanceManagerBin
,
1483 BootMaintenanceManagerUiLibStrings
,
1486 ASSERT (mBmmCallbackInfo
->BmmHiiHandle
!= NULL
);
1489 // Locate Formbrowser2 protocol
1491 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &mBmmCallbackInfo
->FormBrowser2
);
1492 ASSERT_EFI_ERROR (Status
);
1494 EfiBootManagerRefreshAllBootOption ();
1497 // Create LoadOption in BmmCallbackInfo for Driver Callback
1499 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
1500 ASSERT (Ptr
!= NULL
);
1503 // Initialize Bmm callback data.
1505 mBmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
1506 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
1508 mBmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
1509 Ptr
+= sizeof (BM_FILE_CONTEXT
);
1511 mBmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
1512 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
1514 mBmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
1516 mBmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
1517 mBmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
1519 InitAllMenu (mBmmCallbackInfo
);
1523 // Update boot maintenance manager page
1525 InitializeBmmConfig(mBmmCallbackInfo
);
1527 BmmInitialBootModeInfo();
1533 Unloads the application and its installed protocol.
1535 @param ImageHandle Handle that identifies the image to be unloaded.
1536 @param SystemTable The system table.
1538 @retval EFI_SUCCESS The image has been unloaded.
1543 BootMaintenanceManagerUiLibDestructor (
1544 IN EFI_HANDLE ImageHandle
,
1545 IN EFI_SYSTEM_TABLE
*SystemTable
1549 if (mStartOpCodeHandle
!= NULL
) {
1550 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
1553 if (mEndOpCodeHandle
!= NULL
) {
1554 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1560 // Remove our IFR data from HII database
1562 HiiRemovePackages (mBmmCallbackInfo
->BmmHiiHandle
);
1564 gBS
->UninstallMultipleProtocolInterfaces (
1565 mBmmCallbackInfo
->BmmDriverHandle
,
1566 &gEfiDevicePathProtocolGuid
,
1567 &mBmmHiiVendorDevicePath
,
1568 &gEfiHiiConfigAccessProtocolGuid
,
1569 &mBmmCallbackInfo
->BmmConfigAccess
,
1573 FreePool (mBmmCallbackInfo
->LoadContext
);