]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
Add PcdDxe and PcdPEIM to all-arch for EdkModulePkg-All-Archs.fpd
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
index 9df18008ccf9ae9466951a2b1f6ed24340998e9e..6686de9f1d8592387800cd5f09a849b3d09bc549 100644 (file)
@@ -17,50 +17,77 @@ 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
 import java.util.HashMap;\r
+import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 import java.util.UUID;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
 \r
 import org.apache.xmlbeans.XmlException;\r
 import org.apache.xmlbeans.XmlObject;\r
-import org.tianocore.FrameworkPlatformDescriptionDocument;\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.PcdDeclarationsDocument;\r
+import org.tianocore.PlatformSurfaceAreaDocument;\r
+import org.tianocore.PcdBuildDefinitionDocument;\r
+import org.tianocore.PlatformSurfaceAreaDocument.PlatformSurfaceArea;\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.PcdDefinitionsDocument.PcdDefinitions;\r
+import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
 import org.tianocore.build.autogen.CommonDefinition;\r
 import org.tianocore.build.global.GlobalData;\r
 import org.tianocore.build.global.SurfaceAreaQuery;\r
+import org.tianocore.build.id.FpdModuleIdentification;\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
 import org.tianocore.build.pcd.entity.UsageInstance;\r
 import org.tianocore.build.pcd.exception.EntityException;\r
