public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto assignment
@ 2018-09-26 11:29 Chasel, Chiu
  2018-09-27  0:39 ` Yao, Jiewen
  0 siblings, 1 reply; 2+ messages in thread
From: Chasel, Chiu @ 2018-09-26 11:29 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jiewen Yao, Gao Liming, Zhu Yonghong, Chasel Chiu

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1211

For reducing maintenance effort, the UPD offset can be
automatic assigned by GenCfgOpt.py following by alignment
requirements.

The usage model as below:
. If UPD offset in DSC file are all '*', GenCfgOpt.py will
  assign offset for all UPD automatically. In this case no
  need to manually hardcode offset to all UPD in DSC.

. If UPD offset in DSC file are all not '*', GenCfgOpt.py
  will use hardcoded offset directly (original usage model)

. Tool does not support mixing scenario so UPD offset in DSC
  should be all '*' or all hardcoded but not mixed.

In auto mode UPD offset will be assigned following natural
alignment (size aligned) rule and the whole structure size
will align to either 32bits or 64bits depends on maximal UPD
size in the structure.

Test: Verified by both UPD offset hardcoded or '*' in DSC and
      generated UPD header files are correct.

Cc: Jiewen Yao <Jiewen.yao@intel.com>
Cc: Gao Liming <liming.gao@intel.com>
Cc: Zhu Yonghong <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
---
 IntelFsp2Pkg/Tools/GenCfgOpt.py | 68 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 3 deletions(-)

diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt.py
index c9b7bc5373..9b8943b702 100644
--- a/IntelFsp2Pkg/Tools/GenCfgOpt.py
+++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py
@@ -1,6 +1,6 @@
 ## @ GenCfgOpt.py
 #
-# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials are licensed and made available under
 # the terms and conditions of the BSD License that accompanies this distribution.
 # The full text of the license may be found at
@@ -418,6 +418,8 @@ EndList
         return ""
 
     def ParseDscFile (self, DscFile, FvDir):
+        Hardcode = False
+        AutoAlign = False
         self._CfgItemList = []
         self._CfgPageDict = {}
         self._CfgBlkDict  = {}
@@ -438,6 +440,8 @@ EndList
         DscLines     = DscFd.readlines()
         DscFd.close()
 
+        MaxAlign = 32   #Default align to 32, but if there are 64 bit unit, align to 64
+        SizeAlign = 0   #record the struct max align
         while len(DscLines):
             DscLine  = DscLines.pop(0).strip()
             Handle   = False
@@ -464,6 +468,7 @@ EndList
                     ConfigDict['comment'] = ''
                     ConfigDict['subreg']  = []
                     IsUpdSect = True
+                    Offset    = 0
             else:
                 if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:
                     if re.match("^!else($|\s+#.+)", DscLine):
@@ -530,6 +535,7 @@ EndList
                                         NewDscLines = IncludeDsc.readlines()
                                         IncludeDsc.close()
                                         DscLines = NewDscLines + DscLines
+                                        Offset = 0
                                     else:
                                         if DscLine.startswith('!'):
                                             print("ERROR: Unrecoginized directive for line '%s'" % DscLine)
@@ -620,13 +626,22 @@ EndList
 
                 # Check VPD/UPD
                 if IsUpdSect:
-                    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)
+                    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)
                 else:
                     Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?",  DscLine)
                 if Match:
                     ConfigDict['space']  = Match.group(1)
                     ConfigDict['cname']  = Match.group(2)
-                    ConfigDict['offset'] = int (Match.group(3), 16)
+                    if Match.group(3) != '*':
+                        Hardcode = True
+                        Offset =  int (Match.group(3), 16)
+                    else:
+                        AutoAlign = True
+
+                    if Hardcode and AutoAlign:
+                        print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")
+                        raise SystemExit
+                    ConfigDict['offset'] = Offset
                     if ConfigDict['order'] == -1:
                         ConfigDict['order'] = ConfigDict['offset'] << 8
                     else:
@@ -638,6 +653,7 @@ EndList
                             Length  = int (Match.group(4), 16)
                         else :
                             Length  = int (Match.group(4))
+                        Offset += Length
                     else:
                         Value = Match.group(4)
                         if Value is None:
@@ -665,6 +681,52 @@ EndList
                         ConfigDict['help']   = ''
                         ConfigDict['type']   = ''
                         ConfigDict['option'] = ''
+                    if IsUpdSect and AutoAlign:
+                        ItemLength = int(ConfigDict['length'])
+                        ItemOffset = int(ConfigDict['offset'])
+                        ItemStruct = ConfigDict['struct']
+                        Unit = 1
+                        if ItemLength in [1, 2, 4, 8] and not ConfigDict['value'].startswith('{'):
+                            Unit = ItemLength
+                            # If there are 64 bit unit, align to 64
+                            if Unit == 8:
+                                MaxAlign = 64
+                                SizeAlign = 8
+                        if ItemStruct != '':
+                            UnitDict = {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}
+                            if ItemStruct in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
+                                Unit = UnitDict[ItemStruct]
+                                # If there are 64 bit unit, align to 64
+                                if Unit == 8:
+                                    MaxAlign = 64
+                                SizeAlign = max(SizeAlign, Unit)
+                        if (ConfigDict['embed'].find(':START') != -1):
+                            Base = ItemOffset
+                        SubOffset = ItemOffset - Base
+                        SubRemainder = SubOffset % Unit
+                        if SubRemainder:
+                            Diff = Unit - SubRemainder
+                            Offset = Offset + Diff
+                            ItemOffset = ItemOffset + Diff
+
+                        if (ConfigDict['embed'].find(':END') != -1):
+                            Remainder = Offset % (MaxAlign/8)   # MaxAlign is either 32 or 64
+                            if Remainder:
+                                Diff = (MaxAlign/8) - Remainder
+                                Offset = Offset + Diff
+                                ItemOffset = ItemOffset + Diff
+                            MaxAlign = 32                       # Reset to default 32 align when struct end
+                        if (ConfigDict['cname'] == 'UpdTerminator'):
+                            # ItemLength is the size of UpdTerminator
+                            # Itemlength might be 16, 32, or 64
+                            # Struct align to 64 if UpdTerminator
+                            # or struct size is 64 bit, else align to 32
+                            Remainder = Offset % max(ItemLength/8, 4, SizeAlign)
+                            Offset = Offset + ItemLength
+                            if Remainder:
+                                Diff = max(ItemLength/8, 4, SizeAlign) - Remainder
+                                ItemOffset = ItemOffset + Diff
+                        ConfigDict['offset'] = ItemOffset
 
                     self._CfgItemList.append(ConfigDict.copy())
                     ConfigDict['name']   = ''
-- 
2.13.3.windows.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto assignment
  2018-09-26 11:29 [PATCH] IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto assignment Chasel, Chiu
@ 2018-09-27  0:39 ` Yao, Jiewen
  0 siblings, 0 replies; 2+ messages in thread
