]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/GenCfgOpt.py
3 # Copyright (c) 2014 - 2022, 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
):
286 def __init__ ( self
, Mode
= '' ):
290 self
._ GlobalDataDef
= """
296 self
._ BuidinOptionTxt
= """
298 Selection 0x1 , "Enabled"
299 Selection 0x0 , "Disabled"
303 self
._ BsfKeyList
= [ 'FIND' , 'NAME' , 'HELP' , 'TYPE' , 'PAGE' , 'PAGES' , 'BLOCK' , 'OPTION' , 'CONDITION' , 'ORDER' , 'MARKER' , 'SUBT' ]
304 self
._ HdrKeyList
= [ 'HEADER' , 'STRUCT' , 'EMBED' , 'COMMENT' ]
305 self
._ BuidinOption
= { '$EN_DIS' : 'EN_DIS' }
310 self
._ CfgBlkDict
= {}
311 self
._ CfgPageDict
= {}
312 self
._ BsfTempDict
= {}
313 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
, Preserve
= False ):
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
)
368 Line
= Line
. replace ( Each
, Each
[ 2 :- 1 ])
371 def ExpandPcds ( self
, Input
):
373 Match
= re
. findall ( "(\w+\.\w+)" , Input
)
375 for PcdName
in Match
:
376 if PcdName
in self
._ PcdsDict
:
377 Line
= Line
. replace ( PcdName
, self
._ PcdsDict
[ PcdName
])
380 print ( "WARN : %s is not defined" % PcdName
)
383 def EvaluateExpress ( self
, Expr
):
384 ExpExpr
= self
. ExpandPcds ( Expr
)
385 ExpExpr
= self
. ExpandMacros ( ExpExpr
)
386 LogExpr
= CLogicalExpression ()
387 Result
= LogExpr
. evaluateExpress ( ExpExpr
)
389 print ( "INFO : Eval Express [ %s ] : %s " % ( Expr
, Result
))
392 def ValueToByteArray ( self
, ValueStr
, Length
):
393 Match
= re
. match ( "\{\s*FILE:(.+)\}" , ValueStr
)
395 FileList
= Match
. group ( 1 ). split ( ',' )
397 for File
in FileList
:
399 BinPath
= os
. path
. join ( os
. path
. dirname ( self
._ DscFile
), File
)
400 Result
. extend ( bytearray ( open ( BinPath
, 'rb' ). read ()))
403 Result
= bytearray ( self
. ValueToList ( ValueStr
, Length
))
404 except ValueError as e
:
405 raise Exception ( "Bytes in ' %s ' must be in range 0~255 !" % ValueStr
)
406 if len ( Result
) < Length
:
407 Result
. extend ( b
' \x00 ' * ( Length
- len ( Result
)))
408 elif len ( Result
) > Length
:
409 raise Exception ( "Value ' %s ' is too big to fit into %d bytes !" % ( ValueStr
, Length
))
411 return Result
[: Length
]
413 def ValueToList ( self
, ValueStr
, Length
):
414 if ValueStr
[ 0 ] == '{' :
416 BinList
= ValueStr
[ 1 :- 1 ]. split ( ',' )
418 LastInBitField
= False
421 for Element
in BinList
:
423 Each
= Element
. strip ()
427 if Each
[ 0 ] in [ '"' , "'" ]:
428 Result
. extend ( list ( bytearray ( Each
[ 1 :- 1 ], 'utf-8' )))
430 Match
= re
. match ( "(.+):(\d+)b" , Each
)
432 raise Exception ( "Invald value list format ' %s ' !" % Each
)
434 CurrentBitLen
= int ( Match
. group ( 2 ))
435 CurrentValue
= (( self
. EvaluateExpress ( Match
. group ( 1 )) & ( 1 << CurrentBitLen
) - 1 )) << BitLen
437 Result
. append ( self
. EvaluateExpress ( Each
. strip ()))
439 Value
+= CurrentValue
440 BitLen
+= CurrentBitLen
441 if LastInBitField
and (( not InBitField
) or ( Element
== BinList
[- 1 ])):
443 raise Exception ( "Invald bit field length!" )
444 Result
. extend ( Val2Bytes ( Value
, BitLen
// 8 ))
447 LastInBitField
= InBitField
448 elif ValueStr
. startswith ( "'" ) and ValueStr
. endswith ( "'" ):
449 Result
= Str2Bytes ( ValueStr
, Length
)
450 elif ValueStr
. startswith ( '"' ) and ValueStr
. endswith ( '"' ):
451 Result
= Str2Bytes ( ValueStr
, Length
)
453 Result
= Val2Bytes ( self
. EvaluateExpress ( ValueStr
), Length
)
456 def FormatListValue ( self
, ConfigDict
):
457 Struct
= ConfigDict
[ 'struct' ]
458 if Struct
not in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
462 binlist
= ConfigDict
[ 'value' ][ 1 :- 1 ]. split ( ',' )
465 if each
. startswith ( '0x' ):
466 value
= int ( each
, 16 )
469 dataarray
. append ( value
)
471 unit
= int ( Struct
[ 4 :]) / 8
472 if int ( ConfigDict
[ 'length' ]) != unit
* len ( dataarray
):
473 raise Exception ( "Array size is not proper for ' %s ' !" % ConfigDict
[ 'cname' ])
476 for each
in dataarray
:
478 for loop
in range ( int ( unit
)):
479 bytearray
. append ( "0x %0 2X" % ( value
& 0xFF ))
481 newvalue
= '{' + ',' . join ( bytearray
) + '}'
482 ConfigDict
[ 'value' ] = newvalue
485 def ParseDscFile ( self
, DscFile
, FvDir
):
488 self
._ CfgItemList
= []
489 self
._ CfgPageDict
= {}
490 self
._ CfgBlkDict
= {}
491 self
._ DscFile
= DscFile
495 self
._ BsfTempDict
= {}
497 # Initial DSC time is parent DSC time.
498 self
._ DscTime
= os
. path
. getmtime ( DscFile
)
516 if type ( DscFile
) is list :
517 # it is DSC lines already
521 DscFd
= open ( DscFile
, "r" )
522 DscLines
= DscFd
. readlines ()
524 self
._ DscFile
= DscFile
528 MaxAlign
= 32 #Default align to 32, but if there are 64 bit unit, align to 64
529 SizeAlign
= 0 #record the struct max align
530 Base
= 0 #Starting offset of sub-structure.
533 DscLine
= DscLines
. pop ( 0 ). strip ()
535 self
._ DscLines
. append ( DscLine
)
537 SkipLines
= SkipLines
- 1
538 if len ( DscLine
) == 0 :
542 Match
= re
. match ( "^\[(.+)\]" , DscLine
)
543 if Match
is not None :
549 SectionName
= Match
. group ( 1 ). lower ()
550 if SectionName
== "Defines" . lower ():
552 if ( SectionName
== "PcdsFeatureFlag" . lower () or SectionName
== "PcdsFixedAtBuild" . lower ()):
554 elif SectionName
== "PcdsDynamicVpd.Tmp" . lower ():
556 elif SectionName
== "PcdsDynamicVpd.Upd" . lower ():
558 ConfigDict
[ 'header' ] = 'ON'
559 ConfigDict
[ 'region' ] = 'UPD'
560 ConfigDict
[ 'order' ] = - 1
561 ConfigDict
[ 'page' ] = ''
562 ConfigDict
[ 'name' ] = ''
563 ConfigDict
[ 'find' ] = ''
564 ConfigDict
[ 'marker' ] = ''
565 ConfigDict
[ 'struct' ] = ''
566 ConfigDict
[ 'embed' ] = ''
567 ConfigDict
[ 'comment' ] = ''
568 ConfigDict
[ 'subreg' ] = []
569 ConfigDict
[ 'condition' ] = ''
570 ConfigDict
[ 'option' ] = ''
574 if IsDefSect
or IsPcdSect
or IsUpdSect
or IsVpdSect
or IsTmpSect
:
576 Match
= False if DscLine
[ 0 ] != '!' else True
578 Match
= re
. match ( "^!(else|endif|ifdef|ifndef|if|elseif|include)\s*(.+)?$" , DscLine
. split ( "#" )[ 0 ])
579 Keyword
= Match
. group ( 1 ) if Match
else ''
580 Remaining
= Match
. group ( 2 ) if Match
else ''
581 Remaining
= '' if Remaining
is None else Remaining
. strip ()
583 if Keyword
in [ 'if' , 'elseif' , 'ifdef' , 'ifndef' , 'include' ] and not Remaining
:
584 raise Exception ( "ERROR: Expression is expected after '!if' or !elseif' for line ' %s '" % DscLine
)
586 if Keyword
== 'else' :
588 IfStack
[- 1 ] = not IfStack
[- 1 ]
590 raise Exception ( "ERROR: No paired '!if' found for '!else' for line ' %s '" % DscLine
)
591 elif Keyword
== 'endif' :
594 Level
= ElifStack
. pop ()
598 raise Exception ( "ERROR: No paired '!if' found for '!endif' for line ' %s '" % DscLine
)
599 elif Keyword
== 'ifdef' or Keyword
== 'ifndef' :
600 Result
= self
. EvaulateIfdef ( Remaining
)
601 if Keyword
== 'ifndef' :
603 IfStack
. append ( Result
)
605 elif Keyword
== 'if' or Keyword
== 'elseif' :
606 Result
= self
. EvaluateExpress ( Remaining
)
609 IfStack
. append ( Result
)
612 IfStack
[- 1 ] = not IfStack
[- 1 ]
613 IfStack
. append ( Result
)
614 ElifStack
[- 1 ] = ElifStack
[- 1 ] + 1
616 raise Exception ( "ERROR: No paired '!if' found for '!elif' for line ' %s '" % DscLine
)
619 Handle
= reduce ( lambda x
, y
: x
and y
, IfStack
)
623 Match
= re
. match ( "!include\s+(.+)" , DscLine
)
625 IncludeFilePath
= Match
. group ( 1 )
626 IncludeFilePath
= self
. ExpandMacros ( IncludeFilePath
)
627 PackagesPath
= os
. getenv ( "PACKAGES_PATH" )
629 for PackagePath
in PackagesPath
. split ( os
. pathsep
):
630 IncludeFilePathAbs
= os
. path
. join ( os
. path
. normpath ( PackagePath
), os
. path
. normpath ( IncludeFilePath
))
631 if os
. path
. exists ( IncludeFilePathAbs
):
632 IncludeDsc
= open ( IncludeFilePathAbs
, "r" )
635 IncludeDsc
= open ( IncludeFilePath
, "r" )
636 if IncludeDsc
== None :
637 print ( "ERROR: Cannot open file ' %s '" % IncludeFilePath
)
640 # Update DscTime when newer DSC time found.
641 CurrentDscTime
= os
. path
. getmtime ( os
. path
. realpath ( IncludeDsc
. name
))
642 if CurrentDscTime
> self
._ DscTime
:
643 self
._ DscTime
= CurrentDscTime
645 NewDscLines
= IncludeDsc
. readlines ()
647 DscLines
= NewDscLines
+ DscLines
648 del self
._ DscLines
[- 1 ]
651 if DscLine
. startswith ( '!' ):
652 print ( "ERROR: Unrecognized directive for line ' %s '" % DscLine
)
655 del self
._ DscLines
[- 1 ]
659 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
660 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
661 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
662 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
663 Match
= re
. match ( "^\s*(?:DEFINE\s+)*(\w+)\s*=\s*(.+)" , DscLine
)
665 self
._ MacroDict
[ Match
. group ( 1 )] = self
. ExpandMacros ( Match
. group ( 2 ))
667 print ( "INFO : DEFINE %s = [ %s ]" % ( Match
. group ( 1 ), self
. ExpandMacros ( Match
. group ( 2 ))))
669 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
670 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
671 Match
= re
. match ( "^\s*([\w\.]+)\s*\|\s*(\w+)" , DscLine
)
673 self
._ PcdsDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
675 print ( "INFO : PCD %s = [ %s ]" % ( Match
. group ( 1 ), Match
. group ( 2 )))
677 while i
< len ( BuildOptionPcd
):
678 Match
= re
. match ( "\s*([\w\.]+)\s*\=\s*(\w+)" , BuildOptionPcd
[ i
])
680 self
._ PcdsDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
684 # !BSF DEFT:{GPIO_TMPL:START}
685 Match
= re
. match ( "^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}" , DscLine
)
687 if Match
. group ( 3 ) == 'START' and not TemplateName
:
688 TemplateName
= Match
. group ( 2 ). strip ()
689 self
._ BsfTempDict
[ TemplateName
] = []
690 if Match
. group ( 3 ) == 'END' and ( TemplateName
== Match
. group ( 2 ). strip ()) and TemplateName
:
694 Match
= re
. match ( "^!include\s*(.+)?$" , DscLine
)
697 self
._ BsfTempDict
[ TemplateName
]. append ( DscLine
)
700 Match
= re
. match ( "^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)" , DscLine
)
702 Remaining
= Match
. group ( 2 )
703 if Match
. group ( 1 ) == '!BSF' or Match
. group ( 1 ) == '@Bsf' :
704 Match
= re
. match ( "(?:^|.+\s+)PAGES:{(.+?)}" , Remaining
)
706 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
707 PageList
= Match
. group ( 1 ). split ( ',' )
708 for Page
in PageList
:
710 Match
= re
. match ( "(\w+): \" (.+) \" " , Page
)
712 self
._ CfgPageDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
714 Match
= re
. match ( "(?:^|.+\s+)BLOCK:{NAME: \" (.+) \" \s*,\s*VER: \" (.+) \" \s*}" , Remaining
)
716 self
._ CfgBlkDict
[ 'name' ] = Match
. group ( 1 )
717 self
._ CfgBlkDict
[ 'ver' ] = Match
. group ( 2 )
719 for Key
in self
._ BsfKeyList
:
720 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
722 if Key
in [ 'NAME' , 'HELP' , 'OPTION' ] and Match
. group ( 1 ). startswith ( '+' ):
723 ConfigDict
[ Key
. lower ()] += Match
. group ( 1 )[ 1 :]
725 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
727 for Key
in self
._ HdrKeyList
:
728 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
730 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
732 Match
= re
. match ( "^\s*#\s+@Prompt\s+(.+)" , DscLine
)
734 ConfigDict
[ 'name' ] = Match
. group ( 1 )
736 Match
= re
. match ( "^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*" , DscLine
)
738 if Match
. group ( 2 ). strip () in self
._ BuidinOption
:
739 ConfigDict
[ 'option' ] = Match
. group ( 2 ). strip ()
741 OptionValueList
= Match
. group ( 2 ). split ( ',' )
742 OptionStringList
= Match
. group ( 3 ). split ( ',' )
744 for Option
in OptionValueList
:
745 Option
= Option
. strip ()
746 ConfigDict
[ 'option' ] = ConfigDict
[ 'option' ] + str ( Option
) + ':' + OptionStringList
[ Index
]. strip ()
748 if Index
in range ( len ( OptionValueList
)):
749 ConfigDict
[ 'option' ] += ', '
750 ConfigDict
[ 'type' ] = "Combo"
752 Match
= re
. match ( "^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*" , DscLine
)
754 if "0x" in Match
. group ( 2 ) or "0x" in Match
. group ( 3 ):
755 ConfigDict
[ 'type' ] = "EditNum, HEX, ( %s , %s )" % ( Match
. group ( 2 ), Match
. group ( 3 ))
757 ConfigDict
[ 'type' ] = "EditNum, DEC, ( %s , %s )" % ( Match
. group ( 2 ), Match
. group ( 3 ))
759 Match
= re
. match ( "^\s*##\s+(.+)" , DscLine
)
761 ConfigDict
[ 'help' ] = Match
. group ( 1 )
765 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
)
767 Match
= re
. match ( "^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?" , DscLine
)
769 ConfigDict
[ 'space' ] = Match
. group ( 1 )
770 ConfigDict
[ 'cname' ] = Match
. group ( 2 )
771 if Match
. group ( 3 ) != '*' :
773 Offset
= int ( Match
. group ( 3 ), 16 )
777 if Hardcode
and AutoAlign
:
778 print ( "Hardcode and auto-align mixed mode is not supported by GenCfgOpt" )
780 ConfigDict
[ 'offset' ] = Offset
781 if ConfigDict
[ 'order' ] == - 1 :
782 ConfigDict
[ 'order' ] = ConfigDict
[ 'offset' ] << 8
784 ( Major
, Minor
) = ConfigDict
[ 'order' ]. split ( '.' )
785 ConfigDict
[ 'order' ] = ( int ( Major
, 16 ) << 8 ) + int ( Minor
, 16 )
787 Value
= Match
. group ( 5 ). strip ()
788 if Match
. group ( 4 ). startswith ( "0x" ):
789 Length
= int ( Match
. group ( 4 ), 16 )
791 Length
= int ( Match
. group ( 4 ))
794 Value
= Match
. group ( 4 )
797 Value
= Value
. strip ()
799 Match
= re
. match ( "^.+\s*\|\s*(.+)" , Value
)
801 Value
= Match
. group ( 1 )
804 ConfigDict
[ 'length' ] = Length
805 Match
= re
. match ( "\$\((\w+)\)" , Value
)
807 if Match
. group ( 1 ) in self
._ MacroDict
:
808 Value
= self
._ MacroDict
[ Match
. group ( 1 )]
810 ConfigDict
[ 'value' ] = Value
811 if ( len ( Value
) > 0 ) and ( Value
[ 0 ] == '{' ):
812 Value
= self
. FormatListValue ( ConfigDict
)
814 if ConfigDict
[ 'name' ] == '' :
815 # Clear BSF specific items
816 ConfigDict
[ 'bsfname' ] = ''
817 ConfigDict
[ 'help' ] = ''
818 ConfigDict
[ 'type' ] = ''
819 ConfigDict
[ 'option' ] = ''
820 if IsUpdSect
and AutoAlign
:
821 ItemLength
= int ( ConfigDict
[ 'length' ])
822 ItemOffset
= int ( ConfigDict
[ 'offset' ])
823 ItemStruct
= ConfigDict
[ 'struct' ]
825 if ItemLength
in [ 1 , 2 , 4 , 8 ] and not ConfigDict
[ 'value' ]. startswith ( '{' ):
827 # If there are 64 bit unit, align to 64
832 UnitDict
= { 'UINT8' : 1 , 'UINT16' : 2 , 'UINT32' : 4 , 'UINT64' : 8 }
833 if ItemStruct
in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
834 Unit
= UnitDict
[ ItemStruct
]
835 # If there are 64 bit unit, align to 64
838 SizeAlign
= max ( SizeAlign
, Unit
)
839 if ( ConfigDict
[ 'embed' ]. find ( ':START' ) != - 1 ):
841 SubOffset
= ItemOffset
- Base
842 SubRemainder
= SubOffset
% Unit
844 Diff
= Unit
- SubRemainder
845 Offset
= Offset
+ Diff
846 ItemOffset
= ItemOffset
+ Diff
848 if ( ConfigDict
[ 'embed' ]. find ( ':END' ) != - 1 ):
849 Remainder
= Offset
% ( MaxAlign
/ 8 ) # MaxAlign is either 32 or 64
851 Diff
= int (( MaxAlign
/ 8 ) - Remainder
)
852 Offset
= Offset
+ Diff
853 ItemOffset
= ItemOffset
+ Diff
854 MaxAlign
= 32 # Reset to default 32 align when struct end
855 if ( ConfigDict
[ 'cname' ] == 'UpdTerminator' ):
856 # ItemLength is the size of UpdTerminator
857 # Itemlength might be 16, 32, or 64
858 # Struct align to 64 if UpdTerminator
859 # or struct size is 64 bit, else align to 32
860 Remainder
= Offset
% max ( ItemLength
/ 8 , 4 , SizeAlign
)
861 Offset
= Offset
+ ItemLength
863 Diff
= int ( max ( ItemLength
/ 8 , 4 , SizeAlign
) - Remainder
)
864 ItemOffset
= ItemOffset
+ Diff
865 ConfigDict
[ 'offset' ] = ItemOffset
867 self
._ CfgItemList
. append ( ConfigDict
. copy ())
868 ConfigDict
[ 'name' ] = ''
869 ConfigDict
[ 'find' ] = ''
870 ConfigDict
[ 'struct' ] = ''
871 ConfigDict
[ 'embed' ] = ''
872 ConfigDict
[ 'comment' ] = ''
873 ConfigDict
[ 'marker' ] = ''
874 ConfigDict
[ 'order' ] = - 1
875 ConfigDict
[ 'subreg' ] = []
876 ConfigDict
[ 'option' ] = ''
878 # It could be a virtual item as below
879 # !BSF FIELD:{SerialDebugPortAddress0:1}
881 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
882 Match
= re
. match ( "^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}" , DscLine
)
884 SubCfgDict
= ConfigDict
. copy ()
885 if ( Match
. group ( 4 ) == None ) or ( Match
. group ( 4 ) == 'B' ):
887 elif Match
. group ( 4 ) == 'b' :
890 print ( "ERROR: Invalide BSF FIELD length for line ' %s '" % DscLine
)
892 SubCfgDict
[ 'cname' ] = Match
. group ( 2 )
893 SubCfgDict
[ 'bitlength' ] = int ( Match
. group ( 3 )) * UnitBitLen
894 if SubCfgDict
[ 'bitlength' ] > 0 :
895 LastItem
= self
._ CfgItemList
[- 1 ]
896 if len ( LastItem
[ 'subreg' ]) == 0 :
899 SubOffset
= LastItem
[ 'subreg' ][- 1 ][ 'bitoffset' ] + LastItem
[ 'subreg' ][- 1 ][ 'bitlength' ]
900 SubCfgDict
[ 'bitoffset' ] = SubOffset
901 LastItem
[ 'subreg' ]. append ( SubCfgDict
. copy ())
902 ConfigDict
[ 'name' ] = ''
905 def GetBsfBitFields ( self
, subitem
, bytes
):
906 start
= subitem
[ 'bitoffset' ]
907 end
= start
+ subitem
[ 'bitlength' ]
908 bitsvalue
= '' . join ( '{0:08b}' . format ( i
) for i
in bytes
[::- 1 ])
909 bitsvalue
= bitsvalue
[::- 1 ]
910 bitslen
= len ( bitsvalue
)
911 if start
> bitslen
or end
> bitslen
:
912 raise Exception ( "Invalid bits offset [ %d , %d ] %d for %s " % ( start
, end
, bitslen
, subitem
[ 'name' ]))
913 return '0x %X ' % ( int ( bitsvalue
[ start
: end
][::- 1 ], 2 ))
915 def UpdateSubRegionDefaultValue ( self
):
917 for Item
in self
._ CfgItemList
:
918 if len ( Item
[ 'subreg' ]) == 0 :
921 if Item
[ 'value' ][ 0 ] == '{' :
922 binlist
= Item
[ 'value' ][ 1 :- 1 ]. split ( ',' )
925 if each
. startswith ( '0x' ):
926 value
= int ( each
, 16 )
929 bytearray
. append ( value
)
931 if Item
[ 'value' ]. startswith ( '0x' ):
932 value
= int ( Item
[ 'value' ], 16 )
934 value
= int ( Item
[ 'value' ])
936 while idx
< Item
[ 'length' ]:
937 bytearray
. append ( value
& 0xFF )
940 for SubItem
in Item
[ 'subreg' ]:
941 valuestr
= self
. GetBsfBitFields ( SubItem
, bytearray
)
942 SubItem
[ 'value' ] = valuestr
945 def NoDscFileChange ( self
, OutPutFile
):
947 if not os
. path
. exists ( OutPutFile
):
950 OutputTime
= os
. path
. getmtime ( OutPutFile
)
951 if self
._ DscTime
> OutputTime
:
955 def CreateSplitUpdTxt ( self
, UpdTxtFile
):
956 GuidList
= [ 'FSP_T_UPD_TOOL_GUID' , 'FSP_M_UPD_TOOL_GUID' , 'FSP_S_UPD_TOOL_GUID' , 'FSP_I_UPD_TOOL_GUID' ]
957 SignatureList
= [ '0x545F' , '0x4D5F' , '0x535F' , '0x495F' ] # _T, _M, _S and _I signature for FSPT, FSPM, FSPS, FSPI
958 for Index
in range ( len ( GuidList
)):
961 if GuidList
[ Index
] not in self
._ MacroDict
:
963 if GuidList
[ Index
] == 'FSP_I_UPD_TOOL_GUID' :
967 self
. Error
= " %s definition is missing in DSC file" % ( GuidList
[ Index
])
971 UpdTxtFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ GuidList
[ Index
]] + '.txt' )
973 if ( self
. NoDscFileChange ( UpdTxtFile
)):
974 # DSC has not been modified yet
975 # So don't have to re-generate other files
976 self
. Error
= 'No DSC file change, skip to create UPD TXT file'
979 TxtFd
= open ( UpdTxtFile
, "w" )
980 TxtFd
. write ( " %s \n " % ( __copyright_txt__
% date
. today (). year
))
988 for Item
in self
._ CfgItemList
:
989 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == SignatureList
[ Index
]:
990 StartAddr
= Item
[ 'offset' ]
991 NextOffset
= StartAddr
993 if Item
[ 'cname' ] == 'UpdTerminator' and InRange
== True :
994 EndAddr
= Item
[ 'offset' ]
997 for Item
in self
._ CfgItemList
:
998 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == SignatureList
[ Index
]:
1002 if Item
[ 'cname' ] == 'UpdTerminator' :
1004 if Item
[ 'region' ] != 'UPD' :
1006 Offset
= Item
[ 'offset' ]
1007 if StartAddr
> Offset
or EndAddr
< Offset
:
1009 if NextOffset
< Offset
:
1011 TxtFd
. write ( " %s .UnusedUpdSpace %d | %s0x%0 4X|0x %0 4X| {0} \n " % ( Item
[ 'space' ], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
1012 SpaceIdx
= SpaceIdx
+ 1
1013 NextOffset
= Offset
+ Item
[ 'length' ]
1014 TxtFd
. write ( " %s . %s | %s0x%0 4X| %s | %s \n " % ( Item
[ 'space' ], Item
[ 'cname' ], Default
, Item
[ 'offset' ] - StartAddr
, Item
[ 'length' ], Item
[ 'value' ]))
1018 def CreateVarDict ( self
):
1021 if len ( self
._ CfgItemList
) > 0 :
1022 Item
= self
._ CfgItemList
[- 1 ]
1023 self
._ VarDict
[ '_LENGTH_' ] = ' %d ' % ( Item
[ 'offset' ] + Item
[ 'length' ])
1024 for Item
in self
._ CfgItemList
:
1025 Embed
= Item
[ 'embed' ]
1026 Match
= re
. match ( "^(\w+):(\w+):(START|END)" , Embed
)
1028 StructName
= Match
. group ( 1 )
1029 VarName
= '_ %s _ %s _' % ( Match
. group ( 3 ), StructName
)
1030 if Match
. group ( 3 ) == 'END' :
1031 self
._ VarDict
[ VarName
] = Item
[ 'offset' ] + Item
[ 'length' ]
1032 self
._ VarDict
[ '_LENGTH_ %s _' % StructName
] = \
1033 self
._ VarDict
[ '_END_ %s _' % StructName
] - self
._ VarDict
[ '_START_ %s _' % StructName
]
1034 if Match
. group ( 2 ). startswith ( 'TAG_' ):
1035 if ( self
. Mode
!= 'FSP' ) and ( self
._ VarDict
[ '_LENGTH_ %s _' % StructName
] % 4 ):
1036 raise Exception ( "Size of structure ' %s ' is %d , not DWORD aligned !" % ( StructName
, self
._ VarDict
[ '_LENGTH_ %s _' % StructName
]))
1037 self
._ VarDict
[ '_TAG_ %s _' % StructName
] = int ( Match
. group ( 2 )[ 4 :], 16 ) & 0xFFF
1039 self
._ VarDict
[ VarName
] = Item
[ 'offset' ]
1041 self
._ VarDict
[ '_OFFSET_ %s _' % Item
[ 'marker' ]. strip ()] = Item
[ 'offset' ]
1044 def UpdateBsfBitUnit ( self
, Item
):
1049 UnitDec
= { 1 : 'BYTE' , 2 : 'WORD' , 4 : 'DWORD' , 8 : 'QWORD' }
1050 for Idx
, SubItem
in enumerate ( Item
[ 'subreg' ]):
1052 Unit
= SubItem
[ 'bitunit' ]
1053 BitLength
= SubItem
[ 'bitlength' ]
1054 BitTotal
+= BitLength
1055 BitOffset
+= BitLength
1057 if BitOffset
> 64 or BitOffset
> Unit
* 8 :
1060 if BitOffset
== Unit
* 8 :
1061 for SubIdx
in range ( StartIdx
, Idx
+ 1 ):
1062 Item
[ 'subreg' ][ SubIdx
][ 'bitunit' ] = Unit
1068 raise Exception ( "Bit fields cannot fit into %s for ' %s . %s ' !" % ( UnitDec
[ Unit
], Item
[ 'cname' ], SubItem
[ 'cname' ]))
1070 ExpectedTotal
= Item
[ 'length' ] * 8
1071 if Item
[ 'length' ] * 8 != BitTotal
:
1072 raise Exception ( "Bit fields total length ( %d ) does not match length ( %d ) of ' %s ' !" % ( BitTotal
, ExpectedTotal
, Item
[ 'cname' ]))
1074 def UpdateDefaultValue ( self
):
1076 for Idx
, Item
in enumerate ( self
._ CfgItemList
):
1077 if len ( Item
[ 'subreg' ]) == 0 :
1078 Value
= Item
[ 'value' ]
1079 if ( len ( Value
) > 0 ) and ( Value
[ 0 ] == '{' or Value
[ 0 ] == "'" or Value
[ 0 ] == '"' ):
1080 # {XXX} or 'XXX' strings
1081 self
. FormatListValue ( self
._ CfgItemList
[ Idx
])
1083 Match
= re
. match ( "(0x[0-9a-fA-F]+|[0-9]+)" , Value
)
1085 NumValue
= self
. EvaluateExpress ( Value
)
1086 Item
[ 'value' ] = '0x %X ' % NumValue
1088 ValArray
= self
. ValueToByteArray ( Item
[ 'value' ], Item
[ 'length' ])
1089 for SubItem
in Item
[ 'subreg' ]:
1090 SubItem
[ 'value' ] = self
. GetBsfBitFields ( SubItem
, ValArray
)
1091 self
. UpdateBsfBitUnit ( Item
)
1094 def ProcessMultilines ( self
, String
, MaxCharLength
):
1096 StringLength
= len ( String
)
1097 CurrentStringStart
= 0
1100 if len ( String
) <= MaxCharLength
:
1101 while ( StringOffset
< StringLength
):
1102 if StringOffset
>= 1 :
1103 if String
[ StringOffset
- 1 ] == ' \\ ' and String
[ StringOffset
] == 'n' :
1104 BreakLineDict
. append ( StringOffset
+ 1 )
1106 if BreakLineDict
!= []:
1107 for Each
in BreakLineDict
:
1108 Multilines
+= " %s \n " % String
[ CurrentStringStart
: Each
]. lstrip ()
1109 CurrentStringStart
= Each
1110 if StringLength
- CurrentStringStart
> 0 :
1111 Multilines
+= " %s \n " % String
[ CurrentStringStart
:]. lstrip ()
1113 Multilines
= " %s \n " % String
1117 FoundSpaceChar
= False
1118 while ( StringOffset
< StringLength
):
1119 if StringOffset
>= 1 :
1120 if NewLineCount
>= MaxCharLength
- 1 :
1121 if String
[ StringOffset
] == ' ' and StringLength
- StringOffset
> 10 :
1122 BreakLineDict
. append ( NewLineStart
+ NewLineCount
)
1123 NewLineStart
= NewLineStart
+ NewLineCount
1125 FoundSpaceChar
= True
1126 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False :
1127 BreakLineDict
. append ( 0 )
1128 if String
[ StringOffset
- 1 ] == ' \\ ' and String
[ StringOffset
] == 'n' :
1129 BreakLineDict
. append ( StringOffset
+ 1 )
1130 NewLineStart
= StringOffset
+ 1
1134 if BreakLineDict
!= []:
1135 BreakLineDict
. sort ()
1136 for Each
in BreakLineDict
:
1138 Multilines
+= " %s \n " % String
[ CurrentStringStart
: Each
]. lstrip ()
1139 CurrentStringStart
= Each
1140 if StringLength
- CurrentStringStart
> 0 :
1141 Multilines
+= " %s \n " % String
[ CurrentStringStart
:]. lstrip ()
1144 def CreateField ( self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
, BitsLength
= None ):
1151 if Length
== 0 and Name
== 'Dummy' :
1155 if Length
in [ 1 , 2 , 4 , 8 ]:
1156 Type
= "UINT %d " % ( Length
* 8 )
1157 if Name
. startswith ( "UnusedUpdSpace" ) and Length
!= 1 :
1164 if Item
and Item
[ 'value' ]. startswith ( '{' ):
1170 if Struct
in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
1172 Unit
= int ( Type
[ 4 :]) / 8
1173 Length
= Length
/ Unit
1178 Name
= Name
+ '[ %d ]' % Length
1180 if len ( Type
) < PosName
:
1181 Space1
= PosName
- len ( Type
)
1186 NameLine
= " - %s \n " % BsfName
1191 HelpLine
= self
. ProcessMultilines ( Help
, 80 )
1194 OptionLine
= self
. ProcessMultilines ( Option
, 80 )
1199 OffsetStr
= '0x %0 4X' % Offset
1201 if BitsLength
is None :
1204 BitsLength
= ' : %d ' % BitsLength
1206 return " \n /** Offset %s%s%s%s **/ \n %s%s%s%s ; \n " % ( OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
, BitsLength
)
1208 def PostProcessBody ( self
, TextBody
):
1214 IsUpdHdrDefined
= False
1216 for Line
in TextBody
:
1217 SplitToLines
= Line
. splitlines ()
1218 MatchComment
= re
. match ( "^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)" , SplitToLines
[ 0 ])
1220 if MatchComment
. group ( 1 ) == 'FSP_UPD_HEADER' :
1224 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1225 CommentLine
= " " + MatchComment
. group ( 2 ) + " \n "
1226 NewTextBody
. append ( "/**" + CommentLine
+ "**/ \n " )
1227 Line
= Line
[( len ( SplitToLines
[ 0 ]) + 1 ):]
1229 Match
= re
. match ( "^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)" , Line
)
1231 Line
= Match
. group ( 4 )
1232 if Match
. group ( 1 ) == 'FSP_UPD_HEADER' :
1237 if Match
and Match
. group ( 3 ) == 'START' :
1238 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1239 NewTextBody
. append ( 'typedef struct { \n ' )
1240 StructName
= Match
. group ( 1 )
1241 VariableName
= Match
. group ( 2 )
1242 MatchOffset
= re
. search ( '/\*\*\sOffset\s0x([a-fA-F0-9]+)' , Line
)
1244 Offset
= int ( MatchOffset
. group ( 1 ), 16 )
1249 OldTextBody
. append ( self
. CreateField ( None , VariableName
, 0 , Offset
, StructName
, '' , '' , '' ))
1251 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1252 NewTextBody
. append ( Line
)
1254 OldTextBody
. append ( Line
)
1256 if Match
and Match
. group ( 3 ) == 'END' :
1257 if ( StructName
!= Match
. group ( 1 )) or ( VariableName
!= Match
. group ( 2 )):
1258 print ( "Unmatched struct name ' %s ' and ' %s ' !" % ( StructName
, Match
. group ( 1 )))
1260 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1261 NewTextBody
. append ( '} %s ; \n\n ' % StructName
)
1262 IsUpdHdrDefined
= True
1264 NewTextBody
. extend ( OldTextBody
)
1267 def WriteLinesWithoutTailingSpace ( self
, HeaderFd
, Line
):
1268 TxtBody2
= Line
. splitlines ( True )
1269 for Line2
in TxtBody2
:
1270 Line2
= Line2
. rstrip ()
1272 HeaderFd
. write ( Line2
)
1274 def CreateHeaderFile ( self
, InputHeaderFile
):
1277 HeaderFileName
= 'FspUpd.h'
1278 HeaderFile
= os
. path
. join ( FvDir
, HeaderFileName
)
1280 # Check if header needs to be recreated
1281 if ( self
. NoDscFileChange ( HeaderFile
)):
1282 # DSC has not been modified yet
1283 # So don't have to re-generate other files
1284 self
. Error
= 'No DSC file change, skip to create UPD header file'
1288 for Item
in self
._ CfgItemList
:
1289 if str ( Item
[ 'cname' ]) == 'Signature' and Item
[ 'length' ] == 8 :
1290 Value
= int ( Item
[ 'value' ], 16 )
1293 Chars
. append ( chr ( Value
& 0xFF ))
1295 SignatureStr
= '' . join ( Chars
)
1296 # Signature will be _T / _M / _S / _I for FSPT / FSPM / FSPS /FSPI accordingly
1297 if '_T' in SignatureStr
[ 6 : 6 + 2 ]:
1298 TxtBody
. append ( "#define FSPT_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1299 elif '_M' in SignatureStr
[ 6 : 6 + 2 ]:
1300 TxtBody
. append ( "#define FSPM_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1301 elif '_S' in SignatureStr
[ 6 : 6 + 2 ]:
1302 TxtBody
. append ( "#define FSPS_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1303 elif '_I' in SignatureStr
[ 6 : 6 + 2 ]:
1305 TxtBody
. append ( "#define FSPI_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1306 TxtBody
. append ( " \n " )
1308 for Region
in [ 'UPD' ]:
1310 UpdSignature
= [ '0x545F' , '0x4D5F' , '0x535F' , '0x495F' ] #['_T', '_M', '_S', '_I'] signature for FSPT, FSPM, FSPS, FSPI
1311 UpdStructure
= [ 'FSPT_UPD' , 'FSPM_UPD' , 'FSPS_UPD' , 'FSPI_UPD' ]
1312 for Item
in self
._ CfgItemList
:
1313 if Item
[ "cname" ] == 'Signature' and Item
[ "value" ][ 0 : 6 ] in UpdSignature
:
1314 Item
[ "offset" ] = 0 # re-initialize offset to 0 when new UPD structure starting
1315 UpdOffsetTable
. append ( Item
[ "offset" ])
1317 for UpdIdx
in range ( len ( UpdOffsetTable
)):
1319 for Item
in self
._ CfgItemList
:
1320 if Item
[ "comment" ] != '' and Item
[ "offset" ] >= UpdOffsetTable
[ UpdIdx
]:
1321 MatchComment
= re
. match ( "^(U|V)PD_DATA_REGION:([\w|\W|\s]+)" , Item
[ "comment" ])
1322 if MatchComment
and MatchComment
. group ( 1 ) == Region
[ 0 ]:
1323 CommentLine
= " " + MatchComment
. group ( 2 ) + " \n "
1324 TxtBody
. append ( "/**" + CommentLine
+ "**/ \n " )
1325 elif Item
[ "offset" ] >= UpdOffsetTable
[ UpdIdx
] and Item
[ "comment" ] == '' :
1326 Match
= re
. match ( "^FSP([\w|\W|\s])_UPD" , UpdStructure
[ UpdIdx
])
1328 TxtBody
. append ( "/** Fsp " + Match
. group ( 1 ) + " UPD Configuration \n **/ \n " )
1329 TxtBody
. append ( "typedef struct { \n " )
1339 for Item
in self
._ CfgItemList
:
1340 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == UpdSignature
[ UpdIdx
] or Region
[ 0 ] == 'V' :
1344 if Item
[ 'cname' ] == 'UpdTerminator' :
1347 if Item
[ 'region' ] != Region
:
1350 if Item
[ "offset" ] < UpdOffsetTable
[ UpdIdx
]:
1353 NextVisible
= LastVisible
1355 if LastVisible
and ( Item
[ 'header' ] == 'OFF' ):
1357 ResvOffset
= Item
[ 'offset' ]
1358 elif ( not LastVisible
) and Item
[ 'header' ] == 'ON' :
1360 Name
= "Reserved" + Region
[ 0 ] + "pdSpace %d " % ResvIdx
1361 ResvIdx
= ResvIdx
+ 1
1362 TxtBody
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - ResvOffset
, ResvOffset
, '' , '' , '' , '' ))
1364 if Offset
< Item
[ "offset" ]:
1366 Name
= "Unused" + Region
[ 0 ] + "pdSpace %d " % SpaceIdx
1367 LineBuffer
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - Offset
, Offset
, '' , '' , '' , '' ))
1368 SpaceIdx
= SpaceIdx
+ 1
1369 Offset
= Item
[ "offset" ]
1371 LastVisible
= NextVisible
1373 Offset
= Offset
+ Item
[ "length" ]
1375 for Each
in LineBuffer
:
1376 TxtBody
. append ( Each
)
1378 Comment
= Item
[ "comment" ]
1379 Embed
= Item
[ "embed" ]. upper ()
1380 if Embed
. endswith ( ':START' ) or Embed
. endswith ( ':END' ):
1381 if not Comment
== '' and Embed
. endswith ( ':START' ):
1382 Marker
= '/* COMMENT: %s */ \n ' % Item
[ "comment" ]
1383 Marker
= Marker
+ '/* EMBED_STRUCT: %s */ ' % Item
[ "embed" ]
1385 Marker
= '/* EMBED_STRUCT: %s */ ' % Item
[ "embed" ]
1390 self
. Error
= "Invalid embedded structure format ' %s '! \n " % Item
[ "embed" ]
1392 Line
= Marker
+ self
. CreateField ( Item
, Item
[ "cname" ], Item
[ "length" ], Item
[ "offset" ], Item
[ 'struct' ], Item
[ 'name' ], Item
[ 'help' ], Item
[ 'option' ])
1393 TxtBody
. append ( Line
)
1394 if Item
[ 'cname' ] == 'UpdTerminator' :
1396 TxtBody
. append ( "} " + UpdStructure
[ UpdIdx
] + "; \n\n " )
1398 # Handle the embedded data structure
1399 TxtBody
= self
. PostProcessBody ( TxtBody
)
1401 HeaderTFileName
= 'FsptUpd.h'
1402 HeaderMFileName
= 'FspmUpd.h'
1403 HeaderSFileName
= 'FspsUpd.h'
1404 HeaderIFileName
= 'FspiUpd.h'
1406 UpdRegionCheck
= [ 'FSPT' , 'FSPM' , 'FSPS' , 'FSPI' ] # FSPX_UPD_REGION
1407 UpdConfigCheck
= [ 'FSP_T' , 'FSP_M' , 'FSP_S' , 'FSP_I' ] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1408 UpdSignatureCheck
= [ 'FSPT_UPD_SIGNATURE' , 'FSPM_UPD_SIGNATURE' , 'FSPS_UPD_SIGNATURE' , 'FSPI_UPD_SIGNATURE' ]
1409 ExcludedSpecificUpd
= [ 'FSPT_ARCH_UPD' , 'FSPM_ARCH_UPD' , 'FSPS_ARCH_UPD' , 'FSPI_ARCH_UPD' ]
1410 ExcludedSpecificUpd1
= [ 'FSPT_ARCH2_UPD' , 'FSPM_ARCH2_UPD' , 'FSPS_ARCH2_UPD' ]
1413 if InputHeaderFile
!= '' :
1414 if not os
. path
. exists ( InputHeaderFile
):
1415 self
. Error
= "Input header file ' %s ' does not exist" % InputHeaderFile
1418 InFd
= open ( InputHeaderFile
, "r" )
1419 IncLines
= InFd
. readlines ()
1422 for item
in range ( len ( UpdRegionCheck
)):
1423 if UpdRegionCheck
[ item
] == 'FSPT' :
1424 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderTFileName
), "w" )
1425 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderTFileName
))
1426 elif UpdRegionCheck
[ item
] == 'FSPM' :
1427 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderMFileName
), "w" )
1428 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderMFileName
))
1429 elif UpdRegionCheck
[ item
] == 'FSPS' :
1430 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderSFileName
), "w" )
1431 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderSFileName
))
1432 elif UpdRegionCheck
[ item
] == 'FSPI' :
1433 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderIFileName
), "w" )
1434 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderIFileName
))
1435 FileName
= FileBase
. replace ( "." , "_" ). upper ()
1436 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
1437 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
1438 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
1439 HeaderFd
. write ( "#include < %s > \n\n " % HeaderFileName
)
1440 HeaderFd
. write ( "#pragma pack(1) \n\n " )
1443 for Line
in IncLines
:
1444 Match
= re
. search ( "!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+" , Line
)
1446 if Match
. group ( 2 ) == "BEGIN" and Match
. group ( 1 ) == UpdRegionCheck
[ item
]:
1453 HeaderFd
. write ( Line
)
1454 HeaderFd
. write ( " \n " )
1460 StructStartWithComment
= []
1462 for Line
in TxtBody
:
1464 Match
= re
. match ( "(typedef struct {)" , Line
)
1466 StartIndex
= Index
- 1
1467 Match
= re
. match ( "}\s([_A-Z0-9]+);" , Line
)
1468 if Match
and ( UpdRegionCheck
[ item
] in Match
. group ( 1 ) or UpdConfigCheck
[ item
] in Match
. group ( 1 )) and ( ExcludedSpecificUpd
[ item
] not in Match
. group ( 1 )) and ( ExcludedSpecificUpd1
[ item
] not in Match
. group ( 1 )):
1470 StructStart
. append ( StartIndex
)
1471 StructEnd
. append ( EndIndex
)
1473 for Line
in TxtBody
:
1475 for Item
in range ( len ( StructStart
)):
1476 if Index
== StructStart
[ Item
]:
1477 Match
= re
. match ( "^(/\*\*\s*)" , Line
)
1479 StructStartWithComment
. append ( StructStart
[ Item
])
1481 StructStartWithComment
. append ( StructStart
[ Item
] + 1 )
1483 for Line
in TxtBody
:
1485 for Item
in range ( len ( StructStart
)):
1486 if Index
>= StructStartWithComment
[ Item
] and Index
<= StructEnd
[ Item
]:
1487 self
. WriteLinesWithoutTailingSpace ( HeaderFd
, Line
)
1488 HeaderFd
. write ( "#pragma pack() \n\n " )
1489 HeaderFd
. write ( "#endif \n " )
1492 HeaderFd
= open ( HeaderFile
, "w" )
1493 FileBase
= os
. path
. basename ( HeaderFile
)
1494 FileName
= FileBase
. replace ( "." , "_" ). upper ()
1495 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
1496 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
1497 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
1498 HeaderFd
. write ( "#include <FspEas.h> \n\n " )
1499 HeaderFd
. write ( "#pragma pack(1) \n\n " )
1501 for item
in range ( len ( UpdRegionCheck
)):
1506 StructStartWithComment
= []
1508 for Line
in TxtBody
:
1510 Match
= re
. match ( "(typedef struct {)" , Line
)
1512 StartIndex
= Index
- 1
1513 Match
= re
. match ( "#define\s([_A-Z0-9]+)\s*" , Line
)
1514 if Match
and ( UpdSignatureCheck
[ item
] in Match
. group ( 1 ) or UpdSignatureCheck
[ item
] in Match
. group ( 1 )):
1515 StructStart
. append ( Index
- 1 )
1516 StructEnd
. append ( Index
)
1518 for Line
in TxtBody
:
1520 for Item
in range ( len ( StructStart
)):
1521 if Index
== StructStart
[ Item
]:
1522 Match
= re
. match ( "^(/\*\*\s*)" , Line
)
1524 StructStartWithComment
. append ( StructStart
[ Item
])
1526 StructStartWithComment
. append ( StructStart
[ Item
] + 1 )
1528 for Line
in TxtBody
:
1530 for Item
in range ( len ( StructStart
)):
1531 if Index
>= StructStartWithComment
[ Item
] and Index
<= StructEnd
[ Item
]:
1532 self
. WriteLinesWithoutTailingSpace ( HeaderFd
, Line
)
1533 HeaderFd
. write ( "#pragma pack() \n\n " )
1534 HeaderFd
. write ( "#endif \n " )
1539 def WriteBsfStruct ( self
, BsfFd
, Item
):
1540 LogExpr
= CLogicalExpression ()
1541 if Item
[ 'type' ] == "None" :
1542 Space
= "gPlatformFspPkgTokenSpaceGuid"
1544 Space
= Item
[ 'space' ]
1545 Line
= " $ %s _ %s " % ( Space
, Item
[ 'cname' ])
1546 Match
= re
. match ( "\s*\{([x0-9a-fA-F,\s]+)\}\s*" , Item
[ 'value' ])
1548 DefaultValue
= Match
. group ( 1 ). strip ()
1550 DefaultValue
= Item
[ 'value' ]. strip ()
1551 if 'bitlength' in Item
:
1552 BsfFd
. write ( " %s%s% 4d bits $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'bitlength' ], DefaultValue
))
1554 BsfFd
. write ( " %s%s% 4d bytes $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'length' ], DefaultValue
))
1556 if Item
[ 'type' ] == "Combo" :
1557 if not Item
[ 'option' ] in self
._ BuidinOption
:
1558 OptList
= Item
[ 'option' ]. split ( ',' )
1559 for Option
in OptList
:
1560 Option
= Option
. strip ()
1561 ( OpVal
, OpStr
) = Option
. split ( ':' )
1562 test
= LogExpr
. getNumber ( OpVal
)
1564 raise Exception ( "Selection Index ' %s ' is not a number" % OpVal
)
1565 TmpList
. append (( OpVal
, OpStr
))
1568 def WriteBsfOption ( self
, BsfFd
, Item
):
1569 PcdName
= Item
[ 'space' ] + '_' + Item
[ 'cname' ]
1571 if Item
[ 'type' ] == "Combo" :
1572 if Item
[ 'option' ] in self
._ BuidinOption
:
1573 Options
= self
._ BuidinOption
[ Item
[ 'option' ]]
1576 BsfFd
. write ( ' %s $ %s , " %s ", & %s , \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ], Options
))
1578 elif Item
[ 'type' ]. startswith ( "EditNum" ):
1579 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' ])
1581 BsfFd
. write ( ' EditNum $ %s , " %s ", %s , \n ' % ( PcdName
, Item
[ 'name' ], Match
. group ( 1 )))
1583 elif Item
[ 'type' ]. startswith ( "EditText" ):
1584 BsfFd
. write ( ' %s $ %s , " %s ", \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]))
1586 elif Item
[ 'type' ] == "Table" :
1587 Columns
= Item
[ 'option' ]. split ( ',' )
1588 if len ( Columns
) != 0 :
1589 BsfFd
. write ( ' %s $ %s " %s ",' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]))
1591 Fmt
= Col
. split ( ':' )
1593 raise Exception ( "Column format ' %s ' is invalid !" % Fmt
)
1595 Dtype
= int ( Fmt
[ 1 ]. strip ())
1597 raise Exception ( "Column size ' %s ' is invalid !" % Fmt
[ 1 ])
1598 BsfFd
. write ( ' \n Column " %s ", %d bytes, %s ' % ( Fmt
[ 0 ]. strip (), Dtype
, Fmt
[ 2 ]. strip ()))
1603 HelpLines
= Item
[ 'help' ]. split ( ' \\ n \\ r' )
1605 for HelpLine
in HelpLines
:
1608 BsfFd
. write ( ' Help " %s " \n ' % ( HelpLine
))
1610 BsfFd
. write ( ' " %s " \n ' % ( HelpLine
))
1612 BsfFd
. write ( ' "Valid range: %s ~ %s " \n ' % ( Match
. group ( 2 ), Match
. group ( 3 )))
1614 def GenerateBsfFile ( self
, BsfFile
):
1617 self
. Error
= "BSF output file ' %s ' is invalid" % BsfFile
1620 if ( self
. NoDscFileChange ( BsfFile
)):
1621 # DSC has not been modified yet
1622 # So don't have to re-generate other files
1623 self
. Error
= 'No DSC file change, skip to create UPD BSF file'
1628 BsfFd
= open ( BsfFile
, "w" )
1629 BsfFd
. write ( " %s \n " % ( __copyright_bsf__
% date
. today (). year
))
1630 BsfFd
. write ( " %s \n " % self
._ GlobalDataDef
)
1631 BsfFd
. write ( "StructDef \n " )
1633 for Item
in self
._ CfgItemList
:
1634 if Item
[ 'find' ] != '' :
1635 BsfFd
. write ( ' \n Find " %s " \n ' % Item
[ 'find' ])
1636 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1637 if Item
[ 'name' ] != '' :
1638 if NextOffset
!= Item
[ 'offset' ]:
1639 BsfFd
. write ( " Skip %d bytes \n " % ( Item
[ 'offset' ] - NextOffset
))
1640 if len ( Item
[ 'subreg' ]) > 0 :
1641 NextOffset
= Item
[ 'offset' ]
1642 BitsOffset
= NextOffset
* 8
1643 for SubItem
in Item
[ 'subreg' ]:
1644 BitsOffset
+= SubItem
[ 'bitlength' ]
1645 if SubItem
[ 'name' ] == '' :
1646 if 'bitlength' in SubItem
:
1647 BsfFd
. write ( " Skip %d bits \n " % ( SubItem
[ 'bitlength' ]))
1649 BsfFd
. write ( " Skip %d bytes \n " % ( SubItem
[ 'length' ]))
1651 Options
= self
. WriteBsfStruct ( BsfFd
, SubItem
)
1652 if len ( Options
) > 0 :
1653 OptionDict
[ SubItem
[ 'space' ]+ '_' + SubItem
[ 'cname' ]] = Options
1655 NextBitsOffset
= ( Item
[ 'offset' ] + Item
[ 'length' ]) * 8
1656 if NextBitsOffset
> BitsOffset
:
1657 BitsGap
= NextBitsOffset
- BitsOffset
1658 BitsRemain
= BitsGap
% 8
1660 BsfFd
. write ( " Skip %d bits \n " % BitsRemain
)
1661 BitsGap
-= BitsRemain
1662 BytesRemain
= int ( BitsGap
/ 8 )
1664 BsfFd
. write ( " Skip %d bytes \n " % BytesRemain
)
1665 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1667 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1668 Options
= self
. WriteBsfStruct ( BsfFd
, Item
)
1669 if len ( Options
) > 0 :
1670 OptionDict
[ Item
[ 'space' ]+ '_' + Item
[ 'cname' ]] = Options
1671 BsfFd
. write ( " \n EndStruct \n\n " )
1673 BsfFd
. write ( " %s " % self
._ BuidinOptionTxt
)
1675 for Each
in OptionDict
:
1676 BsfFd
. write ( "List & %s \n " % Each
)
1677 for Item
in OptionDict
[ Each
]:
1678 BsfFd
. write ( ' Selection %s , " %s " \n ' % ( Item
[ 0 ], Item
[ 1 ]))
1679 BsfFd
. write ( "EndList \n\n " )
1681 BsfFd
. write ( "BeginInfoBlock \n " )
1682 BsfFd
. write ( ' PPVer " %s " \n ' % ( self
._ CfgBlkDict
[ 'ver' ]))
1683 BsfFd
. write ( ' Description " %s " \n ' % ( self
._ CfgBlkDict
[ 'name' ]))
1684 BsfFd
. write ( "EndInfoBlock \n\n " )
1686 for Each
in self
._ CfgPageDict
:
1687 BsfFd
. write ( 'Page " %s " \n ' % self
._ CfgPageDict
[ Each
])
1689 for Item
in self
._ CfgItemList
:
1690 if Item
[ 'name' ] != '' :
1691 if Item
[ 'page' ] != Each
:
1693 if len ( Item
[ 'subreg' ]) > 0 :
1694 for SubItem
in Item
[ 'subreg' ]:
1695 if SubItem
[ 'name' ] != '' :
1696 BsfItems
. append ( SubItem
)
1698 BsfItems
. append ( Item
)
1700 BsfItems
. sort ( key
= lambda x
: x
[ 'order' ])
1702 for Item
in BsfItems
:
1703 self
. WriteBsfOption ( BsfFd
, Item
)
1704 BsfFd
. write ( "EndPage \n\n " )
1711 print ( "GenCfgOpt Version 0.59" )
1713 print ( " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]" )
1714 print ( " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]" )
1715 print ( " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]" )
1719 # Parse the options and args
1723 GenCfgOpt
= CGenCfgOpt ()
1724 while i
< len ( sys
. argv
):
1725 if sys
. argv
[ i
]. strip (). lower () == "--pcd" :
1726 BuildOptionPcd
. append ( sys
. argv
[ i
+ 1 ])
1729 argc
= len ( sys
. argv
)
1734 DscFile
= sys
. argv
[ 2 ]
1735 if not os
. path
. exists ( DscFile
):
1736 print ( "ERROR: Cannot open DSC file ' %s ' !" % DscFile
)
1741 if sys
. argv
[ 4 ][ 0 ] == '-' :
1744 OutFile
= sys
. argv
[ 4 ]
1747 if GenCfgOpt
. ParseMacros ( sys
. argv
[ Start
:]) != 0 :
1748 print ( "ERROR: Macro parsing failed !" )
1752 if not os
. path
. exists ( FvDir
):
1755 if GenCfgOpt
. ParseDscFile ( DscFile
, FvDir
) != 0 :
1756 print ( "ERROR: %s !" % GenCfgOpt
. Error
)
1759 if GenCfgOpt
. UpdateSubRegionDefaultValue () != 0 :
1760 print ( "ERROR: %s !" % GenCfgOpt
. Error
)
1763 if sys
. argv
[ 1 ] == "UPDTXT" :
1764 Ret
= GenCfgOpt
. CreateSplitUpdTxt ( OutFile
)
1766 # No change is detected
1768 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1770 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1772 elif sys
. argv
[ 1 ] == "HEADER" :
1773 Ret
= GenCfgOpt
. CreateHeaderFile ( OutFile
)
1775 # No change is detected
1777 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1779 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1782 elif sys
. argv
[ 1 ] == "GENBSF" :
1783 Ret
= GenCfgOpt
. GenerateBsfFile ( OutFile
)
1785 # No change is detected
1787 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1789 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1796 print ( "ERROR: Unknown command ' %s ' !" % sys
. argv
[ 1 ])
1803 if __name__
== '__main__' :