blob: 2fde44c7b8d540e6f0d216717cd7d4b701fea857 [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:
Kevin Peng5bc82d22021-10-19 11:18:40 +080017 print (str(e) + ' To install it, type:')
18 print ('pip install PyYAML')
Miklos Balint470919c2018-05-22 17:51:29 +020019 exit(1)
20
Edison Ai48b2d9e2019-06-24 14:39:45 +080021donotedit_warning = \
Kevin Peng5bc82d22021-10-19 11:18:40 +080022 '/*********** ' + \
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 = []
Mate Toth-Pal36f21842018-11-08 16:12:51 +010030class TemplateLoader(BaseLoader):
31 """
32 Template loader class.
Miklos Balint470919c2018-05-22 17:51:29 +020033
Mate Toth-Pal36f21842018-11-08 16:12:51 +010034 An instance of this class is passed to the template engine. It is
35 responsible for reading the template file
36 """
37 def __init__(self):
38 pass
Miklos Balint470919c2018-05-22 17:51:29 +020039
Mate Toth-Pal36f21842018-11-08 16:12:51 +010040 def get_source(self, environment, template):
41 """
42 This function reads the template files.
43 For detailed documentation see:
44 http://jinja.pocoo.org/docs/2.10/api/#jinja2.BaseLoader.get_source
45
46 Please note that this function always return 'false' as 'uptodate'
47 value, so the output file will always be generated.
48 """
49 if not os.path.isfile(template):
50 raise TemplateNotFound(template)
51 with open(template) as f:
52 source = f.read()
53 return source, template, False
54
Mingyang Sun294ce2e2021-06-11 11:58:24 +080055def manifest_validation(partition_manifest):
56 """
57 This function validates FF-M compliance for partition manifest, and sets
58 default values for optional attributes.
59 More validation items will be added.
60 """
Kevin Peng5bc82d22021-10-19 11:18:40 +080061
Mingyang Sun294ce2e2021-06-11 11:58:24 +080062 # Service FF-M manifest validation
63 if 'services' not in partition_manifest.keys():
64 return partition_manifest
65
66 for service in partition_manifest['services']:
67 if 'version' not in service.keys():
68 service['version'] = 1
69 if 'version_policy' not in service.keys():
Kevin Peng5bc82d22021-10-19 11:18:40 +080070 service['version_policy'] = 'STRICT'
Mingyang Sun294ce2e2021-06-11 11:58:24 +080071
Kevin Peng5bc82d22021-10-19 11:18:40 +080072 # SID duplication check
73 if service['sid'] in sid_list:
74 raise Exception('Service ID: {} has duplications!'.format(service['sid']))
75 else:
76 sid_list.append(service['sid'])
Ruiqi Jiang71d361c2021-06-23 17:45:55 +010077
Mingyang Sun294ce2e2021-06-11 11:58:24 +080078 return partition_manifest
79
David Hub2694202021-07-15 14:58:39 +080080def process_partition_manifests(manifest_list_files, extra_manifests_list):
Mate Toth-Pal36f21842018-11-08 16:12:51 +010081 """
Kevin Peng655f2392019-11-27 16:33:02 +080082 Parse the input manifest, generate the data base for genereated files
83 and generate manifest header files.
Mate Toth-Pal36f21842018-11-08 16:12:51 +010084
85 Parameters
86 ----------
Raef Colesf42f0882020-07-10 10:01:58 +010087 manifest_list_files:
88 The manifest lists to parse.
David Hub2694202021-07-15 14:58:39 +080089 extra_manifests_list:
90 The extra manifest list to parse and its original path.
Mate Toth-Pal36f21842018-11-08 16:12:51 +010091
92 Returns
93 -------
Kevin Peng5bc82d22021-10-19 11:18:40 +080094 The manifest data base.
Edison Ai48b2d9e2019-06-24 14:39:45 +080095 """
Kevin Peng655f2392019-11-27 16:33:02 +080096
Kevin Peng5bc82d22021-10-19 11:18:40 +080097 context = {}
98
Ken Liu861b0782021-05-22 13:15:08 +080099 partition_list = []
Kevin Peng655f2392019-11-27 16:33:02 +0800100 manifest_list = []
Mingyang Suneab7eae2021-09-30 13:06:52 +0800101 ipc_partition_num = 0
102 sfn_partition_num = 0
Kevin Peng56b0ea62021-10-18 11:32:57 +0800103 pid_list = []
104 no_pid_manifest_idx = []
Kevin Peng655f2392019-11-27 16:33:02 +0800105
Raef Colesf42f0882020-07-10 10:01:58 +0100106 for f in manifest_list_files:
107 with open(f) as manifest_list_yaml_file:
108 manifest_dic = yaml.safe_load(manifest_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800109 manifest_list.extend(manifest_dic['manifest_list'])
Ken Liu861b0782021-05-22 13:15:08 +0800110 manifest_list_yaml_file.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800111
David Hub2694202021-07-15 14:58:39 +0800112 # Out-of-tree secure partition build
113 if extra_manifests_list is not None:
114 for i, item in enumerate(extra_manifests_list):
115 # Skip if current item is the original manifest path
116 if os.path.isdir(item):
117 continue
118
119 # The manifest list file generated by configure_file()
120 with open(item) as manifest_list_yaml_file:
121 manifest_dic = yaml.safe_load(manifest_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800122 extra_manifest_dic = manifest_dic['manifest_list']
David Hub2694202021-07-15 14:58:39 +0800123 for dict in extra_manifest_dic:
124 # Append original directory of out-of-tree partition's
125 # manifest list source code
126 dict['extra_path'] = extra_manifests_list[i + 1]
127 manifest_list.append(dict)
128 manifest_list_yaml_file.close()
129
Xinyu Zhangc46ee1f2021-04-01 10:10:43 +0800130 for i, manifest_item in enumerate(manifest_list):
131 # Check if partition ID is manually set
132 if 'pid' not in manifest_item.keys():
133 no_pid_manifest_idx.append(i)
Xinyu Zhang19504a52021-03-31 16:26:20 +0800134 # Check if partition ID is duplicated
Kevin Peng56b0ea62021-10-18 11:32:57 +0800135 elif manifest_item['pid'] in pid_list:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800136 raise Exception('PID No. {pid} has already been used!'.format(pid=manifest_item['pid']))
Kevin Peng56b0ea62021-10-18 11:32:57 +0800137 else:
138 pid_list.append(manifest_item['pid'])
Xinyu Zhang19504a52021-03-31 16:26:20 +0800139
Raef Coles558487a2020-10-29 13:09:44 +0000140 # Replace environment variables in the manifest path
Kevin Peng655f2392019-11-27 16:33:02 +0800141 manifest_path = os.path.expandvars(manifest_item['manifest'])
David Hub2694202021-07-15 14:58:39 +0800142
143 # Handle out-of-tree secure partition manifest file path
144 if 'extra_path' in manifest_item:
145 if not os.path.isabs(manifest_path):
146 # manifest file path provided by manifest list is relative to
147 # manifest list path
148 manifest_path = os.path.join(manifest_item['extra_path'], manifest_path).replace('\\', '/')
149
Kevin Peng5bc82d22021-10-19 11:18:40 +0800150 with open(manifest_path) as manifest_file:
151 manifest = manifest_validation(yaml.safe_load(manifest_file))
Kevin Peng655f2392019-11-27 16:33:02 +0800152
Mingyang Suneab7eae2021-09-30 13:06:52 +0800153 # Count the number of IPC partitions
Kevin Peng5bc82d22021-10-19 11:18:40 +0800154 if manifest['psa_framework_version'] == 1.1 and manifest['model'] == 'IPC':
Mingyang Suneab7eae2021-09-30 13:06:52 +0800155 ipc_partition_num += 1
Kevin Peng5bc82d22021-10-19 11:18:40 +0800156 elif manifest['psa_framework_version'] == 1.1 and manifest['model'] == 'SFN':
Mingyang Suneab7eae2021-09-30 13:06:52 +0800157 sfn_partition_num += 1
Kevin Peng5bc82d22021-10-19 11:18:40 +0800158 elif 'services' in manifest.keys() or 'irqs' in manifest.keys():
159 # This is only to skip Library Model Partitions
Mingyang Suneab7eae2021-09-30 13:06:52 +0800160 ipc_partition_num += 1
161
Kevin Peng655f2392019-11-27 16:33:02 +0800162 manifest_dir, manifest_name = os.path.split(manifest_path)
Ken Liu861b0782021-05-22 13:15:08 +0800163 manifest_out_basename = manifest_name.replace('.yaml', '').replace('.json', '')
Kevin Peng655f2392019-11-27 16:33:02 +0800164
Kevin Peng4fade072021-10-26 17:57:50 +0800165 if 'output_path' in manifest_item:
166 # Build up generated files directory accroding to the relative
167 # path specified in output_path by the partition
168 output_path = os.path.expandvars(manifest_item['output_path'])
Kevin Peng4fade072021-10-26 17:57:50 +0800169 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800170 output_path = manifest_dir
David Hub2694202021-07-15 14:58:39 +0800171
Kevin Peng5bc82d22021-10-19 11:18:40 +0800172 manifest_head_file = os.path.join(OUT_DIR, output_path, 'psa_manifest',
173 '{}.h'.format(manifest_out_basename))\
174 .replace('\\', '/')
175 intermedia_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
176 'intermedia_{}.c'.format(manifest_out_basename))\
177 .replace('\\', '/')
178 load_info_file = os.path.join(OUT_DIR, output_path, 'auto_generated',
179 'load_info_{}.c'.format(manifest_out_basename))\
180 .replace('\\', '/')
Kevin Peng655f2392019-11-27 16:33:02 +0800181
Kevin Peng5bc82d22021-10-19 11:18:40 +0800182 partition_list.append({'manifest': manifest, 'attr': manifest_item,
183 'manifest_out_basename': manifest_out_basename,
184 'header_file': manifest_head_file,
185 'intermedia_file': intermedia_file,
186 'loadinfo_file': load_info_file})
Ken Liu861b0782021-05-22 13:15:08 +0800187
Kevin Peng56b0ea62021-10-18 11:32:57 +0800188 # Automatically assign PIDs for partitions without 'pid' attribute
189 pid = 256
190 for idx in no_pid_manifest_idx:
191 while pid in pid_list:
192 pid += 1
193 manifest_list[idx]['pid'] = pid
194 pid_list.append(pid)
195
Kevin Peng5bc82d22021-10-19 11:18:40 +0800196 context['partitions'] = partition_list
197 context['ipc_partition_num'] = ipc_partition_num
198 context['sfn_partition_num'] = sfn_partition_num
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100199
Kevin Peng5bc82d22021-10-19 11:18:40 +0800200 context['stateless_services'] = process_stateless_services(partition_list, 32)
Ruiqi Jiang71d361c2021-06-23 17:45:55 +0100201
Kevin Peng5bc82d22021-10-19 11:18:40 +0800202 return context
Ken Liu861b0782021-05-22 13:15:08 +0800203
204def gen_per_partition_files(context):
205 """
206 Generate per-partition files
207
208 Parameters
209 ----------
210 context:
211 context contains partition infos
212 """
213
Kevin Peng5bc82d22021-10-19 11:18:40 +0800214 utilities = {}
215 utilities['donotedit_warning'] = donotedit_warning
Ken Liu861b0782021-05-22 13:15:08 +0800216
Kevin Peng5bc82d22021-10-19 11:18:40 +0800217 partition_context = {}
218 partition_context['utilities'] = utilities
Ken Liu861b0782021-05-22 13:15:08 +0800219
Kevin Peng5bc82d22021-10-19 11:18:40 +0800220 manifesttemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/manifestfilename.template'))
221 memorytemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_intermedia.template'))
222 infotemplate = ENV.get_template(os.path.join(sys.path[0], 'templates/partition_load_info.template'))
Ken Liu861b0782021-05-22 13:15:08 +0800223
Kevin Peng5bc82d22021-10-19 11:18:40 +0800224 print ('Start to generate partition files:')
Ken Liu861b0782021-05-22 13:15:08 +0800225
226 for one_partition in context['partitions']:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800227 partition_context['manifest'] = one_partition['manifest']
228 partition_context['attr'] = one_partition['attr']
229 partition_context['manifest_out_basename'] = one_partition['manifest_out_basename']
Ken Liu861b0782021-05-22 13:15:08 +0800230
Kevin Peng5bc82d22021-10-19 11:18:40 +0800231 print ('Generating Header: ' + one_partition['header_file'])
Ken Liu861b0782021-05-22 13:15:08 +0800232 outfile_path = os.path.dirname(one_partition['header_file'])
Kevin Peng655f2392019-11-27 16:33:02 +0800233 if not os.path.exists(outfile_path):
234 os.makedirs(outfile_path)
235
Kevin Peng5bc82d22021-10-19 11:18:40 +0800236 headerfile = io.open(one_partition['header_file'], 'w', newline=None)
237 headerfile.write(manifesttemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800238 headerfile.close()
Kevin Peng655f2392019-11-27 16:33:02 +0800239
Kevin Peng5bc82d22021-10-19 11:18:40 +0800240 print ('Generating Intermedia: ' + one_partition['intermedia_file'])
Ken Liu861b0782021-05-22 13:15:08 +0800241 intermediafile_path = os.path.dirname(one_partition['intermedia_file'])
Mingyang Sund20999f2020-10-15 14:53:12 +0800242 if not os.path.exists(intermediafile_path):
243 os.makedirs(intermediafile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800244 intermediafile = io.open(one_partition['intermedia_file'], 'w', newline=None)
245 intermediafile.write(memorytemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800246 intermediafile.close()
Mingyang Sund20999f2020-10-15 14:53:12 +0800247
Kevin Peng5bc82d22021-10-19 11:18:40 +0800248 print ('Generating Loadinfo: ' + one_partition['loadinfo_file'])
Ken Liu861b0782021-05-22 13:15:08 +0800249 infofile_path = os.path.dirname(one_partition['loadinfo_file'])
Mingyang Sunf6a78572021-04-02 16:51:05 +0800250 if not os.path.exists(infofile_path):
251 os.makedirs(infofile_path)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800252 infooutfile = io.open(one_partition['loadinfo_file'], 'w', newline=None)
253 infooutfile.write(infotemplate.render(partition_context))
Ken Liu861b0782021-05-22 13:15:08 +0800254 infooutfile.close()
Mingyang Sunf6a78572021-04-02 16:51:05 +0800255
Kevin Peng5bc82d22021-10-19 11:18:40 +0800256 print ('Per-partition files done:')
Mingyang Sunf6a78572021-04-02 16:51:05 +0800257
Ken Liu861b0782021-05-22 13:15:08 +0800258def gen_summary_files(context, gen_file_lists):
Kevin Peng655f2392019-11-27 16:33:02 +0800259 """
260 Generate files according to the gen_file_list
Edison Ai48b2d9e2019-06-24 14:39:45 +0800261
262 Parameters
263 ----------
Raef Colesf42f0882020-07-10 10:01:58 +0100264 gen_file_lists:
265 The lists of files to generate
Edison Ai48b2d9e2019-06-24 14:39:45 +0800266 """
Kevin Peng655f2392019-11-27 16:33:02 +0800267 file_list = []
Shawn Shana9ad1e02019-08-07 15:49:48 +0800268
Raef Colesf42f0882020-07-10 10:01:58 +0100269 for f in gen_file_lists:
270 with open(f) as file_list_yaml_file:
Kevin Peng655f2392019-11-27 16:33:02 +0800271 file_list_yaml = yaml.safe_load(file_list_yaml_file)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800272 file_list.extend(file_list_yaml['file_list'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800273
Kevin Peng5bc82d22021-10-19 11:18:40 +0800274 print('Start to generate file from the generated list:')
Kevin Peng655f2392019-11-27 16:33:02 +0800275 for file in file_list:
Raef Coles558487a2020-10-29 13:09:44 +0000276 # Replace environment variables in the output filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800277 manifest_out_file = os.path.expandvars(file['output'])
Raef Coles558487a2020-10-29 13:09:44 +0000278 # Replace environment variables in the template filepath
Kevin Peng5bc82d22021-10-19 11:18:40 +0800279 templatefile_name = os.path.expandvars(file['template'])
Edison Ai48b2d9e2019-06-24 14:39:45 +0800280
Kevin Peng4fade072021-10-26 17:57:50 +0800281 manifest_out_file = os.path.join(OUT_DIR, manifest_out_file)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800282
Kevin Peng5bc82d22021-10-19 11:18:40 +0800283 print ('Generating ' + manifest_out_file)
edison.ai7b299f52020-07-16 15:44:18 +0800284
Ken Liu861b0782021-05-22 13:15:08 +0800285 outfile_path = os.path.dirname(manifest_out_file)
Kevin Peng655f2392019-11-27 16:33:02 +0800286 if not os.path.exists(outfile_path):
287 os.makedirs(outfile_path)
Edison Ai48b2d9e2019-06-24 14:39:45 +0800288
Kevin Peng655f2392019-11-27 16:33:02 +0800289 template = ENV.get_template(templatefile_name)
Edison Ai6e3f2a32019-06-11 15:29:05 +0800290
Kevin Peng5bc82d22021-10-19 11:18:40 +0800291 outfile = io.open(manifest_out_file, 'w', newline=None)
Kevin Peng655f2392019-11-27 16:33:02 +0800292 outfile.write(template.render(context))
293 outfile.close()
Edison Ai48b2d9e2019-06-24 14:39:45 +0800294
Kevin Peng5bc82d22021-10-19 11:18:40 +0800295 print ('Generation of files done')
Edison Ai48b2d9e2019-06-24 14:39:45 +0800296
Ken Liu861b0782021-05-22 13:15:08 +0800297def process_stateless_services(partitions, stateless_index_max_num):
Mingyang Suna1ca6112021-01-11 11:34:59 +0800298 """
299 This function collects all stateless services together, and allocates
Mingyang Sun4ecea992021-03-30 17:56:26 +0800300 stateless handles for them.
Kevin Pengc05319d2021-04-22 22:59:35 +0800301 Valid stateless handle in service will be converted to an index. If the
302 stateless handle is set as "auto", or not set, framework will allocate a
303 valid index for the service.
304 Framework puts each service into a reordered stateless service list at
305 position of "index". Other unused positions are left None.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800306 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800307 collected_stateless_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800308
309 # Collect all stateless services first.
310 for partition in partitions:
311 # Skip the FF-M 1.0 partitions
312 if partition['manifest']['psa_framework_version'] < 1.1:
313 continue
Mingyang Suna1ca6112021-01-11 11:34:59 +0800314 for service in partition['manifest']['services']:
315 if 'connection_based' not in service:
316 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
317 if service['connection_based'] is False:
Kevin Pengc05319d2021-04-22 22:59:35 +0800318 collected_stateless_services.append(service)
Mingyang Suna1ca6112021-01-11 11:34:59 +0800319
Kevin Pengc05319d2021-04-22 22:59:35 +0800320 if len(collected_stateless_services) == 0:
Mingyang Suna1ca6112021-01-11 11:34:59 +0800321 return []
322
Ken Liu861b0782021-05-22 13:15:08 +0800323 if len(collected_stateless_services) > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800324 raise Exception('Stateless service numbers range exceed {number}.'.format(number=stateless_index_max_num))
Mingyang Suna1ca6112021-01-11 11:34:59 +0800325
326 """
Kevin Pengc05319d2021-04-22 22:59:35 +0800327 Allocate an empty stateless service list to store services.
328 Use "handle - 1" as the index for service, since handle value starts from
329 1 and list index starts from 0.
Mingyang Suna1ca6112021-01-11 11:34:59 +0800330 """
Ken Liu861b0782021-05-22 13:15:08 +0800331 reordered_stateless_services = [None] * stateless_index_max_num
Kevin Pengc05319d2021-04-22 22:59:35 +0800332 auto_alloc_services = []
Mingyang Suna1ca6112021-01-11 11:34:59 +0800333
Kevin Pengc05319d2021-04-22 22:59:35 +0800334 for service in collected_stateless_services:
335 # If not set, it is "auto" by default
336 if 'stateless_handle' not in service:
337 auto_alloc_services.append(service)
338 continue
339
Mingyang Sun4ecea992021-03-30 17:56:26 +0800340 service_handle = service['stateless_handle']
Mingyang Suna1ca6112021-01-11 11:34:59 +0800341
Mingyang Sun4ecea992021-03-30 17:56:26 +0800342 # Fill in service list with specified stateless handle, otherwise skip
343 if isinstance(service_handle, int):
Ken Liu861b0782021-05-22 13:15:08 +0800344 if service_handle < 1 or service_handle > stateless_index_max_num:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800345 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800346 # Convert handle index to reordered service list index
347 service_handle = service_handle - 1
348
349 if reordered_stateless_services[service_handle] is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800350 raise Exception('Duplicated stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800351 reordered_stateless_services[service_handle] = service
Kevin Pengc05319d2021-04-22 22:59:35 +0800352 elif service_handle == 'auto':
353 auto_alloc_services.append(service)
354 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800355 raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
Mingyang Sun4ecea992021-03-30 17:56:26 +0800356
357 # Auto-allocate stateless handle and encode the stateless handle
Ken Liu861b0782021-05-22 13:15:08 +0800358 for i in range(0, stateless_index_max_num):
Mingyang Sun4ecea992021-03-30 17:56:26 +0800359 service = reordered_stateless_services[i]
360
Kevin Pengc05319d2021-04-22 22:59:35 +0800361 if service == None and len(auto_alloc_services) > 0:
362 service = auto_alloc_services.pop(0)
Mingyang Sun4ecea992021-03-30 17:56:26 +0800363
Mingyang Sun453ad402021-03-17 17:58:33 +0800364 """
365 Encode stateless flag and version into stateless handle
366 bit 30: stateless handle indicator
367 bit 15-8: stateless service version
368 bit 7-0: stateless handle index
369 """
Mingyang Sun4ecea992021-03-30 17:56:26 +0800370 stateless_handle_value = 0
371 if service != None:
372 stateless_index = (i & 0xFF)
373 stateless_handle_value |= stateless_index
Mingyang Sun453ad402021-03-17 17:58:33 +0800374 stateless_flag = 1 << 30
375 stateless_handle_value |= stateless_flag
Mingyang Sun4ecea992021-03-30 17:56:26 +0800376 stateless_version = (service['version'] & 0xFF) << 8
Mingyang Sun453ad402021-03-17 17:58:33 +0800377 stateless_handle_value |= stateless_version
Mingyang Sun4ecea992021-03-30 17:56:26 +0800378 service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
Ken Liu861b0782021-05-22 13:15:08 +0800379 service['stateless_handle_index'] = stateless_index
Mingyang Suna1ca6112021-01-11 11:34:59 +0800380
Mingyang Sun4ecea992021-03-30 17:56:26 +0800381 reordered_stateless_services[i] = service
382
383 return reordered_stateless_services
Mingyang Suna1ca6112021-01-11 11:34:59 +0800384
Kevin Peng655f2392019-11-27 16:33:02 +0800385def parse_args():
Raef Coles558487a2020-10-29 13:09:44 +0000386 parser = argparse.ArgumentParser(description='Parse secure partition manifest list and generate files listed by the file list',
387 epilog='Note that environment variables in template files will be replaced with their values')
388
Kevin Peng655f2392019-11-27 16:33:02 +0800389 parser.add_argument('-o', '--outdir'
390 , dest='outdir'
Kevin Peng4fade072021-10-26 17:57:50 +0800391 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800392 , metavar='out_dir'
Kevin Peng4fade072021-10-26 17:57:50 +0800393 , help='The root directory for generated files')
Shawn Shana9ad1e02019-08-07 15:49:48 +0800394
Kevin Peng5bc82d22021-10-19 11:18:40 +0800395 parser.add_argument('-m', '--manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100396 , nargs='+'
Kevin Peng5bc82d22021-10-19 11:18:40 +0800397 , dest='manifest_lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100398 , required=True
Kevin Peng5bc82d22021-10-19 11:18:40 +0800399 , metavar='manifest-lists'
Raef Colesf42f0882020-07-10 10:01:58 +0100400 , help='A set of secure partition manifest lists to parse')
Kevin Peng655f2392019-11-27 16:33:02 +0800401
402 parser.add_argument('-f', '--file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100403 , nargs='+'
Kevin Peng655f2392019-11-27 16:33:02 +0800404 , dest='gen_file_args'
Raef Colesf42f0882020-07-10 10:01:58 +0100405 , required=True
Kevin Peng655f2392019-11-27 16:33:02 +0800406 , metavar='file-list'
Raef Colesf42f0882020-07-10 10:01:58 +0100407 , help='These files descripe the file list to generate')
Kevin Peng655f2392019-11-27 16:33:02 +0800408
David Hub2694202021-07-15 14:58:39 +0800409 parser.add_argument('-e', '--extra-manifest'
410 , nargs='*'
411 , dest='extra_manifests_args'
412 , required=False
413 , default=None
414 , metavar='out-of-tree-manifest-list'
415 , help='Optional. Manifest lists and original paths for out-of-tree secure partitions.')
416
Kevin Peng655f2392019-11-27 16:33:02 +0800417 args = parser.parse_args()
Kevin Peng655f2392019-11-27 16:33:02 +0800418
Kevin Peng655f2392019-11-27 16:33:02 +0800419 return args
420
421ENV = Environment(
422 loader = TemplateLoader(),
423 autoescape = select_autoescape(['html', 'xml']),
424 lstrip_blocks = True,
425 trim_blocks = True,
426 keep_trailing_newline = True
427 )
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100428
Miklos Balint470919c2018-05-22 17:51:29 +0200429def main():
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100430 """
431 The entry point of the script.
432
433 Generates the output files based on the templates and the manifests.
434 """
Shawn Shana9ad1e02019-08-07 15:49:48 +0800435
Kevin Peng655f2392019-11-27 16:33:02 +0800436 global OUT_DIR
Shawn Shana9ad1e02019-08-07 15:49:48 +0800437
Kevin Peng655f2392019-11-27 16:33:02 +0800438 args = parse_args()
Shawn Shana9ad1e02019-08-07 15:49:48 +0800439
David Hub2694202021-07-15 14:58:39 +0800440 extra_manifests_args = args.extra_manifests_args
Kevin Peng5bc82d22021-10-19 11:18:40 +0800441 OUT_DIR = os.path.abspath(args.outdir)
Kevin Peng655f2392019-11-27 16:33:02 +0800442
Kevin Peng5bc82d22021-10-19 11:18:40 +0800443 manifest_lists = [os.path.abspath(x) for x in args.manifest_lists]
444 gen_file_lists = [os.path.abspath(x) for x in args.gen_file_args]
Shawn Shana9ad1e02019-08-07 15:49:48 +0800445
David Hub2694202021-07-15 14:58:39 +0800446 if extra_manifests_args is not None:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800447 extra_manifests_lists = [os.path.abspath(x) for x in extra_manifests_args]
David Hub2694202021-07-15 14:58:39 +0800448 else:
Kevin Peng5bc82d22021-10-19 11:18:40 +0800449 extra_manifests_lists = None
David Hub2694202021-07-15 14:58:39 +0800450
Shawn Shana9ad1e02019-08-07 15:49:48 +0800451 """
Kevin Peng655f2392019-11-27 16:33:02 +0800452 Relative path to TF-M root folder is supported in the manifests
453 and default value of manifest list and generated file list are relative to TF-M root folder as well,
454 so first change directory to TF-M root folder.
Shawn Shana9ad1e02019-08-07 15:49:48 +0800455 By doing this, the script can be executed anywhere
Kevin Peng655f2392019-11-27 16:33:02 +0800456 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 +0800457 """
Kevin Peng5bc82d22021-10-19 11:18:40 +0800458 os.chdir(os.path.join(sys.path[0], '..'))
Shawn Shana9ad1e02019-08-07 15:49:48 +0800459
Kevin Peng5bc82d22021-10-19 11:18:40 +0800460 context = process_partition_manifests(manifest_lists, extra_manifests_lists)
Mate Toth-Pal36f21842018-11-08 16:12:51 +0100461
Edison Ai6e3f2a32019-06-11 15:29:05 +0800462 utilities = {}
Mingyang Suna1ca6112021-01-11 11:34:59 +0800463 utilities['donotedit_warning'] = donotedit_warning
Miklos Balint470919c2018-05-22 17:51:29 +0200464
Kevin Peng655f2392019-11-27 16:33:02 +0800465 context['utilities'] = utilities
Mingyang Suneab7eae2021-09-30 13:06:52 +0800466
Ken Liu861b0782021-05-22 13:15:08 +0800467 gen_per_partition_files(context)
Kevin Peng5bc82d22021-10-19 11:18:40 +0800468 gen_summary_files(context, gen_file_lists)
Miklos Balint470919c2018-05-22 17:51:29 +0200469
Kevin Peng5bc82d22021-10-19 11:18:40 +0800470if __name__ == '__main__':
Miklos Balint470919c2018-05-22 17:51:29 +0200471 main()