blob: 76dc2277fd7c1e339e7d60c7fdc3ef5e501afd8e [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 = []
Mate Toth-Pal36f21842018-11-08 16:12:51 +010036class TemplateLoader(BaseLoader):
37 """
38 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020039
Mate Toth-Pal36f21842018-11-08 16:12:51 +010040 An instance of this class is passed to the template engine. It is
41 responsible for reading the template file
42 """
43 def __init__(self):
44 pass
Miklos Balint470919c2018-05-22 17:51:29 +020045
Mate Toth-Pal36f21842018-11-08 16:12:51 +010046 def get_source(self, environment, template):
47 """
48 This function reads the template files.
49 For detailed documentation see:
50 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
51
52 Please note that this function always return 'false' as 'uptodate'
53 value, so the output file will always be generated.
54 """
55 if not os.path.isfile(template):
56 raise TemplateNotFound(template)
57 with open(template) as f:
58 source = f.read()
59 return source, template, False
60
Kevin Pengce99e5d2021-11-09 18:06:53 +080061def get_single_macro_def_from_file(file_name, macro_name):
62 """
63 This function parses the given file_name to get the definition of the given
64 C Macro (macro_name).
65
66 It assumes that the target Macro has no multiple definitions in different
67 build configurations.
68
69 It supports Macros defined in multi-line, for example:
70 #define SOME_MACRO \
71 the_macro_value
72
73 Inputs:
74 - file_name: the file to get the Macro from
75 - macro_name: the name of the Macro to get
76 Returns:
77 - The Macro definition with '()' stripped, or Exception if not found
78 """
79
80 with open(file_name, 'r') as f:
81 pattern = re.compile(r'#define\s+{}[\\\s]+.*'.format(macro_name))
82 result = pattern.findall(f.read())
83
84 if len(result) != 1:
85 raise Exception('{} not defined or has multiple definitions'.format(macro_name))
86
87 macro_def = result[0].split()[-1].strip('()')
88
89 return macro_def
90
Kevin Pengfb1761b2022-05-12 12:11:31 +080091def parse_configurations(file_paths):
92 """
93 Parses the given config files and return a dict whose key-values are build
94 configurations and their values.
95
96 Valid configurations should be in the format of:
97 "#define VAR [...]" in a single line.
98 The value of the config is optional.
99 """
100 configurations = {}
101
102 lines = []
103 for file in file_paths:
104 with open(file, 'r') as config_file:
105 lines += config_file.readlines()
106
107 for line in lines:
108 if not line.startswith('#define'):
109 continue
110
111 line = line.rstrip('\r\n')
112 line_items = line.split(maxsplit=2)
113 if len(line_items) == 3:
114 configurations[line_items[1]] = line_items[2]
115 elif len(line_items) == 2:
116 configurations[line_items[1]] = ''
117
118 logging.debug(configurations)
119
120 return configurations
121
Kevin Peng5c3fee72022-02-16 22:25:22 +0800122def manifest_validation(manifest, pid):
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800123 """
124 This function validates FF-M compliance for partition manifest, and sets
125 default values for optional attributes.
Kevin Pengce99e5d2021-11-09 18:06:53 +0800126 The validation is skipped for TF-M specific Partitions (PID < TFM_PID_BASE).
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800127 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800128
Kevin Peng5c3fee72022-02-16 22:25:22 +0800129 service_list = manifest.get('services', [])
130 irq_list = manifest.get('irqs', [])
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800131
Kevin Peng5c3fee72022-02-16 22:25:22 +0800132 # "psa_framework_version" validation
133 if manifest['psa_framework_version'] not in [1.0, 1.1]:
134 raise Exception('Invalid psa_framework_version of {}'.format(manifest['name']))
135
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700136 # "type" validation
Kevin Peng5c3fee72022-02-16 22:25:22 +0800137 if manifest['type'] not in ['PSA-ROT', 'APPLICATION-ROT']:
138 raise Exception('Invalid type of {}'.format(manifest['name']))
139
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700140 # "priority" validation
141 if manifest['priority'] not in ['HIGH', 'NORMAL', 'LOW']:
142 raise Exception('Invalid priority of {}'.format(manifest['name']))
143
Chris Brandc422cdd2022-07-21 13:32:47 -0700144 if 'ns_agent' not in manifest:
145 manifest['ns_agent'] = False
146
Kevin Peng5c3fee72022-02-16 22:25:22 +0800147 # Every PSA Partition must have at least either a secure service or an IRQ
Kevin Pengce99e5d2021-11-09 18:06:53 +0800148 if (pid == None or pid >= TFM_PID_BASE) \
Kevin Peng8849b6a2021-11-09 14:17:35 +0800149 and len(service_list) == 0 and len(irq_list) == 0:
150 raise Exception('{} must declare at least either a secure service or an IRQ!'
Kevin Peng5c3fee72022-02-16 22:25:22 +0800151 .format(manifest['name']))
152
153 if manifest['psa_framework_version'] == 1.0:
154 # For 1.0 Partition, the model is IPC
155 manifest['model'] = 'IPC'
156
157 # "model" validation:
158 model = manifest.get('model', None)
159 if model == None:
160 raise Exception('{} is missing the "model" attribute'.format(manifest['name']))
161
162 # Assign a unified 'entry' for templates
163 if model == 'IPC':
164 # entry_point is mandatory for IPC Partitions
165 if 'entry_point' not in manifest.keys():
166 raise Exception('{} is missing the "entry_point" attribute'.format(manifest['name']))
167 manifest['entry'] = manifest['entry_point']
168 elif model == 'SFN':
169 if 'entry_init' in manifest.keys():
170 manifest['entry'] = manifest['entry_init']
171 else:
172 manifest['entry'] = 0
173 else:
174 raise Exception('Invalid "model" of {}'.format(manifest['name']))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800175
176 # Service FF-M manifest validation
177 for service in service_list:
Kevin Peng5c3fee72022-02-16 22:25:22 +0800178 if manifest['psa_framework_version'] == 1.0:
179 service['connection_based'] = True
180 elif 'connection_based' not in service:
181 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
182
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800183 if 'version' not in service.keys():
184 service['version'] = 1
185 if 'version_policy' not in service.keys():
Kevin Peng5bc82d22021-10-19 11:18:40 +0800186 service['version_policy'] = 'STRICT'
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800187
Kevin Peng5bc82d22021-10-19 11:18:40 +0800188 # SID duplication check
189 if service['sid'] in sid_list:
190 raise Exception('Service ID: {} has duplications!'.format(service['sid']))
191 else:
192 sid_list.append(service['sid'])
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100193
Kevin Peng5c3fee72022-02-16 22:25:22 +0800194 return manifest
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800195
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800196def check_circular_dependency(partitions, service_partition_map):
197 """
198 This function detects if there is any circular partition dependency chain.
199 If a circular dependency is detected, the script exits with error.
200
201 Inputs:
202 - partitions: dict of partition manifests
203 - service_partition_map: map between services and their owner Partitions
204 """
205
206 dependency_table = {}
207 for partition in partitions:
208 manifest = partition['manifest']
209 dependencies = manifest['dependencies'].copy() \
210 if 'dependencies' in manifest else []
211 dependencies += manifest['weak_dependencies'].copy() \
212 if 'weak_dependencies' in manifest else []
213 dependency_table[manifest['name']] = {
214 'dependencies': [service_partition_map[dependency]
215 for dependency in dependencies
216 if dependency in service_partition_map],
217 'validated': False
218 }
219
220 for partition in dependency_table.keys():
221 validate_dependency_chain(partition, dependency_table, [])
222
223def validate_dependency_chain(partition,
224 dependency_table,
225 dependency_chain):
226 """
227 Recursively validate if the given partition and its dependencies
228 have a circular dependency with the given dependency_chain.
229 Exit with error code once any circular is detected.
230
231 Inputs:
232 - partition: next partition to be checked
233 - dependency_table: dict of partitions and their dependencies
234 - dependency_chain: list of dependencies in current chain
235 """
236
237 dependency_chain.append(partition)
238 if partition in dependency_chain[:-1]:
239 logging.error(
240 'Circular dependency exists in chain: {}'.format(
241 ', '.join(dependency_chain)))
242 exit(1)
243 for dependency in dependency_table[partition]['dependencies']:
244 if dependency_table[dependency]['validated']:
245 continue
246 validate_dependency_chain(dependency, dependency_table, dependency_chain)
247 dependency_table[partition]['validated'] = True
248
Kevin Peng93efad02022-08-01 17:58:13 +0800249def manifest_attribute_to_int(manifest, attribute, configs):
250 """
251 This method tries to convert the value of the given `attribute` in the given
252 `manifest` to an integer.
253 If the value is a decimal/hexadecimal int, return it directly.
254 Otherwise, treat it as a configuration and find the value in the given `configs`.
255 If the configuration is not found, exit script with error.
256 """
257
258 value = manifest[attribute]
259 try:
260 # base 16 works for both decimal and hexadecimal
261 int(value, base=16)
262 except ValueError:
263 # Not an int, find the value in configs
264 if value not in configs.keys():
265 logging.error('{} is not defined in configurations'.format(value))
266 exit(1)
267
268 value = configs[value]
269
270 return value
271
Kevin Pengfb1761b2022-05-12 12:11:31 +0800272def process_partition_manifests(manifest_lists, configs):
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100273 """
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800274 Parse the input manifest lists, check if manifest settings are valid,
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700275 generate the data base for generated files
Kevin Peng655f2392019-11-27 16:33:02 +0800276 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100277
278 Parameters
279 ----------
Kevin Peng65064c52021-10-27 17:12:17 +0800280 manifest_lists:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800281 A list of Secure Partition manifest lists
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100282
283 Returns
284 -------
Kevin Peng5bc82d22021-10-19 11:18:40 +0800285 The manifest data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +0800286 """
Kevin Peng655f2392019-11-27 16:33:02 +0800287
Kevin Peng5bc82d22021-10-19 11:18:40 +0800288 context = {}
289
Ken Liu861b0782021-05-22 13:15:08 +0800290 partition_list = []
Kevin Peng65064c52021-10-27 17:12:17 +0800291 all_manifests = []
Kevin Peng56b0ea62021-10-18 11:32:57 +0800292 pid_list = []
293 no_pid_manifest_idx = []
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800294 service_partition_map = {}
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800295 partition_statistics = {
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800296 'connection_based_srv_num': 0,
Kevin Peng47c26ec2022-03-11 11:49:52 +0800297 'ipc_partitions': [],
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800298 'flih_num': 0,
299 'slih_num': 0
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800300 }
Kevin Peng9f1a7542022-02-07 16:32:27 +0800301 config_impl = {
302 'CONFIG_TFM_SPM_BACKEND_SFN' : '0',
303 'CONFIG_TFM_SPM_BACKEND_IPC' : '0',
304 'CONFIG_TFM_PSA_API_SFN_CALL' : '0',
305 'CONFIG_TFM_PSA_API_CROSS_CALL' : '0',
306 'CONFIG_TFM_PSA_API_SUPERVISOR_CALL' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800307 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
308 'CONFIG_TFM_FLIH_API' : '0',
309 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800310 }
Kevin Peng655f2392019-11-27 16:33:02 +0800311
Kevin Pengfb1761b2022-05-12 12:11:31 +0800312 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
313 backend = configs['CONFIG_TFM_SPM_BACKEND']
314
Kevin Peng65064c52021-10-27 17:12:17 +0800315 # Get all the manifests information as a dictionary
316 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800317 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500318 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800319 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800320
Kevin Peng65064c52021-10-27 17:12:17 +0800321 # The manifest list file generated by configure_file()
322 with open(item) as manifest_list_yaml_file:
323 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
324 for dict in manifest_dic:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800325 # Replace environment variables in the manifest path and convert to absolute path.
326 # If it's already abspath, the path will not be changed.
327 manifest_path = os.path.join(os.path.dirname(item), # path of manifest list
328 os.path.expandvars(dict['manifest']))\
329 .replace('\\', '/')
330 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800331 all_manifests.append(dict)
332
Chris Brand4b69fcf2022-06-06 09:37:49 -0700333 logging.info("------------ Display partition configuration - start ------------")
334
Kevin Peng65064c52021-10-27 17:12:17 +0800335 # Parse the manifests
336 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800337 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
338 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800339 is_enabled = ''
340
341 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800342 if manifest_item['conditional'] not in configs.keys():
343 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
344 exit(1)
345 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800346 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800347 # Partitions without 'conditional' is always on
348 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800349
350 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300351 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800352 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700353 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300354 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700355 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800356 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
357 'Please set to one of {} or {}, case-insensitive.'\
358 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300359 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800360 valid_enabled_conditions, valid_disabled_conditions))
361
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800362 # Check if partition ID is manually set
363 if 'pid' not in manifest_item.keys():
364 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800365 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800366 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800367 pid = manifest_item['pid']
368
369 # Check if partition ID is duplicated
370 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100371 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800372 else:
373 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800374
Kevin Pengfb1761b2022-05-12 12:11:31 +0800375 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800376 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800377 manifest = yaml.safe_load(manifest_file)
378 if manifest.get('model', None) == 'dual':
379 # If a Partition supports both models, it can set the "model" to "backend".
380 # The actual model used follows the backend being used.
381 manifest['model'] = backend
382 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800383
Kevin Pengce99e5d2021-11-09 18:06:53 +0800384 if pid == None or pid >= TFM_PID_BASE:
Kevin Pengd08f3ba2021-11-18 15:18:56 +0800385 # Count the number of IPC/SFN partitions
Kevin Peng47c26ec2022-03-11 11:49:52 +0800386 if manifest['model'] == 'IPC':
387 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800388
Kevin Peng93efad02022-08-01 17:58:13 +0800389 # Convert stack_size and heap_size to int. They might be configurations.
390 manifest['stack_size'] = manifest_attribute_to_int(manifest, 'stack_size', configs)
391
392 if 'heap_size' in manifest.keys():
393 manifest['heap_size'] = manifest_attribute_to_int(manifest, 'heap_size', configs)
394
Kevin Peng5c3fee72022-02-16 22:25:22 +0800395 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
396 # number (0) when there are no services.
397 srv_idx = -1
398 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800399 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800400 if manifest['model'] == 'IPC':
401 # Assign signal value, the first 4 bits are reserved by FF-M
402 service['signal_value'] = (1 << (srv_idx + 4))
403 else:
404 # Signals of SFN Partitions are SPM internal only, does not
405 # need to reserve 4 bits.
406 service['signal_value'] = (1 << srv_idx)
407 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800408 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800409 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800410
Kevin Peng5c3fee72022-02-16 22:25:22 +0800411 # Set initial value to -1 to make (irq + 1) reflect the correct
412 # number (0) when there are no irqs.
413 irq_idx = -1
414 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
415 # Assign signal value, from the most significant bit
416 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800417 if irq.get('handling', None) == 'FLIH':
418 partition_statistics['flih_num'] += 1
419 else:
420 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800421 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
422
423 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
424 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
425 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800426
Kevin Peng65064c52021-10-27 17:12:17 +0800427 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800428
Kevin Peng4fade072021-10-26 17:57:50 +0800429 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800430 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800431 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800432 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800433
Kevin Peng5bc82d22021-10-19 11:18:40 +0800434 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
435 '{}.h'.format(manifest_out_basename))\
436 .replace('\\', '/')
437 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
438 'intermedia_{}.c'.format(manifest_out_basename))\
439 .replace('\\', '/')
440 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
441 'load_info_{}.c'.format(manifest_out_basename))\
442 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800443 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800444
Kevin Peng5bc82d22021-10-19 11:18:40 +0800445 partition_list.append({'manifest': manifest, 'attr': manifest_item,
446 'manifest_out_basename': manifest_out_basename,
447 'header_file': manifest_head_file,
448 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800449 'loadinfo_file': load_info_file,
450 'output_dir':output_dir})
Ken Liu861b0782021-05-22 13:15:08 +0800451
Chris Brand4b69fcf2022-06-06 09:37:49 -0700452 logging.info("------------ Display partition configuration - end ------------")
453
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800454 check_circular_dependency(partition_list, service_partition_map)
455
Kevin Peng56b0ea62021-10-18 11:32:57 +0800456 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800457 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800458 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800459 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800460 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800461 pid_list.append(pid)
462
Kevin Peng9f1a7542022-02-07 16:32:27 +0800463 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800464 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800465 if len(partition_statistics['ipc_partitions']) > 0:
466 logging.error('SFN backend does not support IPC Partitions:')
467 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800468 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800469
470 if isolation_level > 1:
471 logging.error('SFN backend does not support high isolation levels.')
472 exit(1)
473
Kevin Peng9f1a7542022-02-07 16:32:27 +0800474 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
475 config_impl['CONFIG_TFM_PSA_API_SFN_CALL'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800476 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800477 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
478 if isolation_level > 1:
479 config_impl['CONFIG_TFM_PSA_API_SUPERVISOR_CALL'] = '1'
480 else:
481 config_impl['CONFIG_TFM_PSA_API_CROSS_CALL'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800482
483 if partition_statistics['connection_based_srv_num'] > 0:
484 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
485
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800486 if partition_statistics['flih_num'] > 0:
487 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200488 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800489 config_impl['CONFIG_TFM_SLIH_API'] = 1
490
Kevin Peng5bc82d22021-10-19 11:18:40 +0800491 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800492 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800493 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100494
Kevin Peng5bc82d22021-10-19 11:18:40 +0800495 return context
Ken Liu861b0782021-05-22 13:15:08 +0800496
497def gen_per_partition_files(context):
498 """
499 Generate per-partition files
500
501 Parameters
502 ----------
503 context:
504 context contains partition infos
505 """
506
Kevin Peng5bc82d22021-10-19 11:18:40 +0800507 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800508 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800509 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800510
Kevin Peng5bc82d22021-10-19 11:18:40 +0800511 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
512 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
513 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800514
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500515 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800516
517 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800518 partition_context['manifest'] = one_partition['manifest']
519 partition_context['attr'] = one_partition['attr']
520 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
Ken Liu861b0782021-05-22 13:15:08 +0800521
BohdanHunko6cea95d2022-08-16 15:33:51 +0300522 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800523 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800524 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800525 if not os.path.exists(outfile_path):
526 os.makedirs(outfile_path)
527
Kevin Peng5bc82d22021-10-19 11:18:40 +0800528 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
529 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800530 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800531
Ken Liu861b0782021-05-22 13:15:08 +0800532 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800533 if not os.path.exists(intermediafile_path):
534 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800535 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
536 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800537 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800538
Ken Liu861b0782021-05-22 13:15:08 +0800539 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800540 if not os.path.exists(infofile_path):
541 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800542 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
543 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800544 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800545
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500546 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800547
Ken Liu861b0782021-05-22 13:15:08 +0800548def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800549 """
550 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800551
552 Parameters
553 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100554 gen_file_lists:
555 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800556 """
Kevin Peng655f2392019-11-27 16:33:02 +0800557 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800558
Raef Colesf42f0882020-07-10 10:01:58 +0100559 for f in gen_file_lists:
560 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800561 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800562 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800563
Kevin Peng655f2392019-11-27 16:33:02 +0800564 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000565 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800566 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000567 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800568 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800569
Kevin Peng4fade072021-10-26 17:57:50 +0800570 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800571
Ken Liu861b0782021-05-22 13:15:08 +0800572 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800573 if not os.path.exists(outfile_path):
574 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800575
Kevin Peng655f2392019-11-27 16:33:02 +0800576 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800577
Kevin Peng5bc82d22021-10-19 11:18:40 +0800578 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800579 outfile.write(template.render(context))
580 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800581
Kevin Pengce99e5d2021-11-09 18:06:53 +0800582def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800583 """
584 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800585 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800586 Valid stateless handle in service will be converted to an index. If the
587 stateless handle is set as "auto", or not set, framework will allocate a
588 valid index for the service.
589 Framework puts each service into a reordered stateless service list at
590 position of "index". Other unused positions are left None.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800591 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800592
593 STATIC_HANDLE_CONFIG_FILE = 'secure_fw/spm/cmsis_psa/spm_ipc.h'
594
Kevin Pengc05319d2021-04-22 22:59:35 +0800595 collected_stateless_services = []
Kevin Pengce99e5d2021-11-09 18:06:53 +0800596 stateless_index_max_num = \
597 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_NUM_LIMIT'), base = 10)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800598
599 # Collect all stateless services first.
600 for partition in partitions:
601 # Skip the FF-M 1.0 partitions
602 if partition['manifest']['psa_framework_version'] < 1.1:
603 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800604
605 service_list = partition['manifest'].get('services', [])
606
607 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800608 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800609 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800610
Kevin Pengc05319d2021-04-22 22:59:35 +0800611 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800612 return []
613
Ken Liu861b0782021-05-22 13:15:08 +0800614 if len(collected_stateless_services) > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800615 raise Exception('Stateless service numbers range exceed {number}.'.format(number=stateless_index_max_num))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800616
617 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800618 Allocate an empty stateless service list to store services.
619 Use "handle - 1" as the index for service, since handle value starts from
620 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800621 """
Ken Liu861b0782021-05-22 13:15:08 +0800622 reordered_stateless_services = [None] * stateless_index_max_num
Kevin Pengc05319d2021-04-22 22:59:35 +0800623 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800624
Kevin Pengc05319d2021-04-22 22:59:35 +0800625 for service in collected_stateless_services:
626 # If not set, it is "auto" by default
627 if 'stateless_handle' not in service:
628 auto_alloc_services.append(service)
629 continue
630
Mingyang Sun4ecea992021-03-30 17:56:26 +0800631 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800632
Mingyang Sun4ecea992021-03-30 17:56:26 +0800633 # Fill in service list with specified stateless handle, otherwise skip
634 if isinstance(service_handle, int):
Ken Liu861b0782021-05-22 13:15:08 +0800635 if service_handle < 1 or service_handle > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800636 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800637 # Convert handle index to reordered service list index
638 service_handle = service_handle - 1
639
640 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800641 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800642 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800643 elif service_handle == 'auto':
644 auto_alloc_services.append(service)
645 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800646 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800647
Kevin Pengce99e5d2021-11-09 18:06:53 +0800648 STATIC_HANDLE_IDX_BIT_WIDTH = \
649 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_IDX_BIT_WIDTH'), base = 10)
650 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
651
652 STATIC_HANDLE_INDICATOR_OFFSET = \
653 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_INDICATOR_OFFSET'), base = 10)
654
655 STATIC_HANDLE_VER_OFFSET = \
656 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_OFFSET'), base = 10)
657
658 STATIC_HANDLE_VER_BIT_WIDTH = \
659 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_BIT_WIDTH'), base = 10)
660 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
661
Mingyang Sun4ecea992021-03-30 17:56:26 +0800662 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu861b0782021-05-22 13:15:08 +0800663 for i in range(0, stateless_index_max_num):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800664 service = reordered_stateless_services[i]
665
Kevin Pengc05319d2021-04-22 22:59:35 +0800666 if service == None and len(auto_alloc_services) > 0:
667 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800668
Mingyang Sun453ad402021-03-17 17:58:33 +0800669 """
670 Encode stateless flag and version into stateless handle
Kevin Pengce99e5d2021-11-09 18:06:53 +0800671 Check STATIC_HANDLE_CONFIG_FILE for details
Mingyang Sun453ad402021-03-17 17:58:33 +0800672 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800673 stateless_handle_value = 0
674 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800675 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800676 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800677 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
678 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800679 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800680 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800681 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800682
Mingyang Sun4ecea992021-03-30 17:56:26 +0800683 reordered_stateless_services[i] = service
684
685 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800686
Kevin Peng655f2392019-11-27 16:33:02 +0800687def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000688 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
689 epilog='Note that environment variables in template files will be replaced with their values')
690
Kevin Peng655f2392019-11-27 16:33:02 +0800691 parser.add_argument('-o', '--outdir'
692 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800693 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800694 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800695 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800696
Kevin Peng5bc82d22021-10-19 11:18:40 +0800697 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100698 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800699 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100700 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800701 , metavar='manifest list'
702 , help='A list of Secure Partition manifest lists and their original paths.\n\
703 The manifest lists might be processed by CMake and\n\
704 the path might be different to the original one\n\
705 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800706
707 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100708 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800709 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100710 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800711 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700712 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800713
Kevin Pengfb1761b2022-05-12 12:11:31 +0800714 parser.add_argument('-c', '--config-files'
715 , nargs='+'
716 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800717 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800718 , metavar='config-files'
719 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800720
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500721 parser.add_argument('-q', '--quiet'
722 , dest='quiet'
723 , required=False
724 , default=False
725 , action='store_true'
726 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800727
728 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800729
Kevin Peng655f2392019-11-27 16:33:02 +0800730 return args
731
732ENV = Environment(
733 loader = TemplateLoader(),
734 autoescape = select_autoescape(['html', 'xml']),
735 lstrip_blocks = True,
736 trim_blocks = True,
737 keep_trailing_newline = True
738 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100739
Miklos Balint470919c2018-05-22 17:51:29 +0200740def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100741 """
742 The entry point of the script.
743
744 Generates the output files based on the templates and the manifests.
745 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800746
Kevin Peng655f2392019-11-27 16:33:02 +0800747 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800748
Kevin Peng655f2392019-11-27 16:33:02 +0800749 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800750
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500751 logging.basicConfig(format='%(message)s'
752 , level=logging.WARNING if args.quiet else logging.INFO)
753
Kevin Peng5bc82d22021-10-19 11:18:40 +0800754 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800755
Kevin Peng5bc82d22021-10-19 11:18:40 +0800756 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
757 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800758
Shawn Shana9ad1e02019-08-07 15:49:48 +0800759 """
Kevin Peng655f2392019-11-27 16:33:02 +0800760 Relative path to TF-M root folder is supported in the manifests
761 and default value of manifest list and generated file list are relative to TF-M root folder as well,
762 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800763 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800764 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 +0800765 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800766 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800767
Kevin Peng76c0c162022-02-09 22:49:06 +0800768 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800769 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100770
Edison Ai6e3f2a32019-06-11 15:29:05 +0800771 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800772 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200773
Kevin Peng655f2392019-11-27 16:33:02 +0800774 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800775
Ken Liu861b0782021-05-22 13:15:08 +0800776 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800777 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200778
Kevin Peng5bc82d22021-10-19 11:18:40 +0800779if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200780 main()