blob: b1d1e2ee44f41ca6bf830f21769bb3941fb33fb2 [file] [log] [blame]
/** @file
Dynamically update the pages.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
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;
}
}