/** @file Dynamically update the pages. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "BootMaintenanceManager.h" /** Create the global UpdateData structure. **/ VOID CreateUpdateData ( VOID ) { // // Init OpCode Handle and Allocate space for creation of Buffer // mStartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (mStartOpCodeHandle != NULL); mEndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (mEndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; // // Create Hii Extend Label OpCode as the end opcode // mEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; mEndLabel->Number = LABEL_END; } /** Refresh the global UpdateData structure. **/ VOID RefreshUpdateData ( VOID ) { // // Free current updated date // if (mStartOpCodeHandle != NULL) { HiiFreeOpCodeHandle (mStartOpCodeHandle); } // // Create new OpCode Handle // mStartOpCodeHandle = HiiAllocateOpCodeHandle (); // // Create Hii Extend Label OpCode as the start opcode // mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; } /** Add a "Go back to main page" tag in front of the form when there are no "Apply changes" and "Discard changes" tags in the end of the form. @param CallbackData The BMM context data. **/ VOID UpdatePageStart ( IN BMM_CALLBACK_DATA *CallbackData ) { RefreshUpdateData (); mStartLabel->Number = CallbackData->BmmCurrentPageId; if (!(CallbackData->BmmAskSaveOrNot)) { // // Add a "Go back to main page" tag in front of the form when there are no // "Apply changes" and "Discard changes" tags in the end of the form. // HiiCreateGotoOpCode ( mStartOpCodeHandle, FORM_MAIN_ID, STRING_TOKEN (STR_FORM_GOTO_MAIN), STRING_TOKEN (STR_FORM_GOTO_MAIN), 0, FORM_MAIN_ID ); } } /** Create the "Apply changes" and "Discard changes" tags. And ensure user can return to the main page. @param CallbackData The BMM context data. **/ VOID UpdatePageEnd ( IN BMM_CALLBACK_DATA *CallbackData ) { // // Create the "Apply changes" and "Discard changes" tags. // if (CallbackData->BmmAskSaveOrNot) { HiiCreateSubTitleOpCode ( mStartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0 ); HiiCreateActionOpCode ( mStartOpCodeHandle, KEY_VALUE_SAVE_AND_EXIT, STRING_TOKEN (STR_SAVE_AND_EXIT), STRING_TOKEN (STR_NULL_STRING), EFI_IFR_FLAG_CALLBACK, 0 ); } // // Ensure user can return to the main page. // HiiCreateActionOpCode ( mStartOpCodeHandle, KEY_VALUE_NO_SAVE_AND_EXIT, STRING_TOKEN (STR_NO_SAVE_AND_EXIT), STRING_TOKEN (STR_NULL_STRING), EFI_IFR_FLAG_CALLBACK, 0 ); HiiUpdateForm ( CallbackData->BmmHiiHandle, &mBootMaintGuid, CallbackData->BmmCurrentPageId, mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId mEndOpCodeHandle // LABEL_END ); } /** Clean up the dynamic opcode at label and form specified by both LabelId. @param LabelId It is both the Form ID and Label ID for opcode deletion. @param CallbackData The BMM context data. **/ VOID CleanUpPage ( IN UINT16 LabelId, IN BMM_CALLBACK_DATA *CallbackData ) { RefreshUpdateData (); // // Remove all op-codes from dynamic page // mStartLabel->Number = LabelId; HiiUpdateForm ( CallbackData->BmmHiiHandle, &mBootMaintGuid, LabelId, mStartOpCodeHandle, // Label LabelId mEndOpCodeHandle // LABEL_END ); } /** Create a list of Goto Opcode for all terminal devices logged by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID. @param CallbackData The BMM context data. **/ VOID UpdateConCOMPage ( IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; UINT16 Index; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); HiiCreateGotoOpCode ( mStartOpCodeHandle, FORM_CON_COM_SETUP_ID, NewMenuEntry->DisplayStringToken, STRING_TOKEN (STR_NULL_STRING), EFI_IFR_FLAG_CALLBACK, (UINT16)(TERMINAL_OPTION_OFFSET + Index) ); } UpdatePageEnd (CallbackData); } /** Create a list of boot option from global BootOptionMenu. It allow user to delete the boot option. @param CallbackData The BMM context data. **/ VOID UpdateBootDelPage ( IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; UINT16 Index; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0]))); for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index); NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; if (NewLoadContext->IsLegacy) { continue; } NewLoadContext->Deleted = FALSE; if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) { // // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser // through HiiSetBrowserData function. // CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE; CallbackData->BmmOldFakeNVData.BootOptionDel[Index] = FALSE; } HiiCreateCheckBoxOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(BOOT_OPTION_DEL_QUESTION_ID + Index), VARSTORE_ID_BOOT_MAINT, (UINT16)(BOOT_OPTION_DEL_VAR_OFFSET + Index), NewMenuEntry->DisplayStringToken, NewMenuEntry->HelpStringToken, EFI_IFR_FLAG_CALLBACK, 0, NULL ); } UpdatePageEnd (CallbackData); } /** Create a lit of driver option from global DriverMenu. @param CallbackData The BMM context data. **/ VOID UpdateDrvAddHandlePage ( IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; UINT16 Index; CallbackData->BmmAskSaveOrNot = FALSE; UpdatePageStart (CallbackData); for (Index = 0; Index < DriverMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index); HiiCreateGotoOpCode ( mStartOpCodeHandle, FORM_DRV_ADD_HANDLE_DESC_ID, NewMenuEntry->DisplayStringToken, STRING_TOKEN (STR_NULL_STRING), EFI_IFR_FLAG_CALLBACK, (UINT16)(HANDLE_OPTION_OFFSET + Index) ); } UpdatePageEnd (CallbackData); } /** Create a lit of driver option from global DriverOptionMenu. It allow user to delete the driver option. @param CallbackData The BMM context data. **/ VOID UpdateDrvDelPage ( IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; UINT16 Index; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0]))); for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index); NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) { // // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser // through HiiSetBrowserData function. // CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE; CallbackData->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE; } HiiCreateCheckBoxOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(DRIVER_OPTION_DEL_QUESTION_ID + Index), VARSTORE_ID_BOOT_MAINT, (UINT16)(DRIVER_OPTION_DEL_VAR_OFFSET + Index), NewMenuEntry->DisplayStringToken, NewMenuEntry->HelpStringToken, EFI_IFR_FLAG_CALLBACK, 0, NULL ); } UpdatePageEnd (CallbackData); } /** Prepare the page to allow user to add description for a Driver Option. @param CallbackData The BMM context data. **/ VOID UpdateDriverAddHandleDescPage ( IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; CallbackData->BmmFakeNvData.DriverAddActive = 0x01; CallbackData->BmmFakeNvData.DriverAddForceReconnect = 0x00; CallbackData->BmmAskSaveOrNot = TRUE; NewMenuEntry = CallbackData->MenuEntry; UpdatePageStart (CallbackData); HiiCreateSubTitleOpCode ( mStartOpCodeHandle, NewMenuEntry->DisplayStringToken, 0, 0, 0 ); HiiCreateStringOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)DRV_ADD_HANDLE_DESC_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, DRV_ADD_HANDLE_DESC_VAR_OFFSET, STRING_TOKEN (STR_LOAD_OPTION_DESC), STRING_TOKEN (STR_NULL_STRING), 0, 0, 6, 75, NULL ); HiiCreateCheckBoxOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)DRV_ADD_RECON_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, DRV_ADD_RECON_VAR_OFFSET, STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON), STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON), 0, 0, NULL ); HiiCreateStringOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)DRIVER_ADD_OPTION_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, DRIVER_ADD_OPTION_VAR_OFFSET, STRING_TOKEN (STR_OPTIONAL_DATA), STRING_TOKEN (STR_NULL_STRING), 0, 0, 6, 75, NULL ); UpdatePageEnd (CallbackData); } /** Update console page. @param UpdatePageId The form ID to be updated. @param ConsoleMenu The console menu list. @param CallbackData The BMM context data. **/ VOID UpdateConsolePage ( IN UINT16 UpdatePageId, IN BM_MENU_OPTION *ConsoleMenu, IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; BM_CONSOLE_CONTEXT *NewConsoleContext; BM_TERMINAL_CONTEXT *NewTerminalContext; UINT16 Index; UINT16 Index2; UINT8 CheckFlags; UINT8 *ConsoleCheck; EFI_QUESTION_ID QuestionIdBase; UINT16 VariableOffsetBase; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); ConsoleCheck = NULL; QuestionIdBase = 0; VariableOffsetBase = 0; switch (UpdatePageId) { case FORM_CON_IN_ID: ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0]; QuestionIdBase = CON_IN_DEVICE_QUESTION_ID; VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET; break; case FORM_CON_OUT_ID: ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0]; QuestionIdBase = CON_OUT_DEVICE_QUESTION_ID; VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET; break; case FORM_CON_ERR_ID: ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0]; QuestionIdBase = CON_ERR_DEVICE_QUESTION_ID; VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET; break; } ASSERT (ConsoleCheck != NULL); for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \ (Index < MAX_MENU_NUMBER)); Index++) { CheckFlags = 0; NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index); NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext; if (NewConsoleContext->IsActive) { CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT; ConsoleCheck[Index] = TRUE; } else { ConsoleCheck[Index] = FALSE; } HiiCreateCheckBoxOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(QuestionIdBase + Index), VARSTORE_ID_BOOT_MAINT, (UINT16)(VariableOffsetBase + Index), NewMenuEntry->DisplayStringToken, NewMenuEntry->HelpStringToken, EFI_IFR_FLAG_CALLBACK, CheckFlags, NULL ); } for (Index2 = 0; ((Index2 < TerminalMenu.MenuNumber) && \ (Index2 < MAX_MENU_NUMBER)); Index2++) { CheckFlags = 0; NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index2); NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext; ASSERT (Index < MAX_MENU_NUMBER); if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) || ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) || ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID)) ) { CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT; if (Index < MAX_MENU_NUMBER) { ConsoleCheck[Index] = TRUE; } } else if (Index < MAX_MENU_NUMBER) { ConsoleCheck[Index] = FALSE; } HiiCreateCheckBoxOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(QuestionIdBase + Index), VARSTORE_ID_BOOT_MAINT, (UINT16)(VariableOffsetBase + Index), NewMenuEntry->DisplayStringToken, NewMenuEntry->HelpStringToken, EFI_IFR_FLAG_CALLBACK, CheckFlags, NULL ); Index++; } UpdatePageEnd (CallbackData); } /** Update the page's NV Map if user has changed the order a list. This list can be Boot Order or Driver Order. @param UpdatePageId The form ID to be updated. @param OptionMenu The new list. @param CallbackData The BMM context data. **/ VOID UpdateOrderPage ( IN UINT16 UpdatePageId, IN BM_MENU_OPTION *OptionMenu, IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; UINT16 Index; UINT16 OptionIndex; VOID *OptionsOpCodeHandle; BOOLEAN BootOptionFound; UINT32 *OptionOrder; EFI_QUESTION_ID QuestionId; UINT16 VarOffset; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); OptionOrder = NULL; QuestionId = 0; VarOffset = 0; switch (UpdatePageId) { case FORM_BOOT_CHG_ID: // // If the BootOptionOrder in the BmmFakeNvData are same with the date in the BmmOldFakeNVData, // means all Boot Options has been save in BootOptionMenu, we can get the date from the menu. // else means browser maintains some uncommitted date which are not saved in BootOptionMenu, // so we should not get the data from BootOptionMenu to show it. // if (CompareMem (CallbackData->BmmFakeNvData.BootOptionOrder, CallbackData->BmmOldFakeNVData.BootOptionOrder, sizeof (CallbackData->BmmFakeNvData.BootOptionOrder)) == 0) { GetBootOrder (CallbackData); } OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder; QuestionId = BOOT_OPTION_ORDER_QUESTION_ID; VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET; break; case FORM_DRV_CHG_ID: // // If the DriverOptionOrder in the BmmFakeNvData are same with the date in the BmmOldFakeNVData, // means all Driver Options has been save in DriverOptionMenu, we can get the DriverOptionOrder from the menu. // else means browser maintains some uncommitted date which are not saved in DriverOptionMenu, // so we should not get the data from DriverOptionMenu to show it. // if (CompareMem (CallbackData->BmmFakeNvData.DriverOptionOrder, CallbackData->BmmOldFakeNVData.DriverOptionOrder, sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder)) == 0) { GetDriverOrder (CallbackData); } OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder; QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID; VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET; break; } ASSERT (OptionOrder != NULL); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); NewMenuEntry = NULL; for (OptionIndex = 0; (OptionIndex < MAX_MENU_NUMBER && OptionOrder[OptionIndex] != 0); OptionIndex++) { BootOptionFound = FALSE; for (Index = 0; Index < OptionMenu->MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index); if ((UINT32)(NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) { BootOptionFound = TRUE; break; } } if (BootOptionFound) { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, NewMenuEntry->DisplayStringToken, 0, EFI_IFR_TYPE_NUM_SIZE_32, OptionOrder[OptionIndex] ); } } if (OptionMenu->MenuNumber > 0) { HiiCreateOrderedListOpCode ( mStartOpCodeHandle, // Container for dynamic created opcodes QuestionId, // Question ID VARSTORE_ID_BOOT_MAINT, // VarStore ID VarOffset, // Offset in Buffer Storage STRING_TOKEN (STR_CHANGE_ORDER), // Question prompt text STRING_TOKEN (STR_CHANGE_ORDER), // Question help text 0, // Question flag 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET EFI_IFR_TYPE_NUM_SIZE_32, // Data type of Question value 100, // Maximum container OptionsOpCodeHandle, // Option Opcode list NULL // Default Opcode is NULL ); } HiiFreeOpCodeHandle (OptionsOpCodeHandle); UpdatePageEnd (CallbackData); } /** Refresh the text mode page. @param CallbackData The BMM context data. **/ VOID UpdateConModePage ( IN BMM_CALLBACK_DATA *CallbackData ) { UINTN Mode; UINTN Index; UINTN Col; UINTN Row; CHAR16 ModeString[50]; CHAR16 *PStr; UINTN MaxMode; UINTN ValidMode; EFI_STRING_ID *ModeToken; EFI_STATUS Status; VOID *OptionsOpCodeHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; ConOut = gST->ConOut; Index = 0; ValidMode = 0; MaxMode = (UINTN)(ConOut->Mode->MaxMode); CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); // // Check valid mode // for (Mode = 0; Mode < MaxMode; Mode++) { Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row); if (EFI_ERROR (Status)) { continue; } ValidMode++; } if (ValidMode == 0) { return; } OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); ModeToken = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode); ASSERT (ModeToken != NULL); // // Determin which mode should be the first entry in menu // GetConsoleOutMode (CallbackData); // // Build text mode options // for (Mode = 0; Mode < MaxMode; Mode++) { Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row); if (EFI_ERROR (Status)) { continue; } // // Build mode string Column x Row // UnicodeValueToStringS (ModeString, sizeof (ModeString), 0, Col, 0); PStr = &ModeString[0]; StrnCatS (PStr, ARRAY_SIZE (ModeString), L" x ", StrLen (L" x ") + 1); PStr = PStr + StrLen (PStr); UnicodeValueToStringS ( PStr, sizeof (ModeString) - ((UINTN)PStr - (UINTN)&ModeString[0]), 0, Row, 0 ); ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL); if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, ModeToken[Index], EFI_IFR_OPTION_DEFAULT, EFI_IFR_TYPE_NUM_SIZE_16, (UINT16)Mode ); } else { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, ModeToken[Index], 0, EFI_IFR_TYPE_NUM_SIZE_16, (UINT16)Mode ); } Index++; } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)CON_MODE_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, CON_MODE_VAR_OFFSET, STRING_TOKEN (STR_CON_MODE_SETUP), STRING_TOKEN (STR_CON_MODE_SETUP), EFI_IFR_FLAG_RESET_REQUIRED, EFI_IFR_NUMERIC_SIZE_2, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); FreePool (ModeToken); UpdatePageEnd (CallbackData); } /** Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits, Parity, Stop Bits, Terminal Type. @param CallbackData The BMM context data. **/ VOID UpdateTerminalPage ( IN BMM_CALLBACK_DATA *CallbackData ) { UINT8 Index; UINT8 CheckFlags; BM_MENU_ENTRY *NewMenuEntry; VOID *OptionsOpCodeHandle; UINTN CurrentTerminal; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); CurrentTerminal = CallbackData->CurrentTerminal; NewMenuEntry = BOpt_GetMenuEntry ( &TerminalMenu, CurrentTerminal ); if (NewMenuEntry == NULL) { return; } OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList[0]); Index++) { CheckFlags = 0; if (BaudRateList[Index].Value == 115200) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, BaudRateList[Index].StringToken, CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, Index ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_BAUD_RATE_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_BAUD_RATE), STRING_TOKEN (STR_COM_BAUD_RATE), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < ARRAY_SIZE (DataBitsList); Index++) { CheckFlags = 0; if (DataBitsList[Index].Value == 8) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, DataBitsList[Index].StringToken, CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, Index ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_DATA_RATE_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_DATA_RATE_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_DATA_BITS), STRING_TOKEN (STR_COM_DATA_BITS), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < ARRAY_SIZE (ParityList); Index++) { CheckFlags = 0; if (ParityList[Index].Value == NoParity) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, ParityList[Index].StringToken, CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, Index ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_PARITY_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_PARITY_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_PARITY), STRING_TOKEN (STR_COM_PARITY), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < ARRAY_SIZE (StopBitsList); Index++) { CheckFlags = 0; if (StopBitsList[Index].Value == OneStopBit) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, StopBitsList[Index].StringToken, CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, Index ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_STOP_BITS_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_STOP_BITS_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_STOP_BITS), STRING_TOKEN (STR_COM_STOP_BITS), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < ARRAY_SIZE (TerminalType); Index++) { CheckFlags = 0; if (Index == 0) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, (EFI_STRING_ID)TerminalType[Index], CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, Index ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_TERMINAL_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_TERMINAL_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_TERMI_TYPE), STRING_TOKEN (STR_COM_TERMI_TYPE), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); for (Index = 0; Index < ARRAY_SIZE (mFlowControlType); Index++) { CheckFlags = 0; if (Index == 0) { CheckFlags |= EFI_IFR_OPTION_DEFAULT; } HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, (EFI_STRING_ID)mFlowControlType[Index], CheckFlags, EFI_IFR_TYPE_NUM_SIZE_8, mFlowControlValue[Index] ); } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID)(COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal), VARSTORE_ID_BOOT_MAINT, (UINT16)(COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal), STRING_TOKEN (STR_COM_FLOW_CONTROL), STRING_TOKEN (STR_COM_FLOW_CONTROL), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); UpdatePageEnd (CallbackData); } /** Update add boot/driver option page. @param CallbackData The BMM context data. @param FormId The form ID to be updated. @param DevicePath Device path. **/ VOID UpdateOptionPage ( IN BMM_CALLBACK_DATA *CallbackData, IN EFI_FORM_ID FormId, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CHAR16 *String; EFI_STRING_ID StringToken; String = NULL; if (DevicePath != NULL) { String = ExtractFileNameFromDevicePath (DevicePath); } if (String == NULL) { String = HiiGetString (CallbackData->BmmHiiHandle, STRING_TOKEN (STR_NULL_STRING), NULL); ASSERT (String != NULL); } StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL); FreePool (String); if (FormId == FORM_BOOT_ADD_ID) { if (!CallbackData->BmmFakeNvData.BootOptionChanged) { ZeroMem (CallbackData->BmmFakeNvData.BootOptionalData, sizeof (CallbackData->BmmFakeNvData.BootOptionalData)); ZeroMem (CallbackData->BmmFakeNvData.BootDescriptionData, sizeof (CallbackData->BmmFakeNvData.BootDescriptionData)); ZeroMem (CallbackData->BmmOldFakeNVData.BootOptionalData, sizeof (CallbackData->BmmOldFakeNVData.BootOptionalData)); ZeroMem (CallbackData->BmmOldFakeNVData.BootDescriptionData, sizeof (CallbackData->BmmOldFakeNVData.BootDescriptionData)); } } else if (FormId == FORM_DRV_ADD_FILE_ID) { if (!CallbackData->BmmFakeNvData.DriverOptionChanged) { ZeroMem (CallbackData->BmmFakeNvData.DriverOptionalData, sizeof (CallbackData->BmmFakeNvData.DriverOptionalData)); ZeroMem (CallbackData->BmmFakeNvData.DriverDescriptionData, sizeof (CallbackData->BmmFakeNvData.DriverDescriptionData)); ZeroMem (CallbackData->BmmOldFakeNVData.DriverOptionalData, sizeof (CallbackData->BmmOldFakeNVData.DriverOptionalData)); ZeroMem (CallbackData->BmmOldFakeNVData.DriverDescriptionData, sizeof (CallbackData->BmmOldFakeNVData.DriverDescriptionData)); } } RefreshUpdateData (); mStartLabel->Number = FormId; HiiCreateSubTitleOpCode ( mStartOpCodeHandle, StringToken, 0, 0, 0 ); HiiUpdateForm ( CallbackData->BmmHiiHandle, &mBootMaintGuid, FormId, mStartOpCodeHandle, // Label FormId mEndOpCodeHandle // LABEL_END ); } /** Dispatch the correct update page function to call based on the UpdatePageId. @param UpdatePageId The form ID. @param CallbackData The BMM context data. **/ VOID UpdatePageBody ( IN UINT16 UpdatePageId, IN BMM_CALLBACK_DATA *CallbackData ) { CleanUpPage (UpdatePageId, CallbackData); switch (UpdatePageId) { case FORM_CON_IN_ID: UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData); break; case FORM_CON_OUT_ID: UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData); break; case FORM_CON_ERR_ID: UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData); break; case FORM_BOOT_CHG_ID: UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData); break; case FORM_DRV_CHG_ID: UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData); break; default: break; } } /** Dispatch the display to the next page based on NewPageId. @param Private The BMM context data. @param NewPageId The original page ID. **/ VOID UpdatePageId ( BMM_CALLBACK_DATA *Private, UINT16 NewPageId ) { if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) { // // If we select a handle to add driver option, advance to the add handle description page. // NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID; } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) { // // Return to main page after "Save Changes" or "Discard Changes". // NewPageId = FORM_MAIN_ID; } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) { NewPageId = FORM_CON_COM_SETUP_ID; } if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) { Private->BmmPreviousPageId = Private->BmmCurrentPageId; Private->BmmCurrentPageId = NewPageId; } }