From: Yao, Jiewen @ 2018-09-27  0:39 UTC (permalink / raw)
  To: Chiu, Chasel, edk2-devel@lists.01.org; +Cc: Gao, Liming, Zhu, Yonghong

Reviewed-by: jiewen.yao@intel.com

> -----Original Message-----
> From: Chiu, Chasel
> Sent: Wednesday, September 26, 2018 7:29 PM
> To: edk2-devel@lists.01.org
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Zhu, Yonghong <yonghong.zhu@intel.com>; Chiu,
> Chasel <chasel.chiu@intel.com>
> Subject: [PATCH] IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto
> assignment
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1211
> 
> For reducing maintenance effort, the UPD offset can be
> automatic assigned by GenCfgOpt.py following by alignment
> requirements.
> 
> The usage model as below:
> . If UPD offset in DSC file are all '*', GenCfgOpt.py will
>   assign offset for all UPD automatically. In this case no
>   need to manually hardcode offset to all UPD in DSC.
> 
> . If UPD offset in DSC file are all not '*', GenCfgOpt.py
>   will use hardcoded offset directly (original usage model)
> 
> . Tool does not support mixing scenario so UPD offset in DSC
>   should be all '*' or all hardcoded but not mixed.
> 
> In auto mode UPD offset will be assigned following natural
> alignment (size aligned) rule and the whole structure size
> will align to either 32bits or 64bits depends on maximal UPD
> size in the structure.
> 
> Test: Verified by both UPD offset hardcoded or '*' in DSC and
>       generated UPD header files are correct.
> 
> Cc: Jiewen Yao <Jiewen.yao@intel.com>
> Cc: Gao Liming <liming.gao@intel.com>
> Cc: Zhu Yonghong <yonghong.zhu@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
> ---
>  IntelFsp2Pkg/Tools/GenCfgOpt.py | 68
> +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py
> b/IntelFsp2Pkg/Tools/GenCfgOpt.py
> index c9b7bc5373..9b8943b702 100644
> --- a/IntelFsp2Pkg/Tools/GenCfgOpt.py
> +++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py
> @@ -1,6 +1,6 @@
>  ## @ GenCfgOpt.py
>  #
> -# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
>  # This program and the accompanying materials are licensed and made
> available under
>  # the terms and conditions of the BSD License that accompanies this
> distribution.
>  # The full text of the license may be found at
> @@ -418,6 +418,8 @@ EndList
>          return ""
> 
>      def ParseDscFile (self, DscFile, FvDir):
> +        Hardcode = False
> +        AutoAlign = False
>          self._CfgItemList = []
>          self._CfgPageDict = {}
>          self._CfgBlkDict  = {}
> @@ -438,6 +440,8 @@ EndList
>          DscLines     = DscFd.readlines()
>          DscFd.close()
> 
> +        MaxAlign = 32   #Default align to 32, but if there are 64 bit unit,
> align to 64
> +        SizeAlign = 0   #record the struct max align
>          while len(DscLines):
>              DscLine  = DscLines.pop(0).strip()
>              Handle   = False
> @@ -464,6 +468,7 @@ EndList
>                      ConfigDict['comment'] = ''
>                      ConfigDict['subreg']  = []
>                      IsUpdSect = True
> +                    Offset    = 0
>              else:
>                  if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:
>                      if re.match("^!else($|\s+#.+)", DscLine):
> @@ -530,6 +535,7 @@ EndList
>                                          NewDscLines =
> IncludeDsc.readlines()
>                                          IncludeDsc.close()
>                                          DscLines = NewDscLines +
> DscLines
> +                                        Offset = 0
>                                      else:
>                                          if DscLine.startswith('!'):
>                                              print("ERROR:
> Unrecoginized directive for line '%s'" % DscLine)
> @@ -620,13 +626,22 @@ EndList
> 
>                  # Check VPD/UPD
>                  if IsUpdSect:
> -                    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)
> +                    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)
>                  else:
>                      Match =
> re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.
> +))?",  DscLine)
>                  if Match:
>                      ConfigDict['space']  = Match.group(1)
>                      ConfigDict['cname']  = Match.group(2)
> -                    ConfigDict['offset'] = int (Match.group(3), 16)
> +                    if Match.group(3) != '*':
> +                        Hardcode = True
> +                        Offset =  int (Match.group(3), 16)
> +                    else:
> +                        AutoAlign = True
> +
> +                    if Hardcode and AutoAlign:
> +                        print("Hardcode and auto-align mixed mode is
> not supported by GenCfgOpt")
> +                        raise SystemExit
> +                    ConfigDict['offset'] = Offset
>                      if ConfigDict['order'] == -1:
>                          ConfigDict['order'] = ConfigDict['offset'] << 8
>                      else:
> @@ -638,6 +653,7 @@ EndList
>                              Length  = int (Match.group(4), 16)
>                          else :
>                              Length  = int (Match.group(4))
> +                        Offset += Length
>                      else:
>                          Value = Match.group(4)
>                          if Value is None:
> @@ -665,6 +681,52 @@ EndList
>                          ConfigDict['help']   = ''
>                          ConfigDict['type']   = ''
>                          ConfigDict['option'] = ''
> +                    if IsUpdSect and AutoAlign:
> +                        ItemLength = int(ConfigDict['length'])
> +                        ItemOffset = int(ConfigDict['offset'])
> +                        ItemStruct = ConfigDict['struct']
> +                        Unit = 1
> +                        if ItemLength in [1, 2, 4, 8] and not
> ConfigDict['value'].startswith('{'):
> +                            Unit = ItemLength
> +                            # If there are 64 bit unit, align to 64
> +                            if Unit == 8:
> +                                MaxAlign = 64
> +                                SizeAlign = 8
> +                        if ItemStruct != '':
> +                            UnitDict = {'UINT8':1, 'UINT16':2,
> 'UINT32':4, 'UINT64':8}
> +                            if ItemStruct in ['UINT8', 'UINT16',
> 'UINT32', 'UINT64']:
> +                                Unit = UnitDict[ItemStruct]
> +                                # If there are 64 bit unit, align to 64
> +                                if Unit == 8:
> +                                    MaxAlign = 64
> +                                SizeAlign = max(SizeAlign, Unit)
> +                        if (ConfigDict['embed'].find(':START') != -1):
> +                            Base = ItemOffset
> +                        SubOffset = ItemOffset - Base
> +                        SubRemainder = SubOffset % Unit
> +                        if SubRemainder:
> +                            Diff = Unit - SubRemainder
> +                            Offset = Offset + Diff
> +                            ItemOffset = ItemOffset + Diff
> +
> +                        if (ConfigDict['embed'].find(':END') != -1):
> +                            Remainder = Offset % (MaxAlign/8)   #
> MaxAlign is either 32 or 64
> +                            if Remainder:
> +                                Diff = (MaxAlign/8) - Remainder
> +                                Offset = Offset + Diff
> +                                ItemOffset = ItemOffset + Diff
> +                            MaxAlign = 32
> # Reset to default 32 align when struct end
> +                        if (ConfigDict['cname'] == 'UpdTerminator'):
> +                            # ItemLength is the size of
> UpdTerminator
> +                            # Itemlength might be 16, 32, or 64
> +                            # Struct align to 64 if UpdTerminator
> +                            # or struct size is 64 bit, else align to 32
> +                            Remainder = Offset % max(ItemLength/8,
> 4, SizeAlign)
> +                            Offset = Offset + ItemLength
> +                            if Remainder:
> +                                Diff = max(ItemLength/8, 4,
> SizeAlign) - Remainder
> +                                ItemOffset = ItemOffset + Diff
> +                        ConfigDict['offset'] = ItemOffset
> 
>                      self._CfgItemList.append(ConfigDict.copy())
>                      ConfigDict['name']   = ''
> --
> 2.13.3.windows.1



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-09-27  0:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-26 11:29 [PATCH] IntelFsp2Pkg/GenCfgOpt.py: Support UPD offset auto assignment Chasel, Chiu
2018-09-27  0:39 ` Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox