summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c')
-rw-r--r--MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c3608
1 files changed, 1804 insertions, 1804 deletions
diff --git a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
index 19751642a3..3e9db632dd 100644
--- a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
+++ b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
@@ -1,1804 +1,1804 @@
-/** @file
-The functions for Boot Maintainence Main menu.
-
-Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "BootMaintenanceManager.h"
-
-#define FRONT_PAGE_KEY_OFFSET 0x4000
-//
-// Boot video resolution and text mode.
-//
-UINT32 mBmmBootHorizontalResolution = 0;
-UINT32 mBmmBootVerticalResolution = 0;
-UINT32 mBmmBootTextModeColumn = 0;
-UINT32 mBmmBootTextModeRow = 0;
-//
-// BIOS setup video resolution and text mode.
-//
-UINT32 mBmmSetupTextModeColumn = 0;
-UINT32 mBmmSetupTextModeRow = 0;
-UINT32 mBmmSetupHorizontalResolution = 0;
-UINT32 mBmmSetupVerticalResolution = 0;
-
-BOOLEAN mBmmModeInitialized = FALSE;
-
-EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- END_DEVICE_PATH_LENGTH,
- 0
- }
- }
-};
-
-HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
- (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
- }
- },
- //
- // {165A028F-0BB2-4b5f-8747-77592E3F6499}
- //
- { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 }
- }
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8)(END_DEVICE_PATH_LENGTH),
- (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
- }
- }
-};
-
-EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;
-
-CHAR16 mBootMaintStorageName[] = L"BmmData";
-BMM_CALLBACK_DATA gBootMaintenancePrivate = {
- BMM_CALLBACK_DATA_SIGNATURE,
- NULL,
- NULL,
- {
- BootMaintExtractConfig,
- BootMaintRouteConfig,
- BootMaintCallback
- }
-};
-
-BMM_CALLBACK_DATA *mBmmCallbackInfo = &gBootMaintenancePrivate;
-BOOLEAN mAllMenuInit = FALSE;
-BOOLEAN mFirstEnterBMMForm = FALSE;
-
-/**
- Init all memu.
-
- @param CallbackData The BMM context data.
-
-**/
-VOID
-InitAllMenu (
- IN BMM_CALLBACK_DATA *CallbackData
- );
-
-/**
- Free up all Menu Option list.
-
-**/
-VOID
-FreeAllMenu (
- VOID
- );
-
-/**
-
- Update the menus in the BMM page.
-
-**/
-VOID
-CustomizeMenus (
- VOID
- );
-
-/**
- This function will change video resolution and text mode
- according to defined setup mode or defined boot mode
-
- @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
-
- @retval EFI_SUCCESS Mode is changed successfully.
- @retval Others Mode failed to be changed.
-
-**/
-EFI_STATUS
-BmmSetConsoleMode (
- BOOLEAN IsSetupMode
- )
-{
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
- UINTN SizeOfInfo;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
- UINT32 MaxGopMode;
- UINT32 MaxTextMode;
- UINT32 ModeNumber;
- UINT32 NewHorizontalResolution;
- UINT32 NewVerticalResolution;
- UINT32 NewColumns;
- UINT32 NewRows;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- EFI_STATUS Status;
- UINTN Index;
- UINTN CurrentColumn;
- UINTN CurrentRow;
-
- MaxGopMode = 0;
- MaxTextMode = 0;
-
- //
- // Get current video resolution and text mode
- //
- Status = gBS->HandleProtocol (
- gST->ConsoleOutHandle,
- &gEfiGraphicsOutputProtocolGuid,
- (VOID **)&GraphicsOutput
- );
- if (EFI_ERROR (Status)) {
- GraphicsOutput = NULL;
- }
-
- Status = gBS->HandleProtocol (
- gST->ConsoleOutHandle,
- &gEfiSimpleTextOutProtocolGuid,
- (VOID **)&SimpleTextOut
- );
- if (EFI_ERROR (Status)) {
- SimpleTextOut = NULL;
- }
-
- if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
- return EFI_UNSUPPORTED;
- }
-
- if (IsSetupMode) {
- //
- // The required resolution and text mode is setup mode.
- //
- NewHorizontalResolution = mBmmSetupHorizontalResolution;
- NewVerticalResolution = mBmmSetupVerticalResolution;
- NewColumns = mBmmSetupTextModeColumn;
- NewRows = mBmmSetupTextModeRow;
- } else {
- //
- // The required resolution and text mode is boot mode.
- //
- NewHorizontalResolution = mBmmBootHorizontalResolution;
- NewVerticalResolution = mBmmBootVerticalResolution;
- NewColumns = mBmmBootTextModeColumn;
- NewRows = mBmmBootTextModeRow;
- }
-
- if (GraphicsOutput != NULL) {
- MaxGopMode = GraphicsOutput->Mode->MaxMode;
- }
-
- if (SimpleTextOut != NULL) {
- MaxTextMode = SimpleTextOut->Mode->MaxMode;
- }
-
- //
- // 1. If current video resolution is same with required video resolution,
- // video resolution need not be changed.
- // 1.1. If current text mode is same with required text mode, text mode need not be changed.
- // 1.2. If current text mode is different from required text mode, text mode need be changed.
- // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
- //
- for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
- Status = GraphicsOutput->QueryMode (
- GraphicsOutput,
- ModeNumber,
- &SizeOfInfo,
- &Info
- );
- if (!EFI_ERROR (Status)) {
- if ((Info->HorizontalResolution == NewHorizontalResolution) &&
- (Info->VerticalResolution == NewVerticalResolution))
- {
- if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
- (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution))
- {
- //
- // Current resolution is same with required resolution, check if text mode need be set
- //
- Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
- ASSERT_EFI_ERROR (Status);
- if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
- //
- // If current text mode is same with required text mode. Do nothing
- //
- FreePool (Info);
- return EFI_SUCCESS;
- } else {
- //
- // If current text mode is different from required text mode. Set new video mode
- //
- for (Index = 0; Index < MaxTextMode; Index++) {
- Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
- if (!EFI_ERROR (Status)) {
- if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
- //
- // Required text mode is supported, set it.
- //
- Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
- ASSERT_EFI_ERROR (Status);
- //
- // Update text mode PCD.
- //
- Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);
- ASSERT_EFI_ERROR (Status);
- FreePool (Info);
- return EFI_SUCCESS;
- }
- }
- }
-
- if (Index == MaxTextMode) {
- //
- // If required text mode is not supported, return error.
- //
- FreePool (Info);
- return EFI_UNSUPPORTED;
- }
- }
- } else {
- //
- // If current video resolution is not same with the new one, set new video resolution.
- // In this case, the driver which produces simple text out need be restarted.
- //
- Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
- if (!EFI_ERROR (Status)) {
- FreePool (Info);
- break;
- }
- }
- }
-
- FreePool (Info);
- }
- }
-
- if (ModeNumber == MaxGopMode) {
- //
- // If the resolution is not supported, return error.
- //
- return EFI_UNSUPPORTED;
- }
-
- //
- // Set PCD to Inform GraphicsConsole to change video resolution.
- // Set PCD to Inform Consplitter to change text mode.
- //
- Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutColumn, NewColumns);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutRow, NewRows);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Video mode is changed, so restart graphics console driver and higher level driver.
- // Reconnect graphics console driver and higher level driver.
- // Locate all the handles with GOP protocol and reconnect it.
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextOutProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (!EFI_ERROR (Status)) {
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This function converts an input device structure to a Unicode string.
-
- @param DevPath A pointer to the device path structure.
-
- @return A new allocated Unicode string that represents the device path.
-
-**/
-CHAR16 *
-UiDevicePathToStr (
- IN EFI_DEVICE_PATH_PROTOCOL *DevPath
- )
-{
- EFI_STATUS Status;
- CHAR16 *ToText;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
-
- if (DevPath == NULL) {
- return NULL;
- }
-
- Status = gBS->LocateProtocol (
- &gEfiDevicePathToTextProtocolGuid,
- NULL,
- (VOID **)&DevPathToText
- );
- ASSERT_EFI_ERROR (Status);
- ToText = DevPathToText->ConvertDevicePathToText (
- DevPath,
- FALSE,
- TRUE
- );
- ASSERT (ToText != NULL);
- return ToText;
-}
-
-/**
- Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
- The caller is responsible for freeing the allocated buffer using FreePool().
-
- @param DevicePath Device path.
-
- @return A new allocated string that represents the file name.
-
-**/
-CHAR16 *
-ExtractFileNameFromDevicePath (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- CHAR16 *String;
- CHAR16 *MatchString;
- CHAR16 *LastMatch;
- CHAR16 *FileName;
- UINTN Length;
-
- ASSERT (DevicePath != NULL);
-
- String = UiDevicePathToStr (DevicePath);
- MatchString = String;
- LastMatch = String;
- FileName = NULL;
-
- while (MatchString != NULL) {
- LastMatch = MatchString + 1;
- MatchString = StrStr (LastMatch, L"\\");
- }
-
- Length = StrLen (LastMatch);
- FileName = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), LastMatch);
- if (FileName != NULL) {
- *(FileName + Length) = 0;
- }
-
- FreePool (String);
-
- return FileName;
-}
-
-/**
- Extract device path for given HII handle and class guid.
-
- @param Handle The HII handle.
-
- @retval NULL Fail to get the device path string.
- @return PathString Get the device path string.
-
-**/
-CHAR16 *
-BmmExtractDevicePathFromHiiHandle (
- IN EFI_HII_HANDLE Handle
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE DriverHandle;
-
- ASSERT (Handle != NULL);
-
- if (Handle == NULL) {
- return NULL;
- }
-
- Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Get device path string.
- //
- return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
-}
-
-/**
- Converts the unicode character of the string from uppercase to lowercase.
- This is a internal function.
-
- @param ConfigString String to be converted
-
-**/
-VOID
-HiiToLower (
- IN EFI_STRING ConfigString
- )
-{
- EFI_STRING String;
- BOOLEAN Lower;
-
- ASSERT (ConfigString != NULL);
-
- //
- // Convert all hex digits in range [A-F] in the configuration header to [a-f]
- //
- for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
- if (*String == L'=') {
- Lower = TRUE;
- } else if (*String == L'&') {
- Lower = FALSE;
- } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
- *String = (CHAR16)(*String - L'A' + L'a');
- }
- }
-}
-
-/**
- Update the progress string through the offset value.
-
- @param Offset The offset value
- @param Configuration Point to the configuration string.
-
-**/
-EFI_STRING
-UpdateProgress (
- IN UINTN Offset,
- IN EFI_STRING Configuration
- )
-{
- UINTN Length;
- EFI_STRING StringPtr;
- EFI_STRING ReturnString;
-
- StringPtr = NULL;
- ReturnString = NULL;
-
- //
- // &OFFSET=XXXX followed by a Null-terminator.
- // Length = StrLen (L"&OFFSET=") + 4 + 1
- //
- Length = StrLen (L"&OFFSET=") + 4 + 1;
-
- StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));
-
- if (StringPtr == NULL) {
- return NULL;
- }
-
- UnicodeSPrint (
- StringPtr,
- (8 + 4 + 1) * sizeof (CHAR16),
- L"&OFFSET=%04x",
- Offset
- );
-
- ReturnString = StrStr (Configuration, StringPtr);
-
- if (ReturnString == NULL) {
- //
- // If doesn't find the string in Configuration, convert the string to lower case then search again.
- //
- HiiToLower (StringPtr);
- ReturnString = StrStr (Configuration, StringPtr);
- }
-
- FreePool (StringPtr);
-
- return ReturnString;
-}
-
-/**
- Update the terminal content in TerminalMenu.
-
- @param BmmData The BMM fake NV data.
-
-**/
-VOID
-UpdateTerminalContent (
- IN BMM_FAKE_NV_DATA *BmmData
- )
-{
- UINT16 Index;
- BM_TERMINAL_CONTEXT *NewTerminalContext;
- BM_MENU_ENTRY *NewMenuEntry;
-
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
- ASSERT (NewMenuEntry != NULL);
- NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
- NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];
- ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));
- NewTerminalContext->BaudRate = BaudRateList[BmmData->COMBaudRate[Index]].Value;
- NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];
- ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));
- NewTerminalContext->DataBits = (UINT8)DataBitsList[BmmData->COMDataRate[Index]].Value;
- NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];
- ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));
- NewTerminalContext->StopBits = (UINT8)StopBitsList[BmmData->COMStopBits[Index]].Value;
- NewTerminalContext->ParityIndex = BmmData->COMParity[Index];
- ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));
- NewTerminalContext->Parity = (UINT8)ParityList[BmmData->COMParity[Index]].Value;
- NewTerminalContext->TerminalType = BmmData->COMTerminalType[Index];
- NewTerminalContext->FlowControl = BmmData->COMFlowControl[Index];
- ChangeTerminalDevicePath (
- NewTerminalContext->DevicePath,
- FALSE
- );
- }
-}
-
-/**
- Update the console content in ConsoleMenu.
-
- @param ConsoleName The name for the console device type.
- @param BmmData The BMM fake NV data.
-
-**/
-VOID
-UpdateConsoleContent (
- IN CHAR16 *ConsoleName,
- IN BMM_FAKE_NV_DATA *BmmData
- )
-{
- UINT16 Index;
- BM_CONSOLE_CONTEXT *NewConsoleContext;
- BM_TERMINAL_CONTEXT *NewTerminalContext;
- BM_MENU_ENTRY *NewMenuEntry;
-
- if (StrCmp (ConsoleName, L"ConIn") == 0) {
- for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
- NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index < MAX_MENU_NUMBER);
- NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];
- }
-
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
- NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
- NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];
- }
- }
-
- if (StrCmp (ConsoleName, L"ConOut") == 0) {
- for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
- NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index < MAX_MENU_NUMBER);
- NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];
- }
-
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
- NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
- NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];
- }
- }
-
- if (StrCmp (ConsoleName, L"ErrOut") == 0) {
- for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
- NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index < MAX_MENU_NUMBER);
- NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];
- }
-
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
- NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
- ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
- NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];
- }
- }
-}
-
-/**
- This function allows a caller to extract the current configuration for one
- or more named elements from the target driver.
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Request A null-terminated Unicode string in <ConfigRequest> format.
- @param Progress On return, points to a character in the Request string.
- Points to the string's null terminator if request was successful.
- Points to the most recent '&' before the first failing name/value
- pair (or the beginning of the string if the failure is in the
- first name/value pair) if the request was not successful.
- @param Results A null-terminated Unicode string in <ConfigAltResp> format which
- has all values filled in for the names in the Request string.
- String to be allocated by the called function.
-
- @retval EFI_SUCCESS The Results is filled with the requested values.
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
- @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-BootMaintExtractConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Request,
- OUT EFI_STRING *Progress,
- OUT EFI_STRING *Results
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- BMM_CALLBACK_DATA *Private;
- EFI_STRING ConfigRequestHdr;
- EFI_STRING ConfigRequest;
- BOOLEAN AllocatedRequest;
- UINTN Size;
-
- if ((Progress == NULL) || (Results == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Request;
- if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {
- return EFI_NOT_FOUND;
- }
-
- ConfigRequestHdr = NULL;
- ConfigRequest = NULL;
- AllocatedRequest = FALSE;
- Size = 0;
-
- Private = BMM_CALLBACK_DATA_FROM_THIS (This);
- //
- // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
- //
- BufferSize = sizeof (BMM_FAKE_NV_DATA);
- ConfigRequest = Request;
- if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
- //
- // Request has no request element, construct full request string.
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
- //
- ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);
- Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- ASSERT (ConfigRequest != NULL);
- AllocatedRequest = TRUE;
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
- FreePool (ConfigRequestHdr);
- }
-
- Status = gHiiConfigRouting->BlockToConfig (
- gHiiConfigRouting,
- ConfigRequest,
- (UINT8 *)&Private->BmmFakeNvData,
- BufferSize,
- Results,
- Progress
- );
- //
- // Free the allocated config request string.
- //
- if (AllocatedRequest) {
- FreePool (ConfigRequest);
- ConfigRequest = NULL;
- }
-
- //
- // Set Progress string to the original request string.
- //
- if (Request == NULL) {
- *Progress = NULL;
- } else if (StrStr (Request, L"OFFSET") == NULL) {
- *Progress = Request + StrLen (Request);
- }
-
- return Status;
-}
-
-/**
- This function applies changes in a driver's configuration.
- Input is a Configuration, which has the routing data for this
- driver followed by name / value configuration pairs. The driver
- must apply those pairs to its configurable storage. If the
- driver's configuration is stored in a linear block of data
- and the driver's name / value pairs are in <BlockConfig>
- format, it may use the ConfigToBlock helper function (above) to
- simplify the job. Currently not implemented.
-
- @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param[in] Configuration A null-terminated Unicode string in
- <ConfigString> format.
- @param[out] Progress A pointer to a string filled in with the
- offset of the most recent '&' before the
- first failing name / value pair (or the
- beginn ing of the string if the failure
- is in the first name / value pair) or
- the terminating NULL if all was
- successful.
-
- @retval EFI_SUCCESS The results have been distributed or are
- awaiting distribution.
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
- parts of the results that must be
- stored awaiting possible future
- protocols.
- @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
- Results parameter would result
- in this type of error.
- @retval EFI_NOT_FOUND Target for the specified routing data
- was not found.
-**/
-EFI_STATUS
-EFIAPI
-BootMaintRouteConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Configuration,
- OUT EFI_STRING *Progress
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
- BMM_FAKE_NV_DATA *NewBmmData;
- BMM_FAKE_NV_DATA *OldBmmData;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- UINT16 Index;
- BOOLEAN TerminalAttChange;
- BMM_CALLBACK_DATA *Private;
- UINTN Offset;
-
- if (Progress == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Configuration;
-
- if (Configuration == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check routing data in <ConfigHdr>.
- // Note: there is no name for Name/Value storage, only GUID will be checked
- //
- if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {
- return EFI_NOT_FOUND;
- }
-
- Status = gBS->LocateProtocol (
- &gEfiHiiConfigRoutingProtocolGuid,
- NULL,
- (VOID **)&ConfigRouting
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Private = BMM_CALLBACK_DATA_FROM_THIS (This);
- //
- // Get Buffer Storage data from EFI variable
- //
- BufferSize = sizeof (BMM_FAKE_NV_DATA);
- OldBmmData = &Private->BmmOldFakeNVData;
- NewBmmData = &Private->BmmFakeNvData;
- Offset = 0;
- //
- // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
- //
- Status = ConfigRouting->ConfigToBlock (
- ConfigRouting,
- Configuration,
- (UINT8 *)NewBmmData,
- &BufferSize,
- Progress
- );
- ASSERT_EFI_ERROR (Status);
- //
- // Compare new and old BMM configuration data and only do action for modified item to
- // avoid setting unnecessary non-volatile variable
- //
-
- //
- // Check data which located in BMM main page and save the settings if need
- //
- if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
- Status = Var_UpdateBootNext (Private);
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);
- goto Exit;
- }
- }
-
- //
- // Check data which located in Boot Options Menu and save the settings if need
- //
- if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
- for (Index = 0;
- ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
- Index++)
- {
- NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
- NewBmmData->BootOptionDel[Index] = FALSE;
- NewBmmData->BootOptionDelMark[Index] = FALSE;
- }
-
- Status = Var_DelBootOption ();
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);
- goto Exit;
- }
- }
-
- if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
- Status = Var_UpdateBootOrder (Private);
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);
- goto Exit;
- }
- }
-
- if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {
- Status = gRT->SetVariable (
- L"Timeout",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- sizeof (UINT16),
- &(NewBmmData->BootTimeOut)
- );
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);
- goto Exit;
- }
-
- Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
- }
-
- //
- // Check data which located in Driver Options Menu and save the settings if need
- //
- if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
- for (Index = 0;
- ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
- Index++)
- {
- NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
- NewBmmData->DriverOptionDel[Index] = FALSE;
- NewBmmData->DriverOptionDelMark[Index] = FALSE;
- }
-
- Status = Var_DelDriverOption ();
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);
- goto Exit;
- }
- }
-
- if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
- Status = Var_UpdateDriverOrder (Private);
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);
- goto Exit;
- }
- }
-
- if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {
- Status = Var_UpdateConMode (Private);
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);
- goto Exit;
- }
- }
-
- TerminalAttChange = FALSE;
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
- //
- // only need update modified items
- //
- if ((CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0) &&
- (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0) &&
- (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0) &&
- (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0) &&
- (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0) &&
- (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0))
- {
- continue;
- }
-
- TerminalAttChange = TRUE;
- }
-
- if (TerminalAttChange) {
- if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);
- } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);
- } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);
- } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);
- } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);
- } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);
- }
-
- Status = Var_UpdateConsoleInpOption ();
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- Status = Var_UpdateConsoleOutOption ();
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- Status = Var_UpdateErrorOutOption ();
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- }
-
- //
- // Check data which located in Console Options Menu and save the settings if need
- //
- if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {
- Status = Var_UpdateConsoleInpOption ();
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);
- goto Exit;
- }
- }
-
- if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {
- Status = Var_UpdateConsoleOutOption ();
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);
- goto Exit;
- }
- }
-
- if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {
- Status = Var_UpdateErrorOutOption ();
- if (EFI_ERROR (Status)) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);
- goto Exit;
- }
- }
-
- if ((CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) ||
- (CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0))
- {
- Status = Var_UpdateBootOption (Private);
- NewBmmData->BootOptionChanged = FALSE;
- if (EFI_ERROR (Status)) {
- if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);
- } else {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);
- }
-
- goto Exit;
- }
-
- BOpt_GetBootOptions (Private);
- }
-
- if ((CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) ||
- (CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0))
- {
- Status = Var_UpdateDriverOption (
- Private,
- Private->BmmHiiHandle,
- NewBmmData->DriverDescriptionData,
- NewBmmData->DriverOptionalData,
- NewBmmData->ForceReconnect
- );
- NewBmmData->DriverOptionChanged = FALSE;
- NewBmmData->ForceReconnect = TRUE;
- if (EFI_ERROR (Status)) {
- if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);
- } else {
- Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);
- }
-
- goto Exit;
- }
-
- BOpt_GetDriverOptions (Private);
- }
-
- //
- // After user do the save action, need to update OldBmmData.
- //
- CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
-
- return EFI_SUCCESS;
-
-Exit:
- //
- // Fail to save the data, update the progress string.
- //
- *Progress = UpdateProgress (Offset, Configuration);
- if (Status == EFI_OUT_OF_RESOURCES) {
- return Status;
- } else {
- return EFI_NOT_FOUND;
- }
-}
-
-/**
- This function processes the results of changes in configuration.
-
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Action Specifies the type of action taken by the browser.
- @param QuestionId A unique value which is sent to the original exporting driver
- so that it can identify the type of data to expect.
- @param Type The type of value for the question.
- @param Value A pointer to the data being sent to the original exporting driver.
- @param ActionRequest On return, points to the action requested by the callback function.
-
- @retval EFI_SUCCESS The callback successfully handled the action.
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
- @retval EFI_DEVICE_ERROR The variable could not be saved.
- @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
- @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
-**/
-EFI_STATUS
-EFIAPI
-BootMaintCallback (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN EFI_BROWSER_ACTION Action,
- IN EFI_QUESTION_ID QuestionId,
- IN UINT8 Type,
- IN EFI_IFR_TYPE_VALUE *Value,
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
- )
-{
- BMM_CALLBACK_DATA *Private;
- BM_MENU_ENTRY *NewMenuEntry;
- BMM_FAKE_NV_DATA *CurrentFakeNVMap;
- BMM_FAKE_NV_DATA *OldFakeNVMap;
- UINTN Index;
- EFI_DEVICE_PATH_PROTOCOL *File;
-
- if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
- //
- // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
- //
- return EFI_UNSUPPORTED;
- }
-
- Private = BMM_CALLBACK_DATA_FROM_THIS (This);
-
- if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
- if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {
- if (!mFirstEnterBMMForm) {
- //
- // BMMUiLib depends on LegacyUi library to show legacy menus.
- // If we want to show Legacy menus correctly in BMM page,
- // we must do it after the LegacyUi library has already been initialized.
- // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
- // So we do the tasks which are related to legacy menus here.
- // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
- // 2. Re-scan the BootOption menus (including the legacy boot option).
- //
- CustomizeMenus ();
- EfiBootManagerRefreshAllBootOption ();
- BOpt_GetBootOptions (Private);
- mFirstEnterBMMForm = TRUE;
- }
- }
- }
-
- //
- // Retrieve uncommitted data from Form Browser
- //
- CurrentFakeNVMap = &Private->BmmFakeNvData;
- OldFakeNVMap = &Private->BmmOldFakeNVData;
- HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap);
-
- if (Action == EFI_BROWSER_ACTION_CHANGING) {
- if (Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- UpdatePageId (Private, QuestionId);
-
- if (QuestionId < FILE_OPTION_OFFSET) {
- if (QuestionId < CONFIG_OPTION_OFFSET) {
- switch (QuestionId) {
- case FORM_BOOT_ADD_ID:
- // Leave BMM and enter FileExplorer.
- ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);
- break;
-
- case FORM_DRV_ADD_FILE_ID:
- // Leave BMM and enter FileExplorer.
- ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);
- break;
-
- case FORM_DRV_ADD_HANDLE_ID:
- CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
- UpdateDrvAddHandlePage (Private);
- break;
-
- case FORM_BOOT_DEL_ID:
- CleanUpPage (FORM_BOOT_DEL_ID, Private);
- UpdateBootDelPage (Private);
- break;
-
- case FORM_BOOT_CHG_ID:
- case FORM_DRV_CHG_ID:
- UpdatePageBody (QuestionId, Private);
- break;
-
- case FORM_DRV_DEL_ID:
- CleanUpPage (FORM_DRV_DEL_ID, Private);
- UpdateDrvDelPage (Private);
- break;
-
- case FORM_CON_IN_ID:
- case FORM_CON_OUT_ID:
- case FORM_CON_ERR_ID:
- UpdatePageBody (QuestionId, Private);
- break;
-
- case FORM_CON_MODE_ID:
- CleanUpPage (FORM_CON_MODE_ID, Private);
- UpdateConModePage (Private);
- break;
-
- case FORM_CON_COM_ID:
- CleanUpPage (FORM_CON_COM_ID, Private);
- UpdateConCOMPage (Private);
- break;
-
- default:
- break;
- }
- } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
- Index = (UINT16)(QuestionId - TERMINAL_OPTION_OFFSET);
- Private->CurrentTerminal = Index;
-
- CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
- UpdateTerminalPage (Private);
- } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
- Index = (UINT16)(QuestionId - HANDLE_OPTION_OFFSET);
-
- NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
- ASSERT (NewMenuEntry != NULL);
- Private->HandleContext = (BM_HANDLE_CONTEXT *)NewMenuEntry->VariableContext;
-
- CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
-
- Private->MenuEntry = NewMenuEntry;
- Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
-
- UpdateDriverAddHandleDescPage (Private);
- }
- }
-
- if (QuestionId == KEY_VALUE_BOOT_FROM_FILE) {
- // Leave BMM and enter FileExplorer.
- ChooseFile (NULL, L".efi", BootFromFile, &File);
- }
- } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
- if ((Value == NULL) || (ActionRequest == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
- CleanUselessBeforeSubmit (Private);
- CurrentFakeNVMap->BootOptionChanged = FALSE;
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
- } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
- CleanUselessBeforeSubmit (Private);
- CurrentFakeNVMap->DriverOptionChanged = FALSE;
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
- } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
- //
- // Discard changes and exit formset
- //
- ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));
- ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
- ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));
- ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));
- CurrentFakeNVMap->DriverOptionChanged = FALSE;
- CurrentFakeNVMap->ForceReconnect = TRUE;
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
- } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
- //
- // Discard changes and exit formset
- //
- ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));
- ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
- ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));
- ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));
- CurrentFakeNVMap->BootOptionChanged = FALSE;
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
- } else if ((QuestionId == KEY_VALUE_BOOT_DESCRIPTION) || (QuestionId == KEY_VALUE_BOOT_OPTION)) {
- CurrentFakeNVMap->BootOptionChanged = TRUE;
- } else if ((QuestionId == KEY_VALUE_DRIVER_DESCRIPTION) || (QuestionId == KEY_VALUE_DRIVER_OPTION)) {
- CurrentFakeNVMap->DriverOptionChanged = TRUE;
- }
-
- if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
- if (Value->b) {
- //
- // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
- //
- CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
- } else {
- //
- // Means user remove the old check status.
- //
- CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
- }
- } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
- if (Value->b) {
- CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
- } else {
- CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
- }
- } else {
- switch (QuestionId) {
- case KEY_VALUE_SAVE_AND_EXIT:
- case KEY_VALUE_NO_SAVE_AND_EXIT:
- if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
- CleanUselessBeforeSubmit (Private);
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
- } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
- DiscardChangeHandler (Private, CurrentFakeNVMap);
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
- }
-
- break;
-
- case FORM_RESET:
- gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
- return EFI_UNSUPPORTED;
-
- default:
- break;
- }
- }
-
- //
- // Update the content in Terminal menu and Console menu here.
- //
- if ((QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal) ||
- (QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal) ||
- (QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal)
- )
- {
- UpdateTerminalContent (CurrentFakeNVMap);
- }
-
- if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
- UpdateConsoleContent (L"ConIn", CurrentFakeNVMap);
- } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
- UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);
- } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
- UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);
- }
- }
-
- //
- // Pass changed uncommitted data back to Form Browser
- //
- HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap, NULL);
-
- return EFI_SUCCESS;
-}
-
-/**
- Discard all changes done to the BMM pages such as Boot Order change,
- Driver order change.
-
- @param Private The BMM context data.
- @param CurrentFakeNVMap The current Fack NV Map.
-
-**/
-VOID
-DiscardChangeHandler (
- IN BMM_CALLBACK_DATA *Private,
- IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
- )
-{
- UINT16 Index;
-
- switch (Private->BmmPreviousPageId) {
- case FORM_BOOT_CHG_ID:
- CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
- break;
-
- case FORM_DRV_CHG_ID:
- CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
- break;
-
- case FORM_BOOT_DEL_ID:
- ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
- for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
- CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
- }
-
- break;
-
- case FORM_DRV_DEL_ID:
- ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
- for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
- CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
- }
-
- break;
-
- case FORM_BOOT_NEXT_ID:
- CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
- break;
-
- case FORM_TIME_OUT_ID:
- CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
- break;
-
- case FORM_DRV_ADD_HANDLE_DESC_ID:
- case FORM_DRV_ADD_FILE_ID:
- case FORM_DRV_ADD_HANDLE_ID:
- CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
- CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
- break;
-
- default:
- break;
- }
-}
-
-/**
- This function is to clean some useless data before submit changes.
-
- @param Private The BMM context data.
-
-**/
-VOID
-CleanUselessBeforeSubmit (
- IN BMM_CALLBACK_DATA *Private
- )
-{
- UINT16 Index;
-
- if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {
- for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
- if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {
- Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;
- Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;
- }
- }
- }
-
- if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {
- for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
- if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {
- Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
- Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;
- }
- }
- }
-}
-
-/**
-
- Update the menus in the BMM page.
-
-**/
-VOID
-CustomizeMenus (
- VOID
- )
-{
- VOID *StartOpCodeHandle;
- VOID *EndOpCodeHandle;
- EFI_IFR_GUID_LABEL *StartGuidLabel;
- EFI_IFR_GUID_LABEL *EndGuidLabel;
-
- //
- // Allocate space for creation of UpdateData Buffer
- //
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (StartOpCodeHandle != NULL);
-
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (EndOpCodeHandle != NULL);
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- StartGuidLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- StartGuidLabel->Number = LABEL_FORM_MAIN_START;
- //
- // Create Hii Extend Label OpCode as the end opcode
- //
- EndGuidLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- EndGuidLabel->Number = LABEL_FORM_MAIN_END;
-
- //
- // Updata Front Page form
- //
- UiCustomizeBMMPage (
- mBmmCallbackInfo->BmmHiiHandle,
- StartOpCodeHandle
- );
-
- HiiUpdateForm (
- mBmmCallbackInfo->BmmHiiHandle,
- &mBootMaintGuid,
- FORM_MAIN_ID,
- StartOpCodeHandle,
- EndOpCodeHandle
- );
-
- HiiFreeOpCodeHandle (StartOpCodeHandle);
- HiiFreeOpCodeHandle (EndOpCodeHandle);
-}
-
-/**
- Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
- BmmOldFakeNVData member in BMM context data.
-
- @param CallbackData The BMM context data.
-
-**/
-VOID
-InitializeBmmConfig (
- IN BMM_CALLBACK_DATA *CallbackData
- )
-{
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- UINT16 Index;
-
- ASSERT (CallbackData != NULL);
-
- //
- // Initialize data which located in BMM main page
- //
- CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;
- for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
- NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
-
- if (NewLoadContext->IsBootNext) {
- CallbackData->BmmFakeNvData.BootNext = Index;
- break;
- }
- }
-
- CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
-
- //
- // Initialize data which located in Boot Options Menu
- //
- GetBootOrder (CallbackData);
-
- //
- // Initialize data which located in Driver Options Menu
- //
- GetDriverOrder (CallbackData);
-
- //
- // Initialize data which located in Console Options Menu
- //
- GetConsoleOutMode (CallbackData);
- GetConsoleInCheck (CallbackData);
- GetConsoleOutCheck (CallbackData);
- GetConsoleErrCheck (CallbackData);
- GetTerminalAttribute (CallbackData);
-
- CallbackData->BmmFakeNvData.ForceReconnect = TRUE;
-
- //
- // Backup Initialize BMM configuartion data to BmmOldFakeNVData
- //
- CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
-}
-
-/**
- Initialized all Menu Option List.
-
- @param CallbackData The BMM context data.
-
-**/
-VOID
-InitAllMenu (
- IN BMM_CALLBACK_DATA *CallbackData
- )
-{
- InitializeListHead (&BootOptionMenu.Head);
- InitializeListHead (&DriverOptionMenu.Head);
- BOpt_GetBootOptions (CallbackData);
- BOpt_GetDriverOptions (CallbackData);
- BOpt_FindDrivers ();
- InitializeListHead (&ConsoleInpMenu.Head);
- InitializeListHead (&ConsoleOutMenu.Head);
- InitializeListHead (&ConsoleErrMenu.Head);
- InitializeListHead (&TerminalMenu.Head);
- LocateSerialIo ();
- GetAllConsoles ();
- mAllMenuInit = TRUE;
-}
-
-/**
- Free up all Menu Option list.
-
-**/
-VOID
-FreeAllMenu (
- VOID
- )
-{
- if (!mAllMenuInit) {
- return;
- }
-
- BOpt_FreeMenu (&BootOptionMenu);
- BOpt_FreeMenu (&DriverOptionMenu);
- BOpt_FreeMenu (&DriverMenu);
- FreeAllConsoles ();
- mAllMenuInit = FALSE;
-}
-
-/**
- Initial the boot mode related parameters.
-
-**/
-VOID
-BmmInitialBootModeInfo (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
- UINTN BootTextColumn;
- UINTN BootTextRow;
-
- if (mBmmModeInitialized) {
- return;
- }
-
- //
- // After the console is ready, get current video resolution
- // and text mode before launching setup at first time.
- //
- Status = gBS->HandleProtocol (
- gST->ConsoleOutHandle,
- &gEfiGraphicsOutputProtocolGuid,
- (VOID **)&GraphicsOutput
- );
- if (EFI_ERROR (Status)) {
- GraphicsOutput = NULL;
- }
-
- Status = gBS->HandleProtocol (
- gST->ConsoleOutHandle,
- &gEfiSimpleTextOutProtocolGuid,
- (VOID **)&SimpleTextOut
- );
- if (EFI_ERROR (Status)) {
- SimpleTextOut = NULL;
- }
-
- if (GraphicsOutput != NULL) {
- //
- // Get current video resolution and text mode.
- //
- mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
- mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
- }
-
- if (SimpleTextOut != NULL) {
- Status = SimpleTextOut->QueryMode (
- SimpleTextOut,
- SimpleTextOut->Mode->Mode,
- &BootTextColumn,
- &BootTextRow
- );
- mBmmBootTextModeColumn = (UINT32)BootTextColumn;
- mBmmBootTextModeRow = (UINT32)BootTextRow;
- }
-
- //
- // Get user defined text mode for setup.
- //
- mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
- mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
- mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
- mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
-
- mBmmModeInitialized = TRUE;
-}
-
-/**
-
- Install Boot Maintenance Manager Menu driver.
-
- @param ImageHandle The image handle.
- @param SystemTable The system table.
-
- @retval EFI_SUCEESS Install Boot manager menu success.
- @retval Other Return error status.
-
-**/
-EFI_STATUS
-EFIAPI
-BootMaintenanceManagerUiLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- EFI_STATUS Status;
- UINT8 *Ptr;
-
- Status = EFI_SUCCESS;
-
- //
- // Install Device Path Protocol and Config Access protocol to driver handle
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &mBmmCallbackInfo->BmmDriverHandle,
- &gEfiDevicePathProtocolGuid,
- &mBmmHiiVendorDevicePath,
- &gEfiHiiConfigAccessProtocolGuid,
- &mBmmCallbackInfo->BmmConfigAccess,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Post our Boot Maint VFR binary to the HII database.
- //
- mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
- &mBootMaintGuid,
- mBmmCallbackInfo->BmmDriverHandle,
- BootMaintenanceManagerBin,
- BootMaintenanceManagerUiLibStrings,
- NULL
- );
- ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);
-
- //
- // Locate Formbrowser2 protocol
- //
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&mBmmCallbackInfo->FormBrowser2);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Create LoadOption in BmmCallbackInfo for Driver Callback
- //
- Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
- ASSERT (Ptr != NULL);
-
- //
- // Initialize Bmm callback data.
- //
- mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *)Ptr;
- Ptr += sizeof (BM_LOAD_CONTEXT);
-
- mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *)Ptr;
- Ptr += sizeof (BM_FILE_CONTEXT);
-
- mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *)Ptr;
- Ptr += sizeof (BM_HANDLE_CONTEXT);
-
- mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *)Ptr;
-
- mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
- mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
-
- InitAllMenu (mBmmCallbackInfo);
-
- CreateUpdateData ();
- //
- // Update boot maintenance manager page
- //
- InitializeBmmConfig (mBmmCallbackInfo);
-
- BmmInitialBootModeInfo ();
-
- return EFI_SUCCESS;
-}
-
-/**
- Unloads the application and its installed protocol.
-
- @param ImageHandle Handle that identifies the image to be unloaded.
- @param SystemTable The system table.
-
- @retval EFI_SUCCESS The image has been unloaded.
-
-**/
-EFI_STATUS
-EFIAPI
-BootMaintenanceManagerUiLibDestructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- if (mStartOpCodeHandle != NULL) {
- HiiFreeOpCodeHandle (mStartOpCodeHandle);
- }
-
- if (mEndOpCodeHandle != NULL) {
- HiiFreeOpCodeHandle (mEndOpCodeHandle);
- }
-
- FreeAllMenu ();
-
- //
- // Remove our IFR data from HII database
- //
- HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);
-
- gBS->UninstallMultipleProtocolInterfaces (
- mBmmCallbackInfo->BmmDriverHandle,
- &gEfiDevicePathProtocolGuid,
- &mBmmHiiVendorDevicePath,
- &gEfiHiiConfigAccessProtocolGuid,
- &mBmmCallbackInfo->BmmConfigAccess,
- NULL
- );
-
- FreePool (mBmmCallbackInfo->LoadContext);
- mBmmCallbackInfo->BmmDriverHandle = NULL;
-
- return EFI_SUCCESS;
-}
+/** @file
+The functions for Boot Maintainence Main menu.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BootMaintenanceManager.h"
+
+#define FRONT_PAGE_KEY_OFFSET 0x4000
+//
+// Boot video resolution and text mode.
+//
+UINT32 mBmmBootHorizontalResolution = 0;
+UINT32 mBmmBootVerticalResolution = 0;
+UINT32 mBmmBootTextModeColumn = 0;
+UINT32 mBmmBootTextModeRow = 0;
+//
+// BIOS setup video resolution and text mode.
+//
+UINT32 mBmmSetupTextModeColumn = 0;
+UINT32 mBmmSetupTextModeRow = 0;
+UINT32 mBmmSetupHorizontalResolution = 0;
+UINT32 mBmmSetupVerticalResolution = 0;
+
+BOOLEAN mBmmModeInitialized = FALSE;
+
+EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ //
+ // {165A028F-0BB2-4b5f-8747-77592E3F6499}
+ //
+ { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 }
+ }
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;
+
+CHAR16 mBootMaintStorageName[] = L"BmmData";
+BMM_CALLBACK_DATA gBootMaintenancePrivate = {
+ BMM_CALLBACK_DATA_SIGNATURE,
+ NULL,
+ NULL,
+ {
+ BootMaintExtractConfig,
+ BootMaintRouteConfig,
+ BootMaintCallback
+ }
+};
+
+BMM_CALLBACK_DATA *mBmmCallbackInfo = &gBootMaintenancePrivate;
+BOOLEAN mAllMenuInit = FALSE;
+BOOLEAN mFirstEnterBMMForm = FALSE;
+
+/**
+ Init all memu.
+
+ @param CallbackData The BMM context data.
+
+**/
+VOID
+InitAllMenu (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+/**
+ Free up all Menu Option list.
+
+**/
+VOID
+FreeAllMenu (
+ VOID
+ );
+
+/**
+
+ Update the menus in the BMM page.
+
+**/
+VOID
+CustomizeMenus (
+ VOID
+ );
+
+/**
+ This function will change video resolution and text mode
+ according to defined setup mode or defined boot mode
+
+ @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
+
+ @retval EFI_SUCCESS Mode is changed successfully.
+ @retval Others Mode failed to be changed.
+
+**/
+EFI_STATUS
+BmmSetConsoleMode (
+ BOOLEAN IsSetupMode
+ )
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
+ UINTN SizeOfInfo;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINT32 MaxGopMode;
+ UINT32 MaxTextMode;
+ UINT32 ModeNumber;
+ UINT32 NewHorizontalResolution;
+ UINT32 NewVerticalResolution;
+ UINT32 NewColumns;
+ UINT32 NewRows;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN CurrentColumn;
+ UINTN CurrentRow;
+
+ MaxGopMode = 0;
+ MaxTextMode = 0;
+
+ //
+ // Get current video resolution and text mode
+ //
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **)&GraphicsOutput
+ );
+ if (EFI_ERROR (Status)) {
+ GraphicsOutput = NULL;
+ }
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID **)&SimpleTextOut
+ );
+ if (EFI_ERROR (Status)) {
+ SimpleTextOut = NULL;
+ }
+
+ if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsSetupMode) {
+ //
+ // The required resolution and text mode is setup mode.
+ //
+ NewHorizontalResolution = mBmmSetupHorizontalResolution;
+ NewVerticalResolution = mBmmSetupVerticalResolution;
+ NewColumns = mBmmSetupTextModeColumn;
+ NewRows = mBmmSetupTextModeRow;
+ } else {
+ //
+ // The required resolution and text mode is boot mode.
+ //
+ NewHorizontalResolution = mBmmBootHorizontalResolution;
+ NewVerticalResolution = mBmmBootVerticalResolution;
+ NewColumns = mBmmBootTextModeColumn;
+ NewRows = mBmmBootTextModeRow;
+ }
+
+ if (GraphicsOutput != NULL) {
+ MaxGopMode = GraphicsOutput->Mode->MaxMode;
+ }
+
+ if (SimpleTextOut != NULL) {
+ MaxTextMode = SimpleTextOut->Mode->MaxMode;
+ }
+
+ //
+ // 1. If current video resolution is same with required video resolution,
+ // video resolution need not be changed.
+ // 1.1. If current text mode is same with required text mode, text mode need not be changed.
+ // 1.2. If current text mode is different from required text mode, text mode need be changed.
+ // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
+ //
+ for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
+ Status = GraphicsOutput->QueryMode (
+ GraphicsOutput,
+ ModeNumber,
+ &SizeOfInfo,
+ &Info
+ );
+ if (!EFI_ERROR (Status)) {
+ if ((Info->HorizontalResolution == NewHorizontalResolution) &&
+ (Info->VerticalResolution == NewVerticalResolution))
+ {
+ if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
+ (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution))
+ {
+ //
+ // Current resolution is same with required resolution, check if text mode need be set
+ //
+ Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
+ ASSERT_EFI_ERROR (Status);
+ if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
+ //
+ // If current text mode is same with required text mode. Do nothing
+ //
+ FreePool (Info);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // If current text mode is different from required text mode. Set new video mode
+ //
+ for (Index = 0; Index < MaxTextMode; Index++) {
+ Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
+ if (!EFI_ERROR (Status)) {
+ if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
+ //
+ // Required text mode is supported, set it.
+ //
+ Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Update text mode PCD.
+ //
+ Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);
+ ASSERT_EFI_ERROR (Status);
+ FreePool (Info);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ if (Index == MaxTextMode) {
+ //
+ // If required text mode is not supported, return error.
+ //
+ FreePool (Info);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ } else {
+ //
+ // If current video resolution is not same with the new one, set new video resolution.
+ // In this case, the driver which produces simple text out need be restarted.
+ //
+ Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
+ if (!EFI_ERROR (Status)) {
+ FreePool (Info);
+ break;
+ }
+ }
+ }
+
+ FreePool (Info);
+ }
+ }
+
+ if (ModeNumber == MaxGopMode) {
+ //
+ // If the resolution is not supported, return error.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Set PCD to Inform GraphicsConsole to change video resolution.
+ // Set PCD to Inform Consplitter to change text mode.
+ //
+ Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdConOutColumn, NewColumns);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdConOutRow, NewRows);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Video mode is changed, so restart graphics console driver and higher level driver.
+ // Reconnect graphics console driver and higher level driver.
+ // Locate all the handles with GOP protocol and reconnect it.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleTextOutProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function converts an input device structure to a Unicode string.
+
+ @param DevPath A pointer to the device path structure.
+
+ @return A new allocated Unicode string that represents the device path.
+
+**/
+CHAR16 *
+UiDevicePathToStr (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ToText;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
+
+ if (DevPath == NULL) {
+ return NULL;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathToTextProtocolGuid,
+ NULL,
+ (VOID **)&DevPathToText
+ );
+ ASSERT_EFI_ERROR (Status);
+ ToText = DevPathToText->ConvertDevicePathToText (
+ DevPath,
+ FALSE,
+ TRUE
+ );
+ ASSERT (ToText != NULL);
+ return ToText;
+}
+
+/**
+ Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
+ The caller is responsible for freeing the allocated buffer using FreePool().
+
+ @param DevicePath Device path.
+
+ @return A new allocated string that represents the file name.
+
+**/
+CHAR16 *
+ExtractFileNameFromDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CHAR16 *String;
+ CHAR16 *MatchString;
+ CHAR16 *LastMatch;
+ CHAR16 *FileName;
+ UINTN Length;
+
+ ASSERT (DevicePath != NULL);
+
+ String = UiDevicePathToStr (DevicePath);
+ MatchString = String;
+ LastMatch = String;
+ FileName = NULL;
+
+ while (MatchString != NULL) {
+ LastMatch = MatchString + 1;
+ MatchString = StrStr (LastMatch, L"\\");
+ }
+
+ Length = StrLen (LastMatch);
+ FileName = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), LastMatch);
+ if (FileName != NULL) {
+ *(FileName + Length) = 0;
+ }
+
+ FreePool (String);
+
+ return FileName;
+}
+
+/**
+ Extract device path for given HII handle and class guid.
+
+ @param Handle The HII handle.
+
+ @retval NULL Fail to get the device path string.
+ @return PathString Get the device path string.
+
+**/
+CHAR16 *
+BmmExtractDevicePathFromHiiHandle (
+ IN EFI_HII_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DriverHandle;
+
+ ASSERT (Handle != NULL);
+
+ if (Handle == NULL) {
+ return NULL;
+ }
+
+ Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ //
+ // Get device path string.
+ //
+ return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
+}
+
+/**
+ Converts the unicode character of the string from uppercase to lowercase.
+ This is a internal function.
+
+ @param ConfigString String to be converted
+
+**/
+VOID
+HiiToLower (
+ IN EFI_STRING ConfigString
+ )
+{
+ EFI_STRING String;
+ BOOLEAN Lower;
+
+ ASSERT (ConfigString != NULL);
+
+ //
+ // Convert all hex digits in range [A-F] in the configuration header to [a-f]
+ //
+ for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
+ if (*String == L'=') {
+ Lower = TRUE;
+ } else if (*String == L'&') {
+ Lower = FALSE;
+ } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
+ *String = (CHAR16)(*String - L'A' + L'a');
+ }
+ }
+}
+
+/**
+ Update the progress string through the offset value.
+
+ @param Offset The offset value
+ @param Configuration Point to the configuration string.
+
+**/
+EFI_STRING
+UpdateProgress (
+ IN UINTN Offset,
+ IN EFI_STRING Configuration
+ )
+{
+ UINTN Length;
+ EFI_STRING StringPtr;
+ EFI_STRING ReturnString;
+
+ StringPtr = NULL;
+ ReturnString = NULL;
+
+ //
+ // &OFFSET=XXXX followed by a Null-terminator.
+ // Length = StrLen (L"&OFFSET=") + 4 + 1
+ //
+ Length = StrLen (L"&OFFSET=") + 4 + 1;
+
+ StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));
+
+ if (StringPtr == NULL) {
+ return NULL;
+ }
+
+ UnicodeSPrint (
+ StringPtr,
+ (8 + 4 + 1) * sizeof (CHAR16),
+ L"&OFFSET=%04x",
+ Offset
+ );
+
+ ReturnString = StrStr (Configuration, StringPtr);
+
+ if (ReturnString == NULL) {
+ //
+ // If doesn't find the string in Configuration, convert the string to lower case then search again.
+ //
+ HiiToLower (StringPtr);
+ ReturnString = StrStr (Configuration, StringPtr);
+ }
+
+ FreePool (StringPtr);
+
+ return ReturnString;
+}
+
+/**
+ Update the terminal content in TerminalMenu.
+
+ @param BmmData The BMM fake NV data.
+
+**/
+VOID
+UpdateTerminalContent (
+ IN BMM_FAKE_NV_DATA *BmmData
+ )
+{
+ UINT16 Index;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+ BM_MENU_ENTRY *NewMenuEntry;
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ ASSERT (NewMenuEntry != NULL);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
+ NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];
+ ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));
+ NewTerminalContext->BaudRate = BaudRateList[BmmData->COMBaudRate[Index]].Value;
+ NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];
+ ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));
+ NewTerminalContext->DataBits = (UINT8)DataBitsList[BmmData->COMDataRate[Index]].Value;
+ NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];
+ ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));
+ NewTerminalContext->StopBits = (UINT8)StopBitsList[BmmData->COMStopBits[Index]].Value;
+ NewTerminalContext->ParityIndex = BmmData->COMParity[Index];
+ ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));
+ NewTerminalContext->Parity = (UINT8)ParityList[BmmData->COMParity[Index]].Value;
+ NewTerminalContext->TerminalType = BmmData->COMTerminalType[Index];
+ NewTerminalContext->FlowControl = BmmData->COMFlowControl[Index];
+ ChangeTerminalDevicePath (
+ NewTerminalContext->DevicePath,
+ FALSE
+ );
+ }
+}
+
+/**
+ Update the console content in ConsoleMenu.
+
+ @param ConsoleName The name for the console device type.
+ @param BmmData The BMM fake NV data.
+
+**/
+VOID
+UpdateConsoleContent (
+ IN CHAR16 *ConsoleName,
+ IN BMM_FAKE_NV_DATA *BmmData
+ )
+{
+ UINT16 Index;
+ BM_CONSOLE_CONTEXT *NewConsoleContext;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+ BM_MENU_ENTRY *NewMenuEntry;
+
+ if (StrCmp (ConsoleName, L"ConIn") == 0) {
+ for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index < MAX_MENU_NUMBER);
+ NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
+ NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];
+ }
+ }
+
+ if (StrCmp (ConsoleName, L"ConOut") == 0) {
+ for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index < MAX_MENU_NUMBER);
+ NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
+ NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];
+ }
+ }
+
+ if (StrCmp (ConsoleName, L"ErrOut") == 0) {
+ for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index < MAX_MENU_NUMBER);
+ NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
+ ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
+ NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];
+ }
+ }
+}
+
+/**
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Request A null-terminated Unicode string in <ConfigRequest> format.
+ @param Progress On return, points to a character in the Request string.
+ Points to the string's null terminator if request was successful.
+ Points to the most recent '&' before the first failing name/value
+ pair (or the beginning of the string if the failure is in the
+ first name/value pair) if the request was not successful.
+ @param Results A null-terminated Unicode string in <ConfigAltResp> format which
+ has all values filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
+ @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+BootMaintExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ BMM_CALLBACK_DATA *Private;
+ EFI_STRING ConfigRequestHdr;
+ EFI_STRING ConfigRequest;
+ BOOLEAN AllocatedRequest;
+ UINTN Size;
+
+ if ((Progress == NULL) || (Results == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Progress = Request;
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ AllocatedRequest = FALSE;
+ Size = 0;
+
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request has no request element, construct full request string.
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ }
+
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *)&Private->BmmFakeNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ ConfigRequest = NULL;
+ }
+
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job. Currently not implemented.
+
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+ @param[out] Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found.
+**/
+EFI_STATUS
+EFIAPI
+BootMaintRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
+ BMM_FAKE_NV_DATA *NewBmmData;
+ BMM_FAKE_NV_DATA *OldBmmData;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 Index;
+ BOOLEAN TerminalAttChange;
+ BMM_CALLBACK_DATA *Private;
+ UINTN Offset;
+
+ if (Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Progress = Configuration;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: there is no name for Name/Value storage, only GUID will be checked
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiConfigRoutingProtocolGuid,
+ NULL,
+ (VOID **)&ConfigRouting
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);
+ //
+ // Get Buffer Storage data from EFI variable
+ //
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);
+ OldBmmData = &Private->BmmOldFakeNVData;
+ NewBmmData = &Private->BmmFakeNvData;
+ Offset = 0;
+ //
+ // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+ //
+ Status = ConfigRouting->ConfigToBlock (
+ ConfigRouting,
+ Configuration,
+ (UINT8 *)NewBmmData,
+ &BufferSize,
+ Progress
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Compare new and old BMM configuration data and only do action for modified item to
+ // avoid setting unnecessary non-volatile variable
+ //
+
+ //
+ // Check data which located in BMM main page and save the settings if need
+ //
+ if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
+ Status = Var_UpdateBootNext (Private);
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);
+ goto Exit;
+ }
+ }
+
+ //
+ // Check data which located in Boot Options Menu and save the settings if need
+ //
+ if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
+ for (Index = 0;
+ ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
+ Index++)
+ {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
+ NewBmmData->BootOptionDel[Index] = FALSE;
+ NewBmmData->BootOptionDelMark[Index] = FALSE;
+ }
+
+ Status = Var_DelBootOption ();
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
+ Status = Var_UpdateBootOrder (Private);
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {
+ Status = gRT->SetVariable (
+ L"Timeout",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (UINT16),
+ &(NewBmmData->BootTimeOut)
+ );
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);
+ goto Exit;
+ }
+
+ Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
+ }
+
+ //
+ // Check data which located in Driver Options Menu and save the settings if need
+ //
+ if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
+ for (Index = 0;
+ ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
+ Index++)
+ {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
+ NewBmmData->DriverOptionDel[Index] = FALSE;
+ NewBmmData->DriverOptionDelMark[Index] = FALSE;
+ }
+
+ Status = Var_DelDriverOption ();
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
+ Status = Var_UpdateDriverOrder (Private);
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {
+ Status = Var_UpdateConMode (Private);
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);
+ goto Exit;
+ }
+ }
+
+ TerminalAttChange = FALSE;
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ //
+ // only need update modified items
+ //
+ if ((CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0) &&
+ (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0) &&
+ (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0) &&
+ (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0) &&
+ (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0) &&
+ (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0))
+ {
+ continue;
+ }
+
+ TerminalAttChange = TRUE;
+ }
+
+ if (TerminalAttChange) {
+ if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);
+ } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);
+ } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);
+ } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);
+ } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);
+ } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);
+ }
+
+ Status = Var_UpdateConsoleInpOption ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = Var_UpdateConsoleOutOption ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = Var_UpdateErrorOutOption ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+
+ //
+ // Check data which located in Console Options Menu and save the settings if need
+ //
+ if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {
+ Status = Var_UpdateConsoleInpOption ();
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {
+ Status = Var_UpdateConsoleOutOption ();
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);
+ goto Exit;
+ }
+ }
+
+ if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {
+ Status = Var_UpdateErrorOutOption ();
+ if (EFI_ERROR (Status)) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);
+ goto Exit;
+ }
+ }
+
+ if ((CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) ||
+ (CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0))
+ {
+ Status = Var_UpdateBootOption (Private);
+ NewBmmData->BootOptionChanged = FALSE;
+ if (EFI_ERROR (Status)) {
+ if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);
+ } else {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);
+ }
+
+ goto Exit;
+ }
+
+ BOpt_GetBootOptions (Private);
+ }
+
+ if ((CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) ||
+ (CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0))
+ {
+ Status = Var_UpdateDriverOption (
+ Private,
+ Private->BmmHiiHandle,
+ NewBmmData->DriverDescriptionData,
+ NewBmmData->DriverOptionalData,
+ NewBmmData->ForceReconnect
+ );
+ NewBmmData->DriverOptionChanged = FALSE;
+ NewBmmData->ForceReconnect = TRUE;
+ if (EFI_ERROR (Status)) {
+ if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);
+ } else {
+ Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);
+ }
+
+ goto Exit;
+ }
+
+ BOpt_GetDriverOptions (Private);
+ }
+
+ //
+ // After user do the save action, need to update OldBmmData.
+ //
+ CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
+
+ return EFI_SUCCESS;
+
+Exit:
+ //
+ // Fail to save the data, update the progress string.
+ //
+ *Progress = UpdateProgress (Offset, Configuration);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ return Status;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+}
+
+/**
+ This function processes the results of changes in configuration.
+
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original exporting driver.
+ @param ActionRequest On return, points to the action requested by the callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
+ @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
+**/
+EFI_STATUS
+EFIAPI
+BootMaintCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ BMM_CALLBACK_DATA *Private;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BMM_FAKE_NV_DATA *CurrentFakeNVMap;
+ BMM_FAKE_NV_DATA *OldFakeNVMap;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *File;
+
+ if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
+ //
+ // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);
+
+ if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
+ if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {
+ if (!mFirstEnterBMMForm) {
+ //
+ // BMMUiLib depends on LegacyUi library to show legacy menus.
+ // If we want to show Legacy menus correctly in BMM page,
+ // we must do it after the LegacyUi library has already been initialized.
+ // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
+ // So we do the tasks which are related to legacy menus here.
+ // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
+ // 2. Re-scan the BootOption menus (including the legacy boot option).
+ //
+ CustomizeMenus ();
+ EfiBootManagerRefreshAllBootOption ();
+ BOpt_GetBootOptions (Private);
+ mFirstEnterBMMForm = TRUE;
+ }
+ }
+ }
+
+ //
+ // Retrieve uncommitted data from Form Browser
+ //
+ CurrentFakeNVMap = &Private->BmmFakeNvData;
+ OldFakeNVMap = &Private->BmmOldFakeNVData;
+ HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap);
+
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ if (Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UpdatePageId (Private, QuestionId);
+
+ if (QuestionId < FILE_OPTION_OFFSET) {
+ if (QuestionId < CONFIG_OPTION_OFFSET) {
+ switch (QuestionId) {
+ case FORM_BOOT_ADD_ID:
+ // Leave BMM and enter FileExplorer.
+ ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);
+ break;
+
+ case FORM_DRV_ADD_FILE_ID:
+ // Leave BMM and enter FileExplorer.
+ ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);
+ break;
+
+ case FORM_DRV_ADD_HANDLE_ID:
+ CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
+ UpdateDrvAddHandlePage (Private);
+ break;
+
+ case FORM_BOOT_DEL_ID:
+ CleanUpPage (FORM_BOOT_DEL_ID, Private);
+ UpdateBootDelPage (Private);
+ break;
+
+ case FORM_BOOT_CHG_ID:
+ case FORM_DRV_CHG_ID:
+ UpdatePageBody (QuestionId, Private);
+ break;
+
+ case FORM_DRV_DEL_ID:
+ CleanUpPage (FORM_DRV_DEL_ID, Private);
+ UpdateDrvDelPage (Private);
+ break;
+
+ case FORM_CON_IN_ID:
+ case FORM_CON_OUT_ID:
+ case FORM_CON_ERR_ID:
+ UpdatePageBody (QuestionId, Private);
+ break;
+
+ case FORM_CON_MODE_ID:
+ CleanUpPage (FORM_CON_MODE_ID, Private);
+ UpdateConModePage (Private);
+ break;
+
+ case FORM_CON_COM_ID:
+ CleanUpPage (FORM_CON_COM_ID, Private);
+ UpdateConCOMPage (Private);
+ break;
+
+ default:
+ break;
+ }
+ } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
+ Index = (UINT16)(QuestionId - TERMINAL_OPTION_OFFSET);
+ Private->CurrentTerminal = Index;
+
+ CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
+ UpdateTerminalPage (Private);
+ } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
+ Index = (UINT16)(QuestionId - HANDLE_OPTION_OFFSET);
+
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
+ ASSERT (NewMenuEntry != NULL);
+ Private->HandleContext = (BM_HANDLE_CONTEXT *)NewMenuEntry->VariableContext;
+
+ CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
+
+ Private->MenuEntry = NewMenuEntry;
+ Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
+
+ UpdateDriverAddHandleDescPage (Private);
+ }
+ }
+
+ if (QuestionId == KEY_VALUE_BOOT_FROM_FILE) {
+ // Leave BMM and enter FileExplorer.
+ ChooseFile (NULL, L".efi", BootFromFile, &File);
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ if ((Value == NULL) || (ActionRequest == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
+ CleanUselessBeforeSubmit (Private);
+ CurrentFakeNVMap->BootOptionChanged = FALSE;
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
+ CleanUselessBeforeSubmit (Private);
+ CurrentFakeNVMap->DriverOptionChanged = FALSE;
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
+ //
+ // Discard changes and exit formset
+ //
+ ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));
+ ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
+ ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));
+ ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));
+ CurrentFakeNVMap->DriverOptionChanged = FALSE;
+ CurrentFakeNVMap->ForceReconnect = TRUE;
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
+ //
+ // Discard changes and exit formset
+ //
+ ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));
+ ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
+ ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));
+ ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));
+ CurrentFakeNVMap->BootOptionChanged = FALSE;
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ } else if ((QuestionId == KEY_VALUE_BOOT_DESCRIPTION) || (QuestionId == KEY_VALUE_BOOT_OPTION)) {
+ CurrentFakeNVMap->BootOptionChanged = TRUE;
+ } else if ((QuestionId == KEY_VALUE_DRIVER_DESCRIPTION) || (QuestionId == KEY_VALUE_DRIVER_OPTION)) {
+ CurrentFakeNVMap->DriverOptionChanged = TRUE;
+ }
+
+ if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
+ if (Value->b) {
+ //
+ // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
+ //
+ CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
+ } else {
+ //
+ // Means user remove the old check status.
+ //
+ CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
+ }
+ } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
+ if (Value->b) {
+ CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
+ } else {
+ CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
+ }
+ } else {
+ switch (QuestionId) {
+ case KEY_VALUE_SAVE_AND_EXIT:
+ case KEY_VALUE_NO_SAVE_AND_EXIT:
+ if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
+ CleanUselessBeforeSubmit (Private);
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
+ DiscardChangeHandler (Private, CurrentFakeNVMap);
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ }
+
+ break;
+
+ case FORM_RESET:
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+ return EFI_UNSUPPORTED;
+
+ default:
+ break;
+ }
+ }
+
+ //
+ // Update the content in Terminal menu and Console menu here.
+ //
+ if ((QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal) ||
+ (QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal) ||
+ (QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal)
+ )
+ {
+ UpdateTerminalContent (CurrentFakeNVMap);
+ }
+
+ if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
+ UpdateConsoleContent (L"ConIn", CurrentFakeNVMap);
+ } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
+ UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);
+ } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
+ UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);
+ }
+ }
+
+ //
+ // Pass changed uncommitted data back to Form Browser
+ //
+ HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap, NULL);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Discard all changes done to the BMM pages such as Boot Order change,
+ Driver order change.
+
+ @param Private The BMM context data.
+ @param CurrentFakeNVMap The current Fack NV Map.
+
+**/
+VOID
+DiscardChangeHandler (
+ IN BMM_CALLBACK_DATA *Private,
+ IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
+ )
+{
+ UINT16 Index;
+
+ switch (Private->BmmPreviousPageId) {
+ case FORM_BOOT_CHG_ID:
+ CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
+ break;
+
+ case FORM_DRV_CHG_ID:
+ CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
+ break;
+
+ case FORM_BOOT_DEL_ID:
+ ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
+ }
+
+ break;
+
+ case FORM_DRV_DEL_ID:
+ ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
+ }
+
+ break;
+
+ case FORM_BOOT_NEXT_ID:
+ CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
+ break;
+
+ case FORM_TIME_OUT_ID:
+ CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
+ break;
+
+ case FORM_DRV_ADD_HANDLE_DESC_ID:
+ case FORM_DRV_ADD_FILE_ID:
+ case FORM_DRV_ADD_HANDLE_ID:
+ CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
+ CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ This function is to clean some useless data before submit changes.
+
+ @param Private The BMM context data.
+
+**/
+VOID
+CleanUselessBeforeSubmit (
+ IN BMM_CALLBACK_DATA *Private
+ )
+{
+ UINT16 Index;
+
+ if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {
+ Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;
+ Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;
+ }
+ }
+ }
+
+ if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {
+ Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
+ Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;
+ }
+ }
+ }
+}
+
+/**
+
+ Update the menus in the BMM page.
+
+**/
+VOID
+CustomizeMenus (
+ VOID
+ )
+{
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartGuidLabel;
+ EFI_IFR_GUID_LABEL *EndGuidLabel;
+
+ //
+ // Allocate space for creation of UpdateData Buffer
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartGuidLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartGuidLabel->Number = LABEL_FORM_MAIN_START;
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndGuidLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndGuidLabel->Number = LABEL_FORM_MAIN_END;
+
+ //
+ // Updata Front Page form
+ //
+ UiCustomizeBMMPage (
+ mBmmCallbackInfo->BmmHiiHandle,
+ StartOpCodeHandle
+ );
+
+ HiiUpdateForm (
+ mBmmCallbackInfo->BmmHiiHandle,
+ &mBootMaintGuid,
+ FORM_MAIN_ID,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+}
+
+/**
+ Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
+ BmmOldFakeNVData member in BMM context data.
+
+ @param CallbackData The BMM context data.
+
+**/
+VOID
+InitializeBmmConfig (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 Index;
+
+ ASSERT (CallbackData != NULL);
+
+ //
+ // Initialize data which located in BMM main page
+ //
+ CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
+
+ if (NewLoadContext->IsBootNext) {
+ CallbackData->BmmFakeNvData.BootNext = Index;
+ break;
+ }
+ }
+
+ CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
+
+ //
+ // Initialize data which located in Boot Options Menu
+ //
+ GetBootOrder (CallbackData);
+
+ //
+ // Initialize data which located in Driver Options Menu
+ //
+ GetDriverOrder (CallbackData);
+
+ //
+ // Initialize data which located in Console Options Menu
+ //
+ GetConsoleOutMode (CallbackData);
+ GetConsoleInCheck (CallbackData);
+ GetConsoleOutCheck (CallbackData);
+ GetConsoleErrCheck (CallbackData);
+ GetTerminalAttribute (CallbackData);
+
+ CallbackData->BmmFakeNvData.ForceReconnect = TRUE;
+
+ //
+ // Backup Initialize BMM configuartion data to BmmOldFakeNVData
+ //
+ CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
+}
+
+/**
+ Initialized all Menu Option List.
+
+ @param CallbackData The BMM context data.
+
+**/
+VOID
+InitAllMenu (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ InitializeListHead (&BootOptionMenu.Head);
+ InitializeListHead (&DriverOptionMenu.Head);
+ BOpt_GetBootOptions (CallbackData);
+ BOpt_GetDriverOptions (CallbackData);
+ BOpt_FindDrivers ();
+ InitializeListHead (&ConsoleInpMenu.Head);
+ InitializeListHead (&ConsoleOutMenu.Head);
+ InitializeListHead (&ConsoleErrMenu.Head);
+ InitializeListHead (&TerminalMenu.Head);
+ LocateSerialIo ();
+ GetAllConsoles ();
+ mAllMenuInit = TRUE;
+}
+
+/**
+ Free up all Menu Option list.
+
+**/
+VOID
+FreeAllMenu (
+ VOID
+ )
+{
+ if (!mAllMenuInit) {
+ return;
+ }
+
+ BOpt_FreeMenu (&BootOptionMenu);
+ BOpt_FreeMenu (&DriverOptionMenu);
+ BOpt_FreeMenu (&DriverMenu);
+ FreeAllConsoles ();
+ mAllMenuInit = FALSE;
+}
+
+/**
+ Initial the boot mode related parameters.
+
+**/
+VOID
+BmmInitialBootModeInfo (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
+ UINTN BootTextColumn;
+ UINTN BootTextRow;
+
+ if (mBmmModeInitialized) {
+ return;
+ }
+
+ //
+ // After the console is ready, get current video resolution
+ // and text mode before launching setup at first time.
+ //
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **)&GraphicsOutput
+ );
+ if (EFI_ERROR (Status)) {
+ GraphicsOutput = NULL;
+ }
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID **)&SimpleTextOut
+ );
+ if (EFI_ERROR (Status)) {
+ SimpleTextOut = NULL;
+ }
+
+ if (GraphicsOutput != NULL) {
+ //
+ // Get current video resolution and text mode.
+ //
+ mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
+ mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
+ }
+
+ if (SimpleTextOut != NULL) {
+ Status = SimpleTextOut->QueryMode (
+ SimpleTextOut,
+ SimpleTextOut->Mode->Mode,
+ &BootTextColumn,
+ &BootTextRow
+ );
+ mBmmBootTextModeColumn = (UINT32)BootTextColumn;
+ mBmmBootTextModeRow = (UINT32)BootTextRow;
+ }
+
+ //
+ // Get user defined text mode for setup.
+ //
+ mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+ mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
+ mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
+ mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
+
+ mBmmModeInitialized = TRUE;
+}
+
+/**
+
+ Install Boot Maintenance Manager Menu driver.
+
+ @param ImageHandle The image handle.
+ @param SystemTable The system table.
+
+ @retval EFI_SUCEESS Install Boot manager menu success.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+BootMaintenanceManagerUiLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ EFI_STATUS Status;
+ UINT8 *Ptr;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Install Device Path Protocol and Config Access protocol to driver handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mBmmCallbackInfo->BmmDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mBmmHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mBmmCallbackInfo->BmmConfigAccess,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Post our Boot Maint VFR binary to the HII database.
+ //
+ mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
+ &mBootMaintGuid,
+ mBmmCallbackInfo->BmmDriverHandle,
+ BootMaintenanceManagerBin,
+ BootMaintenanceManagerUiLibStrings,
+ NULL
+ );
+ ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);
+
+ //
+ // Locate Formbrowser2 protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&mBmmCallbackInfo->FormBrowser2);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create LoadOption in BmmCallbackInfo for Driver Callback
+ //
+ Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
+ ASSERT (Ptr != NULL);
+
+ //
+ // Initialize Bmm callback data.
+ //
+ mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *)Ptr;
+ Ptr += sizeof (BM_LOAD_CONTEXT);
+
+ mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *)Ptr;
+ Ptr += sizeof (BM_FILE_CONTEXT);
+
+ mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *)Ptr;
+ Ptr += sizeof (BM_HANDLE_CONTEXT);
+
+ mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *)Ptr;
+
+ mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
+ mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
+
+ InitAllMenu (mBmmCallbackInfo);
+
+ CreateUpdateData ();
+ //
+ // Update boot maintenance manager page
+ //
+ InitializeBmmConfig (mBmmCallbackInfo);
+
+ BmmInitialBootModeInfo ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unloads the application and its installed protocol.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+ @param SystemTable The system table.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+
+**/
+EFI_STATUS
+EFIAPI
+BootMaintenanceManagerUiLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ if (mEndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mEndOpCodeHandle);
+ }
+
+ FreeAllMenu ();
+
+ //
+ // Remove our IFR data from HII database
+ //
+ HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ mBmmCallbackInfo->BmmDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mBmmHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mBmmCallbackInfo->BmmConfigAccess,
+ NULL
+ );
+
+ FreePool (mBmmCallbackInfo->LoadContext);
+ mBmmCallbackInfo->BmmDriverHandle = NULL;
+
+ return EFI_SUCCESS;
+}