]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/GenCfgOpt.py
3 # Copyright (c) 2014 - 2016, 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
):
292 self
.ReleaseMode
= True
294 self
._GlobalDataDef
= """
300 self
._BuidinOptionTxt
= """
302 Selection 0x1 , "Enabled"
303 Selection 0x0 , "Disabled"
308 self
._BsfKeyList
= ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
309 self
._HdrKeyList
= ['HEADER','STRUCT', 'EMBED', 'COMMENT']
310 self
._BuidinOption
= {'$EN_DIS' : 'EN_DIS'}
314 self
._CfgBlkDict
= {}
315 self
._CfgPageDict
= {}
316 self
._CfgItemList
= []
321 def ParseBuildMode (self
, OutputStr
):
322 if "RELEASE_" in OutputStr
:
323 self
.ReleaseMode
= True
324 if "DEBUG_" in OutputStr
:
325 self
.ReleaseMode
= False
328 def ParseMacros (self
, MacroDefStr
):
329 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
332 for Macro
in MacroDefStr
:
333 if Macro
.startswith('-D'):
341 Match
= re
.match("(\w+)=(.+)", Macro
)
343 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
345 Match
= re
.match("(\w+)", Macro
)
347 self
._MacroDict
[Match
.group(1)] = ''
348 if len(self
._MacroDict
) == 0:
353 print "INFO : Macro dictionary:"
354 for Each
in self
._MacroDict
:
355 print " $(%s) = [ %s ]" % (Each
, self
._MacroDict
[Each
])
358 def EvaulateIfdef (self
, Macro
):
359 Result
= Macro
in self
._MacroDict
361 print "INFO : Eval Ifdef [%s] : %s" % (Macro
, Result
)
364 def ExpandMacros (self
, Input
):
366 Match
= re
.findall("\$\(\w+\)", Input
)
369 Variable
= Each
[2:-1]
370 if Variable
in self
._MacroDict
:
371 Line
= Line
.replace(Each
, self
._MacroDict
[Variable
])
374 print "WARN : %s is not defined" % Each
375 Line
= Line
.replace(Each
, Each
[2:-1])
378 def ExpandPcds (self
, Input
):
380 Match
= re
.findall("(\w+\.\w+)", Input
)
382 for PcdName
in Match
:
383 if PcdName
in self
._PcdsDict
:
384 Line
= Line
.replace(PcdName
, self
._PcdsDict
[PcdName
])
387 print "WARN : %s is not defined" % PcdName
390 def EvaluateExpress (self
, Expr
):
391 ExpExpr
= self
.ExpandPcds(Expr
)
392 ExpExpr
= self
.ExpandMacros(ExpExpr
)
393 LogExpr
= CLogicalExpression()
394 Result
= LogExpr
.evaluateExpress (ExpExpr
)
396 print "INFO : Eval Express [%s] : %s" % (Expr
, Result
)
399 def FormatListValue(self
, ConfigDict
):
400 Struct
= ConfigDict
['struct']
401 if Struct
not in ['UINT8','UINT16','UINT32','UINT64']:
405 binlist
= ConfigDict
['value'][1:-1].split(',')
408 if each
.startswith('0x'):
409 value
= int(each
, 16)
412 dataarray
.append(value
)
414 unit
= int(Struct
[4:]) / 8
415 if int(ConfigDict
['length']) != unit
* len(dataarray
):
416 raise Exception("Array size is not proper for '%s' !" % ConfigDict
['cname'])
419 for each
in dataarray
:
421 for loop
in xrange(unit
):
422 bytearray
.append("0x%02X" % (value
& 0xFF))
424 newvalue
= '{' + ','.join(bytearray
) + '}'
425 ConfigDict
['value'] = newvalue
428 def ParseDscFile (self
, DscFile
, FvDir
):
429 self
._CfgItemList
= []
430 self
._CfgPageDict
= {}
431 self
._CfgBlkDict
= {}
432 self
._DscFile
= DscFile
445 DscFd
= open(DscFile
, "r")
446 DscLines
= DscFd
.readlines()
450 DscLine
= DscLines
.pop(0).strip()
452 Match
= re
.match("^\[(.+)\]", DscLine
)
453 if Match
is not None:
458 if Match
.group(1).lower() == "Defines".lower():
460 if Match
.group(1).lower() == "PcdsFeatureFlag".lower():
462 elif Match
.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
464 ConfigDict
['header'] = 'ON'
465 ConfigDict
['region'] = 'UPD'
466 ConfigDict
['order'] = -1
467 ConfigDict
['page'] = ''
468 ConfigDict
['name'] = ''
469 ConfigDict
['find'] = ''
470 ConfigDict
['struct'] = ''
471 ConfigDict
['embed'] = ''
472 ConfigDict
['comment'] = ''
473 ConfigDict
['subreg'] = []
476 if IsDefSect
or IsPcdSect
or IsUpdSect
or IsVpdSect
:
477 if re
.match("^!else($|\s+#.+)", DscLine
):
479 IfStack
[-1] = not IfStack
[-1]
481 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine
)
483 elif re
.match("^!endif($|\s+#.+)", DscLine
):
486 Level
= ElifStack
.pop()
490 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine
)
494 Match
= re
.match("!(ifdef|ifndef)\s+(.+)", DscLine
)
496 Result
= self
.EvaulateIfdef (Match
.group(2))
497 if Match
.group(1) == 'ifndef':
499 IfStack
.append(Result
)
502 Match
= re
.match("!(if|elseif)\s+(.+)", DscLine
)
504 Result
= self
.EvaluateExpress(Match
.group(2))
505 if Match
.group(1) == "if":
507 IfStack
.append(Result
)
510 IfStack
[-1] = not IfStack
[-1]
511 IfStack
.append(Result
)
512 ElifStack
[-1] = ElifStack
[-1] + 1
514 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine
)
518 Handle
= reduce(lambda x
,y
: x
and y
, IfStack
)
522 Match
= re
.match("!include\s+(.+)", DscLine
)
524 IncludeFilePath
= Match
.group(1)
525 IncludeFilePath
= self
.ExpandMacros(IncludeFilePath
)
526 PackagesPath
= os
.getenv("PACKAGES_PATH")
527 for PackagePath
in PackagesPath
.split(os
.pathsep
):
528 IncludeFilePathAbs
= os
.path
.join(os
.path
.normpath(PackagePath
), os
.path
.normpath(IncludeFilePath
))
529 if os
.path
.exists(IncludeFilePathAbs
):
530 IncludeDsc
= open(IncludeFilePathAbs
, "r")
532 if IncludeDsc
== None:
533 print("ERROR: Cannot open file '%s'" % IncludeFilePath
)
535 NewDscLines
= IncludeDsc
.readlines()
537 DscLines
= NewDscLines
+ DscLines
539 if DscLine
.startswith('!'):
540 print("ERROR: Unrecoginized directive for line '%s'" % DscLine
)
546 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
547 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
548 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
549 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
550 Match
= re
.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine
)
552 self
._MacroDict
[Match
.group(1)] = Match
.group(2)
554 print "INFO : DEFINE %s = [ %s ]" % (Match
.group(1), Match
.group(2))
556 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
557 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
558 Match
= re
.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine
)
560 self
._PcdsDict
[Match
.group(1)] = Match
.group(2)
562 print "INFO : PCD %s = [ %s ]" % (Match
.group(1), Match
.group(2))
564 Match
= re
.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine
)
566 Remaining
= Match
.group(2)
567 if Match
.group(1) == '!BSF' or Match
.group(1) == '@Bsf':
568 Match
= re
.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining
)
570 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
571 PageList
= Match
.group(1).split(',')
572 for Page
in PageList
:
574 Match
= re
.match("(\w+):\"(.+)\"", Page
)
575 self
._CfgPageDict
[Match
.group(1)] = Match
.group(2)
577 Match
= re
.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining
)
579 self
._CfgBlkDict
['name'] = Match
.group(1)
580 self
._CfgBlkDict
['ver'] = Match
.group(2)
582 for Key
in self
._BsfKeyList
:
583 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
585 if Key
in ['NAME', 'HELP', 'OPTION'] and Match
.group(1).startswith('+'):
586 ConfigDict
[Key
.lower()] += Match
.group(1)[1:]
588 ConfigDict
[Key
.lower()] = Match
.group(1)
590 for Key
in self
._HdrKeyList
:
591 Match
= re
.match("(?:^|.+\s+)%s:{(.+?)}" % Key
, Remaining
)
593 ConfigDict
[Key
.lower()] = Match
.group(1)
595 Match
= re
.match("^\s*#\s+@Prompt\s+(.+)", DscLine
)
597 ConfigDict
['name'] = Match
.group(1)
599 Match
= re
.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine
)
601 if Match
.group(2).strip() in self
._BuidinOption
:
602 ConfigDict
['option'] = Match
.group(2).strip()
604 OptionValueList
= Match
.group(2).split(',')
605 OptionStringList
= Match
.group(3).split(',')
607 for Option
in OptionValueList
:
608 Option
= Option
.strip()
609 ConfigDict
['option'] = ConfigDict
['option'] + str(Option
) + ':' + OptionStringList
[Index
].strip()
611 if Index
in range(len(OptionValueList
)):
612 ConfigDict
['option'] += ', '
613 ConfigDict
['type'] = "Combo"
615 Match
= re
.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine
)
617 if "0x" in Match
.group(2) or "0x" in Match
.group(3):
618 ConfigDict
['type'] = "EditNum, HEX, (%s,%s)" % (Match
.group(2), Match
.group(3))
620 ConfigDict
['type'] = "EditNum, DEC, (%s,%s)" % (Match
.group(2), Match
.group(3))
622 Match
= re
.match("^\s*##\s+(.+)", DscLine
)
624 ConfigDict
['help'] = Match
.group(1)
628 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
)
630 Match
= re
.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine
)
632 ConfigDict
['space'] = Match
.group(1)
633 ConfigDict
['cname'] = Match
.group(2)
634 ConfigDict
['offset'] = int (Match
.group(3), 16)
635 if ConfigDict
['order'] == -1:
636 ConfigDict
['order'] = ConfigDict
['offset'] << 8
638 (Major
, Minor
) = ConfigDict
['order'].split('.')
639 ConfigDict
['order'] = (int (Major
, 16) << 8 ) + int (Minor
, 16)
641 Value
= Match
.group(5).strip()
642 if Match
.group(4).startswith("0x"):
643 Length
= int (Match
.group(4), 16)
645 Length
= int (Match
.group(4))
647 Value
= Match
.group(4)
650 Value
= Value
.strip()
652 Match
= re
.match("^.+\s*\|\s*(.+)", Value
)
654 Value
= Match
.group(1)
657 ConfigDict
['length'] = Length
658 Match
= re
.match("\$\((\w+)\)", Value
)
660 if Match
.group(1) in self
._MacroDict
:
661 Value
= self
._MacroDict
[Match
.group(1)]
663 ConfigDict
['value'] = Value
664 if (len(Value
) > 0) and (Value
[0] == '{'):
665 Value
= self
.FormatListValue(ConfigDict
)
667 if ConfigDict
['name'] == '':
668 # Clear BSF specific items
669 ConfigDict
['bsfname'] = ''
670 ConfigDict
['help'] = ''
671 ConfigDict
['type'] = ''
672 ConfigDict
['option'] = ''
674 self
._CfgItemList
.append(ConfigDict
.copy())
675 ConfigDict
['name'] = ''
676 ConfigDict
['find'] = ''
677 ConfigDict
['struct'] = ''
678 ConfigDict
['embed'] = ''
679 ConfigDict
['comment'] = ''
680 ConfigDict
['order'] = -1
681 ConfigDict
['subreg'] = []
682 ConfigDict
['option'] = ''
684 # It could be a virtual item as below
685 # !BSF FIELD:{SerialDebugPortAddress0:1}
687 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
688 Match
= re
.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine
)
690 SubCfgDict
= ConfigDict
.copy()
691 if (Match
.group(4) == None) or (Match
.group(4) == 'B'):
693 elif Match
.group(4) == 'b':
696 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine
)
698 SubCfgDict
['cname'] = Match
.group(2)
699 SubCfgDict
['bitlength'] = int (Match
.group(3)) * UnitBitLen
700 if SubCfgDict
['bitlength'] > 0:
701 LastItem
= self
._CfgItemList
[-1]
702 if len(LastItem
['subreg']) == 0:
705 SubOffset
= LastItem
['subreg'][-1]['bitoffset'] + LastItem
['subreg'][-1]['bitlength']
706 SubCfgDict
['bitoffset'] = SubOffset
707 LastItem
['subreg'].append (SubCfgDict
.copy())
708 ConfigDict
['name'] = ''
711 def GetBsfBitFields (self
, subitem
, bytes
):
712 start
= subitem
['bitoffset']
713 end
= start
+ subitem
['bitlength']
714 bitsvalue
= ''.join('{0:08b}'.format(i
) for i
in bytes
[::-1])
715 bitsvalue
= bitsvalue
[::-1]
716 bitslen
= len(bitsvalue
)
717 if start
> bitslen
or end
> bitslen
:
718 print "Invalid bits offset [%d,%d] for %s" % (start
, end
, subitem
['name'])
720 return hex(int(bitsvalue
[start
:end
][::-1], 2))
722 def UpdateSubRegionDefaultValue (self
):
724 for Item
in self
._CfgItemList
:
725 if len(Item
['subreg']) == 0:
728 if Item
['value'][0] == '{':
729 binlist
= Item
['value'][1:-1].split(',')
732 if each
.startswith('0x'):
733 value
= int(each
, 16)
736 bytearray
.append(value
)
738 if Item
['value'].startswith('0x'):
739 value
= int(Item
['value'], 16)
741 value
= int(Item
['value'])
743 while idx
< Item
['length']:
744 bytearray
.append(value
& 0xFF)
747 for SubItem
in Item
['subreg']:
748 valuestr
= self
.GetBsfBitFields(SubItem
, bytearray
)
749 SubItem
['value'] = valuestr
752 def CreateSplitUpdTxt (self
, UpdTxtFile
):
753 GuidList
= ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
754 SignatureList
= ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
755 for Index
in range(len(GuidList
)):
758 if GuidList
[Index
] not in self
._MacroDict
:
759 self
.Error
= "%s definition is missing in DSC file" % (GuidList
[Index
])
763 UpdTxtFile
= os
.path
.join(FvDir
, self
._MacroDict
[GuidList
[Index
]] + '.txt')
766 if not os
.path
.exists(UpdTxtFile
):
769 DscTime
= os
.path
.getmtime(self
._DscFile
)
770 TxtTime
= os
.path
.getmtime(UpdTxtFile
)
771 if DscTime
> TxtTime
:
775 # DSC has not been modified yet
776 # So don't have to re-generate other files
777 self
.Error
= 'No DSC file change, skip to create UPD TXT file'
780 TxtFd
= open(UpdTxtFile
, "w")
781 TxtFd
.write("%s\n" % (__copyright_txt__
% date
.today().year
))
789 for Item
in self
._CfgItemList
:
790 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
791 StartAddr
= Item
['offset']
792 NextOffset
= StartAddr
794 if Item
['cname'] == 'UpdTerminator' and InRange
== True:
795 EndAddr
= Item
['offset']
798 for Item
in self
._CfgItemList
:
799 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == SignatureList
[Index
]:
803 if Item
['cname'] == 'UpdTerminator':
805 if Item
['region'] != 'UPD':
807 Offset
= Item
['offset']
808 if StartAddr
> Offset
or EndAddr
< Offset
:
810 if NextOffset
< Offset
:
812 TxtFd
.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item
['space'], SpaceIdx
, Default
, NextOffset
- StartAddr
, Offset
- NextOffset
))
813 SpaceIdx
= SpaceIdx
+ 1
814 NextOffset
= Offset
+ Item
['length']
815 if Item
['cname'] == 'PcdSerialIoUartDebugEnable':
816 if self
.ReleaseMode
== False:
818 TxtFd
.write("%s.%s|%s0x%04X|%s|%s\n" % (Item
['space'],Item
['cname'],Default
,Item
['offset'] - StartAddr
,Item
['length'],Item
['value']))
822 def ProcessMultilines (self
, String
, MaxCharLength
):
824 StringLength
= len(String
)
825 CurrentStringStart
= 0
828 if len(String
) <= MaxCharLength
:
829 while (StringOffset
< StringLength
):
830 if StringOffset
>= 1:
831 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
832 BreakLineDict
.append (StringOffset
+ 1)
834 if BreakLineDict
!= []:
835 for Each
in BreakLineDict
:
836 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
837 CurrentStringStart
= Each
838 if StringLength
- CurrentStringStart
> 0:
839 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
841 Multilines
= " %s\n" % String
845 FoundSpaceChar
= False
846 while (StringOffset
< StringLength
):
847 if StringOffset
>= 1:
848 if NewLineCount
>= MaxCharLength
- 1:
849 if String
[StringOffset
] == ' ' and StringLength
- StringOffset
> 10:
850 BreakLineDict
.append (NewLineStart
+ NewLineCount
)
851 NewLineStart
= NewLineStart
+ NewLineCount
853 FoundSpaceChar
= True
854 elif StringOffset
== StringLength
- 1 and FoundSpaceChar
== False:
855 BreakLineDict
.append (0)
856 if String
[StringOffset
- 1] == '\\' and String
[StringOffset
] == 'n':
857 BreakLineDict
.append (StringOffset
+ 1)
858 NewLineStart
= StringOffset
+ 1
862 if BreakLineDict
!= []:
863 BreakLineDict
.sort ()
864 for Each
in BreakLineDict
:
866 Multilines
+= " %s\n" % String
[CurrentStringStart
:Each
].lstrip()
867 CurrentStringStart
= Each
868 if StringLength
- CurrentStringStart
> 0:
869 Multilines
+= " %s\n" % String
[CurrentStringStart
:].lstrip()
872 def CreateField (self
, Item
, Name
, Length
, Offset
, Struct
, BsfName
, Help
, Option
):
880 if Length
in [1,2,4,8]:
881 Type
= "UINT%d" % (Length
* 8)
882 if Name
.startswith("UnusedUpdSpace") and Length
!= 1:
889 if Item
and Item
['value'].startswith('{'):
895 if Struct
in ['UINT8','UINT16','UINT32','UINT64']:
897 Unit
= int(Type
[4:]) / 8
898 Length
= Length
/ Unit
903 Name
= Name
+ '[%d]' % Length
905 if len(Type
) < PosName
:
906 Space1
= PosName
- len(Type
)
911 NameLine
=" - %s\n" % BsfName
916 HelpLine
= self
.ProcessMultilines (Help
, 80)
919 OptionLine
= self
.ProcessMultilines (Option
, 80)
924 OffsetStr
= '0x%04X' % Offset
926 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr
, NameLine
, HelpLine
, OptionLine
, Type
, ' ' * Space1
, Name
,)
928 def PostProcessBody (self
, TextBody
):
934 IsUpdHdrDefined
= False
936 for Line
in TextBody
:
937 SplitToLines
= Line
.splitlines()
938 MatchComment
= re
.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines
[0])
940 if MatchComment
.group(1) == 'FSP_UPD_HEADER':
944 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
945 CommentLine
= " " + MatchComment
.group(2) + "\n"
946 NewTextBody
.append("/**" + CommentLine
+ "**/\n")
947 Line
= Line
[(len(SplitToLines
[0]) + 1):]
949 Match
= re
.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line
)
951 Line
= Match
.group(4)
952 if Match
.group(1) == 'FSP_UPD_HEADER':
957 if Match
and Match
.group(3) == 'START':
958 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
959 NewTextBody
.append ('typedef struct {\n')
960 StructName
= Match
.group(1)
961 VariableName
= Match
.group(2)
962 MatchOffset
= re
.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line
)
964 Offset
= int(MatchOffset
.group(1), 16)
969 OldTextBody
.append (self
.CreateField (None, VariableName
, 0, Offset
, StructName
, '', '', ''))
971 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
972 NewTextBody
.append (Line
)
974 OldTextBody
.append (Line
)
976 if Match
and Match
.group(3) == 'END':
977 if (StructName
!= Match
.group(1)) or (VariableName
!= Match
.group(2)):
978 print "Unmatched struct name '%s' and '%s' !" % (StructName
, Match
.group(1))
980 if IsUpdHdrDefined
!= True or IsUpdHeader
!= True:
981 NewTextBody
.append ('} %s;\n\n' % StructName
)
982 IsUpdHdrDefined
= True
984 NewTextBody
.extend(OldTextBody
)
987 def CreateHeaderFile (self
, InputHeaderFile
):
990 HeaderFileName
= 'FspUpd.h'
991 HeaderFile
= os
.path
.join(FvDir
, HeaderFileName
)
993 # Check if header needs to be recreated
997 for Item
in self
._CfgItemList
:
998 if str(Item
['cname']) == 'Signature' and Item
['length'] == 8:
999 Value
= int(Item
['value'], 16)
1002 Chars
.append(chr(Value
& 0xFF))
1004 SignatureStr
= ''.join(Chars
)
1005 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly
1006 if '_T' in SignatureStr
[6:6+2]:
1007 TxtBody
.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1008 elif '_M' in SignatureStr
[6:6+2]:
1009 TxtBody
.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1010 elif '_S' in SignatureStr
[6:6+2]:
1011 TxtBody
.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item
['value'], SignatureStr
))
1012 TxtBody
.append("\n")
1014 for Region
in ['UPD']:
1016 UpdSignature
= ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS
1017 UpdStructure
= ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
1018 for Item
in self
._CfgItemList
:
1019 if Item
["cname"] == 'Signature' and Item
["value"][0:6] in UpdSignature
:
1020 UpdOffsetTable
.append (Item
["offset"])
1022 for UpdIdx
in range(len(UpdOffsetTable
)):
1024 for Item
in self
._CfgItemList
:
1025 if Item
["comment"] != '' and Item
["offset"] >= UpdOffsetTable
[UpdIdx
]:
1026 MatchComment
= re
.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item
["comment"])
1027 if MatchComment
and MatchComment
.group(1) == Region
[0]:
1028 CommentLine
= " " + MatchComment
.group(2) + "\n"
1029 TxtBody
.append("/**" + CommentLine
+ "**/\n")
1030 elif Item
["offset"] >= UpdOffsetTable
[UpdIdx
] and Item
["comment"] == '':
1031 Match
= re
.match("^FSP([\w|\W|\s])_UPD", UpdStructure
[UpdIdx
])
1033 TxtBody
.append("/** Fsp " + Match
.group(1) + " UPD Configuration\n**/\n")
1034 TxtBody
.append("typedef struct {\n")
1044 for Item
in self
._CfgItemList
:
1045 if Item
['cname'] == 'Signature' and str(Item
['value'])[0:6] == UpdSignature
[UpdIdx
] or Region
[0] == 'V':
1049 if Item
['cname'] == 'UpdTerminator':
1052 if Item
['region'] != Region
:
1055 if Item
["offset"] < UpdOffsetTable
[UpdIdx
]:
1058 NextVisible
= LastVisible
1060 if LastVisible
and (Item
['header'] == 'OFF'):
1062 ResvOffset
= Item
['offset']
1063 elif (not LastVisible
) and Item
['header'] == 'ON':
1065 Name
= "Reserved" + Region
[0] + "pdSpace%d" % ResvIdx
1066 ResvIdx
= ResvIdx
+ 1
1067 TxtBody
.append(self
.CreateField (Item
, Name
, Item
["offset"] - ResvOffset
, ResvOffset
, '', '', '', ''))
1069 if Offset
< Item
["offset"]:
1071 Name
= "Unused" + Region
[0] + "pdSpace%d" % SpaceIdx
1072 LineBuffer
.append(self
.CreateField (Item
, Name
, Item
["offset"] - Offset
, Offset
, '', '', '', ''))
1073 SpaceIdx
= SpaceIdx
+ 1
1074 Offset
= Item
["offset"]
1076 LastVisible
= NextVisible
1078 Offset
= Offset
+ Item
["length"]
1080 for Each
in LineBuffer
:
1081 TxtBody
.append (Each
)
1083 Comment
= Item
["comment"]
1084 Embed
= Item
["embed"].upper()
1085 if Embed
.endswith(':START') or Embed
.endswith(':END'):
1086 if not Comment
== '' and Embed
.endswith(':START'):
1087 Marker
= '/* COMMENT:%s */ \n' % Item
["comment"]
1088 Marker
= Marker
+ '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1090 Marker
= '/* EMBED_STRUCT:%s */ ' % Item
["embed"]
1095 self
.Error
= "Invalid embedded structure format '%s'!\n" % Item
["embed"]
1097 Line
= Marker
+ self
.CreateField (Item
, Item
["cname"], Item
["length"], Item
["offset"], Item
['struct'], Item
['name'], Item
['help'], Item
['option'])
1098 TxtBody
.append(Line
)
1099 if Item
['cname'] == 'UpdTerminator':
1101 TxtBody
.append("} " + UpdStructure
[UpdIdx
] + ";\n\n")
1103 # Handle the embedded data structure
1104 TxtBody
= self
.PostProcessBody (TxtBody
)
1106 HeaderTFileName
= 'FsptUpd.h'
1107 HeaderMFileName
= 'FspmUpd.h'
1108 HeaderSFileName
= 'FspsUpd.h'
1110 UpdRegionCheck
= ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
1111 UpdConfigCheck
= ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
1112 UpdSignatureCheck
= ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
1113 ExcludedSpecificUpd
= 'FSPM_ARCH_UPD'
1115 if InputHeaderFile
!= '':
1116 if not os
.path
.exists(InputHeaderFile
):
1117 self
.Error
= "Input header file '%s' does not exist" % InputHeaderFile
1120 InFd
= open(InputHeaderFile
, "r")
1121 IncLines
= InFd
.readlines()
1124 for item
in range(len(UpdRegionCheck
)):
1125 if UpdRegionCheck
[item
] == 'FSPT':
1126 HeaderFd
= open(os
.path
.join(FvDir
, HeaderTFileName
), "w")
1127 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderTFileName
))
1128 elif UpdRegionCheck
[item
] == 'FSPM':
1129 HeaderFd
= open(os
.path
.join(FvDir
, HeaderMFileName
), "w")
1130 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderMFileName
))
1131 elif UpdRegionCheck
[item
] == 'FSPS':
1132 HeaderFd
= open(os
.path
.join(FvDir
, HeaderSFileName
), "w")
1133 FileBase
= os
.path
.basename(os
.path
.join(FvDir
, HeaderSFileName
))
1134 FileName
= FileBase
.replace(".", "_").upper()
1135 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1136 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1137 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1138 HeaderFd
.write("#include <%s>\n\n" % HeaderFileName
)
1139 HeaderFd
.write("#pragma pack(1)\n\n")
1142 for Line
in IncLines
:
1143 Match
= re
.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line
)
1145 if Match
.group(2) == "BEGIN" and Match
.group(1) == UpdRegionCheck
[item
]:
1152 HeaderFd
.write(Line
)
1153 HeaderFd
.write("\n")
1159 StructStartWithComment
= []
1161 for Line
in TxtBody
:
1163 Match
= re
.match("(typedef struct {)", Line
)
1165 StartIndex
= Index
- 1
1166 Match
= re
.match("}\s([_A-Z0-9]+);", Line
)
1167 if Match
and (UpdRegionCheck
[item
] in Match
.group(1) or UpdConfigCheck
[item
] in Match
.group(1)) and (ExcludedSpecificUpd
not in Match
.group(1)):
1169 StructStart
.append(StartIndex
)
1170 StructEnd
.append(EndIndex
)
1172 for Line
in TxtBody
:
1174 for Item
in range(len(StructStart
)):
1175 if Index
== StructStart
[Item
]:
1176 Match
= re
.match("^(/\*\*\s*)", Line
)
1178 StructStartWithComment
.append(StructStart
[Item
])
1180 StructStartWithComment
.append(StructStart
[Item
] + 1)
1182 for Line
in TxtBody
:
1184 for Item
in range(len(StructStart
)):
1185 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1186 HeaderFd
.write (Line
)
1187 HeaderFd
.write("#pragma pack()\n\n")
1188 HeaderFd
.write("#endif\n")
1191 HeaderFd
= open(HeaderFile
, "w")
1192 FileBase
= os
.path
.basename(HeaderFile
)
1193 FileName
= FileBase
.replace(".", "_").upper()
1194 HeaderFd
.write("%s\n" % (__copyright_h__
% date
.today().year
))
1195 HeaderFd
.write("#ifndef __%s__\n" % FileName
)
1196 HeaderFd
.write("#define __%s__\n\n" % FileName
)
1197 HeaderFd
.write("#include <FspEas.h>\n\n")
1198 HeaderFd
.write("#pragma pack(1)\n\n")
1200 for item
in range(len(UpdRegionCheck
)):
1205 StructStartWithComment
= []
1207 for Line
in TxtBody
:
1209 Match
= re
.match("(typedef struct {)", Line
)
1211 StartIndex
= Index
- 1
1212 Match
= re
.match("#define\s([_A-Z0-9]+)\s*", Line
)
1213 if Match
and (UpdSignatureCheck
[item
] in Match
.group(1) or UpdSignatureCheck
[item
] in Match
.group(1)):
1214 StructStart
.append(Index
- 1)
1215 StructEnd
.append(Index
)
1217 for Line
in TxtBody
:
1219 for Item
in range(len(StructStart
)):
1220 if Index
== StructStart
[Item
]:
1221 Match
= re
.match("^(/\*\*\s*)", Line
)
1223 StructStartWithComment
.append(StructStart
[Item
])
1225 StructStartWithComment
.append(StructStart
[Item
] + 1)
1227 for Line
in TxtBody
:
1229 for Item
in range(len(StructStart
)):
1230 if Index
>= StructStartWithComment
[Item
] and Index
<= StructEnd
[Item
]:
1231 HeaderFd
.write (Line
)
1232 HeaderFd
.write("#pragma pack()\n\n")
1233 HeaderFd
.write("#endif\n")
1238 def WriteBsfStruct (self
, BsfFd
, Item
):
1239 if Item
['type'] == "None":
1240 Space
= "gPlatformFspPkgTokenSpaceGuid"
1242 Space
= Item
['space']
1243 Line
= " $%s_%s" % (Space
, Item
['cname'])
1244 Match
= re
.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item
['value'])
1246 DefaultValue
= Match
.group(1).strip()
1248 DefaultValue
= Item
['value'].strip()
1249 if 'bitlength' in Item
:
1250 BsfFd
.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['bitlength'], DefaultValue
))
1252 BsfFd
.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line
, ' ' * (64 - len(Line
)), Item
['length'], DefaultValue
))
1254 if Item
['type'] == "Combo":
1255 if not Item
['option'] in self
._BuidinOption
:
1256 OptList
= Item
['option'].split(',')
1257 for Option
in OptList
:
1258 Option
= Option
.strip()
1259 (OpVal
, OpStr
) = Option
.split(':')
1260 TmpList
.append((OpVal
, OpStr
))
1263 def WriteBsfOption (self
, BsfFd
, Item
):
1264 PcdName
= Item
['space'] + '_' + Item
['cname']
1266 if Item
['type'] == "Combo":
1267 if Item
['option'] in self
._BuidinOption
:
1268 Options
= self
._BuidinOption
[Item
['option']]
1271 BsfFd
.write(' %s $%s, "%s", &%s,\n' % (Item
['type'], PcdName
, Item
['name'], Options
))
1273 elif Item
['type'].startswith("EditNum"):
1274 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'])
1276 BsfFd
.write(' EditNum $%s, "%s", %s,\n' % (PcdName
, Item
['name'], Match
.group(1)))
1278 elif Item
['type'].startswith("EditText"):
1279 BsfFd
.write(' %s $%s, "%s",\n' % (Item
['type'], PcdName
, Item
['name']))
1281 elif Item
['type'] == "Table":
1282 Columns
= Item
['option'].split(',')
1283 if len(Columns
) != 0:
1284 BsfFd
.write(' %s $%s "%s",' % (Item
['type'], PcdName
, Item
['name']))
1286 Fmt
= Col
.split(':')
1288 raise Exception("Column format '%s' is invalid !" % Fmt
)
1290 Dtype
= int(Fmt
[1].strip())
1292 raise Exception("Column size '%s' is invalid !" % Fmt
[1])
1293 BsfFd
.write('\n Column "%s", %d bytes, %s' % (Fmt
[0].strip(), Dtype
, Fmt
[2].strip()))
1298 HelpLines
= Item
['help'].split('\\n\\r')
1300 for HelpLine
in HelpLines
:
1303 BsfFd
.write(' Help "%s"\n' % (HelpLine
))
1305 BsfFd
.write(' "%s"\n' % (HelpLine
))
1307 BsfFd
.write(' "Valid range: %s ~ %s"\n' % (Match
.group(2), Match
.group(3)))
1309 def GenerateBsfFile (self
, BsfFile
):
1312 self
.Error
= "BSF output file '%s' is invalid" % BsfFile
1317 BsfFd
= open(BsfFile
, "w")
1318 BsfFd
.write("%s\n" % (__copyright_bsf__
% date
.today().year
))
1319 BsfFd
.write("%s\n" % self
._GlobalDataDef
)
1320 BsfFd
.write("StructDef\n")
1322 for Item
in self
._CfgItemList
:
1323 if Item
['find'] != '':
1324 BsfFd
.write('\n Find "%s"\n' % Item
['find'])
1325 NextOffset
= Item
['offset'] + Item
['length']
1326 if Item
['name'] != '':
1327 if NextOffset
!= Item
['offset']:
1328 BsfFd
.write(" Skip %d bytes\n" % (Item
['offset'] - NextOffset
))
1329 if len(Item
['subreg']) > 0:
1330 NextOffset
= Item
['offset']
1331 BitsOffset
= NextOffset
* 8
1332 for SubItem
in Item
['subreg']:
1333 BitsOffset
+= SubItem
['bitlength']
1334 if SubItem
['name'] == '':
1335 if 'bitlength' in SubItem
:
1336 BsfFd
.write(" Skip %d bits\n" % (SubItem
['bitlength']))
1338 BsfFd
.write(" Skip %d bytes\n" % (SubItem
['length']))
1340 Options
= self
.WriteBsfStruct(BsfFd
, SubItem
)
1341 if len(Options
) > 0:
1342 OptionDict
[SubItem
['space']+'_'+SubItem
['cname']] = Options
1344 NextBitsOffset
= (Item
['offset'] + Item
['length']) * 8
1345 if NextBitsOffset
> BitsOffset
:
1346 BitsGap
= NextBitsOffset
- BitsOffset
1347 BitsRemain
= BitsGap
% 8
1349 BsfFd
.write(" Skip %d bits\n" % BitsRemain
)
1350 BitsGap
-= BitsRemain
1351 BytesRemain
= BitsGap
/ 8
1353 BsfFd
.write(" Skip %d bytes\n" % BytesRemain
)
1354 NextOffset
= Item
['offset'] + Item
['length']
1356 NextOffset
= Item
['offset'] + Item
['length']
1357 Options
= self
.WriteBsfStruct(BsfFd
, Item
)
1358 if len(Options
) > 0:
1359 OptionDict
[Item
['space']+'_'+Item
['cname']] = Options
1360 BsfFd
.write("\nEndStruct\n\n")
1362 BsfFd
.write("%s" % self
._BuidinOptionTxt
)
1364 for Each
in OptionDict
:
1365 BsfFd
.write("List &%s\n" % Each
)
1366 for Item
in OptionDict
[Each
]:
1367 BsfFd
.write(' Selection %s , "%s"\n' % (Item
[0], Item
[1]))
1368 BsfFd
.write("EndList\n\n")
1370 BsfFd
.write("BeginInfoBlock\n")
1371 BsfFd
.write(' PPVer "%s"\n' % (self
._CfgBlkDict
['ver']))
1372 BsfFd
.write(' Description "%s"\n' % (self
._CfgBlkDict
['name']))
1373 BsfFd
.write("EndInfoBlock\n\n")
1375 for Each
in self
._CfgPageDict
:
1376 BsfFd
.write('Page "%s"\n' % self
._CfgPageDict
[Each
])
1378 for Item
in self
._CfgItemList
:
1379 if Item
['name'] != '':
1380 if Item
['page'] != Each
:
1382 if len(Item
['subreg']) > 0:
1383 for SubItem
in Item
['subreg']:
1384 if SubItem
['name'] != '':
1385 BsfItems
.append(SubItem
)
1387 BsfItems
.append(Item
)
1389 BsfItems
.sort(key
=lambda x
: x
['order'])
1391 for Item
in BsfItems
:
1392 self
.WriteBsfOption (BsfFd
, Item
)
1393 BsfFd
.write("EndPage\n\n")
1400 print "GenCfgOpt Version 0.52"
1402 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
1403 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
1404 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1408 # Parse the options and args
1410 GenCfgOpt
= CGenCfgOpt()
1411 argc
= len(sys
.argv
)
1416 DscFile
= sys
.argv
[2]
1417 if not os
.path
.exists(DscFile
):
1418 print "ERROR: Cannot open DSC file '%s' !" % DscFile
1423 if sys
.argv
[4][0] == '-':
1426 OutFile
= sys
.argv
[4]
1428 GenCfgOpt
.ParseBuildMode(sys
.argv
[3])
1429 if GenCfgOpt
.ParseMacros(sys
.argv
[Start
:]) != 0:
1430 print "ERROR: Macro parsing failed !"
1434 if not os
.path
.exists(FvDir
):
1437 if GenCfgOpt
.ParseDscFile(DscFile
, FvDir
) != 0:
1438 print "ERROR: %s !" % GenCfgOpt
.Error
1441 if GenCfgOpt
.UpdateSubRegionDefaultValue() != 0:
1442 print "ERROR: %s !" % GenCfgOpt
.Error
1445 if sys
.argv
[1] == "UPDTXT":
1446 Ret
= GenCfgOpt
.CreateSplitUpdTxt(OutFile
)
1448 # No change is detected
1450 print "INFO: %s !" % (GenCfgOpt
.Error
)
1452 print "ERROR: %s !" % (GenCfgOpt
.Error
)
1454 elif sys
.argv
[1] == "HEADER":
1455 if GenCfgOpt
.CreateHeaderFile(OutFile
) != 0:
1456 print "ERROR: %s !" % GenCfgOpt
.Error
1458 elif sys
.argv
[1] == "GENBSF":
1459 if GenCfgOpt
.GenerateBsfFile(OutFile
) != 0:
1460 print "ERROR: %s !" % GenCfgOpt
.Error
1466 print "ERROR: Unknown command '%s' !" % sys
.argv
[1]
1473 if __name__
== '__main__':