blob: b603cf0035664083c0ec4ec75ce3c9b9a9f40c13 [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
Raef Coles052e8712023-11-02 15:29:40 +00002# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
Chris Brandf1d6b6f2022-07-22 11:49:01 -07003# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4# or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
Miklos Balint470919c2018-05-22 17:51:29 +02005#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8#-------------------------------------------------------------------------------
9
10import os
Mate Toth-Pal36f21842018-11-08 16:12:51 +010011import io
Kevin Pengce99e5d2021-11-09 18:06:53 +080012import re
Shawn Shana9ad1e02019-08-07 15:49:48 +080013import sys
14import argparse
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050015import logging
Ken Liu1f345b02020-05-30 21:11:05 +080016from jinja2 import Environment, BaseLoader, select_autoescape, TemplateNotFound
Miklos Balint470919c2018-05-22 17:51:29 +020017
18try:
19 import yaml
20except ImportError as e:
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050021 logging.error (str(e) + " To install it, type:")
22 logging.error ("pip install PyYAML")
Miklos Balint470919c2018-05-22 17:51:29 +020023 exit(1)
24
Edison Ai48b2d9e2019-06-24 14:39:45 +080025donotedit_warning = \
Sherry Zhangf58f2bd2022-01-10 17:21:11 +080026 ' WARNING: This is an auto-generated file. Do not edit! '
Kevin Peng655f2392019-11-27 16:33:02 +080027
Kevin Pengce99e5d2021-11-09 18:06:53 +080028TFM_ROOT_DIR = os.path.join(sys.path[0], '..')
Kevin Peng655f2392019-11-27 16:33:02 +080029OUT_DIR = None # The root directory that files are generated to
Edison Ai48b2d9e2019-06-24 14:39:45 +080030
Sherry Zhang87e6d2e2021-12-27 14:48:59 +080031# PID[0, TFM_PID_BASE - 1] are reserved for TF-M SPM and test usages
Kevin Pengce99e5d2021-11-09 18:06:53 +080032TFM_PID_BASE = 256
33
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010034# variable for checking for duplicated sid
35sid_list = []
chesun012345aa52023-04-18 17:31:53 +080036
37# Summary of manifest attributes defined by FFM for use in the Secure Partition manifest file.
38ffm_manifest_attributes = ['psa_framework_version', 'name', 'type', 'priority', 'model', 'entry_point', \
39'stack_size', 'description', 'entry_init', 'heap_size', 'mmio_regions', 'services', 'irqs', 'dependencies']
40
Mate Toth-Pal36f21842018-11-08 16:12:51 +010041class TemplateLoader(BaseLoader):
42 """
43 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020044
Mate Toth-Pal36f21842018-11-08 16:12:51 +010045 An instance of this class is passed to the template engine. It is
46 responsible for reading the template file
47 """
48 def __init__(self):
49 pass
Miklos Balint470919c2018-05-22 17:51:29 +020050
Mate Toth-Pal36f21842018-11-08 16:12:51 +010051 def get_source(self, environment, template):
52 """
53 This function reads the template files.
54 For detailed documentation see:
55 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
56
57 Please note that this function always return 'false' as 'uptodate'
58 value, so the output file will always be generated.
59 """
60 if not os.path.isfile(template):
61 raise TemplateNotFound(template)
62 with open(template) as f:
63 source = f.read()
64 return source, template, False
65
Kevin Pengfb1761b2022-05-12 12:11:31 +080066def parse_configurations(file_paths):
67 """
68 Parses the given config files and return a dict whose key-values are build
69 configurations and their values.
70
71 Valid configurations should be in the format of:
72 "#define VAR [...]" in a single line.
73 The value of the config is optional.
74 """
75 configurations = {}
76
77 lines = []
78 for file in file_paths:
79 with open(file, 'r') as config_file:
80 lines += config_file.readlines()
81
82 for line in lines:
83 if not line.startswith('#define'):
84 continue
85
86 line = line.rstrip('\r\n')
87 line_items = line.split(maxsplit=2)
88 if len(line_items) == 3:
89 configurations[line_items[1]] = line_items[2]
90 elif len(line_items) == 2:
91 configurations[line_items[1]] = ''
92
93 logging.debug(configurations)
94
95 return configurations
96
Kevin Peng5c3fee72022-02-16 22:25:22 +080097def manifest_validation(manifest, pid):
Mingyang Sun294ce2e2021-06-11 11:58:24 +080098 """
99 This function validates FF-M compliance for partition manifest, and sets
100 default values for optional attributes.
Kevin Pengce99e5d2021-11-09 18:06:53 +0800101 The validation is skipped for TF-M specific Partitions (PID < TFM_PID_BASE).
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800102 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800103
Kevin Peng5c3fee72022-02-16 22:25:22 +0800104 service_list = manifest.get('services', [])
105 irq_list = manifest.get('irqs', [])
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800106
Kevin Peng5c3fee72022-02-16 22:25:22 +0800107 # "psa_framework_version" validation
108 if manifest['psa_framework_version'] not in [1.0, 1.1]:
109 raise Exception('Invalid psa_framework_version of {}'.format(manifest['name']))
110
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700111 # "type" validation
Kevin Peng5c3fee72022-02-16 22:25:22 +0800112 if manifest['type'] not in ['PSA-ROT', 'APPLICATION-ROT']:
113 raise Exception('Invalid type of {}'.format(manifest['name']))
114
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700115 # "priority" validation
116 if manifest['priority'] not in ['HIGH', 'NORMAL', 'LOW']:
117 raise Exception('Invalid priority of {}'.format(manifest['name']))
118
Chris Brandc422cdd2022-07-21 13:32:47 -0700119 if 'ns_agent' not in manifest:
120 manifest['ns_agent'] = False
121
Kevin Peng5c3fee72022-02-16 22:25:22 +0800122 # Every PSA Partition must have at least either a secure service or an IRQ
Kevin Pengce99e5d2021-11-09 18:06:53 +0800123 if (pid == None or pid >= TFM_PID_BASE) \
Kevin Peng8849b6a2021-11-09 14:17:35 +0800124 and len(service_list) == 0 and len(irq_list) == 0:
125 raise Exception('{} must declare at least either a secure service or an IRQ!'
Kevin Peng5c3fee72022-02-16 22:25:22 +0800126 .format(manifest['name']))
127
128 if manifest['psa_framework_version'] == 1.0:
129 # For 1.0 Partition, the model is IPC
130 manifest['model'] = 'IPC'
131
132 # "model" validation:
133 model = manifest.get('model', None)
134 if model == None:
135 raise Exception('{} is missing the "model" attribute'.format(manifest['name']))
136
137 # Assign a unified 'entry' for templates
138 if model == 'IPC':
139 # entry_point is mandatory for IPC Partitions
140 if 'entry_point' not in manifest.keys():
141 raise Exception('{} is missing the "entry_point" attribute'.format(manifest['name']))
142 manifest['entry'] = manifest['entry_point']
143 elif model == 'SFN':
144 if 'entry_init' in manifest.keys():
145 manifest['entry'] = manifest['entry_init']
146 else:
147 manifest['entry'] = 0
148 else:
149 raise Exception('Invalid "model" of {}'.format(manifest['name']))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800150
151 # Service FF-M manifest validation
152 for service in service_list:
Kevin Peng5c3fee72022-02-16 22:25:22 +0800153 if manifest['psa_framework_version'] == 1.0:
154 service['connection_based'] = True
155 elif 'connection_based' not in service:
156 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
157
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800158 if 'version' not in service.keys():
159 service['version'] = 1
160 if 'version_policy' not in service.keys():
Kevin Peng5bc82d22021-10-19 11:18:40 +0800161 service['version_policy'] = 'STRICT'
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800162
Kevin Peng5bc82d22021-10-19 11:18:40 +0800163 # SID duplication check
164 if service['sid'] in sid_list:
165 raise Exception('Service ID: {} has duplications!'.format(service['sid']))
166 else:
167 sid_list.append(service['sid'])
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100168
Kevin Peng5c3fee72022-02-16 22:25:22 +0800169 return manifest
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800170
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800171def check_circular_dependency(partitions, service_partition_map):
172 """
173 This function detects if there is any circular partition dependency chain.
174 If a circular dependency is detected, the script exits with error.
175
176 Inputs:
177 - partitions: dict of partition manifests
178 - service_partition_map: map between services and their owner Partitions
179 """
180
181 dependency_table = {}
182 for partition in partitions:
183 manifest = partition['manifest']
184 dependencies = manifest['dependencies'].copy() \
185 if 'dependencies' in manifest else []
186 dependencies += manifest['weak_dependencies'].copy() \
187 if 'weak_dependencies' in manifest else []
188 dependency_table[manifest['name']] = {
189 'dependencies': [service_partition_map[dependency]
190 for dependency in dependencies
191 if dependency in service_partition_map],
192 'validated': False
193 }
194
195 for partition in dependency_table.keys():
196 validate_dependency_chain(partition, dependency_table, [])
197
198def validate_dependency_chain(partition,
199 dependency_table,
200 dependency_chain):
201 """
202 Recursively validate if the given partition and its dependencies
203 have a circular dependency with the given dependency_chain.
204 Exit with error code once any circular is detected.
205
206 Inputs:
207 - partition: next partition to be checked
208 - dependency_table: dict of partitions and their dependencies
209 - dependency_chain: list of dependencies in current chain
210 """
211
212 dependency_chain.append(partition)
213 if partition in dependency_chain[:-1]:
214 logging.error(
215 'Circular dependency exists in chain: {}'.format(
216 ', '.join(dependency_chain)))
217 exit(1)
218 for dependency in dependency_table[partition]['dependencies']:
219 if dependency_table[dependency]['validated']:
220 continue
221 validate_dependency_chain(dependency, dependency_table, dependency_chain)
222 dependency_table[partition]['validated'] = True
223
chesun012345aa52023-04-18 17:31:53 +0800224def manifest_attribute_check(manifest, manifest_item):
225 """
226 Check whether Non-FF-M compliant attributes are explicitly registered in manifest lists.
227
228 Inputs:
229 - manifest: next manifest to be checked
230 - manifest_item: the manifest items in manifest lists
231 """
232 allowed_attributes = ffm_manifest_attributes + manifest_item.get('non_ffm_attributes', [])
233 for keyword in manifest.keys():
234 if keyword not in allowed_attributes:
235 logging.error('The Non-FFM attribute {} is used by {} without registration.'.format(keyword, manifest['name']))
236 exit(1)
237
Kevin Pengfb1761b2022-05-12 12:11:31 +0800238def process_partition_manifests(manifest_lists, configs):
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100239 """
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800240 Parse the input manifest lists, check if manifest settings are valid,
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700241 generate the data base for generated files
Kevin Peng655f2392019-11-27 16:33:02 +0800242 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100243
244 Parameters
245 ----------
Kevin Peng65064c52021-10-27 17:12:17 +0800246 manifest_lists:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800247 A list of Secure Partition manifest lists
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100248
249 Returns
250 -------
Kevin Peng5bc82d22021-10-19 11:18:40 +0800251 The manifest data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +0800252 """
Kevin Peng655f2392019-11-27 16:33:02 +0800253
Kevin Peng5bc82d22021-10-19 11:18:40 +0800254 context = {}
255
Ken Liu861b0782021-05-22 13:15:08 +0800256 partition_list = []
Kevin Peng65064c52021-10-27 17:12:17 +0800257 all_manifests = []
Kevin Peng56b0ea62021-10-18 11:32:57 +0800258 pid_list = []
259 no_pid_manifest_idx = []
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800260 service_partition_map = {}
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800261 partition_statistics = {
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800262 'connection_based_srv_num': 0,
Kevin Peng47c26ec2022-03-11 11:49:52 +0800263 'ipc_partitions': [],
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800264 'mmio_region_num': 0,
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800265 'flih_num': 0,
266 'slih_num': 0
Xinyu Zhang90f08dc2022-01-12 15:55:17 +0800267 }
Kevin Peng9f1a7542022-02-07 16:32:27 +0800268 config_impl = {
269 'CONFIG_TFM_SPM_BACKEND_SFN' : '0',
270 'CONFIG_TFM_SPM_BACKEND_IPC' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800271 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800272 'CONFIG_TFM_MMIO_REGION_ENABLE' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800273 'CONFIG_TFM_FLIH_API' : '0',
274 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800275 }
chesun0122abf0a2023-10-17 13:42:16 +0800276 priority_map = {
277 'LOWEST' : '00',
278 'LOW' : '01',
279 'NORMAL' : '02',
280 'HIGH' : '03',
281 'HIGHEST' : '04'
282 }
Kevin Peng655f2392019-11-27 16:33:02 +0800283
Kevin Pengfb1761b2022-05-12 12:11:31 +0800284 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
285 backend = configs['CONFIG_TFM_SPM_BACKEND']
286
Kevin Peng65064c52021-10-27 17:12:17 +0800287 # Get all the manifests information as a dictionary
288 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800289 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500290 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800291 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800292
Kevin Peng65064c52021-10-27 17:12:17 +0800293 # The manifest list file generated by configure_file()
294 with open(item) as manifest_list_yaml_file:
295 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
296 for dict in manifest_dic:
Raef Coles052e8712023-11-02 15:29:40 +0000297 # Replace environment variables in the manifest path.
298 expanded_path = os.path.expandvars(dict['manifest']).replace('\\', '/')
299
300 # If the manifest exists relative to the manifest list, then use
301 # that. Else, either interpret it as an absolute path or one
302 # relative to the current working directory
303 path_relative_to_manifest_list = os.path.join(os.path.dirname(item), # path of manifest list
304 expanded_path)
305 if os.path.isfile(path_relative_to_manifest_list):
306 manifest_path = path_relative_to_manifest_list
307 else:
308 manifest_path = expanded_path
Kevin Pengfb1761b2022-05-12 12:11:31 +0800309 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800310 all_manifests.append(dict)
311
Chris Brand4b69fcf2022-06-06 09:37:49 -0700312 logging.info("------------ Display partition configuration - start ------------")
313
Kevin Peng65064c52021-10-27 17:12:17 +0800314 # Parse the manifests
315 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800316 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
317 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800318 is_enabled = ''
319
320 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800321 if manifest_item['conditional'] not in configs.keys():
322 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
323 exit(1)
324 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800325 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800326 # Partitions without 'conditional' is always on
327 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800328
329 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300330 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800331 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700332 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300333 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700334 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800335 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
336 'Please set to one of {} or {}, case-insensitive.'\
337 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300338 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800339 valid_enabled_conditions, valid_disabled_conditions))
340
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800341 # Check if partition ID is manually set
342 if 'pid' not in manifest_item.keys():
343 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800344 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800345 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800346 pid = manifest_item['pid']
347
348 # Check if partition ID is duplicated
349 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100350 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800351 else:
352 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800353
Kevin Pengfb1761b2022-05-12 12:11:31 +0800354 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800355 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800356 manifest = yaml.safe_load(manifest_file)
chesun0122abf0a2023-10-17 13:42:16 +0800357 # Check manifest attribute validity
chesun012345aa52023-04-18 17:31:53 +0800358 manifest_attribute_check(manifest, manifest_item)
359
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800360 if manifest.get('model', None) == 'dual':
361 # If a Partition supports both models, it can set the "model" to "backend".
362 # The actual model used follows the backend being used.
363 manifest['model'] = backend
364 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800365
chesun0122abf0a2023-10-17 13:42:16 +0800366 # Priority mapping
367 numbered_priority = priority_map[manifest['priority']]
368
Kevin Pengce99e5d2021-11-09 18:06:53 +0800369 if pid == None or pid >= TFM_PID_BASE:
Kevin Pengd08f3ba2021-11-18 15:18:56 +0800370 # Count the number of IPC/SFN partitions
Kevin Peng47c26ec2022-03-11 11:49:52 +0800371 if manifest['model'] == 'IPC':
372 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800373
Kevin Peng5c3fee72022-02-16 22:25:22 +0800374 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
375 # number (0) when there are no services.
376 srv_idx = -1
377 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800378 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800379 if manifest['model'] == 'IPC':
380 # Assign signal value, the first 4 bits are reserved by FF-M
381 service['signal_value'] = (1 << (srv_idx + 4))
382 else:
383 # Signals of SFN Partitions are SPM internal only, does not
384 # need to reserve 4 bits.
385 service['signal_value'] = (1 << srv_idx)
386 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800387 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800388 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800389
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800390 # Calculate the number of mmio region
391 mmio_region_list = manifest.get('mmio_regions', [])
392 partition_statistics['mmio_region_num'] += len(mmio_region_list)
393
Kevin Peng5c3fee72022-02-16 22:25:22 +0800394 # Set initial value to -1 to make (irq + 1) reflect the correct
395 # number (0) when there are no irqs.
396 irq_idx = -1
397 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
398 # Assign signal value, from the most significant bit
399 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800400 if irq.get('handling', None) == 'FLIH':
401 partition_statistics['flih_num'] += 1
402 else:
403 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800404 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
405
406 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
407 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
408 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800409
Kevin Peng65064c52021-10-27 17:12:17 +0800410 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800411
Kevin Peng4fade072021-10-26 17:57:50 +0800412 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800413 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800414 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800415 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800416
Kevin Peng5bc82d22021-10-19 11:18:40 +0800417 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
418 '{}.h'.format(manifest_out_basename))\
419 .replace('\\', '/')
420 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
421 'intermedia_{}.c'.format(manifest_out_basename))\
422 .replace('\\', '/')
423 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
424 'load_info_{}.c'.format(manifest_out_basename))\
425 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800426 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800427
Kevin Peng5bc82d22021-10-19 11:18:40 +0800428 partition_list.append({'manifest': manifest, 'attr': manifest_item,
429 'manifest_out_basename': manifest_out_basename,
430 'header_file': manifest_head_file,
431 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800432 'loadinfo_file': load_info_file,
chesun0122abf0a2023-10-17 13:42:16 +0800433 'output_dir': output_dir,
434 'numbered_priority': numbered_priority})
Ken Liu861b0782021-05-22 13:15:08 +0800435
Chris Brand4b69fcf2022-06-06 09:37:49 -0700436 logging.info("------------ Display partition configuration - end ------------")
437
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800438 check_circular_dependency(partition_list, service_partition_map)
439
Kevin Peng56b0ea62021-10-18 11:32:57 +0800440 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800441 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800442 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800443 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800444 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800445 pid_list.append(pid)
446
Kevin Peng9f1a7542022-02-07 16:32:27 +0800447 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800448 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800449 if len(partition_statistics['ipc_partitions']) > 0:
450 logging.error('SFN backend does not support IPC Partitions:')
451 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800452 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800453
454 if isolation_level > 1:
455 logging.error('SFN backend does not support high isolation levels.')
456 exit(1)
457
Kevin Peng9f1a7542022-02-07 16:32:27 +0800458 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800459 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800460 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800461
462 if partition_statistics['connection_based_srv_num'] > 0:
463 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
464
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800465 if partition_statistics['mmio_region_num'] > 0:
466 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
467
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800468 if partition_statistics['flih_num'] > 0:
469 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200470 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800471 config_impl['CONFIG_TFM_SLIH_API'] = 1
472
Kevin Peng5bc82d22021-10-19 11:18:40 +0800473 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800474 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800475 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100476
Kevin Peng5bc82d22021-10-19 11:18:40 +0800477 return context
Ken Liu861b0782021-05-22 13:15:08 +0800478
479def gen_per_partition_files(context):
480 """
481 Generate per-partition files
482
483 Parameters
484 ----------
485 context:
486 context contains partition infos
487 """
488
Kevin Peng5bc82d22021-10-19 11:18:40 +0800489 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800490 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800491 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800492
Kevin Peng5bc82d22021-10-19 11:18:40 +0800493 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
494 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
495 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800496
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500497 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800498
499 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800500 partition_context['manifest'] = one_partition['manifest']
501 partition_context['attr'] = one_partition['attr']
502 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
chesun0122abf0a2023-10-17 13:42:16 +0800503 partition_context['numbered_priority'] = one_partition['numbered_priority']
Ken Liu861b0782021-05-22 13:15:08 +0800504
BohdanHunko6cea95d2022-08-16 15:33:51 +0300505 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800506 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800507 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800508 if not os.path.exists(outfile_path):
509 os.makedirs(outfile_path)
510
Kevin Peng5bc82d22021-10-19 11:18:40 +0800511 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
512 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800513 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800514
Ken Liu861b0782021-05-22 13:15:08 +0800515 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800516 if not os.path.exists(intermediafile_path):
517 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800518 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
519 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800520 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800521
Ken Liu861b0782021-05-22 13:15:08 +0800522 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800523 if not os.path.exists(infofile_path):
524 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800525 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
526 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800527 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800528
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500529 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800530
Ken Liu861b0782021-05-22 13:15:08 +0800531def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800532 """
533 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800534
535 Parameters
536 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100537 gen_file_lists:
538 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800539 """
Kevin Peng655f2392019-11-27 16:33:02 +0800540 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800541
Raef Colesf42f0882020-07-10 10:01:58 +0100542 for f in gen_file_lists:
543 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800544 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800545 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800546
Kevin Peng655f2392019-11-27 16:33:02 +0800547 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000548 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800549 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000550 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800551 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800552
Kevin Peng4fade072021-10-26 17:57:50 +0800553 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800554
Ken Liu861b0782021-05-22 13:15:08 +0800555 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800556 if not os.path.exists(outfile_path):
557 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800558
Kevin Peng655f2392019-11-27 16:33:02 +0800559 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800560
Kevin Peng5bc82d22021-10-19 11:18:40 +0800561 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800562 outfile.write(template.render(context))
563 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800564
Kevin Pengce99e5d2021-11-09 18:06:53 +0800565def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800566 """
567 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800568 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800569 Valid stateless handle in service will be converted to an index. If the
570 stateless handle is set as "auto", or not set, framework will allocate a
571 valid index for the service.
572 Framework puts each service into a reordered stateless service list at
573 position of "index". Other unused positions are left None.
Ken Liu50948382022-10-27 12:45:53 +0800574
575 Keep the variable names start with upper case 'STATIC_HANDLE_' the same
576 as the preprocessors in C sources. This could easier the upcomping
577 modification when developer searches these definitions for modification.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800578 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800579
Kevin Pengc05319d2021-04-22 22:59:35 +0800580 collected_stateless_services = []
Ken Liu50948382022-10-27 12:45:53 +0800581 STATIC_HANDLE_NUM_LIMIT = 32
Mingyang Suna1ca6112021-01-11 11:34:59 +0800582
583 # Collect all stateless services first.
584 for partition in partitions:
585 # Skip the FF-M 1.0 partitions
586 if partition['manifest']['psa_framework_version'] < 1.1:
587 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800588
589 service_list = partition['manifest'].get('services', [])
590
591 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800592 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800593 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800594
Kevin Pengc05319d2021-04-22 22:59:35 +0800595 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800596 return []
597
Ken Liu50948382022-10-27 12:45:53 +0800598 if len(collected_stateless_services) > STATIC_HANDLE_NUM_LIMIT:
599 raise Exception('Stateless service numbers range exceed {number}.'.format(number=STATIC_HANDLE_NUM_LIMIT))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800600
601 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800602 Allocate an empty stateless service list to store services.
603 Use "handle - 1" as the index for service, since handle value starts from
604 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800605 """
Ken Liu50948382022-10-27 12:45:53 +0800606 reordered_stateless_services = [None] * STATIC_HANDLE_NUM_LIMIT
Kevin Pengc05319d2021-04-22 22:59:35 +0800607 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800608
Kevin Pengc05319d2021-04-22 22:59:35 +0800609 for service in collected_stateless_services:
610 # If not set, it is "auto" by default
611 if 'stateless_handle' not in service:
612 auto_alloc_services.append(service)
613 continue
614
Mingyang Sun4ecea992021-03-30 17:56:26 +0800615 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800616
Mingyang Sun4ecea992021-03-30 17:56:26 +0800617 # Fill in service list with specified stateless handle, otherwise skip
618 if isinstance(service_handle, int):
Ken Liu50948382022-10-27 12:45:53 +0800619 if service_handle < 1 or service_handle > STATIC_HANDLE_NUM_LIMIT:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800620 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800621 # Convert handle index to reordered service list index
622 service_handle = service_handle - 1
623
624 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800625 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800626 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800627 elif service_handle == 'auto':
628 auto_alloc_services.append(service)
629 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800630 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800631
Xinyu Zhangb2d4ed42023-02-14 11:43:16 +0800632 STATIC_HANDLE_IDX_BIT_WIDTH = 5
Kevin Pengce99e5d2021-11-09 18:06:53 +0800633 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
Ken Liu50948382022-10-27 12:45:53 +0800634 STATIC_HANDLE_INDICATOR_OFFSET = 30
635 STATIC_HANDLE_VER_OFFSET = 8
636 STATIC_HANDLE_VER_BIT_WIDTH = 8
Kevin Pengce99e5d2021-11-09 18:06:53 +0800637 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
638
Mingyang Sun4ecea992021-03-30 17:56:26 +0800639 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu50948382022-10-27 12:45:53 +0800640 for i in range(0, STATIC_HANDLE_NUM_LIMIT):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800641 service = reordered_stateless_services[i]
642
Kevin Pengc05319d2021-04-22 22:59:35 +0800643 if service == None and len(auto_alloc_services) > 0:
644 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800645
Mingyang Sun453ad402021-03-17 17:58:33 +0800646 """
647 Encode stateless flag and version into stateless handle
Mingyang Sun453ad402021-03-17 17:58:33 +0800648 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800649 stateless_handle_value = 0
650 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800651 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800652 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800653 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
654 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800655 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800656 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800657 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800658
Mingyang Sun4ecea992021-03-30 17:56:26 +0800659 reordered_stateless_services[i] = service
660
661 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800662
Kevin Peng655f2392019-11-27 16:33:02 +0800663def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000664 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
665 epilog='Note that environment variables in template files will be replaced with their values')
666
Kevin Peng655f2392019-11-27 16:33:02 +0800667 parser.add_argument('-o', '--outdir'
668 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800669 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800670 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800671 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800672
Kevin Peng5bc82d22021-10-19 11:18:40 +0800673 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100674 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800675 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100676 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800677 , metavar='manifest list'
678 , help='A list of Secure Partition manifest lists and their original paths.\n\
679 The manifest lists might be processed by CMake and\n\
680 the path might be different to the original one\n\
681 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800682
683 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100684 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800685 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100686 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800687 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700688 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800689
Kevin Pengfb1761b2022-05-12 12:11:31 +0800690 parser.add_argument('-c', '--config-files'
691 , nargs='+'
692 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800693 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800694 , metavar='config-files'
695 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800696
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500697 parser.add_argument('-q', '--quiet'
698 , dest='quiet'
699 , required=False
700 , default=False
701 , action='store_true'
702 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800703
704 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800705
Kevin Peng655f2392019-11-27 16:33:02 +0800706 return args
707
708ENV = Environment(
709 loader = TemplateLoader(),
710 autoescape = select_autoescape(['html', 'xml']),
711 lstrip_blocks = True,
712 trim_blocks = True,
713 keep_trailing_newline = True
714 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100715
Miklos Balint470919c2018-05-22 17:51:29 +0200716def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100717 """
718 The entry point of the script.
719
720 Generates the output files based on the templates and the manifests.
721 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800722
Kevin Peng655f2392019-11-27 16:33:02 +0800723 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800724
Kevin Peng655f2392019-11-27 16:33:02 +0800725 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800726
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500727 logging.basicConfig(format='%(message)s'
728 , level=logging.WARNING if args.quiet else logging.INFO)
729
Kevin Peng5bc82d22021-10-19 11:18:40 +0800730 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800731
Kevin Peng5bc82d22021-10-19 11:18:40 +0800732 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
733 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800734
Shawn Shana9ad1e02019-08-07 15:49:48 +0800735 """
Kevin Peng655f2392019-11-27 16:33:02 +0800736 Relative path to TF-M root folder is supported in the manifests
737 and default value of manifest list and generated file list are relative to TF-M root folder as well,
738 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800739 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800740 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 +0800741 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800742 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800743
Kevin Peng76c0c162022-02-09 22:49:06 +0800744 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800745 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100746
Edison Ai6e3f2a32019-06-11 15:29:05 +0800747 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800748 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200749
Kevin Peng655f2392019-11-27 16:33:02 +0800750 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800751
Ken Liu861b0782021-05-22 13:15:08 +0800752 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800753 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200754
Kevin Peng5bc82d22021-10-19 11:18:40 +0800755if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200756 main()