]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/Build: Add SDL support
authorBob Feng <bob.c.feng@intel.com>
Fri, 10 Apr 2015 06:59:47 +0000 (06:59 +0000)
committerbobfeng <bobfeng@Edk2>
Fri, 10 Apr 2015 06:59:47 +0000 (06:59 +0000)
1.BaseTool add ATTRIBUTE (+/-RT, RO) support in PCD declaration in DSC file
2.BaseTool collect valid PCD value in DEC file and generate data base for runtime sanity check
3.BaseTool support SetPcd error.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Bob Feng" <bob.c.feng@intel.com>
Reviewed-by: "Chen, Hesheng" <hesheng.chen@intel.com>
Reviewed-by: "Liu, Yingke D" <yingke.d.liu@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17158 6f19259b-4bc3-4df7-8a09-765794883524

14 files changed:
BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools/Source/Python/AutoGen/GenC.py
BaseTools/Source/Python/AutoGen/GenPcdDb.py
BaseTools/Source/Python/AutoGen/ValidCheckingInfoObject.py [new file with mode: 0644]
BaseTools/Source/Python/Common/BuildToolError.py
BaseTools/Source/Python/Common/DataType.py
BaseTools/Source/Python/Common/Misc.py
BaseTools/Source/Python/Common/RangeExpression.py [new file with mode: 0644]
BaseTools/Source/Python/Common/VariableAttributes.py [new file with mode: 0644]
BaseTools/Source/Python/CommonDataClass/CommonClass.py
BaseTools/Source/Python/Workspace/BuildClassObject.py
BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools/Source/Python/Workspace/WorkspaceDatabase.py

index cd61e8e75896a7fc162cf33cf64661c33830b28b..a1e1818e3b5f5878f89a075630b55c22b20157cc 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Generate AutoGen.h, AutoGen.c and *.depex files\r
 #\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -1813,6 +1813,9 @@ class PlatformAutoGen(AutoGen):
             if not IsValid:\r
                 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,\r
                                 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
+            ToPcd.validateranges = FromPcd.validateranges\r
+            ToPcd.validlists = FromPcd.validlists\r
+            ToPcd.expressions = FromPcd.expressions\r
 \r
         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
index a140cc80a4e4b672ffac5773aed35a166e4f22bc..9bdb0363b2c7d0891a89accb16612d3748f4cc7e 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Routines for generating AutoGen.h and AutoGen.c\r
 #\r
-# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -786,6 +786,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
     DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]\r
     GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName\r
     SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName\r
+    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + Pcd.TokenCName\r
 \r
     PcdExCNameList  = []\r
     if Pcd.Type in gDynamicExPcd:\r
@@ -805,21 +806,27 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             if Pcd.DatumType == 'VOID*':\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             if Pcd.DatumType == 'VOID*':\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
     elif Pcd.Type in gDynamicPcd:\r
         AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
         if Pcd.DatumType == 'VOID*':\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))\r
+            AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
     else:\r
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName\r
         Const = 'const'\r
@@ -963,8 +970,10 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
             if Pcd.DatumType == 'VOID*':\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))\r
+                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrS(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName))\r
             else:\r
                 AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))\r
+                AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS) \n' % (SetModeStatusName, PcdVariableName))\r
         else:\r
             AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)\r
 \r
@@ -1018,6 +1027,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]\r
     GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName\r
     SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName\r
+    SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName\r
 \r
     Type = ''\r
     Array = ''\r
@@ -1046,28 +1056,35 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             if Pcd.DatumType == 'VOID*':\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             if Pcd.DatumType == 'VOID*':\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
+                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
     else:\r
         AutoGenH.Append('#define _PCD_TOKEN_%s  %dU\n' % (TokenCName, TokenNumber))\r
     if PcdItemType in gDynamicPcd:\r
         AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
         if DatumType == 'VOID*':\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))\r
+            AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
     if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:\r
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName\r
         AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )\r
         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))\r
         AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))\r
+        AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS)\n' % (SetModeStatusName, PcdVariableName))\r
     if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:\r
         key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))\r
         \r
index e995e141da7a44be4ea71aec043252f37c8c8d65..4ccd2d65e3907d25db9faccd72ef6a822907d9fb 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Routines for generating Pcd Database\r
 #\r
-# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -14,8 +14,12 @@ from StringIO import StringIO
 from Common.Misc import *\r
 from Common.String import StringToArray\r
 from struct import pack\r
+from ValidCheckingInfoObject import VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER\r
+from ValidCheckingInfoObject import VAR_CHECK_PCD_VARIABLE_TAB\r
+from ValidCheckingInfoObject import VAR_VALID_OBJECT_FACTORY\r
+from Common.VariableAttributes import VariableAttributes\r
 \r
