X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=IntelFsp2Pkg%2FTools%2FGenCfgOpt.py;h=c4fb1f1bb24013c59a35dca9b98ea23da6e32e22;hb=6f219bef55f819cb88c86bd7e9b550de4d4345a1;hp=059cfcb7e4179ba7b91b939f4f11f5539962b07e;hpb=737f812b00b36d2a78971be03fe27efa0a992bfe;p=mirror_edk2.git
diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt.py
index 059cfcb7e4..c4fb1f1bb2 100644
--- a/IntelFsp2Pkg/Tools/GenCfgOpt.py
+++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py
@@ -1,13 +1,7 @@
## @ GenCfgOpt.py
#
-# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
-# 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
-# http://opensource.org/licenses/bsd-license.php.
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+# Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -16,6 +10,7 @@ import re
import sys
import struct
from datetime import date
+from functools import reduce
# Generated file copyright header
@@ -88,17 +83,19 @@ are permitted provided that the following conditions are met:
**/
"""
+BuildOptionPcd = []
+
class CLogicalExpression:
def __init__(self):
self.index = 0
self.string = ''
def errExit(self, err = ''):
- print "ERROR: Express parsing for:"
- print " %s" % self.string
- print " %s^" % (' ' * self.index)
+ print ("ERROR: Express parsing for:")
+ print (" %s" % self.string)
+ print (" %s^" % (' ' * self.index))
if err:
- print "INFO : %s" % err
+ print ("INFO : %s" % err)
raise SystemExit
def getNonNumber (self, n1, n2):
@@ -286,10 +283,10 @@ class CLogicalExpression:
return Result
class CGenCfgOpt:
- def __init__(self):
+ def __init__(self, Mode = ''):
self.Debug = False
self.Error = ''
-
+ self.Mode = Mode
self._GlobalDataDef = """
GlobalDataDef
SKUID = 0, "DEFAULT"
@@ -303,19 +300,22 @@ List &EN_DIS
EndList
"""
-
- self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
+ self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE', 'PAGES', 'BLOCK', 'OPTION','CONDITION','ORDER', 'MARKER', 'SUBT']
self._HdrKeyList = ['HEADER','STRUCT', 'EMBED', 'COMMENT']
self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}
self._MacroDict = {}
+ self._VarDict = {}
self._PcdsDict = {}
self._CfgBlkDict = {}
self._CfgPageDict = {}
+ self._BsfTempDict = {}
self._CfgItemList = []
+ self._DscLines = []
self._DscFile = ''
- self._FvDir = ''
+
self._MapVer = 0
+ self._DscTime = 0
def ParseMacros (self, MacroDefStr):
# ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
@@ -342,18 +342,18 @@ EndList
else:
Error = 0
if self.Debug:
- print "INFO : Macro dictionary:"
+ print ("INFO : Macro dictionary:")
for Each in self._MacroDict:
- print " $(%s) = [ %s ]" % (Each , self._MacroDict[Each])
+ print (" $(%s) = [ %s ]" % (Each , self._MacroDict[Each]))
return Error
def EvaulateIfdef (self, Macro):
Result = Macro in self._MacroDict
if self.Debug:
- print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result)
+ print ("INFO : Eval Ifdef [%s] : %s" % (Macro, Result))
return Result
- def ExpandMacros (self, Input):
+ def ExpandMacros (self, Input, Preserve = False):
Line = Input
Match = re.findall("\$\(\w+\)", Input)
if Match:
@@ -363,8 +363,9 @@ EndList
Line = Line.replace(Each, self._MacroDict[Variable])
else:
if self.Debug:
- print "WARN : %s is not defined" % Each
- Line = Line.replace(Each, Each[2:-1])
+ print ("WARN : %s is not defined" % Each)
+ if not Preserve:
+ Line = Line.replace(Each, Each[2:-1])
return Line
def ExpandPcds (self, Input):
@@ -376,7 +377,7 @@ EndList
Line = Line.replace(PcdName, self._PcdsDict[PcdName])
else:
if self.Debug:
- print "WARN : %s is not defined" % PcdName
+ print ("WARN : %s is not defined" % PcdName)
return Line
def EvaluateExpress (self, Expr):
@@ -385,7 +386,71 @@ EndList
LogExpr = CLogicalExpression()
Result = LogExpr.evaluateExpress (ExpExpr)
if self.Debug:
- print "INFO : Eval Express [%s] : %s" % (Expr, Result)
+ print ("INFO : Eval Express [%s] : %s" % (Expr, Result))
+ return Result
+
+ def ValueToByteArray (self, ValueStr, Length):
+ Match = re.match("\{\s*FILE:(.+)\}", ValueStr)
+ if Match:
+ FileList = Match.group(1).split(',')
+ Result = bytearray()
+ for File in FileList:
+ File = File.strip()
+ BinPath = os.path.join(os.path.dirname(self._DscFile), File)
+ Result.extend(bytearray(open(BinPath, 'rb').read()))
+ else:
+ try:
+ Result = bytearray(self.ValueToList(ValueStr, Length))
+ except ValueError as e:
+ raise Exception ("Bytes in '%s' must be in range 0~255 !" % ValueStr)
+ if len(Result) < Length:
+ Result.extend(b'\x00' * (Length - len(Result)))
+ elif len(Result) > Length:
+ raise Exception ("Value '%s' is too big to fit into %d bytes !" % (ValueStr, Length))
+
+ return Result[:Length]
+
+ def ValueToList (self, ValueStr, Length):
+ if ValueStr[0] == '{':
+ Result = []
+ BinList = ValueStr[1:-1].split(',')
+ InBitField = False
+ LastInBitField = False
+ Value = 0
+ BitLen = 0
+ for Element in BinList:
+ InBitField = False
+ Each = Element.strip()
+ if len(Each) == 0:
+ pass
+ else:
+ if Each[0] in ['"', "'"]:
+ Result.extend(list(bytearray(Each[1:-1], 'utf-8')))
+ elif ':' in Each:
+ Match = re.match("(.+):(\d+)b", Each)
+ if Match is None:
+ raise Exception("Invald value list format '%s' !" % Each)
+ InBitField = True
+ CurrentBitLen = int(Match.group(2))
+ CurrentValue = ((self.EvaluateExpress(Match.group(1)) & (1<> 8
newvalue = '{' + ','.join(bytearray) + '}'
@@ -426,24 +491,53 @@ EndList
self._DscFile = DscFile
self._FvDir = FvDir
+ self._DscLines = []
+ self._BsfTempDict = {}
+
+ # Initial DSC time is parent DSC time.
+ self._DscTime = os.path.getmtime(DscFile)
+
+ CfgDict = {}
+
IsDefSect = False
IsPcdSect = False
IsUpdSect = False
IsVpdSect = False
+ IsTmpSect = False
+
+ TemplateName = ''
IfStack = []
ElifStack = []
Error = 0
ConfigDict = {}
- DscFd = open(DscFile, "r")
- DscLines = DscFd.readlines()
- DscFd.close()
+
+ if type(DscFile) is list:
+ # it is DSC lines already
+ DscLines = DscFile
+ self._DscFile = '.'
+ else:
+ DscFd = open(DscFile, "r")
+ DscLines = DscFd.readlines()
+ DscFd.close()
+ self._DscFile = DscFile
+
+ SkipLines = 0
MaxAlign = 32 #Default align to 32, but if there are 64 bit unit, align to 64
SizeAlign = 0 #record the struct max align
+ Base = 0 #Starting offset of sub-structure.
+
while len(DscLines):
DscLine = DscLines.pop(0).strip()
+ if SkipLines == 0:
+ self._DscLines.append (DscLine)
+ else:
+ SkipLines = SkipLines - 1
+ if len(DscLine) == 0:
+ continue
+
Handle = False
Match = re.match("^\[(.+)\]", DscLine)
if Match is not None:
@@ -451,11 +545,15 @@ EndList
IsPcdSect = False
IsVpdSect = False
IsUpdSect = False
- if Match.group(1).lower() == "Defines".lower():
+ IsTmpSect = False
+ SectionName = Match.group(1).lower()
+ if SectionName == "Defines".lower():
IsDefSect = True
- if (Match.group(1).lower() == "PcdsFeatureFlag".lower() or Match.group(1).lower() == "PcdsFixedAtBuild".lower()):
+ if (SectionName == "PcdsFeatureFlag".lower() or SectionName == "PcdsFixedAtBuild".lower()):
IsPcdSect = True
- elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
+ elif SectionName == "PcdsDynamicVpd.Tmp".lower():
+ IsTmpSect = True
+ elif SectionName == "PcdsDynamicVpd.Upd".lower():
ConfigDict = {}
ConfigDict['header'] = 'ON'
ConfigDict['region'] = 'UPD'
@@ -463,84 +561,98 @@ EndList
ConfigDict['page'] = ''
ConfigDict['name'] = ''
ConfigDict['find'] = ''
+ ConfigDict['marker'] = ''
ConfigDict['struct'] = ''
ConfigDict['embed'] = ''
ConfigDict['comment'] = ''
ConfigDict['subreg'] = []
+ ConfigDict['condition'] = ''
+ ConfigDict['option'] = ''
IsUpdSect = True
Offset = 0
else:
- if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:
- if re.match("^!else($|\s+#.+)", DscLine):
+ if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect or IsTmpSect:
+
+ Match = False if DscLine[0] != '!' else True
+ if Match:
+ Match = re.match("^!(else|endif|ifdef|ifndef|if|elseif|include)\s*(.+)?$", DscLine.split("#")[0])
+ Keyword = Match.group(1) if Match else ''
+ Remaining = Match.group(2) if Match else ''
+ Remaining = '' if Remaining is None else Remaining.strip()
+
+ if Keyword in ['if', 'elseif', 'ifdef', 'ifndef', 'include'] and not Remaining:
+ raise Exception ("ERROR: Expression is expected after '!if' or !elseif' for line '%s'" % DscLine)
+
+ if Keyword == 'else':
if IfStack:
IfStack[-1] = not IfStack[-1]
else:
- print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)
- raise SystemExit
- elif re.match("^!endif($|\s+#.+)", DscLine):
+ raise Exception ("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)
+ elif Keyword == 'endif':
if IfStack:
IfStack.pop()
Level = ElifStack.pop()
if Level > 0:
del IfStack[-Level:]
else:
- print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)
- raise SystemExit
- else:
- Result = False
- Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)
- if Match:
- Result = self.EvaulateIfdef (Match.group(2))
- if Match.group(1) == 'ifndef':
- Result = not Result
- IfStack.append(Result)
+ raise Exception ("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)
+ elif Keyword == 'ifdef' or Keyword == 'ifndef':
+ Result = self.EvaulateIfdef (Remaining)
+ if Keyword == 'ifndef':
+ Result = not Result
+ IfStack.append(Result)
+ ElifStack.append(0)
+ elif Keyword == 'if' or Keyword == 'elseif':
+ Result = self.EvaluateExpress(Remaining)
+ if Keyword == "if":
ElifStack.append(0)
+ IfStack.append(Result)
+ else: #elseif
+ if IfStack:
+ IfStack[-1] = not IfStack[-1]
+ IfStack.append(Result)
+ ElifStack[-1] = ElifStack[-1] + 1
+ else:
+ raise Exception ("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)
+ else:
+ if IfStack:
+ Handle = reduce(lambda x,y: x and y, IfStack)
else:
- Match = re.match("!(if|elseif)\s+(.+)", DscLine.split("#")[0])
+ Handle = True
+ if Handle:
+ Match = re.match("!include\s+(.+)", DscLine)
if Match:
- Result = self.EvaluateExpress(Match.group(2))
- if Match.group(1) == "if":
- ElifStack.append(0)
- IfStack.append(Result)
- else: #elseif
- if IfStack:
- IfStack[-1] = not IfStack[-1]
- IfStack.append(Result)
- ElifStack[-1] = ElifStack[-1] + 1
- else:
- print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)
- raise SystemExit
- else:
- if IfStack:
- Handle = reduce(lambda x,y: x and y, IfStack)
+ IncludeFilePath = Match.group(1)
+ IncludeFilePath = self.ExpandMacros(IncludeFilePath)
+ PackagesPath = os.getenv("PACKAGES_PATH")
+ if PackagesPath:
+ for PackagePath in PackagesPath.split(os.pathsep):
+ IncludeFilePathAbs = os.path.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))
+ if os.path.exists(IncludeFilePathAbs):
+ IncludeDsc = open(IncludeFilePathAbs, "r")
+ break
else:
- Handle = True
- if Handle:
- Match = re.match("!include\s+(.+)", DscLine)
- if Match:
- IncludeFilePath = Match.group(1)
- IncludeFilePath = self.ExpandMacros(IncludeFilePath)
- PackagesPath = os.getenv("PACKAGES_PATH")
- if PackagesPath:
- for PackagePath in PackagesPath.split(os.pathsep):
- IncludeFilePathAbs = os.path.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))
- if os.path.exists(IncludeFilePathAbs):
- IncludeDsc = open(IncludeFilePathAbs, "r")
- break
- else:
- IncludeDsc = open(IncludeFilePath, "r")
- if IncludeDsc == None:
- print("ERROR: Cannot open file '%s'" % IncludeFilePath)
- raise SystemExit
- NewDscLines = IncludeDsc.readlines()
- IncludeDsc.close()
- DscLines = NewDscLines + DscLines
- Offset = 0
- else:
- if DscLine.startswith('!'):
- print("ERROR: Unrecoginized directive for line '%s'" % DscLine)
- raise SystemExit
+ IncludeDsc = open(IncludeFilePath, "r")
+ if IncludeDsc == None:
+ print("ERROR: Cannot open file '%s'" % IncludeFilePath)
+ raise SystemExit
+
+ # Update DscTime when newer DSC time found.
+ CurrentDscTime = os.path.getmtime(os.path.realpath(IncludeDsc.name))
+ if CurrentDscTime > self._DscTime:
+ self._DscTime = CurrentDscTime
+
+ NewDscLines = IncludeDsc.readlines()
+ IncludeDsc.close()
+ DscLines = NewDscLines + DscLines
+ del self._DscLines[-1]
+ Offset = 0
+ else:
+ if DscLine.startswith('!'):
+ print("ERROR: Unrecognized directive for line '%s'" % DscLine)
+ raise SystemExit
if not Handle:
+ del self._DscLines[-1]
continue
if IsDefSect:
@@ -548,11 +660,11 @@ EndList
#DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
#DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
#DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
- Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine)
+ Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*(.+)", DscLine)
if Match:
- self._MacroDict[Match.group(1)] = Match.group(2)
+ self._MacroDict[Match.group(1)] = self.ExpandMacros(Match.group(2))
if self.Debug:
- print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))
+ print ("INFO : DEFINE %s = [ %s ]" % (Match.group(1), self.ExpandMacros(Match.group(2))))
elif IsPcdSect:
#gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
#gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
@@ -560,7 +672,30 @@ EndList
if Match:
self._PcdsDict[Match.group(1)] = Match.group(2)
if self.Debug:
- print "INFO : PCD %s = [ %s ]" % (Match.group(1), Match.group(2))
+ print ("INFO : PCD %s = [ %s ]" % (Match.group(1), Match.group(2)))
+ i = 0
+ while i < len(BuildOptionPcd):
+ Match = re.match("\s*([\w\.]+)\s*\=\s*(\w+)", BuildOptionPcd[i])
+ if Match:
+ self._PcdsDict[Match.group(1)] = Match.group(2)
+ i += 1
+
+ elif IsTmpSect:
+ # !BSF DEFT:{GPIO_TMPL:START}
+ Match = re.match("^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}", DscLine)
+ if Match:
+ if Match.group(3) == 'START' and not TemplateName:
+ TemplateName = Match.group(2).strip()
+ self._BsfTempDict[TemplateName] = []
+ if Match.group(3) == 'END' and (TemplateName == Match.group(2).strip()) and TemplateName:
+ TemplateName = ''
+ else:
+ if TemplateName:
+ Match = re.match("^!include\s*(.+)?$", DscLine)
+ if Match:
+ continue
+ self._BsfTempDict[TemplateName].append(DscLine)
+
else:
Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)
if Match:
@@ -573,7 +708,8 @@ EndList
for Page in PageList:
Page = Page.strip()
Match = re.match("(\w+):\"(.+)\"", Page)
- self._CfgPageDict[Match.group(1)] = Match.group(2)
+ if Match != None:
+ self._CfgPageDict[Match.group(1)] = Match.group(2)
Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)
if Match:
@@ -616,9 +752,9 @@ EndList
Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine)
if Match:
if "0x" in Match.group(2) or "0x" in Match.group(3):
- ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))
+ ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))
else:
- ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))
+ ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))
Match = re.match("^\s*##\s+(.+)", DscLine)
if Match:
@@ -712,7 +848,7 @@ EndList
if (ConfigDict['embed'].find(':END') != -1):
Remainder = Offset % (MaxAlign/8) # MaxAlign is either 32 or 64
if Remainder:
- Diff = (MaxAlign/8) - Remainder
+ Diff = int((MaxAlign/8) - Remainder)
Offset = Offset + Diff
ItemOffset = ItemOffset + Diff
MaxAlign = 32 # Reset to default 32 align when struct end
@@ -724,7 +860,7 @@ EndList
Remainder = Offset % max(ItemLength/8, 4, SizeAlign)
Offset = Offset + ItemLength
if Remainder:
- Diff = max(ItemLength/8, 4, SizeAlign) - Remainder
+ Diff = int(max(ItemLength/8, 4, SizeAlign) - Remainder)
ItemOffset = ItemOffset + Diff
ConfigDict['offset'] = ItemOffset
@@ -734,6 +870,7 @@ EndList
ConfigDict['struct'] = ''
ConfigDict['embed'] = ''
ConfigDict['comment'] = ''
+ ConfigDict['marker'] = ''
ConfigDict['order'] = -1
ConfigDict['subreg'] = []
ConfigDict['option'] = ''
@@ -772,9 +909,8 @@ EndList
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))
+ raise Exception ("Invalid bits offset [%d,%d] %d for %s" % (start, end, bitslen, subitem['name']))
+ return '0x%X' % (int(bitsvalue[start:end][::-1], 2))
def UpdateSubRegionDefaultValue (self):
Error = 0
@@ -806,6 +942,16 @@ EndList
SubItem['value'] = valuestr
return Error
+ def NoDscFileChange (self, OutPutFile):
+ NoFileChange = True
+ if not os.path.exists(OutPutFile):
+ NoFileChange = False
+ else:
+ OutputTime = os.path.getmtime(OutPutFile)
+ if self._DscTime > OutputTime:
+ NoFileChange = False
+ return NoFileChange
+
def CreateSplitUpdTxt (self, UpdTxtFile):
GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
SignatureList = ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
@@ -819,16 +965,7 @@ EndList
if UpdTxtFile == '':
UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.txt')
- ReCreate = False
- if not os.path.exists(UpdTxtFile):
- ReCreate = True
- else:
- DscTime = os.path.getmtime(self._DscFile)
- TxtTime = os.path.getmtime(UpdTxtFile)
- if DscTime > TxtTime:
- ReCreate = True
-
- if not ReCreate:
+ if (self.NoDscFileChange (UpdTxtFile)):
# DSC has not been modified yet
# So don't have to re-generate other files
self.Error = 'No DSC file change, skip to create UPD TXT file'
@@ -873,63 +1010,142 @@ EndList
TxtFd.close()
return 0
- def ProcessMultilines (self, String, MaxCharLength):
- Multilines = ''
- StringLength = len(String)
- CurrentStringStart = 0
- StringOffset = 0
- BreakLineDict = []
- if len(String) <= MaxCharLength:
- while (StringOffset < StringLength):
- if StringOffset >= 1:
- if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
- BreakLineDict.append (StringOffset + 1)
- StringOffset += 1
- if BreakLineDict != []:
- for Each in BreakLineDict:
- Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
- CurrentStringStart = Each
- if StringLength - CurrentStringStart > 0:
- Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
+ def CreateVarDict (self):
+ Error = 0
+ self._VarDict = {}
+ if len(self._CfgItemList) > 0:
+ Item = self._CfgItemList[-1]
+ self._VarDict['_LENGTH_'] = '%d' % (Item['offset'] + Item['length'])
+ for Item in self._CfgItemList:
+ Embed = Item['embed']
+ Match = re.match("^(\w+):(\w+):(START|END)", Embed)
+ if Match:
+ StructName = Match.group(1)
+ VarName = '_%s_%s_' % (Match.group(3), StructName)
+ if Match.group(3) == 'END':
+ self._VarDict[VarName] = Item['offset'] + Item['length']
+ self._VarDict['_LENGTH_%s_' % StructName] = \
+ self._VarDict['_END_%s_' % StructName] - self._VarDict['_START_%s_' % StructName]
+ if Match.group(2).startswith('TAG_'):
+ if (self.Mode != 'FSP') and (self._VarDict['_LENGTH_%s_' % StructName] % 4):
+ raise Exception("Size of structure '%s' is %d, not DWORD aligned !" % (StructName, self._VarDict['_LENGTH_%s_' % StructName]))
+ self._VarDict['_TAG_%s_' % StructName] = int (Match.group(2)[4:], 16) & 0xFFF
else:
- Multilines = " %s\n" % String
+ self._VarDict[VarName] = Item['offset']
+ if Item['marker']:
+ self._VarDict['_OFFSET_%s_' % Item['marker'].strip()] = Item['offset']
+ return Error
+
+ def UpdateBsfBitUnit (self, Item):
+ BitTotal = 0
+ BitOffset = 0
+ StartIdx = 0
+ Unit = None
+ UnitDec = {1:'BYTE', 2:'WORD', 4:'DWORD', 8:'QWORD'}
+ for Idx, SubItem in enumerate(Item['subreg']):
+ if Unit is None:
+ Unit = SubItem['bitunit']
+ BitLength = SubItem['bitlength']
+ BitTotal += BitLength
+ BitOffset += BitLength
+
+ if BitOffset > 64 or BitOffset > Unit * 8:
+ break
+
+ if BitOffset == Unit * 8:
+ for SubIdx in range (StartIdx, Idx + 1):
+ Item['subreg'][SubIdx]['bitunit'] = Unit
+ BitOffset = 0
+ StartIdx = Idx + 1
+ Unit = None
+
+ if BitOffset > 0:
+ raise Exception ("Bit fields cannot fit into %s for '%s.%s' !" % (UnitDec[Unit], Item['cname'], SubItem['cname']))
+
+ ExpectedTotal = Item['length'] * 8
+ if Item['length'] * 8 != BitTotal:
+ raise Exception ("Bit fields total length (%d) does not match length (%d) of '%s' !" % (BitTotal, ExpectedTotal, Item['cname']))
+
+ def UpdateDefaultValue (self):
+ Error = 0
+ for Idx, Item in enumerate(self._CfgItemList):
+ if len(Item['subreg']) == 0:
+ Value = Item['value']
+ if (len(Value) > 0) and (Value[0] == '{' or Value[0] == "'" or Value[0] == '"'):
+ # {XXX} or 'XXX' strings
+ self.FormatListValue(self._CfgItemList[Idx])
+ else:
+ Match = re.match("(0x[0-9a-fA-F]+|[0-9]+)", Value)
+ if not Match:
+ NumValue = self.EvaluateExpress (Value)
+ Item['value'] = '0x%X' % NumValue
else:
- NewLineStart = 0
- NewLineCount = 0
- FoundSpaceChar = False
- while (StringOffset < StringLength):
- if StringOffset >= 1:
- if NewLineCount >= MaxCharLength - 1:
- if String[StringOffset] == ' ' and StringLength - StringOffset > 10:
- BreakLineDict.append (NewLineStart + NewLineCount)
- NewLineStart = NewLineStart + NewLineCount
- NewLineCount = 0
- FoundSpaceChar = True
- elif StringOffset == StringLength - 1 and FoundSpaceChar == False:
- BreakLineDict.append (0)
- if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
- BreakLineDict.append (StringOffset + 1)
- NewLineStart = StringOffset + 1
+ ValArray = self.ValueToByteArray (Item['value'], Item['length'])
+ for SubItem in Item['subreg']:
+ SubItem['value'] = self.GetBsfBitFields(SubItem, ValArray)
+ self.UpdateBsfBitUnit (Item)
+ return Error
+
+ def ProcessMultilines (self, String, MaxCharLength):
+ Multilines = ''
+ StringLength = len(String)
+ CurrentStringStart = 0
+ StringOffset = 0
+ BreakLineDict = []
+ if len(String) <= MaxCharLength:
+ while (StringOffset < StringLength):
+ if StringOffset >= 1:
+ if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
+ BreakLineDict.append (StringOffset + 1)
+ StringOffset += 1
+ if BreakLineDict != []:
+ for Each in BreakLineDict:
+ Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
+ CurrentStringStart = Each
+ if StringLength - CurrentStringStart > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
+ else:
+ Multilines = " %s\n" % String
+ else:
+ NewLineStart = 0
+ NewLineCount = 0
+ FoundSpaceChar = False
+ while (StringOffset < StringLength):
+ if StringOffset >= 1:
+ if NewLineCount >= MaxCharLength - 1:
+ if String[StringOffset] == ' ' and StringLength - StringOffset > 10:
+ BreakLineDict.append (NewLineStart + NewLineCount)
+ NewLineStart = NewLineStart + NewLineCount
NewLineCount = 0
- StringOffset += 1
- NewLineCount += 1
- if BreakLineDict != []:
- BreakLineDict.sort ()
- for Each in BreakLineDict:
- if Each > 0:
- Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
- CurrentStringStart = Each
- if StringLength - CurrentStringStart > 0:
- Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
- return Multilines
-
- def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option):
+ FoundSpaceChar = True
+ elif StringOffset == StringLength - 1 and FoundSpaceChar == False:
+ BreakLineDict.append (0)
+ if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
+ BreakLineDict.append (StringOffset + 1)
+ NewLineStart = StringOffset + 1
+ NewLineCount = 0
+ StringOffset += 1
+ NewLineCount += 1
+ if BreakLineDict != []:
+ BreakLineDict.sort ()
+ for Each in BreakLineDict:
+ if Each > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
+ CurrentStringStart = Each
+ if StringLength - CurrentStringStart > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
+ return Multilines
+
+ def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option, BitsLength = None):
PosName = 28
PosComment = 30
NameLine=''
HelpLine=''
OptionLine=''
+ if Length == 0 and Name == 'Dummy':
+ return '\n'
+
IsArray = False
if Length in [1,2,4,8]:
Type = "UINT%d" % (Length * 8)
@@ -977,7 +1193,12 @@ EndList
else:
OffsetStr = '0x%04X' % Offset
- return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)
+ if BitsLength is None:
+ BitsLength = ''
+ else:
+ BitsLength = ' : %d' % BitsLength
+
+ return "\n/** Offset %s%s%s%s**/\n %s%s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name, BitsLength)
def PostProcessBody (self, TextBody):
NewTextBody = []
@@ -1029,7 +1250,7 @@ EndList
if Match and Match.group(3) == 'END':
if (StructName != Match.group(1)) or (VariableName != Match.group(2)):
- print "Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1))
+ print ("Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1)))
else:
if IsUpdHdrDefined != True or IsUpdHeader != True:
NewTextBody.append ('} %s;\n\n' % StructName)
@@ -1052,7 +1273,11 @@ EndList
HeaderFile = os.path.join(FvDir, HeaderFileName)
# Check if header needs to be recreated
- ReCreate = False
+ if (self.NoDscFileChange (HeaderFile)):
+ # DSC has not been modified yet
+ # So don't have to re-generate other files
+ self.Error = 'No DSC file change, skip to create UPD header file'
+ return 256
TxtBody = []
for Item in self._CfgItemList:
@@ -1078,6 +1303,7 @@ EndList
UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
for Item in self._CfgItemList:
if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:
+ Item["offset"] = 0 # re-initialize offset to 0 when new UPD structure starting
UpdOffsetTable.append (Item["offset"])
for UpdIdx in range(len(UpdOffsetTable)):
@@ -1171,8 +1397,10 @@ EndList
UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
- ExcludedSpecificUpd = 'FSPM_ARCH_UPD'
+ ExcludedSpecificUpd = ['FSPT_ARCH_UPD', 'FSPM_ARCH_UPD', 'FSPS_ARCH_UPD']
+ ExcludedSpecificUpd1 = ['FSPT_ARCH2_UPD', 'FSPM_ARCH2_UPD', 'FSPS_ARCH2_UPD']
+ IncLines = []
if InputHeaderFile != '':
if not os.path.exists(InputHeaderFile):
self.Error = "Input header file '%s' does not exist" % InputHeaderFile
@@ -1225,7 +1453,7 @@ EndList
if Match:
StartIndex = Index - 1
Match = re.match("}\s([_A-Z0-9]+);", Line)
- if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd not in Match.group(1)):
+ if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd[item] not in Match.group(1)) and (ExcludedSpecificUpd1[item] not in Match.group(1)):
EndIndex = Index
StructStart.append(StartIndex)
StructEnd.append(EndIndex)
@@ -1377,6 +1605,12 @@ EndList
self.Error = "BSF output file '%s' is invalid" % BsfFile
return 1
+ if (self.NoDscFileChange (BsfFile)):
+ # DSC has not been modified yet
+ # So don't have to re-generate other files
+ self.Error = 'No DSC file change, skip to create UPD BSF file'
+ return 256
+
Error = 0
OptionDict = {}
BsfFd = open(BsfFile, "w")
@@ -1413,7 +1647,7 @@ EndList
if BitsRemain:
BsfFd.write(" Skip %d bits\n" % BitsRemain)
BitsGap -= BitsRemain
- BytesRemain = BitsGap / 8
+ BytesRemain = int(BitsGap / 8)
if BytesRemain:
BsfFd.write(" Skip %d bytes\n" % BytesRemain)
NextOffset = Item['offset'] + Item['length']
@@ -1462,17 +1696,24 @@ EndList
def Usage():
- print "GenCfgOpt Version 0.52"
- print "Usage:"
- print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
- print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
- print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
+ print ("GenCfgOpt Version 0.57")
+ print ("Usage:")
+ print (" GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]")
+ print (" GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]")
+ print (" GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]")
def Main():
#
# Parse the options and args
#
+ i = 1
+
GenCfgOpt = CGenCfgOpt()
+ while i < len(sys.argv):
+ if sys.argv[i].strip().lower() == "--pcd":
+ BuildOptionPcd.append(sys.argv[i+1])
+ i += 1
+ i += 1
argc = len(sys.argv)
if argc < 4:
Usage()
@@ -1480,7 +1721,7 @@ def Main():
else:
DscFile = sys.argv[2]
if not os.path.exists(DscFile):
- print "ERROR: Cannot open DSC file '%s' !" % DscFile
+ print ("ERROR: Cannot open DSC file '%s' !" % DscFile)
return 2
OutFile = ''
@@ -1492,7 +1733,7 @@ def Main():
Start = 5
if argc > Start:
if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
- print "ERROR: Macro parsing failed !"
+ print ("ERROR: Macro parsing failed !")
return 3
FvDir = sys.argv[3]
@@ -1500,11 +1741,11 @@ def Main():
os.makedirs(FvDir)
if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:
- print "ERROR: %s !" % GenCfgOpt.Error
+ print ("ERROR: %s !" % GenCfgOpt.Error)
return 5
if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:
- print "ERROR: %s !" % GenCfgOpt.Error
+ print ("ERROR: %s !" % GenCfgOpt.Error)
return 7
if sys.argv[1] == "UPDTXT":
@@ -1512,23 +1753,35 @@ def Main():
if Ret != 0:
# No change is detected
if Ret == 256:
- print "INFO: %s !" % (GenCfgOpt.Error)
+ print ("INFO: %s !" % (GenCfgOpt.Error))
else :
- print "ERROR: %s !" % (GenCfgOpt.Error)
+ print ("ERROR: %s !" % (GenCfgOpt.Error))
return Ret
elif sys.argv[1] == "HEADER":
- if GenCfgOpt.CreateHeaderFile(OutFile) != 0:
- print "ERROR: %s !" % GenCfgOpt.Error
- return 8
+ Ret = GenCfgOpt.CreateHeaderFile(OutFile)
+ if Ret != 0:
+ # No change is detected
+ if Ret == 256:
+ print ("INFO: %s !" % (GenCfgOpt.Error))
+ else :
+ print ("ERROR: %s !" % (GenCfgOpt.Error))
+ return 8
+ return Ret
elif sys.argv[1] == "GENBSF":
- if GenCfgOpt.GenerateBsfFile(OutFile) != 0:
- print "ERROR: %s !" % GenCfgOpt.Error
- return 9
+ Ret = GenCfgOpt.GenerateBsfFile(OutFile)
+ if Ret != 0:
+ # No change is detected
+ if Ret == 256:
+ print ("INFO: %s !" % (GenCfgOpt.Error))
+ else :
+ print ("ERROR: %s !" % (GenCfgOpt.Error))
+ return 9
+ return Ret
else:
if argc < 5:
Usage()
return 1
- print "ERROR: Unknown command '%s' !" % sys.argv[1]
+ print ("ERROR: Unknown command '%s' !" % sys.argv[1])
Usage()
return 1
return 0