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