blob: fbc98060fe3d01c2e9936a22ae9a1fcc1a134a91 [file] [log] [blame]
Valerio Setti4f4ade92024-05-03 17:28:04 +02001#!/usr/bin/env python3
2"""This hacky script generates a partition from a manifest file"""
3
4# Copyright The Mbed TLS Contributors
5# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6
7import json
8import os
9import sys
10from os import listdir
11
12if len(sys.argv) != 2:
13 print("Usage: psa_autogen <manifest_file>")
14 sys.exit(1)
15
16FILENAME = str(sys.argv[1])
17
Valerio Setti66fb1c12024-05-10 06:51:16 +020018SCRIPT_PATH = os.path.dirname(__file__)
19GENERATED_H_PATH = os.path.join(SCRIPT_PATH, "..", "include", "psa_manifest")
20GENERATED_C_PATH = os.path.join(SCRIPT_PATH, "..", "src")
Valerio Setti4f4ade92024-05-03 17:28:04 +020021
Valerio Setti1f3c99c2024-05-15 07:29:51 +020022MANIFEST_FILE = os.path.join(GENERATED_H_PATH, "manifest.h")
23PID_FILE = os.path.join(GENERATED_H_PATH, "pid.h")
24SID_FILE = os.path.join(GENERATED_H_PATH, "sid.h")
25
Valerio Setti4f4ade92024-05-03 17:28:04 +020026with open(str(FILENAME), "r") as read_file:
27 data = json.load(read_file)
28 FILENAME = os.path.basename(FILENAME)
29 FILENAME = FILENAME.split('.')[0]
30 print("Base filename is " + str(FILENAME))
31
32 if str(data['psa_framework_version'] == "1.0"):
33 entry_point = str(data['entry_point'])
34 partition_name = str(data['name'])
35 services = data['services']
36 try:
37 irqs = data['irqs']
38 except KeyError:
39 irqs = []
40
41 try:
Valerio Setti66fb1c12024-05-10 06:51:16 +020042 os.mkdir(GENERATED_H_PATH)
Valerio Setti4f4ade92024-05-03 17:28:04 +020043 print("Generating psa_manifest directory")
44 except OSError:
Valerio Setti1f3c99c2024-05-15 07:29:51 +020045 print("PSA manifest directory already exists")
Valerio Setti4f4ade92024-05-03 17:28:04 +020046
Valerio Setti1f3c99c2024-05-15 07:29:51 +020047 manifest_content = []
48 pids_content = []
49 sids_content = []
Valerio Setti4f4ade92024-05-03 17:28:04 +020050
51 if len(services) > 28:
52 print ("Unsupported number of services")
53
54 count = 4 # For creating SID array
55 nsacl = "const int ns_allowed[32] = { "
56 policy = "const int strict_policy[32] = { "
57 qcode = "const char *psa_queues[] = { "
58 versions = "const uint32_t versions[32] = { "
59 queue_path = "psa_service_"
60 start = False
61
62 for x in range(0, count):
63 qcode = qcode + "\"\", "
64 nsacl = nsacl + "0, "
65 policy = policy + "0, "
66 versions = versions + "0, "
67
68 # Go through all the services to make sid.h and pid.h
69 for svc in services:
Valerio Setti1f3c99c2024-05-15 07:29:51 +020070 manifest_content.append("#define {}_SIGNAL 0x{:08x}".format(svc['signal'], 2**count))
71 sids_content.append("#define {}_SID {}".format(svc['name'], svc['sid']))
Valerio Setti4f4ade92024-05-03 17:28:04 +020072 qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\","
73 ns_clients = svc['non_secure_clients']
74 print(str(svc))
75 if ns_clients == "true":
76 nsacl = nsacl + "1, "
77 else:
78 nsacl = nsacl + "0, "
79 try:
80 versions = versions + str(svc['minor_version']) + ", "
81 except KeyError:
82 versions = versions + "1, "
83
84 strict = 0
85 try:
86 if str(svc['minor_policy']).lower() == "strict":
87 strict = 1
88 policy = policy + "1, "
89 else:
90 policy = policy + "0, "
91 except KeyError:
92 strict = 0
93 policy = policy + "0, "
94
95 count = count+1
96
97 sigcode = ""
98 handlercode = "void __sig_handler(int signo) {\n"
99 irqcount = count
100 for irq in irqs:
Valerio Setti1f3c99c2024-05-15 07:29:51 +0200101 manifest_content.append("#define {} 0x{:08x}".format(irq['signal'], 2**irqcount))
Valerio Setti4f4ade92024-05-03 17:28:04 +0200102 sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source'])
103 handlercode = handlercode + \
104 " if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount)
105 irqcount = irqcount+1
106
107 handlercode = handlercode + "}\n"
108
109 while (count < 32):
110 qcode = qcode + "\"\", "
111 nsacl = nsacl + "0, "
112 versions = versions + "0, "
113 policy = policy + "0, "
114 count = count + 1
115
116 qcode = qcode + "};\n"
117 nsacl = nsacl + "};\n"
118 versions = versions + "};\n"
119 policy = policy + "};\n"
120
Valerio Setti1f3c99c2024-05-15 07:29:51 +0200121 with open(MANIFEST_FILE, "wt") as output:
122 output.write("\n".join(manifest_content))
123 with open(SID_FILE, "wt") as output:
124 output.write("\n".join(sids_content))
125 with open(PID_FILE, "wt") as output:
126 output.write("\n".join(pids_content))
Valerio Setti4f4ade92024-05-03 17:28:04 +0200127
128 symbols = []
Valerio Setti4f4ade92024-05-03 17:28:04 +0200129
Valerio Setti66fb1c12024-05-10 06:51:16 +0200130 # Go through source files and look for the entrypoint
131 for root, directories, filenames in os.walk(GENERATED_C_PATH):
Valerio Setti4f4ade92024-05-03 17:28:04 +0200132 for filename in filenames:
Valerio Setti4f4ade92024-05-03 17:28:04 +0200133 if "psa_ff_bootstrap" in filename or filename == "psa_manifest":
134 continue
Valerio Setti4f4ade92024-05-03 17:28:04 +0200135 try:
136 fullpath = os.path.join(root,filename)
137 with open(fullpath, encoding='utf-8') as currentFile:
138 text = currentFile.read()
139 if str(entry_point + "(") in text:
Valerio Setti66fb1c12024-05-10 06:51:16 +0200140 symbols.append(filename)
Valerio Setti4f4ade92024-05-03 17:28:04 +0200141 except IOError:
142 print("Couldn't open " + filename)
Valerio Setti4f4ade92024-05-03 17:28:04 +0200143 except UnicodeDecodeError:
144 pass
145
146 print(str("Number of entrypoints detected: " + str(len(symbols))))
147 if len(symbols) < 1:
148 print("Couldn't find function " + entry_point)
149 sys.exit(1)
150 elif len(symbols) > 1:
151 print("Duplicate entrypoint symbol detected: " + str(symbols))
152 sys.exit(2)
153 else:
Valerio Setti1f3c99c2024-05-15 07:29:51 +0200154 C_FILENAME = os.path.join(GENERATED_C_PATH, "psa_ff_bootstrap_" + partition_name + ".c")
155 c_content = []
156 c_content.append("#include <init.h>")
157 c_content.append("#include \"" + symbols[0] + "\"")
158 c_content.append("#include <signal.h>")
159 c_content.append(qcode)
160 c_content.append(nsacl)
161 c_content.append(policy)
162 c_content.append(versions)
163 c_content.append(handlercode)
164 c_content.append("int main(int argc, char *argv[]) {")
165 c_content.append(" (void) argc;")
166 c_content.append(sigcode)
167 c_content.append(" __init_psasim(psa_queues, 32, ns_allowed, versions,"
168 "strict_policy);")
169 c_content.append(" " + entry_point + "(argc, argv);")
170 c_content.append("}")
171 with open(C_FILENAME, "wt") as output:
172 output.write("\n".join(c_content))
Valerio Setti4f4ade92024-05-03 17:28:04 +0200173
174 print("Success")