]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
1) Change the schema type for <VariableGuid> used in PCD HiiEnable group in FPD file.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
index 4001558ef697092f2c897a3a32b84cc74923c07b..dc60cc6eb75ae1d5e29cfaf68ce43e055bacfc4c 100644 (file)
@@ -17,10 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 package org.tianocore.build.pcd.action;\r
 \r
-import java.io.BufferedReader;\r
+import java.io.BufferedReader;                                                    \r
 import java.io.File;\r
 import java.io.FileReader;\r
 import java.io.IOException;\r
+import java.math.BigInteger;\r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Comparator;\r
@@ -31,20 +32,21 @@ import java.util.UUID;
 \r
 import org.apache.xmlbeans.XmlException;\r
 import org.apache.xmlbeans.XmlObject;\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument;\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData;\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo;\r
 import org.tianocore.FrameworkModulesDocument;\r
 import org.tianocore.FrameworkPlatformDescriptionDocument;\r
 import org.tianocore.FrameworkPlatformDescriptionDocument.FrameworkPlatformDescription;\r
 import org.tianocore.ModuleSADocument;\r
 import org.tianocore.ModuleSADocument.ModuleSA;\r
 import org.tianocore.PackageSurfaceAreaDocument;\r
-import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;\r
-import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData.SkuData;\r
-import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;\r
-import org.tianocore.PcdDynamicBuildDeclarationsDocument.PcdDynamicBuildDeclarations;\r
-import org.tianocore.build.autogen.CommonDefinition;\r
+import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
 import org.tianocore.build.global.GlobalData;\r
 import org.tianocore.build.global.SurfaceAreaQuery;\r
 import org.tianocore.build.pcd.action.ActionMessage;\r
+import org.tianocore.build.pcd.entity.DynamicTokenValue;\r
 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
 import org.tianocore.build.pcd.entity.SkuInstance;\r
 import org.tianocore.build.pcd.entity.Token;\r
@@ -421,8 +423,8 @@ class SkuIdTable {
 \r
         int index;\r
 \r
-        Integer [] skuIds = new Integer[token.maxSkuCount + 1];\r
-        skuIds[0] = new Integer(token.maxSkuCount);\r
+        Integer [] skuIds = new Integer[token.skuData.size() + 1];\r
+        skuIds[0] = new Integer(token.skuData.size());\r
         for (index = 1; index < skuIds.length; index++) {\r
             skuIds[index] = new Integer(token.skuData.get(index - 1).id);\r
         }\r
@@ -512,19 +514,19 @@ class LocalTokenNumberTable {
 \r
         str =  String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());\r
 \r
-        if (token.isStringType()) {\r
+        if (token.isUnicodeStringType()) {\r
             str += " | PCD_TYPE_STRING";\r
         }\r
 \r
-        if (token.skuEnabled) {\r
+        if (token.isSkuEnable()) {\r
             str += " | PCD_TYPE_SKU_ENABLED";\r
         }\r
 \r
-        if (token.hiiEnabled) {\r
+        if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
             str += " | PCD_TYPE_HII";\r
         }\r
 \r
-        if (token.vpdEnabled) {\r
+        if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
             str += " | PCD_TYPE_VPD";\r
         }\r
         \r
@@ -723,15 +725,15 @@ class PcdDatabase {
     }\r
 \r
     private int getAlignmentSize (Token token) {\r
-        if (token.hiiEnabled) {\r
+        if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
             return 2;\r
         }\r
 \r
-        if (token.vpdEnabled) {\r
+        if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
             return 4;\r
         }\r
 \r
-        if (token.isStringType()) {\r
+        if (token.isUnicodeStringType()) {\r
             return 2;\r
         }\r
 \r
@@ -760,7 +762,8 @@ class PcdDatabase {
         return hString;\r
     }\r
 \r
-     public void genCode () {\r
+     public void genCode () \r
+        throws EntityException {\r
 \r
         final String newLine                        = "\r\n";\r
         final String declNewLine                    = ";\r\n";\r
@@ -924,7 +927,8 @@ class PcdDatabase {
         return str;\r
     }\r
 \r
-    private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) {\r
+    private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) \r
+        throws EntityException {\r
 \r
         HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();\r
 \r
@@ -936,7 +940,7 @@ class PcdDatabase {
         for (int index = 0; index < alToken.size(); index++) {\r
             Token token = alToken.get(index);\r
 \r
-            if (token.skuEnabled) {\r
+            if (token.isSkuEnable()) {\r
                 //\r
                 // BugBug: Schema only support Data type now\r
                 //\r
@@ -955,13 +959,13 @@ class PcdDatabase {
                 }\r
 \r
             } else {\r
-                if (token.hiiEnabled) {\r
+                if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
                     decl.add(getVariableEnableTypeDeclaration(token));\r
                     inst.add(getVariableEnableInstantiation(token));\r
-                } else if (token.vpdEnabled) {\r
+                } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
                     decl.add(getVpdEnableTypeDeclaration(token));\r
                     inst.add(getVpdEnableTypeInstantiation(token));\r
-                } else if (token.isStringType()) {\r
+                } else if (token.isUnicodeStringType()) {\r
                     decl.add(getStringTypeDeclaration(token));\r
                     inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));\r
                 }\r
@@ -1011,10 +1015,10 @@ class PcdDatabase {
         } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
             typeStr = "BOOLEAN %s_%s[%d];\r\n";\r
         } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
-            return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);\r
+            return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());\r
         } \r
 \r
-        return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount);\r
+        return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size());\r
 \r
     }\r
 \r
@@ -1022,12 +1026,12 @@ class PcdDatabase {
         String str = "";\r
 \r
         if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
-            return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);\r
+            return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());\r
         } else {\r
             str = "{ ";\r
-            for (int idx = 0; idx < token.maxSkuCount; idx++) {\r
+            for (int idx = 0; idx < token.skuData.size(); idx++) {\r
                 str += token.skuData.get(idx).toString();\r
-                if (idx != token.maxSkuCount - 1) {\r
+                if (idx != token.skuData.size() - 1) {\r
                     str += ", ";\r
                 }\r
             }\r
@@ -1041,9 +1045,9 @@ class PcdDatabase {
     private String getDataTypeInstantiation (Token token) {\r
 \r
         if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
-            return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());\r
+            return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());\r
         } else {\r
-            return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());\r
+            return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());\r
         }\r
     }\r
 \r
