1204 lines
51 KiB
C
1204 lines
51 KiB
C
/** @file
|
|
Code implementing the CLI wrapper & other CLI API's.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
|
|
Copyright (c) 2021 Intel Corporation. All rights
|
|
reserved This software and associated documentation (if any)
|
|
is furnished under a license and may only be used or copied in
|
|
accordance with the terms of the license. Except as permitted
|
|
by the license, no part of this software or documentation may
|
|
be reproduced, stored in a retrieval system, or transmitted in
|
|
any form or by any means without the express written consent
|
|
of Intel Corporation.
|
|
This file contains an 'Sample Driver' and is uniquely
|
|
identified as "Intel Reference Module" and is licensed for Intel
|
|
CPUs and chipsets under the terms of your license agreement with
|
|
Intel or your vendor. This file may be modified by the user, subject
|
|
to additional terms of the license agreement.
|
|
|
|
@par Specification
|
|
**/
|
|
|
|
#include <XmlCliComLib.h>
|
|
#include <Cli.h>
|
|
|
|
|
|
const CLI_COMMAND_ENTRY gCliCommandTable[] = {
|
|
{ READ_BIOS_KNOBS_OPCODE, CliReadBiosKnobs, FALSE},
|
|
{ APPEND_BIOS_KNOBS_OPCODE, CliAppendBiosKnobs, FALSE},
|
|
{ UPDATE_BIOS_KNOBS_OPCODE, CliUpdateBiosKnobs, FALSE},
|
|
{ RESTORE_MODIFY_KNOBS_OPCODE, CliRestoreModifyKnobs, FALSE},
|
|
{ LOAD_DEFAULT_KNOBS_OPCODE, CliLoadDefaultKnobs, FALSE},
|
|
{ GET_SET_VARIABLE_OPCODE, CliGetSetVariable, TRUE }, // This function is supported for XmlCli Lite as well.
|
|
};
|
|
|
|
|
|
UINT8 InstallXmlCli=1;
|
|
CLI_BUFFER* gCliPhyRequestBuffer;
|
|
CLI_BUFFER* gCliPhyResponseBuffer;
|
|
CLI_BUFFER* gCliSharedRequestBuffer;
|
|
CLI_BUFFER* gCliSharedResponseBuffer;
|
|
|
|
/**
|
|
Call Cli Handler for Valid Operation Code.
|
|
Also registers dynamically handled Cli Api for SMM/DXE protocol
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] OpCode Operation code
|
|
|
|
@retval EFI_UNSUPPORTED Invalid Cli Command
|
|
**/
|
|
EFI_STATUS
|
|
CallHandler (
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN UINT16 OpCode
|
|
);
|
|
|
|
/**
|
|
Get command id from Physical Request Buffer
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval UINT16 Request command id
|
|
**/
|
|
UINT16
|
|
GetRequest (
|
|
XML_CLI_COMMON *XmlCliCommon
|
|
);
|
|
|
|
/**
|
|
Entry point method to validate request/response buffer
|
|
and perform operation for given valid operation code as per
|
|
validated request buffer.
|
|
|
|
@param[in] XmlCliCom XmlCli Common Structure
|
|
Defined as VOID so that anyone can use this as
|
|
API without consuming while XML_CLI_COMMON structure
|
|
|
|
@retval EFI_SUCCESS
|
|
@retval EFI_NOT_READY XmlCli Interface is either disabled or not Ready to service the request
|
|
@retval EFI_INVALID_PARAMETER Null pointer passed as parameter
|
|
@retval EFI_NO_RESPONSE Signature in Structure is still not in READY state
|
|
@retval EXIT_OPCODE Specified Operation code in Request buffer match to EXIT_OPCODE
|
|
**/
|
|
EFI_STATUS
|
|
CliEntryPoint (
|
|
IN VOID *XmlCliCom
|
|
)
|
|
{
|
|
UINT16 opcode;
|
|
UINT32 SetupDataAttributes;
|
|
UINTN SetupDataSize;
|
|
EFI_STATUS Status;
|
|
XMLCLI_SETUP XmlCliSetup;
|
|
XML_CLI_COMMON *XmlCliCommon;
|
|
|
|
if (XmlCliCom == NULL){
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
XmlCliCommon = (XML_CLI_COMMON*) XmlCliCom;
|
|
|
|
if ((InstallXmlCli != 0) && (XmlCliCommon != NULL)) {
|
|
SetupDataAttributes=0;
|
|
SetupDataSize = sizeof (XMLCLI_SETUP);
|
|
Status = XmlCliGetNvramData(XmlCliCommon, XMLCLI_SETUP_NAME, &gXmlCliSetupGuid, &SetupDataAttributes, &SetupDataSize, &XmlCliSetup);
|
|
if (Status != EFI_SUCCESS) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: GetVariable on Setup failed !!\n"));
|
|
return EFI_NOT_READY;
|
|
}
|
|
InstallXmlCli = XmlCliSetup.XmlCliSupport;
|
|
|
|
gCliPhyRequestBuffer = (VOID*)(UINTN)XmlCliCommon->CliRequestBufferAddress;
|
|
gCliPhyResponseBuffer = (VOID*)(UINTN)XmlCliCommon->CliResponseBufferAddress;
|
|
|
|
gCliSharedRequestBuffer = gCliPhyRequestBuffer;
|
|
gCliSharedResponseBuffer = gCliPhyResponseBuffer;
|
|
|
|
if (WaitForCommand(XmlCliCommon) != EFI_SUCCESS) {
|
|
return EFI_NO_RESPONSE;
|
|
}
|
|
|
|
opcode = GetRequest(XmlCliCommon);
|
|
if (opcode == EXIT_OPCODE) {
|
|
gCliPhyResponseBuffer->CommandId = EXIT_OPCODE;
|
|
gCliPhyResponseBuffer->ParametersSize = 0;
|
|
gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects = CLI_CMD_NO_SIDE_EFFECT;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
return EXIT_OPCODE;
|
|
}
|
|
Status = CallHandler(XmlCliCommon, opcode);
|
|
if (Status != EFI_SUCCESS) { // In some cases we Fail Silently, hence return Success.
|
|
// DEBUG ((DEBUG_INFO, "XML_CLI: Current CLI command failed !!\n"));
|
|
return EFI_SUCCESS;
|
|
}
|
|
} else {
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
CopyMem((VOID*)&SetupDataAttributes, (VOID*)(UINTN)(XmlCliCommon->DramSharedMBAddr+LEG_MAILBOX_OFFSET+OFF_GEN2_XML_CLI_ENABLED), 4);
|
|
SetupDataAttributes = SetupDataAttributes & 0xFFFFFFFD; // Clear BIT 1, this indicates that XmlCli Interface is now Disabled
|
|
CopyMem((VOID*)(UINTN)(XmlCliCommon->DramSharedMBAddr+LEG_MAILBOX_OFFSET+OFF_GEN2_XML_CLI_ENABLED), (VOID*)&SetupDataAttributes, 4);
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Call Cli Handler for Valid Operation Code.
|
|
Also registers dynamically handled Cli Api for SMM/DXE protocol
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] OpCode Operation code
|
|
|
|
@retval EFI_UNSUPPORTED Invalid Cli Command
|
|
**/
|
|
EFI_STATUS
|
|
CallHandler (
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN UINT16 OpCode
|
|
)
|
|
{
|
|
UINT32 iter;
|
|
UINT32 count;
|
|
UINT32 tableSize;
|
|
REG_CLI_COMMAND_ENTRY *CliApiProtocol=NULL;
|
|
|
|
tableSize = sizeof(gCliCommandTable)/sizeof(CLI_COMMAND_ENTRY);
|
|
|
|
for (iter = 0; iter < tableSize; iter++) {
|
|
if ((XmlCliCommon->EnableXmlCliLite == 1) && (gCliCommandTable[iter].XmlCliLiteSupport == FALSE)) {
|
|
continue;
|
|
}
|
|
if (gCliCommandTable[iter].CommandId == OpCode){
|
|
ZeroMem (gCliPhyResponseBuffer, sizeof(CLI_BUFFER)); // clear/initialize response buffer
|
|
return gCliCommandTable[iter].CmdHandler(XmlCliCommon);
|
|
}
|
|
}
|
|
|
|
// Handle CLI API's that were dynamically registered
|
|
if (XmlCliCommon->CliRT.InSmm) {
|
|
CliApiProtocol = (REG_CLI_COMMAND_ENTRY*)(XmlCliCommon->SmmCliApiProto);
|
|
} else {
|
|
CliApiProtocol = (REG_CLI_COMMAND_ENTRY*)(XmlCliCommon->DxeCliApiProto);
|
|
}
|
|
if (CliApiProtocol == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
for (count=0; count<MAX_CLI_APIs_SUPPORTED; count++) {
|
|
if ((CliApiProtocol->CommandId == 0) || (CliApiProtocol->CmdHandler == NULL)) {
|
|
return EFI_UNSUPPORTED;
|
|
} else {
|
|
if (CliApiProtocol->CommandId == OpCode) {
|
|
ZeroMem (gCliPhyResponseBuffer, sizeof(CLI_BUFFER)); // clear/initialize response buffer
|
|
return CliApiProtocol->CmdHandler(CliApiProtocol->Buffer);
|
|
}
|
|
}
|
|
CliApiProtocol++;
|
|
}
|
|
// no such a command
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
/**
|
|
Wait for Cli Command to execute successfully
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS XmlCli Response is successful and Signature is Ready
|
|
@retval EFI_NO_RESPONSE XmlCli Response is not ready!
|
|
**/
|
|
EFI_STATUS
|
|
WaitForCommand (
|
|
IN XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
if (gCliSharedRequestBuffer->Signature == CLI_GEN2_SGN_REQUEST_READY) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
} else {
|
|
if (gCliSharedRequestBuffer->Signature == CLI_SGN_REQUEST_READY) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
//never should be here
|
|
return EFI_NO_RESPONSE;
|
|
}
|
|
|
|
/**
|
|
Get command id from Physical Request Buffer
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval UINT16 Request command id
|
|
**/
|
|
UINT16
|
|
GetRequest (
|
|
IN XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliSharedRequestBuffer->Signature = CLI_GEN2_SGN_RESPONSE_GET;
|
|
} else {
|
|
gCliSharedRequestBuffer->Signature = CLI_SGN_RESPONSE_GET;
|
|
}
|
|
return gCliPhyRequestBuffer->CommandId;
|
|
}
|
|
|
|
/**
|
|
This function update the NVRAM varstores according to
|
|
varstoreIndex, KnobOffset, KnobSize and KnobValue
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliUpdateBiosKnobs (
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
XmlCliCommon->CliRT.CommandSubType = CLI_KNOB_APPEND; // Set as append
|
|
XmlCliCommon->CliRT.UpdateKnobsEnabled = TRUE;
|
|
CliProcessBiosKnobs(XmlCliCommon); // reuse this guy
|
|
XmlCliCommon->CliRT.UpdateKnobsEnabled = FALSE;
|
|
|
|
((CLI_UPDATE_BIOS_KNOBS_RSP_PARAM*)gCliPhyResponseBuffer->Parameters)->RawAccess = 0;
|
|
if ((gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects == CLI_CMD_RESTART_REQUIRED) || (XmlCliCommon->CliRT.ResetRequired == 1))
|
|
{
|
|
((CLI_UPDATE_BIOS_KNOBS_RSP_PARAM*)gCliPhyResponseBuffer->Parameters)->Status.SetupModified = 1;
|
|
XmlCliCommon->CliRT.ResetRequired = 1; // set the Global Variable, this will be cleared automatically after reboot
|
|
}
|
|
|
|
gCliPhyResponseBuffer->CommandId = UPDATE_BIOS_KNOBS_OPCODE;
|
|
gCliPhyResponseBuffer->ParametersSize = sizeof(CLI_UPDATE_BIOS_KNOBS_RSP_PARAM);
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function update the NVRAM varstores according to
|
|
varstoreIndex, KnobOffset, KnobSize and KnobValue
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliAppendBiosKnobs(
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
XmlCliCommon->CliRT.CommandSubType = CLI_KNOB_APPEND; // Set as append
|
|
CliProcessBiosKnobs(XmlCliCommon); // reuse this guy
|
|
|
|
gCliPhyResponseBuffer->CommandId = APPEND_BIOS_KNOBS_OPCODE;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function update the NVRAM varstores according to
|
|
varstoreIndex, KnobOffset, KnobSize and KnobValue
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliRestoreModifyKnobs(
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
XmlCliCommon->CliRT.CommandSubType = CLI_KNOB_RESTORE_MODIFY;
|
|
CliProcessBiosKnobs(XmlCliCommon); // reuse this guy
|
|
|
|
gCliPhyResponseBuffer->CommandId = RESTORE_MODIFY_KNOBS_OPCODE;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function update the NVRAM varstores according to
|
|
varstoreIndex, KnobOffset, KnobSize and KnobValue
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliReadBiosKnobs(
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
XmlCliCommon->CliRT.CommandSubType = CLI_KNOB_READ_ONLY;
|
|
CliProcessBiosKnobs(XmlCliCommon); // reuse this guy
|
|
|
|
gCliPhyResponseBuffer->CommandId = READ_BIOS_KNOBS_OPCODE;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function update the NVRAM varstores according to
|
|
varstoreIndex, KnobOffset, KnobSize and KnobValue
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliLoadDefaultKnobs (
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
XmlCliCommon->CliRT.CommandSubType = CLI_KNOB_LOAD_DEFAULTS; // Set as append
|
|
CliProcessBiosKnobs(XmlCliCommon); // reuse this guy
|
|
|
|
gCliPhyResponseBuffer->CommandId = LOAD_DEFAULT_KNOBS_OPCODE;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get Knob Variable data from NVRAM
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] UniCodeName Name of the variable in unicode character array
|
|
@param[in] VarGuid Guid of the NVRAM variable
|
|
@param[in] SetupDataAttributes Attribute of the NVRAM Variable
|
|
@param[in] VarSize Size of the NVRAM Variable
|
|
@param[in] NvarData NVRAM Data value (setup knob values)
|
|
|
|
@retval EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
XmlCliGetNvramData (
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN CHAR16 *UniCodeName,
|
|
IN EFI_GUID *VarGuid,
|
|
IN UINT32 *SetupDataAttributes,
|
|
IN UINTN *VarSize,
|
|
IN VOID *NvarData
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
if (XmlCliCommon->CliRT.InSmm) {
|
|
Status = ((EFI_SMM_VARIABLE_PROTOCOL*)XmlCliCommon->SmmVariable)->SmmGetVariable(UniCodeName, VarGuid, SetupDataAttributes, VarSize, NvarData);
|
|
} else
|
|
{
|
|
Status = gRT->GetVariable(UniCodeName, VarGuid, SetupDataAttributes, VarSize, NvarData);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Set Knob Variable data from NVRAM
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] UniCodeName Name of the variable in unicode character array
|
|
@param[in] VarGuid Guid of the NVRAM variable
|
|
@param[in] SetupDataAttributes Attribute of the NVRAM Variable
|
|
@param[in] VarSize Size of the NVRAM Variable
|
|
@param[in] NvarData NVRAM Data value (setup knob values)
|
|
|
|
@retval EFI_STATUS Response Status of SetVariable/SmmSetVariable
|
|
**/
|
|
EFI_STATUS
|
|
XmlCliSetNvramData (
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN CHAR16 *UniCodeName,
|
|
IN EFI_GUID *VarGuid,
|
|
IN UINT32 SetupDataAttributes,
|
|
IN UINTN VarSize,
|
|
IN VOID *NvarData
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
if (XmlCliCommon->CliRT.InSmm) {
|
|
Status = ((EFI_SMM_VARIABLE_PROTOCOL*)XmlCliCommon->SmmVariable)->SmmSetVariable(UniCodeName, VarGuid, SetupDataAttributes, VarSize, NvarData);
|
|
} else {
|
|
Status = gRT->SetVariable(UniCodeName, VarGuid, SetupDataAttributes, VarSize, NvarData);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This function validates the requested knob value whether the
|
|
knob type is valid knob type or not (valid EFI IFR code)
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] KnobXmlEntryOffset Offset of the setup knob
|
|
@param[in] ReqKnobValue Value of Requested Knob
|
|
|
|
@retval TRUE Requested Knob is within allowed range
|
|
(Valid EFI IFR code/Valid Knob type)
|
|
@retval FALSE Requested Knob is not within allowed range
|
|
**/
|
|
BOOLEAN
|
|
IsKnobValValid(
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN UINT32 KnobXmlEntryOffset,
|
|
IN UINT8 *ReqKnobValue
|
|
)
|
|
{
|
|
BOOLEAN ReturnStatus=FALSE;
|
|
UINT8 KnobType=0;
|
|
UINT8 NoOfOptions=0;
|
|
UINT8 KnobSize=0;
|
|
UINT8 LoopCount=0;
|
|
UINT32 KnobValMapAddr;
|
|
UINT32 KnobValMapOffset=0;
|
|
UINTN MinVal=0;
|
|
UINTN MaxVal=0;
|
|
UINTN ReqKnobValInt=0;
|
|
KNOB_ENTRY_TBL *KnobXmlEntry;
|
|
|
|
KnobXmlEntry = (KNOB_ENTRY_TBL*)(UINTN)XmlCliCommon->KnobXmlEntryAddr;
|
|
KnobValMapAddr = XmlCliCommon->KnobValMapAddr;
|
|
KnobValMapOffset = (UINT32)KnobXmlEntry[KnobXmlEntryOffset].KnobValMapOffset;
|
|
KnobSize = (UINT8)KnobXmlEntry[KnobXmlEntryOffset].KnobSize;
|
|
CopyMem((VOID*)&KnobType, (VOID*)(UINTN)(KnobValMapAddr+KnobValMapOffset), 1);
|
|
if (KnobType < KNOB_TYPE_CUTOFF) {
|
|
//
|
|
// if EFI_IFR_ONE_OF_OP
|
|
//
|
|
NoOfOptions = KnobType;
|
|
KnobType = EFI_IFR_ONE_OF_OP;
|
|
for (LoopCount=0; LoopCount < NoOfOptions; LoopCount++) {
|
|
if (CompareMem((UINT8*)ReqKnobValue, (UINT8*)(UINTN)(KnobValMapAddr+KnobValMapOffset+1+(LoopCount*KnobSize)), KnobSize) == 0) {
|
|
ReturnStatus = TRUE; // this means the requested value is found in one of the supported option values
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
KnobType = (KnobType - KNOB_TYPE_CUTOFF); // we added value 0xD0 when we encoded it while generating XML, undoing the same now
|
|
switch(KnobType) {
|
|
case EFI_IFR_CHECKBOX_OP:
|
|
CopyMem((VOID*)&ReqKnobValInt, (VOID*)ReqKnobValue, KnobSize);
|
|
// checkbox can take value 0 or 1 only.
|
|
if ((ReqKnobValInt == 0) || (ReqKnobValInt == 1)) {
|
|
ReturnStatus = TRUE; // this means the requested value is either 0 or 1
|
|
} else {
|
|
ReturnStatus = FALSE; // this means the requested value is the one not supported or viable for CheckBox option
|
|
}
|
|
break;
|
|
case EFI_IFR_NUMERIC_OP:
|
|
CopyMem((VOID*)&ReqKnobValInt, (VOID*)ReqKnobValue, KnobSize);
|
|
CopyMem((VOID*)&MinVal, (VOID*)(UINTN)(KnobValMapAddr+KnobValMapOffset+1), KnobSize);
|
|
CopyMem((VOID*)&MaxVal, (VOID*)(UINTN)(KnobValMapAddr+KnobValMapOffset+1+KnobSize), KnobSize);
|
|
if ((ReqKnobValInt >= MinVal) && (ReqKnobValInt <= MaxVal)) {
|
|
ReturnStatus = TRUE; // this means the requested value is within the allowed range
|
|
} else {
|
|
ReturnStatus = FALSE; // this means the requested value is outside the allowed range
|
|
}
|
|
break;
|
|
case EFI_IFR_STRING_OP:
|
|
CopyMem((VOID*)&MinVal, (VOID*)(UINTN)(KnobValMapAddr+KnobValMapOffset+1), sizeof(UINT8));
|
|
CopyMem((VOID*)&MaxVal, (VOID*)(UINTN)(KnobValMapAddr+KnobValMapOffset+2), sizeof(UINT8));
|
|
while (*ReqKnobValue) {
|
|
ReqKnobValue = ReqKnobValue+2;
|
|
ReqKnobValInt++;
|
|
}
|
|
if ((ReqKnobValInt >= MinVal) && (ReqKnobValInt <= MaxVal)) {
|
|
ReturnStatus = TRUE; // this means the requested value is within the allowed range
|
|
} else {
|
|
ReturnStatus = FALSE; // this means the requested value is outside the allowed range
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: KnobType = 0x%X: KnobSize = %d IsKnobValValid = %a ReqVal = 0x%X\n", KnobType, KnobSize, ReturnStatus? "TRUE":"FALSE", ReqKnobValue));
|
|
return ReturnStatus;
|
|
}
|
|
|
|
/**
|
|
This function validates the requested knob value and if the
|
|
requested value is within the allowed range this function
|
|
will return TRUE, else will return FALSE
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
@param[in] ProcBiosKnobsRsp Processed Bios Knobs Response Buffer
|
|
@param[in] KnobIndex Offset of the Knob within Nvar
|
|
@param[in] VarId Id of Nvar
|
|
@param[in] KnobXmlNvarOffset Nvar Knob Offset within Xml
|
|
@param[in] PreValueData Existing Data before replaced with valid requested value
|
|
@param[in] ReqKnobValue Requested Value of setup knob
|
|
|
|
**/
|
|
VOID
|
|
ReportReplaceKnobData (
|
|
IN XML_CLI_COMMON *XmlCliCommon,
|
|
IN VOID *ProcBiosKnobsRsp,
|
|
IN UINT32 KnobIndex,
|
|
IN UINT16 VarId,
|
|
IN UINTN KnobXmlNvarOffset,
|
|
IN UINT8 *PreValueData,
|
|
IN UINT8 *ReqKnobValue
|
|
)
|
|
{
|
|
BOOLEAN BitWise;
|
|
UINT8 iter;
|
|
UINT8 KnobSize;
|
|
UINT8 CorrectIndex;
|
|
UINT8 CorrectOffset;
|
|
UINT16 count;
|
|
UINT16 found;
|
|
UINT16 KnobEntrySize;
|
|
UINT32 KnobOffset;
|
|
UINT32 GbtXmlBaseAddr;
|
|
UINT32 KnobEntryOfst;
|
|
UINT32 XmlPatchBaseAddr;
|
|
UINT32 XmdBuffSize;
|
|
UINT64 Value;
|
|
UINT64 Data64;
|
|
UINTN Address;
|
|
CHAR8 StrAsciiBuf[200];
|
|
KNOB_ENTRY_TBL *KnobXmlEntry;
|
|
BIT_KNOB_INDEX_LOOKUP *BitKnobLookup;
|
|
CLI_PROCESS_BIOS_KNOBS_RSP_PARAM *ProcessBiosKnobsRsp;
|
|
|
|
ProcessBiosKnobsRsp = (CLI_PROCESS_BIOS_KNOBS_RSP_PARAM*)ProcBiosKnobsRsp;
|
|
GbtXmlBaseAddr = XmlCliCommon->GbtXmlAddress + 4;
|
|
XmlPatchBaseAddr = XmlCliCommon->XmlPatchBaseAddr;
|
|
KnobXmlEntry = (KNOB_ENTRY_TBL*)(UINTN)XmlCliCommon->KnobXmlEntryAddr;
|
|
KnobSize = (UINT8)KnobXmlEntry[KnobXmlNvarOffset+KnobIndex].KnobSize;
|
|
KnobEntryOfst = (UINT32)(KnobXmlEntry[KnobXmlNvarOffset+KnobIndex].KnobXmlEntryOfst);
|
|
KnobEntrySize = (UINT16)KnobXmlEntry[KnobXmlNvarOffset+KnobIndex].XmlEntrySize;
|
|
|
|
//DEBUG ((DEBUG_INFO, "Before Calling ReplaceCurVal: Offset = 0x%X VarId = %d EntryOfst = 0x%X\n", KnobIndex, VarId, KnobEntryOfst));
|
|
//DEBUG ((DEBUG_INFO, "EntrySize =0x%X KnobSize = %d Val = 0x%X XmlPatchBaseAddr = 0x%X\n", KnobEntrySize, KnobSize, ReqKnobValue, XmlCliCommon->XmlPatchBaseAddr));
|
|
//ReplaceCurrentVal(GbtXmlBaseAddr, KnobIndex, VarId, KnobEntryOfst, KnobEntrySize, KnobSize, ReqKnobValue, XmlCliCommon->XmlPatchBaseAddr);
|
|
Address = (UINTN)(GbtXmlBaseAddr+KnobEntryOfst);
|
|
XmdBuffSize = 0;
|
|
Data64 = 0;
|
|
CorrectIndex = 0;
|
|
CorrectOffset = 0;
|
|
found = 0;
|
|
BitWise = FALSE;
|
|
if ((Address != 0) && (KnobEntrySize != 0)) {
|
|
for (count = 0; count < KnobEntrySize; count++) {
|
|
Value = *(UINT64*)Address;
|
|
/// compare with <eIndex=">
|
|
if (Value == 0x223D7865646e4965) {
|
|
Address += 8;
|
|
ZeroMem ((UINT8*)StrAsciiBuf, sizeof(StrAsciiBuf));
|
|
StrAsciiBuf[0] = *(CHAR8*)Address;
|
|
StrAsciiBuf[1] = *(CHAR8*)(Address+1);
|
|
CorrectIndex = ((UINT8)AsciiStrDecimalToUintn(StrAsciiBuf) == VarId) ? 1 : 0;
|
|
Address += 2;
|
|
}
|
|
/// compare with <offset=">
|
|
if (CorrectIndex && (Value == 0x223D74657366666f)) {
|
|
Address += 8;
|
|
ZeroMem ((UINT8*)StrAsciiBuf, sizeof(StrAsciiBuf));
|
|
for (iter = 0 ; iter < 8 ; iter++) {
|
|
if (*(UINT8*)(Address + iter) == 0x22) {
|
|
break;
|
|
}
|
|
StrAsciiBuf[iter] = *(CHAR8*)(Address + iter);
|
|
}
|
|
KnobOffset = KnobIndex;
|
|
Value = AsciiStrHexToUintn(StrAsciiBuf);
|
|
if (Value >= 0xC0000) {
|
|
Value = Value & 0x3FFFF;
|
|
if (KnobXmlEntry[KnobXmlNvarOffset+KnobIndex].IsBitWise) {
|
|
BitWise = TRUE;
|
|
BitKnobLookup = (BIT_KNOB_INDEX_LOOKUP*)(UINTN)(XmlCliCommon->KnobValMapAddr + KnobXmlEntry[KnobXmlNvarOffset+KnobIndex].KnobValMapOffset - sizeof(BIT_KNOB_INDEX_LOOKUP));
|
|
KnobOffset = (BitKnobLookup->ByteOffset*8) + (BitKnobLookup->BitField & 0x7);
|
|
}
|
|
}
|
|
CorrectOffset = (Value == KnobOffset) ? 1 : 0;
|
|
Address += iter;
|
|
}
|
|
// compare with <CurrentV>
|
|
if (CorrectOffset && (Value == 0x56746E6572727543)) {
|
|
Address += 8;
|
|
Value = (*(UINT64*)Address) & 0xFFFFFFFFFFFF;
|
|
// // compare with <al="0x>
|
|
if (Value == 0x7830223D6C61) {
|
|
Address += 6;
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
Address ++;
|
|
}
|
|
if (found) {
|
|
if (XmlPatchBaseAddr != 0) {
|
|
Data64 = (*(UINT64*)(UINTN)XmlPatchBaseAddr) & 0xFFFFFFFFFF;
|
|
// compare with $XKDT
|
|
if (Data64 == 0x54444B5824) {
|
|
CopyMem((UINT8*)&XmdBuffSize, (UINT8*)(UINTN)(XmlPatchBaseAddr+5), 3);
|
|
CopyMem((UINT8*)(((KNOB_PATCH_TBL*)(UINTN)(XmlPatchBaseAddr+8+XmdBuffSize))->KnobXmlEntryOfst), (UINT8*)&KnobEntryOfst, 3);
|
|
((KNOB_PATCH_TBL*)(UINTN)(XmlPatchBaseAddr+8+XmdBuffSize))->CurrentVal.RelOffset = (UINT16)(Address - GbtXmlBaseAddr - KnobEntryOfst);
|
|
((KNOB_PATCH_TBL*)(UINTN)(XmlPatchBaseAddr+8+XmdBuffSize))->KnobSize = KnobSize;
|
|
CopyMem((UINT8*)(UINTN)(XmlPatchBaseAddr+8+XmdBuffSize+sizeof(KNOB_PATCH_TBL)), (UINT8*)ReqKnobValue, KnobSize);
|
|
XmdBuffSize = XmdBuffSize + sizeof(KNOB_PATCH_TBL) + KnobSize;
|
|
CopyMem((UINT8*)(UINTN)(XmlPatchBaseAddr+5), (UINT8*)&XmdBuffSize, 3);
|
|
}
|
|
}
|
|
ZeroMem ((UINT8*)StrAsciiBuf, sizeof(StrAsciiBuf));
|
|
ConvHexArray2asciiVal(StrAsciiBuf, ReqKnobValue, KnobSize);
|
|
CopyMem((UINT8*)Address, (UINT8*)StrAsciiBuf, (KnobSize*2));
|
|
}
|
|
}
|
|
|
|
if (ProcessBiosKnobsRsp != NULL) {
|
|
ProcessBiosKnobsRsp->KnobXmlEntryPtr = GbtXmlBaseAddr+KnobEntryOfst;
|
|
ProcessBiosKnobsRsp->KnobXmlEntrySize = KnobEntrySize;
|
|
ProcessBiosKnobsRsp->VarStoreIndex = (UINT8)VarId;
|
|
if (BitWise) {
|
|
ProcessBiosKnobsRsp->KnobOffset = (UINT16)(BitKnobLookup->ByteOffset | 0x8000);
|
|
ProcessBiosKnobsRsp->KnobSize = BitKnobLookup->BitField;
|
|
} else {
|
|
ProcessBiosKnobsRsp->KnobOffset = (UINT16)KnobIndex;
|
|
ProcessBiosKnobsRsp->KnobSize = KnobSize;
|
|
}
|
|
///
|
|
/// Copy Default Knob Value
|
|
///
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1),(UINT8*)PreValueData, KnobSize);
|
|
|
|
///
|
|
/// Copy Current Knob Value
|
|
///
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+KnobSize),(UINT8*)ReqKnobValue, KnobSize);
|
|
}
|
|
}
|
|
|
|
/**
|
|
XmlCli Function to Process the BIOS Knobs.
|
|
This method is responsible to process the request buffer and determine
|
|
requested operation to perform which could be reading, modifying the knob(s)
|
|
or restoring it to default values.
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
|
|
**/
|
|
EFI_STATUS
|
|
CliProcessBiosKnobs (
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
BOOLEAN BitWise;
|
|
UINT8 Index;
|
|
UINT8 CommandSubType;
|
|
UINT8 KnobSize=0;
|
|
UINT8 CurrVarID;
|
|
UINT8 CurrData[MAX_KNOB_SIZE_SUPPORTED];
|
|
UINT8 ReqKnobValue[MAX_KNOB_SIZE_SUPPORTED];
|
|
UINT8 CurVarList[MAX_KNOB_SIZE_SUPPORTED];
|
|
UINT16 BitWiseIndex;
|
|
UINT16 count;
|
|
UINT16 Offset;
|
|
CHAR16 UniCodeName[64];
|
|
UINT32 KnobXmlEntryOffset;
|
|
UINT32 SetupDataAttributes;
|
|
UINTN KnobEntry;
|
|
UINTN Modified=0;
|
|
UINTN SetupModified=0;
|
|
UINTN loopCount=0;
|
|
UINTN KnobXmlNvarOffset;
|
|
UINTN CurrKnobOffset;
|
|
UINTN VarSize;
|
|
UINT64 Data64;
|
|
UINT64 TempData64;
|
|
EFI_GUID VarGuid;
|
|
EFI_STATUS Status=EFI_SUCCESS;
|
|
KNOB_ENTRY_TBL *KnobXmlEntry=(KNOB_ENTRY_TBL*)(UINTN)XmlCliCommon->KnobXmlEntryAddr;
|
|
BIT_KNOB_INDEX_LOOKUP *BitKnobLookup;
|
|
CLI_PROCESS_BIOS_KNOBS_RQST_PARAM *ProcessKnobsCmd;
|
|
CLI_PROCESS_BIOS_KNOBS_RSP_PARAM *ProcessBiosKnobsRsp;
|
|
VOID *SetupData;
|
|
VOID *DefSetupData;
|
|
VOID *CurrentData;
|
|
|
|
BitWiseIndex = 0;
|
|
KnobXmlEntryOffset = 0;
|
|
|
|
ProcessBiosKnobsRsp = (CLI_PROCESS_BIOS_KNOBS_RSP_PARAM*)(gCliPhyResponseBuffer->Parameters);
|
|
CommandSubType = XmlCliCommon->CliRT.CommandSubType;
|
|
ZeroMem (CurVarList, sizeof (CurVarList));
|
|
|
|
///
|
|
/// Check that we have knobs to set in the command parameters by reading the 'ParametersSize'
|
|
///
|
|
if ((gCliPhyRequestBuffer->ParametersSize == 0) && (CommandSubType != CLI_KNOB_LOAD_DEFAULTS) && (CommandSubType != CLI_KNOB_RESTORE_MODIFY)) {
|
|
gCliPhyResponseBuffer->Flags.Fields.WrongParameter = 1;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (XmlCliCommon->CliRT.UpdateKnobsEnabled == TRUE) {
|
|
loopCount = gCliPhyRequestBuffer->ParametersSize / sizeof(CLI_UPDATE_BIOS_KNOBS_RQST_PARAM);
|
|
} else {
|
|
loopCount = gCliPhyRequestBuffer->ParametersSize;
|
|
}
|
|
|
|
// Check & parse input parameters for optimized operation
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)gCliPhyRequestBuffer->Parameters;
|
|
for (count=0; count < XmlCliCommon->NumberOfVarstores; count++) {
|
|
if ((CommandSubType == CLI_KNOB_LOAD_DEFAULTS) || (CommandSubType == CLI_KNOB_RESTORE_MODIFY)) {
|
|
CurVarList[count] = 0xE9;
|
|
} else {
|
|
CurVarList[count] = 0xFF;
|
|
}
|
|
}
|
|
for (KnobEntry=0; KnobEntry < loopCount; KnobEntry++) {
|
|
if (XmlCliCommon->CliRT.UpdateKnobsEnabled == TRUE) {
|
|
KnobSize = sizeof(UINT64);
|
|
} else {
|
|
KnobSize = ProcessKnobsCmd->KnobSize;
|
|
if (ProcessKnobsCmd->KnobOffset & 0x8000) {
|
|
KnobSize = BitGetByteSize((KnobSize & 0x7), (KnobSize >> 3));
|
|
}
|
|
}
|
|
if (CurVarList[ProcessKnobsCmd->VarStoreIndex] == 0xFF) {
|
|
CurVarList[ProcessKnobsCmd->VarStoreIndex] = 0xE9;
|
|
}
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)((UINT8*)&ProcessKnobsCmd->KnobSize+1+KnobSize);
|
|
}
|
|
|
|
for (Index=0; Index < XmlCliCommon->NumberOfVarstores; Index++) {
|
|
if (((CommandSubType == CLI_KNOB_APPEND) || (CommandSubType == CLI_KNOB_READ_ONLY)) && (CurVarList[Index] != 0xE9)) {
|
|
continue;
|
|
}
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)gCliPhyRequestBuffer->Parameters;
|
|
|
|
KnobXmlNvarOffset = XmlCliCommon->VarstoreTable[Index].KnobXmlEntryBase;
|
|
|
|
VarSize = XmlCliCommon->VarstoreTable[Index].Size;
|
|
SetupDataAttributes = 0;
|
|
DefSetupData = (VOID*)(UINTN)XmlCliCommon->VarstoreTable[Index].DefData;
|
|
SetupData = (VOID*)(UINTN)XmlCliCommon->CurrGetSetVarBuffer;
|
|
CurrentData = (VOID*)((UINT8*)SetupData + VarSize); // Order of the combined Allocated buffer will be || SetupData | CurrentData ||
|
|
AsciiStrToUnicodeStrS ((CHAR8 *) XmlCliCommon->VarstoreTable[Index].Name, UniCodeName, sizeof (UniCodeName));
|
|
VarGuid = XmlCliCommon->VarstoreTable[Index].Guid;
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, SetupData);
|
|
if (EFI_ERROR (Status)) {
|
|
Status = EFI_SUCCESS;
|
|
continue; // ignore these knobs and move to next NVAR
|
|
}
|
|
CopyMem ((UINT8*)CurrentData, (UINT8*)SetupData, VarSize); // Keep a copy of Current Setup Data for later use.
|
|
if (XmlCliCommon->VarstoreTable[Index].DefName[0] == 0) {
|
|
CopyMem ((UINT8*)DefSetupData, (UINT8*)SetupData, VarSize); //Default Var is not defined, use same as current copy.
|
|
} else if ((CommandSubType == CLI_KNOB_RESTORE_MODIFY) || (CommandSubType == CLI_KNOB_LOAD_DEFAULTS)) {
|
|
CopyMem ((UINT8*)SetupData, (UINT8*)DefSetupData, VarSize); // since we are restoring the options
|
|
}
|
|
|
|
if (CommandSubType == CLI_KNOB_LOAD_DEFAULTS) {
|
|
loopCount = 0; // dont iterate over the CLI Knobs request buffer loop
|
|
}
|
|
Modified = 0; // initialize it for current NVAR.
|
|
|
|
for (KnobEntry=0; KnobEntry < loopCount; KnobEntry++) {
|
|
CurrKnobOffset = ProcessKnobsCmd->KnobOffset;
|
|
CurrVarID = ProcessKnobsCmd->VarStoreIndex;
|
|
BitWise = FALSE;
|
|
if (XmlCliCommon->CliRT.UpdateKnobsEnabled == TRUE) {
|
|
KnobSize = sizeof(UINT64);
|
|
} else {
|
|
KnobSize = ProcessKnobsCmd->KnobSize;
|
|
KnobXmlEntryOffset = (UINT32)(KnobXmlNvarOffset + CurrKnobOffset);
|
|
if (CurrKnobOffset & 0x8000) { // if BIT15 is set, this means current knob is BitWise
|
|
BitWise = TRUE;
|
|
CurrKnobOffset = CurrKnobOffset & 0x7FFF;
|
|
BitWiseIndex = BitFetchIndex((UINT32)(UINTN)&KnobXmlEntry[KnobXmlNvarOffset], XmlCliCommon->KnobValMapAddr, (UINT16)CurrKnobOffset, KnobSize);
|
|
KnobSize = BitGetByteSize((KnobSize & 0x7), (KnobSize >> 3));
|
|
if (BitWiseIndex == 0xFFFF) {
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)((UINT8*)&ProcessKnobsCmd->KnobSize+1+KnobSize);
|
|
continue; // invalid bitwise knob entry
|
|
}
|
|
KnobXmlEntryOffset = (UINT32)(KnobXmlNvarOffset + BitWiseIndex);
|
|
}
|
|
}
|
|
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: ReqBuffPtr = 0x%X ResBuffPtr = 0x%X CurProcessingVarID = %d \n", ProcessKnobsCmd, ProcessBiosKnobsRsp, Index));
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: ReqVarID = %d ReqKnobSize = 0x%X ReqKnobOffset = 0x%X\n", CurrVarID, KnobSize, CurrKnobOffset));
|
|
//DEBUG ((DEBUG_INFO, "KnobXmlEntryAddr = 0x%X KnobValMapAddr = 0x%X KnobValMapCurrOff = 0x%X\n", &KnobXmlEntry[KnobXmlEntryOffset], XmlCliCommon->KnobValMapAddr, (UINT32)KnobXmlEntry[KnobXmlEntryOffset].KnobValMapOffset));
|
|
if ((CurrVarID != Index) || (CurrVarID >= XmlCliCommon->NumberOfVarstores)
|
|
|| ((KnobXmlEntry != NULL) && (KnobSize != (UINT8)KnobXmlEntry[KnobXmlEntryOffset].KnobSize))
|
|
|| (CurrKnobOffset > XmlCliCommon->VarstoreTable[ Index ].Size) ) {
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)((UINT8*)&ProcessKnobsCmd->KnobSize+1+KnobSize);
|
|
continue; // process the rest, greacefully treat this error by ignoring this entry.
|
|
}
|
|
|
|
if ((XmlCliCommon->CliRT.UpdateKnobsEnabled != TRUE) && (KnobXmlEntry)) {
|
|
ProcessBiosKnobsRsp->KnobXmlEntryPtr = XmlCliCommon->GbtXmlAddress+4+(UINT32)KnobXmlEntry[KnobXmlEntryOffset].KnobXmlEntryOfst;
|
|
ProcessBiosKnobsRsp->KnobXmlEntrySize = (UINT16)KnobXmlEntry[KnobXmlEntryOffset].XmlEntrySize;
|
|
ProcessBiosKnobsRsp->KnobOffset = ProcessKnobsCmd->KnobOffset;
|
|
ProcessBiosKnobsRsp->VarStoreIndex = CurrVarID;
|
|
ProcessBiosKnobsRsp->KnobSize = ProcessKnobsCmd->KnobSize;
|
|
}
|
|
|
|
ZeroMem((UINT8*)ReqKnobValue, sizeof(ReqKnobValue));
|
|
CopyMem((UINT8*)ReqKnobValue, (UINT8*)&ProcessKnobsCmd->KnobSize+1, KnobSize);
|
|
if ((CommandSubType == CLI_KNOB_APPEND) || (CommandSubType == CLI_KNOB_RESTORE_MODIFY)) {
|
|
if (BitWise) {
|
|
if (BitDataMatch64((VOID*)((UINT8*)SetupData+CurrKnobOffset),(VOID*)ReqKnobValue, (ProcessKnobsCmd->KnobSize & 0x7), (ProcessKnobsCmd->KnobSize >> 3), 0) == FALSE) {
|
|
/// Not equal, need to update this knob
|
|
if (IsKnobValValid(XmlCliCommon, KnobXmlEntryOffset, (UINT8*)ReqKnobValue)) {
|
|
// Knob Value Validation
|
|
BitDataCopy64((VOID*)((UINT8*)SetupData+CurrKnobOffset),(VOID*)ReqKnobValue, (ProcessKnobsCmd->KnobSize & 0x7), (ProcessKnobsCmd->KnobSize >> 3));
|
|
if (CommandSubType == CLI_KNOB_APPEND) {
|
|
ZeroMem((UINT8*)CurrData, sizeof(CurrData));
|
|
CopyMem((UINT8*)CurrData, (UINT8*)CurrentData+CurrKnobOffset, KnobSize);
|
|
ReportReplaceKnobData(XmlCliCommon, NULL, (UINT32)BitWiseIndex, Index, KnobXmlNvarOffset, CurrData, ReqKnobValue);
|
|
Modified++;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (CompareMem((UINT8*)SetupData+CurrKnobOffset, (UINT8*)ReqKnobValue, KnobSize) != 0) {
|
|
//not equal, need to apply this knob
|
|
if (IsKnobValValid(XmlCliCommon, KnobXmlEntryOffset, (UINT8*)ReqKnobValue)) {
|
|
// Knob Value Validation
|
|
CopyMem((UINT8*)SetupData+CurrKnobOffset,(UINT8*)ReqKnobValue, KnobSize);
|
|
if (CommandSubType == CLI_KNOB_APPEND) {
|
|
ZeroMem ((UINT8*)CurrData, sizeof(CurrData));
|
|
CopyMem((UINT8*)CurrData, (UINT8*)CurrentData+CurrKnobOffset, KnobSize);
|
|
ReportReplaceKnobData(XmlCliCommon, NULL, (UINT32)CurrKnobOffset, Index, KnobXmlNvarOffset, CurrData, ReqKnobValue);
|
|
Modified++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!XmlCliCommon->CliRT.UpdateKnobsEnabled) {
|
|
if (BitWise) {
|
|
Data64 = 0;
|
|
CopyMem((UINT8*)&Data64,(UINT8*)DefSetupData+CurrKnobOffset, KnobSize); // copy Default Knob Value
|
|
Data64 = BitExtractValue64(Data64, (ProcessKnobsCmd->KnobSize & 0x7), (ProcessKnobsCmd->KnobSize >> 3));
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1),(UINT8*)&Data64, KnobSize); // copy Default Knob Value
|
|
Data64 = 0;
|
|
CopyMem((UINT8*)&Data64,(UINT8*)SetupData+CurrKnobOffset, KnobSize); // copy Current Knob Value
|
|
Data64 = BitExtractValue64(Data64, (ProcessKnobsCmd->KnobSize & 0x7), (ProcessKnobsCmd->KnobSize >> 3));
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+KnobSize),(UINT8*)&Data64, KnobSize); // copy Default Knob Value
|
|
} else {
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1),(UINT8*)DefSetupData+CurrKnobOffset, KnobSize); // copy Default Knob Value
|
|
CopyMem(((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+KnobSize),(UINT8*)SetupData+CurrKnobOffset, KnobSize); // copy Current Knob Value
|
|
}
|
|
ProcessBiosKnobsRsp = (CLI_PROCESS_BIOS_KNOBS_RSP_PARAM*)((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+(2*KnobSize));
|
|
}
|
|
ProcessKnobsCmd = (CLI_PROCESS_BIOS_KNOBS_RQST_PARAM*)((UINT8*)&ProcessKnobsCmd->KnobSize+1+KnobSize);
|
|
}
|
|
///
|
|
/// Now we have constructed buffer (SetupData) based on User expectation.
|
|
///
|
|
|
|
if ((KnobXmlEntry != NULL) && ((CommandSubType == CLI_KNOB_RESTORE_MODIFY) || (CommandSubType == CLI_KNOB_LOAD_DEFAULTS))) {
|
|
for (Offset=0; Offset < XmlCliCommon->VarstoreTable[Index].Size;) {
|
|
if ((KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobXmlEntryOfst == 0) || (KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize == 0)) {
|
|
Offset++;
|
|
continue;
|
|
}
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: VarIndex: %d KnobXmlNvarOffset = 0x%X KnobOffset = 0x%X\n", Index, KnobXmlNvarOffset, Offset));
|
|
// compare the final buffer with existing values.
|
|
if (CompareMem((UINT8*)SetupData+Offset,(UINT8*)CurrentData+Offset, (UINT8)KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize) != 0) {
|
|
///
|
|
/// Not equal, need to update this knobs CurrentVal in XML
|
|
///
|
|
if (1 == KnobXmlEntry[KnobXmlNvarOffset+Offset].IsBitWise) { // Bitwise Knob
|
|
for (count = (UINT16)((KNOB_ENTRY_TBL_BITWISE*)KnobXmlEntry)[KnobXmlNvarOffset+Offset].StartIndex; count <= (UINT16)((KNOB_ENTRY_TBL_BITWISE*)KnobXmlEntry)[KnobXmlNvarOffset+Offset].EndIndex; count++) {
|
|
if (0 == KnobXmlEntry[KnobXmlNvarOffset+count].IsBitWise) {
|
|
continue;
|
|
}
|
|
BitKnobLookup = (BIT_KNOB_INDEX_LOOKUP*)(UINTN)(XmlCliCommon->KnobValMapAddr + ((KNOB_ENTRY_TBL*)KnobXmlEntry)[KnobXmlNvarOffset+count].KnobValMapOffset - sizeof(BIT_KNOB_INDEX_LOOKUP));
|
|
if (BitKnobLookup->ByteOffset == Offset){
|
|
Data64 = 0;
|
|
TempData64 = 0;
|
|
CopyMem((UINT8*)&TempData64, (UINT8*)SetupData+Offset, (UINT8)KnobXmlEntry[KnobXmlNvarOffset+count].KnobSize);
|
|
CopyMem((UINT8*)&Data64, (UINT8*)CurrentData+Offset, (UINT8)KnobXmlEntry[KnobXmlNvarOffset+count].KnobSize);
|
|
if (!BitDataMatch64((VOID*)&TempData64,(VOID*)&Data64, (BitKnobLookup->BitField & 0x7), ((BitKnobLookup->BitField >> 3) & 0x3F), 1)) {
|
|
Data64 = BitExtractValue64(Data64, (BitKnobLookup->BitField & 0x7), ((BitKnobLookup->BitField >> 3) & 0x3F));
|
|
TempData64 = BitExtractValue64(TempData64, (BitKnobLookup->BitField & 0x7), ((BitKnobLookup->BitField >> 3) & 0x3F));
|
|
if (CommandSubType == CLI_KNOB_RESTORE_MODIFY) {
|
|
ReportReplaceKnobData(XmlCliCommon, NULL, (UINT32)count, Index, KnobXmlNvarOffset, (UINT8*)&Data64, (UINT8*)&TempData64);
|
|
} else {
|
|
ReportReplaceKnobData(XmlCliCommon, (VOID*)ProcessBiosKnobsRsp, (UINT32)count, Index, KnobXmlNvarOffset, (UINT8*)&Data64, (UINT8*)&TempData64);
|
|
ProcessBiosKnobsRsp = (CLI_PROCESS_BIOS_KNOBS_RSP_PARAM*)((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+(2*KnobXmlEntry[KnobXmlNvarOffset+count].KnobSize));
|
|
}
|
|
Modified++;
|
|
}
|
|
}
|
|
}
|
|
} else { // Regular Knob
|
|
ZeroMem((UINT8*)ReqKnobValue, sizeof(ReqKnobValue));
|
|
ZeroMem((UINT8*)CurrData, sizeof(CurrData));
|
|
CopyMem((UINT8*)ReqKnobValue, (UINT8*)SetupData+Offset, (UINT8)KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize);
|
|
CopyMem((UINT8*)CurrData, (UINT8*)CurrentData+Offset, (UINT8)KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize);
|
|
if (CommandSubType == CLI_KNOB_RESTORE_MODIFY) {
|
|
ReportReplaceKnobData(XmlCliCommon, NULL, (UINT32)Offset, Index, KnobXmlNvarOffset, CurrData, ReqKnobValue);
|
|
} else {
|
|
ReportReplaceKnobData(XmlCliCommon, (VOID*)ProcessBiosKnobsRsp, (UINT32)Offset, Index, KnobXmlNvarOffset, CurrData, ReqKnobValue);
|
|
ProcessBiosKnobsRsp = (CLI_PROCESS_BIOS_KNOBS_RSP_PARAM*)((UINT8*)&ProcessBiosKnobsRsp->KnobSize+1+(2*KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize));
|
|
}
|
|
Modified++;
|
|
}
|
|
}
|
|
Offset += (UINT8)KnobXmlEntry[KnobXmlNvarOffset+Offset].KnobSize;
|
|
}
|
|
}
|
|
if (Modified) {
|
|
SetupModified += Modified;
|
|
Status = XmlCliSetNvramData(XmlCliCommon, UniCodeName, &VarGuid, SetupDataAttributes, VarSize, SetupData);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Cli Process Bios Knobs: SetVariable Failed Status = 0x%X!! \n", Status));
|
|
gCliPhyResponseBuffer->Flags.Fields.CannotExecute = 1;
|
|
gCliPhyResponseBuffer->Status = (UINT32)Status;
|
|
return EFI_SUCCESS;
|
|
}
|
|
if (XmlCliCommon->XmlSkipSavingDefVar == TRUE) { // Was Save Defaults Skipped?
|
|
AsciiStrToUnicodeStrS ((CHAR8 *) XmlCliCommon->VarstoreTable[Index].DefName, UniCodeName, sizeof (UniCodeName));
|
|
VarGuid = XmlCliCommon->VarstoreTable[Index].DefGuid;
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, (UINTN*)&VarSize, DefSetupData);
|
|
if (EFI_ERROR(Status)) { // Write current Data As default
|
|
SetupDataAttributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
|
|
Status = XmlCliSetNvramData(XmlCliCommon, UniCodeName, &VarGuid, SetupDataAttributes, VarSize, CurrentData);
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: SetVariable on the L\"%a\" VAR\n", XmlCliCommon->VarstoreTable[Index].DefName));
|
|
}
|
|
}
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: Cli Process Bios Knobs: Modified knobs count = %d modified for VarStore Index = %d\n", Modified, Index));
|
|
}
|
|
}
|
|
|
|
gCliPhyResponseBuffer->Status = (UINT32)Status;
|
|
gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects = CLI_CMD_NO_SIDE_EFFECT;
|
|
if (((gCliPhyResponseBuffer->Flags.Fields.WrongParameter == 0) &&
|
|
(gCliPhyResponseBuffer->Flags.Fields.CannotExecute == 0) &&
|
|
(SetupModified != 0)) || (XmlCliCommon->CliRT.ResetRequired == 1)) {
|
|
gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects = CLI_CMD_RESTART_REQUIRED;
|
|
|
|
///
|
|
/// Set the Global Variable, this will be cleared automatically after reboot
|
|
///
|
|
XmlCliCommon->CliRT.ResetRequired = 1;
|
|
}
|
|
// ((DEBUG_INFO, "XML_CLI: Cli Process Bios Knobs Ended: total Modified knobs count = %d \n", SetupModified));
|
|
if (XmlCliCommon->CliRT.UpdateKnobsEnabled == TRUE) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
gCliPhyResponseBuffer->ParametersSize = (UINT32)((UINT8*)ProcessBiosKnobsRsp - (UINT8*)gCliPhyResponseBuffer->Parameters);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Perform Cli command to get-set variable based on the
|
|
request and request parameters
|
|
|
|
@param[in] XmlCliCommon XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS Successfully performed operation to get or set variable
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
CliGetSetVariable (
|
|
IN XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
BOOLEAN BitWise;
|
|
UINT8 BitOffset;
|
|
UINT8 BitSize;
|
|
UINT8 Operation;
|
|
UINT8 CurSize;
|
|
UINT16 LoopCount;
|
|
UINT16 VarCount;
|
|
UINT16 CurOffset;
|
|
CHAR16 UniCodeName[128];
|
|
UINT32 SetupDataAttributes;
|
|
UINT32 NvarNameLen;
|
|
UINT32 SetupModified;
|
|
UINT32 OverallStatus;
|
|
UINTN VarSize;
|
|
UINTN Currptr;
|
|
UINTN Endptr;
|
|
UINTN DataBufSize;
|
|
EFI_GUID VarGuid;
|
|
EFI_STATUS Status;
|
|
VOID *SetupData;
|
|
CLI_GET_SET_VARIABLE_PARAM *params;
|
|
CLI_GET_SET_VARIABLE_PARAM *rsp;
|
|
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(gCliPhyRequestBuffer->Parameters);
|
|
rsp = (CLI_GET_SET_VARIABLE_PARAM*)(gCliPhyResponseBuffer->Parameters);
|
|
LoopCount = (UINT8)gCliPhyRequestBuffer->ParametersSize;
|
|
if (LoopCount == 0) {
|
|
if (params->Operation == GET_ALL_VARS) {
|
|
VarSize = sizeof(CHAR16);
|
|
ZeroMem (UniCodeName, sizeof(UniCodeName));
|
|
ZeroMem (&VarGuid, sizeof(EFI_GUID));
|
|
while (TRUE) {
|
|
if (XmlCliCommon->CliRT.InSmm) {
|
|
Status = ((EFI_SMM_VARIABLE_PROTOCOL*)XmlCliCommon->SmmVariable)->SmmGetNextVariableName(&VarSize, UniCodeName, &VarGuid);
|
|
} else {
|
|
Status = gRT->GetNextVariableName(&VarSize, UniCodeName, &VarGuid);
|
|
}
|
|
if (Status == EFI_NOT_FOUND) {
|
|
// Only break look when Variable list ends, for every other error Status, data is ignored
|
|
break;
|
|
}
|
|
if (!EFI_ERROR (Status)) {
|
|
params->NvarGuid = VarGuid;
|
|
params->NvarAttribute = 0;
|
|
params->NvarSize = 0;
|
|
params->NvarRetStatus = 0;
|
|
params->Operation = GET_VAR;
|
|
UnicodeStrToAsciiStrS(UniCodeName, (CHAR8*)params->NvarName, (VarSize/2));
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(UINTN)((UINTN)params->NvarName + (VarSize/2)); // return VarName size is in sizeof(CHAR16)*bytes, includes null char, hence divide by 2
|
|
LoopCount++;
|
|
}
|
|
}
|
|
gCliPhyRequestBuffer->ParametersSize = LoopCount;
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(gCliPhyRequestBuffer->Parameters);
|
|
}
|
|
}
|
|
SetupModified = 0;
|
|
Status = EFI_INVALID_PARAMETER;
|
|
OverallStatus = 0;
|
|
for (VarCount=0; VarCount<LoopCount; VarCount++) {
|
|
Operation = params->Operation;
|
|
VarGuid = params->NvarGuid;
|
|
VarSize = (UINTN)(params->NvarSize & 0xFFFFFFFF);
|
|
SetupDataAttributes = params->NvarAttribute;
|
|
ZeroMem (UniCodeName, sizeof(UniCodeName));
|
|
AsciiStrToUnicodeStrS ((CHAR8*)params->NvarName, UniCodeName, sizeof (UniCodeName));
|
|
AsciiStrCpyS(rsp->NvarName, 128, params->NvarName);
|
|
NvarNameLen = (UINT32)AsciiStrSize(rsp->NvarName);
|
|
SetupData = (VOID*)((UINTN)rsp->NvarName + NvarNameLen);
|
|
|
|
//DEBUG ((DEBUG_INFO, "CliGetSetVariable: Name = %S Guid = %g Size, 0x%X DataPtr = 0x%X\n", UniCodeName, VarGuid, VarSize, SetupData));
|
|
if (Operation == GET_VAR) {
|
|
if (VarSize == 0) { // GetVariable
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, NULL);
|
|
}
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, SetupData);
|
|
} else if (Operation == SET_VAR) { // SetVariable
|
|
SetupData = (VOID*)((UINTN)params->NvarName + NvarNameLen);
|
|
Status = XmlCliSetNvramData(XmlCliCommon, UniCodeName, &VarGuid, SetupDataAttributes, VarSize, SetupData);
|
|
SetupModified++;
|
|
if ((!EFI_ERROR(Status)) && (VarSize != 0)) {
|
|
SetupData = (VOID*)((UINTN)rsp->NvarName + NvarNameLen);
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, SetupData);
|
|
}
|
|
} else if (Operation == GET_MOD_SET_VAR) {
|
|
DataBufSize = VarSize;
|
|
VarSize = 0;
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, NULL);
|
|
if (VarSize != 0) {
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, SetupData);
|
|
if (!EFI_ERROR(Status)) {
|
|
Currptr = (UINTN)params->NvarName + NvarNameLen;
|
|
Endptr = Currptr + DataBufSize;
|
|
for (; Currptr < Endptr;) {
|
|
BitWise = FALSE;
|
|
CurOffset = ((NVAR_DATA_BUFF*)Currptr)->Offset;
|
|
CurSize = ((NVAR_DATA_BUFF*)Currptr)->Size;
|
|
if (CurOffset & 0x8000) { // if BIT15 is set, this means current knob is BitWise
|
|
BitWise = TRUE;
|
|
CurOffset = CurOffset & 0x7FFF;
|
|
BitOffset = (CurSize & 0x7);
|
|
BitSize = (CurSize >> 3);
|
|
CurSize = BitGetByteSize(BitOffset, BitSize);
|
|
}
|
|
if ((CurOffset + CurSize) <= VarSize) {
|
|
if (BitWise) {
|
|
if (!BitDataMatch64((VOID*)((UINT8*)SetupData+CurOffset),(VOID*)((UINT8*)(Currptr+sizeof(NVAR_DATA_BUFF))), BitOffset, BitSize, 0)) {
|
|
/// Not equal, need to update this knob
|
|
BitDataCopy64((VOID*)((UINT8*)SetupData+CurOffset),(VOID*)((UINT8*)(Currptr+sizeof(NVAR_DATA_BUFF))), BitOffset, BitSize);
|
|
SetupModified++;
|
|
}
|
|
} else {
|
|
if (CompareMem((UINT8*)SetupData+CurOffset, (UINT8*)(Currptr+sizeof(NVAR_DATA_BUFF)), CurSize) != 0) {
|
|
/// Not equal, need to update this knob
|
|
CopyMem((UINT8*)SetupData+CurOffset,(UINT8*)(Currptr+sizeof(NVAR_DATA_BUFF)), CurSize);
|
|
SetupModified++;
|
|
}
|
|
}
|
|
}
|
|
Currptr = Currptr + sizeof(NVAR_DATA_BUFF) + CurSize;
|
|
}
|
|
if (SetupModified > 0) {
|
|
Status = XmlCliSetNvramData(XmlCliCommon, UniCodeName, &VarGuid, SetupDataAttributes, VarSize, SetupData);
|
|
if ((!EFI_ERROR(Status)) && (VarSize != 0)) {
|
|
Status = XmlCliGetNvramData(XmlCliCommon, UniCodeName, &VarGuid, &SetupDataAttributes, &VarSize, SetupData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Status = EFI_UNSUPPORTED;
|
|
} //error case handling
|
|
//DEBUG ((DEBUG_INFO, "CliGetSetVariable: Name = %S Guid = %g Size, 0x%X DataPtr = 0x%X\n", UniCodeName, VarGuid, VarSize, SetupData));
|
|
rsp->NvarSize = (UINT32)VarSize;
|
|
rsp->NvarAttribute = SetupDataAttributes;
|
|
rsp->NvarGuid = VarGuid;
|
|
rsp->Operation = Operation;
|
|
rsp->NvarRetStatus = (UINT32)Status;
|
|
if (Status != EFI_SUCCESS) {
|
|
OverallStatus++;
|
|
}
|
|
if (Operation == GET_VAR) {
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(UINTN)((UINTN)params->NvarName + NvarNameLen);
|
|
} else if (Operation == SET_VAR) {
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(UINTN)((UINTN)params->NvarName + NvarNameLen + VarSize);
|
|
} else if (Operation == GET_MOD_SET_VAR) {
|
|
params = (CLI_GET_SET_VARIABLE_PARAM*)(UINTN)((UINTN)params->NvarName + NvarNameLen + params->NvarSize);
|
|
}
|
|
rsp = (CLI_GET_SET_VARIABLE_PARAM*)(UINTN)((UINTN)rsp->NvarName + NvarNameLen + VarSize);
|
|
}
|
|
if (LoopCount == 1) {
|
|
OverallStatus = (UINT32)Status;
|
|
} else if (LoopCount != OverallStatus) {
|
|
OverallStatus = 0;
|
|
}
|
|
if (SetupModified == 0) {
|
|
gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects = CLI_CMD_NO_SIDE_EFFECT;
|
|
} else {
|
|
gCliPhyResponseBuffer->Flags.Fields.CommandSideEffects = CLI_CMD_RESTART_REQUIRED;
|
|
}
|
|
gCliPhyResponseBuffer->CommandId = GET_SET_VARIABLE_OPCODE;
|
|
gCliPhyResponseBuffer->ParametersSize = (UINT32)((UINTN)rsp - (UINTN)gCliPhyResponseBuffer->Parameters);
|
|
gCliPhyResponseBuffer->Status = (UINT32) OverallStatus;;
|
|
if (XmlCliCommon->CliGen2Enable) {
|
|
gCliPhyResponseBuffer->Signature = CLI_GEN2_SGN_RESPONSE_READY;
|
|
} else {
|
|
gCliPhyResponseBuffer->Signature = CLI_SGN_RESPONSE_READY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|