]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/GenCfgOpt.py
128b8965926caf390c8a0aca8297c6e65a42773e
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
:
962 self
. Error
= " %s definition is missing in DSC file" % ( GuidList
[ Index
])
966 UpdTxtFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ GuidList
[ Index
]] + '.txt' )
968 if ( self
. NoDscFileChange ( UpdTxtFile
)):
969 # DSC has not been modified yet
970 # So don't have to re-generate other files
971 self
. Error
= 'No DSC file change, skip to create UPD TXT file'
974 TxtFd
= open ( UpdTxtFile
, "w" )
975 TxtFd
. write ( " %s \n " % ( __copyright_txt__
% date
. today (). year
))
983 for Item
in self
._ CfgItemList
:
984 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == SignatureList
[ Index
]:
985 StartAddr
= Item
[ 'offset' ]
986 NextOffset
= StartAddr
988 if Item
[ 'cname' ] == 'UpdTerminator' and InRange
== True :
989 EndAddr
= Item
[ 'offset' ]
992 for Item
in self
._ CfgItemList
:
993 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == SignatureList
[ Index
]:
997 if Item
[ 'cname' ] == 'UpdTerminator' :
999 if Item
[ 'region' ] != 'UPD' :
1001 Offset
= Item
[ 'offset' ]
1002 if StartAddr
> Offset
or EndAddr
< Offset
:
1004 if NextOffset
< Offset
:
1006 TxtFd
. write ( " %s .UnusedUpdSpace %d | %s0x%0 4X|0x %0 4X| {0} \n " % ( Item
[ 'space' ], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
1007 SpaceIdx
= SpaceIdx
+ 1
1008 NextOffset
= Offset
+ Item
[ 'length' ]
1009 TxtFd
. write ( " %s . %s | %s0x%0 4X| %s | %s \n " % ( Item
[ 'space' ], Item
[ 'cname' ], Default
, Item
[ 'offset' ] - StartAddr
, Item
[ 'length' ], Item
[ 'value' ]))
1013 def CreateVarDict ( self
):
1016 if len ( self
._ CfgItemList
) > 0 :
1017 Item
= self
._ CfgItemList
[- 1 ]
1018 self
._ VarDict
[ '_LENGTH_' ] = ' %d ' % ( Item
[ 'offset' ] + Item
[ 'length' ])
1019 for Item
in self
._ CfgItemList
:
1020 Embed
= Item
[ 'embed' ]
1021 Match
= re
. match ( "^(\w+):(\w+):(START|END)" , Embed
)
1023 StructName
= Match
. group ( 1 )
1024 VarName
= '_ %s _ %s _' % ( Match
. group ( 3 ), StructName
)
1025 if Match
. group ( 3 ) == 'END' :
1026 self
._ VarDict
[ VarName
] = Item
[ 'offset' ] + Item
[ 'length' ]
1027 self
._ VarDict
[ '_LENGTH_ %s _' % StructName
] = \
1028 self
._ VarDict
[ '_END_ %s _' % StructName
] - self
._ VarDict
[ '_START_ %s _' % StructName
]
1029 if Match
. group ( 2 ). startswith ( 'TAG_' ):
1030 if ( self
. Mode
!= 'FSP' ) and ( self
._ VarDict
[ '_LENGTH_ %s _' % StructName
] % 4 ):
1031 raise Exception ( "Size of structure ' %s ' is %d , not DWORD aligned !" % ( StructName
, self
._ VarDict
[ '_LENGTH_ %s _' % StructName
]))
1032 self
._ VarDict
[ '_TAG_ %s _' % StructName
] = int ( Match
. group ( 2 )[ 4 :], 16 ) & 0xFFF
1034 self
._ VarDict
[ VarName
] = Item
[ 'offset' ]
1036 self
._ VarDict
[ '_OFFSET_ %s _' % Item
[ 'marker' ]. strip ()] = Item
[ 'offset' ]
1039 def UpdateBsfBitUnit ( self
, Item
):
1044 UnitDec
= { 1 : 'BYTE' , 2 : 'WORD' , 4 : 'DWORD' , 8 : 'QWORD' }
1045 for Idx
, SubItem
in enumerate ( Item
[ 'subreg' ]):
1047 Unit
= SubItem
[ 'bitunit' ]
1048 BitLength
= SubItem
[ 'bitlength' ]
1049 BitTotal
+= BitLength
1050 BitOffset
+= BitLength
1052 if BitOffset
> 64 or BitOffset
> Unit
* 8 :
1055 if BitOffset
== Unit
* 8 :
1056 for SubIdx
in range ( StartIdx
, Idx
+ 1 ):
1057 Item
[ 'subreg' ][ SubIdx
][ 'bitunit' ] = Unit
1063 raise Exception ( "Bit fields cannot fit into %s for ' %s . %s ' !" % ( UnitDec
[ Unit
], Item
[ 'cname' ], SubItem
[ 'cname' ]))
1065 ExpectedTotal
= Item
[ 'length' ] * 8
1066 if Item
[ 'length' ] * 8 != BitTotal
:
1067 raise Exception ( "Bit fields total length ( %d ) does not match length ( %d ) of ' %s ' !" % ( BitTotal
, ExpectedTotal
, Item
[ 'cname' ]))
1069 def UpdateDefaultValue ( self
):
1071 for Idx
, Item
in enumerate ( self
._ CfgItemList
):
1072 if len ( Item
[ 'subreg' ]) == 0 :
1073 Value
= Item
[ 'value' ]
1074 if ( len ( Value
) > 0 ) and ( Value
[ 0 ] == '{' or Value
[ 0 ] == "'" or Value
[ 0 ] == '"' ):
1075 # {XXX} or 'XXX' strings
1076 self
. FormatListValue ( self
._ CfgItemList
[ Idx
])
1078 Match
= re
. match ( "(0x[0-9a-fA-F]+|[0-9]+)" , Value
)
1080 NumValue
= self
. EvaluateExpress ( Value
)
1081 Item
[ 'value' ] = '0x %X ' % NumValue
1083 ValArray
= self
. ValueToByteArray ( Item
[ 'value' ], Item
[ 'length' ])
1084 for SubItem
in Item
[ 'subreg' ]:
1085 SubItem
[ 'value' ] = self
. GetBsfBitFields ( SubItem
, ValArray
)
1086 self
. UpdateBsfBitUnit ( Item
)
1089 def ProcessMultilines ( self
, String
, MaxCharLength
):
1091 StringLength
= len ( String
)
1092 CurrentStringStart
= 0
1095 if len ( String
) <= MaxCharLength
:
1096 while ( StringOffset
< StringLength
):
1097 if StringOffset
>= 1 :
1098 if String
[ StringOffset
- 1 ] == ' \\ ' and String
[ StringOffset
] == 'n' :
1099 BreakLineDict
. append ( StringOffset
+ 1 )
1101 if BreakLineDict
!= []:
1102 for Each
in BreakLineDict
:
1103 Multilines
+= " %s \n " % String
[ CurrentStringStart
: Each
]. lstrip ()
1104 CurrentStringStart
= Each
1105 if StringLength
- CurrentStringStart
> 0 :
1106 Multilines
+= " %s \n " % String
[ CurrentStringStart
:]. lstrip ()
1108 Multilines
= " %s \n " % String
1112 FoundSpaceChar
= False
1113 while ( StringOffset
< StringLength
):
1114 if StringOffset
>= 1 :
1115 if NewLineCount
>= MaxCharLength
- 1 :
1116 if String
[ StringOffset
] == ' ' and StringLength
- StringOffset
> 10 :
1117 BreakLineDict
. append ( NewLineStart
+ NewLineCount
)
1118 NewLineStart
= NewLineStart
+ NewLineCount
1120 FoundSpaceChar
= True
1121 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False :
1122 BreakLineDict
. append ( 0 )
1123 if String
[ StringOffset
- 1 ] == ' \\ ' and String
[ StringOffset
] == 'n' :
1124 BreakLineDict
. append ( StringOffset
+ 1 )
1125 NewLineStart
= StringOffset
+ 1
1129 if BreakLineDict
!= []:
1130 BreakLineDict
. sort ()
1131 for Each
in BreakLineDict
:
1133 Multilines
+= " %s \n " % String
[ CurrentStringStart
: Each
]. lstrip ()
1134 CurrentStringStart
= Each
1135 if StringLength
- CurrentStringStart
> 0 :
1136 Multilines
+= " %s \n " % String
[ CurrentStringStart
:]. lstrip ()
1139 def CreateField ( self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
, BitsLength
= None ):
1146 if Length
== 0 and Name
== 'Dummy' :
1150 if Length
in [ 1 , 2 , 4 , 8 ]:
1151 Type
= "UINT %d " % ( Length
* 8 )
1152 if Name
. startswith ( "UnusedUpdSpace" ) and Length
!= 1 :
1159 if Item
and Item
[ 'value' ]. startswith ( '{' ):
1165 if Struct
in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
1167 Unit
= int ( Type
[ 4 :]) / 8
1168 Length
= Length
/ Unit
1173 Name
= Name
+ '[ %d ]' % Length
1175 if len ( Type
) < PosName
:
1176 Space1
= PosName
- len ( Type
)
1181 NameLine
= " - %s \n " % BsfName
1186 HelpLine
= self
. ProcessMultilines ( Help
, 80 )
1189 OptionLine
= self
. ProcessMultilines ( Option
, 80 )
1194 OffsetStr
= '0x %0 4X' % Offset
1196 if BitsLength
is None :
1199 BitsLength
= ' : %d ' % BitsLength
1201 return " \n /** Offset %s%s%s%s **/ \n %s%s%s%s ; \n " % ( OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
, BitsLength
)
1203 def PostProcessBody ( self
, TextBody
):
1209 IsUpdHdrDefined
= False
1211 for Line
in TextBody
:
1212 SplitToLines
= Line
. splitlines ()
1213 MatchComment
= re
. match ( "^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)" , SplitToLines
[ 0 ])
1215 if MatchComment
. group ( 1 ) == 'FSP_UPD_HEADER' :
1219 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1220 CommentLine
= " " + MatchComment
. group ( 2 ) + " \n "
1221 NewTextBody
. append ( "/**" + CommentLine
+ "**/ \n " )
1222 Line
= Line
[( len ( SplitToLines
[ 0 ]) + 1 ):]
1224 Match
= re
. match ( "^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)" , Line
)
1226 Line
= Match
. group ( 4 )
1227 if Match
. group ( 1 ) == 'FSP_UPD_HEADER' :
1232 if Match
and Match
. group ( 3 ) == 'START' :
1233 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1234 NewTextBody
. append ( 'typedef struct { \n ' )
1235 StructName
= Match
. group ( 1 )
1236 VariableName
= Match
. group ( 2 )
1237 MatchOffset
= re
. search ( '/\*\*\sOffset\s0x([a-fA-F0-9]+)' , Line
)
1239 Offset
= int ( MatchOffset
. group ( 1 ), 16 )
1244 OldTextBody
. append ( self
. CreateField ( None , VariableName
, 0 , Offset
, StructName
, '' , '' , '' ))
1246 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1247 NewTextBody
. append ( Line
)
1249 OldTextBody
. append ( Line
)
1251 if Match
and Match
. group ( 3 ) == 'END' :
1252 if ( StructName
!= Match
. group ( 1 )) or ( VariableName
!= Match
. group ( 2 )):
1253 print ( "Unmatched struct name ' %s ' and ' %s ' !" % ( StructName
, Match
. group ( 1 )))
1255 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True :
1256 NewTextBody
. append ( '} %s ; \n\n ' % StructName
)
1257 IsUpdHdrDefined
= True
1259 NewTextBody
. extend ( OldTextBody
)
1262 def WriteLinesWithoutTailingSpace ( self
, HeaderFd
, Line
):
1263 TxtBody2
= Line
. splitlines ( True )
1264 for Line2
in TxtBody2
:
1265 Line2
= Line2
. rstrip ()
1267 HeaderFd
. write ( Line2
)
1269 def CreateHeaderFile ( self
, InputHeaderFile
):
1272 HeaderFileName
= 'FspUpd.h'
1273 HeaderFile
= os
. path
. join ( FvDir
, HeaderFileName
)
1275 # Check if header needs to be recreated
1276 if ( self
. NoDscFileChange ( HeaderFile
)):
1277 # DSC has not been modified yet
1278 # So don't have to re-generate other files
1279 self
. Error
= 'No DSC file change, skip to create UPD header file'
1283 for Item
in self
._ CfgItemList
:
1284 if str ( Item
[ 'cname' ]) == 'Signature' and Item
[ 'length' ] == 8 :
1285 Value
= int ( Item
[ 'value' ], 16 )
1288 Chars
. append ( chr ( Value
& 0xFF ))
1290 SignatureStr
= '' . join ( Chars
)
1291 # Signature will be _T / _M / _S / _I for FSPT / FSPM / FSPS /FSPI accordingly
1292 if '_T' in SignatureStr
[ 6 : 6 + 2 ]:
1293 TxtBody
. append ( "#define FSPT_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1294 elif '_M' in SignatureStr
[ 6 : 6 + 2 ]:
1295 TxtBody
. append ( "#define FSPM_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1296 elif '_S' in SignatureStr
[ 6 : 6 + 2 ]:
1297 TxtBody
. append ( "#define FSPS_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1298 elif '_I' in SignatureStr
[ 6 : 6 + 2 ]:
1299 TxtBody
. append ( "#define FSPI_UPD_SIGNATURE %s /* ' %s ' */ \n\n " % ( Item
[ 'value' ], SignatureStr
))
1300 TxtBody
. append ( " \n " )
1302 for Region
in [ 'UPD' ]:
1304 UpdSignature
= [ '0x545F' , '0x4D5F' , '0x535F' , '0x495F' ] #['_T', '_M', '_S', '_I'] signature for FSPT, FSPM, FSPS, FSPI
1305 UpdStructure
= [ 'FSPT_UPD' , 'FSPM_UPD' , 'FSPS_UPD' , 'FSPI_UPD' ]
1306 for Item
in self
._ CfgItemList
:
1307 if Item
[ "cname" ] == 'Signature' and Item
[ "value" ][ 0 : 6 ] in UpdSignature
:
1308 Item
[ "offset" ] = 0 # re-initialize offset to 0 when new UPD structure starting
1309 UpdOffsetTable
. append ( Item
[ "offset" ])
1311 for UpdIdx
in range ( len ( UpdOffsetTable
)):
1313 for Item
in self
._ CfgItemList
:
1314 if Item
[ "comment" ] != '' and Item
[ "offset" ] >= UpdOffsetTable
[ UpdIdx
]:
1315 MatchComment
= re
. match ( "^(U|V)PD_DATA_REGION:([\w|\W|\s]+)" , Item
[ "comment" ])
1316 if MatchComment
and MatchComment
. group ( 1 ) == Region
[ 0 ]:
1317 CommentLine
= " " + MatchComment
. group ( 2 ) + " \n "
1318 TxtBody
. append ( "/**" + CommentLine
+ "**/ \n " )
1319 elif Item
[ "offset" ] >= UpdOffsetTable
[ UpdIdx
] and Item
[ "comment" ] == '' :
1320 Match
= re
. match ( "^FSP([\w|\W|\s])_UPD" , UpdStructure
[ UpdIdx
])
1322 TxtBody
. append ( "/** Fsp " + Match
. group ( 1 ) + " UPD Configuration \n **/ \n " )
1323 TxtBody
. append ( "typedef struct { \n " )
1333 for Item
in self
._ CfgItemList
:
1334 if Item
[ 'cname' ] == 'Signature' and str ( Item
[ 'value' ])[ 0 : 6 ] == UpdSignature
[ UpdIdx
] or Region
[ 0 ] == 'V' :
1338 if Item
[ 'cname' ] == 'UpdTerminator' :
1341 if Item
[ 'region' ] != Region
:
1344 if Item
[ "offset" ] < UpdOffsetTable
[ UpdIdx
]:
1347 NextVisible
= LastVisible
1349 if LastVisible
and ( Item
[ 'header' ] == 'OFF' ):
1351 ResvOffset
= Item
[ 'offset' ]
1352 elif ( not LastVisible
) and Item
[ 'header' ] == 'ON' :
1354 Name
= "Reserved" + Region
[ 0 ] + "pdSpace %d " % ResvIdx
1355 ResvIdx
= ResvIdx
+ 1
1356 TxtBody
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - ResvOffset
, ResvOffset
, '' , '' , '' , '' ))
1358 if Offset
< Item
[ "offset" ]:
1360 Name
= "Unused" + Region
[ 0 ] + "pdSpace %d " % SpaceIdx
1361 LineBuffer
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - Offset
, Offset
, '' , '' , '' , '' ))
1362 SpaceIdx
= SpaceIdx
+ 1
1363 Offset
= Item
[ "offset" ]
1365 LastVisible
= NextVisible
1367 Offset
= Offset
+ Item
[ "length" ]
1369 for Each
in LineBuffer
:
1370 TxtBody
. append ( Each
)
1372 Comment
= Item
[ "comment" ]
1373 Embed
= Item
[ "embed" ]. upper ()
1374 if Embed
. endswith ( ':START' ) or Embed
. endswith ( ':END' ):
1375 if not Comment
== '' and Embed
. endswith ( ':START' ):
1376 Marker
= '/* COMMENT: %s */ \n ' % Item
[ "comment" ]
1377 Marker
= Marker
+ '/* EMBED_STRUCT: %s */ ' % Item
[ "embed" ]
1379 Marker
= '/* EMBED_STRUCT: %s */ ' % Item
[ "embed" ]
1384 self
. Error
= "Invalid embedded structure format ' %s '! \n " % Item
[ "embed" ]
1386 Line
= Marker
+ self
. CreateField ( Item
, Item
[ "cname" ], Item
[ "length" ], Item
[ "offset" ], Item
[ 'struct' ], Item
[ 'name' ], Item
[ 'help' ], Item
[ 'option' ])
1387 TxtBody
. append ( Line
)
1388 if Item
[ 'cname' ] == 'UpdTerminator' :
1390 TxtBody
. append ( "} " + UpdStructure
[ UpdIdx
] + "; \n\n " )
1392 # Handle the embedded data structure
1393 TxtBody
= self
. PostProcessBody ( TxtBody
)
1395 HeaderTFileName
= 'FsptUpd.h'
1396 HeaderMFileName
= 'FspmUpd.h'
1397 HeaderSFileName
= 'FspsUpd.h'
1398 HeaderIFileName
= 'FspiUpd.h'
1400 UpdRegionCheck
= [ 'FSPT' , 'FSPM' , 'FSPS' , 'FSPI' ] # FSPX_UPD_REGION
1401 UpdConfigCheck
= [ 'FSP_T' , 'FSP_M' , 'FSP_S' , 'FSP_I' ] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1402 UpdSignatureCheck
= [ 'FSPT_UPD_SIGNATURE' , 'FSPM_UPD_SIGNATURE' , 'FSPS_UPD_SIGNATURE' , 'FSPI_UPD_SIGNATURE' ]
1403 ExcludedSpecificUpd
= [ 'FSPT_ARCH_UPD' , 'FSPM_ARCH_UPD' , 'FSPS_ARCH_UPD' , 'FSPI_ARCH_UPD' ]
1404 ExcludedSpecificUpd1
= [ 'FSPT_ARCH2_UPD' , 'FSPM_ARCH2_UPD' , 'FSPS_ARCH2_UPD' ]
1407 if InputHeaderFile
!= '' :
1408 if not os
. path
. exists ( InputHeaderFile
):
1409 self
. Error
= "Input header file ' %s ' does not exist" % InputHeaderFile
1412 InFd
= open ( InputHeaderFile
, "r" )
1413 IncLines
= InFd
. readlines ()
1416 for item
in range ( len ( UpdRegionCheck
)):
1417 if UpdRegionCheck
[ item
] == 'FSPT' :
1418 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderTFileName
), "w" )
1419 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderTFileName
))
1420 elif UpdRegionCheck
[ item
] == 'FSPM' :
1421 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderMFileName
), "w" )
1422 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderMFileName
))
1423 elif UpdRegionCheck
[ item
] == 'FSPS' :
1424 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderSFileName
), "w" )
1425 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderSFileName
))
1426 elif UpdRegionCheck
[ item
] == 'FSPI' :
1427 HeaderFd
= open ( os
. path
. join ( FvDir
, HeaderIFileName
), "w" )
1428 FileBase
= os
. path
. basename ( os
. path
. join ( FvDir
, HeaderIFileName
))
1429 FileName
= FileBase
. replace ( "." , "_" ). upper ()
1430 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
1431 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
1432 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
1433 HeaderFd
. write ( "#include < %s > \n\n " % HeaderFileName
)
1434 HeaderFd
. write ( "#pragma pack(1) \n\n " )
1437 for Line
in IncLines
:
1438 Match
= re
. search ( "!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+" , Line
)
1440 if Match
. group ( 2 ) == "BEGIN" and Match
. group ( 1 ) == UpdRegionCheck
[ item
]:
1447 HeaderFd
. write ( Line
)
1448 HeaderFd
. write ( " \n " )
1454 StructStartWithComment
= []
1456 for Line
in TxtBody
:
1458 Match
= re
. match ( "(typedef struct {)" , Line
)
1460 StartIndex
= Index
- 1
1461 Match
= re
. match ( "}\s([_A-Z0-9]+);" , Line
)
1462 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 )):
1464 StructStart
. append ( StartIndex
)
1465 StructEnd
. append ( EndIndex
)
1467 for Line
in TxtBody
:
1469 for Item
in range ( len ( StructStart
)):
1470 if Index
== StructStart
[ Item
]:
1471 Match
= re
. match ( "^(/\*\*\s*)" , Line
)
1473 StructStartWithComment
. append ( StructStart
[ Item
])
1475 StructStartWithComment
. append ( StructStart
[ Item
] + 1 )
1477 for Line
in TxtBody
:
1479 for Item
in range ( len ( StructStart
)):
1480 if Index
>= StructStartWithComment
[ Item
] and Index
<= StructEnd
[ Item
]:
1481 self
. WriteLinesWithoutTailingSpace ( HeaderFd
, Line
)
1482 HeaderFd
. write ( "#pragma pack() \n\n " )
1483 HeaderFd
. write ( "#endif \n " )
1486 HeaderFd
= open ( HeaderFile
, "w" )
1487 FileBase
= os
. path
. basename ( HeaderFile
)
1488 FileName
= FileBase
. replace ( "." , "_" ). upper ()
1489 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
1490 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
1491 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
1492 HeaderFd
. write ( "#include <FspEas.h> \n\n " )
1493 HeaderFd
. write ( "#pragma pack(1) \n\n " )
1495 for item
in range ( len ( UpdRegionCheck
)):
1500 StructStartWithComment
= []
1502 for Line
in TxtBody
:
1504 Match
= re
. match ( "(typedef struct {)" , Line
)
1506 StartIndex
= Index
- 1
1507 Match
= re
. match ( "#define\s([_A-Z0-9]+)\s*" , Line
)
1508 if Match
and ( UpdSignatureCheck
[ item
] in Match
. group ( 1 ) or UpdSignatureCheck
[ item
] in Match
. group ( 1 )):
1509 StructStart
. append ( Index
- 1 )
1510 StructEnd
. append ( Index
)
1512 for Line
in TxtBody
:
1514 for Item
in range ( len ( StructStart
)):
1515 if Index
== StructStart
[ Item
]:
1516 Match
= re
. match ( "^(/\*\*\s*)" , Line
)
1518 StructStartWithComment
. append ( StructStart
[ Item
])
1520 StructStartWithComment
. append ( StructStart
[ Item
] + 1 )
1522 for Line
in TxtBody
:
1524 for Item
in range ( len ( StructStart
)):
1525 if Index
>= StructStartWithComment
[ Item
] and Index
<= StructEnd
[ Item
]:
1526 self
. WriteLinesWithoutTailingSpace ( HeaderFd
, Line
)
1527 HeaderFd
. write ( "#pragma pack() \n\n " )
1528 HeaderFd
. write ( "#endif \n " )
1533 def WriteBsfStruct ( self
, BsfFd
, Item
):
1534 LogExpr
= CLogicalExpression ()
1535 if Item
[ 'type' ] == "None" :
1536 Space
= "gPlatformFspPkgTokenSpaceGuid"
1538 Space
= Item
[ 'space' ]
1539 Line
= " $ %s _ %s " % ( Space
, Item
[ 'cname' ])
1540 Match
= re
. match ( "\s*\{([x0-9a-fA-F,\s]+)\}\s*" , Item
[ 'value' ])
1542 DefaultValue
= Match
. group ( 1 ). strip ()
1544 DefaultValue
= Item
[ 'value' ]. strip ()
1545 if 'bitlength' in Item
:
1546 BsfFd
. write ( " %s%s% 4d bits $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'bitlength' ], DefaultValue
))
1548 BsfFd
. write ( " %s%s% 4d bytes $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'length' ], DefaultValue
))
1550 if Item
[ 'type' ] == "Combo" :
1551 if not Item
[ 'option' ] in self
._ BuidinOption
:
1552 OptList
= Item
[ 'option' ]. split ( ',' )
1553 for Option
in OptList
:
1554 Option
= Option
. strip ()
1555 ( OpVal
, OpStr
) = Option
. split ( ':' )
1556 test
= LogExpr
. getNumber ( OpVal
)
1558 raise Exception ( "Selection Index ' %s ' is not a number" % OpVal
)
1559 TmpList
. append (( OpVal
, OpStr
))
1562 def WriteBsfOption ( self
, BsfFd
, Item
):
1563 PcdName
= Item
[ 'space' ] + '_' + Item
[ 'cname' ]
1565 if Item
[ 'type' ] == "Combo" :
1566 if Item
[ 'option' ] in self
._ BuidinOption
:
1567 Options
= self
._ BuidinOption
[ Item
[ 'option' ]]
1570 BsfFd
. write ( ' %s $ %s , " %s ", & %s , \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ], Options
))
1572 elif Item
[ 'type' ]. startswith ( "EditNum" ):
1573 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' ])
1575 BsfFd
. write ( ' EditNum $ %s , " %s ", %s , \n ' % ( PcdName
, Item
[ 'name' ], Match
. group ( 1 )))
1577 elif Item
[ 'type' ]. startswith ( "EditText" ):
1578 BsfFd
. write ( ' %s $ %s , " %s ", \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]))
1580 elif Item
[ 'type' ] == "Table" :
1581 Columns
= Item
[ 'option' ]. split ( ',' )
1582 if len ( Columns
) != 0 :
1583 BsfFd
. write ( ' %s $ %s " %s ",' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]))
1585 Fmt
= Col
. split ( ':' )
1587 raise Exception ( "Column format ' %s ' is invalid !" % Fmt
)
1589 Dtype
= int ( Fmt
[ 1 ]. strip ())
1591 raise Exception ( "Column size ' %s ' is invalid !" % Fmt
[ 1 ])
1592 BsfFd
. write ( ' \n Column " %s ", %d bytes, %s ' % ( Fmt
[ 0 ]. strip (), Dtype
, Fmt
[ 2 ]. strip ()))
1597 HelpLines
= Item
[ 'help' ]. split ( ' \\ n \\ r' )
1599 for HelpLine
in HelpLines
:
1602 BsfFd
. write ( ' Help " %s " \n ' % ( HelpLine
))
1604 BsfFd
. write ( ' " %s " \n ' % ( HelpLine
))
1606 BsfFd
. write ( ' "Valid range: %s ~ %s " \n ' % ( Match
. group ( 2 ), Match
. group ( 3 )))
1608 def GenerateBsfFile ( self
, BsfFile
):
1611 self
. Error
= "BSF output file ' %s ' is invalid" % BsfFile
1614 if ( self
. NoDscFileChange ( BsfFile
)):
1615 # DSC has not been modified yet
1616 # So don't have to re-generate other files
1617 self
. Error
= 'No DSC file change, skip to create UPD BSF file'
1622 BsfFd
= open ( BsfFile
, "w" )
1623 BsfFd
. write ( " %s \n " % ( __copyright_bsf__
% date
. today (). year
))
1624 BsfFd
. write ( " %s \n " % self
._ GlobalDataDef
)
1625 BsfFd
. write ( "StructDef \n " )
1627 for Item
in self
._ CfgItemList
:
1628 if Item
[ 'find' ] != '' :
1629 BsfFd
. write ( ' \n Find " %s " \n ' % Item
[ 'find' ])
1630 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1631 if Item
[ 'name' ] != '' :
1632 if NextOffset
!= Item
[ 'offset' ]:
1633 BsfFd
. write ( " Skip %d bytes \n " % ( Item
[ 'offset' ] - NextOffset
))
1634 if len ( Item
[ 'subreg' ]) > 0 :
1635 NextOffset
= Item
[ 'offset' ]
1636 BitsOffset
= NextOffset
* 8
1637 for SubItem
in Item
[ 'subreg' ]:
1638 BitsOffset
+= SubItem
[ 'bitlength' ]
1639 if SubItem
[ 'name' ] == '' :
1640 if 'bitlength' in SubItem
:
1641 BsfFd
. write ( " Skip %d bits \n " % ( SubItem
[ 'bitlength' ]))
1643 BsfFd
. write ( " Skip %d bytes \n " % ( SubItem
[ 'length' ]))
1645 Options
= self
. WriteBsfStruct ( BsfFd
, SubItem
)
1646 if len ( Options
) > 0 :
1647 OptionDict
[ SubItem
[ 'space' ]+ '_' + SubItem
[ 'cname' ]] = Options
1649 NextBitsOffset
= ( Item
[ 'offset' ] + Item
[ 'length' ]) * 8
1650 if NextBitsOffset
> BitsOffset
:
1651 BitsGap
= NextBitsOffset
- BitsOffset
1652 BitsRemain
= BitsGap
% 8
1654 BsfFd
. write ( " Skip %d bits \n " % BitsRemain
)
1655 BitsGap
-= BitsRemain
1656 BytesRemain
= int ( BitsGap
/ 8 )
1658 BsfFd
. write ( " Skip %d bytes \n " % BytesRemain
)
1659 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1661 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1662 Options
= self
. WriteBsfStruct ( BsfFd
, Item
)
1663 if len ( Options
) > 0 :
1664 OptionDict
[ Item
[ 'space' ]+ '_' + Item
[ 'cname' ]] = Options
1665 BsfFd
. write ( " \n EndStruct \n\n " )
1667 BsfFd
. write ( " %s " % self
._ BuidinOptionTxt
)
1669 for Each
in OptionDict
:
1670 BsfFd
. write ( "List & %s \n " % Each
)
1671 for Item
in OptionDict
[ Each
]:
1672 BsfFd
. write ( ' Selection %s , " %s " \n ' % ( Item
[ 0 ], Item
[ 1 ]))
1673 BsfFd
. write ( "EndList \n\n " )
1675 BsfFd
. write ( "BeginInfoBlock \n " )
1676 BsfFd
. write ( ' PPVer " %s " \n ' % ( self
._ CfgBlkDict
[ 'ver' ]))
1677 BsfFd
. write ( ' Description " %s " \n ' % ( self
._ CfgBlkDict
[ 'name' ]))
1678 BsfFd
. write ( "EndInfoBlock \n\n " )
1680 for Each
in self
._ CfgPageDict
:
1681 BsfFd
. write ( 'Page " %s " \n ' % self
._ CfgPageDict
[ Each
])
1683 for Item
in self
._ CfgItemList
:
1684 if Item
[ 'name' ] != '' :
1685 if Item
[ 'page' ] != Each
:
1687 if len ( Item
[ 'subreg' ]) > 0 :
1688 for SubItem
in Item
[ 'subreg' ]:
1689 if SubItem
[ 'name' ] != '' :
1690 BsfItems
. append ( SubItem
)
1692 BsfItems
. append ( Item
)
1694 BsfItems
. sort ( key
= lambda x
: x
[ 'order' ])
1696 for Item
in BsfItems
:
1697 self
. WriteBsfOption ( BsfFd
, Item
)
1698 BsfFd
. write ( "EndPage \n\n " )
1705 print ( "GenCfgOpt Version 0.58" )
1707 print ( " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]" )
1708 print ( " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]" )
1709 print ( " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]" )
1713 # Parse the options and args
1717 GenCfgOpt
= CGenCfgOpt ()
1718 while i
< len ( sys
. argv
):
1719 if sys
. argv
[ i
]. strip (). lower () == "--pcd" :
1720 BuildOptionPcd
. append ( sys
. argv
[ i
+ 1 ])
1723 argc
= len ( sys
. argv
)
1728 DscFile
= sys
. argv
[ 2 ]
1729 if not os
. path
. exists ( DscFile
):
1730 print ( "ERROR: Cannot open DSC file ' %s ' !" % DscFile
)
1735 if sys
. argv
[ 4 ][ 0 ] == '-' :
1738 OutFile
= sys
. argv
[ 4 ]
1741 if GenCfgOpt
. ParseMacros ( sys
. argv
[ Start
:]) != 0 :
1742 print ( "ERROR: Macro parsing failed !" )
1746 if not os
. path
. exists ( FvDir
):
1749 if GenCfgOpt
. ParseDscFile ( DscFile
, FvDir
) != 0 :
1750 print ( "ERROR: %s !" % GenCfgOpt
. Error
)
1753 if GenCfgOpt
. UpdateSubRegionDefaultValue () != 0 :
1754 print ( "ERROR: %s !" % GenCfgOpt
. Error
)
1757 if sys
. argv
[ 1 ] == "UPDTXT" :
1758 Ret
= GenCfgOpt
. CreateSplitUpdTxt ( OutFile
)
1760 # No change is detected
1762 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1764 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1766 elif sys
. argv
[ 1 ] == "HEADER" :
1767 Ret
= GenCfgOpt
. CreateHeaderFile ( OutFile
)
1769 # No change is detected
1771 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1773 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1776 elif sys
. argv
[ 1 ] == "GENBSF" :
1777 Ret
= GenCfgOpt
. GenerateBsfFile ( OutFile
)
1779 # No change is detected
1781 print ( "INFO: %s !" % ( GenCfgOpt
. Error
))
1783 print ( "ERROR: %s !" % ( GenCfgOpt
. Error
))
1790 print ( "ERROR: Unknown command ' %s ' !" % sys
. argv
[ 1 ])
1797 if __name__
== '__main__' :