blob: 755f2a8db5a4c82d3b084d281e4d9a57945e7905 [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
Xinyu Zhang90f08dc2022-01-12 15:55:17 +08002# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
Chris Brandf1d6b6f2022-07-22 11:49:01 -07003# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4# or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
Miklos Balint470919c2018-05-22 17:51:29 +02005#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8#-------------------------------------------------------------------------------
9
10import os
Mate Toth-Pal36f21842018-11-08 16:12:51 +010011import io
Kevin Pengce99e5d2021-11-09 18:06:53 +080012import re
Shawn Shana9ad1e02019-08-07 15:49:48 +080013import sys
14import argparse
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050015import logging
Ken Liu1f345b02020-05-30 21:11:05 +080016from jinja2 import Environment, BaseLoader, select_autoescape, TemplateNotFound
Miklos Balint470919c2018-05-22 17:51:29 +020017
18try:
19 import yaml
20except ImportError as e:
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -050021 logging.error (str(e) + " To install it, type:")
22 logging.error ("pip install PyYAML")
Miklos Balint470919c2018-05-22 17:51:29 +020023 exit(1)
24
Edison Ai48b2d9e2019-06-24 14:39:45 +080025donotedit_warning = \
Sherry Zhangf58f2bd2022-01-10 17:21:11 +080026 ' WARNING: This is an auto-generated file. Do not edit! '
Kevin Peng655f2392019-11-27 16:33:02 +080027
Kevin Pengce99e5d2021-11-09 18:06:53 +080028TFM_ROOT_DIR = os.path.join(sys.path[0], '..')
Kevin Peng655f2392019-11-27 16:33:02 +080029OUT_DIR = None # The root directory that files are generated to
Edison Ai48b2d9e2019-06-24 14:39:45 +080030
Sherry Zhang87e6d2e2021-12-27 14:48:59 +080031# PID[0, TFM_PID_BASE - 1] are reserved for TF-M SPM and test usages
Kevin Pengce99e5d2021-11-09 18:06:53 +080032TFM_PID_BASE = 256
33
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010034# variable for checking for duplicated sid
35sid_list = []
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',
271 'CONFIG_TFM_PSA_API_SFN_CALL' : '0',
272 'CONFIG_TFM_PSA_API_CROSS_CALL' : '0',
273 'CONFIG_TFM_PSA_API_SUPERVISOR_CALL' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800274 'CONFIG_TFM_CONNECTION_BASED_SERVICE_API' : '0',
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800275 'CONFIG_TFM_MMIO_REGION_ENABLE' : '0',
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800276 'CONFIG_TFM_FLIH_API' : '0',
277 'CONFIG_TFM_SLIH_API' : '0'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800278 }
Kevin Peng655f2392019-11-27 16:33:02 +0800279
Kevin Pengfb1761b2022-05-12 12:11:31 +0800280 isolation_level = int(configs['TFM_ISOLATION_LEVEL'], base = 10)
281 backend = configs['CONFIG_TFM_SPM_BACKEND']
282
Kevin Peng65064c52021-10-27 17:12:17 +0800283 # Get all the manifests information as a dictionary
284 for i, item in enumerate(manifest_lists):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800285 if not os.path.isfile(item):
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500286 logging.error('Manifest list item [{}] must be a file'.format(i))
Kevin Peng65064c52021-10-27 17:12:17 +0800287 exit(1)
Kevin Peng655f2392019-11-27 16:33:02 +0800288
Kevin Peng65064c52021-10-27 17:12:17 +0800289 # The manifest list file generated by configure_file()
290 with open(item) as manifest_list_yaml_file:
291 manifest_dic = yaml.safe_load(manifest_list_yaml_file)['manifest_list']
292 for dict in manifest_dic:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800293 # Replace environment variables in the manifest path and convert to absolute path.
294 # If it's already abspath, the path will not be changed.
295 manifest_path = os.path.join(os.path.dirname(item), # path of manifest list
296 os.path.expandvars(dict['manifest']))\
297 .replace('\\', '/')
298 dict['manifest'] = manifest_path
Kevin Peng65064c52021-10-27 17:12:17 +0800299 all_manifests.append(dict)
300
Chris Brand4b69fcf2022-06-06 09:37:49 -0700301 logging.info("------------ Display partition configuration - start ------------")
302
Kevin Peng65064c52021-10-27 17:12:17 +0800303 # Parse the manifests
304 for i, manifest_item in enumerate(all_manifests):
Kevin Pengfb1761b2022-05-12 12:11:31 +0800305 valid_enabled_conditions = ['1', 'on', 'true', 'enabled']
306 valid_disabled_conditions = ['0', 'off', 'false', 'disabled', '']
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800307 is_enabled = ''
308
309 if 'conditional' in manifest_item.keys():
Kevin Pengfb1761b2022-05-12 12:11:31 +0800310 if manifest_item['conditional'] not in configs.keys():
311 logging.error('Configuration "{}" is not defined!'.format(manifest_item['conditional']))
312 exit(1)
313 is_enabled = configs[manifest_item['conditional']].lower()
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800314 else:
Kevin Pengfb1761b2022-05-12 12:11:31 +0800315 # Partitions without 'conditional' is always on
316 is_enabled = '1'
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800317
318 if is_enabled in valid_disabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300319 logging.info(" {:40s} OFF".format(manifest_item['description']))
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800320 continue
Chris Brand4b69fcf2022-06-06 09:37:49 -0700321 elif is_enabled in valid_enabled_conditions:
BohdanHunko6cea95d2022-08-16 15:33:51 +0300322 logging.info(" {:40s} ON".format(manifest_item['description']))
Chris Brand4b69fcf2022-06-06 09:37:49 -0700323 else:
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800324 raise Exception('Invalid "conditional" attribute: "{}" for {}. '
325 'Please set to one of {} or {}, case-insensitive.'\
326 .format(manifest_item['conditional'],
BohdanHunko6cea95d2022-08-16 15:33:51 +0300327 manifest_item['description'],
Kevin Peng68d9a3a2021-10-18 11:39:54 +0800328 valid_enabled_conditions, valid_disabled_conditions))
329
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800330 # Check if partition ID is manually set
331 if 'pid' not in manifest_item.keys():
332 no_pid_manifest_idx.append(i)
Kevin Peng8849b6a2021-11-09 14:17:35 +0800333 pid = None
Kevin Peng56b0ea62021-10-18 11:32:57 +0800334 else:
Kevin Peng8849b6a2021-11-09 14:17:35 +0800335 pid = manifest_item['pid']
336
337 # Check if partition ID is duplicated
338 if pid in pid_list:
Antonio de Angelisbaa27642022-05-25 11:07:12 +0100339 raise Exception('PID No. {} has already been used!'.format(pid))
Kevin Peng8849b6a2021-11-09 14:17:35 +0800340 else:
341 pid_list.append(pid)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800342
Kevin Pengfb1761b2022-05-12 12:11:31 +0800343 manifest_path = manifest_item['manifest']
Kevin Peng5bc82d22021-10-19 11:18:40 +0800344 with open(manifest_path) as manifest_file:
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800345 manifest = yaml.safe_load(manifest_file)
chesun012345aa52023-04-18 17:31:53 +0800346 # check manifest attribute validity
347 manifest_attribute_check(manifest, manifest_item)
348
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800349 if manifest.get('model', None) == 'dual':
350 # If a Partition supports both models, it can set the "model" to "backend".
351 # The actual model used follows the backend being used.
352 manifest['model'] = backend
353 manifest = manifest_validation(manifest, pid)
Kevin Peng655f2392019-11-27 16:33:02 +0800354
Kevin Pengce99e5d2021-11-09 18:06:53 +0800355 if pid == None or pid >= TFM_PID_BASE:
Kevin Pengd08f3ba2021-11-18 15:18:56 +0800356 # Count the number of IPC/SFN partitions
Kevin Peng47c26ec2022-03-11 11:49:52 +0800357 if manifest['model'] == 'IPC':
358 partition_statistics['ipc_partitions'].append(manifest['name'])
Mingyang Suneab7eae2021-09-30 13:06:52 +0800359
Kevin Peng5c3fee72022-02-16 22:25:22 +0800360 # Set initial value to -1 to make (srv_idx + 1) reflect the correct
361 # number (0) when there are no services.
362 srv_idx = -1
363 for srv_idx, service in enumerate(manifest.get('services', [])):
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800364 service_partition_map[service['name']] = manifest['name']
Kevin Peng5c3fee72022-02-16 22:25:22 +0800365 if manifest['model'] == 'IPC':
366 # Assign signal value, the first 4 bits are reserved by FF-M
367 service['signal_value'] = (1 << (srv_idx + 4))
368 else:
369 # Signals of SFN Partitions are SPM internal only, does not
370 # need to reserve 4 bits.
371 service['signal_value'] = (1 << srv_idx)
372 if service['connection_based']:
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800373 partition_statistics['connection_based_srv_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800374 logging.debug('{} has {} services'.format(manifest['name'], srv_idx +1))
Xinyu Zhang2bc4d572021-12-27 16:37:46 +0800375
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800376 # Calculate the number of mmio region
377 mmio_region_list = manifest.get('mmio_regions', [])
378 partition_statistics['mmio_region_num'] += len(mmio_region_list)
379
Kevin Peng5c3fee72022-02-16 22:25:22 +0800380 # Set initial value to -1 to make (irq + 1) reflect the correct
381 # number (0) when there are no irqs.
382 irq_idx = -1
383 for irq_idx, irq in enumerate(manifest.get('irqs', [])):
384 # Assign signal value, from the most significant bit
385 irq['signal_value'] = (1 << (31 - irq_idx))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800386 if irq.get('handling', None) == 'FLIH':
387 partition_statistics['flih_num'] += 1
388 else:
389 partition_statistics['slih_num'] += 1
Kevin Peng5c3fee72022-02-16 22:25:22 +0800390 logging.debug('{} has {} IRQS'.format(manifest['name'], irq_idx +1))
391
392 if ((srv_idx + 1) + (irq_idx + 1)) > 28:
393 raise Exception('Total number of Services and IRQs of {} exceeds the limit (28)'
394 .format(manifest['name']))
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800395
Kevin Peng65064c52021-10-27 17:12:17 +0800396 manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
Kevin Peng655f2392019-11-27 16:33:02 +0800397
Kevin Peng4fade072021-10-26 17:57:50 +0800398 if 'output_path' in manifest_item:
Kevin Peng4fade072021-10-26 17:57:50 +0800399 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800400 else:
Kevin Peng65064c52021-10-27 17:12:17 +0800401 output_path = ''
David Hub2694202021-07-15 14:58:39 +0800402
Kevin Peng5bc82d22021-10-19 11:18:40 +0800403 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
404 '{}.h'.format(manifest_out_basename))\
405 .replace('\\', '/')
406 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
407 'intermedia_{}.c'.format(manifest_out_basename))\
408 .replace('\\', '/')
409 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
410 'load_info_{}.c'.format(manifest_out_basename))\
411 .replace('\\', '/')
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800412 output_dir = os.path.join(OUT_DIR, output_path).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800413
Kevin Peng5bc82d22021-10-19 11:18:40 +0800414 partition_list.append({'manifest': manifest, 'attr': manifest_item,
415 'manifest_out_basename': manifest_out_basename,
416 'header_file': manifest_head_file,
417 'intermedia_file': intermedia_file,
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800418 'loadinfo_file': load_info_file,
419 'output_dir':output_dir})
Ken Liu861b0782021-05-22 13:15:08 +0800420
Chris Brand4b69fcf2022-06-06 09:37:49 -0700421 logging.info("------------ Display partition configuration - end ------------")
422
Xinyu Zhang7d0a5c82022-05-16 18:15:11 +0800423 check_circular_dependency(partition_list, service_partition_map)
424
Kevin Peng56b0ea62021-10-18 11:32:57 +0800425 # Automatically assign PIDs for partitions without 'pid' attribute
Kevin Pengce99e5d2021-11-09 18:06:53 +0800426 pid = max(pid_list, default = TFM_PID_BASE - 1)
Kevin Peng56b0ea62021-10-18 11:32:57 +0800427 for idx in no_pid_manifest_idx:
Kevin Pengc424eec2021-06-25 17:26:11 +0800428 pid += 1
Kevin Peng65064c52021-10-27 17:12:17 +0800429 all_manifests[idx]['pid'] = pid
Kevin Peng56b0ea62021-10-18 11:32:57 +0800430 pid_list.append(pid)
431
Kevin Peng9f1a7542022-02-07 16:32:27 +0800432 # Set up configurations
Kevin Peng76c0c162022-02-09 22:49:06 +0800433 if backend == 'SFN':
Kevin Peng47c26ec2022-03-11 11:49:52 +0800434 if len(partition_statistics['ipc_partitions']) > 0:
435 logging.error('SFN backend does not support IPC Partitions:')
436 logging.error(partition_statistics['ipc_partitions'])
Kevin Peng9f1a7542022-02-07 16:32:27 +0800437 exit(1)
Kevin Peng76c0c162022-02-09 22:49:06 +0800438
439 if isolation_level > 1:
440 logging.error('SFN backend does not support high isolation levels.')
441 exit(1)
442
Kevin Peng9f1a7542022-02-07 16:32:27 +0800443 config_impl['CONFIG_TFM_SPM_BACKEND_SFN'] = '1'
444 config_impl['CONFIG_TFM_PSA_API_SFN_CALL'] = '1'
Kevin Peng76c0c162022-02-09 22:49:06 +0800445 elif backend == 'IPC':
Kevin Peng9f1a7542022-02-07 16:32:27 +0800446 config_impl['CONFIG_TFM_SPM_BACKEND_IPC'] = '1'
447 if isolation_level > 1:
448 config_impl['CONFIG_TFM_PSA_API_SUPERVISOR_CALL'] = '1'
449 else:
450 config_impl['CONFIG_TFM_PSA_API_CROSS_CALL'] = '1'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800451
452 if partition_statistics['connection_based_srv_num'] > 0:
453 config_impl['CONFIG_TFM_CONNECTION_BASED_SERVICE_API'] = 1
454
Sherry Zhang2ed48fd2022-09-06 11:33:22 +0800455 if partition_statistics['mmio_region_num'] > 0:
456 config_impl['CONFIG_TFM_MMIO_REGION_ENABLE'] = 1
457
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800458 if partition_statistics['flih_num'] > 0:
459 config_impl['CONFIG_TFM_FLIH_API'] = 1
Joakim Anderssoneec5cd32022-06-10 12:02:07 +0200460 if partition_statistics['slih_num'] > 0:
Mingyang Suned5fe7b2022-02-10 17:33:21 +0800461 config_impl['CONFIG_TFM_SLIH_API'] = 1
462
Kevin Peng5bc82d22021-10-19 11:18:40 +0800463 context['partitions'] = partition_list
Kevin Peng9f1a7542022-02-07 16:32:27 +0800464 context['config_impl'] = config_impl
Kevin Pengce99e5d2021-11-09 18:06:53 +0800465 context['stateless_services'] = process_stateless_services(partition_list)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100466
Kevin Peng5bc82d22021-10-19 11:18:40 +0800467 return context
Ken Liu861b0782021-05-22 13:15:08 +0800468
469def gen_per_partition_files(context):
470 """
471 Generate per-partition files
472
473 Parameters
474 ----------
475 context:
476 context contains partition infos
477 """
478
Kevin Peng5bc82d22021-10-19 11:18:40 +0800479 partition_context = {}
Sherry Zhangf58f2bd2022-01-10 17:21:11 +0800480 partition_context['utilities'] = context['utilities']
Sherry Zhangf865c4e2022-03-23 13:53:38 +0800481 partition_context['config_impl'] = context['config_impl']
Ken Liu861b0782021-05-22 13:15:08 +0800482
Kevin Peng5bc82d22021-10-19 11:18:40 +0800483 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
484 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
485 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800486
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500487 logging.info ("Start to generate partition files:")
Ken Liu861b0782021-05-22 13:15:08 +0800488
489 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800490 partition_context['manifest'] = one_partition['manifest']
491 partition_context['attr'] = one_partition['attr']
492 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
Ken Liu861b0782021-05-22 13:15:08 +0800493
BohdanHunko6cea95d2022-08-16 15:33:51 +0300494 logging.info ('Generating {} in {}'.format(one_partition['attr']['description'],
Jianliang Shen785ed5e2022-02-08 14:16:06 +0800495 one_partition['output_dir']))
Ken Liu861b0782021-05-22 13:15:08 +0800496 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800497 if not os.path.exists(outfile_path):
498 os.makedirs(outfile_path)
499
Kevin Peng5bc82d22021-10-19 11:18:40 +0800500 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
501 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800502 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800503
Ken Liu861b0782021-05-22 13:15:08 +0800504 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800505 if not os.path.exists(intermediafile_path):
506 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800507 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
508 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800509 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800510
Ken Liu861b0782021-05-22 13:15:08 +0800511 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800512 if not os.path.exists(infofile_path):
513 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800514 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
515 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800516 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800517
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500518 logging.info ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800519
Ken Liu861b0782021-05-22 13:15:08 +0800520def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800521 """
522 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800523
524 Parameters
525 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100526 gen_file_lists:
527 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800528 """
Kevin Peng655f2392019-11-27 16:33:02 +0800529 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800530
Raef Colesf42f0882020-07-10 10:01:58 +0100531 for f in gen_file_lists:
532 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800533 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800534 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800535
Kevin Peng655f2392019-11-27 16:33:02 +0800536 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000537 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800538 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000539 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800540 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800541
Kevin Peng4fade072021-10-26 17:57:50 +0800542 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800543
Ken Liu861b0782021-05-22 13:15:08 +0800544 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800545 if not os.path.exists(outfile_path):
546 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800547
Kevin Peng655f2392019-11-27 16:33:02 +0800548 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800549
Kevin Peng5bc82d22021-10-19 11:18:40 +0800550 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800551 outfile.write(template.render(context))
552 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800553
Kevin Pengce99e5d2021-11-09 18:06:53 +0800554def process_stateless_services(partitions):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800555 """
556 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800557 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800558 Valid stateless handle in service will be converted to an index. If the
559 stateless handle is set as "auto", or not set, framework will allocate a
560 valid index for the service.
561 Framework puts each service into a reordered stateless service list at
562 position of "index". Other unused positions are left None.
Ken Liu50948382022-10-27 12:45:53 +0800563
564 Keep the variable names start with upper case 'STATIC_HANDLE_' the same
565 as the preprocessors in C sources. This could easier the upcomping
566 modification when developer searches these definitions for modification.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800567 """
Kevin Pengce99e5d2021-11-09 18:06:53 +0800568
Kevin Pengc05319d2021-04-22 22:59:35 +0800569 collected_stateless_services = []
Ken Liu50948382022-10-27 12:45:53 +0800570 STATIC_HANDLE_NUM_LIMIT = 32
Mingyang Suna1ca6112021-01-11 11:34:59 +0800571
572 # Collect all stateless services first.
573 for partition in partitions:
574 # Skip the FF-M 1.0 partitions
575 if partition['manifest']['psa_framework_version'] < 1.1:
576 continue
Kevin Peng8849b6a2021-11-09 14:17:35 +0800577
578 service_list = partition['manifest'].get('services', [])
579
580 for service in service_list:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800581 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800582 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800583
Kevin Pengc05319d2021-04-22 22:59:35 +0800584 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800585 return []
586
Ken Liu50948382022-10-27 12:45:53 +0800587 if len(collected_stateless_services) > STATIC_HANDLE_NUM_LIMIT:
588 raise Exception('Stateless service numbers range exceed {number}.'.format(number=STATIC_HANDLE_NUM_LIMIT))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800589
590 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800591 Allocate an empty stateless service list to store services.
592 Use "handle - 1" as the index for service, since handle value starts from
593 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800594 """
Ken Liu50948382022-10-27 12:45:53 +0800595 reordered_stateless_services = [None] * STATIC_HANDLE_NUM_LIMIT
Kevin Pengc05319d2021-04-22 22:59:35 +0800596 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800597
Kevin Pengc05319d2021-04-22 22:59:35 +0800598 for service in collected_stateless_services:
599 # If not set, it is "auto" by default
600 if 'stateless_handle' not in service:
601 auto_alloc_services.append(service)
602 continue
603
Mingyang Sun4ecea992021-03-30 17:56:26 +0800604 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800605
Mingyang Sun4ecea992021-03-30 17:56:26 +0800606 # Fill in service list with specified stateless handle, otherwise skip
607 if isinstance(service_handle, int):
Ken Liu50948382022-10-27 12:45:53 +0800608 if service_handle < 1 or service_handle > STATIC_HANDLE_NUM_LIMIT:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800609 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800610 # Convert handle index to reordered service list index
611 service_handle = service_handle - 1
612
613 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800614 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800615 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800616 elif service_handle == 'auto':
617 auto_alloc_services.append(service)
618 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800619 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800620
Xinyu Zhangb2d4ed42023-02-14 11:43:16 +0800621 STATIC_HANDLE_IDX_BIT_WIDTH = 5
Kevin Pengce99e5d2021-11-09 18:06:53 +0800622 STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
Ken Liu50948382022-10-27 12:45:53 +0800623 STATIC_HANDLE_INDICATOR_OFFSET = 30
624 STATIC_HANDLE_VER_OFFSET = 8
625 STATIC_HANDLE_VER_BIT_WIDTH = 8
Kevin Pengce99e5d2021-11-09 18:06:53 +0800626 STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
627
Mingyang Sun4ecea992021-03-30 17:56:26 +0800628 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu50948382022-10-27 12:45:53 +0800629 for i in range(0, STATIC_HANDLE_NUM_LIMIT):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800630 service = reordered_stateless_services[i]
631
Kevin Pengc05319d2021-04-22 22:59:35 +0800632 if service == None and len(auto_alloc_services) > 0:
633 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800634
Mingyang Sun453ad402021-03-17 17:58:33 +0800635 """
636 Encode stateless flag and version into stateless handle
Mingyang Sun453ad402021-03-17 17:58:33 +0800637 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800638 stateless_handle_value = 0
639 if service != None:
Kevin Pengce99e5d2021-11-09 18:06:53 +0800640 stateless_index = (i & STATIC_HANDLE_IDX_MASK)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800641 stateless_handle_value |= stateless_index
Kevin Pengce99e5d2021-11-09 18:06:53 +0800642 stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
643 stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
Mingyang Sun453ad402021-03-17 17:58:33 +0800644 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800645 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800646 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800647
Mingyang Sun4ecea992021-03-30 17:56:26 +0800648 reordered_stateless_services[i] = service
649
650 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800651
Kevin Peng655f2392019-11-27 16:33:02 +0800652def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000653 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
654 epilog='Note that environment variables in template files will be replaced with their values')
655
Kevin Peng655f2392019-11-27 16:33:02 +0800656 parser.add_argument('-o', '--outdir'
657 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800658 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800659 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800660 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800661
Kevin Peng5bc82d22021-10-19 11:18:40 +0800662 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100663 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800664 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100665 , required=True
Kevin Peng65064c52021-10-27 17:12:17 +0800666 , metavar='manifest list'
667 , help='A list of Secure Partition manifest lists and their original paths.\n\
668 The manifest lists might be processed by CMake and\n\
669 the path might be different to the original one\n\
670 The format must be [list A, orignal path A, list B, orignal path B, ...]')
Kevin Peng655f2392019-11-27 16:33:02 +0800671
672 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100673 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800674 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100675 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800676 , metavar='file-list'
Chris Brandf1d6b6f2022-07-22 11:49:01 -0700677 , help='These files describe the file list to generate')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800678
Kevin Pengfb1761b2022-05-12 12:11:31 +0800679 parser.add_argument('-c', '--config-files'
680 , nargs='+'
681 , dest='config_files'
Kevin Peng9f1a7542022-02-07 16:32:27 +0800682 , required=True
Kevin Pengfb1761b2022-05-12 12:11:31 +0800683 , metavar='config-files'
684 , help='A header file contains build configurations')
Kevin Peng9f1a7542022-02-07 16:32:27 +0800685
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500686 parser.add_argument('-q', '--quiet'
687 , dest='quiet'
688 , required=False
689 , default=False
690 , action='store_true'
691 , help='Reduce log messages')
Kevin Peng655f2392019-11-27 16:33:02 +0800692
693 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800694
Kevin Peng655f2392019-11-27 16:33:02 +0800695 return args
696
697ENV = Environment(
698 loader = TemplateLoader(),
699 autoescape = select_autoescape(['html', 'xml']),
700 lstrip_blocks = True,
701 trim_blocks = True,
702 keep_trailing_newline = True
703 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100704
Miklos Balint470919c2018-05-22 17:51:29 +0200705def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100706 """
707 The entry point of the script.
708
709 Generates the output files based on the templates and the manifests.
710 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800711
Kevin Peng655f2392019-11-27 16:33:02 +0800712 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800713
Kevin Peng655f2392019-11-27 16:33:02 +0800714 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800715
Jimmy Brisson89d4f8d2021-06-23 10:17:36 -0500716 logging.basicConfig(format='%(message)s'
717 , level=logging.WARNING if args.quiet else logging.INFO)
718
Kevin Peng5bc82d22021-10-19 11:18:40 +0800719 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800720
Kevin Peng5bc82d22021-10-19 11:18:40 +0800721 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
722 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800723
Shawn Shana9ad1e02019-08-07 15:49:48 +0800724 """
Kevin Peng655f2392019-11-27 16:33:02 +0800725 Relative path to TF-M root folder is supported in the manifests
726 and default value of manifest list and generated file list are relative to TF-M root folder as well,
727 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800728 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800729 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 +0800730 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800731 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800732
Kevin Peng76c0c162022-02-09 22:49:06 +0800733 context = process_partition_manifests(manifest_lists,
Kevin Pengfb1761b2022-05-12 12:11:31 +0800734 parse_configurations(args.config_files))
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100735
Edison Ai6e3f2a32019-06-11 15:29:05 +0800736 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800737 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200738
Kevin Peng655f2392019-11-27 16:33:02 +0800739 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800740
Ken Liu861b0782021-05-22 13:15:08 +0800741 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800742 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200743
Kevin Peng5bc82d22021-10-19 11:18:40 +0800744if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200745 main()