+import org.tianocore.logger.EdkLog;\r
+import org.tianocore.ModuleTypeDef;\r
+\r
+class CStructTypeDeclaration {\r
+    String key;\r
+    int alignmentSize;\r
+    String cCode;\r
+    boolean initTable;\r
+    \r
+    public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {\r
+        this.key = key;\r
+        this.alignmentSize = alignmentSize;\r
+        this.cCode = cCode;\r
+        this.initTable = initTable;\r
+    }\r
+}\r
 \r
 class StringTable {\r
     private ArrayList<String>   al; \r
     private ArrayList<String>   alComments;\r
     private String              phase;\r
     int                         len; \r
-    int                         bodyStart;\r
-    int                         bodyLineNum;\r
 \r
     public StringTable (String phase) {\r
         this.phase = phase;\r
         al = new ArrayList<String>();\r
         alComments = new ArrayList<String>();\r
         len = 0;\r
-        bodyStart = 0;\r
-        bodyLineNum = 0;\r
     }\r
 \r
     public String getSizeMacro () {\r
@@ -81,6 +108,74 @@ class StringTable {
     public String getExistanceMacro () {\r
         return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
     }\r
+    \r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {\r
+        final String stringTable = "StringTable";\r
+        final String tab         = "\t";\r
+        final String newLine     = "\r\n";\r
+        final String commaNewLine = ",\r\n";\r
+        \r
+        CStructTypeDeclaration decl;\r
+\r
+        String cDeclCode = "";\r
+        String cInstCode = "";\r
+\r
+        //\r
+        // If we have a empty StringTable\r
+        //\r
+        if (al.size() == 0) {\r
+            cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine; \r
+            decl = new CStructTypeDeclaration (\r
+                                                stringTable,\r
+                                                2,\r
+                                                cDeclCode,\r
+                                                true\r
+                                        );  \r
+            declaList.add(decl);\r
+\r
+            cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";\r
+            instTable.put(stringTable, cInstCode);\r
+        } else {\r
+\r
+            //\r
+            // If there is any String in the StringTable\r
+            //\r
+            for (int i = 0; i < al.size(); i++) {\r
+                String str = al.get(i);\r
+                String stringTableName;\r
+                \r
+                if (i == 0) {\r
+                    //\r
+                    // StringTable is a well-known name in the PCD DXE driver\r
+                    //\r
+                    stringTableName = stringTable;\r
+    \r
+                } else {\r
+                    stringTableName = String.format("%s_%d", stringTable, i);\r
+                    cDeclCode += tab;\r
+                }\r
+                cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", stringTableName, str.length() + 1, alComments.get(i)) + newLine;\r
+                \r
+                if (i == 0) {\r
+                    cInstCode = "/* StringTable */" + newLine;\r
+                }\r
+                cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));\r
+                if (i != al.size() - 1) {\r
+                    cInstCode += commaNewLine;\r
+                }\r
+            }\r
+            \r
+            decl = new CStructTypeDeclaration (\r
+                    stringTable,\r
+                    2,\r
+                    cDeclCode,\r
+                    true\r
+            );  \r
+            declaList.add(decl);\r
+    \r
+            instTable.put(stringTable, cInstCode);\r
+        }\r
+    }\r
 \r
     public String getTypeDeclaration () {\r
 \r
@@ -135,9 +230,33 @@ class StringTable {
         return output;\r
     }\r
 \r
-    public int add (String str, Token token) {\r
+    public int add (String inputStr, Token token) {\r
         int i;\r
+        int pos;\r
+\r
+        String str = inputStr;\r
+        \r
+        //\r
+        // The input can be two types:\r
+        // "L\"Bootmode\"" or "Bootmode". \r
+        // We drop the L\" and \" for the first type. \r
+        if (str.startsWith("L\"") && str.endsWith("\"")) {\r
+            str = str.substring(2, str.length() - 1);\r
+        }\r
+        //\r
+        // Check if StringTable has this String already.\r
+        // If so, return the current pos.\r
+        //\r
+        for (i = 0, pos = 0; i < al.size(); i++) {\r
+            String s = al.get(i);;\r
 \r
+            if (str.equals(s)) {\r
+                return pos;\r
+            }\r
+            pos = s.length() + 1;\r
+            \r
+        }\r
+        \r
         i = len;\r
         //\r
         // Include the NULL character at the end of String\r
@@ -155,16 +274,32 @@ class SizeTable {
     private ArrayList<String>   alComments;\r
     private String              phase;\r
     private int                 len;\r
-    private int             bodyStart;\r
-    private int             bodyLineNum;\r
-\r
+    \r
     public SizeTable (String phase) {\r
         this.phase = phase;\r
         al = new ArrayList<Integer>();\r
         alComments = new ArrayList<String>();\r
         len = 0;\r
-        bodyStart = 0;\r
-        bodyLineNum = 0;\r
+    }\r
+\r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
+        final String name = "SizeTable";\r
+        \r
+        CStructTypeDeclaration decl;\r
+        String cCode;\r
+\r
+        cCode = String.format(PcdDatabase.SizeTableDeclaration, phase); \r
+        decl = new CStructTypeDeclaration (\r
+                                            name,\r
+                                            2,\r
+                                            cCode,\r
+                                            true\r
+                                           );  \r
+        declaList.add(decl);\r
+\r
+\r
+        cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
+        instTable.put(name, cCode);\r
     }\r
 \r
     public String getTypeDeclaration () {\r
@@ -176,14 +311,12 @@ class SizeTable {
 \r
         Output.add("/* SizeTable */");\r
         Output.add("{");\r
-        bodyStart = 2;\r
-\r
         if (al.size() == 0) {\r
-            Output.add("0");\r
+            Output.add("\t0");\r
         } else {\r
             for (int index = 0; index < al.size(); index++) {\r
                 Integer n = al.get(index);\r
-                String str = n.toString();\r
+                String str = "\t" + n.toString();\r
 \r
                 if (index != (al.size() - 1)) {\r
                     str += ",";\r
@@ -191,7 +324,6 @@ class SizeTable {
 \r
                 str += " /* " + alComments.get(index) + " */"; \r
                 Output.add(str);\r
-                bodyLineNum++;\r
     \r
             }\r
         }\r
@@ -200,14 +332,6 @@ class SizeTable {
         return Output;\r
     }\r
 \r
-    public int getBodyStart() {\r
-        return bodyStart;\r
-    }\r
-\r
-    public int getBodyLineNum () {\r
-        return bodyLineNum;\r
-    }\r
-\r
     public int add (Token token) {\r
         int index = len;\r
 \r
@@ -218,18 +342,6 @@ class SizeTable {
         return index;\r
     }\r
     \r
-    private int getDatumSize(Token token) {\r
-        /*\r
-        switch (token.datumType) {\r
-        case Token.DATUM_TYPE.UINT8:\r
-            return 1;\r
-        default:\r
-            return 0;\r
-        }\r
-        */\r
-        return 0;\r
-    }\r
-\r
     public int getTableLen () {\r
         return al.size() == 0 ? 1 : al.size();\r
     }\r
@@ -241,7 +353,6 @@ class GuidTable {
     private ArrayList<String> alComments;\r
     private String          phase;\r
     private int             len;\r
-    private int             bodyStart;\r
     private int             bodyLineNum;\r
 \r
     public GuidTable (String phase) {\r
@@ -249,7 +360,6 @@ class GuidTable {
         al = new ArrayList<UUID>();\r
         alComments = new ArrayList<String>();\r
         len = 0;\r
-        bodyStart = 0;\r
         bodyLineNum = 0;\r
     }\r
 \r
@@ -265,6 +375,26 @@ class GuidTable {
         return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
     }\r
 \r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
+        final String name = "GuidTable";\r
+        \r
+        CStructTypeDeclaration decl;\r
+        String cCode = "";\r
+\r
+        cCode += String.format(PcdDatabase.GuidTableDeclaration, phase); \r
+        decl = new CStructTypeDeclaration (\r
+                                            name,\r
+                                            8,\r
+                                            cCode,\r
+                                            true\r
+                                           );  \r
+        declaList.add(decl);\r
+\r
+\r
+        cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
+        instTable.put(name, cCode);\r
+    }\r
+\r
     public String getTypeDeclaration () {\r
         return String.format(PcdDatabase.GuidTableDeclaration, phase);\r
     }\r
@@ -274,7 +404,7 @@ class GuidTable {
 \r
         guidStrArray =(uuid.toString()).split("-");\r
 \r
-        return String.format("{ 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } }",\r
+        return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",\r
                                          guidStrArray[0],\r
                                          guidStrArray[1],\r
                                          guidStrArray[2],\r
@@ -294,17 +424,16 @@ class GuidTable {
 \r
         Output.add("/* GuidTable */");\r
         Output.add("{");\r
-        bodyStart = 2;\r
 \r
         if (al.size() == 0) {\r
-            Output.add(getUuidCString(new UUID(0, 0)));\r
+            Output.add("\t" + getUuidCString(new UUID(0, 0)));\r
         }\r
         \r
-        for (Object u : al) {\r
-            UUID uuid = (UUID)u;\r
-            String str = getUuidCString(uuid);\r
+        for (int i = 0; i < al.size(); i++) {\r
+            String str = "\t" + getUuidCString(al.get(i));\r
 \r
-            if (al.indexOf(u) != (al.size() - 1)) {\r
+            str += "/* " + alComments.get(i) +  " */";\r
+            if (i != (al.size() - 1)) {\r
                 str += ",";\r
             }\r
             Output.add(str);\r
@@ -316,23 +445,25 @@ class GuidTable {
         return Output;\r
     }\r
 \r
-    public int getBodyStart() {\r
-        return bodyStart;\r
-    }\r
-\r
-    public int getBodyLineNum () {\r
-        return bodyLineNum;\r
-    }\r
-\r
     public int add (UUID uuid, String name) {\r
-        int index = len;\r
         //\r
-        // Include the NULL character at the end of String\r
+        // Check if GuidTable has this entry already.\r
+        // If so, return the GuidTable index.\r
         //\r
+        for (int i = 0; i < al.size(); i++) {\r
+            if (al.get(i).equals(uuid)) {\r
+                return i;\r
+            }\r
+        }\r
+        \r
         len++; \r
         al.add(uuid);\r
+        alComments.add(name);\r
 \r
-        return index;\r
+        //\r
+        // Return the previous Table Index\r
+        //\r
+        return len - 1;\r
     }\r
 \r
     public int getTableLen () {\r
@@ -346,15 +477,11 @@ class SkuIdTable {
     private ArrayList<String>    alComment;\r
     private String               phase;\r
     private int                  len;\r
-    private int                   bodyStart;\r
-    private int                   bodyLineNum;\r
 \r
     public SkuIdTable (String phase) {\r
         this.phase = phase;\r
         al = new ArrayList<Integer[]>();\r
         alComment = new ArrayList<String>();\r
-        bodyStart = 0;\r
-        bodyLineNum = 0;\r
         len = 0;\r
     }\r
 \r
@@ -363,13 +490,49 @@ class SkuIdTable {
     }\r
 \r
     private int getSize () {\r
-        return (al.size() == 0)? 1 : al.size();\r
+        return (len == 0)? 1 : len;\r
     }\r
 \r
     public String getExistanceMacro () {\r
         return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
     }\r
 \r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
+        final String name = "SkuIdTable";\r
+        \r
+        CStructTypeDeclaration decl;\r
+        String cCode = "";\r
+\r
+        cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase); \r
+        decl = new CStructTypeDeclaration (\r
+                                            name,\r
+                                            1,\r
+                                            cCode,\r
+                                            true\r
+                                           );  \r
+        declaList.add(decl);\r
+\r
+\r
+        cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
+        instTable.put(name, cCode);\r
+\r
+        //\r
+        // SystemSkuId is in PEI phase PCD Database\r
+        //\r
+        if (phase.equalsIgnoreCase("PEI")) {\r
+            decl = new CStructTypeDeclaration (\r
+                                                "SystemSkuId",\r
+                                                1,\r
+                                                String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),\r
+                                                true\r
+                                              );\r
+            declaList.add(decl);\r
+            \r
+            instTable.put("SystemSkuId", "0");\r
+        }\r
+\r
+    }\r
+\r
     public String getTypeDeclaration () {\r
         return String.format(PcdDatabase.SkuIdTableDeclaration, phase);\r
     }\r
@@ -379,10 +542,9 @@ class SkuIdTable {
 \r
         Output.add("/* SkuIdTable */");\r
         Output.add("{");\r
-        bodyStart = 2;\r
 \r
         if (al.size() == 0) {\r
-            Output.add("0");\r
+            Output.add("\t0");\r
         }\r
         \r
         for (int index = 0; index < al.size(); index++) {\r
@@ -394,16 +556,15 @@ class SkuIdTable {
 \r
             Integer[] ia = al.get(index);\r
 \r
-            str += ia[0].toString() + ", ";\r
+            str += "\t" + ia[0].toString() + ", ";\r
             for (int index2 = 1; index2 < ia.length; index2++) {\r
                str += ia[index2].toString();\r
-               if (index != al.size() - 1) {\r
+               if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {\r
                    str += ", ";\r
                }\r
             }\r
 \r
             Output.add(str);\r
-            bodyLineNum++;\r
 \r
         }\r
 \r
@@ -415,9 +576,34 @@ class SkuIdTable {
     public int add (Token token) {\r
 \r
         int index;\r
+        int pos;\r
+        \r
+        //\r
+        // Check if this SKU_ID Array is already in the table\r
+        //\r
+        pos = 0;\r
+        for (Object o: al) {\r
+            Integer [] s = (Integer[]) o;\r
+            boolean different = false;\r
+            if (s[0] == token.getSkuIdCount()) {\r
+                for (index = 1; index < s.length; index++) {\r
+                    if (s[index] != token.skuData.get(index-1).id) {\r
+                        different = true;\r
+                        break;\r
+                    }\r
+                }\r
+            } else {\r
+                different = true;\r
+            }\r
+            if (different) {\r
+                pos += s[0] + 1;\r
+            } else {\r
+                return pos;\r
+            }\r
+        }\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
@@ -442,21 +628,18 @@ class LocalTokenNumberTable {
     private ArrayList<String>    alComment;\r
     private String               phase;\r
     private int                  len;\r
-    private int                   bodyStart;\r
-    private int                   bodyLineNum;\r
 \r
     public LocalTokenNumberTable (String phase) {\r
         this.phase = phase;\r
         al = new ArrayList<String>();\r
         alComment = new ArrayList<String>();\r
-        bodyStart = 0;\r
-        bodyLineNum = 0;\r
 \r
         len = 0;\r
     }\r
 \r
     public String getSizeMacro () {\r
-        return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize());\r
+       return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())\r
+                       + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());\r
     }\r
 \r
     public int getSize () {\r
@@ -467,6 +650,25 @@ class LocalTokenNumberTable {
         return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
     }\r
 \r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
+        final String name = "LocalTokenNumberTable";\r
+        \r
+        CStructTypeDeclaration decl;\r
+        String cCode = "";\r
+\r
+        cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase); \r
+        decl = new CStructTypeDeclaration (\r
+                                            name,\r
+                                            4,\r
+                                            cCode,\r
+                                            true\r
+                                           );  \r
+        declaList.add(decl);\r
+\r
+        cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
+        instTable.put(name, cCode);\r
+    }\r
+\r
     public String getTypeDeclaration () {\r
         return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);\r
     }\r
@@ -476,16 +678,15 @@ class LocalTokenNumberTable {
 \r
         output.add("/* LocalTokenNumberTable */");\r
         output.add("{");\r
-        bodyStart = 2;\r
 \r
         if (al.size() == 0) {\r
-            output.add("0");\r
+            output.add("\t0");\r
         }\r
         \r
         for (int index = 0; index < al.size(); index++) {\r
             String str;\r
 \r
-            str = (String)al.get(index);\r
+            str = "\t" + (String)al.get(index);\r
 \r
             str += " /* " + alComment.get(index) + " */ ";\r
 \r
@@ -498,8 +699,6 @@ class LocalTokenNumberTable {
 \r
         }\r
 \r
-        bodyLineNum = al.size();\r
-\r
         output.add("}");\r
 \r
         return output;\r
@@ -513,19 +712,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
@@ -554,15 +753,12 @@ class ExMapTable {
     private ArrayList<String>    alComment;\r
     private String               phase;\r
     private int                  len;\r
-    private int                   bodyStart;\r
     private int                   bodyLineNum;\r
-    private int                   base;\r
-\r
+    \r
     public ExMapTable (String phase) {\r
         this.phase = phase;\r
         al = new ArrayList<ExTriplet>();\r
         alComment = new ArrayList<String>();\r
-        bodyStart = 0;\r
         bodyLineNum = 0;\r
         len = 0;\r
     }\r
@@ -572,14 +768,32 @@ class ExMapTable {
              + String.format(PcdDatabase.ExTokenNumber, phase, al.size());\r
     }\r
 \r
-    private int getSize () {\r
-        return (al.size() == 0)? 1 : al.size();\r
-    }\r
-\r
     public String getExistanceMacro () {\r
         return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
     }\r
 \r
+    public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
+        final String exMapTableName = "ExMapTable";\r
+        \r
+        sortTable();\r
+        \r
+        CStructTypeDeclaration decl;\r
+        String cCode = "";\r
+\r
+        cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase); \r
+        decl = new CStructTypeDeclaration (\r
+                                            exMapTableName,\r
+                                            4,\r
+                                            cCode,\r
+                                            true\r
+                                           );  \r
+        declaList.add(decl);\r
+\r
+\r
+        cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
+        instTable.put(exMapTableName, cCode);\r
+    }\r
+    \r
     public String getTypeDeclaration () {\r
         return String.format(PcdDatabase.ExMapTableDeclaration, phase);\r
     }\r
@@ -589,10 +803,8 @@ class ExMapTable {
 \r
         Output.add("/* ExMapTable */");\r
         Output.add("{");\r
-        bodyStart = 2;\r
-\r
         if (al.size() == 0) {\r
-            Output.add("{0, 0, 0}");\r
+            Output.add("\t{0, 0, 0}");\r
         }\r
         \r
         int index;\r
@@ -601,11 +813,11 @@ class ExMapTable {
 \r
             ExTriplet e = (ExTriplet)al.get(index);\r
 \r
-            str = "{ " + e.exTokenNumber.toString() + ", ";\r
+            str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";\r
             str += e.localTokenIdx.toString() + ", ";\r
             str += e.guidTableIdx.toString();\r
 \r
-            str += " /* " + alComment.get(index) + " */";\r
+            str += "}" + " /* " + alComment.get(index) + " */" ;\r
 \r
             if (index != al.size() - 1) {\r
                 str += ",";\r
@@ -635,22 +847,54 @@ class ExMapTable {
         return al.size() == 0 ? 1 : al.size();\r
     }\r
 \r
+    //\r
+    // To simplify the algorithm for GetNextToken and GetNextTokenSpace in\r
+    // PCD PEIM/Driver, we need to sort the ExMapTable according to the\r
+    // following order:\r
+    // 1) ExGuid\r
+    // 2) ExTokenNumber\r
+    // \r
+    class ExTripletComp implements Comparator<ExTriplet> {\r
+        public int compare (ExTriplet a, ExTriplet b) {\r
+            if (a.guidTableIdx == b.guidTableIdx ) {\r
+                if (a.exTokenNumber > b.exTokenNumber) {\r
+                    return 1;\r
+                } else if (a.exTokenNumber > b.exTokenNumber) {\r
+                    return 1;\r
+                } else {\r
+                    return 0;\r
+                }\r
+            }\r
+            \r
+            return a.guidTableIdx - b.guidTableIdx;\r
+        }\r
+    }\r
+\r
+    private void sortTable () {\r
+        java.util.Comparator<ExTriplet> comparator = new ExTripletComp();\r
+        java.util.Collections.sort(al, comparator);\r
+    }\r
 }\r
 \r
 class PcdDatabase {\r
 \r
-    public final static String ExMapTableDeclaration            = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
-    public final static String GuidTableDeclaration             = "EFI_GUID          GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
-    public final static String LocalTokenNumberTableDeclaration = "UINT32            LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER];\r\n";\r
-    public final static String StringTableDeclaration           = "UINT16            StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
-    public final static String SizeTableDeclaration             = "UINT16            SizeTable[%s_LOCAL_TOKEN_NUMBER];\r\n";\r
-    public final static String SkuIdTableDeclaration              = "UINT8             SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
+    private final static int    SkuHeadAlignmentSize             = 4;\r
+    private final String        newLine                         = "\r\n";\r
+    private final String        commaNewLine                    = ",\r\n";\r
+    private final String        tab                             = "\t";\r
+    public final static String ExMapTableDeclaration            = "DYNAMICEX_MAPPING   ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
+    public final static String GuidTableDeclaration             = "EFI_GUID            GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
+    public final static String LocalTokenNumberTableDeclaration = "UINT32              LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
+    public final static String StringTableDeclaration           = "UINT16              StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
+    public final static String SizeTableDeclaration             = "UINT16              SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
+    public final static String SkuIdTableDeclaration            = "UINT8               SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
 \r
 \r
     public final static String ExMapTableSizeMacro              = "#define %s_EXMAPPING_TABLE_SIZE  %d\r\n";\r
     public final static String ExTokenNumber                    = "#define %s_EX_TOKEN_NUMBER       %d\r\n";\r
-    public final static String GuidTableSizeMacro               = "#define %s_GUID_TABLE_SIZE         %d\r\n";\r
-    public final static String LocalTokenNumberTableSizeMacro   = "#define %s_LOCAL_TOKEN_NUMBER            %d\r\n";\r
+    public final static String GuidTableSizeMacro               = "#define %s_GUID_TABLE_SIZE         %d\r\n"; \r
+    public final static String LocalTokenNumberTableSizeMacro   = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE            %d\r\n";\r
+    public final static String LocalTokenNumberSizeMacro               = "#define %s_LOCAL_TOKEN_NUMBER            %d\r\n";\r
     public final static String StringTableSizeMacro             = "#define %s_STRING_TABLE_SIZE       %d\r\n";\r
     public final static String SkuIdTableSizeMacro              = "#define %s_SKUID_TABLE_SIZE        %d\r\n";\r
 \r
@@ -662,7 +906,11 @@ class PcdDatabase {
     public final static String SkuTableExistenceMacro           = "#define %s_SKUID_TABLE_EMPTY    %s\r\n";\r
 \r
     public final static String offsetOfSkuHeadStrTemplate       = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";\r
+    public final static String offsetOfVariableEnabledDefault   = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";\r
     public final static String offsetOfStrTemplate              = "offsetof(%s_PCD_DATABASE, %s.%s)";\r
+    \r
+    private final static String  skuDataTableTemplate           = "SkuDataTable";\r
+\r
 \r
     private StringTable stringTable;\r
     private GuidTable   guidTable;\r
@@ -675,6 +923,12 @@ class PcdDatabase {
     private String phase;\r
     private int assignedTokenNumber;\r
     \r
+    //\r
+    // Use two class global variable to store\r
+    // temperary \r
+    //\r
+    private String      privateGlobalName;\r
+    private String      privateGlobalCCode;\r
     //\r
     // After Major changes done to the PCD\r
     // database generation class PcdDatabase\r
@@ -682,7 +936,7 @@ class PcdDatabase {
     // also update the version number in PCD\r
     // service PEIM and DXE driver accordingly.\r
     //\r
-    private final int version = 1;\r
+    private final int version = 2;\r
 \r
     private String hString;\r
     private String cString;\r
@@ -694,7 +948,7 @@ class PcdDatabase {
                     - getAlignmentSize(a);\r
         }\r
     }\r
-\r
+    \r
     public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {\r
        phase = exePhase;\r
 \r
@@ -705,10 +959,23 @@ class PcdDatabase {
        sizeTable = new SizeTable(phase);\r
        exMapTable = new ExMapTable(phase); \r
 \r
-       assignedTokenNumber = startLen;\r
+       assignedTokenNumber = startLen + 1;\r
        this.alTokens = alTokens;\r
     }\r
 \r
+    private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {\r
+        for (int i = 0; i < alTokens.size(); i++) {\r
+            Token t = (Token)alTokens.get(i);\r
+            if (t.isDynamicEx()) {\r
+                exTokens.add(t);\r
+            } else {\r
+                nexTokens.add(t);\r
+            }\r
+        }\r
+\r
+        return;\r
+    }\r
+\r
     private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {\r
         for (int i = 0; i < alTokens.size(); i++) {\r
             Token t = (Token)alTokens.get(i);\r
@@ -722,34 +989,63 @@ class PcdDatabase {
         return;\r
     }\r
 \r
+    private int getDataTypeAlignmentSize (Token token) {\r
+        switch (token.datumType) {\r
+        case UINT8:\r
+            return 1;\r
+        case UINT16:\r
+            return 2;\r
+        case UINT32:\r
+            return 4;\r
+        case UINT64:\r
+            return 8;\r
+        case POINTER:\r
+            return 1;\r
+        case BOOLEAN:\r
+            return 1;\r
+        default:\r
+            return 1;\r
+        }\r
+    }\r
+    \r
+    private int getHiiPtrTypeAlignmentSize(Token token) {\r
+        switch (token.datumType) {\r
+        case UINT8:\r
+            return 1;\r
+        case UINT16:\r
+            return 2;\r
+        case UINT32:\r
+            return 4;\r
+        case UINT64:\r
+            return 8;\r
+        case POINTER:\r
+            if (token.isHiiEnable()) {\r
+                if (token.isHiiDefaultValueUnicodeStringType()) {\r
+                    return 2;\r
+                }\r
+            }\r
+            return 1;\r
+        case BOOLEAN:\r
+            return 1;\r
+        default:\r
+            return 1;\r
+        }\r
+    }\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
-        switch (token.datumType) {\r
-            case UINT8:\r
-                return 1;\r
-            case UINT16:\r
-                return 2;\r
-            case UINT32:\r
-                return 4;\r
-            case UINT64:\r
-                return 8;\r
-            case POINTER:\r
-                return 1;\r
-            case BOOLEAN:\r
-                return 1;\r
-            }\r
-            return 1;\r
+        \r
+        return getDataTypeAlignmentSize(token);\r
      }\r
 \r
     public String getCString () {\r
@@ -759,47 +1055,122 @@ class PcdDatabase {
     public String getHString () {\r
         return hString;\r
     }\r
+    \r
+    private void genCodeWorker(Token t,\r
+            ArrayList<CStructTypeDeclaration> declaList,\r
+            HashMap<String, String> instTable, String phase)\r
+            throws EntityException {\r
 \r
-     public void genCode () {\r
+        CStructTypeDeclaration decl;\r
 \r
-        final String newLine                        = "\r\n";\r
-        final String declNewLine                    = ";\r\n";\r
-        final String tab                            = "\t";\r
-        final String commaNewLine                   = ", \r\n";\r
+        //\r
+        // Insert SKU_HEAD if isSkuEnable is true\r
+        //\r
+        if (t.isSkuEnable()) {\r
+            int tableIdx;\r
+            tableIdx = skuIdTable.add(t);\r
+            decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
+                    SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
+            declaList.add(decl);\r
+            instTable.put(t.getPrimaryKeyString(),\r
+                    getSkuEnabledTypeInstantiaion(t, tableIdx));\r
+        }\r
 \r
-        int i;\r
-        ArrayList<String> decla;\r
-        ArrayList<String> inst;\r
+        //\r
+        // Insert PCD_ENTRY declaration and instantiation\r
+        //\r
+        getCDeclarationString(t);\r
 \r
-        String macroStr   = "";\r
-        String initDeclStr = "";\r
-        String initInstStr = "";\r
-        String uninitDeclStr = "";\r
+        decl = new CStructTypeDeclaration(privateGlobalName,\r
+                getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
+        declaList.add(decl);\r
 \r
-        List<Token> initTokens = new ArrayList<Token> ();\r
-        List<Token> uninitTokens = new ArrayList<Token> ();\r
+        if (t.hasDefaultValue()) {\r
+            instTable.put(privateGlobalName, \r
+                          getTypeInstantiation(t, declaList, instTable, phase)\r
+                          );\r
+        }\r
+\r
+    }\r
+\r
+    private void ProcessTokensNew (List<Token> tokens, \r
+                                   ArrayList<CStructTypeDeclaration> cStructDeclList,\r
+                                   HashMap<String, String> cStructInstTable,\r
+                                   String phase\r
+                                   ) \r
+    throws EntityException {\r
         \r
-        HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();\r
-        HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();\r
+        for (int idx = 0; idx < tokens.size(); idx++) {\r
+            Token t = tokens.get(idx);\r
+            \r
+            genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
+            \r
+            sizeTable.add(t);\r
+            localTokenNumberTable.add(t);\r
+            t.tokenNumber = assignedTokenNumber++;\r
+            \r
+            //\r
+            // Add a mapping if this dynamic PCD entry is a EX type\r
+            //\r
+            if (t.isDynamicEx()) {\r
+                exMapTable.add((int)t.tokenNumber, \r
+                                t.dynamicExTokenNumber, \r
+                                guidTable.add(t.tokenSpaceName, t.getPrimaryKeyString()), \r
+                                t.getPrimaryKeyString()\r
+                                );\r
+            }\r
+        }\r
 \r
-        getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);\r
+    }\r
+    \r
+    public void genCodeNew () throws EntityException {\r
+        \r
+        ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
+        HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
+        \r
+        List<Token> nexTokens = new ArrayList<Token> ();\r
+        List<Token> exTokens = new ArrayList<Token> ();\r
 \r
-        //\r
-        // Generate Structure Declaration for PcdTokens without Default Value\r
-        // PEI_PCD_DATABASE_INIT\r
-        //\r
-        java.util.Comparator comparator = new AlignmentSizeComp();\r
-        List<Token> list = initTokens;\r
-        java.util.Collections.sort(list, comparator);\r
-        initCode = processTokens(initTokens);\r
+        getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
 \r
         //\r
-        // Generate Structure Declaration for PcdTokens without Default Value\r
-        // PEI_PCD_DATABASE_UNINIT\r
+        // We have to process Non-Ex type PCD entry first. The reason is\r
+        // that our optimization assumes that the Token Number of Non-Ex \r
+        // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
+        // \r
+        // EX type token number starts from the last Non-EX PCD entry and\r
+        // grows continously upwards.\r
         //\r
-        list = uninitTokens;\r
-        java.util.Collections.sort(list, comparator);\r
-        uninitCode = processTokens(uninitTokens);\r
+        ProcessTokensNew (nexTokens, cStructDeclList, cStructInstTable, phase);\r
+        ProcessTokensNew (exTokens, cStructDeclList, cStructInstTable, phase);\r
+        \r
+        stringTable.genCodeNew(cStructDeclList, cStructInstTable);\r
+        skuIdTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
+        exMapTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
+        localTokenNumberTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
+        sizeTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
+        guidTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
+        \r
+        hString = genCMacroCode ();\r
+        \r
+        HashMap <String, String> result;\r
+        \r
+        result = genCStructCode(cStructDeclList, \r
+                cStructInstTable, \r
+                phase\r
+                );\r
+        \r
+        hString += result.get("initDeclStr");\r
+        hString += result.get("uninitDeclStr");\r
+        \r
+        hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION         %d", phase, version);\r
+        \r
+        cString = newLine + newLine + result.get("initInstStr");\r
+        \r
+    }\r
+    \r
+    private String genCMacroCode () {\r
+        String macroStr   = "";\r
 \r
         //\r
         // Generate size info Macro for all Tables\r
@@ -819,24 +1190,177 @@ class PcdDatabase {
         macroStr += localTokenNumberTable.getExistanceMacro();\r
         macroStr += exMapTable.getExistanceMacro();\r
 \r
+        macroStr += newLine;\r
+        \r
+        return macroStr;\r
+    }\r
+    \r
+    private HashMap <String, String> genCStructCode(\r
+                                            ArrayList<CStructTypeDeclaration> declaList, \r
+                                            HashMap<String, String> instTable, \r
+                                            String phase\r
+                                            ) {\r
+        \r
+        int i;\r
+        HashMap <String, String> result = new HashMap<String, String>();\r
+        HashMap <Integer, ArrayList<String>>    alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
+        HashMap <Integer, ArrayList<String>>    alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
+        HashMap <Integer, ArrayList<String>>    alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
+        \r
         //\r
-        // Generate Structure Declaration for PcdTokens with Default Value\r
-        // for example PEI_PCD_DATABASE_INIT\r
+        // Initialize the storage for each alignment\r
         //\r
-        initDeclStr += "typedef struct {" + newLine;\r
-            {\r
-                initDeclStr += tab + exMapTable.getTypeDeclaration();\r
-                initDeclStr += tab + guidTable.getTypeDeclaration();\r
-                initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();\r
-                initDeclStr += tab + stringTable.getTypeDeclaration();\r
-                initDeclStr += tab + sizeTable.getTypeDeclaration();\r
-                initDeclStr += tab + skuIdTable.getTypeDeclaration();\r
-                if (phase.equalsIgnoreCase("PEI")) {\r
-                    initDeclStr += tab + "SKU_ID            SystemSkuId;" + newLine;\r
-                }\r
+        for (i = 8; i > 0; i>>=1) {\r
+            alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
+            alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
+            alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
+        }\r
+        \r
+        String initDeclStr   = "typedef struct {" + newLine;\r
+        String initInstStr   = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
+        String uninitDeclStr = "typedef struct {" + newLine;\r
 \r
-                decla = initCode.get(new String("Declaration"));\r
-                for (i = 0; i < decla.size(); i++)  {\r
+        //\r
+        // Sort all C declaration and instantiation base on Alignment Size \r
+        //\r
+        for (Object d : declaList) {\r
+            CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
+            \r
+            if (decl.initTable) {\r
+                alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
+                alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
+            } else {\r
+                alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
+            }\r
+        }\r
+\r
+        //\r
+        // Generate code for every alignment size\r
+        //\r
+        boolean uinitDatabaseEmpty = true;\r
+        for (int align = 8; align > 0; align >>= 1) {\r
+            ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
+            ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
+            for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
+                initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
+                initInstStr += tab + instListBasedOnAlignment.get(i);\r
+                \r
+                //\r
+                // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
+                // has a least one data memember with alignment size of 1. So we can\r
+                // remove the last "," in the C structure instantiation string. Luckily,\r
+                // this is true as both data structure has SKUID_TABLE anyway.\r
+                //\r
+                if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
+                    initInstStr += newLine;\r
+                } else {\r
+                    initInstStr += commaNewLine;\r
+                }\r
+            }\r
+            \r
+            declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
+            \r
+            if (declaListBasedOnAlignment.size() != 0) {\r
+                uinitDatabaseEmpty = false;\r
+            }\r
+            \r
+            for (Object d : declaListBasedOnAlignment) {\r
+                String s = (String)d;\r
+                uninitDeclStr += tab + s;\r
+            }\r
+        }\r
+        \r
+        if (uinitDatabaseEmpty) {\r
+            uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
+        }\r
+        \r
+        initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
+        initInstStr += "};" + newLine;\r
+        uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
+        \r
+        result.put("initDeclStr", initDeclStr);\r
+        result.put("initInstStr", initInstStr);\r
+        result.put("uninitDeclStr", uninitDeclStr);\r
+\r
+        return result;\r
+    }\r
+\r
+     public void genCode () \r
+        throws EntityException {\r
+\r
+        final String newLine                        = "\r\n";\r
+        final String declNewLine                    = ";\r\n";\r
+        final String tab                            = "\t";\r
+        final String commaNewLine                   = ", \r\n";\r
+\r
+        int i;\r
+        ArrayList<String> decla;\r
+        ArrayList<String> inst;\r
+\r
+        String macroStr   = "";\r
+        String initDeclStr = "";\r
+        String initInstStr = "";\r
+        String uninitDeclStr = "";\r
+\r
+        List<Token> initTokens = new ArrayList<Token> ();\r
+        List<Token> uninitTokens = new ArrayList<Token> ();\r
+        \r
+        HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();\r
+        HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();\r
+\r
+        getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);\r
+\r
+        //\r
+        // Generate Structure Declaration for PcdTokens without Default Value\r
+        // PEI_PCD_DATABASE_INIT\r
+        //\r
+        java.util.Comparator<Token> comparator = new AlignmentSizeComp();\r
+        java.util.Collections.sort(initTokens, comparator);\r
+        initCode = processTokens(initTokens);\r
+\r
+        //\r
+        // Generate Structure Declaration for PcdTokens without Default Value\r
+        // PEI_PCD_DATABASE_UNINIT\r
+        //\r
+        java.util.Collections.sort(uninitTokens, comparator);\r
+        uninitCode = processTokens(uninitTokens);\r
+\r
+        //\r
+        // Generate size info Macro for all Tables\r
+        //\r
+        macroStr += guidTable.getSizeMacro();\r
+        macroStr += stringTable.getSizeMacro();\r
+        macroStr += skuIdTable.getSizeMacro();\r
+        macroStr += localTokenNumberTable.getSizeMacro();\r
+        macroStr += exMapTable.getSizeMacro();\r
+\r
+        //\r
+        // Generate existance info Macro for all Tables\r
+        //\r
+        macroStr += guidTable.getExistanceMacro();\r
+        macroStr += stringTable.getExistanceMacro();\r
+        macroStr += skuIdTable.getExistanceMacro();\r
+        macroStr += localTokenNumberTable.getExistanceMacro();\r
+        macroStr += exMapTable.getExistanceMacro();\r
+\r
+        //\r
+        // Generate Structure Declaration for PcdTokens with Default Value\r
+        // for example PEI_PCD_DATABASE_INIT\r
+        //\r
+        initDeclStr += "typedef struct {" + newLine;\r
+            {\r
+                initDeclStr += tab + exMapTable.getTypeDeclaration();\r
+                initDeclStr += tab + guidTable.getTypeDeclaration();\r
+                initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();\r
+                initDeclStr += tab + stringTable.getTypeDeclaration();\r
+                initDeclStr += tab + sizeTable.getTypeDeclaration();\r
+                initDeclStr += tab + skuIdTable.getTypeDeclaration();\r
+                if (phase.equalsIgnoreCase("PEI")) {\r
+                    initDeclStr += tab + "SKU_ID            SystemSkuId;" + newLine;\r
+                }\r
+\r
+                decla = initCode.get(new String("Declaration"));\r
+                for (i = 0; i < decla.size(); i++)  {\r
                     initDeclStr += tab + decla.get(i) + declNewLine;\r
                 }\r
 \r
@@ -914,10 +1438,13 @@ class PcdDatabase {
 \r
     }\r
 \r
-    private String genInstantiationStr (ArrayList<String> alStr) {\r
+    public static String genInstantiationStr (ArrayList<String> alStr) {\r
         String str = "";\r
         for (int i = 0; i< alStr.size(); i++) {\r
-            str += "\t" + alStr.get(i);\r
+            if (i != 0) {\r
+                str += "\t";\r
+            }\r
+            str += alStr.get(i);\r
             if (i != alStr.size() - 1) {\r
                 str += "\r\n";\r
             }\r
@@ -926,7 +1453,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
@@ -938,7 +1466,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
@@ -957,13 +1485,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
@@ -977,7 +1505,7 @@ class PcdDatabase {
 \r
             sizeTable.add(token);\r
             localTokenNumberTable.add(token);\r
-            token.assignedtokenNumber = assignedTokenNumber++;\r
+            token.tokenNumber = assignedTokenNumber++;\r
 \r
         }\r
 \r
@@ -990,13 +1518,13 @@ class PcdDatabase {
     }\r
 \r
     private String getSkuEnabledTypeDeclaration (Token token) {\r
-        return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());\r
+        return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
     }\r
 \r
     private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
 \r
         String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
-        return String.format("{ %s, %d }", offsetof, SkuTableIdx);\r
+        return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
     }\r
 \r
     private String getDataTypeDeclarationForSkuEnabled (Token token) {\r
@@ -1013,10 +1541,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
@@ -1024,12 +1552,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
@@ -1040,16 +1568,120 @@ class PcdDatabase {
 \r
     }\r
 \r
+    private String getDataTypeInstantiationForVariableDefault_new (Token token, String cName, int skuId) {\r
+        return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
+    }\r
+\r
     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.getDefaultSku().value, token.getPrimaryKeyString());\r
+        }\r
+    }\r
+\r
+    private String getCType (Token t) \r
+        throws EntityException {\r
+        \r
+        if (t.isHiiEnable()) {\r
+            return "VARIABLE_HEAD";\r
+        }\r
+        \r
+        if (t.isVpdEnable()) {\r
+            return "VPD_HEAD";\r
+        }\r
+        \r
+        if (t.isUnicodeStringType()) {\r
+            return "STRING_HEAD";\r
+        }\r
+        \r
+        switch (t.datumType) {\r
+        case UINT64:\r
+            return "UINT64";\r
+        case UINT32:\r
+            return "UINT32";\r
+        case UINT16:\r
+            return "UINT16";\r
+        case UINT8:\r
+            return "UINT8";\r
+        case BOOLEAN:\r
+            return "BOOLEAN";\r
+        case POINTER:\r
+            return "UINT8";\r
+        default:\r
+            throw new EntityException("Unknown type in getDataTypeCDeclaration");\r
+        }\r
+    }\r
+    \r
+    private void getCDeclarationString(Token t) \r
+        throws EntityException {\r
+        \r
+        if (t.isSkuEnable()) {\r
+            privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
         } else {\r
-            return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());\r
+            privateGlobalName = t.getPrimaryKeyString();\r
+        }\r
+\r
+        String type = getCType(t);\r
+        if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable())) {\r
+            int bufferSize;\r
+            if (t.isASCIIStringType()) {\r
+                //\r
+                // Build tool will add a NULL string at the end of the ASCII string\r
+                //\r
+                bufferSize = t.datumSize + 1;\r
+            } else {\r
+                bufferSize = t.datumSize;\r
+            }\r
+            privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
+        } else {\r
+            privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
         }\r
     }\r
+    \r
+    private String getDataTypeDeclarationForVariableDefault_new (Token token, String cName, int skuId) \r
+    throws EntityException {\r
 \r
+        String typeStr;\r
 \r
+        if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
+            typeStr = "UINT8";\r
+        } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
+            typeStr = "UINT16";\r
+        } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
+            typeStr = "UINT32";\r
+        } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
+            typeStr = "UINT64";\r
+        } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
+            typeStr = "BOOLEAN";\r
+        } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
+            int size;\r
+            if (token.isHiiDefaultValueUnicodeStringType()) {\r
+                typeStr = "UINT16";\r
+                //\r
+                // Include the NULL charactor\r
+                //\r
+                size = token.datumSize / 2 + 1;\r
+            } else {\r
+                typeStr = "UINT8";\r
+                if (token.isHiiDefaultValueASCIIStringType()) {\r
+                    //\r
+                    // Include the NULL charactor\r
+                    //\r
+                    size = token.datumSize + 1;\r
+                } else {\r
+                    size = token.datumSize;\r
+                }\r
+            }\r
+            return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
+        } else {\r
+            throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
+        }\r
+\r
+        return String.format("%-20s%s;\r\n", typeStr, cName);\r
+    }\r
+    \r
     private String getDataTypeDeclaration (Token token) {\r
 \r
         String typeStr = "";\r
@@ -1075,9 +1707,77 @@ class PcdDatabase {
     private String getVpdEnableTypeDeclaration (Token token) {\r
         return String.format("VPD_HEAD %s", token.getPrimaryKeyString());\r
     }\r
+    \r
+    private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
+      \r
+        int     i;\r
+\r
+        String s;\r
+        s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
+        s += tab + "{" + newLine;\r
+\r
+        for (i = 0; i < t.skuData.size(); i++) {\r
+            if (t.isUnicodeStringType()) {\r
+                s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
+            } else if (t.isHiiEnable()) {\r
+                /* VPD_HEAD definition\r
+                   typedef struct {\r
+                      UINT16  GuidTableIndex;   // Offset in Guid Table in units of GUID.\r
+                      UINT16  StringIndex;      // Offset in String Table in units of UINT16.\r
+                      UINT16  Offset;           // Offset in Variable\r
+                      UINT16  DefaultValueOffset; // Offset of the Default Value\r
+                    } VARIABLE_HEAD  ;\r
+                 */\r
+                String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i); \r
+                \r
+                s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
+                                                          stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
+                                                          t.skuData.get(i).value.variableOffset,\r
+                                                          String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
+                                                          );\r
+                //\r
+                // We need to support the default value, so we add the declaration and\r
+                // the instantiation for the default value.\r
+                //\r
+                CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
+                                                        getHiiPtrTypeAlignmentSize(t),\r
+                                                        getDataTypeDeclarationForVariableDefault_new(t, variableDefaultName, i),\r
+                                                        true\r
+                                                        ); \r
+                declaList.add(decl);\r
+                instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault_new (t, variableDefaultName, i));\r
+            } else if (t.isVpdEnable()) {\r
+                    /* typedef  struct {\r
+                        UINT32  Offset;\r
+                      } VPD_HEAD;\r
+                    */\r
+                s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
+            } else {\r
+                if (t.isByteStreamType()) {\r
+                    //\r
+                    // Byte stream type input has their own "{" "}", so we won't help to insert.\r
+                    //\r
+                    s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
+                } else {\r
+                    s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
+                }\r
+            }\r
+            \r
+            if (i != t.skuData.size() - 1) {\r
+                s += commaNewLine;\r
+            } else {\r
+                s += newLine;\r
+            }\r
 \r
+        }\r
+        \r
+        s += tab + "}";\r
+        \r
+        return s;\r
+    }\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
@@ -1095,10 +1795,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
@@ -1116,7 +1820,6 @@ class PcdDatabase {
                                  "Conf" + File.separator +\r
                                  "Pcd" + File.separator +\r
                                  "PcdDatabaseCommonDefinitions.sample");\r
-            System.out.println(GlobalData.getWorkspacePath());\r
             FileReader reader = new FileReader(file);\r
             BufferedReader  in = new BufferedReader(reader);\r
             String str;\r
@@ -1178,6 +1881,29 @@ class PcdDatabase {
 \r
 }\r
 \r
+class ModuleInfo {\r
+    private String                  type;\r
+    private FpdModuleIdentification moduleId;\r
+    private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;\r
+    \r
+    \r
+\r
+    public ModuleInfo (FpdModuleIdentification moduleId, String type, XmlObject pcdDef) {\r
+        this.moduleId = moduleId;\r
+        this.type   = type;\r
+        this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();\r
+    }\r
+    public String getModuleType (){\r
+       return this.type;\r
+    }\r
+    public FpdModuleIdentification getModuleId (){\r
+       return this.moduleId;\r
+    }\r
+    public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){\r
+       return this.pcdBuildDef;\r
+    }\r
+}\r
+\r
 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
     This class will be used for wizard and build tools, So it can *not* inherit\r
     from buildAction or UIAction.\r
@@ -1195,6 +1921,12 @@ public class CollectPCDAction {
     /// Message level for CollectPCDAction.\r
     private int                   originalMessageLevel;\r
 \r
+    /// Cache the fpd docment instance for private usage.\r
+    private PlatformSurfaceAreaDocument fpdDocInstance;\r
+    \r
+    /// xmlObject name\r
+    private static String xmlObjectName = "PcdBuildDefinition"; \r
+       \r
     /**\r
       Set WorkspacePath parameter for this action class.\r
 \r
@@ -1250,103 +1982,33 @@ public class CollectPCDAction {
       Core execution function for this action class.\r
      \r
       This function work flows will be:\r
-      1) Get all token's platform information from FPD, and create token object into memory database.\r
-      2) Get all token's module information from MSA, and create usage instance for every module's PCD entry.\r
-      3) Get all token's inherited information from MSA's library, and create usage instance \r
-         for module who consume this library and create usage instance for library for building.\r
-      4) Collect token's package information from SPD, update these information for token in memory\r
-         database.\r
-      5) Generate 3 strings for a) All modules using Dynamic(Ex) PCD entry. (Token Number)\r
-                                b) PEI PCD Database (C Structure) for PCD Service PEIM\r
-                                c) DXE PCD Database (C structure) for PCD Service DXE\r
+      1) Collect and prepocess PCD information from FPD file, all PCD\r
+      information will be stored into memory database.\r
+      2) Generate 3 strings for\r
+        a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
+        b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
+        c) DXE PCD Database (C structure) for PCD Service DXE.\r
                                 \r
       \r
       @throws  EntityException Exception indicate failed to execute this action.\r
       \r
     **/\r
-    private void execute() throws EntityException {\r
-        FrameworkPlatformDescriptionDocument fpdDoc               = null;\r
-        Object[][]                           modulePCDArray       = null;\r
-        Map<String, XmlObject>               docMap               = null;\r
-        ModuleSADocument.ModuleSA[]          moduleSAs            = null;\r
-        UsageInstance                        usageInstance        = null;\r
-        String                               packageName          = null;\r
-        String                               packageFullPath      = null;\r
-        int                                  index                = 0;\r
-        int                                  libraryIndex         = 0;\r
-        int                                  pcdArrayIndex        = 0;\r
-        List<String>                         listLibraryInstance  = null;\r
-        String                               componentTypeStr     = null;\r
+    public void execute() throws EntityException {\r
+        //\r
+        // Get memoryDatabaseManager instance from GlobalData.\r
+        // The memoryDatabaseManager should be initialized for whatever build\r
+        // tools or wizard tools\r
+        //\r
+        if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
+            throw new EntityException("The instance of PCD memory database manager is null");\r
+        }\r
 \r
         //\r
         // Collect all PCD information defined in FPD file.\r
         // Evenry token defind in FPD will be created as an token into \r
         // memory database.\r
         //\r
-        fpdDoc = createTokenInDBFromFPD();\r
-\r
-        //\r
-        // Searching MSA and SPD document. \r
-        // The information of MSA will be used to create usage instance into database.\r
-        // The information of SPD will be used to update the token information in database.\r
-        //\r
-\r
-        HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();\r
-        map.put("FrameworkPlatformDescription", fpdDoc);\r
-        SurfaceAreaQuery.setDoc(map);    \r
-\r
-        moduleSAs = SurfaceAreaQuery.getFpdModules();\r
-        for(index = 0; index < moduleSAs.length; index ++) {\r
-            //\r
-            // Get module document and use SurfaceAreaQuery to get PCD information\r
-            //\r
-            docMap = GlobalData.getDoc(moduleSAs[index].getModuleName());\r
-            SurfaceAreaQuery.setDoc(docMap);\r
-            modulePCDArray    = SurfaceAreaQuery.getModulePCDTokenArray();\r
-            componentTypeStr  = SurfaceAreaQuery.getComponentType();\r
-            packageName       = \r
-                GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName());\r
-            packageFullPath   = this.workspacePath + File.separator    +\r
-                                GlobalData.getPackagePath(packageName) +\r
-                                packageName + ".spd";\r
-\r
-            if(modulePCDArray != null) {\r
-                //\r
-                // If current MSA contains <PCDs> information, then create usage\r
-                // instance for PCD information from MSA\r
-                //\r
-                for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length; \r
-                     pcdArrayIndex ++) {\r
-                    usageInstance = \r
-                        createUsageInstanceFromMSA(moduleSAs[index].getModuleName(),\r
-                                                   modulePCDArray[pcdArrayIndex]);\r
-\r
-                    if(usageInstance == null) {\r
-                        continue;\r
-                    }\r
-                    //\r
-                    // Get remaining PCD information from the package which this module belongs to\r
-                    //\r
-                    updateTokenBySPD(usageInstance, packageFullPath);\r
-                }\r
-            }\r
-\r
-            //\r
-            // Get inherit PCD information which inherit from library instance of this module.\r
-            //\r
-            listLibraryInstance = \r
-                SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(),\r
-                                                    CommonDefinition.AlwaysConsumed);\r
-            if(listLibraryInstance != null) {\r
-                for(libraryIndex = 0; libraryIndex < listLibraryInstance.size(); \r
-                     libraryIndex ++) {\r
-                    inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex),\r
-                                                  moduleSAs[index].getModuleName(),\r
-                                                  packageName,\r
-                                                  componentTypeStr);\r
-                }\r
-            }\r
-        }\r
+        createTokenInDBFromFPD();\r
         \r
         //\r
         // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver\r
@@ -1363,9 +2025,8 @@ public class CollectPCDAction {
       @throws EntityException  If the token does *not* exist in memory database.\r
 \r
     **/\r
-\r
-    private void genPcdDatabaseSourceCode     ()\r
-      throws EntityException {\r
+    private void genPcdDatabaseSourceCode()\r
+        throws EntityException {\r
         String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();\r
 \r
         ArrayList<Token> alPei = new ArrayList<Token> ();\r
@@ -1373,440 +2034,1069 @@ public class CollectPCDAction {
 \r
         dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
         PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
-        pcdPeiDatabase.genCode();\r
-        dbManager.PcdPeimHString        = PcdCommonHeaderString + pcdPeiDatabase.getHString()\r
+        pcdPeiDatabase.genCodeNew();\r
+        MemoryDatabaseManager.PcdPeimHString        = PcdCommonHeaderString + pcdPeiDatabase.getHString()\r
                                             + PcdDatabase.getPcdPeiDatabaseDefinitions();\r
-        dbManager.PcdPeimCString        = pcdPeiDatabase.getCString();\r
+        MemoryDatabaseManager.PcdPeimCString        = pcdPeiDatabase.getCString();\r
 \r
         PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe, \r
                                                       "DXE",\r
                                                       alPei.size()\r
                                                       );\r
-        pcdDxeDatabase.genCode();\r
-        dbManager.PcdDxeHString   = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()\r
+        pcdDxeDatabase.genCodeNew();\r
+        MemoryDatabaseManager.PcdDxeHString   = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString()\r
                                       + PcdDatabase.getPcdDxeDatabaseDefinitions();\r
-        dbManager.PcdDxeCString   = pcdDxeDatabase.getCString();\r
+        MemoryDatabaseManager.PcdDxeCString   = pcdDxeDatabase.getCString();\r
     }\r
 \r
     /**\r
-      This function will collect inherit PCD information from library for a module.\r
-     \r
-      This function will create two usage instance for inherited PCD token, one is \r
-      for module and another is for library.\r
-      For module, if it inherited a PCD token from library, this PCD token's value \r
-      should be instanced in module level, and belongs to module.\r
-      For library, it also need a usage instance for build.\r
+      Get component array from FPD.\r
       \r
-      @param libraryName         The name of library instance.\r
-      @param moduleName          The name of module.\r
-      @param packageName         The name of package while module belongs to.\r
-      @param parentcomponentType The component type of module.\r
+      This function maybe provided by some Global class.\r
       \r
-      @throws EntityException  If the token does *not* exist in memory database.\r
+      @return List<ModuleInfo> the component array.\r
+      \r
+     */\r
+    private List<ModuleInfo> getComponentsFromFPD() \r
+        throws EntityException {\r
+        List<ModuleInfo>            allModules  = new ArrayList<ModuleInfo>();\r
+        ModuleInfo                  current     = null;\r
+        int                         index       = 0;\r
+        FrameworkModulesDocument.FrameworkModules fModules = null;\r
+        ModuleSADocument.ModuleSA[]               modules  = null;\r
+        HashMap<String, XmlObject>                map      = new HashMap<String, XmlObject>();\r
+\r
+        if (fpdDocInstance == null) {\r
+            try {\r
+                fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
+            } catch(IOException ioE) {\r
+                throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+            } catch(XmlException xmlE) {\r
+                throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
+            }\r
+\r
+        }\r
+\r
+        Map<FpdModuleIdentification,XmlObject>pcdBuildDef = GlobalData.getFpdModuleSaXmlObject(CollectPCDAction.xmlObjectName);\r
+        Set<FpdModuleIdentification> pcdBuildKeySet = pcdBuildDef.keySet();\r
+        Iterator item = pcdBuildKeySet.iterator();\r
+        while (item.hasNext()){\r
+            FpdModuleIdentification id = (FpdModuleIdentification)item.next();\r
+            allModules.add(new ModuleInfo(id, id.getModule().getModuleType(),pcdBuildDef.get(id)));    \r
+        }\r
+        \r
+        return allModules;\r
+    }\r
+\r
+    /**\r
+      Create token instance object into memory database, the token information\r
+      comes for FPD file. Normally, FPD file will contain all token platform \r
+      informations.\r
+      \r
+      @return FrameworkPlatformDescriptionDocument   The FPD document instance for furture usage.\r
+      \r
+      @throws EntityException                        Failed to parse FPD xml file.\r
       \r
     **/\r
-    private void inheritPCDFromLibraryInstance(String libraryName,\r
-                                               String moduleName,\r
-                                               String packageName,\r
-                                               String parentcomponentType) \r
+    private void createTokenInDBFromFPD() \r
         throws EntityException {\r
-        Map<String, XmlObject>  docMap            = null;\r
-        String                  primaryKeyString  = null;\r
-        Object[][]              libPcdDataArray   = null;\r
-        UUID                    nullUUID          = new UUID(0,0);\r
-        UUID                    platformUUID      = nullUUID;\r
-        UUID                    tokenSpaceGuid    = null;\r
-        int                     tokenIndex        = 0;\r
-        Token                   token             = null;\r
-        Token.PCD_TYPE          pcdType           = Token.PCD_TYPE.UNKNOWN;\r
-        UsageInstance           usageInstance     = null;\r
-        String                  packageFullPath   = null;\r
+        int                                 index             = 0;\r
+        int                                 index2            = 0;\r
+        int                                 pcdIndex          = 0;\r
+        List<PcdBuildDefinition.PcdData>    pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
+        PcdBuildDefinition.PcdData          pcdBuildData      = null;\r
+        Token                               token             = null;\r
+        SkuInstance                         skuInstance       = null;\r
+        int                                 skuIndex          = 0;\r
+        List<ModuleInfo>                    modules           = null;\r
+        String                              primaryKey        = null;\r
+        String                              exceptionString   = null;\r
+        UsageInstance                       usageInstance     = null;\r
+        String                              primaryKey1       = null;\r
+        String                              primaryKey2       = null;\r
+        boolean                             isDuplicate       = false;\r
+        Token.PCD_TYPE                      pcdType           = Token.PCD_TYPE.UNKNOWN;\r
+        Token.DATUM_TYPE                    datumType         = Token.DATUM_TYPE.UNKNOWN;\r
+        long                                tokenNumber       = 0;\r
+        String                              moduleName        = null;\r
+        String                              datum             = null;\r
+        int                                 maxDatumSize      = 0;\r
+        String[]                            tokenSpaceStrRet  = null;\r
 \r
         //\r
-        // Query PCD information from library's document.\r
-        //\r
-        docMap          = GlobalData.getDoc(libraryName);\r
-        SurfaceAreaQuery.setDoc(docMap);\r
-        libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray();\r
+        // ----------------------------------------------\r
+        // 1), Get all <ModuleSA> from FPD file.\r
+        // ----------------------------------------------\r
+        // \r
+        modules = getComponentsFromFPD();\r
 \r
-        if(libPcdDataArray == null) {\r
-            return;\r
+        if (modules == null) {\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
-        for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) {\r
-            tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ? \r
-                             nullUUID :(UUID)libPcdDataArray[tokenIndex][2];\r
+        //\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
+            for (index2 = 0; index2 < index; index2 ++) {\r
+                //\r
+                // BUGBUG: For transition schema, we can *not* get module's version from \r
+                // <ModuleSAs>, It is work around code.\r
+                // \r
+                primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).getModuleId().getModule().getName(), \r
+                                                          null,\r
+                                                          null,\r
+                                                          null, \r
+                                                          modules.get(index).getModuleId().getArch(),\r
+                                                          null);\r
+                primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).getModuleId().getModule().getName(), \r
+                                                          null, \r
+                                                          null, \r
+                                                          null, \r
+                                                          modules.get(index2).getModuleId().getArch(), \r
+                                                          null);\r
+                if (primaryKey1.equalsIgnoreCase(primaryKey2)) {\r
+                    isDuplicate = true;\r
+                    break;\r
+                }\r
+            }\r
 \r
-            //\r
-            // Get token from memory database. The token must be created from FPD already.\r
-            //\r
-            primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0],\r
-                                                         tokenSpaceGuid,\r
-                                                         platformUUID\r
-                                                         );\r
+            if (isDuplicate) {\r
+                continue;\r
+            }\r
 \r
-            if(dbManager.isTokenInDatabase(primaryKeyString)) {\r
-                token = dbManager.getTokenByKey(primaryKeyString);\r
-            } else {\r
-                throw new EntityException("The PCD token " + primaryKeyString + \r
-                                          " defined in module " + moduleName + \r
-                                          " does not exist in FPD file!");\r
-            }      \r
+           //\r
+           // It is legal for a module does not contains ANY pcd build definitions.\r
+           // \r
+           if (modules.get(index).getPcdBuildDef() == null) {\r
+                continue;\r
+           }\r
+    \r
+            pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();\r
+\r
+            moduleName = modules.get(index).getModuleId().getModule().getName();\r
 \r
             //\r
-            // Create usage instance for module.\r
-            //\r
-            pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]);\r
-            usageInstance = new UsageInstance(token,\r
-                                              Token.PCD_USAGE.ALWAYS_CONSUMED,\r
-                                              pcdType,\r
-                                              CommonDefinition.getComponentType(parentcomponentType),\r
-                                              libPcdDataArray[tokenIndex][3],\r
-                                              null,\r
-                                             (String) libPcdDataArray[tokenIndex][5],\r
-                                              "",\r
-                                              moduleName,\r
-                                              packageName,\r
-                                              true);\r
-            if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) {\r
-                token.addUsageInstance(usageInstance);\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
+                \r
+                try {\r
+                    tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
+                } catch ( Exception e ) {\r
+                    throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
+                }\r
 \r
-                packageFullPath = this.workspacePath + File.separator    +\r
-                                  GlobalData.getPackagePath(packageName) +\r
-                                  packageName + ".spd";\r
-                updateTokenBySPD(usageInstance, packageFullPath);\r
-            }\r
+                if (tokenSpaceStrRet == null) {\r
+                    throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
+                } \r
+\r
+                primaryKey   = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
+                                                         translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
+                pcdType      = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
+                datumType    = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
+                tokenNumber  = Long.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
-            // We need create second usage instance for inherited case, which\r
-            // add library as an usage instance, because when build a module, and \r
-            // if module inherited from base library, then build process will build\r
-            // library at first. \r
-            //\r
-            if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) {\r
-                packageName   = GlobalData.getPackageNameForModule(libraryName);\r
-                usageInstance = new UsageInstance(token,\r
-                                                  Token.PCD_USAGE.ALWAYS_CONSUMED,\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
+                    // Check token number is valid\r
+                    // \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
+                    // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
+                    // \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
+                    // a usage instance into this token in database.\r
+                    // \r
+                    try {\r
+                        tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
+                    } catch (Exception e) {\r
+                        throw new EntityException("Fail to get token space guid for token " + token.cName);\r
+                    }\r
+\r
+                    if (tokenSpaceStrRet == null) {\r
+                        throw new EntityException("Fail to get token space guid for token " + token.cName);\r
+                    }\r
+\r
+                    token = new Token(pcdBuildData.getCName(), \r
+                                      translateSchemaStringToUUID(tokenSpaceStrRet[1]));\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
+                    dbManager.addTokenToDatabase(primaryKey, token);\r
+                }\r
+\r
+                //\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
+                                                  moduleName, \r
+                                                  null,\r
+                                                  null,\r
+                                                  null,\r
+                                                  CommonDefinition.getModuleType(modules.get(index).getModuleType()), \r
                                                   pcdType,\r
-                                                  CommonDefinition.ComponentTypeLibrary,\r
-                                                  libPcdDataArray[tokenIndex][3],\r
+                                                  modules.get(index).getModuleId().getArch(), \r
                                                   null,\r
-                                                 (String)libPcdDataArray[tokenIndex][5],\r
-                                                  "",\r
-                                                  libraryName,\r
-                                                  packageName,\r
-                                                  false);\r
+                                                  datum,\r
+                                                  maxDatumSize);\r
                 token.addUsageInstance(usageInstance);\r
             }\r
         }\r
     }\r
 \r
     /**\r
-      Create usage instance for PCD token defined in MSA document\r
-\r
-      A PCD token maybe used by many modules, and every module is one of usage\r
-      instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is \r
-      consumer type usage instance of this token, and for ALWAYS_PRODUCED, \r
-      SOMETIMES_PRODUCED, it is produce type usage instance.\r
-     \r
-      @param moduleName      The name of module \r
-      @param tokenInfoInMsa  The PCD token information array retrieved from MSA.\r
-      \r
-      @return UsageInstance  The usage instance created in memroy database.\r
-      \r
-      @throws EntityException  If token did not exist in database yet.\r
-      \r
-    **/\r
-    private UsageInstance createUsageInstanceFromMSA(String   moduleName,\r
-                                                     Object[] tokenInfoInMsa) \r
-        throws EntityException {\r
-        String          packageName         = null;\r
-        UsageInstance   usageInstance       = null;\r
-        UUID            tokenSpaceGuid      = null;\r
-        UUID            nullUUID            = new UUID(0,0);\r
-        String          primaryKeyString    = null;\r
-        UUID            platformTokenSpace  = nullUUID;\r
-        Token           token               = null;\r
-        Token.PCD_TYPE  pcdType             = Token.PCD_TYPE.UNKNOWN;\r
-        Token.PCD_USAGE pcdUsage            = Token.PCD_USAGE.UNKNOWN;\r
-\r
-        tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2];\r
-\r
-        primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0],\r
-                                                     tokenSpaceGuid,\r
-                                                     platformTokenSpace);\r
-\r
-        //\r
-        // Get token object from memory database firstly.\r
-        //\r
-        if(dbManager.isTokenInDatabase(primaryKeyString)) {\r
-            token = dbManager.getTokenByKey(primaryKeyString);\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 datum\r
+       @param datumType\r
+       @param maxDatumSize\r
+       \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
-            throw new EntityException("The PCD token " + primaryKeyString + " defined in module " + \r
-                                      moduleName + " does not exist in FPD file!" );\r
+            moduleName = "module " + moduleName;\r
         }\r
-        pcdType     = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]);\r
-        pcdUsage    = Token.getUsageFromString((String)tokenInfoInMsa[4]);\r
 \r