@@ -1075,7 +1079,7 @@ class PcdDatabase {
     }\r
 \r
     private String getVpdEnableTypeInstantiation (Token token) {\r
-        return String.format("{ %d } /* %s */", token.vpdOffset,\r
+        return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset,\r
                                                 token.getPrimaryKeyString());\r
     }\r
 \r
@@ -1093,10 +1097,14 @@ class PcdDatabase {
       return String.format("VARIABLE_HEAD  %s", token.getPrimaryKeyString());\r
     }\r
 \r
-    private String getVariableEnableInstantiation (Token token) {\r
-        return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()),\r
-                                                        stringTable.add(token.variableName, token),\r
-                                                        token.variableOffset, \r
+    private String getVariableEnableInstantiation (Token token) \r
+        throws EntityException {\r
+        //\r
+        // Need scott fix\r
+        // \r
+        return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()),\r
+                                                        stringTable.add(token.getDefaultSku().getStringOfVariableName(), token),\r
+                                                        token.getDefaultSku().variableOffset, \r
                                                         token.getPrimaryKeyString());\r
     }\r
 \r
@@ -1287,7 +1295,6 @@ public class CollectPCDAction {
         // memory database.\r
         //\r
         createTokenInDBFromFPD();\r
-\r
         \r
         //\r
         // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver\r
@@ -1436,34 +1443,40 @@ public class CollectPCDAction {
         int                                 index             = 0;\r
         int                                 index2            = 0;\r
         int                                 pcdIndex          = 0;\r
-        List<PcdBuildData>                  pcdBuildDataArray = new ArrayList<PcdBuildData>();\r
-        PcdBuildData                        pcdBuildData      = null;\r
+        List<PcdBuildDefinition.PcdData>    pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
+        PcdBuildDefinition.PcdData          pcdBuildData      = null;\r
         Token                               token             = null;\r
-        UUID                                nullUUID          = new UUID(0,0);\r
-        UUID                                platformTokenSpace= nullUUID;\r
         SkuInstance                         skuInstance       = null;\r
         int                                 skuIndex          = 0;\r
         List<ModuleInfo>                    modules           = null;\r
         String                              primaryKey        = null;\r
-        PcdBuildData.SkuData[]              skuDataArray      = null;\r
         String                              exceptionString   = null;\r
         UsageInstance                       usageInstance     = null;\r
         String                              primaryKey1       = null;\r
         String                              primaryKey2       = null;\r
         boolean                             isDuplicate       = false;\r
-        java.util.List<java.lang.String>    tokenGuidStringArray = null;\r
+        Token.PCD_TYPE                      pcdType           = Token.PCD_TYPE.UNKNOWN;\r
+        Token.DATUM_TYPE                    datumType         = Token.DATUM_TYPE.UNKNOWN;\r
+        int                                 tokenNumber       = 0;\r
+        String                              moduleName        = null;\r
+        String                              datum             = null;\r
+        int                                 maxDatumSize      = 0;\r
 \r
         //\r
-        // Get all <ModuleSA> from FPD file.\r
+        // ----------------------------------------------\r
+        // 1), Get all <ModuleSA> from FPD file.\r
+        // ----------------------------------------------\r
         // \r
         modules = getComponentsFromFPD();\r
 \r
         if (modules == null) {\r
-            throw new EntityException("No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
+            throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
         }\r
 \r
         //\r
-        // Loop all modules to process <PcdBuildDeclarations> for each module.\r
+        // -------------------------------------------------------------------\r
+        // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
+        // -------------------------------------------------------------------\r
         // \r
         for (index = 0; index < modules.size(); index ++) {\r
             isDuplicate =  false;\r
@@ -1473,15 +1486,15 @@ public class CollectPCDAction {
                 // <ModuleSAs>, It is work around code.\r
                 // \r
                 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(), \r
-                                                          translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),\r
-                                                          modules.get(index).module.getPackageName()\r
-                                                          translateSchemaStringToUUID(modules.get(index).module.getPackageGuid())\r
+                                                          null,\r
+                                                          null\r
+                                                          null\r
                                                           modules.get(index).module.getArch().toString(),\r
                                                           null);\r
                 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(), \r
-                                                          translateSchemaStringToUUID(modules.get(index2).module.getModuleGuid())\r
-                                                          modules.get(index2).module.getPackageName()\r
-                                                          translateSchemaStringToUUID(modules.get(index2).module.getPackageGuid())\r
+                                                          null\r
+                                                          null\r
+                                                          null\r
                                                           modules.get(index2).module.getArch().toString(), \r
                                                           null);\r
                 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {\r
@@ -1494,52 +1507,160 @@ public class CollectPCDAction {
                 continue;\r
             }\r
 \r
-            if (modules.get(index).module.getPcdBuildDeclarations() == null) {\r
-                continue;\r
-            }\r
-            pcdBuildDataArray = modules.get(index).module.getPcdBuildDeclarations().getPcdBuildDataList();\r
-            if (pcdBuildDataArray == null) {\r
-                continue;\r
-            }\r
-            if (pcdBuildDataArray.size() == 0) {\r
+           //\r
+           // It is legal for a module does not contains ANY pcd build definitions.\r
+           // \r
+           if (modules.get(index).module.getPcdBuildDefinition() == null) {\r
                 continue;\r
-            }\r
+           }\r
+    \r
+            pcdBuildDataArray = modules.get(index).module.getPcdBuildDefinition().getPcdDataList();\r
+\r
+            moduleName = modules.get(index).module.getModuleName();\r
 \r
             //\r
-            // Loop all Pcd entry for a module and add it into memory database.\r
+            // ----------------------------------------------------------------------\r
+            // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
+            // ----------------------------------------------------------------------\r
             // \r
             for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {\r
                 pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
                 primaryKey   = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
                                                          translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));\r
+                pcdType      = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
+                datumType    = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
+                tokenNumber  = Integer.decode(pcdBuildData.getToken().toString());\r
+                if (pcdBuildData.getValue() != null) {\r
+                    datum = pcdBuildData.getValue().toString();\r
+                } else {\r
+                    datum = null;\r
+                }\r
+                maxDatumSize = pcdBuildData.getMaxDatumSize();\r
+\r
+                if ((pcdType    == Token.PCD_TYPE.FEATURE_FLAG) &&\r
+                    (datumType  != Token.DATUM_TYPE.BOOLEAN)){\r
+                    exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
+                                                    "datum type of this PCD entry is not BOOLEAN!",\r
+                                                    pcdBuildData.getCName(),\r
+                                                    moduleName);\r
+                    throw new EntityException(exceptionString);\r
+                }\r
 \r
+                //\r
+                // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools\r
+                // will check that, following checking code could be removed.\r
+                // \r
+                if (pcdBuildData.getTokenSpaceGuid() == null) {\r
+                    exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in module %s! This is required!",\r
+                                                    pcdBuildData.getCName(),\r
+                                                    moduleName);\r
+                    throw new EntityException(exceptionString);\r
+                }\r
+\r
+                //\r
+                // -------------------------------------------------------------------------------------------\r
+                // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
+                // -------------------------------------------------------------------------------------------\r
+                // \r
+                if (!Token.isDynamic(pcdType)) {\r
+                     //\r
+                     // Value is required.\r
+                     // \r
+                     if (datum == null) {\r
+                         exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r
+                                                         pcdBuildData.getCName(),\r
+                                                         moduleName);\r
+                         throw new EntityException(exceptionString);\r
+                     }\r
+\r
+                     //\r
+                     // Check whether the datum size is matched datum type.\r
+                     // \r
+                     if ((exceptionString = verifyDatum(pcdBuildData.getCName(), \r
+                                                        moduleName,\r
+                                                        datum,\r
+                                                        datumType,\r
+                                                        maxDatumSize)) != null) {\r
+                         throw new EntityException(exceptionString);\r
+                     }\r
+                }\r
 \r
