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