]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2Pkg/Tools/GenCfgOpt.py
IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto assignment
[mirror_edk2.git] / IntelFsp2Pkg / Tools / GenCfgOpt.py
index 32cf63ff03a4ee6e74d026f35e4d303862363ace..04b61a5672c8554eeef3382216d683b4a02e09fb 100644 (file)
@@ -418,6 +418,8 @@ EndList
         return ""\r
 \r
     def ParseDscFile (self, DscFile, FvDir):\r
+        Hardcode = False\r
+        AutoAlign = False\r
         self._CfgItemList = []\r
         self._CfgPageDict = {}\r
         self._CfgBlkDict  = {}\r
@@ -438,6 +440,8 @@ EndList
         DscLines     = DscFd.readlines()\r
         DscFd.close()\r
 \r
+        MaxAlign = 32   #Default align to 32, but if there are 64 bit unit, align to 64\r
+        SizeAlign = 0   #record the struct max align\r
         while len(DscLines):\r
             DscLine  = DscLines.pop(0).strip()\r
             Handle   = False\r
@@ -464,6 +468,7 @@ EndList
                     ConfigDict['comment'] = ''\r
                     ConfigDict['subreg']  = []\r
                     IsUpdSect = True\r
+                    Offset    = 0\r
             else:\r
                 if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:\r
                     if re.match("^!else($|\s+#.+)", DscLine):\r
@@ -530,6 +535,7 @@ EndList
                                         NewDscLines = IncludeDsc.readlines()\r
                                         IncludeDsc.close()\r
                                         DscLines = NewDscLines + DscLines\r
+                                        Offset = 0\r
                                     else:\r
                                         if DscLine.startswith('!'):\r
                                             print("ERROR: Unrecoginized directive for line '%s'" % DscLine)\r
@@ -620,13 +626,22 @@ 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]+)\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
                     ConfigDict['space']  = Match.group(1)\r
                     ConfigDict['cname']  = Match.group(2)\r
-                    ConfigDict['offset'] = int (Match.group(3), 16)\r
+                    if Match.group(3) != '*':\r
+                        Hardcode = True\r
+                        Offset =  int (Match.group(3), 16)\r
+                    else:\r
+                        AutoAlign = True\r
+\r
+                    if Hardcode and AutoAlign:\r
+                        print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")\r
+                        raise SystemExit\r
+                    ConfigDict['offset'] = Offset\r
                     if ConfigDict['order'] == -1:\r
                         ConfigDict['order'] = ConfigDict['offset'] << 8\r
                     else:\r
@@ -638,6 +653,7 @@ EndList
                             Length  = int (Match.group(4), 16)\r
                         else :\r
                             Length  = int (Match.group(4))\r
+                        Offset += Length\r
                     else:\r
                         Value = Match.group(4)\r
                         if Value is None:\r
@@ -665,6 +681,52 @@ EndList
                         ConfigDict['help']   = ''\r
                         ConfigDict['type']   = ''\r
                         ConfigDict['option'] = ''\r
+                    if IsUpdSect and AutoAlign:\r
+                        ItemLength = int(ConfigDict['length'])\r
+                        ItemOffset = int(ConfigDict['offset'])\r
+                        ItemStruct = ConfigDict['struct']\r
+                        Unit = 1\r
+                        if ItemLength in [1, 2, 4, 8] and not ConfigDict['value'].startswith('{'):\r
+                            Unit = ItemLength\r
+                            # If there are 64 bit unit, align to 64\r
+                            if Unit == 8:\r
+                                MaxAlign = 64\r
+                                SizeAlign = 8\r
+                        if ItemStruct != '':\r
+                            UnitDict = {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}\r
+                            if ItemStruct in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:\r
+                                Unit = UnitDict[ItemStruct]\r
+                                # If there are 64 bit unit, align to 64\r
+                                if Unit == 8:\r
+                                    MaxAlign = 64\r
+                                SizeAlign = max(SizeAlign, Unit)\r
+                        if (ConfigDict['embed'].find(':START') != -1):\r
+                            Base = ItemOffset\r
+                        SubOffset = ItemOffset - Base\r
+                        SubRemainder = SubOffset % Unit\r
+                        if SubRemainder:\r
+                            Diff = Unit - SubRemainder\r
+                            Offset = Offset + Diff\r
+                            ItemOffset = ItemOffset + Diff\r
+\r
+                        if (ConfigDict['embed'].find(':END') != -1):\r
+                            Remainder = Offset % (MaxAlign/8)   # MaxAlign is either 32 or 64\r
+                            if Remainder:\r
+                                Diff = (MaxAlign/8) - Remainder\r
+                                Offset = Offset + Diff\r
+                                ItemOffset = ItemOffset + Diff\r
+                            MaxAlign = 32                       # Reset to default 32 align when struct end\r
+                        if (ConfigDict['cname'] == 'UpdTerminator'):\r
+                            # ItemLength is the size of UpdTerminator\r
+                            # Itemlength might be 16, 32, or 64\r
+                            # Struct align to 64 if UpdTerminator\r
+                            # or struct size is 64 bit, else align to 32\r
+                            Remainder = Offset % max(ItemLength/8, 4, SizeAlign)\r
+                            Offset = Offset + ItemLength\r
+                            if Remainder:\r
+                                Diff = max(ItemLength/8, 4, SizeAlign) - Remainder\r
+                                ItemOffset = ItemOffset + Diff\r
+                        ConfigDict['offset'] = ItemOffset\r
 \r
                     self._CfgItemList.append(ConfigDict.copy())\r
                     ConfigDict['name']   = ''\r