+                //\r
+                // ---------------------------------------------------------------------------------\r
+                // 2.1.2), Create token or update token information for current anaylized PCD data.\r
+                // ---------------------------------------------------------------------------------\r
+                // \r
                 if (dbManager.isTokenInDatabase(primaryKey)) {\r
                     //\r
                     // If the token is already exist in database, do some necessary checking\r
                     // and add a usage instance into this token in database\r
                     // \r
                     token = dbManager.getTokenByKey(primaryKey);\r
+    \r
+                    //\r
+                    // checking for DatumType, DatumType should be unique for one PCD used in different\r
+                    // modules.\r
+                    // \r
+                    if (token.datumType != datumType) {\r
+                        exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with  %s defined in before!",\r
+                                                        pcdBuildData.getCName(), \r
+                                                        pcdBuildData.getDatumType().toString(), \r
+                                                        Token.getStringOfdatumType(token.datumType));\r
+                        throw new EntityException(exceptionString);\r
+                    }\r
 \r
                     //\r
-                    // Checking for DatumSize\r
+                    // Check token number is valid\r
                     // \r
-                    if (token.datumSize != pcdBuildData.getDatumSize()) {\r
-                        exceptionString = String.format("The datum size of PCD entry %s is %d, which is different with %d defined in before!",\r
-                                                        pcdBuildData.getCName(),  pcdBuildData.getDatumSize(), token.datumSize);\r
+                    if (tokenNumber != token.tokenNumber) {\r
+                        exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",\r
+                                                        pcdBuildData.getCName(),\r
+                                                        moduleName);\r
                         throw new EntityException(exceptionString);\r
                     }\r
 \r
                     //\r
-                    // checking for DatumType\r
+                    // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
                     // \r
