]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/GenCfgOpt.py
3 # Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
4 # This program and the accompanying materials are licensed and made available under
5 # the terms and conditions of the BSD License that accompanies this distribution.
6 # The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php.
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 from datetime
import date
20 # Generated file copyright header
22 __copyright_txt__
= """## @file
24 # THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.
26 # This file lists all VPD informations for a platform collected by build.exe.
28 # Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
29 # This program and the accompanying materials
30 # are licensed and made available under the terms and conditions of the BSD License
31 # which accompanies this distribution. The full text of the license may be found at
32 # http://opensource.org/licenses/bsd-license.php
34 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
35 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
39 __copyright_bsf__
= """/** @file
41 Boot Setting File for Platform Configuration.
43 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
44 This program and the accompanying materials
45 are licensed and made available under the terms and conditions of the BSD License
46 which accompanies this distribution. The full text of the license may be found at
47 http://opensource.org/licenses/bsd-license.php
49 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
50 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
52 This file is automatically generated. Please do NOT modify !!!
58 __copyright_h__
= """/** @file
60 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
62 Redistribution and use in source and binary forms, with or without modification,
63 are permitted provided that the following conditions are met:
65 * Redistributions of source code must retain the above copyright notice, this
66 list of conditions and the following disclaimer.
67 * Redistributions in binary form must reproduce the above copyright notice, this
68 list of conditions and the following disclaimer in the documentation and/or
69 other materials provided with the distribution.
70 * Neither the name of Intel Corporation nor the names of its contributors may
71 be used to endorse or promote products derived from this software without
72 specific prior written permission.
74 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
77 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
78 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
79 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
80 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
81 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
82 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
83 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
84 THE POSSIBILITY OF SUCH DAMAGE.
86 This file is automatically generated. Please do NOT modify !!!
93 class CLogicalExpression
:
98 def errExit(self
, err
= ''):
99 print "ERROR: Express parsing for:"
100 print " %s" % self
.string
101 print " %s^" % (' ' * self
.index
)
103 print "INFO : %s" % err
106 def getNonNumber (self
, n1
, n2
):
113 def getCurr(self
, lens
= 1):
116 return self
.string
[self
.index
:]
118 if self
.index
+ lens
> len(self
.string
):
119 lens
= len(self
.string
) - self
.index
120 return self
.string
[self
.index
: self
.index
+ lens
]
125 return self
.index
== len(self
.string
)
127 def moveNext(self
, len = 1):
131 while not self
.isLast():
132 if self
.getCurr() in ' \t':
137 def normNumber (self
, val
):
138 return True if val
else False
140 def getNumber(self
, var
):
142 if re
.match('^0x[a-fA-F0-9]+$', var
):
144 elif re
.match('^[+-]?\d+$', var
):
150 def parseValue(self
):
153 while not self
.isLast():
154 char
= self
.getCurr()
155 if re
.match('^[\w.]', char
):
160 val
= self
.getNumber(var
)
167 def parseSingleOp(self
):
169 if re
.match('^NOT\W', self
.getCurr(-1)):
171 op
= self
.parseBrace()
172 val
= self
.getNumber (op
)
174 self
.errExit ("'%s' is not a number" % op
)
175 return "%d" % (not self
.normNumber(int(op
)))
177 return self
.parseValue()
179 def parseBrace(self
):
181 char
= self
.getCurr()
184 value
= self
.parseExpr()
186 if self
.getCurr() != ')':
187 self
.errExit ("Expecting closing brace or operator")
191 value
= self
.parseSingleOp()
194 def parseCompare(self
):
195 value
= self
.parseBrace()
198 char
= self
.getCurr()
199 if char
in ['<', '>']:
201 next
= self
.getCurr()
207 result
= self
.parseBrace()
208 test
= self
.getNonNumber(result
, value
)
210 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
212 self
.errExit ("'%s' is not a valid number for comparision" % test
)
213 elif char
in ['=', '!']:
215 if op
in ['==', '!=']:
217 result
= self
.parseBrace()
218 test
= self
.getNonNumber(result
, value
)
220 value
= "%d" % self
.normNumber((eval (value
+ op
+ result
)))
222 value
= "%d" % self
.normNumber(eval ("'" + value
+ "'" + op
+ "'" + result
+ "'"))
230 value
= self
.parseCompare()
233 if re
.match('^AND\W', self
.getCurr(-1)):
235 result
= self
.parseCompare()
236 test
= self
.getNonNumber(result
, value
)
238 value
= "%d" % self
.normNumber(int(value
) & int(result
))
240 self
.errExit ("'%s' is not a valid op number for AND" % test
)
245 def parseOrXor(self
):
246 value
= self
.parseAnd()
251 if re
.match('^XOR\W', self
.getCurr(-1)):
254 elif re
.match('^OR\W', self
.getCurr(-1)):
260 result
= self
.parseAnd()
261 test
= self
.getNonNumber(result
, value
)
263 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
265 self
.errExit ("'%s' is not a valid op number for XOR/OR" % test
)
269 return self
.parseOrXor()
272 value
= self
.parseExpr()
274 if not self
.isLast():
275 self
.errExit ("Unexpected character found '%s'" % self
.getCurr())
276 test
= self
.getNumber(value
)
278 self
.errExit ("Result '%s' is not a number" % value
)
281 def evaluateExpress (self
, Expr
):
295 self
._GlobalDataDef
= """
301 self
._BuidinOptionTxt
= """
303 Selection 0x1 , "Enabled"
304 Selection 0x0 , "Disabled"
309 self
._BsfKeyList
= ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
310 self
._HdrKeyList
= ['HEADER','STRUCT', 'EMBED', 'COMMENT']
311 self
._BuidinOption
= {'$EN_DIS' : 'EN_DIS'}
315 self
._CfgBlkDict
= {}
316 self
._CfgPageDict
= {}
317 self
._CfgItemList
= []
322 def ParseMacros (self
, MacroDefStr
):
323 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
326 for Macro
in MacroDefStr
:
327 if Macro
.startswith('-D'):
335 Match
= re
.match("(\w+)=(.+)", Macro
)
337 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
339 Match
= re
.match("(\w+)", Macro
)
341 self
._MacroDict
[Match
.group(1)] = ''
342 if len(self
._MacroDict
) == 0:
347 print "INFO : Macro dictionary:"
348 for Each
in self
._MacroDict
:
349 print " $(%s) = [ %s ]" % (Each
, self
._MacroDict
[Each
])
352 def EvaulateIfdef (self
, Macro
):
353 Result
= Macro
in self
._MacroDict
355 print "INFO : Eval Ifdef [%s] : %s" % (Macro
, Result
)
358 def ExpandMacros (self
, Input
):
360 Match
= re
.findall("\$\(\w+\)", Input
)
363 Variable
= Each
[2:-1]
364 if Variable
in self
._MacroDict
:
365 Line
= Line
.replace(Each
, self
._MacroDict
[Variable
])
368 print "WARN : %s is not defined" % Each
369 Line
= Line
.replace(Each
, Each
[2:-1])
372 def ExpandPcds (self
, Input
):
374 Match
= re
.findall("(\w+\.\w+)", Input
)
376 for PcdName
in Match
:
377 if PcdName
in self
._PcdsDict
:
378 Line
= Line
.replace(PcdName
, self
._PcdsDict
[PcdName
])
381 print "WARN : %s is not defined" % PcdName
384 def EvaluateExpress (self
, Expr
):
385 ExpExpr
= self
.ExpandPcds(Expr
)
386 ExpExpr
= self
.ExpandMacros(ExpExpr
)
387 LogExpr
= CLogicalExpression()
388 Result
= LogExpr
.evaluateExpress (ExpExpr
)
390 print "INFO : Eval Express [%s] : %s" % (Expr
, Result
)
393 def FormatListValue(self
, ConfigDict
):
394 Struct
= ConfigDict
['struct']
395 if Struct
not in ['UINT8','UINT16','UINT32','UINT64']:
399 binlist
= ConfigDict
['value'][1:-1].split(',')
402 if each
.startswith('0x'):
403 value
= int(each
, 16)
406 dataarray
.append(value
)
408 unit
= int(Struct
[4:]) / 8
409 if int(ConfigDict
['length']) != unit
* len(dataarray
):
410 raise Exception("Array size is not proper for '%s' !" % ConfigDict
['cname'])
413 for each
in dataarray
:
415 for loop
in xrange(unit
):
416 bytearray
.append("0x%02X" % (value
& 0xFF))
418 newvalue
= '{' + ','.join(bytearray
) + '}'
419 ConfigDict
['value'] = newvalue
422 def ParseDscFile (self
, DscFile
, FvDir
):
425 self
._CfgItemList
= []
426 self
._CfgPageDict
= {}
427 self
._CfgBlkDict
= {}
428 self
._DscFile
= DscFile
441 DscFd
= open(DscFile
, "r")
442 DscLines
= DscFd
.readlines()
445 MaxAlign
= 32 #Default align to 32, but if there are 64 bit unit, align to 64
446 SizeAlign
= 0 #record the struct max align
448 DscLine
= DscLines
.pop(0).strip()
450 Match
= re
.match("^\[(.+)\]", DscLine
)
451 if Match
is not None:
456 if Match
.group(1).lower() == "Defines".lower():
458 if (Match
.group(1).lower() == "PcdsFeatureFlag".lower() or Match
.group(1).lower() == "PcdsFixedAtBuild".lower()):
460 elif Match
.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
462 ConfigDict
['header'] = 'ON'
463 ConfigDict
['region'] = 'UPD'
464 ConfigDict
['order'] = -1
465 ConfigDict
['page'] = ''
466 ConfigDict
['name'] = ''
467 ConfigDict
['find'] = ''
468 ConfigDict
['struct'] = ''
469 ConfigDict
['embed'] = ''
470 ConfigDict
['comment'] = ''
471 ConfigDict
['subreg'] = []
475 if IsDefSect
or IsPcdSect
or IsUpdSect
or IsVpdSect
:
476 if re
.match("^!else($|\s+#.+)", DscLine
):
478 IfStack
[-1] = not IfStack
[-1]
480 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine
)
482 elif re
.match("^!endif($|\s+#.+)", DscLine
):
485 Level
= ElifStack
.pop()
489 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine
)
493 Match
= re
.match("!(ifdef|ifndef)\s+(.+)", DscLine
)
495 Result
= self
.EvaulateIfdef (Match
.group(2))
496 if Match
.group(1) == 'ifndef':
498 IfStack
.append(Result
)
501 Match
= re
.match("!(if|elseif)\s+(.+)", DscLine
.split("#")[0])
503 Result
= self
.EvaluateExpress(Match
.group(2))
504 if Match
.group(1) == "if":
506 IfStack
.append(Result
)
509 IfStack
[-1] = not IfStack
[-1]
510 IfStack
.append(Result
)
511 ElifStack
[-1] = ElifStack
[-1] + 1
513 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine
)
517 Handle
= reduce(lambda x
,y
: x
and y
, IfStack
)
521 Match
= re
.match("!include\s+(.+)", DscLine
)
523 IncludeFilePath
= Match
.group(1)
524 IncludeFilePath
= self
.ExpandMacros(IncludeFilePath
)
525 PackagesPath
= os
.getenv("PACKAGES_PATH")
527 for PackagePath
in PackagesPath
.split(os
.pathsep
):
528 IncludeFilePathAbs
= os
.path
.join(os
.path
.normpath(PackagePath
), os
.path
.normpath(IncludeFilePath
))
529 if os
.path
.exists(IncludeFilePathAbs
):
530 IncludeDsc
= open(IncludeFilePathAbs
, "r")
533 IncludeDsc
= open(IncludeFilePath
, "r")
534 if IncludeDsc
== None:
535 print("ERROR: Cannot open file '%s'" % IncludeFilePath
)
537 NewDscLines
= IncludeDsc
.readlines()
539 DscLines
= NewDscLines
+ DscLines
542 if DscLine
.startswith('!'):
543 print("ERROR: Unrecoginized directive for line '%s'" % DscLine
)
549 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
550 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
551 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
552 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
553 Match
= re
.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine
)
555 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
557 print "INFO : DEFINE %s = [ %s ]" % (Match
.group(1), Match
.group(2))
559 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
560 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
561 Match
= re
.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine
)
563 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
565 print "INFO : PCD %s = [ %s ]" % (Match
.group(1), Match
.group(2))
567 while i
< len(BuildOptionPcd
):
568 Match
= re
.match("\s*([\w\.]+)\s*\=\s*(\w+)", BuildOptionPcd
[i
])
570 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
573 Match
= re
.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine
)
575 Remaining
= Match
.group(2)
576 if Match
.group(1) == '!BSF' or Match
.group(1) == '@Bsf':
577 Match
= re
.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining
)
579 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
580 PageList
= Match
.group(1).split(',')
581 for Page
in PageList
:
583 Match
= re
.match("(\w+):\"(.+)\"", Page
)
584 self
._CfgPageDict
[Match
.group(1)] = Match
.group(2)
586 Match
= re
.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining
)
588 self
._CfgBlkDict
['name'] = Match
.group(1)
589 self
._CfgBlkDict
['ver'] = Match
.group(2)
591 for Key
in self
._BsfKeyList
:
592 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
594 if Key
in ['NAME', 'HELP', 'OPTION'] and Match
.group(1).startswith('+'):
595 ConfigDict
[Key
.lower()] += Match
.group(1)[1:]
597 ConfigDict
[Key
.lower()] = Match
.group(1)
599 for Key
in self
._HdrKeyList
:
600 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
602 ConfigDict
[Key
.lower()] = Match
.group(1)
604 Match
= re
.match("^\s*#\s+@Prompt\s+(.+)", DscLine
)
606 ConfigDict
['name'] = Match
.group(1)
608 Match
= re
.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine
)
610 if Match
.group(2).strip() in self
._BuidinOption
:
611 ConfigDict
['option'] = Match
.group(2).strip()
613 OptionValueList
= Match
.group(2).split(',')
614 OptionStringList
= Match
.group(3).split(',')
616 for Option
in OptionValueList
:
617 Option
= Option
.strip()
618 ConfigDict
['option'] = ConfigDict
['option'] + str(Option
) + ':' + OptionStringList
[Index
].strip()
620 if Index
in range(len(OptionValueList
)):
621 ConfigDict
['option'] += ', '
622 ConfigDict
['type'] = "Combo"
624 Match
= re
.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine
)
626 if "0x" in Match
.group(2) or "0x" in Match
.group(3):
627 ConfigDict
['type'] = "EditNum, HEX, (%s,%s)" % (Match
.group(2), Match
.group(3))
629 ConfigDict
['type'] = "EditNum, DEC, (%s,%s)" % (Match
.group(2), Match
.group(3))
631 Match
= re
.match("^\s*##\s+(.+)", DscLine
)
633 ConfigDict
['help'] = Match
.group(1)
637 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
)
639 Match
= re
.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine
)
641 ConfigDict
['space'] = Match
.group(1)
642 ConfigDict
['cname'] = Match
.group(2)
643 if Match
.group(3) != '*':
645 Offset
= int (Match
.group(3), 16)
649 if Hardcode
and AutoAlign
:
650 print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")
652 ConfigDict
['offset'] = Offset
653 if ConfigDict
['order'] == -1:
654 ConfigDict
['order'] = ConfigDict
['offset'] << 8
656 (Major
, Minor
) = ConfigDict
['order'].split('.')
657 ConfigDict
['order'] = (int (Major
, 16) << 8 ) + int (Minor
, 16)
659 Value
= Match
.group(5).strip()
660 if Match
.group(4).startswith("0x"):
661 Length
= int (Match
.group(4), 16)
663 Length
= int (Match
.group(4))
666 Value
= Match
.group(4)
669 Value
= Value
.strip()
671 Match
= re
.match("^.+\s*\|\s*(.+)", Value
)
673 Value
= Match
.group(1)
676 ConfigDict
['length'] = Length
677 Match
= re
.match("\$\((\w+)\)", Value
)
679 if Match
.group(1) in self
._MacroDict
:
680 Value
= self
._MacroDict
[Match
.group(1)]
682 ConfigDict
['value'] = Value
683 if (len(Value
) > 0) and (Value
[0] == '{'):
684 Value
= self
.FormatListValue(ConfigDict
)
686 if ConfigDict
['name'] == '':
687 # Clear BSF specific items
688 ConfigDict
['bsfname'] = ''
689 ConfigDict
['help'] = ''
690 ConfigDict
['type'] = ''
691 ConfigDict
['option'] = ''
692 if IsUpdSect
and AutoAlign
:
693 ItemLength
= int(ConfigDict
['length'])
694 ItemOffset
= int(ConfigDict
['offset'])
695 ItemStruct
= ConfigDict
['struct']
697 if ItemLength
in [1, 2, 4, 8] and not ConfigDict
['value'].startswith('{'):
699 # If there are 64 bit unit, align to 64
704 UnitDict
= {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}
705 if ItemStruct
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
706 Unit
= UnitDict
[ItemStruct
]
707 # If there are 64 bit unit, align to 64
710 SizeAlign
= max(SizeAlign
, Unit
)
711 if (ConfigDict
['embed'].find(':START') != -1):
713 SubOffset
= ItemOffset
- Base
714 SubRemainder
= SubOffset
% Unit
716 Diff
= Unit
- SubRemainder
717 Offset
= Offset
+ Diff
718 ItemOffset
= ItemOffset
+ Diff
720 if (ConfigDict
['embed'].find(':END') != -1):
721 Remainder
= Offset
% (MaxAlign
/8) # MaxAlign is either 32 or 64
723 Diff
= (MaxAlign
/8) - Remainder
724 Offset
= Offset
+ Diff
725 ItemOffset
= ItemOffset
+ Diff
726 MaxAlign
= 32 # Reset to default 32 align when struct end
727 if (ConfigDict
['cname'] == 'UpdTerminator'):
728 # ItemLength is the size of UpdTerminator
729 # Itemlength might be 16, 32, or 64
730 # Struct align to 64 if UpdTerminator
731 # or struct size is 64 bit, else align to 32
732 Remainder
= Offset
% max(ItemLength
/8, 4, SizeAlign
)
733 Offset
= Offset
+ ItemLength
735 Diff
= max(ItemLength
/8, 4, SizeAlign
) - Remainder
736 ItemOffset
= ItemOffset
+ Diff
737 ConfigDict
['offset'] = ItemOffset
739 self
._CfgItemList
.append(ConfigDict
.copy())
740 ConfigDict
['name'] = ''
741 ConfigDict
['find'] = ''
742 ConfigDict
['struct'] = ''
743 ConfigDict
['embed'] = ''
744 ConfigDict
['comment'] = ''
745 ConfigDict
['order'] = -1
746 ConfigDict
['subreg'] = []
747 ConfigDict
['option'] = ''
749 # It could be a virtual item as below
750 # !BSF FIELD:{SerialDebugPortAddress0:1}
752 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
753 Match
= re
.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine
)
755 SubCfgDict
= ConfigDict
.copy()
756 if (Match
.group(4) == None) or (Match
.group(4) == 'B'):
758 elif Match
.group(4) == 'b':
761 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine
)
763 SubCfgDict
['cname'] = Match
.group(2)
764 SubCfgDict
['bitlength'] = int (Match
.group(3)) * UnitBitLen
765 if SubCfgDict
['bitlength'] > 0:
766 LastItem
= self
._CfgItemList
[-1]
767 if len(LastItem
['subreg']) == 0:
770 SubOffset
= LastItem
['subreg'][-1]['bitoffset'] + LastItem
['subreg'][-1]['bitlength']
771 SubCfgDict
['bitoffset'] = SubOffset
772 LastItem
['subreg'].append (SubCfgDict
.copy())
773 ConfigDict
['name'] = ''
776 def GetBsfBitFields (self
, subitem
, bytes
):
777 start
= subitem
['bitoffset']
778 end
= start
+ subitem
['bitlength']
779 bitsvalue
= ''.join('{0:08b}'.format(i
) for i
in bytes
[::-1])
780 bitsvalue
= bitsvalue
[::-1]
781 bitslen
= len(bitsvalue
)
782 if start
> bitslen
or end
> bitslen
:
783 print "Invalid bits offset [%d,%d] for %s" % (start
, end
, subitem
['name'])
785 return hex(int(bitsvalue
[start
:end
][::-1], 2))
787 def UpdateSubRegionDefaultValue (self
):
789 for Item
in self
._CfgItemList
:
790 if len(Item
['subreg']) == 0:
793 if Item
['value'][0] == '{':
794 binlist
= Item
['value'][1:-1].split(',')
797 if each
.startswith('0x'):
798 value
= int(each
, 16)
801 bytearray
.append(value
)
803 if Item
['value'].startswith('0x'):
804 value
= int(Item
['value'], 16)
806 value
= int(Item
['value'])
808 while idx
< Item
['length']:
809 bytearray
.append(value
& 0xFF)
812 for SubItem
in Item
['subreg']:
813 valuestr
= self
.GetBsfBitFields(SubItem
, bytearray
)
814 SubItem
['value'] = valuestr
817 def CreateSplitUpdTxt (self
, UpdTxtFile
):
818 GuidList
= ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
819 SignatureList
= ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
820 for Index
in range(len(GuidList
)):
823 if GuidList
[Index
] not in self
._MacroDict
:
824 self
.Error
= "%s definition is missing in DSC file" % (GuidList
[Index
])
828 UpdTxtFile
= os
.path
.join(FvDir
, self
._MacroDict
[GuidList
[Index
]] + '.txt')
831 if not os
.path
.exists(UpdTxtFile
):
834 DscTime
= os
.path
.getmtime(self
._DscFile
)
835 TxtTime
= os
.path
.getmtime(UpdTxtFile
)
836 if DscTime
> TxtTime
:
840 # DSC has not been modified yet
841 # So don't have to re-generate other files
842 self
.Error
= 'No DSC file change, skip to create UPD TXT file'
845 TxtFd
= open(UpdTxtFile
, "w")
846 TxtFd
.write("%s\n" % (__copyright_txt__
% date
.today().year
))
854 for Item
in self
._CfgItemList
:
855 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
856 StartAddr
= Item
['offset']
857 NextOffset
= StartAddr
859 if Item
['cname'] == 'UpdTerminator' and InRange
== True:
860 EndAddr
= Item
['offset']
863 for Item
in self
._CfgItemList
:
864 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
868 if Item
['cname'] == 'UpdTerminator':
870 if Item
['region'] != 'UPD':
872 Offset
= Item
['offset']
873 if StartAddr
> Offset
or EndAddr
< Offset
:
875 if NextOffset
< Offset
:
877 TxtFd
.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item
['space'], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
878 SpaceIdx
= SpaceIdx
+ 1
879 NextOffset
= Offset
+ Item
['length']
880 TxtFd
.write("%s.%s|%s0x%04X|%s|%s\n" % (Item
['space'],Item
['cname'],Default
,Item
['offset'] - StartAddr
,Item
['length'],Item
['value']))
884 def ProcessMultilines (self
, String
, MaxCharLength
):
886 StringLength
= len(String
)
887 CurrentStringStart
= 0
890 if len(String
) <= MaxCharLength
:
891 while (StringOffset
< StringLength
):
892 if StringOffset
>= 1:
893 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
894 BreakLineDict
.append (StringOffset
+ 1)
896 if BreakLineDict
!= []:
897 for Each
in BreakLineDict
:
898 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
899 CurrentStringStart
= Each
900 if StringLength
- CurrentStringStart
> 0:
901 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
903 Multilines
= " %s\n" % String
907 FoundSpaceChar
= False
908 while (StringOffset
< StringLength
):
909 if StringOffset
>= 1:
910 if NewLineCount
>= MaxCharLength
- 1:
911 if String
[StringOffset
] == ' ' and StringLength
- StringOffset
> 10:
912 BreakLineDict
.append (NewLineStart
+ NewLineCount
)
913 NewLineStart
= NewLineStart
+ NewLineCount
915 FoundSpaceChar
= True
916 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False:
917 BreakLineDict
.append (0)
918 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
919 BreakLineDict
.append (StringOffset
+ 1)
920 NewLineStart
= StringOffset
+ 1
924 if BreakLineDict
!= []:
925 BreakLineDict
.sort ()
926 for Each
in BreakLineDict
:
928 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
929 CurrentStringStart
= Each
930 if StringLength
- CurrentStringStart
> 0:
931 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
934 def CreateField (self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
):
942 if Length
in [1,2,4,8]:
943 Type
= "UINT%d" % (Length
* 8)
944 if Name
.startswith("UnusedUpdSpace") and Length
!= 1:
951 if Item
and Item
['value'].startswith('{'):
957 if Struct
in ['UINT8','UINT16','UINT32','UINT64']:
959 Unit
= int(Type
[4:]) / 8
960 Length
= Length
/ Unit
965 Name
= Name
+ '[%d]' % Length
967 if len(Type
) < PosName
:
968 Space1
= PosName
- len(Type
)
973 NameLine
=" - %s\n" % BsfName
978 HelpLine
= self
.ProcessMultilines (Help
, 80)
981 OptionLine
= self
.ProcessMultilines (Option
, 80)
986 OffsetStr
= '0x%04X' % Offset
988 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
,)
990 def PostProcessBody (self
, TextBody
):
996 IsUpdHdrDefined
= False
998 for Line
in TextBody
:
999 SplitToLines
= Line
.splitlines()
1000 MatchComment
= re
.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines
[0])
1002 if MatchComment
.group(1) == 'FSP_UPD_HEADER':
1006 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1007 CommentLine
= " " + MatchComment
.group(2) + "\n"
1008 NewTextBody
.append("/**" + CommentLine
+ "**/\n")
1009 Line
= Line
[(len(SplitToLines
[0]) + 1):]
1011 Match
= re
.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line
)
1013 Line
= Match
.group(4)
1014 if Match
.group(1) == 'FSP_UPD_HEADER':
1019 if Match
and Match
.group(3) == 'START':
1020 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1021 NewTextBody
.append ('typedef struct {\n')
1022 StructName
= Match
.group(1)
1023 VariableName
= Match
.group(2)
1024 MatchOffset
= re
.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line
)
1026 Offset
= int(MatchOffset
.group(1), 16)
1031 OldTextBody
.append (self
.CreateField (None, VariableName
, 0, Offset
, StructName
, '', '', ''))
1033 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1034 NewTextBody
.append (Line
)
1036 OldTextBody
.append (Line
)
1038 if Match
and Match
.group(3) == 'END':
1039 if (StructName
!= Match
.group(1)) or (VariableName
!= Match
.group(2)):
1040 print "Unmatched struct name '%s' and '%s' !" % (StructName
, Match
.group(1))
1042 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1043 NewTextBody
.append ('} %s;\n\n' % StructName
)
1044 IsUpdHdrDefined
= True
1046 NewTextBody
.extend(OldTextBody
)
1049 def WriteLinesWithoutTailingSpace (self
, HeaderFd
, Line
):
1050 TxtBody2
= Line
.splitlines(True)
1051 for Line2
in TxtBody2
:
1052 Line2
= Line2
.rstrip()
1054 HeaderFd
.write (Line2
)
1056 def CreateHeaderFile (self
, InputHeaderFile
):
1059 HeaderFileName
= 'FspUpd.h'
1060 HeaderFile
= os
.path
.join(FvDir
, HeaderFileName
)
1062 # Check if header needs to be recreated
1066 for Item
in self
._CfgItemList
:
1067 if str(Item
['cname']) == 'Signature' and Item
['length'] == 8:
1068 Value
= int(Item
['value'], 16)
1071 Chars
.append(chr(Value
& 0xFF))
1073 SignatureStr
= ''.join(Chars
)
1074 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly
1075 if '_T' in SignatureStr
[6:6+2]:
1076 TxtBody
.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1077 elif '_M' in SignatureStr
[6:6+2]:
1078 TxtBody
.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1079 elif '_S' in SignatureStr
[6:6+2]:
1080 TxtBody
.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1081 TxtBody
.append("\n")
1083 for Region
in ['UPD']:
1085 UpdSignature
= ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS
1086 UpdStructure
= ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
1087 for Item
in self
._CfgItemList
:
1088 if Item
["cname"] == 'Signature' and Item
["value"][0:6] in UpdSignature
:
1089 UpdOffsetTable
.append (Item
["offset"])
1091 for UpdIdx
in range(len(UpdOffsetTable
)):
1093 for Item
in self
._CfgItemList
:
1094 if Item
["comment"] != '' and Item
["offset"] >= UpdOffsetTable
[UpdIdx
]:
1095 MatchComment
= re
.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item
["comment"])
1096 if MatchComment
and MatchComment
.group(1) == Region
[0]:
1097 CommentLine
= " " + MatchComment
.group(2) + "\n"
1098 TxtBody
.append("/**" + CommentLine
+ "**/\n")
1099 elif Item
["offset"] >= UpdOffsetTable
[UpdIdx
] and Item
["comment"] == '':
1100 Match
= re
.match("^FSP([\w|\W|\s])_UPD", UpdStructure
[UpdIdx
])
1102 TxtBody
.append("/** Fsp " + Match
.group(1) + " UPD Configuration\n**/\n")
1103 TxtBody
.append("typedef struct {\n")
1113 for Item
in self
._CfgItemList
:
1114 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == UpdSignature
[UpdIdx
] or Region
[0] == 'V':
1118 if Item
['cname'] == 'UpdTerminator':
1121 if Item
['region'] != Region
:
1124 if Item
["offset"] < UpdOffsetTable
[UpdIdx
]:
1127 NextVisible
= LastVisible
1129 if LastVisible
and (Item
['header'] == 'OFF'):
1131 ResvOffset
= Item
['offset']
1132 elif (not LastVisible
) and Item
['header'] == 'ON':
1134 Name
= "Reserved" + Region
[0] + "pdSpace%d" % ResvIdx
1135 ResvIdx
= ResvIdx
+ 1
1136 TxtBody
.append(self
.CreateField (Item
, Name
, Item
["offset"] - ResvOffset
, ResvOffset
, '', '', '', ''))
1138 if Offset
< Item
["offset"]:
1140 Name
= "Unused" + Region
[0] + "pdSpace%d" % SpaceIdx
1141 LineBuffer
.append(self
.CreateField (Item
, Name
, Item
["offset"] - Offset
, Offset
, '', '', '', ''))
1142 SpaceIdx
= SpaceIdx
+ 1
1143 Offset
= Item
["offset"]
1145 LastVisible
= NextVisible
1147 Offset
= Offset
+ Item
["length"]
1149 for Each
in LineBuffer
:
1150 TxtBody
.append (Each
)
1152 Comment
= Item
["comment"]
1153 Embed
= Item
["embed"].upper()
1154 if Embed
.endswith(':START') or Embed
.endswith(':END'):
1155 if not Comment
== '' and Embed
.endswith(':START'):
1156 Marker
= '/* COMMENT:%s */ \n' % Item
["comment"]
1157 Marker
= Marker
+ '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1159 Marker
= '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1164 self
.Error
= "Invalid embedded structure format '%s'!\n" % Item
["embed"]
1166 Line
= Marker
+ self
.CreateField (Item
, Item
["cname"], Item
["length"], Item
["offset"], Item
['struct'], Item
['name'], Item
['help'], Item
['option'])
1167 TxtBody
.append(Line
)
1168 if Item
['cname'] == 'UpdTerminator':
1170 TxtBody
.append("} " + UpdStructure
[UpdIdx
] + ";\n\n")
1172 # Handle the embedded data structure
1173 TxtBody
= self
.PostProcessBody (TxtBody
)
1175 HeaderTFileName
= 'FsptUpd.h'
1176 HeaderMFileName
= 'FspmUpd.h'
1177 HeaderSFileName
= 'FspsUpd.h'
1179 UpdRegionCheck
= ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
1180 UpdConfigCheck
= ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1181 UpdSignatureCheck
= ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
1182 ExcludedSpecificUpd
= 'FSPM_ARCH_UPD'
1184 if InputHeaderFile
!= '':
1185 if not os
.path
.exists(InputHeaderFile
):
1186 self
.Error
= "Input header file '%s' does not exist" % InputHeaderFile
1189 InFd
= open(InputHeaderFile
, "r")
1190 IncLines
= InFd
.readlines()
1193 for item
in range(len(UpdRegionCheck
)):
1194 if UpdRegionCheck
[item
] == 'FSPT':
1195 HeaderFd
= open(os
.path
.join(FvDir
, HeaderTFileName
), "w")
1196 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderTFileName
))
1197 elif UpdRegionCheck
[item
] == 'FSPM':
1198 HeaderFd
= open(os
.path
.join(FvDir
, HeaderMFileName
), "w")
1199 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderMFileName
))
1200 elif UpdRegionCheck
[item
] == 'FSPS':
1201 HeaderFd
= open(os
.path
.join(FvDir
, HeaderSFileName
), "w")
1202 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderSFileName
))
1203 FileName
= FileBase
.replace(".", "_").upper()
1204 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1205 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1206 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1207 HeaderFd
.write("#include <%s>\n\n" % HeaderFileName
)
1208 HeaderFd
.write("#pragma pack(1)\n\n")
1211 for Line
in IncLines
:
1212 Match
= re
.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line
)
1214 if Match
.group(2) == "BEGIN" and Match
.group(1) == UpdRegionCheck
[item
]:
1221 HeaderFd
.write(Line
)
1222 HeaderFd
.write("\n")
1228 StructStartWithComment
= []
1230 for Line
in TxtBody
:
1232 Match
= re
.match("(typedef struct {)", Line
)
1234 StartIndex
= Index
- 1
1235 Match
= re
.match("}\s([_A-Z0-9]+);", Line
)
1236 if Match
and (UpdRegionCheck
[item
] in Match
.group(1) or UpdConfigCheck
[item
] in Match
.group(1)) and (ExcludedSpecificUpd
not in Match
.group(1)):
1238 StructStart
.append(StartIndex
)
1239 StructEnd
.append(EndIndex
)
1241 for Line
in TxtBody
:
1243 for Item
in range(len(StructStart
)):
1244 if Index
== StructStart
[Item
]:
1245 Match
= re
.match("^(/\*\*\s*)", Line
)
1247 StructStartWithComment
.append(StructStart
[Item
])
1249 StructStartWithComment
.append(StructStart
[Item
] + 1)
1251 for Line
in TxtBody
:
1253 for Item
in range(len(StructStart
)):
1254 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1255 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1256 HeaderFd
.write("#pragma pack()\n\n")
1257 HeaderFd
.write("#endif\n")
1260 HeaderFd
= open(HeaderFile
, "w")
1261 FileBase
= os
.path
.basename(HeaderFile
)
1262 FileName
= FileBase
.replace(".", "_").upper()
1263 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1264 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1265 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1266 HeaderFd
.write("#include <FspEas.h>\n\n")
1267 HeaderFd
.write("#pragma pack(1)\n\n")
1269 for item
in range(len(UpdRegionCheck
)):
1274 StructStartWithComment
= []
1276 for Line
in TxtBody
:
1278 Match
= re
.match("(typedef struct {)", Line
)
1280 StartIndex
= Index
- 1
1281 Match
= re
.match("#define\s([_A-Z0-9]+)\s*", Line
)
1282 if Match
and (UpdSignatureCheck
[item
] in Match
.group(1) or UpdSignatureCheck
[item
] in Match
.group(1)):
1283 StructStart
.append(Index
- 1)
1284 StructEnd
.append(Index
)
1286 for Line
in TxtBody
:
1288 for Item
in range(len(StructStart
)):
1289 if Index
== StructStart
[Item
]:
1290 Match
= re
.match("^(/\*\*\s*)", Line
)
1292 StructStartWithComment
.append(StructStart
[Item
])
1294 StructStartWithComment
.append(StructStart
[Item
] + 1)
1296 for Line
in TxtBody
:
1298 for Item
in range(len(StructStart
)):
1299 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1300 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1301 HeaderFd
.write("#pragma pack()\n\n")
1302 HeaderFd
.write("#endif\n")
1307 def WriteBsfStruct (self
, BsfFd
, Item
):
1308 LogExpr
= CLogicalExpression()
1309 if Item
['type'] == "None":
1310 Space
= "gPlatformFspPkgTokenSpaceGuid"
1312 Space
= Item
['space']
1313 Line
= " $%s_%s" % (Space
, Item
['cname'])
1314 Match
= re
.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item
['value'])
1316 DefaultValue
= Match
.group(1).strip()
1318 DefaultValue
= Item
['value'].strip()
1319 if 'bitlength' in Item
:
1320 BsfFd
.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['bitlength'], DefaultValue
))
1322 BsfFd
.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['length'], DefaultValue
))
1324 if Item
['type'] == "Combo":
1325 if not Item
['option'] in self
._BuidinOption
:
1326 OptList
= Item
['option'].split(',')
1327 for Option
in OptList
:
1328 Option
= Option
.strip()
1329 (OpVal
, OpStr
) = Option
.split(':')
1330 test
= LogExpr
.getNumber (OpVal
)
1332 raise Exception("Selection Index '%s' is not a number" % OpVal
)
1333 TmpList
.append((OpVal
, OpStr
))
1336 def WriteBsfOption (self
, BsfFd
, Item
):
1337 PcdName
= Item
['space'] + '_' + Item
['cname']
1339 if Item
['type'] == "Combo":
1340 if Item
['option'] in self
._BuidinOption
:
1341 Options
= self
._BuidinOption
[Item
['option']]
1344 BsfFd
.write(' %s $%s, "%s", &%s,\n' % (Item
['type'], PcdName
, Item
['name'], Options
))
1346 elif Item
['type'].startswith("EditNum"):
1347 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'])
1349 BsfFd
.write(' EditNum $%s, "%s", %s,\n' % (PcdName
, Item
['name'], Match
.group(1)))
1351 elif Item
['type'].startswith("EditText"):
1352 BsfFd
.write(' %s $%s, "%s",\n' % (Item
['type'], PcdName
, Item
['name']))
1354 elif Item
['type'] == "Table":
1355 Columns
= Item
['option'].split(',')
1356 if len(Columns
) != 0:
1357 BsfFd
.write(' %s $%s "%s",' % (Item
['type'], PcdName
, Item
['name']))
1359 Fmt
= Col
.split(':')
1361 raise Exception("Column format '%s' is invalid !" % Fmt
)
1363 Dtype
= int(Fmt
[1].strip())
1365 raise Exception("Column size '%s' is invalid !" % Fmt
[1])
1366 BsfFd
.write('\n Column "%s", %d bytes, %s' % (Fmt
[0].strip(), Dtype
, Fmt
[2].strip()))
1371 HelpLines
= Item
['help'].split('\\n\\r')
1373 for HelpLine
in HelpLines
:
1376 BsfFd
.write(' Help "%s"\n' % (HelpLine
))
1378 BsfFd
.write(' "%s"\n' % (HelpLine
))
1380 BsfFd
.write(' "Valid range: %s ~ %s"\n' % (Match
.group(2), Match
.group(3)))
1382 def GenerateBsfFile (self
, BsfFile
):
1385 self
.Error
= "BSF output file '%s' is invalid" % BsfFile
1390 BsfFd
= open(BsfFile
, "w")
1391 BsfFd
.write("%s\n" % (__copyright_bsf__
% date
.today().year
))
1392 BsfFd
.write("%s\n" % self
._GlobalDataDef
)
1393 BsfFd
.write("StructDef\n")
1395 for Item
in self
._CfgItemList
:
1396 if Item
['find'] != '':
1397 BsfFd
.write('\n Find "%s"\n' % Item
['find'])
1398 NextOffset
= Item
['offset'] + Item
['length']
1399 if Item
['name'] != '':
1400 if NextOffset
!= Item
['offset']:
1401 BsfFd
.write(" Skip %d bytes\n" % (Item
['offset'] - NextOffset
))
1402 if len(Item
['subreg']) > 0:
1403 NextOffset
= Item
['offset']
1404 BitsOffset
= NextOffset
* 8
1405 for SubItem
in Item
['subreg']:
1406 BitsOffset
+= SubItem
['bitlength']
1407 if SubItem
['name'] == '':
1408 if 'bitlength' in SubItem
:
1409 BsfFd
.write(" Skip %d bits\n" % (SubItem
['bitlength']))
1411 BsfFd
.write(" Skip %d bytes\n" % (SubItem
['length']))
1413 Options
= self
.WriteBsfStruct(BsfFd
, SubItem
)
1414 if len(Options
) > 0:
1415 OptionDict
[SubItem
['space']+'_'+SubItem
['cname']] = Options
1417 NextBitsOffset
= (Item
['offset'] + Item
['length']) * 8
1418 if NextBitsOffset
> BitsOffset
:
1419 BitsGap
= NextBitsOffset
- BitsOffset
1420 BitsRemain
= BitsGap
% 8
1422 BsfFd
.write(" Skip %d bits\n" % BitsRemain
)
1423 BitsGap
-= BitsRemain
1424 BytesRemain
= BitsGap
/ 8
1426 BsfFd
.write(" Skip %d bytes\n" % BytesRemain
)
1427 NextOffset
= Item
['offset'] + Item
['length']
1429 NextOffset
= Item
['offset'] + Item
['length']
1430 Options
= self
.WriteBsfStruct(BsfFd
, Item
)
1431 if len(Options
) > 0:
1432 OptionDict
[Item
['space']+'_'+Item
['cname']] = Options
1433 BsfFd
.write("\nEndStruct\n\n")
1435 BsfFd
.write("%s" % self
._BuidinOptionTxt
)
1437 for Each
in OptionDict
:
1438 BsfFd
.write("List &%s\n" % Each
)
1439 for Item
in OptionDict
[Each
]:
1440 BsfFd
.write(' Selection %s , "%s"\n' % (Item
[0], Item
[1]))
1441 BsfFd
.write("EndList\n\n")
1443 BsfFd
.write("BeginInfoBlock\n")
1444 BsfFd
.write(' PPVer "%s"\n' % (self
._CfgBlkDict
['ver']))
1445 BsfFd
.write(' Description "%s"\n' % (self
._CfgBlkDict
['name']))
1446 BsfFd
.write("EndInfoBlock\n\n")
1448 for Each
in self
._CfgPageDict
:
1449 BsfFd
.write('Page "%s"\n' % self
._CfgPageDict
[Each
])
1451 for Item
in self
._CfgItemList
:
1452 if Item
['name'] != '':
1453 if Item
['page'] != Each
:
1455 if len(Item
['subreg']) > 0:
1456 for SubItem
in Item
['subreg']:
1457 if SubItem
['name'] != '':
1458 BsfItems
.append(SubItem
)
1460 BsfItems
.append(Item
)
1462 BsfItems
.sort(key
=lambda x
: x
['order'])
1464 for Item
in BsfItems
:
1465 self
.WriteBsfOption (BsfFd
, Item
)
1466 BsfFd
.write("EndPage\n\n")
1473 print "GenCfgOpt Version 0.53"
1475 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
1476 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
1477 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1481 # Parse the options and args
1485 GenCfgOpt
= CGenCfgOpt()
1486 while i
< len(sys
.argv
):
1487 if sys
.argv
[i
].strip().lower() == "--pcd":
1488 BuildOptionPcd
.append(sys
.argv
[i
+1])
1491 argc
= len(sys
.argv
)
1496 DscFile
= sys
.argv
[2]
1497 if not os
.path
.exists(DscFile
):
1498 print "ERROR: Cannot open DSC file '%s' !" % DscFile
1503 if sys
.argv
[4][0] == '-':
1506 OutFile
= sys
.argv
[4]
1509 if GenCfgOpt
.ParseMacros(sys
.argv
[Start
:]) != 0:
1510 print "ERROR: Macro parsing failed !"
1514 if not os
.path
.exists(FvDir
):
1517 if GenCfgOpt
.ParseDscFile(DscFile
, FvDir
) != 0:
1518 print "ERROR: %s !" % GenCfgOpt
.Error
1521 if GenCfgOpt
.UpdateSubRegionDefaultValue() != 0:
1522 print "ERROR: %s !" % GenCfgOpt
.Error
1525 if sys
.argv
[1] == "UPDTXT":
1526 Ret
= GenCfgOpt
.CreateSplitUpdTxt(OutFile
)
1528 # No change is detected
1530 print "INFO: %s !" % (GenCfgOpt
.Error
)
1532 print "ERROR: %s !" % (GenCfgOpt
.Error
)
1534 elif sys
.argv
[1] == "HEADER":
1535 if GenCfgOpt
.CreateHeaderFile(OutFile
) != 0:
1536 print "ERROR: %s !" % GenCfgOpt
.Error
1538 elif sys
.argv
[1] == "GENBSF":
1539 if GenCfgOpt
.GenerateBsfFile(OutFile
) != 0:
1540 print "ERROR: %s !" % GenCfgOpt
.Error
1546 print "ERROR: Unknown command '%s' !" % sys
.argv
[1]
1553 if __name__
== '__main__':