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