-                    if (token.datumType != Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString())) {\r
-                        exceptionString = String.format("The datum type of PCD entry %s is %s, which is different with  %s defined in before!",\r
-                                                        pcdBuildData.getCName(), \r
-                                                        pcdBuildData.getDatumType().toString(), \r
-                                                        Token.getStringOfdatumType(token.datumType));\r
+                    if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
+                        exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
+                                                        "is different with others module's",\r
+                                                        token.cName,\r
+                                                        moduleName);\r
                         throw new EntityException(exceptionString);\r
                     }\r
+\r
+                    if (token.isDynamicPCD) {\r
+                        //\r
+                        // Check datum is equal the datum in dynamic information.\r
+                        // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
+                        // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
+                        // \r
+                        if (!token.isSkuEnable() && \r
+                            (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
+                            (datum != null)) {\r
+                            if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
+                                exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
+                                                                "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
+                                                                "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
+                                                                token.cName,\r
+                                                                moduleName);\r
+                                throw new EntityException(exceptionString);\r
+                            }\r
+                        }\r
+\r
+                        if ((maxDatumSize != 0) &&\r
+                            (maxDatumSize != token.datumSize)){\r
+                            exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r
+                                                            "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
+                                                            token.cName,\r
+                                                            moduleName,\r
+                                                            maxDatumSize,\r
+                                                            token.datumSize);\r
+                            throw new EntityException(exceptionString);\r
+                        }\r
+                    }\r
+                    \r
                 } else {\r
                     //\r
                     // If the token is not in database, create a new token instance and add\r
@@ -1547,71 +1668,398 @@ public class CollectPCDAction {
                     // \r
                     token = new Token(pcdBuildData.getCName(), \r
                                       translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));\r
-\r
-                    token.datum         = pcdBuildData.getDefaultValue();\r
-                    token.pcdType       = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
-                    token.datumType     = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
-                    token.datumSize     = pcdBuildData.getDatumSize();\r
-                    token.skuId         = Integer.decode(pcdBuildData.getSkuId());\r
-\r
-                    if (pcdBuildData.getToken() == null) {\r
-                        exceptionString = String.format("In FPD file, No <TokenNumber> defined for PCD entry %s in module %s",\r
-                                                        token.cName,\r
-                                                        modules.get(index).module.getModuleName());\r
-                        throw new EntityException(exceptionString);\r
-                    }\r
-                    token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());\r
-\r
-                    if ((token.pcdType == Token.PCD_TYPE.DYNAMIC) ||\r
-                        (token.pcdType == Token.PCD_TYPE.DYNAMIC_EX)) {\r
-                        updateDynamicInformation(modules.get(index).module.getModuleName(),  token);\r
+    \r
+                    token.datumType     = datumType;\r
+                    token.tokenNumber   = tokenNumber;\r
+                    token.isDynamicPCD  = Token.isDynamic(pcdType);\r
+                    token.datumSize     = maxDatumSize;\r
+                    \r
+                    if (token.isDynamicPCD) {\r
+                        //\r
+                        // For Dynamic and Dynamic Ex type, need find the dynamic information\r
+                        // in <DynamicPcdBuildDefinition> section in FPD file.\r
+                        // \r
+                        updateDynamicInformation(moduleName, \r
+                                                 token,\r
+                                                 datum,\r
+                                                 maxDatumSize);\r
                     }\r
-\r
+    \r
                     dbManager.addTokenToDatabase(primaryKey, token);\r
                 }\r
 \r
                 //\r
-                // Create an usage instance for this token\r
+                // -----------------------------------------------------------------------------------\r
+                // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
+                // -----------------------------------------------------------------------------------\r
+                // \r
+                token.updateSupportPcdType(pcdType);\r
+\r
+                //\r
+                // ------------------------------------------------\r
+                // 2.1.4), Create an usage instance for this token.\r
+                // ------------------------------------------------\r
                 // \r
                 usageInstance = new UsageInstance(token, \r
-                                                  Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),\r
-                                                  modules.get(index).module.getModuleName(), \r
-                                                  translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),\r
-                                                  modules.get(index).module.getPackageName(),\r
-                                                  translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()),\r
+                                                  moduleName, \r
+                                                  null,\r
+                                                  null,\r
+                                                  null,\r
                                                   modules.get(index).type, \r
-                                                  Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),\r
+                                                  pcdType,\r
                                                   modules.get(index).module.getArch().toString(), \r
                                                   null,\r
