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