-        packageName = GlobalData.getPackageNameForModule(moduleName);\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
-        if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) {\r
-            //\r
-            // BUGBUG: It is legal that same base name exist in one FPD file. In furture\r
-            //         we should use "Guid, Version, Package" and "Arch" to differ a module.\r
-            //         So currently, warning should be disabled.\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
-            //ActionMessage.warning(this,\r
-            //                      "In module " + moduleName + " exist more than one PCD token " + token.cName\r
-            //                      );\r
-            return null;\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
-        // BUGBUG: following code could be enabled at current schema. Because \r
-        //         current schema does not provide usage information.\r
-        // \r
-        // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his \r
-        // usage is always ALWAYS_CONSUMED\r
-        //\r
-        //if((pcdType != Token.PCD_TYPE.DYNAMIC) &&\r
-        //   (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) {\r
-        pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED;\r
-        //}\r
-\r
-        usageInstance = new UsageInstance(token,\r
-                                          pcdUsage,\r
-                                          pcdType,\r
-                                          CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()),\r
-                                          tokenInfoInMsa[3],\r
-                                          null,\r
-                                         (String) tokenInfoInMsa[5],\r
-                                          "",\r
-                                          moduleName,\r
-                                          packageName,\r
-                                          false);\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
+        int    index             = 0;\r
+        String exceptionString   = null;\r
+        String dynamicPrimaryKey = null;\r
+        DynamicPcdBuildDefinitions                    dynamicPcdBuildDefinitions = null;\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray   = null;\r
+        String[]                                      tokenSpaceStrRet           = null;\r
 \r
         //\r
