1137 lines
50 KiB
C
1137 lines
50 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright 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 Corp.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
/** @file
|
|
Xml Cli Common Dxe driver implementation.
|
|
|
|
@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 Reference:
|
|
**/
|
|
|
|
#include <XmlCliComLib.h>
|
|
#include <Protocol/LoadedImage.h>
|
|
#include <Protocol/FirmwareVolumeBlock.h>
|
|
#include <Pi/PiFirmwareVolume.h>
|
|
#include <Pi/PiFirmwareFile.h>
|
|
#include <Library/RngLib.h>
|
|
#include <Library/BaseCryptLib.h>
|
|
#include <Cli.h>
|
|
|
|
|
|
#pragma pack(push, 1)
|
|
typedef struct {
|
|
UINT32 XmlCliTmpBuffPtr;
|
|
UINT8 Digest[DIGEST_SIZE];
|
|
} DXE_PROTOCOL_PTR;
|
|
|
|
typedef
|
|
VOID
|
|
(*GEN_GBT_XML) (
|
|
VOID *XmlCliProto
|
|
);
|
|
|
|
typedef struct _XML_CLI_PROTOCOL {
|
|
// this (GenerateGbtXml) has to be the first entry always.
|
|
GEN_GBT_XML GenerateGbtXml;
|
|
// there should not be any entry before the one above
|
|
XML_CLI_COMMON *XmlCliCommon;
|
|
BOOLEAN XmlCliStructInitialized;
|
|
UINT32 KnobsSignature;
|
|
} XML_CLI_PROTOCOL;
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
/**
|
|
Cli Entry Point Exposed as a XmlCli API structure
|
|
|
|
@param[in] XmlCliCom XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS
|
|
@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
|
|
CliEntry (
|
|
IN VOID *XmlCliCom
|
|
);
|
|
|
|
/**
|
|
Generate GBT Xml file at GbtXmlAddress
|
|
|
|
@param[in] XmlCliProto Pointer to XmlCli Protocol
|
|
|
|
@retval VOID
|
|
**/
|
|
VOID
|
|
GenerateGbtXml (
|
|
IN VOID *XmlCliProto
|
|
);
|
|
|
|
/**
|
|
This is the entrypoint of the XmlCliCommonHii driver.
|
|
This initialize the XmlCli configuration form.
|
|
|
|
@retval EFI_SUCCESS The XmlCli configuration form is initialized.
|
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
|
@retval Others Other errors as indicated.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
InitXmlCliSetupEntry ();
|
|
|
|
DXE_PROTOCOL_PTR DxeProtocolPtr;
|
|
|
|
SHARED_MAILBOX_TYPE DramMailBoxTable[] = {
|
|
{ LEG_MAILBOX_SIG, LEG_MAILBOX_OFFSET, LEG_MAILBOX_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE },
|
|
{ CLI_REQ_SIG, CLI_REQ_BUFFER_OFFSET, CLI_BUFFER_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE},
|
|
{ CLI_RES_SIG, CLI_RES_BUFFER_OFFSET, CLI_BUFFER_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE},
|
|
{ SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG}
|
|
};
|
|
|
|
SHARED_MAILBOX_TYPE DramMailBoxTableLite[] = {
|
|
{ LEG_MAILBOX_SIG, LEG_MAILBOX_OFFSET, LEG_MAILBOX_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE },
|
|
{ CLI_REQ_SIG, CLI_REQ_BUFFER_OFFSET, CLI_LITE_BUFFER_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE},
|
|
{ CLI_RES_SIG, CLI_LITE_RES_BUFFER_OFFSET, CLI_LITE_BUFFER_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE},
|
|
{ SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG, SHARED_MB_LAST_SIG}
|
|
};
|
|
|
|
|
|
/**
|
|
Find Address and size of FFS Region for given GUID
|
|
|
|
@param[in] ImageHandle EFI_HANDLE image
|
|
@param[in] MyFfsGuid Guid of FFS to lookup for
|
|
@param[out] MyFfsDataAddr Address of FFS
|
|
@param[out] MyFfsDataSize Size of FFS
|
|
|
|
@retval EFI_SUCCESS FFS Found
|
|
@retval !EFI_SUCCESS Failure
|
|
**/
|
|
EFI_STATUS
|
|
FindMyFfs (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_GUID *MyFfsGuid,
|
|
OUT UINT32 *MyFfsDataAddr,
|
|
OUT UINT32 *MyFfsDataSize
|
|
)
|
|
{
|
|
UINT32 FfsSize;
|
|
UINT32 FFSDataOffset;
|
|
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
|
|
EFI_PHYSICAL_ADDRESS FvMainPtr;
|
|
EFI_PHYSICAL_ADDRESS FvEndAddr;
|
|
EFI_STATUS Status=EFI_NOT_FOUND;
|
|
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
|
|
|
Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
|
|
Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
|
|
|
|
if (((EFI_FIRMWARE_VOLUME_HEADER*)FvbBaseAddress)->FvLength == 0xFFFFFFFFFFFFFFFF) {
|
|
return Status;
|
|
}
|
|
|
|
if (((EFI_FIRMWARE_VOLUME_HEADER*)FvbBaseAddress)->ExtHeaderOffset != 0) {
|
|
FvMainPtr = FvbBaseAddress + ((EFI_FIRMWARE_VOLUME_HEADER*)FvbBaseAddress)->ExtHeaderOffset;
|
|
FvMainPtr = FvMainPtr + ((EFI_FIRMWARE_VOLUME_EXT_HEADER*)FvMainPtr)->ExtHeaderSize;
|
|
} else {
|
|
FvMainPtr = FvbBaseAddress + ((EFI_FIRMWARE_VOLUME_HEADER*)FvbBaseAddress)->HeaderLength;
|
|
}
|
|
|
|
FvMainPtr = ((FvMainPtr + 7) & 0xFFFFFFF8); // ffs always starts ar 8 byte aligned address.
|
|
FvEndAddr = FvbBaseAddress + ((EFI_FIRMWARE_VOLUME_HEADER*)FvbBaseAddress)->FvLength;
|
|
while(FvMainPtr < FvEndAddr) {
|
|
if (IS_FFS_FILE2 (FvMainPtr)) {
|
|
FfsSize = FFS_FILE2_SIZE (FvMainPtr) ;
|
|
FFSDataOffset = sizeof(EFI_FFS_FILE_HEADER2) + sizeof(EFI_COMMON_SECTION_HEADER2);
|
|
} else {
|
|
FfsSize = FFS_FILE_SIZE (FvMainPtr) ;
|
|
FFSDataOffset = sizeof(EFI_FFS_FILE_HEADER) + sizeof(EFI_COMMON_SECTION_HEADER);
|
|
}
|
|
if ((FfsSize == 0) || ((FfsSize & 0xFFFFFF) == 0xFFFFFF)) {
|
|
break;
|
|
}
|
|
if (CompareGuid (&((EFI_FFS_FILE_HEADER*)FvMainPtr)->Name, MyFfsGuid)){
|
|
*MyFfsDataAddr = (UINT32)(FvMainPtr + FFSDataOffset);
|
|
*MyFfsDataSize = (UINT32)(FfsSize - FFSDataOffset);
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Found Given FFS at Address = 0x%X DataSize = 0x%X\n", *MyFfsDataAddr, *MyFfsDataSize));
|
|
return EFI_SUCCESS;
|
|
}
|
|
FvMainPtr = ((FvMainPtr + FfsSize + 7) & 0xFFFFFFF8); // ffs always starts ar 8 byte aligned address.
|
|
}
|
|
Status = EFI_NOT_FOUND;
|
|
DEBUG ((DEBUG_INFO, "XML_CLI[%a:%a]: FFS not found!!! Status=%r\n", gEfiCallerBaseName, __FUNCTION__, Status));
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
For XmlCli Lite Features allow to store Default values of All of the Nvar
|
|
|
|
@param[in] DataPtr Pointer to current Nvar data buffer.
|
|
@param[in] BiosKnobsDataAddr Address of Bios knobs Data bin.
|
|
@param[in] BiosKnobsDataSize Size of the Bios knobs Data bin.
|
|
|
|
**/
|
|
VOID
|
|
SaveDefNvars (
|
|
IN VOID *DataPtr,
|
|
IN UINT32 BiosKnobsDataAddr,
|
|
IN UINT32 BiosKnobsDataSize
|
|
)
|
|
{
|
|
EFI_STATUS Status=EFI_SUCCESS;
|
|
CHAR8 DefName[MAX_VARSTORE_NAME];
|
|
CHAR16 UniCodeName[MAX_VARSTORE_NAME];
|
|
UINT32 SetupDataAttributes = 0;
|
|
UINTN Size;
|
|
EFI_GUID MyGuid;
|
|
UINT8 *KnobsBuffPtrStart;
|
|
KNOB_BIN_HDR *KnobBinHdr;
|
|
VOID *DefDataPtr=NULL;
|
|
|
|
if ((BiosKnobsDataAddr != 0) && (BiosKnobsDataSize != 0)) {
|
|
for (KnobsBuffPtrStart = (UINT8*)(UINTN)BiosKnobsDataAddr; (KnobsBuffPtrStart < (UINT8*)(UINTN)(BiosKnobsDataAddr+BiosKnobsDataSize));) {
|
|
KnobBinHdr = (KNOB_BIN_HDR*) KnobsBuffPtrStart;
|
|
if (KnobBinHdr->Hdr0.Signature == NVRO_SIGNATURE) { // compare Signature with "$NVRO"
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + KnobBinHdr->Hdr1.NvarPktSize; // Skip NVRO, i.e. Read only Variables
|
|
continue;
|
|
}
|
|
if (KnobBinHdr->Hdr0.Signature == NVAR_SIGNATURE) { // compare Signature with "$NVAR"
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + KnobBinHdr->Hdr1.NvarPktSize;
|
|
AsciiStrToUnicodeStrS ((CHAR8 *)(KnobBinHdr->NvarName), UniCodeName, sizeof (UniCodeName));
|
|
MyGuid = KnobBinHdr->NvarGuid;
|
|
if (KnobBinHdr->NvarSize == 0) { // If Size is zero, skip this entry
|
|
continue;
|
|
}
|
|
Size = 0; // set Size to 0, to Get actual Size of current Variable
|
|
SetupDataAttributes = 0;
|
|
Status = gRT->GetVariable (UniCodeName, &MyGuid, &SetupDataAttributes, (UINTN*)&Size, NULL);
|
|
if (Size == 0) { // If Size is 0 is still zero, skip this entry
|
|
continue;
|
|
}
|
|
Status = gRT->GetVariable (UniCodeName, &MyGuid, &SetupDataAttributes, (UINTN*)&Size, DataPtr);
|
|
if (!EFI_ERROR(Status)) {
|
|
AsciiStrCpyS((CHAR8*)DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)"Def");
|
|
AsciiStrCatS((CHAR8*)DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)KnobBinHdr->NvarName);
|
|
AsciiStrToUnicodeStrS ((CHAR8 *)DefName, UniCodeName, sizeof (UniCodeName));
|
|
MyGuid = KnobBinHdr->NvarGuid;
|
|
// modify first 4 bytes of DefGuid so that they dont conflict with GlobalVariable Guid or any other restricted Guid.
|
|
MyGuid.Data1 = 0xDEFA901D;
|
|
DefDataPtr = (VOID*)((UINT8*)DataPtr + Size + 0x100);
|
|
Status = gRT->GetVariable (UniCodeName, &MyGuid, &SetupDataAttributes, (UINTN*)&Size, DefDataPtr);
|
|
if (EFI_ERROR(Status)) { // Write current Nvar Data As default
|
|
SetupDataAttributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
|
|
Status = gRT->SetVariable (UniCodeName, &MyGuid, SetupDataAttributes, Size, DataPtr);
|
|
ASSERT_EFI_ERROR(Status);
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: SetVariable on the L\"%a\" VAR\n", DefName));
|
|
}
|
|
}
|
|
} else {
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + sizeof(KNOB_BIN_HDR);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Generate XmlCli Hash at given Address pointer
|
|
|
|
@param[in,out] AddressPtr Pointer at which XmlCli reads input for digest
|
|
|
|
**/
|
|
VOID
|
|
GenXmlCliHash (
|
|
IN OUT VOID *AddressPtr
|
|
)
|
|
{
|
|
UINT8 Digest[DIGEST_SIZE];
|
|
EFI_GUID XmlCliValidatorGuid = {0x5b8483ee, 0x0af6, 0x4ca0, {0x7c, 0x80, 0x31, 0x0d, 0xef, 0xd9, 0x4a, 0x32}};
|
|
VOID *HmacContext;
|
|
|
|
ZeroMem (Digest, DIGEST_SIZE);
|
|
HmacContext = HmacSha256New();
|
|
|
|
//[-start-211005-IB18410108-modify]//
|
|
HmacSha256Init(HmacContext, (UINT8*)((UINTN)AddressPtr + KEY_OFFSET), KEY_SIZE);
|
|
//[-end-211005-IB18410108-modify]//
|
|
HmacSha256Update(HmacContext, (VOID*)&XmlCliValidatorGuid, GUID_SIZE);
|
|
HmacSha256Final(HmacContext, Digest);
|
|
|
|
CopyMem((VOID *)((UINTN) AddressPtr + DIGEST_OFFSET), &Digest, DIGEST_SIZE);
|
|
HmacSha256Free(HmacContext);
|
|
}
|
|
|
|
/**
|
|
Compress and save the data
|
|
|
|
@param[in] CompStartAddr Address at which compress data to be stored
|
|
@param[in] DataBaseAddr Base Address for Data to be compressed
|
|
@param[in] DataSize Size of the data to be compressed
|
|
@param[in] DataType Type of data to be compressed
|
|
|
|
@retval UINT32 Address where compressed data is stored
|
|
**/
|
|
UINT32
|
|
XmlCompressSave (
|
|
IN UINT32 CompStartAddr,
|
|
IN UINT32 DataBaseAddr,
|
|
IN UINT32 DataSize,
|
|
IN UINT8 DataType
|
|
)
|
|
{
|
|
UINT32 CompSize32;
|
|
UINT32 XmlPatchingDataAddr;
|
|
EFI_STATUS Status;
|
|
|
|
CompSize32 = 0x80000;
|
|
Status = TianoCompress((UINT8*)(UINTN)DataBaseAddr, DataSize, (UINT8*)(UINTN)(CompStartAddr+8), &CompSize32);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Tiano XML Compression Failed, continue with regular boot \n"));
|
|
CompSize32 = 0;
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Tiano XML Compression done, Base = 0x%X size = 0x%X Ratio = %d \n", CompStartAddr, CompSize32, (DataSize/CompSize32)));
|
|
if (DataType == KNOBS_DATA_BIN) {
|
|
CopyMem((VOID*)(UINTN)CompStartAddr, (VOID*)"$TNKB", 5);
|
|
} else {
|
|
CopyMem((VOID*)(UINTN)CompStartAddr, (VOID*)"$TNOC", 5);
|
|
}
|
|
CopyMem((VOID*)((UINT8*)(UINTN)CompStartAddr+5), (VOID*)&CompSize32, 3);
|
|
CompStartAddr = ((CompStartAddr+8+CompSize32+EFI_PAGE_MASK) & PAGE_ALIGNMENT_32_BIT);
|
|
}
|
|
XmlPatchingDataAddr = CompStartAddr;
|
|
CopyMem((VOID*)(UINTN)XmlPatchingDataAddr, (VOID*)"$XKDT", 5);
|
|
CompSize32 = 0;
|
|
CopyMem((VOID*)((UINT8*)(UINTN)XmlPatchingDataAddr+5), (VOID*)&CompSize32, 3);
|
|
return (UINT32)XmlPatchingDataAddr;
|
|
}
|
|
|
|
/**
|
|
This function is called from DXE Dispatcher.
|
|
This is Entry point for DXE phase of XmlCli and responsible
|
|
for initializing buffers, installing protocols
|
|
|
|
@param[in] ImageHandle EFI Image Handle for driver entry point
|
|
@param[in] SystemTable EFI System Table for driver entry point
|
|
|
|
@retval EFI_PROTOCOL_ERROR Failed to
|
|
Publishishing XmlCliCommon Protocol
|
|
or Allocating XmlCliCommon Protocol
|
|
or Publishishing GBT XML Protocol
|
|
or Allocating GBT XML Protocol
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
XmlCliCommonDxeInit (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
BOOLEAN GetVarFailed=FALSE;
|
|
UINT8 XmlCliVar;
|
|
UINT8 VarIndex;
|
|
UINT8 NvroCount;
|
|
UINT8 *KnobsBuffPtrStart;
|
|
UINT8 XmlCliSupport=FixedPcdGet8(PcdXmlCliSupport); // Default XmlCliSupport is 1(Enabled) for Server BIOS, & 0(Disabled) for Client BIOS or any external bios
|
|
UINT8 PublishSetupPgPtr=FixedPcdGet8(PcdPublishSetupPgPtr);
|
|
UINT8 EnableXmlCliLite=FixedPcdGet8(PcdEnableXmlCliLite);
|
|
UINT32 Attributes;
|
|
UINT32 XmlCliTmpAddr;
|
|
UINT32 InterfaceMemSize;
|
|
UINT32 XmlCliCommSize;
|
|
UINT32 Data32;
|
|
UINT32 CliBuffSize;
|
|
UINT32 BiosKnobsDataAddr=0;
|
|
UINT32 BiosKnobsDataSize=0;
|
|
UINTN VariableSize;
|
|
UINTN GBT_XML_Memory=0;
|
|
EFI_HANDLE Handle=NULL;
|
|
EFI_STATUS Status;
|
|
XMLCLI_SETUP XmlCliSetup;
|
|
XML_CLI_COMMON *XmlCliCommon;
|
|
XML_CLI_PROTOCOL *XmlCliProtocol;
|
|
KNOB_BIN_HDR *KnobBinHdr;
|
|
VOID *DxeCliApiProto;
|
|
VOID *XmlCliTempBuff;
|
|
|
|
Status = InitXmlCliSetupEntry();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "XML_CLI[%a]: Setup Initilization Failed \n", __FUNCTION__));
|
|
}
|
|
|
|
Attributes = 0;
|
|
VariableSize = sizeof(XMLCLI_SETUP);
|
|
Status = gRT->GetVariable(XMLCLI_SETUP_NAME, &gXmlCliSetupGuid, &Attributes, &VariableSize, &XmlCliSetup);
|
|
if (!EFI_ERROR (Status)) {
|
|
// XmlCli Setup Variable is available and found
|
|
GetVarFailed = FALSE;
|
|
XmlCliSupport = XmlCliSetup.XmlCliSupport;
|
|
PublishSetupPgPtr = XmlCliSetup.PublishSetupPgPtr;
|
|
EnableXmlCliLite = XmlCliSetup.EnableXmlCliLite;
|
|
} else {
|
|
// XmlCli Setup Variable not found
|
|
GetVarFailed = TRUE;
|
|
DEBUG((DEBUG_INFO, "XMLCLI[%a]: Failed to get xmlcli setup variable: Status: %r. \n", __FUNCTION__, Status));
|
|
DEBUG((DEBUG_INFO, "XMLCLI[%a]: Initializing PCD Default values", __FUNCTION__));
|
|
XmlCliSupport = FixedPcdGet8(PcdXmlCliSupport);
|
|
PublishSetupPgPtr = FixedPcdGet8(PcdPublishSetupPgPtr);
|
|
EnableXmlCliLite = FixedPcdGet8(PcdEnableXmlCliLite);
|
|
DEBUG((DEBUG_INFO, "XMLCLI[%a]: New Values XmlCliSupport:%X EnableXmlCliLite:%X", __FUNCTION__, XmlCliSupport, EnableXmlCliLite));
|
|
}
|
|
|
|
// Find FFS where Bios knobs data bin is stored
|
|
Status = FindMyFfs(ImageHandle, &gBiosKnobsDataBinGuid, &BiosKnobsDataAddr, &BiosKnobsDataSize);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "XML_CLI[%a]: FindMyFfs -> FFS not found..\n", __FUNCTION__));
|
|
BiosKnobsDataAddr = 0;
|
|
BiosKnobsDataSize = 0;
|
|
}
|
|
|
|
//
|
|
// Installing XmlCli Protocol
|
|
//
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, CLI_TEMP_BUFFER_SIZE, (VOID**)&XmlCliTempBuff);
|
|
ZeroMem((VOID*)XmlCliTempBuff, CLI_TEMP_BUFFER_SIZE); //Clear data
|
|
XmlCliTmpAddr = ((UINT32)(UINTN)XmlCliTempBuff + ADDRESS_ALIGNMENT) & 0xFFFFFFC0; // 0x40 byte aligned address
|
|
CopyMem((VOID*)(UINTN)XmlCliTmpAddr, &gXmlCliInterfaceBufferGuid, GUID_SIZE);
|
|
GetRandomNumber128((UINT64*)(UINTN)(XmlCliTmpAddr + GUID_SIZE)); // 0x10 bytes random numbers
|
|
GetRandomNumber128((UINT64*)(UINTN)(XmlCliTmpAddr + GUID_SIZE + 0x10)); // 0x10 bytes random numbers
|
|
// Generate Hash value from the random numbers
|
|
GenXmlCliHash((VOID*)((UINTN)XmlCliTmpAddr));
|
|
XmlCliTempBuff = NULL;
|
|
gBS->AllocatePool(EfiReservedMemoryType, CLI_TEMP_BUFFER_RESERVE, (VOID**)&XmlCliTempBuff);
|
|
CopyMem((VOID*)(UINTN)XmlCliTempBuff, &XmlCliTmpAddr, 4);
|
|
CopyMem((VOID*)((UINTN)XmlCliTempBuff+4), (VOID*)(UINTN)(XmlCliTmpAddr+DIGEST_OFFSET), DIGEST_SIZE); // Copy Result hash
|
|
ZeroMem((VOID*)&DxeProtocolPtr, sizeof(DXE_PROTOCOL_PTR)); //Clear data
|
|
DxeProtocolPtr.XmlCliTmpBuffPtr = *(UINT32*)(UINTN)(XmlCliTempBuff);
|
|
CopyMem((VOID*)DxeProtocolPtr.Digest, (VOID*)(UINTN)(XmlCliTmpAddr+DIGEST_OFFSET), DIGEST_SIZE); // Copy Result hash
|
|
ZeroMem((VOID*)(UINTN)(XmlCliTmpAddr+DIGEST_OFFSET), DIGEST_SIZE); // Clear data
|
|
Handle = NULL;
|
|
gBS->InstallProtocolInterface(&Handle, &gXmlCliVarGuid, EFI_NATIVE_INTERFACE, (VOID*)(UINTN)XmlCliTempBuff);
|
|
|
|
//
|
|
// We exit here if XmlCli is disabled (gXmlCliProtocolGuid is not installed so XmlCliSmm DEPEX fails)
|
|
//
|
|
if (0 == XmlCliSupport) {
|
|
SHARED_MEMORY_TABLE sharedMemTable;
|
|
VOID *TempData32;
|
|
SharedMemInitTable(&sharedMemTable, (UINT16)(ITP_XDP_VEND_DEV_ID >> 16) , ITP_XDP_BAR_NO);
|
|
sharedMemTable.Header.CliSpecVersion.MinorVersion = 0;
|
|
sharedMemTable.Header.CliSpecVersion.MajorVersion = 8;
|
|
sharedMemTable.Header.CliSpecVersion.ReleaseVersion = 0;
|
|
|
|
Status = SharedMemAddEntry(&sharedMemTable, XML_CLI_DISABLED_SIG, (UINT32)XmlCliTmpAddr, CLI_TEMP_BUFFER_SIZE, SHARED_MEMORY_FLAG_MEMORY_TYPE);
|
|
ASSERT_EFI_ERROR(Status);
|
|
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, 0x10100, (VOID**)&TempData32);
|
|
ZeroMem((VOID*)TempData32, 0x10100); //Clear data
|
|
Data32 = ((UINT32)(UINTN)TempData32 + 0xFFFF) & ALIGNMENT_64_KB_32_BIT;
|
|
CopyMem ((VOID*)(UINTN)Data32, &sharedMemTable, sizeof(SHARED_MEMORY_TABLE));
|
|
gBS->InstallConfigurationTable (&gDramSharedMailBoxGuid, (VOID*)(UINTN)Data32);
|
|
WriteDramMbAddr2Cmos(Data32);
|
|
//
|
|
// Check whether XmlCli utility has set the XmlCli variable
|
|
//
|
|
VariableSize = sizeof(XmlCliVar);
|
|
Status = gRT->GetVariable(XMLCLI_SETUP_NAME, &gXmlCliVarGuid, NULL, &VariableSize, &XmlCliVar);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "XmlCliVar = %d\n", XmlCliVar));
|
|
if ((XmlCliVar == 1) && (GetVarFailed == FALSE)) {
|
|
XmlCliSetup.XmlCliSupport = 1;
|
|
VariableSize = sizeof(XMLCLI_SETUP);
|
|
Status = gRT->SetVariable (XMLCLI_SETUP_NAME, &gXmlCliSetupGuid, Attributes, VariableSize, &XmlCliSetup);
|
|
ASSERT_EFI_ERROR(Status);
|
|
//
|
|
// Delete the XmlCli Variable if the Variable exist, we dont need it anymore and then Reset the system.
|
|
//
|
|
VariableSize = XmlCliVar = 0;
|
|
Attributes = (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE);
|
|
Status = gRT->SetVariable(XMLCLI_SETUP_NAME, &gXmlCliVarGuid, Attributes, 0, NULL);
|
|
ASSERT_EFI_ERROR(Status);
|
|
DEBUG ((DEBUG_INFO, "Rebooting the System for the XmlCli support enabling to take effect\n"));
|
|
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); // Perform System Reboot, doesn't return anything
|
|
//
|
|
// Do not do anything after ResetSystem
|
|
//
|
|
CpuDeadLoop();
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (EnableXmlCliLite) {
|
|
InterfaceMemSize = FixedPcdGet32(PcdLiteXmlReserved);
|
|
XmlCliCommSize = sizeof (XML_CLI_BASE);
|
|
CliBuffSize = CLI_LITE_BUFFER_SIZE;
|
|
} else {
|
|
InterfaceMemSize = FixedPcdGet32(PcdGbtXmlReserved);
|
|
XmlCliCommSize = sizeof (XML_CLI_COMMON);
|
|
CliBuffSize = CLI_BUFFER_SIZE;
|
|
}
|
|
|
|
// Allocate BootServices memory for the XmlCliCommon protocol instance.
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, XmlCliCommSize, (VOID**)&XmlCliCommon);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Allocating XmlCliCommon Protocol, returning! \n"));
|
|
return EFI_PROTOCOL_ERROR;
|
|
}
|
|
ZeroMem((VOID*)XmlCliCommon, XmlCliCommSize); //Clear data
|
|
|
|
// Install the XmlCliCommon onto a new handle.
|
|
Handle = NULL;
|
|
Status = gBS->InstallProtocolInterface (&Handle, &gXmlCliCommonGuid, EFI_NATIVE_INTERFACE, XmlCliCommon);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Publishing XmlCliCommon Protocol, returning! \n"));
|
|
gBS->FreePool(XmlCliCommon);
|
|
return EFI_PROTOCOL_ERROR;
|
|
}
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: XmlCliCommon Protocol published at Addr = 0x%X Size = 0x%X.\n", XmlCliCommon, XmlCliCommSize));
|
|
XmlCliCommon->PcieAddr = (UINT32)(UINTN)(VOID*)XmlCliCommon; // set some Value that is much above DramSharedMB for now, other Platform modules should populate correct Pcie Address value.
|
|
XmlCliCommon->XmlCliInterfaceMemSize = InterfaceMemSize;
|
|
XmlCliCommon->EnableXmlCliLite = EnableXmlCliLite;
|
|
XmlCliCommon->CliBuffSize = CliBuffSize;
|
|
XmlCliCommon->CliGen2Enable = TRUE;
|
|
XmlCliCommon->BiosKnobsDataAddr = BiosKnobsDataAddr;
|
|
XmlCliCommon->BiosKnobsDataSize = BiosKnobsDataSize;
|
|
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, (sizeof(REG_CLI_COMMAND_ENTRY)*MAX_CLI_APIs_SUPPORTED), (VOID**)&DxeCliApiProto);
|
|
if (!EFI_ERROR (Status)) {
|
|
ZeroMem((VOID*)DxeCliApiProto, (sizeof(REG_CLI_COMMAND_ENTRY)*MAX_CLI_APIs_SUPPORTED)); //Clear data
|
|
Handle = NULL;
|
|
Status = gBS->InstallProtocolInterface (&Handle, &gDxeCliApiGuid, EFI_NATIVE_INTERFACE, DxeCliApiProto);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Publishing DxeCliApiProto! \n"));
|
|
gBS->FreePool(DxeCliApiProto);
|
|
}
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: DxeCliApi Protocol published at 0x%X.\n", DxeCliApiProto));
|
|
XmlCliCommon->DxeCliApiProto = DxeCliApiProto;
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Allocating DxeCliApi Protocol! \n"));
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Allocating GBT_XML_Memory (size = %x)\n", InterfaceMemSize));
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, (UINTN)InterfaceMemSize, (VOID*)&GBT_XML_Memory);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
ZeroMem((VOID*)(UINTN)GBT_XML_Memory, InterfaceMemSize); //Clear data
|
|
// Align the GBT Address to a 4 KB boundary Allocate pool assigns address from TOLM and below growing down for EfiRuntimeServicesCode
|
|
//DEBUG ((DEBUG_INFO, "XML_CLI: GBT_XML_Memory address before alignment (0x%lX)\n", GBT_XML_Memory));
|
|
GBT_XML_Memory = (UINT32)(((UINTN)GBT_XML_Memory + EFI_PAGE_MASK) & ~(UINTN)EFI_PAGE_MASK);
|
|
XmlCliCommon->GbtXmlAddress = (UINT32)GBT_XML_Memory;
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: GBT_XML_Memory address after alignment (0x%lX)\n", GBT_XML_Memory));
|
|
|
|
UpdateBiosVersionBiosRepository(XmlCliCommon);
|
|
#ifdef SKIP_AUTHENTICATE_XML_CLI_API
|
|
XmlCliCommon->XmlType = XML_OS_INT;
|
|
#else
|
|
XmlCliCommon->XmlType = XML_OS_EXT;
|
|
#endif
|
|
|
|
XmlCliCommon->DramSharedMBAddr = ((XmlCliCommon->GbtXmlAddress + InterfaceMemSize - (LEG_MAILBOX_OFFSET + LEG_MAILBOX_SIZE + CliBuffSize + CliBuffSize + EFI_PAGE_SIZE)) & ALIGNMENT_64_KB_32_BIT);
|
|
XmlCliCommon->CliRequestBufferAddress = XmlCliCommon->DramSharedMBAddr + CLI_REQ_BUFFER_OFFSET;
|
|
XmlCliCommon->CliResponseBufferAddress = XmlCliCommon->CliRequestBufferAddress + CliBuffSize;
|
|
XmlCliCommon->XmlCliApi.DxeCliEntry = CliEntry;
|
|
XmlCliCommon->XmlCliApi.CliDxeRegisterApi = CliDxeRegisterApi;
|
|
XmlCliCommon->XmlCliApi.CliGetSetMyVariable = CliGetSetMyVariable;
|
|
XmlCliCommon->XmlCliApi.TianoCompress = TianoCompress;
|
|
XmlCliCommon->XmlCliApi.TianoDecompress = TianoDecompress;
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Shared Mailbox Memory address (0x%lX)\n", XmlCliCommon->DramSharedMBAddr));
|
|
|
|
XmlCliTmpAddr = XmlCliTmpAddr & 0xFFFF0000;
|
|
WRITE_MAILBOX(OFF_XML_CLI_TEMP_ADDR, 4, &XmlCliTmpAddr, XmlCliCommon->DramSharedMBAddr, XmlCliCommon->PcieAddr);
|
|
gBS->InstallConfigurationTable (&gDramSharedMailBoxGuid, (VOID*)(UINTN)XmlCliCommon->DramSharedMBAddr);
|
|
WriteDramMbAddr2Cmos(XmlCliCommon->DramSharedMBAddr);
|
|
|
|
if ((XmlCliSetup.XmlCliDramCmosAddr == 0xFFFFFFFF) || (XmlCliSetup.XmlCliDramCmosAddr < 0x10000) || ((XmlCliSetup.XmlCliDramCmosAddr & 0xFFFF) != 0)) {
|
|
XmlCliCommon->XmlSkipSavingDefVar = TRUE; // let Platform Settle with all dynamics.
|
|
} else {
|
|
XmlCliCommon->XmlSkipSavingDefVar = FALSE;
|
|
}
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: XmlCliSetup.XmlCliDramCmosAddr = 0x%X\n", XmlCliSetup.XmlCliDramCmosAddr));
|
|
//
|
|
// Restoring DramSharedMBAddr in nvram, to be used during S3 resume flow.
|
|
//
|
|
if ((XmlCliSetup.XmlCliDramCmosAddr != XmlCliCommon->DramSharedMBAddr) && (GetVarFailed == FALSE)) {
|
|
XmlCliSetup.XmlCliDramCmosAddr = XmlCliCommon->DramSharedMBAddr;
|
|
Status = gRT->SetVariable (XMLCLI_SETUP_NAME, &gXmlCliSetupGuid, Attributes, VariableSize, &XmlCliSetup);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
if (EnableXmlCliLite) {
|
|
Data32 = (UINT32)(GBT_XML_Memory + 4);
|
|
MyPrintf((UINTN)&Data32, (CHAR8*)"<SYSTEM>\r\n\t<PLATFORM NAME=\"UNKNOWN\" CPU=\"UNKNOWN\" CHIPSET=\"UNKNOWN\"/>\r\n\t<BIOS VERSION=\"%a\" TSTAMP=\"%a\"/>\r\n\t<GBT Version=\"3.0302\" TSTAMP=\"Feb 25 2015\" Type=\"OsInternal\" XmlCliVer=\"%a\" XmlCliType=\"Lite\"/>\r\n</SYSTEM>\r\n", XmlCliCommon->BiosVersion, XmlCliCommon->BuildTimeStamp, XML_CLI_VERSION);
|
|
*(UINT32*)(UINTN)GBT_XML_Memory = (UINT32)AsciiStrLen((CHAR8*)(UINTN)(GBT_XML_Memory+4));
|
|
XmlCompressSave((UINT32)(GBT_XML_Memory+0x1000), BiosKnobsDataAddr, BiosKnobsDataSize, KNOBS_DATA_BIN); // Compress Bios Knobs Data bin FFS.
|
|
SharedMemConstructSharedMB((VOID*)XmlCliCommon, DramMailBoxTableLite, ITP_XDP_BAR_NO, ITP_XDP_VEND_DEV_ID, XmlCliCommon->DramSharedMBAddr);
|
|
XmlCliCommon->CurrGetSetVarBuffer = XmlCliCommon->DramSharedMBAddr - 0x8000;
|
|
if (XmlCliCommon->XmlSkipSavingDefVar == FALSE) {
|
|
SaveDefNvars((VOID*)(UINTN)XmlCliCommon->CurrGetSetVarBuffer, BiosKnobsDataAddr, BiosKnobsDataSize);
|
|
}
|
|
} else {
|
|
XmlCliCommon->SkipXmlComprs = 0;
|
|
|
|
if ((BiosKnobsDataAddr == 0) || (BiosKnobsDataSize == 0)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: gBiosKnobsDataBin FFS not found..\n"));
|
|
} else {
|
|
VarIndex = 0;
|
|
NvroCount = 0;
|
|
for (KnobsBuffPtrStart = (UINT8*)(UINTN)BiosKnobsDataAddr; (KnobsBuffPtrStart < (UINT8*)(UINTN)(BiosKnobsDataAddr+BiosKnobsDataSize));) {
|
|
KnobBinHdr = (KNOB_BIN_HDR*) KnobsBuffPtrStart;
|
|
if (KnobBinHdr->Hdr0.Signature == NVRO_SIGNATURE) { // compare Signature with "$NVRO"
|
|
NvroCount++;
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + KnobBinHdr->Hdr1.NvarPktSize; // Skip NVRO, i.e. Read only Variables
|
|
continue;
|
|
}
|
|
if (KnobBinHdr->Hdr0.Signature == NVAR_SIGNATURE) { // compare Signature with "$NVAR"
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + KnobBinHdr->Hdr1.NvarPktSize;
|
|
XmlCliCommon->VarstoreTable[VarIndex].Size = (UINT16)KnobBinHdr->NvarSize;
|
|
XmlCliCommon->VarstoreTable[VarIndex].BitKnobCount = (UINT16)KnobBinHdr->BitKnobCount;
|
|
AsciiStrCpyS((CHAR8*)XmlCliCommon->VarstoreTable[VarIndex].Name, sizeof(KnobBinHdr->NvarName), (CHAR8*)KnobBinHdr->NvarName);
|
|
XmlCliCommon->VarstoreTable[VarIndex].Guid = KnobBinHdr->NvarGuid;
|
|
if (KnobBinHdr->NvarSize == 0) { // If Size is zero, skip this entry
|
|
VarIndex++;
|
|
continue;
|
|
}
|
|
AsciiStrCpyS((CHAR8*)XmlCliCommon->VarstoreTable[VarIndex].DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)"Def");
|
|
AsciiStrCatS((CHAR8*)XmlCliCommon->VarstoreTable[VarIndex].DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)KnobBinHdr->NvarName);
|
|
XmlCliCommon->VarstoreTable[VarIndex].DefGuid = KnobBinHdr->NvarGuid;
|
|
// modify first 4 bytes of DefGuid so that they dont conflict with GlobalVariable Guid or any other restricted Guid.
|
|
XmlCliCommon->VarstoreTable[VarIndex].DefGuid.Data1 = 0xDEFA901D;
|
|
VarIndex++;
|
|
} else {
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + sizeof(KNOB_BIN_HDR);
|
|
}
|
|
}
|
|
XmlCliCommon->NumberOfVarstores = (UINT8)VarIndex;
|
|
XmlCliCommon->NvroCount = (UINT8)NvroCount;
|
|
}
|
|
|
|
XmlCliCommon->PublishSetupPgPtr = PublishSetupPgPtr;
|
|
XmlCliCommon->XmlGenBiosKnobsSection = XmlGenBiosKnobsSection;
|
|
XmlCliCommon->DxeXmlCompress = DxeXmlCompress;
|
|
XmlCliCommon->KnobXmlEntryAddr = XmlCliCommon->DramSharedMBAddr - FixedPcdGet32(PcdKnobsEntriesSize);
|
|
XmlCliCommon->KnobValMapAddr = XmlCliCommon->KnobXmlEntryAddr - FixedPcdGet32(PcdKnobValueMapSize);
|
|
XmlCliCommon->XmlCliDebugLogBuff = XmlCliCommon->KnobValMapAddr - XMLCLI_DEBUG_LOG_BUFF_SIZE;
|
|
XmlCliCommon->CurrGetSetVarBuffer = XmlCliCommon->XmlCliDebugLogBuff - GET_SET_TEMP_DATA_BUFF_SIZE;
|
|
|
|
SharedMemConstructSharedMB((VOID*)XmlCliCommon, DramMailBoxTable, ITP_XDP_BAR_NO, ITP_XDP_VEND_DEV_ID, XmlCliCommon->DramSharedMBAddr);
|
|
|
|
// **************** ------Install Default Common XmlCli Protocol Start ------ ***************
|
|
// Allocate BootServices memory for the XmlCliProtocol protocol instance.
|
|
Status = gBS->AllocatePool (EfiReservedMemoryType, sizeof (XML_CLI_PROTOCOL), (VOID**)&XmlCliProtocol);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Allocating GBT XML Protocol, returning! \n"));
|
|
return EFI_PROTOCOL_ERROR;
|
|
}
|
|
ZeroMem((VOID*)XmlCliProtocol, sizeof(XML_CLI_PROTOCOL)); //Clear data
|
|
|
|
// Install the XmlCliProtocol onto a new handle.
|
|
Handle = NULL;
|
|
Status = gBS->InstallProtocolInterface (&Handle, &gXmlCliProtocolGuid, EFI_NATIVE_INTERFACE, XmlCliProtocol);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error Publishing GBT XML Protocol, returning! \n"));
|
|
gBS->FreePool(XmlCliProtocol);
|
|
return EFI_PROTOCOL_ERROR;
|
|
}
|
|
XmlCliCommon->XmlCliProtocolHandle = Handle;
|
|
XmlCliProtocol->XmlCliCommon = XmlCliCommon;
|
|
XmlCliProtocol->GenerateGbtXml = GenerateGbtXml;
|
|
}
|
|
|
|
// **************** ------Install Default Common XmlCli Protocol End ------ ***************
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
We have this function so that we can have following XML block generating functions
|
|
available only in one driver and the other driver will just reuse them.
|
|
Not required, but will save both FV_MAIN & RunTime/BootTime memory resources.
|
|
|
|
@param[in] XmlCliCom XmlCli Common Structure
|
|
@param[out] NewXmlWriterContext Get New XmlCi Writer Context at the specified pointer
|
|
|
|
**/
|
|
UINTN
|
|
XmlGenBiosKnobsSection (
|
|
IN VOID *XmlCliCom,
|
|
OUT VOID *NewXmlWriterContext
|
|
)
|
|
{
|
|
UINTN CurrXmlWriterContext;
|
|
XML_CLI_COMMON *XmlCliCommon=(XML_CLI_COMMON*)XmlCliCom;
|
|
|
|
OvrdXmlWriterContext(NewXmlWriterContext);
|
|
DEBUG ((DEBUG_INFO, "\t XmlGenerateBiosKnobs\n"));
|
|
XmlGenerateBiosKnobs(XmlCliCommon); // <biosknobs>
|
|
CurrXmlWriterContext = (UINTN)RetXmlWriterContext();
|
|
return CurrXmlWriterContext;
|
|
}
|
|
|
|
/**
|
|
Compress the XML specified at location
|
|
XmlPatchBaseAddr from parameter XmlCli Common structure.
|
|
|
|
|
|
@param[in] XmlCliCom XmlCli Common Structure
|
|
@param[in] XmlSize Uncompressed Xml Size
|
|
|
|
@retval UINT32 End Address of the Compressed XML
|
|
**/
|
|
UINT32
|
|
DxeXmlCompress (
|
|
IN VOID *XmlCliCom,
|
|
IN UINT32 XmlSize
|
|
)
|
|
{
|
|
UINT32 XmlDataEndAddress=0;
|
|
XML_CLI_COMMON *XmlCliCommon = (XML_CLI_COMMON*)XmlCliCom;
|
|
|
|
XmlDataEndAddress = ((XmlCliCommon->GbtXmlAddress + 4 + XmlSize + EFI_PAGE_MASK) & PAGE_ALIGNMENT_32_BIT);
|
|
if (XmlCliCommon->SkipXmlComprs == 0) { // Skip compression if its disabled.
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Start Xml Compression\n"));
|
|
XmlCliCommon->XmlPatchBaseAddr = XmlCompressSave(XmlDataEndAddress, (XmlCliCommon->GbtXmlAddress+4), XmlSize, XML_DATA_ONLY); // Compress XML Data
|
|
CopyMem ((VOID*)(UINTN)(XmlCliCommon->DramSharedMBAddr + LEG_MAILBOX_OFFSET + OFF_GEN2_GBT_COMPR_ADDR), &XmlDataEndAddress, 4); // Compress XML Data
|
|
XmlCliCommon->XmlPatchBaseAddr = XmlCompressSave(XmlCliCommon->XmlPatchBaseAddr, XmlCliCommon->BiosKnobsDataAddr, XmlCliCommon->BiosKnobsDataSize, KNOBS_DATA_BIN); // Compress Bios Knobs Data bin FFS.
|
|
XmlDataEndAddress = (UINT32)((XmlCliCommon->XmlPatchBaseAddr + FixedPcdGet32(PcdKnobPatchDataBufferSize) + 0xFFF)& 0xFFFFF000); // reserved XML patch DataBuffer of size 0x20000 for XML Knobs delta information
|
|
}
|
|
return XmlDataEndAddress;
|
|
}
|
|
|
|
/**
|
|
Registers the Cli API
|
|
to expose the Api this function has to be used
|
|
usage:
|
|
CliDxeRegisterApi(MEM_READ_OPCODE, CliMemRead, XmlCliProtocol)
|
|
|
|
@param[in] CommandId Command Id for the API
|
|
@param[in] ClicmdHandler Handler function
|
|
@param[in] Buffer Pointer to Protocol Structure
|
|
|
|
@retval VOID
|
|
**/
|
|
VOID
|
|
CliDxeRegisterApi (
|
|
IN UINT16 CommandId,
|
|
IN CLI_CMD_HANDLER_FUNC ClicmdHandler,
|
|
IN VOID *Buffer
|
|
)
|
|
{
|
|
UINT8 count;
|
|
EFI_STATUS Status;
|
|
REG_CLI_COMMAND_ENTRY *DxeCliApiProto=NULL;
|
|
|
|
Status = gBS->LocateProtocol(&gDxeCliApiGuid, NULL, (VOID **)&DxeCliApiProto);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: Error locating DxeCliApiProto! \n"));
|
|
return;
|
|
}
|
|
if (DxeCliApiProto == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (count = 0; count < MAX_CLI_APIs_SUPPORTED; count++) {
|
|
if ((DxeCliApiProto->CommandId == 0) && (DxeCliApiProto->CmdHandler == NULL)) {
|
|
DxeCliApiProto->CommandId = CommandId;
|
|
DxeCliApiProto->CmdHandler = ClicmdHandler;
|
|
DxeCliApiProto->Buffer = Buffer;
|
|
return;
|
|
}
|
|
DxeCliApiProto++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Cli Entry Point Exposed as a XmlCli API structure
|
|
|
|
@param[in] XmlCliCom XmlCli Common Structure
|
|
|
|
@retval EFI_SUCCESS
|
|
@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
|
|
CliEntry (
|
|
IN VOID *XmlCliCom
|
|
)
|
|
{
|
|
BOOLEAN TmpInSmmVar;
|
|
UINT32 Signature=0;
|
|
EFI_STATUS Status=EFI_SUCCESS;
|
|
XML_CLI_COMMON *XmlCliCommon;
|
|
|
|
XmlCliCommon = (XML_CLI_COMMON*)XmlCliCom;
|
|
Signature = ((CLI_BUFFER*)(UINTN)XmlCliCommon->CliRequestBufferAddress)->Signature;
|
|
if ((Signature == CLI_GEN2_SGN_REQUEST_READY) || (Signature == CLI_SGN_REQUEST_READY)) { // Enter Only if Req Buff Signature is valid, Optimized Call
|
|
#ifndef SKIP_AUTHENTICATE_XML_CLI_API
|
|
if (CompareMem((VOID*)((UINTN)DxeProtocolPtr.Digest), (VOID*)((UINTN)DxeProtocolPtr.XmlCliTmpBuffPtr + DIGEST_OFFSET), DIGEST_SIZE) == 0) {
|
|
ZeroMem((VOID*)((UINTN)DxeProtocolPtr.XmlCliTmpBuffPtr + DIGEST_OFFSET), DIGEST_SIZE);
|
|
#endif // SKIP_AUTHENTICATE_XML_CLI_API
|
|
|
|
TmpInSmmVar = XmlCliCommon->CliRT.InSmm;
|
|
XmlCliCommon->CliRT.InSmm = FALSE; // Set InSmm False
|
|
Status = CliEntryPoint((VOID*)XmlCliCommon);
|
|
XmlCliCommon->CliRT.InSmm = TmpInSmmVar; // Restore the original Value
|
|
|
|
#ifndef SKIP_AUTHENTICATE_XML_CLI_API
|
|
*(UINT64*)(UINTN)(DxeProtocolPtr.XmlCliTmpBuffPtr + DIGEST_OFFSET) = XMLCLI_REQUEST_VALIDATED_SIG1;
|
|
*(UINT64*)(UINTN)(DxeProtocolPtr.XmlCliTmpBuffPtr + DIGEST_OFFSET + sizeof(UINT64)) = XMLCLI_REQUEST_VALIDATED_SIG2;
|
|
}
|
|
#endif // SKIP_AUTHENTICATE_XML_CLI_API
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Generate GBT Xml file at GbtXmlAddress
|
|
|
|
@param[in] XmlCliProto Pointer to XmlCli Protocol
|
|
|
|
@retval VOID
|
|
**/
|
|
VOID
|
|
GenerateGbtXml (
|
|
IN VOID *XmlCliProto
|
|
)
|
|
{
|
|
UINT32 XmlSize;
|
|
UINT32 XmlDataEndAddress;
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE Handle=NULL;
|
|
XML_CLI_PROTOCOL *XmlCliProtocol=(XML_CLI_PROTOCOL*)XmlCliProto;
|
|
VOID *CurrXmlWrtrContext;
|
|
|
|
if (XmlCliProtocol == NULL) { // XmlCliProtocol not published.
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: XmlCliProtocol is NULL, returning! \n"));
|
|
return;
|
|
} else {
|
|
if ((XmlCliProtocol->XmlCliCommon->GbtXmlAddress != 0) && (XmlCliProtocol->XmlCliStructInitialized == TRUE)) {
|
|
if (XmlValid(XmlCliProtocol->XmlCliCommon->GbtXmlAddress)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: GBT XML is already published, returning! \n"));
|
|
return; // XML is already published, return
|
|
}
|
|
}
|
|
}
|
|
|
|
XmlCliProtocol->XmlCliCommon->MergeDuplicateKnobs = 0; // Merge Duplicate knobs.
|
|
|
|
OpenXmlFile(XmlCliProtocol->XmlCliCommon->GbtXmlAddress);
|
|
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: XmlGenerateSystemInfo\n"));
|
|
XmlGenerateSystemInfo(XmlCliProtocol->XmlCliCommon);
|
|
|
|
CurrXmlWrtrContext = RetXmlWriterContext();
|
|
CurrXmlWrtrContext = (VOID*)(XmlCliProtocol->XmlCliCommon->XmlGenBiosKnobsSection (XmlCliProtocol->XmlCliCommon, CurrXmlWrtrContext));
|
|
OvrdXmlWriterContext(CurrXmlWrtrContext);
|
|
|
|
XmlSize = CloseXmlFile(XmlCliProtocol->XmlCliCommon->GbtXmlAddress);
|
|
XmlDataEndAddress = XmlCliProtocol->XmlCliCommon->DxeXmlCompress((VOID*)XmlCliProtocol->XmlCliCommon, XmlSize);
|
|
|
|
XmlCliProtocol->XmlCliCommon->FreeGbtMemAddr = XmlDataEndAddress;
|
|
if (XmlCliProtocol->XmlCliCommon->KnobValMapAddr <= XmlCliProtocol->XmlCliCommon->FreeGbtMemAddr) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: ERROR: XML Size exceeded than what we expected \n"));
|
|
ASSERT(FALSE);
|
|
} else {
|
|
XmlCliProtocol->XmlCliCommon->FreeGbtMemSize = XmlCliProtocol->XmlCliCommon->KnobValMapAddr - XmlCliProtocol->XmlCliCommon->FreeGbtMemAddr;
|
|
DEBUG ((DEBUG_INFO, "XML_CLI: XML Base = 0x%X XML size = 0x%X DramMbAddress = 0x%x SafetyBuffer = %d KB\n", XmlCliProtocol->XmlCliCommon->GbtXmlAddress, XmlSize, XmlCliProtocol->XmlCliCommon->DramSharedMBAddr, (XmlCliProtocol->XmlCliCommon->FreeGbtMemSize/1024)));
|
|
}
|
|
XmlCliProtocol->XmlCliStructInitialized = TRUE;
|
|
Status = gBS->InstallProtocolInterface(&Handle, &gXmlCliInterfaceReadyGuid, EFI_NATIVE_INTERFACE, NULL);
|
|
DEBUG((DEBUG_INFO, "XML_CLI: Triggerring Dummy protocol to Mark Xmlcli Ready, Status: %r\n", Status));
|
|
}
|
|
|
|
/**
|
|
Checks whether the Knob data is valid by matching the header
|
|
Signature to NVAR_SIGNATURE (0x5241564E24)
|
|
|
|
@param[in,out] XmlCliCommon XmlCli Common Structure
|
|
Update BiosKnobsDataAddr if Data32 found when
|
|
Reading Mailbox
|
|
|
|
@retval TRUE Knob header Signature match to NVAR_SIGNATURE `$NVAR`
|
|
@retval FALSE Failure
|
|
**/
|
|
BOOLEAN
|
|
IsKnobsDataBinValid (
|
|
IN OUT XML_CLI_COMMON *XmlCliCommon
|
|
)
|
|
{
|
|
UINT32 Data32;
|
|
KNOB_BIN_HDR *KnobBinHdr;
|
|
READ_MAILBOX(OFF_BIOS_KNOBS_DATA_BIN_ADDR, 4, &Data32, XmlCliCommon->DramSharedMBAddr, XmlCliCommon->PcieAddr);
|
|
if (Data32) {
|
|
KnobBinHdr = (KNOB_BIN_HDR*)(UINTN)Data32;
|
|
if (KnobBinHdr->Hdr0.Signature == NVAR_SIGNATURE) {
|
|
XmlCliCommon->BiosKnobsDataAddr = Data32;
|
|
READ_MAILBOX(OFF_BIOS_KNOBS_DATA_BIN_SIZE, 4, &Data32, XmlCliCommon->DramSharedMBAddr, XmlCliCommon->PcieAddr);
|
|
XmlCliCommon->BiosKnobsDataSize = Data32;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Get Offset and size of the knob(setup variable) from Bios Knobs Data bin.
|
|
|
|
@param[in] BiosKnobsDataAddr Address of Bios knobs Data bin.
|
|
@param[in] BiosKnobsDataSize Size of Bios knobs Data bin.
|
|
@param[in] VarName Name of Nvar.
|
|
@param[in] VarGuid Nvar Guid.
|
|
@param[in,out] MyKnobList List of knob for which Offset and size to be find.
|
|
Size and offset will be part of the structure as output.
|
|
@param[in] MyKnobCount Total number of knob for which Offset and size to be find.
|
|
@param[in,out] NvarSize Size of the setup variable
|
|
|
|
@retval UINT16
|
|
**/
|
|
UINT16
|
|
CliGetSetMyVariable (
|
|
IN VOID *XmlCliCom,
|
|
IN UINT8 Operation,
|
|
IN OUT VOID *MyKnobList,
|
|
IN UINT16 MyKnobCount
|
|
)
|
|
{
|
|
BOOLEAN SkipThisNvar;
|
|
BOOLEAN ValidDataFound=FALSE;
|
|
BOOLEAN BitWise;
|
|
UINT8 BitField;
|
|
UINT8 KnobTypeSz;
|
|
UINT8 CurKnobSize;
|
|
CHAR8 DefName[64];
|
|
CHAR16 UniCodeName[64];
|
|
CHAR16 DefUniCodeName[64];
|
|
UINT16 DataOffset;
|
|
UINT16 Modified=0;
|
|
UINT16 SetupModified=0;
|
|
UINT16 Count=0;
|
|
UINT16 CurCount=0;
|
|
UINT32 Attributes=0;
|
|
UINT32 DefAttributes=0;
|
|
UINTN VariableSize;
|
|
UINTN DefVariableSize;
|
|
EFI_STATUS Status;
|
|
EFI_GUID MyGuid;
|
|
EFI_GUID DefGuid;
|
|
UINT8 *BufferPtr;
|
|
UINT8 *KnobsBuffPtrStart;
|
|
KNOB_LIST *MyKnobListPtr;
|
|
KNOB_BIN_HDR *KnobBinHdr;
|
|
XML_CLI_COMMON *XmlCliCommon;
|
|
VOID *Setup=NULL;
|
|
VOID *DefSetup=NULL;
|
|
|
|
MyKnobListPtr = (KNOB_LIST *)MyKnobList;
|
|
for (Count=0; Count < MyKnobCount; Count++, MyKnobListPtr++) {
|
|
MyKnobListPtr->KnobSize = 0; // this also indicates that the knob was not processed.
|
|
MyKnobListPtr->KnobOffset = 0;
|
|
}
|
|
XmlCliCommon = (XML_CLI_COMMON*)XmlCliCom;
|
|
if ((XmlCliCommon == 0) || (MyKnobCount == 0)) {
|
|
return 0;
|
|
}
|
|
|
|
if ((XmlCliCommon->BiosKnobsDataAddr == 0) || (XmlCliCommon->BiosKnobsDataSize == 0)) {
|
|
ValidDataFound = IsKnobsDataBinValid(XmlCliCommon);
|
|
} else {
|
|
KnobBinHdr = (KNOB_BIN_HDR*)(UINTN)XmlCliCommon->BiosKnobsDataAddr;
|
|
if (KnobBinHdr->Hdr0.Signature == NVAR_SIGNATURE) {
|
|
ValidDataFound = TRUE;
|
|
} else {
|
|
ValidDataFound = IsKnobsDataBinValid(XmlCliCommon);
|
|
}
|
|
}
|
|
|
|
if (ValidDataFound != TRUE) {
|
|
DEBUG ((DEBUG_ERROR, "XML_CLI: gBiosKnobsDataBin FFS not found..\n"));
|
|
return 0;
|
|
}
|
|
// DEBUG ((DEBUG_INFO, "BiosKnobsData Addr = 0x%X Size = 0x%X MyKnobCount= %d\n", XmlCliCommon->BiosKnobsDataAddr, XmlCliCommon->BiosKnobsDataSize, MyKnobCount));
|
|
|
|
if (Operation == GET_VAR) {
|
|
(VOID) gBS->AllocatePool(EfiBootServicesData, 0x10000, (VOID**)&Setup); // Allocate common 64K buffer for all Get Variables, will be faster.
|
|
} else {
|
|
(VOID) gBS->AllocatePool(EfiBootServicesData, 0x20000, (VOID**)&Setup); // Allocate common 64K * 2 buffer for all Get Variables, will be faster.
|
|
DefSetup = (VOID*) ((UINTN) Setup + 0x10000);
|
|
}
|
|
SetupModified = 0;
|
|
for (KnobsBuffPtrStart = (UINT8*)(UINTN) XmlCliCommon->BiosKnobsDataAddr; (KnobsBuffPtrStart < (UINT8*)(UINTN)(XmlCliCommon->BiosKnobsDataAddr+XmlCliCommon->BiosKnobsDataSize));) {
|
|
KnobBinHdr = (KNOB_BIN_HDR*) KnobsBuffPtrStart;
|
|
if (CurCount >= MyKnobCount) {
|
|
break;
|
|
}
|
|
if ((KnobBinHdr->Hdr0.Signature == NVAR_SIGNATURE) || (KnobBinHdr->Hdr0.Signature == NVRO_SIGNATURE)) { // compare Signature with "$NVAR" or "$NVRO"
|
|
MyGuid = KnobBinHdr->NvarGuid;
|
|
VariableSize = 0;
|
|
SkipThisNvar = FALSE;
|
|
Modified = 0;
|
|
for (BufferPtr=(KnobsBuffPtrStart+sizeof(KNOB_BIN_HDR)); ((BufferPtr < (KnobsBuffPtrStart+KnobBinHdr->Hdr1.DupKnobBufOff)) && ((UINT32)(UINTN) BufferPtr < (XmlCliCommon->BiosKnobsDataAddr+XmlCliCommon->BiosKnobsDataSize)));) {
|
|
if (SkipThisNvar) {
|
|
break; // This Nvar has some issues, skip it
|
|
}
|
|
if (CurCount >= MyKnobCount) {
|
|
break;
|
|
}
|
|
CopyMem(&DataOffset, BufferPtr, 2);
|
|
BufferPtr = BufferPtr + 2; // Aditionally ignore 1 byte of data (reserved for Knob Type[7:4] & KnobSize[3:0])
|
|
CopyMem(&KnobTypeSz, BufferPtr, 1);
|
|
BufferPtr = BufferPtr + 1; // 1 byte of data (reserved for Knob Type[7:4] & KnobSize[3:0])
|
|
BitWise = FALSE;
|
|
CurKnobSize = 7;
|
|
if ((KnobTypeSz & 0x80) == 0) { // dont process EFI_IFR_STRING_OP
|
|
if ((KnobTypeSz & 0xF) >= 0xC) { // this indicates that the given Knob is Bitwise and is of Size mentioned in subsequent fields
|
|
BitWise = TRUE;
|
|
CopyMem (&BitField, BufferPtr, 1);
|
|
BufferPtr = BufferPtr + 1; // 1 byte of data Bitsize[7:3] BitOffset[2:0]
|
|
CurKnobSize = BitGetByteSize((BitField & 0x7), ((BitField >> 3) & 0x3F));
|
|
} else {
|
|
CurKnobSize = (KnobTypeSz & 0xF);
|
|
}
|
|
}
|
|
MyKnobListPtr = (KNOB_LIST *)MyKnobList;
|
|
for (Count = 0; Count < MyKnobCount; Count++, MyKnobListPtr++) {
|
|
if (MyKnobListPtr->KnobSize) {
|
|
continue; // This knob was processed already
|
|
}
|
|
if (AsciiStrCmp((CHAR8*)(VOID*)BufferPtr, MyKnobListPtr->KnobName) == 0) {
|
|
if (VariableSize == 0) {
|
|
MyKnobListPtr->VarId = (UINT8)KnobBinHdr->Hdr0.VarId;
|
|
ZeroMem((VOID*)UniCodeName, sizeof(UniCodeName)); //Clear data
|
|
AsciiStrToUnicodeStrS (KnobBinHdr->NvarName, UniCodeName, (sizeof (UniCodeName)/sizeof(CHAR16)));
|
|
(VOID) gRT->GetVariable(UniCodeName, &MyGuid, &Attributes, &VariableSize, NULL);
|
|
if (VariableSize != 0) {
|
|
Status = gRT->GetVariable(UniCodeName, &MyGuid, &Attributes, &VariableSize, Setup);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "XML_CLI[GetSetMyVar]: Status=%r\n", Status));
|
|
SkipThisNvar = TRUE;
|
|
break;
|
|
} else {
|
|
if (Operation == GET_DEF_CUR_VAR || Operation == GET_MOD_SET_VAR) {
|
|
AsciiStrCpyS((CHAR8*)DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)"Def");
|
|
AsciiStrCatS((CHAR8*)DefName, sizeof(KnobBinHdr->NvarName), (CHAR8*)KnobBinHdr->NvarName);
|
|
ZeroMem((VOID*)DefUniCodeName, sizeof(DefUniCodeName)); //Clear data
|
|
AsciiStrToUnicodeStrS ((CHAR8 *)DefName, DefUniCodeName, sizeof (DefUniCodeName));
|
|
DefGuid = MyGuid;
|
|
DefGuid.Data1 = 0xDEFA901D;
|
|
DefVariableSize = VariableSize;
|
|
Status = gRT->GetVariable(DefUniCodeName, &DefGuid, &DefAttributes, &DefVariableSize, DefSetup);
|
|
if (EFI_ERROR (Status)) {
|
|
CopyMem (DefSetup, Setup, VariableSize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CurCount++;
|
|
if (CurKnobSize == 7) { // EFI_IFR_STRING_OP
|
|
MyKnobListPtr->KnobSize = 0x7; // Limit String Type knob's size to a non valid 7 bytes, this means we dont support String type knobs as of now.
|
|
continue;
|
|
} else {
|
|
MyKnobListPtr->KnobSize = CurKnobSize;
|
|
}
|
|
MyKnobListPtr->KnobOffset = DataOffset;
|
|
if ((VariableSize != 0) && (MyKnobListPtr->KnobSize <= sizeof(UINTN))) {
|
|
if ((Operation == GET_VAR) || (Operation == GET_DEF_CUR_VAR)) {
|
|
MyKnobListPtr->KnobValue = 0;
|
|
CopyMem(&MyKnobListPtr->KnobValue, (UINT8*)Setup+DataOffset, MyKnobListPtr->KnobSize);
|
|
if (BitWise) {
|
|
MyKnobListPtr->KnobValue = BitExtractValue64(MyKnobListPtr->KnobValue, (BitField & 0x7), ((BitField >> 3) & 0x3F));
|
|
}
|
|
if (Operation == GET_DEF_CUR_VAR) {
|
|
MyKnobListPtr->DefKnobValue = 0;
|
|
CopyMem(&MyKnobListPtr->DefKnobValue, (UINT8*)DefSetup+DataOffset, MyKnobListPtr->KnobSize);
|
|
if (BitWise) {
|
|
MyKnobListPtr->DefKnobValue = BitExtractValue64(MyKnobListPtr->DefKnobValue, (BitField & 0x7), ((BitField >> 3) & 0x3F));
|
|
}
|
|
}
|
|
} else if (Operation == GET_MOD_SET_VAR) {
|
|
MyKnobListPtr->DefKnobValue = 0;
|
|
CopyMem(&MyKnobListPtr->DefKnobValue, (UINT8*)DefSetup+DataOffset, MyKnobListPtr->KnobSize);
|
|
if (MyKnobListPtr->KnobValue <= (0xFFFFFFFFFFFFFFFF >> (64-(8*MyKnobListPtr->KnobSize)))) { // Allow only if input Value is within the Knob size range
|
|
if (BitWise) {
|
|
if(BitDataMatch64((VOID*)((UINT8*)Setup+DataOffset),(VOID*)&MyKnobListPtr->KnobValue, (BitField & 0x7), (BitField >> 3), 0) == FALSE) {
|
|
BitDataCopy64((VOID*)((UINT8*)Setup+DataOffset),(VOID*)&MyKnobListPtr->KnobValue, (BitField & 0x7), (BitField >> 3));
|
|
Modified++;
|
|
SetupModified++;
|
|
}
|
|
} else {
|
|
if (CompareMem((UINT8*)Setup+DataOffset, &MyKnobListPtr->KnobValue, MyKnobListPtr->KnobSize) != 0) {
|
|
CopyMem((UINT8*)Setup+DataOffset, &MyKnobListPtr->KnobValue, MyKnobListPtr->KnobSize);
|
|
Modified++;
|
|
SetupModified++;
|
|
}
|
|
}
|
|
} else {
|
|
MyKnobListPtr->KnobValue = 0;
|
|
CopyMem(&MyKnobListPtr->KnobValue, (UINT8*)Setup+DataOffset, MyKnobListPtr->KnobSize);
|
|
if (BitWise) {
|
|
MyKnobListPtr->KnobValue = BitExtractValue64(MyKnobListPtr->KnobValue, (BitField & 0x7), ((BitField >> 3) & 0x3F));
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
MyKnobListPtr->KnobSize = 0; // this means this specific Knob was not found or consider it as InValid
|
|
}
|
|
// DEBUG ((DEBUG_INFO, "%a[0x%04X][%d] = 0x%X\n", BufferPtr, DataOffset, MyKnobListPtr->KnobSize, MyKnobListPtr->KnobValue));
|
|
if (CurCount >= MyKnobCount) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// increment the knob name string
|
|
while (*BufferPtr) {
|
|
BufferPtr++;
|
|
}
|
|
BufferPtr++; // Skip Null byte encounter
|
|
// Skip the DEPEX
|
|
while (*BufferPtr) {
|
|
BufferPtr++;
|
|
}
|
|
BufferPtr++; // Skip Null byte encounter
|
|
}
|
|
if (Modified) {
|
|
Status = gRT->SetVariable(UniCodeName, &MyGuid, Attributes, VariableSize, Setup);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "XML_CLI[GetSetMyVar]: Set Variable Status = %r..for %s \n", Status, UniCodeName));
|
|
}
|
|
}
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + KnobBinHdr->Hdr1.NvarPktSize;
|
|
} else {
|
|
KnobsBuffPtrStart = KnobsBuffPtrStart + sizeof(KNOB_BIN_HDR);
|
|
}
|
|
}
|
|
// DEBUG ((DEBUG_INFO, "XML_CLI[GetSetMyVar]: Total Modified Knobs = %d \n", SetupModified));
|
|
gBS->FreePool(Setup);
|
|
return SetupModified;
|
|
}
|