blob: 9d3ce77bb5b241ca8b05b5876200ed50766e772c [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
Xinyu Zhang90f08dc2022-01-12 15:55:17 +08002# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
Chris Brandf1d6b6f2022-07-22 11:49:01 -07003# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4# or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
Miklos Balint470919c2018-05-22 17:51:29 +02005#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8#-------------------------------------------------------------------------------
9
10import os
Mate Toth-Pal36f21842018-11-08 16:12:51 +010011import io
Kevin Pengce99e5d2021-11-09 18:06:53 +080012import re
Shawn Shana9ad1e02019-08-07 15:49:48 +080013import sys
14import argparse
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050015import logging
Ken Liu1f345b02020-05-30 21:11:05 +080016from jinja2 import Environment, BaseLoader, select_autoescape, TemplateNotFound
Miklos Balint470919c2018-05-22 17:51:29 +020017
18try:
19 import yaml
20except ImportError as e:
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050021 logging.error (str(e) + " To install it, type:")
22 logging.error ("pip install PyYAML")
Miklos Balint470919c2018-05-22 17:51:29 +020023 exit(1)
24
Edison Ai48b2d9e2019-06-24 14:39:45 +080025donotedit_warning = \
Sherry Zhangf58f2bd2022-01-10 17:21:11 +080026 ' WARNING: This is an auto-generated file. Do not edit! '
Kevin Peng655f2392019-11-27 16:33:02 +080027
Kevin Pengce99e5d2021-11-09 18:06:53 +080028TFM_ROOT_DIR = os.path.join(sys.path[0], '..')
Kevin Peng655f2392019-11-27 16:33:02 +080029OUT_DIR = None # The root directory that files are generated to
Edison Ai48b2d9e2019-06-24 14:39:45 +080030
Sherry Zhang87e6d2e2021-12-27 14:48:59 +080031# PID[0, TFM_PID_BASE - 1] are reserved for TF-M SPM and test usages
Kevin Pengce99e5d2021-11-09 18:06:53 +080032TFM_PID_BASE = 256
33
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010034# variable for checking for duplicated sid
35sid_list = []
chesun012345aa52023-04-18 17:31:53 +080036
37# Summary of manifest attributes defined by FFM for use in the Secure Partition manifest file.
38ffm_manifest_attributes = ['psa_framework_version', 'name', 'type', 'priority', 'model', 'entry_point', \
39'stack_size', 'description', 'entry_init', 'heap_size', 'mmio_regions', 'services', 'irqs', 'dependencies']
40
Mate Toth-Pal36f21842018-11-08 16:12:51 +010041class TemplateLoader(BaseLoader):
42 """
43 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020044
Mate Toth-Pal36f21842018-11-08 16:12:51 +010045 An instance of this class is passed to the template engine. It is
46 responsible for reading the template file
47 """
48 def __init__(self):
49 pass
Miklos Balint470919c2018-05-22 17:51:29 +020050
Mate Toth-Pal36f21842018-11-08 16:12:51 +010051 def get_source(self, environment, template):
52 """
53 This function reads the template files.
54 For detailed documentation see:
55 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
56
57 Please note that this function always return 'false' as 'uptodate'
58 value, so the output file will always be generated.
59 """
60 if not os.path.isfile(template):
61 raise TemplateNotFound(template)
62 with open(template) as f:
63 source = f.read()
64 return source, template, False
65
Kevin Pengfb1761b2022-05-12 12:11:31 +080066def parse_configurations(file_paths):
67 """
68 Parses the given config files and return a dict whose key-values are build
69 configurations and their values.
70
71 Valid configurations should be in the format of:
72 "#define VAR [...]" in a single line.
73 The value of the config is optional.
74 """
75 configurations = {}
76
77 lines = []
78 for file in file_paths:
79 with open(file, 'r') as config_file:
80 lines += config_file.readlines()
81
82 for line in lines:
83 if not line.startswith('#define'):
84 continue
85
86 line = line.rstrip('\r\n')
87 line_items = line.split(maxsplit=2)
88 if len(line_items) == 3:
89 configurations[line_items[1]] = line_items[2]
90 elif len(line_items) == 2:
91 configurations[line_items[1]] = ''
92
93 logging.debug(configurations)
94
95 return configurations
96
Kevin Peng5c3fee72022-02-16 22:25:22 +080097def manifest_validation(manifest, pid):
Mingyang Sun294ce2e2021-06-11 11:58:24 +080098 """
99 This function validates FF-M compliance for partition manifest, and sets
100 default values for optional attributes.
Kevin Pengce99e5d2021-11-09 18:06:53 +0800101 The validation is skipped for TF-M specific Partitions (PID < TFM_PID_BASE).
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800102 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800103
Kevin Peng5c3fee72022-02-16 22:25:22 +0800104 service_list = manifest.get('services', [])
105 irq_list = manifest.get('irqs', [])
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800106
Kevin Peng5c3fee72022-02-16 22:25:22 +0800107 # "psa_framework_version" validation
108 if manifest['psa_framework_version'] not in [1.0, 1.1]:
109 raise Exception('Invalid psa_framework_version of {}'.format(manifest['name']))
110
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700111 # "type" validation
Kevin Peng5c3fee72022-02-16 22:25:22 +0800112 if manifest['type'] not in ['PSA-ROT', 'APPLICATION-ROT']:
113 raise Exception('Invalid type of {}'.format(manifest['name']))
114
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700115 # "priority" validation
116 if manifest['priority'] not in ['HIGH', 'NORMAL', 'LOW']:
117 raise Exception('Invalid priority of {}'.format(manifest['name']))
118
Chris Brandc422cdd2022-07-21 13:32:47 -0700119 if 'ns_agent' not in manifest:
120 manifest['ns_agent'] = False
121
Kevin Peng5c3fee72022-02-16 22:25:22 +0800122 # Every PSA Partition must have at least either a secure service or an IRQ
Kevin Pengce99e5d2021-11-09 18:06:53 +0800123 if (pid == None or pid >= TFM_PID_BASE) \
Kevin Peng8849b6a2021-11-09 14:17:35 +0800124 and len(service_list) == 0 and len(irq_list) == 0:
125 raise Exception('{} must declare at least either a secure service or an IRQ!'
Kevin Peng5c3fee72022-02-16 22:25:22 +0800126 .format(manifest['name']))
127
128 if manifest['psa_framework_version'] == 1.0:
129 # For 1.0 Partition, the model is IPC
130 manifest['model'] = 'IPC'
131
132 # "model" validation:
133 model = manifest.get('model', None)
134 if model == None:
135 raise Exception('{} is missing the "model" attribute'.format(manifest['name']))
136
137 # Assign a unified 'entry' for templates
138 if model == 'IPC':
139 # entry_point is mandatory for IPC Partitions
140 if 'entry_point' not in manifest.keys():
141 raise Exception('{} is missing the "entry_point" attribute'.format(manifest['name']))
142 manifest['entry'] = manifest['entry_point']
143 elif model == 'SFN':
144 if 'entry_init' in manifest.keys():
145 manifest['entry'] = manifest['entry_init']
146 else:
147 manifest['entry'] = 0
148 else:
149 raise Exception('Invalid "model" of {}'.format(manifest['name']))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800150
151 # Service FF-M manifest validation
152 for service in service_list:
Kevin Peng5c3fee72022-02-16 22:25:22 +0800153 if manifest['psa_framework_version'] == 1.0:
154 service['connection_based'] = True
155 elif 'connection_based' not in service:
156 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
157
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800158 if 'version' not in service.keys():
159 service['version'] = 1
160 if 'version_policy' not in service.keys():
Kevin Peng5bc82d22021-10-19 11:18:40 +0800161 service['version_policy'] = 'STRICT'
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800162
Kevin Peng5bc82d22021-10-19 11:18:40 +0800163 # SID duplication check
164 if service['sid'] in sid_list:
165 raise Exception('Service ID: {} has duplications!'.format(service['sid']))
166 else:
167 sid_list.append(service['sid'])
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100168
Kevin Peng5c3fee72022-02-16 22:25:22 +0800169 return manifest
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800170
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800171def check_circular_dependency(partitions, service_partition_map):
172 """
173 This function detects if there is any circular partition dependency chain.
174 If a circular dependency is detected, the script exits with error.
175
176 Inputs:
177 - partitions: dict of partition manifests
178 - service_partition_map: map between services and their owner Partitions
179 """
180
181 dependency_table = {}
182 for partition in partitions:
183 manifest = partition['manifest']
184 dependencies = manifest['dependencies'].copy() \
185 if 'dependencies' in manifest else []
186 dependencies += manifest['weak_dependencies'].copy() \
187 if 'weak_dependencies' in manifest else []
188 dependency_table[manifest['name']] = {
189 'dependencies': [service_partition_map[dependency]
190 for dependency in dependencies
191 if dependency in service_partition_map],
192 'validated': False
193 }
194
195 for partition in dependency_table.keys():
196 validate_dependency_chain(partition, dependency_table, [])
197
198def validate_dependency_chain(partition,
199 dependency_table,
200 dependency_chain):
201 """
202 Recursively validate if the given partition and its dependencies
203 have a circular dependency with the given dependency_chain.
204 Exit with error code once any circular is detected.
205
206 Inputs:
207 - partition: next partition to be checked
208 - dependency_table: dict of partitions and their dependencies
209 - dependency_chain: list of dependencies in current chain
210 """
211
212 dependency_chain.append(partition)
213 if partition in dependency_chain[:-1]:
214 logging.error(
215 'Circular dependency exists in chain: {}'.format(
216 ', '.join(dependency_chain)))
217 exit(1)
218 for dependency in dependency_table[partition]['dependencies']:
219 if dependency_table[dependency]['validated']:
220 continue
221 validate_dependency_chain(dependency, dependency_table, dependency_chain)
222 dependency_table[partition]['validated'] = True
223
chesun012345aa52023-04-18 17:31:53 +0800224def manifest_attribute_check(manifest, manifest_item):
225 """
226 Check whether Non-FF-M compliant attributes are explicitly registered in manifest lists.
227
228 Inputs:
229 - manifest: next manifest to be checked
230 - manifest_item: the manifest items in manifest lists
231 """
232 allowed_attributes = ffm_manifest_attributes + manifest_item.get('non_ffm_attributes', [])
233 for keyword in manifest.keys():
234 if keyword not in allowed_attributes:
235 logging.error('The Non-FFM attribute {} is used by {} without registration.'.format(keyword, manifest['name']))
236 exit(1)
237
Kevin Pengfb1761b2022-05-12 12:11:31 +0800238def process_partition_manifests(manifest_lists, configs):
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100239 """
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800240 Parse the input manifest lists, check if manifest settings are valid,
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700241 generate the data base for generated files
Kevin Peng655f2392019-11-27 16:33:02 +0800242 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100243
244 Parameters
245 ----------
Kevin Peng65064c52021-10-27 17:12:17 +0800246 manifest_lists:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800247 A list of Secure Partition manifest lists
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100248
249 Returns
250 -------
Kevin Peng5bc82d22021-10-19 11:18:40 +0800251 The manifest data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +0800252 """
Kevin Peng655f2392019-11-27 16:33:02 +0800253
Kevin Peng5bc82d22021-10-19 11:18:40 +0800254 context = {}
255
Ken Liu861b0782021-05-22 13:15:08 +0800256 partition_list = []
Kevin Peng65064c52021-10-27 17:12:17 +0800257 all_manifests = []
Kevin Peng56b0ea62021-10-18 11:32:57 +0800258 pid_list = []
259 no_pid_manifest_idx = []
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800260 service_partition_map = {}
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800261 partition_statistics = {
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800262 'connection_based_srv_num': 0,
Kevin Peng47c26ec2022-03-11 11:49:52 +0800263 'ipc_partitions': [],
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800264 'mmio_region_num': 0,
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800265 'flih_num': 0,
266 'slih_num': 0
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800267 }
Kevin Peng9f1a7542022-02-07 16:32:27 +0800268 config_impl = {
269 'CONFIG_TFM_SPM_BACKEND_SFN' : '0',
270 'CONFIG_TFM_SPM_BACKEND_IPC' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800271 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800272 'CONFIG_TFM_MMIO_REGION_ENABLE' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800273 'CONFIG_TFM_FLIH_API' : '0',
274 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800275 }
chesun0122abf0a2023-10-17 13:42:16 +0800276 priority_map = {
277 'LOWEST' : '00',
278 'LOW' : '01',
279 'NORMAL' : '02',
280 'HIGH' : '03',
281 'HIGHEST' : '04'
282 }
Kevin Peng655f2392019-11-27 16:33:02 +0800283
Kevin Pengfb1761b2022-05-12 12:11:31 +0800284 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
285 backend = configs['CONFIG_TFM_SPM_BACKEND']
286
Kevin Peng65064c52021-10-27 17:12:17 +0800287 # Get all the manifests information as a dictionary
288 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800289 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500290 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800291 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800292
Kevin Peng65064c52021-10-27 17:12:17 +0800293 # The manifest list file generated by configure_file()
294 with open(item) as manifest_list_yaml_file:
295 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
296 for dict in manifest_dic:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800297 # Replace environment variables in the manifest path and convert to absolute path.
298 # If it's already abspath, the path will not be changed.
299 manifest_path = os.path.join(os.path.dirname(item), # path of manifest list
300 os.path.expandvars(dict['manifest']))\
301 .replace('\\', '/')
302 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800303 all_manifests.append(dict)
304
Chris Brand4b69fcf2022-06-06 09:37:49 -0700305 logging.info("------------ Display partition configuration - start ------------")
306
Kevin Peng65064c52021-10-27 17:12:17 +0800307 # Parse the manifests
308 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800309 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
310 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800311 is_enabled = ''
312
313 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800314 if manifest_item['conditional'] not in configs.keys():
315 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
316 exit(1)
317 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800318 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800319 # Partitions without 'conditional' is always on
320 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800321
322 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300323 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800324 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700325 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300326 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700327 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800328 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
329 'Please set to one of {} or {}, case-insensitive.'\
330 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300331 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800332 valid_enabled_conditions, valid_disabled_conditions))
333
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800334 # Check if partition ID is manually set
335 if 'pid' not in manifest_item.keys():
336 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800337 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800338 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800339 pid = manifest_item['pid']
340
341 # Check if partition ID is duplicated
342 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100343 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800344 else:
345 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800346
Kevin Pengfb1761b2022-05-12 12:11:31 +0800347 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800348 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800349 manifest = yaml.safe_load(manifest_file)
chesun0122abf0a2023-10-17 13:42:16 +0800350 # Check manifest attribute validity
chesun012345aa52023-04-18 17:31:53 +0800351 manifest_attribute_check(manifest, manifest_item)
352
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800353 if manifest.get('model', None) == 'dual':
354 # If a Partition supports both models, it can set the "model" to "backend".
355 # The actual model used follows the backend being used.
356 manifest['model'] = backend
357 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800358
chesun0122abf0a2023-10-17 13:42:16 +0800359 # Priority mapping
360 numbered_priority = priority_map[manifest['priority']]
361
Kevin Pengce99e5d2021-11-09 18:06:53 +0800362 if pid == None or pid >= TFM_PID_BASE:
Kevin Pengd08f3ba2021-11-18 15:18:56 +0800363 # Count the number of IPC/SFN partitions
Kevin Peng47c26ec2022-03-11 11:49:52 +0800364 if manifest['model'] == 'IPC':
365 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800366
Kevin Peng5c3fee72022-02-16 22:25:22 +0800367 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
368 # number (0) when there are no services.
369 srv_idx = -1
370 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800371 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800372 if manifest['model'] == 'IPC':
373 # Assign signal value, the first 4 bits are reserved by FF-M
374 service['signal_value'] = (1 << (srv_idx + 4))
375 else:
376 # Signals of SFN Partitions are SPM internal only, does not
377 # need to reserve 4 bits.
378 service['signal_value'] = (1 << srv_idx)
379 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800380 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800381 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800382
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800383 # Calculate the number of mmio region
384 mmio_region_list = manifest.get('mmio_regions', [])
385 partition_statistics['mmio_region_num'] += len(mmio_region_list)
386
Kevin Peng5c3fee72022-02-16 22:25:22 +0800387 # Set initial value to -1 to make (irq + 1) reflect the correct
388 # number (0) when there are no irqs.
389 irq_idx = -1
390 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
391 # Assign signal value, from the most significant bit
392 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800393 if irq.get('handling', None) == 'FLIH':
394 partition_statistics['flih_num'] += 1
395 else:
396 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800397 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
398
399 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
400 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
401 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800402
Kevin Peng65064c52021-10-27 17:12:17 +0800403 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800404
Kevin Peng4fade072021-10-26 17:57:50 +0800405 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800406 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800407 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800408 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800409
Kevin Peng5bc82d22021-10-19 11:18:40 +0800410 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
411 '{}.h'.format(manifest_out_basename))\
412 .replace('\\', '/')
413 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
414 'intermedia_{}.c'.format(manifest_out_basename))\
415 .replace('\\', '/')
416 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
417 'load_info_{}.c'.format(manifest_out_basename))\
418 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800419 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800420
Kevin Peng5bc82d22021-10-19 11:18:40 +0800421 partition_list.append({'manifest': manifest, 'attr': manifest_item,
422 'manifest_out_basename': manifest_out_basename,
423 'header_file': manifest_head_file,
424 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800425 'loadinfo_file': load_info_file,
chesun0122abf0a2023-10-17 13:42:16 +0800426 'output_dir': output_dir,
427 'numbered_priority': numbered_priority})
Ken Liu861b0782021-05-22 13:15:08 +0800428
Chris Brand4b69fcf2022-06-06 09:37:49 -0700429 logging.info("------------ Display partition configuration - end ------------")
430
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800431 check_circular_dependency(partition_list, service_partition_map)
432
Kevin Peng56b0ea62021-10-18 11:32:57 +0800433 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800434 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800435 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800436 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800437 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800438 pid_list.append(pid)
439
Kevin Peng9f1a7542022-02-07 16:32:27 +0800440 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800441 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800442 if len(partition_statistics['ipc_partitions']) > 0:
443 logging.error('SFN backend does not support IPC Partitions:')
444 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800445 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800446
447 if isolation_level > 1:
448 logging.error('SFN backend does not support high isolation levels.')
449 exit(1)
450
Kevin Peng9f1a7542022-02-07 16:32:27 +0800451 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800452 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800453 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800454
455 if partition_statistics['connection_based_srv_num'] > 0:
456 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
457
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800458 if partition_statistics['mmio_region_num'] > 0:
459 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
460
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800461 if partition_statistics['flih_num'] > 0:
462 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200463 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800464 config_impl['CONFIG_TFM_SLIH_API'] = 1
465
Kevin Peng5bc82d22021-10-19 11:18:40 +0800466 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800467 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800468 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100469
Kevin Peng5bc82d22021-10-19 11:18:40 +0800470 return context
Ken Liu861b0782021-05-22 13:15:08 +0800471
472def gen_per_partition_files(context):
473 """
474 Generate per-partition files
475
476 Parameters
477 ----------
478 context:
479 context contains partition infos
480 """
481
Kevin Peng5bc82d22021-10-19 11:18:40 +0800482 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800483 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800484 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800485
Kevin Peng5bc82d22021-10-19 11:18:40 +0800486 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
487 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
488 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800489
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500490 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800491
492 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800493 partition_context['manifest'] = one_partition['manifest']
494 partition_context['attr'] = one_partition['attr']
495 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
chesun0122abf0a2023-10-17 13:42:16 +0800496 partition_context['numbered_priority'] = one_partition['numbered_priority']
Ken Liu861b0782021-05-22 13:15:08 +0800497
BohdanHunko6cea95d2022-08-16 15:33:51 +0300498 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800499 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800500 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800501 if not os.path.exists(outfile_path):
502 os.makedirs(outfile_path)
503
Kevin Peng5bc82d22021-10-19 11:18:40 +0800504 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
505 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800506 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800507
Ken Liu861b0782021-05-22 13:15:08 +0800508 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800509 if not os.path.exists(intermediafile_path):
510 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800511 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
512 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800513 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800514
Ken Liu861b0782021-05-22 13:15:08 +0800515 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800516 if not os.path.exists(infofile_path):
517 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800518 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
519 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800520 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800521
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500522 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800523
Ken Liu861b0782021-05-22 13:15:08 +0800524def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800525 """
526 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800527
528 Parameters
529 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100530 gen_file_lists:
531 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800532 """
Kevin Peng655f2392019-11-27 16:33:02 +0800533 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800534
Raef Colesf42f0882020-07-10 10:01:58 +0100535 for f in gen_file_lists:
536 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800537 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800538 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800539
Kevin Peng655f2392019-11-27 16:33:02 +0800540 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000541 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800542 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000543 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800544 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800545
Kevin Peng4fade072021-10-26 17:57:50 +0800546 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800547
Ken Liu861b0782021-05-22 13:15:08 +0800548 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800549 if not os.path.exists(outfile_path):
550 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800551
Kevin Peng655f2392019-11-27 16:33:02 +0800552 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800553
Kevin Peng5bc82d22021-10-19 11:18:40 +0800554 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800555 outfile.write(template.render(context))
556 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800557
Kevin Pengce99e5d2021-11-09 18:06:53 +0800558def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800559 """
560 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800561 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800562 Valid stateless handle in service will be converted to an index. If the
563 stateless handle is set as "auto", or not set, framework will allocate a
564 valid index for the service.
565 Framework puts each service into a reordered stateless service list at
566 position of "index". Other unused positions are left None.
Ken Liu50948382022-10-27 12:45:53 +0800567
568 Keep the variable names start with upper case 'STATIC_HANDLE_' the same
569 as the preprocessors in C sources. This could easier the upcomping
570 modification when developer searches these definitions for modification.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800571 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800572
Kevin Pengc05319d2021-04-22 22:59:35 +0800573 collected_stateless_services = []
Ken Liu50948382022-10-27 12:45:53 +0800574 STATIC_HANDLE_NUM_LIMIT = 32
Mingyang Suna1ca6112021-01-11 11:34:59 +0800575
576 # Collect all stateless services first.
577 for partition in partitions:
578 # Skip the FF-M 1.0 partitions
579 if partition['manifest']['psa_framework_version'] < 1.1:
580 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800581
582 service_list = partition['manifest'].get('services', [])
583
584 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800585 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800586 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800587
Kevin Pengc05319d2021-04-22 22:59:35 +0800588 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800589 return []
590
Ken Liu50948382022-10-27 12:45:53 +0800591 if len(collected_stateless_services) > STATIC_HANDLE_NUM_LIMIT:
592 raise Exception('Stateless service numbers range exceed {number}.'.format(number=STATIC_HANDLE_NUM_LIMIT))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800593
594 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800595 Allocate an empty stateless service list to store services.
596 Use "handle - 1" as the index for service, since handle value starts from
597 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800598 """
Ken Liu50948382022-10-27 12:45:53 +0800599 reordered_stateless_services = [None] * STATIC_HANDLE_NUM_LIMIT
Kevin Pengc05319d2021-04-22 22:59:35 +0800600 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800601
Kevin Pengc05319d2021-04-22 22:59:35 +0800602 for service in collected_stateless_services:
603 # If not set, it is "auto" by default
604 if 'stateless_handle' not in service:
605 auto_alloc_services.append(service)
606 continue
607
Mingyang Sun4ecea992021-03-30 17:56:26 +0800608 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800609
Mingyang Sun4ecea992021-03-30 17:56:26 +0800610 # Fill in service list with specified stateless handle, otherwise skip
611 if isinstance(service_handle, int):
Ken Liu50948382022-10-27 12:45:53 +0800612 if service_handle < 1 or service_handle > STATIC_HANDLE_NUM_LIMIT:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800613 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800614 # Convert handle index to reordered service list index
615 service_handle = service_handle - 1
616
617 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800618 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800619 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800620 elif service_handle == 'auto':
621 auto_alloc_services.append(service)
622 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800623 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800624
Xinyu Zhangb2d4ed42023-02-14 11:43:16 +0800625 STATIC_HANDLE_IDX_BIT_WIDTH = 5
Kevin Pengce99e5d2021-11-09 18:06:53 +0800626 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
Ken Liu50948382022-10-27 12:45:53 +0800627 STATIC_HANDLE_INDICATOR_OFFSET = 30
628 STATIC_HANDLE_VER_OFFSET = 8
629 STATIC_HANDLE_VER_BIT_WIDTH = 8
Kevin Pengce99e5d2021-11-09 18:06:53 +0800630 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
631
Mingyang Sun4ecea992021-03-30 17:56:26 +0800632 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu50948382022-10-27 12:45:53 +0800633 for i in range(0, STATIC_HANDLE_NUM_LIMIT):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800634 service = reordered_stateless_services[i]
635
Kevin Pengc05319d2021-04-22 22:59:35 +0800636 if service == None and len(auto_alloc_services) > 0:
637 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800638
Mingyang Sun453ad402021-03-17 17:58:33 +0800639 """
640 Encode stateless flag and version into stateless handle
Mingyang Sun453ad402021-03-17 17:58:33 +0800641 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800642 stateless_handle_value = 0
643 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800644 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800645 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800646 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
647 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800648 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800649 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800650 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800651
Mingyang Sun4ecea992021-03-30 17:56:26 +0800652 reordered_stateless_services[i] = service
653
654 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800655
Kevin Peng655f2392019-11-27 16:33:02 +0800656def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000657 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
658 epilog='Note that environment variables in template files will be replaced with their values')
659
Kevin Peng655f2392019-11-27 16:33:02 +0800660 parser.add_argument('-o', '--outdir'
661 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800662 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800663 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800664 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800665
Kevin Peng5bc82d22021-10-19 11:18:40 +0800666 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100667 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800668 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100669 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800670 , metavar='manifest list'
671 , help='A list of Secure Partition manifest lists and their original paths.\n\
672 The manifest lists might be processed by CMake and\n\
673 the path might be different to the original one\n\
674 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800675
676 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100677 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800678 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100679 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800680 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700681 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800682
Kevin Pengfb1761b2022-05-12 12:11:31 +0800683 parser.add_argument('-c', '--config-files'
684 , nargs='+'
685 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800686 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800687 , metavar='config-files'
688 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800689
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500690 parser.add_argument('-q', '--quiet'
691 , dest='quiet'
692 , required=False
693 , default=False
694 , action='store_true'
695 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800696
697 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800698
Kevin Peng655f2392019-11-27 16:33:02 +0800699 return args
700
701ENV = Environment(
702 loader = TemplateLoader(),
703 autoescape = select_autoescape(['html', 'xml']),
704 lstrip_blocks = True,
705 trim_blocks = True,
706 keep_trailing_newline = True
707 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100708
Miklos Balint470919c2018-05-22 17:51:29 +0200709def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100710 """
711 The entry point of the script.
712
713 Generates the output files based on the templates and the manifests.
714 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800715
Kevin Peng655f2392019-11-27 16:33:02 +0800716 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800717
Kevin Peng655f2392019-11-27 16:33:02 +0800718 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800719
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500720 logging.basicConfig(format='%(message)s'
721 , level=logging.WARNING if args.quiet else logging.INFO)
722
Kevin Peng5bc82d22021-10-19 11:18:40 +0800723 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800724
Kevin Peng5bc82d22021-10-19 11:18:40 +0800725 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
726 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800727
Shawn Shana9ad1e02019-08-07 15:49:48 +0800728 """
Kevin Peng655f2392019-11-27 16:33:02 +0800729 Relative path to TF-M root folder is supported in the manifests
730 and default value of manifest list and generated file list are relative to TF-M root folder as well,
731 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800732 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800733 The script is located in <TF-M root folder>/tools, so sys.path[0]<location of the script>/.. is TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800734 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800735 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800736
Kevin Peng76c0c162022-02-09 22:49:06 +0800737 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800738 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100739
Edison Ai6e3f2a32019-06-11 15:29:05 +0800740 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800741 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200742
Kevin Peng655f2392019-11-27 16:33:02 +0800743 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800744
Ken Liu861b0782021-05-22 13:15:08 +0800745 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800746 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200747
Kevin Peng5bc82d22021-10-19 11:18:40 +0800748if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200749 main()