-                                                  pcdBuildData.getDefaultValue());\r
+                                                  datum,\r
+                                                  maxDatumSize);\r
                 token.addUsageInstance(usageInstance);\r
             }\r
         }\r
     }\r
 \r
     /**\r
-       Update dynamic information for PCD entry.\r
-       \r
-       Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
-       FPD file.\r
+       Verify the datum value according its datum size and datum type, this\r
+       function maybe moved to FPD verification tools in future.\r
        \r
+       @param cName\r
        @param moduleName\r
-       @param token\r
+       @param datum\r
+       @param datumType\r
+       @param maxDatumSize\r
        \r
-       @return Token\r
-    **/\r
-    private Token updateDynamicInformation(String moduleName, Token token) \r
+       @return String\r
+     */\r
+    /***/\r
+    public String verifyDatum(String            cName,\r
+                              String            moduleName,\r
+                              String            datum, \r
+                              Token.DATUM_TYPE  datumType, \r
+                              int               maxDatumSize) {\r
+        String      exceptionString = null;\r
+        int         value;\r
+        BigInteger  value64;\r
+        String      subStr;\r
+        int         index;\r
+\r
+        if (moduleName == null) {\r
+            moduleName = "section <DynamicPcdBuildDefinitions>";\r
+        } else {\r
+            moduleName = "module " + moduleName;\r
+        }\r
+\r
+        if (maxDatumSize == 0) {\r
+            exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r
+                                            cName,\r
+                                            moduleName);\r
+            return exceptionString;\r
+        }\r
+\r
+        switch (datumType) {\r
+        case UINT8:\r
+            if (maxDatumSize != 1) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT8, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    value = Integer.decode(datum);\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r
+                                                    "digital format of UINT8",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                if (value > 0xFF) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r
+                                                    " the max size of UINT8 - 0xFF",\r
+                                                    cName, \r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT16:\r
+            if (maxDatumSize != 2) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT16, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+            if (datum != null) {\r
+                try {\r
+                    value = Integer.decode(datum);\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r
+                                                    "not valid digital of UINT16",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                if (value > 0xFFFF) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
+                                                    "which exceed the range of UINT16 - 0xFFFF",\r
+                                                    cName, \r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT32:\r
+            if (maxDatumSize != 4) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT32, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    if (datum.length() > 2) {\r
+                        if ((datum.charAt(0) == '0')        && \r
+                            ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
+                            subStr = datum.substring(2, datum.length());\r
+                            value64 = new BigInteger(subStr, 16);\r
+                        } else {\r
+                            value64 = new BigInteger(datum);\r
+                        }\r
+                    } else {\r
+                        value64 = new BigInteger(datum);\r
+                    }\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r
+                                                    "valid digital of UINT32",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                if (value64.bitLength() > 32) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r
+                                                    "exceed the range of UINT32 - 0xFFFFFFFF",\r
+                                                    cName, \r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT64:\r
+            if (maxDatumSize != 8) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT64, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    if (datum.length() > 2) {\r
+                        if ((datum.charAt(0) == '0')        && \r
+                            ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
+                            subStr = datum.substring(2, datum.length());\r
+                            value64 = new BigInteger(subStr, 16);\r
+                        } else {\r
+                            value64 = new BigInteger(datum);\r
+                        }\r
+                    } else {\r
+                        value64 = new BigInteger(datum);\r
+                    }\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r
+                                                    " digital of UINT64",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                if (value64.bitLength() > 64) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
+                                                    "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r
+                                                    cName, \r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case BOOLEAN:\r
+            if (maxDatumSize != 1) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is BOOLEAN, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                if (!(datum.equalsIgnoreCase("TRUE") ||\r
+                     datum.equalsIgnoreCase("FALSE"))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                    "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+            }\r
+            break;\r
+        case POINTER:\r
+            if (datum == null) {\r
+                break;\r
+            }\r
+\r
+            char    ch     = datum.charAt(0);\r
+            int     start, end;\r
+            String  strValue;\r
+            //\r
+            // For void* type PCD, only three datum is support:\r
+            // 1) Unicode: string with start char is "L"\r
+            // 2) Ansci: String start char is ""\r
+            // 3) byte array: String start char "{"\r
+            // \r
+            if (ch == 'L') {\r
+                start       = datum.indexOf('\"');\r
+                end         = datum.lastIndexOf('\"');\r
+                if ((start > end)           || \r
+                    (end   > datum.length())||\r
+                    ((start == end) && (datum.length() > 0))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
+                                                    "a UNICODE string because start with L\", but format maybe"+\r
+                                                    "is not right, correct UNICODE string is L\"...\"!",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                strValue    = datum.substring(start + 1, end);\r
+                if ((strValue.length() * 2) > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
+                                                    "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValue.length() * 2, \r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else if (ch == '\"'){\r
+                start       = datum.indexOf('\"');\r
+                end         = datum.lastIndexOf('\"');\r
+                if ((start > end)           || \r
+                    (end   > datum.length())||\r
+                    ((start == end) && (datum.length() > 0))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
+                                                    "a ANSCII string because start with \", but format maybe"+\r
+                                                    "is not right, correct ANSIC string is \"...\"!",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                strValue    = datum.substring(start + 1, end);\r
+                if ((strValue.length()) > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
+                                                    "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValue.length(),\r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else if (ch =='{') {\r
+                String[]  strValueArray;\r
+\r
+                start           = datum.indexOf('{');\r
+                end             = datum.lastIndexOf('}');\r
+                strValue        = datum.substring(start + 1, end);\r
+                strValue        = strValue.trim();\r
+                if (strValue.length() == 0) {\r
+                    break;\r
+                }\r
+                strValueArray   = strValue.split(",");\r
+                for (index = 0; index < strValueArray.length; index ++) {\r
+                    try{\r
+                        value = Integer.decode(strValueArray[index].trim());\r
+                    } catch (NumberFormatException nfeEx) {\r
+                        exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
+                                                         "it is byte array in fact. For every byte in array should be a valid"+\r
+                                                         "byte digital, but element %s is not a valid byte digital!",\r
+                                                         cName,\r
+                                                         moduleName,\r
+                                                         strValueArray[index]);\r
+                        return exceptionString;\r
+                    }\r
+                    if (value > 0xFF) {\r
+                        exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r
+                                                        "it is byte array in fact. But the element of %s exceed the byte range",\r
+                                                        cName,\r
+                                                        moduleName,\r
+                                                        strValueArray[index]);\r
+                        return exceptionString;\r
+                    }\r
+                }\r
+\r
+                if (strValueArray.length > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r
+                                                    "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValueArray.length,\r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+\r
+                                                "1) UNICODE string: like L\"xxxx\";\r\n"+\r
+                                                "2) ANSIC string: like \"xxx\";\r\n"+\r
+                                                "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r
+                                                "But the datum in seems does not following above format!",\r
+                                                cName, \r
+                                                moduleName);\r
+                return exceptionString;\r
+            }\r
+            break;\r
+        default:\r
+            exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r
+                                            "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r
+                                            cName,\r
+                                            moduleName);\r
+            return exceptionString;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+       Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
+       \r
+       This function should be implemented in GlobalData in future.\r
+       \r
+       @param token         The token instance which has hold module's PCD information\r
+       @param moduleName    The name of module who will use this Dynamic PCD.\r
+       \r
+       @return DynamicPcdBuildDefinitions.PcdBuildData\r
+     */\r
+    /***/\r
+    private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token     token,\r
+                                                                          String    moduleName)\r
         throws EntityException {\r
-        PcdDynamicBuildDeclarations                pcdDynamicBuildDescriptions = null;\r
-        \r
-        boolean                                    isFound                     = false;            \r
-        int                                        index                       = 0;\r
-        String                                     primaryKey                  = null;\r
-        SkuInstance                                skuInstance                 = null;\r
-        int                                        skuIndex                    = 0;\r
-        String                                     exceptionString             = null;\r
-        PcdDynamicBuildDeclarations.PcdBuildData.SkuData[] skuDataArray             = null;\r
-        List<PcdDynamicBuildDeclarations.PcdBuildData>     pcdDynamicBuildDataArray = null;\r
+        int    index             = 0;\r
+        String exceptionString   = null;\r
+        String dynamicPrimaryKey = null;\r
+        DynamicPcdBuildDefinitions                    dynamicPcdBuildDefinitions = null;\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray   = null;\r
 \r
         //\r
         // If FPD document is not be opened, open and initialize it.\r
@@ -1626,106 +2074,254 @@ public class CollectPCDAction {
             }\r
         }\r
 \r
-        pcdDynamicBuildDescriptions = fpdDocInstance.getFrameworkPlatformDescription().getPcdDynamicBuildDeclarations();\r
-        if (pcdDynamicBuildDescriptions == null) {\r
-            throw new EntityException(String.format("There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
-                                                    "PCD entry %s in module %s!",\r
-                                                    token.cName,\r
-                                                    moduleName));\r
+        dynamicPcdBuildDefinitions = fpdDocInstance.getFrameworkPlatformDescription().getDynamicPcdBuildDefinitions();\r
+        if (dynamicPcdBuildDefinitions == null) {\r
+            exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
+                                            "PCD entry %s in module %s!",\r
+                                            token.cName,\r
+                                            moduleName);\r
+            throw new EntityException(exceptionString);\r
         }\r
 \r
-        pcdDynamicBuildDataArray    = pcdDynamicBuildDescriptions.getPcdBuildDataList();\r
-        if (pcdDynamicBuildDataArray == null) {\r
-            throw new EntityException(String.format("There are no PcdDynamicBuildData in <PcdDynamicBuildDeclaration> section but contains Dynamic type"+\r
-                                                    "PCD entry %s in module %s.!",\r
-                                                    token.cName,\r
-                                                    moduleName));\r
-        }\r
+        dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
+        for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
+            //\r
+            // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools\r
+            // will check that, following checking code could be removed.\r
+            // \r
+            if (dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid() == null) {\r
+                exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in <DynamicPcdBuildDefinitions>! This is required!",\r
+                                                dynamicPcdBuildDataArray.get(index).getCName());\r
+                throw new EntityException(exceptionString);\r
+            }\r
 \r
-        isFound = false;\r
-        for (index = 0; index < pcdDynamicBuildDataArray.size(); index ++) {\r
-            if (pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().size() != 0) {\r
-                primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), \r
-                                                       translateSchemaStringToUUID(pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().get(0)));\r
-            } else {\r
-                primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), \r
-                                                       translateSchemaStringToUUID(null));\r
+            dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
+                                                          translateSchemaStringToUUID(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid()));\r
+            if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
+                return dynamicPcdBuildDataArray.get(index);\r
             }\r
