Infineon: Add support for PSOC C3 family
diff --git a/boot/cypress/scripts/feature.py b/boot/cypress/scripts/feature.py
index 01dbb1e..a0a61c4 100644
--- a/boot/cypress/scripts/feature.py
+++ b/boot/cypress/scripts/feature.py
@@ -1,5 +1,5 @@
"""
-Copyright 2023 Cypress Semiconductor Corporation (an Infineon company)
+Copyright 2024 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");
@@ -15,10 +15,11 @@
limitations under the License.
"""
-
-import sys
+import argparse
import json
-import click
+import sys
+import os
+
def load_json(file_path):
"""
@@ -106,7 +107,8 @@
'image_encryption' : 'ENC_IMG',
'fault_injection_hardening' : 'FIH_PROFILE_LEVEL',
'combine_hex' : 'COMBINE_HEX',
- 'hw_key' : 'USE_HW_KEY'
+ 'hw_key' : 'USE_HW_KEY',
+ 'built_in_keys' : 'USE_BUILT_IN_KEYS'
}
debug_level_dict = {
@@ -193,7 +195,7 @@
"""
Handle any dictionary of 'feature_config'
"""
- dont_print_list = set(("validation_key", "version", "description", "target"))
+ dont_print_list = set(("validation_key", "encryption_key", "version", "description", "target"))
for k in f_dict:
@@ -206,12 +208,27 @@
if k == 'serial_logging':
f_out.write(self.__gen_debug_level(f_dict.get(k).get("value")))
+ if k == "validation_key":
+ value = f_dict.get(k).get("value")
+ if value != '':
+ f_out.write(f'ECDSA_PUBLIC_KEY={value}\n')
+
+ if k == "encryption_key":
+ value = f_dict.get(k).get("value")
+ if value != '':
+ f_out.write(f'ENC_PRIVATE_KEY={value}\n')
+
def make_file_generate(self, feature_json):
"""
Processing all keys and creation of a mk-file
"""
+ out_dir = os.path.dirname(self.out_f)
+
+ if not os.path.exists(out_dir):
+ os.mkdir(out_dir)
+
with open(self.out_f, "w", encoding='UTF-8') as f_out:
f_out.write(FeatureProcessor.generate_header_guard())
@@ -224,19 +241,25 @@
self.__handle_dictionary(feature_json, f_out)
-@click.group()
def cli():
- """
- Feature config parser to run from CLI
- """
+ parser = argparse.ArgumentParser(description='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')
+ parser.add_argument('-f', '--feature_config', required=True,
+ help='Feature configuration file path')
+ parser.add_argument('-p', '--platform_properties', required=True,
+ help='Platform properties file path')
+ parser.add_argument('-n', '--output_name', required=True,
+ help='The name of the make file that will be generated')
+ parser.add_argument('other_args', nargs='?',
+ help='Ignore all other arguments, such as: run')
+
+ args = parser.parse_args()
+
+ run(args.feature_config, args.platform_properties, args.output_name)
+
+ # run('C:/Work/mcuboot/mtb-example-bootloader-solution/platforms/PSC3/feature_config.json',
+ # 'C:/Work/mcuboot/mtb-example-bootloader-solution/mtb_shared/mcuboot/1.9.3-ifx-boy2-es10/boot/cypress/platforms/memory/PSC3/flashmap/platform_properties.json',
+ # 'C:/Work/mcuboot/mtb-example-bootloader-solution/platforms/PSC3/feature_config.mk')
def run(feature_config, platform_properties, output_name):
diff --git a/boot/cypress/scripts/find_cysectools.py b/boot/cypress/scripts/find_cysectools.py
index 7bea0fc..8733575 100644
--- a/boot/cypress/scripts/find_cysectools.py
+++ b/boot/cypress/scripts/find_cysectools.py
@@ -17,7 +17,7 @@
import subprocess
import sys
-package = 'cysecuretools'
+package = 'edgeprotecttools'
def find_cysectools(package_name):
diff --git a/boot/cypress/scripts/memorymap_rework.py b/boot/cypress/scripts/memorymap_rework.py
index 855cf23..01b541f 100644
--- a/boot/cypress/scripts/memorymap_rework.py
+++ b/boot/cypress/scripts/memorymap_rework.py
@@ -1,5 +1,5 @@
"""
-Copyright 2023 Cypress Semiconductor Corporation (an Infineon company)
+Copyright 2024 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");
@@ -15,9 +15,10 @@
limitations under the License.
"""
-import sys
+import argparse
import json
-import click
+import sys
+import os
APP_LIMIT = 8
@@ -41,6 +42,10 @@
, 'bootloader_ram_address' : 'BOOTLOADER_RAM_ORIGIN'
, 'bootloader_ram_size' : 'BOOTLOADER_RAM_SIZE'
, 'bootloader_area' : 'BOOTLOADER_AREA'
+ , 'staging_area' : 'USE_RAM_APPS_STAGING'
+ , 'ram_apps_staging_addr' : 'RAM_APPS_STAGING_ADDR'
+ , 'ram_apps_staging_size' : 'RAM_APPS_STAGING_SIZE'
+ , 'bootloader_ram_load' : 'BOOTLOADER_IN_RAM'
, 'application_count' : 'MCUBOOT_IMAGE_NUMBER'
, 'boot_image' : 'BOOT_IMAGE_NUMBER'
, 'sectors_count' : 'MAX_IMG_SECTORS'
@@ -113,10 +118,12 @@
def __init__(self):
self.bootloader_area : Memory = None
self.ram : Memory = None
+ self.ram_boot : Memory = None
self.scratch_area : Memory = None
self.status_area : Memory = None
self.shared_data : Memory = None
self.shared_upgrade : Memory = None
+ self.staging_area : Memory = None
self.core_name : int = None
@property
@@ -135,14 +142,17 @@
def has_status_area(self) -> bool:
return self.status_area is not None
+ @property
+ def has_staging_area(self) -> bool:
+ return self.staging_area is not None
+
def parse(self, section : json):
'''
- Parse JSON section and init fields.
+ Parse JSON 'bootloader' section and init fields.
'''
try:
- fields = ('bootloader_area', 'scratch_area', 'status_area', \
- 'shared_data', 'shared_upgrade', 'ram')
- for field in fields:
+ list_of_fields = section.keys()
+ for field in list_of_fields:
area = section.get(field)
if area:
setattr(self, field, Memory(int(area['address'], 0),
@@ -337,6 +347,7 @@
boot_area = main_app.boot_area
upgrade_area = main_app.upgrade_area
scratch_area = self.boot_layout.scratch_area
+ staging_area = self.boot_layout.staging_area
param_dict.update({'bootloader': [bootloader_area, 'FLASH_AREA_BOOTLOADER', 0]})
param_dict.update({'app_1_boot': [boot_area, 'FLASH_AREA_IMG_1_PRIMARY', 1]})
@@ -349,6 +360,10 @@
if self.boot_layout.has_scratch_area:
param_dict.update({'scratch_area': [scratch_area, 'FLASH_AREA_IMAGE_SCRATCH', 3]})
+ # Generate scratch area index
+ if self.boot_layout.has_staging_area:
+ param_dict.update({'staging_area': [staging_area, 'FLASH_AREA_RAM_APP_STAGING', 255]})
+
# Generate multiple app area indexes
multi_app_area_idx = 4
if len(self.apps) > 1:
@@ -382,9 +397,12 @@
'''
C-file generation, file name and path must be given by script user
'''
- path = f'{self.output_folder}/{self.output_name}.c'
+ path = os.path.join(self.output_folder, f'{self.output_name}.c')
include = f'{self.output_name}.h'
+ if not os.path.exists(self.output_folder):
+ os.mkdir(self.output_folder)
+
with open(path, "w", encoding='UTF-8') as f_out:
f_out.write(f'#include "{include}"\n')
f_out.write(f'#include "flash_map_backend.h"\n\n')
@@ -392,7 +410,7 @@
f_out.write('{\n')
for region in self.regions:
if region.mem_type[0] in self.region_types:
- f_out.write(f'\t[{region.mem_type[0]}] = ' + '{\n')
+ f_out.write('\t{\n')
f_out.write(f'\t\t.address = {hex(region.addr)}U,\n')
f_out.write(f'\t\t.size = {hex(region.sz)}U,\n')
f_out.write(f'\t\t.erase_size = {hex(region.erase_sz)}U,\n')
@@ -432,6 +450,7 @@
f_out.write('\n};\n\n')
f_out.write('image_boot_config_t image_boot_config[BOOT_IMAGE_NUMBER] = {\n')
+
for app in self.apps:
f_out.writelines('\n'.join([
'\t{\n'
@@ -442,7 +461,11 @@
f_out.write('};\n')
def __header_gen(self):
- path = f'{self.output_folder}/{self.output_name}.h'
+ path = os.path.join(self.output_folder, f'{self.output_name}.h')
+
+ if not os.path.exists(self.output_folder):
+ os.mkdir(self.output_folder)
+
with open(path, "w", encoding='UTF-8') as f_out:
header_guard_generate(f_out)
@@ -457,10 +480,11 @@
f_out.write('enum \n{\n')
- # it's critical to use 'regions' here!
+ # it's critical to use 'self.regions' here!
# because it fixes the bug when enum {INTERNAL_RRAM, EXTERNAL_FLASH,}
# is generated in incorrect sequence.
for region in self.regions:
+ if region.mem_type[0] in self.region_types:
f_out.write(f'\t{str(region.mem_type[0])},\n')
f_out.write('};\n\n')
@@ -483,6 +507,8 @@
f_out.write('extern image_boot_config_t image_boot_config[BOOT_IMAGE_NUMBER];\n\n')
def __bootloader_mk_file_gen(self):
+ print('\n[memorymap_rework.py] Generating boot mk file', file=sys.stderr)
+
boot = self.boot_layout
for mem_type in self.region_types:
@@ -491,6 +517,10 @@
for mem_type in self.region_types_alt:
print(f'USE_{mem_type} := 1')
+ # RAM app staging area
+ if boot.staging_area is None:
+ print(settings_dict['staging_area'], ':= 1')
+
# Upgrade mode
if boot.scratch_area is None and boot.status_area is None:
print(settings_dict['overwrite'], ':= 1')
@@ -518,10 +548,21 @@
print(f'{settings_dict["bootloader_app_address"]} :=', hex(boot.bootloader_area.addr))
print(f'{settings_dict["bootloader_app_size"]} :=', hex(boot.bootloader_area.sz))
- if boot.ram is not None:
+ if boot.ram:
print('# Bootloader ram area')
print(f'{settings_dict["bootloader_ram_address"]} :=', hex(boot.ram.addr))
print(f'{settings_dict["bootloader_ram_size"]} :=', hex(boot.ram.sz))
+
+ if boot.ram_boot:
+ print(f'{settings_dict["bootloader_ram_load"]} := 1')
+ print(f'{settings_dict["bootloader_ram_address"]} :=', hex(boot.ram_boot.addr))
+ print(f'{settings_dict["bootloader_ram_size"]} :=', hex(boot.ram_boot.sz))
+
+ if boot.staging_area:
+ print('# Bootloader RAM app staging area')
+ print(f'{settings_dict["staging_area"]} := 1')
+ print(f'{settings_dict["ram_apps_staging_addr"]} :=', hex(boot.staging_area.addr))
+ print(f'{settings_dict["ram_apps_staging_size"]} :=', hex(boot.staging_area.sz))
print('# Application area')
for img_id, app in enumerate(self.apps):
@@ -632,10 +673,12 @@
self.__memory_areas_create()
if app_id is None:
+ print('\n[memorymap_rework.py] Generating boot sources', file=sys.stderr)
self.__source_gen()
self.__header_gen()
self.__bootloader_mk_file_gen()
else:
+ print('\n[memorymap_rework.py] Generating app sources', file=sys.stderr)
self.__application_mk_file_gen()
except (FileNotFoundError, OSError):
@@ -643,23 +686,27 @@
sys.exit(-1)
-@click.group()
def cli():
- '''
- Memory map layout parser-configurator
- '''
+ parser = argparse.ArgumentParser(description='Memory map layout parser-configurator')
-@cli.command()
-@click.option('-i', '--memory_config', required=True,
- help='memory configuration file path')
-@click.option('-p', '--platform_config', required=True,
- help='platform configuration file path')
-@click.option('-n', '--output_name', required=True,
- help='generated areas path')
-@click.option('-o', '--output_folder', required=True,
- help='generated regions path')
-@click.option('-d', '--image_id', required=False,
- help='application image number')
+ parser.add_argument('-i', '--memory_config', required=True,
+ help='memory configuration file path')
+ parser.add_argument('-p', '--platform_config', required=True,
+ help='platform configuration file path')
+ parser.add_argument('-n', '--output_name', required=True,
+ help='generated areas path')
+ parser.add_argument('-o', '--output_folder', required=True,
+ help='generated regions path')
+ parser.add_argument('-d', '--image_id', required=False,
+ help='application image number')
+ parser.add_argument('other_args', nargs='?',
+ help='Ignore all other arguments, such as: run')
+
+ args = parser.parse_args()
+
+ run(args.memory_config, args.platform_config, args.output_folder, args.output_name,
+ args.image_id)
+
def run(memory_config, platform_config, output_folder, output_name, image_id):
''''