]> 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 6b850f66012f0285364774badfb7a0c70e7b3f6b..a38da70212a8cceee328e6b1667ceef6751ef3a9 100644 (file)
@@ -88,6 +88,48 @@ 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
@@ -305,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
@@ -425,7 +467,7 @@ EndList
         DscFd.close()\r
 \r
         while len(DscLines):\r
-            DscLine  = DscLines.pop(0).strip()            \r
+            DscLine  = DscLines.pop(0).strip()\r
             Handle   = False\r
             Match    = re.match("^\[(.+)\]", DscLine)\r
             if Match is not None:\r
@@ -442,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
@@ -455,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
@@ -527,7 +571,6 @@ EndList
                                         if DscLine.startswith('!'):\r
                                             print("ERROR: Unrecoginized directive for line '%s'" % DscLine)\r
                                             raise SystemExit\r
-                                        \r
             if not Handle:\r
                 continue\r
 \r
@@ -560,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
@@ -572,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
@@ -613,6 +656,7 @@ EndList
 \r
                     if ConfigDict['name']  == '':\r
                         # Clear BSF specific items\r
+                        ConfigDict['bsfname']   = ''\r
                         ConfigDict['help']   = ''\r
                         ConfigDict['type']   = ''\r
                         ConfigDict['option'] = ''\r
@@ -621,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
@@ -774,9 +819,11 @@ EndList
         TxtFd.close()\r
         return 0\r
 \r
-    def CreateField (self, Item, 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 in [1,2,4,8]:\r
@@ -785,7 +832,7 @@ EndList
             IsArray = True\r
             Type = "UINT8"\r
 \r
-        if Item['value'].startswith('{'):\r
+        if Item and Item['value'].startswith('{'):\r
             Type = "UINT8"\r
             IsArray = True\r
 \r
@@ -806,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
@@ -842,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
@@ -879,14 +953,12 @@ 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
@@ -894,10 +966,10 @@ EndList
                 ImageRev = struct.unpack('<I', BinFd.read(0x04))\r
                 BinFd.close()\r
 \r
-                HeaderFd.write("#define FSP_IMAGE_ID    0x%016X        /* '%s' */\n" % (ImageId[0], IdStr))\r
-                HeaderFd.write("#define FSP_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
@@ -919,35 +991,81 @@ EndList
                         NextVisible = True\r
                         Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx\r
                         ResvIdx = ResvIdx + 1\r
-                        HeaderFd.write(self.CreateField (Item, 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 (Item, 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, 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
-            HeaderFd.write("} " + Region[0] + "PD_DATA_REGION;\n\n")\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
+            \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
@@ -989,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
@@ -1101,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
@@ -1109,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