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