From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Loo, Tung Lun" <tung.lun.loo@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Loo, Tung Lun" <tung.lun.loo@intel.com>,
"Ma, Maurice" <maurice.ma@intel.com>,
"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
"Zeng, Star" <star.zeng@intel.com>
Subject: Re: [PATCH v2] IntelFsp2Pkg: Add YAML file generation support
Date: Fri, 5 Feb 2021 02:09:41 +0000 [thread overview]
Message-ID: <SN6PR11MB2814F9C03DFE3716DE9598C4E6B29@SN6PR11MB2814.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20210204035953.1123-1-tung.lun.loo@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> -----Original Message-----
> From: Loo Tung Lun <tung.lun.loo@intel.com>
> Sent: Thursday, February 4, 2021 12:00 PM
> To: devel@edk2.groups.io
> Cc: Loo, Tung Lun <tung.lun.loo@intel.com>; Ma, Maurice
> <maurice.ma@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Zeng, Star <star.zeng@intel.com>; Chiu,
> Chasel <chasel.chiu@intel.com>
> Subject: [PATCH v2] IntelFsp2Pkg: Add YAML file generation support
>
> Add support for YAML format file generation in addition
> to current BSF structure. Configuration of YAML format
> output will be supported by an open source ConfigEditor.
>
> Reference to YAML code, test and ConfigEditor is at
> https://github.com/joshloo/fsp_yaml_cfg/tree/master/Tools
>
> A unit test is also added in Tests folder. This test compares
> the generated yaml file against the expected output to know
> if it is constructing the yaml data structure as expected.
>
> Cc: Maurice Ma <maurice.ma@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Signed-off-by: Loo Tung Lun <tung.lun.loo@intel.com>
> ---
> IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py | 875
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++
> IntelFsp2Pkg/Tools/GenCfgOpt.py | 470
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++------------------------------------------------------------------------------
> ------------------------------------------------------
> IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h | 16 ++++++++++++++++
> IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h | 75
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++
> IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h | 69
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++
> IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h | 87
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++
> IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf | 88
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++
> IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml | 270
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++
> IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 469
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++
> IntelFsp2Pkg/Tools/Tests/test_yaml.py | 96
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++
> IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md | 39
> +++++++++++++++++++++++++++++++++++++++
> 11 files changed, 2422 insertions(+), 132 deletions(-)
>
> diff --git a/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py
> b/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py
> new file mode 100644
> index 0000000000..2a2ee72ac2
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py
> @@ -0,0 +1,875 @@
> +#!/usr/bin/env python
>
> +## @ FspDscBsf2Yaml.py
>
> +# This script convert DSC or BSF format file into YAML format
>
> +#
>
> +# Copyright(c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +import os
>
> +import re
>
> +import sys
>
> +from datetime import date
>
> +from collections import OrderedDict
>
> +from functools import reduce
>
> +
>
> +from GenCfgOpt import CGenCfgOpt
>
> +
>
> +__copyright_tmp__ = """## @file
>
> +#
>
> +# YAML CFGDATA %s File.
>
> +#
>
> +# 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])
>
> +
>
> +
>
> +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])
>
> + cfg_item['value'] = '0x%X' % Bytes2Val(finds[0][1].encode('UTF-8'))
>
> + 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.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.prefix = ''
>
> + self.unused_idx = 0
>
> + self.offset = 0
>
> + self.base_offset = 0
>
> +
>
> + def load_config_data_from_dsc(self, file_name):
>
> + """
>
> + Load and parse a DSC CFGDATA file.
>
> + """
>
> + gen_cfg_data = CGenCfgOpt('FSP')
>
> + if file_name.endswith('.dsc'):
>
> + # if gen_cfg_data.ParseDscFileYaml(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):
>
> + """
>
> + Debug function to print all DSC lines.
>
> + """
>
> + for line in self.gen_cfg_data._DscLines:
>
> + print(line)
>
> +
>
> + def format_value(self, field, text, indent=''):
>
> + """
>
> + Format a CFGDATA item into YAML format.
>
> + """
>
> + 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])
>
> +
>
> + def reformat_pages(self, val):
>
> + # Convert XXX:YYY into XXX::YYY format for page definition
>
> + parts = val.split(',')
>
> + if len(parts) <= 1:
>
> + return val
>
> +
>
> + new_val = []
>
> + for each in parts:
>
> + nodes = each.split(':')
>
> + if len(nodes) == 2:
>
> + each = '%s::%s' % (nodes[0], nodes[1])
>
> + new_val.append(each)
>
> + ret = ','.join(new_val)
>
> + return ret
>
> +
>
> + def reformat_struct_value(self, utype, val):
>
> + # Convert DSC UINT16/32/64 array into new format by
>
> + # adding prefix 0:0[WDQ] to provide hint to the array format
>
> + if utype in ['UINT16', 'UINT32', 'UINT64']:
>
> + if val and val[0] == '{' and val[-1] == '}':
>
> + if utype == 'UINT16':
>
> + unit = 'W'
>
> + elif utype == 'UINT32':
>
> + unit = 'D'
>
> + else:
>
> + unit = 'Q'
>
> + val = '{ 0:0%s, %s }' % (unit, val[1:-1])
>
> + return val
>
> +
>
> + def process_config(self, cfg):
>
> + if 'page' in cfg:
>
> + cfg['page'] = self.reformat_pages(cfg['page'])
>
> +
>
> + if 'struct' in cfg:
>
> + 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)
>
> + if match:
>
> + match = self.cfg_reg_exp.match(match.group(2))
>
> + if not match:
>
> + return False
>
> + config_dict['cname'] = self.prefix + match.group(1)
>
> + value = match.group(4).strip()
>
> + length = match.group(3).strip()
>
> + config_dict['length'] = length
>
> + config_dict['value'] = value
>
> + if match.group(2) == '*':
>
> + self.offset += int(length, 0)
>
> + else:
>
> + org_offset = int(match.group(2), 0)
>
> + if org_offset == 0:
>
> + self.base_offset = self.offset
>
> + offset = org_offset + self.base_offset
>
> + if self.offset != offset:
>
> + if offset > self.offset:
>
> + init_dict['padding'] = offset - self.offset
>
> + self.offset = offset + int(length, 0)
>
> + return True
>
> +
>
> + match = re.match(r"^\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
>
> + init_dict = dict(config_dict)
>
> + config_dict.clear()
>
> + config_dict['cname'] = '$ACTION'
>
> + if match.group(1) == '<':
>
> + config_dict['include'] = match.group(2)
>
> + else:
>
> + config_dict['include'] = ''
>
> + return True
>
> +
>
> + match = re.match(r"^\s*#\s+(!BSF|!HDR)\s+(.+)", dsc_line)
>
> + if not match:
>
> + return False
>
> +
>
> + remaining = match.group(2)
>
> + if match.group(1) == '!BSF':
>
> + result = self.bsf_reg_exp.findall(remaining)
>
> + if not result:
>
> + return False
>
> +
>
> + for each in result:
>
> + key = each[0].lower()
>
> + val = each[1]
>
> + if key == 'field':
>
> + name = each[1]
>
> + if ':' not in name:
>
> + raise Exception('Incorrect bit field format !')
>
> + parts = name.split(':')
>
> + config_dict['length'] = parts[1]
>
> + config_dict['cname'] = '@' + parts[0]
>
> + return True
>
> + elif key in ['pages', 'page', 'find']:
>
> + init_dict = dict(config_dict)
>
> + config_dict.clear()
>
> + config_dict['cname'] = '$ACTION'
>
> + if key == 'find':
>
> + config_dict['find'] = val
>
> + else:
>
> + config_dict['page'] = val
>
> + return True
>
> + elif key == 'subt':
>
> + config_dict.clear()
>
> + parts = each[1].split(':')
>
> + 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:]) + ' ] }'
>
> + else:
>
> + 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('+'):
>
> + val = config_dict[key] + '\n' + val[1:]
>
> + if val.strip() == '':
>
> + val = "''"
>
> + config_dict[key] = val
>
> +
>
> + else:
>
> + match = self.hdr_reg_exp.match(remaining)
>
> + if not match:
>
> + return False
>
> + key = match.group(1)
>
> + remaining = match.group(2)
>
> + if key == 'EMBED':
>
> + parts = remaining.split(':')
>
> + names = parts[0].split(',')
>
> + if parts[-1] == 'END':
>
> + prefix = '>'
>
> + else:
>
> + prefix = '<'
>
> + skip = False
>
> + if parts[1].startswith('TAG_'):
>
> + tag_txt = '%s:%s' % (names[0], parts[1])
>
> + else:
>
> + tag_txt = names[0]
>
> + if parts[2] in ['START', 'END']:
>
> + if names[0] == 'PCIE_RP_PIN_CTRL[]':
>
> + skip = True
>
> + else:
>
> + tag_txt = '%s:%s' % (names[0], parts[1])
>
> + if not skip:
>
> + config_dict.clear()
>
> + config_dict['cname'] = prefix + tag_txt
>
> + return True
>
> +
>
> + if key == 'STRUCT':
>
> + text = remaining.strip()
>
> + config_dict[key.lower()] = text
>
> +
>
> + return False
>
> +
>
> + def process_template_lines(self, lines):
>
> + """
>
> + Process a line in DSC template section.
>
> + """
>
> + template_name = ''
>
> + bsf_temp_dict = OrderedDict()
>
> + temp_file_dict = OrderedDict()
>
> + include_file = ['.']
>
> +
>
> + for line in lines:
>
> + match = re.match(r"^\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)
>
> + 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:
>
> + template_name = ''
>
> + else:
>
> + if template_name:
>
> + bsf_temp_dict[template_name].append(line)
>
> + return bsf_temp_dict, temp_file_dict
>
> +
>
> + def process_option_lines(self, lines):
>
> + """
>
> + Process a line in DSC config section.
>
> + """
>
> + cfgs = []
>
> + struct_end = False
>
> + config_dict = dict()
>
> + init_dict = dict()
>
> + include = ['']
>
> + for line in lines:
>
> + ret = self.parse_dsc_line(line, config_dict, init_dict, include)
>
> + if ret:
>
> + if 'padding' in init_dict:
>
> + num = init_dict['padding']
>
> + init_dict.clear()
>
> + padding_dict = {}
>
> + cfgs.append(padding_dict)
>
> + 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] ==
> '@':
>
> + # it is a bit field, mark the previous one as virtual
>
> + cname = cfgs[-1]['cname']
>
> + new_cfg = dict(cfgs[-1])
>
> + new_cfg['cname'] = '@$STRUCT'
>
> + cfgs[-1].clear()
>
> + cfgs[-1]['cname'] = cname
>
> + cfgs.append(new_cfg)
>
> +
>
> + 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
>
> + cfgs[-1]['expand'] = cfgs[-1]['expand'].replace(
>
> + '_$FFF_', '0x%s' %
>
> + config_dict['cname'].split(':')[1][4:])
>
> + cfgs.insert(-1, config_dict)
>
> + else:
>
> + self.process_config(config_dict)
>
> + if struct_end:
>
> + struct_end = False
>
> + cfgs.insert(-1, config_dict)
>
> + else:
>
> + cfgs.append(config_dict)
>
> + if config_dict['cname'][0] == '>':
>
> + struct_end = True
>
> +
>
> + config_dict = dict(init_dict)
>
> + return cfgs
>
> +
>
> + def variable_fixup(self, each):
>
> + """
>
> + Fix up some variable definitions for SBL.
>
> + """
>
> + key = each
>
> + val = self.gen_cfg_data._MacroDict[each]
>
> + return key, val
>
> +
>
> + def template_fixup(self, tmp_name, tmp_list):
>
> + """
>
> + Fix up some special config templates for SBL
>
> + """
>
> + return
>
> +
>
> + def config_fixup(self, cfg_list):
>
> + """
>
> + Fix up some special config items for SBL.
>
> + """
>
> +
>
> + # Insert FSPT_UPD/FSPM_UPD/FSPS_UPD tag so as to create C strcture
>
> + idxs = []
>
> + for idx, cfg in enumerate(cfg_list):
>
> + if cfg['cname'].startswith('<FSP_UPD_HEADER'):
>
> + idxs.append(idx)
>
> +
>
> + if len(idxs) != 3:
>
> + return
>
> +
>
> + # Handle insert backwards so that the index does not change in the loop
>
> + fsp_comp = 'SMT'
>
> + idx_comp = 0
>
> + for idx in idxs[::-1]:
>
> + # Add current FSP?_UPD start tag
>
> + cfgfig_dict = {}
>
> + cfgfig_dict['cname'] = '<FSP%s_UPD' % fsp_comp[idx_comp]
>
> + cfg_list.insert(idx, cfgfig_dict)
>
> + if idx_comp < 2:
>
> + # Add previous FSP?_UPD end tag
>
> + cfgfig_dict = {}
>
> + cfgfig_dict['cname'] = '>FSP%s_UPD' % fsp_comp[idx_comp + 1]
>
> + cfg_list.insert(idx, cfgfig_dict)
>
> + idx_comp += 1
>
> +
>
> + # Add final FSPS_UPD end tag
>
> + cfgfig_dict = {}
>
> + cfgfig_dict['cname'] = '>FSP%s_UPD' % fsp_comp[0]
>
> + cfg_list.append(cfgfig_dict)
>
> +
>
> + return
>
> +
>
> + def get_section_range(self, section_name):
>
> + """
>
> + Extract line number range from config file for a given section name.
>
> + """
>
> + start = -1
>
> + end = -1
>
> + for idx, line in enumerate(self.gen_cfg_data._DscLines):
>
> + if start < 0 and line.startswith('[%s]' % section_name):
>
> + start = idx
>
> + elif start >= 0 and line.startswith('['):
>
> + end = idx
>
> + break
>
> + if start == -1:
>
> + start = 0
>
> + if end == -1:
>
> + end = len(self.gen_cfg_data._DscLines)
>
> + return start, end
>
> +
>
> + def normalize_file_name(self, file, is_temp=False):
>
> + """
>
> + Normalize file name convention so that it is consistent.
>
> + """
>
> + if file.endswith('.dsc'):
>
> + file = file[:-4] + '.yaml'
>
> + dir_name = os.path.dirname(file)
>
> + base_name = os.path.basename(file)
>
> + if is_temp:
>
> + if 'Template_' not in file:
>
> + base_name = base_name.replace('Template', 'Template_')
>
> + else:
>
> + if 'CfgData_' not in file:
>
> + base_name = base_name.replace('CfgData', 'CfgData_')
>
> + if dir_name:
>
> + path = dir_name + '/' + base_name
>
> + else:
>
> + path = base_name
>
> + return path
>
> +
>
> + def output_variable(self):
>
> + """
>
> + Output variable block into a line list.
>
> + """
>
> + lines = []
>
> + for each in self.gen_cfg_data._MacroDict:
>
> + key, value = self.variable_fixup(each)
>
> + lines.append('%-30s : %s' % (key, value))
>
> + return lines
>
> +
>
> + def output_template(self):
>
> + """
>
> + Output template block into a line list.
>
> + """
>
> + 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])
>
> + template_dict = dict()
>
> + lines = []
>
> + file_lines = {}
>
> + last_file = '.'
>
> + 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)
>
> + 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)
>
> +
>
> + 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], ''])
>
> + last_file = file
>
> + if file not in file_lines:
>
> + file_lines[file] = []
>
> + lines = file_lines[file]
>
> + text = bsf_temp_dict[tmp_name]
>
> + tmp_list = self.process_option_lines(text)
>
> + self.template_fixup(tmp_name, tmp_list)
>
> + template_dict[tmp_name] = tmp_list
>
> + lines.append('%s: >' % tmp_name)
>
> + lines.extend(self.output_dict(tmp_list, False)['.'])
>
> + lines.append('\n')
>
> + return file_lines
>
> +
>
> + def output_config(self):
>
> + """
>
> + Output config block into a line list.
>
> + """
>
> + 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])
>
> + self.config_fixup(cfgs)
>
> + file_lines = self.output_dict(cfgs, True)
>
> + return file_lines
>
> +
>
> + def output_dict(self, cfgs, is_configs):
>
> + """
>
> + Output one config item into a line list.
>
> + """
>
> + file_lines = {}
>
> + level = 0
>
> + file = '.'
>
> + for each in cfgs:
>
> + if 'length' in each 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'], ''])
>
> + file = each['include']
>
> + else:
>
> + file = '.'
>
> + continue
>
> +
>
> + if file not in file_lines:
>
> + file_lines[file] = []
>
> +
>
> + lines = file_lines[file]
>
> + name = each['cname']
>
> +
>
> + prefix = name[0]
>
> + if prefix == '<':
>
> + level += 1
>
> +
>
> + padding = ' ' * level
>
> + if prefix not in '<>@':
>
> + padding += ' '
>
> + else:
>
> + name = name[1:]
>
> + if prefix == '@':
>
> + padding += ' '
>
> +
>
> + if ':' in name:
>
> + parts = name.split(':')
>
> + name = parts[0]
>
> +
>
> + padding = padding[2:] if is_configs else padding
>
> +
>
> + if prefix != '>':
>
> + if 'expand' in each:
>
> + lines.append('%s- %s' % (padding, each['expand']))
>
> + else:
>
> + lines.append('%s- %-12s :' % (padding, name))
>
> +
>
> + for field in each:
>
> + if field in ['cname', 'expand', 'include']:
>
> + continue
>
> + value_str = self.format_value(field, each[field], padding + ' ' * 16)
>
> + full_line = ' %s %-12s : %s' % (padding, field, value_str)
>
> + lines.extend(full_line.splitlines())
>
> +
>
> + if prefix == '>':
>
> + level -= 1
>
> + if level == 0:
>
> + lines.append('')
>
> +
>
> + return file_lines
>
> +
>
> +
>
> +def bsf_to_dsc(bsf_file, dsc_file):
>
> + fsp_dsc = CFspBsf2Dsc(bsf_file)
>
> + dsc_lines = fsp_dsc.get_dsc_lines()
>
> + fd = open(dsc_file, 'w')
>
> + fd.write('\n'.join(dsc_lines))
>
> + fd.close()
>
> + return
>
> +
>
> +
>
> +def dsc_to_yaml(dsc_file, yaml_file):
>
> + dsc2yaml = CFspDsc2Yaml()
>
> + dsc2yaml.load_config_data_from_dsc(dsc_file)
>
> +
>
> + cfgs = {}
>
> + for cfg in ['Template', 'Option']:
>
> + if cfg == 'Template':
>
> + file_lines = dsc2yaml.output_template()
>
> + else:
>
> + file_lines = dsc2yaml.output_config()
>
> + for file in file_lines:
>
> + lines = file_lines[file]
>
> + if file == '.':
>
> + cfgs[cfg] = lines
>
> + else:
>
> + 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')
>
> + for line in lines:
>
> + fo.write(line + '\n')
>
> + fo.close()
>
> +
>
> + variables = dsc2yaml.output_variable()
>
> + fo = open(yaml_file, 'w')
>
> + fo.write(__copyright_tmp__ % ('Default', date.today().year))
>
> + if len(variables) > 0:
>
> + fo.write('\n\nvariable:\n')
>
> + for line in variables:
>
> + fo.write(' ' + line + '\n')
>
> +
>
> + fo.write('\n\ntemplate:\n')
>
> + for line in cfgs['Template']:
>
> + fo.write(' ' + line + '\n')
>
> +
>
> + fo.write('\n\nconfigs:\n')
>
> + for line in cfgs['Option']:
>
> + fo.write(' ' + line + '\n')
>
> +
>
> + fo.close()
>
> +
>
> +
>
> +def get_fsp_name_from_path(bsf_file):
>
> + name = ''
>
> + parts = bsf_file.split(os.sep)
>
> + for part in parts:
>
> + if part.endswith('FspBinPkg'):
>
> + name = part[:-9]
>
> + break
>
> + if not name:
>
> + raise Exception('Could not get FSP name from file path!')
>
> + return name
>
> +
>
> +
>
> +def usage():
>
> + print('\n'.join([
>
> + "FspDscBsf2Yaml Version 0.10",
>
> + "Usage:",
>
> + " FspDscBsf2Yaml BsfFile|DscFile YamlFile"
>
> + ]))
>
> +
>
> +
>
> +def main():
>
> + #
>
> + # Parse the options and args
>
> + #
>
> + argc = len(sys.argv)
>
> + if argc < 3:
>
> + usage()
>
> + return 1
>
> +
>
> + 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')
>
> +
>
> + if bsf_file.endswith('.dsc'):
>
> + dsc_file = bsf_file
>
> + bsf_file = ''
>
> + else:
>
> + dsc_file = os.path.splitext(yaml_file)[0] + '.dsc'
>
> + bsf_to_dsc(bsf_file, dsc_file)
>
> +
>
> + dsc_to_yaml(dsc_file, yaml_file)
>
> +
>
> + print("'%s' was created successfully!" % yaml_file)
>
> +
>
> + return 0
>
> +
>
> +
>
> +if __name__ == '__main__':
>
> + sys.exit(main())
>
> diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py
> b/IntelFsp2Pkg/Tools/GenCfgOpt.py
> index a0b8bba81e..660824b740 100644
> --- a/IntelFsp2Pkg/Tools/GenCfgOpt.py
> +++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py
> @@ -1,6 +1,6 @@
> ## @ GenCfgOpt.py
>
> #
>
> -# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
>
> +# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> #
>
> ##
>
> @@ -283,10 +283,10 @@ class CLogicalExpression:
> return Result
>
>
>
> class CGenCfgOpt:
>
> - def __init__(self):
>
> + def __init__(self, Mode = ''):
>
> self.Debug = False
>
> self.Error = ''
>
> -
>
> + self.Mode = Mode
>
> self._GlobalDataDef = """
>
> GlobalDataDef
>
> SKUID = 0, "DEFAULT"
>
> @@ -300,18 +300,20 @@ List &EN_DIS
> EndList
>
>
>
> """
>
> -
>
> - self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
>
> + self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE', 'PAGES', 'BLOCK',
> 'OPTION','CONDITION','ORDER', 'MARKER', 'SUBT']
>
> self._HdrKeyList = ['HEADER','STRUCT', 'EMBED', 'COMMENT']
>
> self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}
>
>
>
> self._MacroDict = {}
>
> + self._VarDict = {}
>
> self._PcdsDict = {}
>
> self._CfgBlkDict = {}
>
> self._CfgPageDict = {}
>
> + self._BsfTempDict = {}
>
> self._CfgItemList = []
>
> + self._DscLines = []
>
> self._DscFile = ''
>
> - self._FvDir = ''
>
> +
>
> self._MapVer = 0
>
> self._DscTime = 0
>
>
>
> @@ -351,7 +353,7 @@ EndList
> print ("INFO : Eval Ifdef [%s] : %s" % (Macro, Result))
>
> return Result
>
>
>
> - def ExpandMacros (self, Input):
>
> + def ExpandMacros (self, Input, Preserve = False):
>
> Line = Input
>
> Match = re.findall("\$\(\w+\)", Input)
>
> if Match:
>
> @@ -362,7 +364,8 @@ EndList
> else:
>
> if self.Debug:
>
> print ("WARN : %s is not defined" % Each)
>
> - Line = Line.replace(Each, Each[2:-1])
>
> + if not Preserve:
>
> + Line = Line.replace(Each, Each[2:-1])
>
> return Line
>
>
>
> def ExpandPcds (self, Input):
>
> @@ -386,6 +389,70 @@ EndList
> print ("INFO : Eval Express [%s] : %s" % (Expr, Result))
>
> return Result
>
>
>
> + def ValueToByteArray (self, ValueStr, Length):
>
> + Match = re.match("\{\s*FILE:(.+)\}", ValueStr)
>
> + if Match:
>
> + FileList = Match.group(1).split(',')
>
> + Result = bytearray()
>
> + for File in FileList:
>
> + File = File.strip()
>
> + BinPath = os.path.join(os.path.dirname(self._DscFile), File)
>
> + Result.extend(bytearray(open(BinPath, 'rb').read()))
>
> + else:
>
> + try:
>
> + Result = bytearray(self.ValueToList(ValueStr, Length))
>
> + except ValueError as e:
>
> + raise Exception ("Bytes in '%s' must be in range 0~255 !" % ValueStr)
>
> + if len(Result) < Length:
>
> + Result.extend(b'\x00' * (Length - len(Result)))
>
> + elif len(Result) > Length:
>
> + raise Exception ("Value '%s' is too big to fit into %d bytes !" % (ValueStr,
> Length))
>
> +
>
> + return Result[:Length]
>
> +
>
> + def ValueToList (self, ValueStr, Length):
>
> + if ValueStr[0] == '{':
>
> + Result = []
>
> + BinList = ValueStr[1:-1].split(',')
>
> + InBitField = False
>
> + LastInBitField = False
>
> + Value = 0
>
> + BitLen = 0
>
> + for Element in BinList:
>
> + InBitField = False
>
> + Each = Element.strip()
>
> + if len(Each) == 0:
>
> + pass
>
> + else:
>
> + if Each[0] in ['"', "'"]:
>
> + Result.extend(list(bytearray(Each[1:-1], 'utf-8')))
>
> + elif ':' in Each:
>
> + Match = re.match("(.+):(\d+)b", Each)
>
> + if Match is None:
>
> + raise Exception("Invald value list format '%s' !" % Each)
>
> + InBitField = True
>
> + CurrentBitLen = int(Match.group(2))
>
> + CurrentValue = ((self.EvaluateExpress(Match.group(1)) &
> (1<<CurrentBitLen) - 1)) << BitLen
>
> + else:
>
> + Result.append(self.EvaluateExpress(Each.strip()))
>
> + if InBitField:
>
> + Value += CurrentValue
>
> + BitLen += CurrentBitLen
>
> + if LastInBitField and ((not InBitField) or (Element == BinList[-1])):
>
> + if BitLen % 8 != 0:
>
> + raise Exception("Invald bit field length!")
>
> + Result.extend(Val2Bytes(Value, BitLen // 8))
>
> + Value = 0
>
> + BitLen = 0
>
> + LastInBitField = InBitField
>
> + elif ValueStr.startswith("'") and ValueStr.endswith("'"):
>
> + Result = Str2Bytes (ValueStr, Length)
>
> + elif ValueStr.startswith('"') and ValueStr.endswith('"'):
>
> + Result = Str2Bytes (ValueStr, Length)
>
> + else:
>
> + Result = Val2Bytes (self.EvaluateExpress(ValueStr), Length)
>
> + return Result
>
> +
>
> def FormatListValue(self, ConfigDict):
>
> Struct = ConfigDict['struct']
>
> if Struct not in ['UINT8','UINT16','UINT32','UINT64']:
>
> @@ -424,28 +491,53 @@ EndList
> self._DscFile = DscFile
>
> self._FvDir = FvDir
>
>
>
> + self._DscLines = []
>
> + self._BsfTempDict = {}
>
> +
>
> # Initial DSC time is parent DSC time.
>
> self._DscTime = os.path.getmtime(DscFile)
>
>
>
> + CfgDict = {}
>
> +
>
> IsDefSect = False
>
> IsPcdSect = False
>
> IsUpdSect = False
>
> IsVpdSect = False
>
> + IsTmpSect = False
>
> +
>
> + TemplateName = ''
>
>
>
> IfStack = []
>
> ElifStack = []
>
> Error = 0
>
> ConfigDict = {}
>
>
>
> - DscFd = open(DscFile, "r")
>
> - DscLines = DscFd.readlines()
>
> - DscFd.close()
>
> +
>
> + if type(DscFile) is list:
>
> + # it is DSC lines already
>
> + DscLines = DscFile
>
> + self._DscFile = '.'
>
> + else:
>
> + DscFd = open(DscFile, "r")
>
> + DscLines = DscFd.readlines()
>
> + DscFd.close()
>
> + self._DscFile = DscFile
>
> +
>
> + SkipLines = 0
>
>
>
> MaxAlign = 32 #Default align to 32, but if there are 64 bit unit, align to 64
>
> SizeAlign = 0 #record the struct max align
>
> Base = 0 #Starting offset of sub-structure.
>
> +
>
> while len(DscLines):
>
> DscLine = DscLines.pop(0).strip()
>
> + if SkipLines == 0:
>
> + self._DscLines.append (DscLine)
>
> + else:
>
> + SkipLines = SkipLines - 1
>
> + if len(DscLine) == 0:
>
> + continue
>
> +
>
> Handle = False
>
> Match = re.match("^\[(.+)\]", DscLine)
>
> if Match is not None:
>
> @@ -453,11 +545,15 @@ EndList
> IsPcdSect = False
>
> IsVpdSect = False
>
> IsUpdSect = False
>
> - if Match.group(1).lower() == "Defines".lower():
>
> + IsTmpSect = False
>
> + SectionName = Match.group(1).lower()
>
> + if SectionName == "Defines".lower():
>
> IsDefSect = True
>
> - if (Match.group(1).lower() == "PcdsFeatureFlag".lower() or
> Match.group(1).lower() == "PcdsFixedAtBuild".lower()):
>
> + if (SectionName == "PcdsFeatureFlag".lower() or SectionName ==
> "PcdsFixedAtBuild".lower()):
>
> IsPcdSect = True
>
> - elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
>
> + elif SectionName == "PcdsDynamicVpd.Tmp".lower():
>
> + IsTmpSect = True
>
> + elif SectionName == "PcdsDynamicVpd.Upd".lower():
>
> ConfigDict = {}
>
> ConfigDict['header'] = 'ON'
>
> ConfigDict['region'] = 'UPD'
>
> @@ -465,90 +561,98 @@ EndList
> ConfigDict['page'] = ''
>
> ConfigDict['name'] = ''
>
> ConfigDict['find'] = ''
>
> + ConfigDict['marker'] = ''
>
> ConfigDict['struct'] = ''
>
> ConfigDict['embed'] = ''
>
> ConfigDict['comment'] = ''
>
> ConfigDict['subreg'] = []
>
> + ConfigDict['condition'] = ''
>
> + ConfigDict['option'] = ''
>
> IsUpdSect = True
>
> Offset = 0
>
> else:
>
> - if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:
>
> - if re.match("^!else($|\s+#.+)", DscLine):
>
> + if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect or IsTmpSect:
>
> +
>
> + Match = False if DscLine[0] != '!' else True
>
> + if Match:
>
> + Match =
> re.match("^!(else|endif|ifdef|ifndef|if|elseif|include)\s*(.+)?$",
> DscLine.split("#")[0])
>
> + Keyword = Match.group(1) if Match else ''
>
> + Remaining = Match.group(2) if Match else ''
>
> + Remaining = '' if Remaining is None else Remaining.strip()
>
> +
>
> + if Keyword in ['if', 'elseif', 'ifdef', 'ifndef', 'include'] and not
> Remaining:
>
> + raise Exception ("ERROR: Expression is expected after '!if'
> or !elseif' for line '%s'" % DscLine)
>
> +
>
> + if Keyword == 'else':
>
> if IfStack:
>
> IfStack[-1] = not IfStack[-1]
>
> else:
>
> - print("ERROR: No paired '!if' found for '!else' for line '%s'" %
> DscLine)
>
> - raise SystemExit
>
> - elif re.match("^!endif($|\s+#.+)", DscLine):
>
> + raise Exception ("ERROR: No paired '!if' found for '!else' for line
> '%s'" % DscLine)
>
> + elif Keyword == 'endif':
>
> if IfStack:
>
> IfStack.pop()
>
> Level = ElifStack.pop()
>
> if Level > 0:
>
> del IfStack[-Level:]
>
> else:
>
> - print("ERROR: No paired '!if' found for '!endif' for line '%s'" %
> DscLine)
>
> - raise SystemExit
>
> - else:
>
> - Result = False
>
> - Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)
>
> - if Match:
>
> - Result = self.EvaulateIfdef (Match.group(2))
>
> - if Match.group(1) == 'ifndef':
>
> - Result = not Result
>
> - IfStack.append(Result)
>
> + raise Exception ("ERROR: No paired '!if' found for '!endif' for
> line '%s'" % DscLine)
>
> + elif Keyword == 'ifdef' or Keyword == 'ifndef':
>
> + Result = self.EvaulateIfdef (Remaining)
>
> + if Keyword == 'ifndef':
>
> + Result = not Result
>
> + IfStack.append(Result)
>
> + ElifStack.append(0)
>
> + elif Keyword == 'if' or Keyword == 'elseif':
>
> + Result = self.EvaluateExpress(Remaining)
>
> + if Keyword == "if":
>
> ElifStack.append(0)
>
> + IfStack.append(Result)
>
> + else: #elseif
>
> + if IfStack:
>
> + IfStack[-1] = not IfStack[-1]
>
> + IfStack.append(Result)
>
> + ElifStack[-1] = ElifStack[-1] + 1
>
> + else:
>
> + raise Exception ("ERROR: No paired '!if' found for '!elif' for
> line '%s'" % DscLine)
>
> + else:
>
> + if IfStack:
>
> + Handle = reduce(lambda x,y: x and y, IfStack)
>
> else:
>
> - Match = re.match("!(if|elseif)\s+(.+)", DscLine.split("#")[0])
>
> + Handle = True
>
> + if Handle:
>
> + Match = re.match("!include\s+(.+)", DscLine)
>
> if Match:
>
> - Result = self.EvaluateExpress(Match.group(2))
>
> - if Match.group(1) == "if":
>
> - ElifStack.append(0)
>
> - IfStack.append(Result)
>
> - else: #elseif
>
> - if IfStack:
>
> - IfStack[-1] = not IfStack[-1]
>
> - IfStack.append(Result)
>
> - ElifStack[-1] = ElifStack[-1] + 1
>
> - else:
>
> - print("ERROR: No paired '!if' found for '!elif' for line '%s'"
> % DscLine)
>
> - raise SystemExit
>
> - else:
>
> - if IfStack:
>
> - Handle = reduce(lambda x,y: x and y, IfStack)
>
> + IncludeFilePath = Match.group(1)
>
> + IncludeFilePath = self.ExpandMacros(IncludeFilePath)
>
> + PackagesPath = os.getenv("PACKAGES_PATH")
>
> + if PackagesPath:
>
> + for PackagePath in PackagesPath.split(os.pathsep):
>
> + IncludeFilePathAbs =
> os.path.join(os.path.normpath(PackagePath),
> os.path.normpath(IncludeFilePath))
>
> + if os.path.exists(IncludeFilePathAbs):
>
> + IncludeDsc = open(IncludeFilePathAbs, "r")
>
> + break
>
> else:
>
> - Handle = True
>
> - if Handle:
>
> - Match = re.match("!include\s+(.+)", DscLine)
>
> - if Match:
>
> - IncludeFilePath = Match.group(1)
>
> - IncludeFilePath = self.ExpandMacros(IncludeFilePath)
>
> - PackagesPath = os.getenv("PACKAGES_PATH")
>
> - if PackagesPath:
>
> - for PackagePath in PackagesPath.split(os.pathsep):
>
> - IncludeFilePathAbs =
> os.path.join(os.path.normpath(PackagePath),
> os.path.normpath(IncludeFilePath))
>
> - if os.path.exists(IncludeFilePathAbs):
>
> - IncludeDsc = open(IncludeFilePathAbs, "r")
>
> - break
>
> - else:
>
> - IncludeDsc = open(IncludeFilePath, "r")
>
> - if IncludeDsc == None:
>
> - print("ERROR: Cannot open file '%s'" % IncludeFilePath)
>
> - raise SystemExit
>
> -
>
> - # Update DscTime when newer DSC time found.
>
> - CurrentDscTime =
> os.path.getmtime(os.path.realpath(IncludeDsc.name))
>
> - if CurrentDscTime > self._DscTime:
>
> - self._DscTime = CurrentDscTime
>
> -
>
> - NewDscLines = IncludeDsc.readlines()
>
> - IncludeDsc.close()
>
> - DscLines = NewDscLines + DscLines
>
> - Offset = 0
>
> - else:
>
> - if DscLine.startswith('!'):
>
> - print("ERROR: Unrecognized directive for line '%s'" %
> DscLine)
>
> - raise SystemExit
>
> + IncludeDsc = open(IncludeFilePath, "r")
>
> + if IncludeDsc == None:
>
> + print("ERROR: Cannot open file '%s'" % IncludeFilePath)
>
> + raise SystemExit
>
> +
>
> + # Update DscTime when newer DSC time found.
>
> + CurrentDscTime =
> os.path.getmtime(os.path.realpath(IncludeDsc.name))
>
> + if CurrentDscTime > self._DscTime:
>
> + self._DscTime = CurrentDscTime
>
> +
>
> + NewDscLines = IncludeDsc.readlines()
>
> + IncludeDsc.close()
>
> + DscLines = NewDscLines + DscLines
>
> + del self._DscLines[-1]
>
> + Offset = 0
>
> + else:
>
> + if DscLine.startswith('!'):
>
> + print("ERROR: Unrecognized directive for line '%s'" %
> DscLine)
>
> + raise SystemExit
>
> if not Handle:
>
> + del self._DscLines[-1]
>
> continue
>
>
>
> if IsDefSect:
>
> @@ -556,7 +660,7 @@ EndList
> #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-
> BA630F0714C6
>
> #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-
> E2BD3C0E2385
>
> #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-
> 27D54273C40F
>
> - Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([/$()-.\w]+)",
> DscLine)
>
> + Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*(.+)", DscLine)
>
> if Match:
>
> self._MacroDict[Match.group(1)] =
> self.ExpandMacros(Match.group(2))
>
> if self.Debug:
>
> @@ -575,6 +679,23 @@ EndList
> if Match:
>
> self._PcdsDict[Match.group(1)] = Match.group(2)
>
> i += 1
>
> +
>
> + elif IsTmpSect:
>
> + # !BSF DEFT:{GPIO_TMPL:START}
>
> + Match = re.match("^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}",
> DscLine)
>
> + if Match:
>
> + if Match.group(3) == 'START' and not TemplateName:
>
> + TemplateName = Match.group(2).strip()
>
> + self._BsfTempDict[TemplateName] = []
>
> + if Match.group(3) == 'END' and (TemplateName ==
> Match.group(2).strip()) and TemplateName:
>
> + TemplateName = ''
>
> + else:
>
> + if TemplateName:
>
> + Match = re.match("^!include\s*(.+)?$", DscLine)
>
> + if Match:
>
> + continue
>
> + self._BsfTempDict[TemplateName].append(DscLine)
>
> +
>
> else:
>
> Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)
>
> if Match:
>
> @@ -630,9 +751,9 @@ EndList
> Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-
> \s*(.+)\s*", DscLine)
>
> if Match:
>
> if "0x" in Match.group(2) or "0x" in Match.group(3):
>
> - ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2),
> Match.group(3))
>
> + ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2),
> Match.group(3))
>
> else:
>
> - ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2),
> Match.group(3))
>
> + ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2),
> Match.group(3))
>
>
>
> Match = re.match("^\s*##\s+(.+)", DscLine)
>
> if Match:
>
> @@ -748,6 +869,7 @@ EndList
> ConfigDict['struct'] = ''
>
> ConfigDict['embed'] = ''
>
> ConfigDict['comment'] = ''
>
> + ConfigDict['marker'] = ''
>
> ConfigDict['order'] = -1
>
> ConfigDict['subreg'] = []
>
> ConfigDict['option'] = ''
>
> @@ -786,9 +908,8 @@ EndList
> bitsvalue = bitsvalue[::-1]
>
> bitslen = len(bitsvalue)
>
> if start > bitslen or end > bitslen:
>
> - print ("Invalid bits offset [%d,%d] for %s" % (start, end, subitem['name']))
>
> - raise SystemExit
>
> - return hex(int(bitsvalue[start:end][::-1], 2))
>
> + raise Exception ("Invalid bits offset [%d,%d] %d for %s" % (start, end,
> bitslen, subitem['name']))
>
> + return '0x%X' % (int(bitsvalue[start:end][::-1], 2))
>
>
>
> def UpdateSubRegionDefaultValue (self):
>
> Error = 0
>
> @@ -888,63 +1009,142 @@ EndList
> TxtFd.close()
>
> return 0
>
>
>
> - def ProcessMultilines (self, String, MaxCharLength):
>
> - Multilines = ''
>
> - StringLength = len(String)
>
> - CurrentStringStart = 0
>
> - StringOffset = 0
>
> - BreakLineDict = []
>
> - if len(String) <= MaxCharLength:
>
> - while (StringOffset < StringLength):
>
> - if StringOffset >= 1:
>
> - if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
>
> - BreakLineDict.append (StringOffset + 1)
>
> - StringOffset += 1
>
> - if BreakLineDict != []:
>
> - for Each in BreakLineDict:
>
> - Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
>
> - CurrentStringStart = Each
>
> - if StringLength - CurrentStringStart > 0:
>
> - Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
>
> + def CreateVarDict (self):
>
> + Error = 0
>
> + self._VarDict = {}
>
> + if len(self._CfgItemList) > 0:
>
> + Item = self._CfgItemList[-1]
>
> + self._VarDict['_LENGTH_'] = '%d' % (Item['offset'] + Item['length'])
>
> + for Item in self._CfgItemList:
>
> + Embed = Item['embed']
>
> + Match = re.match("^(\w+):(\w+):(START|END)", Embed)
>
> + if Match:
>
> + StructName = Match.group(1)
>
> + VarName = '_%s_%s_' % (Match.group(3), StructName)
>
> + if Match.group(3) == 'END':
>
> + self._VarDict[VarName] = Item['offset'] + Item['length']
>
> + self._VarDict['_LENGTH_%s_' % StructName] = \
>
> + self._VarDict['_END_%s_' % StructName] -
> self._VarDict['_START_%s_' % StructName]
>
> + if Match.group(2).startswith('TAG_'):
>
> + if (self.Mode != 'FSP') and (self._VarDict['_LENGTH_%s_' %
> StructName] % 4):
>
> + raise Exception("Size of structure '%s' is %d, not DWORD
> aligned !" % (StructName, self._VarDict['_LENGTH_%s_' % StructName]))
>
> + self._VarDict['_TAG_%s_' % StructName] = int
> (Match.group(2)[4:], 16) & 0xFFF
>
> else:
>
> - Multilines = " %s\n" % String
>
> + self._VarDict[VarName] = Item['offset']
>
> + if Item['marker']:
>
> + self._VarDict['_OFFSET_%s_' % Item['marker'].strip()] = Item['offset']
>
> + return Error
>
> +
>
> + def UpdateBsfBitUnit (self, Item):
>
> + BitTotal = 0
>
> + BitOffset = 0
>
> + StartIdx = 0
>
> + Unit = None
>
> + UnitDec = {1:'BYTE', 2:'WORD', 4:'DWORD', 8:'QWORD'}
>
> + for Idx, SubItem in enumerate(Item['subreg']):
>
> + if Unit is None:
>
> + Unit = SubItem['bitunit']
>
> + BitLength = SubItem['bitlength']
>
> + BitTotal += BitLength
>
> + BitOffset += BitLength
>
> +
>
> + if BitOffset > 64 or BitOffset > Unit * 8:
>
> + break
>
> +
>
> + if BitOffset == Unit * 8:
>
> + for SubIdx in range (StartIdx, Idx + 1):
>
> + Item['subreg'][SubIdx]['bitunit'] = Unit
>
> + BitOffset = 0
>
> + StartIdx = Idx + 1
>
> + Unit = None
>
> +
>
> + if BitOffset > 0:
>
> + raise Exception ("Bit fields cannot fit into %s for '%s.%s' !" %
> (UnitDec[Unit], Item['cname'], SubItem['cname']))
>
> +
>
> + ExpectedTotal = Item['length'] * 8
>
> + if Item['length'] * 8 != BitTotal:
>
> + raise Exception ("Bit fields total length (%d) does not match length (%d)
> of '%s' !" % (BitTotal, ExpectedTotal, Item['cname']))
>
> +
>
> + def UpdateDefaultValue (self):
>
> + Error = 0
>
> + for Idx, Item in enumerate(self._CfgItemList):
>
> + if len(Item['subreg']) == 0:
>
> + Value = Item['value']
>
> + if (len(Value) > 0) and (Value[0] == '{' or Value[0] == "'" or Value[0] ==
> '"'):
>
> + # {XXX} or 'XXX' strings
>
> + self.FormatListValue(self._CfgItemList[Idx])
>
> + else:
>
> + Match = re.match("(0x[0-9a-fA-F]+|[0-9]+)", Value)
>
> + if not Match:
>
> + NumValue = self.EvaluateExpress (Value)
>
> + Item['value'] = '0x%X' % NumValue
>
> else:
>
> - NewLineStart = 0
>
> - NewLineCount = 0
>
> - FoundSpaceChar = False
>
> - while (StringOffset < StringLength):
>
> - if StringOffset >= 1:
>
> - if NewLineCount >= MaxCharLength - 1:
>
> - if String[StringOffset] == ' ' and StringLength - StringOffset > 10:
>
> - BreakLineDict.append (NewLineStart + NewLineCount)
>
> - NewLineStart = NewLineStart + NewLineCount
>
> - NewLineCount = 0
>
> - FoundSpaceChar = True
>
> - elif StringOffset == StringLength - 1 and FoundSpaceChar ==
> False:
>
> - BreakLineDict.append (0)
>
> - if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
>
> - BreakLineDict.append (StringOffset + 1)
>
> - NewLineStart = StringOffset + 1
>
> + ValArray = self.ValueToByteArray (Item['value'], Item['length'])
>
> + for SubItem in Item['subreg']:
>
> + SubItem['value'] = self.GetBsfBitFields(SubItem, ValArray)
>
> + self.UpdateBsfBitUnit (Item)
>
> + return Error
>
> +
>
> + def ProcessMultilines (self, String, MaxCharLength):
>
> + Multilines = ''
>
> + StringLength = len(String)
>
> + CurrentStringStart = 0
>
> + StringOffset = 0
>
> + BreakLineDict = []
>
> + if len(String) <= MaxCharLength:
>
> + while (StringOffset < StringLength):
>
> + if StringOffset >= 1:
>
> + if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
>
> + BreakLineDict.append (StringOffset + 1)
>
> + StringOffset += 1
>
> + if BreakLineDict != []:
>
> + for Each in BreakLineDict:
>
> + Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
>
> + CurrentStringStart = Each
>
> + if StringLength - CurrentStringStart > 0:
>
> + Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
>
> + else:
>
> + Multilines = " %s\n" % String
>
> + else:
>
> + NewLineStart = 0
>
> + NewLineCount = 0
>
> + FoundSpaceChar = False
>
> + while (StringOffset < StringLength):
>
> + if StringOffset >= 1:
>
> + if NewLineCount >= MaxCharLength - 1:
>
> + if String[StringOffset] == ' ' and StringLength - StringOffset > 10:
>
> + BreakLineDict.append (NewLineStart + NewLineCount)
>
> + NewLineStart = NewLineStart + NewLineCount
>
> NewLineCount = 0
>
> - StringOffset += 1
>
> - NewLineCount += 1
>
> - if BreakLineDict != []:
>
> - BreakLineDict.sort ()
>
> - for Each in BreakLineDict:
>
> - if Each > 0:
>
> - Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
>
> - CurrentStringStart = Each
>
> - if StringLength - CurrentStringStart > 0:
>
> - Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
>
> - return Multilines
>
> -
>
> - def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help,
> Option):
>
> + FoundSpaceChar = True
>
> + elif StringOffset == StringLength - 1 and FoundSpaceChar == False:
>
> + BreakLineDict.append (0)
>
> + if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
>
> + BreakLineDict.append (StringOffset + 1)
>
> + NewLineStart = StringOffset + 1
>
> + NewLineCount = 0
>
> + StringOffset += 1
>
> + NewLineCount += 1
>
> + if BreakLineDict != []:
>
> + BreakLineDict.sort ()
>
> + for Each in BreakLineDict:
>
> + if Each > 0:
>
> + Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
>
> + CurrentStringStart = Each
>
> + if StringLength - CurrentStringStart > 0:
>
> + Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
>
> + return Multilines
>
> +
>
> + def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help,
> Option, BitsLength = None):
>
> PosName = 28
>
> PosComment = 30
>
> NameLine=''
>
> HelpLine=''
>
> OptionLine=''
>
>
>
> + if Length == 0 and Name == 'Dummy':
>
> + return '\n'
>
> +
>
> IsArray = False
>
> if Length in [1,2,4,8]:
>
> Type = "UINT%d" % (Length * 8)
>
> @@ -992,7 +1192,12 @@ EndList
> else:
>
> OffsetStr = '0x%04X' % Offset
>
>
>
> - return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine,
> HelpLine, OptionLine, Type, ' ' * Space1, Name,)
>
> + if BitsLength is None:
>
> + BitsLength = ''
>
> + else:
>
> + BitsLength = ' : %d' % BitsLength
>
> +
>
> + return "\n/** Offset %s%s%s%s**/\n %s%s%s%s;\n" % (OffsetStr,
> NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name, BitsLength)
>
>
>
> def PostProcessBody (self, TextBody):
>
> NewTextBody = []
>
> @@ -1097,6 +1302,7 @@ EndList
> UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
>
> for Item in self._CfgItemList:
>
> if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:
>
> + Item["offset"] = 0 # re-initialize offset to 0 when new UPD structure
> starting
>
> UpdOffsetTable.append (Item["offset"])
>
>
>
> for UpdIdx in range(len(UpdOffsetTable)):
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h
> b/IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h
> new file mode 100644
> index 0000000000..be2ed8aa99
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h
> @@ -0,0 +1,16 @@
> +#ifndef __FSPUPD_H__
>
> +#define __FSPUPD_H__
>
> +
>
> +#include <FspEas.h>
>
> +
>
> +#pragma pack(1)
>
> +
>
> +#define FSPT_UPD_SIGNATURE 0x545F4450554D4551 /*
> 'QEMUPD_T' */
>
> +
>
> +#define FSPM_UPD_SIGNATURE 0x4D5F4450554D4551 /*
> 'QEMUPD_M' */
>
> +
>
> +#define FSPS_UPD_SIGNATURE 0x535F4450554D4551 /*
> 'QEMUPD_S' */
>
> +
>
> +#pragma pack()
>
> +
>
> +#endif
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h
> b/IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h
> new file mode 100644
> index 0000000000..83fd06ecb4
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h
> @@ -0,0 +1,75 @@
> +#ifndef __FSPMUPD_H__
>
> +#define __FSPMUPD_H__
>
> +
>
> +#include <FspUpd.h>
>
> +
>
> +#pragma pack(1)
>
> +
>
> +
>
> +/** Fsp M Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x00C8 - Debug Serial Port Base address
>
> + Debug serial port base address. This option will be used only when the 'Serial
> Port
>
> + Debug Device' option is set to 'External Device'. 0x00000000(Default).
>
> +**/
>
> + UINT32 SerialDebugPortAddress;
>
> +
>
> +/** Offset 0x00CC - Debug Serial Port Type
>
> + 16550 compatible debug serial port resource type. NONE means no serial port
> support.
>
> + 0x02:MMIO(Default).
>
> + 0:NONE, 1:I/O, 2:MMIO
>
> +**/
>
> + UINT8 SerialDebugPortType;
>
> +
>
> +/** Offset 0x00CD - Serial Port Debug Device
>
> + Select active serial port device for debug. For SOC UART devices,'Debug Serial
> Port
>
> + Base' options will be ignored. 0x02:SOC UART2(Default).
>
> + 0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External Device
>
> +**/
>
> + UINT8 SerialDebugPortDevice;
>
> +
>
> +/** Offset 0x00CE - Debug Serial Port Stride Size
>
> + Debug serial port register map stride size in bytes. 0x00:1, 0x02:4(Default).
>
> + 0:1, 2:4
>
> +**/
>
> + UINT8 SerialDebugPortStrideSize;
>
> +
>
> +/** Offset 0x00CF
>
> +**/
>
> + UINT8 UnusedUpdSpace2[1];
>
> +
>
> +/** Offset 0x00D0
>
> +**/
>
> + UINT8 ReservedFspmUpd[4];
>
> +} FSP_M_CONFIG;
>
> +
>
> +/** Fsp M UPD Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0000
>
> +**/
>
> + FSP_UPD_HEADER FspUpdHeader;
>
> +
>
> +/** Offset 0x00A8
>
> +**/
>
> + FSPM_ARCH_UPD FspmArchUpd;
>
> +
>
> +/** Offset 0x00C8
>
> +**/
>
> + FSP_M_CONFIG FspmConfig;
>
> +
>
> +/** Offset 0x00D4
>
> +**/
>
> + UINT8 UnusedUpdSpace3[2];
>
> +
>
> +/** Offset 0x00D6
>
> +**/
>
> + UINT16 UpdTerminator;
>
> +} FSPM_UPD;
>
> +
>
> +#pragma pack()
>
> +
>
> +#endif
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h
> b/IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h
> new file mode 100644
> index 0000000000..e2bc54a61d
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h
> @@ -0,0 +1,69 @@
> +#ifndef __FSPSUPD_H__
>
> +#define __FSPSUPD_H__
>
> +
>
> +#include <FspUpd.h>
>
> +
>
> +#pragma pack(1)
>
> +
>
> +
>
> +/** Fsp S Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0118 - BMP Logo Data Size
>
> + BMP logo data buffer size. 0x00000000(Default).
>
> +**/
>
> + UINT32 LogoSize;
>
> +
>
> +/** Offset 0x011C - BMP Logo Data Pointer
>
> + BMP logo data pointer to a BMP format buffer. 0x00000000(Default).
>
> +**/
>
> + UINT32 LogoPtr;
>
> +
>
> +/** Offset 0x0120 - Graphics Configuration Data Pointer
>
> + Graphics configuration data used for initialization. 0x00000000(Default).
>
> +**/
>
> + UINT32 GraphicsConfigPtr;
>
> +
>
> +/** Offset 0x0124 - PCI GFX Temporary MMIO Base
>
> + PCI Temporary PCI GFX Base used before full PCI enumeration.
> 0x80000000(Default).
>
> +**/
>
> + UINT32 PciTempResourceBase;
>
> +
>
> +/** Offset 0x0128
>
> +**/
>
> + UINT8 UnusedUpdSpace1[3];
>
> +
>
> +/** Offset 0x012B
>
> +**/
>
> + UINT8 ReservedFspsUpd;
>
> +} FSP_S_CONFIG;
>
> +
>
> +/** Fsp S UPD Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0000
>
> +**/
>
> + FSP_UPD_HEADER FspUpdHeader;
>
> +
>
> +/** Offset 0x00F8
>
> +**/
>
> + FSPS_ARCH_UPD FspsArchUpd;
>
> +
>
> +/** Offset 0x0118
>
> +**/
>
> + FSP_S_CONFIG FspsConfig;
>
> +
>
> +/** Offset 0x012C
>
> +**/
>
> + UINT8 UnusedUpdSpace2[2];
>
> +
>
> +/** Offset 0x012E
>
> +**/
>
> + UINT16 UpdTerminator;
>
> +} FSPS_UPD;
>
> +
>
> +#pragma pack()
>
> +
>
> +#endif
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h
> b/IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h
> new file mode 100644
> index 0000000000..25b8a7d63a
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h
> @@ -0,0 +1,87 @@
> +#ifndef __FSPTUPD_H__
>
> +#define __FSPTUPD_H__
>
> +
>
> +#include <FspUpd.h>
>
> +
>
> +#pragma pack(1)
>
> +
>
> +
>
> +/** Fsp T Common UPD
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0040
>
> +**/
>
> + UINT8 Revision;
>
> +
>
> +/** Offset 0x0041
>
> +**/
>
> + UINT8 Reserved[3];
>
> +
>
> +/** Offset 0x0044
>
> +**/
>
> + UINT32 MicrocodeRegionBase;
>
> +
>
> +/** Offset 0x0048
>
> +**/
>
> + UINT32 MicrocodeRegionLength;
>
> +
>
> +/** Offset 0x004C
>
> +**/
>
> + UINT32 CodeRegionBase;
>
> +
>
> +/** Offset 0x0050
>
> +**/
>
> + UINT32 CodeRegionLength;
>
> +
>
> +/** Offset 0x0054
>
> +**/
>
> + UINT8 Reserved1[12];
>
> +} FSPT_COMMON_UPD;
>
> +
>
> +/** Fsp T Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0060 - Chicken bytes to test Hex config
>
> + This option shows how to present option for 4 bytes data
>
> +**/
>
> + UINT32 ChickenBytes;
>
> +
>
> +/** Offset 0x0064
>
> +**/
>
> + UINT8 ReservedFsptUpd1[28];
>
> +} FSP_T_CONFIG;
>
> +
>
> +/** Fsp T UPD Configuration
>
> +**/
>
> +typedef struct {
>
> +
>
> +/** Offset 0x0000
>
> +**/
>
> + FSP_UPD_HEADER FspUpdHeader;
>
> +
>
> +/** Offset 0x0020
>
> +**/
>
> + FSPT_ARCH_UPD FsptArchUpd;
>
> +
>
> +/** Offset 0x0040
>
> +**/
>
> + FSPT_COMMON_UPD FsptCommonUpd;
>
> +
>
> +/** Offset 0x0060
>
> +**/
>
> + FSP_T_CONFIG FsptConfig;
>
> +
>
> +/** Offset 0x0080
>
> +**/
>
> + UINT8 UnusedUpdSpace0[6];
>
> +
>
> +/** Offset 0x0086
>
> +**/
>
> + UINT16 UpdTerminator;
>
> +} FSPT_UPD;
>
> +
>
> +#pragma pack()
>
> +
>
> +#endif
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf
> b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf
> new file mode 100644
> index 0000000000..750e1b4faf
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf
> @@ -0,0 +1,88 @@
> +GlobalDataDef
>
> + SKUID = 0, "DEFAULT"
>
> +EndGlobalData
>
> +
>
> +
>
> +StructDef
>
> +
>
> + Find "QEMUPD_T"
>
> + $gQemuFspPkgTokenSpaceGuid_Revision 1 bytes
> $_DEFAULT_ = 0x01
>
> + Skip 87 bytes
>
> + $gQemuFspPkgTokenSpaceGuid_ChickenBytes 4 bytes
> $_DEFAULT_ = 0x00000000
>
> +
>
> + Find "QEMUPD_M"
>
> + $gQemuFspPkgTokenSpaceGuid_Revision 1 bytes
> $_DEFAULT_ = 0x01
>
> + Skip 35 bytes
>
> + $gQemuFspPkgTokenSpaceGuid_StackBase 4 bytes
> $_DEFAULT_ = 0x00070000
>
> + $gQemuFspPkgTokenSpaceGuid_StackSize 4 bytes
> $_DEFAULT_ = 0x00010000
>
> + $gQemuFspPkgTokenSpaceGuid_BootLoaderTolumSize 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + $gPlatformFspPkgTokenSpaceGuid_Bootmode 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + Skip 8 bytes
>
> + $gQemuFspPkgTokenSpaceGuid_SerialDebugPortAddress 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + $gQemuFspPkgTokenSpaceGuid_SerialDebugPortType 1 bytes
> $_DEFAULT_ = 0x02
>
> + $gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice 1 bytes
> $_DEFAULT_ = 0x02
>
> + $gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize 1 bytes
> $_DEFAULT_ = 0x02
>
> +
>
> + Find "QEMUPD_S"
>
> + $gQemuFspPkgTokenSpaceGuid_Revision 1 bytes
> $_DEFAULT_ = 0x01
>
> + Skip 55 bytes
>
> + $gQemuFspPkgTokenSpaceGuid_LogoSize 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + $gQemuFspPkgTokenSpaceGuid_LogoPtr 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + $gQemuFspPkgTokenSpaceGuid_GraphicsConfigPtr 4 bytes
> $_DEFAULT_ = 0x00000000
>
> + $gQemuFspPkgTokenSpaceGuid_PciTempResourceBase 4 bytes
> $_DEFAULT_ = 0x80000000
>
> +
>
> +EndStruct
>
> +
>
> +
>
> +List &EN_DIS
>
> + Selection 0x1 , "Enabled"
>
> + Selection 0x0 , "Disabled"
>
> +EndList
>
> +
>
> +List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortType
>
> + Selection 0 , "NONE"
>
> + Selection 1 , "I/O"
>
> + Selection 2 , "MMIO"
>
> +EndList
>
> +
>
> +List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice
>
> + Selection 0 , "SOC UART0"
>
> + Selection 1 , "SOC UART1"
>
> + Selection 2 , "SOC UART2"
>
> + Selection 3 , "External Device"
>
> +EndList
>
> +
>
> +List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize
>
> + Selection 0 , "1"
>
> + Selection 2 , "4"
>
> +EndList
>
> +
>
> +BeginInfoBlock
>
> + PPVer "0.1"
>
> + Description "QEMU Platform"
>
> +EndInfoBlock
>
> +
>
> +Page "FSP T"
>
> + EditNum $gQemuFspPkgTokenSpaceGuid_ChickenBytes, "Chicken bytes to
> test Hex config", HEX,
>
> + Help "This option shows how to present option for 4 bytes data"
>
> + "Valid range: 0x00000000 ~ 0xFFFFFFFF"
>
> +EndPage
>
> +
>
> +Page "FSP MemoryInit Settings"
>
> + EditNum $gQemuFspPkgTokenSpaceGuid_SerialDebugPortAddress, "Debug
> Serial Port Base address", HEX,
>
> + Help "Debug serial port base address. This option will be used only when
> the 'Serial Port Debug Device' option is set to 'External Device'.
> 0x00000000(Default)."
>
> + "Valid range: 0x00000000 ~ 0xFFFFFFFF"
>
> + Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortType, "Debug Serial
> Port Type", &gQemuFspPkgTokenSpaceGuid_SerialDebugPortType,
>
> + Help "16550 compatible debug serial port resource type. NONE means no
> serial port support. 0x02:MMIO(Default)."
>
> + Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice, "Serial Port
> Debug Device", &gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice,
>
> + Help "Select active serial port device for debug. For SOC UART
> devices,'Debug Serial Port Base' options will be ignored. 0x02:SOC
> UART2(Default)."
>
> + Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize, "Debug
> Serial Port Stride Size",
> &gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize,
>
> + Help "Debug serial port register map stride size in bytes. 0x00:1,
> 0x02:4(Default)."
>
> +EndPage
>
> +
>
> +Page "FSP SiliconInit Settings"
>
> + EditNum $gQemuFspPkgTokenSpaceGuid_PciTempResourceBase, "PCI GFX
> Temporary MMIO Base", HEX,
>
> + Help "PCI Temporary PCI GFX Base used before full PCI enumeration.
> 0x80000000(Default)."
>
> + "Valid range: 0x80000000 ~ 0xDFFFFFFF"
>
> +EndPage
>
> +
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml
> b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml
> new file mode 100644
> index 0000000000..3594b9895e
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml
> @@ -0,0 +1,270 @@
> +variable:
>
> + PLATFORM_NAME : QemuFspPkg
>
> + PLATFORM_GUID : 1BEDB57A-7904-406e-8486-C89FC7FB39EE
>
> + PLATFORM_VERSION : 0.1
>
> + DSC_SPECIFICATION : 0x00010005
>
> + OUTPUT_DIRECTORY : Build/QemuFspPkg
>
> + SUPPORTED_ARCHITECTURES : IA32|X64
>
> + BUILD_TARGETS : DEBUG|RELEASE
>
> + SKUID_IDENTIFIER : DEFAULT
>
> + FLASH_DEFINITION : QemuFspPkg/QemuFspPkg.fdf
>
> + FSP_T_UPD_TOOL_GUID : 34686CA3-34F9-4901-B82A-BA630F0714C6
>
> + FSP_V_UPD_TOOL_GUID : 4E2F4725-734A-4399-BAF5-B4E16348EB2F
>
> + FSP_M_UPD_TOOL_GUID : 39A250DB-E465-4DD1-A2AC-
> E2BD3C0E2385
>
> + FSP_S_UPD_TOOL_GUID : CAE3605B-5B34-4C85-B3D7-27D54273C40F
>
> + FSP_T_UPD_FFS_GUID : 70BCF6A5-FFB1-47D8-B1AE-EFE5508E23EA
>
> + FSP_V_UPD_FFS_GUID : 0197EF5E-2FFC-4089-8E55-F70400B18146
>
> + FSP_M_UPD_FFS_GUID : D5B86AEA-6AF7-40D4-8014-982301BC3D89
>
> + FSP_S_UPD_FFS_GUID : E3CD9B18-998C-4F76-B65E-98B154E5446F
>
> + FSP_PACKAGE : QemuFspPkg
>
> + FSP_IMAGE_ID : 0x245053464D455124 # $QEMFSP$
>
> + FSP_IMAGE_REV : 0x00001010
>
> + CAR_BASE_ADDRESS : 0x00000000
>
> + CAR_REGION_SIZE : 0x00080000
>
> + CAR_BLD_REGION_SIZE : 0x00070000
>
> + CAR_FSP_REGION_SIZE : 0x00010000
>
> + FSP_ARCH : X64
>
> +
>
> +
>
> +template:
>
> +
>
> +
>
> +configs:
>
> + - $ACTION :
>
> + page : TMP::"FSP T", MEM::"FSP MemoryInit Settings", SIL::"FSP
> SiliconInit Settings"
>
> + - $ACTION :
>
> + find : QEMUPD_T
>
> + - FSPT_UPD :
>
> + - FSP_UPD_HEADER :
>
> + - Signature :
>
> + length : 0x08
>
> + value : 0x545F4450554D4551
>
> + - Revision :
>
> + name : FsptUpdRevision
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x17
>
> + value : {0x00}
>
> + - FSPT_ARCH_UPD :
>
> + - Revision :
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x03
>
> + value : {0x00}
>
> + - Length :
>
> + length : 0x04
>
> + value : 0x00000020
>
> + - FspDebugHandler :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - Reserved1 :
>
> + length : 0x14
>
> + value : {0x00}
>
> + - FSPT_COMMON_UPD :
>
> + - Revision :
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x03
>
> + value : {0x00}
>
> + - MicrocodeRegionBase :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - MicrocodeRegionLength :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - CodeRegionBase :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - CodeRegionLength :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - Reserved1 :
>
> + length : 0x0C
>
> + value : {0x00}
>
> + - FSP_T_CONFIG :
>
> + - $ACTION :
>
> + page : TMP
>
> + - ChickenBytes :
>
> + name : Chicken bytes to test Hex config
>
> + type : EditNum, HEX, (0x00000000,0xFFFFFFFF)
>
> + help : >
>
> + This option shows how to present option for 4 bytes data
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - ReservedFsptUpd1 :
>
> + length : 0x1C
>
> + value : {0x00}
>
> + - UpdTerminator :
>
> + length : 0x02
>
> + value : 0x55AA
>
> + - $ACTION :
>
> + find : QEMUPD_M
>
> +
>
> + - FSPM_UPD :
>
> + - FSP_UPD_HEADER :
>
> + - Signature :
>
> + length : 0x08
>
> + value : 0x4D5F4450554D4551
>
> + - Revision :
>
> + name : FspmUpdRevision
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x17
>
> + value : {0x00}
>
> + - FSPM_ARCH_UPD :
>
> + - Revision :
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x03
>
> + value : {0x00}
>
> + - NvsBufferPtr :
>
> + struct : VOID*
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - StackBase :
>
> + struct : VOID*
>
> + name : StackBase
>
> + help : >
>
> + Stack base for FSP use. Default- 0xFEF16000
>
> + length : 0x04
>
> + value : $(CAR_BLD_REGION_SIZE)
>
> + - StackSize :
>
> + name : StackSize
>
> + help : >
>
> + To pass the stack size for FSP use. Bootloader can
> programmatically get the FSP requested StackSize by using the defaults in the
> FSP-M component. This is the minimum stack size expected by this revision of
> FSP. Default- 0x2A000
>
> + length : 0x04
>
> + value : $(CAR_FSP_REGION_SIZE)
>
> + - BootLoaderTolumSize :
>
> + name : BootLoaderTolumSize
>
> + help : >
>
> + To pass Bootloader Tolum size.
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - Bootmode :
>
> + name : Bootmode
>
> + help : >
>
> + To maintain Bootmode details.
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - Reserved1 :
>
> + length : 0x08
>
> + value : {0x00}
>
> + - FSP_M_CONFIG :
>
> + - $ACTION :
>
> + page : MEM
>
> + - SerialDebugPortAddress :
>
> + name : Debug Serial Port Base address
>
> + type : EditNum, HEX, (0x00000000,0xFFFFFFFF)
>
> + help : >
>
> + Debug serial port base address. This option will be used only
> when the 'Serial Port Debug Device'
>
> + option is set to 'External Device'. 0x00000000(Default).
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - SerialDebugPortType :
>
> + name : Debug Serial Port Type
>
> + type : Combo
>
> + option : 0:NONE, 1:I/O, 2:MMIO
>
> + help : >
>
> + 16550 compatible debug serial port resource type. NONE means
> no serial port support. 0x02:MMIO(Default).
>
> + length : 0x01
>
> + value : 0x02
>
> + - SerialDebugPortDevice :
>
> + name : Serial Port Debug Device
>
> + type : Combo
>
> + option : 0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External Device
>
> + help : >
>
> + Select active serial port device for debug.
>
> + For SOC UART devices,'Debug Serial Port Base' options will be
> ignored. 0x02:SOC UART2(Default).
>
> + length : 0x01
>
> + value : 0x02
>
> + - SerialDebugPortStrideSize :
>
> + name : Debug Serial Port Stride Size
>
> + type : Combo
>
> + option : 0:1, 2:4
>
> + help : >
>
> + Debug serial port register map stride size in bytes. 0x00:1,
> 0x02:4(Default).
>
> + length : 0x01
>
> + value : 0x02
>
> + - ReservedFspmUpd :
>
> + length : 0x04
>
> + value : {0x00}
>
> + - UpdTerminator :
>
> + length : 0x02
>
> + value : 0x55AA
>
> + - $ACTION :
>
> + find : QEMUPD_S
>
> +
>
> + - FSPS_UPD :
>
> + - FSP_UPD_HEADER :
>
> + - Signature :
>
> + length : 0x08
>
> + value : 0x535F4450554D4551
>
> + - Revision :
>
> + name : FspsUpdRevision
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x17
>
> + value : {0x00}
>
> + - FSPS_ARCH_UPD :
>
> + - Revision :
>
> + length : 0x01
>
> + value : 0x01
>
> + - Reserved :
>
> + length : 0x03
>
> + value : {0x00}
>
> + - Length :
>
> + length : 0x04
>
> + value : 0x00000020
>
> + - FspEventHandler :
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - EnableMultiPhaseSiliconInit :
>
> + length : 0x01
>
> + value : 0x00
>
> + - Reserved1 :
>
> + length : 0x13
>
> + value : {0x00}
>
> + - FSP_S_CONFIG :
>
> + - $ACTION :
>
> + page : SIL
>
> + - LogoSize :
>
> + name : BMP Logo Data Size
>
> + type : Reserved
>
> + help : >
>
> + BMP logo data buffer size. 0x00000000(Default).
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - LogoPtr :
>
> + name : BMP Logo Data Pointer
>
> + type : Reserved
>
> + help : >
>
> + BMP logo data pointer to a BMP format buffer.
> 0x00000000(Default).
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - GraphicsConfigPtr :
>
> + name : Graphics Configuration Data Pointer
>
> + type : Reserved
>
> + help : >
>
> + Graphics configuration data used for initialization.
> 0x00000000(Default).
>
> + length : 0x04
>
> + value : 0x00000000
>
> + - PciTempResourceBase :
>
> + name : PCI GFX Temporary MMIO Base
>
> + type : EditNum, HEX, (0x80000000,0xDFFFFFFF)
>
> + help : >
>
> + PCI Temporary PCI GFX Base used before full PCI enumeration.
> 0x80000000(Default).
>
> + length : 0x04
>
> + value : 0x80000000
>
> + - ReservedFspsUpd :
>
> + length : 0x01
>
> + value : 0x00
>
> + - UpdTerminator :
>
> + length : 0x02
>
> + value : 0x55AA
>
> +
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc
> b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc
> new file mode 100644
> index 0000000000..af0bd4e717
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc
> @@ -0,0 +1,469 @@
> +## @file
>
> +# FSP DSC build file for QEMU platform
>
> +#
>
> +# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
>
> +#
>
> +# This program and the accompanying materials
>
> +# are licensed and made available under the terms and conditions of the BSD
> License
>
> +# which accompanies this distribution. The full text of the license may be
> found at
>
> +# http://opensource.org/licenses/bsd-license.php
>
> +#
>
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
>
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
>
> +#
>
> +##
>
> +
>
> +################################################################
> ################
>
> +#
>
> +# Defines Section - statements that will be processed to create a Makefile.
>
> +#
>
> +################################################################
> ################
>
> +[Defines]
>
> + PLATFORM_NAME = QemuFspPkg
>
> + PLATFORM_GUID = 1BEDB57A-7904-406e-8486-C89FC7FB39EE
>
> + PLATFORM_VERSION = 0.1
>
> + DSC_SPECIFICATION = 0x00010005
>
> + OUTPUT_DIRECTORY = Build/QemuFspPkg
>
> + SUPPORTED_ARCHITECTURES = IA32|X64
>
> + BUILD_TARGETS = DEBUG|RELEASE
>
> + SKUID_IDENTIFIER = DEFAULT
>
> + FLASH_DEFINITION = QemuFspPkg/QemuFspPkg.fdf
>
> +
>
> + #
>
> + # UPD tool definition
>
> + #
>
> + FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
>
> + FSP_V_UPD_TOOL_GUID = 4E2F4725-734A-4399-BAF5-B4E16348EB2F
>
> + FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-
> E2BD3C0E2385
>
> + FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
>
> + FSP_T_UPD_FFS_GUID = 70BCF6A5-FFB1-47D8-B1AE-EFE5508E23EA
>
> + FSP_V_UPD_FFS_GUID = 0197EF5E-2FFC-4089-8E55-F70400B18146
>
> + FSP_M_UPD_FFS_GUID = D5B86AEA-6AF7-40D4-8014-982301BC3D89
>
> + FSP_S_UPD_FFS_GUID = E3CD9B18-998C-4F76-B65E-98B154E5446F
>
> +
>
> + #
>
> + # Set platform specific package/folder name, same as passed from PREBUILD
> script.
>
> + # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as
> package build folder
>
> + # DEFINE only takes effect at R9 DSC and FDF.
>
> + #
>
> + DEFINE FSP_PACKAGE = QemuFspPkg
>
> + DEFINE FSP_IMAGE_ID = 0x245053464D455124 # $QEMFSP$
>
> + DEFINE FSP_IMAGE_REV = 0x00001010
>
> +
>
> + DEFINE CAR_BASE_ADDRESS = 0x00000000
>
> + DEFINE CAR_REGION_SIZE = 0x00080000
>
> + DEFINE CAR_BLD_REGION_SIZE = 0x00070000
>
> + DEFINE CAR_FSP_REGION_SIZE = 0x00010000
>
> +
>
> + DEFINE FSP_ARCH = X64
>
> +
>
> +################################################################
> ################
>
> +#
>
> +# SKU Identification section - list of all SKU IDs supported by this
>
> +# Platform.
>
> +#
>
> +################################################################
> ################
>
> +[SkuIds]
>
> + 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.
>
> +
>
> +################################################################
> ################
>
> +#
>
> +# Library Class section - list of all Library Classes needed by this Platform.
>
> +#
>
> +################################################################
> ################
>
> +
>
> +[LibraryClasses]
>
> + PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
>
> + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
>
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDe
> bugPrintErrorLevelLib.inf
>
> + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
>
> + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
>
> + PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
>
> + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
>
> + PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
>
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr
> .inf
>
> + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
>
> + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>
> + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
>
> +
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiSe
> rvicesTablePointerLibIdt.inf
>
> + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
>
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllo
> cationLib.inf
>
> +
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeC
> offGetEntryPointLib.inf
>
> +
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiRepo
> rtStatusCodeLib.inf
>
> +
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCache
> MaintenanceLib.inf
>
> + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
>
> +
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCo
> ffExtraActionLibNull.inf
>
> +
> UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecomp
> ressLib.inf
>
> +
> SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizati
> onLib.inf
>
> + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
>
> +
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtrac
> tGuidedSectionLib.inf
>
> + CacheLib|IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
>
> +
> CacheAsRamLib|IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRa
> mLibNull.inf
>
> +
> FspSwitchStackLib|IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchS
> tackLib.inf
>
> +
> FspCommonLib|IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.i
> nf
>
> +
> FspPlatformLib|IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.in
> f
>
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatfo
> rmHookLibNull.inf
>
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLib
> Null.inf
>
> +
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/
> OemHookStatusCodeLibNull.inf
>
> + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
>
> +!if $(TARGET) == DEBUG
>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
>
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib
> 16550.inf
>
> +!else
>
> + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
>
> + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
>
> +!endif
>
> +
>
> +
>
> +################################################################
> ################
>
> +#
>
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
>
> +#
>
> +################################################################
> ################
>
> +[PcdsFixedAtBuild]
>
> + gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot | TRUE
>
> + gQemuFspPkgTokenSpaceGuid.PcdFspHeaderRevision | 0x03
>
> + gQemuFspPkgTokenSpaceGuid.PcdFspImageIdString | $(FSP_IMAGE_ID)
>
> + gQemuFspPkgTokenSpaceGuid.PcdFspImageRevision |
> $(FSP_IMAGE_REV)
>
> + #
>
> + # FSP CAR Usages (BL RAM | FSP RAM | FSP CODE)
>
> + #
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase |
> $(CAR_BASE_ADDRESS)
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize |
> $(CAR_REGION_SIZE)
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize |
> $(CAR_FSP_REGION_SIZE)
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize | 0x0100
>
> +
>
> + # This defines how much space will be used for heap in FSP temporary
> memory
>
> + # x % of FSP temporary memory will be used for heap
>
> + # (100 - x) % of FSP temporary memory will be used for stack
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage | 65
>
> +
>
> + # This is a platform specific global pointer used by FSP
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress | 0xFED00148
>
> + gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength | 0x00100000
>
> +
>
> +!if $(TARGET) == RELEASE
>
> + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel | 0x00000000
>
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0
>
> +!else
>
> + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel | 0x80000047
>
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x27
>
> +!endif
>
> +
>
> +[PcdsPatchableInModule]
>
> + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress | 0xE0000000
>
> + #
>
> + # This entry will be patched during the build process
>
> + #
>
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress | 0x12345678
>
> +
>
> +!if $(TARGET) == RELEASE
>
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0
>
> +!else
>
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x80000047
>
> +!endif
>
> +
>
> +[PcdsDynamicVpd.Upd]
>
> + #
>
> + # This section is not used by the normal build process
>
> + # However, FSP will use dedicated tool to handle it and generate a
>
> + # VPD similar binary block (User Configuration Data). This block will
>
> + # be accessed through a generated data structure directly rather than
>
> + # PCD services. This is for size consideration.
>
> + # Format:
>
> + # gQemuFspPkgTokenSpaceGuid.Updxxxxxxxxxxxxn | OFFSET | LENGTH |
> VALUE
>
> + # Only simple data type is supported
>
> + #
>
> +
>
> + #
>
> + # Comments with !BSF will be used to generate BSF file
>
> + # Comments with !HDR will be used to generate H header file
>
> + #
>
> +
>
> + # Global definitions in BSF
>
> + # !BSF PAGES:{TMP:"FSP T", MEM:"FSP MemoryInit Settings", SIL:"FSP
> SiliconInit Settings"}
>
> + # !BSF BLOCK:{NAME:"QEMU Platform", VER:"0.1"}
>
> +
>
> + # !BSF FIND:{QEMUPD_T}
>
> + # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}
>
> + # FsptUpdSignature: {QEMUPD_T}
>
> + gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 |
> 0x545F4450554D4551
>
> + # !BSF NAME:{FsptUpdRevision}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSPT_ARCH_UPD:FSPT_ARCH_UPD}
>
> + # !HDR EMBED:{FSPT_ARCH_UPD:FsptArchUpd:START}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00}
>
> + gQemuFspPkgTokenSpaceGuid.Length | * | 0x04 | 0x00000020
>
> + gQemuFspPkgTokenSpaceGuid.FspDebugHandler | * | 0x04 |
> 0x00000000
>
> + # !HDR EMBED:{FSPT_ARCH_UPD:FsptArchUpd:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x14 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSPT_COMMON_UPD:Fsp T Common UPD}
>
> + # !HDR EMBED:{FSPT_COMMON_UPD:FsptCommonUpd:START}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00}
>
> +
>
> + # Base address of the microcode region.
>
> + gQemuFspPkgTokenSpaceGuid.MicrocodeRegionBase | * | 0x04 |
> 0x00000000
>
> +
>
> + # Length of the microcode region.
>
> + gQemuFspPkgTokenSpaceGuid.MicrocodeRegionLength | * | 0x04 |
> 0x00000000
>
> +
>
> + # Base address of the cacheable flash region.
>
> + gQemuFspPkgTokenSpaceGuid.CodeRegionBase | * | 0x04 |
> 0x00000000
>
> +
>
> + # Length of the cacheable flash region.
>
> + gQemuFspPkgTokenSpaceGuid.CodeRegionLength | * | 0x04 |
> 0x00000000
>
> +
>
> + # !HDR EMBED:{FSPT_COMMON_UPD:FsptCommonUpd:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x0C | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSP_T_CONFIG:Fsp T Configuration}
>
> + # !HDR EMBED:{FSP_T_CONFIG:FsptConfig:START}
>
> + # !BSF PAGE:{TMP}
>
> + # !BSF NAME:{Chicken bytes to test Hex config}
>
> + # !BSF TYPE:{EditNum, HEX, (0x00000000,0xFFFFFFFF)}
>
> + # !BSF HELP:{This option shows how to present option for 4 bytes data}
>
> + gQemuFspPkgTokenSpaceGuid.ChickenBytes | * | 0x04 | 0x00000000
>
> +
>
> + # !HDR EMBED:{FSP_T_CONFIG:FsptConfig:END}
>
> + gQemuFspPkgTokenSpaceGuid.ReservedFsptUpd1 | * | 0x1C | {0x00}
>
> +
>
> + # Note please keep "UpdTerminator" at the end of each UPD region.
>
> + # The tool will use this field to determine the actual end of the UPD data
>
> + # structure.
>
> + gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55AA
>
> +
>
> +
> #################################################################
> ###############
>
> + #
>
> + # UPDs consumed in FspMemoryInit Api
>
> + #
>
> +
> #################################################################
> ###############
>
> + # !BSF FIND:{QEMUPD_M}
>
> + # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}
>
> + # FspmUpdSignature: {QEMUPD_M}
>
> + gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 |
> 0x4D5F4450554D4551
>
> + # !BSF NAME:{FspmUpdRevision}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSPM_ARCH_UPD:Fsp M Architectural UPD}
>
> + # !HDR EMBED:{FSPM_ARCH_UPD:FspmArchUpd:START}
>
> +
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> +
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00}
>
> +
>
> + # !HDR STRUCT:{VOID*}
>
> + gQemuFspPkgTokenSpaceGuid.NvsBufferPtr | * | 0x04 | 0x00000000
>
> +
>
> + # !HDR STRUCT:{VOID*}
>
> + # !BSF NAME:{StackBase}
>
> + # !BSF HELP:{Stack base for FSP use. Default: 0xFEF16000}
>
> + gQemuFspPkgTokenSpaceGuid.StackBase | * | 0x04 |
> $(CAR_BLD_REGION_SIZE)
>
> +
>
> + # !BSF NAME:{StackSize}
>
> + # !BSF HELP:{To pass the stack size for FSP use. Bootloader can
> programmatically get the FSP requested StackSize by using the defaults in the
> FSP-M component. This is the minimum stack size expected by this revision of
> FSP. Default: 0x2A000}
>
> + gQemuFspPkgTokenSpaceGuid.StackSize | * | 0x04 |
> $(CAR_FSP_REGION_SIZE)
>
> +
>
> + # !BSF NAME:{BootLoaderTolumSize}
>
> + # !BSF HELP:{To pass Bootloader Tolum size.}
>
> + gQemuFspPkgTokenSpaceGuid.BootLoaderTolumSize | * | 0x04 |
> 0x00000000
>
> +
>
> + # !BSF NAME:{Bootmode}
>
> + # !BSF HELP:{To maintain Bootmode details.}
>
> + gPlatformFspPkgTokenSpaceGuid.Bootmode | * | 0x04 |
> 0x00000000
>
> +
>
> + # !HDR EMBED:{FSPM_ARCH_UPD:FspmArchUpd:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x08 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSP_M_CONFIG:Fsp M Configuration}
>
> + # !HDR EMBED:{FSP_M_CONFIG:FspmConfig:START}
>
> + # !BSF PAGE:{MEM}
>
> + # !BSF NAME:{Debug Serial Port Base address}
>
> + # !BSF TYPE:{EditNum, HEX, (0x00000000,0xFFFFFFFF)}
>
> + # !BSF HELP:{Debug serial port base address. This option will be used only
> when the 'Serial Port Debug Device'}
>
> + # !BSF HELP:{+ option is set to 'External Device'. 0x00000000(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.SerialDebugPortAddress | * | 0x04 |
> 0x00000000
>
> +
>
> + # !BSF NAME:{Debug Serial Port Type} TYPE:{Combo}
>
> + # !BSF OPTION:{0:NONE, 1:I/O, 2:MMIO}
>
> + # !BSF HELP:{16550 compatible debug serial port resource type. NONE means
> no serial port support. 0x02:MMIO(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.SerialDebugPortType | * | 0x01 | 0x02
>
> +
>
> + # !BSF NAME:{Serial Port Debug Device} TYPE:{Combo}
>
> + # !BSF OPTION:{0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External Device}
>
> + # !BSF HELP:{Select active serial port device for debug. }
>
> + # !BSF HELP:{+For SOC UART devices,'Debug Serial Port Base' options will be
> ignored. 0x02:SOC UART2(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.SerialDebugPortDevice | * | 0x01 | 0x02
>
> +
>
> + # !BSF NAME:{Debug Serial Port Stride Size} TYPE:{Combo}
>
> + # !BSF OPTION:{0:1, 2:4}
>
> + # !BSF HELP:{Debug serial port register map stride size in bytes. 0x00:1,
> 0x02:4(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.SerialDebugPortStrideSize | * | 0x01 | 0x02
>
> +
>
> +
>
> + # !HDR EMBED:{FSP_M_CONFIG:FspmConfig:END}
>
> + gQemuFspPkgTokenSpaceGuid.ReservedFspmUpd | * | 0x04 | {0x00}
>
> +
>
> +
>
> + # Note please keep "UpdTerminator" at the end of each UPD region.
>
> + # The tool will use this field to determine the actual end of the UPD data
>
> + # structure.
>
> + gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55AA
>
> +
>
> +
> #################################################################
> ###############
>
> + #
>
> + # UPDs consumed in FspSiliconInit Api
>
> + #
>
> +
> #################################################################
> ###############
>
> + # !BSF FIND:{QEMUPD_S}
>
> + # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}
>
> + # FspsUpdSignature: {QEMUPD_S}
>
> + gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 |
> 0x535F4450554D4551
>
> + # !BSF NAME:{FspsUpdRevision}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSPS_ARCH_UPD:FSPS_ARCH_UPD}
>
> + # !HDR EMBED:{FSPS_ARCH_UPD:FspsArchUpd:START}
>
> + gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01
>
> + gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00}
>
> + gQemuFspPkgTokenSpaceGuid.Length | * | 0x04 | 0x00000020
>
> + gQemuFspPkgTokenSpaceGuid.FspEventHandler | * | 0x04 |
> 0x00000000
>
> + gQemuFspPkgTokenSpaceGuid.EnableMultiPhaseSiliconInit | * | 0x01 | 0x00
>
> + # !HDR EMBED:{FSPS_ARCH_UPD:FspsArchUpd:END}
>
> + gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x13 | {0x00}
>
> +
>
> + # !HDR COMMENT:{FSP_S_CONFIG:Fsp S Configuration}
>
> + # !HDR EMBED:{FSP_S_CONFIG:FspsConfig:START}
>
> + # !BSF PAGE:{SIL}
>
> +
>
> + # !BSF NAME:{BMP Logo Data Size}
>
> + # !BSF TYPE:{Reserved}
>
> + # !BSF HELP:{BMP logo data buffer size. 0x00000000(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.LogoSize | * | 0x04 | 0x00000000
>
> +
>
> + # !BSF NAME:{BMP Logo Data Pointer}
>
> + # !BSF TYPE:{Reserved}
>
> + # !BSF HELP:{BMP logo data pointer to a BMP format buffer.
> 0x00000000(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.LogoPtr | * | 0x04 | 0x00000000
>
> +
>
> + # !BSF NAME:{Graphics Configuration Data Pointer}
>
> + # !BSF TYPE:{Reserved}
>
> + # !BSF HELP:{Graphics configuration data used for initialization.
> 0x00000000(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.GraphicsConfigPtr | * | 0x04 |
> 0x00000000
>
> +
>
> + # !BSF NAME:{PCI GFX Temporary MMIO Base}
>
> + # !BSF TYPE:{EditNum, HEX, (0x80000000,0xDFFFFFFF)}
>
> + # !BSF HELP:{PCI Temporary PCI GFX Base used before full PCI enumeration.
> 0x80000000(Default).}
>
> + gQemuFspPkgTokenSpaceGuid.PciTempResourceBase | * | 0x04 |
> 0x80000000
>
> +
>
> + # !HDR EMBED:{FSP_S_CONFIG:FspsConfig:END}
>
> + gQemuFspPkgTokenSpaceGuid.ReservedFspsUpd | * | 0x01 | 0x00
>
> +
>
> + # Note please keep "UpdTerminator" at the end of each UPD region.
>
> + # The tool will use this field to determine the actual end of the UPD data
>
> + # structure.
>
> + gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55AA
>
> +
>
> +################################################################
> ###################################
>
> +#
>
> +# Components Section - list of the modules and components that will be
> processed by compilation
>
> +# tools and the EDK II tools to generate PE32/PE32+/Coff image
> files.
>
> +#
>
> +# Note: The EDK II DSC file is not used to specify how compiled binary images
> get placed
>
> +# into firmware volume images. This section is just a list of modules to
> compile from
>
> +# source into UEFI-compliant binaries.
>
> +# It is the FDF file that contains information on combining binary files into
> firmware
>
> +# volume images, whose concept is beyond UEFI and is described in PI
> specification.
>
> +# Binary modules do not need to be listed in this section, as they should be
>
> +# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT
> binary (Fat.efi),
>
> +# Logo (Logo.bmp), and etc.
>
> +# There may also be modules listed in this section that are not required in
> the FDF file,
>
> +# When a module listed here is excluded from FDF file, then UEFI-compliant
> binary will be
>
> +# generated for it, but the binary will not be put into any firmware volume.
>
> +#
>
> +################################################################
> ###################################
>
> +[Components.IA32]
>
> + #
>
> + # FSP Binary Components
>
> + #
>
> + $(FSP_PACKAGE)/FspHeader/FspHeader.inf
>
> +
>
> + #
>
> + # SEC
>
> + #
>
> + IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf {
>
> + <LibraryClasses>
>
> +
> FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0PlatformSecTLi
> b.inf
>
> + }
>
> +
>
> +[Components.$(FSP_ARCH)]
>
> + IntelFsp2Pkg/FspSecCore/FspSecCoreV.inf {
>
> + <LibraryClasses>
>
> +
> FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0PlatformSecVLi
> b.inf
>
> + }
>
> +
>
> + IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf {
>
> + <LibraryClasses>
>
> +
> FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0PlatformSecML
> ib.inf
>
> + }
>
> +
>
> + IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf {
>
> + <LibraryClasses>
>
> +
> FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0PlatformSecSLi
> b.inf
>
> + }
>
> +
>
> + #
>
> + # PEI Core
>
> + #
>
> + MdeModulePkg/Core/Pei/PeiMain.inf
>
> +
>
> + #
>
> + # PCD
>
> + #
>
> + MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
>
> + <LibraryClasses>
>
> + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
>
> + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
>
> + }
>
> +
>
> + $(FSP_PACKAGE)/FspvInit/FspvInit.inf
>
> + $(FSP_PACKAGE)/FspmInit/FspmInit.inf
>
> + $(FSP_PACKAGE)/FspsInit/FspsInit.inf
>
> + $(FSP_PACKAGE)/QemuVideo/QemuVideo.inf
>
> + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
>
> + <LibraryClasses>
>
> +
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull
> .inf
>
> +
> ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSys
> temLibNull.inf
>
> + }
>
> + IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf
>
> +
>
> +################################################################
> ###################################
>
> +#
>
> +# BuildOptions Section - Define the module specific tool chain flags that should
> be used as
>
> +# the default flags for a module. These flags are appended to any
>
> +# standard flags that are defined by the build process. They can be
>
> +# applied for any modules or only those modules with the specific
>
> +# module style (EDK or EDKII) specified in [Components] section.
>
> +#
>
> +################################################################
> ###################################
>
> +[BuildOptions]
>
> +# Append build options for EDK and EDKII drivers (= is Append, == is Replace)
>
> + # Enable link-time optimization when building with GCC49
>
> + *_GCC49_IA32_CC_FLAGS = -flto
>
> + *_GCC49_IA32_DLINK_FLAGS = -flto
>
> + *_GCC5_IA32_CC_FLAGS = -fno-pic
>
> + *_GCC5_IA32_DLINK_FLAGS = -no-pie
>
> + *_GCC5_IA32_ASLCC_FLAGS = -fno-pic
>
> + *_GCC5_IA32_ASLDLINK_FLAGS = -no-pie
>
> diff --git a/IntelFsp2Pkg/Tools/Tests/test_yaml.py
> b/IntelFsp2Pkg/Tools/Tests/test_yaml.py
> new file mode 100644
> index 0000000000..d81d7f7c4e
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/Tests/test_yaml.py
> @@ -0,0 +1,96 @@
> +# @file
>
> +# Split a file into two pieces at the request offset.
>
> +#
>
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +#
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +# Import Modules
>
> +import unittest
>
> +import tempfile
>
> +import os
>
> +import shutil
>
> +import struct as st
>
> +import filecmp
>
> +
>
> +import os, sys
>
> +currentdir = os.path.dirname(os.path.realpath(__file__))
>
> +parentdir = os.path.dirname(currentdir)
>
> +sys.path.append(parentdir)
>
> +import FspDscBsf2Yaml
>
> +
>
> +YamlHeaderLineLength = 10
>
> +HdrFileHeaderLineLength = 32
>
> +BsfFileHeaderLineLength = 19
>
> +
>
> +def GenFileWithoutHdr(inputfile, numLineToStrip):
>
> + yaml_file = open(inputfile, "r")
>
> + lines = yaml_file.readlines()
>
> + yaml_file.close()
>
> + del lines[:numLineToStrip]
>
> +
>
> + noHdrOutputFileName = "no-header-" + inputfile
>
> + stripped_file = open(noHdrOutputFileName, "w")
>
> + for line in lines:
>
> + stripped_file.write(line)
>
> + stripped_file.close()
>
> + return noHdrOutputFileName
>
> +
>
> +class TestFspScripts(unittest.TestCase):
>
> + def test_generateFspHeader_fromDsc(self):
>
> + # Generate HEADER
>
> + cmd = '{} {} HEADER {} {} {}'.format(
>
> + 'python',
>
> + '..\GenCfgOpt.py',
>
> + 'QemuFspPkg.dsc',
>
> + '.',
>
> + "")
>
> + os.system(cmd)
>
> + noHdrOutputFileName = GenFileWithoutHdr("FspUpd.h",
> HdrFileHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedFspUpd.h'))
>
> +
>
> + def test_generateFspsHeader_fromDsc(self):
>
> + noHdrOutputFileName = GenFileWithoutHdr("FspsUpd.h",
> HdrFileHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedFspsUpd.h'))
>
> +
>
> + def test_generateFsptHeader_fromDsc(self):
>
> + noHdrOutputFileName = GenFileWithoutHdr("FsptUpd.h",
> HdrFileHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedFsptUpd.h'))
>
> +
>
> + def test_generateFspmHeader_fromDsc(self):
>
> + noHdrOutputFileName = GenFileWithoutHdr("FspmUpd.h",
> HdrFileHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedFspmUpd.h'))
>
> +
>
> + def test_generateBsf_fromDsc(self):
>
> + # Generate BSF
>
> + cmd = '{} {} GENBSF {} {} {}'.format(
>
> + 'python',
>
> + '..\GenCfgOpt.py',
>
> + 'QemuFspPkg.dsc',
>
> + '.',
>
> + "Output.bsf")
>
> + os.system(cmd)
>
> + noHdrOutputFileName = GenFileWithoutHdr("Output.bsf",
> BsfFileHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedOutput.bsf'))
>
> +
>
> + def test_generateYaml_fromDsc(self):
>
> + # Generate YAML
>
> + cmd = '{} {} {} {}'.format(
>
> + 'python',
>
> + '..\FspDscBsf2Yaml.py',
>
> + 'QemuFspPkg.dsc',
>
> + "Output.yaml")
>
> + os.system(cmd)
>
> + noHdrOutputFileName = GenFileWithoutHdr("Output.yaml",
> YamlHeaderLineLength)
>
> + self.assertTrue(filecmp.cmp(noHdrOutputFileName,
>
> + 'ExpectedOutput.yaml'))
>
> +
>
> +if __name__ == '__main__':
>
> + unittest.main()
>
> diff --git a/IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md
> b/IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md
> new file mode 100644
> index 0000000000..ba2311445c
> --- /dev/null
> +++ b/IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md
> @@ -0,0 +1,39 @@
> +#Name
>
> +**FspDscBsf2Yaml.py** The python script that generates YAML file for
>
> +the Boot Settings from an EDK II Platform Description (**DSC**) file
>
> +or from a Boot Settings File (**BSF**). It is created to help
>
> +transitioning FSP Updateable Product Data (**UPD**) file format to
>
> +new standardized YAML format so that it can be configured through
>
> +open source tools.
>
> +
>
> +#Synopsis
>
> +```
>
> +FspDscBsf2Yaml DscFile|BsfFile YamlFile
>
> +```
>
> +
>
> +#Description
>
> +**FspDscBsf2Yaml.py** is a script that generates configuration options from
> an
>
> +**EDK II Platform Description (DSC)** file or **a Boot Settings File (BSF)** file.
>
> +
>
> +It generates a **YAML file** that can be used by the **Config Editor** to
> provide
>
> +a graphical user interface for manipulating settings in the UPD regions.
>
> +
>
> +The following sections explain the usage of this script.
>
> +
>
> +## 1. FspDscBsf2Yaml.py DscFile YamlFile
>
> +
>
> +The **DscFile** option is an input DSC file.
>
> +
>
> +The **YamlFile** option is an output YAML file.
>
> +
>
> +The script takes the FSP DSC file consisting BSF syntax and generates a YAML
>
> +output file describing the boot settings.
>
> +
>
> +## 2. FspDscBsf2Yaml.py BsfFile YamlFile
>
> +
>
> +The **BsfFile** option is an input BSF file.
>
> +
>
> +The **YamlFile** option is an output YAML file.
>
> +
>
> +The script generates a YAML output file from a BSF file. The BSF file
>
> +can be generated using GenCfgOpt tool.
>
> --
> 2.28.0.windows.1
prev parent reply other threads:[~2021-02-05 2:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-04 3:59 [PATCH v2] IntelFsp2Pkg: Add YAML file generation support Tung Lun
2021-02-05 2:09 ` Chiu, Chasel [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=SN6PR11MB2814F9C03DFE3716DE9598C4E6B29@SN6PR11MB2814.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox