From 23f3e119c7b154f6c9386588b5b74c6037a1251c Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Fri, 10 Apr 2015 09:01:46 +0000 Subject: [PATCH] MdeModulePkg: Add ATTRIBUTE (+/-RT, RO) support in PCD declaration in DSC file. Also update PCD_SERVICE_PEI_VERSION and PCD_SERVICE_DXE_VERSION to match with the new PcdDataBase binary generated by BaseTools. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng Reviewed-by: Liming Gao Reviewed-by: Jiewen Yao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17161 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Include/Guid/PcdDataBaseSignatureGuid.h | 17 ++- MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 17 ++- MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | 5 +- MdeModulePkg/Universal/PCD/Dxe/Service.c | 126 +++++++++++++++--- MdeModulePkg/Universal/PCD/Dxe/Service.h | 23 +++- MdeModulePkg/Universal/PCD/Pei/Service.h | 4 +- 6 files changed, 158 insertions(+), 34 deletions(-) diff --git a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h index 22c0d95f60..ac95f7e21a 100644 --- a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h +++ b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h @@ -1,13 +1,13 @@ /** @file Guid for Pcd DataBase Signature. -Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that accompanies this distribution. +Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. +http://opensource.org/licenses/bsd-license.php. -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ @@ -71,6 +71,9 @@ typedef struct { UINT32 DefaultValueOffset; // Offset of the Default Value. UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID. UINT16 Offset; // Offset in Variable. + UINT32 Attributes; // Variable attributes. + UINT16 Property; // Variable property. + UINT16 Reserved; } VARIABLE_HEAD; typedef struct { @@ -117,11 +120,11 @@ typedef struct { //DYNAMICEX_MAPPING ExMapTable[]; // DynamicEx PCD mapped to LocalIndex in LocalTokenNumberTable. It can be accessed by the ExMapTableOffset. //UINT32 LocalTokenNumberTable[]; // Offset | DataType | PCD Type. It can be accessed by LocalTokenNumberTableOffset. //GUID GuidTable[]; // GUID for DynamicEx and HII PCD variable Guid. It can be accessed by the GuidTableOffset. - //STRING_HEAD StringHead[]; // String PCD + //STRING_HEAD StringHead[]; // String PCD //PCD_NAME_INDEX PcdNameTable[]; // PCD name index info. It can be accessed by the PcdNameTableOffset. //VARIABLE_HEAD VariableHead[]; // HII PCD //SKU_HEAD SkuHead[]; // Store SKU info for each PCD with SKU enable. - //UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset. + //UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset. //SIZE_INFO SizeTable[]; // MaxSize and CurSize for String PCD. It can be accessed by SizeTableOffset. //UINT16 ValueUint16[]; //UINT8 ValueUint8[]; diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c index 4828af2b9d..6afcd18dff 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c @@ -3,7 +3,7 @@ produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in PI 1.2 Vol3. -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
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 @@ -129,7 +129,8 @@ PcdDxeInit ( ) { EFI_STATUS Status; - + VOID *Registration; + // // Make sure the Pcd Protocol is not already installed in the system // @@ -167,6 +168,18 @@ PcdDxeInit ( ASSERT_EFI_ERROR (Status); } + // + // Register callback function upon VariableLockProtocol + // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + // + EfiCreateProtocolNotifyEvent ( + &gEdkiiVariableLockProtocolGuid, + TPL_CALLBACK, + VariableLockCallBack, + NULL, + &Registration + ); + return Status; } diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf index be8ad90c87..54cd8d9b9f 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf @@ -279,7 +279,7 @@ # - Variable GUID for HII type PCD # - Token space GUID for dynamicex type PCD # -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -338,6 +338,9 @@ gEfiPcdProtocolGuid ## PRODUCES gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES + ## NOTIFY + ## SOMETIMES_CONSUMES + gEdkiiVariableLockProtocolGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c index 13f4d9c5e9..7b0932a6e4 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c @@ -1112,6 +1112,7 @@ SetWorker ( EFI_GUID *Guid; UINT16 *Name; UINTN VariableOffset; + UINT32 Attributes; VOID *InternalData; VARIABLE_HEAD *VariableHead; UINTN Offset; @@ -1223,20 +1224,8 @@ SetWorker ( Guid = GuidTable + VariableHead->GuidTableIndex; Name = (UINT16*) (StringTable + VariableHead->StringIndex); VariableOffset = VariableHead->Offset; - Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset); - - if (EFI_NOT_FOUND == Status) { - if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) { - CopyMem ( - StringTable + *(STRING_HEAD *)(PcdDb + VariableHead->DefaultValueOffset), - Data, - *Size - ); - } else { - CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size); - } - Status = EFI_SUCCESS; - } + Attributes = VariableHead->Attributes; + Status = SetHiiVariable (Guid, Name, Attributes, Data, *Size, VariableOffset); break; case PCD_TYPE_DATA: @@ -1373,6 +1362,7 @@ ExSetWorker ( @param VariableGuid Guid of variable which stored value of a HII-type PCD. @param VariableName Unicode name of variable which stored value of a HII-type PCD. + @param SetAttributes Attributes bitmask to set for the variable. @param Data Value want to be set. @param DataSize Size of value @param Offset Value offset of HII-type PCD in variable. @@ -1384,6 +1374,7 @@ EFI_STATUS SetHiiVariable ( IN EFI_GUID *VariableGuid, IN UINT16 *VariableName, + IN UINT32 SetAttributes, IN CONST VOID *Data, IN UINTN DataSize, IN UINTN Offset @@ -1413,7 +1404,7 @@ SetHiiVariable ( // // Patch new PCD's value to offset in given HII variable. // - if (Size >= (DataSize + Offset)) { + if (Size >= (DataSize + Offset)) { SetSize = Size; } else { SetSize = DataSize + Offset; @@ -1433,10 +1424,14 @@ SetHiiVariable ( CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); + if (SetAttributes == 0) { + SetAttributes = Attribute; + } + Status = gRT->SetVariable ( VariableName, VariableGuid, - Attribute, + SetAttributes, SetSize, Buffer ); @@ -1454,11 +1449,15 @@ SetHiiVariable ( ASSERT (Buffer != NULL); CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); - + + if (SetAttributes == 0) { + SetAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; + } + Status = gRT->SetVariable ( VariableName, VariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + SetAttributes, Size, Buffer ); @@ -1468,8 +1467,7 @@ SetHiiVariable ( } // - // If we drop to here, the value is failed to be written in to variable area - // So, we will save the data in the PCD Database's volatile area. + // If we drop to here, the value is failed to be written in to variable area. // return Status; } @@ -1820,3 +1818,91 @@ SetPtrTypeSize ( } } } + +/** + VariableLock DynamicHiiPcd. + + @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + @param[in] VariableLock Pointer to VariableLockProtocol. + +**/ +VOID +VariableLockDynamicHiiPcd ( + IN BOOLEAN IsPeiDb, + IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock + ) +{ + EFI_STATUS Status; + PCD_DATABASE_INIT *Database; + UINT32 LocalTokenCount; + UINTN TokenNumber; + UINT32 LocalTokenNumber; + UINTN Offset; + EFI_GUID *GuidTable; + UINT8 *StringTable; + VARIABLE_HEAD *VariableHead; + EFI_GUID *Guid; + UINT16 *Name; + + Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb; + LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount: mDxeLocalTokenCount; + + // + // Go through PCD database to find out DynamicHii PCDs. + // + for (TokenNumber = 0; TokenNumber < LocalTokenCount; TokenNumber++) { + if (IsPeiDb) { + LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber); + } else { + LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount); + } + if ((LocalTokenNumber & PCD_TYPE_HII) != 0) { + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + VariableHead = (VARIABLE_HEAD *) ((UINT8 *) Database + Offset); + // + // Why not to set property by VarCheckProtocol with Attributes and Property directly here? + // It is because that set property by VarCheckProtocol will indicate the variable to + // be a system variable, but the unknown max size of the variable is dangerous to + // the system variable region. + // + if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) { + // + // DynamicHii PCD with RO property set in *.dsc. + // + StringTable = (UINT8 *) ((UINT8 *) Database + Database->StringTableOffset); + GuidTable = (EFI_GUID *) ((UINT8 *) Database + Database->GuidTableOffset); + Guid = GuidTable + VariableHead->GuidTableIndex; + Name = (UINT16*) (StringTable + VariableHead->StringIndex); + Status = VariableLock->RequestToLock (VariableLock, Name, Guid); + ASSERT_EFI_ERROR (Status); + } + } + } +} + +/** + VariableLockProtocol callback + to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +VariableLockCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; + + Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock); + if (!EFI_ERROR (Status)) { + VariableLockDynamicHiiPcd (TRUE, VariableLock); + VariableLockDynamicHiiPcd (FALSE, VariableLock); + } +} + diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h index 55717dc982..4d8ab0f13f 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.h +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h @@ -1,7 +1,7 @@ /** @file Private functions used by PCD DXE driver. -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
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 @@ -22,6 +22,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include +#include #include #include #include @@ -37,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Please make sure the PCD Serivce DXE Version is consistent with // the version of the generated DXE PCD Database by build tool. // -#define PCD_SERVICE_DXE_VERSION 4 +#define PCD_SERVICE_DXE_VERSION 5 // // PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h. @@ -1003,6 +1005,7 @@ GetHiiVariable ( @param VariableGuid Guid of variable which stored value of a HII-type PCD. @param VariableName Unicode name of variable which stored value of a HII-type PCD. + @param SetAttributes Attributes bitmask to set for the variable. @param Data Value want to be set. @param DataSize Size of value @param Offset Value offset of HII-type PCD in variable. @@ -1014,6 +1017,7 @@ EFI_STATUS SetHiiVariable ( IN EFI_GUID *VariableGuid, IN UINT16 *VariableName, + IN UINT32 SetAttributes, IN CONST VOID *Data, IN UINTN DataSize, IN UINTN Offset @@ -1158,6 +1162,21 @@ SetPtrTypeSize ( IN OUT UINTN *CurrentSize ); +/** + VariableLockProtocol callback + to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +VariableLockCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ); + extern PCD_DATABASE mPcdDatabase; extern UINT32 mPcdTotalTokenCount; diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h index 916e708959..c75187c2b1 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.h +++ b/MdeModulePkg/Universal/PCD/Pei/Service.h @@ -1,7 +1,7 @@ /** @file The internal header file declares the private functions used by PeiPcd driver. -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
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 @@ -36,7 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Please make sure the PCD Serivce PEIM Version is consistent with // the version of the generated PEIM PCD Database by build tool. // -#define PCD_SERVICE_PEIM_VERSION 4 +#define PCD_SERVICE_PEIM_VERSION 5 // // PCD_PEI_SERVICE_DRIVER_VERSION is defined in Autogen.h. -- 2.39.2