]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/Tools/GenCfgOpt.py
FmpDevicePkg: Fix various typos
[mirror_edk2.git] / IntelFsp2Pkg / Tools / GenCfgOpt.py
CommitLineData
cf1d4549
JY
1## @ GenCfgOpt.py\r
2#\r
c3f0829b 3# Copyright (c) 2014 - 2019, 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
cf1d4549
JY
442 while len(DscLines):\r
443 DscLine = DscLines.pop(0).strip()\r
444 Handle = False\r
445 Match = re.match("^\[(.+)\]", DscLine)\r
446 if Match is not None:\r
62997d5e
MM
447 IsDefSect = False\r
448 IsPcdSect = False\r
449 IsVpdSect = False\r
450 IsUpdSect = False\r
cf1d4549
JY
451 if Match.group(1).lower() == "Defines".lower():\r
452 IsDefSect = True\r
ccacc4d2 453 if (Match.group(1).lower() == "PcdsFeatureFlag".lower() or Match.group(1).lower() == "PcdsFixedAtBuild".lower()):\r
62997d5e 454 IsPcdSect = True\r
cf1d4549
JY
455 elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():\r
456 ConfigDict = {}\r
457 ConfigDict['header'] = 'ON'\r
458 ConfigDict['region'] = 'UPD'\r
459 ConfigDict['order'] = -1\r
460 ConfigDict['page'] = ''\r
461 ConfigDict['name'] = ''\r
462 ConfigDict['find'] = ''\r
463 ConfigDict['struct'] = ''\r
464 ConfigDict['embed'] = ''\r
465 ConfigDict['comment'] = ''\r
466 ConfigDict['subreg'] = []\r
cf1d4549 467 IsUpdSect = True\r
1d7eed41 468 Offset = 0\r
cf1d4549 469 else:\r
62997d5e 470 if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:\r
cf1d4549
JY
471 if re.match("^!else($|\s+#.+)", DscLine):\r
472 if IfStack:\r
473 IfStack[-1] = not IfStack[-1]\r
474 else:\r
475 print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)\r
476 raise SystemExit\r
477 elif re.match("^!endif($|\s+#.+)", DscLine):\r
478 if IfStack:\r
479 IfStack.pop()\r
480 Level = ElifStack.pop()\r
481 if Level > 0:\r
482 del IfStack[-Level:]\r
483 else:\r
484 print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)\r
485 raise SystemExit\r
486 else:\r
487 Result = False\r
488 Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)\r
489 if Match:\r
490 Result = self.EvaulateIfdef (Match.group(2))\r
491 if Match.group(1) == 'ifndef':\r
492 Result = not Result\r
493 IfStack.append(Result)\r
494 ElifStack.append(0)\r
495 else:\r
ccacc4d2 496 Match = re.match("!(if|elseif)\s+(.+)", DscLine.split("#")[0])\r
cf1d4549 497 if Match:\r
62997d5e 498 Result = self.EvaluateExpress(Match.group(2))\r
cf1d4549
JY
499 if Match.group(1) == "if":\r
500 ElifStack.append(0)\r
501 IfStack.append(Result)\r
502 else: #elseif\r
503 if IfStack:\r
504 IfStack[-1] = not IfStack[-1]\r
505 IfStack.append(Result)\r
506 ElifStack[-1] = ElifStack[-1] + 1\r
507 else:\r
508 print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)\r
509 raise SystemExit\r
510 else:\r
511 if IfStack:\r
512 Handle = reduce(lambda x,y: x and y, IfStack)\r
513 else:\r
514 Handle = True\r
515 if Handle:\r
516 Match = re.match("!include\s+(.+)", DscLine)\r
517 if Match:\r
518 IncludeFilePath = Match.group(1)\r
519 IncludeFilePath = self.ExpandMacros(IncludeFilePath)\r
41d739e4 520 PackagesPath = os.getenv("PACKAGES_PATH")\r
60131098
SZ
521 if PackagesPath:\r
522 for PackagePath in PackagesPath.split(os.pathsep):\r
523 IncludeFilePathAbs = os.path.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))\r
524 if os.path.exists(IncludeFilePathAbs):\r
525 IncludeDsc = open(IncludeFilePathAbs, "r")\r
526 break\r
527 else:\r
528 IncludeDsc = open(IncludeFilePath, "r")\r
41d739e4 529 if IncludeDsc == None:\r
cf1d4549
JY
530 print("ERROR: Cannot open file '%s'" % IncludeFilePath)\r
531 raise SystemExit\r
532 NewDscLines = IncludeDsc.readlines()\r
533 IncludeDsc.close()\r
534 DscLines = NewDscLines + DscLines\r
1d7eed41 535 Offset = 0\r
cf1d4549
JY
536 else:\r
537 if DscLine.startswith('!'):\r
f527942e 538 print("ERROR: Unrecognized directive for line '%s'" % DscLine)\r
cf1d4549
JY
539 raise SystemExit\r
540 if not Handle:\r
541 continue\r
542\r
543 if IsDefSect:\r
544 #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09\r
545 #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6\r
546 #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385\r
547 #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F\r
548 Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine)\r
549 if Match:\r
550 self._MacroDict[Match.group(1)] = Match.group(2)\r
551 if self.Debug:\r
c3f0829b 552 print ("INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2)))\r
62997d5e
MM
553 elif IsPcdSect:\r
554 #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE\r
555 #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE\r
556 Match = re.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine)\r
557 if Match:\r
558 self._PcdsDict[Match.group(1)] = Match.group(2)\r
559 if self.Debug:\r
c3f0829b 560 print ("INFO : PCD %s = [ %s ]" % (Match.group(1), Match.group(2)))\r
b9c055f7
CC
561 i = 0\r
562 while i < len(BuildOptionPcd):\r
563 Match = re.match("\s*([\w\.]+)\s*\=\s*(\w+)", BuildOptionPcd[i])\r
564 if Match:\r
565 self._PcdsDict[Match.group(1)] = Match.group(2)\r
566 i += 1\r
cf1d4549
JY
567 else:\r
568 Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)\r
569 if Match:\r
570 Remaining = Match.group(2)\r
571 if Match.group(1) == '!BSF' or Match.group(1) == '@Bsf':\r
572 Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)\r
573 if Match:\r
574 # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}\r
575 PageList = Match.group(1).split(',')\r
576 for Page in PageList:\r
577 Page = Page.strip()\r
578 Match = re.match("(\w+):\"(.+)\"", Page)\r
579 self._CfgPageDict[Match.group(1)] = Match.group(2)\r
580\r
581 Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)\r
582 if Match:\r
583 self._CfgBlkDict['name'] = Match.group(1)\r
584 self._CfgBlkDict['ver'] = Match.group(2)\r
585\r
586 for Key in self._BsfKeyList:\r
587 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
588 if Match:\r
589 if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'):\r
590 ConfigDict[Key.lower()] += Match.group(1)[1:]\r
591 else:\r
592 ConfigDict[Key.lower()] = Match.group(1)\r
593 else:\r
594 for Key in self._HdrKeyList:\r
595 Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
596 if Match:\r
597 ConfigDict[Key.lower()] = Match.group(1)\r
598\r
599 Match = re.match("^\s*#\s+@Prompt\s+(.+)", DscLine)\r
600 if Match:\r
601 ConfigDict['name'] = Match.group(1)\r
602\r
603 Match = re.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine)\r
604 if Match:\r
605 if Match.group(2).strip() in self._BuidinOption:\r
606 ConfigDict['option'] = Match.group(2).strip()\r
607 else:\r
608 OptionValueList = Match.group(2).split(',')\r
609 OptionStringList = Match.group(3).split(',')\r
610 Index = 0\r
611 for Option in OptionValueList:\r
612 Option = Option.strip()\r
613 ConfigDict['option'] = ConfigDict['option'] + str(Option) + ':' + OptionStringList[Index].strip()\r
614 Index += 1\r
615 if Index in range(len(OptionValueList)):\r
616 ConfigDict['option'] += ', '\r
617 ConfigDict['type'] = "Combo"\r
618\r
619 Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine)\r
620 if Match:\r
621 if "0x" in Match.group(2) or "0x" in Match.group(3):\r
622 ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))\r
623 else:\r
624 ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))\r
625\r
626 Match = re.match("^\s*##\s+(.+)", DscLine)\r
627 if Match:\r
628 ConfigDict['help'] = Match.group(1)\r
629\r
630 # Check VPD/UPD\r
631 if IsUpdSect:\r
1d7eed41 632 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
633 else:\r
634 Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine)\r
635 if Match:\r
636 ConfigDict['space'] = Match.group(1)\r
637 ConfigDict['cname'] = Match.group(2)\r
1d7eed41
CC
638 if Match.group(3) != '*':\r
639 Hardcode = True\r
640 Offset = int (Match.group(3), 16)\r
641 else:\r
642 AutoAlign = True\r
643\r
644 if Hardcode and AutoAlign:\r
645 print("Hardcode and auto-align mixed mode is not supported by GenCfgOpt")\r
646 raise SystemExit\r
647 ConfigDict['offset'] = Offset\r
cf1d4549
JY
648 if ConfigDict['order'] == -1:\r
649 ConfigDict['order'] = ConfigDict['offset'] << 8\r
650 else:\r
651 (Major, Minor) = ConfigDict['order'].split('.')\r
652 ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16)\r
653 if IsUpdSect:\r
654 Value = Match.group(5).strip()\r
655 if Match.group(4).startswith("0x"):\r
656 Length = int (Match.group(4), 16)\r
657 else :\r
658 Length = int (Match.group(4))\r
1d7eed41 659 Offset += Length\r
cf1d4549
JY
660 else:\r
661 Value = Match.group(4)\r
662 if Value is None:\r
663 Value = ''\r
664 Value = Value.strip()\r
665 if '|' in Value:\r
666 Match = re.match("^.+\s*\|\s*(.+)", Value)\r
667 if Match:\r
668 Value = Match.group(1)\r
669 Length = -1\r
670\r
671 ConfigDict['length'] = Length\r
672 Match = re.match("\$\((\w+)\)", Value)\r
673 if Match:\r
674 if Match.group(1) in self._MacroDict:\r
675 Value = self._MacroDict[Match.group(1)]\r
676\r
677 ConfigDict['value'] = Value\r
678 if (len(Value) > 0) and (Value[0] == '{'):\r
679 Value = self.FormatListValue(ConfigDict)\r
680\r
681 if ConfigDict['name'] == '':\r
682 # Clear BSF specific items\r
683 ConfigDict['bsfname'] = ''\r
684 ConfigDict['help'] = ''\r
685 ConfigDict['type'] = ''\r
686 ConfigDict['option'] = ''\r
1d7eed41
CC
687 if IsUpdSect and AutoAlign:\r
688 ItemLength = int(ConfigDict['length'])\r
689 ItemOffset = int(ConfigDict['offset'])\r
690 ItemStruct = ConfigDict['struct']\r
691 Unit = 1\r
692 if ItemLength in [1, 2, 4, 8] and not ConfigDict['value'].startswith('{'):\r
693 Unit = ItemLength\r
694 # If there are 64 bit unit, align to 64\r
695 if Unit == 8:\r
696 MaxAlign = 64\r
697 SizeAlign = 8\r
698 if ItemStruct != '':\r
699 UnitDict = {'UINT8':1, 'UINT16':2, 'UINT32':4, 'UINT64':8}\r
700 if ItemStruct in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:\r
701 Unit = UnitDict[ItemStruct]\r
702 # If there are 64 bit unit, align to 64\r
703 if Unit == 8:\r
704 MaxAlign = 64\r
705 SizeAlign = max(SizeAlign, Unit)\r
706 if (ConfigDict['embed'].find(':START') != -1):\r
707 Base = ItemOffset\r
708 SubOffset = ItemOffset - Base\r
709 SubRemainder = SubOffset % Unit\r
710 if SubRemainder:\r
711 Diff = Unit - SubRemainder\r
712 Offset = Offset + Diff\r
713 ItemOffset = ItemOffset + Diff\r
714\r
715 if (ConfigDict['embed'].find(':END') != -1):\r
716 Remainder = Offset % (MaxAlign/8) # MaxAlign is either 32 or 64\r
717 if Remainder:\r
718 Diff = (MaxAlign/8) - Remainder\r
719 Offset = Offset + Diff\r
720 ItemOffset = ItemOffset + Diff\r
721 MaxAlign = 32 # Reset to default 32 align when struct end\r
722 if (ConfigDict['cname'] == 'UpdTerminator'):\r
723 # ItemLength is the size of UpdTerminator\r
724 # Itemlength might be 16, 32, or 64\r
725 # Struct align to 64 if UpdTerminator\r
726 # or struct size is 64 bit, else align to 32\r
727 Remainder = Offset % max(ItemLength/8, 4, SizeAlign)\r
728 Offset = Offset + ItemLength\r
729 if Remainder:\r
730 Diff = max(ItemLength/8, 4, SizeAlign) - Remainder\r
731 ItemOffset = ItemOffset + Diff\r
732 ConfigDict['offset'] = ItemOffset\r
cf1d4549
JY
733\r
734 self._CfgItemList.append(ConfigDict.copy())\r
735 ConfigDict['name'] = ''\r
736 ConfigDict['find'] = ''\r
737 ConfigDict['struct'] = ''\r
738 ConfigDict['embed'] = ''\r
739 ConfigDict['comment'] = ''\r
740 ConfigDict['order'] = -1\r
741 ConfigDict['subreg'] = []\r
742 ConfigDict['option'] = ''\r
743 else:\r
744 # It could be a virtual item as below\r
62997d5e 745 # !BSF FIELD:{SerialDebugPortAddress0:1}\r
cf1d4549 746 # or\r
62997d5e
MM
747 # @Bsf FIELD:{SerialDebugPortAddress0:1b}\r
748 Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine)\r
cf1d4549 749 if Match:\r
62997d5e
MM
750 SubCfgDict = ConfigDict.copy()\r
751 if (Match.group(4) == None) or (Match.group(4) == 'B'):\r
752 UnitBitLen = 8\r
753 elif Match.group(4) == 'b':\r
754 UnitBitLen = 1\r
755 else:\r
756 print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine)\r
757 raise SystemExit\r
cf1d4549 758 SubCfgDict['cname'] = Match.group(2)\r
62997d5e
MM
759 SubCfgDict['bitlength'] = int (Match.group(3)) * UnitBitLen\r
760 if SubCfgDict['bitlength'] > 0:\r
cf1d4549
JY
761 LastItem = self._CfgItemList[-1]\r
762 if len(LastItem['subreg']) == 0:\r
763 SubOffset = 0\r
764 else:\r
62997d5e
MM
765 SubOffset = LastItem['subreg'][-1]['bitoffset'] + LastItem['subreg'][-1]['bitlength']\r
766 SubCfgDict['bitoffset'] = SubOffset\r
cf1d4549
JY
767 LastItem['subreg'].append (SubCfgDict.copy())\r
768 ConfigDict['name'] = ''\r
769 return Error\r
770\r
62997d5e
MM
771 def GetBsfBitFields (self, subitem, bytes):\r
772 start = subitem['bitoffset']\r
773 end = start + subitem['bitlength']\r
774 bitsvalue = ''.join('{0:08b}'.format(i) for i in bytes[::-1])\r
775 bitsvalue = bitsvalue[::-1]\r
776 bitslen = len(bitsvalue)\r
777 if start > bitslen or end > bitslen:\r
c3f0829b 778 print ("Invalid bits offset [%d,%d] for %s" % (start, end, subitem['name']))\r
62997d5e
MM
779 raise SystemExit\r
780 return hex(int(bitsvalue[start:end][::-1], 2))\r
781\r
cf1d4549
JY
782 def UpdateSubRegionDefaultValue (self):\r
783 Error = 0\r
784 for Item in self._CfgItemList:\r
785 if len(Item['subreg']) == 0:\r
786 continue\r
787 bytearray = []\r
788 if Item['value'][0] == '{':\r
789 binlist = Item['value'][1:-1].split(',')\r
790 for each in binlist:\r
791 each = each.strip()\r
792 if each.startswith('0x'):\r
793 value = int(each, 16)\r
794 else:\r
795 value = int(each)\r
796 bytearray.append(value)\r
797 else:\r
798 if Item['value'].startswith('0x'):\r
799 value = int(Item['value'], 16)\r
800 else:\r
801 value = int(Item['value'])\r
62997d5e 802 idx = 0\r
cf1d4549
JY
803 while idx < Item['length']:\r
804 bytearray.append(value & 0xFF)\r
805 value = value >> 8\r
806 idx = idx + 1\r
807 for SubItem in Item['subreg']:\r
62997d5e
MM
808 valuestr = self.GetBsfBitFields(SubItem, bytearray)\r
809 SubItem['value'] = valuestr\r
cf1d4549
JY
810 return Error\r
811\r
812 def CreateSplitUpdTxt (self, UpdTxtFile):\r
813 GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']\r
814 SignatureList = ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS\r
815 for Index in range(len(GuidList)):\r
816 UpdTxtFile = ''\r
817 FvDir = self._FvDir\r
818 if GuidList[Index] not in self._MacroDict:\r
819 self.Error = "%s definition is missing in DSC file" % (GuidList[Index])\r
820 return 1\r
821\r
822 if UpdTxtFile == '':\r
823 UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.txt')\r
824\r
825 ReCreate = False\r
826 if not os.path.exists(UpdTxtFile):\r
827 ReCreate = True\r
828 else:\r
829 DscTime = os.path.getmtime(self._DscFile)\r
830 TxtTime = os.path.getmtime(UpdTxtFile)\r
831 if DscTime > TxtTime:\r
832 ReCreate = True\r
833\r
834 if not ReCreate:\r
835 # DSC has not been modified yet\r
836 # So don't have to re-generate other files\r
837 self.Error = 'No DSC file change, skip to create UPD TXT file'\r
838 return 256\r
839\r
840 TxtFd = open(UpdTxtFile, "w")\r
841 TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year))\r
842\r
843 NextOffset = 0\r
844 SpaceIdx = 0\r
845 StartAddr = 0\r
846 EndAddr = 0\r
847 Default = 'DEFAULT|'\r
848 InRange = False\r
849 for Item in self._CfgItemList:\r
850 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
851 StartAddr = Item['offset']\r
852 NextOffset = StartAddr\r
853 InRange = True\r
854 if Item['cname'] == 'UpdTerminator' and InRange == True:\r
855 EndAddr = Item['offset']\r
856 InRange = False\r
857 InRange = False\r
858 for Item in self._CfgItemList:\r
859 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
860 InRange = True\r
861 if InRange != True:\r
862 continue\r
863 if Item['cname'] == 'UpdTerminator':\r
864 InRange = False\r
865 if Item['region'] != 'UPD':\r
866 continue\r
867 Offset = Item['offset']\r
868 if StartAddr > Offset or EndAddr < Offset:\r
869 continue\r
870 if NextOffset < Offset:\r
871 # insert one line\r
872 TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset - StartAddr, Offset - NextOffset))\r
873 SpaceIdx = SpaceIdx + 1\r
874 NextOffset = Offset + Item['length']\r
cf1d4549
JY
875 TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'] - StartAddr,Item['length'],Item['value']))\r
876 TxtFd.close()\r
877 return 0\r
878\r
879 def ProcessMultilines (self, String, MaxCharLength):\r
880 Multilines = ''\r
881 StringLength = len(String)\r
882 CurrentStringStart = 0\r
883 StringOffset = 0\r
884 BreakLineDict = []\r
885 if len(String) <= MaxCharLength:\r
886 while (StringOffset < StringLength):\r
887 if StringOffset >= 1:\r
888 if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
889 BreakLineDict.append (StringOffset + 1)\r
890 StringOffset += 1\r
891 if BreakLineDict != []:\r
892 for Each in BreakLineDict:\r
893 Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()\r
894 CurrentStringStart = Each\r
895 if StringLength - CurrentStringStart > 0:\r
896 Multilines += " %s\n" % String[CurrentStringStart:].lstrip()\r
897 else:\r
898 Multilines = " %s\n" % String\r
899 else:\r
900 NewLineStart = 0\r
901 NewLineCount = 0\r
902 FoundSpaceChar = False\r
903 while (StringOffset < StringLength):\r
904 if StringOffset >= 1:\r
905 if NewLineCount >= MaxCharLength - 1:\r
906 if String[StringOffset] == ' ' and StringLength - StringOffset > 10:\r
907 BreakLineDict.append (NewLineStart + NewLineCount)\r
908 NewLineStart = NewLineStart + NewLineCount\r
909 NewLineCount = 0\r
910 FoundSpaceChar = True\r
911 elif StringOffset == StringLength - 1 and FoundSpaceChar == False:\r
912 BreakLineDict.append (0)\r
913 if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
914 BreakLineDict.append (StringOffset + 1)\r
915 NewLineStart = StringOffset + 1\r
916 NewLineCount = 0\r
917 StringOffset += 1\r
918 NewLineCount += 1\r
919 if BreakLineDict != []:\r
920 BreakLineDict.sort ()\r
921 for Each in BreakLineDict:\r
922 if Each > 0:\r
923 Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()\r
924 CurrentStringStart = Each\r
925 if StringLength - CurrentStringStart > 0:\r
926 Multilines += " %s\n" % String[CurrentStringStart:].lstrip()\r
927 return Multilines\r
928\r
929 def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option):\r
930 PosName = 28\r
931 PosComment = 30\r
932 NameLine=''\r
933 HelpLine=''\r
934 OptionLine=''\r
935\r
936 IsArray = False\r
937 if Length in [1,2,4,8]:\r
938 Type = "UINT%d" % (Length * 8)\r
cd3692b1
SY
939 if Name.startswith("UnusedUpdSpace") and Length != 1:\r
940 IsArray = True\r
941 Type = "UINT8"\r
cf1d4549
JY
942 else:\r
943 IsArray = True\r
944 Type = "UINT8"\r
945\r
946 if Item and Item['value'].startswith('{'):\r
947 Type = "UINT8"\r
948 IsArray = True\r
949\r
950 if Struct != '':\r
951 Type = Struct\r
952 if Struct in ['UINT8','UINT16','UINT32','UINT64']:\r
953 IsArray = True\r
954 Unit = int(Type[4:]) / 8\r
955 Length = Length / Unit\r
956 else:\r
957 IsArray = False\r
958\r
959 if IsArray:\r
960 Name = Name + '[%d]' % Length\r
961\r
962 if len(Type) < PosName:\r
963 Space1 = PosName - len(Type)\r
964 else:\r
965 Space1 = 1\r
966\r
967 if BsfName != '':\r
968 NameLine=" - %s\n" % BsfName\r
969 else:\r
970 NameLine="\n"\r
971\r
972 if Help != '':\r
973 HelpLine = self.ProcessMultilines (Help, 80)\r
974\r
975 if Option != '':\r
976 OptionLine = self.ProcessMultilines (Option, 80)\r
977\r
978 if Offset is None:\r
979 OffsetStr = '????'\r
980 else:\r
981 OffsetStr = '0x%04X' % Offset\r
982\r
983 return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)\r
984\r
985 def PostProcessBody (self, TextBody):\r
986 NewTextBody = []\r
987 OldTextBody = []\r
988 IncludeLine = False\r
989 StructName = ''\r
990 VariableName = ''\r
991 IsUpdHdrDefined = False\r
992 IsUpdHeader = False\r
993 for Line in TextBody:\r
994 SplitToLines = Line.splitlines()\r
995 MatchComment = re.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines[0])\r
996 if MatchComment:\r
997 if MatchComment.group(1) == 'FSP_UPD_HEADER':\r
998 IsUpdHeader = True\r
999 else:\r
1000 IsUpdHeader = False\r
1001 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1002 CommentLine = " " + MatchComment.group(2) + "\n"\r
1003 NewTextBody.append("/**" + CommentLine + "**/\n")\r
1004 Line = Line[(len(SplitToLines[0]) + 1):]\r
1005\r
1006 Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)\r
1007 if Match:\r
1008 Line = Match.group(4)\r
1009 if Match.group(1) == 'FSP_UPD_HEADER':\r
1010 IsUpdHeader = True\r
1011 else:\r
1012 IsUpdHeader = False\r
1013\r
1014 if Match and Match.group(3) == 'START':\r
1015 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1016 NewTextBody.append ('typedef struct {\n')\r
1017 StructName = Match.group(1)\r
1018 VariableName = Match.group(2)\r
1019 MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)\r
1020 if MatchOffset:\r
1021 Offset = int(MatchOffset.group(1), 16)\r
1022 else:\r
1023 Offset = None\r
1024 Line\r
1025 IncludeLine = True\r
1026 OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', '', ''))\r
1027 if IncludeLine:\r
1028 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1029 NewTextBody.append (Line)\r
1030 else:\r
1031 OldTextBody.append (Line)\r
1032\r
62997d5e 1033 if Match and Match.group(3) == 'END':\r
cf1d4549 1034 if (StructName != Match.group(1)) or (VariableName != Match.group(2)):\r
c3f0829b 1035 print ("Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1)))\r
cf1d4549
JY
1036 else:\r
1037 if IsUpdHdrDefined != True or IsUpdHeader != True:\r
1038 NewTextBody.append ('} %s;\n\n' % StructName)\r
1039 IsUpdHdrDefined = True\r
1040 IncludeLine = False\r
1041 NewTextBody.extend(OldTextBody)\r
1042 return NewTextBody\r
1043\r
d75c07bc
CC
1044 def WriteLinesWithoutTailingSpace (self, HeaderFd, Line):\r
1045 TxtBody2 = Line.splitlines(True)\r
1046 for Line2 in TxtBody2:\r
1047 Line2 = Line2.rstrip()\r
1048 Line2 += '\n'\r
1049 HeaderFd.write (Line2)\r
1050 return 0\r
cf1d4549
JY
1051 def CreateHeaderFile (self, InputHeaderFile):\r
1052 FvDir = self._FvDir\r
1053\r
1054 HeaderFileName = 'FspUpd.h'\r
1055 HeaderFile = os.path.join(FvDir, HeaderFileName)\r
1056\r
1057 # Check if header needs to be recreated\r
1058 ReCreate = False\r
1059\r
1060 TxtBody = []\r
1061 for Item in self._CfgItemList:\r
1062 if str(Item['cname']) == 'Signature' and Item['length'] == 8:\r
1063 Value = int(Item['value'], 16)\r
1064 Chars = []\r
1065 while Value != 0x0:\r
1066 Chars.append(chr(Value & 0xFF))\r
1067 Value = Value >> 8\r
1068 SignatureStr = ''.join(Chars)\r
1069 # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly\r
1070 if '_T' in SignatureStr[6:6+2]:\r
1071 TxtBody.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1072 elif '_M' in SignatureStr[6:6+2]:\r
1073 TxtBody.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1074 elif '_S' in SignatureStr[6:6+2]:\r
1075 TxtBody.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
1076 TxtBody.append("\n")\r
1077\r
1078 for Region in ['UPD']:\r
1079 UpdOffsetTable = []\r
1080 UpdSignature = ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS\r
1081 UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']\r
1082 for Item in self._CfgItemList:\r
1083 if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:\r
1084 UpdOffsetTable.append (Item["offset"])\r
1085\r
1086 for UpdIdx in range(len(UpdOffsetTable)):\r
1087 CommentLine = ""\r
1088 for Item in self._CfgItemList:\r
1089 if Item["comment"] != '' and Item["offset"] >= UpdOffsetTable[UpdIdx]:\r
1090 MatchComment = re.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item["comment"])\r
1091 if MatchComment and MatchComment.group(1) == Region[0]:\r
1092 CommentLine = " " + MatchComment.group(2) + "\n"\r
1093 TxtBody.append("/**" + CommentLine + "**/\n")\r
1094 elif Item["offset"] >= UpdOffsetTable[UpdIdx] and Item["comment"] == '':\r
1095 Match = re.match("^FSP([\w|\W|\s])_UPD", UpdStructure[UpdIdx])\r
1096 if Match:\r
1097 TxtBody.append("/** Fsp " + Match.group(1) + " UPD Configuration\n**/\n")\r
1098 TxtBody.append("typedef struct {\n")\r
1099 NextOffset = 0\r
1100 SpaceIdx = 0\r
1101 Offset = 0\r
1102\r
1103 LastVisible = True\r
1104 ResvOffset = 0\r
1105 ResvIdx = 0\r
1106 LineBuffer = []\r
1107 InRange = False\r
1108 for Item in self._CfgItemList:\r
1109 if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == UpdSignature[UpdIdx] or Region[0] == 'V':\r
1110 InRange = True\r
1111 if InRange != True:\r
1112 continue\r
1113 if Item['cname'] == 'UpdTerminator':\r
1114 InRange = False\r
1115\r
1116 if Item['region'] != Region:\r
1117 continue\r
1118\r
1119 if Item["offset"] < UpdOffsetTable[UpdIdx]:\r
1120 continue\r
1121\r
1122 NextVisible = LastVisible\r
1123\r
1124 if LastVisible and (Item['header'] == 'OFF'):\r
1125 NextVisible = False\r
1126 ResvOffset = Item['offset']\r
1127 elif (not LastVisible) and Item['header'] == 'ON':\r
1128 NextVisible = True\r
1129 Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx\r
1130 ResvIdx = ResvIdx + 1\r
1131 TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', '', ''))\r
1132\r
1133 if Offset < Item["offset"]:\r
1134 if LastVisible:\r
1135 Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx\r
1136 LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', '', ''))\r
1137 SpaceIdx = SpaceIdx + 1\r
1138 Offset = Item["offset"]\r
1139\r
1140 LastVisible = NextVisible\r
1141\r
1142 Offset = Offset + Item["length"]\r
1143 if LastVisible:\r
1144 for Each in LineBuffer:\r
1145 TxtBody.append (Each)\r
1146 LineBuffer = []\r
1147 Comment = Item["comment"]\r
1148 Embed = Item["embed"].upper()\r
1149 if Embed.endswith(':START') or Embed.endswith(':END'):\r
1150 if not Comment == '' and Embed.endswith(':START'):\r
1151 Marker = '/* COMMENT:%s */ \n' % Item["comment"]\r
1152 Marker = Marker + '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
1153 else:\r
1154 Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
1155 else:\r
1156 if Embed == '':\r
62997d5e 1157 Marker = ''\r
cf1d4549
JY
1158 else:\r
1159 self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]\r
1160 return 4\r
1161 Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'], Item['option'])\r
1162 TxtBody.append(Line)\r
1163 if Item['cname'] == 'UpdTerminator':\r
1164 break\r
1165 TxtBody.append("} " + UpdStructure[UpdIdx] + ";\n\n")\r
62997d5e 1166\r
cf1d4549
JY
1167 # Handle the embedded data structure\r
1168 TxtBody = self.PostProcessBody (TxtBody)\r
1169\r
1170 HeaderTFileName = 'FsptUpd.h'\r
1171 HeaderMFileName = 'FspmUpd.h'\r
1172 HeaderSFileName = 'FspsUpd.h'\r
1173\r
1174 UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION\r
1175 UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG\r
1176 UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']\r
1177 ExcludedSpecificUpd = 'FSPM_ARCH_UPD'\r
1178\r
1179 if InputHeaderFile != '':\r
1180 if not os.path.exists(InputHeaderFile):\r
1181 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
1182 return 6\r
1183\r
1184 InFd = open(InputHeaderFile, "r")\r
1185 IncLines = InFd.readlines()\r
1186 InFd.close()\r
1187\r
1188 for item in range(len(UpdRegionCheck)):\r
1189 if UpdRegionCheck[item] == 'FSPT':\r
1190 HeaderFd = open(os.path.join(FvDir, HeaderTFileName), "w")\r
1191 FileBase = os.path.basename(os.path.join(FvDir, HeaderTFileName))\r
1192 elif UpdRegionCheck[item] == 'FSPM':\r
1193 HeaderFd = open(os.path.join(FvDir, HeaderMFileName), "w")\r
1194 FileBase = os.path.basename(os.path.join(FvDir, HeaderMFileName))\r
1195 elif UpdRegionCheck[item] == 'FSPS':\r
1196 HeaderFd = open(os.path.join(FvDir, HeaderSFileName), "w")\r
1197 FileBase = os.path.basename(os.path.join(FvDir, HeaderSFileName))\r
1198 FileName = FileBase.replace(".", "_").upper()\r
1199 HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))\r
1200 HeaderFd.write("#ifndef __%s__\n" % FileName)\r
1201 HeaderFd.write("#define __%s__\n\n" % FileName)\r
1202 HeaderFd.write("#include <%s>\n\n" % HeaderFileName)\r
cd3692b1 1203 HeaderFd.write("#pragma pack(1)\n\n")\r
cf1d4549
JY
1204\r
1205 Export = False\r
1206 for Line in IncLines:\r
1207 Match = re.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
1208 if Match:\r
1209 if Match.group(2) == "BEGIN" and Match.group(1) == UpdRegionCheck[item]:\r
1210 Export = True\r
1211 continue\r
1212 else:\r
1213 Export = False\r
1214 continue\r
1215 if Export:\r
1216 HeaderFd.write(Line)\r
1217 HeaderFd.write("\n")\r
1218\r
1219 Index = 0\r
1220 StartIndex = 0\r
1221 EndIndex = 0\r
1222 StructStart = []\r
1223 StructStartWithComment = []\r
1224 StructEnd = []\r
1225 for Line in TxtBody:\r
1226 Index += 1\r
1227 Match = re.match("(typedef struct {)", Line)\r
1228 if Match:\r
1229 StartIndex = Index - 1\r
1230 Match = re.match("}\s([_A-Z0-9]+);", Line)\r
1231 if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd not in Match.group(1)):\r
1232 EndIndex = Index\r
1233 StructStart.append(StartIndex)\r
1234 StructEnd.append(EndIndex)\r
1235 Index = 0\r
1236 for Line in TxtBody:\r
1237 Index += 1\r
1238 for Item in range(len(StructStart)):\r
1239 if Index == StructStart[Item]:\r
1240 Match = re.match("^(/\*\*\s*)", Line)\r
1241 if Match:\r
1242 StructStartWithComment.append(StructStart[Item])\r
1243 else:\r
1244 StructStartWithComment.append(StructStart[Item] + 1)\r
1245 Index = 0\r
1246 for Line in TxtBody:\r
1247 Index += 1\r
1248 for Item in range(len(StructStart)):\r
1249 if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
d75c07bc 1250 self.WriteLinesWithoutTailingSpace(HeaderFd, Line)\r
cd3692b1 1251 HeaderFd.write("#pragma pack()\n\n")\r
cf1d4549
JY
1252 HeaderFd.write("#endif\n")\r
1253 HeaderFd.close()\r
1254\r
1255 HeaderFd = open(HeaderFile, "w")\r
1256 FileBase = os.path.basename(HeaderFile)\r
1257 FileName = FileBase.replace(".", "_").upper()\r
1258 HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))\r
1259 HeaderFd.write("#ifndef __%s__\n" % FileName)\r
1260 HeaderFd.write("#define __%s__\n\n" % FileName)\r
1261 HeaderFd.write("#include <FspEas.h>\n\n")\r
cd3692b1 1262 HeaderFd.write("#pragma pack(1)\n\n")\r
cf1d4549
JY
1263\r
1264 for item in range(len(UpdRegionCheck)):\r
1265 Index = 0\r
1266 StartIndex = 0\r
1267 EndIndex = 0\r
1268 StructStart = []\r
1269 StructStartWithComment = []\r
1270 StructEnd = []\r
1271 for Line in TxtBody:\r
1272 Index += 1\r
1273 Match = re.match("(typedef struct {)", Line)\r
1274 if Match:\r
1275 StartIndex = Index - 1\r
1276 Match = re.match("#define\s([_A-Z0-9]+)\s*", Line)\r
1277 if Match and (UpdSignatureCheck[item] in Match.group(1) or UpdSignatureCheck[item] in Match.group(1)):\r
1278 StructStart.append(Index - 1)\r
1279 StructEnd.append(Index)\r
1280 Index = 0\r
1281 for Line in TxtBody:\r
1282 Index += 1\r
1283 for Item in range(len(StructStart)):\r
1284 if Index == StructStart[Item]:\r
1285 Match = re.match("^(/\*\*\s*)", Line)\r
1286 if Match:\r
1287 StructStartWithComment.append(StructStart[Item])\r
1288 else:\r
1289 StructStartWithComment.append(StructStart[Item] + 1)\r
1290 Index = 0\r
1291 for Line in TxtBody:\r
1292 Index += 1\r
1293 for Item in range(len(StructStart)):\r
1294 if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
d75c07bc 1295 self.WriteLinesWithoutTailingSpace(HeaderFd, Line)\r
cd3692b1 1296 HeaderFd.write("#pragma pack()\n\n")\r
cf1d4549
JY
1297 HeaderFd.write("#endif\n")\r
1298 HeaderFd.close()\r
1299\r
1300 return 0\r
1301\r
1302 def WriteBsfStruct (self, BsfFd, Item):\r
ba8ea427 1303 LogExpr = CLogicalExpression()\r
cf1d4549
JY
1304 if Item['type'] == "None":\r
1305 Space = "gPlatformFspPkgTokenSpaceGuid"\r
1306 else:\r
1307 Space = Item['space']\r
1308 Line = " $%s_%s" % (Space, Item['cname'])\r
1309 Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])\r
1310 if Match:\r
1311 DefaultValue = Match.group(1).strip()\r
1312 else:\r
1313 DefaultValue = Item['value'].strip()\r
62997d5e
MM
1314 if 'bitlength' in Item:\r
1315 BsfFd.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['bitlength'], DefaultValue))\r
1316 else:\r
1317 BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))\r
cf1d4549
JY
1318 TmpList = []\r
1319 if Item['type'] == "Combo":\r
1320 if not Item['option'] in self._BuidinOption:\r
1321 OptList = Item['option'].split(',')\r
1322 for Option in OptList:\r
1323 Option = Option.strip()\r
1324 (OpVal, OpStr) = Option.split(':')\r
ba8ea427
TRM
1325 test = LogExpr.getNumber (OpVal)\r
1326 if test is None:\r
1327 raise Exception("Selection Index '%s' is not a number" % OpVal)\r
cf1d4549
JY
1328 TmpList.append((OpVal, OpStr))\r
1329 return TmpList\r
1330\r
1331 def WriteBsfOption (self, BsfFd, Item):\r
1332 PcdName = Item['space'] + '_' + Item['cname']\r
1333 WriteHelp = 0\r
1334 if Item['type'] == "Combo":\r
1335 if Item['option'] in self._BuidinOption:\r
1336 Options = self._BuidinOption[Item['option']]\r
1337 else:\r
1338 Options = PcdName\r
62997d5e 1339 BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options))\r
cf1d4549
JY
1340 WriteHelp = 1\r
1341 elif Item['type'].startswith("EditNum"):\r
1342 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
1343 if Match:\r
62997d5e 1344 BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)))\r
cf1d4549
JY
1345 WriteHelp = 2\r
1346 elif Item['type'].startswith("EditText"):\r
62997d5e 1347 BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']))\r
cf1d4549
JY
1348 WriteHelp = 1\r
1349 elif Item['type'] == "Table":\r
1350 Columns = Item['option'].split(',')\r
1351 if len(Columns) != 0:\r
62997d5e 1352 BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name']))\r
cf1d4549
JY
1353 for Col in Columns:\r
1354 Fmt = Col.split(':')\r
1355 if len(Fmt) != 3:\r
1356 raise Exception("Column format '%s' is invalid !" % Fmt)\r
1357 try:\r
1358 Dtype = int(Fmt[1].strip())\r
1359 except:\r
1360 raise Exception("Column size '%s' is invalid !" % Fmt[1])\r
1361 BsfFd.write('\n Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))\r
1362 BsfFd.write(',\n')\r
1363 WriteHelp = 1\r
62997d5e 1364\r
cf1d4549
JY
1365 if WriteHelp > 0:\r
1366 HelpLines = Item['help'].split('\\n\\r')\r
1367 FirstLine = True\r
1368 for HelpLine in HelpLines:\r
1369 if FirstLine:\r
1370 FirstLine = False\r
62997d5e 1371 BsfFd.write(' Help "%s"\n' % (HelpLine))\r
cf1d4549 1372 else:\r
62997d5e 1373 BsfFd.write(' "%s"\n' % (HelpLine))\r
cf1d4549 1374 if WriteHelp == 2:\r
62997d5e 1375 BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)))\r
cf1d4549
JY
1376\r
1377 def GenerateBsfFile (self, BsfFile):\r
1378\r
1379 if BsfFile == '':\r
1380 self.Error = "BSF output file '%s' is invalid" % BsfFile\r
1381 return 1\r
1382\r
1383 Error = 0\r
1384 OptionDict = {}\r
1385 BsfFd = open(BsfFile, "w")\r
1386 BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))\r
62997d5e 1387 BsfFd.write("%s\n" % self._GlobalDataDef)\r
cf1d4549
JY
1388 BsfFd.write("StructDef\n")\r
1389 NextOffset = -1\r
1390 for Item in self._CfgItemList:\r
1391 if Item['find'] != '':\r
1392 BsfFd.write('\n Find "%s"\n' % Item['find'])\r
1393 NextOffset = Item['offset'] + Item['length']\r
1394 if Item['name'] != '':\r
1395 if NextOffset != Item['offset']:\r
1396 BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))\r
1397 if len(Item['subreg']) > 0:\r
1398 NextOffset = Item['offset']\r
62997d5e 1399 BitsOffset = NextOffset * 8\r
cf1d4549 1400 for SubItem in Item['subreg']:\r
62997d5e 1401 BitsOffset += SubItem['bitlength']\r
cf1d4549 1402 if SubItem['name'] == '':\r
62997d5e
MM
1403 if 'bitlength' in SubItem:\r
1404 BsfFd.write(" Skip %d bits\n" % (SubItem['bitlength']))\r
1405 else:\r
1406 BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))\r
cf1d4549
JY
1407 else:\r
1408 Options = self.WriteBsfStruct(BsfFd, SubItem)\r
1409 if len(Options) > 0:\r
1410 OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options\r
62997d5e
MM
1411\r
1412 NextBitsOffset = (Item['offset'] + Item['length']) * 8\r
1413 if NextBitsOffset > BitsOffset:\r
1414 BitsGap = NextBitsOffset - BitsOffset\r
1415 BitsRemain = BitsGap % 8\r
1416 if BitsRemain:\r
1417 BsfFd.write(" Skip %d bits\n" % BitsRemain)\r
1418 BitsGap -= BitsRemain\r
1419 BytesRemain = BitsGap / 8\r
1420 if BytesRemain:\r
1421 BsfFd.write(" Skip %d bytes\n" % BytesRemain)\r
1422 NextOffset = Item['offset'] + Item['length']\r
cf1d4549
JY
1423 else:\r
1424 NextOffset = Item['offset'] + Item['length']\r
1425 Options = self.WriteBsfStruct(BsfFd, Item)\r
1426 if len(Options) > 0:\r
1427 OptionDict[Item['space']+'_'+Item['cname']] = Options\r
1428 BsfFd.write("\nEndStruct\n\n")\r
1429\r
62997d5e 1430 BsfFd.write("%s" % self._BuidinOptionTxt)\r
cf1d4549
JY
1431\r
1432 for Each in OptionDict:\r
62997d5e 1433 BsfFd.write("List &%s\n" % Each)\r
cf1d4549 1434 for Item in OptionDict[Each]:\r
62997d5e
MM
1435 BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]))\r
1436 BsfFd.write("EndList\n\n")\r
cf1d4549 1437\r
62997d5e
MM
1438 BsfFd.write("BeginInfoBlock\n")\r
1439 BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']))\r
1440 BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']))\r
1441 BsfFd.write("EndInfoBlock\n\n")\r
cf1d4549
JY
1442\r
1443 for Each in self._CfgPageDict:\r
62997d5e 1444 BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each])\r
cf1d4549
JY
1445 BsfItems = []\r
1446 for Item in self._CfgItemList:\r
1447 if Item['name'] != '':\r
1448 if Item['page'] != Each:\r
1449 continue\r
1450 if len(Item['subreg']) > 0:\r
1451 for SubItem in Item['subreg']:\r
1452 if SubItem['name'] != '':\r
1453 BsfItems.append(SubItem)\r
1454 else:\r
1455 BsfItems.append(Item)\r
1456\r
1457 BsfItems.sort(key=lambda x: x['order'])\r
1458\r
1459 for Item in BsfItems:\r
1460 self.WriteBsfOption (BsfFd, Item)\r
62997d5e 1461 BsfFd.write("EndPage\n\n")\r
cf1d4549
JY
1462\r
1463 BsfFd.close()\r
1464 return Error\r
1465\r
1466\r
1467def Usage():\r
c3f0829b
CC
1468 print ("GenCfgOpt Version 0.54")\r
1469 print ("Usage:")\r
1470 print (" GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]")\r
1471 print (" GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]")\r
1472 print (" GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]")\r
cf1d4549
JY
1473\r
1474def Main():\r
1475 #\r
1476 # Parse the options and args\r
1477 #\r
b9c055f7
CC
1478 i = 1\r
1479\r
cf1d4549 1480 GenCfgOpt = CGenCfgOpt()\r
b9c055f7
CC
1481 while i < len(sys.argv):\r
1482 if sys.argv[i].strip().lower() == "--pcd":\r
1483 BuildOptionPcd.append(sys.argv[i+1])\r
1484 i += 1\r
1485 i += 1\r
cf1d4549
JY
1486 argc = len(sys.argv)\r
1487 if argc < 4:\r
1488 Usage()\r
1489 return 1\r
1490 else:\r
1491 DscFile = sys.argv[2]\r
1492 if not os.path.exists(DscFile):\r
c3f0829b 1493 print ("ERROR: Cannot open DSC file '%s' !" % DscFile)\r
cf1d4549 1494 return 2\r
cf1d4549
JY
1495\r
1496 OutFile = ''\r
1497 if argc > 4:\r
62997d5e 1498 if sys.argv[4][0] == '-':\r
cf1d4549
JY
1499 Start = 4\r
1500 else:\r
62997d5e 1501 OutFile = sys.argv[4]\r
cf1d4549 1502 Start = 5\r
e4408576
OBO
1503 if argc > Start:\r
1504 if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:\r
c3f0829b 1505 print ("ERROR: Macro parsing failed !")\r
e4408576 1506 return 3\r
cf1d4549
JY
1507\r
1508 FvDir = sys.argv[3]\r
1509 if not os.path.exists(FvDir):\r
1510 os.makedirs(FvDir)\r
1511\r
62997d5e 1512 if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:\r
c3f0829b 1513 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1514 return 5\r
1515\r
1516 if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:\r
c3f0829b 1517 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1518 return 7\r
1519\r
1520 if sys.argv[1] == "UPDTXT":\r
1521 Ret = GenCfgOpt.CreateSplitUpdTxt(OutFile)\r
1522 if Ret != 0:\r
1523 # No change is detected\r
1524 if Ret == 256:\r
c3f0829b 1525 print ("INFO: %s !" % (GenCfgOpt.Error))\r
cf1d4549 1526 else :\r
c3f0829b 1527 print ("ERROR: %s !" % (GenCfgOpt.Error))\r
cf1d4549
JY
1528 return Ret\r
1529 elif sys.argv[1] == "HEADER":\r
1530 if GenCfgOpt.CreateHeaderFile(OutFile) != 0:\r
c3f0829b 1531 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1532 return 8\r
1533 elif sys.argv[1] == "GENBSF":\r
1534 if GenCfgOpt.GenerateBsfFile(OutFile) != 0:\r
c3f0829b 1535 print ("ERROR: %s !" % GenCfgOpt.Error)\r
cf1d4549
JY
1536 return 9\r
1537 else:\r
1538 if argc < 5:\r
1539 Usage()\r
1540 return 1\r
c3f0829b 1541 print ("ERROR: Unknown command '%s' !" % sys.argv[1])\r
cf1d4549
JY
1542 Usage()\r
1543 return 1\r
1544 return 0\r
1545 return 0\r
1546\r
1547\r
1548if __name__ == '__main__':\r
1549 sys.exit(Main())\r