]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Tools/FspGenCfgData.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2Pkg / Tools / FspGenCfgData.py
1 # @ GenCfgData.py
2 #
3 # Copyright (c) 2014 - 2021, 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 marshal
12 from functools import reduce
13 from datetime import date
14
15 # Generated file copyright header
16
17 __copyright_tmp__ = """/** @file
18
19 Configuration %s File.
20
21 Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
22 SPDX-License-Identifier: BSD-2-Clause-Patent
23
24 This file is automatically generated. Please do NOT modify !!!
25
26 **/
27 """
28
29 __copyright_dsc__ = """## @file
30 #
31 # Copyright (c) %04d, Intel Corporation. All rights reserved.<BR>
32 # SPDX-License-Identifier: BSD-2-Clause-Patent
33 #
34 ##
35
36 [PcdsDynamicVpd.Upd]
37 #
38 # Global definitions in BSF
39 # !BSF BLOCK:{NAME:"FSP UPD Configuration", VER:"0.1"}
40 #
41
42 """
43
44
45 def Bytes2Val(Bytes):
46 return reduce(lambda x, y: (x << 8) | y, Bytes[::-1])
47
48
49 def Bytes2Str(Bytes):
50 return '{ %s }' % (', '.join('0x%02X' % i for i in Bytes))
51
52
53 def Str2Bytes(Value, Blen):
54 Result = bytearray(Value[1:-1], 'utf-8') # Excluding quotes
55 if len(Result) < Blen:
56 Result.extend(b'\x00' * (Blen - len(Result)))
57 return Result
58
59
60 def Val2Bytes(Value, Blen):
61 return [(Value >> (i * 8) & 0xff) for i in range(Blen)]
62
63
64 def Array2Val(ValStr):
65 ValStr = ValStr.strip()
66 if ValStr.startswith('{'):
67 ValStr = ValStr[1:]
68 if ValStr.endswith('}'):
69 ValStr = ValStr[:-1]
70 if ValStr.startswith("'"):
71 ValStr = ValStr[1:]
72 if ValStr.endswith("'"):
73 ValStr = ValStr[:-1]
74 Value = 0
75 for Each in ValStr.split(',')[::-1]:
76 Each = Each.strip()
77 if Each.startswith('0x'):
78 Base = 16
79 else:
80 Base = 10
81 Value = (Value << 8) | int(Each, Base)
82 return Value
83
84
85 def GetCopyrightHeader(FileType, AllowModify=False):
86 FileDescription = {
87 'bsf': 'Boot Setting',
88 'dsc': 'Definition',
89 'dlt': 'Delta',
90 'inc': 'C Binary Blob',
91 'h': 'C Struct Header'
92 }
93 if FileType in ['bsf', 'dsc', 'dlt']:
94 CommentChar = '#'
95 else:
96 CommentChar = ''
97 Lines = __copyright_tmp__.split('\n')
98
99 if AllowModify:
100 Lines = [Line for Line in Lines if 'Please do NOT modify' not in Line]
101
102 CopyrightHdr = '\n'.join('%s%s' % (
103 CommentChar, Line) for Line in Lines)[:-1] + '\n'
104
105 return CopyrightHdr % (FileDescription[FileType], date.today().year)
106
107
108 class CLogicalExpression:
109 def __init__(self):
110 self.index = 0
111 self.string = ''
112
113 def errExit(self, err=''):
114 print("ERROR: Express parsing for:")
115 print(" %s" % self.string)
116 print(" %s^" % (' ' * self.index))
117 if err:
118 print("INFO : %s" % err)
119 raise SystemExit
120
121 def getNonNumber(self, n1, n2):
122 if not n1.isdigit():
123 return n1
124 if not n2.isdigit():
125 return n2
126 return None
127
128 def getCurr(self, lens=1):
129 try:
130 if lens == -1:
131 return self.string[self.index:]
132 else:
133 if self.index + lens > len(self.string):
134 lens = len(self.string) - self.index
135 return self.string[self.index: self.index + lens]
136 except Exception:
137 return ''
138
139 def isLast(self):
140 return self.index == len(self.string)
141
142 def moveNext(self, len=1):
143 self.index += len
144
145 def skipSpace(self):
146 while not self.isLast():
147 if self.getCurr() in ' \t':
148 self.moveNext()
149 else:
150 return
151
152 def normNumber(self, val):
153 return True if val else False
154
155 def getNumber(self, var):
156 var = var.strip()
157 if re.match('^0x[a-fA-F0-9]+$', var):
158 value = int(var, 16)
159 elif re.match('^[+-]?\\d+$', var):
160 value = int(var, 10)
161 else:
162 value = None
163 return value
164
165 def parseValue(self):
166 self.skipSpace()
167 var = ''
168 while not self.isLast():
169 char = self.getCurr()
170 if re.match('^[\\w.]', char):
171 var += char
172 self.moveNext()
173 else:
174 break
175 val = self.getNumber(var)
176 if val is None:
177 value = var
178 else:
179 value = "%d" % val
180 return value
181
182 def parseSingleOp(self):
183 self.skipSpace()
184 if re.match('^NOT\\W', self.getCurr(-1)):
185 self.moveNext(3)
186 op = self.parseBrace()
187 val = self.getNumber(op)
188 if val is None:
189 self.errExit("'%s' is not a number" % op)
190 return "%d" % (not self.normNumber(int(op)))
191 else:
192 return self.parseValue()
193
194 def parseBrace(self):
195 self.skipSpace()
196 char = self.getCurr()
197 if char == '(':
198 self.moveNext()
199 value = self.parseExpr()
200 self.skipSpace()
201 if self.getCurr() != ')':
202 self.errExit("Expecting closing brace or operator")
203 self.moveNext()
204 return value
205 else:
206 value = self.parseSingleOp()
207 return value
208
209 def parseCompare(self):
210 value = self.parseBrace()
211 while True:
212 self.skipSpace()
213 char = self.getCurr()
214 if char in ['<', '>']:
215 self.moveNext()
216 next = self.getCurr()
217 if next == '=':
218 op = char + next
219 self.moveNext()
220 else:
221 op = char
222 result = self.parseBrace()
223 test = self.getNonNumber(result, value)
224 if test is None:
225 value = "%d" % self.normNumber(eval(value + op + result))
226 else:
227 self.errExit("'%s' is not a valid number for comparision"
228 % test)
229 elif char in ['=', '!']:
230 op = self.getCurr(2)
231 if op in ['==', '!=']:
232 self.moveNext(2)
233 result = self.parseBrace()
234 test = self.getNonNumber(result, value)
235 if test is None:
236 value = "%d" % self.normNumber((eval(value + op
237 + result)))
238 else:
239 value = "%d" % self.normNumber(eval("'" + value +
240 "'" + op + "'" +
241 result + "'"))
242 else:
243 break
244 else:
245 break
246 return value
247
248 def parseAnd(self):
249 value = self.parseCompare()
250 while True:
251 self.skipSpace()
252 if re.match('^AND\\W', self.getCurr(-1)):
253 self.moveNext(3)
254 result = self.parseCompare()
255 test = self.getNonNumber(result, value)
256 if test is None:
257 value = "%d" % self.normNumber(int(value) & int(result))
258 else:
259 self.errExit("'%s' is not a valid op number for AND" %
260 test)
261 else:
262 break
263 return value
264
265 def parseOrXor(self):
266 value = self.parseAnd()
267 op = None
268 while True:
269 self.skipSpace()
270 op = None
271 if re.match('^XOR\\W', self.getCurr(-1)):
272 self.moveNext(3)
273 op = '^'
274 elif re.match('^OR\\W', self.getCurr(-1)):
275 self.moveNext(2)
276 op = '|'
277 else:
278 break
279 if op:
280 result = self.parseAnd()
281 test = self.getNonNumber(result, value)
282 if test is None:
283 value = "%d" % self.normNumber(eval(value + op + result))
284 else:
285 self.errExit("'%s' is not a valid op number for XOR/OR" %
286 test)
287 return value
288
289 def parseExpr(self):
290 return self.parseOrXor()
291
292 def getResult(self):
293 value = self.parseExpr()
294 self.skipSpace()
295 if not self.isLast():
296 self.errExit("Unexpected character found '%s'" % self.getCurr())
297 test = self.getNumber(value)
298 if test is None:
299 self.errExit("Result '%s' is not a number" % value)
300 return int(value)
301
302 def evaluateExpress(self, Expr):
303 self.index = 0
304 self.string = Expr
305 if self.getResult():
306 Result = True
307 else:
308 Result = False
309 return Result
310
311
312 class CFspBsf2Dsc:
313
314 def __init__(self, bsf_file):
315 self.cfg_list = CFspBsf2Dsc.parse_bsf(bsf_file)
316
317 def get_dsc_lines(self):
318 return CFspBsf2Dsc.generate_dsc(self.cfg_list)
319
320 def save_dsc(self, dsc_file):
321 return CFspBsf2Dsc.generate_dsc(self.cfg_list, dsc_file)
322
323 @staticmethod
324 def parse_bsf(bsf_file):
325
326 fd = open(bsf_file, 'r')
327 bsf_txt = fd.read()
328 fd.close()
329
330 find_list = []
331 regex = re.compile(r'\s+Find\s+"(.*?)"(.*?)^\s+(\$(.*?)|Skip)\s+',
332 re.S | re.MULTILINE)
333 for match in regex.finditer(bsf_txt):
334 find = match.group(1)
335 name = match.group(3)
336 line = bsf_txt[:match.end()].count("\n")
337 find_list.append((name, find, line))
338
339 idx = 0
340 count = 0
341 prefix = ''
342 chk_dict = {}
343 cfg_list = []
344 cfg_temp = {'find': '', 'cname': '', 'length': 0, 'value': '0',
345 'type': 'Reserved', 'isbit': False,
346 'embed': '', 'page': '', 'option': '', 'instance': 0}
347 regex = re.compile(
348 r'^\s+(\$(.*?)|Skip)\s+(\d+)\s+(bits|bytes)(\s+\$_DEFAULT_\s'
349 r'+=\s+(.+?))?$', re.S |
350 re.MULTILINE)
351
352 for match in regex.finditer(bsf_txt):
353 dlen = int(match.group(3))
354 if match.group(1) == 'Skip':
355 key = 'gPlatformFspPkgTokenSpaceGuid_BsfSkip%d' % idx
356 val = ', '.join(['%02X' % ord(i) for i in '\x00' * dlen])
357 idx += 1
358 option = '$SKIP'
359 else:
360 key = match.group(2)
361 val = match.group(6)
362 option = ''
363 is_bit = True if match.group(4) == 'bits' else False
364
365 cfg_item = dict(cfg_temp)
366 line = bsf_txt[:match.end()].count("\n")
367 finds = [i for i in find_list if line >= i[2]]
368 if len(finds) > 0:
369 prefix = finds[0][1]
370 cfg_item['embed'] = '%s:TAG_%03X:START' % \
371 (prefix, ord(prefix[-1]))
372 cfg_item['find'] = prefix
373 cfg_item['cname'] = 'Signature'
374 cfg_item['length'] = len(finds[0][1])
375 str2byte = Str2Bytes("'" + finds[0][1] + "'",
376 len(finds[0][1]))
377 cfg_item['value'] = '0x%X' % Bytes2Val(str2byte)
378
379 cfg_list.append(dict(cfg_item))
380 cfg_item = dict(cfg_temp)
381 find_list.pop(0)
382 count = 0
383
384 cfg_item['cname'] = key
385 cfg_item['length'] = dlen
386 cfg_item['value'] = val
387 cfg_item['option'] = option
388 cfg_item['isbit'] = is_bit
389
390 if key not in chk_dict.keys():
391 chk_dict[key] = 0
392 else:
393 chk_dict[key] += 1
394 cfg_item['instance'] = chk_dict[key]
395
396 cfg_list.append(cfg_item)
397 count += 1
398
399 if prefix:
400 cfg_item = dict(cfg_temp)
401 cfg_item['cname'] = 'Dummy'
402 cfg_item['embed'] = '%s:%03X:END' % (prefix, ord(prefix[-1]))
403 cfg_list.append(cfg_item)
404
405 option_dict = {}
406 selreg = re.compile(
407 r'\s+Selection\s*(.+?)\s*,\s*"(.*?)"$', re.S |
408 re.MULTILINE)
409 regex = re.compile(
410 r'^List\s&(.+?)$(.+?)^EndList$', re.S | re.MULTILINE)
411 for match in regex.finditer(bsf_txt):
412 key = match.group(1)
413 option_dict[key] = []
414 for select in selreg.finditer(match.group(2)):
415 option_dict[key].append(
416 (int(select.group(1), 0), select.group(2)))
417
418 chk_dict = {}
419 pagereg = re.compile(
420 r'^Page\s"(.*?)"$(.+?)^EndPage$', re.S | re.MULTILINE)
421 for match in pagereg.finditer(bsf_txt):
422 page = match.group(1)
423 for line in match.group(2).splitlines():
424 match = re.match(
425 r'\s+(Combo|EditNum)\s\$(.+?),\s"(.*?)",\s(.+?),$', line)
426 if match:
427 cname = match.group(2)
428 if cname not in chk_dict.keys():
429 chk_dict[cname] = 0
430 else:
431 chk_dict[cname] += 1
432 instance = chk_dict[cname]
433 cfg_idxs = [i for i, j in enumerate(cfg_list)
434 if j['cname'] == cname and
435 j['instance'] == instance]
436 if len(cfg_idxs) != 1:
437 raise Exception(
438 "Multiple CFG item '%s' found !" % cname)
439 cfg_item = cfg_list[cfg_idxs[0]]
440 cfg_item['page'] = page
441 cfg_item['type'] = match.group(1)
442 cfg_item['prompt'] = match.group(3)
443 cfg_item['range'] = None
444 if cfg_item['type'] == 'Combo':
445 cfg_item['option'] = option_dict[match.group(4)[1:]]
446 elif cfg_item['type'] == 'EditNum':
447 cfg_item['option'] = match.group(4)
448 match = re.match(r'\s+ Help\s"(.*?)"$', line)
449 if match:
450 cfg_item['help'] = match.group(1)
451
452 match = re.match(r'\s+"Valid\srange:\s(.*)"$', line)
453 if match:
454 parts = match.group(1).split()
455 cfg_item['option'] = (
456 (int(parts[0], 0), int(parts[2], 0),
457 cfg_item['option']))
458
459 return cfg_list
460
461 @staticmethod
462 def generate_dsc(option_list, dsc_file=None):
463 dsc_lines = []
464 header = '%s' % (__copyright_dsc__ % date.today().year)
465 dsc_lines.extend(header.splitlines())
466
467 pages = []
468 for cfg_item in option_list:
469 if cfg_item['page'] and (cfg_item['page'] not in pages):
470 pages.append(cfg_item['page'])
471
472 page_id = 0
473 for page in pages:
474 dsc_lines.append(' # !BSF PAGES:{PG%02X::"%s"}' % (page_id, page))
475 page_id += 1
476 dsc_lines.append('')
477
478 last_page = ''
479
480 is_bit = False
481 dlen = 0
482 dval = 0
483 bit_fields = []
484 for idx, option in enumerate(option_list):
485 if not is_bit and option['isbit']:
486 is_bit = True
487 dlen = 0
488 dval = 0
489 idxs = idx
490 if is_bit and not option['isbit']:
491 is_bit = False
492 if dlen % 8 != 0:
493 raise Exception("Bit fields are not aligned at "
494 "byte boundary !")
495 bit_fields.append((idxs, idx, dlen, dval))
496 if is_bit:
497 blen = option['length']
498 bval = int(option['value'], 0)
499 dval = dval + ((bval & ((1 << blen) - 1)) << dlen)
500 print(dlen, blen, bval, hex(dval))
501 dlen += blen
502
503 struct_idx = 0
504 for idx, option in enumerate(option_list):
505 dsc_lines.append('')
506 default = option['value']
507 pos = option['cname'].find('_')
508 name = option['cname'][pos + 1:]
509
510 for start_idx, end_idx, bits_len, bits_val in bit_fields:
511 if idx == start_idx:
512 val_str = Bytes2Str(Val2Bytes(bits_val, bits_len // 8))
513 dsc_lines.append(' # !HDR STRUCT:{BIT_FIELD_DATA_%d}'
514 % struct_idx)
515 dsc_lines.append(' # !BSF NAME:{BIT_FIELD_STRUCT}')
516 dsc_lines.append(' gCfgData.BitFiledStruct%d '
517 ' | * | 0x%04X | %s' %
518 (struct_idx, bits_len // 8, val_str))
519 dsc_lines.append('')
520 struct_idx += 1
521
522 if option['find']:
523 dsc_lines.append(' # !BSF FIND:{%s}' % option['find'])
524 dsc_lines.append('')
525
526 if option['instance'] > 0:
527 name = name + '_%s' % option['instance']
528
529 if option['embed']:
530 dsc_lines.append(' # !HDR EMBED:{%s}' % option['embed'])
531
532 if option['type'] == 'Reserved':
533 dsc_lines.append(' # !BSF NAME:{Reserved} TYPE:{Reserved}')
534 if option['option'] == '$SKIP':
535 dsc_lines.append(' # !BSF OPTION:{$SKIP}')
536 else:
537 prompt = option['prompt']
538
539 if last_page != option['page']:
540 last_page = option['page']
541 dsc_lines.append(' # !BSF PAGE:{PG%02X}' %
542 (pages.index(option['page'])))
543
544 if option['type'] == 'Combo':
545 dsc_lines.append(' # !BSF NAME:{%s} TYPE:{%s}' %
546 (prompt, option['type']))
547 ops = []
548 for val, text in option['option']:
549 ops.append('0x%x:%s' % (val, text))
550 dsc_lines.append(' # !BSF OPTION:{%s}' % (', '.join(ops)))
551 elif option['type'] == 'EditNum':
552 cfg_len = option['length']
553 if ',' in default and cfg_len > 8:
554 dsc_lines.append(' # !BSF NAME:{%s} TYPE:{Table}' %
555 (prompt))
556 if cfg_len > 16:
557 cfg_len = 16
558 ops = []
559 for i in range(cfg_len):
560 ops.append('%X:1:HEX' % i)
561 dsc_lines.append(' # !BSF OPTION:{%s}' %
562 (', '.join(ops)))
563 else:
564 dsc_lines.append(
565 ' # !BSF NAME:{%s} TYPE:{%s, %s, (0x%X, 0x%X)}' %
566 (prompt, option['type'], option['option'][2],
567 option['option'][0], option['option'][1]))
568 dsc_lines.append(' # !BSF HELP:{%s}' % option['help'])
569
570 if ',' in default:
571 default = '{%s}' % default
572
573 if option['isbit']:
574 dsc_lines.append(' # !BSF FIELD:{%s:%db}'
575 % (name, option['length']))
576 else:
577 dsc_lines.append(' gCfgData.%-30s | * | 0x%04X | %s' %
578 (name, option['length'], default))
579
580 if dsc_file:
581 fd = open(dsc_file, 'w')
582 fd.write('\n'.join(dsc_lines))
583 fd.close()
584
585 return dsc_lines
586
587
588 class CGenCfgData:
589 def __init__(self, Mode=''):
590 self.Debug = False
591 self.Error = ''
592 self.ReleaseMode = True
593 self.Mode = Mode
594 self._GlobalDataDef = """
595 GlobalDataDef
596 SKUID = 0, "DEFAULT"
597 EndGlobalData
598
599 """
600 self._BuidinOptionTxt = """
601 List &EN_DIS
602 Selection 0x1 , "Enabled"
603 Selection 0x0 , "Disabled"
604 EndList
605
606 """
607 self._StructType = ['UINT8', 'UINT16', 'UINT32', 'UINT64']
608 self._BsfKeyList = ['FIND', 'NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES',
609 'BLOCK', 'OPTION', 'CONDITION', 'ORDER', 'MARKER',
610 'SUBT']
611 self._HdrKeyList = ['HEADER', 'STRUCT', 'EMBED', 'COMMENT']
612 self._BuidinOption = {'$EN_DIS': 'EN_DIS'}
613
614 self._MacroDict = {}
615 self._VarDict = {}
616 self._PcdsDict = {}
617 self._CfgBlkDict = {}
618 self._CfgPageDict = {}
619 self._CfgOptsDict = {}
620 self._BsfTempDict = {}
621 self._CfgItemList = []
622 self._DscLines = []
623 self._DscFile = ''
624 self._CfgPageTree = {}
625
626 self._MapVer = 0
627 self._MinCfgTagId = 0x100
628
629 def ParseMacros(self, MacroDefStr):
630 # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
631 self._MacroDict = {}
632 IsExpression = False
633 for Macro in MacroDefStr:
634 if Macro.startswith('-D'):
635 IsExpression = True
636 if len(Macro) > 2:
637 Macro = Macro[2:]
638 else:
639 continue
640 if IsExpression:
641 IsExpression = False
642 Match = re.match("(\\w+)=(.+)", Macro)
643 if Match:
644 self._MacroDict[Match.group(1)] = Match.group(2)
645 else:
646 Match = re.match("(\\w+)", Macro)
647 if Match:
648 self._MacroDict[Match.group(1)] = ''
649 if len(self._MacroDict) == 0:
650 Error = 1
651 else:
652 Error = 0
653 if self.Debug:
654 print("INFO : Macro dictionary:")
655 for Each in self._MacroDict:
656 print(" $(%s) = [ %s ]" % (Each,
657 self._MacroDict[Each]))
658 return Error
659
660 def EvaulateIfdef(self, Macro):
661 Result = Macro in self._MacroDict
662 if self.Debug:
663 print("INFO : Eval Ifdef [%s] : %s" % (Macro, Result))
664 return Result
665
666 def ExpandMacros(self, Input, Preserve=False):
667 Line = Input
668 Match = re.findall("\\$\\(\\w+\\)", Input)
669 if Match:
670 for Each in Match:
671 Variable = Each[2:-1]
672 if Variable in self._MacroDict:
673 Line = Line.replace(Each, self._MacroDict[Variable])
674 else:
675 if self.Debug:
676 print("WARN : %s is not defined" % Each)
677 if not Preserve:
678 Line = Line.replace(Each, Each[2:-1])
679 return Line
680
681 def ExpandPcds(self, Input):
682 Line = Input
683 Match = re.findall("(\\w+\\.\\w+)", Input)
684 if Match:
685 for PcdName in Match:
686 if PcdName in self._PcdsDict:
687 Line = Line.replace(PcdName, self._PcdsDict[PcdName])
688 else:
689 if self.Debug:
690 print("WARN : %s is not defined" % PcdName)
691 return Line
692
693 def EvaluateExpress(self, Expr):
694 ExpExpr = self.ExpandPcds(Expr)
695 ExpExpr = self.ExpandMacros(ExpExpr)
696 LogExpr = CLogicalExpression()
697 Result = LogExpr.evaluateExpress(ExpExpr)
698 if self.Debug:
699 print("INFO : Eval Express [%s] : %s" % (Expr, Result))
700 return Result
701
702 def ValueToByteArray(self, ValueStr, Length):
703 Match = re.match("\\{\\s*FILE:(.+)\\}", ValueStr)
704 if Match:
705 FileList = Match.group(1).split(',')
706 Result = bytearray()
707 for File in FileList:
708 File = File.strip()
709 BinPath = os.path.join(os.path.dirname(self._DscFile), File)
710 Result.extend(bytearray(open(BinPath, 'rb').read()))
711 else:
712 try:
713 Result = bytearray(self.ValueToList(ValueStr, Length))
714 except ValueError:
715 raise Exception("Bytes in '%s' must be in range 0~255 !" %
716 ValueStr)
717 if len(Result) < Length:
718 Result.extend(b'\x00' * (Length - len(Result)))
719 elif len(Result) > Length:
720 raise Exception("Value '%s' is too big to fit into %d bytes !" %
721 (ValueStr, Length))
722
723 return Result[:Length]
724
725 def ValueToList(self, ValueStr, Length):
726 if ValueStr[0] == '{':
727 Result = []
728 BinList = ValueStr[1:-1].split(',')
729 InBitField = False
730 LastInBitField = False
731 Value = 0
732 BitLen = 0
733 for Element in BinList:
734 InBitField = False
735 Each = Element.strip()
736 if len(Each) == 0:
737 pass
738 else:
739 if Each[0] in ['"', "'"]:
740 Result.extend(list(bytearray(Each[1:-1], 'utf-8')))
741 elif ':' in Each:
742 Match = re.match("(.+):(\\d+)b", Each)
743 if Match is None:
744 raise Exception("Invald value list format '%s' !"
745 % Each)
746 InBitField = True
747 CurrentBitLen = int(Match.group(2))
748 CurrentValue = ((self.EvaluateExpress(Match.group(1))
749 & (1 << CurrentBitLen) - 1)) << BitLen
750 else:
751 Result.append(self.EvaluateExpress(Each.strip()))
752 if InBitField:
753 Value += CurrentValue
754 BitLen += CurrentBitLen
755 if LastInBitField and ((not InBitField) or (Element ==
756 BinList[-1])):
757 if BitLen % 8 != 0:
758 raise Exception("Invald bit field length!")
759 Result.extend(Val2Bytes(Value, BitLen // 8))
760 Value = 0
761 BitLen = 0
762 LastInBitField = InBitField
763 elif ValueStr.startswith("'") and ValueStr.endswith("'"):
764 Result = Str2Bytes(ValueStr, Length)
765 elif ValueStr.startswith('"') and ValueStr.endswith('"'):
766 Result = Str2Bytes(ValueStr, Length)
767 else:
768 Result = Val2Bytes(self.EvaluateExpress(ValueStr), Length)
769 return Result
770
771 def FormatDeltaValue(self, ConfigDict):
772 ValStr = ConfigDict['value']
773 if ValStr[0] == "'":
774 # Remove padding \x00 in the value string
775 ValStr = "'%s'" % ValStr[1:-1].rstrip('\x00')
776
777 Struct = ConfigDict['struct']
778 if Struct in self._StructType:
779 # Format the array using its struct type
780 Unit = int(Struct[4:]) // 8
781 Value = Array2Val(ConfigDict['value'])
782 Loop = ConfigDict['length'] // Unit
783 Values = []
784 for Each in range(Loop):
785 Values.append(Value & ((1 << (Unit * 8)) - 1))
786 Value = Value >> (Unit * 8)
787 ValStr = '{ ' + ', '.join([('0x%%0%dX' % (Unit * 2)) %
788 x for x in Values]) + ' }'
789
790 return ValStr
791
792 def FormatListValue(self, ConfigDict):
793 Struct = ConfigDict['struct']
794 if Struct not in self._StructType:
795 return
796
797 DataList = self.ValueToList(ConfigDict['value'], ConfigDict['length'])
798 Unit = int(Struct[4:]) // 8
799 if int(ConfigDict['length']) != Unit * len(DataList):
800 # Fallback to byte array
801 Unit = 1
802 if int(ConfigDict['length']) != len(DataList):
803 raise Exception("Array size is not proper for '%s' !" %
804 ConfigDict['cname'])
805
806 ByteArray = []
807 for Value in DataList:
808 for Loop in range(Unit):
809 ByteArray.append("0x%02X" % (Value & 0xFF))
810 Value = Value >> 8
811 NewValue = '{' + ','.join(ByteArray) + '}'
812 ConfigDict['value'] = NewValue
813
814 return ""
815
816 def GetOrderNumber(self, Offset, Order, BitOff=0):
817 if isinstance(Order, int):
818 if Order == -1:
819 Order = Offset << 16
820 else:
821 (Major, Minor) = Order.split('.')
822 Order = (int(Major, 16) << 16) + ((int(Minor, 16) & 0xFF) << 8)
823 return Order + (BitOff & 0xFF)
824
825 def SubtituteLine(self, Line, Args):
826 Args = Args.strip()
827 Vars = Args.split(':')
828 Line = self.ExpandMacros(Line, True)
829 for Idx in range(len(Vars)-1, 0, -1):
830 Line = Line.replace('$(%d)' % Idx, Vars[Idx].strip())
831 return Line
832
833 def CfgDuplicationCheck(self, CfgDict, Name):
834 if not self.Debug:
835 return
836
837 if Name == 'Dummy':
838 return
839
840 if Name not in CfgDict:
841 CfgDict[Name] = 1
842 else:
843 print("WARNING: Duplicated item found '%s' !" %
844 CfgDict['cname'])
845
846 def AddBsfChildPage(self, Child, Parent='root'):
847 def AddBsfChildPageRecursive(PageTree, Parent, Child):
848 Key = next(iter(PageTree))
849 if Parent == Key:
850 PageTree[Key].append({Child: []})
851 return True
852 else:
853 Result = False
854 for Each in PageTree[Key]:
855 if AddBsfChildPageRecursive(Each, Parent, Child):
856 Result = True
857 break
858 return Result
859
860 return AddBsfChildPageRecursive(self._CfgPageTree, Parent, Child)
861
862 def ParseDscFile(self, DscFile):
863 self._DscLines = []
864 self._CfgItemList = []
865 self._CfgPageDict = {}
866 self._CfgBlkDict = {}
867 self._BsfTempDict = {}
868 self._CfgPageTree = {'root': []}
869
870 CfgDict = {}
871
872 SectionNameList = ["Defines".lower(), "PcdsFeatureFlag".lower(),
873 "PcdsDynamicVpd.Tmp".lower(),
874 "PcdsDynamicVpd.Upd".lower()]
875
876 IsDefSect = False
877 IsPcdSect = False
878 IsUpdSect = False
879 IsTmpSect = False
880
881 TemplateName = ''
882
883 IfStack = []
884 ElifStack = []
885 Error = 0
886 ConfigDict = {}
887
888 if type(DscFile) is list:
889 # it is DSC lines already
890 DscLines = DscFile
891 self._DscFile = '.'
892 else:
893 DscFd = open(DscFile, "r")
894 DscLines = DscFd.readlines()
895 DscFd.close()
896 self._DscFile = DscFile
897
898 BsfRegExp = re.compile("(%s):{(.+?)}(?:$|\\s+)" % '|'.
899 join(self._BsfKeyList))
900 HdrRegExp = re.compile("(%s):{(.+?)}" % '|'.join(self._HdrKeyList))
901 CfgRegExp = re.compile("^([_a-zA-Z0-9]+)\\s*\\|\\s*\
902 (0x[0-9A-F]+|\\*)\\s*\\|\\s*(\\d+|0x[0-9a-fA-F]+)\\s*\\|\\s*(.+)")
903 TksRegExp = re.compile("^(g[_a-zA-Z0-9]+\\.)(.+)")
904 SkipLines = 0
905 while len(DscLines):
906 DscLine = DscLines.pop(0).strip()
907 if SkipLines == 0:
908 self._DscLines.append(DscLine)
909 else:
910 SkipLines = SkipLines - 1
911 if len(DscLine) == 0:
912 continue
913
914 Handle = False
915 Match = re.match("^\\[(.+)\\]", DscLine)
916 if Match is not None:
917 IsDefSect = False
918 IsPcdSect = False
919 IsUpdSect = False
920 IsTmpSect = False
921 SectionName = Match.group(1).lower()
922 if SectionName == SectionNameList[0]:
923 IsDefSect = True
924 if SectionName == SectionNameList[1]:
925 IsPcdSect = True
926 elif SectionName == SectionNameList[2]:
927 IsTmpSect = True
928 elif SectionName == SectionNameList[3]:
929 ConfigDict = {
930 'header': 'ON',
931 'page': '',
932 'name': '',
933 'find': '',
934 'struct': '',
935 'embed': '',
936 'marker': '',
937 'option': '',
938 'comment': '',
939 'condition': '',
940 'order': -1,
941 'subreg': []
942 }
943 IsUpdSect = True
944 Offset = 0
945 else:
946 if IsDefSect or IsPcdSect or IsUpdSect or IsTmpSect:
947 Match = False if DscLine[0] != '!' else True
948 if Match:
949 Match = re.match("^!(else|endif|ifdef|ifndef|if|elseif\
950 |include)\\s*(.+)?$", DscLine.split("#")[0])
951 Keyword = Match.group(1) if Match else ''
952 Remaining = Match.group(2) if Match else ''
953 Remaining = '' if Remaining is None else Remaining.strip()
954
955 if Keyword in ['if', 'elseif', 'ifdef', 'ifndef', 'include'
956 ] and not Remaining:
957 raise Exception("ERROR: Expression is expected after \
958 '!if' or !elseif' for line '%s'" % DscLine)
959
960 if Keyword == 'else':
961 if IfStack:
962 IfStack[-1] = not IfStack[-1]
963 else:
964 raise Exception("ERROR: No paired '!if' found for \
965 '!else' for line '%s'" % DscLine)
966 elif Keyword == 'endif':
967 if IfStack:
968 IfStack.pop()
969 Level = ElifStack.pop()
970 if Level > 0:
971 del IfStack[-Level:]
972 else:
973 raise Exception("ERROR: No paired '!if' found for \
974 '!endif' for line '%s'" % DscLine)
975 elif Keyword == 'ifdef' or Keyword == 'ifndef':
976 Result = self.EvaulateIfdef(Remaining)
977 if Keyword == 'ifndef':
978 Result = not Result
979 IfStack.append(Result)
980 ElifStack.append(0)
981 elif Keyword == 'if' or Keyword == 'elseif':
982 Result = self.EvaluateExpress(Remaining)
983 if Keyword == "if":
984 ElifStack.append(0)
985 IfStack.append(Result)
986 else: # elseif
987 if IfStack:
988 IfStack[-1] = not IfStack[-1]
989 IfStack.append(Result)
990 ElifStack[-1] = ElifStack[-1] + 1
991 else:
992 raise Exception("ERROR: No paired '!if' found for \
993 '!elif' for line '%s'" % DscLine)
994 else:
995 if IfStack:
996 Handle = reduce(lambda x, y: x and y, IfStack)
997 else:
998 Handle = True
999 if Handle:
1000 if Keyword == 'include':
1001 Remaining = self.ExpandMacros(Remaining)
1002 # Relative to DSC filepath
1003 IncludeFilePath = os.path.join(
1004 os.path.dirname(self._DscFile), Remaining)
1005 if not os.path.exists(IncludeFilePath):
1006 # Relative to repository to find \
1007 # dsc in common platform
1008 IncludeFilePath = os.path.join(
1009 os.path.dirname(self._DscFile), "..",
1010 Remaining)
1011
1012 try:
1013 IncludeDsc = open(IncludeFilePath, "r")
1014 except Exception:
1015 raise Exception("ERROR: Cannot open \
1016 file '%s'." % IncludeFilePath)
1017 NewDscLines = IncludeDsc.readlines()
1018 IncludeDsc.close()
1019 DscLines = NewDscLines + DscLines
1020 del self._DscLines[-1]
1021 else:
1022 if DscLine.startswith('!'):
1023 raise Exception("ERROR: Unrecoginized \
1024 directive for line '%s'" % DscLine)
1025
1026 if not Handle:
1027 del self._DscLines[-1]
1028 continue
1029
1030 if IsDefSect:
1031 Match = re.match("^\\s*(?:DEFINE\\s+)*(\\w+)\\s*=\\s*(.+)",
1032 DscLine)
1033 if Match:
1034 self._MacroDict[Match.group(1)] = Match.group(2)
1035 if self.Debug:
1036 print("INFO : DEFINE %s = [ %s ]" % (Match.group(1),
1037 Match.group(2)))
1038
1039 elif IsPcdSect:
1040 Match = re.match("^\\s*([\\w\\.]+)\\s*\\|\\s*(\\w+)", DscLine)
1041 if Match:
1042 self._PcdsDict[Match.group(1)] = Match.group(2)
1043 if self.Debug:
1044 print("INFO : PCD %s = [ %s ]" % (Match.group(1),
1045 Match.group(2)))
1046
1047 elif IsTmpSect:
1048 # !BSF DEFT:{GPIO_TMPL:START}
1049 Match = re.match("^\\s*#\\s+(!BSF)\\s+DEFT:{(.+?):\
1050 (START|END)}", DscLine)
1051 if Match:
1052 if Match.group(3) == 'START' and not TemplateName:
1053 TemplateName = Match.group(2).strip()
1054 self._BsfTempDict[TemplateName] = []
1055 if Match.group(3) == 'END' and (
1056 TemplateName == Match.group(2).strip()
1057 ) and TemplateName:
1058 TemplateName = ''
1059 else:
1060 if TemplateName:
1061 Match = re.match("^!include\\s*(.+)?$", DscLine)
1062 if Match:
1063 continue
1064 self._BsfTempDict[TemplateName].append(DscLine)
1065
1066 else:
1067 Match = re.match("^\\s*#\\s+(!BSF|!HDR)\\s+(.+)", DscLine)
1068 if Match:
1069 Remaining = Match.group(2)
1070 if Match.group(1) == '!BSF':
1071 Result = BsfRegExp.findall(Remaining)
1072 if Result:
1073 for Each in Result:
1074 Key = Each[0]
1075 Remaining = Each[1]
1076
1077 if Key == 'BLOCK':
1078 Match = re.match(
1079 "NAME:\"(.+)\"\\s*,\\s*\
1080 VER:\"(.+)\"\\s*", Remaining)
1081 if Match:
1082 self._CfgBlkDict['name'] = \
1083 Match.group(1)
1084 self._CfgBlkDict['ver'] = Match.group(2
1085 )
1086
1087 elif Key == 'SUBT':
1088 # GPIO_TMPL:1:2:3
1089 Remaining = Remaining.strip()
1090 Match = re.match("(\\w+)\\s*:", Remaining)
1091 if Match:
1092 TemplateName = Match.group(1)
1093 for Line in self._BsfTempDict[
1094 TemplateName][::-1]:
1095 NewLine = self.SubtituteLine(
1096 Line, Remaining)
1097 DscLines.insert(0, NewLine)
1098 SkipLines += 1
1099
1100 elif Key == 'PAGES':
1101 # !BSF PAGES:{HSW:"Haswell System Agent", \
1102 # LPT:"Lynx Point PCH"}
1103 PageList = Remaining.split(',')
1104 for Page in PageList:
1105 Page = Page.strip()
1106 Match = re.match('(\\w+):\
1107 (\\w*:)?\\"(.+)\\"', Page)
1108 if Match:
1109 PageName = Match.group(1)
1110 ParentName = Match.group(2)
1111 if not ParentName or \
1112 ParentName == ':':
1113 ParentName = 'root'
1114 else:
1115 ParentName = ParentName[:-1]
1116 if not self.AddBsfChildPage(
1117 PageName, ParentName):
1118 raise Exception("Cannot find \
1119 parent page '%s'!" % ParentName)
1120 self._CfgPageDict[
1121 PageName] = Match.group(3)
1122 else:
1123 raise Exception("Invalid page \
1124 definitions '%s'!" % Page)
1125
1126 elif Key in ['NAME', 'HELP', 'OPTION'
1127 ] and Remaining.startswith('+'):
1128 # Allow certain options to be extended \
1129 # to multiple lines
1130 ConfigDict[Key.lower()] += Remaining[1:]
1131
1132 else:
1133 if Key == 'NAME':
1134 Remaining = Remaining.strip()
1135 elif Key == 'CONDITION':
1136 Remaining = self.ExpandMacros(
1137 Remaining.strip())
1138 ConfigDict[Key.lower()] = Remaining
1139 else:
1140 Match = HdrRegExp.match(Remaining)
1141 if Match:
1142 Key = Match.group(1)
1143 Remaining = Match.group(2)
1144 if Key == 'EMBED':
1145 Parts = Remaining.split(':')
1146 Names = Parts[0].split(',')
1147 DummyDict = ConfigDict.copy()
1148 if len(Names) > 1:
1149 Remaining = Names[0] + ':' + ':'.join(
1150 Parts[1:])
1151 DummyDict['struct'] = Names[1]
1152 else:
1153 DummyDict['struct'] = Names[0]
1154 DummyDict['cname'] = 'Dummy'
1155 DummyDict['name'] = ''
1156 DummyDict['embed'] = Remaining
1157 DummyDict['offset'] = Offset
1158 DummyDict['length'] = 0
1159 DummyDict['value'] = '0'
1160 DummyDict['type'] = 'Reserved'
1161 DummyDict['help'] = ''
1162 DummyDict['subreg'] = []
1163 self._CfgItemList.append(DummyDict)
1164 else:
1165 ConfigDict[Key.lower()] = Remaining
1166 # Check CFG line
1167 # gCfgData.VariableName | * | 0x01 | 0x1
1168 Clear = False
1169
1170 Match = TksRegExp.match(DscLine)
1171 if Match:
1172 DscLine = 'gCfgData.%s' % Match.group(2)
1173
1174 if DscLine.startswith('gCfgData.'):
1175 Match = CfgRegExp.match(DscLine[9:])
1176 else:
1177 Match = None
1178 if Match:
1179 ConfigDict['space'] = 'gCfgData'
1180 ConfigDict['cname'] = Match.group(1)
1181 if Match.group(2) != '*':
1182 Offset = int(Match.group(2), 16)
1183 ConfigDict['offset'] = Offset
1184 ConfigDict['order'] = self.GetOrderNumber(
1185 ConfigDict['offset'], ConfigDict['order'])
1186
1187 Value = Match.group(4).strip()
1188 if Match.group(3).startswith("0x"):
1189 Length = int(Match.group(3), 16)
1190 else:
1191 Length = int(Match.group(3))
1192
1193 Offset += Length
1194
1195 ConfigDict['length'] = Length
1196 Match = re.match("\\$\\((\\w+)\\)", Value)
1197 if Match:
1198 if Match.group(1) in self._MacroDict:
1199 Value = self._MacroDict[Match.group(1)]
1200
1201 ConfigDict['value'] = Value
1202 if re.match("\\{\\s*FILE:(.+)\\}", Value):
1203 # Expand embedded binary file
1204 ValArray = self.ValueToByteArray(ConfigDict['value'],
1205 ConfigDict['length'])
1206 NewValue = Bytes2Str(ValArray)
1207 self._DscLines[-1] = re.sub(r'(.*)(\{\s*FILE:.+\})',
1208 r'\1 %s' % NewValue,
1209 self._DscLines[-1])
1210 ConfigDict['value'] = NewValue
1211
1212 if ConfigDict['name'] == '':
1213 # Clear BSF specific items
1214 ConfigDict['bsfname'] = ''
1215 ConfigDict['help'] = ''
1216 ConfigDict['type'] = ''
1217 ConfigDict['option'] = ''
1218
1219 self.CfgDuplicationCheck(CfgDict, ConfigDict['cname'])
1220 self._CfgItemList.append(ConfigDict.copy())
1221 Clear = True
1222
1223 else:
1224 # It could be a virtual item as below
1225 # !BSF FIELD:{SerialDebugPortAddress0:1}
1226 # or
1227 # @Bsf FIELD:{SerialDebugPortAddress0:1b}
1228 Match = re.match(r"^\s*#\s+(!BSF)\s+FIELD:{(.+)}", DscLine)
1229 if Match:
1230 BitFieldTxt = Match.group(2)
1231 Match = re.match("(.+):(\\d+)b([BWDQ])?", BitFieldTxt)
1232 if not Match:
1233 raise Exception("Incorrect bit field \
1234 format '%s' !" % BitFieldTxt)
1235 UnitBitLen = 1
1236 SubCfgDict = ConfigDict.copy()
1237 SubCfgDict['cname'] = Match.group(1)
1238 SubCfgDict['bitlength'] = int(
1239 Match.group(2)) * UnitBitLen
1240 if SubCfgDict['bitlength'] > 0:
1241 LastItem = self._CfgItemList[-1]
1242 if len(LastItem['subreg']) == 0:
1243 SubOffset = 0
1244 else:
1245 SubOffset = \
1246 LastItem['subreg'][-1]['bitoffset'] \
1247 + LastItem['subreg'][-1]['bitlength']
1248 if Match.group(3) == 'B':
1249 SubCfgDict['bitunit'] = 1
1250 elif Match.group(3) == 'W':
1251 SubCfgDict['bitunit'] = 2
1252 elif Match.group(3) == 'Q':
1253 SubCfgDict['bitunit'] = 8
1254 else:
1255 SubCfgDict['bitunit'] = 4
1256 SubCfgDict['bitoffset'] = SubOffset
1257 SubCfgDict['order'] = self.GetOrderNumber(
1258 SubCfgDict['offset'], SubCfgDict['order'],
1259 SubOffset)
1260 SubCfgDict['value'] = ''
1261 SubCfgDict['cname'] = '%s_%s' % (LastItem['cname'],
1262 Match.group(1))
1263 self.CfgDuplicationCheck(CfgDict,
1264 SubCfgDict['cname'])
1265 LastItem['subreg'].append(SubCfgDict.copy())
1266 Clear = True
1267
1268 if Clear:
1269 ConfigDict['name'] = ''
1270 ConfigDict['find'] = ''
1271 ConfigDict['struct'] = ''
1272 ConfigDict['embed'] = ''
1273 ConfigDict['marker'] = ''
1274 ConfigDict['comment'] = ''
1275 ConfigDict['order'] = -1
1276 ConfigDict['subreg'] = []
1277 ConfigDict['option'] = ''
1278 ConfigDict['condition'] = ''
1279
1280 return Error
1281
1282 def GetBsfBitFields(self, subitem, bytes):
1283 start = subitem['bitoffset']
1284 end = start + subitem['bitlength']
1285 bitsvalue = ''.join('{0:08b}'.format(i) for i in bytes[::-1])
1286 bitsvalue = bitsvalue[::-1]
1287 bitslen = len(bitsvalue)
1288 if start > bitslen or end > bitslen:
1289 raise Exception("Invalid bits offset [%d,%d] %d for %s" %
1290 (start, end, bitslen, subitem['name']))
1291 return '0x%X' % (int(bitsvalue[start:end][::-1], 2))
1292
1293 def UpdateBsfBitFields(self, SubItem, NewValue, ValueArray):
1294 Start = SubItem['bitoffset']
1295 End = Start + SubItem['bitlength']
1296 Blen = len(ValueArray)
1297 BitsValue = ''.join('{0:08b}'.format(i) for i in ValueArray[::-1])
1298 BitsValue = BitsValue[::-1]
1299 BitsLen = len(BitsValue)
1300 if Start > BitsLen or End > BitsLen:
1301 raise Exception("Invalid bits offset [%d,%d] %d for %s" %
1302 (Start, End, BitsLen, SubItem['name']))
1303 BitsValue = BitsValue[:Start] + '{0:0{1}b}'.format(
1304 NewValue, SubItem['bitlength'])[::-1] + BitsValue[End:]
1305 ValueArray[:] = bytearray.fromhex(
1306 '{0:0{1}x}'.format(int(BitsValue[::-1], 2), Blen * 2))[::-1]
1307
1308 def CreateVarDict(self):
1309 Error = 0
1310 self._VarDict = {}
1311 if len(self._CfgItemList) > 0:
1312 Item = self._CfgItemList[-1]
1313 self._VarDict['_LENGTH_'] = '%d' % (Item['offset'] +
1314 Item['length'])
1315 for Item in self._CfgItemList:
1316 Embed = Item['embed']
1317 Match = re.match("^(\\w+):(\\w+):(START|END)", Embed)
1318 if Match:
1319 StructName = Match.group(1)
1320 VarName = '_%s_%s_' % (Match.group(3), StructName)
1321 if Match.group(3) == 'END':
1322 self._VarDict[VarName] = Item['offset'] + Item['length']
1323 self._VarDict['_LENGTH_%s_' % StructName] = \
1324 self._VarDict['_END_%s_' % StructName] - \
1325 self._VarDict['_START_%s_' % StructName]
1326 if Match.group(2).startswith('TAG_'):
1327 if (self.Mode != 'FSP') and (self._VarDict
1328 ['_LENGTH_%s_' %
1329 StructName] % 4):
1330 raise Exception("Size of structure '%s' is %d, \
1331 not DWORD aligned !" % (StructName, self._VarDict['_LENGTH_%s_' % StructName]))
1332 self._VarDict['_TAG_%s_' % StructName] = int(
1333 Match.group(2)[4:], 16) & 0xFFF
1334 else:
1335 self._VarDict[VarName] = Item['offset']
1336 if Item['marker']:
1337 self._VarDict['_OFFSET_%s_' % Item['marker'].strip()] = \
1338 Item['offset']
1339 return Error
1340
1341 def UpdateBsfBitUnit(self, Item):
1342 BitTotal = 0
1343 BitOffset = 0
1344 StartIdx = 0
1345 Unit = None
1346 UnitDec = {1: 'BYTE', 2: 'WORD', 4: 'DWORD', 8: 'QWORD'}
1347 for Idx, SubItem in enumerate(Item['subreg']):
1348 if Unit is None:
1349 Unit = SubItem['bitunit']
1350 BitLength = SubItem['bitlength']
1351 BitTotal += BitLength
1352 BitOffset += BitLength
1353
1354 if BitOffset > 64 or BitOffset > Unit * 8:
1355 break
1356
1357 if BitOffset == Unit * 8:
1358 for SubIdx in range(StartIdx, Idx + 1):
1359 Item['subreg'][SubIdx]['bitunit'] = Unit
1360 BitOffset = 0
1361 StartIdx = Idx + 1
1362 Unit = None
1363
1364 if BitOffset > 0:
1365 raise Exception("Bit fields cannot fit into %s for \
1366 '%s.%s' !" % (UnitDec[Unit], Item['cname'], SubItem['cname']))
1367
1368 ExpectedTotal = Item['length'] * 8
1369 if Item['length'] * 8 != BitTotal:
1370 raise Exception("Bit fields total length (%d) does not match \
1371 length (%d) of '%s' !" % (BitTotal, ExpectedTotal, Item['cname']))
1372
1373 def UpdateDefaultValue(self):
1374 Error = 0
1375 for Idx, Item in enumerate(self._CfgItemList):
1376 if len(Item['subreg']) == 0:
1377 Value = Item['value']
1378 if (len(Value) > 0) and (Value[0] == '{' or Value[0] == "'" or
1379 Value[0] == '"'):
1380 # {XXX} or 'XXX' strings
1381 self.FormatListValue(self._CfgItemList[Idx])
1382 else:
1383 Match = re.match("(0x[0-9a-fA-F]+|[0-9]+)", Value)
1384 if not Match:
1385 NumValue = self.EvaluateExpress(Value)
1386 Item['value'] = '0x%X' % NumValue
1387 else:
1388 ValArray = self.ValueToByteArray(Item['value'], Item['length'])
1389 for SubItem in Item['subreg']:
1390 SubItem['value'] = self.GetBsfBitFields(SubItem, ValArray)
1391 self.UpdateBsfBitUnit(Item)
1392 return Error
1393
1394 @staticmethod
1395 def ExpandIncludeFiles(FilePath, CurDir=''):
1396 if CurDir == '':
1397 CurDir = os.path.dirname(FilePath)
1398 FilePath = os.path.basename(FilePath)
1399
1400 InputFilePath = os.path.join(CurDir, FilePath)
1401 File = open(InputFilePath, "r")
1402 Lines = File.readlines()
1403 File.close()
1404
1405 NewLines = []
1406 for LineNum, Line in enumerate(Lines):
1407 Match = re.match("^!include\\s*(.+)?$", Line)
1408 if Match:
1409 IncPath = Match.group(1)
1410 TmpPath = os.path.join(CurDir, IncPath)
1411 OrgPath = TmpPath
1412 if not os.path.exists(TmpPath):
1413 CurDir = os.path.join(os.path.dirname(
1414 os.path.realpath(__file__)), "..", "..")
1415 TmpPath = os.path.join(CurDir, IncPath)
1416 if not os.path.exists(TmpPath):
1417 raise Exception("ERROR: Cannot open include file '%s'." %
1418 OrgPath)
1419 else:
1420 NewLines.append(('# Included from file: %s\n' %
1421 IncPath, TmpPath, 0))
1422 NewLines.append(('# %s\n' % ('=' * 80), TmpPath, 0))
1423 NewLines.extend(CGenCfgData.ExpandIncludeFiles
1424 (IncPath, CurDir))
1425 else:
1426 NewLines.append((Line, InputFilePath, LineNum))
1427
1428 return NewLines
1429
1430 def OverrideDefaultValue(self, DltFile):
1431 Error = 0
1432 DltLines = CGenCfgData.ExpandIncludeFiles(DltFile)
1433
1434 PlatformId = None
1435 for Line, FilePath, LineNum in DltLines:
1436 Line = Line.strip()
1437 if not Line or Line.startswith('#'):
1438 continue
1439 Match = re.match("\\s*(\\w+)\\.(\\w+)(\\.\\w+)?\\s*\\|\\s*(.+)",
1440 Line)
1441 if not Match:
1442 raise Exception("Unrecognized line '%s' (File:'%s' Line:%d) !"
1443 % (Line, FilePath, LineNum + 1))
1444
1445 Found = False
1446 InScope = False
1447 for Idx, Item in enumerate(self._CfgItemList):
1448 if not InScope:
1449 if not (Item['embed'].endswith(':START') and
1450 Item['embed'].startswith(Match.group(1))):
1451 continue
1452 InScope = True
1453 if Item['cname'] == Match.group(2):
1454 Found = True
1455 break
1456 if Item['embed'].endswith(':END') and \
1457 Item['embed'].startswith(Match.group(1)):
1458 break
1459 Name = '%s.%s' % (Match.group(1), Match.group(2))
1460 if not Found:
1461 ErrItem = Match.group(2) if InScope else Match.group(1)
1462 raise Exception("Invalid configuration '%s' in '%s' \
1463 (File:'%s' Line:%d) !" % (ErrItem, Name, FilePath, LineNum + 1))
1464
1465 ValueStr = Match.group(4).strip()
1466 if Match.group(3) is not None:
1467 # This is a subregion item
1468 BitField = Match.group(3)[1:]
1469 Found = False
1470 if len(Item['subreg']) > 0:
1471 for SubItem in Item['subreg']:
1472 if SubItem['cname'] == '%s_%s' % \
1473 (Item['cname'], BitField):
1474 Found = True
1475 break
1476 if not Found:
1477 raise Exception("Invalid configuration bit field \
1478 '%s' in '%s.%s' (File:'%s' Line:%d) !" % (BitField, Name, BitField,
1479 FilePath, LineNum + 1))
1480
1481 try:
1482 Value = int(ValueStr, 16) if ValueStr.startswith('0x') \
1483 else int(ValueStr, 10)
1484 except Exception:
1485 raise Exception("Invalid value '%s' for bit field '%s.%s' \
1486 (File:'%s' Line:%d) !" % (ValueStr, Name, BitField, FilePath, LineNum + 1))
1487
1488 if Value >= 2 ** SubItem['bitlength']:
1489 raise Exception("Invalid configuration bit field value \
1490 '%s' for '%s.%s' (File:'%s' Line:%d) !" % (Value, Name, BitField,
1491 FilePath, LineNum + 1))
1492
1493 ValArray = self.ValueToByteArray(Item['value'], Item['length'])
1494 self.UpdateBsfBitFields(SubItem, Value, ValArray)
1495
1496 if Item['value'].startswith('{'):
1497 Item['value'] = '{' + ', '.join('0x%02X' % i
1498 for i in ValArray) + '}'
1499 else:
1500 BitsValue = ''.join('{0:08b}'.format(i)
1501 for i in ValArray[::-1])
1502 Item['value'] = '0x%X' % (int(BitsValue, 2))
1503 else:
1504 if Item['value'].startswith('{') and \
1505 not ValueStr.startswith('{'):
1506 raise Exception("Data array required for '%s' \
1507 (File:'%s' Line:%d) !" % (Name, FilePath, LineNum + 1))
1508 Item['value'] = ValueStr
1509
1510 if Name == 'PLATFORMID_CFG_DATA.PlatformId':
1511 PlatformId = ValueStr
1512
1513 if (PlatformId is None) and (self.Mode != 'FSP'):
1514 raise Exception("PLATFORMID_CFG_DATA.PlatformId is missing \
1515 in file '%s' !" % (DltFile))
1516
1517 return Error
1518
1519 def ProcessMultilines(self, String, MaxCharLength):
1520 Multilines = ''
1521 StringLength = len(String)
1522 CurrentStringStart = 0
1523 StringOffset = 0
1524 BreakLineDict = []
1525 if len(String) <= MaxCharLength:
1526 while (StringOffset < StringLength):
1527 if StringOffset >= 1:
1528 if String[StringOffset - 1] == '\\' and \
1529 String[StringOffset] == 'n':
1530 BreakLineDict.append(StringOffset + 1)
1531 StringOffset += 1
1532 if BreakLineDict != []:
1533 for Each in BreakLineDict:
1534 Multilines += " %s\n" % String[CurrentStringStart:Each].\
1535 lstrip()
1536 CurrentStringStart = Each
1537 if StringLength - CurrentStringStart > 0:
1538 Multilines += " %s\n" % String[CurrentStringStart:].\
1539 lstrip()
1540 else:
1541 Multilines = " %s\n" % String
1542 else:
1543 NewLineStart = 0
1544 NewLineCount = 0
1545 FoundSpaceChar = False
1546 while(StringOffset < StringLength):
1547 if StringOffset >= 1:
1548 if NewLineCount >= MaxCharLength - 1:
1549 if String[StringOffset] == ' ' and \
1550 StringLength - StringOffset > 10:
1551 BreakLineDict.append(NewLineStart + NewLineCount)
1552 NewLineStart = NewLineStart + NewLineCount
1553 NewLineCount = 0
1554 FoundSpaceChar = True
1555 elif StringOffset == StringLength - 1 \
1556 and FoundSpaceChar is False:
1557 BreakLineDict.append(0)
1558 if String[StringOffset - 1] == '\\' and \
1559 String[StringOffset] == 'n':
1560 BreakLineDict.append(StringOffset + 1)
1561 NewLineStart = StringOffset + 1
1562 NewLineCount = 0
1563 StringOffset += 1
1564 NewLineCount += 1
1565 if BreakLineDict != []:
1566 BreakLineDict.sort()
1567 for Each in BreakLineDict:
1568 if Each > 0:
1569 Multilines += " %s\n" % String[
1570 CurrentStringStart:Each].lstrip()
1571 CurrentStringStart = Each
1572 if StringLength - CurrentStringStart > 0:
1573 Multilines += " %s\n" % String[CurrentStringStart:].\
1574 lstrip()
1575 return Multilines
1576
1577 def CreateField(self, Item, Name, Length, Offset, Struct,
1578 BsfName, Help, Option, BitsLength=None):
1579 PosName = 28
1580 NameLine = ''
1581 HelpLine = ''
1582 OptionLine = ''
1583
1584 if Length == 0 and Name == 'Dummy':
1585 return '\n'
1586
1587 IsArray = False
1588 if Length in [1, 2, 4, 8]:
1589 Type = "UINT%d" % (Length * 8)
1590 else:
1591 IsArray = True
1592 Type = "UINT8"
1593
1594 if Item and Item['value'].startswith('{'):
1595 Type = "UINT8"
1596 IsArray = True
1597
1598 if Struct != '':
1599 Type = Struct
1600 if Struct in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
1601 IsArray = True
1602 Unit = int(Type[4:]) // 8
1603 Length = Length / Unit
1604 else:
1605 IsArray = False
1606
1607 if IsArray:
1608 Name = Name + '[%d]' % Length
1609
1610 if len(Type) < PosName:
1611 Space1 = PosName - len(Type)
1612 else:
1613 Space1 = 1
1614
1615 if BsfName != '':
1616 NameLine = " %s\n" % BsfName
1617 else:
1618 NameLine = "\n"
1619
1620 if Help != '':
1621 HelpLine = self.ProcessMultilines(Help, 80)
1622
1623 if Option != '':
1624 OptionLine = self.ProcessMultilines(Option, 80)
1625
1626 if BitsLength is None:
1627 BitsLength = ''
1628 else:
1629 BitsLength = ' : %d' % BitsLength
1630
1631 return "\n/** %s%s%s**/\n %s%s%s%s;\n" % \
1632 (NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,
1633 BitsLength)
1634
1635 def SplitTextBody(self, TextBody):
1636 Marker1 = '{ /* _COMMON_STRUCT_START_ */'
1637 Marker2 = '; /* _COMMON_STRUCT_END_ */'
1638 ComBody = []
1639 TxtBody = []
1640 IsCommon = False
1641 for Line in TextBody:
1642 if Line.strip().endswith(Marker1):
1643 Line = Line.replace(Marker1[1:], '')
1644 IsCommon = True
1645 if Line.strip().endswith(Marker2):
1646 Line = Line.replace(Marker2[1:], '')
1647 if IsCommon:
1648 ComBody.append(Line)
1649 IsCommon = False
1650 continue
1651 if IsCommon:
1652 ComBody.append(Line)
1653 else:
1654 TxtBody.append(Line)
1655 return ComBody, TxtBody
1656
1657 def GetStructArrayInfo(self, Input):
1658 ArrayStr = Input.split('[')
1659 Name = ArrayStr[0]
1660 if len(ArrayStr) > 1:
1661 NumStr = ''.join(c for c in ArrayStr[-1] if c.isdigit())
1662 NumStr = '1000' if len(NumStr) == 0 else NumStr
1663 ArrayNum = int(NumStr)
1664 else:
1665 ArrayNum = 0
1666 return Name, ArrayNum
1667
1668 def PostProcessBody(self, TextBody, IncludeEmbedOnly=True):
1669 NewTextBody = []
1670 OldTextBody = []
1671 IncTextBody = []
1672 StructBody = []
1673 IncludeLine = False
1674 EmbedFound = False
1675 StructName = ''
1676 ArrayVarName = ''
1677 VariableName = ''
1678 Count = 0
1679 Level = 0
1680 IsCommonStruct = False
1681
1682 for Line in TextBody:
1683 if Line.startswith('#define '):
1684 IncTextBody.append(Line)
1685 continue
1686
1687 if not Line.startswith('/* EMBED_STRUCT:'):
1688 Match = False
1689 else:
1690 Match = re.match("^/\\*\\sEMBED_STRUCT:([\\w\\[\\]\\*]+):\
1691 ([\\w\\[\\]\\*]+):(\\w+):(START|END)([\\s\\d]+)\\*/([\\s\\S]*)", Line)
1692
1693 if Match:
1694 ArrayMarker = Match.group(5)
1695 if Match.group(4) == 'END':
1696 Level -= 1
1697 if Level == 0:
1698 Line = Match.group(6)
1699 else: # 'START'
1700 Level += 1
1701 if Level == 1:
1702 Line = Match.group(6)
1703 else:
1704 EmbedFound = True
1705 TagStr = Match.group(3)
1706 if TagStr.startswith('TAG_'):
1707 try:
1708 TagVal = int(TagStr[4:], 16)
1709 except Exception:
1710 TagVal = -1
1711 if (TagVal >= 0) and (TagVal < self._MinCfgTagId):
1712 IsCommonStruct = True
1713
1714 if Level == 1:
1715 if IsCommonStruct:
1716 Suffix = ' /* _COMMON_STRUCT_START_ */'
1717 else:
1718 Suffix = ''
1719 StructBody = ['typedef struct {%s' % Suffix]
1720 StructName = Match.group(1)
1721 StructType = Match.group(2)
1722 VariableName = Match.group(3)
1723 MatchOffset = re.search('/\\*\\*\\sOffset\\s0x\
1724 ([a-fA-F0-9]+)', Line)
1725 if MatchOffset:
1726 Offset = int(MatchOffset.group(1), 16)
1727 else:
1728 Offset = None
1729 IncludeLine = True
1730
1731 ModifiedStructType = StructType.rstrip()
1732 if ModifiedStructType.endswith(']'):
1733 Idx = ModifiedStructType.index('[')
1734 if ArrayMarker != ' ':
1735 # Auto array size
1736 OldTextBody.append('')
1737 ArrayVarName = VariableName
1738 if int(ArrayMarker) == 1000:
1739 Count = 1
1740 else:
1741 Count = int(ArrayMarker) + 1000
1742 else:
1743 if Count < 1000:
1744 Count += 1
1745
1746 VariableTemp = ArrayVarName + '[%d]' % (
1747 Count if Count < 1000 else Count - 1000)
1748 OldTextBody[-1] = self.CreateField(
1749 None, VariableTemp, 0, Offset,
1750 ModifiedStructType[:Idx], '',
1751 'Structure Array', '')
1752 else:
1753 ArrayVarName = ''
1754 OldTextBody.append(self.CreateField(
1755 None, VariableName, 0, Offset,
1756 ModifiedStructType, '', '', ''))
1757
1758 if IncludeLine:
1759 StructBody.append(Line)
1760 else:
1761 OldTextBody.append(Line)
1762
1763 if Match and Match.group(4) == 'END':
1764 if Level == 0:
1765 if (StructType != Match.group(2)) or \
1766 (VariableName != Match.group(3)):
1767 print("Unmatched struct name '%s' and '%s' !" %
1768 (StructName, Match.group(2)))
1769 else:
1770 if IsCommonStruct:
1771 Suffix = ' /* _COMMON_STRUCT_END_ */'
1772 else:
1773 Suffix = ''
1774 Line = '} %s;%s\n\n\n' % (StructName, Suffix)
1775 StructBody.append(Line)
1776 if (Line not in NewTextBody) and \
1777 (Line not in OldTextBody):
1778 NewTextBody.extend(StructBody)
1779 IncludeLine = False
1780 IsCommonStruct = False
1781
1782 if not IncludeEmbedOnly:
1783 NewTextBody.extend(OldTextBody)
1784
1785 if EmbedFound:
1786 NewTextBody = self.PostProcessBody(NewTextBody, False)
1787
1788 NewTextBody = IncTextBody + NewTextBody
1789 return NewTextBody
1790
1791 def WriteHeaderFile(self, TxtBody, FileName, Type='h'):
1792 FileNameDef = os.path.basename(FileName).replace('.', '_')
1793 FileNameDef = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', FileNameDef)
1794 FileNameDef = re.sub('([a-z0-9])([A-Z])', r'\1_\2',
1795 FileNameDef).upper()
1796
1797 Lines = []
1798 Lines.append("%s\n" % GetCopyrightHeader(Type))
1799 Lines.append("#ifndef __%s__\n" % FileNameDef)
1800 Lines.append("#define __%s__\n\n" % FileNameDef)
1801 if Type == 'h':
1802 Lines.append("#pragma pack(1)\n\n")
1803 Lines.extend(TxtBody)
1804 if Type == 'h':
1805 Lines.append("#pragma pack()\n\n")
1806 Lines.append("#endif\n")
1807
1808 # Don't rewrite if the contents are the same
1809 Create = True
1810 if os.path.exists(FileName):
1811 HdrFile = open(FileName, "r")
1812 OrgTxt = HdrFile.read()
1813 HdrFile.close()
1814
1815 NewTxt = ''.join(Lines)
1816 if OrgTxt == NewTxt:
1817 Create = False
1818
1819 if Create:
1820 HdrFile = open(FileName, "w")
1821 HdrFile.write(''.join(Lines))
1822 HdrFile.close()
1823
1824 def CreateHeaderFile(self, HdrFileName, ComHdrFileName=''):
1825 LastStruct = ''
1826 SpaceIdx = 0
1827 Offset = 0
1828 FieldIdx = 0
1829 LastFieldIdx = 0
1830 ResvOffset = 0
1831 ResvIdx = 0
1832 TxtBody = []
1833 LineBuffer = []
1834 CfgTags = []
1835 LastVisible = True
1836
1837 TxtBody.append("typedef struct {\n")
1838 for Item in self._CfgItemList:
1839 # Search for CFGDATA tags
1840 Embed = Item["embed"].upper()
1841 if Embed.endswith(':START'):
1842 Match = re.match(r'(\w+)_CFG_DATA:TAG_([0-9A-F]+):START',
1843 Embed)
1844 if Match:
1845 TagName = Match.group(1)
1846 TagId = int(Match.group(2), 16)
1847 CfgTags.append((TagId, TagName))
1848
1849 # Only process visible items
1850 NextVisible = LastVisible
1851
1852 if LastVisible and (Item['header'] == 'OFF'):
1853 NextVisible = False
1854 ResvOffset = Item['offset']
1855 elif (not LastVisible) and Item['header'] == 'ON':
1856 NextVisible = True
1857 Name = "ReservedUpdSpace%d" % ResvIdx
1858 ResvIdx = ResvIdx + 1
1859 TxtBody.append(self.CreateField(
1860 Item, Name, Item["offset"] - ResvOffset,
1861 ResvOffset, '', '', '', ''))
1862 FieldIdx += 1
1863
1864 if Offset < Item["offset"]:
1865 if LastVisible:
1866 Name = "UnusedUpdSpace%d" % SpaceIdx
1867 LineBuffer.append(self.CreateField
1868 (Item, Name, Item["offset"] -
1869 Offset, Offset, '', '', '', ''))
1870 FieldIdx += 1
1871 SpaceIdx = SpaceIdx + 1
1872 Offset = Item["offset"]
1873
1874 LastVisible = NextVisible
1875
1876 Offset = Offset + Item["length"]
1877 if LastVisible:
1878 for Each in LineBuffer:
1879 TxtBody.append(Each)
1880 LineBuffer = []
1881 Embed = Item["embed"].upper()
1882 if Embed.endswith(':START') or Embed.endswith(':END'):
1883 # EMBED_STRUCT: StructName : \
1884 # ItemName : VariableName : START|END
1885 Name, ArrayNum = self.GetStructArrayInfo(Item["struct"])
1886 Remaining = Item["embed"]
1887 if (LastFieldIdx + 1 == FieldIdx) and (LastStruct == Name):
1888 ArrayMarker = ' '
1889 else:
1890 ArrayMarker = '%d' % ArrayNum
1891 LastFieldIdx = FieldIdx
1892 LastStruct = Name
1893 Marker = '/* EMBED_STRUCT:%s:%s%s*/ ' % (Name, Remaining,
1894 ArrayMarker)
1895 # if Embed.endswith(':START') and Comment != '':
1896 # Marker = '/* COMMENT:%s */ \n' % Item["comment"] + Marker
1897 else:
1898 if Embed == '':
1899 Marker = ''
1900 else:
1901 self.Error = "Invalid embedded structure \
1902 format '%s'!\n" % Item["embed"]
1903 return 4
1904
1905 # Generate bit fields for structure
1906 if len(Item['subreg']) > 0 and Item["struct"]:
1907 StructType = Item["struct"]
1908 StructName, ArrayNum = self.GetStructArrayInfo(StructType)
1909 if (LastFieldIdx + 1 == FieldIdx) and \
1910 (LastStruct == Item["struct"]):
1911 ArrayMarker = ' '
1912 else:
1913 ArrayMarker = '%d' % ArrayNum
1914 TxtBody.append('/* EMBED_STRUCT:%s:%s:%s:START%s*/\n' %
1915 (StructName, StructType, Item["cname"],
1916 ArrayMarker))
1917 for SubItem in Item['subreg']:
1918 Name = SubItem["cname"]
1919 if Name.startswith(Item["cname"]):
1920 Name = Name[len(Item["cname"]) + 1:]
1921 Line = self.CreateField(
1922 SubItem, Name, SubItem["bitunit"],
1923 SubItem["offset"], SubItem['struct'],
1924 SubItem['name'], SubItem['help'],
1925 SubItem['option'], SubItem['bitlength'])
1926 TxtBody.append(Line)
1927 TxtBody.append('/* EMBED_STRUCT:%s:%s:%s:END%s*/\n' %
1928 (StructName, StructType, Item["cname"],
1929 ArrayMarker))
1930 LastFieldIdx = FieldIdx
1931 LastStruct = Item["struct"]
1932 FieldIdx += 1
1933 else:
1934 FieldIdx += 1
1935 Line = Marker + self.CreateField(
1936 Item, Item["cname"], Item["length"], Item["offset"],
1937 Item['struct'], Item['name'], Item['help'],
1938 Item['option'])
1939 TxtBody.append(Line)
1940
1941 TxtBody.append("}\n\n")
1942
1943 # Handle the embedded data structure
1944 TxtBody = self.PostProcessBody(TxtBody)
1945 ComBody, TxtBody = self.SplitTextBody(TxtBody)
1946
1947 # Prepare TAG defines
1948 PltTagDefTxt = ['\n']
1949 ComTagDefTxt = ['\n']
1950 for TagId, TagName in sorted(CfgTags):
1951 TagLine = '#define %-30s 0x%03X\n' % ('CDATA_%s_TAG' %
1952 TagName, TagId)
1953 if TagId < self._MinCfgTagId:
1954 # TAG ID < 0x100, it is a generic TAG
1955 ComTagDefTxt.append(TagLine)
1956 else:
1957 PltTagDefTxt.append(TagLine)
1958 PltTagDefTxt.append('\n\n')
1959 ComTagDefTxt.append('\n\n')
1960
1961 # Write file back
1962 self.WriteHeaderFile(PltTagDefTxt + TxtBody, HdrFileName)
1963 if ComHdrFileName:
1964 self.WriteHeaderFile(ComTagDefTxt + ComBody, ComHdrFileName)
1965
1966 return 0
1967
1968 def UpdateConfigItemValue(self, Item, ValueStr):
1969 IsArray = True if Item['value'].startswith('{') else False
1970 IsString = True if Item['value'].startswith("'") else False
1971 Bytes = self.ValueToByteArray(ValueStr, Item['length'])
1972 if IsString:
1973 NewValue = "'%s'" % Bytes.decode("utf-8")
1974 elif IsArray:
1975 NewValue = Bytes2Str(Bytes)
1976 else:
1977 Fmt = '0x%X' if Item['value'].startswith('0x') else '%d'
1978 NewValue = Fmt % Bytes2Val(Bytes)
1979 Item['value'] = NewValue
1980
1981 def LoadDefaultFromBinaryArray(self, BinDat, IgnoreFind=False):
1982 FindOff = 0
1983 StartOff = 0
1984 for Item in self._CfgItemList:
1985 if Item['length'] == 0:
1986 continue
1987 if not IgnoreFind and Item['find']:
1988 FindBin = Item['find'].encode()
1989 Offset = BinDat.find(FindBin)
1990 if Offset >= 0:
1991 TestOff = BinDat[Offset+len(FindBin):].find(FindBin)
1992 if TestOff >= 0:
1993 raise Exception('Multiple match found for "%s" !' %
1994 Item['find'])
1995 FindOff = Offset + len(FindBin)
1996 StartOff = Item['offset']
1997 else:
1998 raise Exception('Could not find "%s" !' % Item['find'])
1999 if Item['offset'] + Item['length'] > len(BinDat):
2000 raise Exception('Mismatching format between DSC \
2001 and BIN files !')
2002 Offset = FindOff + (Item['offset'] - StartOff)
2003 ValStr = Bytes2Str(BinDat[Offset: Offset + Item['length']])
2004 self.UpdateConfigItemValue(Item, ValStr)
2005
2006 self.UpdateDefaultValue()
2007
2008 def PatchBinaryArray(self, BinDat):
2009 FileOff = 0
2010 Offset = 0
2011 FindOff = 0
2012
2013 PatchList = []
2014 CfgBin = bytearray()
2015 for Item in self._CfgItemList:
2016 if Item['length'] == 0:
2017 continue
2018
2019 if Item['find']:
2020 if len(CfgBin) > 0:
2021 PatchList.append((FileOff, CfgBin))
2022 FindBin = Item['find'].encode()
2023 FileOff = BinDat.find(FindBin)
2024 if FileOff < 0:
2025 raise Exception('Could not find "%s" !' % Item['find'])
2026 else:
2027 TestOff = BinDat[FileOff+len(FindBin):].find(FindBin)
2028 if TestOff >= 0:
2029 raise Exception('Multiple match found for "%s" !' %
2030 Item['find'])
2031 FileOff += len(FindBin)
2032 Offset = Item['offset']
2033 FindOff = Offset
2034 CfgBin = bytearray()
2035
2036 if Item['offset'] > Offset:
2037 Gap = Item['offset'] - Offset
2038 CfgBin.extend(b'\x00' * Gap)
2039
2040 if Item['type'] == 'Reserved' and Item['option'] == '$SKIP':
2041 # keep old data
2042 NewOff = FileOff + (Offset - FindOff)
2043 FileData = bytearray(BinDat[NewOff: NewOff + Item['length']])
2044 CfgBin.extend(FileData)
2045 else:
2046 CfgBin.extend(self.ValueToByteArray(Item['value'],
2047 Item['length']))
2048 Offset = Item['offset'] + Item['length']
2049
2050 if len(CfgBin) > 0:
2051 PatchList.append((FileOff, CfgBin))
2052
2053 for FileOff, CfgBin in PatchList:
2054 Length = len(CfgBin)
2055 if FileOff + Length < len(BinDat):
2056 BinDat[FileOff:FileOff+Length] = CfgBin[:]
2057
2058 return BinDat
2059
2060 def GenerateBinaryArray(self):
2061 Offset = 0
2062 BinDat = bytearray()
2063 for Item in self._CfgItemList:
2064 if Item['offset'] > Offset:
2065 Gap = Item['offset'] - Offset
2066 BinDat.extend(b'\x00' * Gap)
2067 BinDat.extend(self.ValueToByteArray(Item['value'], Item['length']))
2068 Offset = Item['offset'] + Item['length']
2069 return BinDat
2070
2071 def GenerateBinary(self, BinFileName):
2072 BinFile = open(BinFileName, "wb")
2073 BinFile.write(self.GenerateBinaryArray())
2074 BinFile.close()
2075 return 0
2076
2077 def GenerateDataIncFile(self, DatIncFileName, BinFile=None):
2078 # Put a prefix GUID before CFGDATA so that it can be located later on
2079 Prefix = b'\xa7\xbd\x7f\x73\x20\x1e\x46\xd6\xbe\x8f\
2080 x64\x12\x05\x8d\x0a\xa8'
2081 if BinFile:
2082 Fin = open(BinFile, 'rb')
2083 BinDat = Prefix + bytearray(Fin.read())
2084 Fin.close()
2085 else:
2086 BinDat = Prefix + self.GenerateBinaryArray()
2087
2088 FileName = os.path.basename(DatIncFileName).upper()
2089 FileName = FileName.replace('.', '_')
2090
2091 TxtLines = []
2092
2093 TxtLines.append("UINT8 mConfigDataBlob[%d] = {\n" % len(BinDat))
2094 Count = 0
2095 Line = [' ']
2096 for Each in BinDat:
2097 Line.append('0x%02X, ' % Each)
2098 Count = Count + 1
2099 if (Count & 0x0F) == 0:
2100 Line.append('\n')
2101 TxtLines.append(''.join(Line))
2102 Line = [' ']
2103 if len(Line) > 1:
2104 TxtLines.append(''.join(Line) + '\n')
2105
2106 TxtLines.append("};\n\n")
2107
2108 self.WriteHeaderFile(TxtLines, DatIncFileName, 'inc')
2109
2110 return 0
2111
2112 def CheckCfgData(self):
2113 # Check if CfgData contains any duplicated name
2114 def AddItem(Item, ChkList):
2115 Name = Item['cname']
2116 if Name in ChkList:
2117 return Item
2118 if Name not in ['Dummy', 'Reserved', 'CfgHeader', 'CondValue']:
2119 ChkList.append(Name)
2120 return None
2121
2122 Duplicate = None
2123 ChkList = []
2124 for Item in self._CfgItemList:
2125 Duplicate = AddItem(Item, ChkList)
2126 if not Duplicate:
2127 for SubItem in Item['subreg']:
2128 Duplicate = AddItem(SubItem, ChkList)
2129 if Duplicate:
2130 break
2131 if Duplicate:
2132 break
2133 if Duplicate:
2134 self.Error = "Duplicated CFGDATA '%s' found !\n" % \
2135 Duplicate['cname']
2136 return -1
2137 return 0
2138
2139 def PrintData(self):
2140 for Item in self._CfgItemList:
2141 if not Item['length']:
2142 continue
2143 print("%-10s @Offset:0x%04X Len:%3d Val:%s" %
2144 (Item['cname'], Item['offset'], Item['length'],
2145 Item['value']))
2146 for SubItem in Item['subreg']:
2147 print(" %-20s BitOff:0x%04X BitLen:%-3d Val:%s" %
2148 (SubItem['cname'], SubItem['bitoffset'],
2149 SubItem['bitlength'], SubItem['value']))
2150
2151 def FormatArrayValue(self, Input, Length):
2152 Dat = self.ValueToByteArray(Input, Length)
2153 return ','.join('0x%02X' % Each for Each in Dat)
2154
2155 def GetItemOptionList(self, Item):
2156 TmpList = []
2157 if Item['type'] == "Combo":
2158 if not Item['option'] in self._BuidinOption:
2159 OptList = Item['option'].split(',')
2160 for Option in OptList:
2161 Option = Option.strip()
2162 try:
2163 (OpVal, OpStr) = Option.split(':')
2164 except Exception:
2165 raise Exception("Invalide option format '%s' !" %
2166 Option)
2167 TmpList.append((OpVal, OpStr))
2168 return TmpList
2169
2170 def WriteBsfStruct(self, BsfFd, Item):
2171 if Item['type'] == "None":
2172 Space = "gPlatformFspPkgTokenSpaceGuid"
2173 else:
2174 Space = Item['space']
2175 Line = " $%s_%s" % (Space, Item['cname'])
2176 Match = re.match("\\s*(\\{.+\\})\\s*", Item['value'])
2177 if Match:
2178 DefaultValue = self.FormatArrayValue(Match.group(1).strip(),
2179 Item['length'])
2180 else:
2181 DefaultValue = Item['value'].strip()
2182 if 'bitlength' in Item:
2183 if Item['bitlength']:
2184 BsfFd.write(" %s%s%4d bits $_DEFAULT_ = %s\n" %
2185 (Line, ' ' * (64 - len(Line)), Item['bitlength'],
2186 DefaultValue))
2187 else:
2188 if Item['length']:
2189 BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" %
2190 (Line, ' ' * (64 - len(Line)), Item['length'],
2191 DefaultValue))
2192
2193 return self.GetItemOptionList(Item)
2194
2195 def GetBsfOption(self, OptionName):
2196 if OptionName in self._CfgOptsDict:
2197 return self._CfgOptsDict[OptionName]
2198 else:
2199 return OptionName
2200
2201 def WriteBsfOption(self, BsfFd, Item):
2202 PcdName = Item['space'] + '_' + Item['cname']
2203 WriteHelp = 0
2204 BsfLines = []
2205 if Item['type'] == "Combo":
2206 if Item['option'] in self._BuidinOption:
2207 Options = self._BuidinOption[Item['option']]
2208 else:
2209 Options = self.GetBsfOption(PcdName)
2210 BsfLines.append(' %s $%s, "%s", &%s,\n' % (
2211 Item['type'], PcdName, Item['name'], Options))
2212 WriteHelp = 1
2213 elif Item['type'].startswith("EditNum"):
2214 Match = re.match("EditNum\\s*,\\s*(HEX|DEC)\\s*,\\s*\\(\
2215 (\\d+|0x[0-9A-Fa-f]+)\\s*,\\s*(\\d+|0x[0-9A-Fa-f]+)\\)", Item['type'])
2216 if Match:
2217 BsfLines.append(' EditNum $%s, "%s", %s,\n' % (
2218 PcdName, Item['name'], Match.group(1)))
2219 WriteHelp = 2
2220 elif Item['type'].startswith("EditText"):
2221 BsfLines.append(' %s $%s, "%s",\n' % (Item['type'], PcdName,
2222 Item['name']))
2223 WriteHelp = 1
2224 elif Item['type'] == "Table":
2225 Columns = Item['option'].split(',')
2226 if len(Columns) != 0:
2227 BsfLines.append(' %s $%s "%s",' % (Item['type'], PcdName,
2228 Item['name']))
2229 for Col in Columns:
2230 Fmt = Col.split(':')
2231 if len(Fmt) != 3:
2232 raise Exception("Column format '%s' is invalid !" %
2233 Fmt)
2234 try:
2235 Dtype = int(Fmt[1].strip())
2236 except Exception:
2237 raise Exception("Column size '%s' is invalid !" %
2238 Fmt[1])
2239 BsfLines.append('\n Column "%s", %d bytes, %s' %
2240 (Fmt[0].strip(), Dtype, Fmt[2].strip()))
2241 BsfLines.append(',\n')
2242 WriteHelp = 1
2243
2244 if WriteHelp > 0:
2245 HelpLines = Item['help'].split('\\n\\r')
2246 FirstLine = True
2247 for HelpLine in HelpLines:
2248 if FirstLine:
2249 FirstLine = False
2250 BsfLines.append(' Help "%s"\n' % (HelpLine))
2251 else:
2252 BsfLines.append(' "%s"\n' % (HelpLine))
2253 if WriteHelp == 2:
2254 BsfLines.append(' "Valid range: %s ~ %s"\n' %
2255 (Match.group(2), Match.group(3)))
2256
2257 if len(Item['condition']) > 4:
2258 CondList = Item['condition'].split(',')
2259 Idx = 0
2260 for Cond in CondList:
2261 Cond = Cond.strip()
2262 if Cond.startswith('#'):
2263 BsfLines.insert(Idx, Cond + '\n')
2264 Idx += 1
2265 elif Cond.startswith('@#'):
2266 BsfLines.append(Cond[1:] + '\n')
2267
2268 for Line in BsfLines:
2269 BsfFd.write(Line)
2270
2271 def WriteBsfPages(self, PageTree, BsfFd):
2272 BsfFd.write('\n')
2273 Key = next(iter(PageTree))
2274 for Page in PageTree[Key]:
2275 PageName = next(iter(Page))
2276 BsfFd.write('Page "%s"\n' % self._CfgPageDict[PageName])
2277 if len(PageTree[Key]):
2278 self.WriteBsfPages(Page, BsfFd)
2279
2280 BsfItems = []
2281 for Item in self._CfgItemList:
2282 if Item['name'] != '':
2283 if Item['page'] != PageName:
2284 continue
2285 if len(Item['subreg']) > 0:
2286 for SubItem in Item['subreg']:
2287 if SubItem['name'] != '':
2288 BsfItems.append(SubItem)
2289 else:
2290 BsfItems.append(Item)
2291
2292 BsfItems.sort(key=lambda x: x['order'])
2293
2294 for Item in BsfItems:
2295 self.WriteBsfOption(BsfFd, Item)
2296 BsfFd.write("EndPage\n\n")
2297
2298 def GenerateBsfFile(self, BsfFile):
2299
2300 if BsfFile == '':
2301 self.Error = "BSF output file '%s' is invalid" % BsfFile
2302 return 1
2303
2304 Error = 0
2305 OptionDict = {}
2306 BsfFd = open(BsfFile, "w")
2307 BsfFd.write("%s\n" % GetCopyrightHeader('bsf'))
2308 BsfFd.write("%s\n" % self._GlobalDataDef)
2309 BsfFd.write("StructDef\n")
2310 NextOffset = -1
2311 for Item in self._CfgItemList:
2312 if Item['find'] != '':
2313 BsfFd.write('\n Find "%s"\n' % Item['find'])
2314 NextOffset = Item['offset'] + Item['length']
2315 if Item['name'] != '':
2316 if NextOffset != Item['offset']:
2317 BsfFd.write(" Skip %d bytes\n" %
2318 (Item['offset'] - NextOffset))
2319 if len(Item['subreg']) > 0:
2320 NextOffset = Item['offset']
2321 BitsOffset = NextOffset * 8
2322 for SubItem in Item['subreg']:
2323 BitsOffset += SubItem['bitlength']
2324 if SubItem['name'] == '':
2325 if 'bitlength' in SubItem:
2326 BsfFd.write(" Skip %d bits\n" %
2327 (SubItem['bitlength']))
2328 else:
2329 BsfFd.write(" Skip %d bytes\n" %
2330 (SubItem['length']))
2331 else:
2332 Options = self.WriteBsfStruct(BsfFd, SubItem)
2333 if len(Options) > 0:
2334 OptionDict[SubItem
2335 ['space']+'_'+SubItem
2336 ['cname']] = Options
2337
2338 NextBitsOffset = (Item['offset'] + Item['length']) * 8
2339 if NextBitsOffset > BitsOffset:
2340 BitsGap = NextBitsOffset - BitsOffset
2341 BitsRemain = BitsGap % 8
2342 if BitsRemain:
2343 BsfFd.write(" Skip %d bits\n" % BitsRemain)
2344 BitsGap -= BitsRemain
2345 BytesRemain = BitsGap // 8
2346 if BytesRemain:
2347 BsfFd.write(" Skip %d bytes\n" %
2348 BytesRemain)
2349 NextOffset = Item['offset'] + Item['length']
2350 else:
2351 NextOffset = Item['offset'] + Item['length']
2352 Options = self.WriteBsfStruct(BsfFd, Item)
2353 if len(Options) > 0:
2354 OptionDict[Item['space']+'_'+Item['cname']] = Options
2355 BsfFd.write("\nEndStruct\n\n")
2356
2357 BsfFd.write("%s" % self._BuidinOptionTxt)
2358
2359 NameList = []
2360 OptionList = []
2361 for Each in sorted(OptionDict):
2362 if OptionDict[Each] not in OptionList:
2363 NameList.append(Each)
2364 OptionList.append(OptionDict[Each])
2365 BsfFd.write("List &%s\n" % Each)
2366 for Item in OptionDict[Each]:
2367 BsfFd.write(' Selection %s , "%s"\n' %
2368 (self.EvaluateExpress(Item[0]), Item[1]))
2369 BsfFd.write("EndList\n\n")
2370 else:
2371 # Item has idential options as other item
2372 # Try to reuse the previous options instead
2373 Idx = OptionList.index(OptionDict[Each])
2374 self._CfgOptsDict[Each] = NameList[Idx]
2375
2376 BsfFd.write("BeginInfoBlock\n")
2377 BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']))
2378 BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']))
2379 BsfFd.write("EndInfoBlock\n\n")
2380
2381 self.WriteBsfPages(self._CfgPageTree, BsfFd)
2382
2383 BsfFd.close()
2384 return Error
2385
2386 def WriteDeltaLine(self, OutLines, Name, ValStr, IsArray):
2387 if IsArray:
2388 Output = '%s | { %s }' % (Name, ValStr)
2389 else:
2390 Output = '%s | 0x%X' % (Name, Array2Val(ValStr))
2391 OutLines.append(Output)
2392
2393 def WriteDeltaFile(self, OutFile, PlatformId, OutLines):
2394 DltFd = open(OutFile, "w")
2395 DltFd.write("%s\n" % GetCopyrightHeader('dlt', True))
2396 if PlatformId is not None:
2397 DltFd.write('#\n')
2398 DltFd.write('# Delta configuration values \
2399 for platform ID 0x%04X\n' % PlatformId)
2400 DltFd.write('#\n\n')
2401 for Line in OutLines:
2402 DltFd.write('%s\n' % Line)
2403 DltFd.close()
2404
2405 def GenerateDeltaFile(self, OutFile, AbsfFile):
2406 # Parse ABSF Build in dict
2407 if not os.path.exists(AbsfFile):
2408 Lines = []
2409 else:
2410 with open(AbsfFile) as Fin:
2411 Lines = Fin.readlines()
2412
2413 AbsfBuiltValDict = {}
2414 Process = False
2415 for Line in Lines:
2416 Line = Line.strip()
2417 if Line.startswith('StructDef'):
2418 Process = True
2419 if Line.startswith('EndStruct'):
2420 break
2421 if not Process:
2422 continue
2423 Match = re.match('\\s*\\$gCfgData_(\\w+)\\s+\
2424 (\\d+)\\s+(bits|bytes)\\s+\\$_AS_BUILT_\\s+=\\s+(.+)\\$', Line)
2425 if Match:
2426 if Match.group(1) not in AbsfBuiltValDict:
2427 AbsfBuiltValDict[Match.group(1)] = Match.group(4).strip()
2428 else:
2429 raise Exception("Duplicated configuration \
2430 name '%s' found !", Match.group(1))
2431
2432 # Match config item in DSC
2433 PlatformId = None
2434 OutLines = []
2435 TagName = ''
2436 Level = 0
2437 for Item in self._CfgItemList:
2438 Name = None
2439 if Level == 0 and Item['embed'].endswith(':START'):
2440 TagName = Item['embed'].split(':')[0]
2441 Level += 1
2442 if Item['cname'] in AbsfBuiltValDict:
2443 ValStr = AbsfBuiltValDict[Item['cname']]
2444 Name = '%s.%s' % (TagName, Item['cname'])
2445 if not Item['subreg'] and Item['value'].startswith('{'):
2446 Value = Array2Val(Item['value'])
2447 IsArray = True
2448 else:
2449 Value = int(Item['value'], 16)
2450 IsArray = False
2451 AbsfVal = Array2Val(ValStr)
2452 if AbsfVal != Value:
2453 if 'PLATFORMID_CFG_DATA.PlatformId' == Name:
2454 PlatformId = AbsfVal
2455 self.WriteDeltaLine(OutLines, Name, ValStr, IsArray)
2456 else:
2457 if 'PLATFORMID_CFG_DATA.PlatformId' == Name:
2458 raise Exception("'PlatformId' has the \
2459 same value as DSC default !")
2460
2461 if Item['subreg']:
2462 for SubItem in Item['subreg']:
2463 if SubItem['cname'] in AbsfBuiltValDict:
2464 ValStr = AbsfBuiltValDict[SubItem['cname']]
2465 if Array2Val(ValStr) == int(SubItem['value'], 16):
2466 continue
2467 Name = '%s.%s.%s' % (TagName, Item['cname'],
2468 SubItem['cname'])
2469 self.WriteDeltaLine(OutLines, Name, ValStr, False)
2470
2471 if Item['embed'].endswith(':END'):
2472 Level -= 1
2473
2474 if PlatformId is None and Lines:
2475 raise Exception("'PlatformId' configuration \
2476 is missing in ABSF file!")
2477 else:
2478 PlatformId = 0
2479
2480 self.WriteDeltaFile(OutFile, PlatformId, Lines)
2481
2482 return 0
2483
2484 def GenerateDscFile(self, OutFile):
2485 DscFd = open(OutFile, "w")
2486 for Line in self._DscLines:
2487 DscFd.write(Line + '\n')
2488 DscFd.close()
2489 return 0
2490
2491
2492 def Usage():
2493 print('\n'.join([
2494 "GenCfgData Version 0.01",
2495 "Usage:",
2496 " GenCfgData GENINC BinFile \
2497 IncOutFile [-D Macros]",
2498 " GenCfgData GENPKL DscFile \
2499 PklOutFile [-D Macros]",
2500 " GenCfgData GENINC DscFile[;DltFile] \
2501 IncOutFile [-D Macros]",
2502 " GenCfgData GENBIN DscFile[;DltFile] \
2503 BinOutFile [-D Macros]",
2504 " GenCfgData GENBSF DscFile[;DltFile] \
2505 BsfOutFile [-D Macros]",
2506 " GenCfgData GENDLT DscFile[;AbsfFile] \
2507 DltOutFile [-D Macros]",
2508 " GenCfgData GENDSC DscFile \
2509 DscOutFile [-D Macros]",
2510 " GenCfgData GENHDR DscFile[;DltFile] \
2511 HdrOutFile[;ComHdrOutFile] [-D Macros]"
2512 ]))
2513
2514
2515 def Main():
2516 #
2517 # Parse the options and args
2518 #
2519 argc = len(sys.argv)
2520 if argc < 4:
2521 Usage()
2522 return 1
2523
2524 GenCfgData = CGenCfgData()
2525 Command = sys.argv[1].upper()
2526 OutFile = sys.argv[3]
2527
2528 if argc > 5 and GenCfgData.ParseMacros(sys.argv[4:]) != 0:
2529 raise Exception("ERROR: Macro parsing failed !")
2530
2531 FileList = sys.argv[2].split(';')
2532 if len(FileList) == 2:
2533 DscFile = FileList[0]
2534 DltFile = FileList[1]
2535 elif len(FileList) == 1:
2536 DscFile = FileList[0]
2537 DltFile = ''
2538 else:
2539 raise Exception("ERROR: Invalid parameter '%s' !" % sys.argv[2])
2540
2541 if Command == "GENDLT" and DscFile.endswith('.dlt'):
2542 # It needs to expand an existing DLT file
2543 DltFile = DscFile
2544 Lines = CGenCfgData.ExpandIncludeFiles(DltFile)
2545 OutTxt = ''.join([x[0] for x in Lines])
2546 OutFile = open(OutFile, "w")
2547 OutFile.write(OutTxt)
2548 OutFile.close()
2549 return 0
2550
2551 if not os.path.exists(DscFile):
2552 raise Exception("ERROR: Cannot open file '%s' !" % DscFile)
2553
2554 CfgBinFile = ''
2555 if DltFile:
2556 if not os.path.exists(DltFile):
2557 raise Exception("ERROR: Cannot open file '%s' !" % DltFile)
2558 if Command == "GENDLT":
2559 CfgBinFile = DltFile
2560 DltFile = ''
2561
2562 BinFile = ''
2563 if (DscFile.lower().endswith('.bin')) and (Command == "GENINC"):
2564 # It is binary file
2565 BinFile = DscFile
2566 DscFile = ''
2567
2568 if BinFile:
2569 if GenCfgData.GenerateDataIncFile(OutFile, BinFile) != 0:
2570 raise Exception(GenCfgData.Error)
2571 return 0
2572
2573 if DscFile.lower().endswith('.pkl'):
2574 with open(DscFile, "rb") as PklFile:
2575 GenCfgData.__dict__ = marshal.load(PklFile)
2576 else:
2577 if GenCfgData.ParseDscFile(DscFile) != 0:
2578 raise Exception(GenCfgData.Error)
2579
2580 # if GenCfgData.CheckCfgData() != 0:
2581 # raise Exception(GenCfgData.Error)
2582
2583 if GenCfgData.CreateVarDict() != 0:
2584 raise Exception(GenCfgData.Error)
2585
2586 if Command == 'GENPKL':
2587 with open(OutFile, "wb") as PklFile:
2588 marshal.dump(GenCfgData.__dict__, PklFile)
2589 return 0
2590
2591 if DltFile and Command in ['GENHDR', 'GENBIN', 'GENINC', 'GENBSF']:
2592 if GenCfgData.OverrideDefaultValue(DltFile) != 0:
2593 raise Exception(GenCfgData.Error)
2594
2595 if GenCfgData.UpdateDefaultValue() != 0:
2596 raise Exception(GenCfgData.Error)
2597
2598 # GenCfgData.PrintData ()
2599
2600 if sys.argv[1] == "GENBIN":
2601 if GenCfgData.GenerateBinary(OutFile) != 0:
2602 raise Exception(GenCfgData.Error)
2603
2604 elif sys.argv[1] == "GENHDR":
2605 OutFiles = OutFile.split(';')
2606 BrdOutFile = OutFiles[0].strip()
2607 if len(OutFiles) > 1:
2608 ComOutFile = OutFiles[1].strip()
2609 else:
2610 ComOutFile = ''
2611 if GenCfgData.CreateHeaderFile(BrdOutFile, ComOutFile) != 0:
2612 raise Exception(GenCfgData.Error)
2613
2614 elif sys.argv[1] == "GENBSF":
2615 if GenCfgData.GenerateBsfFile(OutFile) != 0:
2616 raise Exception(GenCfgData.Error)
2617
2618 elif sys.argv[1] == "GENINC":
2619 if GenCfgData.GenerateDataIncFile(OutFile) != 0:
2620 raise Exception(GenCfgData.Error)
2621
2622 elif sys.argv[1] == "GENDLT":
2623 if GenCfgData.GenerateDeltaFile(OutFile, CfgBinFile) != 0:
2624 raise Exception(GenCfgData.Error)
2625
2626 elif sys.argv[1] == "GENDSC":
2627 if GenCfgData.GenerateDscFile(OutFile) != 0:
2628 raise Exception(GenCfgData.Error)
2629
2630 else:
2631 raise Exception("Unsuported command '%s' !" % Command)
2632
2633 return 0
2634
2635
2636 if __name__ == '__main__':
2637 sys.exit(Main())