From nobody Sun May 12 15:52:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111694+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111694+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1700811000; cv=none; d=zohomail.com; s=zohoarc; b=g6xGyueqpDTLcXaoedbkqq3NuRz5OQj3ye55Dusie6KXjbSV9eh/dx8A7+lkEtl4TgCXfQh79bTHC/q13pCvEj8SO+OBy/JBHhiVAERvRQ5fvtr2b+SBGzbjn3ERbk3uS3PnOeykKQ4wIhelYuAeX2OzRUkHXk7pZR4s8LCgM8M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700811000; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:Sender:Subject:Subject:To:To:Message-Id; bh=89yHJTzSXYkPbAl0uXkYlgwtYaWAbt5ygSaY1X73kIY=; b=I54Zz4JAzmcPJyUsD0EUSZ2uIeZCXYaeOHmqbxw0U/wHyws4QvToGxVDanxTrm7zVnnkC+br6wSuYDB5KtNtv9TD9vJ2pbC+HVwE57hj9EtfLi/taZn3DjfCXFx6s9f7MnFs/cQn0fmq/ACk20UTkxGhnn94bD09gzvvYlcouuw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111694+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700811000649679.95048291746; Thu, 23 Nov 2023 23:30:00 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=OEJ276mZtASwI83NAY7j9nX5W4OdFQLmyARm4zlvE64=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700811000; v=1; b=ekMf002SMdm2hHERVBJHPE0Xjd/F03uJQXSSBEuqmrBQkpKal2ncR0XS94ndT1EPxj2yw2Wg JljAFOOlQuXX9Yj3WSNREWBL+F1Xtm6y7F/twNqPt2+K6IZRWiKsawId+tOw1L3dBIkdGs7UHBq bCZU68x7qbdwj7uosgjY//Es= X-Received: by 127.0.0.2 with SMTP id 8KxJYY1788612xDJJRlekNCc; Thu, 23 Nov 2023 23:30:00 -0800 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web10.130911.1700810998906630959 for ; Thu, 23 Nov 2023 23:29:59 -0800 X-IronPort-AV: E=McAfee;i="6600,9927,10902"; a="395196454" X-IronPort-AV: E=Sophos;i="6.04,223,1695711600"; d="scan'208";a="395196454" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2023 23:29:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10902"; a="940849211" X-IronPort-AV: E=Sophos;i="6.04,223,1695711600"; d="scan'208";a="940849211" X-Received: from basfe001.gar.corp.intel.com ([10.66.244.207]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2023 23:29:54 -0800 From: "Arun Sura" To: devel@edk2.groups.io Cc: Arun Sura , Chasel Chiu , Duggapu Chinni B , Nate DeSimone , Ray Han Lim Ng , Star Zeng , Ted Kuo , Ashraf Ali S , Susovan Mohapatra Subject: [edk2-devel] [PATCH] [Patch V2]IntelFsp2Pkg\Tools\ConfigEditor: Added new USF config workstream. Date: Fri, 24 Nov 2023 12:59:26 +0530 Message-Id: <20231124072926.31962-1-arun.surax.soundara.pandian@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,arun.surax.soundara.pandian@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 3MNcbd81MrNZaFO0EAmnoDDMx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700811001418100003 Content-Type: text/plain; charset="utf-8" Config Editor utility addition/changes: Support to enable config editor tool to have a new feature that can load and view the configuration data of compiled VFR or HFR in form of YAML. This can help users to understand and track the configuration data when modifications are made. Requires compiled vfr file as input in YAML format. Running Configuration Editor: python ConfigEditor.py Cc: Chasel Chiu Cc: Duggapu Chinni B Cc: Nate DeSimone Cc: Ray Han Lim Ng Cc: Star Zeng Cc: Ted Kuo Cc: Ashraf Ali S Cc: Susovan Mohapatra Signed-off-by: Arun Sura Reviewed-by: Chasel Chiu --- IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py | 226 +++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++----------------------------------- IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py | 197 +++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++-------------------- IntelFsp2Pkg/Tools/Tests/test_vfr_yaml.yml | 233 +++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md | 2 ++ 4 files changed, 603 insertions(+), 55 deletions(-) diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py b/IntelFsp2Pkg= /Tools/ConfigEditor/ConfigEditor.py index 5271504282..228ebe91a6 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py @@ -1015,6 +1015,10 @@ class application(tkinter.Frame): "Unsupported file '%s' !" % path) return =20 + # VFR Format Page modification + def page_construct(self): + self.left.bind("<>", self.on_config_page_select_ch= ange) + def search_bar(self): # get data from text box self.search_text =3D self.edit.get() @@ -1165,7 +1169,8 @@ class application(tkinter.Frame): page_id =3D next(iter(page)) # Put CFG items into related page list self.page_list[page_id] =3D self.cfg_data_obj.get_cfg_list(pag= e_id) - self.page_list[page_id].sort(key=3Dlambda x: x['order']) + if self.mode =3D=3D 'fsp': + self.page_list[page_id].sort(key=3Dlambda x: x['order']) page_name =3D self.cfg_data_obj.get_page_title(page_id) child =3D self.left.insert( parent, 'end', @@ -1199,17 +1204,23 @@ class application(tkinter.Frame): for item in self.get_current_config_data(): disp_list.append(item) row =3D 0 - disp_list.sort(key=3Dlambda x: x['order']) - for item in disp_list: - self.add_config_item(item, row) - row +=3D 2 - if self.invalid_values: - string =3D 'The following contails invalid options/values \n\n' - for i in self.invalid_values: - string +=3D i + ": " + str(self.invalid_values[i]) + "\n" - reply =3D messagebox.showwarning('Warning!', string) - if reply =3D=3D 'ok': - self.invalid_values.clear() + if self.mode =3D=3D 'fsp': + disp_list.sort(key=3Dlambda x: x['order']) + for item in disp_list: + self.add_config_item(item, row) + row +=3D 2 + if self.invalid_values: + string =3D 'The following contails invalid options/values = \n\n' + for i in self.invalid_values: + string +=3D i + ": " + str(self.invalid_values[i]) + "= \n" + reply =3D messagebox.showwarning('Warning!', string) + if reply =3D=3D 'ok': + self.invalid_values.clear() + elif self.mode =3D=3D 'vfr': + for item in disp_list: + self.add_vfr_config_item(item, row) + row +=3D 2 + =20 fsp_version =3D '' =20 @@ -1219,16 +1230,19 @@ class application(tkinter.Frame): with open(file_name, "rb") as pkl_file: gen_cfg_data.__dict__ =3D marshal.load(pkl_file) gen_cfg_data.prepare_marshal(False) - elif file_name.endswith('.yaml'): + elif file_name.endswith('.yaml') or file_name.endswith('.yml'): if gen_cfg_data.load_yaml(file_name) !=3D 0: raise Exception(gen_cfg_data.get_last_error()) else: raise Exception('Unsupported file "%s" !' % file_name) + + self.mode =3D gen_cfg_data.yaml_type # checking fsp version - if gen_cfg_data.detect_fsp(): - self.fsp_version =3D '2.X' - else: - self.fsp_version =3D '1.X' + if gen_cfg_data.yaml_type =3D=3D 'fsp': + if gen_cfg_data.detect_fsp(): + self.fsp_version =3D '2.X' + else: + self.fsp_version =3D '1.X' =20 return gen_cfg_data =20 @@ -1252,7 +1266,7 @@ class application(tkinter.Frame): elif ftype =3D=3D 'bin': question =3D 'All configuration will be reloaded from BIN = file, \ continue ?' - elif ftype =3D=3D 'yaml': + elif ftype =3D=3D 'yaml' or ftype =3D=3D 'yml': question =3D '' elif ftype =3D=3D 'bsf': question =3D '' @@ -1263,13 +1277,13 @@ class application(tkinter.Frame): if reply =3D=3D 'no': return None =20 - if ftype =3D=3D 'yaml': - if self.mode =3D=3D 'FSP': + if ftype =3D=3D 'yaml' or ftype =3D=3D 'yml': + if self.mode =3D=3D 'fsp': file_type =3D 'YAML' file_ext =3D 'yaml' else: file_type =3D 'YAML or PKL' - file_ext =3D 'pkl *.yaml' + file_ext =3D 'pkl *.yaml *.yml' else: file_type =3D ftype.upper() file_ext =3D ftype @@ -1364,20 +1378,22 @@ class application(tkinter.Frame): self.left.delete(*self.left.get_children()) =20 self.cfg_data_obj =3D self.load_config_data(path) - - self.update_last_dir(path) - self.org_cfg_data_bin =3D self.cfg_data_obj.generate_binary_array() self.build_config_page_tree(self.cfg_data_obj.get_cfg_page()['root= '], '') =20 - msg_string =3D 'Click YES if it is FULL FSP '\ - + self.fsp_version + ' Binary' - reply =3D messagebox.askquestion('Form', msg_string) - if reply =3D=3D 'yes': - self.load_from_bin() + self.update_last_dir(path) + if self.cfg_data_obj.yaml_type =3D=3D 'fsp': + self.org_cfg_data_bin =3D self.cfg_data_obj.generate_binary_ar= ray() =20 - for menu in self.menu_string: - self.file_menu.entryconfig(menu, state=3D"normal") + + msg_string =3D 'Click YES if it is FULL FSP '\ + + self.fsp_version + ' Binary' + reply =3D messagebox.askquestion('Form', msg_string) + if reply =3D=3D 'yes': + self.load_from_bin() + + for menu in self.menu_string: + self.file_menu.entryconfig(menu, state=3D"normal") =20 return 0 =20 @@ -1405,8 +1421,9 @@ class application(tkinter.Frame): return =20 self.update_config_data_on_page() - new_data =3D self.cfg_data_obj.generate_binary_array() - self.cfg_data_obj.generate_delta_file_from_bin(path, + if self.mode =3D=3D "fsp": + new_data =3D self.cfg_data_obj.generate_binary_array() + self.cfg_data_obj.generate_delta_file_from_bin(path, self.org_cfg_data_b= in, new_data, full) =20 @@ -1526,6 +1543,13 @@ class application(tkinter.Frame): new_value =3D bytes_to_bracket_str(widget.get()) self.set_config_item_value(item, new_value) =20 + #YAML VFR Part Start + def update_vfr_config_data_from_widget(self, widget, args): + + item =3D self.get_config_data_item_from_widget(widget) + + #YAML VFR Part End + def evaluate_condition(self, item): try: result =3D self.cfg_data_obj.evaluate_condition(item) @@ -1535,6 +1559,132 @@ class application(tkinter.Frame): result =3D 1 return result =20 + #YAML VFR Part Start + def add_vfr_config_item(self, item, row): + parent =3D self.right_grid + widget =3D None + if item['type'] =3D=3D 'string': + value =3D '' + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + + elif item['type'] =3D=3D 'text': + value =3D '' + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + elif item['type'] =3D=3D 'label': + value =3D '' + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + + elif item['type'] =3D=3D 'checkbox': + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + widget =3D tkinter.Checkbutton(parent, text=3D item['prompt'].= split("#")[0], variable=3D 1) + + elif item['type'] =3D=3D 'subtitle': + value =3D '' + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + + elif item['type'] =3D=3D 'oneof': + OPTIONS =3D [] + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + for key in item: + if key.startswith("option"): + if type(item[key]) =3D=3D type([]): + for option_data in item[key]: + OPTIONS.append(option_data['text']) + else: + OPTIONS.append(item[key]["text"]) + txt_val =3D tkinter.StringVar() + txt_val.set(OPTIONS[0]) # set default value + widget =3D tkinter.OptionMenu(parent, txt_val, *OPTIONS) + txt_val.set(OPTIONS[0]) + + elif item['type'] =3D=3D 'numeric': + value =3D 0 + for key in item.keys(): + if key =3D=3D "value": + value =3D item['value'] + elif key =3D=3D 'default': + for dict_key in item['default']: + if dict_key =3D=3D "value": + value =3D item['default']['value'] + else: + continue + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + + elif item['type'] =3D=3D 'orderedlist': + OPTIONS =3D [] + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + for key in item: + if key.startswith("option"): + if type(item[key]) =3D=3D type([]): + for option_data in item[key]: + OPTIONS.append(option_data['text']) + else: + OPTIONS.append(item[key]["text"]) + txt_val =3D tkinter.StringVar() + txt_val.set(OPTIONS[0]) # default value + widget =3D tkinter.OptionMenu(parent, txt_val, *OPTIONS) + txt_val.set(OPTIONS[0]) + + elif item['type'] =3D=3D 'date': + value =3D '' + for key in item.keys(): + if key =3D=3D "value": + value =3D item['value'] + elif key =3D=3D 'default': + for dict_key in item['default']: + if dict_key =3D=3D "value": + value =3D item['default']['value'] + else: + continue + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + elif item['type'] =3D=3D 'time': + value =3D '' + for key in item.keys(): + if key =3D=3D "value": + value =3D item['value'] + elif key =3D=3D 'default': + for dict_key in item['default']: + if dict_key =3D=3D "value": + value =3D item['default']['value'] + else: + continue + name =3D tkinter.Label(parent, text=3Ditem['prompt'].split("#"= )[0], anchor=3D"w") + txt_val =3D tkinter.StringVar() + widget =3D tkinter.Entry(parent, textvariable=3Dtxt_val) + txt_val.set(value) + + + if widget: + if item['type'] =3D=3D 'string' or item['type'] =3D=3D 'text' = or item['type'] =3D=3D 'numeric' or item['type'] =3D=3D "oneof"\ + or item['type'] =3D=3D 'date' or item['type'] =3D=3D 'time= ' or item['type'] =3D=3D 'orderedlist' or item['type'] =3D=3D 'label':# or = item['type'] =3D=3D 'goto'or item['type'] =3D=3D 'checkbox': + + if 'help' in item.keys(): + create_tool_tip(widget, item['help'].split("#")[0]) + + name.grid(row=3Drow, column=3D0, padx=3D5, pady=3D5, sticky=3D= "nsew") + widget.grid(row=3Drow + 1, rowspan=3D1, column=3D0, + padx=3D5, pady=3D5, sticky=3D"nsew") + + #YAML VFR Part End + def add_config_item(self, item, row): parent =3D self.right_grid =20 @@ -1611,9 +1761,15 @@ class application(tkinter.Frame): padx=3D10, pady=3D5, sticky=3D"nsew") =20 def update_config_data_on_page(self): - self.walk_widgets_in_layout(self.right_grid, - self.update_config_data_from_widget) =20 + if self.mode =3D=3D "fsp": + self.walk_widgets_in_layout(self.right_grid, + self.update_config_data_from_widget) + elif self.mode =3D=3D "vfr": + self.walk_widgets_in_layout(self.right_grid, + self.update_vfr_config_data_from_widge= t) + else: + print("WARNING: Invalid config file!!") =20 if __name__ =3D=3D '__main__': root =3D tkinter.Tk() diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py b/IntelFsp2Pkg/T= ools/ConfigEditor/GenYamlCfg.py index 90d7a11184..3b1f099125 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py @@ -226,6 +226,7 @@ class CFG_YAML(): TEMPLATE =3D 'template' CONFIGS =3D 'configs' VARIABLE =3D 'variable' + FORMSET =3D 'formset' =20 def __init__(self): self.log_line =3D False @@ -235,6 +236,7 @@ class CFG_YAML(): self.var_dict =3D None self.def_dict =3D {} self.yaml_path =3D '' + self.yaml_type =3D 'fsp' self.lines =3D [] self.full_lines =3D [] self.index =3D 0 @@ -418,6 +420,7 @@ class CFG_YAML(): last_indent =3D None key =3D '' temp_chk =3D {} + temp_data =3D [] =20 while True: line =3D self.get_line() @@ -425,6 +428,9 @@ class CFG_YAML(): break =20 curr_line =3D line.strip() + if curr_line =3D=3D "## DO NOT REMOVE -- YAML Mode": + self.yaml_type =3D "vfr" + if curr_line =3D=3D '' or curr_line[0] =3D=3D '#': continue =20 @@ -482,9 +488,14 @@ class CFG_YAML(): return curr =20 marker1 =3D curr_line[0] - marker2 =3D curr_line[-1] start =3D 1 if marker1 =3D=3D '-' else 0 pos =3D curr_line.find(': ') + if marker1 =3D=3D '-': + marker2 =3D curr_line[curr_line.find(":")] + pos =3D -1 + else: + marker2 =3D curr_line[-1] + if pos > 0: child =3D None key =3D curr_line[start:pos].strip() @@ -516,15 +527,31 @@ class CFG_YAML(): # special virtual nodes, rename to ensure unique key key =3D '$ACTION_%04X' % self.index self.index +=3D 1 - if key in curr: - if key not in temp_chk: - # check for duplicated keys at same level - temp_chk[key] =3D 1 - else: - raise Exception("Duplicated item '%s:%s' found !" - % (parent_name, key)) =20 - curr[key] =3D child + if self.yaml_type =3D=3D'fsp': + if key in curr: + if key not in temp_chk: + # check for duplicated keys at same level + temp_chk[key] =3D 1 + else: + raise Exception("Duplicated item '%s:%s' found= !" + % (parent_name, key)) + + curr[key] =3D child + if self.yaml_type =3D=3D 'vfr': + if key in curr.keys(): + if type(curr[key]) =3D=3D type([]): + temp_data =3D curr[key] + else: + temp_data.append(curr[key]) + + temp_data.append(child) + if level < 5: + curr[key] =3D temp_data + temp_data =3D [] + else: + if level < 5: + curr[key] =3D child if self.var_dict is None and key =3D=3D CFG_YAML.VARIABLE: self.var_dict =3D child if self.tmp_tree is None and key =3D=3D CFG_YAML.TEMPLATE: @@ -537,6 +564,8 @@ class CFG_YAML(): if self.tmp_tree and key =3D=3D CFG_YAML.CONFIGS: # apply template for the main configs self.allow_template =3D True + if self.tmp_tree and key =3D=3D CFG_YAML.FORMSET: + self.allow_template =3D True else: child =3D None # - !include cfg_opt.yaml @@ -550,8 +579,30 @@ class CFG_YAML(): self.yaml_path =3D os.path.dirname(opt_file) self.load_file(opt_file) yaml_tree =3D self.parse() - self.tmp_tree =3D yaml_tree[CFG_YAML.TEMPLATE] - self.cfg_tree =3D yaml_tree[CFG_YAML.CONFIGS] + for key in yaml_tree.keys(): + if key.lower() =3D=3D "configs": + self.yaml_type =3D 'fsp' + self.tmp_tree =3D yaml_tree[CFG_YAML.TEMPLATE] + self.cfg_tree =3D yaml_tree[CFG_YAML.CONFIGS] + break + else: + self.cfg_tree =3D yaml_tree + break + + if self.yaml_type =3D=3D 'vfr': + formset_found =3D True + for key in yaml_tree.keys(): + if key =3D=3D CFG_YAML.FORMSET: + self.cfg_tree =3D yaml_tree[CFG_YAML.FORMSET] + formset_found =3D False + break + + if formset_found =3D=3D True: + self.cfg_tree =3D yaml_tree + elif self.yaml_type =3D=3D 'fsp': + self.tmp_tree =3D yaml_tree[CFG_YAML.TEMPLATE] + self.cfg_tree =3D yaml_tree[CFG_YAML.CONFIGS] + return self.cfg_tree =20 def expand_yaml(self, opt_file): @@ -594,9 +645,14 @@ class CGenYamlCfg: self._cfg_list =3D [] self._cfg_page =3D {'root': {'title': '', 'child': []}} self._cur_page =3D '' + self._main_page =3D '' self._var_dict =3D {} self._def_dict =3D {} self._yaml_path =3D '' + self.yaml_type =3D '' + #Added to overcome duplicate formid + self.form_page_map =3D {} + self.formset_level =3D 0 =20 @staticmethod def deep_convert_dict(layer): @@ -760,13 +816,22 @@ class CGenYamlCfg: return error =20 def get_cfg_list(self, page_id=3DNone): + cfgs =3D [] if page_id is None: # return full list return self._cfg_list else: - # build a new list for items under a page ID - cfgs =3D [i for i in self._cfg_list if i['cname'] and - (i['page'] =3D=3D page_id)] + if self.yaml_type =3D=3D 'fsp': + # build a new list for items under a page ID + cfgs =3D [i for i in self._cfg_list if i['cname'] and + (i['page'] =3D=3D page_id)] + #VFR YAML Support Start + elif self.yaml_type =3D=3D'vfr': + for cfg in self._cfg_list: + for i in cfg: + if (i['page'] =3D=3D page_id): + cfgs.append(i) + #VFR YAML Support End return cfgs =20 def get_cfg_page(self): @@ -1002,6 +1067,9 @@ option format '%s' !" % option) def _locate_cfg_item(root, path, level=3D0): if len(path) =3D=3D level: return root + if type(root) =3D=3D type([]): + for temp_root in root: + return _locate_cfg_item(temp_root, path, level) next_root =3D root.get(path[level], None) if next_root is None: if allow_exp: @@ -1158,7 +1226,7 @@ option format '%s' !" % option) =20 self.set_cur_page(item.get('page', '')) =20 - if name[0] =3D=3D '$': + if name !=3D '' and name[0] =3D=3D '$': # skip all virtual node return 0 =20 @@ -1188,7 +1256,7 @@ option format '%s' !" % option) # define is length in bytes length =3D length * 8 =20 - if not name.isidentifier(): + if name !=3D '' and not name.isidentifier(): raise Exception("Invalid config name '%s' for '%s' !" % (name, '.'.join(path))) =20 @@ -1288,6 +1356,90 @@ option format '%s' !" % option) raise SystemExit("Error: Bits length not aligned for %s !"= % str(path)) =20 +#EDK2 VFR YAML Support start + + def build_formset_list(self, form_name=3D'', top=3DNone, parent_form= =3D'',path =3D[]): + + if self.formset_level =3D=3D 1: + self._cfg_page['root']['title'] =3D 'Platform' + self._cfg_page['root']['child'].append({form_name: {'title': f= orm_name, + 'child': []}}) + self._main_page =3D form_name + + if top is None: + top =3D self._cfg_tree + form_name =3D "Formset" + self._cfg_page['root']['title'] =3D 'Formset' + + is_leaf =3D True + + if form_name =3D=3D "form" or form_name =3D=3D "formid": + self._cur_page =3D top["title"].split('#')[0] + self.form_page_map[top['formid'].split('#')[0]] =3D self._cur_= page + for driver in self._cfg_page['root']['child']: + if list(driver.keys())[0] =3D=3D self._main_page: + driver[self._main_page]['child'].append({self._cur_pag= e: {'title': self._cur_page, 'child': []}}) + + if form_name =3D=3D "formmap": + self._cur_page =3D top["formid"].split('#')[0] + self.form_page_map[top['FormId'].split('#')[0]] =3D self._cur_= page + self._cfg_page['root']['child'].append({self._cur_page: {'titl= e': self._cur_page, + 'child': []}}) + + + form_data =3D {} + temp_data =3D [] + + for key in top: + if key =3D=3D 'include': + form_data['type'] =3D key + form_data["page"] =3D self._cur_page + continue + if type(top[key]) is list and self.formset_level <=3D 3: + self.formset_level +=3D 1 + path.append(key) + for data in top[key]: + self.build_formset_list(key, data, key, path) + path.pop() + self.formset_level -=3D 1 + elif type(top[key]) is OrderedDict and (self.formset_level <= =3D 3): + if parent_form !=3D '': + self.formset_level +=3D 1 + path.append(key) + self.build_formset_list(key, top[key], form_name, path) + path.pop() + self.formset_level -=3D 1 + else: + self.formset_level +=3D 1 + path.append(key) + self.build_formset_list(key, top[key], key, path) + path.pop() + self.formset_level -=3D 1 + + else: + form_data["page"] =3D self._cur_page + form_data[key] =3D top[key] + form_data['path'] =3D ".".join(path) + if form_name !=3D 'form' or form_name !=3D "formid": + form_data["type"] =3D form_name + else: + form_data["type"] =3D " " + count =3D 0 + if self._cfg_list !=3D []: + for cfg_name in self._cfg_list: + for list_data in cfg_name: + if key =3D=3D list_data['type']: + count +=3D1 + if count > 1: + temp_data =3D cfg_name + + if len(temp_data) !=3D 0 or len(form_data)!=3D0: + temp_data.append(form_data) + self._cfg_list.append(temp_data) + return + +#EDK2 VFR YAML Support End + def get_field_value(self, top=3DNone): def _get_field_value(name, cfgs, level): if 'indx' in cfgs: @@ -2196,10 +2348,14 @@ xbe\x8f\x64\x12\x05\x8d\x0a\xa8' self.initialize() self._cfg_tree =3D cfg_yaml.load_yaml(cfg_file) self._def_dict =3D cfg_yaml.def_dict + self.yaml_type =3D cfg_yaml.yaml_type self._yaml_path =3D os.path.dirname(cfg_file) - self.build_cfg_list() - self.build_var_dict() - self.update_def_value() + if self.yaml_type =3D=3D 'vfr': + self.build_formset_list() + elif self.yaml_type =3D=3D 'fsp': + self.build_cfg_list() + self.build_var_dict() + self.update_def_value() return 0 =20 =20 @@ -2338,7 +2494,8 @@ def main(): if dlt_file: gen_cfg_data.override_default_value(dlt_file) =20 - gen_cfg_data.detect_fsp() + if gen_cfg_data.yaml_type =3D=3D 'fsp': + gen_cfg_data.detect_fsp() =20 if command =3D=3D "GENBIN": if len(file_list) =3D=3D 3: diff --git a/IntelFsp2Pkg/Tools/Tests/test_vfr_yaml.yml b/IntelFsp2Pkg/Tool= s/Tests/test_vfr_yaml.yml new file mode 100644 index 0000000000..4ebb963baa --- /dev/null +++ b/IntelFsp2Pkg/Tools/Tests/test_vfr_yaml.yml @@ -0,0 +1,233 @@ +## DO NOT REMOVE -- YAML Mode +Bluetooth Connection Manager: + formset: + guid: {0x4f4ef7f0, 0xaa29, 0x4ce9, { 0xba, 0x41, 0x64, 0x3e, 0x1, 0x2= 3, 0xa9, 0x9f}} + help: Config the Bluetooth parameter + title: Bluetooth Configuration + component: + - form: + formid: 2 + title: Bluetooth Host Controller Management + component: + - text: + help: Address of the bluetooth host controller + prompt: Address + text: Address + - string: + questionid: 24578 + varstoreid: 0 # Optional Input + varname: 65535 # Question VarName + varoffset: 65535 # Question VarOffset + questionflags: 4 # Optional Input + prompt: Local Name + help: Name for the host controller, valid length from 2 to 19 + opcodeflags: 0x0 # optional input + minsize: 2 + maxsize: 19 + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Host Id + help: Shows the Host Controller Id + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 5 + - goto: + questionid: 24577 + varstoreid: 0 # Optional Input + varname: 65535 # Question VarName + varoffset: 65535 # Question VarOffset + questionflags: 4 # Optional Input + prompt: Device Management + help: Goto Device Management form + formid: 0x3 + question: 0x6001 # Optional Input + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Device Count + help: Shows the number of devices + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 3 + - form: + formid: 3 + title: Bluetooth Management - Device Management + component: + - label: + prompt: Device Management + number: 0x1500 # Number + - subtitle: + prompt: Active Device + flags: 0 # Optional Input + - subtitle: + prompt: Paired Device + flags: 0 # Optional Input + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Paired Device Count + help: Lists the Number of Paired Devices + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 2 + - action: + questionid: 24579 + varstoreid: 0 # Optional Input + varname: 65535 # Question VarName + varoffset: 65535 # Question VarOffset + questionflags: 4 # Optional Input + prompt: Address + help: Address + config: 4 # QuestionConfig + component: + - refreshguid: + guid: {0xf5e655d9, 0x2a6, 0x46f2, { 0x9e, 0x76, 0xb8, 0xb= e, 0x8e, 0x60, 0xab, 0x22}} + - subtitle: + prompt: Available Device + flags: 0 # Optional Input + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Available Device Count + help: List the number of Available devices + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 4 + - form: + formid: 4 + title: Remote Device Info + component: + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Device Count + help: Lists the Device Count + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 3 + - text: + condition: grayoutif TRUE + help: Address for this bluetooth host controller + prompt: Address + text: Address + - subtitle: + condition: grayoutif TRUE + prompt: Remote Device + flags: 0 # Optional Input + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Available Devices + help: Lists the available devices + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 5 + - text: + condition: grayoutif TRUE + help: Available Services for the remote device + prompt: Available Services + - oneof: + questionid: 4130 + varstoreid: 4096 # Optional Input + varname: 5 # Question VarName + varoffset: 5 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Active Device + help: 0x0015 + opcodeflags: 0x10 # optional input + maximum: 3 # Optional Input + minimum: 0 # Optional Input + step: 0x0 # Optional Input + component: + - option: + text: 0x0016 + flags: 16 # Optional Input + type: 0x0000 # Optional Input + value: 0x0 + - option: + text: 0x0017 + flags: 0 # Optional Input + type: 0x0000 # Optional Input + value: 0x1 + - option: + text: 0x0018 + flags: 0 # Optional Input + type: 0x0000 # Optional Input + value: 0x2 + - option: + text: 0x0019 + flags: 0 # Optional Input + type: 0x0000 # Optional Input + value: 0x3 + - numeric: + questionid: 4114 + varstoreid: 4099 # Optional Input + varname: 0 # Question VarName + varoffset: 0 # Question VarOffset + questionflags: 0 # Optional Input + prompt: Paired device count + help: Lists the number of devices paired + opcodeflags: 0x11 # optional input + maximum: 65535 # Optional Input + minimum: 0 # Optional Input + step: 0 # Optional Input + component: + - default: + defaultId: 0 + type: 1 + value: 3 diff --git a/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md b/Int= elFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md index da21df2432..721b2fdaf9 100644 --- a/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md +++ b/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md @@ -12,6 +12,8 @@ It supports the following options: ## 1. Open Config YAML file This option loads the YAML file for a FSP UPD into the ConfigEditor to cha= nge the desired configuration values. =20 +This option loads the YAML file for a VFR config data into the ConfigEdito= r to view the desired form values. + #####Example: ``` ![Example ConfigEditor 1](https://slimbootloader.github.io/_images/CfgEdit= Open.png) --=20 2.30.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111694): https://edk2.groups.io/g/devel/message/111694 Mute This Topic: https://groups.io/mt/102777434/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-