]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFspPkg/Tools/GenCfgOpt.py
Add Dual-FSP support (MemoryInitUpd/SiliconInitUpd)
[mirror_edk2.git] / IntelFspPkg / Tools / GenCfgOpt.py
1 ## @ GenCfgOpt.py
2 #
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.
8 #
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.
11 #
12 ##
13
14 import os
15 import re
16 import sys
17 import struct
18 from datetime import date
19
20 # Generated file copyright header
21
22 __copyright_txt__ = """## @file
23 #
24 # THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.
25 #
26 # This file lists all VPD informations for a platform collected by build.exe.
27 #
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
33 #
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.
36 #
37 """
38
39 __copyright_bsf__ = """/** @file
40
41 Boot Setting File for Platform Configuration.
42
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
48
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.
51
52 This file is automatically generated. Please do NOT modify !!!
53
54 **/
55
56 """
57
58 __copyright_h__ = """/** @file
59
60 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
61
62 Redistribution and use in source and binary forms, with or without modification,
63 are permitted provided that the following conditions are met:
64
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.
73
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.
85
86 This file is automatically generated. Please do NOT modify !!!
87
88 **/
89 """
90
91 def UpdateMemSiUpdInitOffsetValue (DscFile):
92 DscFd = open(DscFile, "r")
93 DscLines = DscFd.readlines()
94 DscFd.close()
95
96 DscContent = []
97 MemUpdInitOffset = 0
98 SiUpdInitOffset = 0
99 MemUpdInitOffsetValue = 0
100 SiUpdInitOffsetValue = 0
101
102 while len(DscLines):
103 DscLine = DscLines.pop(0)
104 DscContent.append(DscLine)
105 DscLine = DscLine.strip()
106 Match = re.match("^([_a-zA-Z0-9]+).(MemoryInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
107 if Match:
108 MemUpdInitOffsetValue = int(Match.group(5), 0)
109 Match = re.match("^\s*([_a-zA-Z0-9]+).(SiliconInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
110 if Match:
111 SiUpdInitOffsetValue = int(Match.group(5), 0)
112 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*(0x244450554D454D24)",DscLine)
113 if Match:
114 MemUpdInitOffset = int(Match.group(3), 0)
115 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*(0x244450555F495324)",DscLine)
116 if Match:
117 SiUpdInitOffset = int(Match.group(3), 0)
118
119 if MemUpdInitOffsetValue != MemUpdInitOffset or SiUpdInitOffsetValue != SiUpdInitOffset:
120 MemUpdInitOffsetStr = "0x%08X" % MemUpdInitOffset
121 SiUpdInitOffsetStr = "0x%08X" % SiUpdInitOffset
122 DscFd = open(DscFile,"w")
123 for DscLine in DscContent:
124 Match = re.match("^\s*([_a-zA-Z0-9]+).(MemoryInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
125 if Match:
126 DscLine = re.sub(r'(?:[^\s]+\s*$)', MemUpdInitOffsetStr + '\n', DscLine)
127 Match = re.match("^\s*([_a-zA-Z0-9]+).(SiliconInitUpdOffset)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
128 if Match:
129 DscLine = re.sub(r'(?:[^\s]+\s*$)', SiUpdInitOffsetStr + '\n', line)
130 DscFd.writelines(DscLine)
131 DscFd.close()
132
133 class CLogicalExpression:
134 def __init__(self):
135 self.index = 0
136 self.string = ''
137
138 def errExit(self, err = ''):
139 print "ERROR: Express parsing for:"
140 print " %s" % self.string
141 print " %s^" % (' ' * self.index)
142 if err:
143 print "INFO : %s" % err
144 raise SystemExit
145
146 def getNonNumber (self, n1, n2):
147 if not n1.isdigit():
148 return n1
149 if not n2.isdigit():
150 return n2
151 return None
152
153 def getCurr(self, lens = 1):
154 try:
155 if lens == -1:
156 return self.string[self.index :]
157 else:
158 if self.index + lens > len(self.string):
159 lens = len(self.string) - self.index
160 return self.string[self.index : self.index + lens]
161 except Exception:
162 return ''
163
164 def isLast(self):
165 return self.index == len(self.string)
166
167 def moveNext(self, len = 1):
168 self.index += len
169
170 def skipSpace(self):
171 while not self.isLast():
172 if self.getCurr() in ' \t':
173 self.moveNext()
174 else:
175 return
176
177 def normNumber (self, val):
178 return True if val else False
179
180 def getNumber(self, var):
181 var = var.strip()
182 if re.match('^0x[a-fA-F0-9]+$', var):
183 value = int(var, 16)
184 elif re.match('^[+-]?\d+$', var):
185 value = int(var, 10)
186 else:
187 value = None
188 return value
189
190 def parseValue(self):
191 self.skipSpace()
192 var = ''
193 while not self.isLast():
194 char = self.getCurr()
195 if re.match('^[\w.]', char):
196 var += char
197 self.moveNext()
198 else:
199 break
200 val = self.getNumber(var)
201 if val is None:
202 value = var
203 else:
204 value = "%d" % val
205 return value
206
207 def parseSingleOp(self):
208 self.skipSpace()
209 if re.match('^NOT\W', self.getCurr(-1)):
210 self.moveNext(3)
211 op = self.parseBrace()
212 val = self.getNumber (op)
213 if val is None:
214 self.errExit ("'%s' is not a number" % op)
215 return "%d" % (not self.normNumber(int(op)))
216 else:
217 return self.parseValue()
218
219 def parseBrace(self):
220 self.skipSpace()
221 char = self.getCurr()
222 if char == '(':
223 self.moveNext()
224 value = self.parseExpr()
225 self.skipSpace()
226 if self.getCurr() != ')':
227 self.errExit ("Expecting closing brace or operator")
228 self.moveNext()
229 return value
230 else:
231 value = self.parseSingleOp()
232 return value
233
234 def parseCompare(self):
235 value = self.parseBrace()
236 while True:
237 self.skipSpace()
238 char = self.getCurr()
239 if char in ['<', '>']:
240 self.moveNext()
241 next = self.getCurr()
242 if next == '=':
243 op = char + next
244 self.moveNext()
245 else:
246 op = char
247 result = self.parseBrace()
248 test = self.getNonNumber(result, value)
249 if test is None:
250 value = "%d" % self.normNumber(eval (value + op + result))
251 else:
252 self.errExit ("'%s' is not a valid number for comparision" % test)
253 elif char in ['=', '!']:
254 op = self.getCurr(2)
255 if op in ['==', '!=']:
256 self.moveNext(2)
257 result = self.parseBrace()
258 test = self.getNonNumber(result, value)
259 if test is None:
260 value = "%d" % self.normNumber((eval (value + op + result)))
261 else:
262 value = "%d" % self.normNumber(eval ("'" + value + "'" + op + "'" + result + "'"))
263 else:
264 break
265 else:
266 break
267 return value
268
269 def parseAnd(self):
270 value = self.parseCompare()
271 while True:
272 self.skipSpace()
273 if re.match('^AND\W', self.getCurr(-1)):
274 self.moveNext(3)
275 result = self.parseCompare()
276 test = self.getNonNumber(result, value)
277 if test is None:
278 value = "%d" % self.normNumber(int(value) & int(result))
279 else:
280 self.errExit ("'%s' is not a valid op number for AND" % test)
281 else:
282 break
283 return value
284
285 def parseOrXor(self):
286 value = self.parseAnd()
287 op = None
288 while True:
289 self.skipSpace()
290 op = None
291 if re.match('^XOR\W', self.getCurr(-1)):
292 self.moveNext(3)
293 op = '^'
294 elif re.match('^OR\W', self.getCurr(-1)):
295 self.moveNext(2)
296 op = '|'
297 else:
298 break
299 if op:
300 result = self.parseAnd()
301 test = self.getNonNumber(result, value)
302 if test is None:
303 value = "%d" % self.normNumber(eval (value + op + result))
304 else:
305 self.errExit ("'%s' is not a valid op number for XOR/OR" % test)
306 return value
307
308 def parseExpr(self):
309 return self.parseOrXor()
310
311 def getResult(self):
312 value = self.parseExpr()
313 self.skipSpace()
314 if not self.isLast():
315 self.errExit ("Unexpected character found '%s'" % self.getCurr())
316 test = self.getNumber(value)
317 if test is None:
318 self.errExit ("Result '%s' is not a number" % value)
319 return int(value)
320
321 def evaluateExpress (self, Expr):
322 self.index = 0
323 self.string = Expr
324 if self.getResult():
325 Result = True
326 else:
327 Result = False
328 return Result
329
330 class CGenCfgOpt:
331 def __init__(self):
332 self.Debug = False
333 self.Error = ''
334
335 self._GlobalDataDef = """
336 GlobalDataDef
337 SKUID = 0, "DEFAULT"
338 EndGlobalData
339
340 """
341 self._BuidinOptionTxt = """
342 List &EN_DIS
343 Selection 0x1 , "Enabled"
344 Selection 0x0 , "Disabled"
345 EndList
346
347 """
348
349 self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
350 self._HdrKeyList = ['HEADER','STRUCT', 'EMBED']
351 self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}
352
353 self._MacroDict = {}
354 self._CfgBlkDict = {}
355 self._CfgPageDict = {}
356 self._CfgItemList = []
357 self._DscFile = ''
358 self._FvDir = ''
359 self._MapVer = 0
360
361 def ParseMacros (self, MacroDefStr):
362 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
363 self._MacroDict = {}
364 IsExpression = False
365 for Macro in MacroDefStr:
366 if Macro.startswith('-D'):
367 IsExpression = True
368 if len(Macro) > 2:
369 Macro = Macro[2:]
370 else :
371 continue
372 if IsExpression:
373 IsExpression = False
374 Match = re.match("(\w+)=(.+)", Macro)
375 if Match:
376 self._MacroDict[Match.group(1)] = Match.group(2)
377 else:
378 Match = re.match("(\w+)", Macro)
379 if Match:
380 self._MacroDict[Match.group(1)] = ''
381 if len(self._MacroDict) == 0:
382 Error = 1
383 else:
384 Error = 0
385 if self.Debug:
386 print "INFO : Macro dictionary:"
387 for Each in self._MacroDict:
388 print " $(%s) = [ %s ]" % (Each , self._MacroDict[Each])
389 return Error
390
391 def EvaulateIfdef (self, Macro):
392 Result = Macro in self._MacroDict
393 if self.Debug:
394 print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result)
395 return Result
396
397 def ExpandMacros (self, Input):
398 Line = Input
399 Match = re.findall("\$\(\w+\)", Input)
400 if Match:
401 for Each in Match:
402 Variable = Each[2:-1]
403 if Variable in self._MacroDict:
404 Line = Line.replace(Each, self._MacroDict[Variable])
405 else:
406 if self.Debug:
407 print "WARN : %s is not defined" % Each
408 Line = Line.replace(Each, Each[2:-1])
409 return Line
410
411 def EvaluateExpress (self, Expr):
412 ExpExpr = self.ExpandMacros(Expr)
413 LogExpr = CLogicalExpression()
414 Result = LogExpr.evaluateExpress (ExpExpr)
415 if self.Debug:
416 print "INFO : Eval Express [%s] : %s" % (Expr, Result)
417 return Result
418
419 def FormatListValue(self, ConfigDict):
420 Struct = ConfigDict['struct']
421 if Struct not in ['UINT8','UINT16','UINT32','UINT64']:
422 return
423
424 dataarray = []
425 binlist = ConfigDict['value'][1:-1].split(',')
426 for each in binlist:
427 each = each.strip()
428 if each.startswith('0x'):
429 value = int(each, 16)
430 else:
431 value = int(each)
432 dataarray.append(value)
433
434 unit = int(Struct[4:]) / 8
435 if int(ConfigDict['length']) != unit * len(dataarray):
436 raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname'])
437
438 bytearray = []
439 for each in dataarray:
440 value = each
441 for loop in xrange(unit):
442 bytearray.append("0x%02X" % (value & 0xFF))
443 value = value >> 8
444 newvalue = '{' + ','.join(bytearray) + '}'
445 ConfigDict['value'] = newvalue
446 return ""
447
448 def ParseDscFile (self, DscFile, FvDir):
449 self._CfgItemList = []
450 self._CfgPageDict = {}
451 self._CfgBlkDict = {}
452 self._DscFile = DscFile
453 self._FvDir = FvDir
454
455 IsDefSect = False
456 IsUpdSect = False
457 IsVpdSect = False
458 Found = False
459
460 IfStack = []
461 ElifStack = []
462 Error = 0
463 ConfigDict = {}
464
465 DscFd = open(DscFile, "r")
466 DscLines = DscFd.readlines()
467 DscFd.close()
468
469 while len(DscLines):
470 DscLine = DscLines.pop(0).strip()
471 Handle = False
472 Match = re.match("^\[(.+)\]", DscLine)
473 if Match is not None:
474 if Match.group(1).lower() == "Defines".lower():
475 IsDefSect = True
476 IsVpdSect = False
477 IsUpdSect = False
478 elif Match.group(1).lower() == "PcdsDynamicVpd".lower():
479 ConfigDict = {}
480 ConfigDict['header'] = 'ON'
481 ConfigDict['region'] = 'VPD'
482 ConfigDict['order'] = -1
483 ConfigDict['page'] = ''
484 ConfigDict['name'] = ''
485 ConfigDict['find'] = ''
486 ConfigDict['struct'] = ''
487 ConfigDict['embed'] = ''
488 ConfigDict['subreg'] = []
489 IsDefSect = False
490 IsVpdSect = True
491 IsUpdSect = False
492 elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
493 ConfigDict = {}
494 ConfigDict['header'] = 'ON'
495 ConfigDict['region'] = 'UPD'
496 ConfigDict['order'] = -1
497 ConfigDict['page'] = ''
498 ConfigDict['name'] = ''
499 ConfigDict['find'] = ''
500 ConfigDict['struct'] = ''
501 ConfigDict['embed'] = ''
502 ConfigDict['subreg'] = []
503 IsDefSect = False
504 IsUpdSect = True
505 IsVpdSect = False
506 Found = True
507 else:
508 IsDefSect = False
509 IsUpdSect = False
510 IsVpdSect = False
511 else:
512 if IsDefSect or IsUpdSect or IsVpdSect:
513 if re.match("^!else($|\s+#.+)", DscLine):
514 if IfStack:
515 IfStack[-1] = not IfStack[-1]
516 else:
517 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)
518 raise SystemExit
519 elif re.match("^!endif($|\s+#.+)", DscLine):
520 if IfStack:
521 IfStack.pop()
522 Level = ElifStack.pop()
523 if Level > 0:
524 del IfStack[-Level:]
525 else:
526 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)
527 raise SystemExit
528 else:
529 Result = False
530 Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)
531 if Match:
532 Result = self.EvaulateIfdef (Match.group(2))
533 if Match.group(1) == 'ifndef':
534 Result = not Result
535 IfStack.append(Result)
536 ElifStack.append(0)
537 else:
538 Match = re.match("!(if|elseif)\s+(.+)", DscLine)
539 if Match:
540 Result = self.EvaluateExpress(Match.group(2))
541 if Match.group(1) == "if":
542 ElifStack.append(0)
543 IfStack.append(Result)
544 else: #elseif
545 if IfStack:
546 IfStack[-1] = not IfStack[-1]
547 IfStack.append(Result)
548 ElifStack[-1] = ElifStack[-1] + 1
549 else:
550 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)
551 raise SystemExit
552 else:
553 if IfStack:
554 Handle = reduce(lambda x,y: x and y, IfStack)
555 else:
556 Handle = True
557 if Handle:
558 Match = re.match("!include\s+(.+)", DscLine)
559 if Match:
560 IncludeFilePath = Match.group(1)
561 IncludeFilePath = self.ExpandMacros(IncludeFilePath)
562 try:
563 IncludeDsc = open(IncludeFilePath, "r")
564 except:
565 print("ERROR: Cannot open file '%s'" % IncludeFilePath)
566 raise SystemExit
567 NewDscLines = IncludeDsc.readlines()
568 IncludeDsc.close()
569 DscLines = NewDscLines + DscLines
570 else:
571 if DscLine.startswith('!'):
572 print("ERROR: Unrecoginized directive for line '%s'" % DscLine)
573 raise SystemExit
574 if not Handle:
575 continue
576
577 if IsDefSect:
578 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
579 Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine)
580 if Match:
581 self._MacroDict[Match.group(1)] = Match.group(2)
582 if self.Debug:
583 print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))
584 else:
585 Match = re.match("^\s*#\s+!(BSF|HDR)\s+(.+)", DscLine)
586 if Match:
587 Remaining = Match.group(2)
588 if Match.group(1) == 'BSF':
589 Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)
590 if Match:
591 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
592 PageList = Match.group(1).split(',')
593 for Page in PageList:
594 Page = Page.strip()
595 Match = re.match("(\w+):\"(.+)\"", Page)
596 self._CfgPageDict[Match.group(1)] = Match.group(2)
597
598 Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)
599 if Match:
600 self._CfgBlkDict['name'] = Match.group(1)
601 self._CfgBlkDict['ver'] = Match.group(2)
602
603 for Key in self._BsfKeyList:
604 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
605 if Match:
606 if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'):
607 ConfigDict[Key.lower()] += Match.group(1)[1:]
608 else:
609 ConfigDict[Key.lower()] = Match.group(1)
610 else:
611 for Key in self._HdrKeyList:
612 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
613 if Match:
614 ConfigDict[Key.lower()] = Match.group(1)
615
616 # Check VPD/UPD
617 if IsUpdSect:
618 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)
619 else:
620 Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine)
621 if Match:
622 ConfigDict['space'] = Match.group(1)
623 ConfigDict['cname'] = Match.group(2)
624 ConfigDict['offset'] = int (Match.group(3), 16)
625 if ConfigDict['order'] == -1:
626 ConfigDict['order'] = ConfigDict['offset'] << 8
627 else:
628 (Major, Minor) = ConfigDict['order'].split('.')
629 ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16)
630 if IsUpdSect:
631 Value = Match.group(5).strip()
632 if Match.group(4).startswith("0x"):
633 Length = int (Match.group(4), 16)
634 else :
635 Length = int (Match.group(4))
636 else:
637 Value = Match.group(4)
638 if Value is None:
639 Value = ''
640 Value = Value.strip()
641 if '|' in Value:
642 Match = re.match("^.+\s*\|\s*(.+)", Value)
643 if Match:
644 Value = Match.group(1)
645 Length = -1
646
647 ConfigDict['length'] = Length
648 Match = re.match("\$\((\w+)\)", Value)
649 if Match:
650 if Match.group(1) in self._MacroDict:
651 Value = self._MacroDict[Match.group(1)]
652
653 ConfigDict['value'] = Value
654 if (len(Value) > 0) and (Value[0] == '{'):
655 Value = self.FormatListValue(ConfigDict)
656
657 if ConfigDict['name'] == '':
658 # Clear BSF specific items
659 ConfigDict['bsfname'] = ''
660 ConfigDict['help'] = ''
661 ConfigDict['type'] = ''
662 ConfigDict['option'] = ''
663
664 self._CfgItemList.append(ConfigDict.copy())
665 ConfigDict['name'] = ''
666 ConfigDict['find'] = ''
667 ConfigDict['struct'] = ''
668 ConfigDict['embed'] = ''
669 ConfigDict['order'] = -1
670 ConfigDict['subreg'] = []
671 else:
672 # It could be a virtual item as below
673 # !BSF FIELD:{1:SerialDebugPortAddress0}
674 Match = re.match("^\s*#\s+!BSF\s+FIELD:{(.+):(\d+)}", DscLine)
675 if Match:
676 SubCfgDict = ConfigDict
677 SubCfgDict['cname'] = Match.group(1)
678 SubCfgDict['length'] = int (Match.group(2))
679 if SubCfgDict['length'] > 0:
680 LastItem = self._CfgItemList[-1]
681 if len(LastItem['subreg']) == 0:
682 SubOffset = 0
683 else:
684 SubOffset += LastItem['subreg'][-1]['length']
685 SubCfgDict['offset'] = SubOffset
686 LastItem['subreg'].append (SubCfgDict.copy())
687 ConfigDict['name'] = ''
688 return Error
689
690 def UpdateSubRegionDefaultValue (self):
691 Error = 0
692 for Item in self._CfgItemList:
693 if len(Item['subreg']) == 0:
694 continue
695 bytearray = []
696 if Item['value'][0] == '{':
697 binlist = Item['value'][1:-1].split(',')
698 for each in binlist:
699 each = each.strip()
700 if each.startswith('0x'):
701 value = int(each, 16)
702 else:
703 value = int(each)
704 bytearray.append(value)
705 else:
706 if Item['value'].startswith('0x'):
707 value = int(Item['value'], 16)
708 else:
709 value = int(Item['value'])
710 idx = 0;
711 while idx < Item['length']:
712 bytearray.append(value & 0xFF)
713 value = value >> 8
714 idx = idx + 1
715 for SubItem in Item['subreg']:
716 if SubItem['length'] in (1,2,4,8):
717 valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]]
718 valuelist.reverse()
719 valuestr = "".join('%02X' % b for b in valuelist)
720 SubItem['value'] = '0x%s' % valuestr
721 else:
722 valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']])
723 SubItem['value'] = '{%s}' % valuestr
724 return Error
725
726 def UpdateVpdSizeField (self):
727 FvDir = self._FvDir;
728
729 if 'VPD_TOOL_GUID' not in self._MacroDict:
730 self.Error = "VPD_TOOL_GUID definition is missing in DSC file"
731 return 1
732
733 VpdMapFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + '.map')
734 if not os.path.exists(VpdMapFile):
735 self.Error = "VPD MAP file '%s' does not exist" % VpdMapFile
736 return 2
737
738 MapFd = open(VpdMapFile, "r")
739 MapLines = MapFd.readlines()
740 MapFd.close()
741
742 VpdDict = {}
743 PcdDict = {}
744 for MapLine in MapLines:
745 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | DEFAULT | 0x0000 | 8 | 0x534450565F425346
746 #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | 0x0000 | 8 | 0x534450565F425346
747 #gPlatformFspPkgTokenSpaceGuid.PcdTest | 0x0008 | 5 | {0x01,0x02,0x03,0x04,0x05}
748 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)
749 if Match:
750 Space = Match.group(1)
751 Name = Match.group(2)
752 if (self._MapVer == 0) and (Match.group(3) != None):
753 self._MapVer = 1
754 Offset = int (Match.group(4), 16)
755 if Match.group(5).startswith("0x"):
756 Length = int (Match.group(5), 16)
757 else :
758 Length = int (Match.group(5))
759 PcdDict["len"] = Length
760 PcdDict["value"] = Match.group(6)
761 VpdDict[Space+'.'+Name] = dict(PcdDict)
762
763 for Item in self._CfgItemList:
764 if Item['value'] == '':
765 Item['value'] = VpdDict[Item['space']+'.'+Item['cname']]['value']
766 if Item['length'] == -1:
767 Item['length'] = VpdDict[Item['space']+'.'+Item['cname']]['len']
768 if Item['struct'] != '':
769 Type = Item['struct'].strip()
770 if Type.endswith('*') and (Item['length'] != 4):
771 self.Error = "Struct pointer '%s' has invalid size" % Type
772 return 3
773
774 return 0
775
776 def CreateUpdTxtFile (self, UpdTxtFile):
777 FvDir = self._FvDir
778 if 'UPD_TOOL_GUID' not in self._MacroDict:
779 self.Error = "UPD_TOOL_GUID definition is missing in DSC file"
780 return 1
781
782 if UpdTxtFile == '':
783 UpdTxtFile = os.path.join(FvDir, self._MacroDict['UPD_TOOL_GUID'] + '.txt')
784
785 ReCreate = False
786 if not os.path.exists(UpdTxtFile):
787 ReCreate = True
788 else:
789 DscTime = os.path.getmtime(self._DscFile)
790 TxtTime = os.path.getmtime(UpdTxtFile)
791 if DscTime > TxtTime:
792 ReCreate = True
793
794 if not ReCreate:
795 # DSC has not been modified yet
796 # So don't have to re-generate other files
797 self.Error = 'No DSC file change, skip to create UPD TXT file'
798 return 256
799
800 TxtFd = open(UpdTxtFile, "w")
801 TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year))
802
803 NextOffset = 0
804 SpaceIdx = 0
805 if self._MapVer == 1:
806 Default = 'DEFAULT|'
807 else:
808 Default = ''
809 for Item in self._CfgItemList:
810 if Item['region'] != 'UPD':
811 continue
812 Offset = Item['offset']
813 if NextOffset < Offset:
814 # insert one line
815 TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset, Offset - NextOffset))
816 SpaceIdx = SpaceIdx + 1
817 NextOffset = Offset + Item['length']
818 TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'],Item['length'],Item['value']))
819 TxtFd.close()
820 return 0
821
822 def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help):
823 PosName = 28
824 PosComment = 30
825 NameLine=''
826 HelpLine=''
827
828 IsArray = False
829 if Length in [1,2,4,8]:
830 Type = "UINT%d" % (Length * 8)
831 else:
832 IsArray = True
833 Type = "UINT8"
834
835 if Item and Item['value'].startswith('{'):
836 Type = "UINT8"
837 IsArray = True
838
839 if Struct != '':
840 Type = Struct
841 if Struct in ['UINT8','UINT16','UINT32','UINT64']:
842 IsArray = True
843 Unit = int(Type[4:]) / 8
844 Length = Length / Unit
845 else:
846 IsArray = False
847
848 if IsArray:
849 Name = Name + '[%d]' % Length
850
851 if len(Type) < PosName:
852 Space1 = PosName - len(Type)
853 else:
854 Space1 = 1
855
856 if BsfName != '':
857 NameLine=" %s\n" % BsfName
858
859 if Help != '':
860 HelpLine=" %s\n" % Help
861
862 if Offset is None:
863 OffsetStr = '????'
864 else:
865 OffsetStr = '0x%04X' % Offset
866
867 return "/** Offset %s\n%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, Type, ' ' * Space1, Name,)
868
869 def PostProcessBody (self, TextBody):
870 NewTextBody = []
871 OldTextBody = []
872 IncludeLine = False
873 StructName = ''
874 VariableName = ''
875 for Line in TextBody:
876 Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)
877 if Match:
878 Line = Match.group(4)
879
880 if Match and Match.group(3) == 'START':
881 NewTextBody.append ('typedef struct {\n')
882 StructName = Match.group(1)
883 VariableName = Match.group(2)
884 MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)
885 if MatchOffset:
886 Offset = int(MatchOffset.group(1), 16)
887 else:
888 Offset = None
889 Line
890 IncludeLine = True
891 OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', ''))
892 if IncludeLine:
893 NewTextBody.append (Line)
894 else:
895 OldTextBody.append (Line)
896
897 if Match and Match.group(3) == 'END':
898 if (StructName != Match.group(1)) or (VariableName != Match.group(2)):
899 print "Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1))
900 else:
901 NewTextBody.append ('} %s;\n\n' % StructName)
902 IncludeLine = False
903 NewTextBody.extend(OldTextBody)
904 return NewTextBody
905
906 def CreateHeaderFile (self, InputHeaderFile, IsInternal):
907 FvDir = self._FvDir
908
909 if IsInternal:
910 HeaderFile = os.path.join(FvDir, 'FspUpdVpdInternal.h')
911 else:
912 HeaderFile = os.path.join(FvDir, 'FspUpdVpd.h')
913
914 # Check if header needs to be recreated
915 ReCreate = False
916 if IsInternal:
917 if not os.path.exists(HeaderFile):
918 ReCreate = True
919 else:
920 DscTime = os.path.getmtime(self._DscFile)
921 HeadTime = os.path.getmtime(HeaderFile)
922 if not os.path.exists(InputHeaderFile):
923 InpTime = HeadTime
924 else:
925 InpTime = os.path.getmtime(InputHeaderFile)
926 if DscTime > HeadTime or InpTime > HeadTime:
927 ReCreate = True
928
929 if not ReCreate:
930 self.Error = "No DSC or input header file is changed, skip the header file generating"
931 return 256
932
933 TxtBody = []
934 for Item in self._CfgItemList:
935 if str(Item['cname']) == 'Signature' and Item['length'] == 8:
936 Value = int(Item['value'], 16)
937 Chars = []
938 while Value != 0x0:
939 Chars.append(chr(Value & 0xFF))
940 Value = Value >> 8
941 SignatureStr = ''.join(Chars)
942 if int(Item['offset']) == 0:
943 TxtBody.append("#define FSP_UPD_SIGNATURE %s /* '%s' */\n" % (Item['value'], SignatureStr))
944 elif 'MEM' in SignatureStr:
945 TxtBody.append("#define FSP_MEMORY_INIT_UPD_SIGNATURE %s /* '%s' */\n" % (Item['value'], SignatureStr))
946 else:
947 TxtBody.append("#define FSP_SILICON_INIT_UPD_SIGNATURE %s /* '%s' */\n" % (Item['value'], SignatureStr))
948 TxtBody.append("\n")
949
950 for Region in ['UPD', 'VPD']:
951
952 # Write PcdVpdRegionSign and PcdImageRevision
953 if Region[0] == 'V':
954 if 'VPD_TOOL_GUID' not in self._MacroDict:
955 self.Error = "VPD_TOOL_GUID definition is missing in DSC file"
956 return 1
957
958 BinFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + ".bin")
959 if not os.path.exists(BinFile):
960 self.Error = "VPD binary file '%s' does not exist" % BinFile
961 return 2
962
963 BinFd = open(BinFile, "rb")
964 IdStr = BinFd.read(0x08)
965 ImageId = struct.unpack('<Q', IdStr)
966 ImageRev = struct.unpack('<I', BinFd.read(0x04))
967 BinFd.close()
968
969 TxtBody.append("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (ImageId[0], IdStr))
970 TxtBody.append("#define FSP_IMAGE_REV 0x%08X \n\n" % ImageRev[0])
971
972 TxtBody.append("typedef struct _" + Region[0] + "PD_DATA_REGION {\n")
973 NextOffset = 0
974 SpaceIdx = 0
975 Offset = 0
976
977 LastVisible = True
978 ResvOffset = 0
979 ResvIdx = 0
980 LineBuffer = []
981 for Item in self._CfgItemList:
982 if Item['region'] != Region:
983 continue
984
985 NextVisible = LastVisible
986 if not IsInternal:
987 if LastVisible and (Item['header'] == 'OFF'):
988 NextVisible = False
989 ResvOffset = Item['offset']
990 elif (not LastVisible) and Item['header'] == 'ON':
991 NextVisible = True
992 Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx
993 ResvIdx = ResvIdx + 1
994 TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', ''))
995
996 if Offset < Item["offset"]:
997 if IsInternal or LastVisible:
998 Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx
999 LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', ''))
1000 SpaceIdx = SpaceIdx + 1
1001 Offset = Item["offset"]
1002
1003 if Offset != Item["offset"]:
1004 self.Error = "Unsorted offset 0x%04X\n" % Item["offset"]
1005 return 3
1006
1007 LastVisible = NextVisible
1008
1009 Offset = Offset + Item["length"]
1010 if IsInternal or LastVisible:
1011 for Each in LineBuffer:
1012 TxtBody.append (Each)
1013 LineBuffer = []
1014 Embed = Item["embed"].upper()
1015 if Embed.endswith(':START') or Embed.endswith(':END'):
1016 Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]
1017 else:
1018 if Embed == '':
1019 Marker = '';
1020 else:
1021 self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]
1022 return 4
1023 Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'])
1024 TxtBody.append(Line)
1025
1026 TxtBody.append("} " + Region[0] + "PD_DATA_REGION;\n\n")
1027
1028 # Handle the embedded data structure
1029 TxtBody = self.PostProcessBody (TxtBody)
1030
1031 HeaderFd = open(HeaderFile, "w")
1032 FileBase = os.path.basename(HeaderFile)
1033 FileName = FileBase.replace(".", "_").upper()
1034 HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))
1035 HeaderFd.write("#ifndef __%s__\n" % FileName)
1036 HeaderFd.write("#define __%s__\n\n" % FileName)
1037 HeaderFd.write("#pragma pack(1)\n\n")
1038
1039 if InputHeaderFile != '':
1040 if not os.path.exists(InputHeaderFile):
1041 self.Error = "Input header file '%s' does not exist" % InputHeaderFile
1042 return 6
1043
1044 InFd = open(InputHeaderFile, "r")
1045 IncLines = InFd.readlines()
1046 InFd.close()
1047
1048 Export = False
1049 for Line in IncLines:
1050 Match = re.search ("!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)
1051 if Match:
1052 if Match.group(1) == "BEGIN":
1053 Export = True
1054 continue
1055 else:
1056 Export = False
1057 continue
1058 if Export:
1059 HeaderFd.write(Line)
1060 HeaderFd.write("\n\n")
1061
1062 for Line in TxtBody:
1063 HeaderFd.write (Line)
1064 HeaderFd.write("#pragma pack()\n\n")
1065 HeaderFd.write("#endif\n")
1066 HeaderFd.close()
1067
1068 return 0
1069
1070 def WriteBsfStruct (self, BsfFd, Item):
1071 if Item['type'] == "None":
1072 Space = "gPlatformFspPkgTokenSpaceGuid"
1073 else:
1074 Space = Item['space']
1075 Line = " $%s_%s" % (Space, Item['cname'])
1076 Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])
1077 if Match:
1078 DefaultValue = Match.group(1).strip()
1079 else:
1080 DefaultValue = Item['value'].strip()
1081 BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))
1082 TmpList = []
1083 if Item['type'] == "Combo":
1084 if not Item['option'] in self._BuidinOption:
1085 OptList = Item['option'].split(',')
1086 for Option in OptList:
1087 Option = Option.strip()
1088 (OpVal, OpStr) = Option.split(':')
1089 TmpList.append((OpVal, OpStr))
1090 return TmpList
1091
1092 def WriteBsfOption (self, BsfFd, Item):
1093 PcdName = Item['space'] + '_' + Item['cname']
1094 WriteHelp = 0
1095 if Item['type'] == "Combo":
1096 if Item['option'] in self._BuidinOption:
1097 Options = self._BuidinOption[Item['option']]
1098 else:
1099 Options = PcdName
1100 BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options));
1101 WriteHelp = 1
1102 elif Item['type'].startswith("EditNum"):
1103 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'])
1104 if Match:
1105 BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)));
1106 WriteHelp = 2
1107 elif Item['type'].startswith("EditText"):
1108 BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']));
1109 WriteHelp = 1
1110 elif Item['type'] == "Table":
1111 Columns = Item['option'].split(',')
1112 if len(Columns) != 0:
1113 BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name']));
1114 for Col in Columns:
1115 Fmt = Col.split(':')
1116 if len(Fmt) != 3:
1117 raise Exception("Column format '%s' is invalid !" % Fmt)
1118 try:
1119 Dtype = int(Fmt[1].strip())
1120 except:
1121 raise Exception("Column size '%s' is invalid !" % Fmt[1])
1122 BsfFd.write('\n Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))
1123 BsfFd.write(',\n')
1124 WriteHelp = 1
1125
1126 if WriteHelp > 0:
1127 HelpLines = Item['help'].split('\\n\\r')
1128 FirstLine = True
1129 for HelpLine in HelpLines:
1130 if FirstLine:
1131 FirstLine = False
1132 BsfFd.write(' Help "%s"\n' % (HelpLine));
1133 else:
1134 BsfFd.write(' "%s"\n' % (HelpLine));
1135 if WriteHelp == 2:
1136 BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)));
1137
1138 def GenerateBsfFile (self, BsfFile):
1139
1140 if BsfFile == '':
1141 self.Error = "BSF output file '%s' is invalid" % BsfFile
1142 return 1
1143
1144 Error = 0
1145 OptionDict = {}
1146 BsfFd = open(BsfFile, "w")
1147 BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))
1148 BsfFd.write("%s\n" % self._GlobalDataDef);
1149 BsfFd.write("StructDef\n")
1150 NextOffset = -1
1151 for Item in self._CfgItemList:
1152 if Item['find'] != '':
1153 BsfFd.write('\n Find "%s"\n' % Item['find'])
1154 NextOffset = Item['offset'] + Item['length']
1155 if Item['name'] != '':
1156 if NextOffset != Item['offset']:
1157 BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))
1158 if len(Item['subreg']) > 0:
1159 NextOffset = Item['offset']
1160 for SubItem in Item['subreg']:
1161 NextOffset += SubItem['length']
1162 if SubItem['name'] == '':
1163 BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))
1164 else:
1165 Options = self.WriteBsfStruct(BsfFd, SubItem)
1166 if len(Options) > 0:
1167 OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options
1168 if (Item['offset'] + Item['length']) < NextOffset:
1169 self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname'])
1170 return 2
1171 else:
1172 NextOffset = Item['offset'] + Item['length']
1173 Options = self.WriteBsfStruct(BsfFd, Item)
1174 if len(Options) > 0:
1175 OptionDict[Item['space']+'_'+Item['cname']] = Options
1176 BsfFd.write("\nEndStruct\n\n")
1177
1178 BsfFd.write("%s" % self._BuidinOptionTxt);
1179
1180 for Each in OptionDict:
1181 BsfFd.write("List &%s\n" % Each);
1182 for Item in OptionDict[Each]:
1183 BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]));
1184 BsfFd.write("EndList\n\n");
1185
1186 BsfFd.write("BeginInfoBlock\n");
1187 BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']));
1188 BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']));
1189 BsfFd.write("EndInfoBlock\n\n");
1190
1191 for Each in self._CfgPageDict:
1192 BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]);
1193 BsfItems = []
1194 for Item in self._CfgItemList:
1195 if Item['name'] != '':
1196 if Item['page'] != Each:
1197 continue
1198 if len(Item['subreg']) > 0:
1199 for SubItem in Item['subreg']:
1200 if SubItem['name'] != '':
1201 BsfItems.append(SubItem)
1202 else:
1203 BsfItems.append(Item)
1204
1205 BsfItems.sort(key=lambda x: x['order'])
1206
1207 for Item in BsfItems:
1208 self.WriteBsfOption (BsfFd, Item)
1209 BsfFd.write("EndPage\n\n");
1210
1211 BsfFd.close()
1212 return Error
1213
1214
1215 def Usage():
1216 print "GenCfgOpt Version 0.50"
1217 print "Usage:"
1218 print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]"
1219 print " GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]"
1220 print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
1221
1222 def Main():
1223 #
1224 # Parse the options and args
1225 #
1226 GenCfgOpt = CGenCfgOpt()
1227 argc = len(sys.argv)
1228 if argc < 4:
1229 Usage()
1230 return 1
1231 else:
1232 DscFile = sys.argv[2]
1233 if not os.path.exists(DscFile):
1234 print "ERROR: Cannot open DSC file '%s' !" % DscFile
1235 return 2
1236
1237 UpdateMemSiUpdInitOffsetValue(DscFile)
1238
1239 OutFile = ''
1240 if argc > 4:
1241 if sys.argv[4][0] == '-':
1242 Start = 4
1243 else:
1244 OutFile = sys.argv[4]
1245 Start = 5
1246 if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
1247 print "ERROR: Macro parsing failed !"
1248 return 3
1249
1250 FvDir = sys.argv[3]
1251 if not os.path.isdir(FvDir):
1252 print "ERROR: FV folder '%s' is invalid !" % FvDir
1253 return 4
1254
1255 if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:
1256 print "ERROR: %s !" % GenCfgOpt.Error
1257 return 5
1258
1259 if GenCfgOpt.UpdateVpdSizeField() != 0:
1260 print "ERROR: %s !" % GenCfgOpt.Error
1261 return 6
1262
1263 if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:
1264 print "ERROR: %s !" % GenCfgOpt.Error
1265 return 7
1266
1267 if sys.argv[1] == "UPDTXT":
1268 Ret = GenCfgOpt.CreateUpdTxtFile(OutFile)
1269 if Ret != 0:
1270 # No change is detected
1271 if Ret == 256:
1272 print "INFO: %s !" % (GenCfgOpt.Error)
1273 else :
1274 print "ERROR: %s !" % (GenCfgOpt.Error)
1275 return Ret
1276 elif sys.argv[1] == "HEADER":
1277 Ret = GenCfgOpt.CreateHeaderFile(OutFile, True)
1278 if Ret != 0:
1279 # No change is detected
1280 if Ret == 256:
1281 print "INFO: %s !" % (GenCfgOpt.Error)
1282 else :
1283 print "ERROR: %s !" % (GenCfgOpt.Error)
1284 return Ret
1285 if GenCfgOpt.CreateHeaderFile(OutFile, False) != 0:
1286 print "ERROR: %s !" % GenCfgOpt.Error
1287 return 8
1288 elif sys.argv[1] == "GENBSF":
1289 if GenCfgOpt.GenerateBsfFile(OutFile) != 0:
1290 print "ERROR: %s !" % GenCfgOpt.Error
1291 return 9
1292 else:
1293 if argc < 5:
1294 Usage()
1295 return 1
1296 print "ERROR: Unknown command '%s' !" % sys.argv[1]
1297 Usage()
1298 return 1
1299 return 0
1300 return 0
1301
1302
1303 if __name__ == '__main__':
1304 sys.exit(Main())