blob: 2aa1279c5f61e11e71fcfef5ce4f456ff162953c [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': [],
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800298 'mmio_region_num': 0,
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800299 'flih_num': 0,
300 'slih_num': 0
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800301 }
Kevin Peng9f1a7542022-02-07 16:32:27 +0800302 config_impl = {
303 'CONFIG_TFM_SPM_BACKEND_SFN' : '0',
304 'CONFIG_TFM_SPM_BACKEND_IPC' : '0',
305 'CONFIG_TFM_PSA_API_SFN_CALL' : '0',
306 'CONFIG_TFM_PSA_API_CROSS_CALL' : '0',
307 'CONFIG_TFM_PSA_API_SUPERVISOR_CALL' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800308 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800309 'CONFIG_TFM_MMIO_REGION_ENABLE' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800310 'CONFIG_TFM_FLIH_API' : '0',
311 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800312 }
Kevin Peng655f2392019-11-27 16:33:02 +0800313
Kevin Pengfb1761b2022-05-12 12:11:31 +0800314 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
315 backend = configs['CONFIG_TFM_SPM_BACKEND']
316
Kevin Peng65064c52021-10-27 17:12:17 +0800317 # Get all the manifests information as a dictionary
318 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800319 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500320 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800321 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800322
Kevin Peng65064c52021-10-27 17:12:17 +0800323 # The manifest list file generated by configure_file()
324 with open(item) as manifest_list_yaml_file:
325 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
326 for dict in manifest_dic:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800327 # Replace environment variables in the manifest path and convert to absolute path.
328 # If it's already abspath, the path will not be changed.
329 manifest_path = os.path.join(os.path.dirname(item), # path of manifest list
330 os.path.expandvars(dict['manifest']))\
331 .replace('\\', '/')
332 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800333 all_manifests.append(dict)
334
Chris Brand4b69fcf2022-06-06 09:37:49 -0700335 logging.info("------------ Display partition configuration - start ------------")
336
Kevin Peng65064c52021-10-27 17:12:17 +0800337 # Parse the manifests
338 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800339 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
340 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800341 is_enabled = ''
342
343 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800344 if manifest_item['conditional'] not in configs.keys():
345 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
346 exit(1)
347 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800348 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800349 # Partitions without 'conditional' is always on
350 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800351
352 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300353 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800354 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700355 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300356 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700357 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800358 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
359 'Please set to one of {} or {}, case-insensitive.'\
360 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300361 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800362 valid_enabled_conditions, valid_disabled_conditions))
363
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800364 # Check if partition ID is manually set
365 if 'pid' not in manifest_item.keys():
366 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800367 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800368 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800369 pid = manifest_item['pid']
370
371 # Check if partition ID is duplicated
372 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100373 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800374 else:
375 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800376
Kevin Pengfb1761b2022-05-12 12:11:31 +0800377 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800378 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800379 manifest = yaml.safe_load(manifest_file)
380 if manifest.get('model', None) == 'dual':
381 # If a Partition supports both models, it can set the "model" to "backend".
382 # The actual model used follows the backend being used.
383 manifest['model'] = backend
384 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800385
Kevin Pengce99e5d2021-11-09 18:06:53 +0800386 if pid == None or pid >= TFM_PID_BASE:
Kevin Pengd08f3ba2021-11-18 15:18:56 +0800387 # Count the number of IPC/SFN partitions
Kevin Peng47c26ec2022-03-11 11:49:52 +0800388 if manifest['model'] == 'IPC':
389 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800390
Kevin Peng93efad02022-08-01 17:58:13 +0800391 # Convert stack_size and heap_size to int. They might be configurations.
392 manifest['stack_size'] = manifest_attribute_to_int(manifest, 'stack_size', configs)
393
394 if 'heap_size' in manifest.keys():
395 manifest['heap_size'] = manifest_attribute_to_int(manifest, 'heap_size', configs)
396
Kevin Peng5c3fee72022-02-16 22:25:22 +0800397 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
398 # number (0) when there are no services.
399 srv_idx = -1
400 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800401 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800402 if manifest['model'] == 'IPC':
403 # Assign signal value, the first 4 bits are reserved by FF-M
404 service['signal_value'] = (1 << (srv_idx + 4))
405 else:
406 # Signals of SFN Partitions are SPM internal only, does not
407 # need to reserve 4 bits.
408 service['signal_value'] = (1 << srv_idx)
409 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800410 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800411 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800412
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800413 # Calculate the number of mmio region
414 mmio_region_list = manifest.get('mmio_regions', [])
415 partition_statistics['mmio_region_num'] += len(mmio_region_list)
416
Kevin Peng5c3fee72022-02-16 22:25:22 +0800417 # Set initial value to -1 to make (irq + 1) reflect the correct
418 # number (0) when there are no irqs.
419 irq_idx = -1
420 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
421 # Assign signal value, from the most significant bit
422 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800423 if irq.get('handling', None) == 'FLIH':
424 partition_statistics['flih_num'] += 1
425 else:
426 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800427 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
428
429 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
430 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
431 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800432
Kevin Peng65064c52021-10-27 17:12:17 +0800433 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800434
Kevin Peng4fade072021-10-26 17:57:50 +0800435 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800436 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800437 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800438 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800439
Kevin Peng5bc82d22021-10-19 11:18:40 +0800440 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
441 '{}.h'.format(manifest_out_basename))\
442 .replace('\\', '/')
443 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
444 'intermedia_{}.c'.format(manifest_out_basename))\
445 .replace('\\', '/')
446 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
447 'load_info_{}.c'.format(manifest_out_basename))\
448 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800449 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800450
Kevin Peng5bc82d22021-10-19 11:18:40 +0800451 partition_list.append({'manifest': manifest, 'attr': manifest_item,
452 'manifest_out_basename': manifest_out_basename,
453 'header_file': manifest_head_file,
454 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800455 'loadinfo_file': load_info_file,
456 'output_dir':output_dir})
Ken Liu861b0782021-05-22 13:15:08 +0800457
Chris Brand4b69fcf2022-06-06 09:37:49 -0700458 logging.info("------------ Display partition configuration - end ------------")
459
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800460 check_circular_dependency(partition_list, service_partition_map)
461
Kevin Peng56b0ea62021-10-18 11:32:57 +0800462 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800463 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800464 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800465 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800466 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800467 pid_list.append(pid)
468
Kevin Peng9f1a7542022-02-07 16:32:27 +0800469 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800470 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800471 if len(partition_statistics['ipc_partitions']) > 0:
472 logging.error('SFN backend does not support IPC Partitions:')
473 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800474 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800475
476 if isolation_level > 1:
477 logging.error('SFN backend does not support high isolation levels.')
478 exit(1)
479
Kevin Peng9f1a7542022-02-07 16:32:27 +0800480 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
481 config_impl['CONFIG_TFM_PSA_API_SFN_CALL'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800482 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800483 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
484 if isolation_level > 1:
485 config_impl['CONFIG_TFM_PSA_API_SUPERVISOR_CALL'] = '1'
486 else:
487 config_impl['CONFIG_TFM_PSA_API_CROSS_CALL'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800488
489 if partition_statistics['connection_based_srv_num'] > 0:
490 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
491
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800492 if partition_statistics['mmio_region_num'] > 0:
493 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
494
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800495 if partition_statistics['flih_num'] > 0:
496 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200497 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800498 config_impl['CONFIG_TFM_SLIH_API'] = 1
499
Kevin Peng5bc82d22021-10-19 11:18:40 +0800500 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800501 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800502 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100503
Kevin Peng5bc82d22021-10-19 11:18:40 +0800504 return context
Ken Liu861b0782021-05-22 13:15:08 +0800505
506def gen_per_partition_files(context):
507 """
508 Generate per-partition files
509
510 Parameters
511 ----------
512 context:
513 context contains partition infos
514 """
515
Kevin Peng5bc82d22021-10-19 11:18:40 +0800516 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800517 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800518 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800519
Kevin Peng5bc82d22021-10-19 11:18:40 +0800520 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
521 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
522 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800523
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500524 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800525
526 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800527 partition_context['manifest'] = one_partition['manifest']
528 partition_context['attr'] = one_partition['attr']
529 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
Ken Liu861b0782021-05-22 13:15:08 +0800530
BohdanHunko6cea95d2022-08-16 15:33:51 +0300531 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800532 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800533 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800534 if not os.path.exists(outfile_path):
535 os.makedirs(outfile_path)
536
Kevin Peng5bc82d22021-10-19 11:18:40 +0800537 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
538 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800539 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800540
Ken Liu861b0782021-05-22 13:15:08 +0800541 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800542 if not os.path.exists(intermediafile_path):
543 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800544 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
545 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800546 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800547
Ken Liu861b0782021-05-22 13:15:08 +0800548 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800549 if not os.path.exists(infofile_path):
550 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800551 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
552 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800553 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800554
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500555 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800556
Ken Liu861b0782021-05-22 13:15:08 +0800557def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800558 """
559 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800560
561 Parameters
562 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100563 gen_file_lists:
564 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800565 """
Kevin Peng655f2392019-11-27 16:33:02 +0800566 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800567
Raef Colesf42f0882020-07-10 10:01:58 +0100568 for f in gen_file_lists:
569 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800570 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800571 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800572
Kevin Peng655f2392019-11-27 16:33:02 +0800573 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000574 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800575 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000576 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800577 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800578
Kevin Peng4fade072021-10-26 17:57:50 +0800579 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800580
Ken Liu861b0782021-05-22 13:15:08 +0800581 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800582 if not os.path.exists(outfile_path):
583 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800584
Kevin Peng655f2392019-11-27 16:33:02 +0800585 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800586
Kevin Peng5bc82d22021-10-19 11:18:40 +0800587 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800588 outfile.write(template.render(context))
589 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800590
Kevin Pengce99e5d2021-11-09 18:06:53 +0800591def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800592 """
593 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800594 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800595 Valid stateless handle in service will be converted to an index. If the
596 stateless handle is set as "auto", or not set, framework will allocate a
597 valid index for the service.
598 Framework puts each service into a reordered stateless service list at
599 position of "index". Other unused positions are left None.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800600 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800601
602 STATIC_HANDLE_CONFIG_FILE = 'secure_fw/spm/cmsis_psa/spm_ipc.h'
603
Kevin Pengc05319d2021-04-22 22:59:35 +0800604 collected_stateless_services = []
Kevin Pengce99e5d2021-11-09 18:06:53 +0800605 stateless_index_max_num = \
606 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_NUM_LIMIT'), base = 10)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800607
608 # Collect all stateless services first.
609 for partition in partitions:
610 # Skip the FF-M 1.0 partitions
611 if partition['manifest']['psa_framework_version'] < 1.1:
612 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800613
614 service_list = partition['manifest'].get('services', [])
615
616 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800617 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800618 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800619
Kevin Pengc05319d2021-04-22 22:59:35 +0800620 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800621 return []
622
Ken Liu861b0782021-05-22 13:15:08 +0800623 if len(collected_stateless_services) > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800624 raise Exception('Stateless service numbers range exceed {number}.'.format(number=stateless_index_max_num))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800625
626 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800627 Allocate an empty stateless service list to store services.
628 Use "handle - 1" as the index for service, since handle value starts from
629 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800630 """
Ken Liu861b0782021-05-22 13:15:08 +0800631 reordered_stateless_services = [None] * stateless_index_max_num
Kevin Pengc05319d2021-04-22 22:59:35 +0800632 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800633
Kevin Pengc05319d2021-04-22 22:59:35 +0800634 for service in collected_stateless_services:
635 # If not set, it is "auto" by default
636 if 'stateless_handle' not in service:
637 auto_alloc_services.append(service)
638 continue
639
Mingyang Sun4ecea992021-03-30 17:56:26 +0800640 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800641
Mingyang Sun4ecea992021-03-30 17:56:26 +0800642 # Fill in service list with specified stateless handle, otherwise skip
643 if isinstance(service_handle, int):
Ken Liu861b0782021-05-22 13:15:08 +0800644 if service_handle < 1 or service_handle > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800645 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800646 # Convert handle index to reordered service list index
647 service_handle = service_handle - 1
648
649 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800650 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800651 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800652 elif service_handle == 'auto':
653 auto_alloc_services.append(service)
654 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800655 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800656
Kevin Pengce99e5d2021-11-09 18:06:53 +0800657 STATIC_HANDLE_IDX_BIT_WIDTH = \
658 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_IDX_BIT_WIDTH'), base = 10)
659 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
660
661 STATIC_HANDLE_INDICATOR_OFFSET = \
662 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_INDICATOR_OFFSET'), base = 10)
663
664 STATIC_HANDLE_VER_OFFSET = \
665 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_OFFSET'), base = 10)
666
667 STATIC_HANDLE_VER_BIT_WIDTH = \
668 int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_BIT_WIDTH'), base = 10)
669 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
670
Mingyang Sun4ecea992021-03-30 17:56:26 +0800671 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu861b0782021-05-22 13:15:08 +0800672 for i in range(0, stateless_index_max_num):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800673 service = reordered_stateless_services[i]
674
Kevin Pengc05319d2021-04-22 22:59:35 +0800675 if service == None and len(auto_alloc_services) > 0:
676 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800677
Mingyang Sun453ad402021-03-17 17:58:33 +0800678 """
679 Encode stateless flag and version into stateless handle
Kevin Pengce99e5d2021-11-09 18:06:53 +0800680 Check STATIC_HANDLE_CONFIG_FILE for details
Mingyang Sun453ad402021-03-17 17:58:33 +0800681 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800682 stateless_handle_value = 0
683 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800684 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800685 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800686 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
687 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800688 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800689 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800690 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800691
Mingyang Sun4ecea992021-03-30 17:56:26 +0800692 reordered_stateless_services[i] = service
693
694 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800695
Kevin Peng655f2392019-11-27 16:33:02 +0800696def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000697 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
698 epilog='Note that environment variables in template files will be replaced with their values')
699
Kevin Peng655f2392019-11-27 16:33:02 +0800700 parser.add_argument('-o', '--outdir'
701 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800702 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800703 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800704 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800705
Kevin Peng5bc82d22021-10-19 11:18:40 +0800706 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100707 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800708 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100709 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800710 , metavar='manifest list'
711 , help='A list of Secure Partition manifest lists and their original paths.\n\
712 The manifest lists might be processed by CMake and\n\
713 the path might be different to the original one\n\
714 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800715
716 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100717 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800718 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100719 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800720 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700721 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800722
Kevin Pengfb1761b2022-05-12 12:11:31 +0800723 parser.add_argument('-c', '--config-files'
724 , nargs='+'
725 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800726 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800727 , metavar='config-files'
728 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800729
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500730 parser.add_argument('-q', '--quiet'
731 , dest='quiet'
732 , required=False
733 , default=False
734 , action='store_true'
735 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800736
737 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800738
Kevin Peng655f2392019-11-27 16:33:02 +0800739 return args
740
741ENV = Environment(
742 loader = TemplateLoader(),
743 autoescape = select_autoescape(['html', 'xml']),
744 lstrip_blocks = True,
745 trim_blocks = True,
746 keep_trailing_newline = True
747 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100748
Miklos Balint470919c2018-05-22 17:51:29 +0200749def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100750 """
751 The entry point of the script.
752
753 Generates the output files based on the templates and the manifests.
754 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800755
Kevin Peng655f2392019-11-27 16:33:02 +0800756 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800757
Kevin Peng655f2392019-11-27 16:33:02 +0800758 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800759
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500760 logging.basicConfig(format='%(message)s'
761 , level=logging.WARNING if args.quiet else logging.INFO)
762
Kevin Peng5bc82d22021-10-19 11:18:40 +0800763 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800764
Kevin Peng5bc82d22021-10-19 11:18:40 +0800765 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
766 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800767
Shawn Shana9ad1e02019-08-07 15:49:48 +0800768 """
Kevin Peng655f2392019-11-27 16:33:02 +0800769 Relative path to TF-M root folder is supported in the manifests
770 and default value of manifest list and generated file list are relative to TF-M root folder as well,
771 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800772 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800773 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 +0800774 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800775 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800776
Kevin Peng76c0c162022-02-09 22:49:06 +0800777 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800778 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100779
Edison Ai6e3f2a32019-06-11 15:29:05 +0800780 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800781 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200782
Kevin Peng655f2392019-11-27 16:33:02 +0800783 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800784
Ken Liu861b0782021-05-22 13:15:08 +0800785 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800786 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200787
Kevin Peng5bc82d22021-10-19 11:18:40 +0800788if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200789 main()