+        }\r
 \r
-            if (primaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
-                isFound = true;\r
+        return null;\r
+    }\r
 \r
-                //\r
-                // For Hii related value\r
-                // \r
-                token.hiiEnabled    = pcdDynamicBuildDataArray.get(index).getHiiEnable();\r
-                if (token.hiiEnabled) {\r
-                    token.variableGuid      = Token.getGUIDFromSchemaObject(pcdDynamicBuildDataArray.get(index).getVariableGuid());\r
-                    if (token.variableGuid == null) {\r
-                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +\r
-                                                                "but no <VariableGuid> is found! Please fix the FPD file!",\r
-                                                                token.cName));\r
+    /**\r
+       Update dynamic information for PCD entry.\r
+       \r
+       Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
+       FPD file.\r
+       \r
+       @param moduleName        The name of the module who use this PCD\r
+       @param token             The token instance\r
+       @param datum             The <datum> in module's PCD information\r
+       @param maxDatumSize      The <maxDatumSize> in module's PCD information\r
+       \r
+       @return Token\r
+     */\r
+    private Token updateDynamicInformation(String   moduleName, \r
+                                           Token    token,\r
+                                           String   datum,\r
+                                           int      maxDatumSize) \r
+        throws EntityException {\r
+        int                 index           = 0;\r
+        int                 offset;\r
+        String              exceptionString = null;\r
+        DynamicTokenValue   dynamicValue;\r
+        SkuInstance         skuInstance     = null;\r
+        String              temp;\r
+        boolean             hasSkuId0       = false;\r
+        Token.PCD_TYPE      pcdType         = Token.PCD_TYPE.UNKNOWN;\r
+        int                 tokenNumber     = 0;\r
+        String              hiiDefaultValue = null;\r
+        String[]            variableGuidString = null;\r
+\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo>   skuInfoList = null;\r
+        DynamicPcdBuildDefinitions.PcdBuildData                 dynamicInfo = null;\r
+\r
+        dynamicInfo = getDynamicInfoFromFPD(token, moduleName);\r
+        if (dynamicInfo == null) {\r
+            exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r
+                                            "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
+                                            "in FPD file, but it is required!",\r
+                                            token.cName,\r
+                                            moduleName);\r
+            throw new EntityException(exceptionString);\r
+        }\r
 \r