-        // Use default value defined in MSA to update datum of token,\r
-        // if datum of token does not defined in FPD file.\r
-        //\r
-        if((token.datum == null) &&(tokenInfoInMsa[3] != null)) {\r
-            token.datum = tokenInfoInMsa[3];\r
+        // If FPD document is not be opened, open and initialize it.\r
+        // \r
+        if (fpdDocInstance == null) {\r
+            try {\r
+                fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
+            } catch(IOException ioE) {\r
+                throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+            } catch(XmlException xmlE) {\r
+                throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
+            }\r
         }\r
+        \r
+        dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().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
+        dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
+        for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
+            //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];\r
+            String tokenSpaceGuidString = null;\r
+            try {\r
+                tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
+            } catch (Exception e) {\r
+                throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
+            }\r
+            \r
+            if (tokenSpaceStrRet == null) {\r
+                throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
+            }\r
 \r
-        token.addUsageInstance(usageInstance);\r
+            dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
+                                                          translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
+            if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
+                return dynamicPcdBuildDataArray.get(index);\r
+            }\r
+        }\r
 \r
-        return usageInstance;\r
+        return null;\r
     }\r
 \r
     /**\r
-      Create token instance object into memory database, the token information\r
-      comes for FPD file. Normally, FPD file will contain all token platform \r
-      informations.\r
-     \r
-      This fucntion should be executed at firsly before others collection work\r
-      such as searching token information from MSA, SPD.\r
-      \r
-      @return FrameworkPlatformDescriptionDocument   The FPD document instance for furture usage.\r
-      \r
-      @throws EntityException                        Failed to parse FPD xml file.\r
-      \r
-    **/\r
-    private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD() \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
-        XmlObject                            doc               = null;\r
-        FrameworkPlatformDescriptionDocument fpdDoc            = null;\r
-        int                                  index             = 0;\r
-        List<PcdBuildData>                   pcdBuildDataArray = new ArrayList<PcdBuildData>();\r
-        PcdBuildData                         pcdBuildData      = null;\r
-        Token                                token             = null;\r
-        UUID                                 nullUUID          = new UUID(0,0);\r
-        UUID                                 platformTokenSpace= nullUUID;\r
-        List                                 skuDataArray      = new ArrayList();\r
-        SkuInstance                          skuInstance       = null;\r
-        int                                  skuIndex          = 0;\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
+        long                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
-        // Get all tokens from FPD file and create token into database.\r
-        // \r
+        token.datumSize = dynamicInfo.getMaxDatumSize();\r
 \r
