From nobody Mon Apr 29 18:09:21 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+79411+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+79411+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1629186217; cv=none; d=zohomail.com; s=zohoarc; b=N+RAreww672RotuM9AsiaMxmygxWDYyHLjn98Qwx0PkVpprxdAG966ZVsi+dnBQup85joijKjYiS2aLY0gFJM2rZIvsgX3SrLPx2umFFxaHP/0bXpEtmlPwFMlfzhvVrKBm4bylmf2sy47FPDp76GmsUVI4mnzBmxuhk6R8+5no= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629186217; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=AQ45YNoAsMY/ZQDssaYNs1uefJHP4Qn0xKtikuzyPLY=; b=NWu5q+Sss+kQWszAwpAXAJXAftlsC9CWn9iKBzU3Cjq5LKbqExyc4qPd3NGqz6shUExjsoS/BMToRy8SMtdpAUroo70XhSz1ZHYl7uhj+fr5nEDwicFeSjA6y32QobPldMG/34OvpeQwWZ3J08gM1iPOtOivU630Hi0WUaNFW2o= 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+79411+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 1629186217182398.93676111573393; Tue, 17 Aug 2021 00:43:37 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8Mh2YY1788612xmLtG6p78CF; Tue, 17 Aug 2021 00:43:36 -0700 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web10.36271.1629186215441601753 for ; Tue, 17 Aug 2021 00:43:36 -0700 X-IronPort-AV: E=McAfee;i="6200,9189,10078"; a="277042085" X-IronPort-AV: E=Sophos;i="5.84,328,1620716400"; d="scan'208";a="277042085" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Aug 2021 00:43:34 -0700 X-IronPort-AV: E=Sophos;i="5.84,328,1620716400"; d="scan'208";a="471071037" X-Received: from tunglunl-mobl4.gar.corp.intel.com ([10.214.173.199]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Aug 2021 00:43:31 -0700 From: "Tung Lun" To: devel@edk2.groups.io Cc: "Loo, Tung Lun" , Maurice Ma , Nate DeSimone , Star Zeng , Chasel Chiu Subject: [edk2-devel] [PATCH] IntelFsp2Pkg: Support Config File and Binary delta comparison Date: Tue, 17 Aug 2021 15:43:12 +0800 Message-Id: <20210817074312.1313-1-tung.lun.loo@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: 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,tung.lun.loo@intel.com X-Gm-Message-State: WDj3ukXIFLUVkyFJ5z3D73lYx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629186216; bh=HG/ZXnKZ+/EABIBx3BsNqgInGaf0jOmmASUMHUp8dZE=; h=Cc:Date:From:Reply-To:Subject:To; b=QiSR4GVk9ONlmw46yIkZDIdnDRwqEftv4kCYT4AVwyQsnJlFFbQt+uAKwhb/+SHkKt9 2Mr6MU5NuUNVUDvjhLAncnd65l/fRFaR762OKZ05zBpc4z3tUBL/gbyB3zweCKIfE4V67 diJLihZWYE1tdT0civvE1bHOWv8dLhinaVU= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629186218348100001 Content-Type: text/plain; charset="utf-8" From: "Loo, Tung Lun" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3567 This patch is to enable config editor to have a new feature that can spell out the delta between the default configuration files' data, such as YAML and BSF, against the data stored in the binary. This can help users understand and track the difference when modifications are made. Cc: Maurice Ma Cc: Nate DeSimone Cc: Star Zeng Cc: Chasel Chiu Signed-off-by: Loo Tung Lun Reviewed-by: Chasel Chiu --- IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py | 43 ++++++++++++++++++++= ++++++++++++++++++----- IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py | 121 ++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++--------- 2 files changed, 150 insertions(+), 14 deletions(-) diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py b/IntelFsp2Pkg= /Tools/ConfigEditor/ConfigEditor.py index 008c7d7a16..680b90e09d 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py @@ -807,12 +807,12 @@ class application(tkinter.Frame): self.page_id =3D '' self.page_list =3D {} self.conf_list =3D {} + self.cfg_page_dict =3D {} self.cfg_data_obj =3D None self.org_cfg_data_bin =3D None self.in_left =3D state() self.in_right =3D state() self.search_text =3D '' - self.binseg_dict =3D {} =20 # Check if current directory contains a file with a .yaml extension # if not default self.last_dir to a Platform directory where it is @@ -1009,10 +1009,17 @@ class application(tkinter.Frame): return visible if self.cfg_data_obj.binseg_dict: str_split =3D item['path'].split('.') - if self.cfg_data_obj.binseg_dict[str_split[-2]] =3D=3D -1: - visible =3D False - widget.grid_remove() - return visible + if str_split[-2] not in CGenYamlCfg.available_fv and \ + str_split[-2] not in CGenYamlCfg.missing_fv: + if self.cfg_data_obj.binseg_dict[str_split[-3]] =3D=3D -1: + visible =3D False + widget.grid_remove() + return visible + else: + if self.cfg_data_obj.binseg_dict[str_split[-2]] =3D=3D -1: + visible =3D False + widget.grid_remove() + return visible result =3D 1 if item['condition']: result =3D self.evaluate_condition(item) @@ -1371,8 +1378,34 @@ class application(tkinter.Frame): self.clear_widgets_inLayout() self.on_config_page_select_change(None) =20 + def set_config_data_page(self): + page_id_list =3D [] + for idx, page in enumerate( + self.cfg_data_obj._cfg_page['root']['child']): + page_id_list.append(list(page.keys())[0]) + page_list =3D self.cfg_data_obj.get_cfg_list(page_id_list[idx]) + self.cfg_page_dict[page_id_list[idx]] =3D 0 + for item in page_list: + str_split =3D item['path'].split('.') + if str_split[-2] not in CGenYamlCfg.available_fv and \ + str_split[-2] not in CGenYamlCfg.missing_fv: + if self.cfg_data_obj.binseg_dict[str_split[-3]] !=3D -= 1: + self.cfg_page_dict[page_id_list[idx]] +=3D 1 + else: + if self.cfg_data_obj.binseg_dict[str_split[-2]] !=3D -= 1: + self.cfg_page_dict[page_id_list[idx]] +=3D 1 + removed_page =3D 0 + for idx, id in enumerate(page_id_list): + if self.cfg_page_dict[id] =3D=3D 0: + del self.cfg_data_obj._cfg_page['root']['child'][idx-remov= ed_page] # noqa: E501 + removed_page +=3D 1 + def reload_config_data_from_bin(self, bin_dat): self.cfg_data_obj.load_default_from_bin(bin_dat) + self.set_config_data_page() + self.left.delete(*self.left.get_children()) + self.build_config_page_tree(self.cfg_data_obj.get_cfg_page()['root= '], + '') self.refresh_config_data_page() =20 def set_config_item_value(self, item, value_str): diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py b/IntelFsp2Pkg/T= ools/ConfigEditor/GenYamlCfg.py index 611a9a9c72..b593885807 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py @@ -13,6 +13,7 @@ import string import operator as op import ast import tkinter.messagebox as messagebox +import tkinter =20 from datetime import date from collections import OrderedDict @@ -583,7 +584,6 @@ class CGenYamlCfg: self._mode =3D '' self._debug =3D False self._macro_dict =3D {} - self.bin_offset =3D [] self.binseg_dict =3D {} self.initialize() =20 @@ -1046,6 +1046,7 @@ option format '%s' !" % option) try: value =3D self.reformat_value_str(act_cfg['value'], act_cfg['length']) + except Exception: value =3D act_cfg['value'] length =3D bit_len // 8 @@ -1298,18 +1299,85 @@ option format '%s' !" % option) self.traverse_cfg_tree(_get_field_value, top) return result =20 + data_diff =3D '' + + def find_data_difference(self, act_val, act_cfg): + # checks for any difference between BSF and Binary file + config_val =3D '' + if act_val !=3D act_cfg['value']: + + if 'DEC' in act_cfg['type']: + bsf_val =3D '0x%x' % int(act_val) + if bsf_val !=3D act_cfg['value']: + config_val =3D bsf_val + else: + config_val =3D '' + else: + config_val =3D act_val + + available_fv1 =3D 'none' + available_fv2 =3D 'none' + + if self.detect_fsp(): + if len(self.available_fv) >=3D 1: + if len(self.available_fv) > 1: + available_fv1 =3D self.available_fv[1] + if self.available_fv[2]: + available_fv2 =3D self.available_fv[2] + else: + available_fv1 =3D self.available_fv[1] + if act_cfg['length'] =3D=3D 16: + config_val =3D int(config_val, 16) + config_val =3D '0x%x' % config_val + act_cfg['value'] =3D int( + act_cfg['value'], 16) + act_cfg['value'] =3D '0x%x' % \ + act_cfg['value'] + + if config_val: + string =3D ('.' + act_cfg['cname']) + if (act_cfg['path'].endswith(self.available_fv[0] + string) + or act_cfg['path'].endswith(available_fv1 + string) + or act_cfg['path'].endswith(available_fv2 + string)) \ + and 'BsfSkip' not in act_cfg['cname'] \ + and 'Reserved' not in act_cfg['name']: + if act_cfg['option'] !=3D '': + if act_cfg['length'] =3D=3D 8: + config_val =3D int(config_val, 16) + config_val =3D '0x%x' % config_val + act_cfg['value'] =3D int( + act_cfg['value'], 16) + act_cfg['value'] =3D '0x%x' % \ + act_cfg['value'] + option =3D act_cfg['option'] + + cfg_val =3D '' + bin_val =3D '' + for i in option.split(','): + if act_cfg['value'] in i: + bin_val =3D i + elif config_val in i: + cfg_val =3D i + if cfg_val !=3D '' and bin_val !=3D '': + self.data_diff +=3D '\n\nBinary: ' \ + + act_cfg['name'] \ + + ': ' + bin_val.replace(' ', '') \ + + '\nConfig file: ' \ + + act_cfg['name'] + ': ' \ + + cfg_val.replace(' ', '') + '\n' + else: + self.data_diff +=3D '\n\nBinary: ' \ + + act_cfg['name'] + ': ' + act_cfg['value'] \ + + '\nConfig file: ' + act_cfg['name'] \ + + ': ' + config_val + '\n' + def set_field_value(self, top, value_bytes, force=3DFalse): def _set_field_value(name, cfgs, level): if 'indx' not in cfgs: return act_cfg =3D self.get_item_by_index(cfgs['indx']) actual_offset =3D act_cfg['offset'] - struct_info['offset'] - set_value =3D True - for each in self.bin_offset: - if actual_offset in range(each[0], (each[0] + each[2]) * 8= ): - if each[1] < 0: - set_value =3D False - if set_value and force or act_cfg['value'] =3D=3D '': + if force or act_cfg['value'] =3D=3D '': value =3D get_bits_from_bytes(full_bytes, actual_offset, act_cfg['length']) @@ -1321,6 +1389,7 @@ option format '%s' !" % option) act_val) act_cfg['value'] =3D self.format_value_to_str( value, act_cfg['length'], act_val) + self.find_data_difference(act_val, act_cfg) =20 if 'indx' in top: # it is config option @@ -1438,6 +1507,9 @@ for '%s' !" % (act_cfg['value'], act_cfg['path'])) =20 return bin_segs =20 + available_fv =3D [] + missing_fv =3D [] + def extract_cfg_from_bin(self, bin_data): # get cfg bin length cfg_bins =3D bytearray() @@ -1445,12 +1517,12 @@ for '%s' !" % (act_cfg['value'], act_cfg['path'])) Dummy_offset =3D 0 for each in bin_segs: if each[1] !=3D -1: - self.bin_offset.append([Dummy_offset, each[1], each[2]]) cfg_bins.extend(bin_data[each[1]:each[1] + each[2]]) + self.available_fv.append(each[0]) else: + self.missing_fv.append(each[0]) string =3D each[0] + ' is not availabe.' messagebox.showinfo('', string) - self.bin_offset.append([Dummy_offset, each[1], each[2]]) cfg_bins.extend(bytearray(each[2])) Dummy_offset +=3D each[2] return cfg_bins @@ -1476,10 +1548,41 @@ for '%s' !" % (act_cfg['value'], act_cfg['path'])) print('Patched the loaded binary successfully !') return bin_data =20 + def show_data_difference(self, data_diff): + # Displays if any data difference detected in BSF and Binary file + pop_up_text =3D 'There are differences in Config file and binary '\ + 'data detected!\n' + pop_up_text +=3D data_diff + + window =3D tkinter.Tk() + window.title("Data Difference") + window.resizable(1, 1) + # Window Size + window.geometry("800x400") + frame =3D tkinter.Frame(window, height=3D800, width=3D700) + frame.pack(side=3Dtkinter.BOTTOM) + # Vertical (y) Scroll Bar + scroll =3D tkinter.Scrollbar(window) + scroll.pack(side=3Dtkinter.RIGHT, fill=3Dtkinter.Y) + + text =3D tkinter.Text(window, wrap=3Dtkinter.NONE, + yscrollcommand=3Dscroll.set, + width=3D700, height=3D400) + text.insert(tkinter.INSERT, pop_up_text) + text.pack() + # Configure the scrollbars + scroll.config(command=3Dtext.yview) + exit_button =3D tkinter.Button( + window, text=3D"Close", command=3Dwindow.destroy) + exit_button.pack(in_=3Dframe, side=3Dtkinter.RIGHT, padx=3D20, pad= y=3D10) + def load_default_from_bin(self, bin_data): self._old_bin =3D bin_data cfg_bins =3D self.extract_cfg_from_bin(bin_data) self.set_field_value(self._cfg_tree, cfg_bins, True) + + if self.data_diff: + self.show_data_difference(self.data_diff) return cfg_bins =20 def generate_binary_array(self, path=3D''): --=20 2.26.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 (#79411): https://edk2.groups.io/g/devel/message/79411 Mute This Topic: https://groups.io/mt/84943126/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-