-                    }\r
-                    token.variableName      = pcdDynamicBuildDataArray.get(index).getVariableName();\r
-                    if (token.variableName == null) {\r
-                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +\r
-                                                                "but no <VariableName> is found! Please fix the FPD file!",\r
-                                                                token.cName));\r
-                    }\r
+        token.datumSize = dynamicInfo.getMaxDatumSize();\r
 \r
-                    if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {\r
-                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +\r
-                                                                "but no <DataOffset> is found! Please fix the FPD file!",\r
-                                                                token.cName));\r
-                    }\r
-                    token.variableOffset    = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());\r
+        exceptionString = verifyDatum(token.cName, \r
+                                      moduleName,\r
+                                      null, \r
+                                      token.datumType, \r
+                                      token.datumSize);\r
+        if (exceptionString != null) {\r
+            throw new EntityException(exceptionString);\r
+        }\r
+\r
+        if ((maxDatumSize != 0) && \r
+            (maxDatumSize != token.datumSize)) {\r
+            exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r
+                                            "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
+                                            token.cName,\r
+                                            moduleName, \r
+                                            maxDatumSize,\r
+                                            dynamicInfo.getMaxDatumSize());\r
+            throw new EntityException(exceptionString);\r
+        }\r
+        tokenNumber = Integer.decode(dynamicInfo.getToken().toString());\r
+        if (tokenNumber != token.tokenNumber) {\r
+            exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
+                                            "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
+                                            token.cName,\r
+                                            moduleName,\r
+                                            token.tokenNumber,\r
+                                            tokenNumber);\r
+            throw new EntityException(exceptionString);\r
+        }\r
+\r
+        pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r
+        if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
+            token.dynamicExTokenNumber = tokenNumber;\r
+        }\r
+\r
+        skuInfoList = dynamicInfo.getSkuInfoList();\r
+\r
+        //\r
+        // Loop all sku data \r
+        // \r
+        for (index = 0; index < skuInfoList.size(); index ++) {\r
+            skuInstance = new SkuInstance();\r
+            //\r
+            // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
+            // \r
+            temp = skuInfoList.get(index).getSkuId().toString();\r
+            skuInstance.id = Integer.decode(temp);\r
+            if (skuInstance.id == 0) {\r
+                hasSkuId0 = true;\r
+            }\r
+            //\r
+            // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
+            // \r
+            if (skuInfoList.get(index).getValue() != null) {\r
+                skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
+                if ((exceptionString = verifyDatum(token.cName, \r
+                                                   null, \r
+                                                   skuInfoList.get(index).getValue().toString(), \r
+                                                   token.datumType, \r
+                                                   token.datumSize)) != null) {\r
+                    throw new EntityException(exceptionString);\r
                 }\r
 \r
+                token.skuData.add(skuInstance);\r
+\r
                 //\r
-                // For Vpd related value\r
+                // Judege wether is same of datum between module's information\r
+                // and dynamic information.\r
                 // \r
-                token.vpdEnabled    = pcdDynamicBuildDataArray.get(index).getVpdEnable();\r
-                if (token.vpdEnabled) {\r
-                    if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {\r
-                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, VpdEnable is true" +\r
-                                                                "but no <DataOffset> is found! Please fix the FPD file!",\r
-                                                                token.cName));\r
+                if (datum != null) {\r
+                    if ((skuInstance.id == 0)                                   &&\r
+                        !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
+                        exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
+                                          "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
+                                          " or you could not define value for a dynamic PCD in every <ModuleSA>!"; \r
+                        throw new EntityException(exceptionString);\r
                     }\r
-                    token.vpdOffset         = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());\r
                 }\r
+                continue;\r
+            }\r
 \r