-        try {\r
-            doc = XmlObject.Factory.parse(new File(fpdFilePath));\r
-        } catch(IOException ioE) {\r
-            throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath);\r
-        } catch(XmlException xmlE) {\r
-            throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath);\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
-        //\r
-        // Get memoryDatabaseManager instance from GlobalData.\r
-        //\r
-        if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
-            throw new EntityException("The instance of PCD memory database manager is null");\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 = Long.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
-        dbManager = new MemoryDatabaseManager();\r
-\r
-        if(!(doc instanceof FrameworkPlatformDescriptionDocument)) {\r
-            throw new EntityException("File " + fpdFilePath + \r
-                                       " is not a FrameworkPlatformDescriptionDocument");\r
+        pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r
+        if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
+            token.dynamicExTokenNumber = tokenNumber;\r
         }\r
 \r
-        fpdDoc =(FrameworkPlatformDescriptionDocument)doc;\r
+        skuInfoList = dynamicInfo.getSkuInfoList();\r
 \r
         //\r
-        // Add all tokens in FPD into Memory Database.\r
-        //\r
-        pcdBuildDataArray = \r
-            fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList();\r
-        for(index = 0; \r
-             index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray(); \r
-             index ++) {\r
-            pcdBuildData = pcdBuildDataArray.get(index);\r
-            token        = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0));\r
+        // Loop all sku data \r
+        // \r
+        for (index = 0; index < skuInfoList.size(); index ++) {\r
+            skuInstance = new SkuInstance();\r
             //\r
-            // BUGBUG: in FPD, <defaultValue> should be defined as <Value>\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
-            token.datum        = pcdBuildData.getDefaultValue();\r
-            token.tokenNumber  = Integer.decode(pcdBuildData.getToken().getStringValue());\r
-            token.hiiEnabled   = pcdBuildData.getHiiEnable();\r
-            token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid());\r
-            token.variableName = pcdBuildData.getVariableName();\r
-            token.variableOffset = Integer.decode(pcdBuildData.getDataOffset());\r
-            token.skuEnabled   = pcdBuildData.getSkuEnable();\r
-            token.maxSkuCount  = Integer.decode(pcdBuildData.getMaxSku());\r
-            token.skuId        = Integer.decode(pcdBuildData.getSkuId());\r
-            token.skuDataArrayEnabled  = pcdBuildData.getSkuDataArrayEnable();\r
-            token.assignedtokenNumber  = Integer.decode(pcdBuildData.getToken().getStringValue());\r
-            skuDataArray               = pcdBuildData.getSkuDataArray1();\r
-            token.datumType    = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
-            token.datumSize    = pcdBuildData.getDatumSize();\r
-\r
-            if(skuDataArray != null) {\r
-                for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) {\r
-                    //\r
-                    // BUGBUG: Now in current schema, The value is defined as String type, \r
-                    // it is not correct, the type should be same as the datumType\r
-                    //\r
-                    skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(),\r
-                                                  ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue());\r
-                    token.skuData.add(skuInstance);\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
 \r
