]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFspPkg/Tools/GenCfgOpt.py
Handle extra module patchable PCD variable in Linux map.
[mirror_edk2.git] / IntelFspPkg / Tools / GenCfgOpt.py
index 78b330a2ac420d00d6912d5fbd9a7c4f6206d053..a38da70212a8cceee328e6b1667ceef6751ef3a9 100644 (file)
@@ -1,6 +1,6 @@
 ## @ GenCfgOpt.py\r
 #\r
-# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials are licensed and made available under\r
 # the terms and conditions of the BSD License that accompanies this distribution.\r
 # The full text of the license may be found at\r
@@ -88,8 +88,248 @@ are permitted provided that the following conditions are met:
 **/\r
 """\r
 \r
+def UpdateMemSiUpdInitOffsetValue (DscFile):\r
+    DscFd        = open(DscFile, "r")\r
+    DscLines     = DscFd.readlines()\r
+    DscFd.close()\r
+\r
+    DscContent = []\r
+    MemUpdInitOffset = 0\r
+    SiUpdInitOffset = 0\r
+    MemUpdInitOffsetValue = 0\r
+    SiUpdInitOffsetValue = 0\r
+\r
+    while len(DscLines):\r
+        DscLine  = DscLines.pop(0)\r
+        DscContent.append(DscLine)\r
+        DscLine = DscLine.strip()\r
+        Match = re.match("^([_a-zA-Z0-9]+).(MemoryInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+        if Match:\r
+            MemUpdInitOffsetValue = int(Match.group(5), 0)\r
+        Match = re.match("^\s*([_a-zA-Z0-9]+).(SiliconInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+        if Match:\r
+            SiUpdInitOffsetValue = int(Match.group(5), 0)\r
+        Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(0x244450554D454D24)",DscLine)\r
+        if Match:\r
+            MemUpdInitOffset = int(Match.group(3), 0)\r
+        Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(0x244450555F495324)",DscLine)\r
+        if Match:\r
+            SiUpdInitOffset = int(Match.group(3), 0)\r
+\r
+    if MemUpdInitOffsetValue != MemUpdInitOffset or SiUpdInitOffsetValue != SiUpdInitOffset:\r
+        MemUpdInitOffsetStr = "0x%08X" % MemUpdInitOffset\r
+        SiUpdInitOffsetStr = "0x%08X" % SiUpdInitOffset\r
+        DscFd = open(DscFile,"w")\r
+        for DscLine in DscContent:\r
+            Match = re.match("^\s*([_a-zA-Z0-9]+).(MemoryInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+            if Match:\r
+                 DscLine = re.sub(r'(?:[^\s]+\s*$)', MemUpdInitOffsetStr + '\n', DscLine)\r
+            Match = re.match("^\s*([_a-zA-Z0-9]+).(SiliconInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+            if Match:\r
+                 DscLine = re.sub(r'(?:[^\s]+\s*$)', SiUpdInitOffsetStr + '\n', line)\r
+            DscFd.writelines(DscLine)\r
+        DscFd.close()\r
+\r
+class CLogicalExpression:\r
+    def __init__(self):\r
+        self.index    = 0\r
+        self.string   = ''\r
+\r
+    def errExit(self, err = ''):\r
+        print "ERROR: Express parsing for:"\r
+        print "       %s" % self.string\r
+        print "       %s^" % (' ' * self.index)\r
+        if err:\r
+            print "INFO : %s" % err\r
+        raise SystemExit\r
+\r
+    def getNonNumber (self, n1, n2):\r
+        if not n1.isdigit():\r
+            return n1\r
+        if not n2.isdigit():\r
+            return n2\r
+        return None\r
+\r
+    def getCurr(self, lens = 1):\r
+        try:\r
+            if lens == -1:\r
+                return self.string[self.index :]\r
+            else:\r
+                if self.index + lens > len(self.string):\r
+                    lens = len(self.string) - self.index\r
+                return self.string[self.index : self.index + lens]\r
+        except Exception:\r
+            return ''\r
+\r
+    def isLast(self):\r
+        return self.index == len(self.string)\r
+\r
+    def moveNext(self, len = 1):\r
+        self.index += len\r
+\r
+    def skipSpace(self):\r
+        while not self.isLast():\r
+            if self.getCurr() in ' \t':\r
+                self.moveNext()\r
+            else:\r
+                return\r
+\r
+    def normNumber (self, val):\r
+        return True if val else False\r
+\r
+    def getNumber(self, var):\r
+        var = var.strip()\r
+        if   re.match('^0x[a-fA-F0-9]+$', var):\r
+            value = int(var, 16)\r
+        elif re.match('^[+-]?\d+$', var):\r
+            value = int(var, 10)\r
+        else:\r
+            value = None\r
+        return value\r
+\r
+    def parseValue(self):\r
+        self.skipSpace()\r
+        var = ''\r
+        while not self.isLast():\r
+            char = self.getCurr()\r
+            if re.match('^[\w.]', char):\r
+                var += char\r
+                self.moveNext()\r
+            else:\r
+                break\r
+        val = self.getNumber(var)\r
+        if val is None:\r
+            value = var\r
+        else:\r
+            value = "%d" % val\r
+        return value\r
+\r
+    def parseSingleOp(self):\r
+        self.skipSpace()\r
+        if re.match('^NOT\W', self.getCurr(-1)):\r
+            self.moveNext(3)\r
+            op  = self.parseBrace()\r
+            val = self.getNumber (op)\r
+            if val is None:\r
+                self.errExit ("'%s' is not a number" % op)\r
+            return "%d" % (not self.normNumber(int(op)))\r
+        else:\r
+            return self.parseValue()\r
+\r
+    def parseBrace(self):\r
+        self.skipSpace()\r
+        char = self.getCurr()\r
+        if char == '(':\r
+            self.moveNext()\r
+            value = self.parseExpr()\r
+            self.skipSpace()\r
+            if self.getCurr() != ')':\r
+                self.errExit ("Expecting closing brace or operator")\r
+            self.moveNext()\r
+            return value\r
+        else:\r
+            value = self.parseSingleOp()\r
+            return value\r
+\r
+    def parseCompare(self):\r
+        value = self.parseBrace()\r
+        while True:\r
+            self.skipSpace()\r
+            char = self.getCurr()\r
+            if char in ['<', '>']:\r
+                self.moveNext()\r
+                next = self.getCurr()\r
+                if next == '=':\r
+                    op = char + next\r
+                    self.moveNext()\r
+                else:\r
+                    op = char\r
+                result = self.parseBrace()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(eval (value + op + result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid number for comparision" % test)\r
+            elif char in ['=', '!']:\r
+                op = self.getCurr(2)\r
+                if op in ['==', '!=']:\r
+                    self.moveNext(2)\r
+                    result = self.parseBrace()\r
+                    test = self.getNonNumber(result, value)\r
+                    if test is None:\r
+                        value = "%d" % self.normNumber((eval (value + op + result)))\r
+                    else:\r
+                        value = "%d" % self.normNumber(eval ("'" + value + "'" + op + "'" + result + "'"))\r
+                else:\r
+                    break\r
+            else:\r
+                break\r
+        return value\r
+\r
+    def parseAnd(self):\r
+        value = self.parseCompare()\r
+        while True:\r
+            self.skipSpace()\r
+            if re.match('^AND\W', self.getCurr(-1)):\r
+                self.moveNext(3)\r
+                result = self.parseCompare()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(int(value) & int(result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid op number for AND" % test)\r
+            else:\r
+                break\r
+        return value\r
+\r
+    def parseOrXor(self):\r
+        value  = self.parseAnd()\r
+        op     = None\r
+        while True:\r
+            self.skipSpace()\r
+            op = None\r
+            if re.match('^XOR\W', self.getCurr(-1)):\r
+                self.moveNext(3)\r
+                op = '^'\r
+            elif re.match('^OR\W', self.getCurr(-1)):\r
+                self.moveNext(2)\r
+                op = '|'\r
+            else:\r
+                break\r
+            if op:\r
+                result = self.parseAnd()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(eval (value + op + result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid op number for XOR/OR" % test)\r
+        return value\r
+\r
+    def parseExpr(self):\r
+        return self.parseOrXor()\r
+\r
+    def getResult(self):\r
+        value = self.parseExpr()\r
+        self.skipSpace()\r
+        if not self.isLast():\r
+            self.errExit ("Unexpected character found '%s'" % self.getCurr())\r
+        test = self.getNumber(value)\r
+        if test is None:\r
+            self.errExit ("Result '%s' is not a number" % value)\r
+        return int(value)\r
+\r
+    def evaluateExpress (self, Expr):\r
+        self.index     = 0\r
+        self.string    = Expr\r
+        if self.getResult():\r
+            Result = True\r
+        else:\r
+            Result = False\r
+        return Result\r
+\r
 class CGenCfgOpt:\r
     def __init__(self):\r
+        self.Debug          = False\r
         self.Error          = ''\r
 \r
         self._GlobalDataDef = """\r
