/** @file | |
Variable operation that will be used by bootmaint | |
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "BootMaintenanceManager.h" | |
/** | |
Delete Boot Option that represent a Deleted state in BootOptionMenu. | |
@retval EFI_SUCCESS If all boot load option EFI Variables corresponding to | |
BM_LOAD_CONTEXT marked for deletion is deleted. | |
@retval EFI_NOT_FOUND If can not find the boot option want to be deleted. | |
@return Others If failed to update the "BootOrder" variable after deletion. | |
**/ | |
EFI_STATUS | |
Var_DelBootOption ( | |
VOID | |
) | |
{ | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_LOAD_CONTEXT *NewLoadContext; | |
EFI_STATUS Status; | |
UINTN Index; | |
UINTN Index2; | |
Index2 = 0; | |
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) { | |
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2)); | |
if (NULL == NewMenuEntry) { | |
return EFI_NOT_FOUND; | |
} | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
if (!NewLoadContext->Deleted) { | |
continue; | |
} | |
Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeBoot); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Index2++; | |
// | |
// If current Load Option is the same as BootNext, | |
// must delete BootNext in order to make sure | |
// there will be no panic on next boot | |
// | |
if (NewLoadContext->IsBootNext) { | |
EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid); | |
} | |
RemoveEntryList (&NewMenuEntry->Link); | |
BOpt_DestroyMenuEntry (NewMenuEntry); | |
NewMenuEntry = NULL; | |
} | |
BootOptionMenu.MenuNumber -= Index2; | |
return EFI_SUCCESS; | |
} | |
/** | |
Delete Load Option that represent a Deleted state in DriverOptionMenu. | |
@retval EFI_SUCCESS Load Option is successfully updated. | |
@retval EFI_NOT_FOUND Fail to find the driver option want to be deleted. | |
@return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI | |
Variable. | |
**/ | |
EFI_STATUS | |
Var_DelDriverOption ( | |
VOID | |
) | |
{ | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_LOAD_CONTEXT *NewLoadContext; | |
EFI_STATUS Status; | |
UINTN Index; | |
UINTN Index2; | |
Index2 = 0; | |
for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { | |
NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2)); | |
if (NULL == NewMenuEntry) { | |
return EFI_NOT_FOUND; | |
} | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
if (!NewLoadContext->Deleted) { | |
continue; | |
} | |
Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeDriver); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Index2++; | |
RemoveEntryList (&NewMenuEntry->Link); | |
BOpt_DestroyMenuEntry (NewMenuEntry); | |
NewMenuEntry = NULL; | |
} | |
DriverOptionMenu.MenuNumber -= Index2; | |
return EFI_SUCCESS; | |
} | |
/** | |
This function delete and build multi-instance device path for | |
specified type of console device. | |
This function clear the EFI variable defined by ConsoleName and | |
gEfiGlobalVariableGuid. It then build the multi-instance device | |
path by appending the device path of the Console (In/Out/Err) instance | |
in ConsoleMenu. Then it scan all corresponding console device by | |
scanning Terminal (built from device supporting Serial I/O instances) | |
devices in TerminalMenu. At last, it save a EFI variable specifed | |
by ConsoleName and gEfiGlobalVariableGuid. | |
@param ConsoleName The name for the console device type. They are | |
usually "ConIn", "ConOut" and "ErrOut". | |
@param ConsoleMenu The console memu which is a list of console devices. | |
@param UpdatePageId The flag specifying which type of console device | |
to be processed. | |
@retval EFI_SUCCESS The function complete successfully. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateConsoleOption ( | |
IN UINT16 *ConsoleName, | |
IN BM_MENU_OPTION *ConsoleMenu, | |
IN UINT16 UpdatePageId | |
) | |
{ | |
EFI_DEVICE_PATH_PROTOCOL *ConDevicePath; | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_CONSOLE_CONTEXT *NewConsoleContext; | |
BM_TERMINAL_CONTEXT *NewTerminalContext; | |
EFI_STATUS Status; | |
VENDOR_DEVICE_PATH Vendor; | |
EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath; | |
UINTN Index; | |
GetEfiGlobalVariable2 (ConsoleName, (VOID **)&ConDevicePath, NULL); | |
if (ConDevicePath != NULL) { | |
EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid); | |
FreePool (ConDevicePath); | |
ConDevicePath = NULL; | |
} | |
// | |
// First add all console input device from console input menu | |
// | |
for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) { | |
NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index); | |
NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext; | |
if (NewConsoleContext->IsActive) { | |
ConDevicePath = AppendDevicePathInstance ( | |
ConDevicePath, | |
NewConsoleContext->DevicePath | |
); | |
} | |
} | |
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { | |
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); | |
NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext; | |
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)) | |
) | |
{ | |
Vendor.Header.Type = MESSAGING_DEVICE_PATH; | |
Vendor.Header.SubType = MSG_VENDOR_DP; | |
ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid))); | |
CopyMem ( | |
&Vendor.Guid, | |
&TerminalTypeGuid[NewTerminalContext->TerminalType], | |
sizeof (EFI_GUID) | |
); | |
SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH)); | |
TerminalDevicePath = AppendDevicePathNode ( | |
NewTerminalContext->DevicePath, | |
(EFI_DEVICE_PATH_PROTOCOL *)&Vendor | |
); | |
ASSERT (TerminalDevicePath != NULL); | |
ChangeTerminalDevicePath (TerminalDevicePath, TRUE); | |
ConDevicePath = AppendDevicePathInstance ( | |
ConDevicePath, | |
TerminalDevicePath | |
); | |
} | |
} | |
if (ConDevicePath != NULL) { | |
Status = gRT->SetVariable ( | |
ConsoleName, | |
&gEfiGlobalVariableGuid, | |
VAR_FLAG, | |
GetDevicePathSize (ConDevicePath), | |
ConDevicePath | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function delete and build multi-instance device path ConIn | |
console device. | |
@retval EFI_SUCCESS The function complete successfully. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateConsoleInpOption ( | |
VOID | |
) | |
{ | |
return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID); | |
} | |
/** | |
This function delete and build multi-instance device path ConOut | |
console device. | |
@retval EFI_SUCCESS The function complete successfully. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateConsoleOutOption ( | |
VOID | |
) | |
{ | |
return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID); | |
} | |
/** | |
This function delete and build multi-instance device path ErrOut | |
console device. | |
@retval EFI_SUCCESS The function complete successfully. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateErrorOutOption ( | |
VOID | |
) | |
{ | |
return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID); | |
} | |
/** | |
This function create a currently loaded Drive Option from | |
the BMM. It then appends this Driver Option to the end of | |
the "DriverOrder" list. It append this Driver Opotion to the end | |
of DriverOptionMenu. | |
@param CallbackData The BMM context data. | |
@param HiiHandle The HII handle associated with the BMM formset. | |
@param DescriptionData The description of this driver option. | |
@param OptionalData The optional load option. | |
@param ForceReconnect If to force reconnect. | |
@retval other Contain some errors when excuting this function.See function | |
EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl | |
for detail return information. | |
@retval EFI_SUCCESS If function completes successfully. | |
**/ | |
EFI_STATUS | |
Var_UpdateDriverOption ( | |
IN BMM_CALLBACK_DATA *CallbackData, | |
IN EFI_HII_HANDLE HiiHandle, | |
IN UINT16 *DescriptionData, | |
IN UINT16 *OptionalData, | |
IN UINT8 ForceReconnect | |
) | |
{ | |
UINT16 Index; | |
UINT16 DriverString[12]; | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_LOAD_CONTEXT *NewLoadContext; | |
BOOLEAN OptionalDataExist; | |
EFI_STATUS Status; | |
EFI_BOOT_MANAGER_LOAD_OPTION LoadOption; | |
UINT8 *OptionalDesData; | |
UINT32 OptionalDataSize; | |
OptionalDataExist = FALSE; | |
OptionalDesData = NULL; | |
OptionalDataSize = 0; | |
Index = BOpt_GetDriverOptionNumber (); | |
UnicodeSPrint ( | |
DriverString, | |
sizeof (DriverString), | |
L"Driver%04x", | |
Index | |
); | |
if (*DescriptionData == 0x0000) { | |
StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString); | |
} | |
if (*OptionalData != 0x0000) { | |
OptionalDataExist = TRUE; | |
OptionalDesData = (UINT8 *)OptionalData; | |
OptionalDataSize = (UINT32)StrSize (OptionalData); | |
} | |
NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); | |
if (NULL == NewMenuEntry) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Status = EfiBootManagerInitializeLoadOption ( | |
&LoadOption, | |
Index, | |
LoadOptionTypeDriver, | |
LOAD_OPTION_ACTIVE | (ForceReconnect << 1), | |
DescriptionData, | |
CallbackData->LoadContext->FilePathList, | |
OptionalDesData, | |
OptionalDataSize | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1); | |
if (EFI_ERROR (Status)) { | |
EfiBootManagerFreeLoadOption (&LoadOption); | |
return Status; | |
} | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
NewLoadContext->Deleted = FALSE; | |
NewLoadContext->Attributes = LoadOption.Attributes; | |
NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath); | |
NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData)); | |
ASSERT (NewLoadContext->Description != NULL); | |
NewMenuEntry->DisplayString = NewLoadContext->Description; | |
CopyMem ( | |
NewLoadContext->Description, | |
LoadOption.Description, | |
StrSize (DescriptionData) | |
); | |
NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); | |
ASSERT (NewLoadContext->FilePathList != NULL); | |
CopyMem ( | |
NewLoadContext->FilePathList, | |
LoadOption.FilePath, | |
GetDevicePathSize (CallbackData->LoadContext->FilePathList) | |
); | |
NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); | |
NewMenuEntry->OptionNumber = Index; | |
NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL); | |
NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL); | |
if (OptionalDataExist) { | |
NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize); | |
ASSERT (NewLoadContext->OptionalData != NULL); | |
CopyMem ( | |
NewLoadContext->OptionalData, | |
LoadOption.OptionalData, | |
LoadOption.OptionalDataSize | |
); | |
} | |
InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); | |
DriverOptionMenu.MenuNumber++; | |
EfiBootManagerFreeLoadOption (&LoadOption); | |
return EFI_SUCCESS; | |
} | |
/** | |
This function create a currently loaded Boot Option from | |
the BMM. It then appends this Boot Option to the end of | |
the "BootOrder" list. It also append this Boot Opotion to the end | |
of BootOptionMenu. | |
@param CallbackData The BMM context data. | |
@retval other Contain some errors when excuting this function. See function | |
EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl | |
for detail return information. | |
@retval EFI_SUCCESS If function completes successfully. | |
**/ | |
EFI_STATUS | |
Var_UpdateBootOption ( | |
IN BMM_CALLBACK_DATA *CallbackData | |
) | |
{ | |
UINT16 BootString[10]; | |
UINT16 Index; | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_LOAD_CONTEXT *NewLoadContext; | |
BOOLEAN OptionalDataExist; | |
EFI_STATUS Status; | |
BMM_FAKE_NV_DATA *NvRamMap; | |
EFI_BOOT_MANAGER_LOAD_OPTION LoadOption; | |
UINT8 *OptionalData; | |
UINT32 OptionalDataSize; | |
OptionalDataExist = FALSE; | |
NvRamMap = &CallbackData->BmmFakeNvData; | |
OptionalData = NULL; | |
OptionalDataSize = 0; | |
Index = BOpt_GetBootOptionNumber (); | |
UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); | |
if (NvRamMap->BootDescriptionData[0] == 0x0000) { | |
StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString); | |
} | |
if (NvRamMap->BootOptionalData[0] != 0x0000) { | |
OptionalDataExist = TRUE; | |
OptionalData = (UINT8 *)NvRamMap->BootOptionalData; | |
OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData); | |
} | |
NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); | |
if (NULL == NewMenuEntry) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Status = EfiBootManagerInitializeLoadOption ( | |
&LoadOption, | |
Index, | |
LoadOptionTypeBoot, | |
LOAD_OPTION_ACTIVE, | |
NvRamMap->BootDescriptionData, | |
CallbackData->LoadContext->FilePathList, | |
OptionalData, | |
OptionalDataSize | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1); | |
if (EFI_ERROR (Status)) { | |
EfiBootManagerFreeLoadOption (&LoadOption); | |
return Status; | |
} | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
NewLoadContext->Deleted = FALSE; | |
NewLoadContext->Attributes = LoadOption.Attributes; | |
NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath); | |
NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); | |
ASSERT (NewLoadContext->Description != NULL); | |
NewMenuEntry->DisplayString = NewLoadContext->Description; | |
CopyMem ( | |
NewLoadContext->Description, | |
LoadOption.Description, | |
StrSize (NvRamMap->BootDescriptionData) | |
); | |
NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); | |
ASSERT (NewLoadContext->FilePathList != NULL); | |
CopyMem ( | |
NewLoadContext->FilePathList, | |
LoadOption.FilePath, | |
GetDevicePathSize (CallbackData->LoadContext->FilePathList) | |
); | |
NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); | |
NewMenuEntry->OptionNumber = Index; | |
NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL); | |
NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL); | |
if (OptionalDataExist) { | |
NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize); | |
ASSERT (NewLoadContext->OptionalData != NULL); | |
CopyMem ( | |
NewLoadContext->OptionalData, | |
LoadOption.OptionalData, | |
LoadOption.OptionalDataSize | |
); | |
} | |
InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); | |
BootOptionMenu.MenuNumber++; | |
EfiBootManagerFreeLoadOption (&LoadOption); | |
return EFI_SUCCESS; | |
} | |
/** | |
This function update the "BootNext" EFI Variable. If there is | |
no "BootNext" specified in BMM, this EFI Variable is deleted. | |
It also update the BMM context data specified the "BootNext" | |
vaule. | |
@param CallbackData The BMM context data. | |
@retval EFI_SUCCESS The function complete successfully. | |
@return The EFI variable can be saved. See gRT->SetVariable | |
for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateBootNext ( | |
IN BMM_CALLBACK_DATA *CallbackData | |
) | |
{ | |
BM_MENU_ENTRY *NewMenuEntry; | |
BM_LOAD_CONTEXT *NewLoadContext; | |
BMM_FAKE_NV_DATA *CurrentFakeNVMap; | |
UINT16 Index; | |
EFI_STATUS Status; | |
Status = EFI_SUCCESS; | |
CurrentFakeNVMap = &CallbackData->BmmFakeNvData; | |
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) { | |
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index); | |
ASSERT (NULL != NewMenuEntry); | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
NewLoadContext->IsBootNext = FALSE; | |
} | |
if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) { | |
EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid); | |
return EFI_SUCCESS; | |
} | |
NewMenuEntry = BOpt_GetMenuEntry ( | |
&BootOptionMenu, | |
CurrentFakeNVMap->BootNext | |
); | |
ASSERT (NewMenuEntry != NULL); | |
NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext; | |
Status = gRT->SetVariable ( | |
L"BootNext", | |
&gEfiGlobalVariableGuid, | |
VAR_FLAG, | |
sizeof (UINT16), | |
&NewMenuEntry->OptionNumber | |
); | |
NewLoadContext->IsBootNext = TRUE; | |
CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext; | |
return Status; | |
} | |
/** | |
This function update the "BootOrder" EFI Variable based on | |
BMM Formset's NV map. It then refresh BootOptionMenu | |
with the new "BootOrder" list. | |
@param CallbackData The BMM context data. | |
@retval EFI_SUCCESS The function complete successfully. | |
@retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateBootOrder ( | |
IN BMM_CALLBACK_DATA *CallbackData | |
) | |
{ | |
EFI_STATUS Status; | |
UINT16 Index; | |
UINT16 OrderIndex; | |
UINT16 *BootOrder; | |
UINTN BootOrderSize; | |
UINT16 OptionNumber; | |
// | |
// First check whether BootOrder is present in current configuration | |
// | |
GetEfiGlobalVariable2 (L"BootOrder", (VOID **)&BootOrder, &BootOrderSize); | |
if (BootOrder == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0]))); | |
// | |
// OptionOrder is subset of BootOrder | |
// | |
for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) { | |
for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) { | |
if ((BootOrder[Index] == (UINT16)(CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) { | |
OptionNumber = BootOrder[Index]; | |
CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16)); | |
BootOrder[OrderIndex] = OptionNumber; | |
} | |
} | |
} | |
Status = gRT->SetVariable ( | |
L"BootOrder", | |
&gEfiGlobalVariableGuid, | |
VAR_FLAG, | |
BootOrderSize, | |
BootOrder | |
); | |
FreePool (BootOrder); | |
BOpt_FreeMenu (&BootOptionMenu); | |
BOpt_GetBootOptions (CallbackData); | |
return Status; | |
} | |
/** | |
This function update the "DriverOrder" EFI Variable based on | |
BMM Formset's NV map. It then refresh DriverOptionMenu | |
with the new "DriverOrder" list. | |
@param CallbackData The BMM context data. | |
@retval EFI_SUCCESS The function complete successfully. | |
@retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. | |
@return The EFI variable can not be saved. See gRT->SetVariable for detail return information. | |
**/ | |
EFI_STATUS | |
Var_UpdateDriverOrder ( | |
IN BMM_CALLBACK_DATA *CallbackData | |
) | |
{ | |
EFI_STATUS Status; | |
UINT16 Index; | |
UINT16 *DriverOrderList; | |
UINT16 *NewDriverOrderList; | |
UINTN DriverOrderListSize; | |
DriverOrderList = NULL; | |
DriverOrderListSize = 0; | |
// | |
// First check whether DriverOrder is present in current configuration | |
// | |
GetEfiGlobalVariable2 (L"DriverOrder", (VOID **)&DriverOrderList, &DriverOrderListSize); | |
NewDriverOrderList = AllocateZeroPool (DriverOrderListSize); | |
if (NewDriverOrderList == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// | |
// If exists, delete it to hold new DriverOrder | |
// | |
if (DriverOrderList != NULL) { | |
EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid); | |
FreePool (DriverOrderList); | |
} | |
ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0]))); | |
for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { | |
NewDriverOrderList[Index] = (UINT16)(CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1); | |
} | |
Status = gRT->SetVariable ( | |
L"DriverOrder", | |
&gEfiGlobalVariableGuid, | |
VAR_FLAG, | |
DriverOrderListSize, | |
NewDriverOrderList | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
BOpt_FreeMenu (&DriverOptionMenu); | |
BOpt_GetDriverOptions (CallbackData); | |
return EFI_SUCCESS; | |
} | |
/** | |
Update the Text Mode of Console. | |
@param CallbackData The context data for BMM. | |
@retval EFI_SUCCSS If the Text Mode of Console is updated. | |
@return Other value if the Text Mode of Console is not updated. | |
**/ | |
EFI_STATUS | |
Var_UpdateConMode ( | |
IN BMM_CALLBACK_DATA *CallbackData | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Mode; | |
CONSOLE_OUT_MODE ModeInfo; | |
Mode = CallbackData->BmmFakeNvData.ConsoleOutMode; | |
Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row)); | |
if (!EFI_ERROR (Status)) { | |
Status = PcdSet32S (PcdSetupConOutColumn, (UINT32)ModeInfo.Column); | |
if (!EFI_ERROR (Status)) { | |
Status = PcdSet32S (PcdSetupConOutRow, (UINT32)ModeInfo.Row); | |
} | |
} | |
return Status; | |
} |