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 14import os 15import re 16import sys 17import struct 18from 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 60Copyright (c) %4d, Intel Corporation. All rights reserved.<BR> 61 62Redistribution and use in source and binary forms, with or without modification, 63are 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 91def 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 133class 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 330class CGenCfgOpt: 331 def __init__(self): 332 self.Debug = False 333 self.Error = '' 334 335 self._GlobalDataDef = """ 336GlobalDataDef 337 SKUID = 0, "DEFAULT" 338EndGlobalData 339 340""" 341 self._BuidinOptionTxt = """ 342List &EN_DIS 343 Selection 0x1 , "Enabled" 344 Selection 0x0 , "Disabled" 345EndList 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 1215def 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 1222def 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 1303if __name__ == '__main__': 1304 sys.exit(Main()) 1305