blob: 75ecd9c7278d7379adf2ea355f75d17056c8a3b5 [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
Jamie Foxb15418a2024-01-18 11:10:20 +00002# Copyright (c) 2018-2024, 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', \
Sherry Zhang357069e2023-11-16 19:28:58 +080039'stack_size', 'description', 'entry_init', 'heap_size', 'mmio_regions', 'services', 'irqs', 'dependencies',\
40'client_id_base', 'client_id_limit']
chesun012345aa52023-04-18 17:31:53 +080041
Mate Toth-Pal36f21842018-11-08 16:12:51 +010042class TemplateLoader(BaseLoader):
43 """
44 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020045
Mate Toth-Pal36f21842018-11-08 16:12:51 +010046 An instance of this class is passed to the template engine. It is
47 responsible for reading the template file
48 """
49 def __init__(self):
50 pass
Miklos Balint470919c2018-05-22 17:51:29 +020051
Mate Toth-Pal36f21842018-11-08 16:12:51 +010052 def get_source(self, environment, template):
53 """
54 This function reads the template files.
55 For detailed documentation see:
56 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
57
58 Please note that this function always return 'false' as 'uptodate'
59 value, so the output file will always be generated.
60 """
61 if not os.path.isfile(template):
62 raise TemplateNotFound(template)
63 with open(template) as f:
64 source = f.read()
65 return source, template, False
66
Kevin Pengfb1761b2022-05-12 12:11:31 +080067def parse_configurations(file_paths):
68 """
69 Parses the given config files and return a dict whose key-values are build
70 configurations and their values.
71
72 Valid configurations should be in the format of:
73 "#define VAR [...]" in a single line.
74 The value of the config is optional.
75 """
76 configurations = {}
77
78 lines = []
79 for file in file_paths:
80 with open(file, 'r') as config_file:
81 lines += config_file.readlines()
82
83 for line in lines:
84 if not line.startswith('#define'):
85 continue
86
87 line = line.rstrip('\r\n')
88 line_items = line.split(maxsplit=2)
89 if len(line_items) == 3:
90 configurations[line_items[1]] = line_items[2]
91 elif len(line_items) == 2:
92 configurations[line_items[1]] = ''
93
94 logging.debug(configurations)
95
96 return configurations
97
Kevin Peng5c3fee72022-02-16 22:25:22 +080098def manifest_validation(manifest, pid):
Mingyang Sun294ce2e2021-06-11 11:58:24 +080099 """
100 This function validates FF-M compliance for partition manifest, and sets
101 default values for optional attributes.
Kevin Pengce99e5d2021-11-09 18:06:53 +0800102 The validation is skipped for TF-M specific Partitions (PID < TFM_PID_BASE).
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800103 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800104
Kevin Peng5c3fee72022-02-16 22:25:22 +0800105 service_list = manifest.get('services', [])
106 irq_list = manifest.get('irqs', [])
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800107
Kevin Peng5c3fee72022-02-16 22:25:22 +0800108 # "psa_framework_version" validation
109 if manifest['psa_framework_version'] not in [1.0, 1.1]:
110 raise Exception('Invalid psa_framework_version of {}'.format(manifest['name']))
111
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700112 # "type" validation
Kevin Peng5c3fee72022-02-16 22:25:22 +0800113 if manifest['type'] not in ['PSA-ROT', 'APPLICATION-ROT']:
114 raise Exception('Invalid type of {}'.format(manifest['name']))
115
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700116 # "priority" validation
117 if manifest['priority'] not in ['HIGH', 'NORMAL', 'LOW']:
118 raise Exception('Invalid priority of {}'.format(manifest['name']))
119
Chris Brandc422cdd2022-07-21 13:32:47 -0700120 if 'ns_agent' not in manifest:
121 manifest['ns_agent'] = False
122
Kevin Peng5c3fee72022-02-16 22:25:22 +0800123 # Every PSA Partition must have at least either a secure service or an IRQ
Kevin Pengce99e5d2021-11-09 18:06:53 +0800124 if (pid == None or pid >= TFM_PID_BASE) \
Kevin Peng8849b6a2021-11-09 14:17:35 +0800125 and len(service_list) == 0 and len(irq_list) == 0:
126 raise Exception('{} must declare at least either a secure service or an IRQ!'
Kevin Peng5c3fee72022-02-16 22:25:22 +0800127 .format(manifest['name']))
128
129 if manifest['psa_framework_version'] == 1.0:
130 # For 1.0 Partition, the model is IPC
131 manifest['model'] = 'IPC'
132
133 # "model" validation:
134 model = manifest.get('model', None)
135 if model == None:
136 raise Exception('{} is missing the "model" attribute'.format(manifest['name']))
137
138 # Assign a unified 'entry' for templates
139 if model == 'IPC':
140 # entry_point is mandatory for IPC Partitions
141 if 'entry_point' not in manifest.keys():
142 raise Exception('{} is missing the "entry_point" attribute'.format(manifest['name']))
143 manifest['entry'] = manifest['entry_point']
144 elif model == 'SFN':
145 if 'entry_init' in manifest.keys():
146 manifest['entry'] = manifest['entry_init']
147 else:
148 manifest['entry'] = 0
149 else:
150 raise Exception('Invalid "model" of {}'.format(manifest['name']))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800151
152 # Service FF-M manifest validation
153 for service in service_list:
Kevin Peng5c3fee72022-02-16 22:25:22 +0800154 if manifest['psa_framework_version'] == 1.0:
155 service['connection_based'] = True
156 elif 'connection_based' not in service:
157 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
158
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800159 if 'version' not in service.keys():
160 service['version'] = 1
161 if 'version_policy' not in service.keys():
Kevin Peng5bc82d22021-10-19 11:18:40 +0800162 service['version_policy'] = 'STRICT'
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800163
Kevin Peng5bc82d22021-10-19 11:18:40 +0800164 # SID duplication check
165 if service['sid'] in sid_list:
166 raise Exception('Service ID: {} has duplications!'.format(service['sid']))
167 else:
168 sid_list.append(service['sid'])
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100169
Kevin Peng5c3fee72022-02-16 22:25:22 +0800170 return manifest
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800171
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800172def check_circular_dependency(partitions, service_partition_map):
173 """
174 This function detects if there is any circular partition dependency chain.
175 If a circular dependency is detected, the script exits with error.
176
177 Inputs:
178 - partitions: dict of partition manifests
179 - service_partition_map: map between services and their owner Partitions
180 """
181
182 dependency_table = {}
183 for partition in partitions:
184 manifest = partition['manifest']
185 dependencies = manifest['dependencies'].copy() \
186 if 'dependencies' in manifest else []
187 dependencies += manifest['weak_dependencies'].copy() \
188 if 'weak_dependencies' in manifest else []
189 dependency_table[manifest['name']] = {
190 'dependencies': [service_partition_map[dependency]
191 for dependency in dependencies
192 if dependency in service_partition_map],
193 'validated': False
194 }
195
196 for partition in dependency_table.keys():
197 validate_dependency_chain(partition, dependency_table, [])
198
199def validate_dependency_chain(partition,
200 dependency_table,
201 dependency_chain):
202 """
203 Recursively validate if the given partition and its dependencies
204 have a circular dependency with the given dependency_chain.
205 Exit with error code once any circular is detected.
206
207 Inputs:
208 - partition: next partition to be checked
209 - dependency_table: dict of partitions and their dependencies
210 - dependency_chain: list of dependencies in current chain
211 """
212
213 dependency_chain.append(partition)
214 if partition in dependency_chain[:-1]:
215 logging.error(
216 'Circular dependency exists in chain: {}'.format(
217 ', '.join(dependency_chain)))
218 exit(1)
219 for dependency in dependency_table[partition]['dependencies']:
220 if dependency_table[dependency]['validated']:
221 continue
222 validate_dependency_chain(dependency, dependency_table, dependency_chain)
223 dependency_table[partition]['validated'] = True
224
chesun012345aa52023-04-18 17:31:53 +0800225def manifest_attribute_check(manifest, manifest_item):
226 """
227 Check whether Non-FF-M compliant attributes are explicitly registered in manifest lists.
228
229 Inputs:
230 - manifest: next manifest to be checked
231 - manifest_item: the manifest items in manifest lists
232 """
233 allowed_attributes = ffm_manifest_attributes + manifest_item.get('non_ffm_attributes', [])
234 for keyword in manifest.keys():
235 if keyword not in allowed_attributes:
236 logging.error('The Non-FFM attribute {} is used by {} without registration.'.format(keyword, manifest['name']))
237 exit(1)
238
Kevin Pengfb1761b2022-05-12 12:11:31 +0800239def process_partition_manifests(manifest_lists, configs):
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100240 """
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800241 Parse the input manifest lists, check if manifest settings are valid,
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700242 generate the data base for generated files
Kevin Peng655f2392019-11-27 16:33:02 +0800243 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100244
245 Parameters
246 ----------
Kevin Peng65064c52021-10-27 17:12:17 +0800247 manifest_lists:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800248 A list of Secure Partition manifest lists
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100249
250 Returns
251 -------
Kevin Peng5bc82d22021-10-19 11:18:40 +0800252 The manifest data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +0800253 """
Kevin Peng655f2392019-11-27 16:33:02 +0800254
Kevin Peng5bc82d22021-10-19 11:18:40 +0800255 context = {}
256
Ken Liu861b0782021-05-22 13:15:08 +0800257 partition_list = []
Kevin Peng65064c52021-10-27 17:12:17 +0800258 all_manifests = []
Kevin Peng56b0ea62021-10-18 11:32:57 +0800259 pid_list = []
260 no_pid_manifest_idx = []
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800261 service_partition_map = {}
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800262 partition_statistics = {
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800263 'connection_based_srv_num': 0,
Kevin Peng47c26ec2022-03-11 11:49:52 +0800264 'ipc_partitions': [],
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800265 'mmio_region_num': 0,
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800266 'flih_num': 0,
267 'slih_num': 0
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800268 }
Kevin Peng9f1a7542022-02-07 16:32:27 +0800269 config_impl = {
270 'CONFIG_TFM_SPM_BACKEND_SFN' : '0',
271 'CONFIG_TFM_SPM_BACKEND_IPC' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800272 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800273 'CONFIG_TFM_MMIO_REGION_ENABLE' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800274 'CONFIG_TFM_FLIH_API' : '0',
275 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800276 }
chesun0122abf0a2023-10-17 13:42:16 +0800277 priority_map = {
278 'LOWEST' : '00',
279 'LOW' : '01',
280 'NORMAL' : '02',
281 'HIGH' : '03',
282 'HIGHEST' : '04'
283 }
Kevin Peng655f2392019-11-27 16:33:02 +0800284
Kevin Pengfb1761b2022-05-12 12:11:31 +0800285 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
286 backend = configs['CONFIG_TFM_SPM_BACKEND']
287
Kevin Peng65064c52021-10-27 17:12:17 +0800288 # Get all the manifests information as a dictionary
289 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800290 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500291 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800292 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800293
Kevin Peng65064c52021-10-27 17:12:17 +0800294 # The manifest list file generated by configure_file()
295 with open(item) as manifest_list_yaml_file:
296 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
297 for dict in manifest_dic:
Raef Coles052e8712023-11-02 15:29:40 +0000298 # Replace environment variables in the manifest path.
299 expanded_path = os.path.expandvars(dict['manifest']).replace('\\', '/')
300
301 # If the manifest exists relative to the manifest list, then use
302 # that. Else, either interpret it as an absolute path or one
303 # relative to the current working directory
304 path_relative_to_manifest_list = os.path.join(os.path.dirname(item), # path of manifest list
305 expanded_path)
306 if os.path.isfile(path_relative_to_manifest_list):
307 manifest_path = path_relative_to_manifest_list
308 else:
309 manifest_path = expanded_path
Kevin Pengfb1761b2022-05-12 12:11:31 +0800310 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800311 all_manifests.append(dict)
312
Anton Komlev52920712024-05-16 13:45:46 +0100313 logging.info("----------- Secure Partitions ------------------------")
Chris Brand4b69fcf2022-06-06 09:37:49 -0700314
Kevin Peng65064c52021-10-27 17:12:17 +0800315 # Parse the manifests
316 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800317 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
318 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800319 is_enabled = ''
320
321 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800322 if manifest_item['conditional'] not in configs.keys():
323 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
324 exit(1)
325 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800326 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800327 # Partitions without 'conditional' is always on
328 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800329
330 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300331 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800332 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700333 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300334 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700335 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800336 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
337 'Please set to one of {} or {}, case-insensitive.'\
338 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300339 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800340 valid_enabled_conditions, valid_disabled_conditions))
341
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800342 # Check if partition ID is manually set
343 if 'pid' not in manifest_item.keys():
344 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800345 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800346 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800347 pid = manifest_item['pid']
348
349 # Check if partition ID is duplicated
350 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100351 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800352 else:
353 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800354
Kevin Pengfb1761b2022-05-12 12:11:31 +0800355 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800356 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800357 manifest = yaml.safe_load(manifest_file)
chesun0122abf0a2023-10-17 13:42:16 +0800358 # Check manifest attribute validity
chesun012345aa52023-04-18 17:31:53 +0800359 manifest_attribute_check(manifest, manifest_item)
360
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800361 if manifest.get('model', None) == 'dual':
362 # If a Partition supports both models, it can set the "model" to "backend".
363 # The actual model used follows the backend being used.
364 manifest['model'] = backend
365 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800366
chesun0122abf0a2023-10-17 13:42:16 +0800367 # Priority mapping
368 numbered_priority = priority_map[manifest['priority']]
369
Jamie Foxb15418a2024-01-18 11:10:20 +0000370 if (pid == None or pid >= TFM_PID_BASE) and not manifest['ns_agent']:
371 # Count the number of IPC/SFN partitions (excluding TF-M internal
372 # and agent partitions)
Kevin Peng47c26ec2022-03-11 11:49:52 +0800373 if manifest['model'] == 'IPC':
374 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800375
Kevin Peng5c3fee72022-02-16 22:25:22 +0800376 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
377 # number (0) when there are no services.
378 srv_idx = -1
379 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800380 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800381 if manifest['model'] == 'IPC':
382 # Assign signal value, the first 4 bits are reserved by FF-M
383 service['signal_value'] = (1 << (srv_idx + 4))
384 else:
385 # Signals of SFN Partitions are SPM internal only, does not
386 # need to reserve 4 bits.
387 service['signal_value'] = (1 << srv_idx)
388 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800389 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800390 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800391
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800392 # Calculate the number of mmio region
393 mmio_region_list = manifest.get('mmio_regions', [])
394 partition_statistics['mmio_region_num'] += len(mmio_region_list)
395
Kevin Peng5c3fee72022-02-16 22:25:22 +0800396 # Set initial value to -1 to make (irq + 1) reflect the correct
397 # number (0) when there are no irqs.
398 irq_idx = -1
399 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
400 # Assign signal value, from the most significant bit
401 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800402 if irq.get('handling', None) == 'FLIH':
403 partition_statistics['flih_num'] += 1
404 else:
405 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800406 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
407
408 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
409 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
410 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800411
Kevin Peng65064c52021-10-27 17:12:17 +0800412 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800413
Kevin Peng4fade072021-10-26 17:57:50 +0800414 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800415 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800416 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800417 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800418
Kevin Peng5bc82d22021-10-19 11:18:40 +0800419 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
420 '{}.h'.format(manifest_out_basename))\
421 .replace('\\', '/')
422 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
423 'intermedia_{}.c'.format(manifest_out_basename))\
424 .replace('\\', '/')
425 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
426 'load_info_{}.c'.format(manifest_out_basename))\
427 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800428 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800429
Kevin Peng5bc82d22021-10-19 11:18:40 +0800430 partition_list.append({'manifest': manifest, 'attr': manifest_item,
431 'manifest_out_basename': manifest_out_basename,
432 'header_file': manifest_head_file,
433 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800434 'loadinfo_file': load_info_file,
chesun0122abf0a2023-10-17 13:42:16 +0800435 'output_dir': output_dir,
436 'numbered_priority': numbered_priority})
Ken Liu861b0782021-05-22 13:15:08 +0800437
Anton Komlev52920712024-05-16 13:45:46 +0100438 logging.info("------------------------------------------------------")
Chris Brand4b69fcf2022-06-06 09:37:49 -0700439
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800440 check_circular_dependency(partition_list, service_partition_map)
441
Kevin Peng56b0ea62021-10-18 11:32:57 +0800442 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800443 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800444 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800445 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800446 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800447 pid_list.append(pid)
448
Kevin Peng9f1a7542022-02-07 16:32:27 +0800449 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800450 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800451 if len(partition_statistics['ipc_partitions']) > 0:
452 logging.error('SFN backend does not support IPC Partitions:')
453 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800454 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800455
456 if isolation_level > 1:
457 logging.error('SFN backend does not support high isolation levels.')
458 exit(1)
459
Kevin Peng9f1a7542022-02-07 16:32:27 +0800460 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800461 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800462 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800463
464 if partition_statistics['connection_based_srv_num'] > 0:
465 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
466
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800467 if partition_statistics['mmio_region_num'] > 0:
468 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
469
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800470 if partition_statistics['flih_num'] > 0:
471 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200472 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800473 config_impl['CONFIG_TFM_SLIH_API'] = 1
474
Kevin Peng5bc82d22021-10-19 11:18:40 +0800475 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800476 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800477 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100478
Kevin Peng5bc82d22021-10-19 11:18:40 +0800479 return context
Ken Liu861b0782021-05-22 13:15:08 +0800480
481def gen_per_partition_files(context):
482 """
483 Generate per-partition files
484
485 Parameters
486 ----------
487 context:
488 context contains partition infos
489 """
490
Kevin Peng5bc82d22021-10-19 11:18:40 +0800491 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800492 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800493 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800494
Kevin Peng5bc82d22021-10-19 11:18:40 +0800495 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
496 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
497 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800498
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500499 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800500
501 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800502 partition_context['manifest'] = one_partition['manifest']
503 partition_context['attr'] = one_partition['attr']
504 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
chesun0122abf0a2023-10-17 13:42:16 +0800505 partition_context['numbered_priority'] = one_partition['numbered_priority']
Ken Liu861b0782021-05-22 13:15:08 +0800506
BohdanHunko6cea95d2022-08-16 15:33:51 +0300507 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800508 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800509 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800510 if not os.path.exists(outfile_path):
511 os.makedirs(outfile_path)
512
Kevin Peng5bc82d22021-10-19 11:18:40 +0800513 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
514 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800515 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800516
Ken Liu861b0782021-05-22 13:15:08 +0800517 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800518 if not os.path.exists(intermediafile_path):
519 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800520 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
521 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800522 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800523
Ken Liu861b0782021-05-22 13:15:08 +0800524 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800525 if not os.path.exists(infofile_path):
526 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800527 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
528 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800529 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800530
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500531 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800532
Ken Liu861b0782021-05-22 13:15:08 +0800533def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800534 """
535 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800536
537 Parameters
538 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100539 gen_file_lists:
540 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800541 """
Kevin Peng655f2392019-11-27 16:33:02 +0800542 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800543
Raef Colesf42f0882020-07-10 10:01:58 +0100544 for f in gen_file_lists:
545 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800546 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800547 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800548
Kevin Peng655f2392019-11-27 16:33:02 +0800549 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000550 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800551 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000552 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800553 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800554
Kevin Peng4fade072021-10-26 17:57:50 +0800555 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800556
Ken Liu861b0782021-05-22 13:15:08 +0800557 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800558 if not os.path.exists(outfile_path):
559 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800560
Kevin Peng655f2392019-11-27 16:33:02 +0800561 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800562
Kevin Peng5bc82d22021-10-19 11:18:40 +0800563 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800564 outfile.write(template.render(context))
565 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800566
Kevin Pengce99e5d2021-11-09 18:06:53 +0800567def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800568 """
569 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800570 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800571 Valid stateless handle in service will be converted to an index. If the
572 stateless handle is set as "auto", or not set, framework will allocate a
573 valid index for the service.
574 Framework puts each service into a reordered stateless service list at
575 position of "index". Other unused positions are left None.
Ken Liu50948382022-10-27 12:45:53 +0800576
577 Keep the variable names start with upper case 'STATIC_HANDLE_' the same
578 as the preprocessors in C sources. This could easier the upcomping
579 modification when developer searches these definitions for modification.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800580 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800581
Kevin Pengc05319d2021-04-22 22:59:35 +0800582 collected_stateless_services = []
Ken Liu50948382022-10-27 12:45:53 +0800583 STATIC_HANDLE_NUM_LIMIT = 32
Mingyang Suna1ca6112021-01-11 11:34:59 +0800584
585 # Collect all stateless services first.
586 for partition in partitions:
587 # Skip the FF-M 1.0 partitions
588 if partition['manifest']['psa_framework_version'] < 1.1:
589 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800590
591 service_list = partition['manifest'].get('services', [])
592
593 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800594 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800595 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800596
Kevin Pengc05319d2021-04-22 22:59:35 +0800597 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800598 return []
599
Ken Liu50948382022-10-27 12:45:53 +0800600 if len(collected_stateless_services) > STATIC_HANDLE_NUM_LIMIT:
601 raise Exception('Stateless service numbers range exceed {number}.'.format(number=STATIC_HANDLE_NUM_LIMIT))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800602
603 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800604 Allocate an empty stateless service list to store services.
605 Use "handle - 1" as the index for service, since handle value starts from
606 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800607 """
Ken Liu50948382022-10-27 12:45:53 +0800608 reordered_stateless_services = [None] * STATIC_HANDLE_NUM_LIMIT
Kevin Pengc05319d2021-04-22 22:59:35 +0800609 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800610
Kevin Pengc05319d2021-04-22 22:59:35 +0800611 for service in collected_stateless_services:
612 # If not set, it is "auto" by default
613 if 'stateless_handle' not in service:
614 auto_alloc_services.append(service)
615 continue
616
Mingyang Sun4ecea992021-03-30 17:56:26 +0800617 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800618
Mingyang Sun4ecea992021-03-30 17:56:26 +0800619 # Fill in service list with specified stateless handle, otherwise skip
620 if isinstance(service_handle, int):
Ken Liu50948382022-10-27 12:45:53 +0800621 if service_handle < 1 or service_handle > STATIC_HANDLE_NUM_LIMIT:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800622 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800623 # Convert handle index to reordered service list index
624 service_handle = service_handle - 1
625
626 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800627 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800628 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800629 elif service_handle == 'auto':
630 auto_alloc_services.append(service)
631 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800632 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800633
Xinyu Zhangb2d4ed42023-02-14 11:43:16 +0800634 STATIC_HANDLE_IDX_BIT_WIDTH = 5
Kevin Pengce99e5d2021-11-09 18:06:53 +0800635 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
Ken Liu50948382022-10-27 12:45:53 +0800636 STATIC_HANDLE_INDICATOR_OFFSET = 30
637 STATIC_HANDLE_VER_OFFSET = 8
638 STATIC_HANDLE_VER_BIT_WIDTH = 8
Kevin Pengce99e5d2021-11-09 18:06:53 +0800639 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
640
Mingyang Sun4ecea992021-03-30 17:56:26 +0800641 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu50948382022-10-27 12:45:53 +0800642 for i in range(0, STATIC_HANDLE_NUM_LIMIT):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800643 service = reordered_stateless_services[i]
644
Kevin Pengc05319d2021-04-22 22:59:35 +0800645 if service == None and len(auto_alloc_services) > 0:
646 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800647
Mingyang Sun453ad402021-03-17 17:58:33 +0800648 """
649 Encode stateless flag and version into stateless handle
Mingyang Sun453ad402021-03-17 17:58:33 +0800650 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800651 stateless_handle_value = 0
652 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800653 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800654 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800655 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
656 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800657 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800658 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800659 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800660
Mingyang Sun4ecea992021-03-30 17:56:26 +0800661 reordered_stateless_services[i] = service
662
663 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800664
Kevin Peng655f2392019-11-27 16:33:02 +0800665def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000666 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
Juha Ylinenbc261272024-06-19 13:00:00 +0300667 epilog='Note that environment variables in template files will be replaced with their values',
668 allow_abbrev=False)
Raef Coles558487a2020-10-29 13:09:44 +0000669
Kevin Peng655f2392019-11-27 16:33:02 +0800670 parser.add_argument('-o', '--outdir'
671 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800672 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800673 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800674 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800675
Kevin Peng5bc82d22021-10-19 11:18:40 +0800676 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100677 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800678 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100679 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800680 , metavar='manifest list'
681 , help='A list of Secure Partition manifest lists and their original paths.\n\
682 The manifest lists might be processed by CMake and\n\
683 the path might be different to the original one\n\
684 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800685
686 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100687 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800688 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100689 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800690 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700691 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800692
Kevin Pengfb1761b2022-05-12 12:11:31 +0800693 parser.add_argument('-c', '--config-files'
694 , nargs='+'
695 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800696 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800697 , metavar='config-files'
698 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800699
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500700 parser.add_argument('-q', '--quiet'
701 , dest='quiet'
702 , required=False
703 , default=False
704 , action='store_true'
705 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800706
707 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800708
Kevin Peng655f2392019-11-27 16:33:02 +0800709 return args
710
711ENV = Environment(
712 loader = TemplateLoader(),
713 autoescape = select_autoescape(['html', 'xml']),
714 lstrip_blocks = True,
715 trim_blocks = True,
716 keep_trailing_newline = True
717 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100718
Miklos Balint470919c2018-05-22 17:51:29 +0200719def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100720 """
721 The entry point of the script.
722
723 Generates the output files based on the templates and the manifests.
724 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800725
Kevin Peng655f2392019-11-27 16:33:02 +0800726 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800727
Kevin Peng655f2392019-11-27 16:33:02 +0800728 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800729
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500730 logging.basicConfig(format='%(message)s'
731 , level=logging.WARNING if args.quiet else logging.INFO)
732
Kevin Peng5bc82d22021-10-19 11:18:40 +0800733 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800734
Kevin Peng5bc82d22021-10-19 11:18:40 +0800735 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
736 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800737
Shawn Shana9ad1e02019-08-07 15:49:48 +0800738 """
Kevin Peng655f2392019-11-27 16:33:02 +0800739 Relative path to TF-M root folder is supported in the manifests
740 and default value of manifest list and generated file list are relative to TF-M root folder as well,
741 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800742 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800743 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 +0800744 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800745 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800746
Kevin Peng76c0c162022-02-09 22:49:06 +0800747 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800748 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100749
Edison Ai6e3f2a32019-06-11 15:29:05 +0800750 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800751 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200752
Kevin Peng655f2392019-11-27 16:33:02 +0800753 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800754
Ken Liu861b0782021-05-22 13:15:08 +0800755 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800756 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200757
Kevin Peng5bc82d22021-10-19 11:18:40 +0800758if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200759 main()