]>
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 !!!
91 class CLogicalExpression
:
96 def errExit(self
, err
= ''):
97 print "ERROR: Express parsing for:"
98 print " %s" % self
.string
99 print " %s^" % (' ' * self
.index
)
101 print "INFO : %s" % err
104 def getNonNumber (self
, n1
, n2
):
111 def getCurr(self
, lens
= 1):
114 return self
.string
[self
.index
:]
116 if self
.index
+ lens
> len(self
.string
):
117 lens
= len(self
.string
) - self
.index
118 return self
.string
[self
.index
: self
.index
+ lens
]
123 return self
.index
== len(self
.string
)
125 def moveNext(self
, len = 1):
129 while not self
.isLast():
130 if self
.getCurr() in ' \t':
135 def normNumber (self
, val
):
136 return True if val
else False
138 def getNumber(self
, var
):
140 if re
.match('^0x[a-fA-F0-9]+$', var
):
142 elif re
.match('^[+-]?\d+$', var
):
148 def parseValue(self
):
151 while not self
.isLast():
152 char
= self
.getCurr()
153 if re
.match('^[\w.]', char
):
158 val
= self
.getNumber(var
)
165 def parseSingleOp(self
):
167 if re
.match('^NOT\W', self
.getCurr(-1)):
169 op
= self
.parseBrace()
170 val
= self
.getNumber (op
)
172 self
.errExit ("'%s' is not a number" % op
)
173 return "%d" % (not self
.normNumber(int(op
)))
175 return self
.parseValue()
177 def parseBrace(self
):
179 char
= self
.getCurr()
182 value
= self
.parseExpr()
184 if self
.getCurr() != ')':
185 self
.errExit ("Expecting closing brace or operator")
189 value
= self
.parseSingleOp()
192 def parseCompare(self
):
193 value
= self
.parseBrace()
196 char
= self
.getCurr()
197 if char
in ['<', '>']:
199 next
= self
.getCurr()
205 result
= self
.parseBrace()
206 test
= self
.getNonNumber(result
, value
)
208 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
210 self
.errExit ("'%s' is not a valid number for comparision" % test
)
211 elif char
in ['=', '!']:
213 if op
in ['==', '!=']:
215 result
= self
.parseBrace()
216 test
= self
.getNonNumber(result
, value
)
218 value
= "%d" % self
.normNumber((eval (value
+ op
+ result
)))
220 value
= "%d" % self
.normNumber(eval ("'" + value
+ "'" + op
+ "'" + result
+ "'"))
228 value
= self
.parseCompare()
231 if re
.match('^AND\W', self
.getCurr(-1)):
233 result
= self
.parseCompare()
234 test
= self
.getNonNumber(result
, value
)
236 value
= "%d" % self
.normNumber(int(value
) & int(result
))
238 self
.errExit ("'%s' is not a valid op number for AND" % test
)
243 def parseOrXor(self
):
244 value
= self
.parseAnd()
249 if re
.match('^XOR\W', self
.getCurr(-1)):
252 elif re
.match('^OR\W', self
.getCurr(-1)):
258 result
= self
.parseAnd()
259 test
= self
.getNonNumber(result
, value
)
261 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
263 self
.errExit ("'%s' is not a valid op number for XOR/OR" % test
)
267 return self
.parseOrXor()
270 value
= self
.parseExpr()
272 if not self
.isLast():
273 self
.errExit ("Unexpected character found '%s'" % self
.getCurr())
274 test
= self
.getNumber(value
)
276 self
.errExit ("Result '%s' is not a number" % value
)
279 def evaluateExpress (self
, Expr
):
293 self
._GlobalDataDef
= """
299 self
._BuidinOptionTxt
= """
301 Selection 0x1 , "Enabled"
302 Selection 0x0 , "Disabled"
307 self
._BsfKeyList
= ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
308 self
._HdrKeyList
= ['HEADER','STRUCT', 'EMBED', 'COMMENT']
309 self
._BuidinOption
= {'$EN_DIS' : 'EN_DIS'}
313 self
._CfgBlkDict
= {}
314 self
._CfgPageDict
= {}
315 self
._CfgItemList
= []
320 def ParseMacros (self
, MacroDefStr
):
321 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
324 for Macro
in MacroDefStr
:
325 if Macro
.startswith('-D'):
333 Match
= re
.match("(\w+)=(.+)", Macro
)
335 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
337 Match
= re
.match("(\w+)", Macro
)
339 self
._MacroDict
[Match
.group(1)] = ''
340 if len(self
._MacroDict
) == 0:
345 print "INFO : Macro dictionary:"
346 for Each
in self
._MacroDict
:
347 print " $(%s) = [ %s ]" % (Each
, self
._MacroDict
[Each
])
350 def EvaulateIfdef (self
, Macro
):
351 Result
= Macro
in self
._MacroDict
353 print "INFO : Eval Ifdef [%s] : %s" % (Macro
, Result
)
356 def ExpandMacros (self
, Input
):
358 Match
= re
.findall("\$\(\w+\)", Input
)
361 Variable
= Each
[2:-1]
362 if Variable
in self
._MacroDict
:
363 Line
= Line
.replace(Each
, self
._MacroDict
[Variable
])
366 print "WARN : %s is not defined" % Each
367 Line
= Line
.replace(Each
, Each
[2:-1])
370 def ExpandPcds (self
, Input
):
372 Match
= re
.findall("(\w+\.\w+)", Input
)
374 for PcdName
in Match
:
375 if PcdName
in self
._PcdsDict
:
376 Line
= Line
.replace(PcdName
, self
._PcdsDict
[PcdName
])
379 print "WARN : %s is not defined" % PcdName
382 def EvaluateExpress (self
, Expr
):
383 ExpExpr
= self
.ExpandPcds(Expr
)
384 ExpExpr
= self
.ExpandMacros(ExpExpr
)
385 LogExpr
= CLogicalExpression()
386 Result
= LogExpr
.evaluateExpress (ExpExpr
)
388 print "INFO : Eval Express [%s] : %s" % (Expr
, Result
)
391 def FormatListValue(self
, ConfigDict
):
392 Struct
= ConfigDict
['struct']
393 if Struct
not in ['UINT8','UINT16','UINT32','UINT64']:
397 binlist
= ConfigDict
['value'][1:-1].split(',')
400 if each
.startswith('0x'):
401 value
= int(each
, 16)
404 dataarray
.append(value
)
406 unit
= int(Struct
[4:]) / 8
407 if int(ConfigDict
['length']) != unit
* len(dataarray
):
408 raise Exception("Array size is not proper for '%s' !" % ConfigDict
['cname'])
411 for each
in dataarray
:
413 for loop
in xrange(unit
):
414 bytearray
.append("0x%02X" % (value
& 0xFF))
416 newvalue
= '{' + ','.join(bytearray
) + '}'
417 ConfigDict
['value'] = newvalue
420 def ParseDscFile (self
, DscFile
, FvDir
):
423 self
._CfgItemList
= []
424 self
._CfgPageDict
= {}
425 self
._CfgBlkDict
= {}
426 self
._DscFile
= DscFile
439 DscFd
= open(DscFile
, "r")
440 DscLines
= DscFd
.readlines()
443 MaxAlign
= 32 #Default align to 32, but if there are 64 bit unit, align to 64
444 SizeAlign
= 0 #record the struct max align
446 DscLine
= DscLines
.pop(0).strip()
448 Match
= re
.match("^\[(.+)\]", DscLine
)
449 if Match
is not None:
454 if Match
.group(1).lower() == "Defines".lower():
456 if (Match
.group(1).lower() == "PcdsFeatureFlag".lower() or Match
.group(1).lower() == "PcdsFixedAtBuild".lower()):
458 elif Match
.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
460 ConfigDict
['header'] = 'ON'
461 ConfigDict
['region'] = 'UPD'
462 ConfigDict
['order'] = -1
463 ConfigDict
['page'] = ''
464 ConfigDict
['name'] = ''
465 ConfigDict
['find'] = ''
466 ConfigDict
['struct'] = ''
467 ConfigDict
['embed'] = ''
468 ConfigDict
['comment'] = ''
469 ConfigDict
['subreg'] = []
473 if IsDefSect
or IsPcdSect
or IsUpdSect
or IsVpdSect
:
474 if re
.match("^!else($|\s+#.+)", DscLine
):
476 IfStack
[-1] = not IfStack
[-1]
478 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine
)
480 elif re
.match("^!endif($|\s+#.+)", DscLine
):
483 Level
= ElifStack
.pop()
487 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine
)
491 Match
= re
.match("!(ifdef|ifndef)\s+(.+)", DscLine
)
493 Result
= self
.EvaulateIfdef (Match
.group(2))
494 if Match
.group(1) == 'ifndef':
496 IfStack
.append(Result
)
499 Match
= re
.match("!(if|elseif)\s+(.+)", DscLine
.split("#")[0])
501 Result
= self
.EvaluateExpress(Match
.group(2))
502 if Match
.group(1) == "if":
504 IfStack
.append(Result
)
507 IfStack
[-1] = not IfStack
[-1]
508 IfStack
.append(Result
)
509 ElifStack
[-1] = ElifStack
[-1] + 1
511 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine
)
515 Handle
= reduce(lambda x
,y
: x
and y
, IfStack
)
519 Match
= re
.match("!include\s+(.+)", DscLine
)
521 IncludeFilePath
= Match
.group(1)
522 IncludeFilePath
= self
.ExpandMacros(IncludeFilePath
)
523 PackagesPath
= os
.getenv("PACKAGES_PATH")
525 for PackagePath
in PackagesPath
.split(os
.pathsep
):
526 IncludeFilePathAbs
= os
.path
.join(os
.path
.normpath(PackagePath
), os
.path
.normpath(IncludeFilePath
))
527 if os
.path
.exists(IncludeFilePathAbs
):
528 IncludeDsc
= open(IncludeFilePathAbs
, "r")
531 IncludeDsc
= open(IncludeFilePath
, "r")
532 if IncludeDsc
== None:
533 print("ERROR: Cannot open file '%s'" % IncludeFilePath
)
535 NewDscLines
= IncludeDsc
.readlines()
537 DscLines
= NewDscLines
+ DscLines
540 if DscLine
.startswith('!'):
541 print("ERROR: Unrecoginized directive for line '%s'" % DscLine
)
547 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
548 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
549 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
550 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
551 Match
= re
.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine
)
553 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
555 print "INFO : DEFINE %s = [ %s ]" % (Match
.group(1), Match
.group(2))
557 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
558 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
559 Match
= re
.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine
)
561 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
563 print "INFO : PCD %s = [ %s ]" % (Match
.group(1), Match
.group(2))
565 Match
= re
.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine
)
567 Remaining
= Match
.group(2)
568 if Match
.group(1) == '!BSF' or Match
.group(1) == '@Bsf':
569 Match
= re
.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining
)
571 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
572 PageList
= Match
.group(1).split(',')
573 for Page
in PageList
:
575 Match
= re
.match("(\w+):\"(.+)\"", Page
)
576 self
._CfgPageDict
[Match
.group(1)] = Match
.group(2)
578 Match
= re
.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining
)
580 self
._CfgBlkDict
['name'] = Match
.group(1)
581 self
._CfgBlkDict
['ver'] = Match
.group(2)
583 for Key
in self
._BsfKeyList
:
584 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
586 if Key
in ['NAME', 'HELP', 'OPTION'] and Match
.group(1).startswith('+'):
587 ConfigDict
[Key
.lower()] += Match
.group(1)[1:]
589 ConfigDict
[Key
.lower()] = Match
.group(1)
591 for Key
in self
._HdrKeyList
:
592 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
594 ConfigDict
[Key
.lower()] = Match
.group(1)
596 Match
= re
.match("^\s*#\s+@Prompt\s+(.+)", DscLine
)
598 ConfigDict
['name'] = Match
.group(1)
600 Match
= re
.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine
)
602 if Match
.group(2).strip() in self
._BuidinOption
:
603 ConfigDict
['option'] = Match
.group(2).strip()
605 OptionValueList
= Match
.group(2).split(',')
606 OptionStringList
= Match
.group(3).split(',')
608 for Option
in OptionValueList
:
609 Option
= Option
.strip()
610 ConfigDict
['option'] = ConfigDict
['option'] + str(Option
) + ':' + OptionStringList
[Index
].strip()
612 if Index
in range(len(OptionValueList
)):
613 ConfigDict
['option'] += ', '
614 ConfigDict
['type'] = "Combo"
616 Match
= re
.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine
)
618 if "0x" in Match
.group(2) or "0x" in Match
.group(3):
619 ConfigDict
['type'] = "EditNum, HEX, (%s,%s)" % (Match
.group(2), Match
.group(3))
621 ConfigDict
['type'] = "EditNum, DEC, (%s,%s)" % (Match
.group(2), Match
.group(3))
623 Match
= re
.match("^\s*##\s+(.+)", DscLine
)
625 ConfigDict
['help'] = Match
.group(1)
629 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
)
631 Match
= re
.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine
)
633 ConfigDict
['space'] = Match
.group(1)
634 ConfigDict
['cname'] = Match
.group(2)
635 if Match
.group(3) != '*':
637 Offset
= int (Match
.group(3), 16)
641 if Hardcode
and AutoAlign
:
642 print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")
644 ConfigDict
['offset'] = Offset
645 if ConfigDict
['order'] == -1:
646 ConfigDict
['order'] = ConfigDict
['offset'] << 8
648 (Major
, Minor
) = ConfigDict
['order'].split('.')
649 ConfigDict
['order'] = (int (Major
, 16) << 8 ) + int (Minor
, 16)
651 Value
= Match
.group(5).strip()
652 if Match
.group(4).startswith("0x"):
653 Length
= int (Match
.group(4), 16)
655 Length
= int (Match
.group(4))
658 Value
= Match
.group(4)
661 Value
= Value
.strip()
663 Match
= re
.match("^.+\s*\|\s*(.+)", Value
)
665 Value
= Match
.group(1)
668 ConfigDict
['length'] = Length
669 Match
= re
.match("\$\((\w+)\)", Value
)
671 if Match
.group(1) in self
._MacroDict
:
672 Value
= self
._MacroDict
[Match
.group(1)]
674 ConfigDict
['value'] = Value
675 if (len(Value
) > 0) and (Value
[0] == '{'):
676 Value
= self
.FormatListValue(ConfigDict
)
678 if ConfigDict
['name'] == '':
679 # Clear BSF specific items
680 ConfigDict
['bsfname'] = ''
681 ConfigDict
['help'] = ''
682 ConfigDict
['type'] = ''
683 ConfigDict
['option'] = ''
684 if IsUpdSect
and AutoAlign
:
685 ItemLength
= int(ConfigDict
['length'])
686 ItemOffset
= int(ConfigDict
['offset'])
687 ItemStruct
= ConfigDict
['struct']
689 if ItemLength
in [1, 2, 4, 8] and not ConfigDict
['value'].startswith('{'):
691 # If there are 64 bit unit, align to 64
696 UnitDict
= {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}
697 if ItemStruct
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
698 Unit
= UnitDict
[ItemStruct
]
699 # If there are 64 bit unit, align to 64
702 SizeAlign
= max(SizeAlign
, Unit
)
703 if (ConfigDict
['embed'].find(':START') != -1):
705 SubOffset
= ItemOffset
- Base
706 SubRemainder
= SubOffset
% Unit
708 Diff
= Unit
- SubRemainder
709 Offset
= Offset
+ Diff
710 ItemOffset
= ItemOffset
+ Diff
712 if (ConfigDict
['embed'].find(':END') != -1):
713 Remainder
= Offset
% (MaxAlign
/8) # MaxAlign is either 32 or 64
715 Diff
= (MaxAlign
/8) - Remainder
716 Offset
= Offset
+ Diff
717 ItemOffset
= ItemOffset
+ Diff
718 MaxAlign
= 32 # Reset to default 32 align when struct end
719 if (ConfigDict
['cname'] == 'UpdTerminator'):
720 # ItemLength is the size of UpdTerminator
721 # Itemlength might be 16, 32, or 64
722 # Struct align to 64 if UpdTerminator
723 # or struct size is 64 bit, else align to 32
724 Remainder
= Offset
% max(ItemLength
/8, 4, SizeAlign
)
725 Offset
= Offset
+ ItemLength
727 Diff
= max(ItemLength
/8, 4, SizeAlign
) - Remainder
728 ItemOffset
= ItemOffset
+ Diff
729 ConfigDict
['offset'] = ItemOffset
731 self
._CfgItemList
.append(ConfigDict
.copy())
732 ConfigDict
['name'] = ''
733 ConfigDict
['find'] = ''
734 ConfigDict
['struct'] = ''
735 ConfigDict
['embed'] = ''
736 ConfigDict
['comment'] = ''
737 ConfigDict
['order'] = -1
738 ConfigDict
['subreg'] = []
739 ConfigDict
['option'] = ''
741 # It could be a virtual item as below
742 # !BSF FIELD:{SerialDebugPortAddress0:1}
744 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
745 Match
= re
.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine
)
747 SubCfgDict
= ConfigDict
.copy()
748 if (Match
.group(4) == None) or (Match
.group(4) == 'B'):
750 elif Match
.group(4) == 'b':
753 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine
)
755 SubCfgDict
['cname'] = Match
.group(2)
756 SubCfgDict
['bitlength'] = int (Match
.group(3)) * UnitBitLen
757 if SubCfgDict
['bitlength'] > 0:
758 LastItem
= self
._CfgItemList
[-1]
759 if len(LastItem
['subreg']) == 0:
762 SubOffset
= LastItem
['subreg'][-1]['bitoffset'] + LastItem
['subreg'][-1]['bitlength']
763 SubCfgDict
['bitoffset'] = SubOffset
764 LastItem
['subreg'].append (SubCfgDict
.copy())
765 ConfigDict
['name'] = ''
768 def GetBsfBitFields (self
, subitem
, bytes
):
769 start
= subitem
['bitoffset']
770 end
= start
+ subitem
['bitlength']
771 bitsvalue
= ''.join('{0:08b}'.format(i
) for i
in bytes
[::-1])
772 bitsvalue
= bitsvalue
[::-1]
773 bitslen
= len(bitsvalue
)
774 if start
> bitslen
or end
> bitslen
:
775 print "Invalid bits offset [%d,%d] for %s" % (start
, end
, subitem
['name'])
777 return hex(int(bitsvalue
[start
:end
][::-1], 2))
779 def UpdateSubRegionDefaultValue (self
):
781 for Item
in self
._CfgItemList
:
782 if len(Item
['subreg']) == 0:
785 if Item
['value'][0] == '{':
786 binlist
= Item
['value'][1:-1].split(',')
789 if each
.startswith('0x'):
790 value
= int(each
, 16)
793 bytearray
.append(value
)
795 if Item
['value'].startswith('0x'):
796 value
= int(Item
['value'], 16)
798 value
= int(Item
['value'])
800 while idx
< Item
['length']:
801 bytearray
.append(value
& 0xFF)
804 for SubItem
in Item
['subreg']:
805 valuestr
= self
.GetBsfBitFields(SubItem
, bytearray
)
806 SubItem
['value'] = valuestr
809 def CreateSplitUpdTxt (self
, UpdTxtFile
):
810 GuidList
= ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
811 SignatureList
= ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
812 for Index
in range(len(GuidList
)):
815 if GuidList
[Index
] not in self
._MacroDict
:
816 self
.Error
= "%s definition is missing in DSC file" % (GuidList
[Index
])
820 UpdTxtFile
= os
.path
.join(FvDir
, self
._MacroDict
[GuidList
[Index
]] + '.txt')
823 if not os
.path
.exists(UpdTxtFile
):
826 DscTime
= os
.path
.getmtime(self
._DscFile
)
827 TxtTime
= os
.path
.getmtime(UpdTxtFile
)
828 if DscTime
> TxtTime
:
832 # DSC has not been modified yet
833 # So don't have to re-generate other files
834 self
.Error
= 'No DSC file change, skip to create UPD TXT file'
837 TxtFd
= open(UpdTxtFile
, "w")
838 TxtFd
.write("%s\n" % (__copyright_txt__
% date
.today().year
))
846 for Item
in self
._CfgItemList
:
847 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
848 StartAddr
= Item
['offset']
849 NextOffset
= StartAddr
851 if Item
['cname'] == 'UpdTerminator' and InRange
== True:
852 EndAddr
= Item
['offset']
855 for Item
in self
._CfgItemList
:
856 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
860 if Item
['cname'] == 'UpdTerminator':
862 if Item
['region'] != 'UPD':
864 Offset
= Item
['offset']
865 if StartAddr
> Offset
or EndAddr
< Offset
:
867 if NextOffset
< Offset
:
869 TxtFd
.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item
['space'], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
870 SpaceIdx
= SpaceIdx
+ 1
871 NextOffset
= Offset
+ Item
['length']
872 TxtFd
.write("%s.%s|%s0x%04X|%s|%s\n" % (Item
['space'],Item
['cname'],Default
,Item
['offset'] - StartAddr
,Item
['length'],Item
['value']))
876 def ProcessMultilines (self
, String
, MaxCharLength
):
878 StringLength
= len(String
)
879 CurrentStringStart
= 0
882 if len(String
) <= MaxCharLength
:
883 while (StringOffset
< StringLength
):
884 if StringOffset
>= 1:
885 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
886 BreakLineDict
.append (StringOffset
+ 1)
888 if BreakLineDict
!= []:
889 for Each
in BreakLineDict
:
890 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
891 CurrentStringStart
= Each
892 if StringLength
- CurrentStringStart
> 0:
893 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
895 Multilines
= " %s\n" % String
899 FoundSpaceChar
= False
900 while (StringOffset
< StringLength
):
901 if StringOffset
>= 1:
902 if NewLineCount
>= MaxCharLength
- 1:
903 if String
[StringOffset
] == ' ' and StringLength
- StringOffset
> 10:
904 BreakLineDict
.append (NewLineStart
+ NewLineCount
)
905 NewLineStart
= NewLineStart
+ NewLineCount
907 FoundSpaceChar
= True
908 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False:
909 BreakLineDict
.append (0)
910 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
911 BreakLineDict
.append (StringOffset
+ 1)
912 NewLineStart
= StringOffset
+ 1
916 if BreakLineDict
!= []:
917 BreakLineDict
.sort ()
918 for Each
in BreakLineDict
:
920 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
921 CurrentStringStart
= Each
922 if StringLength
- CurrentStringStart
> 0:
923 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
926 def CreateField (self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
):
934 if Length
in [1,2,4,8]:
935 Type
= "UINT%d" % (Length
* 8)
936 if Name
.startswith("UnusedUpdSpace") and Length
!= 1:
943 if Item
and Item
['value'].startswith('{'):
949 if Struct
in ['UINT8','UINT16','UINT32','UINT64']:
951 Unit
= int(Type
[4:]) / 8
952 Length
= Length
/ Unit
957 Name
= Name
+ '[%d]' % Length
959 if len(Type
) < PosName
:
960 Space1
= PosName
- len(Type
)
965 NameLine
=" - %s\n" % BsfName
970 HelpLine
= self
.ProcessMultilines (Help
, 80)
973 OptionLine
= self
.ProcessMultilines (Option
, 80)
978 OffsetStr
= '0x%04X' % Offset
980 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
,)
982 def PostProcessBody (self
, TextBody
):
988 IsUpdHdrDefined
= False
990 for Line
in TextBody
:
991 SplitToLines
= Line
.splitlines()
992 MatchComment
= re
.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines
[0])
994 if MatchComment
.group(1) == 'FSP_UPD_HEADER':
998 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
999 CommentLine
= " " + MatchComment
.group(2) + "\n"
1000 NewTextBody
.append("/**" + CommentLine
+ "**/\n")
1001 Line
= Line
[(len(SplitToLines
[0]) + 1):]
1003 Match
= re
.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line
)
1005 Line
= Match
.group(4)
1006 if Match
.group(1) == 'FSP_UPD_HEADER':
1011 if Match
and Match
.group(3) == 'START':
1012 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1013 NewTextBody
.append ('typedef struct {\n')
1014 StructName
= Match
.group(1)
1015 VariableName
= Match
.group(2)
1016 MatchOffset
= re
.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line
)
1018 Offset
= int(MatchOffset
.group(1), 16)
1023 OldTextBody
.append (self
.CreateField (None, VariableName
, 0, Offset
, StructName
, '', '', ''))
1025 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1026 NewTextBody
.append (Line
)
1028 OldTextBody
.append (Line
)
1030 if Match
and Match
.group(3) == 'END':
1031 if (StructName
!= Match
.group(1)) or (VariableName
!= Match
.group(2)):
1032 print "Unmatched struct name '%s' and '%s' !" % (StructName
, Match
.group(1))
1034 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1035 NewTextBody
.append ('} %s;\n\n' % StructName
)
1036 IsUpdHdrDefined
= True
1038 NewTextBody
.extend(OldTextBody
)
1041 def WriteLinesWithoutTailingSpace (self
, HeaderFd
, Line
):
1042 TxtBody2
= Line
.splitlines(True)
1043 for Line2
in TxtBody2
:
1044 Line2
= Line2
.rstrip()
1046 HeaderFd
.write (Line2
)
1048 def CreateHeaderFile (self
, InputHeaderFile
):
1051 HeaderFileName
= 'FspUpd.h'
1052 HeaderFile
= os
.path
.join(FvDir
, HeaderFileName
)
1054 # Check if header needs to be recreated
1058 for Item
in self
._CfgItemList
:
1059 if str(Item
['cname']) == 'Signature' and Item
['length'] == 8:
1060 Value
= int(Item
['value'], 16)
1063 Chars
.append(chr(Value
& 0xFF))
1065 SignatureStr
= ''.join(Chars
)
1066 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly
1067 if '_T' in SignatureStr
[6:6+2]:
1068 TxtBody
.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1069 elif '_M' in SignatureStr
[6:6+2]:
1070 TxtBody
.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1071 elif '_S' in SignatureStr
[6:6+2]:
1072 TxtBody
.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1073 TxtBody
.append("\n")
1075 for Region
in ['UPD']:
1077 UpdSignature
= ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS
1078 UpdStructure
= ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
1079 for Item
in self
._CfgItemList
:
1080 if Item
["cname"] == 'Signature' and Item
["value"][0:6] in UpdSignature
:
1081 UpdOffsetTable
.append (Item
["offset"])
1083 for UpdIdx
in range(len(UpdOffsetTable
)):
1085 for Item
in self
._CfgItemList
:
1086 if Item
["comment"] != '' and Item
["offset"] >= UpdOffsetTable
[UpdIdx
]:
1087 MatchComment
= re
.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item
["comment"])
1088 if MatchComment
and MatchComment
.group(1) == Region
[0]:
1089 CommentLine
= " " + MatchComment
.group(2) + "\n"
1090 TxtBody
.append("/**" + CommentLine
+ "**/\n")
1091 elif Item
["offset"] >= UpdOffsetTable
[UpdIdx
] and Item
["comment"] == '':
1092 Match
= re
.match("^FSP([\w|\W|\s])_UPD", UpdStructure
[UpdIdx
])
1094 TxtBody
.append("/** Fsp " + Match
.group(1) + " UPD Configuration\n**/\n")
1095 TxtBody
.append("typedef struct {\n")
1105 for Item
in self
._CfgItemList
:
1106 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == UpdSignature
[UpdIdx
] or Region
[0] == 'V':
1110 if Item
['cname'] == 'UpdTerminator':
1113 if Item
['region'] != Region
:
1116 if Item
["offset"] < UpdOffsetTable
[UpdIdx
]:
1119 NextVisible
= LastVisible
1121 if LastVisible
and (Item
['header'] == 'OFF'):
1123 ResvOffset
= Item
['offset']
1124 elif (not LastVisible
) and Item
['header'] == 'ON':
1126 Name
= "Reserved" + Region
[0] + "pdSpace%d" % ResvIdx
1127 ResvIdx
= ResvIdx
+ 1
1128 TxtBody
.append(self
.CreateField (Item
, Name
, Item
["offset"] - ResvOffset
, ResvOffset
, '', '', '', ''))
1130 if Offset
< Item
["offset"]:
1132 Name
= "Unused" + Region
[0] + "pdSpace%d" % SpaceIdx
1133 LineBuffer
.append(self
.CreateField (Item
, Name
, Item
["offset"] - Offset
, Offset
, '', '', '', ''))
1134 SpaceIdx
= SpaceIdx
+ 1
1135 Offset
= Item
["offset"]
1137 LastVisible
= NextVisible
1139 Offset
= Offset
+ Item
["length"]
1141 for Each
in LineBuffer
:
1142 TxtBody
.append (Each
)
1144 Comment
= Item
["comment"]
1145 Embed
= Item
["embed"].upper()
1146 if Embed
.endswith(':START') or Embed
.endswith(':END'):
1147 if not Comment
== '' and Embed
.endswith(':START'):
1148 Marker
= '/* COMMENT:%s */ \n' % Item
["comment"]
1149 Marker
= Marker
+ '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1151 Marker
= '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1156 self
.Error
= "Invalid embedded structure format '%s'!\n" % Item
["embed"]
1158 Line
= Marker
+ self
.CreateField (Item
, Item
["cname"], Item
["length"], Item
["offset"], Item
['struct'], Item
['name'], Item
['help'], Item
['option'])
1159 TxtBody
.append(Line
)
1160 if Item
['cname'] == 'UpdTerminator':
1162 TxtBody
.append("} " + UpdStructure
[UpdIdx
] + ";\n\n")
1164 # Handle the embedded data structure
1165 TxtBody
= self
.PostProcessBody (TxtBody
)
1167 HeaderTFileName
= 'FsptUpd.h'
1168 HeaderMFileName
= 'FspmUpd.h'
1169 HeaderSFileName
= 'FspsUpd.h'
1171 UpdRegionCheck
= ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
1172 UpdConfigCheck
= ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1173 UpdSignatureCheck
= ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
1174 ExcludedSpecificUpd
= 'FSPM_ARCH_UPD'
1176 if InputHeaderFile
!= '':
1177 if not os
.path
.exists(InputHeaderFile
):
1178 self
.Error
= "Input header file '%s' does not exist" % InputHeaderFile
1181 InFd
= open(InputHeaderFile
, "r")
1182 IncLines
= InFd
.readlines()
1185 for item
in range(len(UpdRegionCheck
)):
1186 if UpdRegionCheck
[item
] == 'FSPT':
1187 HeaderFd
= open(os
.path
.join(FvDir
, HeaderTFileName
), "w")
1188 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderTFileName
))
1189 elif UpdRegionCheck
[item
] == 'FSPM':
1190 HeaderFd
= open(os
.path
.join(FvDir
, HeaderMFileName
), "w")
1191 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderMFileName
))
1192 elif UpdRegionCheck
[item
] == 'FSPS':
1193 HeaderFd
= open(os
.path
.join(FvDir
, HeaderSFileName
), "w")
1194 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderSFileName
))
1195 FileName
= FileBase
.replace(".", "_").upper()
1196 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1197 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1198 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1199 HeaderFd
.write("#include <%s>\n\n" % HeaderFileName
)
1200 HeaderFd
.write("#pragma pack(1)\n\n")
1203 for Line
in IncLines
:
1204 Match
= re
.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line
)
1206 if Match
.group(2) == "BEGIN" and Match
.group(1) == UpdRegionCheck
[item
]:
1213 HeaderFd
.write(Line
)
1214 HeaderFd
.write("\n")
1220 StructStartWithComment
= []
1222 for Line
in TxtBody
:
1224 Match
= re
.match("(typedef struct {)", Line
)
1226 StartIndex
= Index
- 1
1227 Match
= re
.match("}\s([_A-Z0-9]+);", Line
)
1228 if Match
and (UpdRegionCheck
[item
] in Match
.group(1) or UpdConfigCheck
[item
] in Match
.group(1)) and (ExcludedSpecificUpd
not in Match
.group(1)):
1230 StructStart
.append(StartIndex
)
1231 StructEnd
.append(EndIndex
)
1233 for Line
in TxtBody
:
1235 for Item
in range(len(StructStart
)):
1236 if Index
== StructStart
[Item
]:
1237 Match
= re
.match("^(/\*\*\s*)", Line
)
1239 StructStartWithComment
.append(StructStart
[Item
])
1241 StructStartWithComment
.append(StructStart
[Item
] + 1)
1243 for Line
in TxtBody
:
1245 for Item
in range(len(StructStart
)):
1246 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1247 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1248 HeaderFd
.write("#pragma pack()\n\n")
1249 HeaderFd
.write("#endif\n")
1252 HeaderFd
= open(HeaderFile
, "w")
1253 FileBase
= os
.path
.basename(HeaderFile
)
1254 FileName
= FileBase
.replace(".", "_").upper()
1255 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1256 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1257 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1258 HeaderFd
.write("#include <FspEas.h>\n\n")
1259 HeaderFd
.write("#pragma pack(1)\n\n")
1261 for item
in range(len(UpdRegionCheck
)):
1266 StructStartWithComment
= []
1268 for Line
in TxtBody
:
1270 Match
= re
.match("(typedef struct {)", Line
)
1272 StartIndex
= Index
- 1
1273 Match
= re
.match("#define\s([_A-Z0-9]+)\s*", Line
)
1274 if Match
and (UpdSignatureCheck
[item
] in Match
.group(1) or UpdSignatureCheck
[item
] in Match
.group(1)):
1275 StructStart
.append(Index
- 1)
1276 StructEnd
.append(Index
)
1278 for Line
in TxtBody
:
1280 for Item
in range(len(StructStart
)):
1281 if Index
== StructStart
[Item
]:
1282 Match
= re
.match("^(/\*\*\s*)", Line
)
1284 StructStartWithComment
.append(StructStart
[Item
])
1286 StructStartWithComment
.append(StructStart
[Item
] + 1)
1288 for Line
in TxtBody
:
1290 for Item
in range(len(StructStart
)):
1291 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1292 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1293 HeaderFd
.write("#pragma pack()\n\n")
1294 HeaderFd
.write("#endif\n")
1299 def WriteBsfStruct (self
, BsfFd
, Item
):
1300 LogExpr
= CLogicalExpression()
1301 if Item
['type'] == "None":
1302 Space
= "gPlatformFspPkgTokenSpaceGuid"
1304 Space
= Item
['space']
1305 Line
= " $%s_%s" % (Space
, Item
['cname'])
1306 Match
= re
.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item
['value'])
1308 DefaultValue
= Match
.group(1).strip()
1310 DefaultValue
= Item
['value'].strip()
1311 if 'bitlength' in Item
:
1312 BsfFd
.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['bitlength'], DefaultValue
))
1314 BsfFd
.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['length'], DefaultValue
))
1316 if Item
['type'] == "Combo":
1317 if not Item
['option'] in self
._BuidinOption
:
1318 OptList
= Item
['option'].split(',')
1319 for Option
in OptList
:
1320 Option
= Option
.strip()
1321 (OpVal
, OpStr
) = Option
.split(':')
1322 test
= LogExpr
.getNumber (OpVal
)
1324 raise Exception("Selection Index '%s' is not a number" % OpVal
)
1325 TmpList
.append((OpVal
, OpStr
))
1328 def WriteBsfOption (self
, BsfFd
, Item
):
1329 PcdName
= Item
['space'] + '_' + Item
['cname']
1331 if Item
['type'] == "Combo":
1332 if Item
['option'] in self
._BuidinOption
:
1333 Options
= self
._BuidinOption
[Item
['option']]
1336 BsfFd
.write(' %s $%s, "%s", &%s,\n' % (Item
['type'], PcdName
, Item
['name'], Options
))
1338 elif Item
['type'].startswith("EditNum"):
1339 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'])
1341 BsfFd
.write(' EditNum $%s, "%s", %s,\n' % (PcdName
, Item
['name'], Match
.group(1)))
1343 elif Item
['type'].startswith("EditText"):
1344 BsfFd
.write(' %s $%s, "%s",\n' % (Item
['type'], PcdName
, Item
['name']))
1346 elif Item
['type'] == "Table":
1347 Columns
= Item
['option'].split(',')
1348 if len(Columns
) != 0:
1349 BsfFd
.write(' %s $%s "%s",' % (Item
['type'], PcdName
, Item
['name']))
1351 Fmt
= Col
.split(':')
1353 raise Exception("Column format '%s' is invalid !" % Fmt
)
1355 Dtype
= int(Fmt
[1].strip())
1357 raise Exception("Column size '%s' is invalid !" % Fmt
[1])
1358 BsfFd
.write('\n Column "%s", %d bytes, %s' % (Fmt
[0].strip(), Dtype
, Fmt
[2].strip()))
1363 HelpLines
= Item
['help'].split('\\n\\r')
1365 for HelpLine
in HelpLines
:
1368 BsfFd
.write(' Help "%s"\n' % (HelpLine
))
1370 BsfFd
.write(' "%s"\n' % (HelpLine
))
1372 BsfFd
.write(' "Valid range: %s ~ %s"\n' % (Match
.group(2), Match
.group(3)))
1374 def GenerateBsfFile (self
, BsfFile
):
1377 self
.Error
= "BSF output file '%s' is invalid" % BsfFile
1382 BsfFd
= open(BsfFile
, "w")
1383 BsfFd
.write("%s\n" % (__copyright_bsf__
% date
.today().year
))
1384 BsfFd
.write("%s\n" % self
._GlobalDataDef
)
1385 BsfFd
.write("StructDef\n")
1387 for Item
in self
._CfgItemList
:
1388 if Item
['find'] != '':
1389 BsfFd
.write('\n Find "%s"\n' % Item
['find'])
1390 NextOffset
= Item
['offset'] + Item
['length']
1391 if Item
['name'] != '':
1392 if NextOffset
!= Item
['offset']:
1393 BsfFd
.write(" Skip %d bytes\n" % (Item
['offset'] - NextOffset
))
1394 if len(Item
['subreg']) > 0:
1395 NextOffset
= Item
['offset']
1396 BitsOffset
= NextOffset
* 8
1397 for SubItem
in Item
['subreg']:
1398 BitsOffset
+= SubItem
['bitlength']
1399 if SubItem
['name'] == '':
1400 if 'bitlength' in SubItem
:
1401 BsfFd
.write(" Skip %d bits\n" % (SubItem
['bitlength']))
1403 BsfFd
.write(" Skip %d bytes\n" % (SubItem
['length']))
1405 Options
= self
.WriteBsfStruct(BsfFd
, SubItem
)
1406 if len(Options
) > 0:
1407 OptionDict
[SubItem
['space']+'_'+SubItem
['cname']] = Options
1409 NextBitsOffset
= (Item
['offset'] + Item
['length']) * 8
1410 if NextBitsOffset
> BitsOffset
:
1411 BitsGap
= NextBitsOffset
- BitsOffset
1412 BitsRemain
= BitsGap
% 8
1414 BsfFd
.write(" Skip %d bits\n" % BitsRemain
)
1415 BitsGap
-= BitsRemain
1416 BytesRemain
= BitsGap
/ 8
1418 BsfFd
.write(" Skip %d bytes\n" % BytesRemain
)
1419 NextOffset
= Item
['offset'] + Item
['length']
1421 NextOffset
= Item
['offset'] + Item
['length']
1422 Options
= self
.WriteBsfStruct(BsfFd
, Item
)
1423 if len(Options
) > 0:
1424 OptionDict
[Item
['space']+'_'+Item
['cname']] = Options
1425 BsfFd
.write("\nEndStruct\n\n")
1427 BsfFd
.write("%s" % self
._BuidinOptionTxt
)
1429 for Each
in OptionDict
:
1430 BsfFd
.write("List &%s\n" % Each
)
1431 for Item
in OptionDict
[Each
]:
1432 BsfFd
.write(' Selection %s , "%s"\n' % (Item
[0], Item
[1]))
1433 BsfFd
.write("EndList\n\n")
1435 BsfFd
.write("BeginInfoBlock\n")
1436 BsfFd
.write(' PPVer "%s"\n' % (self
._CfgBlkDict
['ver']))
1437 BsfFd
.write(' Description "%s"\n' % (self
._CfgBlkDict
['name']))
1438 BsfFd
.write("EndInfoBlock\n\n")
1440 for Each
in self
._CfgPageDict
:
1441 BsfFd
.write('Page "%s"\n' % self
._CfgPageDict
[Each
])
1443 for Item
in self
._CfgItemList
:
1444 if Item
['name'] != '':
1445 if Item
['page'] != Each
:
1447 if len(Item
['subreg']) > 0:
1448 for SubItem
in Item
['subreg']:
1449 if SubItem
['name'] != '':
1450 BsfItems
.append(SubItem
)
1452 BsfItems
.append(Item
)
1454 BsfItems
.sort(key
=lambda x
: x
['order'])
1456 for Item
in BsfItems
:
1457 self
.WriteBsfOption (BsfFd
, Item
)
1458 BsfFd
.write("EndPage\n\n")
1465 print "GenCfgOpt Version 0.52"
1467 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
1468 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
1469 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1473 # Parse the options and args
1475 GenCfgOpt
= CGenCfgOpt()
1476 argc
= len(sys
.argv
)
1481 DscFile
= sys
.argv
[2]
1482 if not os
.path
.exists(DscFile
):
1483 print "ERROR: Cannot open DSC file '%s' !" % DscFile
1488 if sys
.argv
[4][0] == '-':
1491 OutFile
= sys
.argv
[4]
1494 if GenCfgOpt
.ParseMacros(sys
.argv
[Start
:]) != 0:
1495 print "ERROR: Macro parsing failed !"
1499 if not os
.path
.exists(FvDir
):
1502 if GenCfgOpt
.ParseDscFile(DscFile
, FvDir
) != 0:
1503 print "ERROR: %s !" % GenCfgOpt
.Error
1506 if GenCfgOpt
.UpdateSubRegionDefaultValue() != 0:
1507 print "ERROR: %s !" % GenCfgOpt
.Error
1510 if sys
.argv
[1] == "UPDTXT":
1511 Ret
= GenCfgOpt
.CreateSplitUpdTxt(OutFile
)
1513 # No change is detected
1515 print "INFO: %s !" % (GenCfgOpt
.Error
)
1517 print "ERROR: %s !" % (GenCfgOpt
.Error
)
1519 elif sys
.argv
[1] == "HEADER":
1520 if GenCfgOpt
.CreateHeaderFile(OutFile
) != 0:
1521 print "ERROR: %s !" % GenCfgOpt
.Error
1523 elif sys
.argv
[1] == "GENBSF":
1524 if GenCfgOpt
.GenerateBsfFile(OutFile
) != 0:
1525 print "ERROR: %s !" % GenCfgOpt
.Error
1531 print "ERROR: Unknown command '%s' !" % sys
.argv
[1]
1538 if __name__
== '__main__':