IntelFsp2Pkg/Tools: Add BSF bit field support in GenCfgOpt tool

The current GenCfgOpt tool does not generate bit fields in BSF.
This change will allow bit fields to be created in BSF for a specific
FSP UPD item. The argument for the tool is also updated to be in sync
with the old usage model in IntelFspPkg.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
This commit is contained in:
Maurice Ma 2016-05-25 11:21:18 -07:00
parent 27a4059387
commit 62997d5ede
1 changed files with 113 additions and 111 deletions

View File

@ -310,6 +310,7 @@ EndList
self._BuidinOption = {'$EN_DIS' : 'EN_DIS'} self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}
self._MacroDict = {} self._MacroDict = {}
self._PcdsDict = {}
self._CfgBlkDict = {} self._CfgBlkDict = {}
self._CfgPageDict = {} self._CfgPageDict = {}
self._CfgItemList = [] self._CfgItemList = []
@ -374,8 +375,21 @@ EndList
Line = Line.replace(Each, Each[2:-1]) Line = Line.replace(Each, Each[2:-1])
return Line return Line
def ExpandPcds (self, Input):
Line = Input
Match = re.findall("(\w+\.\w+)", Input)
if Match:
for PcdName in Match:
if PcdName in self._PcdsDict:
Line = Line.replace(PcdName, self._PcdsDict[PcdName])
else:
if self.Debug:
print "WARN : %s is not defined" % PcdName
return Line
def EvaluateExpress (self, Expr): def EvaluateExpress (self, Expr):
ExpExpr = self.ExpandMacros(Expr) ExpExpr = self.ExpandPcds(Expr)
ExpExpr = self.ExpandMacros(ExpExpr)
LogExpr = CLogicalExpression() LogExpr = CLogicalExpression()
Result = LogExpr.evaluateExpress (ExpExpr) Result = LogExpr.evaluateExpress (ExpExpr)
if self.Debug: if self.Debug:
@ -411,7 +425,7 @@ EndList
ConfigDict['value'] = newvalue ConfigDict['value'] = newvalue
return "" return ""
def ParseDscFile (self, DscFile, FvDir, ConfigDscFile, ExtConfigDscFile): def ParseDscFile (self, DscFile, FvDir):
self._CfgItemList = [] self._CfgItemList = []
self._CfgPageDict = {} self._CfgPageDict = {}
self._CfgBlkDict = {} self._CfgBlkDict = {}
@ -419,9 +433,9 @@ EndList
self._FvDir = FvDir self._FvDir = FvDir
IsDefSect = False IsDefSect = False
IsPcdSect = False
IsUpdSect = False IsUpdSect = False
IsVpdSect = False IsVpdSect = False
Found = False
IfStack = [] IfStack = []
ElifStack = [] ElifStack = []
@ -437,10 +451,14 @@ EndList
Handle = False Handle = False
Match = re.match("^\[(.+)\]", DscLine) Match = re.match("^\[(.+)\]", DscLine)
if Match is not None: if Match is not None:
if Match.group(1).lower() == "Defines".lower(): IsDefSect = False
IsDefSect = True IsPcdSect = False
IsVpdSect = False IsVpdSect = False
IsUpdSect = False IsUpdSect = False
if Match.group(1).lower() == "Defines".lower():
IsDefSect = True
if Match.group(1).lower() == "PcdsFeatureFlag".lower():
IsPcdSect = True
elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower(): elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
ConfigDict = {} ConfigDict = {}
ConfigDict['header'] = 'ON' ConfigDict['header'] = 'ON'
@ -453,16 +471,9 @@ EndList
ConfigDict['embed'] = '' ConfigDict['embed'] = ''
ConfigDict['comment'] = '' ConfigDict['comment'] = ''
ConfigDict['subreg'] = [] ConfigDict['subreg'] = []
IsDefSect = False
IsUpdSect = True IsUpdSect = True
IsVpdSect = False
Found = True
else: else:
IsDefSect = False if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:
IsUpdSect = False
IsVpdSect = False
else:
if IsDefSect or IsUpdSect or IsVpdSect:
if re.match("^!else($|\s+#.+)", DscLine): if re.match("^!else($|\s+#.+)", DscLine):
if IfStack: if IfStack:
IfStack[-1] = not IfStack[-1] IfStack[-1] = not IfStack[-1]
@ -490,40 +501,6 @@ EndList
else: else:
Match = re.match("!(if|elseif)\s+(.+)", DscLine) Match = re.match("!(if|elseif)\s+(.+)", DscLine)
if Match: if Match:
IsFoundInFile = False
MatchPcdFormat = re.match("^\s*(.+)\.(.+)\s*==\s*(.+)", Match.group(2))
if MatchPcdFormat:
ExtConfigDsc = open(ExtConfigDscFile, "r")
ExtConfigDscLines = ExtConfigDsc.readlines()
ExtConfigDsc.close()
while len(ExtConfigDscLines):
ExtConfigDscLine = ExtConfigDscLines.pop(0).strip()
MatchExtConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ExtConfigDscLine)
if MatchExtConfigPcd and IsFoundInFile == False:
PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))
ExtConfigPcd = str(MatchExtConfigPcd.group(1))
Result = False
if PcdFormatStr.strip() == ExtConfigPcd.strip():
Result = self.EvaluateExpress(str(str(MatchExtConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))
IsFoundInFile = True
break
if IsFoundInFile == False:
ConfigDsc = open(ConfigDscFile, "r")
ConfigDscLines = ConfigDsc.readlines()
ConfigDsc.close()
while len(ConfigDscLines):
ConfigDscLine = ConfigDscLines.pop(0).strip()
MatchConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ConfigDscLine)
if MatchConfigPcd:
PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))
ConfigPcd = str(MatchConfigPcd.group(1))
Result = False
if PcdFormatStr.strip() == ConfigPcd.strip():
Result = self.EvaluateExpress(str(str(MatchConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))
IsFoundInFile = True
break
else:
Result = self.EvaluateExpress(Match.group(2)) Result = self.EvaluateExpress(Match.group(2))
if Match.group(1) == "if": if Match.group(1) == "if":
ElifStack.append(0) ElifStack.append(0)
@ -571,6 +548,14 @@ EndList
self._MacroDict[Match.group(1)] = Match.group(2) self._MacroDict[Match.group(1)] = Match.group(2)
if self.Debug: if self.Debug:
print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2)) print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))
elif IsPcdSect:
#gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
#gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
Match = re.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine)
if Match:
self._PcdsDict[Match.group(1)] = Match.group(2)
if self.Debug:
print "INFO : PCD %s = [ %s ]" % (Match.group(1), Match.group(2))
else: else:
Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine) Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)
if Match: if Match:
@ -693,25 +678,43 @@ EndList
ConfigDict['option'] = '' ConfigDict['option'] = ''
else: else:
# It could be a virtual item as below # It could be a virtual item as below
# !BSF FIELD:{1:SerialDebugPortAddress0} # !BSF FIELD:{SerialDebugPortAddress0:1}
# or # or
# @Bsf FIELD:{1:SerialDebugPortAddress0} # @Bsf FIELD:{SerialDebugPortAddress0:1b}
Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)}", DscLine) Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine)
if Match: if Match:
SubCfgDict = ConfigDict SubCfgDict = ConfigDict.copy()
if (Match.group(4) == None) or (Match.group(4) == 'B'):
UnitBitLen = 8
elif Match.group(4) == 'b':
UnitBitLen = 1
else:
print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine)
raise SystemExit
SubCfgDict['cname'] = Match.group(2) SubCfgDict['cname'] = Match.group(2)
SubCfgDict['length'] = int (Match.group(3)) SubCfgDict['bitlength'] = int (Match.group(3)) * UnitBitLen
if SubCfgDict['length'] > 0: if SubCfgDict['bitlength'] > 0:
LastItem = self._CfgItemList[-1] LastItem = self._CfgItemList[-1]
if len(LastItem['subreg']) == 0: if len(LastItem['subreg']) == 0:
SubOffset = 0 SubOffset = 0
else: else:
SubOffset += LastItem['subreg'][-1]['length'] SubOffset = LastItem['subreg'][-1]['bitoffset'] + LastItem['subreg'][-1]['bitlength']
SubCfgDict['offset'] = SubOffset SubCfgDict['bitoffset'] = SubOffset
LastItem['subreg'].append (SubCfgDict.copy()) LastItem['subreg'].append (SubCfgDict.copy())
ConfigDict['name'] = '' ConfigDict['name'] = ''
return Error return Error
def GetBsfBitFields (self, subitem, bytes):
start = subitem['bitoffset']
end = start + subitem['bitlength']
bitsvalue = ''.join('{0:08b}'.format(i) for i in bytes[::-1])
bitsvalue = bitsvalue[::-1]
bitslen = len(bitsvalue)
if start > bitslen or end > bitslen:
print "Invalid bits offset [%d,%d] for %s" % (start, end, subitem['name'])
raise SystemExit
return hex(int(bitsvalue[start:end][::-1], 2))
def UpdateSubRegionDefaultValue (self): def UpdateSubRegionDefaultValue (self):
Error = 0 Error = 0
for Item in self._CfgItemList: for Item in self._CfgItemList:
@ -732,20 +735,14 @@ EndList
value = int(Item['value'], 16) value = int(Item['value'], 16)
else: else:
value = int(Item['value']) value = int(Item['value'])
idx = 0; idx = 0
while idx < Item['length']: while idx < Item['length']:
bytearray.append(value & 0xFF) bytearray.append(value & 0xFF)
value = value >> 8 value = value >> 8
idx = idx + 1 idx = idx + 1
for SubItem in Item['subreg']: for SubItem in Item['subreg']:
if SubItem['length'] in (1,2,4,8): valuestr = self.GetBsfBitFields(SubItem, bytearray)
valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]] SubItem['value'] = valuestr
valuelist.reverse()
valuestr = "".join('%02X' % b for b in valuelist)
SubItem['value'] = '0x%s' % valuestr
else:
valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']])
SubItem['value'] = '{%s}' % valuestr
return Error return Error
def CreateSplitUpdTxt (self, UpdTxtFile): def CreateSplitUpdTxt (self, UpdTxtFile):
@ -1086,7 +1083,7 @@ EndList
Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"] Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]
else: else:
if Embed == '': if Embed == '':
Marker = ''; Marker = ''
else: else:
self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"] self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]
return 4 return 4
@ -1242,6 +1239,9 @@ EndList
DefaultValue = Match.group(1).strip() DefaultValue = Match.group(1).strip()
else: else:
DefaultValue = Item['value'].strip() DefaultValue = Item['value'].strip()
if 'bitlength' in Item:
BsfFd.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['bitlength'], DefaultValue))
else:
BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue)) BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))
TmpList = [] TmpList = []
if Item['type'] == "Combo": if Item['type'] == "Combo":
@ -1261,20 +1261,20 @@ EndList
Options = self._BuidinOption[Item['option']] Options = self._BuidinOption[Item['option']]
else: else:
Options = PcdName Options = PcdName
BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options)); BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options))
WriteHelp = 1 WriteHelp = 1
elif Item['type'].startswith("EditNum"): elif Item['type'].startswith("EditNum"):
Match = re.match("EditNum\s*,\s*(HEX|DEC)\s*,\s*\((\d+|0x[0-9A-Fa-f]+)\s*,\s*(\d+|0x[0-9A-Fa-f]+)\)", Item['type']) Match = re.match("EditNum\s*,\s*(HEX|DEC)\s*,\s*\((\d+|0x[0-9A-Fa-f]+)\s*,\s*(\d+|0x[0-9A-Fa-f]+)\)", Item['type'])
if Match: if Match:
BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1))); BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)))
WriteHelp = 2 WriteHelp = 2
elif Item['type'].startswith("EditText"): elif Item['type'].startswith("EditText"):
BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name'])); BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']))
WriteHelp = 1 WriteHelp = 1
elif Item['type'] == "Table": elif Item['type'] == "Table":
Columns = Item['option'].split(',') Columns = Item['option'].split(',')
if len(Columns) != 0: if len(Columns) != 0:
BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name'])); BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name']))
for Col in Columns: for Col in Columns:
Fmt = Col.split(':') Fmt = Col.split(':')
if len(Fmt) != 3: if len(Fmt) != 3:
@ -1293,11 +1293,11 @@ EndList
for HelpLine in HelpLines: for HelpLine in HelpLines:
if FirstLine: if FirstLine:
FirstLine = False FirstLine = False
BsfFd.write(' Help "%s"\n' % (HelpLine)); BsfFd.write(' Help "%s"\n' % (HelpLine))
else: else:
BsfFd.write(' "%s"\n' % (HelpLine)); BsfFd.write(' "%s"\n' % (HelpLine))
if WriteHelp == 2: if WriteHelp == 2:
BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3))); BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)))
def GenerateBsfFile (self, BsfFile): def GenerateBsfFile (self, BsfFile):
@ -1309,7 +1309,7 @@ EndList
OptionDict = {} OptionDict = {}
BsfFd = open(BsfFile, "w") BsfFd = open(BsfFile, "w")
BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year)) BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))
BsfFd.write("%s\n" % self._GlobalDataDef); BsfFd.write("%s\n" % self._GlobalDataDef)
BsfFd.write("StructDef\n") BsfFd.write("StructDef\n")
NextOffset = -1 NextOffset = -1
for Item in self._CfgItemList: for Item in self._CfgItemList:
@ -1321,17 +1321,30 @@ EndList
BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset)) BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))
if len(Item['subreg']) > 0: if len(Item['subreg']) > 0:
NextOffset = Item['offset'] NextOffset = Item['offset']
BitsOffset = NextOffset * 8
for SubItem in Item['subreg']: for SubItem in Item['subreg']:
NextOffset += SubItem['length'] BitsOffset += SubItem['bitlength']
if SubItem['name'] == '': if SubItem['name'] == '':
if 'bitlength' in SubItem:
BsfFd.write(" Skip %d bits\n" % (SubItem['bitlength']))
else:
BsfFd.write(" Skip %d bytes\n" % (SubItem['length'])) BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))
else: else:
Options = self.WriteBsfStruct(BsfFd, SubItem) Options = self.WriteBsfStruct(BsfFd, SubItem)
if len(Options) > 0: if len(Options) > 0:
OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options
if (Item['offset'] + Item['length']) < NextOffset:
self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname']) NextBitsOffset = (Item['offset'] + Item['length']) * 8
return 2 if NextBitsOffset > BitsOffset:
BitsGap = NextBitsOffset - BitsOffset
BitsRemain = BitsGap % 8
if BitsRemain:
BsfFd.write(" Skip %d bits\n" % BitsRemain)
BitsGap -= BitsRemain
BytesRemain = BitsGap / 8
if BytesRemain:
BsfFd.write(" Skip %d bytes\n" % BytesRemain)
NextOffset = Item['offset'] + Item['length']
else: else:
NextOffset = Item['offset'] + Item['length'] NextOffset = Item['offset'] + Item['length']
Options = self.WriteBsfStruct(BsfFd, Item) Options = self.WriteBsfStruct(BsfFd, Item)
@ -1339,21 +1352,21 @@ EndList
OptionDict[Item['space']+'_'+Item['cname']] = Options OptionDict[Item['space']+'_'+Item['cname']] = Options
BsfFd.write("\nEndStruct\n\n") BsfFd.write("\nEndStruct\n\n")
BsfFd.write("%s" % self._BuidinOptionTxt); BsfFd.write("%s" % self._BuidinOptionTxt)
for Each in OptionDict: for Each in OptionDict:
BsfFd.write("List &%s\n" % Each); BsfFd.write("List &%s\n" % Each)
for Item in OptionDict[Each]: for Item in OptionDict[Each]:
BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1])); BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]))
BsfFd.write("EndList\n\n"); BsfFd.write("EndList\n\n")
BsfFd.write("BeginInfoBlock\n"); BsfFd.write("BeginInfoBlock\n")
BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver'])); BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']))
BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name'])); BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']))
BsfFd.write("EndInfoBlock\n\n"); BsfFd.write("EndInfoBlock\n\n")
for Each in self._CfgPageDict: for Each in self._CfgPageDict:
BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]); BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each])
BsfItems = [] BsfItems = []
for Item in self._CfgItemList: for Item in self._CfgItemList:
if Item['name'] != '': if Item['name'] != '':
@ -1370,21 +1383,18 @@ EndList
for Item in BsfItems: for Item in BsfItems:
self.WriteBsfOption (BsfFd, Item) self.WriteBsfOption (BsfFd, Item)
BsfFd.write("EndPage\n\n"); BsfFd.write("EndPage\n\n")
BsfFd.close() BsfFd.close()
return Error return Error
def Usage(): def Usage():
print "GenCfgOpt Version 0.51" print "GenCfgOpt Version 0.52"
print "Usage:" print "Usage:"
print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile" print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
print " [-D Macros]" print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
print " GenCfgOpt HEADER PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile" print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
print " InputHFile [-D Macros]"
print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile"
print " BsfOutFile [-D Macros]"
def Main(): def Main():
# #
@ -1400,21 +1410,13 @@ def Main():
if not os.path.exists(DscFile): if not os.path.exists(DscFile):
print "ERROR: Cannot open DSC file '%s' !" % DscFile print "ERROR: Cannot open DSC file '%s' !" % DscFile
return 2 return 2
ConfigDscFile = sys.argv[4]
if not os.path.exists(ConfigDscFile):
print "ERROR: Cannot open Config DSC file '%s' !" % ConfigDscFile
return 2
ExtConfigDscFile = sys.argv[5]
if not os.path.exists(ExtConfigDscFile):
print "ERROR: Cannot open Ext Config DSC file '%s' !" % ExtConfigDscFile
return 2
OutFile = '' OutFile = ''
if argc > 4: if argc > 4:
if sys.argv[6][0] == '-': if sys.argv[4][0] == '-':
Start = 4 Start = 4
else: else:
OutFile = sys.argv[6] OutFile = sys.argv[4]
Start = 5 Start = 5
GenCfgOpt.ParseBuildMode(sys.argv[3]) GenCfgOpt.ParseBuildMode(sys.argv[3])
if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0: if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
@ -1425,7 +1427,7 @@ def Main():
if not os.path.exists(FvDir): if not os.path.exists(FvDir):
os.makedirs(FvDir) os.makedirs(FvDir)
if GenCfgOpt.ParseDscFile(DscFile, FvDir, ConfigDscFile, ExtConfigDscFile) != 0: if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:
print "ERROR: %s !" % GenCfgOpt.Error print "ERROR: %s !" % GenCfgOpt.Error
return 5 return 5