summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/PCD
diff options
context:
space:
mode:
authorStar Zeng <star.zeng@intel.com>2016-05-19 11:23:41 +0800
committerStar Zeng <star.zeng@intel.com>2016-06-20 17:27:58 +0800
commitc73cf875524666582343a479665e0469444a38c8 (patch)
tree8445e15cafbfe51a58c613cf2cf383dd962bef37 /MdeModulePkg/Universal/PCD
parentcc0b456a05f8dd1ebfb9be485465be37e96999e7 (diff)
downloadedk2-c73cf875524666582343a479665e0469444a38c8.tar.gz
edk2-c73cf875524666582343a479665e0469444a38c8.tar.bz2
edk2-c73cf875524666582343a479665e0469444a38c8.zip
MdeModulePkg PCD: Avoid DynamicHii PCD set to override other values
When Hii variable is not present and if we try to update a variable offset with some value, we are creating a new variable by Zeroing all the variable offsets except the one which we are trying to update. This will override all the other variable default values which are programmed as a part of initial PCD definition. DXE PCD driver could be enhanced to combine the DynamicHii PCDs(related to same variable) default values and only update the offset PcdSetXXX want to set, then set the combined values to variable. Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
Diffstat (limited to 'MdeModulePkg/Universal/PCD')
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.c94
1 files changed, 89 insertions, 5 deletions
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
index eb1e1cef0b..9ab456624f 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c
@@ -2,7 +2,7 @@
Help functions used by PCD DXE driver.
Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1370,6 +1370,84 @@ ExSetWorker (
}
/**
+ Get variable size and data from HII-type PCDs.
+
+ @param[in] VariableGuid Guid of variable which stored value of a HII-type PCD.
+ @param[in] VariableName Unicode name of variable which stored value of a HII-type PCD.
+ @param[out] VariableSize Pointer to variable size got from HII-type PCDs.
+ @param[out] VariableData Pointer to variable data got from HII-type PCDs.
+
+**/
+VOID
+GetVariableSizeAndDataFromHiiPcd (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ OUT UINTN *VariableSize,
+ OUT VOID *VariableData OPTIONAL
+ )
+{
+ BOOLEAN IsPeiDb;
+ PCD_DATABASE_INIT *Database;
+ UINTN TokenNumber;
+ UINT32 LocalTokenNumber;
+ UINTN Offset;
+ EFI_GUID *GuidTable;
+ UINT8 *StringTable;
+ VARIABLE_HEAD *VariableHead;
+ EFI_GUID *Guid;
+ UINT16 *Name;
+ UINTN PcdDataSize;
+ UINTN Size;
+ UINT8 *VaraiableDefaultBuffer;
+ STRING_HEAD StringTableIdx;
+
+ *VariableSize = 0;
+
+ //
+ // Go through PCD database to find out DynamicHii PCDs.
+ //
+ for (TokenNumber = 1; TokenNumber <= mPcdTotalTokenCount; TokenNumber++) {
+ IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
+ if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {
+ //
+ // Get the Variable Guid and Name pointer.
+ //
+ Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
+ VariableHead = (VARIABLE_HEAD *) ((UINT8 *) Database + Offset);
+ StringTable = (UINT8 *) ((UINT8 *) Database + Database->StringTableOffset);
+ GuidTable = (EFI_GUID *) ((UINT8 *) Database + Database->GuidTableOffset);
+ Guid = GuidTable + VariableHead->GuidTableIndex;
+ Name = (UINT16*) (StringTable + VariableHead->StringIndex);
+ if (CompareGuid (VariableGuid, Guid) && (StrCmp (VariableName, Name) == 0)) {
+ //
+ // It is the matched DynamicHii PCD.
+ //
+ PcdDataSize = DxePcdGetSize (TokenNumber);
+ Size = VariableHead->Offset + PcdDataSize;
+ if (Size > *VariableSize) {
+ *VariableSize = Size;
+ }
+ if (VariableData != NULL) {
+ if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
+ //
+ // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
+ // string array in string table.
+ //
+ StringTableIdx = *(STRING_HEAD *) ((UINT8 *) Database + VariableHead->DefaultValueOffset);
+ VaraiableDefaultBuffer = (UINT8 *) (StringTable + StringTableIdx);
+ } else {
+ VaraiableDefaultBuffer = (UINT8 *) Database + VariableHead->DefaultValueOffset;
+ }
+ CopyMem ((UINT8 *) VariableData + VariableHead->Offset, VaraiableDefaultBuffer, PcdDataSize);
+ }
+ }
+ }
+ }
+}
+
+/**
Set value for HII-type PCD.
A HII-type PCD's value is stored in a variable. Setting/Getting the value of
@@ -1457,12 +1535,18 @@ SetHiiVariable (
//
// If variable does not exist, a new variable need to be created.
//
-
- Size = Offset + DataSize;
-
+
+ //
+ // Get size, allocate buffer and get data.
+ //
+ GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, NULL);
Buffer = AllocateZeroPool (Size);
ASSERT (Buffer != NULL);
-
+ GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, Buffer);
+
+ //
+ // Update buffer.
+ //
CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
if (SetAttributes == 0) {