-            if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName, \r
-                                                                      token.tokenSpaceName, \r
-                                                                      platformTokenSpace))) {\r
+                token.skuData.add(skuInstance);\r
+\r
                 //\r
-                // If found duplicate token, Should tool be hold?\r
+                // Judege wether is same of datum between module's information\r
+                // and dynamic information.\r
+                // \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
+                }\r
+                continue;\r
+            }\r
+\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
+                }\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
+                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
+\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
-                ActionMessage.warning(this, \r
-                                       "Token " + token.cName + " exists in token database");\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.getGuidInfoFromCname(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
+                String variableStr = skuInfoList.get(index).getVariableName();\r
+                Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
+                Matcher matcher = pattern.matcher(variableStr);\r
+                List<String> varNameList = new ArrayList<String>();\r
+                while (matcher.find()){\r
+                       String str = variableStr.substring(matcher.start(),matcher.end());\r
+                       varNameList.add(str);\r
+                }\r
+                \r
+                skuInstance.value.setHiiData(varNameList,\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
-            token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
-            dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName, \r
-                                                                   token.tokenSpaceName, \r
-                                                                   platformTokenSpace), \r
-                                         token);\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
+\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
-        return fpdDoc;\r
+        return token;\r
     }\r
 \r
     /**\r
-      Update PCD token in memory database by help information in SPD.\r
-\r
-      After create token from FPD and create usage instance from MSA, we should collect\r
-      PCD package level information from SPD and update token information in memory \r
-      database.\r
-      \r
-      @param usageInstance   The usage instance defined in MSA and want to search in SPD.\r
-      @param packageFullPath The SPD file path.\r
-      \r
-      @throws EntityException Failed to parse SPD xml file.\r
-      \r
+       Translate the schema string to UUID instance.\r
+       \r
+       In schema, the string of UUID is defined as following two types string:\r
+        1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
+        )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
+       \r
+        2) GuidNamingConvention: pattern =\r
+        [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r
+       \r
+       This function will convert string and create uuid instance.\r
+       \r
+       @param uuidString    UUID string in XML file\r
+       \r
+       @return UUID         UUID instance\r
     **/\r
