]>
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' , 'EMBED' ]
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
[ 'embed' ] = ''
446 ConfigDict
[ 'subreg' ] = []
450 elif Match
. group ( 1 ). lower () == "PcdsDynamicVpd.Upd" . lower ():
452 ConfigDict
[ 'header' ] = 'ON'
453 ConfigDict
[ 'region' ] = 'UPD'
454 ConfigDict
[ 'order' ] = - 1
455 ConfigDict
[ 'page' ] = ''
456 ConfigDict
[ 'name' ] = ''
457 ConfigDict
[ 'find' ] = ''
458 ConfigDict
[ 'struct' ] = ''
459 ConfigDict
[ 'embed' ] = ''
460 ConfigDict
[ 'subreg' ] = []
470 if IsDefSect
or IsUpdSect
or IsVpdSect
:
471 if re
. match ( "^!else($|\s+#.+)" , DscLine
):
473 IfStack
[- 1 ] = not IfStack
[- 1 ]
475 print ( "ERROR: No paired '!if' found for '!else' for line ' %s '" % DscLine
)
477 elif re
. match ( "^!endif($|\s+#.+)" , DscLine
):
480 Level
= ElifStack
. pop ()
484 print ( "ERROR: No paired '!if' found for '!endif' for line ' %s '" % DscLine
)
488 Match
= re
. match ( "!(ifdef|ifndef)\s+(.+)" , DscLine
)
490 Result
= self
. EvaulateIfdef ( Match
. group ( 2 ))
491 if Match
. group ( 1 ) == 'ifndef' :
493 IfStack
. append ( Result
)
496 Match
= re
. match ( "!(if|elseif)\s+(.+)" , DscLine
)
498 Result
= self
. EvaluateExpress ( Match
. group ( 2 ))
499 if Match
. group ( 1 ) == "if" :
501 IfStack
. append ( Result
)
504 IfStack
[- 1 ] = not IfStack
[- 1 ]
505 IfStack
. append ( Result
)
506 ElifStack
[- 1 ] = ElifStack
[- 1 ] + 1
508 print ( "ERROR: No paired '!if' found for '!elif' for line ' %s '" % DscLine
)
512 Handle
= reduce ( lambda x
, y
: x
and y
, IfStack
)
516 Match
= re
. match ( "!include\s+(.+)" , DscLine
)
518 IncludeFilePath
= Match
. group ( 1 )
519 IncludeFilePath
= self
. ExpandMacros ( IncludeFilePath
)
521 IncludeDsc
= open ( IncludeFilePath
, "r" )
523 print ( "ERROR: Cannot open file ' %s '" % IncludeFilePath
)
525 NewDscLines
= IncludeDsc
. readlines ()
527 DscLines
= NewDscLines
+ DscLines
529 if DscLine
. startswith ( '!' ):
530 print ( "ERROR: Unrecoginized directive for line ' %s '" % DscLine
)
536 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
537 Match
= re
. match ( "^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)" , DscLine
)
539 self
._ MacroDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
541 print "INFO : DEFINE %s = [ %s ]" % ( Match
. group ( 1 ), Match
. group ( 2 ))
543 Match
= re
. match ( "^\s*#\s+!(BSF|HDR)\s+(.+)" , DscLine
)
545 Remaining
= Match
. group ( 2 )
546 if Match
. group ( 1 ) == 'BSF' :
547 Match
= re
. match ( "(?:^|.+\s+)PAGES:{(.+?)}" , Remaining
)
549 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
550 PageList
= Match
. group ( 1 ). split ( ',' )
551 for Page
in PageList
:
553 Match
= re
. match ( "(\w+): \" (.+) \" " , Page
)
554 self
._ CfgPageDict
[ Match
. group ( 1 )] = Match
. group ( 2 )
556 Match
= re
. match ( "(?:^|.+\s+)BLOCK:{NAME: \" (.+) \" \s*,\s*VER: \" (.+) \" \s*}" , Remaining
)
558 self
._ CfgBlkDict
[ 'name' ] = Match
. group ( 1 )
559 self
._ CfgBlkDict
[ 'ver' ] = Match
. group ( 2 )
561 for Key
in self
._ BsfKeyList
:
562 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
564 if Key
in [ 'NAME' , 'HELP' , 'OPTION' ] and Match
. group ( 1 ). startswith ( '+' ):
565 ConfigDict
[ Key
. lower ()] += Match
. group ( 1 )[ 1 :]
567 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
569 for Key
in self
._ HdrKeyList
:
570 Match
= re
. match ( "(?:^|.+\s+) %s :{(.+?)}" % Key
, Remaining
)
572 ConfigDict
[ Key
. lower ()] = Match
. group ( 1 )
576 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
)
578 Match
= re
. match ( "^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?" , DscLine
)
580 ConfigDict
[ 'space' ] = Match
. group ( 1 )
581 ConfigDict
[ 'cname' ] = Match
. group ( 2 )
582 ConfigDict
[ 'offset' ] = int ( Match
. group ( 3 ), 16 )
583 if ConfigDict
[ 'order' ] == - 1 :
584 ConfigDict
[ 'order' ] = ConfigDict
[ 'offset' ] << 8
586 ( Major
, Minor
) = ConfigDict
[ 'order' ]. split ( '.' )
587 ConfigDict
[ 'order' ] = ( int ( Major
, 16 ) << 8 ) + int ( Minor
, 16 )
589 Value
= Match
. group ( 5 ). strip ()
590 if Match
. group ( 4 ). startswith ( "0x" ):
591 Length
= int ( Match
. group ( 4 ), 16 )
593 Length
= int ( Match
. group ( 4 ))
595 Value
= Match
. group ( 4 )
598 Value
= Value
. strip ()
600 Match
= re
. match ( "^.+\s*\|\s*(.+)" , Value
)
602 Value
= Match
. group ( 1 )
605 ConfigDict
[ 'length' ] = Length
606 Match
= re
. match ( "\$\((\w+)\)" , Value
)
608 if Match
. group ( 1 ) in self
._ MacroDict
:
609 Value
= self
._ MacroDict
[ Match
. group ( 1 )]
611 ConfigDict
[ 'value' ] = Value
612 if ( len ( Value
) > 0 ) and ( Value
[ 0 ] == '{' ):
613 Value
= self
. FormatListValue ( ConfigDict
)
615 if ConfigDict
[ 'name' ] == '' :
616 # Clear BSF specific items
617 ConfigDict
[ 'bsfname' ] = ''
618 ConfigDict
[ 'help' ] = ''
619 ConfigDict
[ 'type' ] = ''
620 ConfigDict
[ 'option' ] = ''
622 self
._ CfgItemList
. append ( ConfigDict
. copy ())
623 ConfigDict
[ 'name' ] = ''
624 ConfigDict
[ 'find' ] = ''
625 ConfigDict
[ 'struct' ] = ''
626 ConfigDict
[ 'embed' ] = ''
627 ConfigDict
[ 'order' ] = - 1
628 ConfigDict
[ 'subreg' ] = []
630 # It could be a virtual item as below
631 # !BSF FIELD:{1:SerialDebugPortAddress0}
632 Match
= re
. match ( "^\s*#\s+!BSF\s+FIELD:{(.+):(\d+)}" , DscLine
)
634 SubCfgDict
= ConfigDict
635 SubCfgDict
[ 'cname' ] = Match
. group ( 1 )
636 SubCfgDict
[ 'length' ] = int ( Match
. group ( 2 ))
637 if SubCfgDict
[ 'length' ] > 0 :
638 LastItem
= self
._ CfgItemList
[- 1 ]
639 if len ( LastItem
[ 'subreg' ]) == 0 :
642 SubOffset
+= LastItem
[ 'subreg' ][- 1 ][ 'length' ]
643 SubCfgDict
[ 'offset' ] = SubOffset
644 LastItem
[ 'subreg' ]. append ( SubCfgDict
. copy ())
645 ConfigDict
[ 'name' ] = ''
648 def UpdateSubRegionDefaultValue ( self
):
650 for Item
in self
._ CfgItemList
:
651 if len ( Item
[ 'subreg' ]) == 0 :
654 if Item
[ 'value' ][ 0 ] == '{' :
655 binlist
= Item
[ 'value' ][ 1 :- 1 ]. split ( ',' )
658 if each
. startswith ( '0x' ):
659 value
= int ( each
, 16 )
662 bytearray
. append ( value
)
664 if Item
[ 'value' ]. startswith ( '0x' ):
665 value
= int ( Item
[ 'value' ], 16 )
667 value
= int ( Item
[ 'value' ])
669 while idx
< Item
[ 'length' ]:
670 bytearray
. append ( value
& 0xFF )
673 for SubItem
in Item
[ 'subreg' ]:
674 if SubItem
[ 'length' ] in ( 1 , 2 , 4 , 8 ):
675 valuelist
= [ b
for b
in bytearray
[ SubItem
[ 'offset' ]: SubItem
[ 'offset' ]+ SubItem
[ 'length' ]]]
677 valuestr
= "" . join ( ' %0 2X' % b
for b
in valuelist
)
678 SubItem
[ 'value' ] = '0x %s ' % valuestr
680 valuestr
= "," . join ( '0x %0 2X' % b
for b
in bytearray
[ SubItem
[ 'offset' ]: SubItem
[ 'offset' ]+ SubItem
[ 'length' ]])
681 SubItem
[ 'value' ] = '{ %s }' % valuestr
684 def UpdateVpdSizeField ( self
):
687 if 'VPD_TOOL_GUID' not in self
._ MacroDict
:
688 self
. Error
= "VPD_TOOL_GUID definition is missing in DSC file"
691 VpdMapFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'VPD_TOOL_GUID' ] + '.map' )
692 if not os
. path
. exists ( VpdMapFile
):
693 self
. Error
= "VPD MAP file ' %s ' does not exist" % VpdMapFile
696 MapFd
= open ( VpdMapFile
, "r" )
697 MapLines
= MapFd
. readlines ()
702 for MapLine
in MapLines
:
703 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | DEFAULT | 0x0000 | 8 | 0x534450565F425346
704 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | 0x0000 | 8 | 0x534450565F425346
705 #gPlatformFspPkgTokenSpaceGuid.PcdTest | 0x0008 | 5 | {0x01,0x02,0x03,0x04,0x05}
706 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
)
708 Space
= Match
. group ( 1 )
709 Name
= Match
. group ( 2 )
710 if ( self
._ MapVer
== 0 ) and ( Match
. group ( 3 ) != None ):
712 Offset
= int ( Match
. group ( 4 ), 16 )
713 if Match
. group ( 5 ). startswith ( "0x" ):
714 Length
= int ( Match
. group ( 5 ), 16 )
716 Length
= int ( Match
. group ( 5 ))
717 PcdDict
[ "len" ] = Length
718 PcdDict
[ "value" ] = Match
. group ( 6 )
719 VpdDict
[ Space
+ '.' + Name
] = dict ( PcdDict
)
721 for Item
in self
._ CfgItemList
:
722 if Item
[ 'value' ] == '' :
723 Item
[ 'value' ] = VpdDict
[ Item
[ 'space' ]+ '.' + Item
[ 'cname' ]][ 'value' ]
724 if Item
[ 'length' ] == - 1 :
725 Item
[ 'length' ] = VpdDict
[ Item
[ 'space' ]+ '.' + Item
[ 'cname' ]][ 'len' ]
726 if Item
[ 'struct' ] != '' :
727 Type
= Item
[ 'struct' ]. strip ()
728 if Type
. endswith ( '*' ) and ( Item
[ 'length' ] != 4 ):
729 self
. Error
= "Struct pointer ' %s ' has invalid size" % Type
734 def CreateUpdTxtFile ( self
, UpdTxtFile
):
736 if 'UPD_TOOL_GUID' not in self
._ MacroDict
:
737 self
. Error
= "UPD_TOOL_GUID definition is missing in DSC file"
741 UpdTxtFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'UPD_TOOL_GUID' ] + '.txt' )
744 if not os
. path
. exists ( UpdTxtFile
):
747 DscTime
= os
. path
. getmtime ( self
._ DscFile
)
748 TxtTime
= os
. path
. getmtime ( UpdTxtFile
)
749 if DscTime
> TxtTime
:
753 # DSC has not been modified yet
754 # So don't have to re-generate other files
755 self
. Error
= 'No DSC file change, skip to create UPD TXT file'
758 TxtFd
= open ( UpdTxtFile
, "w" )
759 TxtFd
. write ( " %s \n " % ( __copyright_txt__
% date
. today (). year
))
763 if self
._ MapVer
== 1 :
767 for Item
in self
._ CfgItemList
:
768 if Item
[ 'region' ] != 'UPD' :
770 Offset
= Item
[ 'offset' ]
771 if NextOffset
< Offset
:
773 TxtFd
. write ( " %s .UnusedUpdSpace %d | %s0x%0 4X|0x %0 4X| {0} \n " % ( Item
[ 'space' ], SpaceIdx
, Default
, NextOffset
, Offset
- NextOffset
))
774 SpaceIdx
= SpaceIdx
+ 1
775 NextOffset
= Offset
+ Item
[ 'length' ]
776 TxtFd
. write ( " %s . %s | %s0x%0 4X| %s | %s \n " % ( Item
[ 'space' ], Item
[ 'cname' ], Default
, Item
[ 'offset' ], Item
[ 'length' ], Item
[ 'value' ]))
780 def CreateField ( self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
):
787 if Length
in [ 1 , 2 , 4 , 8 ]:
788 Type
= "UINT %d " % ( Length
* 8 )
793 if Item
and Item
[ 'value' ]. startswith ( '{' ):
799 if Struct
in [ 'UINT8' , 'UINT16' , 'UINT32' , 'UINT64' ]:
801 Unit
= int ( Type
[ 4 :]) / 8
802 Length
= Length
/ Unit
807 Name
= Name
+ '[ %d ]' % Length
809 if len ( Type
) < PosName
:
810 Space1
= PosName
- len ( Type
)
815 NameLine
= " %s \n " % BsfName
818 HelpLine
= " %s \n " % Help
823 OffsetStr
= '0x %0 4X' % Offset
825 return "/** Offset %s \n %s%s **/ \n %s%s%s ; \n " % ( OffsetStr
, NameLine
, HelpLine
, Type
, ' ' * Space1
, Name
,)
827 def PostProcessBody ( self
, TextBody
):
833 for Line
in TextBody
:
834 Match
= re
. match ( "^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)" , Line
)
836 Line
= Match
. group ( 4 )
838 if Match
and Match
. group ( 3 ) == 'START' :
839 NewTextBody
. append ( 'typedef struct { \n ' )
840 StructName
= Match
. group ( 1 )
841 VariableName
= Match
. group ( 2 )
842 MatchOffset
= re
. search ( '/\*\*\sOffset\s0x([a-fA-F0-9]+)' , Line
)
844 Offset
= int ( MatchOffset
. group ( 1 ), 16 )
849 OldTextBody
. append ( self
. CreateField ( None , VariableName
, 0 , Offset
, StructName
, '' , '' ))
851 NewTextBody
. append ( Line
)
853 OldTextBody
. append ( Line
)
855 if Match
and Match
. group ( 3 ) == 'END' :
856 if ( StructName
!= Match
. group ( 1 )) or ( VariableName
!= Match
. group ( 2 )):
857 print "Unmatched struct name ' %s ' and ' %s ' !" % ( StructName
, Match
. group ( 1 ))
859 NewTextBody
. append ( '} %s ; \n\n ' % StructName
)
861 NewTextBody
. extend ( OldTextBody
)
864 def CreateHeaderFile ( self
, InputHeaderFile
, IsInternal
):
868 HeaderFile
= os
. path
. join ( FvDir
, 'FspUpdVpdInternal.h' )
870 HeaderFile
= os
. path
. join ( FvDir
, 'FspUpdVpd.h' )
872 # Check if header needs to be recreated
875 if not os
. path
. exists ( HeaderFile
):
878 DscTime
= os
. path
. getmtime ( self
._ DscFile
)
879 HeadTime
= os
. path
. getmtime ( HeaderFile
)
880 if not os
. path
. exists ( InputHeaderFile
):
883 InpTime
= os
. path
. getmtime ( InputHeaderFile
)
884 if DscTime
> HeadTime
or InpTime
> HeadTime
:
888 self
. Error
= "No DSC or input header file is changed, skip the header file generating"
892 for Region
in [ 'UPD' , 'VPD' ]:
894 # Write PcdVpdRegionSign and PcdImageRevision
896 if 'VPD_TOOL_GUID' not in self
._ MacroDict
:
897 self
. Error
= "VPD_TOOL_GUID definition is missing in DSC file"
900 BinFile
= os
. path
. join ( FvDir
, self
._ MacroDict
[ 'VPD_TOOL_GUID' ] + ".bin" )
901 if not os
. path
. exists ( BinFile
):
902 self
. Error
= "VPD binary file ' %s ' does not exist" % BinFile
905 BinFd
= open ( BinFile
, "rb" )
906 IdStr
= BinFd
. read ( 0x08 )
907 ImageId
= struct
. unpack ( '<Q' , IdStr
)
908 ImageRev
= struct
. unpack ( '<I' , BinFd
. read ( 0x04 ))
911 TxtBody
. append ( "#define FSP_IMAGE_ID 0x %0 16X /* ' %s ' */ \n " % ( ImageId
[ 0 ], IdStr
))
912 TxtBody
. append ( "#define FSP_IMAGE_REV 0x %0 8X \n\n " % ImageRev
[ 0 ])
914 TxtBody
. append ( "typedef struct _" + Region
[ 0 ] + "PD_DATA_REGION { \n " )
923 for Item
in self
._ CfgItemList
:
924 if Item
[ 'region' ] != Region
:
927 NextVisible
= LastVisible
929 if LastVisible
and ( Item
[ 'header' ] == 'OFF' ):
931 ResvOffset
= Item
[ 'offset' ]
932 elif ( not LastVisible
) and Item
[ 'header' ] == 'ON' :
934 Name
= "Reserved" + Region
[ 0 ] + "pdSpace %d " % ResvIdx
935 ResvIdx
= ResvIdx
+ 1
936 TxtBody
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - ResvOffset
, ResvOffset
, '' , '' , '' ))
938 if Offset
< Item
[ "offset" ]:
939 if IsInternal
or LastVisible
:
940 Name
= "Unused" + Region
[ 0 ] + "pdSpace %d " % SpaceIdx
941 LineBuffer
. append ( self
. CreateField ( Item
, Name
, Item
[ "offset" ] - Offset
, Offset
, '' , '' , '' ))
942 SpaceIdx
= SpaceIdx
+ 1
943 Offset
= Item
[ "offset" ]
945 if Offset
!= Item
[ "offset" ]:
946 self
. Error
= "Unsorted offset 0x %0 4X \n " % Item
[ "offset" ]
949 LastVisible
= NextVisible
951 Offset
= Offset
+ Item
[ "length" ]
952 if IsInternal
or LastVisible
:
953 for Each
in LineBuffer
:
954 TxtBody
. append ( Each
)
956 Embed
= Item
[ "embed" ]. upper ()
957 if Embed
. endswith ( ':START' ) or Embed
. endswith ( ':END' ):
958 Marker
= '/* EMBED_STRUCT: %s */ ' % Item
[ "embed" ]
963 self
. Error
= "Invalid embedded structure format ' %s '! \n " % Item
[ "embed" ]
965 Line
= Marker
+ self
. CreateField ( Item
, Item
[ "cname" ], Item
[ "length" ], Item
[ "offset" ], Item
[ 'struct' ], Item
[ 'name' ], Item
[ 'help' ])
968 TxtBody
. append ( "} " + Region
[ 0 ] + "PD_DATA_REGION; \n\n " )
970 # Handle the embedded data structure
971 TxtBody
= self
. PostProcessBody ( TxtBody
)
973 HeaderFd
= open ( HeaderFile
, "w" )
974 FileBase
= os
. path
. basename ( HeaderFile
)
975 FileName
= FileBase
. replace ( "." , "_" ). upper ()
976 HeaderFd
. write ( " %s \n " % ( __copyright_h__
% date
. today (). year
))
977 HeaderFd
. write ( "#ifndef __ %s __ \n " % FileName
)
978 HeaderFd
. write ( "#define __ %s __ \n\n " % FileName
)
979 HeaderFd
. write ( "#pragma pack(1) \n\n " )
981 if InputHeaderFile
!= '' :
982 if not os
. path
. exists ( InputHeaderFile
):
983 self
. Error
= "Input header file ' %s ' does not exist" % InputHeaderFile
986 InFd
= open ( InputHeaderFile
, "r" )
987 IncLines
= InFd
. readlines ()
991 for Line
in IncLines
:
992 Match
= re
. search ( "!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+" , Line
)
994 if Match
. group ( 1 ) == "BEGIN" :
1001 HeaderFd
. write ( Line
)
1002 HeaderFd
. write ( " \n\n " )
1004 for Line
in TxtBody
:
1005 HeaderFd
. write ( Line
)
1006 HeaderFd
. write ( "#pragma pack() \n\n " )
1007 HeaderFd
. write ( "#endif \n " )
1012 def WriteBsfStruct ( self
, BsfFd
, Item
):
1013 if Item
[ 'type' ] == "None" :
1014 Space
= "gPlatformFspPkgTokenSpaceGuid"
1016 Space
= Item
[ 'space' ]
1017 Line
= " $ %s _ %s " % ( Space
, Item
[ 'cname' ])
1018 Match
= re
. match ( "\s*\{([x0-9a-fA-F,\s]+)\}\s*" , Item
[ 'value' ])
1020 DefaultValue
= Match
. group ( 1 ). strip ()
1022 DefaultValue
= Item
[ 'value' ]. strip ()
1023 BsfFd
. write ( " %s%s% 4d bytes $_DEFAULT_ = %s \n " % ( Line
, ' ' * ( 64 - len ( Line
)), Item
[ 'length' ], DefaultValue
))
1025 if Item
[ 'type' ] == "Combo" :
1026 if not Item
[ 'option' ] in self
._ BuidinOption
:
1027 OptList
= Item
[ 'option' ]. split ( ',' )
1028 for Option
in OptList
:
1029 Option
= Option
. strip ()
1030 ( OpVal
, OpStr
) = Option
. split ( ':' )
1031 TmpList
. append (( OpVal
, OpStr
))
1034 def WriteBsfOption ( self
, BsfFd
, Item
):
1035 PcdName
= Item
[ 'space' ] + '_' + Item
[ 'cname' ]
1037 if Item
[ 'type' ] == "Combo" :
1038 if Item
[ 'option' ] in self
._ BuidinOption
:
1039 Options
= self
._ BuidinOption
[ Item
[ 'option' ]]
1042 BsfFd
. write ( ' %s $ %s , " %s ", & %s , \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ], Options
));
1044 elif Item
[ 'type' ]. startswith ( "EditNum" ):
1045 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' ])
1047 BsfFd
. write ( ' EditNum $ %s , " %s ", %s , \n ' % ( PcdName
, Item
[ 'name' ], Match
. group ( 1 )));
1049 elif Item
[ 'type' ]. startswith ( "EditText" ):
1050 BsfFd
. write ( ' %s $ %s , " %s ", \n ' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]));
1052 elif Item
[ 'type' ] == "Table" :
1053 Columns
= Item
[ 'option' ]. split ( ',' )
1054 if len ( Columns
) != 0 :
1055 BsfFd
. write ( ' %s $ %s " %s ",' % ( Item
[ 'type' ], PcdName
, Item
[ 'name' ]));
1057 Fmt
= Col
. split ( ':' )
1059 raise Exception ( "Column format ' %s ' is invalid !" % Fmt
)
1061 Dtype
= int ( Fmt
[ 1 ]. strip ())
1063 raise Exception ( "Column size ' %s ' is invalid !" % Fmt
[ 1 ])
1064 BsfFd
. write ( ' \n Column " %s ", %d bytes, %s ' % ( Fmt
[ 0 ]. strip (), Dtype
, Fmt
[ 2 ]. strip ()))
1069 HelpLines
= Item
[ 'help' ]. split ( ' \\ n \\ r' )
1071 for HelpLine
in HelpLines
:
1074 BsfFd
. write ( ' Help " %s " \n ' % ( HelpLine
));
1076 BsfFd
. write ( ' " %s " \n ' % ( HelpLine
));
1078 BsfFd
. write ( ' "Valid range: %s ~ %s " \n ' % ( Match
. group ( 2 ), Match
. group ( 3 )));
1080 def GenerateBsfFile ( self
, BsfFile
):
1083 self
. Error
= "BSF output file ' %s ' is invalid" % BsfFile
1088 BsfFd
= open ( BsfFile
, "w" )
1089 BsfFd
. write ( " %s \n " % ( __copyright_bsf__
% date
. today (). year
))
1090 BsfFd
. write ( " %s \n " % self
._ GlobalDataDef
);
1091 BsfFd
. write ( "StructDef \n " )
1093 for Item
in self
._ CfgItemList
:
1094 if Item
[ 'find' ] != '' :
1095 BsfFd
. write ( ' \n Find " %s " \n ' % Item
[ 'find' ])
1096 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1097 if Item
[ 'name' ] != '' :
1098 if NextOffset
!= Item
[ 'offset' ]:
1099 BsfFd
. write ( " Skip %d bytes \n " % ( Item
[ 'offset' ] - NextOffset
))
1100 if len ( Item
[ 'subreg' ]) > 0 :
1101 NextOffset
= Item
[ 'offset' ]
1102 for SubItem
in Item
[ 'subreg' ]:
1103 NextOffset
+= SubItem
[ 'length' ]
1104 if SubItem
[ 'name' ] == '' :
1105 BsfFd
. write ( " Skip %d bytes \n " % ( SubItem
[ 'length' ]))
1107 Options
= self
. WriteBsfStruct ( BsfFd
, SubItem
)
1108 if len ( Options
) > 0 :
1109 OptionDict
[ SubItem
[ 'space' ]+ '_' + SubItem
[ 'cname' ]] = Options
1110 if ( Item
[ 'offset' ] + Item
[ 'length' ]) < NextOffset
:
1111 self
. Error
= "BSF sub region ' %s ' length does not match" % ( Item
[ 'space' ]+ '.' + Item
[ 'cname' ])
1114 NextOffset
= Item
[ 'offset' ] + Item
[ 'length' ]
1115 Options
= self
. WriteBsfStruct ( BsfFd
, Item
)
1116 if len ( Options
) > 0 :
1117 OptionDict
[ Item
[ 'space' ]+ '_' + Item
[ 'cname' ]] = Options
1118 BsfFd
. write ( " \n EndStruct \n\n " )
1120 BsfFd
. write ( " %s " % self
._ BuidinOptionTxt
);
1122 for Each
in OptionDict
:
1123 BsfFd
. write ( "List & %s \n " % Each
);
1124 for Item
in OptionDict
[ Each
]:
1125 BsfFd
. write ( ' Selection %s , " %s " \n ' % ( Item
[ 0 ], Item
[ 1 ]));
1126 BsfFd
. write ( "EndList \n\n " );
1128 BsfFd
. write ( "BeginInfoBlock \n " );
1129 BsfFd
. write ( ' PPVer " %s " \n ' % ( self
._ CfgBlkDict
[ 'ver' ]));
1130 BsfFd
. write ( ' Description " %s " \n ' % ( self
._ CfgBlkDict
[ 'name' ]));
1131 BsfFd
. write ( "EndInfoBlock \n\n " );
1133 for Each
in self
._ CfgPageDict
:
1134 BsfFd
. write ( 'Page " %s " \n ' % self
._ CfgPageDict
[ Each
]);
1136 for Item
in self
._ CfgItemList
:
1137 if Item
[ 'name' ] != '' :
1138 if Item
[ 'page' ] != Each
:
1140 if len ( Item
[ 'subreg' ]) > 0 :
1141 for SubItem
in Item
[ 'subreg' ]:
1142 if SubItem
[ 'name' ] != '' :
1143 BsfItems
. append ( SubItem
)
1145 BsfItems
. append ( Item
)
1147 BsfItems
. sort ( key
= lambda x
: x
[ 'order' ])
1149 for Item
in BsfItems
:
1150 self
. WriteBsfOption ( BsfFd
, Item
)
1151 BsfFd
. write ( "EndPage \n\n " );
1158 print "GenCfgOpt Version 0.50"
1160 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]"
1161 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]"
1162 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1166 # Parse the options and args
1168 GenCfgOpt
= CGenCfgOpt ()
1169 argc
= len ( sys
. argv
)
1174 DscFile
= sys
. argv
[ 2 ]
1175 if not os
. path
. exists ( DscFile
):
1176 print "ERROR: Cannot open DSC file ' %s ' !" % DscFile
1181 if sys
. argv
[ 4 ][ 0 ] == '-' :
1184 OutFile
= sys
. argv
[ 4 ]
1186 if GenCfgOpt
. ParseMacros ( sys
. argv
[ Start
:]) != 0 :
1187 print "ERROR: Macro parsing failed !"
1191 if not os
. path
. isdir ( FvDir
):
1192 print "ERROR: FV folder ' %s ' is invalid !" % FvDir
1195 if GenCfgOpt
. ParseDscFile ( DscFile
, FvDir
) != 0 :
1196 print "ERROR: %s !" % GenCfgOpt
. Error
1199 if GenCfgOpt
. UpdateVpdSizeField () != 0 :
1200 print "ERROR: %s !" % GenCfgOpt
. Error
1203 if GenCfgOpt
. UpdateSubRegionDefaultValue () != 0 :
1204 print "ERROR: %s !" % GenCfgOpt
. Error
1207 if sys
. argv
[ 1 ] == "UPDTXT" :
1208 Ret
= GenCfgOpt
. CreateUpdTxtFile ( OutFile
)
1210 # No change is detected
1212 print "INFO: %s !" % ( GenCfgOpt
. Error
)
1214 print "ERROR: %s !" % ( GenCfgOpt
. Error
)
1216 elif sys
. argv
[ 1 ] == "HEADER" :
1217 Ret
= GenCfgOpt
. CreateHeaderFile ( OutFile
, True )
1219 # No change is detected
1221 print "INFO: %s !" % ( GenCfgOpt
. Error
)
1223 print "ERROR: %s !" % ( GenCfgOpt
. Error
)
1225 if GenCfgOpt
. CreateHeaderFile ( OutFile
, False ) != 0 :
1226 print "ERROR: %s !" % GenCfgOpt
. Error
1228 elif sys
. argv
[ 1 ] == "GENBSF" :
1229 if GenCfgOpt
. GenerateBsfFile ( OutFile
) != 0 :
1230 print "ERROR: %s !" % GenCfgOpt
. Error
1236 print "ERROR: Unknown command ' %s ' !" % sys
. argv
[ 1 ]
1243 if __name__
== '__main__' :