]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/Tools/GenCfgOpt.py
BaseTools Build_Rule: Add the missing ASM16_FLAGS for ASM16 source file
[mirror_edk2.git] / IntelFsp2Pkg / Tools / GenCfgOpt.py
CommitLineData
cf1d4549
JY
1## @ GenCfgOpt.py\r
2#\r
7a38ad07 3# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>\r
9672cd30 4# SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
5#\r
6##\r
7\r
8import os\r
9import re\r
10import sys\r
11import struct\r
12from datetime import date\r
c3f0829b 13from functools import reduce\r
cf1d4549
JY
14\r
15# Generated file copyright header\r
16\r
17__copyright_txt__ = """## @file\r
18#\r
19# THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.\r
20#\r
21# This file lists all VPD informations for a platform collected by build.exe.\r
22#\r
23# Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
24# This program and the accompanying materials\r
25# are licensed and made available under the terms and conditions of the BSD License\r
26# which accompanies this distribution. The full text of the license may be found at\r
27# http://opensource.org/licenses/bsd-license.php\r
28#\r
29# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
30# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
31#\r
32"""\r
33\r
34__copyright_bsf__ = """/** @file\r
35\r
36 Boot Setting File for Platform Configuration.\r
37\r
38 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
39 This program and the accompanying materials\r
40 are licensed and made available under the terms and conditions of the BSD License\r
41 which accompanies this distribution. The full text of the license may be found at\r
42 http://opensource.org/licenses/bsd-license.php\r
43\r
44 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
45 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
46\r
47 This file is automatically generated. Please do NOT modify !!!\r
48\r
49**/\r
50\r
51"""\r
52\r
53__copyright_h__ = """/** @file\r
54\r
55Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
56\r
57Redistribution and use in source and binary forms, with or without modification,\r
58are permitted provided that the following conditions are met:\r
59\r
60* Redistributions of source code must retain the above copyright notice, this\r
61 list of conditions and the following disclaimer.\r
62* Redistributions in binary form must reproduce the above copyright notice, this\r
63 list of conditions and the following disclaimer in the documentation and/or\r
64 other materials provided with the distribution.\r
65* Neither the name of Intel Corporation nor the names of its contributors may\r
66 be used to endorse or promote products derived from this software without\r
67 specific prior written permission.\r
68\r
69 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
70 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
71 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
72 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
73 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
74 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
75 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
76 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
77 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
78 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
79 THE POSSIBILITY OF SUCH DAMAGE.\r
80\r
81 This file is automatically generated. Please do NOT modify !!!\r
82\r
83**/\r
84"""\r
85\r
b9c055f7
CC
86BuildOptionPcd = []\r
87\r
cf1d4549
JY
88class CLogicalExpression:\r
89 def __init__(self):\r
90 self.index = 0\r
91 self.string = ''\r
92\r
93 def errExit(self, err = ''):\r
c3f0829b
CC
94 print ("ERROR: Express parsing for:")\r
95 print (" %s" % self.string)\r
96 print (" %s^" % (' ' * self.index))\r
cf1d4549 97 if err:\r
c3f0829b 98 print ("INFO : %s" % err)\r
cf1d4549
JY
99 raise SystemExit\r
100\r
101 def getNonNumber (self, n1, n2):\r
102 if not n1.isdigit():\r
103 return n1\r
104 if not n2.isdigit():\r
105 return n2\r
106 return None\r
107\r
108 def getCurr(self, lens = 1):\r
109 try:\r
110 if lens == -1:\r
111 return self.string[self.index :]\r
112 else:\r
113 if self.index + lens > len(self.string):\r
114 lens = len(self.string) - self.index\r
115 return self.string[self.index : self.index + lens]\r
116 except Exception:\r
117 return ''\r
118\r
119 def isLast(self):\r
120 return self.index == len(self.string)\r
121\r
122 def moveNext(self, len = 1):\r
123 self.index += len\r
124\r
125 def skipSpace(self):\r
126 while not self.isLast():\r
127 if self.getCurr() in ' \t':\r
128 self.moveNext()\r
129 else:\r
130 return\r
131\r
132 def normNumber (self, val):\r
133 return True if val else False\r
134\r
135 def getNumber(self, var):\r
136 var = var.strip()\r
137 if re.match('^0x[a-fA-F0-9]+$', var):\r
138 value = int(var, 16)\r
139 elif re.match('^[+-]?\d+$', var):\r
140 value = int(var, 10)\r
141 else:\r
142 value = None\r
143 return value\r
144\r
145 def parseValue(self):\r
146 self.skipSpace()\r
147 var = ''\r
148 while not self.isLast():\r
149 char = self.getCurr()\r
150 if re.match('^[\w.]', char):\r
151 var += char\r
152 self.moveNext()\r
153 else:\r
154 break\r
155 val = self.getNumber(var)\r
156 if val is None:\r
157 value = var\r
158 else:\r
159 value = "%d" % val\r
160 return value\r
161\r
162 def parseSingleOp(self):\r
163 self.skipSpace()\r
164 if re.match('^NOT\W', self.getCurr(-1)):\r
165 self.moveNext(3)\r
166 op = self.parseBrace()\r
167 val = self.getNumber (op)\r
168 if val is None:\r
169 self.errExit ("'%s' is not a number" % op)\r
170 return "%d" % (not self.normNumber(int(op)))\r
171 else:\r
172 return self.parseValue()\r
173\r
174 def parseBrace(self):\r
175 self.skipSpace()\r
176 char = self.getCurr()\r
177 if char == '(':\r
178 self.moveNext()\r
179 value = self.parseExpr()\r
180 self.skipSpace()\r
181 if self.getCurr() != ')':\r
182 self.errExit ("Expecting closing brace or operator")\r
183 self.moveNext()\r
184 return value\r
185 else:\r
186 value = self.parseSingleOp()\r
187 return value\r
188\r
189 def parseCompare(self):\r
190 value = self.parseBrace()\r
191 while True:\r
192 self.skipSpace()\r
193 char = self.getCurr()\r
194 if char in ['<', '>']:\r
195 self.moveNext()\r
196 next = self.getCurr()\r
197 if next == '=':\r
198 op = char + next\r
199 self.moveNext()\r
200 else:\r
201 op = char\r
202 result = self.parseBrace()\r
203 test = self.getNonNumber(result, value)\r
204 if test is None:\r
205 value = "%d" % self.normNumber(eval (value + op + result))\r
206 else:\r
207 self.errExit ("'%s' is not a valid number for comparision" % test)\r
208 elif char in ['=', '!']:\r
209 op = self.getCurr(2)\r
210 if op in ['==', '!=']:\r
211 self.moveNext(2)\r
212 result = self.parseBrace()\r
213 test = self.getNonNumber(result, value)\r
214 if test is None:\r
215 value = "%d" % self.normNumber((eval (value + op + result)))\r
216 else:\r
217 value = "%d" % self.normNumber(eval ("'" + value + "'" + op + "'" + result + "'"))\r
218 else:\r
219 break\r
220 else:\r
221 break\r
222 return value\r
223\r
224 def parseAnd(self):\r
225 value = self.parseCompare()\r
226 while True:\r
227 self.skipSpace()\r
228 if re.match('^AND\W', self.getCurr(-1)):\r
229 self.moveNext(3)\r
230 result = self.parseCompare()\r
231 test = self.getNonNumber(result, value)\r
232 if test is None:\r
233 value = "%d" % self.normNumber(int(value) & int(result))\r
234 else:\r
235 self.errExit ("'%s' is not a valid op number for AND" % test)\r
236 else:\r
237 break\r
238 return value\r
239\r
240 def parseOrXor(self):\r
241 value = self.parseAnd()\r
242 op = None\r
243 while True:\r
244 self.skipSpace()\r
245 op = None\r
246 if re.match('^XOR\W', self.getCurr(-1)):\r
247 self.moveNext(3)\r
248 op = '^'\r
249 elif re.match('^OR\W', self.getCurr(-1)):\r
250 self.moveNext(2)\r
251 op = '|'\r
252 else:\r
253 break\r
254 if op:\r
255 result = self.parseAnd()\r
256 test = self.getNonNumber(result, value)\r
257 if test is None:\r
258 value = "%d" % self.normNumber(eval (value + op + result))\r
259 else:\r
260 self.errExit ("'%s' is not a valid op number for XOR/OR" % test)\r
261 return value\r
262\r
263 def parseExpr(self):\r
264 return self.parseOrXor()\r
265\r
266 def getResult(self):\r
267 value = self.parseExpr()\r
268 self.skipSpace()\r
269 if not self.isLast():\r
270 self.errExit ("Unexpected character found '%s'" % self.getCurr())\r
271 test = self.getNumber(value)\r
272 if test is None:\r
273 self.errExit ("Result '%s' is not a number" % value)\r
274 return int(value)\r
275\r
276 def evaluateExpress (self, Expr):\r
277 self.index = 0\r
278 self.string = Expr\r
279 if self.getResult():\r
280 Result = True\r
281 else:\r
282 Result = False\r
283 return Result\r
284\r
285class CGenCfgOpt:\r
286 def __init__(self):\r
287 self.Debug = False\r
288 self.Error = ''\r
cf1d4549
JY
289\r
290 self._GlobalDataDef = """\r
291GlobalDataDef\r
292 SKUID = 0, "DEFAULT"\r
293EndGlobalData\r
294\r
295"""\r
296 self._BuidinOptionTxt = """\r
297List &EN_DIS\r
298 Selection 0x1 , "Enabled"\r
299 Selection 0x0 , "Disabled"\r
300EndList\r
301\r
302"""\r
303\r
304 self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']\r
305 self._HdrKeyList = ['HEADER','STRUCT', 'EMBED', 'COMMENT']\r
306 self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}\r
307\r
308 self._MacroDict = {}\r
62997d5e 309 self._PcdsDict = {}\r
cf1d4549
JY
310 self._CfgBlkDict = {}\r
311 self._CfgPageDict = {}\r
312 self._CfgItemList = []\r
313 self._DscFile = ''\r
314 self._FvDir = ''\r
315 self._MapVer = 0\r
316\r
cf1d4549
JY
317 def ParseMacros (self, MacroDefStr):\r
318 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']\r
319 self._MacroDict = {}\r
320 IsExpression = False\r
321 for Macro in MacroDefStr:\r
322 if Macro.startswith('-D'):\r
323 IsExpression = True\r
324 if len(Macro) > 2:\r
325 Macro = Macro[2:]\r
326 else :\r
327 continue\r
328 if IsExpression:\r
329 IsExpression = False\r
330 Match = re.match("(\w+)=(.+)", Macro)\r
331 if Match:\r
332 self._MacroDict[Match.group(1)] = Match.group(2)\r
333 else:\r
334 Match = re.match("(\w+)", Macro)\r
335 if Match:\r
336 self._MacroDict[Match.group(1)] = ''\r
337 if len(self._MacroDict) == 0:\r
338 Error = 1\r
339 else:\r
340 Error = 0\r
341 if self.Debug:\r
c3f0829b 342 print ("INFO : Macro dictionary:")\r
cf1d4549 343 for Each in self._MacroDict:\r
c3f0829b 344 print (" $(%s) = [ %s ]" % (Each , self._MacroDict[Each]))\r
cf1d4549
JY
345 return Error\r
346\r
347 def EvaulateIfdef (self, Macro):\r
348 Result = Macro in self._MacroDict\r
349 if self.Debug:\r
c3f0829b 350 print ("INFO : Eval Ifdef [%s] : %s" % (Macro, Result))\r
cf1d4549
JY
351 return Result\r
352\r
353 def ExpandMacros (self, Input):\r
354 Line = Input\r
355 Match = re.findall("\$\(\w+\)", Input)\r
356 if Match:\r
357 for Each in Match:\r
358 Variable = Each[2:-1]\r
359 if Variable in self._MacroDict:\r
360 Line = Line.replace(Each, self._MacroDict[Variable])\r
361 else:\r
362 if self.Debug:\r
c3f0829b 363 print ("WARN : %s is not defined" % Each)\r
cf1d4549
JY
364 Line = Line.replace(Each, Each[2:-1])\r
365 return Line\r
366\r
62997d5e
MM
367 def ExpandPcds (self, Input):\r
368 Line = Input\r
369 Match = re.findall("(\w+\.\w+)", Input)\r
370 if Match:\r
371 for PcdName in Match:\r
372 if PcdName in self._PcdsDict:\r
373 Line = Line.replace(PcdName, self._PcdsDict[PcdName])\r
374 else:\r
375 if self.Debug:\r
c3f0829b 376 print ("WARN : %s is not defined" % PcdName)\r
62997d5e
MM
377 return Line\r
378\r
cf1d4549 379 def EvaluateExpress (self, Expr):\r
62997d5e
MM
380 ExpExpr = self.ExpandPcds(Expr)\r
381 ExpExpr = self.ExpandMacros(ExpExpr)\r
cf1d4549
JY
382 LogExpr = CLogicalExpression()\r
383 Result = LogExpr.evaluateExpress (ExpExpr)\r
384 if self.Debug:\r
c3f0829b 385 print ("INFO : Eval Express [%s] : %s" % (Expr, Result))\r
cf1d4549
JY
386 return Result\r
387\r
388 def FormatListValue(self, ConfigDict):\r
389 Struct = ConfigDict['struct']\r
390 if Struct not in ['UINT8','UINT16','UINT32','UINT64']:\r
391 return\r
392\r
393 dataarray = []\r
394 binlist = ConfigDict['value'][1:-1].split(',')\r
395 for each in binlist:\r
396 each = each.strip()\r
397 if each.startswith('0x'):\r
398 value = int(each, 16)\r
399 else:\r
400 value = int(each)\r
401 dataarray.append(value)\r
402\r
403 unit = int(Struct[4:]) / 8\r
404 if int(ConfigDict['length']) != unit * len(dataarray):\r
405 raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname'])\r
406\r
407 bytearray = []\r
408 for each in dataarray:\r
409 value = each\r
c3f0829b 410 for loop in range(int(unit)):\r
cf1d4549
JY
411 bytearray.append("0x%02X" % (value & 0xFF))\r
412 value = value >> 8\r
413 newvalue = '{' + ','.join(bytearray) + '}'\r
414 ConfigDict['value'] = newvalue\r
415 return ""\r
416\r
62997d5e 417 def ParseDscFile (self, DscFile, FvDir):\r
1d7eed41
CC
418 Hardcode = False\r
419 AutoAlign = False\r
cf1d4549
JY
420 self._CfgItemList = []\r
421 self._CfgPageDict = {}\r
422 self._CfgBlkDict = {}\r
423 self._DscFile = DscFile\r
424 self._FvDir = FvDir\r
425\r
426 IsDefSect = False\r
62997d5e 427 IsPcdSect = False\r
cf1d4549
JY
428 IsUpdSect = False\r
429 IsVpdSect = False\r
cf1d4549
JY
430\r
431 IfStack = []\r
432 ElifStack = []\r
433 Error = 0\r
434 ConfigDict = {}\r
435\r
436 DscFd = open(DscFile, "r")\r
437 DscLines = DscFd.readlines()\r
438 DscFd.close()\r
439\r
1d7eed41
CC
440 MaxAlign = 32 #Default align to 32, but if there are 64 bit unit, align to 64\r
441 SizeAlign = 0 #record the struct max align\r
7a38ad07 442 Base = 0 #Starting offset of sub-structure.\r
cf1d4549
JY
443 while len(DscLines):\r
444 DscLine = DscLines.pop(0).strip()\r
445 Handle = False\r
446 Match = re.match("^\[(.+)\]", DscLine)\r
447 if Match is not None:\r
62997d5e
MM
448 IsDefSect = False\r
449 IsPcdSect = False\r
450 IsVpdSect = False\r
451 IsUpdSect = False\r
cf1d4549
JY
452 if Match.group(1).lower() == "Defines".lower():\r
453 IsDefSect = True\r
ccacc4d2 454 if (Match.group(1).lower() == "PcdsFeatureFlag".lower() or Match.group(1).lower() == "PcdsFixedAtBuild".lower()):\r
62997d5e 455 IsPcdSect = True\r
cf1d4549
JY
456 elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():\r
457 ConfigDict = {}\r
458 ConfigDict['header'] = 'ON'\r
459 ConfigDict['region'] = 'UPD'\r
460 ConfigDict['order'] = -1\r
461 ConfigDict['page'] = ''\r
462 ConfigDict['name'] = ''\r
463 ConfigDict['find'] = ''\r
464 ConfigDict['struct'] = ''\r
465 ConfigDict['embed'] = ''\r
466 ConfigDict['comment'] = ''\r
467 ConfigDict['subreg'] = []\r
cf1d4549 468 IsUpdSect = True\r
1d7eed41 469 Offset = 0\r
cf1d4549 470 else:\r
62997d5e 471 if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:\r
cf1d4549
JY
472 if re.match("^!else($|\s+#.+)", DscLine):\r
473 if IfStack:\r
474 IfStack[-1] = not IfStack[-1]\r
475 else:\r
476 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)\r
477 raise SystemExit\r
478 elif re.match("^!endif($|\s+#.+)", DscLine):\r
479 if IfStack:\r
480 IfStack.pop()\r
481 Level = ElifStack.pop()\r
482 if Level > 0:\r
483 del IfStack[-Level:]\r
484 else:\r
485 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)\r
486 raise SystemExit\r
487 else:\r
488 Result = False\r
489 Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)\r
490 if Match:\r
491 Result = self.EvaulateIfdef (Match.group(2))\r
492 if Match.group(1) == 'ifndef':\r
493 Result = not Result\r
494 IfStack.append(Result)\r
495 ElifStack.append(0)\r
496 else:\r
ccacc4d2 497 Match = re.match("!(if|elseif)\s+(.+)", DscLine.split("#")[0])\r
cf1d4549 498 if Match:\r
62997d5e 499 Result = self.EvaluateExpress(Match.group(2))\r
cf1d4549
JY
500 if Match.group(1) == "if":\r
501 ElifStack.append(0)\r
502 IfStack.append(Result)\r
503 else: #elseif\r
504 if IfStack:\r
505 IfStack[-1] = not IfStack[-1]\r
506 IfStack.append(Result)\r
507 ElifStack[-1] = ElifStack[-1] + 1\r
508 else:\r
509 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)\r
510 raise SystemExit\r
511 else:\r
512 if IfStack:\r
513 Handle = reduce(lambda x,y: x and y, IfStack)\r
514 else:\r
515 Handle = True\r
516 if Handle:\r
517 Match = re.match("!include\s+(.+)", DscLine)\r
518 if Match:\r
519 IncludeFilePath = Match.group(1)\r
520 IncludeFilePath = self.ExpandMacros(IncludeFilePath)\r
41d739e4 521 PackagesPath = os.getenv("PACKAGES_PATH")\r
60131098
SZ
522 if PackagesPath:\r
523 for PackagePath in PackagesPath.split(os.pathsep):\r
524 IncludeFilePathAbs = os.path.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))\r
525 if os.path.exists(IncludeFilePathAbs):\r
526 IncludeDsc = open(IncludeFilePathAbs, "r")\r
527 break\r
528 else:\r
529 IncludeDsc = open(IncludeFilePath, "r")\r
41d739e4 530 if IncludeDsc == None:\r
cf1d4549
JY
531 print("ERROR: Cannot open file '%s'" % IncludeFilePath)\r
532 raise SystemExit\r
533 NewDscLines = IncludeDsc.readlines()\r
534 IncludeDsc.close()\r
535 DscLines = NewDscLines + DscLines\r
1d7eed41 536 Offset = 0\r
cf1d4549
JY
537 else:\r
538 if DscLine.startswith('!'):\r
91cc60ba 539 print("ERROR: Unrecognized directive for line '%s'" % DscLine)\r
cf1d4549
JY
540 raise SystemExit\r
541 if not Handle:\r
542 continue\r
543\r
544 if IsDefSect:\r
545 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09\r
546 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6\r
547 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385\r
548 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F\r
50528537 549 Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([/$()-.\w]+)", DscLine)\r
cf1d4549 550 if Match:\r
50528537 551 self._MacroDict[Match.group(1)] = self.ExpandMacros(Match.group(2))\r
cf1d4549 552 if self.Debug:\r
50528537 553 print ("INFO : DEFINE %s = [ %s ]" % (Match.group(1), self.ExpandMacros(Match.group(2))))\r
62997d5e
MM
554 elif IsPcdSect:\r
555 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE\r
556 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE\r
557 Match = re.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine)\r
558 if Match:\r
559 self._PcdsDict[Match.group(1)] = Match.group(2)\r
560 if self.Debug:\r
c3f0829b 561 print ("INFO : PCD %s = [ %s ]" % (Match.group(1), Match.group(2)))\r
b9c055f7
CC
562 i = 0\r
563 while i < len(BuildOptionPcd):\r
564 Match = re.match("\s*([\w\.]+)\s*\=\s*(\w+)", BuildOptionPcd[i])\r
565 if Match:\r
566 self._PcdsDict[Match.group(1)] = Match.group(2)\r
567 i += 1\r
cf1d4549
JY
568 else:\r
569 Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)\r
570 if Match:\r
571 Remaining = Match.group(2)\r
572 if Match.group(1) == '!BSF' or Match.group(1) == '@Bsf':\r
573 Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)\r
574 if Match:\r
575 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}\r
576 PageList = Match.group(1).split(',')\r
577 for Page in PageList:\r
578 Page = Page.strip()\r
579 Match = re.match("(\w+):\"(.+)\"", Page)\r
580 self._CfgPageDict[Match.group(1)] = Match.group(2)\r
581\r
582 Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)\r
583 if Match:\r
584 self._CfgBlkDict['name'] = Match.group(1)\r
585 self._CfgBlkDict['ver'] = Match.group(2)\r
586\r
587 for Key in self._BsfKeyList:\r
588 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
589 if Match:\r
590 if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'):\r
591 ConfigDict[Key.lower()] += Match.group(1)[1:]\r
592 else:\r
593 ConfigDict[Key.lower()] = Match.group(1)\r
594 else:\r
595 for Key in self._HdrKeyList:\r
596 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
597 if Match:\r
598 ConfigDict[Key.lower()] = Match.group(1)\r
599\r
600 Match = re.match("^\s*#\s+@Prompt\s+(.+)", DscLine)\r
601 if Match:\r
602 ConfigDict['name'] = Match.group(1)\r
603\r
604 Match = re.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine)\r
605 if Match:\r
606 if Match.group(2).strip() in self._BuidinOption:\r
607 ConfigDict['option'] = Match.group(2).strip()\r
608 else:\r
609 OptionValueList = Match.group(2).split(',')\r
610 OptionStringList = Match.group(3).split(',')\r
611 Index = 0\r
612 for Option in OptionValueList:\r
613 Option = Option.strip()\r
614 ConfigDict['option'] = ConfigDict['option'] + str(Option) + ':' + OptionStringList[Index].strip()\r
615 Index += 1\r
616 if Index in range(len(OptionValueList)):\r
617 ConfigDict['option'] += ', '\r
618 ConfigDict['type'] = "Combo"\r
619\r
620 Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine)\r
621 if Match:\r
622 if "0x" in Match.group(2) or "0x" in Match.group(3):\r
623 ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))\r
624 else:\r
625 ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))\r
626\r
627 Match = re.match("^\s*##\s+(.+)", DscLine)\r
628 if Match:\r
629 ConfigDict['help'] = Match.group(1)\r
630\r
631 # Check VPD/UPD\r
632 if IsUpdSect:\r
1d7eed41 633 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)\r
cf1d4549
JY
634 else:\r
635 Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine)\r
636 if Match:\r
637 ConfigDict['space'] = Match.group(1)\r
638 ConfigDict['cname'] = Match.group(2)\r
1d7eed41
CC
639 if Match.group(3) != '*':\r
640 Hardcode = True\r
641 Offset = int (Match.group(3), 16)\r
642 else:\r
643 AutoAlign = True\r
644\r
645 if Hardcode and AutoAlign:\r
646 print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")\r
647 raise SystemExit\r
648 ConfigDict['offset'] = Offset\r
cf1d4549
JY
649 if ConfigDict['order'] == -1:\r
650 ConfigDict['order'] = ConfigDict['offset'] << 8\r
651 else:\r
652 (Major, Minor) = ConfigDict['order'].split('.')\r
653 ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16)\r
654 if IsUpdSect:\r
655 Value = Match.group(5).strip()\r
656 if Match.group(4).startswith("0x"):\r
657 Length = int (Match.group(4), 16)\r
658 else :\r
659 Length = int (Match.group(4))\r
1d7eed41 660 Offset += Length\r
cf1d4549
JY
661 else:\r
662 Value = Match.group(4)\r
663 if Value is None:\r
664 Value = ''\r
665 Value = Value.strip()\r
666 if '|' in Value:\r
667 Match = re.match("^.+\s*\|\s*(.+)", Value)\r
668 if Match:\r
669 Value = Match.group(1)\r
670 Length = -1\r
671\r
672 ConfigDict['length'] = Length\r
673 Match = re.match("\$\((\w+)\)", Value)\r
674 if Match:\r
675 if Match.group(1) in self._MacroDict:\r
676 Value = self._MacroDict[Match.group(1)]\r
677\r
678 ConfigDict['value'] = Value\r
679 if (len(Value) > 0) and (Value[0] == '{'):\r
680 Value = self.FormatListValue(ConfigDict)\r
681\r
682 if ConfigDict['name'] == '':\r
683 # Clear BSF specific items\r
684 ConfigDict['bsfname'] = ''\r
685 ConfigDict['help'] = ''\r
686 ConfigDict['type'] = ''\r
687 ConfigDict['option'] = ''\r
1d7eed41
CC
688 if IsUpdSect and AutoAlign:\r
689 ItemLength = int(ConfigDict['length'])\r
690 ItemOffset = int(ConfigDict['offset'])\r
691 ItemStruct = ConfigDict['struct']\r
692 Unit = 1\r
693 if ItemLength in [1, 2, 4, 8] and not ConfigDict['value'].startswith('{'):\r
694 Unit = ItemLength\r
695 # If there are 64 bit unit, align to 64\r
696 if Unit == 8:\r
697 MaxAlign = 64\r
698 SizeAlign = 8\r
699 if ItemStruct != '':\r
700 UnitDict = {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}\r
701 if ItemStruct in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:\r
702 Unit = UnitDict[ItemStruct]\r
703 # If there are 64 bit unit, align to 64\r
704 if Unit == 8:\r
705 MaxAlign = 64\r
706 SizeAlign = max(SizeAlign, Unit)\r
707 if (ConfigDict['embed'].find(':START') != -1):\r
708 Base = ItemOffset\r
709 SubOffset = ItemOffset - Base\r
710 SubRemainder = SubOffset % Unit\r
711 if SubRemainder:\r
712 Diff = Unit - SubRemainder\r
713 Offset = Offset + Diff\r
714 ItemOffset = ItemOffset + Diff\r
715\r
716 if (ConfigDict['embed'].find(':END') != -1):\r
717 Remainder = Offset % (MaxAlign/8) # MaxAlign is either 32 or 64\r
718 if Remainder:\r
5e4ebd9e 719 Diff = int((MaxAlign/8) - Remainder)\r
1d7eed41
CC
720 Offset = Offset + Diff\r
721 ItemOffset = ItemOffset + Diff\r
722 MaxAlign = 32 # Reset to default 32 align when struct end\r
723 if (ConfigDict['cname'] == 'UpdTerminator'):\r
724 # ItemLength is the size of UpdTerminator\r
725 # Itemlength might be 16, 32, or 64\r
726 # Struct align to 64 if UpdTerminator\r
727 # or struct size is 64 bit, else align to 32\r
728 Remainder = Offset % max(ItemLength/8, 4, SizeAlign)\r
729 Offset = Offset + ItemLength\r
730 if Remainder:\r
5e4ebd9e 731 Diff = int(max(ItemLength/8, 4, SizeAlign) - Remainder)\r
1d7eed41
CC
732 ItemOffset = ItemOffset + Diff\r
733 ConfigDict['offset'] = ItemOffset\r
cf1d4549
JY
734\r
735 self._CfgItemList.append(ConfigDict.copy())\r
736 ConfigDict['name'] = ''\r
737 ConfigDict['find'] = ''\r
738 ConfigDict['struct'] = ''\r
739 ConfigDict['embed'] = ''\r
740 ConfigDict['comment'] = ''\r
741 ConfigDict['order'] = -1\r
742 ConfigDict['subreg'] = []\r
743 ConfigDict['option'] = ''\r
744 else:\r
745 # It could be a virtual item as below\r
62997d5e 746 # !BSF FIELD:{SerialDebugPortAddress0:1}\r
cf1d4549 747 # or\r
62997d5e
MM
748 # @Bsf FIELD:{SerialDebugPortAddress0:1b}\r
749 Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine)\r
cf1d4549 750 if Match:\r
62997d5e
MM
751 SubCfgDict = ConfigDict.copy()\r
752 if (Match.group(4) == None) or (Match.group(4) == 'B'):\r
753 UnitBitLen = 8\r
754 elif Match.group(4) == 'b':\r
755 UnitBitLen = 1\r
756 else:\r
757 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine)\r
758 raise SystemExit\r
cf1d4549 759 SubCfgDict['cname'] = Match.group(2)\r
62997d5e
MM
760 SubCfgDict['bitlength'] = int (Match.group(3)) * UnitBitLen\r
761 if SubCfgDict['bitlength'] > 0:\r
cf1d4549
JY
762 LastItem = self._CfgItemList[-1]\r
763 if len(LastItem['subreg']) == 0:\r
764 SubOffset = 0\r
765 else:\r
62997d5e
MM
766 SubOffset = LastItem['subreg'][-1]['bitoffset'] + LastItem['subreg'][-1]['bitlength']\r
767 SubCfgDict['bitoffset'] = SubOffset\r
cf1d4549
JY
768 LastItem['subreg'].append (SubCfgDict.copy())\r
769 ConfigDict['name'] = ''\r
770 return Error\r
771\r
62997d5e
MM
772 def GetBsfBitFields (self, subitem, bytes):\r
773 start = subitem['bitoffset']\r
774 end = start + subitem['bitlength']\r
775 bitsvalue = ''.join('{0:08b}'.format(i) for i in bytes[::-1])\r
776 bitsvalue = bitsvalue[::-1]\r
777 bitslen = len(bitsvalue)\r
778 if start > bitslen or end > bitslen:\r
c3f0829b 779 print ("Invalid bits offset [%d,%d] for %s" % (start, end, subitem['name']))\r
62997d5e
MM
780 raise SystemExit\r
781 return hex(int(bitsvalue[start:end][::-1], 2))\r
782\r
cf1d4549
JY
783 def UpdateSubRegionDefaultValue (self):\r
784 Error = 0\r
785 for Item in self._CfgItemList:\r
786 if len(Item['subreg']) == 0:\r
787 continue\r
788 bytearray = []\r
789 if Item['value'][0] == '{':\r
790 binlist = Item['value'][1:-1].split(',')\r
791 for each in binlist:\r
792 each = each.strip()\r
793 if each.startswith('0x'):\r
794 value = int(each, 16)\r
795 else:\r
796 value = int(each)\r
797 bytearray.append(value)\r
798 else:\r
799 if Item['value'].startswith('0x'):\r
800 value = int(Item['value'], 16)\r
801 else:\r
802 value = int(Item['value'])\r
62997d5e 803 idx = 0\r
cf1d4549
JY
804 while idx < Item['length']:\r
805 bytearray.append(value & 0xFF)\r
806 value = value >> 8\r
807 idx = idx + 1\r
808 for SubItem in Item['subreg']:\r
62997d5e
MM
809 valuestr = self.GetBsfBitFields(SubItem, bytearray)\r
810 SubItem['value'] = valuestr\r
cf1d4549
JY
811 return Error\r
812\r
813 def CreateSplitUpdTxt (self, UpdTxtFile):\r
814 GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']\r
815 SignatureList = ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS\r
816 for Index in range(len(GuidList)):\r
817 UpdTxtFile = ''\r
818 FvDir = self._FvDir\r
819 if GuidList[Index] not in self._MacroDict:\r
820 self.Error = "%s definition is missing in DSC file" % (GuidList[Index])\r
821 return 1\r
822\r
823 if UpdTxtFile == '':\r
824 UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.txt')\r
825\r
826 ReCreate = False\r
827 if not os.path.exists(UpdTxtFile):\r
828 ReCreate = True\r
829 else:\r
830 DscTime = os.path.getmtime(self._DscFile)\r
831 TxtTime = os.path.getmtime(UpdTxtFile)\r
832 if DscTime > TxtTime:\r
833 ReCreate = True\r
834\r
835 if not ReCreate:\r
836 # DSC has not been modified yet\r
837 # So don't have to re-generate other files\r
838 self.Error = 'No DSC file change, skip to create UPD TXT file'\r
839 return 256\r
840\r
841 TxtFd = open(UpdTxtFile, "w")\r
842 TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year))\r
843\r
844 NextOffset = 0\r
845 SpaceIdx = 0\r
846 StartAddr = 0\r
847 EndAddr = 0\r
848 Default = 'DEFAULT|'\r
849 InRange = False\r
850 for Item in self._CfgItemList:\r
851 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
852 StartAddr = Item['offset']\r
853 NextOffset = StartAddr\r
854 InRange = True\r
855 if Item['cname'] == 'UpdTerminator' and InRange == True:\r
856 EndAddr = Item['offset']\r
857 InRange = False\r
858 InRange = False\r
859 for Item in self._CfgItemList:\r
860 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
861 InRange = True\r
862 if InRange != True:\r
863 continue\r
864 if Item['cname'] == 'UpdTerminator':\r
865 InRange = False\r
866 if Item['region'] != 'UPD':\r
867 continue\r
868 Offset = Item['offset']\r
869 if StartAddr > Offset or EndAddr < Offset:\r
870 continue\r
871 if NextOffset < Offset:\r
872 # insert one line\r
873 TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset - StartAddr, Offset - NextOffset))\r
874 SpaceIdx = SpaceIdx + 1\r
875 NextOffset = Offset + Item['length']\r
cf1d4549
JY
876 TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'] - StartAddr,Item['length'],Item['value']))\r
877 TxtFd.close()\r
878 return 0\r
879\r
880 def ProcessMultilines (self, String, MaxCharLength):\r
881 Multilines = ''\r
882 StringLength = len(String)\r
883 CurrentStringStart = 0\r
884 StringOffset = 0\r
885 BreakLineDict = []\r
886 if len(String) <= MaxCharLength:\r
887 while (StringOffset < StringLength):\r
888 if StringOffset >= 1:\r
889 if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
890 BreakLineDict.append (StringOffset + 1)\r
891 StringOffset += 1\r
892 if BreakLineDict != []:\r
893 for Each in BreakLineDict:\r
894 Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()\r
895 CurrentStringStart = Each\r
896 if StringLength - CurrentStringStart > 0:\r
897 Multilines += " %s\n" % String[CurrentStringStart:].lstrip()\r
898 else:\r
899 Multilines = " %s\n" % String\r
900 else:\r
901 NewLineStart = 0\r
902 NewLineCount = 0\r
903 FoundSpaceChar = False\r
904 while (StringOffset < StringLength):\r
905 if StringOffset >= 1:\r
906 if NewLineCount >= MaxCharLength - 1:\r
907 if String[StringOffset] == ' ' and StringLength - StringOffset > 10:\r
908 BreakLineDict.append (NewLineStart + NewLineCount)\r
909 NewLineStart = NewLineStart + NewLineCount\r
910 NewLineCount = 0\r
911 FoundSpaceChar = True\r
912 elif StringOffset == StringLength - 1 and FoundSpaceChar == False:\r
913 BreakLineDict.append (0)\r
914 if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
915 BreakLineDict.append (StringOffset + 1)\r
916 NewLineStart = StringOffset + 1\r
917 NewLineCount = 0\r
918 StringOffset += 1\r
919 NewLineCount += 1\r
920 if BreakLineDict != []:\r
921 BreakLineDict.sort ()\r
922 for Each in BreakLineDict:\r
923 if Each > 0:\r
924 Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()\r
925 CurrentStringStart = Each\r
926 if StringLength - CurrentStringStart > 0:\r
927 Multilines += " %s\n" % String[CurrentStringStart:].lstrip()\r
928 return Multilines\r
929\r
930 def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option):\r
931 PosName = 28\r
932 PosComment = 30\r
933 NameLine=''\r
934 HelpLine=''\r
935 OptionLine=''\r
936\r
937 IsArray = False\r
938 if Length in [1,2,4,8]:\r
939 Type = "UINT%d" % (Length * 8)\r
cd3692b1
SY
940 if Name.startswith("UnusedUpdSpace") and Length != 1:\r
941 IsArray = True\r
942 Type = "UINT8"\r
cf1d4549
JY
943 else:\r
944 IsArray = True\r
945 Type = "UINT8"\r
946\r
947 if Item and Item['value'].startswith('{'):\r
948 Type = "UINT8"\r
949 IsArray = True\r
950\r
951 if Struct != '':\r
952 Type = Struct\r
953 if Struct in ['UINT8','UINT16','UINT32','UINT64']:\r
954 IsArray = True\r
955 Unit = int(Type[4:]) / 8\r
956 Length = Length / Unit\r
957 else:\r
958 IsArray = False\r
959\r
960 if IsArray:\r
961 Name = Name + '[%d]' % Length\r
962\r
963 if len(Type) < PosName:\r
964 Space1 = PosName - len(Type)\r
965 else:\r
966 Space1 = 1\r
967\r
968 if BsfName != '':\r
969 NameLine=" - %s\n" % BsfName\r
970 else:\r
971 NameLine="\n"\r
972\r
973 if Help != '':\r
974 HelpLine = self.ProcessMultilines (Help, 80)\r
975\r
976 if Option != '':\r
977 OptionLine = self.ProcessMultilines (Option, 80)\r
978\r
979 if Offset is None:\r
980 OffsetStr = '????'\r
981 else:\r
982 OffsetStr = '0x%04X' % Offset\r
983\r
984 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)\r
985\r
986 def PostProcessBody (self, TextBody):\r
987 NewTextBody = []\r
988 OldTextBody = []\r
989 IncludeLine = False\r
990 StructName = ''\r
991 VariableName = ''\r
992 IsUpdHdrDefined = False\r
993 IsUpdHeader = False\r
994 for Line in TextBody:\r
995 SplitToLines = Line.splitlines()\r
996 MatchComment = re.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines[0])\r
997 if MatchComment:\r
998 if MatchComment.group(1) == 'FSP_UPD_HEADER':\r
999 IsUpdHeader = True\r
1000 else:\r
1001 IsUpdHeader = False\r
1002 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1003 CommentLine = " " + MatchComment.group(2) + "\n"\r
1004 NewTextBody.append("/**" + CommentLine + "**/\n")\r
1005 Line = Line[(len(SplitToLines[0]) + 1):]\r
1006\r
1007 Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)\r
1008 if Match:\r
1009 Line = Match.group(4)\r
1010 if Match.group(1) == 'FSP_UPD_HEADER':\r
1011 IsUpdHeader = True\r
1012 else:\r
1013 IsUpdHeader = False\r
1014\r
1015 if Match and Match.group(3) == 'START':\r
1016 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1017 NewTextBody.append ('typedef struct {\n')\r
1018 StructName = Match.group(1)\r
1019 VariableName = Match.group(2)\r
1020 MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)\r
1021 if MatchOffset:\r
1022 Offset = int(MatchOffset.group(1), 16)\r
1023 else:\r
1024 Offset = None\r
1025 Line\r
1026 IncludeLine = True\r
1027 OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', '', ''))\r
1028 if IncludeLine:\r
1029 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1030 NewTextBody.append (Line)\r
1031 else:\r
1032 OldTextBody.append (Line)\r
1033\r
62997d5e 1034 if Match and Match.group(3) == 'END':\r
cf1d4549 1035 if (StructName != Match.group(1)) or (VariableName != Match.group(2)):\r
c3f0829b 1036 print ("Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1)))\r
cf1d4549
JY
1037 else:\r
1038 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1039 NewTextBody.append ('} %s;\n\n' % StructName)\r
1040 IsUpdHdrDefined = True\r
1041 IncludeLine = False\r
1042 NewTextBody.extend(OldTextBody)\r
1043 return NewTextBody\r
1044\r
d75c07bc
CC
1045 def WriteLinesWithoutTailingSpace (self, HeaderFd, Line):\r
1046 TxtBody2 = Line.splitlines(True)\r
1047 for Line2 in TxtBody2:\r
1048 Line2 = Line2.rstrip()\r
1049 Line2 += '\n'\r
1050 HeaderFd.write (Line2)\r
1051 return 0\r
cf1d4549
JY
1052 def CreateHeaderFile (self, InputHeaderFile):\r
1053 FvDir = self._FvDir\r
1054\r
1055 HeaderFileName = 'FspUpd.h'\r
1056 HeaderFile = os.path.join(FvDir, HeaderFileName)\r
1057\r
1058 # Check if header needs to be recreated\r
1059 ReCreate = False\r
1060\r
1061 TxtBody = []\r
1062 for Item in self._CfgItemList:\r
1063 if str(Item['cname']) == 'Signature' and Item['length'] == 8:\r
1064 Value = int(Item['value'], 16)\r
1065 Chars = []\r
1066 while Value != 0x0:\r
1067 Chars.append(chr(Value & 0xFF))\r
1068 Value = Value >> 8\r
1069 SignatureStr = ''.join(Chars)\r
1070 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly\r
1071 if '_T' in SignatureStr[6:6+2]:\r
1072 TxtBody.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1073 elif '_M' in SignatureStr[6:6+2]:\r
1074 TxtBody.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1075 elif '_S' in SignatureStr[6:6+2]:\r
1076 TxtBody.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1077 TxtBody.append("\n")\r
1078\r
1079 for Region in ['UPD']:\r
1080 UpdOffsetTable = []\r
1081 UpdSignature = ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS\r
1082 UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']\r
1083 for Item in self._CfgItemList:\r
1084 if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:\r
1085 UpdOffsetTable.append (Item["offset"])\r
1086\r
1087 for UpdIdx in range(len(UpdOffsetTable)):\r
1088 CommentLine = ""\r
1089 for Item in self._CfgItemList:\r
1090 if Item["comment"] != '' and Item["offset"] >= UpdOffsetTable[UpdIdx]:\r
1091 MatchComment = re.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item["comment"])\r
1092 if MatchComment and MatchComment.group(1) == Region[0]:\r
1093 CommentLine = " " + MatchComment.group(2) + "\n"\r
1094 TxtBody.append("/**" + CommentLine + "**/\n")\r
1095 elif Item["offset"] >= UpdOffsetTable[UpdIdx] and Item["comment"] == '':\r
1096 Match = re.match("^FSP([\w|\W|\s])_UPD", UpdStructure[UpdIdx])\r
1097 if Match:\r
1098 TxtBody.append("/** Fsp " + Match.group(1) + " UPD Configuration\n**/\n")\r
1099 TxtBody.append("typedef struct {\n")\r
1100 NextOffset = 0\r
1101 SpaceIdx = 0\r
1102 Offset = 0\r
1103\r
1104 LastVisible = True\r
1105 ResvOffset = 0\r
1106 ResvIdx = 0\r
1107 LineBuffer = []\r
1108 InRange = False\r
1109 for Item in self._CfgItemList:\r
1110 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == UpdSignature[UpdIdx] or Region[0] == 'V':\r
1111 InRange = True\r
1112 if InRange != True:\r
1113 continue\r
1114 if Item['cname'] == 'UpdTerminator':\r
1115 InRange = False\r
1116\r
1117 if Item['region'] != Region:\r
1118 continue\r
1119\r
1120 if Item["offset"] < UpdOffsetTable[UpdIdx]:\r
1121 continue\r
1122\r
1123 NextVisible = LastVisible\r
1124\r
1125 if LastVisible and (Item['header'] == 'OFF'):\r
1126 NextVisible = False\r
1127 ResvOffset = Item['offset']\r
1128 elif (not LastVisible) and Item['header'] == 'ON':\r
1129 NextVisible = True\r
1130 Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx\r
1131 ResvIdx = ResvIdx + 1\r
1132 TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', '', ''))\r
1133\r
1134 if Offset < Item["offset"]:\r
1135 if LastVisible:\r
1136 Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx\r
1137 LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', '', ''))\r
1138 SpaceIdx = SpaceIdx + 1\r
1139 Offset = Item["offset"]\r
1140\r
1141 LastVisible = NextVisible\r
1142\r
1143 Offset = Offset + Item["length"]\r
1144 if LastVisible:\r
1145 for Each in LineBuffer:\r
1146 TxtBody.append (Each)\r
1147 LineBuffer = []\r
1148 Comment = Item["comment"]\r
1149 Embed = Item["embed"].upper()\r
1150 if Embed.endswith(':START') or Embed.endswith(':END'):\r
1151 if not Comment == '' and Embed.endswith(':START'):\r
1152 Marker = '/* COMMENT:%s */ \n' % Item["comment"]\r
1153 Marker = Marker + '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
1154 else:\r
1155 Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
1156 else:\r
1157 if Embed == '':\r
62997d5e 1158 Marker = ''\r
cf1d4549
JY
1159 else:\r
1160 self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]\r
1161 return 4\r
1162 Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'], Item['option'])\r
1163 TxtBody.append(Line)\r
1164 if Item['cname'] == 'UpdTerminator':\r
1165 break\r
1166 TxtBody.append("} " + UpdStructure[UpdIdx] + ";\n\n")\r
62997d5e 1167\r
cf1d4549
JY
1168 # Handle the embedded data structure\r
1169 TxtBody = self.PostProcessBody (TxtBody)\r
1170\r
1171 HeaderTFileName = 'FsptUpd.h'\r
1172 HeaderMFileName = 'FspmUpd.h'\r
1173 HeaderSFileName = 'FspsUpd.h'\r
1174\r
1175 UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION\r
1176 UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG\r
1177 UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']\r
89f569ae 1178 ExcludedSpecificUpd = ['FSPT_ARCH_UPD', 'FSPM_ARCH_UPD', 'FSPS_ARCH_UPD']\r
cf1d4549 1179\r
1d058c3e 1180 IncLines = []\r
cf1d4549
JY
1181 if InputHeaderFile != '':\r
1182 if not os.path.exists(InputHeaderFile):\r
1183 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
1184 return 6\r
1185\r
1186 InFd = open(InputHeaderFile, "r")\r
1187 IncLines = InFd.readlines()\r
1188 InFd.close()\r
1189\r
1190 for item in range(len(UpdRegionCheck)):\r
1191 if UpdRegionCheck[item] == 'FSPT':\r
1192 HeaderFd = open(os.path.join(FvDir, HeaderTFileName), "w")\r
1193 FileBase = os.path.basename(os.path.join(FvDir, HeaderTFileName))\r
1194 elif UpdRegionCheck[item] == 'FSPM':\r
1195 HeaderFd = open(os.path.join(FvDir, HeaderMFileName), "w")\r
1196 FileBase = os.path.basename(os.path.join(FvDir, HeaderMFileName))\r
1197 elif UpdRegionCheck[item] == 'FSPS':\r
1198 HeaderFd = open(os.path.join(FvDir, HeaderSFileName), "w")\r
1199 FileBase = os.path.basename(os.path.join(FvDir, HeaderSFileName))\r
1200 FileName = FileBase.replace(".", "_").upper()\r
1201 HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))\r
1202 HeaderFd.write("#ifndef __%s__\n" % FileName)\r
1203 HeaderFd.write("#define __%s__\n\n" % FileName)\r
1204 HeaderFd.write("#include <%s>\n\n" % HeaderFileName)\r
cd3692b1 1205 HeaderFd.write("#pragma pack(1)\n\n")\r
cf1d4549
JY
1206\r
1207 Export = False\r
1208 for Line in IncLines:\r
1209 Match = re.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
1210 if Match:\r
1211 if Match.group(2) == "BEGIN" and Match.group(1) == UpdRegionCheck[item]:\r
1212 Export = True\r
1213 continue\r
1214 else:\r
1215 Export = False\r
1216 continue\r
1217 if Export:\r
1218 HeaderFd.write(Line)\r
1219 HeaderFd.write("\n")\r
1220\r
1221 Index = 0\r
1222 StartIndex = 0\r
1223 EndIndex = 0\r
1224 StructStart = []\r
1225 StructStartWithComment = []\r
1226 StructEnd = []\r
1227 for Line in TxtBody:\r
1228 Index += 1\r
1229 Match = re.match("(typedef struct {)", Line)\r
1230 if Match:\r
1231 StartIndex = Index - 1\r
1232 Match = re.match("}\s([_A-Z0-9]+);", Line)\r
89f569ae 1233 if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd[item] not in Match.group(1)):\r
cf1d4549
JY
1234 EndIndex = Index\r
1235 StructStart.append(StartIndex)\r
1236 StructEnd.append(EndIndex)\r
1237 Index = 0\r
1238 for Line in TxtBody:\r
1239 Index += 1\r
1240 for Item in range(len(StructStart)):\r
1241 if Index == StructStart[Item]:\r
1242 Match = re.match("^(/\*\*\s*)", Line)\r
1243 if Match:\r
1244 StructStartWithComment.append(StructStart[Item])\r
1245 else:\r
1246 StructStartWithComment.append(StructStart[Item] + 1)\r
1247 Index = 0\r
1248 for Line in TxtBody:\r
1249 Index += 1\r
1250 for Item in range(len(StructStart)):\r
1251 if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
d75c07bc 1252 self.WriteLinesWithoutTailingSpace(HeaderFd, Line)\r
cd3692b1 1253 HeaderFd.write("#pragma pack()\n\n")\r
cf1d4549
JY
1254 HeaderFd.write("#endif\n")\r
1255 HeaderFd.close()\r
1256\r
1257 HeaderFd = open(HeaderFile, "w")\r
1258 FileBase = os.path.basename(HeaderFile)\r
1259 FileName = FileBase.replace(".", "_").upper()\r
1260 HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))\r
1261 HeaderFd.write("#ifndef __%s__\n" % FileName)\r
1262 HeaderFd.write("#define __%s__\n\n" % FileName)\r
1263 HeaderFd.write("#include <FspEas.h>\n\n")\r
cd3692b1 1264 HeaderFd.write("#pragma pack(1)\n\n")\r
cf1d4549
JY
1265\r
1266 for item in range(len(UpdRegionCheck)):\r
1267 Index = 0\r
1268 StartIndex = 0\r
1269 EndIndex = 0\r
1270 StructStart = []\r
1271 StructStartWithComment = []\r
1272 StructEnd = []\r
1273 for Line in TxtBody:\r
1274 Index += 1\r
1275 Match = re.match("(typedef struct {)", Line)\r
1276 if Match:\r
1277 StartIndex = Index - 1\r
1278 Match = re.match("#define\s([_A-Z0-9]+)\s*", Line)\r
1279 if Match and (UpdSignatureCheck[item] in Match.group(1) or UpdSignatureCheck[item] in Match.group(1)):\r
1280 StructStart.append(Index - 1)\r
1281 StructEnd.append(Index)\r
1282 Index = 0\r
1283 for Line in TxtBody:\r
1284 Index += 1\r
1285 for Item in range(len(StructStart)):\r
1286 if Index == StructStart[Item]:\r
1287 Match = re.match("^(/\*\*\s*)", Line)\r
1288 if Match:\r
1289 StructStartWithComment.append(StructStart[Item])\r
1290 else:\r
1291 StructStartWithComment.append(StructStart[Item] + 1)\r
1292 Index = 0\r
1293 for Line in TxtBody:\r
1294 Index += 1\r
1295 for Item in range(len(StructStart)):\r
1296 if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
d75c07bc 1297 self.WriteLinesWithoutTailingSpace(HeaderFd, Line)\r
cd3692b1 1298 HeaderFd.write("#pragma pack()\n\n")\r
cf1d4549
JY
1299 HeaderFd.write("#endif\n")\r
1300 HeaderFd.close()\r
1301\r
1302 return 0\r
1303\r
1304 def WriteBsfStruct (self, BsfFd, Item):\r
ba8ea427 1305 LogExpr = CLogicalExpression()\r
cf1d4549
JY
1306 if Item['type'] == "None":\r
1307 Space = "gPlatformFspPkgTokenSpaceGuid"\r
1308 else:\r
1309 Space = Item['space']\r
1310 Line = " $%s_%s" % (Space, Item['cname'])\r
1311 Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])\r
1312 if Match:\r
1313 DefaultValue = Match.group(1).strip()\r
1314 else:\r
1315 DefaultValue = Item['value'].strip()\r
62997d5e
MM
1316 if 'bitlength' in Item:\r
1317 BsfFd.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['bitlength'], DefaultValue))\r
1318 else:\r
1319 BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))\r
cf1d4549
JY
1320 TmpList = []\r
1321 if Item['type'] == "Combo":\r
1322 if not Item['option'] in self._BuidinOption:\r
1323 OptList = Item['option'].split(',')\r
1324 for Option in OptList:\r
1325 Option = Option.strip()\r
1326 (OpVal, OpStr) = Option.split(':')\r
ba8ea427
TRM
1327 test = LogExpr.getNumber (OpVal)\r
1328 if test is None:\r
1329 raise Exception("Selection Index '%s' is not a number" % OpVal)\r
cf1d4549
JY
1330 TmpList.append((OpVal, OpStr))\r
1331 return TmpList\r
1332\r
1333 def WriteBsfOption (self, BsfFd, Item):\r
1334 PcdName = Item['space'] + '_' + Item['cname']\r
1335 WriteHelp = 0\r
1336 if Item['type'] == "Combo":\r
1337 if Item['option'] in self._BuidinOption:\r
1338 Options = self._BuidinOption[Item['option']]\r
1339 else:\r
1340 Options = PcdName\r
62997d5e 1341 BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options))\r
cf1d4549
JY
1342 WriteHelp = 1\r
1343 elif Item['type'].startswith("EditNum"):\r
1344 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'])\r
1345 if Match:\r
62997d5e 1346 BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)))\r
cf1d4549
JY
1347 WriteHelp = 2\r
1348 elif Item['type'].startswith("EditText"):\r
62997d5e 1349 BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']))\r
cf1d4549
JY
1350 WriteHelp = 1\r
1351 elif Item['type'] == "Table":\r
1352 Columns = Item['option'].split(',')\r
1353 if len(Columns) != 0:\r
62997d5e 1354 BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name']))\r
cf1d4549
JY
1355 for Col in Columns:\r
1356 Fmt = Col.split(':')\r
1357 if len(Fmt) != 3:\r
1358 raise Exception("Column format '%s' is invalid !" % Fmt)\r
1359 try:\r
1360 Dtype = int(Fmt[1].strip())\r
1361 except:\r
1362 raise Exception("Column size '%s' is invalid !" % Fmt[1])\r
1363 BsfFd.write('\n Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))\r
1364 BsfFd.write(',\n')\r
1365 WriteHelp = 1\r
62997d5e 1366\r
cf1d4549
JY
1367 if WriteHelp > 0:\r
1368 HelpLines = Item['help'].split('\\n\\r')\r
1369 FirstLine = True\r
1370 for HelpLine in HelpLines:\r
1371 if FirstLine:\r
1372 FirstLine = False\r
62997d5e 1373 BsfFd.write(' Help "%s"\n' % (HelpLine))\r
cf1d4549 1374 else:\r
62997d5e 1375 BsfFd.write(' "%s"\n' % (HelpLine))\r
cf1d4549 1376 if WriteHelp == 2:\r
62997d5e 1377 BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)))\r
cf1d4549
JY
1378\r
1379 def GenerateBsfFile (self, BsfFile):\r
1380\r
1381 if BsfFile == '':\r
1382 self.Error = "BSF output file '%s' is invalid" % BsfFile\r
1383 return 1\r
1384\r
1385 Error = 0\r
1386 OptionDict = {}\r
1387 BsfFd = open(BsfFile, "w")\r
1388 BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))\r
62997d5e 1389 BsfFd.write("%s\n" % self._GlobalDataDef)\r
cf1d4549
JY
1390 BsfFd.write("StructDef\n")\r
1391 NextOffset = -1\r
1392 for Item in self._CfgItemList:\r
1393 if Item['find'] != '':\r
1394 BsfFd.write('\n Find "%s"\n' % Item['find'])\r
1395 NextOffset = Item['offset'] + Item['length']\r
1396 if Item['name'] != '':\r
1397 if NextOffset != Item['offset']:\r
1398 BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))\r
1399 if len(Item['subreg']) > 0:\r
1400 NextOffset = Item['offset']\r
62997d5e 1401 BitsOffset = NextOffset * 8\r
cf1d4549 1402 for SubItem in Item['subreg']:\r
62997d5e 1403 BitsOffset += SubItem['bitlength']\r
cf1d4549 1404 if SubItem['name'] == '':\r
62997d5e
MM
1405 if 'bitlength' in SubItem:\r
1406 BsfFd.write(" Skip %d bits\n" % (SubItem['bitlength']))\r
1407 else:\r
1408 BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))\r
cf1d4549
JY
1409 else:\r
1410 Options = self.WriteBsfStruct(BsfFd, SubItem)\r
1411 if len(Options) > 0:\r
1412 OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options\r
62997d5e
MM
1413\r
1414 NextBitsOffset = (Item['offset'] + Item['length']) * 8\r
1415 if NextBitsOffset > BitsOffset:\r
1416 BitsGap = NextBitsOffset - BitsOffset\r
1417 BitsRemain = BitsGap % 8\r
1418 if BitsRemain:\r
1419 BsfFd.write(" Skip %d bits\n" % BitsRemain)\r
1420 BitsGap -= BitsRemain\r
5e4ebd9e 1421 BytesRemain = int(BitsGap / 8)\r
62997d5e
MM
1422 if BytesRemain:\r
1423 BsfFd.write(" Skip %d bytes\n" % BytesRemain)\r
1424 NextOffset = Item['offset'] + Item['length']\r
cf1d4549
JY
1425 else:\r
1426 NextOffset = Item['offset'] + Item['length']\r
1427 Options = self.WriteBsfStruct(BsfFd, Item)\r
1428 if len(Options) > 0:\r
1429 OptionDict[Item['space']+'_'+Item['cname']] = Options\r
1430 BsfFd.write("\nEndStruct\n\n")\r
1431\r
62997d5e 1432 BsfFd.write("%s" % self._BuidinOptionTxt)\r
cf1d4549
JY
1433\r
1434 for Each in OptionDict:\r
62997d5e 1435 BsfFd.write("List &%s\n" % Each)\r
cf1d4549 1436 for Item in OptionDict[Each]:\r
62997d5e
MM
1437 BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]))\r
1438 BsfFd.write("EndList\n\n")\r
cf1d4549 1439\r
62997d5e
MM
1440 BsfFd.write("BeginInfoBlock\n")\r
1441 BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']))\r
1442 BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']))\r
1443 BsfFd.write("EndInfoBlock\n\n")\r
cf1d4549
JY
1444\r
1445 for Each in self._CfgPageDict:\r
62997d5e 1446 BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each])\r
cf1d4549
JY
1447 BsfItems = []\r
1448 for Item in self._CfgItemList:\r
1449 if Item['name'] != '':\r
1450 if Item['page'] != Each:\r
1451 continue\r
1452 if len(Item['subreg']) > 0:\r
1453 for SubItem in Item['subreg']:\r
1454 if SubItem['name'] != '':\r
1455 BsfItems.append(SubItem)\r
1456 else:\r
1457 BsfItems.append(Item)\r
1458\r
1459 BsfItems.sort(key=lambda x: x['order'])\r
1460\r
1461 for Item in BsfItems:\r
1462 self.WriteBsfOption (BsfFd, Item)\r
62997d5e 1463 BsfFd.write("EndPage\n\n")\r
cf1d4549
JY
1464\r
1465 BsfFd.close()\r
1466 return Error\r
1467\r
1468\r
1469def Usage():\r
89f569ae 1470 print ("GenCfgOpt Version 0.55")\r
c3f0829b
CC
1471 print ("Usage:")\r
1472 print (" GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]")\r
1473 print (" GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]")\r
1474 print (" GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]")\r
cf1d4549
JY
1475\r
1476def Main():\r
1477 #\r
1478 # Parse the options and args\r
1479 #\r
b9c055f7
CC
1480 i = 1\r
1481\r
cf1d4549 1482 GenCfgOpt = CGenCfgOpt()\r
b9c055f7
CC
1483 while i < len(sys.argv):\r
1484 if sys.argv[i].strip().lower() == "--pcd":\r
1485 BuildOptionPcd.append(sys.argv[i+1])\r
1486 i += 1\r
1487 i += 1\r
cf1d4549
JY
1488 argc = len(sys.argv)\r
1489 if argc < 4:\r
1490 Usage()\r
1491 return 1\r
1492 else:\r
1493 DscFile = sys.argv[2]\r
1494 if not os.path.exists(DscFile):\r
c3f0829b 1495 print ("ERROR: Cannot open DSC file '%s' !" % DscFile)\r
cf1d4549 1496 return 2\r
cf1d4549
JY
1497\r
1498 OutFile = ''\r
1499 if argc > 4:\r
62997d5e 1500 if sys.argv[4][0] == '-':\r
cf1d4549
JY
1501 Start = 4\r
1502 else:\r
62997d5e 1503 OutFile = sys.argv[4]\r
cf1d4549 1504 Start = 5\r
e4408576
OBO
1505 if argc > Start:\r
1506 if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:\r
c3f0829b 1507 print ("ERROR: Macro parsing failed !")\r
e4408576 1508 return 3\r
cf1d4549
JY
1509\r
1510 FvDir = sys.argv[3]\r
1511 if not os.path.exists(FvDir):\r
1512 os.makedirs(FvDir)\r
1513\r
62997d5e 1514 if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:\r
c3f0829b 1515 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1516 return 5\r
1517\r
1518 if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:\r
c3f0829b 1519 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1520 return 7\r
1521\r
1522 if sys.argv[1] == "UPDTXT":\r
1523 Ret = GenCfgOpt.CreateSplitUpdTxt(OutFile)\r
1524 if Ret != 0:\r
1525 # No change is detected\r
1526 if Ret == 256:\r
c3f0829b 1527 print ("INFO: %s !" % (GenCfgOpt.Error))\r
cf1d4549 1528 else :\r
c3f0829b 1529 print ("ERROR: %s !" % (GenCfgOpt.Error))\r
cf1d4549
JY
1530 return Ret\r
1531 elif sys.argv[1] == "HEADER":\r
1532 if GenCfgOpt.CreateHeaderFile(OutFile) != 0:\r
c3f0829b 1533 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1534 return 8\r
1535 elif sys.argv[1] == "GENBSF":\r
1536 if GenCfgOpt.GenerateBsfFile(OutFile) != 0:\r
c3f0829b 1537 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1538 return 9\r
1539 else:\r
1540 if argc < 5:\r
1541 Usage()\r
1542 return 1\r
c3f0829b 1543 print ("ERROR: Unknown command '%s' !" % sys.argv[1])\r
cf1d4549
JY
1544 Usage()\r
1545 return 1\r
1546 return 0\r
1547 return 0\r
1548\r
1549\r
1550if __name__ == '__main__':\r
1551 sys.exit(Main())\r