-                //\r
-                // For SkuData\r
-                // \r
-                token.skuEnabled    = pcdDynamicBuildDataArray.get(index).getSkuEnable();\r
-                if (token.skuEnabled) {\r
-                    skuDataArray      = (PcdDynamicBuildDeclarations.PcdBuildData.SkuData[])pcdDynamicBuildDataArray.get(index).getSkuDataList().toArray();\r
-                    token.maxSkuCount = Integer.decode(pcdDynamicBuildDataArray.get(index).getMaxSku());\r
-                    if (skuDataArray == null) {\r
-                        exceptionString = String.format("In FPD file, the <SkuEnable> is true for PCD entry %s in module %s, But no any sku data.",\r
-                                                        token.cName, moduleName);\r
+            //\r
+            // Judge whether is HII group case.\r
+            // \r
+            if (skuInfoList.get(index).getVariableName() != null) {\r
+                exceptionString = null;\r
+                if (skuInfoList.get(index).getVariableGuid() == null) {\r
+                    exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    if (exceptionString != null) {\r
                         throw new EntityException(exceptionString);\r
-                    }\r
-                    if (token.maxSkuCount != pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray()) {\r
-                        exceptionString = String.format("In FPD file, <MaxSku> is not equal to the size of <SkuDataArray> for PCD entry %s in module %s",\r
-                                                        token.cName, moduleName);\r
+                    }                                                    \r
+                }\r
+\r
+                if (skuInfoList.get(index).getVariableOffset() == null) {\r
+                    exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    if (exceptionString != null) {\r
                         throw new EntityException(exceptionString);\r
                     }\r
+                }\r
 \r
-                    for (skuIndex = 0; skuIndex < pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray(); skuIndex ++) {\r
-                        skuInstance = new SkuInstance(skuDataArray[skuIndex].getId(),\r
-                                                      skuDataArray[skuIndex].getValue());\r
-                        token.skuData.add(skuInstance);\r
+                if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
+                    exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    if (exceptionString != null) {\r
+                        throw new EntityException(exceptionString);\r
                     }\r
                 }\r
-                break;\r
+\r
+                if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
+                    hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
+                } else {\r
+                    hiiDefaultValue = null;\r
+                }\r
+\r
+                if ((exceptionString = verifyDatum(token.cName, \r
+                                                   null, \r
+                                                   hiiDefaultValue, \r
+                                                   token.datumType, \r
+                                                   token.datumSize)) != null) {\r
+                    throw new EntityException(exceptionString);\r
+                }\r
+\r
+                offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
+                if (offset > 0xFFFF) {\r
+                    throw new EntityException(String.format("[FPD file error] For dynamic PCD %s ,  the variable offset defined in sku %d data "+\r
+                                                            "exceed 64K, it is not allowed!",\r
+                                                            token.cName,\r
+                                                            index));\r
+                }\r
+\r
+                //\r
+                // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
+                // \r
+                variableGuidString = GlobalData.getGuidInfoGuid(skuInfoList.get(index).getVariableGuid().toString());\r
+                if (variableGuidString == null) {\r
+                    throw new EntityException(String.format("[GUID Error] For dynamic PCD %s,  the variable guid %s can be found in all SPD file!",\r
+                                                            token.cName, \r
+                                                            skuInfoList.get(index).getVariableGuid().toString()));\r
+                }\r
+\r
+                skuInstance.value.setHiiData(skuInfoList.get(index).getVariableName(),\r
+                                             translateSchemaStringToUUID(variableGuidString[1]),\r
+                                             skuInfoList.get(index).getVariableOffset(),\r
+                                             skuInfoList.get(index).getHiiDefaultValue().toString());\r
+                token.skuData.add(skuInstance);\r
+                continue;\r
             }\r
+\r
+            if (skuInfoList.get(index).getVpdOffset() != null) {\r
+                skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
+                token.skuData.add(skuInstance);\r
+                continue;\r
+            }\r
+\r
+            exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
+                                            "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
+                                            token.cName);\r
+            throw new EntityException(exceptionString);\r
         }\r
-        if (!isFound) {\r
-            exceptionString = String.format("In FPD file, No dynamic PCD data for PCD entry %s in module %s",\r
-                                            token.cName,\r
-                                            moduleName);\r
+\r
+        if (!hasSkuId0) {\r
+            exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
+                                            "no sku id = 0 data, which is required for every dynamic PCD",\r
+                                            token.cName);\r
             throw new EntityException(exceptionString);\r
         }\r
 \r
@@ -1764,6 +2360,14 @@ public class CollectPCDAction {
             return null;\r
         }\r
 \r
+        if (uuidString.equals("0") ||\r
+            uuidString.equalsIgnoreCase("0x0")) {\r
+            return new UUID(0, 0);\r
+        }\r
+\r
+        uuidString = uuidString.replaceAll("\\{", "");\r
+        uuidString = uuidString.replaceAll("\\}", "");\r
+\r
         //\r
         // If the UUID schema string is GuidArrayType type then need translate \r
         // to GuidNamingConvention type at first.\r
@@ -1771,7 +2375,7 @@ public class CollectPCDAction {
         if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
             splitStringArray = uuidString.split("," );\r
             if (splitStringArray.length != 11) {\r
-                throw new EntityException ("Wrong format for UUID string: " + uuidString);\r
+                throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
             }\r
 \r
             //\r
@@ -1848,11 +2452,11 @@ public class CollectPCDAction {
     **/\r
     public static void main(String argv[]) throws EntityException {\r
         CollectPCDAction ca = new CollectPCDAction();\r
-        ca.setWorkspacePath("M:/ForPcd/edk2");\r
-        ca.setFPDFilePath("M:/ForPcd/edk2/EdkNt32Pkg/Nt32.fpd");\r
+        ca.setWorkspacePath("m:/tianocore/edk2");\r
+        ca.setFPDFilePath("m:/tianocore/edk2/EdkNt32Pkg/Nt32.fpd");\r
         ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
         GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
-                            "M:/ForPcd/edk2");\r
+                            "m:/tianocore/edk2");\r
         ca.execute();\r
     }\r
 }\r