]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: DSC Components section support flexible PCD
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
index 75b877a5aac3b1861977dc409f773576ea5dd07c..a5089a900b255a41b1afd4185793b5783fee1e4d 100644 (file)
@@ -37,7 +37,9 @@ from Common.Parsing import IsValidWord
 from Common.VariableAttributes import VariableAttributes\r
 import Common.GlobalData as GlobalData\r
 import subprocess\r
+from Common.Misc import SaveFileOnChange\r
 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject\r
+from collections import OrderedDict\r
 \r
 #\r
 # Treat CHAR16 as a synonym for UINT16.  CHAR16 support is required for VFR C structs\r
@@ -89,7 +91,6 @@ LIBS = $(LIB_PATH)\Common.lib
 '''\r
 \r
 PcdGccMakefile = '''\r
-ARCH ?= IA32\r
 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r
 LIBS = -lCommon\r
 '''\r
@@ -156,12 +157,15 @@ class DscBuildData(PlatformBuildClassObject):
         self._ToolChainFamily = None\r
         self._Clear()\r
         self._HandleOverridePath()\r
-        if os.getenv("WORKSPACE"):\r
-            self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)\r
-        else:\r
-            self.OutputPath = os.path.dirname(self.DscFile)\r
+        self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""\r
         self.DefaultStores = None\r
         self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)\r
+    @property\r
+    def OutputPath(self):\r
+        if os.getenv("WORKSPACE"):\r
+            return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain,PcdValueInitName)\r
+        else:\r
+            return os.path.dirname(self.DscFile)\r
 \r
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -679,8 +683,9 @@ class DscBuildData(PlatformBuildClassObject):
                 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
                     TokenList = GetSplitValueList(Setting)\r
                     DefaultValue = TokenList[0]\r
-                    if len(TokenList) > 1:\r
-                        MaxDatumSize = TokenList[1]\r
+                    # the format is PcdName| Value | VOID* | MaxDatumSize\r
+                    if len(TokenList) > 2:\r
+                        MaxDatumSize = TokenList[2]\r
                     else:\r
                         MaxDatumSize = ''\r
                     TypeString = self._PCD_TYPE_STRING_[Type]\r
@@ -894,12 +899,11 @@ class DscBuildData(PlatformBuildClassObject):
                 if pcd[2] == "":\r
                     pcdset.append((pcd[0],pcd[1],pcd[3]))\r
                 else:\r
-                    pcdobj = self._Pcds.get((pcd[1],pcd[0]))\r
-                    if pcdobj:\r
-                        pcdset.append((pcd[0],pcd[1], pcdobj.DefaultValue))\r
-                    else:\r
+                    if (pcd[1],pcd[0]) not in self._Pcds:\r
                         pcdvalue = pcd[3] if len(pcd) == 4 else pcd[2]\r
                         pcdset.append((pcd[0],pcd[1],pcdvalue))\r
+                    #else:\r
+                        # remove the settings from command line since it has been handled.\r
         GlobalData.BuildOptionPcd = pcdset\r
     def GetFieldValueFromComm(self,ValueStr,TokenSpaceGuidCName, TokenCName, FieldName):\r
         PredictedFieldType = "VOID*"\r
@@ -991,6 +995,8 @@ class DscBuildData(PlatformBuildClassObject):
                     NewValue = self.GetFieldValueFromComm(pcdvalue, TokenSpaceGuidCName, TokenCName, FieldName)\r
                     GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))\r
                 else:\r
+                    # Replace \' to ', \\\' to \'\r
+                    pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")\r
                     for key in self.DecPcds:\r
                         PcdItem = self.DecPcds[key]\r
                         if HasTokenSpace:\r
@@ -1002,7 +1008,7 @@ class DscBuildData(PlatformBuildClassObject):
                                     except BadExpression, Value:\r
                                         EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
                                                         (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                    if PcdDatumType == "VOID*":\r
+                                    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
                                         pcdvalue = 'H' + pcdvalue\r
                                 elif pcdvalue.startswith("L'"):\r
                                     try:\r
@@ -1010,7 +1016,7 @@ class DscBuildData(PlatformBuildClassObject):
                                     except BadExpression, Value:\r
                                         EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
                                                         (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                    if pcdvalue.startswith('{'):\r
+                                    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
                                         pcdvalue = 'H' + pcdvalue\r
                                 elif pcdvalue.startswith("'"):\r
                                     try:\r
@@ -1018,7 +1024,7 @@ class DscBuildData(PlatformBuildClassObject):
                                     except BadExpression, Value:\r
                                         EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
                                                         (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                    if pcdvalue.startswith('{'):\r
+                                    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
                                         pcdvalue = 'H' + pcdvalue\r
                                 elif pcdvalue.startswith('L'):\r
                                     pcdvalue = 'L"' + pcdvalue[1:] + '"'\r
@@ -1031,8 +1037,12 @@ class DscBuildData(PlatformBuildClassObject):
                                     try:\r
                                         pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
                                     except BadExpression, Value:\r
-                                        EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
-                                                        (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
+                                        try:\r
+                                            pcdvalue = '"' + pcdvalue + '"'\r
+                                            pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
+                                        except BadExpression, Value:\r
+                                            EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
+                                                            (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
                                 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
                                 FoundFlag = True\r
                         else:\r
@@ -1048,7 +1058,7 @@ class DscBuildData(PlatformBuildClassObject):
                                             except BadExpression, Value:\r
                                                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
                                                                 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                            if PcdDatumType == "VOID*":\r
+                                            if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:\r
                                                 pcdvalue = 'H' + pcdvalue\r
                                         elif pcdvalue.startswith("L'"):\r
                                             try:\r
@@ -1057,7 +1067,7 @@ class DscBuildData(PlatformBuildClassObject):
                                             except BadExpression, Value:\r
                                                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
                                                                 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                            if pcdvalue.startswith('{'):\r
+                                            if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
                                                 pcdvalue = 'H' + pcdvalue\r
                                         elif pcdvalue.startswith("'"):\r
                                             try:\r
@@ -1066,7 +1076,7 @@ class DscBuildData(PlatformBuildClassObject):
                                             except BadExpression, Value:\r
                                                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
                                                                 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
-                                            if pcdvalue.startswith('{'):\r
+                                            if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
                                                 pcdvalue = 'H' + pcdvalue\r
                                         elif pcdvalue.startswith('L'):\r
                                             pcdvalue = 'L"' + pcdvalue[1:] + '"'\r
@@ -1080,9 +1090,12 @@ class DscBuildData(PlatformBuildClassObject):
                                             try:\r
                                                 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
                                             except BadExpression, Value:\r
-                                                EdkLogger.error('Parser', FORMAT_INVALID,\r
-                                                                'PCD [%s.%s] Value "%s",  %s' %\r
-                                                                (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
+                                                try:\r
+                                                    pcdvalue = '"' + pcdvalue + '"'\r
+                                                    pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
+                                                except BadExpression, Value:\r
+                                                    EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %\r
+                                                                    (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
                                         NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
                                         FoundFlag = True\r
                                     else:\r
@@ -1272,7 +1285,7 @@ class DscBuildData(PlatformBuildClassObject):
 \r
         # handle pcd value override\r
         StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
-        S_pcd_set = {}\r
+        S_pcd_set = OrderedDict()\r
         for str_pcd in StrPcdSet:\r
             str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
             str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
@@ -1291,7 +1304,7 @@ class DscBuildData(PlatformBuildClassObject):
                     str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
                 for str_pcd_data in StrPcdSet[str_pcd]:\r
                     if str_pcd_data[3] in SkuIds:\r
-                        str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File,LineNo=str_pcd_data[5])\r
+                        str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],LineNo=str_pcd_data[5])\r
                 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
             else:\r
                 EdkLogger.error('build', PARSER_ERROR,\r
@@ -1319,12 +1332,15 @@ class DscBuildData(PlatformBuildClassObject):
                     continue\r
                 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
                 NoDefault = False\r
-                while nextskuid not in stru_pcd.SkuOverrideValues:\r
-                    if nextskuid == "DEFAULT":\r
-                        NoDefault = True\r
-                        break\r
-                    nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
-                stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {'STANDARD':stru_pcd.DefaultValues})\r
+                if skuid not in stru_pcd.SkuOverrideValues:\r
+                    while nextskuid not in stru_pcd.SkuOverrideValues:\r
+                        if nextskuid == "DEFAULT":\r
+                            NoDefault = True\r
+                            break\r
+                        nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
+                    stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {'STANDARD':stru_pcd.DefaultValues})\r
+                    if not NoDefault:\r
+                        stru_pcd.ValueChain[(skuid,'')]= (nextskuid,'')\r
             if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
                 for skuid in SkuIds:\r
                     nextskuid = skuid\r
@@ -1343,6 +1359,7 @@ class DscBuildData(PlatformBuildClassObject):
                     for defaultstoreid in DefaultStores:\r
                         if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
                             stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
+                            stru_pcd.ValueChain[(skuid,defaultstoreid)]= (nextskuid,mindefaultstorename)\r
         S_pcd_set = self.OverrideByFdfComm(S_pcd_set)\r
         Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
         if Str_Pcd_Values:\r
@@ -1550,8 +1567,205 @@ class DscBuildData(PlatformBuildClassObject):
         Result = Result + '"'\r
         return Result\r
 \r
-    def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
-        OverrideValues = {DefaultStoreName:""}\r
+    def GenerateSizeFunction(self,Pcd):\r
+        CApp = "// Default Value in Dec \n"\r
+        CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        for FieldList in [Pcd.DefaultValues]:\r
+            if not FieldList:\r
+                continue\r
+            for FieldName in FieldList:\r
+                FieldName = "." + FieldName\r
+                IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
+                if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r
+                    try:\r
+                        Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
+                    except BadExpression:\r
+                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                        (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
+                    Value, ValueSize = ParseFieldValue(Value)\r
+                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));  // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);\r
+                else:\r
+                    NewFieldName = ''\r
+                    FieldName_ori = FieldName.strip('.')\r
+                    while '[' in  FieldName:\r
+                        NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
+                        ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
+                        FieldName = FieldName.split(']', 1)[1]\r
+                    FieldName = NewFieldName + FieldName\r
+                    while '[' in FieldName:\r
+                        FieldName = FieldName.rsplit('[', 1)[0]\r
+                        CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])\r
+        for skuname in Pcd.SkuOverrideValues:\r
+            if skuname == "COMMON":\r
+                continue\r
+            for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:\r
+                CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
+                for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:\r
+                    if not FieldList:\r
+                        continue\r
+                    for FieldName in FieldList:\r
+                        FieldName = "." + FieldName\r
+                        IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
+                        if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r
+                            try:\r
+                                Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
+                            except BadExpression:\r
+                                EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                                (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
+                            Value, ValueSize = ParseFieldValue(Value)\r
+                            CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);\r
+                        else:\r
+                            NewFieldName = ''\r
+                            FieldName_ori = FieldName.strip('.')\r
+                            while '[' in  FieldName:\r
+                                NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
+                                ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
+                                FieldName = FieldName.split(']', 1)[1]\r
+                            FieldName = NewFieldName + FieldName\r
+                            while '[' in FieldName:\r
+                                FieldName = FieldName.rsplit('[', 1)[0]\r
+                                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])\r
+        CApp = CApp + "}\n"\r
+        return CApp\r
+    def GenerateSizeStatments(self,Pcd):\r
+        CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)\r
+        CApp = CApp + '  Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        return CApp\r
+    def GenerateDefaultValueAssignFunction(self,Pcd):\r
+        CApp = "// Default value in Dec \n"\r
+        CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)\r
+        CApp = CApp + '  UINT32  FieldSize;\n'\r
+        CApp = CApp + '  CHAR8   *Value;\n'\r
+        DefaultValueFromDec = Pcd.DefaultValueFromDec\r
+        IsArray = self.IsFieldValueAnArray(Pcd.DefaultValueFromDec)\r
+        if IsArray:\r
+            try:\r
+                DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)\r
+            except BadExpression:\r
+                EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %\r
+                                (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))\r
+        Value, ValueSize = ParseFieldValue (DefaultValueFromDec)\r
+        if isinstance(Value, str):\r
+            CApp = CApp + '  Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)\r
+        elif IsArray:\r
+        #\r
+        # Use memcpy() to copy value into field\r
+        #\r
+            CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)\r
+            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
+        for FieldList in [Pcd.DefaultValues]:\r
+            if not FieldList:\r
+                continue\r
+            for FieldName in FieldList:\r
+                IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
+                if IsArray:\r
+                    try:\r
+                        FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
+                    except BadExpression:\r
+                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                        (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))\r
+\r
+                try:\r
+                    Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
+                except Exception:\r
+                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))\r
+                if isinstance(Value, str):\r
+                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
+                    CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
+                else:\r
+                    if ValueSize > 4:\r
+                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    else:\r
+                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+        CApp = CApp + "}\n"\r
+        return CApp\r
+    def GenerateDefaultValueAssignStatement(self,Pcd):\r
+        CApp = '  Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        return CApp\r
+    def GenerateInitValueFunction(self,Pcd,SkuName,DefaultStoreName):\r
+        CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,DefaultStoreName)\r
+        CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName,Pcd.DatumType)\r
+        CApp = CApp + '  UINT32  FieldSize;\n'\r
+        CApp = CApp + '  CHAR8   *Value;\n'\r
+\r
+        CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % ('DEFAULT', 'STANDARD')\r
+        inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
+        if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):\r
+            pcddefaultvalue = Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue\r
+        else:\r
+            pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)\r
+        for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]:\r
+            if not FieldList:\r
+                continue\r
+            if pcddefaultvalue and FieldList == pcddefaultvalue:\r
+                IsArray = self.IsFieldValueAnArray(FieldList)\r
+                if IsArray:\r
+                    try:\r
+                        FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r
+                    except BadExpression:\r
+                        EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r
+                                        (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
+                Value, ValueSize = ParseFieldValue (FieldList)\r
+\r
+                if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):\r
+                    if isinstance(Value, str):\r
+                        CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
+                    elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
+                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
+                else:\r
+                    if isinstance(Value, str):\r
+                        CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))\r
+                    elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))\r
+                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
+                continue\r
+            if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )):\r
+                for FieldName in FieldList:\r
+                    IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
+                    if IsArray:\r
+                        try:\r
+                            FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
+                        except BadExpression:\r
+                            EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                            (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
+                    try:\r
+                        Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
+                    except Exception:\r
+                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))\r
+                    if isinstance(Value, str):\r
+                        CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
+                        CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                        CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
+                    else:\r
+                        if ValueSize > 4:\r
+                            CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                        else:\r
+                            CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+        CApp = CApp + "}\n"\r
+        return CApp\r
+    def GenerateInitValueStatement(self,Pcd,SkuName,DefaultStoreName):\r
+        CApp = '  Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName)\r
+        return CApp\r
+    def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):\r
+        OverrideValues = {DefaultStore:""}\r
         if Pcd.SkuOverrideValues:\r
             OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
         for DefaultStoreName in OverrideValues.keys():\r
@@ -1569,7 +1783,7 @@ class DscBuildData(PlatformBuildClassObject):
             CApp = CApp + '\n'\r
 \r
             if SkuName in Pcd.SkuInfoList:\r
-                DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue  else Pcd.SkuInfoList[SkuName].DefaultValue\r
+                DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue  else Pcd.SkuInfoList[SkuName].DefaultValue)\r
             else:\r
                 DefaultValue = Pcd.DefaultValue\r
             PcdDefaultValue = StringToArray(DefaultValue.strip())\r
@@ -1589,65 +1803,7 @@ class DscBuildData(PlatformBuildClassObject):
             # in a structure.  The size formula for this case is:\r
             # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
             #\r
-            CApp = CApp + '  Size = sizeof(%s);\n' % (Pcd.DatumType)\r
-            CApp = CApp + "// Default Value in Dec \n"\r
-            for FieldList in [Pcd.DefaultValues]:\r
-                if not FieldList:\r
-                    continue\r
-                for FieldName in FieldList:\r
-                    FieldName = "." + FieldName\r
-                    IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
-                    if IsArray:\r
-                        try:\r
-                            Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
-                        except BadExpression:\r
-                            EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
-                                            (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
-                        Value, ValueSize = ParseFieldValue(Value)\r
-                        CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));  // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);\r
-                    else:\r
-                        NewFieldName = ''\r
-                        FieldName_ori = FieldName.strip('.')\r
-                        while '[' in  FieldName:\r
-                            NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
-                            ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
-                            FieldName = FieldName.split(']', 1)[1]\r
-                        FieldName = NewFieldName + FieldName\r
-                        while '[' in FieldName:\r
-                            FieldName = FieldName.rsplit('[', 1)[0]\r
-                            CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])\r
-            for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
-                inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
-                storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]\r
-                for defaultstorenameitem in storeset:\r
-                    CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
-                    for FieldList in [inherit_OverrideValues.get(defaultstorenameitem)]:\r
-                        if not FieldList:\r
-                            continue\r
-                        for FieldName in FieldList:\r
-                            FieldName = "." + FieldName\r
-                            IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
-                            if IsArray:\r
-                                try:\r
-                                    Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
-                                except BadExpression:\r
-                                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
-                                                    (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
-                                Value, ValueSize = ParseFieldValue(Value)\r
-                                CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);\r
-                            else:\r
-                                NewFieldName = ''\r
-                                FieldName_ori = FieldName.strip('.')\r
-                                while '[' in  FieldName:\r
-                                    NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
-                                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
-                                    FieldName = FieldName.split(']', 1)[1]\r
-                                FieldName = NewFieldName + FieldName\r
-                                while '[' in FieldName:\r
-                                    FieldName = FieldName.rsplit('[', 1)[0]\r
-                                    CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])\r
-                if skuname == SkuName:\r
-                    break\r
+            CApp = CApp + self.GenerateSizeStatments(Pcd)\r
 \r
             #\r
             # Allocate and zero buffer for the PCD\r
@@ -1666,92 +1822,19 @@ class DscBuildData(PlatformBuildClassObject):
             #\r
             # Assign field values in PCD\r
             #\r
-            CApp = CApp + "// Default value in Dec \n"\r
-            for FieldList in [Pcd.DefaultValues]:\r
-                if not FieldList:\r
-                    continue\r
-                for FieldName in FieldList:\r
-                    IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
-                    if IsArray:\r
-                        try:\r
-                            FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
-                        except BadExpression:\r
-                            EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
-                                            (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))\r
-\r
-                    try:\r
-                        Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
-                    except Exception:\r
-                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))\r
-                    if isinstance(Value, str):\r
-                        CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                    elif IsArray:\r
-                        #\r
-                        # Use memcpy() to copy value into field\r
-                        #\r
-                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
-                        CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                        CApp = CApp + '  memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
-                    else:\r
-                        if ValueSize > 4:\r
-                            CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                        else:\r
-                            CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-            for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
-                inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
-                storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]\r
-                for defaultstorenameitem in storeset:\r
-                    CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
-                    pcddefaultvalue = Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue\r
-                    for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(defaultstorenameitem)]:\r
-                        if not FieldList:\r
-                            continue\r
-                        if pcddefaultvalue and FieldList == pcddefaultvalue:\r
-                            IsArray = self.IsFieldValueAnArray(FieldList)\r
-                            if IsArray:\r
-                                try:\r
-                                    FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r
-                                except BadExpression:\r
-                                    EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r
-                                                    (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
-                            Value, ValueSize = ParseFieldValue (FieldList)\r
-                            if isinstance(Value, str):\r
-                                CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
-                            elif IsArray:\r
-                            #\r
-                            # Use memcpy() to copy value into field\r
-                            #\r
-                                CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
-                                CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
-                            continue\r
-                        for FieldName in FieldList:\r
-                            IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
-                            if IsArray:\r
-                                try:\r
-                                    FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
-                                except BadExpression:\r
-                                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
-                                                    (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
-                            try:\r
-                                Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
-                            except Exception:\r
-                                EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))\r
-                            if isinstance(Value, str):\r
-                                CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                            elif IsArray:\r
-                            #\r
-                            # Use memcpy() to copy value into field\r
-                            #\r
-                                CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
-                                CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                                CApp = CApp + '  memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
-                            else:\r
-                                if ValueSize > 4:\r
-                                    CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                                else:\r
-                                    CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
-                if skuname == SkuName:\r
-                    break\r
+            CApp = CApp + self.GenerateDefaultValueAssignStatement(Pcd)\r
+            if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
+                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
+                for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
+                    storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]\r
+                    for defaultstorenameitem in storeset:\r
+                        CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
+                        CApp = CApp + self.GenerateInitValueStatement(Pcd,skuname,defaultstorenameitem)\r
+                    if skuname == SkuName:\r
+                        break\r
+            else:\r
+                CApp = CApp + "// SkuName: DEFAULT,  DefaultStoreName: STANDARD \n"\r
+                CApp = CApp + self.GenerateInitValueStatement(Pcd,"DEFAULT","STANDARD")\r
             #\r
             # Set new PCD value and size\r
             #\r
@@ -1783,10 +1866,21 @@ class DscBuildData(PlatformBuildClassObject):
                     Includes[IncludeFile] = True\r
                     CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
         CApp = CApp + '\n'\r
-\r
         for PcdName in StructuredPcds:\r
             Pcd = StructuredPcds[PcdName]\r
-            if not Pcd.SkuOverrideValues:\r
+            CApp = CApp + self.GenerateSizeFunction(Pcd)\r
+            CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)\r
+            if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
+                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
+                CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, 'STANDARD')\r
+            else:\r
+                for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
+                    if SkuName not in Pcd.SkuOverrideValues:\r
+                        continue\r
+                    for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
+                        CApp = CApp + self.GenerateInitValueFunction(Pcd,SkuName,DefaultStoreName)\r
+            if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
+                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
                 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
             else:\r
                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
@@ -1802,7 +1896,7 @@ class DscBuildData(PlatformBuildClassObject):
         CApp = CApp + '  )\n'\r
         CApp = CApp + '{\n'\r
         for Pcd in StructuredPcds.values():\r
-            if not Pcd.SkuOverrideValues:\r
+            if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
                 CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
             else:\r
                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
@@ -1817,13 +1911,11 @@ class DscBuildData(PlatformBuildClassObject):
         if not os.path.exists(self.OutputPath):\r
             os.makedirs(self.OutputPath)\r
         CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
-        File = open (CAppBaseFileName + '.c', 'w')\r
-        File.write(CApp)\r
-        File.close()\r
+        SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)\r
 \r
         MakeApp = PcdMakefileHeader\r
         if sys.platform == "win32":\r
-            MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
+            MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
         else:\r
             MakeApp = MakeApp + PcdGccMakefile\r
             MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
@@ -1835,7 +1927,7 @@ class DscBuildData(PlatformBuildClassObject):
                 continue\r
             if Cache.Includes:\r
                 if str(Cache.MetaFile.Path) not in PlatformInc:\r
-                    PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
+                    PlatformInc[str(Cache.MetaFile.Path)] = Cache.CommonIncludes\r
 \r
         PcdDependDEC = []\r
         for Pcd in StructuredPcds.values():\r
@@ -1899,80 +1991,78 @@ class DscBuildData(PlatformBuildClassObject):
         if sys.platform == "win32":\r
             MakeApp = MakeApp + PcdMakefileEnd\r
         MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
-        File = open (MakeFileName, 'w')\r
-        File.write(MakeApp)\r
-        File.close()\r
+        SaveFileOnChange(MakeFileName, MakeApp, False)\r
 \r
         InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
         OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
-        File = open (InputValueFile, 'w')\r
-        File.write(InitByteValue)\r
-        File.close()\r
-\r
-        Messages = ''\r
-        if sys.platform == "win32":\r
-            MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)\r
-            returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
-            Messages = StdOut\r
-        else:\r
-            MakeCommand = 'make clean & make -f %s' % (MakeFileName)\r
-            returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
-            Messages = StdErr\r
-        Messages = Messages.split('\n')\r
-        MessageGroup = []\r
-        if returncode <>0:\r
-            CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
-            File = open (CAppBaseFileName + '.c', 'r')\r
-            FileData = File.readlines()\r
-            File.close()\r
-            for Message in Messages:\r
-                if " error" in Message or "warning" in Message:\r
-                    FileInfo = Message.strip().split('(')\r
-                    if len (FileInfo) > 1:\r
-                        FileName = FileInfo [0]\r
-                        FileLine = FileInfo [1].split (')')[0]\r
-                    else:\r
-                        FileInfo = Message.strip().split(':')\r
-                        FileName = FileInfo [0]\r
-                        FileLine = FileInfo [1]\r
-                    if FileLine.isdigit():\r
-                        error_line = FileData[int (FileLine) - 1]\r
-                        if r"//" in error_line:\r
-                            c_line,dsc_line = error_line.split(r"//")\r
-                        else:\r
-                            dsc_line = error_line\r
-                        message_itmes = Message.split(":")\r
-                        Index = 0\r
-                        if "PcdValueInit.c" not in Message:\r
-                            break\r
-                        else:\r
-                            for item in message_itmes:\r
-                                if "PcdValueInit.c" in item:\r
-                                    Index = message_itmes.index(item)\r
-                                    message_itmes[Index] = dsc_line.strip()\r
-                                    break\r
-                            MessageGroup.append(":".join(message_itmes[Index:]).strip())\r
-                            continue\r
-                    else:\r
-                        MessageGroup.append(Message)\r
-            if MessageGroup:\r
-                EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )\r
-            else:\r
-                EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)\r
+        SaveFileOnChange(InputValueFile, InitByteValue, False)\r
 \r
         PcdValueInitExe = PcdValueInitName\r
         if not sys.platform == "win32":\r
             PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
-\r
-        Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)\r
-        returncode, StdOut, StdErr = self.ExecuteCommand (Command)\r
-        if returncode <> 0:\r
-            EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)\r
-            FileBuffer = []\r
         else:\r
-            File = open (OutputValueFile, 'r')\r
-            FileBuffer = File.readlines()\r
-            File.close()\r
+            PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"\r
+        if not os.path.exists(PcdValueInitExe) or self.NeedUpdateOutput(OutputValueFile, CAppBaseFileName + '.c',MakeFileName,InputValueFile):\r
+            Messages = ''\r
+            if sys.platform == "win32":\r
+                MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)\r
+                returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
+                Messages = StdOut\r
+            else:\r
+                MakeCommand = 'make clean & make -f %s' % (MakeFileName)\r
+                returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
+                Messages = StdErr\r
+            Messages = Messages.split('\n')\r
+            MessageGroup = []\r
+            if returncode <>0:\r
+                CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
+                File = open (CAppBaseFileName + '.c', 'r')\r
+                FileData = File.readlines()\r
+                File.close()\r
+                for Message in Messages:\r
+                    if " error" in Message or "warning" in Message:\r
+                        FileInfo = Message.strip().split('(')\r
+                        if len (FileInfo) > 1:\r
+                            FileName = FileInfo [0]\r
+                            FileLine = FileInfo [1].split (')')[0]\r
+                        else:\r
+                            FileInfo = Message.strip().split(':')\r
+                            FileName = FileInfo [0]\r
+                            FileLine = FileInfo [1]\r
+                        if FileLine.isdigit():\r
+                            error_line = FileData[int (FileLine) - 1]\r
+                            if r"//" in error_line:\r
+                                c_line,dsc_line = error_line.split(r"//")\r
+                            else:\r
+                                dsc_line = error_line\r
+                            message_itmes = Message.split(":")\r
+                            Index = 0\r
+                            if "PcdValueInit.c" not in Message:\r
+                                if not MessageGroup:\r
+                                    MessageGroup.append(Message)\r
+                                break\r
+                            else:\r
+                                for item in message_itmes:\r
+                                    if "PcdValueInit.c" in item:\r
+                                        Index = message_itmes.index(item)\r
+                                        message_itmes[Index] = dsc_line.strip()\r
+                                        break\r
+                                MessageGroup.append(":".join(message_itmes[Index:]).strip())\r
+                                continue\r
+                        else:\r
+                            MessageGroup.append(Message)\r
+                if MessageGroup:\r
+                    EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )\r
+                else:\r
+                    EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)\r
+            Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)\r
+            returncode, StdOut, StdErr = self.ExecuteCommand (Command)\r
+            if returncode <> 0:\r
+                EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)\r
+\r
+        File = open (OutputValueFile, 'r')\r
+        FileBuffer = File.readlines()\r
+        File.close()\r
 \r
         StructurePcdSet = []\r
         for Pcd in FileBuffer:\r
@@ -1981,6 +2071,17 @@ class DscBuildData(PlatformBuildClassObject):
             StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
         return StructurePcdSet\r
 \r
+    def NeedUpdateOutput(self,OutputFile, ValueCFile, MakeFile, StructureInput):\r
+        if not os.path.exists(OutputFile):\r
+            return True\r
+        if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:\r
+            return True\r
+        if os.stat(OutputFile).st_mtime <= os.stat(MakeFile).st_mtime:\r
+            return True\r
+        if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:\r
+            return True\r
+        return False\r
+\r
     ## Retrieve dynamic PCD settings\r
     #\r
     #   @param  Type    PCD type\r
@@ -2094,6 +2195,16 @@ class DscBuildData(PlatformBuildClassObject):
             return True\r
         else:\r
             return False\r
+    def CopyDscRawValue(self,Pcd):\r
+        if Pcd.DscRawValue is None:\r
+            Pcd.DscRawValue = dict()\r
+        for skuname in Pcd.SkuInfoList:\r
+            Pcd.DscRawValue[skuname] = {}\r
+            if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
+                for defaultstore in Pcd.SkuInfoList[skuname].DefaultStoreDict:\r
+                    Pcd.DscRawValue[skuname][defaultstore] = Pcd.SkuInfoList[skuname].DefaultStoreDict[defaultstore]\r
+            else:\r
+                Pcd.DscRawValue[skuname]['STANDARD'] = Pcd.SkuInfoList[skuname].DefaultValue\r
     def CompletePcdValues(self,PcdSet):\r
         Pcds = {}\r
         DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
@@ -2109,6 +2220,7 @@ class DscBuildData(PlatformBuildClassObject):
                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
                 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
                 continue\r
+            self.CopyDscRawValue(PcdObj)\r
             PcdType = PcdObj.Type\r
             if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
                 for skuid in PcdObj.SkuInfoList:\r