@@ -107,7 +347,7 @@ EndList
 """\r
 \r
         self._BsfKeyList    = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']\r
-        self._HdrKeyList    = ['HEADER','STRUCT']\r
+        self._HdrKeyList    = ['HEADER','STRUCT', 'EMBED']\r
         self._BuidinOption  = {'$EN_DIS' : 'EN_DIS'}\r
 \r
         self._MacroDict   = {}\r
@@ -139,12 +379,71 @@ EndList
                     if Match:\r
                         self._MacroDict[Match.group(1)] = ''\r
         if len(self._MacroDict) == 0:\r
-            self.Error = "Invalid MACRO arguments"\r
             Error = 1\r
         else:\r
             Error = 0\r
+            if self.Debug:\r
+                print "INFO : Macro dictionary:"\r
+                for Each in self._MacroDict:\r
+                    print "       $(%s) = [ %s ]" % (Each , self._MacroDict[Each])\r
         return Error\r
 \r
+    def EvaulateIfdef   (self, Macro):\r
+        Result = Macro in self._MacroDict\r
+        if self.Debug:\r
+            print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result)\r
+        return  Result\r
+\r
+    def ExpandMacros (self, Input):\r
+        Line = Input\r
+        Match = re.findall("\$\(\w+\)", Input)\r
+        if Match:\r
+            for Each in Match:\r
+              Variable = Each[2:-1]\r
+              if Variable in self._MacroDict:\r
+                  Line = Line.replace(Each, self._MacroDict[Variable])\r
+              else:\r
+                  if self.Debug:\r
+                      print "WARN : %s is not defined" % Each\r
+                  Line = Line.replace(Each, Each[2:-1])\r
+        return Line\r
+\r
+    def EvaluateExpress (self, Expr):\r
+        ExpExpr = self.ExpandMacros(Expr)\r
+        LogExpr = CLogicalExpression()\r
+        Result  = LogExpr.evaluateExpress (ExpExpr)\r
+        if self.Debug:\r
+            print "INFO : Eval Express [%s] : %s" % (Expr, Result)\r
+        return Result\r
+\r
+    def FormatListValue(self, ConfigDict):\r
+        Struct = ConfigDict['struct']\r
+        if Struct not in ['UINT8','UINT16','UINT32','UINT64']:\r
+            return\r
+\r
+        dataarray = []\r
+        binlist = ConfigDict['value'][1:-1].split(',')\r
+        for each in binlist:\r
+            each = each.strip()\r
+            if each.startswith('0x'):\r
+                value = int(each, 16)\r
+            else:\r
+                value = int(each)\r
+            dataarray.append(value)\r
+\r
+        unit = int(Struct[4:]) / 8\r
+        if int(ConfigDict['length']) != unit * len(dataarray):\r
+            raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname'])\r
+\r
+        bytearray = []\r
+        for each in dataarray:\r
+            value = each\r
+            for loop in xrange(unit):\r
+                bytearray.append("0x%02X" % (value & 0xFF))\r
+                value = value >> 8\r
+        newvalue  = '{'  + ','.join(bytearray) + '}'\r
+        ConfigDict['value'] = newvalue\r
+        return ""\r
 \r
     def ParseDscFile (self, DscFile, FvDir):\r
         self._CfgItemList = []\r
@@ -158,20 +457,19 @@ EndList
         IsVpdSect       = False\r
         Found           = False\r
 \r
-        IfStack         = [True]\r
+        IfStack         = []\r
         ElifStack       = []\r
         Error           = 0\r
+        ConfigDict      = {}\r
 \r
         DscFd        = open(DscFile, "r")\r
         DscLines     = DscFd.readlines()\r
         DscFd.close()\r
 \r
-        ConfigDict      = {}\r
-\r
-        for DscLine in DscLines:\r
-            Handle     = False\r
-            DscLine = DscLine.strip()\r
-            Match = re.match("^\[(.+)\]", DscLine)\r
+        while len(DscLines):\r
+            DscLine  = DscLines.pop(0).strip()\r
+            Handle   = False\r
+            Match    = re.match("^\[(.+)\]", DscLine)\r
             if Match is not None:\r
                 if  Match.group(1).lower() == "Defines".lower():\r
                     IsDefSect = True\r
@@ -186,6 +484,7 @@ EndList
                     ConfigDict['name']    = ''\r
                     ConfigDict['find']    = ''\r
                     ConfigDict['struct']  = ''\r
+                    ConfigDict['embed']   = ''\r
                     ConfigDict['subreg']  = []\r
                     IsDefSect = False\r
                     IsVpdSect = True\r
@@ -199,6 +498,7 @@ EndList
                     ConfigDict['name']    = ''\r
                     ConfigDict['find']    = ''\r
                     ConfigDict['struct']  = ''\r
+                    ConfigDict['embed']   = ''\r
                     ConfigDict['subreg']  = []\r
                     IsDefSect = False\r
                     IsUpdSect = True\r
@@ -210,65 +510,77 @@ EndList
                     IsVpdSect = False\r
             else:\r
                 if IsDefSect or IsUpdSect or IsVpdSect:\r
-                    if DscLine == "!else":\r
-                        IfStack[-1] = not IfStack[-1]\r
-                    elif DscLine == "!endif":\r
-                        IfStack.pop()\r
-                        Level = ElifStack.pop()\r
-                        while Level > 0:\r
+                    if re.match("^!else($|\s+#.+)", DscLine):\r
+                        if IfStack:\r
+                            IfStack[-1] = not IfStack[-1]\r
+                        else:\r
+                            print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)\r
+                            raise SystemExit\r
+                    elif re.match("^!endif($|\s+#.+)", DscLine):\r
+                        if IfStack:\r
                             IfStack.pop()\r
-                            Level = Level - 1\r
+                            Level = ElifStack.pop()\r
+                            if Level > 0:\r
+                                del IfStack[-Level:]\r
+                        else:\r
+                            print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)\r
+                            raise SystemExit\r
                     else:\r
                         Result = False\r
-                        Match = re.match("!(ifdef|ifndef)\s+\$\((\w+)\)", DscLine)\r
-                        if Match is not None:\r
-                            if Match.group(2) in self._MacroDict:\r
-                                if Match.group(1) == 'ifdef':\r
-                                    Result = True\r
-                            else:\r
-                                if Match.group(1) == 'ifndef':\r
-                                    Result = True\r
-                            ElifStack.append(0)\r
+                        Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)\r
+                        if Match:\r
+                            Result = self.EvaulateIfdef (Match.group(2))\r
+                            if Match.group(1) == 'ifndef':\r
+                                Result = not Result\r
                             IfStack.append(Result)\r
+                            ElifStack.append(0)\r
                         else:\r
-                            Match = re.match("!(if|elseif)\s+\$\\((\w+)\)\s*==\s*(\w+|\$\(\w+\))", DscLine)\r
-                            if Match is not None:\r
-                                if Match.group(2) in self._MacroDict:\r
-                                    MacroName = self._MacroDict[Match.group(2)]\r
-                                else:\r
-                                    MacroName = ''\r
-                                Value = Match.group(3)\r
-                                if Value.startswith('$'):\r
-                                    if Value[2:-1] in self._MacroDict:\r
-                                        Value = self._MacroDict[Value[2:-1]]\r
-                                    else:\r
-                                        Value = ''\r
-                                if MacroName == Value:\r
-                                    Result = True\r
+                            Match  = re.match("!(if|elseif)\s+(.+)", DscLine)\r
+                            if Match:\r
+                                Result = self.EvaluateExpress(Match.group(2))\r
                                 if Match.group(1) == "if":\r
                                     ElifStack.append(0)\r
                                     IfStack.append(Result)\r
                                 else:   #elseif\r
-                                    IfStack[-1] = not IfStack[-1]\r
-                                    IfStack.append(Result)\r
-                                    ElifStack[-1] = ElifStack[-1] + 1\r
+                                    if IfStack:\r
+                                        IfStack[-1] = not IfStack[-1]\r
+                                        IfStack.append(Result)\r
+                                        ElifStack[-1] = ElifStack[-1] + 1\r
+                                    else:\r
+                                        print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)\r
+                                        raise SystemExit\r
                             else:\r
-                                if len(DscLine) > 0 and DscLine[0] == '!':\r
-                                    self.Error = "Invalid DscLine '%s'" % DscLine\r
-                                    Error = 3\r
-                                    break;\r
+                                if IfStack:\r
+                                    Handle = reduce(lambda x,y: x and y, IfStack)\r
                                 else:\r
-                                    if reduce(lambda x,y: x and y, IfStack):\r
-                                        Handle = True\r
-\r
+                                    Handle = True\r
+                                if Handle:\r
+                                    Match = re.match("!include\s+(.+)", DscLine)\r
+                                    if Match:\r
+                                        IncludeFilePath = Match.group(1)\r
+                                        IncludeFilePath = self.ExpandMacros(IncludeFilePath)\r
+                                        try:\r
+                                            IncludeDsc  = open(IncludeFilePath, "r")\r
+                                        except:\r
+                                            print("ERROR: Cannot open file '%s'" % IncludeFilePath)\r
+                                            raise SystemExit\r
+                                        NewDscLines = IncludeDsc.readlines()\r
+                                        IncludeDsc.close()\r
+                                        DscLines = NewDscLines + DscLines\r
+                                    else:\r
+                                        if DscLine.startswith('!'):\r
+                                            print("ERROR: Unrecoginized directive for line '%s'" % DscLine)\r
+                                            raise SystemExit\r
             if not Handle:\r
                 continue\r
 \r
             if IsDefSect:\r
                 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09\r
-                Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-\w]+)", DscLine)\r
+                Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine)\r
                 if Match:\r
                     self._MacroDict[Match.group(1)] = Match.group(2)\r
+                    if self.Debug:\r
+                        print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))\r
             else:\r
                 Match = re.match("^\s*#\s+!(BSF|HDR)\s+(.+)", DscLine)\r
                 if Match:\r
@@ -291,7 +603,7 @@ EndList
                         for Key in self._BsfKeyList:\r
                             Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
                             if Match:\r
-                                if Key in ['HELP', 'OPTION'] and Match.group(1).startswith('+'):\r
+                                if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'):\r
                                     ConfigDict[Key.lower()] += Match.group(1)[1:]\r
                                 else:\r
                                     ConfigDict[Key.lower()]  = Match.group(1)\r
@@ -303,7 +615,7 @@ EndList
 \r
                 # Check VPD/UPD\r
                 if IsUpdSect:\r
-                    Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]{4})\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+                    Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
                 else:\r
                     Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?",  DscLine)\r
                 if Match:\r
@@ -337,9 +649,14 @@ EndList
                     if Match:\r
                         if Match.group(1) in self._MacroDict:\r
                             Value = self._MacroDict[Match.group(1)]\r
+\r
                     ConfigDict['value']  = Value\r
+                    if (len(Value) > 0)  and (Value[0] == '{'):\r
+                        Value = self.FormatListValue(ConfigDict)\r
+\r
                     if ConfigDict['name']  == '':\r
                         # Clear BSF specific items\r
+                        ConfigDict['bsfname']   = ''\r
                         ConfigDict['help']   = ''\r
                         ConfigDict['type']   = ''\r
                         ConfigDict['option'] = ''\r
@@ -348,6 +665,7 @@ EndList
                     ConfigDict['name']   = ''\r
                     ConfigDict['find']   = ''\r
                     ConfigDict['struct'] = ''\r
+                    ConfigDict['embed']  = ''\r
                     ConfigDict['order']  = -1\r
                     ConfigDict['subreg'] = []\r
                 else:\r
@@ -501,26 +819,31 @@ EndList
         TxtFd.close()\r
         return 0\r
 \r
-    def CreateField (self, Name, Length, Offset, Struct):\r
+    def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help):\r
         PosName    = 28\r
         PosComment = 30\r
+        NameLine=''\r
+        HelpLine=''\r
 \r
         IsArray = False\r
-        if Length == 1:\r
-            Type = "UINT8"\r
-        elif Length == 2:\r
-            Type = "UINT16"\r
-        elif Length == 4:\r
-            Type = "UINT32"\r
-        elif Length == 8:\r
-            Type = "UINT64"\r
+        if Length in [1,2,4,8]:\r
+            Type = "UINT%d" % (Length * 8)\r
         else:\r
+            IsArray = True\r
+            Type = "UINT8"\r
+\r
+        if Item and Item['value'].startswith('{'):\r
             Type = "UINT8"\r
             IsArray = True\r
 \r
         if Struct != '':\r
-            IsArray = False\r
             Type = Struct\r
+            if Struct in ['UINT8','UINT16','UINT32','UINT64']:\r
+                IsArray = True\r
+                Unit = int(Type[4:]) / 8\r
+                Length = Length / Unit\r
+            else:\r
+                IsArray = False\r
 \r
         if IsArray:\r
             Name = Name + '[%d]' % Length\r
@@ -530,22 +853,63 @@ EndList
         else:\r
             Space1 = 1\r
 \r
-        if len(Name) < PosComment:\r
-            Space2 = PosComment - len(Name)\r
-        else:\r
-            Space2 = 1\r
+        if BsfName != '':\r
+            NameLine="    %s\n" % BsfName\r
 \r
-        return "  %s%s%s;%s/* Offset 0x%04X */\n" % (Type, ' ' * Space1, Name, ' ' * Space2, Offset)\r
+        if Help != '':\r
+            HelpLine="    %s\n" % Help\r
 \r
+        if Offset is None:\r
+            OffsetStr = '????'\r
+        else:\r
+            OffsetStr = '0x%04X' % Offset\r
+\r
+        return "/** Offset %s\n%s%s**/\n  %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, Type, ' ' * Space1, Name,)\r
+\r
+    def PostProcessBody (self, TextBody):\r
+        NewTextBody = []\r
+        OldTextBody = []\r
+        IncludeLine = False\r
+        StructName  = ''\r
+        VariableName = ''\r
+        for Line in TextBody:\r
+           Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)\r
+           if Match:\r
+               Line = Match.group(4)\r
+\r
+           if Match and Match.group(3) == 'START':\r
+               NewTextBody.append ('typedef struct {\n')\r
+               StructName   = Match.group(1)\r
+               VariableName = Match.group(2)\r
+               MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)\r
+               if MatchOffset:\r
+                   Offset = int(MatchOffset.group(1), 16)\r
+               else:\r
+                   Offset = None\r
+               Line\r
+               IncludeLine = True\r
+               OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', ''))\r
+           if IncludeLine:\r
+               NewTextBody.append (Line)\r
+           else:\r
+               OldTextBody.append (Line)\r
+\r
+           if Match and Match.group(3) == 'END':  \r
+               if (StructName != Match.group(1)) or (VariableName != Match.group(2)):\r
+                   print "Unmatched struct name '%s' and '%s' !"  % (StructName, Match.group(1))\r
+               else:\r
+                   NewTextBody.append ('} %s;\n\n' %  StructName)\r
+               IncludeLine = False\r
+        NewTextBody.extend(OldTextBody)\r
+        return NewTextBody\r
 \r
     def CreateHeaderFile (self, InputHeaderFile, IsInternal):\r
-        Error = 0\r
         FvDir = self._FvDir\r
 \r
         if IsInternal:\r
-            HeaderFile = os.path.join(FvDir, 'VpdHeader.h')\r
+            HeaderFile = os.path.join(FvDir, 'FspUpdVpdInternal.h')\r
         else:\r
-            HeaderFile = os.path.join(FvDir, 'fsp_vpd.h')\r
+            HeaderFile = os.path.join(FvDir, 'FspUpdVpd.h')\r
 \r
         # Check if header needs to be recreated\r
         ReCreate = False\r
@@ -566,36 +930,22 @@ EndList
                 self.Error = "No DSC or input header file is changed, skip the header file generating"\r
                 return 256\r
 \r
-        HeaderFd = open(HeaderFile, "w")\r
-        FileBase = os.path.basename(HeaderFile)\r
-        FileName = FileBase.replace(".", "_").upper()\r
-        HeaderFd.write("%s\n"   % (__copyright_h__ % date.today().year))\r
-        HeaderFd.write("#ifndef __%s__\n"   % FileName)\r
-        HeaderFd.write("#define __%s__\n\n" % FileName)\r
-        HeaderFd.write("#pragma pack(1)\n\n")\r
-\r
-        if InputHeaderFile != '':\r
-            if not os.path.exists(InputHeaderFile):\r
-                 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
-                 return 2\r
-\r
-            InFd         = open(InputHeaderFile, "r")\r
-            IncLines     = InFd.readlines()\r
-            InFd.close()\r
-\r
-            Export = False\r
-            for Line in IncLines:\r
-                Match = re.search ("!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
-                if Match:\r
-                    if Match.group(1) == "BEGIN":\r
-                        Export = True\r
-                        continue\r
-                    else:\r
-                        Export = False\r
-                        continue\r
-                if Export:\r
-                    HeaderFd.write(Line)\r
-            HeaderFd.write("\n\n")\r
+        TxtBody = []\r
+        for Item in self._CfgItemList:\r
+           if str(Item['cname']) == 'Signature' and Item['length'] == 8:\r
+               Value = int(Item['value'], 16)\r
+               Chars = []\r
+               while Value != 0x0:\r
+                   Chars.append(chr(Value & 0xFF))\r
+                   Value = Value >> 8\r
+               SignatureStr = ''.join(Chars)\r
+               if int(Item['offset']) == 0:\r
+                   TxtBody.append("#define FSP_UPD_SIGNATURE                %s        /* '%s' */\n" % (Item['value'], SignatureStr))\r
+               elif 'MEM' in SignatureStr:\r
+                   TxtBody.append("#define FSP_MEMORY_INIT_UPD_SIGNATURE    %s        /* '%s' */\n" % (Item['value'], SignatureStr))\r
+               else:\r
+                   TxtBody.append("#define FSP_SILICON_INIT_UPD_SIGNATURE   %s        /* '%s' */\n" % (Item['value'], SignatureStr))\r
+        TxtBody.append("\n")\r
 \r
         for Region in ['UPD', 'VPD']:\r
 \r
@@ -603,25 +953,23 @@ EndList
             if Region[0] == 'V':\r
                 if 'VPD_TOOL_GUID' not in self._MacroDict:\r
                     self.Error = "VPD_TOOL_GUID definition is missing in DSC file"\r
-                    Error = 1\r
-                    break\r
+                    return 1\r
 \r
                 BinFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + ".bin")\r
                 if not os.path.exists(BinFile):\r
                     self.Error = "VPD binary file '%s' does not exist" % BinFile\r
-                    Error = 2\r
-                    break\r
+                    return 2\r
 \r
                 BinFd = open(BinFile, "rb")\r
                 IdStr    = BinFd.read(0x08)\r
-                ImageId  = struct.unpack('Q', IdStr)\r
-                ImageRev = struct.unpack('I', BinFd.read(0x04))\r
+                ImageId  = struct.unpack('<Q', IdStr)\r
+                ImageRev = struct.unpack('<I', BinFd.read(0x04))\r
                 BinFd.close()\r
 \r
-                HeaderFd.write("#define VPD_IMAGE_ID    0x%016X        /* '%s' */\n" % (ImageId[0], IdStr))\r
-                HeaderFd.write("#define VPD_IMAGE_REV   0x%08X \n\n" % ImageRev[0])\r
+                TxtBody.append("#define FSP_IMAGE_ID    0x%016X        /* '%s' */\n" % (ImageId[0], IdStr))\r
+                TxtBody.append("#define FSP_IMAGE_REV   0x%08X \n\n" % ImageRev[0])\r
 \r
-            HeaderFd.write("typedef struct _" + Region[0]  + "PD_DATA_REGION {\n")\r
+            TxtBody.append("typedef struct _" + Region[0]  + "PD_DATA_REGION {\n")\r
             NextOffset  = 0\r
             SpaceIdx    = 0\r
             Offset      = 0\r
@@ -643,35 +991,81 @@ EndList
                         NextVisible = True\r
                         Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx\r
                         ResvIdx = ResvIdx + 1\r
-                        HeaderFd.write(self.CreateField (Name, Item["offset"] - ResvOffset, ResvOffset, ''))\r
+                        TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', ''))\r
 \r
                 if  Offset < Item["offset"]:\r
                     if IsInternal or LastVisible:\r
                         Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx\r
-                        LineBuffer.append(self.CreateField (Name, Item["offset"] - Offset, Offset, ''))\r
+                        LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', ''))\r
                     SpaceIdx = SpaceIdx + 1\r
                     Offset   = Item["offset"]\r
 \r
                 if Offset != Item["offset"]:\r
-                    print "Unsorted offset 0x%04X\n" % Item["offset"]\r
-                    error = 2\r
-                    break;\r
+                    self.Error = "Unsorted offset 0x%04X\n" % Item["offset"]\r
+                    return 3                    \r
 \r
                 LastVisible = NextVisible\r
 \r
                 Offset = Offset + Item["length"]\r
                 if IsInternal or LastVisible:\r
                     for Each in LineBuffer:\r
-                        HeaderFd.write (Each)\r
+                        TxtBody.append (Each)\r
                     LineBuffer = []\r
-                    HeaderFd.write(self.CreateField (Item["cname"], Item["length"], Item["offset"], Item['struct']))\r
+                    Embed = Item["embed"].upper()\r
+                    if Embed.endswith(':START') or Embed.endswith(':END'):\r
+                        Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
+                    else:\r
+                        if Embed == '':\r
+                            Marker = '';\r
+                        else:\r
+                            self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]\r
+                            return 4\r
+                    Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'])\r
+                    TxtBody.append(Line)\r
+                    \r
+            TxtBody.append("} " + Region[0] + "PD_DATA_REGION;\n\n")\r
+        \r
+        # Handle the embedded data structure\r
+        TxtBody = self.PostProcessBody (TxtBody)\r
+\r
+        HeaderFd = open(HeaderFile, "w")\r
+        FileBase = os.path.basename(HeaderFile)\r
+        FileName = FileBase.replace(".", "_").upper()\r
+        HeaderFd.write("%s\n"   % (__copyright_h__ % date.today().year))\r
+        HeaderFd.write("#ifndef __%s__\n"   % FileName)\r
+        HeaderFd.write("#define __%s__\n\n" % FileName)\r
+        HeaderFd.write("#pragma pack(1)\n\n")\r
+\r
+        if InputHeaderFile != '':\r
+            if not os.path.exists(InputHeaderFile):\r
+                 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
+                 return 6\r
+\r
+            InFd         = open(InputHeaderFile, "r")\r
+            IncLines     = InFd.readlines()\r
+            InFd.close()\r
 \r
-            HeaderFd.write("} " + Region[0] + "PD_DATA_REGION;\n\n")\r
+            Export = False\r
+            for Line in IncLines:\r
+                Match = re.search ("!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
+                if Match:\r
+                    if Match.group(1) == "BEGIN":\r
+                        Export = True\r
+                        continue\r
+                    else:\r
+                        Export = False\r
+                        continue\r
+                if Export:\r
+                    HeaderFd.write(Line)\r
+            HeaderFd.write("\n\n")\r
+            \r
+        for Line in TxtBody:\r
+            HeaderFd.write (Line)\r
         HeaderFd.write("#pragma pack()\n\n")\r
         HeaderFd.write("#endif\n")\r
         HeaderFd.close()\r
 \r
-        return Error\r
+        return 0\r
 \r
     def WriteBsfStruct  (self, BsfFd, Item):\r
         if Item['type'] == "None":\r
@@ -713,7 +1107,22 @@ EndList
         elif Item['type'].startswith("EditText"):\r
             BsfFd.write('    %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']));\r
             WriteHelp = 1\r
-\r
+        elif Item['type'] == "Table":\r
+            Columns = Item['option'].split(',')\r
+            if len(Columns) != 0:\r
+                BsfFd.write('    %s $%s "%s",' % (Item['type'], PcdName, Item['name']));\r
+                for Col in Columns:\r
+                    Fmt = Col.split(':')\r
+                    if len(Fmt) != 3:\r
+                        raise Exception("Column format '%s' is invalid !" % Fmt)\r
+                    try:\r
+                        Dtype = int(Fmt[1].strip())\r
+                    except:\r
+                        raise Exception("Column size '%s' is invalid !" % Fmt[1])\r
+                    BsfFd.write('\n        Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))\r
+                BsfFd.write(',\n')\r
+                WriteHelp = 1\r
+            \r
         if WriteHelp  > 0:\r
             HelpLines = Item['help'].split('\\n\\r')\r
             FirstLine = True\r
@@ -825,6 +1234,8 @@ def Main():
             print "ERROR: Cannot open DSC file '%s' !" % DscFile\r
             return 2\r
 \r
+        UpdateMemSiUpdInitOffsetValue(DscFile)\r
+\r
         OutFile = ''\r
         if argc > 4:\r
             if sys.argv[4][0] == '-':\r
@@ -833,7 +1244,7 @@ def Main():
                 OutFile = sys.argv[4]\r
                 Start = 5\r
             if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:\r
-                print "ERROR: %s !" % GenCfgOpt.Error\r
+                print "ERROR: Macro parsing failed !"\r
                 return 3\r
 \r
         FvDir = sys.argv[3]\r
@@ -845,7 +1256,6 @@ def Main():
             print "ERROR: %s !" % GenCfgOpt.Error\r
             return 5\r
 \r
-\r
         if GenCfgOpt.UpdateVpdSizeField() != 0:\r
             print "ERROR: %s !" % GenCfgOpt.Error\r
             return 6\r