Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/cypress/scripts/feature.py b/boot/cypress/scripts/feature.py
new file mode 100644
index 0000000..4bc428c
--- /dev/null
+++ b/boot/cypress/scripts/feature.py
@@ -0,0 +1,251 @@
+"""
+Copyright 2023 Cypress Semiconductor Corporation (an Infineon company)
+or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+
+import sys
+import json
+import click
+
+def load_json(file_path):
+    """
+    Loads JSON from file.
+    """
+
+    data_json = None
+
+    try:
+        with open(file_path, encoding="utf-8") as file:
+            data_json = json.load(file)
+
+    except FileNotFoundError:
+        print(f'\nERROR: Cannot find {file_path}')
+        sys.exit(-1)
+
+    return data_json
+
+
+class FieldsValidator:
+    """
+        Validation of required fields and their cross-dependencies.
+    """
+
+    @staticmethod
+    def validate(feature_json, properties_json):
+        """
+            Check 'target' and properties of a platform.
+        """
+        p_target = properties_json.get('target')
+        if p_target is None:
+            raise AttributeError('Field "target" must be present in platform_properties.json')
+
+        f_target = feature_json.get('target')
+        if f_target is None:
+            raise AttributeError('Field "target" must be present in a feature_config.json')
+
+        if f_target not in p_target:
+            raise AttributeError('Target in feature config is not correct.'
+                                    ' It must be among the target list of platform_properties.json')
+
+        f_security_setup = feature_json.get('security_setup')
+        p_security_setup = properties_json.get('security_setup')
+
+        if f_security_setup:
+
+            if p_security_setup is None:
+                raise AttributeError("This platform doesn't have any 'secure_setup' features")
+
+            if f_security_setup.get('hw_rollback_prot'):
+                if p_security_setup.get('hw_rollback_prot') is None:
+                    raise AttributeError("This platform doesn't have HW anti roll-back counter")
+
+            if f_security_setup.get('hw_crypto_acceleration'):
+                if p_security_setup.get('hw_crypto_acceleration') is None:
+                    raise AttributeError("The platform doesn't support HW crypto acceleration")
+
+            if f_security_setup.get('validate_upgrade').get('value') is False:
+                raise AttributeError("Deactivation of image validation during the upgrade \
+                                        process isn't implemented yet")
+
+
+class FeatureProcessor:
+
+    """
+        The general handler of all needed fields and filling the new mk-file.
+    """
+
+    settings_dict = {
+        'validate_boot'             :   'MCUBOOT_SKIP_IMAGE_VALIDATION',
+        'validate_upgrade'          :   'MCUBOOT_SKIP_UPGRADE_VALIDATION',
+        'dependency_check'          :   'MCUBOOT_DEPENDENCY_CHECK',
+        'serial_logging'            :   'MCUBOOT_LOG_LEVEL',
+        'hw_rollback_prot'          :   'USE_HW_ROLLBACK_PROT',
+        'hw_crypto_acceleration'    :   "USE_CRYPTO_HW",
+        'sw_downgrade_prev'         :   'USE_SW_DOWNGRADE_PREV',
+        'ram_app_staging'           :   'USE_STAGE_RAM_APPS',
+        'xip'                       :   'USE_XIP',
+        'image_encryption'          :   'ENC_IMG',
+        'fault_injection_hardening' :   'FIH_PROFILE_LEVEL',
+        'combine_hex'               :   'COMBINE_HEX',
+        'hw_key'                    :   'USE_HW_KEY'
+    }
+
+    debug_level_dict = {
+        'off'       :   '_OFF',
+        'error'     :   '_ERROR',
+        'warning'   :   '_WARNING',
+        'info'      :   '_INFO',
+        'debug'     :   '_DEBUG'
+    }
+
+    fih_level_dict = {
+        'off'       :   'OFF',
+        'low'       :   'LOW',
+        'medium'    :   'MEDIUM',
+        'high'      :   'HIGH'
+    }
+
+    def __init__(self, output_name):
+        self.out_f = output_name
+
+    @staticmethod
+    def generate_header_guard():
+        """
+            Print header line at the begining of a mk-file
+        """
+        guard_lines = ('# AUTO-GENERATED FILE, DO NOT EDIT.'
+                        ' ALL CHANGES WILL BE LOST! #\n\n')
+
+        return guard_lines
+
+    @staticmethod
+    def insert_res(val_to_check) -> str:
+        """
+            Simlpe check result and return the string with value.
+        """
+        return f' := {1 if val_to_check else 0}\n'
+
+    @staticmethod
+    def insert_inverted_res(val_to_check) -> str:
+        """
+            Simlpe check result and return the string with inverted value.
+        """
+        return f' := {0 if val_to_check else 1}\n'
+
+    def __prnt_dict_primitive_key(self, dict_feature_config, settings_dict_key, f_out):
+        """
+            Print kyes of 'feature_config' with bool type of 'value'
+        """
+        val = dict_feature_config.get(settings_dict_key).get('value')
+
+        if isinstance(val, bool):
+
+            # invert because variable use 'skip' command
+            need_invertion = set(("validate_boot", "validate_upgrade"))
+
+            f_out.write(self.settings_dict[settings_dict_key])
+
+            if settings_dict_key not in need_invertion:
+                f_out.write(FeatureProcessor.insert_res(val))
+            else:
+                f_out.write(FeatureProcessor.insert_inverted_res(val))
+
+
+    def __gen_fih_level(self, fih_value):
+        """
+            Print only FIH_
+        """
+        res = f"{self.settings_dict['fault_injection_hardening']} ?= "\
+              f"{self.fih_level_dict[fih_value]}\n"
+
+        return res
+
+    def __gen_debug_level(self, logging_value):
+        """
+            Print only MCUBOOT_LOG_LEVEL
+        """
+        param_txt = self.settings_dict['serial_logging']
+        res_str = f"{param_txt} ?= {param_txt}{self.debug_level_dict[logging_value]}\n"
+
+        return res_str
+
+
+    def __handle_dictionary(self, f_dict, f_out):
+        """
+            Handle any dictionary of 'feature_config'
+        """
+        dont_print_list = set(("validation_key", "version", "description", "target"))
+
+        for k in f_dict:
+
+            if k not in dont_print_list:
+                self.__prnt_dict_primitive_key(f_dict, k, f_out)
+
+            if k == 'fault_injection_hardening':
+                f_out.write(self.__gen_fih_level(f_dict.get(k).get("value")))
+
+            if k == 'serial_logging':
+                f_out.write(self.__gen_debug_level(f_dict.get(k).get("value")))
+
+
+    def make_file_generate(self, feature_json):
+        """
+            Processing all keys and creation of a mk-file
+        """
+
+        with open(self.out_f, "w", encoding='UTF-8') as f_out:
+            f_out.write(FeatureProcessor.generate_header_guard())
+
+            f_security_setup_dict = feature_json.get('security_setup')
+
+            # handling of 'security_setup' section
+            if f_security_setup_dict:
+                self.__handle_dictionary(f_security_setup_dict, f_out)
+
+            self.__handle_dictionary(feature_json, f_out)
+
+
+@click.group()
+def cli():
+    """
+        Feature config parser to run from CLI
+    """
+
+@cli.command()
+@click.option('-f', '--feature_config', required=True,
+              help='feature configuration file path')
+@click.option('-p', '--platform_properties', required=True,
+              help='platform properties file path')
+@click.option('-n', '--output_name', required=True,
+              help='the name of the make file that will be generated')
+
+
+def run(feature_config, platform_properties, output_name):
+    """
+        The main CLI command to run mk-file generation
+    """
+
+    feature_config_json = load_json(feature_config)
+    platform_properties_json = load_json(platform_properties)
+
+    FieldsValidator.validate(feature_config_json, platform_properties_json)
+
+    fprocessor = FeatureProcessor(output_name)
+    fprocessor.make_file_generate(feature_config_json)
+
+
+if __name__ == '__main__':
+    cli()