diff options
Diffstat (limited to 'IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py')
-rw-r--r-- | IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py | 369 |
1 files changed, 76 insertions, 293 deletions
diff --git a/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py b/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py index d2ca7145ae..923fa6eead 100644 --- a/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py +++ b/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py @@ -10,277 +10,38 @@ import os
import re
import sys
-from datetime import date
+
from collections import OrderedDict
-from functools import reduce
+from datetime import date
-from GenCfgOpt import CGenCfgOpt
+from FspGenCfgData import CFspBsf2Dsc, CGenCfgData
__copyright_tmp__ = """## @file
#
-# YAML CFGDATA %s File.
+# Slim Bootloader CFGDATA %s File.
#
-# Copyright(c) %4d, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
"""
-__copyright_dsc__ = """## @file
-#
-# Copyright (c) %04d, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[PcdsDynamicVpd.Upd]
- #
- # Global definitions in BSF
- # !BSF BLOCK:{NAME:"FSP UPD Configuration", VER:"0.1"}
- #
-
-"""
-
-
-def Bytes2Val(Bytes):
- return reduce(lambda x, y: (x << 8) | y, Bytes[::-1])
-
-
-def Str2Bytes(Value, Blen):
- Result = bytearray(Value[1:-1], 'utf-8') # Excluding quotes
- if len(Result) < Blen:
- Result.extend(b'\x00' * (Blen - len(Result)))
- return Result
-
-
-class CFspBsf2Dsc:
-
- def __init__(self, bsf_file):
- self.cfg_list = CFspBsf2Dsc.parse_bsf(bsf_file)
-
- def get_dsc_lines(self):
- return CFspBsf2Dsc.generate_dsc(self.cfg_list)
-
- def save_dsc(self, dsc_file):
- return CFspBsf2Dsc.generate_dsc(self.cfg_list, dsc_file)
-
- @staticmethod
- def parse_bsf(bsf_file):
-
- fd = open(bsf_file, 'r')
- bsf_txt = fd.read()
- fd.close()
-
- find_list = []
- regex = re.compile(r'\s+Find\s+"(.*?)"(.*?)^\s+\$(.*?)\s+', re.S | re.MULTILINE)
- for match in regex.finditer(bsf_txt):
- find = match.group(1)
- name = match.group(3)
- if not name.endswith('_Revision'):
- raise Exception("Unexpected CFG item following 'Find' !")
- find_list.append((name, find))
-
- idx = 0
- count = 0
- prefix = ''
- chk_dict = {}
- cfg_list = []
- cfg_temp = {'find': '', 'cname': '', 'length': 0, 'value': '0', 'type': 'Reserved',
- 'embed': '', 'page': '', 'option': '', 'instance': 0}
- regex = re.compile(r'^\s+(\$(.*?)|Skip)\s+(\d+)\s+bytes(\s+\$_DEFAULT_\s+=\s+(.+?))?$',
- re.S | re.MULTILINE)
-
- for match in regex.finditer(bsf_txt):
- dlen = int(match.group(3))
- if match.group(1) == 'Skip':
- key = 'gPlatformFspPkgTokenSpaceGuid_BsfSkip%d' % idx
- val = ', '.join(['%02X' % ord(i) for i in '\x00' * dlen])
- idx += 1
- option = '$SKIP'
- else:
- key = match.group(2)
- val = match.group(5)
- option = ''
-
- cfg_item = dict(cfg_temp)
- finds = [i for i in find_list if i[0] == key]
- if len(finds) > 0:
- if count >= 1:
- # Append a dummy one
- cfg_item['cname'] = 'Dummy'
- cfg_list.append(dict(cfg_item))
- cfg_list[-1]['embed'] = '%s:TAG_%03X:END' % (prefix, ord(prefix[-1]))
- prefix = finds[0][1]
- cfg_item['embed'] = '%s:TAG_%03X:START' % (prefix, ord(prefix[-1]))
- cfg_item['find'] = prefix
- cfg_item['cname'] = 'Signature'
- cfg_item['length'] = len(finds[0][1])
- str2byte = Str2Bytes("'" + finds[0][1] + "'", len(finds[0][1]))
- cfg_item['value'] = '0x%X' % Bytes2Val(str2byte)
- cfg_list.append(dict(cfg_item))
- cfg_item = dict(cfg_temp)
- find_list.pop(0)
- count = 0
-
- cfg_item['cname'] = key
- cfg_item['length'] = dlen
- cfg_item['value'] = val
- cfg_item['option'] = option
-
- if key not in chk_dict.keys():
- chk_dict[key] = 0
- else:
- chk_dict[key] += 1
- cfg_item['instance'] = chk_dict[key]
-
- cfg_list.append(cfg_item)
- count += 1
-
- if prefix:
- cfg_item = dict(cfg_temp)
- cfg_item['cname'] = 'Dummy'
- cfg_item['embed'] = '%s:%03X:END' % (prefix, ord(prefix[-1]))
- cfg_list.append(cfg_item)
-
- option_dict = {}
- selreg = re.compile(r'\s+Selection\s*(.+?)\s*,\s*"(.*?)"$', re.S | re.MULTILINE)
- regex = re.compile(r'^List\s&(.+?)$(.+?)^EndList$', re.S | re.MULTILINE)
- for match in regex.finditer(bsf_txt):
- key = match.group(1)
- option_dict[key] = []
- for select in selreg.finditer(match.group(2)):
- option_dict[key].append((int(select.group(1), 0), select.group(2)))
-
- chk_dict = {}
- pagereg = re.compile(r'^Page\s"(.*?)"$(.+?)^EndPage$', re.S | re.MULTILINE)
- for match in pagereg.finditer(bsf_txt):
- page = match.group(1)
- for line in match.group(2).splitlines():
- match = re.match(r'\s+(Combo|EditNum)\s\$(.+?),\s"(.*?)",\s(.+?),$', line)
- if match:
- cname = match.group(2)
- if cname not in chk_dict.keys():
- chk_dict[cname] = 0
- else:
- chk_dict[cname] += 1
- instance = chk_dict[cname]
- cfg_idxs = [i for i, j in enumerate(cfg_list) if j['cname'] == cname and j['instance'] == instance]
- if len(cfg_idxs) != 1:
- raise Exception("Multiple CFG item '%s' found !" % cname)
- cfg_item = cfg_list[cfg_idxs[0]]
- cfg_item['page'] = page
- cfg_item['type'] = match.group(1)
- cfg_item['prompt'] = match.group(3)
- cfg_item['range'] = None
- if cfg_item['type'] == 'Combo':
- cfg_item['option'] = option_dict[match.group(4)[1:]]
- elif cfg_item['type'] == 'EditNum':
- cfg_item['option'] = match.group(4)
- match = re.match(r'\s+ Help\s"(.*?)"$', line)
- if match:
- cfg_item['help'] = match.group(1)
-
- match = re.match(r'\s+"Valid\srange:\s(.*)"$', line)
- if match:
- parts = match.group(1).split()
- cfg_item['option'] = (
- (int(parts[0], 0), int(parts[2], 0), cfg_item['option']))
-
- return cfg_list
-
- @staticmethod
- def generate_dsc(option_list, dsc_file=None):
- dsc_lines = []
- header = '%s' % (__copyright_dsc__ % date.today().year)
- dsc_lines.extend(header.splitlines())
-
- pages = []
- for cfg_item in option_list:
- if cfg_item['page'] and (cfg_item['page'] not in pages):
- pages.append(cfg_item['page'])
-
- page_id = 0
- for page in pages:
- dsc_lines.append(' # !BSF PAGES:{PG%02X::"%s"}' % (page_id, page))
- page_id += 1
- dsc_lines.append('')
-
- last_page = ''
- for option in option_list:
- dsc_lines.append('')
- default = option['value']
- pos = option['cname'].find('_')
- name = option['cname'][pos + 1:]
-
- if option['find']:
- dsc_lines.append(' # !BSF FIND:{%s}' % option['find'])
- dsc_lines.append('')
-
- if option['instance'] > 0:
- name = name + '_%s' % option['instance']
-
- if option['embed']:
- dsc_lines.append(' # !HDR EMBED:{%s}' % option['embed'])
-
- if option['type'] == 'Reserved':
- dsc_lines.append(' # !BSF NAME:{Reserved} TYPE:{Reserved}')
- if option['option'] == '$SKIP':
- dsc_lines.append(' # !BSF OPTION:{$SKIP}')
- else:
- prompt = option['prompt']
-
- if last_page != option['page']:
- last_page = option['page']
- dsc_lines.append(' # !BSF PAGE:{PG%02X}' % (pages.index(option['page'])))
-
- if option['type'] == 'Combo':
- dsc_lines.append(' # !BSF NAME:{%s} TYPE:{%s}' %
- (prompt, option['type']))
- ops = []
- for val, text in option['option']:
- ops.append('0x%x:%s' % (val, text))
- dsc_lines.append(' # !BSF OPTION:{%s}' % (', '.join(ops)))
- elif option['type'] == 'EditNum':
- cfg_len = option['length']
- if ',' in default and cfg_len > 8:
- dsc_lines.append(' # !BSF NAME:{%s} TYPE:{Table}' % (prompt))
- if cfg_len > 16:
- cfg_len = 16
- ops = []
- for i in range(cfg_len):
- ops.append('%X:1:HEX' % i)
- dsc_lines.append(' # !BSF OPTION:{%s}' % (', '.join(ops)))
- else:
- dsc_lines.append(
- ' # !BSF NAME:{%s} TYPE:{%s, %s,(0x%X, 0x%X)}' %
- (prompt, option['type'], option['option'][2],
- option['option'][0], option['option'][1]))
- dsc_lines.append(' # !BSF HELP:{%s}' % option['help'])
-
- if ',' in default:
- default = '{%s}' % default
- dsc_lines.append(' gCfgData.%-30s | * | 0x%04X | %s' %
- (name, option['length'], default))
-
- if dsc_file:
- fd = open(dsc_file, 'w')
- fd.write('\n'.join(dsc_lines))
- fd.close()
-
- return dsc_lines
-
class CFspDsc2Yaml():
def __init__(self):
self._Hdr_key_list = ['EMBED', 'STRUCT']
- self._Bsf_key_list = ['NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES', 'OPTION',
- 'CONDITION', 'ORDER', 'MARKER', 'SUBT', 'FIELD', 'FIND']
+ self._Bsf_key_list = ['NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES',
+ 'OPTION', 'CONDITION', 'ORDER', 'MARKER',
+ 'SUBT', 'FIELD', 'FIND']
self.gen_cfg_data = None
- self.cfg_reg_exp = re.compile(r"^([_a-zA-Z0-9$\(\)]+)\s*\|\s*(0x[0-9A-F]+|\*)\s*\|"
- + r"\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)")
- self.bsf_reg_exp = re.compile(r"(%s):{(.+?)}(?:$|\s+)" % '|'.join(self._Bsf_key_list))
- self.hdr_reg_exp = re.compile(r"(%s):{(.+?)}" % '|'.join(self._Hdr_key_list))
+ self.cfg_reg_exp = re.compile(
+ "^([_a-zA-Z0-9$\\(\\)]+)\\s*\\|\\s*(0x[0-9A-F]+|\\*)"
+ "\\s*\\|\\s*(\\d+|0x[0-9a-fA-F]+)\\s*\\|\\s*(.+)")
+ self.bsf_reg_exp = re.compile("(%s):{(.+?)}(?:$|\\s+)"
+ % '|'.join(self._Bsf_key_list))
+ self.hdr_reg_exp = re.compile("(%s):{(.+?)}"
+ % '|'.join(self._Hdr_key_list))
self.prefix = ''
self.unused_idx = 0
self.offset = 0
@@ -290,15 +51,15 @@ class CFspDsc2Yaml(): """
Load and parse a DSC CFGDATA file.
"""
- gen_cfg_data = CGenCfgOpt('FSP')
+ gen_cfg_data = CGenCfgData('FSP')
if file_name.endswith('.dsc'):
- # if gen_cfg_data.ParseDscFileYaml(file_name, '') != 0:
- if gen_cfg_data.ParseDscFile(file_name, '') != 0:
+ if gen_cfg_data.ParseDscFile(file_name) != 0:
raise Exception('DSC file parsing error !')
if gen_cfg_data.CreateVarDict() != 0:
raise Exception('DSC variable creation error !')
else:
raise Exception('Unsupported file "%s" !' % file_name)
+ gen_cfg_data.UpdateDefaultValue()
self.gen_cfg_data = gen_cfg_data
def print_dsc_line(self):
@@ -312,14 +73,15 @@ class CFspDsc2Yaml(): """
Format a CFGDATA item into YAML format.
"""
- if(not text.startswith('!expand')) and (': ' in text):
+ if (not text.startswith('!expand')) and (': ' in text):
tgt = ':' if field == 'option' else '- '
text = text.replace(': ', tgt)
lines = text.splitlines()
if len(lines) == 1 and field != 'help':
return text
else:
- return '>\n ' + '\n '.join([indent + i.lstrip() for i in lines])
+ return '>\n ' + '\n '.join(
+ [indent + i.lstrip() for i in lines])
def reformat_pages(self, val):
# Convert XXX:YYY into XXX::YYY format for page definition
@@ -355,14 +117,16 @@ class CFspDsc2Yaml(): cfg['page'] = self.reformat_pages(cfg['page'])
if 'struct' in cfg:
- cfg['value'] = self.reformat_struct_value(cfg['struct'], cfg['value'])
+ cfg['value'] = self.reformat_struct_value(
+ cfg['struct'], cfg['value'])
def parse_dsc_line(self, dsc_line, config_dict, init_dict, include):
"""
Parse a line in DSC and update the config dictionary accordingly.
"""
init_dict.clear()
- match = re.match(r'g(CfgData|\w+FspPkgTokenSpaceGuid)\.(.+)', dsc_line)
+ match = re.match('g(CfgData|\\w+FspPkgTokenSpaceGuid)\\.(.+)',
+ dsc_line)
if match:
match = self.cfg_reg_exp.match(match.group(2))
if not match:
@@ -385,7 +149,7 @@ class CFspDsc2Yaml(): self.offset = offset + int(length, 0)
return True
- match = re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", dsc_line)
+ match = re.match("^\\s*#\\s+!([<>])\\s+include\\s+(.+)", dsc_line)
if match and len(config_dict) == 0:
# !include should not be inside a config field
# if so, do not convert include into YAML
@@ -398,7 +162,7 @@ class CFspDsc2Yaml(): config_dict['include'] = ''
return True
- match = re.match(r"^\s*#\s+(!BSF|!HDR)\s+(.+)", dsc_line)
+ match = re.match("^\\s*#\\s+(!BSF|!HDR)\\s+(.+)", dsc_line)
if not match:
return False
@@ -434,16 +198,19 @@ class CFspDsc2Yaml(): tmp_name = parts[0][:-5]
if tmp_name == 'CFGHDR':
cfg_tag = '_$FFF_'
- sval = '!expand { %s_TMPL : [ ' % tmp_name + '%s, %s, ' % (parts[1], cfg_tag) \
- + ', '.join(parts[2:]) + ' ] }'
+ sval = '!expand { %s_TMPL : [ ' % \
+ tmp_name + '%s, %s, ' % (parts[1], cfg_tag) + \
+ ', '.join(parts[2:]) + ' ] }'
else:
- sval = '!expand { %s_TMPL : [ ' % tmp_name + ', '.join(parts[1:]) + ' ] }'
+ sval = '!expand { %s_TMPL : [ ' % \
+ tmp_name + ', '.join(parts[1:]) + ' ] }'
config_dict.clear()
config_dict['cname'] = tmp_name
config_dict['expand'] = sval
return True
else:
- if key in ['name', 'help', 'option'] and val.startswith('+'):
+ if key in ['name', 'help', 'option'] and \
+ val.startswith('+'):
val = config_dict[key] + '\n' + val[1:]
if val.strip() == '':
val = "''"
@@ -493,21 +260,23 @@ class CFspDsc2Yaml(): include_file = ['.']
for line in lines:
- match = re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", line)
+ match = re.match("^\\s*#\\s+!([<>])\\s+include\\s+(.+)", line)
if match:
if match.group(1) == '<':
include_file.append(match.group(2))
else:
include_file.pop()
- match = re.match(r"^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}", line)
+ match = re.match(
+ "^\\s*#\\s+(!BSF)\\s+DEFT:{(.+?):(START|END)}", line)
if match:
if match.group(3) == 'START' and not template_name:
template_name = match.group(2).strip()
temp_file_dict[template_name] = list(include_file)
bsf_temp_dict[template_name] = []
- if match.group(3) == 'END' and (template_name == match.group(2).strip()) \
- and template_name:
+ if match.group(3) == 'END' and \
+ (template_name == match.group(2).strip()) and \
+ template_name:
template_name = ''
else:
if template_name:
@@ -531,12 +300,14 @@ class CFspDsc2Yaml(): init_dict.clear()
padding_dict = {}
cfgs.append(padding_dict)
- padding_dict['cname'] = 'UnusedUpdSpace%d' % self.unused_idx
+ padding_dict['cname'] = 'UnusedUpdSpace%d' % \
+ self.unused_idx
padding_dict['length'] = '0x%x' % num
padding_dict['value'] = '{ 0 }'
self.unused_idx += 1
- if cfgs and cfgs[-1]['cname'][0] != '@' and config_dict['cname'][0] == '@':
+ if cfgs and cfgs[-1]['cname'][0] != '@' and \
+ config_dict['cname'][0] == '@':
# it is a bit field, mark the previous one as virtual
cname = cfgs[-1]['cname']
new_cfg = dict(cfgs[-1])
@@ -545,7 +316,8 @@ class CFspDsc2Yaml(): cfgs[-1]['cname'] = cname
cfgs.append(new_cfg)
- if cfgs and cfgs[-1]['cname'] == 'CFGHDR' and config_dict['cname'][0] == '<':
+ if cfgs and cfgs[-1]['cname'] == 'CFGHDR' and \
+ config_dict['cname'][0] == '<':
# swap CfgHeader and the CFG_DATA order
if ':' in config_dict['cname']:
# replace the real TAG for CFG_DATA
@@ -661,7 +433,7 @@ class CFspDsc2Yaml(): lines = []
for each in self.gen_cfg_data._MacroDict:
key, value = self.variable_fixup(each)
- lines.append('%-30s : %s' % (key, value))
+ lines.append('%-30s : %s' % (key, value))
return lines
def output_template(self):
@@ -671,7 +443,8 @@ class CFspDsc2Yaml(): self.offset = 0
self.base_offset = 0
start, end = self.get_section_range('PcdsDynamicVpd.Tmp')
- bsf_temp_dict, temp_file_dict = self.process_template_lines(self.gen_cfg_data._DscLines[start:end])
+ bsf_temp_dict, temp_file_dict = self.process_template_lines(
+ self.gen_cfg_data._DscLines[start:end])
template_dict = dict()
lines = []
file_lines = {}
@@ -679,15 +452,18 @@ class CFspDsc2Yaml(): file_lines[last_file] = []
for tmp_name in temp_file_dict:
- temp_file_dict[tmp_name][-1] = self.normalize_file_name(temp_file_dict[tmp_name][-1], True)
+ temp_file_dict[tmp_name][-1] = self.normalize_file_name(
+ temp_file_dict[tmp_name][-1], True)
if len(temp_file_dict[tmp_name]) > 1:
- temp_file_dict[tmp_name][-2] = self.normalize_file_name(temp_file_dict[tmp_name][-2], True)
+ temp_file_dict[tmp_name][-2] = self.normalize_file_name(
+ temp_file_dict[tmp_name][-2], True)
for tmp_name in bsf_temp_dict:
file = temp_file_dict[tmp_name][-1]
if last_file != file and len(temp_file_dict[tmp_name]) > 1:
inc_file = temp_file_dict[tmp_name][-2]
- file_lines[inc_file].extend(['', '- !include %s' % temp_file_dict[tmp_name][-1], ''])
+ file_lines[inc_file].extend(
+ ['', '- !include %s' % temp_file_dict[tmp_name][-1], ''])
last_file = file
if file not in file_lines:
file_lines[file] = []
@@ -708,7 +484,8 @@ class CFspDsc2Yaml(): self.offset = 0
self.base_offset = 0
start, end = self.get_section_range('PcdsDynamicVpd.Upd')
- cfgs = self.process_option_lines(self.gen_cfg_data._DscLines[start:end])
+ cfgs = self.process_option_lines(
+ self.gen_cfg_data._DscLines[start:end])
self.config_fixup(cfgs)
file_lines = self.output_dict(cfgs, True)
return file_lines
@@ -721,13 +498,17 @@ class CFspDsc2Yaml(): level = 0
file = '.'
for each in cfgs:
- if 'length' in each and int(each['length'], 0) == 0:
- continue
+ if 'length' in each:
+ if not each['length'].endswith('b') and int(each['length'],
+ 0) == 0:
+ continue
if 'include' in each:
if each['include']:
- each['include'] = self.normalize_file_name(each['include'])
- file_lines[file].extend(['', '- !include %s' % each['include'], ''])
+ each['include'] = self.normalize_file_name(
+ each['include'])
+ file_lines[file].extend(
+ ['', '- !include %s' % each['include'], ''])
file = each['include']
else:
file = '.'
@@ -766,7 +547,8 @@ class CFspDsc2Yaml(): for field in each:
if field in ['cname', 'expand', 'include']:
continue
- value_str = self.format_value(field, each[field], padding + ' ' * 16)
+ value_str = self.format_value(
+ field, each[field], padding + ' ' * 16)
full_line = ' %s %-12s : %s' % (padding, field, value_str)
lines.extend(full_line.splitlines())
@@ -802,11 +584,13 @@ def dsc_to_yaml(dsc_file, yaml_file): if file == '.':
cfgs[cfg] = lines
else:
- if('/' in file or '\\' in file):
+ if ('/' in file or '\\' in file):
continue
file = os.path.basename(file)
- fo = open(os.path.join(file), 'w')
- fo.write(__copyright_tmp__ % (cfg, date.today().year) + '\n\n')
+ out_dir = os.path.dirname(file)
+ fo = open(os.path.join(out_dir, file), 'w')
+ fo.write(__copyright_tmp__ % (
+ cfg, date.today().year) + '\n\n')
for line in lines:
fo.write(line + '\n')
fo.close()
@@ -821,13 +605,11 @@ def dsc_to_yaml(dsc_file, yaml_file): fo.write('\n\ntemplate:\n')
for line in cfgs['Template']:
- if line != '':
- fo.write(' ' + line + '\n')
+ fo.write(' ' + line + '\n')
fo.write('\n\nconfigs:\n')
for line in cfgs['Option']:
- if line != '':
- fo.write(' ' + line + '\n')
+ fo.write(' ' + line + '\n')
fo.close()
@@ -864,7 +646,8 @@ def main(): bsf_file = sys.argv[1]
yaml_file = sys.argv[2]
if os.path.isdir(yaml_file):
- yaml_file = os.path.join(yaml_file, get_fsp_name_from_path(bsf_file) + '.yaml')
+ yaml_file = os.path.join(
+ yaml_file, get_fsp_name_from_path(bsf_file) + '.yaml')
if bsf_file.endswith('.dsc'):
dsc_file = bsf_file
|