blob: 3f1e2693827f7b679a6567f6a91ee4572976deb2 [file] [log] [blame]
Miklos Balint470919c2018-05-22 17:51:29 +02001#-------------------------------------------------------------------------------
Kevin Peng578a8492020-12-31 10:22:59 +08002# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
Miklos Balint470919c2018-05-22 17:51:29 +02003#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8import os
Mate Toth-Pal36f21842018-11-08 16:12:51 +01009import io
Shawn Shana9ad1e02019-08-07 15:49:48 +080010import sys
11import argparse
Ken Liu1f345b02020-05-30 21:11:05 +080012from jinja2 import Environment, BaseLoader, select_autoescape, TemplateNotFound
Miklos Balint470919c2018-05-22 17:51:29 +020013
14try:
15 import yaml
16except ImportError as e:
Mate Toth-Pala99ec6b2019-05-07 11:00:56 +020017 print (str(e) + " To install it, type:")
Mate Toth-Pal36f21842018-11-08 16:12:51 +010018 print ("pip install PyYAML")
Miklos Balint470919c2018-05-22 17:51:29 +020019 exit(1)
20
Edison Ai48b2d9e2019-06-24 14:39:45 +080021donotedit_warning = \
22 "/*********** " + \
23 "WARNING: This is an auto-generated file. Do not edit!" + \
24 " ***********/"
Kevin Peng655f2392019-11-27 16:33:02 +080025
Kevin Peng655f2392019-11-27 16:33:02 +080026OUT_DIR = None # The root directory that files are generated to
Edison Ai48b2d9e2019-06-24 14:39:45 +080027
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010028# variable for checking for duplicated sid
29sid_list = []
30partition_list_sid = []
31service_list = []
32sid_duplicated_partition = []
33sid_duplicated_sid = []
34sid_duplicated_service = []
35
Mate Toth-Pal36f21842018-11-08 16:12:51 +010036class TemplateLoader(BaseLoader):
37 """
38 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020039
Mate Toth-Pal36f21842018-11-08 16:12:51 +010040 An instance of this class is passed to the template engine. It is
41 responsible for reading the template file
42 """
43 def __init__(self):
44 pass
Miklos Balint470919c2018-05-22 17:51:29 +020045
Mate Toth-Pal36f21842018-11-08 16:12:51 +010046 def get_source(self, environment, template):
47 """
48 This function reads the template files.
49 For detailed documentation see:
50 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
51
52 Please note that this function always return 'false' as 'uptodate'
53 value, so the output file will always be generated.
54 """
55 if not os.path.isfile(template):
56 raise TemplateNotFound(template)
57 with open(template) as f:
58 source = f.read()
59 return source, template, False
60
Mingyang Sun294ce2e2021-06-11 11:58:24 +080061def manifest_validation(partition_manifest):
62 """
63 This function validates FF-M compliance for partition manifest, and sets
64 default values for optional attributes.
65 More validation items will be added.
66 """
67 # Service FF-M manifest validation
68 if 'services' not in partition_manifest.keys():
69 return partition_manifest
70
71 for service in partition_manifest['services']:
72 if 'version' not in service.keys():
73 service['version'] = 1
74 if 'version_policy' not in service.keys():
75 service['version_policy'] = "STRICT"
76
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010077 for k in range (len(sid_list)):
78 sid_item = sid_list[k]
79 if ((service['sid'] == sid_item) & (service['name'] != service_list[k])):
80 sid_duplicated_partition.append(partition_list_sid[k])
81 sid_duplicated_partition.append(partition_manifest['name'])
82 sid_duplicated_sid.append(sid_item)
83 sid_duplicated_sid.append(service['sid'])
84 sid_duplicated_service.append(service_list[k])
85 sid_duplicated_service.append(service['name'])
86
87 sid_list.append(service['sid'])
88 partition_list_sid.append(partition_manifest['name'])
89 service_list.append(service['name'])
90
Mingyang Sun294ce2e2021-06-11 11:58:24 +080091 return partition_manifest
92
David Hub2694202021-07-15 14:58:39 +080093def process_partition_manifests(manifest_list_files, extra_manifests_list):
Mate Toth-Pal36f21842018-11-08 16:12:51 +010094 """
Kevin Peng655f2392019-11-27 16:33:02 +080095 Parse the input manifest, generate the data base for genereated files
96 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +010097
98 Parameters
99 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100100 manifest_list_files:
101 The manifest lists to parse.
David Hub2694202021-07-15 14:58:39 +0800102 extra_manifests_list:
103 The extra manifest list to parse and its original path.
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100104
105 Returns
106 -------
Kevin Peng578a8492020-12-31 10:22:59 +0800107 The partition data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +0800108 """
Kevin Peng655f2392019-11-27 16:33:02 +0800109
Ken Liu861b0782021-05-22 13:15:08 +0800110 partition_list = []
Kevin Peng655f2392019-11-27 16:33:02 +0800111 manifest_list = []
Mingyang Suneab7eae2021-09-30 13:06:52 +0800112 ipc_partition_num = 0
113 sfn_partition_num = 0
Kevin Peng56b0ea62021-10-18 11:32:57 +0800114 pid_list = []
115 no_pid_manifest_idx = []
Kevin Peng655f2392019-11-27 16:33:02 +0800116
Raef Colesf42f0882020-07-10 10:01:58 +0100117 for f in manifest_list_files:
118 with open(f) as manifest_list_yaml_file:
119 manifest_dic = yaml.safe_load(manifest_list_yaml_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800120 manifest_list.extend(manifest_dic["manifest_list"])
Ken Liu861b0782021-05-22 13:15:08 +0800121 manifest_list_yaml_file.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800122
David Hub2694202021-07-15 14:58:39 +0800123 # Out-of-tree secure partition build
124 if extra_manifests_list is not None:
125 for i, item in enumerate(extra_manifests_list):
126 # Skip if current item is the original manifest path
127 if os.path.isdir(item):
128 continue
129
130 # The manifest list file generated by configure_file()
131 with open(item) as manifest_list_yaml_file:
132 manifest_dic = yaml.safe_load(manifest_list_yaml_file)
133 extra_manifest_dic = manifest_dic["manifest_list"]
134 for dict in extra_manifest_dic:
135 # Append original directory of out-of-tree partition's
136 # manifest list source code
137 dict['extra_path'] = extra_manifests_list[i + 1]
138 manifest_list.append(dict)
139 manifest_list_yaml_file.close()
140
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800141 for i, manifest_item in enumerate(manifest_list):
142 # Check if partition ID is manually set
143 if 'pid' not in manifest_item.keys():
144 no_pid_manifest_idx.append(i)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800145 # Check if partition ID is duplicated
Kevin Peng56b0ea62021-10-18 11:32:57 +0800146 elif manifest_item['pid'] in pid_list:
Xinyu Zhang19504a52021-03-31 16:26:20 +0800147 raise Exception("PID No. {pid} has already been used!".format(pid=manifest_item['pid']))
Kevin Peng56b0ea62021-10-18 11:32:57 +0800148 else:
149 pid_list.append(manifest_item['pid'])
Xinyu Zhang19504a52021-03-31 16:26:20 +0800150
Raef Coles558487a2020-10-29 13:09:44 +0000151 # Replace environment variables in the manifest path
Kevin Peng655f2392019-11-27 16:33:02 +0800152 manifest_path = os.path.expandvars(manifest_item['manifest'])
David Hub2694202021-07-15 14:58:39 +0800153
154 # Handle out-of-tree secure partition manifest file path
155 if 'extra_path' in manifest_item:
156 if not os.path.isabs(manifest_path):
157 # manifest file path provided by manifest list is relative to
158 # manifest list path
159 manifest_path = os.path.join(manifest_item['extra_path'], manifest_path).replace('\\', '/')
160
Kevin Peng655f2392019-11-27 16:33:02 +0800161 file = open(manifest_path)
Mingyang Sun294ce2e2021-06-11 11:58:24 +0800162 manifest = manifest_validation(yaml.safe_load(file))
Ken Liu861b0782021-05-22 13:15:08 +0800163 file.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800164
Mingyang Suneab7eae2021-09-30 13:06:52 +0800165 # Count the number of IPC partitions
166 if manifest["psa_framework_version"] == 1.1 and manifest["model"] == 'IPC':
167 ipc_partition_num += 1
168 elif manifest["psa_framework_version"] == 1.1 and manifest["model"] == 'SFN':
169 sfn_partition_num += 1
170 elif "services" in manifest.keys():
171 ipc_partition_num += 1
172
Kevin Peng655f2392019-11-27 16:33:02 +0800173 manifest_dir, manifest_name = os.path.split(manifest_path)
Ken Liu861b0782021-05-22 13:15:08 +0800174 manifest_out_basename = manifest_name.replace('.yaml', '').replace('.json', '')
Kevin Peng655f2392019-11-27 16:33:02 +0800175
Kevin Peng4fade072021-10-26 17:57:50 +0800176 if 'output_path' in manifest_item:
177 # Build up generated files directory accroding to the relative
178 # path specified in output_path by the partition
179 output_path = os.path.expandvars(manifest_item['output_path'])
180 manifest_head_file = os.path.join(output_path, "psa_manifest", manifest_out_basename + '.h')
181 intermedia_file = os.path.join(output_path, "auto_generated", 'intermedia_' + manifest_out_basename + '.c')
182 load_info_file = os.path.join(output_path, "auto_generated", 'load_info_' + manifest_out_basename + '.c')
183 else:
184 manifest_head_file = os.path.join(manifest_dir, "psa_manifest", manifest_out_basename + '.h')
185 intermedia_file = os.path.join(manifest_dir, "auto_generated", 'intermedia_' + manifest_out_basename + '.c')
186 load_info_file = os.path.join(manifest_dir, "auto_generated", 'load_info_' + manifest_out_basename + '.c')
David Hub2694202021-07-15 14:58:39 +0800187
Kevin Peng4fade072021-10-26 17:57:50 +0800188 """
189 Remove the `source_path` portion of the filepaths, so that it can be
190 interpreted as a relative path from the OUT_DIR.
191 """
192 if 'source_path' in manifest_item:
193 # Replace environment variables in the source path
194 source_path = os.path.expandvars(manifest_item['source_path'])
195 manifest_head_file = os.path.relpath(manifest_head_file, start = source_path)
196 intermedia_file = os.path.relpath(intermedia_file, start = source_path)
197 load_info_file = os.path.relpath(load_info_file, start = source_path)
MartinaHanusovaNXP35957f12021-07-14 15:30:15 +0200198
Kevin Peng4fade072021-10-26 17:57:50 +0800199 manifest_head_file = os.path.join(OUT_DIR, manifest_head_file).replace('\\', '/')
200 intermedia_file = os.path.join(OUT_DIR, intermedia_file).replace('\\', '/')
201 load_info_file = os.path.join(OUT_DIR, load_info_file).replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800202
Ken Liu861b0782021-05-22 13:15:08 +0800203 partition_list.append({"manifest": manifest, "attr": manifest_item,
204 "manifest_out_basename": manifest_out_basename,
205 "header_file": manifest_head_file,
206 "intermedia_file": intermedia_file,
207 "loadinfo_file": load_info_file})
208
Kevin Peng56b0ea62021-10-18 11:32:57 +0800209 # Automatically assign PIDs for partitions without 'pid' attribute
210 pid = 256
211 for idx in no_pid_manifest_idx:
212 while pid in pid_list:
213 pid += 1
214 manifest_list[idx]['pid'] = pid
215 pid_list.append(pid)
216
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100217 if len(sid_duplicated_sid) != 0:
218 print("The following signals have duplicated sids."
219 "A Service requires a unique sid")
220 for i in range(len(sid_duplicated_sid)):
221 print("Partition: {parti} , Service: {servi} , SID: {sidn}".format(
222 parti = sid_duplicated_partition[i],
223 servi = sid_duplicated_service[i],
224 sidn = sid_duplicated_sid[i])
225 )
226
227 raise Exception("Duplicated SID found, check above for details")
228
Mingyang Suneab7eae2021-09-30 13:06:52 +0800229 return partition_list, ipc_partition_num, sfn_partition_num
Ken Liu861b0782021-05-22 13:15:08 +0800230
231def gen_per_partition_files(context):
232 """
233 Generate per-partition files
234
235 Parameters
236 ----------
237 context:
238 context contains partition infos
239 """
240
241 subutilities = {}
242 subutilities['donotedit_warning'] = donotedit_warning
243
244 subcontext = {}
245 subcontext['utilities'] = subutilities
246
Ken Liu72c031e2021-08-09 16:42:54 +0800247 manifesttemplate = ENV.get_template(os.path.join(os.path.relpath(os.path.dirname(__file__)), 'templates/manifestfilename.template'))
248 memorytemplate = ENV.get_template(os.path.join(os.path.relpath(os.path.dirname(__file__)), 'templates/partition_intermedia.template'))
249 infotemplate = ENV.get_template(os.path.join(os.path.relpath(os.path.dirname(__file__)), 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800250
251 print ("Start to generate partition files:")
252
253 for one_partition in context['partitions']:
254 subcontext['manifest'] = one_partition['manifest']
255 subcontext['attr'] = one_partition['attr']
256 subcontext['manifest_out_basename'] = one_partition['manifest_out_basename']
257
258 print ("Generating Header: " + one_partition['header_file'])
259 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800260 if not os.path.exists(outfile_path):
261 os.makedirs(outfile_path)
262
Ken Liu861b0782021-05-22 13:15:08 +0800263 headerfile = io.open(one_partition['header_file'], "w", newline=None)
264 headerfile.write(manifesttemplate.render(subcontext))
265 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800266
Ken Liu861b0782021-05-22 13:15:08 +0800267 print ("Generating Intermedia: " + one_partition['intermedia_file'])
268 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800269 if not os.path.exists(intermediafile_path):
270 os.makedirs(intermediafile_path)
Ken Liu861b0782021-05-22 13:15:08 +0800271 intermediafile = io.open(one_partition['intermedia_file'], "w", newline=None)
272 intermediafile.write(memorytemplate.render(subcontext))
273 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800274
Ken Liu861b0782021-05-22 13:15:08 +0800275 print ("Generating Loadinfo: " + one_partition['loadinfo_file'])
276 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800277 if not os.path.exists(infofile_path):
278 os.makedirs(infofile_path)
Ken Liu861b0782021-05-22 13:15:08 +0800279 infooutfile = io.open(one_partition['loadinfo_file'], "w", newline=None)
280 infooutfile.write(infotemplate.render(subcontext))
281 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800282
Ken Liu861b0782021-05-22 13:15:08 +0800283 print ("Per-partition files done:")
Mingyang Sunf6a78572021-04-02 16:51:05 +0800284
Ken Liu861b0782021-05-22 13:15:08 +0800285def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800286 """
287 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800288
289 Parameters
290 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100291 gen_file_lists:
292 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800293 """
Kevin Peng655f2392019-11-27 16:33:02 +0800294 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800295
Raef Colesf42f0882020-07-10 10:01:58 +0100296 for f in gen_file_lists:
297 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800298 file_list_yaml = yaml.safe_load(file_list_yaml_file)
299 file_list.extend(file_list_yaml["file_list"])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800300
edison.ai7b299f52020-07-16 15:44:18 +0800301 print("Start to generate file from the generated list:")
Kevin Peng655f2392019-11-27 16:33:02 +0800302 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000303 # Replace environment variables in the output filepath
Ken Liu861b0782021-05-22 13:15:08 +0800304 manifest_out_file = os.path.expandvars(file["output"])
Raef Coles558487a2020-10-29 13:09:44 +0000305 # Replace environment variables in the template filepath
Kevin Peng1ec5e7c2019-11-29 10:52:00 +0800306 templatefile_name = os.path.expandvars(file["template"])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800307
Kevin Peng4fade072021-10-26 17:57:50 +0800308 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800309
Ken Liu861b0782021-05-22 13:15:08 +0800310 print ("Generating " + manifest_out_file)
edison.ai7b299f52020-07-16 15:44:18 +0800311
Ken Liu861b0782021-05-22 13:15:08 +0800312 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800313 if not os.path.exists(outfile_path):
314 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800315
Kevin Peng655f2392019-11-27 16:33:02 +0800316 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800317
Ken Liu861b0782021-05-22 13:15:08 +0800318 outfile = io.open(manifest_out_file, "w", newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800319 outfile.write(template.render(context))
320 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800321
Kevin Peng655f2392019-11-27 16:33:02 +0800322 print ("Generation of files done")
Edison Ai48b2d9e2019-06-24 14:39:45 +0800323
Ken Liu861b0782021-05-22 13:15:08 +0800324def process_stateless_services(partitions, stateless_index_max_num):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800325 """
326 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800327 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800328 Valid stateless handle in service will be converted to an index. If the
329 stateless handle is set as "auto", or not set, framework will allocate a
330 valid index for the service.
331 Framework puts each service into a reordered stateless service list at
332 position of "index". Other unused positions are left None.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800333 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800334 collected_stateless_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800335
336 # Collect all stateless services first.
337 for partition in partitions:
338 # Skip the FF-M 1.0 partitions
339 if partition['manifest']['psa_framework_version'] < 1.1:
340 continue
Mingyang Suna1ca6112021-01-11 11:34:59 +0800341 for service in partition['manifest']['services']:
342 if 'connection_based' not in service:
343 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
344 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800345 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800346
Kevin Pengc05319d2021-04-22 22:59:35 +0800347 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800348 return []
349
Ken Liu861b0782021-05-22 13:15:08 +0800350 if len(collected_stateless_services) > stateless_index_max_num:
351 raise Exception("Stateless service numbers range exceed {number}.".format(number=stateless_index_max_num))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800352
353 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800354 Allocate an empty stateless service list to store services.
355 Use "handle - 1" as the index for service, since handle value starts from
356 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800357 """
Ken Liu861b0782021-05-22 13:15:08 +0800358 reordered_stateless_services = [None] * stateless_index_max_num
Kevin Pengc05319d2021-04-22 22:59:35 +0800359 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800360
Kevin Pengc05319d2021-04-22 22:59:35 +0800361 for service in collected_stateless_services:
362 # If not set, it is "auto" by default
363 if 'stateless_handle' not in service:
364 auto_alloc_services.append(service)
365 continue
366
Mingyang Sun4ecea992021-03-30 17:56:26 +0800367 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800368
Mingyang Sun4ecea992021-03-30 17:56:26 +0800369 # Fill in service list with specified stateless handle, otherwise skip
370 if isinstance(service_handle, int):
Ken Liu861b0782021-05-22 13:15:08 +0800371 if service_handle < 1 or service_handle > stateless_index_max_num:
Kevin Pengc05319d2021-04-22 22:59:35 +0800372 raise Exception("Invalid stateless_handle setting: {handle}.".format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800373 # Convert handle index to reordered service list index
374 service_handle = service_handle - 1
375
376 if reordered_stateless_services[service_handle] is not None:
Kevin Pengc05319d2021-04-22 22:59:35 +0800377 raise Exception("Duplicated stateless_handle setting: {handle}.".format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800378 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800379 elif service_handle == 'auto':
380 auto_alloc_services.append(service)
381 else:
382 raise Exception("Invalid stateless_handle setting: {handle}.".format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800383
384 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu861b0782021-05-22 13:15:08 +0800385 for i in range(0, stateless_index_max_num):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800386 service = reordered_stateless_services[i]
387
Kevin Pengc05319d2021-04-22 22:59:35 +0800388 if service == None and len(auto_alloc_services) > 0:
389 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800390
Mingyang Sun453ad402021-03-17 17:58:33 +0800391 """
392 Encode stateless flag and version into stateless handle
393 bit 30: stateless handle indicator
394 bit 15-8: stateless service version
395 bit 7-0: stateless handle index
396 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800397 stateless_handle_value = 0
398 if service != None:
399 stateless_index = (i & 0xFF)
400 stateless_handle_value |= stateless_index
Mingyang Sun453ad402021-03-17 17:58:33 +0800401 stateless_flag = 1 << 30
402 stateless_handle_value |= stateless_flag
Mingyang Sun4ecea992021-03-30 17:56:26 +0800403 stateless_version = (service['version'] & 0xFF) << 8
Mingyang Sun453ad402021-03-17 17:58:33 +0800404 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800405 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800406 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800407
Mingyang Sun4ecea992021-03-30 17:56:26 +0800408 reordered_stateless_services[i] = service
409
410 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800411
Kevin Peng655f2392019-11-27 16:33:02 +0800412def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000413 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
414 epilog='Note that environment variables in template files will be replaced with their values')
415
Kevin Peng655f2392019-11-27 16:33:02 +0800416 parser.add_argument('-o', '--outdir'
417 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800418 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800419 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800420 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800421
Kevin Peng655f2392019-11-27 16:33:02 +0800422 parser.add_argument('-m', '--manifest'
Raef Colesf42f0882020-07-10 10:01:58 +0100423 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800424 , dest='manifest_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100425 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800426 , metavar='manifest'
Raef Colesf42f0882020-07-10 10:01:58 +0100427 , help='A set of secure partition manifest lists to parse')
Kevin Peng655f2392019-11-27 16:33:02 +0800428
429 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100430 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800431 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100432 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800433 , metavar='file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100434 , help='These files descripe the file list to generate')
Kevin Peng655f2392019-11-27 16:33:02 +0800435
David Hub2694202021-07-15 14:58:39 +0800436 parser.add_argument('-e', '--extra-manifest'
437 , nargs='*'
438 , dest='extra_manifests_args'
439 , required=False
440 , default=None
441 , metavar='out-of-tree-manifest-list'
442 , help='Optional. Manifest lists and original paths for out-of-tree secure partitions.')
443
Kevin Peng655f2392019-11-27 16:33:02 +0800444 args = parser.parse_args()
445 manifest_args = args.manifest_args
446 gen_file_args = args.gen_file_args
447
Kevin Peng655f2392019-11-27 16:33:02 +0800448 return args
449
450ENV = Environment(
451 loader = TemplateLoader(),
452 autoescape = select_autoescape(['html', 'xml']),
453 lstrip_blocks = True,
454 trim_blocks = True,
455 keep_trailing_newline = True
456 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100457
Miklos Balint470919c2018-05-22 17:51:29 +0200458def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100459 """
460 The entry point of the script.
461
462 Generates the output files based on the templates and the manifests.
463 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800464
Kevin Peng655f2392019-11-27 16:33:02 +0800465 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800466
Kevin Peng655f2392019-11-27 16:33:02 +0800467 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800468
Kevin Peng655f2392019-11-27 16:33:02 +0800469 manifest_args = args.manifest_args
470 gen_file_args = args.gen_file_args
David Hub2694202021-07-15 14:58:39 +0800471 extra_manifests_args = args.extra_manifests_args
Kevin Peng655f2392019-11-27 16:33:02 +0800472 OUT_DIR = args.outdir
Kevin Peng655f2392019-11-27 16:33:02 +0800473
Raef Coles558487a2020-10-29 13:09:44 +0000474 manifest_list = [os.path.abspath(x) for x in args.manifest_args]
475 gen_file_list = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800476
David Hub2694202021-07-15 14:58:39 +0800477 if extra_manifests_args is not None:
478 extra_manifests_list = [os.path.abspath(x) for x in extra_manifests_args]
479 else:
480 extra_manifests_list = None
481
Shawn Shana9ad1e02019-08-07 15:49:48 +0800482 """
Kevin Peng655f2392019-11-27 16:33:02 +0800483 Relative path to TF-M root folder is supported in the manifests
484 and default value of manifest list and generated file list are relative to TF-M root folder as well,
485 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800486 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800487 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 +0800488 """
489 os.chdir(os.path.join(sys.path[0], ".."))
490
Mingyang Suneab7eae2021-09-30 13:06:52 +0800491 partition_list, ipc_partition_num, sfn_partition_num = process_partition_manifests(manifest_list, extra_manifests_list)
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100492
Edison Ai6e3f2a32019-06-11 15:29:05 +0800493 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800494 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200495
Ken Liu861b0782021-05-22 13:15:08 +0800496 context = {}
497 context['partitions'] = partition_list
Kevin Peng655f2392019-11-27 16:33:02 +0800498 context['utilities'] = utilities
Ken Liu861b0782021-05-22 13:15:08 +0800499 context['stateless_services'] = process_stateless_services(partition_list, 32)
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100500
Mingyang Suneab7eae2021-09-30 13:06:52 +0800501 context['ipc_partition_num'] = ipc_partition_num
502 context['sfn_partition_num'] = sfn_partition_num
503
Ken Liu861b0782021-05-22 13:15:08 +0800504 gen_per_partition_files(context)
505 gen_summary_files(context, gen_file_list)
Miklos Balint470919c2018-05-22 17:51:29 +0200506
507if __name__ == "__main__":
508 main()