-    private void updateTokenBySPD(UsageInstance  usageInstance,\r
-                                  String         packageFullPath) \r
+    private UUID translateSchemaStringToUUID(String uuidString) \r
         throws EntityException {\r
-        PackageSurfaceAreaDocument      pkgDoc          = null;\r
-        PcdDefinitions                  pcdDefinitions  = null;\r
-        List<PcdDefinitions.PcdEntry>   pcdEntryArray   = new ArrayList<PcdDefinitions.PcdEntry>();\r
-        int                             index           = 0;\r
-        boolean                         isFoundInSpd    = false;\r
-        Token.DATUM_TYPE                datumType       = Token.DATUM_TYPE.UNKNOWN;\r
+        String      temp;\r
+        String[]    splitStringArray;\r
+        int         index;\r
+        int         chIndex;\r
+        int         chLen;\r
 \r
-        try {\r
-            pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath));\r
-        } catch(IOException ioE) {\r
-            throw new EntityException("Can't find the FPD xml fle:" + packageFullPath);\r
-        } catch(XmlException xmlE) {\r
-            throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath);\r
-        }\r
-        pcdDefinitions = pkgDoc.getPackageSurfaceArea().getPcdDefinitions();\r
-        //\r
-        // It is illege for SPD file does not contains any PCD information.\r
-        //\r
-        if (pcdDefinitions == null) {\r
-            return;\r
+        if (uuidString == null) {\r
+            return null;\r
         }\r
 \r
-        pcdEntryArray = pcdDefinitions.getPcdEntryList();\r
-        if (pcdEntryArray == null) {\r
-            return;\r
+        if (uuidString.length() == 0) {\r
+            return null;\r
         }\r
-        for(index = 0; index < pcdEntryArray.size(); index ++) {\r
-            if(pcdEntryArray.get(index).getCName().equalsIgnoreCase(\r
-                usageInstance.parentToken.cName)) {\r
-                isFoundInSpd = true;\r
-                //\r
-                // From SPD file , we can get following information.\r
-                //  Token:        Token number defined in package level.\r
-                //  PcdItemType:  This item does not single one. It means all supported item type.\r
-                //  datumType:    UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN \r
-                //  datumSize:    The size of default value or maxmine size.\r
-                //  defaultValue: This value is defined in package level.\r
-                //  HelpText:     The help text is provided in package level.\r
-                //\r
 \r
-                usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken());\r
+        if (uuidString.equals("0") ||\r
+            uuidString.equalsIgnoreCase("0x0")) {\r
+            return new UUID(0, 0);\r
+        }\r
 \r
-                if(pcdEntryArray.get(index).getDatumType() != null) {\r
-                    datumType = Token.getdatumTypeFromString(\r
-                        pcdEntryArray.get(index).getDatumType().toString());\r
-                    if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) {\r
-                        usageInstance.parentToken.datumType = datumType;\r
-                    } else {\r
-                        if(datumType != usageInstance.parentToken.datumType) {\r
-                            throw new EntityException("Different datum types are defined for Token :" + \r
-                                                      usageInstance.parentToken.cName);\r
-                        }\r
-                    }\r
+        uuidString = uuidString.replaceAll("\\{", "");\r
+        uuidString = uuidString.replaceAll("\\}", "");\r
 \r
-                } else {\r
-                    throw new EntityException("The datum type for token " + usageInstance.parentToken.cName + \r
-                                              " is not defind in SPD file " + packageFullPath);\r
-                }\r
+        //\r
+        // If the UUID schema string is GuidArrayType type then need translate \r
+        // to GuidNamingConvention type at first.\r
+        // \r
+        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 ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
+            }\r
 \r
-                usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue();\r
-                usageInstance.helpTextInSPD     = "Help Text in SPD";\r
+            //\r
+            // Remove blank space from these string and remove header string "0x"\r
+            // \r
+            for (index = 0; index < 11; index ++) {\r
+                splitStringArray[index] = splitStringArray[index].trim();\r
+                splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
+            }\r
 \r
-                //\r
-                // If token's datum is not valid, it indicate that datum is not provided\r
-                // in FPD and defaultValue is not provided in MSA, then use defaultValue\r
-                // in SPD as the datum of token.\r
-                //\r
-                if(usageInstance.parentToken.datum == null) {\r
-                    if(pcdEntryArray.get(index).getDefaultValue() != null) {\r
-                        usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue();\r
-                    } else {\r
-                        throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName +\r
-                                                  ", MSA and SPD also does not provide <defaultValue> for this token!");\r
-                    }\r
+            //\r
+            // Add heading '0' to normalize the string length\r
+            // \r
+            for (index = 3; index < 11; index ++) {\r
+                chLen = splitStringArray[index].length();\r
+                for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
+                    splitStringArray[index] = "0" + splitStringArray[index];\r
                 }\r
             }\r
+\r
+            //\r
+            // construct the final GuidNamingConvention string\r
+            // \r
+            temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
+                                 splitStringArray[0],\r
+                                 splitStringArray[1],\r
+                                 splitStringArray[2],\r
+                                 splitStringArray[3],\r
+                                 splitStringArray[4],\r
+                                 splitStringArray[5],\r
+                                 splitStringArray[6],\r
+                                 splitStringArray[7],\r
+                                 splitStringArray[8],\r
+                                 splitStringArray[9],\r
+                                 splitStringArray[10]);\r
+            uuidString = temp;\r
         }\r
+\r
+        return UUID.fromString(uuidString);\r
     }\r
 \r
     /**\r
@@ -1844,11 +3134,11 @@ public class CollectPCDAction {
     **/\r
     public static void main(String argv[]) throws EntityException {\r
         CollectPCDAction ca = new CollectPCDAction();\r
-        ca.setWorkspacePath("G:/mdk");\r
-        ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/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
-                            "G:/mdk");\r
-        ca.execute();\r
+//        GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
+//                            "m:/tianocore/edk2");\r
+//        ca.execute();\r
     }\r
 }\r