blob: 53b1fea746c02e762f3c9889120f602f52b83a4b [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
18
19with open(str(FILENAME), "r") as read_file:
20 data = json.load(read_file)
21 FILENAME = os.path.basename(FILENAME)
22 FILENAME = FILENAME.split('.')[0]
23 print("Base filename is " + str(FILENAME))
24
25 if str(data['psa_framework_version'] == "1.0"):
26 entry_point = str(data['entry_point'])
27 partition_name = str(data['name'])
28 services = data['services']
29 try:
30 irqs = data['irqs']
31 except KeyError:
32 irqs = []
33
34 try:
35 os.mkdir("psa_manifest")
36 print("Generating psa_manifest directory")
37 except OSError:
38 print ("PSA manifest directory already exists")
39
40 man = open(str("psa_manifest/" + FILENAME + ".h"), "w")
41 pids = open("psa_manifest/pid.h", "a")
42 sids = open("psa_manifest/sid.h", "a")
43
44 if len(services) > 28:
45 print ("Unsupported number of services")
46
47 count = 4 # For creating SID array
48 nsacl = "const int ns_allowed[32] = { "
49 policy = "const int strict_policy[32] = { "
50 qcode = "const char *psa_queues[] = { "
51 versions = "const uint32_t versions[32] = { "
52 queue_path = "psa_service_"
53 start = False
54
55 for x in range(0, count):
56 qcode = qcode + "\"\", "
57 nsacl = nsacl + "0, "
58 policy = policy + "0, "
59 versions = versions + "0, "
60
61 # Go through all the services to make sid.h and pid.h
62 for svc in services:
63 man.write("#define {}_SIGNAL 0x{:08x}\n".format(svc['signal'], 2**count))
64 sids.write("#define {}_SID {}\n".format(svc['name'], svc['sid']))
65 qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\","
66 ns_clients = svc['non_secure_clients']
67 print(str(svc))
68 if ns_clients == "true":
69 nsacl = nsacl + "1, "
70 else:
71 nsacl = nsacl + "0, "
72 try:
73 versions = versions + str(svc['minor_version']) + ", "
74 except KeyError:
75 versions = versions + "1, "
76
77 strict = 0
78 try:
79 if str(svc['minor_policy']).lower() == "strict":
80 strict = 1
81 policy = policy + "1, "
82 else:
83 policy = policy + "0, "
84 except KeyError:
85 strict = 0
86 policy = policy + "0, "
87
88 count = count+1
89
90 sigcode = ""
91 handlercode = "void __sig_handler(int signo) {\n"
92 irqcount = count
93 for irq in irqs:
94 man.write("#define {} 0x{:08x}\n".format(irq['signal'], 2**irqcount))
95 sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source'])
96 handlercode = handlercode + \
97 " if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount)
98 irqcount = irqcount+1
99
100 handlercode = handlercode + "}\n"
101
102 while (count < 32):
103 qcode = qcode + "\"\", "
104 nsacl = nsacl + "0, "
105 versions = versions + "0, "
106 policy = policy + "0, "
107 count = count + 1
108
109 qcode = qcode + "};\n"
110 nsacl = nsacl + "};\n"
111 versions = versions + "};\n"
112 policy = policy + "};\n"
113
114 pids.close()
115 sids.close()
116 man.close()
117
118 symbols = []
119 # Go through all the files in the current directory and look for the entrypoint
120
121 for root, directories, filenames in os.walk('.'):
122 for filename in filenames:
123
124 if "psa_ff_bootstrap" in filename or filename == "psa_manifest":
125 continue
126
127 try:
128 fullpath = os.path.join(root,filename)
129 with open(fullpath, encoding='utf-8') as currentFile:
130 text = currentFile.read()
131 if str(entry_point + "(") in text:
132 symbols.append(fullpath)
133 except IOError:
134 print("Couldn't open " + filename)
135
136 except UnicodeDecodeError:
137 pass
138
139 print(str("Number of entrypoints detected: " + str(len(symbols))))
140 if len(symbols) < 1:
141 print("Couldn't find function " + entry_point)
142 sys.exit(1)
143 elif len(symbols) > 1:
144 print("Duplicate entrypoint symbol detected: " + str(symbols))
145 sys.exit(2)
146 else:
147 bs = open(str("psa_ff_bootstrap_" + str(partition_name) + ".c"), "w")
148 bs.write("#include <psasim/init.h>\n")
149 bs.write("#include \"" + symbols[0] + "\"\n")
150 bs.write("#include <signal.h>\n\n")
151 bs.write(qcode)
152 bs.write(nsacl)
153 bs.write(policy)
154 bs.write(versions)
155 bs.write("\n")
156 bs.write(handlercode)
157 bs.write("\n")
158 bs.write("int main(int argc, char *argv[]) {\n")
159 bs.write(" (void) argc;\n")
160 bs.write(sigcode)
161 bs.write(" __init_psasim(psa_queues, 32, ns_allowed, versions, strict_policy);\n")
162 bs.write(" " + entry_point + "(argc, argv);\n}\n")
163 bs.close()
164
165 print("Success")