Tools: Avoid hard-code in manifest tool
This patch adds a method in manifest tool to get configurations from
codes.
And then uses the configuration values to avoid hard-code numbers.
Change-Id: I2de17a1b777ffcd45aabff0d4f28388fce8ff2c2
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index 6142165..773a160 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -7,6 +7,7 @@
import os
import io
+import re
import sys
import argparse
from jinja2 import Environment, BaseLoader, select_autoescape, TemplateNotFound
@@ -23,8 +24,12 @@
'WARNING: This is an auto-generated file. Do not edit!' + \
' ***********/'
+TFM_ROOT_DIR = os.path.join(sys.path[0], '..')
OUT_DIR = None # The root directory that files are generated to
+# PID[0, TFM_PID_BASE] are reserved for TF-M SPM and test usages
+TFM_PID_BASE = 256
+
# variable for checking for duplicated sid
sid_list = []
class TemplateLoader(BaseLoader):
@@ -52,18 +57,48 @@
source = f.read()
return source, template, False
+def get_single_macro_def_from_file(file_name, macro_name):
+ """
+ This function parses the given file_name to get the definition of the given
+ C Macro (macro_name).
+
+ It assumes that the target Macro has no multiple definitions in different
+ build configurations.
+
+ It supports Macros defined in multi-line, for example:
+ #define SOME_MACRO \
+ the_macro_value
+
+ Inputs:
+ - file_name: the file to get the Macro from
+ - macro_name: the name of the Macro to get
+ Returns:
+ - The Macro definition with '()' stripped, or Exception if not found
+ """
+
+ with open(file_name, 'r') as f:
+ pattern = re.compile(r'#define\s+{}[\\\s]+.*'.format(macro_name))
+ result = pattern.findall(f.read())
+
+ if len(result) != 1:
+ raise Exception('{} not defined or has multiple definitions'.format(macro_name))
+
+ macro_def = result[0].split()[-1].strip('()')
+
+ return macro_def
+
def manifest_validation(partition_manifest, pid):
"""
This function validates FF-M compliance for partition manifest, and sets
default values for optional attributes.
- The validation is skipped for TF-M specific Partitions (PID < 256).
+ The validation is skipped for TF-M specific Partitions (PID < TFM_PID_BASE).
More validation items will be added.
"""
service_list = partition_manifest.get('services', [])
irq_list = partition_manifest.get('irqs', [])
- if (pid == None or pid >= 256) \
+ if (pid == None or pid >= TFM_PID_BASE) \
and len(service_list) == 0 and len(irq_list) == 0:
raise Exception('{} must declare at least either a secure service or an IRQ!'
.format(partition_manifest['name']))
@@ -176,7 +211,7 @@
with open(manifest_path) as manifest_file:
manifest = manifest_validation(yaml.safe_load(manifest_file), pid)
- if pid == None or pid >= 256:
+ if pid == None or pid >= TFM_PID_BASE:
# Count the number of IPC/SFN partitions
if manifest['psa_framework_version'] == 1.1 and manifest['model'] == 'SFN':
sfn_partition_num += 1
@@ -207,7 +242,7 @@
'loadinfo_file': load_info_file})
# Automatically assign PIDs for partitions without 'pid' attribute
- pid = max(pid_list, default = 256 - 1)
+ pid = max(pid_list, default = TFM_PID_BASE - 1)
for idx in no_pid_manifest_idx:
pid += 1
all_manifests[idx]['pid'] = pid
@@ -217,7 +252,7 @@
context['ipc_partition_num'] = ipc_partition_num
context['sfn_partition_num'] = sfn_partition_num
- context['stateless_services'] = process_stateless_services(partition_list, 32)
+ context['stateless_services'] = process_stateless_services(partition_list)
return context
@@ -314,7 +349,7 @@
print ('Generation of files done')
-def process_stateless_services(partitions, stateless_index_max_num):
+def process_stateless_services(partitions):
"""
This function collects all stateless services together, and allocates
stateless handles for them.
@@ -324,7 +359,12 @@
Framework puts each service into a reordered stateless service list at
position of "index". Other unused positions are left None.
"""
+
+ STATIC_HANDLE_CONFIG_FILE = 'secure_fw/spm/cmsis_psa/spm_ipc.h'
+
collected_stateless_services = []
+ stateless_index_max_num = \
+ int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_NUM_LIMIT'), base = 10)
# Collect all stateless services first.
for partition in partitions:
@@ -377,6 +417,20 @@
else:
raise Exception('Invalid stateless_handle setting: {handle}.'.format(handle=service['stateless_handle']))
+ STATIC_HANDLE_IDX_BIT_WIDTH = \
+ int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_IDX_BIT_WIDTH'), base = 10)
+ STATIC_HANDLE_IDX_MASK = (1 << STATIC_HANDLE_IDX_BIT_WIDTH) - 1
+
+ STATIC_HANDLE_INDICATOR_OFFSET = \
+ int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_INDICATOR_OFFSET'), base = 10)
+
+ STATIC_HANDLE_VER_OFFSET = \
+ int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_OFFSET'), base = 10)
+
+ STATIC_HANDLE_VER_BIT_WIDTH = \
+ int(get_single_macro_def_from_file(STATIC_HANDLE_CONFIG_FILE, 'STATIC_HANDLE_VER_BIT_WIDTH'), base = 10)
+ STATIC_HANDLE_VER_MASK = (1 << STATIC_HANDLE_VER_BIT_WIDTH) - 1
+
# Auto-allocate stateless handle and encode the stateless handle
for i in range(0, stateless_index_max_num):
service = reordered_stateless_services[i]
@@ -386,17 +440,14 @@
"""
Encode stateless flag and version into stateless handle
- bit 30: stateless handle indicator
- bit 15-8: stateless service version
- bit 7-0: stateless handle index
+ Check STATIC_HANDLE_CONFIG_FILE for details
"""
stateless_handle_value = 0
if service != None:
- stateless_index = (i & 0xFF)
+ stateless_index = (i & STATIC_HANDLE_IDX_MASK)
stateless_handle_value |= stateless_index
- stateless_flag = 1 << 30
- stateless_handle_value |= stateless_flag
- stateless_version = (service['version'] & 0xFF) << 8
+ stateless_handle_value |= (1 << STATIC_HANDLE_INDICATOR_OFFSET)
+ stateless_version = (service['version'] & STATIC_HANDLE_VER_MASK) << STATIC_HANDLE_VER_OFFSET
stateless_handle_value |= stateless_version
service['stateless_handle_value'] = '0x{0:08x}'.format(stateless_handle_value)
service['stateless_handle_index'] = stateless_index