2081 lines
66 KiB
C
2081 lines
66 KiB
C
/** @file
|
|
|
|
Initial and callback functions for Secure Option Rom Control Setup page
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "PciDevLookupTable.h"
|
|
#include "SecureOptionRomControlSetup.h"
|
|
|
|
BOOLEAN mSetupInitDone = FALSE;
|
|
EFI_HANDLE mDriverHandle = NULL;
|
|
SECURE_OPROM_CONTROL_PRIVATE_DATA *mPrivateData = NULL;
|
|
CHAR16 mVariableName[] = L"SecOpRomConfig";
|
|
|
|
HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {
|
|
{
|
|
{
|
|
HARDWARE_DEVICE_PATH,
|
|
HW_VENDOR_DP,
|
|
{
|
|
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
|
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
|
}
|
|
},
|
|
SECURE_OPTION_ROM_CONTROL_FORMSET_GUID
|
|
},
|
|
{
|
|
END_DEVICE_PATH_TYPE,
|
|
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
|
{
|
|
(UINT8) (END_DEVICE_PATH_LENGTH),
|
|
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
|
}
|
|
}
|
|
};
|
|
|
|
LIST_ENTRY mOpRomPolicyListForSetup = INITIALIZE_LIST_HEAD_VARIABLE(mOpRomPolicyListForSetup);
|
|
|
|
OPTION_ROM_DEVICE_LIST *mOpRomDeviceList; // For delete function used.
|
|
|
|
/**
|
|
Get the description for the PCI slot.
|
|
|
|
@param[in] DevicePath - The pointer of the device path of the PCI slot.
|
|
@param[out] Description - The pointer of the description of the PCI slot
|
|
|
|
@retval EFI_NOT_FOUND - Can't find the description.
|
|
@retval EFI_SUCCESS - Find the description.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDescriptionName (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
|
OUT CHAR16 **Description
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN TokenNum;
|
|
EFI_DEVICE_PATH_PROTOCOL *WorkingDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *PlatformDevPath;
|
|
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
|
|
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevPathFromText;
|
|
CHAR8 *TempStr8;
|
|
CHAR16 TempStr[100] = {0};
|
|
BOOLEAN Match;
|
|
EFI_GUID TargetTokenSpaceGuid;
|
|
UINTN DescriptionStrSize;
|
|
UINT32 DeviceAttribCount;
|
|
|
|
if (!IsDevicePathValid(DevicePath, 0) || DevicePath == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiDevicePathFromTextProtocolGuid,
|
|
NULL,
|
|
(VOID **) &DevPathFromText
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TargetTokenSpaceGuid = gH2ODeviceInfoTokenSpaceGuid;
|
|
|
|
TokenNum = LibPcdGetNextToken(&TargetTokenSpaceGuid, 0);
|
|
while (TokenNum != 0) {
|
|
Status = EFI_NOT_FOUND;
|
|
if (IsDevicePathPci(TokenNum) != TRUE) {
|
|
continue;
|
|
}
|
|
Match = TRUE;
|
|
Status = GetDeviceInfo(TokenNum, &PlatformDevPath, &DeviceAttribCount);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
WorkingDevicePath = DuplicateDevicePath(DevicePath);
|
|
TempDevicePath = WorkingDevicePath;
|
|
while (!IsDevicePathEnd (PlatformDevPath)) {
|
|
if (CompareMem (WorkingDevicePath, PlatformDevPath, DevicePathNodeLength (WorkingDevicePath)) != 0) {
|
|
Match = FALSE;
|
|
}
|
|
WorkingDevicePath = NextDevicePathNode (WorkingDevicePath);
|
|
PlatformDevPath = NextDevicePathNode (PlatformDevPath);
|
|
}
|
|
|
|
FreePool (TempDevicePath);
|
|
|
|
if (!Match) {
|
|
TokenNum = LibPcdGetNextToken(&TargetTokenSpaceGuid, TokenNum);
|
|
Status = EFI_NOT_FOUND;
|
|
} else {
|
|
Status = GetDeviceInfoAttribByName (TokenNum, "name", &TempStr8);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// Add one CHAR16 size to point to the correct pointer of string.
|
|
//
|
|
AsciiStrToUnicodeStrS(TempStr8, TempStr, AsciiStrSize (TempStr8));
|
|
DescriptionStrSize = (StrLen (TempStr) + 1) * sizeof (CHAR16);
|
|
*Description = (CHAR16 *) AllocateZeroPool (DescriptionStrSize);
|
|
StrCpyS (*Description, DescriptionStrSize, TempStr);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get all option Rom name list and return the number of them.
|
|
|
|
@param[in,out] *OptionNumber - The pointer of the total number of Option Rom policy.
|
|
|
|
@retval OPTION_ROM_LIST_OPTION - Get the option just been created
|
|
@retval NULL - Failed to get the new option
|
|
|
|
**/
|
|
CHAR16 **
|
|
EFIAPI
|
|
GetOpRomNameList (
|
|
IN OUT UINT32 *OptionNumber
|
|
)
|
|
{
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
CHAR16 **OpRomNameList;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
UINT32 OptionNum;
|
|
UINT32 Index;
|
|
CHAR16 *PciVendorIDString = NULL;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
OptionNum = 0;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
OptionNum++;
|
|
}
|
|
|
|
OpRomNameList = AllocateZeroPool (sizeof (CHAR16*) * OptionNum);
|
|
if (OpRomNameList == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
mOpRomDeviceList = AllocateZeroPool (sizeof (OPTION_ROM_DEVICE_LIST) * OptionNum);
|
|
if (mOpRomDeviceList == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
Index = 0;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
mOpRomDeviceList[Index].VendorId = Option->OpRomOption.VendorId;
|
|
mOpRomDeviceList[Index].DeviceId = Option->OpRomOption.DeviceId;
|
|
mOpRomDeviceList[Index].OptionNum = Option->OptionNumber;
|
|
OpRomNameList[Index] = AllocateZeroPool (sizeof (CHAR16) * MAX_OPROM_NAME_ID_NUM);
|
|
if (OpRomNameList[Index] == NULL) {
|
|
break;
|
|
}
|
|
GetVerdorIdShortName (Option->OpRomOption.VendorId, &PciVendorIDString);
|
|
if (PciVendorIDString == NULL) {
|
|
UnicodeSPrint (OpRomNameList[Index] , sizeof (CHAR16) * MAX_OPROM_NAME_ID_NUM, L"0x%04x 0x%04x", Option->OpRomOption.VendorId, Option->OpRomOption.DeviceId);
|
|
} else {
|
|
UnicodeSPrint (OpRomNameList[Index] , sizeof (CHAR16) * MAX_OPROM_NAME_ID_NUM, L"%s 0x%04x", PciVendorIDString, Option->OpRomOption.DeviceId);
|
|
}
|
|
Index++;
|
|
}
|
|
|
|
*OptionNumber = Index;
|
|
|
|
return OpRomNameList;
|
|
|
|
}
|
|
|
|
/**
|
|
Build the OpRom#### option from the VariableName and the build OpRom#### will
|
|
also be linked to BdsCommonOptionList
|
|
|
|
@param[in,out] *OpRomList - The header of the OpRom#### option link list.
|
|
@param[in] OptionNumber - The number for the OpRom#### variable.
|
|
|
|
@retval OPTION_ROM_LIST_OPTION - Get the option just been created
|
|
@retval NULL - Failed to get the new option
|
|
|
|
**/
|
|
OPTION_ROM_LIST_OPTION *
|
|
EFIAPI
|
|
OpRomVariableToOption (
|
|
IN OUT EFI_LIST_ENTRY *OpRomList,
|
|
IN UINT16 OptionNumber
|
|
)
|
|
{
|
|
UINTN VariableSize;
|
|
UINT8 *Variable;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
CHAR16 OptionName[20];
|
|
EFI_STATUS Status;
|
|
OPTION_ROM_OPTION *OpRomOption;
|
|
|
|
UnicodeSPrint (OptionName, sizeof (OptionName), L"OpRom%04x", OptionNumber);
|
|
//
|
|
// Read the variable. We will never free this data.
|
|
//
|
|
Status = CommonGetVariableDataAndSize (
|
|
OptionName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
&VariableSize,
|
|
(VOID **) &Variable
|
|
);
|
|
if (EFI_ERROR (Status) || (Variable == NULL)) {
|
|
DEBUG ((DEBUG_ERROR, "GetVariable %s: %r\n", OptionName, Status));
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Validate the variable content.
|
|
//
|
|
OpRomOption = (OPTION_ROM_OPTION *) Variable;
|
|
Status = ValidateOpRomVariable (OpRomOption);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Validate Variable %s: %r\n", OptionName, Status));
|
|
return NULL;
|
|
}
|
|
|
|
Option = AllocateZeroPool (sizeof (OPTION_ROM_LIST_OPTION) + OpRomOption->DevicePathSize);
|
|
if (Option == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "AllocatePool for Option to %s: Fail.\n", OptionName));
|
|
return NULL;
|
|
}
|
|
Option->Signature = OPTION_ROM_LIST_OPTION_SIGNATURE;
|
|
CopyMem (&Option->OpRomOption, Variable, VariableSize);
|
|
Option->OptionNumber = OptionNumber;
|
|
InsertTailList (OpRomList, &Option->Link);
|
|
FreePool (Variable);
|
|
return Option;
|
|
}
|
|
|
|
/**
|
|
This function use OpRom#### and OpRomOrder variable to initialize
|
|
option ROM list.
|
|
|
|
@param[in] RomOptionList - The header of the OptionRom policy link list
|
|
|
|
@retval EFI_SUCCESS - Initialize option ROM list successful.
|
|
@retval EFI_ALREADY_STARTED - The option ROM list has been initialized
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetOptionRomPolicyList (
|
|
IN EFI_LIST_ENTRY *RomOptionList
|
|
)
|
|
{
|
|
UINT16 *OptionOrder;
|
|
UINTN OptionOrderSize;
|
|
UINTN Index;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
EFI_STATUS Status;
|
|
|
|
Status = CommonGetVariableDataAndSize (
|
|
L"OpRomOrder",
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
&OptionOrderSize,
|
|
(VOID **) &OptionOrder
|
|
);
|
|
if (EFI_ERROR (Status) || (OptionOrder == NULL)) {
|
|
return Status;
|
|
}
|
|
|
|
for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
|
|
DEBUG ((DEBUG_ERROR, "OpRomVariableToOption() OptionOrder[%d]: %04x\n", Index, OptionOrder[Index]));
|
|
Option = OpRomVariableToOption (RomOptionList, OptionOrder[Index]);
|
|
}
|
|
|
|
if (OptionOrder != NULL) {
|
|
FreePool (OptionOrder);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize Secure Option Rom Control sub-menu for setuputility use.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] *OptionList - The header of the Option Rom policy link list
|
|
@param[in] *StartOpCodeHandle - Handle to the buffer of opcodes.
|
|
@param[in] CreateType - Type of the Option Rom. (Active/Inactive)
|
|
@param[in,out] *OptionNum - Number of Option Rom option.
|
|
|
|
@retval EFI_SUCCESS - Function has completed successfully.
|
|
@retval Others - Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
CreateOptionRomPolicies (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_LIST_ENTRY *OptionList,
|
|
IN VOID *StartOpCodeHandle,
|
|
IN VOID *EndOpCodeHandle,
|
|
IN UINT8 CreateType,
|
|
IN OUT UINTN *OptionNum
|
|
)
|
|
{
|
|
EFI_LIST_ENTRY *Link;
|
|
VOID *OptionsOpCodeHandle;
|
|
UINT8 OptionFlags;
|
|
UINT8 QuestionFlags;
|
|
UINTN IfrOptionCount;
|
|
CHAR16 *NewString;
|
|
CHAR16 OpRomName[MAX_STRING_BUFFER_NUM];
|
|
CHAR16 OpRomHelp[MAX_HELP_BUFFER_NUM];
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
EFI_STRING_ID OptionRomStringId;
|
|
EFI_STRING_ID OptionRomHelpStringId;
|
|
UINTN Index;
|
|
EFI_STRING_ID OpRomTypeStrings [] = {
|
|
STRING_TOKEN (STR_NONE_TEXT),
|
|
STRING_TOKEN (STR_LEGACY_ROM_TEXT),
|
|
STRING_TOKEN (STR_UNSIGNED_EFI_ROM_TEXT),
|
|
STRING_TOKEN (STR_SIGNED_EFI_ROM_TEXT),
|
|
STRING_TOKEN (STR_ALL_TEXT)
|
|
};
|
|
SECURE_OPROM_CONTROL_CONFIGURATION SecureOpRonConfig = {0};
|
|
CHAR16 *PciVendorIDString = NULL;
|
|
UINT8 OpRomPolicy;
|
|
OPTION_ROM_POLICY_SETTING OpRomPolicySetting = {0};
|
|
CHAR16 *PciDevicePathString = NULL;
|
|
EFI_STATUS Status;
|
|
CHAR16 *DevicePathStr;
|
|
BOOLEAN RefreshOpRomVariable;
|
|
UINTN OnBoardIndex;
|
|
|
|
if (OptionList == NULL || StartOpCodeHandle == NULL || OptionNum == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (FALSE == HiiGetBrowserData (&gH2OSecureOptionRomControlFormsetGuid, mVariableName, sizeof(SECURE_OPROM_CONTROL_CONFIGURATION), (UINT8 *)&SecureOpRonConfig)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
OpRomPolicy = SecureOpRonConfig.OptionRomPolicy;
|
|
IfrOptionCount = sizeof (OpRomTypeStrings) / sizeof (EFI_STRING_ID);
|
|
|
|
//
|
|
// Dynamic create all of OP ROM policy
|
|
//
|
|
if (OptionList->ForwardLink == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
RefreshOpRomVariable = FALSE;
|
|
OnBoardIndex = 1;
|
|
for (Link = OptionList->ForwardLink; Link != OptionList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
DEBUG ((DEBUG_INFO, "Option->OptionNumber: 0x%x\n", Option->OptionNumber));
|
|
if ((Option->OpRomOption.FoundRomType & (HAVE_LEGACY_ROM | HAVE_UNSIGNED_EFI_ROM | HAVE_SIGNED_EFI_ROM)) == 0) {
|
|
//
|
|
// For the origianl option content, and the RomType is not detected any type.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Option->OpRomOption.FoundRomType: 0x%x\n", Option->OpRomOption.FoundRomType));
|
|
if (IsSupportedPciSlotDevicePath((EFI_DEVICE_PATH_PROTOCOL *)Option->OpRomOption.DevicePath) == TRUE) {
|
|
//
|
|
// For option which is on the slot, clear the ID content, so that will show "not install"
|
|
//
|
|
Option->OpRomOption.VendorId = 0;
|
|
Option->OpRomOption.DeviceId = 0;
|
|
Option->OpRomOption.OpRomPolicy = 0;
|
|
SetMem (&Option->OpRomOption.HashValue, OPROM_CONTROL_HASH_SIZE, 0);
|
|
DEBUG ((DEBUG_INFO, "For option which is on the slot, clear the ID content, so that will show \"not install\"\n"));
|
|
} else {
|
|
if (FeaturePcdGet (PcdH2OPciOptionRomSecurityControlBySlot)) {
|
|
//
|
|
// For option which is not on the slot, skip showing it and remove it from OpRom list.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "For option which is not on the slot, skip showing it and remove it from OpRom list.\n"));
|
|
RemoveEntryList (&Option->Link);
|
|
FreePool (Option);
|
|
RefreshOpRomVariable = TRUE;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
GetVerdorIdShortName (Option->OpRomOption.VendorId, &PciVendorIDString);
|
|
Status = GetDescriptionName ((EFI_DEVICE_PATH_PROTOCOL *)Option->OpRomOption.DevicePath, &PciDevicePathString);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// Slot-based display.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "PciDevicePathString: %s\n", PciDevicePathString));
|
|
if (PciVendorIDString != NULL) {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" %s: %s -(DID)0x%04x",
|
|
PciDevicePathString,
|
|
PciVendorIDString,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
} else if (Option->OpRomOption.VendorId != 0) {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" %s: (VID)0x%04x -(DID)0x%04x",
|
|
PciDevicePathString,
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
} else {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" %s: Not installed",
|
|
PciDevicePathString,
|
|
Option->OpRomOption.VendorId
|
|
);
|
|
}
|
|
DEBUG ((DEBUG_INFO, "OpRomName: %s\n", OpRomName));
|
|
FreePool (PciDevicePathString);
|
|
} else {
|
|
//
|
|
// On Board device option ROM display.
|
|
//
|
|
if (((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) == OP_ROM_ACTIVE && (CreateType & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) ||
|
|
((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) != OP_ROM_ACTIVE && (CreateType & OP_ROM_INACTIVE) == OP_ROM_INACTIVE)) {
|
|
if (FeaturePcdGet (PcdH2OPciOptionRomSecurityControlBySlot)) {
|
|
//
|
|
// PCI Slot-based display.
|
|
//
|
|
|
|
//
|
|
// Title: L" OnBoard Vendor ID - Devive ID"
|
|
//
|
|
if (PciVendorIDString == NULL) {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" OnBoard %02d: 0x%04x -(DID)0x%04x",
|
|
OnBoardIndex,
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
} else {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" OnBoard %02d: %s -(DID)0x%04x",
|
|
OnBoardIndex,
|
|
PciVendorIDString,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
}
|
|
OnBoardIndex++;
|
|
|
|
} else {
|
|
//
|
|
// PCI VID/DID-based display.
|
|
//
|
|
if (OpRomPolicy == OPTION_ROM_POLICY_AUTO) {
|
|
//
|
|
// Title: L" Vendor ID - Devive ID"
|
|
//
|
|
if (PciVendorIDString == NULL) {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" 0x%04x -(DID)0x%04x",
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
} else {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" %s -(DID)0x%04x",
|
|
PciVendorIDString,
|
|
Option->OpRomOption.DeviceId
|
|
);
|
|
}
|
|
} else {
|
|
//
|
|
// Title: L" Vendor ID - Devive ID (Active/Inactive)"
|
|
//
|
|
if (PciVendorIDString == NULL) {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" 0x%04x -(DID)0x%04x %s",
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId,
|
|
(((CreateType & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) ? L"(Active)":L"(Inactive)")
|
|
);
|
|
} else {
|
|
UnicodeSPrint (
|
|
OpRomName,
|
|
sizeof (OpRomName),
|
|
L" %s -(DID)0x%04x %s",
|
|
PciVendorIDString,
|
|
Option->OpRomOption.DeviceId,
|
|
(((CreateType & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) ? L"(Active)":L"(Inactive)")
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < IfrOptionCount; Index++) {
|
|
OptionFlags = 0;
|
|
if (Option->OpRomOption.OpRomPolicy == Index) {
|
|
OptionFlags = EFI_IFR_OPTION_DEFAULT;
|
|
|
|
if (HiiGetBrowserData (&gH2OSecureOptionRomControlFormsetGuid, L"OpRomSetting", sizeof(OPTION_ROM_POLICY_SETTING), (UINT8 *)&OpRomPolicySetting)) {
|
|
OpRomPolicySetting.OptionRomPolicySetting[Option->OptionNumber] = (UINT8) Index;
|
|
DEBUG ((DEBUG_ERROR, "OpRomPolicySetting[%d]: %d\n", Option->OptionNumber, OpRomPolicySetting.OptionRomPolicySetting[Option->OptionNumber]));
|
|
HiiSetBrowserData (
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
L"OpRomSetting",
|
|
sizeof (OPTION_ROM_POLICY_SETTING),
|
|
(UINT8 *) &OpRomPolicySetting,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
OpRomTypeStrings[Index],
|
|
OptionFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
(UINT8)Index
|
|
);
|
|
}
|
|
|
|
NewString = HiiGetString (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_OPTION_ROM_POLICY_HELP),
|
|
NULL
|
|
);
|
|
if (FeaturePcdGet (PcdH2OPciOptionRomSecurityControlBySlot)) {
|
|
DevicePathStr = ConvertDevicePathToText ((CONST EFI_DEVICE_PATH_PROTOCOL *)(Option->OpRomOption.DevicePath), FALSE, FALSE);
|
|
UnicodeSPrint (
|
|
OpRomHelp,
|
|
sizeof (OpRomHelp),
|
|
L"%s\nSupported ROM Type:\n- Legacy ROM: %s\n- Unsigned UEFI ROM: %s\n- Signed UEFI ROM: %s \n- VID: %04X\n- DID: %04X \n- Active: %s \n- DevicePath: %s",
|
|
NewString,
|
|
((Option->OpRomOption.FoundRomType & HAVE_LEGACY_ROM) ? L"YES":L"NO"),
|
|
((Option->OpRomOption.FoundRomType & HAVE_UNSIGNED_EFI_ROM) ? L"YES":L"NO"),
|
|
((Option->OpRomOption.FoundRomType & HAVE_SIGNED_EFI_ROM) ? L"YES":L"NO"),
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId,
|
|
(((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) ? L"YES":L"NO"),
|
|
DevicePathStr
|
|
);
|
|
} else {
|
|
UnicodeSPrint (
|
|
OpRomHelp,
|
|
sizeof (OpRomHelp),
|
|
L"%s\nSupported ROM Type:\n- Legacy ROM: %s\n- Unsigned UEFI ROM: %s\n- Signed UEFI ROM: %s \n- VID: %04X\n- DID: %04X \n- Active: %s \n",
|
|
NewString,
|
|
((Option->OpRomOption.FoundRomType & HAVE_LEGACY_ROM) ? L"YES":L"NO"),
|
|
((Option->OpRomOption.FoundRomType & HAVE_UNSIGNED_EFI_ROM) ? L"YES":L"NO"),
|
|
((Option->OpRomOption.FoundRomType & HAVE_SIGNED_EFI_ROM) ? L"YES":L"NO"),
|
|
Option->OpRomOption.VendorId,
|
|
Option->OpRomOption.DeviceId,
|
|
(((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) ? L"YES":L"NO")
|
|
);
|
|
}
|
|
|
|
OptionRomStringId = HiiSetString (HiiHandle, 0, OpRomName, NULL);
|
|
OptionRomHelpStringId = HiiSetString (HiiHandle, 0, OpRomHelp, NULL);
|
|
QuestionFlags = EFI_IFR_FLAG_CALLBACK;
|
|
|
|
HiiCreateOneOfOpCode (
|
|
StartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (KEY_OPTION_ROM_POLICY_BASE + Option->OptionNumber),
|
|
SETTING_VARSTORE_ID,
|
|
Option->OptionNumber,
|
|
OptionRomStringId,
|
|
OptionRomHelpStringId,
|
|
QuestionFlags,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiUpdateForm (
|
|
HiiHandle,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
(EFI_FORM_ID) SECURE_OPTION_ROM_CONTROL_FORM_ID,
|
|
StartOpCodeHandle,
|
|
EndOpCodeHandle
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
(*OptionNum)++;
|
|
FreePool (NewString);
|
|
}
|
|
|
|
if (RefreshOpRomVariable == TRUE) {
|
|
SetOpRomPolicies ();
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize Secure Option Rom Control sub-menu for setuputility use.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] OptionList - Hii hanlde for the call back routine.
|
|
|
|
@retval EFI_SUCCESS - Function has completed successfully.
|
|
@retval Others - Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UpdateSecureOpRomDynamicItems (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_LIST_ENTRY *OptionList
|
|
)
|
|
{
|
|
VOID *StartOpCodeHandle = NULL;
|
|
VOID *EndOpCodeHandle = NULL;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
EFI_IFR_GUID_LABEL *EndLabel;
|
|
EFI_STATUS Status;
|
|
UINTN OpRomPolicyNum;
|
|
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (StartOpCodeHandle != NULL);
|
|
|
|
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (EndOpCodeHandle != NULL);
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = SECURE_OPTION_ROM_POLICY_LABEL;
|
|
|
|
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
EndLabel->Number = SECURE_OPTION_ROM_POLICY_END_LABEL;
|
|
|
|
OpRomPolicyNum = 0;
|
|
if (FeaturePcdGet (PcdH2OPciOptionRomSecurityControlBySlot)) {
|
|
CreateOptionRomPolicies (HiiHandle, OptionList, StartOpCodeHandle, EndOpCodeHandle, OP_ROM_ACTIVE, &OpRomPolicyNum);
|
|
} else {
|
|
CreateOptionRomPolicies (HiiHandle, OptionList, StartOpCodeHandle, EndOpCodeHandle, OP_ROM_ACTIVE, &OpRomPolicyNum);
|
|
CreateOptionRomPolicies (HiiHandle, OptionList, StartOpCodeHandle, EndOpCodeHandle, OP_ROM_INACTIVE, &OpRomPolicyNum);
|
|
}
|
|
|
|
Status = HiiUpdateForm (
|
|
HiiHandle,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
(EFI_FORM_ID) SECURE_OPTION_ROM_CONTROL_FORM_ID,
|
|
StartOpCodeHandle,
|
|
EndOpCodeHandle
|
|
);
|
|
|
|
if (StartOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
}
|
|
if (EndOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (EndOpCodeHandle);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Initialize Secure Option Rom Control sub-menu for setuputility use
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine
|
|
|
|
@retval EFI_SUCCESS - Function has completed successfully.
|
|
@retval Others - Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
InitSecureOpRomSubMenu (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
SECURE_OPROM_CONTROL_CONFIGURATION Configuration = {0};
|
|
|
|
|
|
BufferSize = sizeof (SECURE_OPROM_CONTROL_CONFIGURATION);
|
|
Status = gRT->GetVariable (
|
|
mVariableName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Configuration
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
HiiSetBrowserData (
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
mVariableName,
|
|
sizeof (SECURE_OPROM_CONTROL_CONFIGURATION),
|
|
(UINT8 *) &Configuration,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink != NULL) {
|
|
FreeOptionRomPolicyList ();
|
|
}
|
|
|
|
InitializeListHead (&mOpRomPolicyListForSetup);
|
|
GetOptionRomPolicyList (&mOpRomPolicyListForSetup);
|
|
|
|
Status = UpdateSecureOpRomDynamicItems (HiiHandle, &mOpRomPolicyListForSetup);
|
|
if (!EFI_ERROR (Status)) {
|
|
mSetupInitDone = TRUE;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Find OP ROM policy in active/inactive Option ROM list.
|
|
|
|
@param[in] OpRomPolicyNum - Number of Option ROM list.
|
|
|
|
@retval Option - OpRom entry in Option ROM list.
|
|
@retval NULL - Not found the OpRom entry.
|
|
|
|
**/
|
|
OPTION_ROM_LIST_OPTION *
|
|
EFIAPI
|
|
FindOptionRomPolicy (
|
|
IN UINT16 OpRomPolicyNum
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
BOOLEAN OptionRomPolicyFound;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
OptionRomPolicyFound = FALSE;
|
|
Option = NULL;
|
|
Status = EFI_NOT_FOUND;
|
|
//
|
|
// Try to find matched OP ROM policy in active OP ROM Policy list first
|
|
//
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if ((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) {
|
|
if (Option->OptionNumber == OpRomPolicyNum) {
|
|
OptionRomPolicyFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// If can not find OP ROM policy in active OP ROM list, try to find mathced OP
|
|
// ROM in inactive option ROM policy list
|
|
//
|
|
if (!OptionRomPolicyFound) {
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if ((Option->OpRomOption.Attribute & OP_ROM_INACTIVE) == OP_ROM_INACTIVE) {
|
|
if (Option->OptionNumber == OpRomPolicyNum) {
|
|
OptionRomPolicyFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!OptionRomPolicyFound) {
|
|
Option = NULL;
|
|
}
|
|
return Option;
|
|
|
|
}
|
|
|
|
/**
|
|
Update Option ROM policy in Option ROM list.
|
|
|
|
@param[in] OpRomPolicyNum - Number of Option ROM list.
|
|
@param[in] Type - Policy of the OpRom entry.
|
|
|
|
@retval EFI_SUCCESS - OpRom entry in Option ROM list.
|
|
@retval EFI_NOT_FOUND - Not found the OpRom entry.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UpdateOptionRomPolicy (
|
|
IN UINT16 OpRomPolicyNum,
|
|
IN UINT8 Type
|
|
)
|
|
{
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
EFI_STATUS Status;
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
Option = FindOptionRomPolicy (OpRomPolicyNum);
|
|
if (Option != NULL) {
|
|
Option->OpRomOption.OpRomPolicy = Type;
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Find Option ROM policy with related Index num.
|
|
|
|
@param[in] OpRomPolicyIndexedNum - Index num of the related PCI Option ROM.
|
|
|
|
@retval Option - OpRom entry in Option ROM list.
|
|
@retval NULL - Not found the OpRom entry.
|
|
|
|
**/
|
|
OPTION_ROM_LIST_OPTION *
|
|
EFIAPI
|
|
FindOptionRomPolicyByIndexNum (
|
|
IN UINT16 OpRomPolicyIndexedNum
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 Index;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
BOOLEAN OptionRomPolicyFound;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
return NULL;
|
|
}
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
Index = 0;
|
|
OptionRomPolicyFound = FALSE;
|
|
Option = NULL;
|
|
Status = EFI_NOT_FOUND;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if (Option->OptionNumber == OpRomPolicyIndexedNum) {
|
|
OptionRomPolicyFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!OptionRomPolicyFound) {
|
|
Option = NULL;
|
|
}
|
|
return Option;
|
|
}
|
|
|
|
/**
|
|
Find Option ROM policy with related Vendor ID/ Device ID.
|
|
|
|
@param[in] VendorId - Vendor ID of the related PCI Option ROM.
|
|
@param[in] DeviceId - Device ID of the related PCI Option ROM.
|
|
|
|
@retval Option - OpRom entry in Option ROM list.
|
|
@retval NULL - Not found the OpRom entry.
|
|
|
|
**/
|
|
OPTION_ROM_LIST_OPTION *
|
|
EFIAPI
|
|
FindOptionRomPolicyByID (
|
|
IN UINT16 VendorId,
|
|
IN UINT16 DeviceId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 Index;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
BOOLEAN OptionRomPolicyFound;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
Index = 0;
|
|
OptionRomPolicyFound = FALSE;
|
|
Option = NULL;
|
|
Status = EFI_NOT_FOUND;
|
|
//
|
|
// Try to find matched OP ROM policy in active OP ROM Policy list first
|
|
//
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if ((Option->OpRomOption.Attribute & OP_ROM_ACTIVE) == OP_ROM_ACTIVE) {
|
|
if ((Option->OpRomOption.VendorId == VendorId) && (Option->OpRomOption.DeviceId == DeviceId)) {
|
|
OptionRomPolicyFound = TRUE;
|
|
break;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
//
|
|
// If can not find OP ROM policy in active OP ROM list, try to find mathced OP
|
|
// ROM in inactive option ROM policy list
|
|
//
|
|
if (!OptionRomPolicyFound) {
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if ((Option->OpRomOption.Attribute & OP_ROM_INACTIVE) == OP_ROM_INACTIVE) {
|
|
if ((Option->OpRomOption.VendorId == VendorId) && (Option->OpRomOption.DeviceId == DeviceId)) {
|
|
OptionRomPolicyFound = TRUE;
|
|
break;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
}
|
|
if (!OptionRomPolicyFound) {
|
|
Option = NULL;
|
|
}
|
|
return Option;
|
|
|
|
}
|
|
|
|
/**
|
|
Get new OP ROM option number for OpRom#### variable
|
|
|
|
@param[out] NewOptionNum - Pointer to new OP ROM option number
|
|
|
|
@retval EFI_SUCCESS - Get New OP ROM option number
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetNewOpRomOptionNoForSetup (
|
|
OUT UINT16 *NewOptionNum
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 Index;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
UINT16 OptionNum;
|
|
BOOLEAN OptionNumFound;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
*NewOptionNum = 0;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
OptionNum = 0;
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
Index = 0;
|
|
Option = NULL;
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
OptionNum++;
|
|
}
|
|
|
|
for (Index = 0; Index < OptionNum; Index++) {
|
|
OptionNumFound = FALSE;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
if (Option->OptionNumber == Index) {
|
|
OptionNumFound = TRUE;
|
|
}
|
|
}
|
|
if (!OptionNumFound) {
|
|
break;
|
|
}
|
|
}
|
|
*NewOptionNum = Index;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Insert the Option ROM policy into Option ROM policy list.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] VendorId - Vendor ID of the related PCI Option ROM.
|
|
@param[in] DeviceId - Device ID of the related PCI Option ROM.
|
|
|
|
@retval EFI_SUCCESS - Insert the Option ROM policy entry success.
|
|
@retval other - Insert the Option ROM policy entry failure.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
InsertOptionRomPolicy (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN UINT16 VendorId,
|
|
IN UINT16 DeviceId
|
|
)
|
|
{
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
EFI_STATUS Status;
|
|
SECURE_OPROM_CONTROL_CONFIGURATION SecureOpRonConfig = {0};
|
|
|
|
//
|
|
// Check this policy exist or not?
|
|
//
|
|
Option = FindOptionRomPolicyByID (VendorId, DeviceId);
|
|
if (Option != NULL) {
|
|
return EFI_ABORTED;
|
|
}
|
|
|
|
Option = AllocateZeroPool (sizeof (OPTION_ROM_LIST_OPTION));
|
|
if (Option == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
if (FALSE == HiiGetBrowserData (&gH2OSecureOptionRomControlFormsetGuid, mVariableName, sizeof(SECURE_OPROM_CONTROL_CONFIGURATION), (UINT8 *)&SecureOpRonConfig)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Option->Signature = OPTION_ROM_LIST_OPTION_SIGNATURE;
|
|
Option->OpRomOption.Attribute = OP_ROM_INACTIVE;
|
|
Option->OpRomOption.FoundRomType = 0;
|
|
Option->OpRomOption.OpRomPolicy = (SecureOpRonConfig.OptionRomPolicy == OPTION_ROM_POLICY_AUTO) ? SUPPORT_ALL_OPTION_ROM : (SecureOpRonConfig.OptionRomPolicy - 1);
|
|
Option->OpRomOption.VendorId = VendorId;
|
|
Option->OpRomOption.DeviceId = DeviceId;
|
|
GetNewOpRomOptionNoForSetup (&Option->OptionNumber);
|
|
InsertTailList (&mOpRomPolicyListForSetup, &Option->Link);
|
|
|
|
Status = UpdateSecureOpRomDynamicItems (
|
|
HiiHandle,
|
|
&mOpRomPolicyListForSetup
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
SetOpRomPolicies ();
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Delete the Option ROM policy from Option ROM policy list.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] OpRomPolicyIndexedNum - Number of Option ROM list.
|
|
|
|
@retval EFI_SUCCESS - Delete the Option ROM policy entry success.
|
|
@retval other - Delete the Option ROM policy entry failure.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DeleteOptionRomPolicy (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN UINT16 OpRomPolicyIndexedNum
|
|
)
|
|
{
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
EFI_STATUS Status;
|
|
OPTION_ROM_POLICY_SETTING OpRomPolicySetting = {0};
|
|
EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
|
|
CHAR16 *ConfigRequest;
|
|
UINTN ConfigRequestSize;
|
|
UINT8 MyNameValue0;
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
Option = FindOptionRomPolicyByIndexNum (OpRomPolicyIndexedNum);
|
|
if (Option != NULL) {
|
|
HiiSetBrowserData (
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
L"OpRomSetting",
|
|
sizeof (OPTION_ROM_POLICY_SETTING),
|
|
(UINT8 *) &OpRomPolicySetting,
|
|
NULL
|
|
);
|
|
MyNameValue0 = (UINT8) (Option->OptionNumber + 1);
|
|
//
|
|
// Remove the selected option ROM policy and update form to HII handle.
|
|
//
|
|
RemoveEntryList (&Option->Link);
|
|
FreePool (Option);
|
|
Status = UpdateSecureOpRomDynamicItems (
|
|
HiiHandle,
|
|
&mOpRomPolicyListForSetup
|
|
);
|
|
FreePool (mOpRomDeviceList);
|
|
|
|
//
|
|
// Change name value data to make form brower will call RouteConfig () when SubmitForm ()
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
|
|
if (!EFI_ERROR (Status)) {
|
|
ConfigRequestSize = 0x100;
|
|
ConfigRequest = AllocateZeroPool (ConfigRequestSize);
|
|
UnicodeSPrint (ConfigRequest, ConfigRequestSize, L"MyNameValue0=%02x", MyNameValue0);
|
|
FormBrowser2->BrowserCallback (
|
|
FormBrowser2,
|
|
&ConfigRequestSize,
|
|
ConfigRequest,
|
|
FALSE,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
L"MyNameValue0"
|
|
);
|
|
FreePool (ConfigRequest);
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Set variables "OpRomXXXX" and "OpRomOrder" to describe the each OpRom entry.
|
|
|
|
@param VOID
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SetOpRomPolicies (
|
|
VOID
|
|
)
|
|
{
|
|
UINT16 OptionNum;
|
|
UINT16 Index;
|
|
UINT16 *OptionOrder;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
CHAR16 OptionName[20];
|
|
EFI_STATUS Status;
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
UINTN OptionOrderSize;
|
|
UINT16 *OpRomOrder;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
//
|
|
// No Option ROM policy can save.
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
OptionNum = 0;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
//
|
|
// Set inactive when exiting SCU, the variables will be re-initialize in next boot.
|
|
//
|
|
Option->OpRomOption.Attribute = OP_ROM_INACTIVE;
|
|
UnicodeSPrint (OptionName, sizeof (OptionName), L"OpRom%04x", Option->OptionNumber);
|
|
Status = SetVariableToSensitiveVariable (
|
|
OptionName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (OPTION_ROM_OPTION) + Option->OpRomOption.DevicePathSize,
|
|
&(Option->OpRomOption)
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "SetVariable OpRom%04x: %r\n", Option->OptionNumber, Status));
|
|
} else {
|
|
//
|
|
// Todo:
|
|
// Add code to set this variable in Sensitive variable through SMI.
|
|
// Need the interface provided by later kernel version.
|
|
|
|
|
|
}
|
|
OptionNum++;
|
|
}
|
|
|
|
OptionOrder = (OptionNum == 0) ? NULL : AllocateZeroPool (OptionNum * sizeof (UINT16));
|
|
if (OptionOrder != NULL) {
|
|
Index = 0;
|
|
for (Link = OptionRomPolicyList->ForwardLink; Link != OptionRomPolicyList; Link = Link->ForwardLink) {
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
OptionOrder[Index++] = Option->OptionNumber;
|
|
}
|
|
}
|
|
Status = SetVariableToSensitiveVariable (
|
|
L"OpRomOrder",
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
OptionNum * sizeof (UINT16),
|
|
OptionOrder
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "SetVariable OpRomOrder: %r\n", Status));
|
|
} else {
|
|
//
|
|
// Todo:
|
|
// Add code to set this variable in Sensitive variable through SMI.
|
|
// Need the interface provided by later kernel version.
|
|
|
|
|
|
DEBUG_CODE (
|
|
Status = CommonGetVariableDataAndSize(
|
|
L"OpRomOrder",
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
&OptionOrderSize,
|
|
(VOID **) &OpRomOrder
|
|
);
|
|
if (EFI_ERROR (Status) || (OpRomOrder == NULL)) {
|
|
DEBUG ((DEBUG_ERROR, "GetVariable OpRomOrder: %r.\n", Status));
|
|
} else {
|
|
for (Index = 0; Index < (OptionOrderSize / sizeof(UINT16)); Index++) {
|
|
DEBUG ((DEBUG_ERROR, "OpRomOrder[%d] = %d\n", Index, OpRomOrder[Index]));
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
if (OptionOrder != NULL) {
|
|
FreePool (OptionOrder);
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Callback function for inserting the Option ROM policy.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] *H2ODialog - Protocol interface of H2O Dialog protocol.
|
|
|
|
@retval EFI_SUCCESS - Insert the Option ROM policy entry success.
|
|
@retval other - Insert the Option ROM policy entry failure.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
InsertOptionRomPolicyCallback (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN H2O_DIALOG_PROTOCOL *H2ODialog
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT64 VendorID;
|
|
UINT64 DeviceID;
|
|
|
|
Status = H2ODialog->NumericDialog (
|
|
L"Set Vendor ID (Hex)",
|
|
0,
|
|
0xFFFE,
|
|
1,
|
|
TRUE,
|
|
&VendorID
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (VendorID == 0) {
|
|
return Status;
|
|
}
|
|
|
|
Status = H2ODialog->NumericDialog (
|
|
L"Set Device ID (Hex)",
|
|
0,
|
|
0xFFFF,
|
|
1,
|
|
TRUE,
|
|
&DeviceID
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = InsertOptionRomPolicy (HiiHandle, (UINT16)VendorID, (UINT16)DeviceID);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Insert Option ROM policy: %r.\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Callback function for deleting the Option ROM policy.
|
|
|
|
@param[in] HiiHandle - Hii hanlde for the call back routine.
|
|
@param[in] *H2ODialog - Protocol interface of H2O Dialog protocol.
|
|
|
|
@retval EFI_SUCCESS - Delete the Option ROM policy entry success.
|
|
@retval other - Delete the Option ROM policy entry failure.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DeleteOptionRomPolicyCallback (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN H2O_DIALOG_PROTOCOL *H2ODialog
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT32 SelectedIndex;
|
|
CHAR16 **OpRomNameList;
|
|
UINT32 OpRomNum;
|
|
CHAR16 *StringPtr;
|
|
CHAR16 StringBuffer[MAX_STRING_BUFFER_NUM];
|
|
EFI_INPUT_KEY Key;
|
|
|
|
OpRomNum = 0;
|
|
OpRomNameList = GetOpRomNameList (&OpRomNum);
|
|
if (OpRomNum == 0) {
|
|
UnicodeSPrint (StringBuffer , MAX_STRING_BUFFER_NUM, L"There is no OpROM option can delete!");
|
|
H2ODialog->ConfirmDialog (
|
|
DlgOk,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
StringBuffer
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
StringPtr = HiiGetString (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_DELETE_OPROM_POLICY_DIAG),
|
|
NULL
|
|
);
|
|
H2ODialog->OneOfOptionDialog(
|
|
(UINT32)OpRomNum, // OpRom Number
|
|
FALSE,
|
|
NULL,
|
|
&Key,
|
|
MAX_OPROM_NAME_ID_NUM,
|
|
StringPtr,
|
|
&SelectedIndex,
|
|
(CHAR16 **) (OpRomNameList),
|
|
0
|
|
);
|
|
FreePool (StringPtr);
|
|
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
StringPtr = AllocateZeroPool (MAX_STRING_BUFFER_NUM);
|
|
//
|
|
// User select the device to delete.
|
|
// Popup a dialogue to check again.
|
|
//
|
|
UnicodeSPrint (StringBuffer , MAX_STRING_BUFFER_NUM, L"Do you want to delete \"%s\"", OpRomNameList[SelectedIndex]);
|
|
H2ODialog->ConfirmDialog (
|
|
DlgYesNo,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
StringBuffer
|
|
);
|
|
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
Status = DeleteOptionRomPolicy (HiiHandle, (UINT16)SelectedIndex);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Delete Option ROM policy: %r.\n", Status));
|
|
}
|
|
}
|
|
}
|
|
|
|
FreePool (OpRomNameList);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Remove OpRom Entries from OpRomPolicyList in Setup Utility configuration.
|
|
|
|
@param VOID
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
FreeOptionRomPolicyList (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_LIST_ENTRY *OptionRomPolicyList;
|
|
EFI_LIST_ENTRY *Link;
|
|
OPTION_ROM_LIST_OPTION *Option;
|
|
|
|
if (mOpRomPolicyListForSetup.ForwardLink == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
OptionRomPolicyList = &mOpRomPolicyListForSetup;
|
|
while (!IsListEmpty (OptionRomPolicyList)) {
|
|
Link = OptionRomPolicyList->ForwardLink;
|
|
Option = CR (Link, OPTION_ROM_LIST_OPTION, Link, OPTION_ROM_LIST_OPTION_SIGNATURE);
|
|
RemoveEntryList (Link);
|
|
FreePool (Option);
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Clear the content OpRomPolicyList in Setup Utility configuration.
|
|
|
|
@param[in] VOID
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
LoadOpRomPolicyListToDefault (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SECURE_OPROM_CONTROL_CONFIGURATION SecureOpRonConfig = {0};
|
|
BOOLEAN BoolStatus;
|
|
|
|
Status = FreeOptionRomPolicyList ();
|
|
if (!EFI_ERROR (Status)) {
|
|
InitializeListHead (&mOpRomPolicyListForSetup);
|
|
if (FeaturePcdGet (PcdH2OPciOptionRomSecurityControlBySlot)) {
|
|
GetDefaultOptionRomPolicyList (&mOpRomPolicyListForSetup, 0);
|
|
}
|
|
UpdateSecureOpRomDynamicItems (HiiHandle, &mOpRomPolicyListForSetup);
|
|
SecureOpRonConfig.OptionRomPolicy = OPTION_ROM_POLICY_AUTO;
|
|
BoolStatus = HiiSetBrowserData (
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
mVariableName,
|
|
sizeof (SECURE_OPROM_CONTROL_CONFIGURATION),
|
|
(UINT8 *) &SecureOpRonConfig,
|
|
NULL
|
|
);
|
|
DEBUG ((DEBUG_ERROR, "HiiSetBrowserData: %d \n", BoolStatus));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
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 illegal syntax, or unknown name.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
|
driver.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ExtractConfig (
|
|
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;
|
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
|
EFI_STRING ConfigRequest;
|
|
EFI_STRING ConfigRequestHdr;
|
|
UINTN Size;
|
|
BOOLEAN AllocatedRequest;
|
|
EFI_STRING Value;
|
|
UINTN ValueStrLen;
|
|
UINT8 MyNameValue0;
|
|
CHAR16 BackupChar;
|
|
|
|
if (Progress == NULL || Results == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Initialize the local variables.
|
|
//
|
|
ConfigRequestHdr = NULL;
|
|
ConfigRequest = NULL;
|
|
Size = 0;
|
|
*Progress = Request;
|
|
AllocatedRequest = FALSE;
|
|
|
|
HiiConfigRouting = mPrivateData->HiiConfigRouting;
|
|
|
|
//
|
|
// Get Buffer Storage data from EFI variable.
|
|
// Try to get the current setting from variable.
|
|
//
|
|
BufferSize = sizeof (SECURE_OPROM_CONTROL_CONFIGURATION);
|
|
Status = gRT->GetVariable (
|
|
mVariableName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&mPrivateData->Configuration
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (Request == NULL) {
|
|
//
|
|
// Request is set to NULL, 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 (&gH2OSecureOptionRomControlFormsetGuid, mVariableName, mPrivateData->DriverHandle);
|
|
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);
|
|
ConfigRequestHdr = NULL;
|
|
} else {
|
|
if (!HiiIsConfigHdrMatch (Request, &gH2OSecureOptionRomControlFormsetGuid, mVariableName)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
//
|
|
// Set Request to the unified request string.
|
|
//
|
|
ConfigRequest = Request;
|
|
}
|
|
|
|
if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
|
|
//
|
|
// If requesting Name/Value storage, return value 0.
|
|
//
|
|
//
|
|
// Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
|
|
// <Request> ::=<ConfigHdr>&Name0&Name1&Name2
|
|
// <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
|
|
//
|
|
BufferSize = (StrLen (ConfigRequest) + 1 + sizeof (MyNameValue0) * 2 + 1) * sizeof (CHAR16);
|
|
*Results = AllocateZeroPool (BufferSize);
|
|
ASSERT (*Results != NULL);
|
|
StrCpyS (*Results, BufferSize / sizeof(CHAR16), ConfigRequest);
|
|
Value = *Results;
|
|
|
|
//
|
|
// Append value of NameValueVar0, type is UINT8
|
|
//
|
|
if ((Value = StrStr (*Results, L"MyNameValue0")) != NULL) {
|
|
MyNameValue0 = 0;
|
|
|
|
Value += StrLen (L"MyNameValue0");
|
|
ValueStrLen = ((sizeof (MyNameValue0) * 2) + 1);
|
|
CopyMem (&Value[ValueStrLen], Value, StrSize (Value));
|
|
|
|
BackupChar = Value[ValueStrLen];
|
|
*Value++ = L'=';
|
|
Value += UnicodeValueToStringS (
|
|
Value,
|
|
BufferSize - ((UINTN) Value - (UINTN) *Results),
|
|
PREFIX_ZERO | RADIX_HEX,
|
|
MyNameValue0,
|
|
sizeof (MyNameValue0) * 2
|
|
);
|
|
*Value = BackupChar;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = HiiConfigRouting->BlockToConfig (
|
|
HiiConfigRouting,
|
|
ConfigRequest,
|
|
(UINT8 *)&mPrivateData->Configuration,
|
|
1,
|
|
Results,
|
|
Progress
|
|
);
|
|
//
|
|
// Free the allocated config request string.
|
|
//
|
|
if (AllocatedRequest) {
|
|
FreePool (ConfigRequest);
|
|
}
|
|
|
|
//
|
|
// 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 EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function processes the results of changes in configuration.
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param Configuration A null-terminated Unicode string in <ConfigResp>
|
|
format.
|
|
@param Progress A pointer to a string filled in with the offset of
|
|
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) or
|
|
the terminating NULL if all was successful.
|
|
|
|
@retval EFI_SUCCESS The Results is processed successfully.
|
|
@retval EFI_INVALID_PARAMETER Configuration is NULL.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
|
driver.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RouteConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Configuration,
|
|
OUT EFI_STRING *Progress
|
|
)
|
|
{
|
|
SECURE_OPROM_CONTROL_CONFIGURATION SecureOpRonConfig = {0};
|
|
EFI_STATUS Status;
|
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
|
UINTN BufferSize;
|
|
|
|
if (Configuration == NULL || Progress == NULL || This == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Progress = Configuration;
|
|
if (!HiiIsConfigHdrMatch(Configuration, &gH2OSecureOptionRomControlFormsetGuid, mVariableName)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
SetOpRomPolicies ();
|
|
|
|
HiiConfigRouting = mPrivateData->HiiConfigRouting;
|
|
BufferSize = sizeof (SECURE_OPROM_CONTROL_CONFIGURATION);
|
|
Status = HiiConfigRouting->ConfigToBlock (
|
|
HiiConfigRouting,
|
|
Configuration,
|
|
(UINT8 *) &SecureOpRonConfig,
|
|
&BufferSize,
|
|
Progress
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// Store broswer data Buffer Storage to EFI variable
|
|
//
|
|
Status = SetVariableToSensitiveVariable (
|
|
mVariableName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (SECURE_OPROM_CONTROL_CONFIGURATION),
|
|
&SecureOpRonConfig
|
|
);
|
|
return Status;
|
|
|
|
}
|
|
|
|
/**
|
|
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.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverCallback (
|
|
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
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_DIALOG_PROTOCOL *H2ODialog;
|
|
|
|
if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
|
|
(ActionRequest == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
switch (Action) {
|
|
case EFI_BROWSER_ACTION_FORM_OPEN:
|
|
DEBUG ((DEBUG_ERROR, "EFI_BROWSER_ACTION_FORM_OPEN. \n"));
|
|
if (mSetupInitDone == FALSE) {
|
|
Status = InitSecureOpRomSubMenu (mPrivateData->HiiHandle);
|
|
return Status;
|
|
}
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_CHANGING:
|
|
DEBUG ((DEBUG_ERROR, "EFI_BROWSER_ACTION_CHANGING. \n"));
|
|
{
|
|
Status = gBS->LocateProtocol (
|
|
&gH2ODialogProtocolGuid,
|
|
NULL,
|
|
(VOID **)&H2ODialog
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
switch (QuestionId) {
|
|
case KEY_OPROM_POLICY_INSERT:
|
|
DEBUG ((DEBUG_ERROR, "KEY_OPROM_POLICY_INSERT!!\n"));
|
|
Status = InsertOptionRomPolicyCallback (mPrivateData->HiiHandle, H2ODialog);
|
|
break;
|
|
|
|
case KEY_OPROM_POLICY_DELETE:
|
|
DEBUG ((DEBUG_ERROR, "KEY_OPROM_POLICY_DELETE!!\n"));
|
|
Status = DeleteOptionRomPolicyCallback (mPrivateData->HiiHandle, H2ODialog);
|
|
break;
|
|
|
|
case KEY_OPROM_POLICY_CONTROL:
|
|
DEBUG ((DEBUG_ERROR, "KEY_OPROM_POLICY_CONTROL!!\n"));
|
|
Status = UpdateSecureOpRomDynamicItems (mPrivateData->HiiHandle, &mOpRomPolicyListForSetup);
|
|
break;
|
|
|
|
default:
|
|
if ((QuestionId >= KEY_OPTION_ROM_POLICY_BASE) && (QuestionId < KEY_OPTION_ROM_POLICY_BASE + MAX_OPTION_ROM_POLICY)) {
|
|
Status = UpdateOptionRomPolicy (QuestionId - KEY_OPTION_ROM_POLICY_BASE, Value->u8);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
|
|
DEBUG ((DEBUG_ERROR, "EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING. \n"));
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
|
|
DEBUG ((DEBUG_ERROR, "EFI_BROWSER_ACTION_DEFAULT_STANDARD. \n"));
|
|
if (QuestionId == KEY_LOAD_DEFAULT) {
|
|
//
|
|
// Load Option Rom Policy list to default. The action is to delete all of specific
|
|
// option ROM policy.
|
|
//
|
|
LoadOpRomPolicyListToDefault (mPrivateData->HiiHandle);
|
|
} else {
|
|
Status = EFI_UNSUPPORTED;
|
|
}
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_RETRIEVE:
|
|
DEBUG ((DEBUG_ERROR, "EFI_BROWSER_ACTION_RETRIEVE. \n"));
|
|
if (QuestionId == KEY_LOAD_DEFAULT) {
|
|
Status = EFI_SUCCESS;
|
|
} else {
|
|
Status = EFI_UNSUPPORTED;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Unloads the application and its installed protocol.
|
|
|
|
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
|
|
|
@retval EFI_SUCCESS The image has been unloaded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SetupUnload (
|
|
IN EFI_HANDLE ImageHandle
|
|
)
|
|
{
|
|
|
|
ASSERT (mPrivateData != NULL);
|
|
|
|
if (mDriverHandle != NULL) {
|
|
gBS->UninstallMultipleProtocolInterfaces (
|
|
mDriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&mHiiVendorDevicePath0,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
&mPrivateData->ConfigAccess,
|
|
NULL
|
|
);
|
|
mDriverHandle = NULL;
|
|
}
|
|
|
|
if (mPrivateData->HiiHandle != NULL) {
|
|
HiiRemovePackages (mPrivateData->HiiHandle);
|
|
}
|
|
|
|
FreePool (mPrivateData);
|
|
mPrivateData = NULL;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
SetupUtilityApplicationNotifyFn (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SETUP_UTILITY_BROWSER_PROTOCOL *Interface;
|
|
|
|
DEBUG ((DEBUG_ERROR, "SetupUtilityApplicationNotifyFn Start.\n"));
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSetupUtilityApplicationProtocolGuid,
|
|
NULL,
|
|
(VOID **) &Interface
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return;
|
|
}
|
|
|
|
DEBUG ((DEBUG_ERROR, "Set mSetupInitDone to FALSE.\n"));
|
|
mSetupInitDone = FALSE;
|
|
|
|
DEBUG ((DEBUG_ERROR, "SetupUtilityApplicationNotifyFn End.\n"));
|
|
return;
|
|
|
|
}
|
|
|
|
/**
|
|
Initialization for the Setup related functions.
|
|
|
|
@param ImageHandle Image handle this driver.
|
|
@param SystemTable Pointer to SystemTable.
|
|
|
|
@retval EFI_SUCESS This function always complete successfully.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SetupInit (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HII_HANDLE HiiHandle;
|
|
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
|
|
EFI_HII_STRING_PROTOCOL *HiiString;
|
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
|
CHAR16 *NewString;
|
|
UINTN BufferSize;
|
|
SECURE_OPROM_CONTROL_CONFIGURATION *Configuration;
|
|
BOOLEAN ActionFlag;
|
|
EFI_STRING ConfigRequestHdr;
|
|
EFI_EVENT Event;
|
|
VOID *Registration;
|
|
|
|
//
|
|
// Initialize the local variables.
|
|
//
|
|
ConfigRequestHdr = NULL;
|
|
NewString = NULL;
|
|
|
|
//
|
|
// When installing Setup Utility Browser, set mSetupInitDone to FALSE to initialize the vfr.
|
|
//
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_CALLBACK - 1,
|
|
SetupUtilityApplicationNotifyFn,
|
|
NULL,
|
|
&Event
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&gEfiSetupUtilityApplicationProtocolGuid,
|
|
Event,
|
|
&Registration
|
|
);
|
|
}
|
|
|
|
//
|
|
// Initialize driver private data
|
|
//
|
|
mPrivateData = AllocateZeroPool (sizeof (SECURE_OPROM_CONTROL_PRIVATE_DATA));
|
|
if (mPrivateData == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
mPrivateData->Signature = SECURE_OPROM_CONTROL_PRIVATE_SIGNATURE;
|
|
|
|
mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
|
|
mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
|
|
mPrivateData->ConfigAccess.Callback = DriverCallback;
|
|
|
|
//
|
|
// Locate Hii Database protocol
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mPrivateData->HiiDatabase = HiiDatabase;
|
|
|
|
//
|
|
// Locate HiiString protocol
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mPrivateData->HiiString = HiiString;
|
|
|
|
//
|
|
// Locate ConfigRouting protocol
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mPrivateData->HiiConfigRouting = HiiConfigRouting;
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&mDriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&mHiiVendorDevicePath0,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
&mPrivateData->ConfigAccess,
|
|
NULL
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
mPrivateData->DriverHandle = mDriverHandle;
|
|
|
|
//
|
|
// Publish our HII data
|
|
//
|
|
HiiHandle = HiiAddPackages (
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
mDriverHandle,
|
|
SecureOptionRomControlDxeStrings,
|
|
SecureOptionRomControlSetupBin,
|
|
NULL
|
|
);
|
|
if (HiiHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
mPrivateData->HiiHandle = HiiHandle;
|
|
|
|
//
|
|
// Initialize configuration data
|
|
//
|
|
Configuration = &mPrivateData->Configuration;
|
|
ZeroMem (Configuration, sizeof (SECURE_OPROM_CONTROL_CONFIGURATION));
|
|
|
|
//
|
|
// Try to read NV config EFI variable first
|
|
//
|
|
ConfigRequestHdr = HiiConstructConfigHdr (&gH2OSecureOptionRomControlFormsetGuid, mVariableName, mDriverHandle);
|
|
ASSERT (ConfigRequestHdr != NULL);
|
|
if (ConfigRequestHdr == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
DEBUG ((DEBUG_ERROR, "ConfigRequestHdr: %s\n", ConfigRequestHdr));
|
|
|
|
BufferSize = sizeof (SECURE_OPROM_CONTROL_CONFIGURATION);
|
|
Status = gRT->GetVariable (mVariableName, &gH2OSecureOptionRomControlFormsetGuid, NULL, &BufferSize, Configuration);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Store zero data Buffer Storage to EFI variable
|
|
//
|
|
Status = SetVariableToSensitiveVariable (
|
|
mVariableName,
|
|
&gH2OSecureOptionRomControlFormsetGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (SECURE_OPROM_CONTROL_CONFIGURATION),
|
|
Configuration
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
SetupUnload (ImageHandle);
|
|
return Status;
|
|
}
|
|
//
|
|
// EFI variable for NV config doesn't exit, we should build this variable
|
|
// based on default values stored in IFR
|
|
//
|
|
|
|
ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
|
|
if (!ActionFlag) {
|
|
SetupUnload (ImageHandle);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
} else {
|
|
//
|
|
// EFI variable does exist and Validate Current Setting
|
|
//
|
|
|
|
ActionFlag = HiiValidateSettings (ConfigRequestHdr);
|
|
if (!ActionFlag) {
|
|
SetupUnload (ImageHandle);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
FreePool (ConfigRequestHdr);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|