]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFspPkg/Tools/GenCfgOpt.py
3 # Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
4 # This program and the accompanying materials are licensed and made available under
5 # the terms and conditions of the BSD License that accompanies this distribution.
6 # The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php.
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 from datetime
import date
20 # Generated file copyright header
22 __copyright_txt__
= """## @file
24 # THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.
26 # This file lists all VPD informations for a platform collected by build.exe.
28 # Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
29 # This program and the accompanying materials
30 # are licensed and made available under the terms and conditions of the BSD License
31 # which accompanies this distribution. The full text of the license may be found at
32 # http://opensource.org/licenses/bsd-license.php
34 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
35 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
39 __copyright_bsf__
= """/** @file
41 Boot Setting File for Platform Configuration.
43 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
44 This program and the accompanying materials
45 are licensed and made available under the terms and conditions of the BSD License
46 which accompanies this distribution. The full text of the license may be found at
47 http://opensource.org/licenses/bsd-license.php
49 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
50 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
52 This file is automatically generated. Please do NOT modify !!!
58 __copyright_h__
= """/** @file
60 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
62 Redistribution and use in source and binary forms, with or without modification,
63 are permitted provided that the following conditions are met:
65 * Redistributions of source code must retain the above copyright notice, this
66 list of conditions and the following disclaimer.
67 * Redistributions in binary form must reproduce the above copyright notice, this
68 list of conditions and the following disclaimer in the documentation and/or
69 other materials provided with the distribution.
70 * Neither the name of Intel Corporation nor the names of its contributors may
71 be used to endorse or promote products derived from this software without
72 specific prior written permission.
74 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
77 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
78 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
79 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
80 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
81 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
82 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
83 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
84 THE POSSIBILITY OF SUCH DAMAGE.
86 This file is automatically generated. Please do NOT modify !!!
91 class CLogicalExpression
:
96 def errExit ( self
, err
= '' ):
97 print "ERROR: Express parsing for:"
98 print " %s " % self
. string
99 print " %s ^" % ( ' ' * self
. index
)
101 print "INFO : %s " % err
104 def getNonNumber ( self
, n1
, n2
):
111 def getCurr ( self
, lens
= 1 ):
114 return self
. string
[ self
. index
:]
116 if self
. index
+ lens
> len ( self
. string
):
117 lens
= len ( self
. string
) - self
. index
118 return self
. string
[ self
. index
: self
. index
+ lens
]
123 return self
. index
== len ( self
. string
)
125 def moveNext ( self
, len = 1 ):
129 while not self
. isLast ():
130 if self
. getCurr () in ' \t ' :
135 def normNumber ( self
, val
):
136 return True if val
else False
138 def getNumber ( self
, var
):
140 if re
. match ( '^0x[a-fA-F0-9]+$' , var
):
142 elif re
. match ( '^[+-]?\d+$' , var
):
148 def parseValue ( self
):
151 while not self
. isLast ():
152 char
= self
. getCurr ()
153 if re
. match ( '^[\w.]' , char
):
158 val
= self
. getNumber ( var
)
165 def parseSingleOp ( self
):
167 if re
. match ( '^NOT\W' , self
. getCurr (- 1 )):
169 op
= self
. parseBrace ()
170 val
= self
. getNumber ( op
)
172 self
. errExit ( "' %s ' is not a number" % op
)
173 return " %d " % ( not self
. normNumber ( int ( op
)))
175 return self
. parseValue ()
177 def parseBrace ( self
):
179 char
= self
. getCurr ()
182 value
= self
. parseExpr ()
184 if self
. getCurr () != ')' :
185 self
. errExit ( "Expecting closing brace or operator" )
189 value
= self
. parseSingleOp ()
192 def parseCompare ( self
):
193 value
= self
. parseBrace ()
196 char
= self
. getCurr ()
197 if char
in [ '<' , '>' ]:
199 next
= self
. getCurr ()
205 result
= self
. parseBrace ()
206 test
= self
. getNonNumber ( result
, value
)
208 value
= " %d " % self
. normNumber ( eval ( value
+ op
+ result
))
210 self
. errExit ( "' %s ' is not a valid number for comparision" % test
)
211 elif char
in [ '=' , '!' ]:
213 if op
in [ '==' , '!=' ]:
215 result
= self
. parseBrace ()
216 test
= self
. getNonNumber ( result
, value
)
218 value
= " %d " % self
. normNumber (( eval ( value
+ op
+ result
)))
220 value
= " %d " % self
. normNumber ( eval ( "'" + value
+ "'" + op
+ "'" + result
+ "'" ))
228 value
= self
. parseCompare ()
231 if re
. match ( '^AND\W' , self
. getCurr (- 1 )):
233 result
= self
. parseCompare ()
234 test
= self
. getNonNumber ( result
, value
)
236 value
= " %d " % self
. normNumber ( int ( value
) & int ( result
))
238 self
. errExit ( "' %s ' is not a valid op number for AND" % test
)
243 def parseOrXor ( self
):
244 value
= self
. parseAnd ()
249 if re
. match ( '^XOR\W' , self
. getCurr (- 1 )):
252 elif re
. match ( '^OR\W' , self
. getCurr (- 1 )):
258 result
= self
. parseAnd ()
259 test
= self
. getNonNumber ( result
, value
)
261 value
= " %d " % self
. normNumber ( eval ( value
+ op
+ result
))
263 self
. errExit ( "' %s ' is not a valid op number for XOR/OR" % test
)
267 return self
. parseOrXor ()
270 value
= self
. parseExpr ()
272 if not self
. isLast ():
273 self
. errExit ( "Unexpected character found ' %s '" % self
. getCurr ())
274 test
= self
. getNumber ( value
)
276 self
. errExit ( "Result ' %s ' is not a number" % value
)
279 def evaluateExpress ( self
, Expr
):
293 self
._ GlobalDataDef
= """
299 self
._ BuidinOptionTxt
= """
301 Selection 0x1 , "Enabled"
302 Selection 0x0 , "Disabled"
307 self
._ BsfKeyList
= [ 'FIND' , 'NAME' , 'HELP' , 'TYPE' , 'PAGE' , 'OPTION' , 'ORDER' ]
308 self
._ HdrKeyList
= [ 'HEADER' , 'STRUCT' ]
309 self
._ BuidinOption
= { '$EN_DIS' : 'EN_DIS' }
312 self
._ CfgBlkDict
= {}
313 self
._ CfgPageDict
= {}
314 self
._ CfgItemList
= []
319 def ParseMacros ( self
, MacroDefStr
):
320 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
323 for Macro
in MacroDefStr
:
324 if Macro
. startswith ( '-D' ):
332 Match
= re
. match ( "(\w+)=(.+)" , Macro
)
334 self
._ MacroDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
336 Match
= re
. match ( "(\w+)" , Macro
)
338 self
._ MacroDict
[ Match
. group ( 1 )] = ''
339 if len ( self
._ MacroDict
) == 0 :
344 print "INFO : Macro dictionary:"
345 for Each
in self
._ MacroDict
:
346 print " $( %s ) = [ %s ]" % ( Each
, self
._ MacroDict
[ Each
])
349 def EvaulateIfdef ( self
, Macro
):
350 Result
= Macro
in self
._ MacroDict
352 print "INFO : Eval Ifdef [ %s ] : %s " % ( Macro
, Result
)
355 def ExpandMacros ( self
, Input
):
357 Match
= re
. findall ( "\$\(\w+\)" , Input
)
360 Variable
= Each
[ 2 :- 1 ]
361 if Variable
in self
._ MacroDict
:
362 Line
= Line
. replace ( Each
, self
._ MacroDict
[ Variable
])
365 print "WARN : %s is not defined" % Each
366 Line
= Line
. replace ( Each
, Each
[ 2 :- 1 ])
369 def EvaluateExpress ( self
, Expr
):
370 ExpExpr
= self
. ExpandMacros ( Expr
)
371 LogExpr
= CLogicalExpression ()
372 Result
= LogExpr
. evaluateExpress ( ExpExpr
)
374 print "INFO : Eval Express [ %s ] : %s " % ( Expr
, Result
)
377 def FormatListValue ( self
, ConfigDict
):
378 Struct
= ConfigDict
[ 'struct' ]
379 if Struct
not in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
383 binlist
= ConfigDict
[ 'value' ][ 1 :- 1 ]. split ( ',' )
386 if each
. startswith ( '0x' ):
387 value
= int ( each
, 16 )
390 dataarray
. append ( value
)
392 unit
= int ( Struct
[ 4 :]) / 8
393 if int ( ConfigDict
[ 'length' ]) != unit
* len ( dataarray
):
394 raise Exception ( "Array size is not proper for ' %s ' !" % ConfigDict
[ 'cname' ])
397 for each
in dataarray
:
399 for loop
in xrange ( unit
):
400 bytearray
. append ( "0x %0 2X" % ( value
& 0xFF ))
402 newvalue
= '{' + ',' . join ( bytearray
) + '}'
403 ConfigDict
[ 'value' ] = newvalue
406 def ParseDscFile ( self
, DscFile
, FvDir
):
407 self
._ CfgItemList
= []
408 self
._ CfgPageDict
= {}
409 self
._ CfgBlkDict
= {}
410 self
._ DscFile
= DscFile
423 DscFd
= open ( DscFile
, "r" )
424 DscLines
= DscFd
. readlines ()
428 DscLine
= DscLines
. pop ( 0 ). strip ()
430 Match
= re
. match ( "^\[(.+)\]" , DscLine
)
431 if Match
is not None :
432 if Match
. group ( 1 ). lower () == "Defines" . lower ():
436 elif Match
. group ( 1 ). lower () == "PcdsDynamicVpd" . lower ():
438 ConfigDict
[ 'header' ] = 'ON'
439 ConfigDict
[ 'region' ] = 'VPD'
440 ConfigDict
[ 'order' ] = - 1
441 ConfigDict
[ 'page' ] = ''
442 ConfigDict
[ 'name' ] = ''
443 ConfigDict
[ 'find' ] = ''
444 ConfigDict
[ 'struct' ] = ''
445 ConfigDict
[ 'subreg' ] = []
449 elif Match
. group ( 1 ). lower () == "PcdsDynamicVpd.Upd" . lower ():
451 ConfigDict
[ 'header' ] = 'ON'
452 ConfigDict
[ 'region' ] = 'UPD'
453 ConfigDict
[ 'order' ] = - 1
454 ConfigDict
[ 'page' ] = ''
455 ConfigDict
[ 'name' ] = ''
456 ConfigDict
[ 'find' ] = ''
457 ConfigDict
[ 'struct' ] = ''
458 ConfigDict
[ 'subreg' ] = []
468 if IsDefSect
or IsUpdSect
or IsVpdSect
:
469 if re
. match ( "^!else($|\s+#.+)" , DscLine
):
471 IfStack
[- 1 ] = not IfStack
[- 1 ]
473 print ( "ERROR: No paired '!if' found for '!else' for line ' %s '" % DscLine
)
475 elif re
. match ( "^!endif($|\s+#.+)" , DscLine
):
478 Level
= ElifStack
. pop ()
482 print ( "ERROR: No paired '!if' found for '!endif' for line ' %s '" % DscLine
)
486 Match
= re
. match ( "!(ifdef|ifndef)\s+(.+)" , DscLine
)
488 Result
= self
. EvaulateIfdef ( Match
. group ( 2 ))
489 if Match
. group ( 1 ) == 'ifndef' :
491 IfStack
. append ( Result
)
494 Match
= re
. match ( "!(if|elseif)\s+(.+)" , DscLine
)
496 Result
= self
. EvaluateExpress ( Match
. group ( 2 ))
497 if Match
. group ( 1 ) == "if" :
499 IfStack
. append ( Result
)
502 IfStack
[- 1 ] = not IfStack
[- 1 ]
503 IfStack
. append ( Result
)
504 ElifStack
[- 1 ] = ElifStack
[- 1 ] + 1
506 print ( "ERROR: No paired '!if' found for '!elif' for line ' %s '" % DscLine
)
510 Handle
= reduce ( lambda x
, y
: x
and y
, IfStack
)
514 Match
= re
. match ( "!include\s+(.+)" , DscLine
)
516 IncludeFilePath
= Match
. group ( 1 )
517 IncludeFilePath
= self
. ExpandMacros ( IncludeFilePath
)
519 IncludeDsc
= open ( IncludeFilePath
, "r" )
521 print ( "ERROR: Cannot open file ' %s '" % IncludeFilePath
)
523 NewDscLines
= IncludeDsc
. readlines ()
525 DscLines
= NewDscLines
+ DscLines
527 if DscLine
. startswith ( '!' ):
528 print ( "ERROR: Unrecoginized directive for line ' %s '" % DscLine
)
535 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
536 Match
= re
. match ( "^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)" , DscLine
)
538 self
._ MacroDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
540 print "INFO : DEFINE %s = [ %s ]" % ( Match
. group ( 1 ), Match
. group ( 2 ))
542 Match
= re
. match ( "^\s*#\s+!(BSF|HDR)\s+(.+)" , DscLine
)
544 Remaining
= Match
. group ( 2 )
545 if Match
. group ( 1 ) == 'BSF' :
546 Match
= re
. match ( "(?:^|.+\s+)PAGES:{(.+?)}" , Remaining
)
548 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
549 PageList
= Match
. group ( 1 ). split ( ',' )
550 for Page
in PageList
:
552 Match
= re
. match ( "(\w+): \" (.+) \" " , Page
)
553 self
._ CfgPageDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
555 Match
= re
. match ( "(?:^|.+\s+)BLOCK:{NAME: \" (.+) \" \s*,\s*VER: \" (.+) \" \s*}" , Remaining
)
557 self
._ CfgBlkDict
[ 'name' ] = Match
. group ( 1 )
558 self
._ CfgBlkDict
[ 'ver' ] = Match
. group ( 2 )
560 for Key
in self
._ BsfKeyList
:
561 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
563 if Key
in [ 'HELP' , 'OPTION' ] and Match
. group ( 1 ). startswith ( '+' ):
564 ConfigDict
[ Key
. lower ()] += Match
. group ( 1 )[ 1 :]
566 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
568 for Key
in self
._ HdrKeyList
:
569 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
571 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
575 Match
= re
. match ( "^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F] {4} )\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)" , DscLine
)
577 Match
= re
. match ( "^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?" , DscLine
)
579 ConfigDict
[ 'space' ] = Match
. group ( 1 )
580 ConfigDict
[ 'cname' ] = Match
. group ( 2 )
581 ConfigDict
[ 'offset' ] = int ( Match
. group ( 3 ), 16 )
582 if ConfigDict
[ 'order' ] == - 1 :
583 ConfigDict
[ 'order' ] = ConfigDict
[ 'offset' ] << 8
585 ( Major
, Minor
) = ConfigDict
[ 'order' ]. split ( '.' )
586 ConfigDict
[ 'order' ] = ( int ( Major
, 16 ) << 8 ) + int ( Minor
, 16 )
588 Value
= Match
. group ( 5 ). strip ()
589 if Match
. group ( 4 ). startswith ( "0x" ):
590 Length
= int ( Match
. group ( 4 ), 16 )
592 Length
= int ( Match
. group ( 4 ))
594 Value
= Match
. group ( 4 )
597 Value
= Value
. strip ()
599 Match
= re
. match ( "^.+\s*\|\s*(.+)" , Value
)
601 Value
= Match
. group ( 1 )
604 ConfigDict
[ 'length' ] = Length
605 Match
= re
. match ( "\$\((\w+)\)" , Value
)
607 if Match
. group ( 1 ) in self
._ MacroDict
:
608 Value
= self
._ MacroDict
[ Match
. group ( 1 )]
610 ConfigDict
[ 'value' ] = Value
611 if ( len ( Value
) > 0 ) and ( Value
[ 0 ] == '{' ):
612 Value
= self
. FormatListValue ( ConfigDict
)
614 if ConfigDict
[ 'name' ] == '' :
615 # Clear BSF specific items
616 ConfigDict
[ 'help' ] = ''
617 ConfigDict
[ 'type' ] = ''
618 ConfigDict
[ 'option' ] = ''
620 self
._ CfgItemList
. append ( ConfigDict
. copy ())
621 ConfigDict
[ 'name' ] = ''
622 ConfigDict
[ 'find' ] = ''
623 ConfigDict
[ 'struct' ] = ''
624 ConfigDict
[ 'order' ] = - 1
625 ConfigDict
[ 'subreg' ] = []
627 # It could be a virtual item as below
628 # !BSF FIELD:{1:SerialDebugPortAddress0}
629 Match
= re
. match ( "^\s*#\s+!BSF\s+FIELD:{(.+):(\d+)}" , DscLine
)
631 SubCfgDict
= ConfigDict
632 SubCfgDict
[ 'cname' ] = Match
. group ( 1 )
633 SubCfgDict
[ 'length' ] = int ( Match
. group ( 2 ))
634 if SubCfgDict
[ 'length' ] > 0 :
635 LastItem
= self
._ CfgItemList
[- 1 ]
636 if len ( LastItem
[ 'subreg' ]) == 0 :
639 SubOffset
+= LastItem
[ 'subreg' ][- 1 ][ 'length' ]
640 SubCfgDict
[ 'offset' ] = SubOffset
641 LastItem
[ 'subreg' ]. append ( SubCfgDict
. copy ())
642 ConfigDict
[ 'name' ] = ''
645 def UpdateSubRegionDefaultValue ( self
):
647 for Item
in self
._ CfgItemList
:
648 if len ( Item
[ 'subreg' ]) == 0 :
651 if Item
[ 'value' ][ 0 ] == '{' :
652 binlist
= Item
[ 'value' ][ 1 :- 1 ]. split ( ',' )
655 if each
. startswith ( '0x' ):
656 value
= int ( each
, 16 )
659 bytearray
. append ( value
)
661 if Item
[ 'value' ]. startswith ( '0x' ):
662 value
= int ( Item
[ 'value' ], 16 )
664 value
= int ( Item
[ 'value' ])
666 while idx
< Item
[ 'length' ]:
667 bytearray
. append ( value
& 0xFF )
670 for SubItem
in Item
[ 'subreg' ]:
671 if SubItem
[ 'length' ] in ( 1 , 2 , 4 , 8 ):
672 valuelist
= [ b
for b
in bytearray
[ SubItem
[ 'offset' ]: SubItem
[ 'offset' ]+ SubItem
[ 'length' ]]]
674 valuestr
= "" . join ( ' %0 2X' % b
for b
in valuelist
)
675 SubItem
[ 'value' ] = '0x %s ' % valuestr
677 valuestr
= "," . join ( '0x %0 2X' % b
for b
in bytearray
[ SubItem
[ 'offset' ]: SubItem
[ 'offset' ]+ SubItem
[ 'length' ]])
678 SubItem
[ 'value' ] = '{ %s }' % valuestr
681 def UpdateVpdSizeField ( self
):
684 if 'VPD_TOOL_GUID' not in self
._ MacroDict
:
685 self
. Error
= "VPD_TOOL_GUID definition is missing in DSC file"
688 VpdMapFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'VPD_TOOL_GUID' ] + '.map' )
689 if not os
. path
. exists ( VpdMapFile
):
690 self
. Error
= "VPD MAP file ' %s ' does not exist" % VpdMapFile
693 MapFd
= open ( VpdMapFile
, "r" )
694 MapLines
= MapFd
. readlines ()
699 for MapLine
in MapLines
:
700 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | DEFAULT | 0x0000 | 8 | 0x534450565F425346
701 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | 0x0000 | 8 | 0x534450565F425346
702 #gPlatformFspPkgTokenSpaceGuid.PcdTest | 0x0008 | 5 | {0x01,0x02,0x03,0x04,0x05}
703 Match
= re
. match ( "([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)(\s\|\sDEFAULT)?\s\|\s(0x[0-9A-F] {4} )\s\|\s(\d+|0x[0-9a-fA-F]+)\s\|\s(\{?[x0-9a-fA-F,\s]+\}?)" , MapLine
)
705 Space
= Match
. group ( 1 )
706 Name
= Match
. group ( 2 )
707 if ( self
._ MapVer
== 0 ) and ( Match
. group ( 3 ) != None ):
709 Offset
= int ( Match
. group ( 4 ), 16 )
710 if Match
. group ( 5 ). startswith ( "0x" ):
711 Length
= int ( Match
. group ( 5 ), 16 )
713 Length
= int ( Match
. group ( 5 ))
714 PcdDict
[ "len" ] = Length
715 PcdDict
[ "value" ] = Match
. group ( 6 )
716 VpdDict
[ Space
+ '.' + Name
] = dict ( PcdDict
)
718 for Item
in self
._ CfgItemList
:
719 if Item
[ 'value' ] == '' :
720 Item
[ 'value' ] = VpdDict
[ Item
[ 'space' ]+ '.' + Item
[ 'cname' ]][ 'value' ]
721 if Item
[ 'length' ] == - 1 :
722 Item
[ 'length' ] = VpdDict
[ Item
[ 'space' ]+ '.' + Item
[ 'cname' ]][ 'len' ]
723 if Item
[ 'struct' ] != '' :
724 Type
= Item
[ 'struct' ]. strip ()
725 if Type
. endswith ( '*' ) and ( Item
[ 'length' ] != 4 ):
726 self
. Error
= "Struct pointer ' %s ' has invalid size" % Type
731 def CreateUpdTxtFile ( self
, UpdTxtFile
):
733 if 'UPD_TOOL_GUID' not in self
._ MacroDict
:
734 self
. Error
= "UPD_TOOL_GUID definition is missing in DSC file"
738 UpdTxtFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'UPD_TOOL_GUID' ] + '.txt' )
741 if not os
. path
. exists ( UpdTxtFile
):
744 DscTime
= os
. path
. getmtime ( self
._ DscFile
)
745 TxtTime
= os
. path
. getmtime ( UpdTxtFile
)
746 if DscTime
> TxtTime
:
750 # DSC has not been modified yet
751 # So don't have to re-generate other files
752 self
. Error
= 'No DSC file change, skip to create UPD TXT file'
755 TxtFd
= open ( UpdTxtFile
, "w" )
756 TxtFd
. write ( " %s \n " % ( __copyright_txt__
% date
. today (). year
))
760 if self
._ MapVer
== 1 :
764 for Item
in self
._ CfgItemList
:
765 if Item
[ 'region' ] != 'UPD' :
767 Offset
= Item
[ 'offset' ]
768 if NextOffset
< Offset
:
770 TxtFd
. write ( " %s .UnusedUpdSpace %d | %s0x%0 4X|0x %0 4X| {0} \n " % ( Item
[ 'space' ], SpaceIdx
, Default
, NextOffset
, Offset
- NextOffset
))
771 SpaceIdx
= SpaceIdx
+ 1
772 NextOffset
= Offset
+ Item
[ 'length' ]
773 TxtFd
. write ( " %s . %s | %s0x%0 4X| %s | %s \n " % ( Item
[ 'space' ], Item
[ 'cname' ], Default
, Item
[ 'offset' ], Item
[ 'length' ], Item
[ 'value' ]))
777 def CreateField ( self
, Item
, Name
, Length
, Offset
, Struct
):
782 if Length
in [ 1 , 2 , 4 , 8 ]:
783 Type
= "UINT %d " % ( Length
* 8 )
788 if Item
[ 'value' ]. startswith ( '{' ):
794 if Struct
in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
796 Unit
= int ( Type
[ 4 :]) / 8
797 Length
= Length
/ Unit
802 Name
= Name
+ '[ %d ]' % Length
804 if len ( Type
) < PosName
:
805 Space1
= PosName
- len ( Type
)
809 if len ( Name
) < PosComment
:
810 Space2
= PosComment
- len ( Name
)
814 return " %s%s%s ; %s /* Offset 0x %0 4X */ \n " % ( Type
, ' ' * Space1
, Name
, ' ' * Space2
, Offset
)
817 def CreateHeaderFile ( self
, InputHeaderFile
, IsInternal
):
822 HeaderFile
= os
. path
. join ( FvDir
, 'VpdHeader.h' )
824 HeaderFile
= os
. path
. join ( FvDir
, 'fsp_vpd.h' )
826 # Check if header needs to be recreated
829 if not os
. path
. exists ( HeaderFile
):
832 DscTime
= os
. path
. getmtime ( self
._ DscFile
)
833 HeadTime
= os
. path
. getmtime ( HeaderFile
)
834 if not os
. path
. exists ( InputHeaderFile
):
837 InpTime
= os
. path
. getmtime ( InputHeaderFile
)
838 if DscTime
> HeadTime
or InpTime
> HeadTime
:
842 self
. Error
= "No DSC or input header file is changed, skip the header file generating"
845 HeaderFd
= open ( HeaderFile
, "w" )
846 FileBase
= os
. path
. basename ( HeaderFile
)
847 FileName
= FileBase
. replace ( "." , "_" ). upper ()
848 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
849 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
850 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
851 HeaderFd
. write ( "#pragma pack(1) \n\n " )
853 if InputHeaderFile
!= '' :
854 if not os
. path
. exists ( InputHeaderFile
):
855 self
. Error
= "Input header file ' %s ' does not exist" % InputHeaderFile
858 InFd
= open ( InputHeaderFile
, "r" )
859 IncLines
= InFd
. readlines ()
863 for Line
in IncLines
:
864 Match
= re
. search ( "!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+" , Line
)
866 if Match
. group ( 1 ) == "BEGIN" :
874 HeaderFd
. write ( " \n\n " )
876 for Region
in [ 'UPD' , 'VPD' ]:
878 # Write PcdVpdRegionSign and PcdImageRevision
880 if 'VPD_TOOL_GUID' not in self
._ MacroDict
:
881 self
. Error
= "VPD_TOOL_GUID definition is missing in DSC file"
885 BinFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'VPD_TOOL_GUID' ] + ".bin" )
886 if not os
. path
. exists ( BinFile
):
887 self
. Error
= "VPD binary file ' %s ' does not exist" % BinFile
891 BinFd
= open ( BinFile
, "rb" )
892 IdStr
= BinFd
. read ( 0x08 )
893 ImageId
= struct
. unpack ( '<Q' , IdStr
)
894 ImageRev
= struct
. unpack ( '<I' , BinFd
. read ( 0x04 ))
897 HeaderFd
. write ( "#define FSP_IMAGE_ID 0x %0 16X /* ' %s ' */ \n " % ( ImageId
[ 0 ], IdStr
))
898 HeaderFd
. write ( "#define FSP_IMAGE_REV 0x %0 8X \n\n " % ImageRev
[ 0 ])
900 HeaderFd
. write ( "typedef struct _" + Region
[ 0 ] + "PD_DATA_REGION { \n " )
909 for Item
in self
._ CfgItemList
:
910 if Item
[ 'region' ] != Region
:
913 NextVisible
= LastVisible
915 if LastVisible
and ( Item
[ 'header' ] == 'OFF' ):
917 ResvOffset
= Item
[ 'offset' ]
918 elif ( not LastVisible
) and Item
[ 'header' ] == 'ON' :
920 Name
= "Reserved" + Region
[ 0 ] + "pdSpace %d " % ResvIdx
921 ResvIdx
= ResvIdx
+ 1
922 HeaderFd
. write ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - ResvOffset
, ResvOffset
, '' ))
924 if Offset
< Item
[ "offset" ]:
925 if IsInternal
or LastVisible
:
926 Name
= "Unused" + Region
[ 0 ] + "pdSpace %d " % SpaceIdx
927 LineBuffer
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - Offset
, Offset
, '' ))
928 SpaceIdx
= SpaceIdx
+ 1
929 Offset
= Item
[ "offset" ]
931 if Offset
!= Item
[ "offset" ]:
932 print "Unsorted offset 0x %0 4X \n " % Item
[ "offset" ]
936 LastVisible
= NextVisible
938 Offset
= Offset
+ Item
[ "length" ]
939 if IsInternal
or LastVisible
:
940 for Each
in LineBuffer
:
941 HeaderFd
. write ( Each
)
943 HeaderFd
. write ( self
. CreateField ( Item
, Item
[ "cname" ], Item
[ "length" ], Item
[ "offset" ], Item
[ 'struct' ]))
945 HeaderFd
. write ( "} " + Region
[ 0 ] + "PD_DATA_REGION; \n\n " )
946 HeaderFd
. write ( "#pragma pack() \n\n " )
947 HeaderFd
. write ( "#endif \n " )
952 def WriteBsfStruct ( self
, BsfFd
, Item
):
953 if Item
[ 'type' ] == "None" :
954 Space
= "gPlatformFspPkgTokenSpaceGuid"
956 Space
= Item
[ 'space' ]
957 Line
= " $ %s _ %s " % ( Space
, Item
[ 'cname' ])
958 Match
= re
. match ( "\s*\{([x0-9a-fA-F,\s]+)\}\s*" , Item
[ 'value' ])
960 DefaultValue
= Match
. group ( 1 ). strip ()
962 DefaultValue
= Item
[ 'value' ]. strip ()
963 BsfFd
. write ( " %s%s% 4d bytes $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'length' ], DefaultValue
))
965 if Item
[ 'type' ] == "Combo" :
966 if not Item
[ 'option' ] in self
._ BuidinOption
:
967 OptList
= Item
[ 'option' ]. split ( ',' )
968 for Option
in OptList
:
969 Option
= Option
. strip ()
970 ( OpVal
, OpStr
) = Option
. split ( ':' )
971 TmpList
. append (( OpVal
, OpStr
))
974 def WriteBsfOption ( self
, BsfFd
, Item
):
975 PcdName
= Item
[ 'space' ] + '_' + Item
[ 'cname' ]
977 if Item
[ 'type' ] == "Combo" :
978 if Item
[ 'option' ] in self
._ BuidinOption
:
979 Options
= self
._ BuidinOption
[ Item
[ 'option' ]]
982 BsfFd
. write ( ' %s $ %s , " %s ", & %s , \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ], Options
));
984 elif Item
[ 'type' ]. startswith ( "EditNum" ):
985 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' ])
987 BsfFd
. write ( ' EditNum $ %s , " %s ", %s , \n ' % ( PcdName
, Item
[ 'name' ], Match
. group ( 1 )));
989 elif Item
[ 'type' ]. startswith ( "EditText" ):
990 BsfFd
. write ( ' %s $ %s , " %s ", \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]));
994 HelpLines
= Item
[ 'help' ]. split ( ' \\ n \\ r' )
996 for HelpLine
in HelpLines
:
999 BsfFd
. write ( ' Help " %s " \n ' % ( HelpLine
));
1001 BsfFd
. write ( ' " %s " \n ' % ( HelpLine
));
1003 BsfFd
. write ( ' "Valid range: %s ~ %s " \n ' % ( Match
. group ( 2 ), Match
. group ( 3 )));
1005 def GenerateBsfFile ( self
, BsfFile
):
1008 self
. Error
= "BSF output file ' %s ' is invalid" % BsfFile
1013 BsfFd
= open ( BsfFile
, "w" )
1014 BsfFd
. write ( " %s \n " % ( __copyright_bsf__
% date
. today (). year
))
1015 BsfFd
. write ( " %s \n " % self
._ GlobalDataDef
);
1016 BsfFd
. write ( "StructDef \n " )
1018 for Item
in self
._ CfgItemList
:
1019 if Item
[ 'find' ] != '' :
1020 BsfFd
. write ( ' \n Find " %s " \n ' % Item
[ 'find' ])
1021 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1022 if Item
[ 'name' ] != '' :
1023 if NextOffset
!= Item
[ 'offset' ]:
1024 BsfFd
. write ( " Skip %d bytes \n " % ( Item
[ 'offset' ] - NextOffset
))
1025 if len ( Item
[ 'subreg' ]) > 0 :
1026 NextOffset
= Item
[ 'offset' ]
1027 for SubItem
in Item
[ 'subreg' ]:
1028 NextOffset
+= SubItem
[ 'length' ]
1029 if SubItem
[ 'name' ] == '' :
1030 BsfFd
. write ( " Skip %d bytes \n " % ( SubItem
[ 'length' ]))
1032 Options
= self
. WriteBsfStruct ( BsfFd
, SubItem
)
1033 if len ( Options
) > 0 :
1034 OptionDict
[ SubItem
[ 'space' ]+ '_' + SubItem
[ 'cname' ]] = Options
1035 if ( Item
[ 'offset' ] + Item
[ 'length' ]) < NextOffset
:
1036 self
. Error
= "BSF sub region ' %s ' length does not match" % ( Item
[ 'space' ]+ '.' + Item
[ 'cname' ])
1039 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1040 Options
= self
. WriteBsfStruct ( BsfFd
, Item
)
1041 if len ( Options
) > 0 :
1042 OptionDict
[ Item
[ 'space' ]+ '_' + Item
[ 'cname' ]] = Options
1043 BsfFd
. write ( " \n EndStruct \n\n " )
1045 BsfFd
. write ( " %s " % self
._ BuidinOptionTxt
);
1047 for Each
in OptionDict
:
1048 BsfFd
. write ( "List & %s \n " % Each
);
1049 for Item
in OptionDict
[ Each
]:
1050 BsfFd
. write ( ' Selection %s , " %s " \n ' % ( Item
[ 0 ], Item
[ 1 ]));
1051 BsfFd
. write ( "EndList \n\n " );
1053 BsfFd
. write ( "BeginInfoBlock \n " );
1054 BsfFd
. write ( ' PPVer " %s " \n ' % ( self
._ CfgBlkDict
[ 'ver' ]));
1055 BsfFd
. write ( ' Description " %s " \n ' % ( self
._ CfgBlkDict
[ 'name' ]));
1056 BsfFd
. write ( "EndInfoBlock \n\n " );
1058 for Each
in self
._ CfgPageDict
:
1059 BsfFd
. write ( 'Page " %s " \n ' % self
._ CfgPageDict
[ Each
]);
1061 for Item
in self
._ CfgItemList
:
1062 if Item
[ 'name' ] != '' :
1063 if Item
[ 'page' ] != Each
:
1065 if len ( Item
[ 'subreg' ]) > 0 :
1066 for SubItem
in Item
[ 'subreg' ]:
1067 if SubItem
[ 'name' ] != '' :
1068 BsfItems
. append ( SubItem
)
1070 BsfItems
. append ( Item
)
1072 BsfItems
. sort ( key
= lambda x
: x
[ 'order' ])
1074 for Item
in BsfItems
:
1075 self
. WriteBsfOption ( BsfFd
, Item
)
1076 BsfFd
. write ( "EndPage \n\n " );
1083 print "GenCfgOpt Version 0.50"
1085 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]"
1086 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]"
1087 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1091 # Parse the options and args
1093 GenCfgOpt
= CGenCfgOpt ()
1094 argc
= len ( sys
. argv
)
1099 DscFile
= sys
. argv
[ 2 ]
1100 if not os
. path
. exists ( DscFile
):
1101 print "ERROR: Cannot open DSC file ' %s ' !" % DscFile
1106 if sys
. argv
[ 4 ][ 0 ] == '-' :
1109 OutFile
= sys
. argv
[ 4 ]
1111 if GenCfgOpt
. ParseMacros ( sys
. argv
[ Start
:]) != 0 :
1112 print "ERROR: %s !" % GenCfgOpt
. Error
1116 if not os
. path
. isdir ( FvDir
):
1117 print "ERROR: FV folder ' %s ' is invalid !" % FvDir
1120 if GenCfgOpt
. ParseDscFile ( DscFile
, FvDir
) != 0 :
1121 print "ERROR: %s !" % GenCfgOpt
. Error
1124 if GenCfgOpt
. UpdateVpdSizeField () != 0 :
1125 print "ERROR: %s !" % GenCfgOpt
. Error
1128 if GenCfgOpt
. UpdateSubRegionDefaultValue () != 0 :
1129 print "ERROR: %s !" % GenCfgOpt
. Error
1132 if sys
. argv
[ 1 ] == "UPDTXT" :
1133 Ret
= GenCfgOpt
. CreateUpdTxtFile ( OutFile
)
1135 # No change is detected
1137 print "INFO: %s !" % ( GenCfgOpt
. Error
)
1139 print "ERROR: %s !" % ( GenCfgOpt
. Error
)
1141 elif sys
. argv
[ 1 ] == "HEADER" :
1142 Ret
= GenCfgOpt
. CreateHeaderFile ( OutFile
, True )
1144 # No change is detected
1146 print "INFO: %s !" % ( GenCfgOpt
. Error
)
1148 print "ERROR: %s !" % ( GenCfgOpt
. Error
)
1150 if GenCfgOpt
. CreateHeaderFile ( OutFile
, False ) != 0 :
1151 print "ERROR: %s !" % GenCfgOpt
. Error
1153 elif sys
. argv
[ 1 ] == "GENBSF" :
1154 if GenCfgOpt
. GenerateBsfFile ( OutFile
) != 0 :
1155 print "ERROR: %s !" % GenCfgOpt
. Error
1161 print "ERROR: Unknown command ' %s ' !" % sys
. argv
[ 1 ]
1168 if __name__
== '__main__' :