-DATABASE_VERSION = 4\r
+DATABASE_VERSION = 5\r
 \r
 gPcdDatabaseAutoGenC = TemplateString("""\r
 //\r
@@ -444,7 +448,7 @@ class DbVariableTableItemList (DbComItemList):
             RawDataList = []\r
         DbComItemList.__init__(self, ItemSize, DataList, RawDataList)\r
     def PackData(self):\r
-        PackStr = "=LLHH"\r
+        PackStr = "=LLHHLHH"\r
         Buffer = ''\r
         for DataList in self.RawDataList:\r
             for Data in DataList:\r
@@ -452,7 +456,10 @@ class DbVariableTableItemList (DbComItemList):
                                GetIntegerValue(Data[0]),\r
                                GetIntegerValue(Data[1]),\r
                                GetIntegerValue(Data[2]),\r
-                               GetIntegerValue(Data[3]))\r
+                               GetIntegerValue(Data[3]),\r
+                               GetIntegerValue(Data[4]),\r
+                               GetIntegerValue(Data[5]),\r
+                               GetIntegerValue(0))\r
         return Buffer\r
 \r
 class DbStringHeadTableItemList(DbItemList):\r
@@ -712,7 +719,7 @@ def BuildExDataBase(Dict):
     # DbItemList to DbStringHeadTableItemList\r
     DbStringHeadValue = DbStringHeadTableItemList(4, RawDataList = StringHeadValue)\r
     VariableTable = Dict['VARIABLE_DB_VALUE']\r
-    DbVariableTable = DbVariableTableItemList(12, RawDataList = VariableTable)\r
+    DbVariableTable = DbVariableTableItemList(20, RawDataList = VariableTable)\r
     NumberOfSkuEnabledPcd = GetIntegerValue(Dict['SKU_HEAD_SIZE'])\r
     Dict['SKUHEAD_TABLE_VALUE'] = [(0,0) for i in xrange(NumberOfSkuEnabledPcd)]\r
     SkuTable = Dict['SKUHEAD_TABLE_VALUE']  # Generated later\r
@@ -852,7 +859,7 @@ def BuildExDataBase(Dict):
     for VariableEntries in VariableTable:\r
         skuindex = 0\r
         for VariableEntryPerSku in VariableEntries:\r
-            (VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable) = VariableEntryPerSku[:]\r
+            (VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable, VariableAttribute) = VariableEntryPerSku[:]\r
             DbIndex = 0\r
             DbOffset = FixedHeaderLen\r
             for DbIndex in xrange(len(DbTotal)):\r
@@ -867,8 +874,8 @@ def BuildExDataBase(Dict):
             skuindex += 1\r
             if DbIndex >= InitTableNum:\r
                 assert(False)\r
-\r
-            VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset)\r
+            VarAttr, VarProp = VariableAttributes.GetVarAttributes(VariableAttribute)\r
+            VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset, VarAttr, VarProp)\r
 \r
     # calculate various table offset now\r
     DbTotalLength = FixedHeaderLen\r
@@ -1113,6 +1120,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
     NumberOfSizeItems = 0\r
     NumberOfSkuEnabledPcd = 0\r
     GuidList = []\r
+    VarCheckTab = VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER()\r
     i = 0\r
     ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)\r
     for Pcd in ReorderedDynPcdList:\r
@@ -1182,6 +1190,29 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
             SkuIdIndex += 1\r
     \r
             if len(Sku.VariableName) > 0:\r
+                VariableGuidStructure = Sku.VariableGuidValue\r
+                VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)\r
+                if Platform.Platform.VarCheckFlag:\r
+                    var_check_obj = VAR_CHECK_PCD_VARIABLE_TAB(VariableGuidStructure, StringToArray(Sku.VariableName))\r
+                    try:\r
+                        var_check_obj.push_back(VAR_VALID_OBJECT_FACTORY.Get_valid_object(Pcd, Sku.VariableOffset))\r
+                        VarAttr, _ = VariableAttributes.GetVarAttributes(Sku.VariableAttribute)\r
+                        var_check_obj.SetAttributes(VarAttr)\r
+                        var_check_obj.UpdateSize()\r
+                        VarCheckTab.push_back(var_check_obj)\r
+                    except Exception:\r
+                        ValidInfo = ''\r
+                        if Pcd.validateranges:\r
+                            ValidInfo = Pcd.validateranges[0]\r
+                        if Pcd.validlists:\r
+                            ValidInfo = Pcd.validlists[0]\r
+                        if ValidInfo:\r
+                            EdkLogger.error("build", PCD_VALIDATION_INFO_ERROR,\r
+                                                "The PCD '%s.%s' Validation information defined in DEC file has incorrect format." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),\r
+                                                ExtraData = "[%s]" % str(ValidInfo))\r
+                        else:\r
+                            EdkLogger.error("build", PCD_VALIDATION_INFO_ERROR,\r
+                                                "The PCD '%s.%s' Validation information defined in DEC file has incorrect format." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
                 Pcd.TokenTypeList += ['PCD_TYPE_HII']\r
                 Pcd.InitString = 'INIT'\r
                 # Store all variable names of one HII PCD under different SKU to stringTable\r
@@ -1215,8 +1246,6 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
                         \r
                 VariableHeadStringIndex = VariableHeadList[SkuIdIndex - 2]\r
                 # store VariableGuid to GuidTable and get the VariableHeadGuidIndex\r
-                VariableGuidStructure = Sku.VariableGuidValue\r
-                VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)\r
 \r
                 if VariableGuid not in GuidList:\r
                     GuidList += [VariableGuid]\r
@@ -1268,7 +1297,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
                     # the Pcd default value was filled before\r
                     VariableOffset = len(Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]) - 1\r
                     VariableRefTable = Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]\r
-                VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable])\r
+                VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable, Sku.VariableAttribute])\r
 \r
             elif Sku.VpdOffset != '':\r
                 Pcd.TokenTypeList += ['PCD_TYPE_VPD']\r
@@ -1600,6 +1629,9 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
                 \r
         AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))\r
     \r
+    if Platform.Platform.VarCheckFlag:\r
+        dest = os.path.join(Platform.BuildDir, 'FV')\r
+        VarCheckTab.dump(dest, Phase)\r
     Buffer = BuildExDataBase(Dict)\r
     return AutoGenH, AutoGenC, Buffer\r
 \r
diff --git a/BaseTools/Source/Python/AutoGen/ValidCheckingInfoObject.py b/BaseTools/Source/Python/AutoGen/ValidCheckingInfoObject.py
new file mode 100644 (file)
index 0000000..4a6e031
--- /dev/null
@@ -0,0 +1,351 @@
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+#\r
+# This file is used to collect the Variable checking information\r
+#\r
+\r
+# #\r
+# Import Modules\r
+#\r
+import os\r
+from Common.RangeExpression import RangeExpression\r
+from Common.Misc import *\r
+from StringIO import StringIO\r
+from struct import pack\r
+\r
+class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):\r
+    def __init__(self):\r
+        self.var_check_info = []\r
+        \r
+    def push_back(self, var_check_tab):\r
+        for tab in self.var_check_info:\r
+            if tab.equal(var_check_tab):\r
+                tab.merge(var_check_tab)\r
+                break\r
+        else:\r
+            self.var_check_info.append(var_check_tab)\r
+        \r
+    def dump(self, dest, Phase):\r
+        \r
+        FormatMap = {}\r
+        FormatMap[1] = "=B"\r
+        FormatMap[2] = "=H"\r
+        FormatMap[4] = "=L"\r
+        FormatMap[8] = "=Q"\r
+        \r
+        if not os.path.isabs(dest):\r
+            return\r
+        if not os.path.exists(dest):\r
+            os.mkdir(dest)\r
+        BinFileName = "PcdVarCheck.bin"\r
+        BinFilePath = os.path.join(dest, BinFileName)\r
+        Buffer = ''\r
+        index = 0\r
+        for var_check_tab in self.var_check_info:\r
+            index += 1\r
+            realLength = 0\r
+            realLength += 32\r
+            Name = var_check_tab.Name[1:-1]\r
+            NameChars = Name.split(",")\r
+            realLength += len(NameChars)\r
+            if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):\r
+                realLength += (4 - (realLength % 4))\r
+            itemIndex = 0\r
+            for item in var_check_tab.validtab:\r
+                itemIndex += 1\r
+                realLength += 5\r
+                for v_data in item.data:\r
+                    if type(v_data) == type(1):\r
+                        realLength += item.StorageWidth\r
+                    else:\r
+                        realLength += item.StorageWidth\r
+                        realLength += item.StorageWidth\r
+                if (index == len(self.var_check_info)) :\r
+                    if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:\r
+                        realLength += (4 - (realLength % 4))\r
+                else:\r
+                    if realLength % 4:\r
+                        realLength += (4 - (realLength % 4))\r
+            var_check_tab.Length = realLength\r
+        realLength = 0\r
+        index = 0\r
+        for var_check_tab in self.var_check_info:\r
+            index += 1\r
+\r
+            b = pack("=H", var_check_tab.Revision)\r
+            Buffer += b\r
+            realLength += 2\r
+\r
+            b = pack("=H", var_check_tab.HeaderLength)\r
+            Buffer += b\r
+            realLength += 2\r
+\r
+            b = pack("=L", var_check_tab.Length)\r
+            Buffer += b\r
+            realLength += 4\r
+\r
+            b = pack("=B", var_check_tab.Type)\r
+            Buffer += b\r
+            realLength += 1\r
+\r
+            for i in range(0, 3):\r
+                b = pack("=B", var_check_tab.Reserved)\r
+                Buffer += b\r
+                realLength += 1\r
+\r
+            b = pack("=L", var_check_tab.Attributes)\r
+            Buffer += b\r
+            realLength += 4\r
+\r
+            Guid = var_check_tab.Guid\r
+            b = pack('=LHHBBBBBBBB',\r
+                Guid[0],\r
+                Guid[1],\r
+                Guid[2],\r
+                Guid[3],\r
+                Guid[4],\r
+                Guid[5],\r
+                Guid[6],\r
+                Guid[7],\r
+                Guid[8],\r
+                Guid[9],\r
+                Guid[10],\r
+                )\r
+            Buffer += b\r
+            realLength += 16\r
+\r
+            Name = var_check_tab.Name[1:-1]\r
+            NameChars = Name.split(",")\r
+            for NameChar in NameChars:\r
+                NameCharNum = int(NameChar, 16)\r
+                b = pack("=B", NameCharNum)\r
+                Buffer += b\r
+                realLength += 1\r
+\r
+            if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):\r
+                for i in range(4 - (realLength % 4)):\r
+                    b = pack("=B", var_check_tab.pad)\r
+                    Buffer += b\r
+                    realLength += 1\r
+            itemIndex = 0\r
+            for item in var_check_tab.validtab:\r
+                itemIndex += 1\r
+\r
+                b = pack("=B", item.Type)\r
+                Buffer += b\r
+                realLength += 1\r
+\r
+                b = pack("=B", item.Length)\r
+                Buffer += b\r
+                realLength += 1\r
+\r
+                b = pack("=H", int(item.VarOffset, 16))\r
+                Buffer += b\r
+                realLength += 2\r
+\r
+                b = pack("=B", item.StorageWidth)\r
+                Buffer += b\r
+                realLength += 1\r
+                \r
+                for v_data in item.data:\r
+                    if type(v_data) == type(1):\r
+                        b = pack(FormatMap[item.StorageWidth], v_data)\r
+                        Buffer += b\r
+                        realLength += item.StorageWidth\r
+                    else:\r
+                        b = pack(FormatMap[item.StorageWidth], v_data[0])\r
+                        Buffer += b\r
+                        realLength += item.StorageWidth\r
+                        b = pack(FormatMap[item.StorageWidth], v_data[1])\r
+                        Buffer += b\r
+                        realLength += item.StorageWidth\r
+\r
+                if (index == len(self.var_check_info)) :\r
+                    if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:\r
+                        for i in range(4 - (realLength % 4)):\r
+                            b = pack("=B", var_check_tab.pad)\r
+                            Buffer += b\r
+                            realLength += 1\r
+                else:\r
+                    if realLength % 4:\r
+                        for i in range(4 - (realLength % 4)):\r
+                            b = pack("=B", var_check_tab.pad)\r
+                            Buffer += b\r
+                            realLength += 1\r
+        \r
+        DbFile = StringIO()\r
+        if Phase == 'DXE' and os.path.exists(BinFilePath):\r
+            BinFile = open(BinFilePath, "rb")\r
+            BinBuffer = BinFile.read()\r
+            BinFile.close()\r
+            BinBufferSize = len(BinBuffer)\r
+            if (BinBufferSize % 4):\r
+                for i in range(4 - (BinBufferSize % 4)):\r
+                    b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad)\r
+                    BinBuffer += b\r
+            Buffer = BinBuffer + Buffer\r
+        DbFile.write(Buffer)\r
+        SaveFileOnChange(BinFilePath, DbFile.getvalue(), True)\r
+    \r
+\r
+class VAR_CHECK_PCD_VARIABLE_TAB(object):\r
+    pad = 0xDA\r
+    def __init__(self, TokenSpaceGuid, PcdCName):\r
+        self.Revision = 0x0001\r
+        self.HeaderLength = 0\r
+        self.Length = 0  # Length include this header\r
+        self.Type = 0\r
+        self.Reserved = 0\r
+        self.Attributes = 0x00000000\r
+        self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]")\r
+        self.Name = PcdCName\r
+        self.validtab = []\r
+\r
+    def UpdateSize(self):\r
+        self.HeaderLength = 32 + len(self.Name.split(","))\r
+        self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen()\r
+    \r
+    def GetValidTabLen(self):\r
+        validtablen = 0\r
+        for item in self.validtab:\r
+            validtablen += item.Length  \r
+        return validtablen \r
+    \r
+    def SetAttributes(self, attributes):\r
+        self.Attributes = attributes\r
+            \r
+    def push_back(self, valid_obj):\r
+        if valid_obj is not None:\r
+            self.validtab.append(valid_obj)\r
+        \r
+    def equal(self, varchecktab):\r
+        if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name:\r
+            return True\r
+        else:\r
+            return False\r
+        \r
+    def merge(self, varchecktab):\r
+        for validobj in varchecktab.validtab:\r
+            if validobj in self.validtab:\r
+                continue\r
+            self.validtab.append(validobj)\r
+        self.UpdateSize()\r
+\r
+\r
+class VAR_CHECK_PCD_VALID_OBJ(object):\r
+    def __init__(self, VarOffset, data, PcdDataType):\r
+        self.Type = 1\r
+        self.Length = 0  # Length include this header\r
+        self.VarOffset = VarOffset\r
+        self.StorageWidth = 0\r
+        self.PcdDataType = PcdDataType.strip()\r
+        self.rawdata = data\r
+        self.data = set()\r
+        self.ValidData = True\r
+        self.updateStorageWidth()\r
+    def updateStorageWidth(self):\r
+        if self.PcdDataType == "UINT8" or self.PcdDataType == "BOOLEAN":\r
+            self.StorageWidth = 1\r
+        elif self.PcdDataType == "UINT16":\r
+            self.StorageWidth = 2\r
+        elif self.PcdDataType == "UINT32":\r
+            self.StorageWidth = 4\r
+        elif self.PcdDataType == "UINT64":\r
+            self.StorageWidth = 8\r
+        else:\r
+            self.StorageWidth = 0\r
+            self.ValidData = False\r
+            \r
+    def __eq__(self, validObj):       \r
+        if self.VarOffset == validObj.VarOffset:\r
+            return True\r
+        else:\r
+            return False\r
+         \r
+class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ):\r
+    def __init__(self, VarOffset, validlist, PcdDataType):\r
+        super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType)\r
+        self.Type = 1\r
+        self.update_data()\r
+        self.update_size()\r
+    def update_data(self):\r
+        valid_num_list = []\r
+        data_list = []\r
+        for item in self.rawdata:\r
+            valid_num_list.extend(item.split(','))\r
+        \r
+        for valid_num in valid_num_list:\r
+            valid_num = valid_num.strip()\r
+\r
+            if valid_num.startswith('0x') or valid_num.startswith('0X'):\r
+                data_list.append(int(valid_num, 16))\r
+            else:\r
+                data_list.append(int(valid_num))\r
+\r
+                \r
+        self.data = set(data_list)\r
+        \r
+    def update_size(self):\r
+        self.Length = 5 + len(self.data) * self.StorageWidth\r
+        \r
+           \r
+class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ):\r
+    def __init__(self, VarOffset, validrange, PcdDataType):\r
+        super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType)\r
+        self.Type = 2\r
+        self.update_data()\r
+        self.update_size()\r
+    def update_data(self):\r
+        RangeExpr = ""\r
+        data_list = []\r
+        i = 0\r
+        for item in self.rawdata:\r
+            if i == 0:\r
+                RangeExpr = "( " + item + " )"\r
+            else:\r
+                RangeExpr = RangeExpr + "OR ( " + item + " )"\r
+        range_result = RangeExpression(RangeExpr, self.PcdDataType)(True)\r
+        for rangelist in range_result:\r
+            for obj in rangelist.pop():\r
+                data_list.append((obj.start, obj.end))\r
+        self.data = set(data_list)\r
+    \r
+    def update_size(self):\r
+        self.Length = 5 + len(self.data) * 2 * self.StorageWidth\r
+        \r
+\r
+class VAR_VALID_OBJECT_FACTORY(object):\r
+    def __init__(self):\r
+        pass\r
+    @staticmethod\r
+    def Get_valid_object(PcdClass, VarOffset):\r
+        if PcdClass.validateranges:\r
+            return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType)\r
+        if PcdClass.validlists:\r
+            return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType)\r
+        else:\r
+            return None\r
+\r
+if __name__ == "__main__":\r
+    class TestObj(object):\r
+        def __init__(self, number1):\r
+            self.number_1 = number1\r
+        def __eq__(self, testobj):\r
+            if self.number_1 == testobj.number_1:\r
+                return True\r
+            else:\r
+                return False\r
+    test1 = TestObj(1)\r
+    test2 = TestObj(2)\r
+    \r
+    testarr = [test1, test2]\r
+    print TestObj(2) in testarr\r
+    print TestObj(2) == test2\r
+    \r
index b9512a1b4dbda424ad82e72c1aba02b5c24289d6..0a393fec60ca724f475a9fdf13a20c1df07768c4 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Standardized Error Hanlding infrastructures.\r
 #\r
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -81,6 +81,9 @@ EOT_ERROR = 0xF005
 DDC_ERROR = 0xF009\r
 WARNING_AS_ERROR = 0xF006\r
 MIGRATION_ERROR = 0xF010\r
+PCD_VALIDATION_INFO_ERROR = 0xF011\r
+PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012\r
+PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013\r
 ABORT_ERROR = 0xFFFE\r
 UNKNOWN_ERROR = 0xFFFF\r
 \r
index 6d66523847479543dae0f0230aade83037d4c21c..b4abc88e3ec09d154c89f67b4e065c636e4d74df 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define common static strings used by INF/DEC/DSC files\r
 #\r
-# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
@@ -398,6 +398,7 @@ TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
 TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'\r
 TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'\r
 TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION'\r
+TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION = 'PCD_VAR_CHECK_GENERATION'\r
 TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'\r
 TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'\r
 TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'\r
index 96ee30b2bfe8683591ff7ce982faeed7b91f560b..79073e2fef7b7e7cdb0065a48e8318da3cc399a4 100644 (file)
@@ -1508,15 +1508,17 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
         return [VpdOffset, Size, Value], IsValid, 2\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
-        Guid = Offset = Value = ''\r
+        Guid = Offset = Value = Attribute = ''\r
         if len(FieldList) > 1:\r
             Guid = FieldList[1]\r
         if len(FieldList) > 2:\r
             Offset = FieldList[2]\r
         if len(FieldList) > 3:\r
             Value = FieldList[3]\r
-        IsValid = (3 <= len(FieldList) <= 4)\r
-        return [HiiString, Guid, Offset, Value], IsValid, 3\r
+        if len(FieldList) > 4:\r
+            Attribute = FieldList[4]\r
+        IsValid = (3 <= len(FieldList) <= 5)\r
+        return [HiiString, Guid, Offset, Value, Attribute], IsValid, 3\r
     return [], False, 0\r
 \r
 ## AnalyzePcdData\r
diff --git a/BaseTools/Source/Python/Common/RangeExpression.py b/BaseTools/Source/Python/Common/RangeExpression.py
new file mode 100644 (file)
index 0000000..5da4a47
--- /dev/null
@@ -0,0 +1,737 @@
+# # @file\r
+# This file is used to parse and evaluate range expression in Pcd declaration.\r
+#\r
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.    The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+# # Import Modules\r
+#\r
+from Common.GlobalData import *\r
+from CommonDataClass.Exceptions import BadExpression\r
+from CommonDataClass.Exceptions import WrnExpression\r
+import uuid\r
+\r
+ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'\r
+ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'\r
+ERR_MATCH = 'No matching right parenthesis.'\r
+ERR_STRING_TOKEN = 'Bad string token: [%s].'\r
+ERR_MACRO_TOKEN = 'Bad macro token: [%s].'\r
+ERR_EMPTY_TOKEN = 'Empty token is not allowed.'\r
+ERR_PCD_RESOLVE = 'PCD token cannot be resolved: [%s].'\r
+ERR_VALID_TOKEN = 'No more valid token found from rest of string: [%s].'\r
+ERR_EXPR_TYPE = 'Different types found in expression.'\r
+ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]'\r
+ERR_REL_NOT_IN = 'Expect "IN" after "not" operator.'\r
+WRN_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'\r
+WRN_EQCMP_STR_OTHERS = '== Comparison between Operand of string type and Boolean/Number Type always return False.'\r
+WRN_NECMP_STR_OTHERS = '!= Comparison between Operand of string type and Boolean/Number Type always return True.'\r
+ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Number Type is not allowed: [%s].'\r
+ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'\r
+ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'\r
+ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'\r
+ERR_EMPTY_EXPR = 'Empty expression is not allowed.'\r
+ERR_IN_OPERAND = 'Macro after IN operator can only be: $(FAMILY), $(ARCH), $(TOOL_CHAIN_TAG) and $(TARGET).'\r
+\r
+def MaxOfType(DataType):\r
+    if DataType == 'UINT8':\r
+        return int('0xFF', 16)\r
+    if DataType == 'UINT16':\r
+        return int('0xFFFF', 16)\r
+    if DataType == 'UINT32':\r
+        return int('0xFFFFFFFF', 16)\r
+    if DataType == 'UINT64':\r
+        return int('0xFFFFFFFFFFFFFFFF', 16)\r
+\r
+class RangeObject(object):\r
+    def __init__(self, start, end, empty = False):\r
+        \r
+        if int(start) < int(end):\r
+            self.start = int(start)\r
+            self.end = int(end)\r
+        else:\r
+            self.start = int(end)\r
+            self.end = int(start)\r
+        self.empty = empty\r
+\r
+class RangeContainer(object):\r
+    def __init__(self):\r
+        self.rangelist = []\r
+        \r
+    def push(self, RangeObject):\r
+        self.rangelist.append(RangeObject)\r
+        self.rangelist = sorted(self.rangelist, key = lambda rangeobj : rangeobj.start)\r
+        self.merge()\r
+        \r
+    def pop(self):\r
+        for item in self.rangelist:\r
+            yield item\r
+   \r
+    def __clean__(self):   \r
+        newrangelist = []\r
+        for rangeobj in self.rangelist:\r
+            if rangeobj.empty == True:\r
+                continue\r
+            else:\r
+                newrangelist.append(rangeobj)\r
+        self.rangelist = newrangelist      \r
+    def merge(self):\r
+        self.__clean__()\r
+        for i in range(0, len(self.rangelist) - 1):\r
+            if self.rangelist[i + 1].start > self.rangelist[i].end:\r
+                continue\r
+            else:\r
+                self.rangelist[i + 1].start = self.rangelist[i].start\r
+                self.rangelist[i + 1].end = self.rangelist[i + 1].end > self.rangelist[i].end and self.rangelist[i + 1].end or self.rangelist[i].end \r
+                self.rangelist[i].empty = True\r
+\r
+        self.__clean__()\r
+        \r
+    def dump(self):\r
+        print "----------------------"\r
+        rangelist = ""\r
+        for object in self.rangelist:\r
+            rangelist = rangelist + "[%d , %d]" % (object.start, object.end)\r
+        print rangelist\r
+        \r
+        \r
+class XOROperatorObject(object):   \r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable): \r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "XOR ..."\r
+            raise BadExpression(ERR_SNYTAX % Expr)\r
+        rangeId = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(0, int(Operand) - 1))\r
+        rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))\r
+        SymbolTable[rangeId] = rangeContainer\r
+        return rangeId\r
+\r
+class LEOperatorObject(object):\r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable): \r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "LE ..."\r
+            raise BadExpression(ERR_SNYTAX % Expr)\r
+        rangeId1 = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(0, int(Operand)))\r
+        SymbolTable[rangeId1] = rangeContainer\r
+        return rangeId1\r
+class LTOperatorObject(object):\r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable):\r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "LT ..." \r
+            raise BadExpression(ERR_SNYTAX % Expr) \r
+        rangeId1 = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(0, int(Operand) - 1))\r
+        SymbolTable[rangeId1] = rangeContainer\r
+        return rangeId1   \r
+\r
+class GEOperatorObject(object):\r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable): \r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "GE ..."\r
+            raise BadExpression(ERR_SNYTAX % Expr)\r
+        rangeId1 = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(int(Operand), MaxOfType(DataType)))\r
+        SymbolTable[rangeId1] = rangeContainer\r
+        return rangeId1   \r
+      \r
+class GTOperatorObject(object):\r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable): \r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "GT ..."\r
+            raise BadExpression(ERR_SNYTAX % Expr)\r
+        rangeId1 = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))\r
+        SymbolTable[rangeId1] = rangeContainer\r
+        return rangeId1   \r
+    \r
+class EQOperatorObject(object):\r
+    def __init__(self):     \r
+        pass\r
+    def Calculate(self, Operand, DataType, SymbolTable): \r
+        if type(Operand) == type('') and not Operand.isalnum():\r
+            Expr = "EQ ..."\r
+            raise BadExpression(ERR_SNYTAX % Expr)\r
+        rangeId1 = str(uuid.uuid1())\r
+        rangeContainer = RangeContainer()\r
+        rangeContainer.push(RangeObject(int(Operand) , int(Operand)))\r
+        SymbolTable[rangeId1] = rangeContainer\r
+        return rangeId1   \r
+    \r
+def GetOperatorObject(Operator):\r
+    if Operator == '>':\r
+        return GTOperatorObject()\r
+    elif Operator == '>=':\r
+        return GEOperatorObject()\r
+    elif Operator == '<':\r
+        return LTOperatorObject()\r
+    elif Operator == '<=':\r
+        return LEOperatorObject()\r
+    elif Operator == '==':\r
+        return EQOperatorObject()\r
+    elif Operator == '^':\r
+        return XOROperatorObject()\r
+    else:\r
+        raise BadExpression("Bad Operator")\r
+\r
+class RangeExpression(object):\r
+    # Logical operator mapping\r
+    LogicalOperators = {\r
+        '&&' : 'and', '||' : 'or',\r
+        '!'  : 'not', 'AND': 'and',\r
+        'OR' : 'or' , 'NOT': 'not',\r
+        'XOR': '^'  , 'xor': '^',\r
+        'EQ' : '==' , 'NE' : '!=',\r
+        'GT' : '>'  , 'LT' : '<',\r
+        'GE' : '>=' , 'LE' : '<=',\r
+        'IN' : 'in'\r
+    }\r
+\r
+    NonLetterOpLst = ['+', '-', '&', '|', '^', '!', '=', '>', '<']\r
+\r
+    PcdPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*$')\r
+    HexPattern = re.compile(r'0[xX][0-9a-fA-F]+')\r
+    RegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')\r
+    ExRegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')\r
+    \r
+    SymbolPattern = re.compile("("\r
+                                 "\$\([A-Z][A-Z0-9_]*\)|\$\(\w+\.\w+\)|\w+\.\w+|"\r
+                                 "&&|\|\||!(?!=)|"\r
+                                 "(?<=\W)AND(?=\W)|(?<=\W)OR(?=\W)|(?<=\W)NOT(?=\W)|(?<=\W)XOR(?=\W)|"\r
+                                 "(?<=\W)EQ(?=\W)|(?<=\W)NE(?=\W)|(?<=\W)GT(?=\W)|(?<=\W)LT(?=\W)|(?<=\W)GE(?=\W)|(?<=\W)LE(?=\W)"\r
+                               ")")\r
+    \r
+    RangePattern = re.compile(r'[0-9]+ - [0-9]+')\r
+\r
+    def preProcessRangeExpr(self, expr):\r
+        # convert hex to int\r
+        # convert interval to object index. ex. 1 - 10 to a GUID\r
+        expr = expr.strip()\r
+        NumberDict = {}\r
+        for HexNumber in self.HexPattern.findall(expr):\r
+            Number = str(int(HexNumber, 16))\r
+            NumberDict[HexNumber] = Number\r
+        for HexNum in NumberDict:\r
+            expr = expr.replace(HexNum, NumberDict[HexNum])\r
+        \r
+        rangedict = {}    \r
+        for validrange in self.RangePattern.findall(expr):\r
+            start, end = validrange.split(" - ")\r
+            start = start.strip()\r
+            end = end.strip()\r
+            rangeid = str(uuid.uuid1())\r
+            rangeContainer = RangeContainer()\r
+            rangeContainer.push(RangeObject(start, end))\r
+            self.operanddict[str(rangeid)] = rangeContainer\r
+            rangedict[validrange] = str(rangeid)\r
+            \r
+        for validrange in rangedict:\r
+            expr = expr.replace(validrange, rangedict[validrange])\r
+         \r
+        self._Expr = expr    \r
+        return expr\r
+            \r
+        \r
+    def EvalRange(self, Operator, Oprand):\r
+\r
+        operatorobj = GetOperatorObject(Operator)\r
+        return operatorobj.Calculate(Oprand, self.PcdDataType, self.operanddict)\r
+        \r
+    def Rangeintersection(self, Oprand1, Oprand2):\r
+        rangeContainer1 = self.operanddict[Oprand1]\r
+        rangeContainer2 = self.operanddict[Oprand2]\r
+        rangeContainer = RangeContainer()\r
+        for range1 in rangeContainer1.pop():\r
+            for range2 in rangeContainer2.pop():\r
+                if range1.start >= range2.start:\r
+                    start = range1.start\r
+                    end = range1.end\r
+                    range1.start = range2.start\r
+                    range1.end = range2.end\r
+                    range2.start = start\r
+                    range2.end = end\r
+                if range1.empty:\r
+                    rangeid = str(uuid.uuid1())\r
+                    rangeContainer.push(RangeObject(0, 0, True))\r
+                if range1.end < range2.start:\r
+                    rangeid = str(uuid.uuid1())\r
+                    rangeContainer.push(RangeObject(0, 0, True))\r
+                elif range1.end == range2.start:\r
+                    rangeid = str(uuid.uuid1())\r
+                    rangeContainer.push(RangeObject(range1.end, range1.end))\r
+                elif range1.end <= range2.end and range1.end > range2.start:\r
+                    rangeid = str(uuid.uuid1())\r
+                    rangeContainer.push(RangeObject(range2.start, range1.end))\r
+                elif range1.end >= range2.end:\r
+                    rangeid = str(uuid.uuid1())\r
+                    rangeContainer.push(RangeObject(range2.start, range2.end))\r
+        \r
+        self.operanddict[rangeid] = rangeContainer\r
+#        rangeContainer.dump()\r
+        return rangeid\r
+            \r
+    def Rangecollections(self, Oprand1, Oprand2):\r
+\r
+        rangeContainer1 = self.operanddict[Oprand1]\r
+        rangeContainer2 = self.operanddict[Oprand2]\r
+        rangeContainer = RangeContainer()\r
+        \r
+        for rangeobj in rangeContainer2.pop():\r
+            rangeContainer.push(rangeobj)\r
+        for rangeobj in rangeContainer1.pop():\r
+            rangeContainer.push(rangeobj)\r
+        \r
+        rangeid = str(uuid.uuid1())\r
+        self.operanddict[rangeid] = rangeContainer\r
+        \r
+#        rangeContainer.dump()\r
+        return rangeid\r
+        \r
+            \r
+    def NegtiveRange(self, Oprand1):\r
+        rangeContainer1 = self.operanddict[Oprand1]\r
+        \r
+        \r
+        rangeids = []\r
+        \r
+        for rangeobj in rangeContainer1.pop():\r
+            rangeContainer = RangeContainer()\r
+            rangeid = str(uuid.uuid1())\r
+            if rangeobj.empty:\r
+                rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))\r
+            else:\r
+                if rangeobj.start > 0:\r
+                    rangeContainer.push(RangeObject(0, rangeobj.start - 1))\r
+                if rangeobj.end < MaxOfType(self.PcdDataType):\r
+                    rangeContainer.push(RangeObject(rangeobj.end + 1, MaxOfType(self.PcdDataType)))\r
+            self.operanddict[rangeid] = rangeContainer\r
+            rangeids.append(rangeid)\r
+\r
+        if len(rangeids) == 0:\r
+            rangeContainer = RangeContainer()\r
+            rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))\r
+            rangeid = str(uuid.uuid1())\r
+            self.operanddict[rangeid] = rangeContainer\r
+            return rangeid\r
+\r
+        if len(rangeids) == 1:\r
+            return rangeids[0]\r
+\r
+        re = self.Rangeintersection(rangeids[0], rangeids[1])\r
+        for i in range(2, len(rangeids)):\r
+            re = self.Rangeintersection(re, rangeids[i])\r
+            \r
+        rangeid2 = str(uuid.uuid1())\r
+        self.operanddict[rangeid2] = self.operanddict[re]\r
+        return rangeid2\r
+        \r
+    def Eval(self, Operator, Oprand1, Oprand2 = None):\r
+        \r
+        if Operator in ["!", "NOT", "not"]:\r
+            if not self.RegGuidPattern.match(Oprand1.strip()):\r
+                raise BadExpression(ERR_STRING_EXPR % Operator)\r
+            return self.NegtiveRange(Oprand1)\r
+        else:\r
+            if Operator in ["==", ">=", "<=", ">", "<", '^']:\r
+                return self.EvalRange(Operator, Oprand1)\r
+            elif Operator == 'and' :\r
+                if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):\r
+                    raise BadExpression(ERR_STRING_EXPR % Operator)\r
+                return self.Rangeintersection(Oprand1, Oprand2)    \r
+            elif Operator == 'or':\r
+                if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):\r
+                    raise BadExpression(ERR_STRING_EXPR % Operator)\r
+                return self.Rangecollections(Oprand1, Oprand2)\r
+            else:\r
+                raise BadExpression(ERR_STRING_EXPR % Operator)\r
+\r
+\r
+    def __init__(self, Expression, PcdDataType, SymbolTable = {}):\r
+        self._NoProcess = False\r
+        if type(Expression) != type(''):\r
+            self._Expr = Expression\r
+            self._NoProcess = True\r
+            return\r
+\r
+        self._Expr = Expression.strip()\r
+\r
+        if not self._Expr.strip():\r
+            raise BadExpression(ERR_EMPTY_EXPR)\r
+\r
+        #\r
+        # The symbol table including PCD and macro mapping\r
+        #\r
+        self._Symb = SymbolTable\r
+        self._Symb.update(self.LogicalOperators)\r
+        self._Idx = 0\r
+        self._Len = len(self._Expr)\r
+        self._Token = ''\r
+        self._WarnExcept = None\r
+        \r
+\r
+        # Literal token without any conversion\r
+        self._LiteralToken = ''\r
+        \r
+        # store the operand object\r
+        self.operanddict = {}\r
+        # The Pcd max value depends on PcdDataType\r
+        self.PcdDataType = PcdDataType\r
+\r
+    # Public entry for this class\r
+    #   @param RealValue: False: only evaluate if the expression is true or false, used for conditional expression\r
+    #                     True : return the evaluated str(value), used for PCD value\r
+    #\r
+    #   @return: True or False if RealValue is False\r
+    #            Evaluated value of string format if RealValue is True\r
+    #\r
+    def __call__(self, RealValue = False, Depth = 0):\r
+        if self._NoProcess:\r
+            return self._Expr\r
+\r
+        self._Depth = Depth\r
+\r
+        self._Expr = self._Expr.strip()\r
+        \r
+        self.preProcessRangeExpr(self._Expr)\r
+        \r
+        # check if the expression does not need to evaluate\r
+        if RealValue and Depth == 0:\r
+            self._Token = self._Expr\r
+            if self.ExRegGuidPattern.match(self._Expr):\r
+                return [self.operanddict[self._Expr] ]\r
+\r
+            self._Idx = 0\r
+            self._Token = ''\r
+\r
+        Val = self._OrExpr()\r
+        RealVal = Val\r
+        \r
+        RangeIdList = RealVal.split("or")\r
+        RangeList = []\r
+        for rangeid in RangeIdList:\r
+            RangeList.append(self.operanddict[rangeid.strip()])\r
+            \r
+        return RangeList\r
+\r
+    # Template function to parse binary operators which have same precedence\r
+    # Expr [Operator Expr]*\r
+    def _ExprFuncTemplate(self, EvalFunc, OpLst):\r
+        Val = EvalFunc()\r
+        while self._IsOperator(OpLst):\r
+            Op = self._Token\r
+            try:\r
+                Val = self.Eval(Op, Val, EvalFunc())\r
+            except WrnExpression, Warn:\r
+                self._WarnExcept = Warn\r
+                Val = Warn.result\r
+        return Val\r
+\r
+    # A [|| B]*\r
+    def _OrExpr(self):\r
+        return self._ExprFuncTemplate(self._AndExpr, ["OR", "or"])\r
+\r
+    # A [&& B]*\r
+    def _AndExpr(self):\r
+        return self._ExprFuncTemplate(self._NeExpr, ["AND", "and"])\r
+\r
+    def _NeExpr(self):\r
+        Val = self._RelExpr()\r
+        while self._IsOperator([ "!=", "NOT", "not"]):\r
+            Op = self._Token\r
+            if Op in ["!", "NOT", "not"]:\r
+                if not self._IsOperator(["IN", "in"]):\r
+                    raise BadExpression(ERR_REL_NOT_IN)\r
+                Op += ' ' + self._Token\r
+            try:\r
+                Val = self.Eval(Op, Val, self._RelExpr())\r
+            except WrnExpression, Warn:\r
+                self._WarnExcept = Warn\r
+                Val = Warn.result\r
+        return Val\r
+\r
+    # [!]*A\r
+    def _RelExpr(self):\r
+        if self._IsOperator(["NOT" , "LE", "GE", "LT", "GT", "EQ", "XOR"]):\r
+            Token = self._Token\r
+            Val = self._NeExpr()\r
+            try:\r
+                return self.Eval(Token, Val)\r
+            except WrnExpression, Warn:\r
+                self._WarnExcept = Warn\r
+                return Warn.result\r
+        return self._IdenExpr()\r
+\r
+    # Parse identifier or encapsulated expression\r
+    def _IdenExpr(self):\r
+        Tk = self._GetToken()\r
+        if Tk == '(':\r
+            Val = self._OrExpr()\r
+            try:\r
+                # _GetToken may also raise BadExpression\r
+                if self._GetToken() != ')':\r
+                    raise BadExpression(ERR_MATCH)\r
+            except BadExpression:\r
+                raise BadExpression(ERR_MATCH)\r
+            return Val\r
+        return Tk\r
+\r
+    # Skip whitespace or tab\r
+    def __SkipWS(self):\r
+        for Char in self._Expr[self._Idx:]:\r
+            if Char not in ' \t':\r
+                break\r
+            self._Idx += 1\r
+\r
+    # Try to convert string to number\r
+    def __IsNumberToken(self):\r
+        Radix = 10\r
+        if self._Token.lower()[0:2] == '0x' and len(self._Token) > 2:\r
+            Radix = 16\r
+        try:\r
+            self._Token = int(self._Token, Radix)\r
+            return True\r
+        except ValueError:\r
+            return False\r
+        except TypeError:\r
+            return False\r
+\r
+    # Parse array: {...}\r
+    def __GetArray(self):\r
+        Token = '{'\r
+        self._Idx += 1\r
+        self.__GetNList(True)\r
+        Token += self._LiteralToken\r
+        if self._Idx >= self._Len or self._Expr[self._Idx] != '}':\r
+            raise BadExpression(ERR_ARRAY_TOKEN % Token)\r
+        Token += '}'\r
+\r
+        # All whitespace and tabs in array are already stripped.\r
+        IsArray = IsGuid = False\r
+        if len(Token.split(',')) == 11 and len(Token.split(',{')) == 2 \\r
+            and len(Token.split('},')) == 1:\r
+            HexLen = [11, 6, 6, 5, 4, 4, 4, 4, 4, 4, 6]\r
+            HexList = Token.split(',')\r
+            if HexList[3].startswith('{') and \\r
+                not [Index for Index, Hex in enumerate(HexList) if len(Hex) > HexLen[Index]]:\r
+                IsGuid = True\r
+        if Token.lstrip('{').rstrip('}').find('{') == -1:\r
+            if not [Hex for Hex in Token.lstrip('{').rstrip('}').split(',') if len(Hex) > 4]:\r
+                IsArray = True\r
+        if not IsArray and not IsGuid:\r
+            raise BadExpression(ERR_ARRAY_TOKEN % Token)\r
+        self._Idx += 1\r
+        self._Token = self._LiteralToken = Token\r
+        return self._Token\r
+\r
+    # Parse string, the format must be: "..."\r
+    def __GetString(self):\r
+        Idx = self._Idx\r
+\r
+        # Skip left quote\r
+        self._Idx += 1\r
+\r
+        # Replace escape \\\", \"\r
+        Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace('\\\"', '\\\'')\r
+        for Ch in Expr:\r
+            self._Idx += 1\r
+            if Ch == '"':\r
+                break\r
+        self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]\r
+        if not self._Token.endswith('"'):\r
+            raise BadExpression(ERR_STRING_TOKEN % self._Token)\r
+        self._Token = self._Token[1:-1]\r
+        return self._Token\r
+\r
+    # Get token that is comprised by alphanumeric, underscore or dot(used by PCD)\r
+    # @param IsAlphaOp: Indicate if parsing general token or script operator(EQ, NE...)\r
+    def __GetIdToken(self, IsAlphaOp = False):\r
+        IdToken = ''\r
+        for Ch in self._Expr[self._Idx:]:\r
+            if not self.__IsIdChar(Ch):\r
+                break\r
+            self._Idx += 1\r
+            IdToken += Ch\r
+\r
+        self._Token = self._LiteralToken = IdToken\r
+        if not IsAlphaOp:\r
+            self.__ResolveToken()\r
+        return self._Token\r
+\r
+    # Try to resolve token\r
+    def __ResolveToken(self):\r
+        if not self._Token:\r
+            raise BadExpression(ERR_EMPTY_TOKEN)\r
+\r
+        # PCD token\r
+        if self.PcdPattern.match(self._Token):\r
+            if self._Token not in self._Symb:\r
+                Ex = BadExpression(ERR_PCD_RESOLVE % self._Token)\r
+                Ex.Pcd = self._Token\r
+                raise Ex\r
+            self._Token = RangeExpression(self._Symb[self._Token], self._Symb)(True, self._Depth + 1)\r
+            if type(self._Token) != type(''):\r
+                self._LiteralToken = hex(self._Token)\r
+                return\r
+\r
+        if self._Token.startswith('"'):\r
+            self._Token = self._Token[1:-1]\r
+        elif self._Token in ["FALSE", "false", "False"]:\r
+            self._Token = False\r
+        elif self._Token in ["TRUE", "true", "True"]:\r
+            self._Token = True\r
+        else:\r
+            self.__IsNumberToken()\r
+\r
+    def __GetNList(self, InArray = False):\r
+        self._GetSingleToken()\r
+        if not self.__IsHexLiteral():\r
+            if InArray:\r
+                raise BadExpression(ERR_ARRAY_ELE % self._Token)\r
+            return self._Token\r
+\r
+        self.__SkipWS()\r
+        Expr = self._Expr[self._Idx:]\r
+        if not Expr.startswith(','):\r
+            return self._Token\r
+\r
+        NList = self._LiteralToken\r
+        while Expr.startswith(','):\r
+            NList += ','\r
+            self._Idx += 1\r
+            self.__SkipWS()\r
+            self._GetSingleToken()\r
+            if not self.__IsHexLiteral():\r
+                raise BadExpression(ERR_ARRAY_ELE % self._Token)\r
+            NList += self._LiteralToken\r
+            self.__SkipWS()\r
+            Expr = self._Expr[self._Idx:]\r
+        self._Token = self._LiteralToken = NList\r
+        return self._Token\r
+\r
+    def __IsHexLiteral(self):\r
+        if self._LiteralToken.startswith('{') and \\r
+            self._LiteralToken.endswith('}'):\r
+            return True\r
+\r
+        if self.HexPattern.match(self._LiteralToken):\r
+            Token = self._LiteralToken[2:]\r
+            Token = Token.lstrip('0')\r
+            if not Token:\r
+                self._LiteralToken = '0x0'\r
+            else:\r
+                self._LiteralToken = '0x' + Token.lower()\r
+            return True\r
+        return False\r
+\r
+    def _GetToken(self):\r
+        return self.__GetNList()\r
+\r
+    @staticmethod\r
+    def __IsIdChar(Ch):\r
+        return Ch in '._/:' or Ch.isalnum()\r
+\r
+    # Parse operand\r
+    def _GetSingleToken(self):\r
+        self.__SkipWS()\r
+        Expr = self._Expr[self._Idx:]\r
+        if Expr.startswith('L"'):\r
+            # Skip L\r
+            self._Idx += 1\r
+            UStr = self.__GetString()\r
+            self._Token = 'L"' + UStr + '"'\r
+            return self._Token\r
+\r
+        self._Token = ''\r
+        if Expr:\r
+            Ch = Expr[0]\r
+            Match = self.RegGuidPattern.match(Expr)\r
+            if Match and not Expr[Match.end():Match.end() + 1].isalnum() \\r
+                and Expr[Match.end():Match.end() + 1] != '_':\r
+                self._Idx += Match.end()\r
+                self._Token = Expr[0:Match.end()]\r
+                return self._Token\r
+            elif self.__IsIdChar(Ch):\r
+                return self.__GetIdToken()\r
+            elif Ch == '(' or Ch == ')':\r
+                self._Idx += 1\r
+                self._Token = Ch\r
+                return self._Token\r
+\r
+        raise BadExpression(ERR_VALID_TOKEN % Expr)\r
+\r
+    # Parse operator\r
+    def _GetOperator(self):\r
+        self.__SkipWS()\r
+        LegalOpLst = ['&&', '||', '!=', '==', '>=', '<='] + self.NonLetterOpLst\r
+\r
+        self._Token = ''\r
+        Expr = self._Expr[self._Idx:]\r
+\r
+        # Reach end of expression\r
+        if not Expr:\r
+            return ''\r
+\r
+        # Script operator: LT, GT, LE, GE, EQ, NE, and, or, xor, not\r
+        if Expr[0].isalpha():\r
+            return self.__GetIdToken(True)\r
+\r
+        # Start to get regular operator: +, -, <, > ...\r
+        if Expr[0] not in self.NonLetterOpLst:\r
+            return ''\r
+\r
+        OpToken = ''\r
+        for Ch in Expr:\r
+            if Ch in self.NonLetterOpLst:\r
+                if '!' == Ch and OpToken:\r
+                    break\r
+                self._Idx += 1\r
+                OpToken += Ch\r
+            else:\r
+                break\r
+\r
+        if OpToken not in LegalOpLst:\r
+            raise BadExpression(ERR_OPERATOR_UNSUPPORT % OpToken)\r
+        self._Token = OpToken\r
+        return OpToken\r
+\r
+    # Check if current token matches the operators given from OpList\r
+    def _IsOperator(self, OpList):\r
+        Idx = self._Idx\r
+        self._GetOperator()\r
+        if self._Token in OpList:\r
+            if self._Token in self.LogicalOperators:\r
+                self._Token = self.LogicalOperators[self._Token]\r
+            return True\r
+        self._Idx = Idx\r
+        return False\r
+\r
+\r
+    \r
+    \r
+    \r
+    \r
+\r
+\r
+\r
+\r
+#    UTRangeList()\r
diff --git a/BaseTools/Source/Python/Common/VariableAttributes.py b/BaseTools/Source/Python/Common/VariableAttributes.py
new file mode 100644 (file)
index 0000000..a2e22ca
--- /dev/null
@@ -0,0 +1,57 @@
+# # @file\r
+# \r
+# This file is used to handle the variable attributes and property information\r
+#\r
+#\r
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+   \r
+class VariableAttributes(object):\r
+    EFI_VARIABLE_NON_VOLATILE = 0x00000001\r
+    EFI_VARIABLE_BOOTSERVICE_ACCESS = 0x00000002\r
+    EFI_VARIABLE_RUNTIME_ACCESS = 0x00000004\r
+    VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY = 0x00000001\r
+    VarAttributesMap = {\r
+                     "NV":EFI_VARIABLE_NON_VOLATILE,\r
+                     "BS":EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                     "RT":EFI_VARIABLE_RUNTIME_ACCESS,\r
+                     "RO":VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY\r
+                     }\r
+    \r
+    def __init__(self):\r
+        pass\r
+    \r
+    @staticmethod\r
+    def GetVarAttributes(var_attr_str):\r
+        VarAttr = 0x00000000\r
+        VarProp = 0x00000000\r
+        \r
+        attr_list = var_attr_str.split(",")\r
+        for attr in attr_list:\r
+            attr = attr.strip()\r
+            if attr == 'RO':\r
+                VarProp = VariableAttributes.VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY\r
+            else:\r
+                VarAttr = VarAttr | VariableAttributes.VarAttributesMap.get(attr, 0x00000000)   \r
+        return VarAttr, VarProp\r
+    @staticmethod\r
+    def ValidateVarAttributes(var_attr_str):\r
+        if not var_attr_str:\r
+            return True, ""\r
+        attr_list = var_attr_str.split(",")\r
+        attr_temp = []\r
+        for attr in attr_list:\r
+            attr = attr.strip()\r
+            attr_temp.append(attr)\r
+            if attr not in VariableAttributes.VarAttributesMap:\r
+                return False, "The variable attribute %s is not support to be specified in dsc file. Supported variable attribute are ['BS','NV','RT','RO'] "\r
+        if 'RT' in attr_temp and 'BS' not in attr_temp:\r
+            return False, "the RT attribute need the BS attribute to be present"\r
+        return True, ""\r
index bb4b434af8f03c656f04f1bd8571ed6293e295e6..5e908a6edf2ae75618622bb943c1c89ecb914631 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define common items of class object\r
 #\r
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.    The full text of the license may be found at\r
@@ -270,7 +270,7 @@ class PpiClass(GuidProtocolPpiCommonClass):
 #\r
 class SkuInfoClass(object):\r
     def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', \r
-                 HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = ''):\r
+                 HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = '', VariableAttribute = ''):\r
         self.SkuIdName = SkuIdName\r
         self.SkuId = SkuId\r
         \r
@@ -282,6 +282,7 @@ class SkuInfoClass(object):
         self.VariableGuidValue = VariableGuidValue\r
         self.VariableOffset = VariableOffset\r
         self.HiiDefaultValue = HiiDefaultValue\r
+        self.VariableAttribute = VariableAttribute\r
         \r
         #\r
         # Used by Vpd\r
index 8b98f164fd0847e4a3b4304380f7d4c5df4bd509..ea26e5e5a137c212487d122a0e3f906e2ec25c87 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define each component of the build database\r
 #\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -44,7 +44,7 @@ from Common.BuildToolError import *
 # @var Phase:                To store value for Phase, default is "DXE"\r
 #\r
 class PcdClassObject(object):\r
-    def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False, GuidValue = None):\r
+    def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False, GuidValue = None, validateranges = [], validlists = [], expressions = []):\r
         self.TokenCName = Name\r
         self.TokenSpaceGuidCName = Guid\r
         self.TokenSpaceGuidValue = GuidValue\r
@@ -59,6 +59,9 @@ class PcdClassObject(object):
         self.IsOverrided = IsOverrided\r
         self.IsFromBinaryInf = False\r
         self.IsFromDsc = False\r
+        self.validateranges = validateranges\r
+        self.validlists = validlists\r
+        self.expressions = expressions\r
         \r
     ## Convert the class to a string\r
     #\r
index f96c73c1db5d3ec257316b98db225f0308b16862..eb02b664a6362ca21a64d9ce229ccd9aa3c46774 100644 (file)
@@ -376,7 +376,8 @@ class MetaFileParser(object):
                 File=self.MetaFile,\r
                 Line=self._LineIndex + 1\r
                 )\r
-\r
+    def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
+        return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)\r
     def _GetMacros(self):\r
         Macros = {}\r
         Macros.update(self._FileLocalMacros)\r
@@ -814,6 +815,7 @@ class DscParser(MetaFileParser):
         "PLATFORM_VERSION",\r
         "SKUID_IDENTIFIER",\r
         "PCD_INFO_GENERATION",\r
+        "PCD_VAR_CHECK_GENERATION",\r
         "SUPPORTED_ARCHITECTURES",\r
         "BUILD_TARGETS",\r
         "OUTPUT_DIRECTORY",\r
index 607225a0ef6028059a21fada8fdf872cedff6d15..89a12cd228018398c1edc1d5cf8d11499cca0e51 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create/update/query/erase a meta file table\r
 #\r
-# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -225,6 +225,26 @@ class PackageTable(MetaFileTable):
         SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
         return self.Exec(SqlCommand)\r
 \r
+    def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
+        SqlCommand = "select Value1 from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName)\r
+        self.Cur.execute(SqlCommand)\r
+        validateranges = []\r
+        validlists = []\r
+        expressions = []\r
+        for row in self.Cur:\r
+            comment = row[0]\r
+            comment = comment.strip("#")\r
+            comment = comment.strip()\r
+            if comment.startswith("@ValidRange"):\r
+                comment = comment.replace("@ValidRange", "", 1)\r
+                validateranges.append(comment.split("|")[1].strip())\r
+            if comment.startswith("@ValidList"):\r
+                comment = comment.replace("@ValidList", "", 1)\r
+                validlists.append(comment.split("|")[1].strip())\r
+            if comment.startswith("@Expression"):\r
+                comment = comment.replace("@Expression", "", 1)\r
+                expressions.append(comment.split("|")[1].strip())\r
+        return set(validateranges), set(validlists), set(expressions)\r
 ## Python class representation of table storing platform data\r
 class PlatformTable(MetaFileTable):\r
     _COLUMN_ = '''\r
index 83f730e62913675e4e8d6dbb081579889de33e15..9f79f74e8f419cc0d01527e0b73d3ecc4831cec5 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
-# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -38,7 +38,7 @@ from Common.Misc import AnalyzeDscPcd
 from Common.Misc import ProcessDuplicatedInf\r
 import re\r
 from Common.Parsing import IsValidWord\r
-\r
+from Common.VariableAttributes import VariableAttributes\r
 import Common.GlobalData as GlobalData\r
 \r
 ## Platform build information from DSC file\r
@@ -133,6 +133,7 @@ class DscBuildData(PlatformBuildClassObject):
         self._SkuName           = None\r
         self._SkuIdentifier     = None\r
         self._PcdInfoFlag       = None\r
+        self._VarCheckFlag = None\r
         self._FlashDefinition   = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
@@ -233,6 +234,8 @@ class DscBuildData(PlatformBuildClassObject):
                 self._SkuIdentifier = Record[2]\r
             elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
                 self._PcdInfoFlag = Record[2]\r
+            elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
+                self._VarCheckFlag = Record[2]\r
             elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
                 try:\r
                     self._LoadFixAddress = int (Record[2], 0)\r
@@ -352,6 +355,13 @@ class DscBuildData(PlatformBuildClassObject):
             return True\r
         else:\r
             return False\r
+    def _GetVarCheckFlag(self):  \r
+        if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
+            return False\r
+        elif self._VarCheckFlag.upper() == 'TRUE':\r
+            return True\r
+        else:\r
+            return False\r
             \r
     def _GetSkuIdentifier(self):\r
         if self._SkuName:\r
@@ -898,6 +908,17 @@ class DscBuildData(PlatformBuildClassObject):
                \r
         return Pcds\r
 \r
+    def CompareVarAttr(self, Attr1, Attr2):\r
+        if not Attr1 or not Attr2:  # for empty string\r
+            return True\r
+        Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
+        Attr1Set = set(Attr1s)\r
+        Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
+        Attr2Set = set(Attr2s)\r
+        if Attr2Set == Attr1Set:\r
+            return True\r
+        else:\r
+            return False\r
     ## Retrieve dynamic HII PCD settings\r
     #\r
     #   @param  Type    PCD type\r
@@ -907,6 +928,7 @@ class DscBuildData(PlatformBuildClassObject):
     def _GetDynamicHiiPcd(self, Type):\r
         \r
         SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        VariableAttrs = {}\r
         \r
         Pcds = sdict()\r
         #\r
@@ -931,8 +953,12 @@ class DscBuildData(PlatformBuildClassObject):
             Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            VariableName, VariableGuid, VariableOffset, DefaultValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
             \r
+            rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
+            if not rt:\r
+                EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
+                        ExtraData = "[%s]" % VarAttribute)\r
             ExceedMax = False\r
             FormatCorrect = True\r
             if VariableOffset.isdigit():\r
@@ -955,8 +981,14 @@ class DscBuildData(PlatformBuildClassObject):
             \r
             if ExceedMax:\r
                 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
+            if (VariableName, VariableGuid) not in VariableAttrs:\r
+                VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
+            else:\r
+                if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
+                    EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))\r
             \r
-            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)\r
+            pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
             if (PcdCName,TokenSpaceGuid) in Pcds.keys():  \r
                 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
                 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
@@ -971,7 +1003,10 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 {SkuName : SkuInfo},\r
                                                 False,\r
-                                                None\r
+                                                None,\r
+                                                pcdDecObject.validateranges,\r
+                                                pcdDecObject.validlists,\r
+                                                pcdDecObject.expressions\r
                                                 )\r
                 \r
 \r
@@ -1143,6 +1178,7 @@ class DscBuildData(PlatformBuildClassObject):
     SkuName             = property(_GetSkuName, _SetSkuName)\r
     SkuIdentifier       = property(_GetSkuIdentifier)\r
     PcdInfoFlag         = property(_GetPcdInfoFlag)\r
+    VarCheckFlag = property(_GetVarCheckFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
@@ -1462,6 +1498,7 @@ class DecBuildData(PackageBuildClassObject):
 \r
             DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
                                        \r
+            validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)                          \r
             Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
                                                                             PcdCName,\r
                                                                             TokenSpaceGuid,\r
@@ -1472,7 +1509,10 @@ class DecBuildData(PackageBuildClassObject):
                                                                             '',\r
                                                                             {},\r
                                                                             False,\r
-                                                                            None\r
+                                                                            None,\r
+                                                                            list(validateranges),\r
+                                                                            list(validlists),\r
+                                                                            list(expressions)\r
                                                                             )\r
         return Pcds\r
 \r