]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/GenCfgOpt.py
3 # Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
4 # SPDX-License-Identifier: BSD-2-Clause-Patent
12 from datetime
import date
13 from functools
import reduce
15 # Generated file copyright header
17 __copyright_txt__
= """## @file
19 # THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.
21 # This file lists all VPD informations for a platform collected by build.exe.
23 # Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
24 # This program and the accompanying materials
25 # are licensed and made available under the terms and conditions of the BSD License
26 # which accompanies this distribution. The full text of the license may be found at
27 # http://opensource.org/licenses/bsd-license.php
29 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
30 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
34 __copyright_bsf__
= """/** @file
36 Boot Setting File for Platform Configuration.
38 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
39 This program and the accompanying materials
40 are licensed and made available under the terms and conditions of the BSD License
41 which accompanies this distribution. The full text of the license may be found at
42 http://opensource.org/licenses/bsd-license.php
44 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
45 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
47 This file is automatically generated. Please do NOT modify !!!
53 __copyright_h__
= """/** @file
55 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
57 Redistribution and use in source and binary forms, with or without modification,
58 are permitted provided that the following conditions are met:
60 * Redistributions of source code must retain the above copyright notice, this
61 list of conditions and the following disclaimer.
62 * Redistributions in binary form must reproduce the above copyright notice, this
63 list of conditions and the following disclaimer in the documentation and/or
64 other materials provided with the distribution.
65 * Neither the name of Intel Corporation nor the names of its contributors may
66 be used to endorse or promote products derived from this software without
67 specific prior written permission.
69 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
70 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
72 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
73 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
74 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
75 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
77 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
78 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
79 THE POSSIBILITY OF SUCH DAMAGE.
81 This file is automatically generated. Please do NOT modify !!!
88 class CLogicalExpression
:
93 def errExit(self
, err
= ''):
94 print ("ERROR: Express parsing for:")
95 print (" %s" % self
.string
)
96 print (" %s^" % (' ' * self
.index
))
98 print ("INFO : %s" % err
)
101 def getNonNumber (self
, n1
, n2
):
108 def getCurr(self
, lens
= 1):
111 return self
.string
[self
.index
:]
113 if self
.index
+ lens
> len(self
.string
):
114 lens
= len(self
.string
) - self
.index
115 return self
.string
[self
.index
: self
.index
+ lens
]
120 return self
.index
== len(self
.string
)
122 def moveNext(self
, len = 1):
126 while not self
.isLast():
127 if self
.getCurr() in ' \t':
132 def normNumber (self
, val
):
133 return True if val
else False
135 def getNumber(self
, var
):
137 if re
.match('^0x[a-fA-F0-9]+$', var
):
139 elif re
.match('^[+-]?\d+$', var
):
145 def parseValue(self
):
148 while not self
.isLast():
149 char
= self
.getCurr()
150 if re
.match('^[\w.]', char
):
155 val
= self
.getNumber(var
)
162 def parseSingleOp(self
):
164 if re
.match('^NOT\W', self
.getCurr(-1)):
166 op
= self
.parseBrace()
167 val
= self
.getNumber (op
)
169 self
.errExit ("'%s' is not a number" % op
)
170 return "%d" % (not self
.normNumber(int(op
)))
172 return self
.parseValue()
174 def parseBrace(self
):
176 char
= self
.getCurr()
179 value
= self
.parseExpr()
181 if self
.getCurr() != ')':
182 self
.errExit ("Expecting closing brace or operator")
186 value
= self
.parseSingleOp()
189 def parseCompare(self
):
190 value
= self
.parseBrace()
193 char
= self
.getCurr()
194 if char
in ['<', '>']:
196 next
= self
.getCurr()
202 result
= self
.parseBrace()
203 test
= self
.getNonNumber(result
, value
)
205 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
207 self
.errExit ("'%s' is not a valid number for comparision" % test
)
208 elif char
in ['=', '!']:
210 if op
in ['==', '!=']:
212 result
= self
.parseBrace()
213 test
= self
.getNonNumber(result
, value
)
215 value
= "%d" % self
.normNumber((eval (value
+ op
+ result
)))
217 value
= "%d" % self
.normNumber(eval ("'" + value
+ "'" + op
+ "'" + result
+ "'"))
225 value
= self
.parseCompare()
228 if re
.match('^AND\W', self
.getCurr(-1)):
230 result
= self
.parseCompare()
231 test
= self
.getNonNumber(result
, value
)
233 value
= "%d" % self
.normNumber(int(value
) & int(result
))
235 self
.errExit ("'%s' is not a valid op number for AND" % test
)
240 def parseOrXor(self
):
241 value
= self
.parseAnd()
246 if re
.match('^XOR\W', self
.getCurr(-1)):
249 elif re
.match('^OR\W', self
.getCurr(-1)):
255 result
= self
.parseAnd()
256 test
= self
.getNonNumber(result
, value
)
258 value
= "%d" % self
.normNumber(eval (value
+ op
+ result
))
260 self
.errExit ("'%s' is not a valid op number for XOR/OR" % test
)
264 return self
.parseOrXor()
267 value
= self
.parseExpr()
269 if not self
.isLast():
270 self
.errExit ("Unexpected character found '%s'" % self
.getCurr())
271 test
= self
.getNumber(value
)
273 self
.errExit ("Result '%s' is not a number" % value
)
276 def evaluateExpress (self
, Expr
):
290 self
._GlobalDataDef
= """
296 self
._BuidinOptionTxt
= """
298 Selection 0x1 , "Enabled"
299 Selection 0x0 , "Disabled"
304 self
._BsfKeyList
= ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
305 self
._HdrKeyList
= ['HEADER','STRUCT', 'EMBED', 'COMMENT']
306 self
._BuidinOption
= {'$EN_DIS' : 'EN_DIS'}
310 self
._CfgBlkDict
= {}
311 self
._CfgPageDict
= {}
312 self
._CfgItemList
= []
317 def ParseMacros (self
, MacroDefStr
):
318 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
321 for Macro
in MacroDefStr
:
322 if Macro
.startswith('-D'):
330 Match
= re
.match("(\w+)=(.+)", Macro
)
332 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
334 Match
= re
.match("(\w+)", Macro
)
336 self
._MacroDict
[Match
.group(1)] = ''
337 if len(self
._MacroDict
) == 0:
342 print ("INFO : Macro dictionary:")
343 for Each
in self
._MacroDict
:
344 print (" $(%s) = [ %s ]" % (Each
, self
._MacroDict
[Each
]))
347 def EvaulateIfdef (self
, Macro
):
348 Result
= Macro
in self
._MacroDict
350 print ("INFO : Eval Ifdef [%s] : %s" % (Macro
, Result
))
353 def ExpandMacros (self
, Input
):
355 Match
= re
.findall("\$\(\w+\)", Input
)
358 Variable
= Each
[2:-1]
359 if Variable
in self
._MacroDict
:
360 Line
= Line
.replace(Each
, self
._MacroDict
[Variable
])
363 print ("WARN : %s is not defined" % Each
)
364 Line
= Line
.replace(Each
, Each
[2:-1])
367 def ExpandPcds (self
, Input
):
369 Match
= re
.findall("(\w+\.\w+)", Input
)
371 for PcdName
in Match
:
372 if PcdName
in self
._PcdsDict
:
373 Line
= Line
.replace(PcdName
, self
._PcdsDict
[PcdName
])
376 print ("WARN : %s is not defined" % PcdName
)
379 def EvaluateExpress (self
, Expr
):
380 ExpExpr
= self
.ExpandPcds(Expr
)
381 ExpExpr
= self
.ExpandMacros(ExpExpr
)
382 LogExpr
= CLogicalExpression()
383 Result
= LogExpr
.evaluateExpress (ExpExpr
)
385 print ("INFO : Eval Express [%s] : %s" % (Expr
, Result
))
388 def FormatListValue(self
, ConfigDict
):
389 Struct
= ConfigDict
['struct']
390 if Struct
not in ['UINT8','UINT16','UINT32','UINT64']:
394 binlist
= ConfigDict
['value'][1:-1].split(',')
397 if each
.startswith('0x'):
398 value
= int(each
, 16)
401 dataarray
.append(value
)
403 unit
= int(Struct
[4:]) / 8
404 if int(ConfigDict
['length']) != unit
* len(dataarray
):
405 raise Exception("Array size is not proper for '%s' !" % ConfigDict
['cname'])
408 for each
in dataarray
:
410 for loop
in range(int(unit
)):
411 bytearray
.append("0x%02X" % (value
& 0xFF))
413 newvalue
= '{' + ','.join(bytearray
) + '}'
414 ConfigDict
['value'] = newvalue
417 def ParseDscFile (self
, DscFile
, FvDir
):
420 self
._CfgItemList
= []
421 self
._CfgPageDict
= {}
422 self
._CfgBlkDict
= {}
423 self
._DscFile
= DscFile
436 DscFd
= open(DscFile
, "r")
437 DscLines
= DscFd
.readlines()
440 MaxAlign
= 32 #Default align to 32, but if there are 64 bit unit, align to 64
441 SizeAlign
= 0 #record the struct max align
443 DscLine
= DscLines
.pop(0).strip()
445 Match
= re
.match("^\[(.+)\]", DscLine
)
446 if Match
is not None:
451 if Match
.group(1).lower() == "Defines".lower():
453 if (Match
.group(1).lower() == "PcdsFeatureFlag".lower() or Match
.group(1).lower() == "PcdsFixedAtBuild".lower()):
455 elif Match
.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
457 ConfigDict
['header'] = 'ON'
458 ConfigDict
['region'] = 'UPD'
459 ConfigDict
['order'] = -1
460 ConfigDict
['page'] = ''
461 ConfigDict
['name'] = ''
462 ConfigDict
['find'] = ''
463 ConfigDict
['struct'] = ''
464 ConfigDict
['embed'] = ''
465 ConfigDict
['comment'] = ''
466 ConfigDict
['subreg'] = []
470 if IsDefSect
or IsPcdSect
or IsUpdSect
or IsVpdSect
:
471 if re
.match("^!else($|\s+#.+)", DscLine
):
473 IfStack
[-1] = not IfStack
[-1]
475 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine
)
477 elif re
.match("^!endif($|\s+#.+)", DscLine
):
480 Level
= ElifStack
.pop()
484 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine
)
488 Match
= re
.match("!(ifdef|ifndef)\s+(.+)", DscLine
)
490 Result
= self
.EvaulateIfdef (Match
.group(2))
491 if Match
.group(1) == 'ifndef':
493 IfStack
.append(Result
)
496 Match
= re
.match("!(if|elseif)\s+(.+)", DscLine
.split("#")[0])
498 Result
= self
.EvaluateExpress(Match
.group(2))
499 if Match
.group(1) == "if":
501 IfStack
.append(Result
)
504 IfStack
[-1] = not IfStack
[-1]
505 IfStack
.append(Result
)
506 ElifStack
[-1] = ElifStack
[-1] + 1
508 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine
)
512 Handle
= reduce(lambda x
,y
: x
and y
, IfStack
)
516 Match
= re
.match("!include\s+(.+)", DscLine
)
518 IncludeFilePath
= Match
.group(1)
519 IncludeFilePath
= self
.ExpandMacros(IncludeFilePath
)
520 PackagesPath
= os
.getenv("PACKAGES_PATH")
522 for PackagePath
in PackagesPath
.split(os
.pathsep
):
523 IncludeFilePathAbs
= os
.path
.join(os
.path
.normpath(PackagePath
), os
.path
.normpath(IncludeFilePath
))
524 if os
.path
.exists(IncludeFilePathAbs
):
525 IncludeDsc
= open(IncludeFilePathAbs
, "r")
528 IncludeDsc
= open(IncludeFilePath
, "r")
529 if IncludeDsc
== None:
530 print("ERROR: Cannot open file '%s'" % IncludeFilePath
)
532 NewDscLines
= IncludeDsc
.readlines()
534 DscLines
= NewDscLines
+ DscLines
537 if DscLine
.startswith('!'):
538 print("ERROR: Unrecoginized directive for line '%s'" % DscLine
)
544 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
545 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
546 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
547 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
548 Match
= re
.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine
)
550 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
552 print ("INFO : DEFINE %s = [ %s ]" % (Match
.group(1), Match
.group(2)))
554 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
555 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
556 Match
= re
.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine
)
558 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
560 print ("INFO : PCD %s = [ %s ]" % (Match
.group(1), Match
.group(2)))
562 while i
< len(BuildOptionPcd
):
563 Match
= re
.match("\s*([\w\.]+)\s*\=\s*(\w+)", BuildOptionPcd
[i
])
565 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
568 Match
= re
.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine
)
570 Remaining
= Match
.group(2)
571 if Match
.group(1) == '!BSF' or Match
.group(1) == '@Bsf':
572 Match
= re
.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining
)
574 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
575 PageList
= Match
.group(1).split(',')
576 for Page
in PageList
:
578 Match
= re
.match("(\w+):\"(.+)\"", Page
)
579 self
._CfgPageDict
[Match
.group(1)] = Match
.group(2)
581 Match
= re
.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining
)
583 self
._CfgBlkDict
['name'] = Match
.group(1)
584 self
._CfgBlkDict
['ver'] = Match
.group(2)
586 for Key
in self
._BsfKeyList
:
587 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
589 if Key
in ['NAME', 'HELP', 'OPTION'] and Match
.group(1).startswith('+'):
590 ConfigDict
[Key
.lower()] += Match
.group(1)[1:]
592 ConfigDict
[Key
.lower()] = Match
.group(1)
594 for Key
in self
._HdrKeyList
:
595 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
597 ConfigDict
[Key
.lower()] = Match
.group(1)
599 Match
= re
.match("^\s*#\s+@Prompt\s+(.+)", DscLine
)
601 ConfigDict
['name'] = Match
.group(1)
603 Match
= re
.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine
)
605 if Match
.group(2).strip() in self
._BuidinOption
:
606 ConfigDict
['option'] = Match
.group(2).strip()
608 OptionValueList
= Match
.group(2).split(',')
609 OptionStringList
= Match
.group(3).split(',')
611 for Option
in OptionValueList
:
612 Option
= Option
.strip()
613 ConfigDict
['option'] = ConfigDict
['option'] + str(Option
) + ':' + OptionStringList
[Index
].strip()
615 if Index
in range(len(OptionValueList
)):
616 ConfigDict
['option'] += ', '
617 ConfigDict
['type'] = "Combo"
619 Match
= re
.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine
)
621 if "0x" in Match
.group(2) or "0x" in Match
.group(3):
622 ConfigDict
['type'] = "EditNum, HEX, (%s,%s)" % (Match
.group(2), Match
.group(3))
624 ConfigDict
['type'] = "EditNum, DEC, (%s,%s)" % (Match
.group(2), Match
.group(3))
626 Match
= re
.match("^\s*##\s+(.+)", DscLine
)
628 ConfigDict
['help'] = Match
.group(1)
632 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
)
634 Match
= re
.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine
)
636 ConfigDict
['space'] = Match
.group(1)
637 ConfigDict
['cname'] = Match
.group(2)
638 if Match
.group(3) != '*':
640 Offset
= int (Match
.group(3), 16)
644 if Hardcode
and AutoAlign
:
645 print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")
647 ConfigDict
['offset'] = Offset
648 if ConfigDict
['order'] == -1:
649 ConfigDict
['order'] = ConfigDict
['offset'] << 8
651 (Major
, Minor
) = ConfigDict
['order'].split('.')
652 ConfigDict
['order'] = (int (Major
, 16) << 8 ) + int (Minor
, 16)
654 Value
= Match
.group(5).strip()
655 if Match
.group(4).startswith("0x"):
656 Length
= int (Match
.group(4), 16)
658 Length
= int (Match
.group(4))
661 Value
= Match
.group(4)
664 Value
= Value
.strip()
666 Match
= re
.match("^.+\s*\|\s*(.+)", Value
)
668 Value
= Match
.group(1)
671 ConfigDict
['length'] = Length
672 Match
= re
.match("\$\((\w+)\)", Value
)
674 if Match
.group(1) in self
._MacroDict
:
675 Value
= self
._MacroDict
[Match
.group(1)]
677 ConfigDict
['value'] = Value
678 if (len(Value
) > 0) and (Value
[0] == '{'):
679 Value
= self
.FormatListValue(ConfigDict
)
681 if ConfigDict
['name'] == '':
682 # Clear BSF specific items
683 ConfigDict
['bsfname'] = ''
684 ConfigDict
['help'] = ''
685 ConfigDict
['type'] = ''
686 ConfigDict
['option'] = ''
687 if IsUpdSect
and AutoAlign
:
688 ItemLength
= int(ConfigDict
['length'])
689 ItemOffset
= int(ConfigDict
['offset'])
690 ItemStruct
= ConfigDict
['struct']
692 if ItemLength
in [1, 2, 4, 8] and not ConfigDict
['value'].startswith('{'):
694 # If there are 64 bit unit, align to 64
699 UnitDict
= {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}
700 if ItemStruct
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
701 Unit
= UnitDict
[ItemStruct
]
702 # If there are 64 bit unit, align to 64
705 SizeAlign
= max(SizeAlign
, Unit
)
706 if (ConfigDict
['embed'].find(':START') != -1):
708 SubOffset
= ItemOffset
- Base
709 SubRemainder
= SubOffset
% Unit
711 Diff
= Unit
- SubRemainder
712 Offset
= Offset
+ Diff
713 ItemOffset
= ItemOffset
+ Diff
715 if (ConfigDict
['embed'].find(':END') != -1):
716 Remainder
= Offset
% (MaxAlign
/8) # MaxAlign is either 32 or 64
718 Diff
= (MaxAlign
/8) - Remainder
719 Offset
= Offset
+ Diff
720 ItemOffset
= ItemOffset
+ Diff
721 MaxAlign
= 32 # Reset to default 32 align when struct end
722 if (ConfigDict
['cname'] == 'UpdTerminator'):
723 # ItemLength is the size of UpdTerminator
724 # Itemlength might be 16, 32, or 64
725 # Struct align to 64 if UpdTerminator
726 # or struct size is 64 bit, else align to 32
727 Remainder
= Offset
% max(ItemLength
/8, 4, SizeAlign
)
728 Offset
= Offset
+ ItemLength
730 Diff
= max(ItemLength
/8, 4, SizeAlign
) - Remainder
731 ItemOffset
= ItemOffset
+ Diff
732 ConfigDict
['offset'] = ItemOffset
734 self
._CfgItemList
.append(ConfigDict
.copy())
735 ConfigDict
['name'] = ''
736 ConfigDict
['find'] = ''
737 ConfigDict
['struct'] = ''
738 ConfigDict
['embed'] = ''
739 ConfigDict
['comment'] = ''
740 ConfigDict
['order'] = -1
741 ConfigDict
['subreg'] = []
742 ConfigDict
['option'] = ''
744 # It could be a virtual item as below
745 # !BSF FIELD:{SerialDebugPortAddress0:1}
747 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
748 Match
= re
.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine
)
750 SubCfgDict
= ConfigDict
.copy()
751 if (Match
.group(4) == None) or (Match
.group(4) == 'B'):
753 elif Match
.group(4) == 'b':
756 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine
)
758 SubCfgDict
['cname'] = Match
.group(2)
759 SubCfgDict
['bitlength'] = int (Match
.group(3)) * UnitBitLen
760 if SubCfgDict
['bitlength'] > 0:
761 LastItem
= self
._CfgItemList
[-1]
762 if len(LastItem
['subreg']) == 0:
765 SubOffset
= LastItem
['subreg'][-1]['bitoffset'] + LastItem
['subreg'][-1]['bitlength']
766 SubCfgDict
['bitoffset'] = SubOffset
767 LastItem
['subreg'].append (SubCfgDict
.copy())
768 ConfigDict
['name'] = ''
771 def GetBsfBitFields (self
, subitem
, bytes
):
772 start
= subitem
['bitoffset']
773 end
= start
+ subitem
['bitlength']
774 bitsvalue
= ''.join('{0:08b}'.format(i
) for i
in bytes
[::-1])
775 bitsvalue
= bitsvalue
[::-1]
776 bitslen
= len(bitsvalue
)
777 if start
> bitslen
or end
> bitslen
:
778 print ("Invalid bits offset [%d,%d] for %s" % (start
, end
, subitem
['name']))
780 return hex(int(bitsvalue
[start
:end
][::-1], 2))
782 def UpdateSubRegionDefaultValue (self
):
784 for Item
in self
._CfgItemList
:
785 if len(Item
['subreg']) == 0:
788 if Item
['value'][0] == '{':
789 binlist
= Item
['value'][1:-1].split(',')
792 if each
.startswith('0x'):
793 value
= int(each
, 16)
796 bytearray
.append(value
)
798 if Item
['value'].startswith('0x'):
799 value
= int(Item
['value'], 16)
801 value
= int(Item
['value'])
803 while idx
< Item
['length']:
804 bytearray
.append(value
& 0xFF)
807 for SubItem
in Item
['subreg']:
808 valuestr
= self
.GetBsfBitFields(SubItem
, bytearray
)
809 SubItem
['value'] = valuestr
812 def CreateSplitUpdTxt (self
, UpdTxtFile
):
813 GuidList
= ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
814 SignatureList
= ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
815 for Index
in range(len(GuidList
)):
818 if GuidList
[Index
] not in self
._MacroDict
:
819 self
.Error
= "%s definition is missing in DSC file" % (GuidList
[Index
])
823 UpdTxtFile
= os
.path
.join(FvDir
, self
._MacroDict
[GuidList
[Index
]] + '.txt')
826 if not os
.path
.exists(UpdTxtFile
):
829 DscTime
= os
.path
.getmtime(self
._DscFile
)
830 TxtTime
= os
.path
.getmtime(UpdTxtFile
)
831 if DscTime
> TxtTime
:
835 # DSC has not been modified yet
836 # So don't have to re-generate other files
837 self
.Error
= 'No DSC file change, skip to create UPD TXT file'
840 TxtFd
= open(UpdTxtFile
, "w")
841 TxtFd
.write("%s\n" % (__copyright_txt__
% date
.today().year
))
849 for Item
in self
._CfgItemList
:
850 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
851 StartAddr
= Item
['offset']
852 NextOffset
= StartAddr
854 if Item
['cname'] == 'UpdTerminator' and InRange
== True:
855 EndAddr
= Item
['offset']
858 for Item
in self
._CfgItemList
:
859 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
863 if Item
['cname'] == 'UpdTerminator':
865 if Item
['region'] != 'UPD':
867 Offset
= Item
['offset']
868 if StartAddr
> Offset
or EndAddr
< Offset
:
870 if NextOffset
< Offset
:
872 TxtFd
.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item
['space'], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
873 SpaceIdx
= SpaceIdx
+ 1
874 NextOffset
= Offset
+ Item
['length']
875 TxtFd
.write("%s.%s|%s0x%04X|%s|%s\n" % (Item
['space'],Item
['cname'],Default
,Item
['offset'] - StartAddr
,Item
['length'],Item
['value']))
879 def ProcessMultilines (self
, String
, MaxCharLength
):
881 StringLength
= len(String
)
882 CurrentStringStart
= 0
885 if len(String
) <= MaxCharLength
:
886 while (StringOffset
< StringLength
):
887 if StringOffset
>= 1:
888 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
889 BreakLineDict
.append (StringOffset
+ 1)
891 if BreakLineDict
!= []:
892 for Each
in BreakLineDict
:
893 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
894 CurrentStringStart
= Each
895 if StringLength
- CurrentStringStart
> 0:
896 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
898 Multilines
= " %s\n" % String
902 FoundSpaceChar
= False
903 while (StringOffset
< StringLength
):
904 if StringOffset
>= 1:
905 if NewLineCount
>= MaxCharLength
- 1:
906 if String
[StringOffset
] == ' ' and StringLength
- StringOffset
> 10:
907 BreakLineDict
.append (NewLineStart
+ NewLineCount
)
908 NewLineStart
= NewLineStart
+ NewLineCount
910 FoundSpaceChar
= True
911 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False:
912 BreakLineDict
.append (0)
913 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
914 BreakLineDict
.append (StringOffset
+ 1)
915 NewLineStart
= StringOffset
+ 1
919 if BreakLineDict
!= []:
920 BreakLineDict
.sort ()
921 for Each
in BreakLineDict
:
923 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
924 CurrentStringStart
= Each
925 if StringLength
- CurrentStringStart
> 0:
926 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
929 def CreateField (self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
):
937 if Length
in [1,2,4,8]:
938 Type
= "UINT%d" % (Length
* 8)
939 if Name
.startswith("UnusedUpdSpace") and Length
!= 1:
946 if Item
and Item
['value'].startswith('{'):
952 if Struct
in ['UINT8','UINT16','UINT32','UINT64']:
954 Unit
= int(Type
[4:]) / 8
955 Length
= Length
/ Unit
960 Name
= Name
+ '[%d]' % Length
962 if len(Type
) < PosName
:
963 Space1
= PosName
- len(Type
)
968 NameLine
=" - %s\n" % BsfName
973 HelpLine
= self
.ProcessMultilines (Help
, 80)
976 OptionLine
= self
.ProcessMultilines (Option
, 80)
981 OffsetStr
= '0x%04X' % Offset
983 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
,)
985 def PostProcessBody (self
, TextBody
):
991 IsUpdHdrDefined
= False
993 for Line
in TextBody
:
994 SplitToLines
= Line
.splitlines()
995 MatchComment
= re
.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines
[0])
997 if MatchComment
.group(1) == 'FSP_UPD_HEADER':
1001 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1002 CommentLine
= " " + MatchComment
.group(2) + "\n"
1003 NewTextBody
.append("/**" + CommentLine
+ "**/\n")
1004 Line
= Line
[(len(SplitToLines
[0]) + 1):]
1006 Match
= re
.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line
)
1008 Line
= Match
.group(4)
1009 if Match
.group(1) == 'FSP_UPD_HEADER':
1014 if Match
and Match
.group(3) == 'START':
1015 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1016 NewTextBody
.append ('typedef struct {\n')
1017 StructName
= Match
.group(1)
1018 VariableName
= Match
.group(2)
1019 MatchOffset
= re
.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line
)
1021 Offset
= int(MatchOffset
.group(1), 16)
1026 OldTextBody
.append (self
.CreateField (None, VariableName
, 0, Offset
, StructName
, '', '', ''))
1028 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1029 NewTextBody
.append (Line
)
1031 OldTextBody
.append (Line
)
1033 if Match
and Match
.group(3) == 'END':
1034 if (StructName
!= Match
.group(1)) or (VariableName
!= Match
.group(2)):
1035 print ("Unmatched struct name '%s' and '%s' !" % (StructName
, Match
.group(1)))
1037 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
1038 NewTextBody
.append ('} %s;\n\n' % StructName
)
1039 IsUpdHdrDefined
= True
1041 NewTextBody
.extend(OldTextBody
)
1044 def WriteLinesWithoutTailingSpace (self
, HeaderFd
, Line
):
1045 TxtBody2
= Line
.splitlines(True)
1046 for Line2
in TxtBody2
:
1047 Line2
= Line2
.rstrip()
1049 HeaderFd
.write (Line2
)
1051 def CreateHeaderFile (self
, InputHeaderFile
):
1054 HeaderFileName
= 'FspUpd.h'
1055 HeaderFile
= os
.path
.join(FvDir
, HeaderFileName
)
1057 # Check if header needs to be recreated
1061 for Item
in self
._CfgItemList
:
1062 if str(Item
['cname']) == 'Signature' and Item
['length'] == 8:
1063 Value
= int(Item
['value'], 16)
1066 Chars
.append(chr(Value
& 0xFF))
1068 SignatureStr
= ''.join(Chars
)
1069 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly
1070 if '_T' in SignatureStr
[6:6+2]:
1071 TxtBody
.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1072 elif '_M' in SignatureStr
[6:6+2]:
1073 TxtBody
.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1074 elif '_S' in SignatureStr
[6:6+2]:
1075 TxtBody
.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1076 TxtBody
.append("\n")
1078 for Region
in ['UPD']:
1080 UpdSignature
= ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS
1081 UpdStructure
= ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
1082 for Item
in self
._CfgItemList
:
1083 if Item
["cname"] == 'Signature' and Item
["value"][0:6] in UpdSignature
:
1084 UpdOffsetTable
.append (Item
["offset"])
1086 for UpdIdx
in range(len(UpdOffsetTable
)):
1088 for Item
in self
._CfgItemList
:
1089 if Item
["comment"] != '' and Item
["offset"] >= UpdOffsetTable
[UpdIdx
]:
1090 MatchComment
= re
.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item
["comment"])
1091 if MatchComment
and MatchComment
.group(1) == Region
[0]:
1092 CommentLine
= " " + MatchComment
.group(2) + "\n"
1093 TxtBody
.append("/**" + CommentLine
+ "**/\n")
1094 elif Item
["offset"] >= UpdOffsetTable
[UpdIdx
] and Item
["comment"] == '':
1095 Match
= re
.match("^FSP([\w|\W|\s])_UPD", UpdStructure
[UpdIdx
])
1097 TxtBody
.append("/** Fsp " + Match
.group(1) + " UPD Configuration\n**/\n")
1098 TxtBody
.append("typedef struct {\n")
1108 for Item
in self
._CfgItemList
:
1109 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == UpdSignature
[UpdIdx
] or Region
[0] == 'V':
1113 if Item
['cname'] == 'UpdTerminator':
1116 if Item
['region'] != Region
:
1119 if Item
["offset"] < UpdOffsetTable
[UpdIdx
]:
1122 NextVisible
= LastVisible
1124 if LastVisible
and (Item
['header'] == 'OFF'):
1126 ResvOffset
= Item
['offset']
1127 elif (not LastVisible
) and Item
['header'] == 'ON':
1129 Name
= "Reserved" + Region
[0] + "pdSpace%d" % ResvIdx
1130 ResvIdx
= ResvIdx
+ 1
1131 TxtBody
.append(self
.CreateField (Item
, Name
, Item
["offset"] - ResvOffset
, ResvOffset
, '', '', '', ''))
1133 if Offset
< Item
["offset"]:
1135 Name
= "Unused" + Region
[0] + "pdSpace%d" % SpaceIdx
1136 LineBuffer
.append(self
.CreateField (Item
, Name
, Item
["offset"] - Offset
, Offset
, '', '', '', ''))
1137 SpaceIdx
= SpaceIdx
+ 1
1138 Offset
= Item
["offset"]
1140 LastVisible
= NextVisible
1142 Offset
= Offset
+ Item
["length"]
1144 for Each
in LineBuffer
:
1145 TxtBody
.append (Each
)
1147 Comment
= Item
["comment"]
1148 Embed
= Item
["embed"].upper()
1149 if Embed
.endswith(':START') or Embed
.endswith(':END'):
1150 if not Comment
== '' and Embed
.endswith(':START'):
1151 Marker
= '/* COMMENT:%s */ \n' % Item
["comment"]
1152 Marker
= Marker
+ '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1154 Marker
= '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1159 self
.Error
= "Invalid embedded structure format '%s'!\n" % Item
["embed"]
1161 Line
= Marker
+ self
.CreateField (Item
, Item
["cname"], Item
["length"], Item
["offset"], Item
['struct'], Item
['name'], Item
['help'], Item
['option'])
1162 TxtBody
.append(Line
)
1163 if Item
['cname'] == 'UpdTerminator':
1165 TxtBody
.append("} " + UpdStructure
[UpdIdx
] + ";\n\n")
1167 # Handle the embedded data structure
1168 TxtBody
= self
.PostProcessBody (TxtBody
)
1170 HeaderTFileName
= 'FsptUpd.h'
1171 HeaderMFileName
= 'FspmUpd.h'
1172 HeaderSFileName
= 'FspsUpd.h'
1174 UpdRegionCheck
= ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
1175 UpdConfigCheck
= ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1176 UpdSignatureCheck
= ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
1177 ExcludedSpecificUpd
= 'FSPM_ARCH_UPD'
1179 if InputHeaderFile
!= '':
1180 if not os
.path
.exists(InputHeaderFile
):
1181 self
.Error
= "Input header file '%s' does not exist" % InputHeaderFile
1184 InFd
= open(InputHeaderFile
, "r")
1185 IncLines
= InFd
.readlines()
1188 for item
in range(len(UpdRegionCheck
)):
1189 if UpdRegionCheck
[item
] == 'FSPT':
1190 HeaderFd
= open(os
.path
.join(FvDir
, HeaderTFileName
), "w")
1191 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderTFileName
))
1192 elif UpdRegionCheck
[item
] == 'FSPM':
1193 HeaderFd
= open(os
.path
.join(FvDir
, HeaderMFileName
), "w")
1194 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderMFileName
))
1195 elif UpdRegionCheck
[item
] == 'FSPS':
1196 HeaderFd
= open(os
.path
.join(FvDir
, HeaderSFileName
), "w")
1197 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderSFileName
))
1198 FileName
= FileBase
.replace(".", "_").upper()
1199 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1200 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1201 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1202 HeaderFd
.write("#include <%s>\n\n" % HeaderFileName
)
1203 HeaderFd
.write("#pragma pack(1)\n\n")
1206 for Line
in IncLines
:
1207 Match
= re
.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line
)
1209 if Match
.group(2) == "BEGIN" and Match
.group(1) == UpdRegionCheck
[item
]:
1216 HeaderFd
.write(Line
)
1217 HeaderFd
.write("\n")
1223 StructStartWithComment
= []
1225 for Line
in TxtBody
:
1227 Match
= re
.match("(typedef struct {)", Line
)
1229 StartIndex
= Index
- 1
1230 Match
= re
.match("}\s([_A-Z0-9]+);", Line
)
1231 if Match
and (UpdRegionCheck
[item
] in Match
.group(1) or UpdConfigCheck
[item
] in Match
.group(1)) and (ExcludedSpecificUpd
not in Match
.group(1)):
1233 StructStart
.append(StartIndex
)
1234 StructEnd
.append(EndIndex
)
1236 for Line
in TxtBody
:
1238 for Item
in range(len(StructStart
)):
1239 if Index
== StructStart
[Item
]:
1240 Match
= re
.match("^(/\*\*\s*)", Line
)
1242 StructStartWithComment
.append(StructStart
[Item
])
1244 StructStartWithComment
.append(StructStart
[Item
] + 1)
1246 for Line
in TxtBody
:
1248 for Item
in range(len(StructStart
)):
1249 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1250 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1251 HeaderFd
.write("#pragma pack()\n\n")
1252 HeaderFd
.write("#endif\n")
1255 HeaderFd
= open(HeaderFile
, "w")
1256 FileBase
= os
.path
.basename(HeaderFile
)
1257 FileName
= FileBase
.replace(".", "_").upper()
1258 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1259 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1260 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1261 HeaderFd
.write("#include <FspEas.h>\n\n")
1262 HeaderFd
.write("#pragma pack(1)\n\n")
1264 for item
in range(len(UpdRegionCheck
)):
1269 StructStartWithComment
= []
1271 for Line
in TxtBody
:
1273 Match
= re
.match("(typedef struct {)", Line
)
1275 StartIndex
= Index
- 1
1276 Match
= re
.match("#define\s([_A-Z0-9]+)\s*", Line
)
1277 if Match
and (UpdSignatureCheck
[item
] in Match
.group(1) or UpdSignatureCheck
[item
] in Match
.group(1)):
1278 StructStart
.append(Index
- 1)
1279 StructEnd
.append(Index
)
1281 for Line
in TxtBody
:
1283 for Item
in range(len(StructStart
)):
1284 if Index
== StructStart
[Item
]:
1285 Match
= re
.match("^(/\*\*\s*)", Line
)
1287 StructStartWithComment
.append(StructStart
[Item
])
1289 StructStartWithComment
.append(StructStart
[Item
] + 1)
1291 for Line
in TxtBody
:
1293 for Item
in range(len(StructStart
)):
1294 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1295 self
.WriteLinesWithoutTailingSpace(HeaderFd
, Line
)
1296 HeaderFd
.write("#pragma pack()\n\n")
1297 HeaderFd
.write("#endif\n")
1302 def WriteBsfStruct (self
, BsfFd
, Item
):
1303 LogExpr
= CLogicalExpression()
1304 if Item
['type'] == "None":
1305 Space
= "gPlatformFspPkgTokenSpaceGuid"
1307 Space
= Item
['space']
1308 Line
= " $%s_%s" % (Space
, Item
['cname'])
1309 Match
= re
.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item
['value'])
1311 DefaultValue
= Match
.group(1).strip()
1313 DefaultValue
= Item
['value'].strip()
1314 if 'bitlength' in Item
:
1315 BsfFd
.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['bitlength'], DefaultValue
))
1317 BsfFd
.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['length'], DefaultValue
))
1319 if Item
['type'] == "Combo":
1320 if not Item
['option'] in self
._BuidinOption
:
1321 OptList
= Item
['option'].split(',')
1322 for Option
in OptList
:
1323 Option
= Option
.strip()
1324 (OpVal
, OpStr
) = Option
.split(':')
1325 test
= LogExpr
.getNumber (OpVal
)
1327 raise Exception("Selection Index '%s' is not a number" % OpVal
)
1328 TmpList
.append((OpVal
, OpStr
))
1331 def WriteBsfOption (self
, BsfFd
, Item
):
1332 PcdName
= Item
['space'] + '_' + Item
['cname']
1334 if Item
['type'] == "Combo":
1335 if Item
['option'] in self
._BuidinOption
:
1336 Options
= self
._BuidinOption
[Item
['option']]
1339 BsfFd
.write(' %s $%s, "%s", &%s,\n' % (Item
['type'], PcdName
, Item
['name'], Options
))
1341 elif Item
['type'].startswith("EditNum"):
1342 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'])
1344 BsfFd
.write(' EditNum $%s, "%s", %s,\n' % (PcdName
, Item
['name'], Match
.group(1)))
1346 elif Item
['type'].startswith("EditText"):
1347 BsfFd
.write(' %s $%s, "%s",\n' % (Item
['type'], PcdName
, Item
['name']))
1349 elif Item
['type'] == "Table":
1350 Columns
= Item
['option'].split(',')
1351 if len(Columns
) != 0:
1352 BsfFd
.write(' %s $%s "%s",' % (Item
['type'], PcdName
, Item
['name']))
1354 Fmt
= Col
.split(':')
1356 raise Exception("Column format '%s' is invalid !" % Fmt
)
1358 Dtype
= int(Fmt
[1].strip())
1360 raise Exception("Column size '%s' is invalid !" % Fmt
[1])
1361 BsfFd
.write('\n Column "%s", %d bytes, %s' % (Fmt
[0].strip(), Dtype
, Fmt
[2].strip()))
1366 HelpLines
= Item
['help'].split('\\n\\r')
1368 for HelpLine
in HelpLines
:
1371 BsfFd
.write(' Help "%s"\n' % (HelpLine
))
1373 BsfFd
.write(' "%s"\n' % (HelpLine
))
1375 BsfFd
.write(' "Valid range: %s ~ %s"\n' % (Match
.group(2), Match
.group(3)))
1377 def GenerateBsfFile (self
, BsfFile
):
1380 self
.Error
= "BSF output file '%s' is invalid" % BsfFile
1385 BsfFd
= open(BsfFile
, "w")
1386 BsfFd
.write("%s\n" % (__copyright_bsf__
% date
.today().year
))
1387 BsfFd
.write("%s\n" % self
._GlobalDataDef
)
1388 BsfFd
.write("StructDef\n")
1390 for Item
in self
._CfgItemList
:
1391 if Item
['find'] != '':
1392 BsfFd
.write('\n Find "%s"\n' % Item
['find'])
1393 NextOffset
= Item
['offset'] + Item
['length']
1394 if Item
['name'] != '':
1395 if NextOffset
!= Item
['offset']:
1396 BsfFd
.write(" Skip %d bytes\n" % (Item
['offset'] - NextOffset
))
1397 if len(Item
['subreg']) > 0:
1398 NextOffset
= Item
['offset']
1399 BitsOffset
= NextOffset
* 8
1400 for SubItem
in Item
['subreg']:
1401 BitsOffset
+= SubItem
['bitlength']
1402 if SubItem
['name'] == '':
1403 if 'bitlength' in SubItem
:
1404 BsfFd
.write(" Skip %d bits\n" % (SubItem
['bitlength']))
1406 BsfFd
.write(" Skip %d bytes\n" % (SubItem
['length']))
1408 Options
= self
.WriteBsfStruct(BsfFd
, SubItem
)
1409 if len(Options
) > 0:
1410 OptionDict
[SubItem
['space']+'_'+SubItem
['cname']] = Options
1412 NextBitsOffset
= (Item
['offset'] + Item
['length']) * 8
1413 if NextBitsOffset
> BitsOffset
:
1414 BitsGap
= NextBitsOffset
- BitsOffset
1415 BitsRemain
= BitsGap
% 8
1417 BsfFd
.write(" Skip %d bits\n" % BitsRemain
)
1418 BitsGap
-= BitsRemain
1419 BytesRemain
= BitsGap
/ 8
1421 BsfFd
.write(" Skip %d bytes\n" % BytesRemain
)
1422 NextOffset
= Item
['offset'] + Item
['length']
1424 NextOffset
= Item
['offset'] + Item
['length']
1425 Options
= self
.WriteBsfStruct(BsfFd
, Item
)
1426 if len(Options
) > 0:
1427 OptionDict
[Item
['space']+'_'+Item
['cname']] = Options
1428 BsfFd
.write("\nEndStruct\n\n")
1430 BsfFd
.write("%s" % self
._BuidinOptionTxt
)
1432 for Each
in OptionDict
:
1433 BsfFd
.write("List &%s\n" % Each
)
1434 for Item
in OptionDict
[Each
]:
1435 BsfFd
.write(' Selection %s , "%s"\n' % (Item
[0], Item
[1]))
1436 BsfFd
.write("EndList\n\n")
1438 BsfFd
.write("BeginInfoBlock\n")
1439 BsfFd
.write(' PPVer "%s"\n' % (self
._CfgBlkDict
['ver']))
1440 BsfFd
.write(' Description "%s"\n' % (self
._CfgBlkDict
['name']))
1441 BsfFd
.write("EndInfoBlock\n\n")
1443 for Each
in self
._CfgPageDict
:
1444 BsfFd
.write('Page "%s"\n' % self
._CfgPageDict
[Each
])
1446 for Item
in self
._CfgItemList
:
1447 if Item
['name'] != '':
1448 if Item
['page'] != Each
:
1450 if len(Item
['subreg']) > 0:
1451 for SubItem
in Item
['subreg']:
1452 if SubItem
['name'] != '':
1453 BsfItems
.append(SubItem
)
1455 BsfItems
.append(Item
)
1457 BsfItems
.sort(key
=lambda x
: x
['order'])
1459 for Item
in BsfItems
:
1460 self
.WriteBsfOption (BsfFd
, Item
)
1461 BsfFd
.write("EndPage\n\n")
1468 print ("GenCfgOpt Version 0.54")
1470 print (" GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]")
1471 print (" GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]")
1472 print (" GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]")
1476 # Parse the options and args
1480 GenCfgOpt
= CGenCfgOpt()
1481 while i
< len(sys
.argv
):
1482 if sys
.argv
[i
].strip().lower() == "--pcd":
1483 BuildOptionPcd
.append(sys
.argv
[i
+1])
1486 argc
= len(sys
.argv
)
1491 DscFile
= sys
.argv
[2]
1492 if not os
.path
.exists(DscFile
):
1493 print ("ERROR: Cannot open DSC file '%s' !" % DscFile
)
1498 if sys
.argv
[4][0] == '-':
1501 OutFile
= sys
.argv
[4]
1504 if GenCfgOpt
.ParseMacros(sys
.argv
[Start
:]) != 0:
1505 print ("ERROR: Macro parsing failed !")
1509 if not os
.path
.exists(FvDir
):
1512 if GenCfgOpt
.ParseDscFile(DscFile
, FvDir
) != 0:
1513 print ("ERROR: %s !" % GenCfgOpt
.Error
)
1516 if GenCfgOpt
.UpdateSubRegionDefaultValue() != 0:
1517 print ("ERROR: %s !" % GenCfgOpt
.Error
)
1520 if sys
.argv
[1] == "UPDTXT":
1521 Ret
= GenCfgOpt
.CreateSplitUpdTxt(OutFile
)
1523 # No change is detected
1525 print ("INFO: %s !" % (GenCfgOpt
.Error
))
1527 print ("ERROR: %s !" % (GenCfgOpt
.Error
))
1529 elif sys
.argv
[1] == "HEADER":
1530 if GenCfgOpt
.CreateHeaderFile(OutFile
) != 0:
1531 print ("ERROR: %s !" % GenCfgOpt
.Error
)
1533 elif sys
.argv
[1] == "GENBSF":
1534 if GenCfgOpt
.GenerateBsfFile(OutFile
) != 0:
1535 print ("ERROR: %s !" % GenCfgOpt
.Error
)
1541 print ("ERROR: Unknown command '%s' !" % sys
.argv
[1])
1548 if __name__
== '__main__':