blob: 4b8ddc942611c2d38be2539676fa2d7abb225e97 [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', \
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
Jamie Foxb15418a2024-01-18 11:10:20 +0000369 if (pid == None or pid >= TFM_PID_BASE) and not manifest['ns_agent']:
370 # Count the number of IPC/SFN partitions (excluding TF-M internal
371 # and agent partitions)
Kevin Peng47c26ec2022-03-11 11:49:52 +0800372 if manifest['model'] == 'IPC':
373 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800374
Kevin Peng5c3fee72022-02-16 22:25:22 +0800375 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
376 # number (0) when there are no services.
377 srv_idx = -1
378 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800379 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800380 if manifest['model'] == 'IPC':
381 # Assign signal value, the first 4 bits are reserved by FF-M
382 service['signal_value'] = (1 << (srv_idx + 4))
383 else:
384 # Signals of SFN Partitions are SPM internal only, does not
385 # need to reserve 4 bits.
386 service['signal_value'] = (1 << srv_idx)
387 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800388 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800389 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800390
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800391 # Calculate the number of mmio region
392 mmio_region_list = manifest.get('mmio_regions', [])
393 partition_statistics['mmio_region_num'] += len(mmio_region_list)
394
Kevin Peng5c3fee72022-02-16 22:25:22 +0800395 # Set initial value to -1 to make (irq + 1) reflect the correct
396 # number (0) when there are no irqs.
397 irq_idx = -1
398 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
399 # Assign signal value, from the most significant bit
400 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800401 if irq.get('handling', None) == 'FLIH':
402 partition_statistics['flih_num'] += 1
403 else:
404 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800405 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
406
407 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
408 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
409 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800410
Kevin Peng65064c52021-10-27 17:12:17 +0800411 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800412
Kevin Peng4fade072021-10-26 17:57:50 +0800413 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800414 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800415 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800416 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800417
Kevin Peng5bc82d22021-10-19 11:18:40 +0800418 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
419 '{}.h'.format(manifest_out_basename))\
420 .replace('\\', '/')
421 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
422 'intermedia_{}.c'.format(manifest_out_basename))\
423 .replace('\\', '/')
424 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
425 'load_info_{}.c'.format(manifest_out_basename))\
426 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800427 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800428
Kevin Peng5bc82d22021-10-19 11:18:40 +0800429 partition_list.append({'manifest': manifest, 'attr': manifest_item,
430 'manifest_out_basename': manifest_out_basename,
431 'header_file': manifest_head_file,
432 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800433 'loadinfo_file': load_info_file,
chesun0122abf0a2023-10-17 13:42:16 +0800434 'output_dir': output_dir,
435 'numbered_priority': numbered_priority})
Ken Liu861b0782021-05-22 13:15:08 +0800436
Chris Brand4b69fcf2022-06-06 09:37:49 -0700437 logging.info("------------ Display partition configuration - end ------------")
438
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800439 check_circular_dependency(partition_list, service_partition_map)
440
Kevin Peng56b0ea62021-10-18 11:32:57 +0800441 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800442 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800443 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800444 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800445 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800446 pid_list.append(pid)
447
Kevin Peng9f1a7542022-02-07 16:32:27 +0800448 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800449 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800450 if len(partition_statistics['ipc_partitions']) > 0:
451 logging.error('SFN backend does not support IPC Partitions:')
452 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800453 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800454
455 if isolation_level > 1:
456 logging.error('SFN backend does not support high isolation levels.')
457 exit(1)
458
Kevin Peng9f1a7542022-02-07 16:32:27 +0800459 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800460 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800461 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800462
463 if partition_statistics['connection_based_srv_num'] > 0:
464 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
465
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800466 if partition_statistics['mmio_region_num'] > 0:
467 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
468
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800469 if partition_statistics['flih_num'] > 0:
470 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200471 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800472 config_impl['CONFIG_TFM_SLIH_API'] = 1
473
Kevin Peng5bc82d22021-10-19 11:18:40 +0800474 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800475 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800476 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100477
Kevin Peng5bc82d22021-10-19 11:18:40 +0800478 return context
Ken Liu861b0782021-05-22 13:15:08 +0800479
480def gen_per_partition_files(context):
481 """
482 Generate per-partition files
483
484 Parameters
485 ----------
486 context:
487 context contains partition infos
488 """
489
Kevin Peng5bc82d22021-10-19 11:18:40 +0800490 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800491 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800492 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800493
Kevin Peng5bc82d22021-10-19 11:18:40 +0800494 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
495 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
496 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800497
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500498 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800499
500 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800501 partition_context['manifest'] = one_partition['manifest']
502 partition_context['attr'] = one_partition['attr']
503 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
chesun0122abf0a2023-10-17 13:42:16 +0800504 partition_context['numbered_priority'] = one_partition['numbered_priority']
Ken Liu861b0782021-05-22 13:15:08 +0800505
BohdanHunko6cea95d2022-08-16 15:33:51 +0300506 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800507 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800508 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800509 if not os.path.exists(outfile_path):
510 os.makedirs(outfile_path)
511
Kevin Peng5bc82d22021-10-19 11:18:40 +0800512 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
513 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800514 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800515
Ken Liu861b0782021-05-22 13:15:08 +0800516 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800517 if not os.path.exists(intermediafile_path):
518 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800519 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
520 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800521 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800522
Ken Liu861b0782021-05-22 13:15:08 +0800523 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800524 if not os.path.exists(infofile_path):
525 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800526 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
527 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800528 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800529
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500530 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800531
Ken Liu861b0782021-05-22 13:15:08 +0800532def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800533 """
534 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800535
536 Parameters
537 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100538 gen_file_lists:
539 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800540 """
Kevin Peng655f2392019-11-27 16:33:02 +0800541 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800542
Raef Colesf42f0882020-07-10 10:01:58 +0100543 for f in gen_file_lists:
544 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800545 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800546 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800547
Kevin Peng655f2392019-11-27 16:33:02 +0800548 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000549 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800550 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000551 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800552 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800553
Kevin Peng4fade072021-10-26 17:57:50 +0800554 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800555
Ken Liu861b0782021-05-22 13:15:08 +0800556 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800557 if not os.path.exists(outfile_path):
558 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800559
Kevin Peng655f2392019-11-27 16:33:02 +0800560 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800561
Kevin Peng5bc82d22021-10-19 11:18:40 +0800562 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800563 outfile.write(template.render(context))
564 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800565
Kevin Pengce99e5d2021-11-09 18:06:53 +0800566def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800567 """
568 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800569 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800570 Valid stateless handle in service will be converted to an index. If the
571 stateless handle is set as "auto", or not set, framework will allocate a
572 valid index for the service.
573 Framework puts each service into a reordered stateless service list at
574 position of "index". Other unused positions are left None.
Ken Liu50948382022-10-27 12:45:53 +0800575
576 Keep the variable names start with upper case 'STATIC_HANDLE_' the same
577 as the preprocessors in C sources. This could easier the upcomping
578 modification when developer searches these definitions for modification.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800579 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800580
Kevin Pengc05319d2021-04-22 22:59:35 +0800581 collected_stateless_services = []
Ken Liu50948382022-10-27 12:45:53 +0800582 STATIC_HANDLE_NUM_LIMIT = 32
Mingyang Suna1ca6112021-01-11 11:34:59 +0800583
584 # Collect all stateless services first.
585 for partition in partitions:
586 # Skip the FF-M 1.0 partitions
587 if partition['manifest']['psa_framework_version'] < 1.1:
588 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800589
590 service_list = partition['manifest'].get('services', [])
591
592 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800593 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800594 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800595
Kevin Pengc05319d2021-04-22 22:59:35 +0800596 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800597 return []
598
Ken Liu50948382022-10-27 12:45:53 +0800599 if len(collected_stateless_services) > STATIC_HANDLE_NUM_LIMIT:
600 raise Exception('Stateless service numbers range exceed {number}.'.format(number=STATIC_HANDLE_NUM_LIMIT))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800601
602 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800603 Allocate an empty stateless service list to store services.
604 Use "handle - 1" as the index for service, since handle value starts from
605 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800606 """
Ken Liu50948382022-10-27 12:45:53 +0800607 reordered_stateless_services = [None] * STATIC_HANDLE_NUM_LIMIT
Kevin Pengc05319d2021-04-22 22:59:35 +0800608 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800609
Kevin Pengc05319d2021-04-22 22:59:35 +0800610 for service in collected_stateless_services:
611 # If not set, it is "auto" by default
612 if 'stateless_handle' not in service:
613 auto_alloc_services.append(service)
614 continue
615
Mingyang Sun4ecea992021-03-30 17:56:26 +0800616 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800617
Mingyang Sun4ecea992021-03-30 17:56:26 +0800618 # Fill in service list with specified stateless handle, otherwise skip
619 if isinstance(service_handle, int):
Ken Liu50948382022-10-27 12:45:53 +0800620 if service_handle < 1 or service_handle > STATIC_HANDLE_NUM_LIMIT:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800621 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800622 # Convert handle index to reordered service list index
623 service_handle = service_handle - 1
624
625 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800626 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800627 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800628 elif service_handle == 'auto':
629 auto_alloc_services.append(service)
630 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800631 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800632
Xinyu Zhangb2d4ed42023-02-14 11:43:16 +0800633 STATIC_HANDLE_IDX_BIT_WIDTH = 5
Kevin Pengce99e5d2021-11-09 18:06:53 +0800634 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
Ken Liu50948382022-10-27 12:45:53 +0800635 STATIC_HANDLE_INDICATOR_OFFSET = 30
636 STATIC_HANDLE_VER_OFFSET = 8
637 STATIC_HANDLE_VER_BIT_WIDTH = 8
Kevin Pengce99e5d2021-11-09 18:06:53 +0800638 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
639
Mingyang Sun4ecea992021-03-30 17:56:26 +0800640 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu50948382022-10-27 12:45:53 +0800641 for i in range(0, STATIC_HANDLE_NUM_LIMIT):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800642 service = reordered_stateless_services[i]
643
Kevin Pengc05319d2021-04-22 22:59:35 +0800644 if service == None and len(auto_alloc_services) > 0:
645 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800646
Mingyang Sun453ad402021-03-17 17:58:33 +0800647 """
648 Encode stateless flag and version into stateless handle
Mingyang Sun453ad402021-03-17 17:58:33 +0800649 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800650 stateless_handle_value = 0
651 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800652 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800653 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800654 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
655 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800656 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800657 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800658 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800659
Mingyang Sun4ecea992021-03-30 17:56:26 +0800660 reordered_stateless_services[i] = service
661
662 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800663
Kevin Peng655f2392019-11-27 16:33:02 +0800664def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000665 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
666 epilog='Note that environment variables in template files will be replaced with their values')
667
Kevin Peng655f2392019-11-27 16:33:02 +0800668 parser.add_argument('-o', '--outdir'
669 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800670 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800671 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800672 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800673
Kevin Peng5bc82d22021-10-19 11:18:40 +0800674 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100675 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800676 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100677 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800678 , metavar='manifest list'
679 , help='A list of Secure Partition manifest lists and their original paths.\n\
680 The manifest lists might be processed by CMake and\n\
681 the path might be different to the original one\n\
682 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800683
684 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100685 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800686 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100687 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800688 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700689 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800690
Kevin Pengfb1761b2022-05-12 12:11:31 +0800691 parser.add_argument('-c', '--config-files'
692 , nargs='+'
693 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800694 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800695 , metavar='config-files'
696 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800697
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500698 parser.add_argument('-q', '--quiet'
699 , dest='quiet'
700 , required=False
701 , default=False
702 , action='store_true'
703 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800704
705 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800706
Kevin Peng655f2392019-11-27 16:33:02 +0800707 return args
708
709ENV = Environment(
710 loader = TemplateLoader(),
711 autoescape = select_autoescape(['html', 'xml']),
712 lstrip_blocks = True,
713 trim_blocks = True,
714 keep_trailing_newline = True
715 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100716
Miklos Balint470919c2018-05-22 17:51:29 +0200717def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100718 """
719 The entry point of the script.
720
721 Generates the output files based on the templates and the manifests.
722 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800723
Kevin Peng655f2392019-11-27 16:33:02 +0800724 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800725
Kevin Peng655f2392019-11-27 16:33:02 +0800726 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800727
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500728 logging.basicConfig(format='%(message)s'
729 , level=logging.WARNING if args.quiet else logging.INFO)
730
Kevin Peng5bc82d22021-10-19 11:18:40 +0800731 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800732
Kevin Peng5bc82d22021-10-19 11:18:40 +0800733 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
734 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800735
Shawn Shana9ad1e02019-08-07 15:49:48 +0800736 """
Kevin Peng655f2392019-11-27 16:33:02 +0800737 Relative path to TF-M root folder is supported in the manifests
738 and default value of manifest list and generated file list are relative to TF-M root folder as well,
739 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800740 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800741 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 +0800742 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800743 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800744
Kevin Peng76c0c162022-02-09 22:49:06 +0800745 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800746 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100747
Edison Ai6e3f2a32019-06-11 15:29:05 +0800748 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800749 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200750
Kevin Peng655f2392019-11-27 16:33:02 +0800751 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800752
Ken Liu861b0782021-05-22 13:15:08 +0800753 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800754 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200755
Kevin Peng5bc82d22021-10-19 11:18:40 +0800756if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200757 main()