psa_autogen.py (5655B)
1 #!/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 7 import json 8 import os 9 import sys 10 from os import listdir 11 12 if len(sys.argv) != 2: 13 print("Usage: psa_autogen <manifest_file>") 14 sys.exit(1) 15 16 FILENAME = str(sys.argv[1]) 17 18 19 with 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 = "/tmp/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 " + str(svc['signal']) + "_SIGNAL " + str(2 ** (count)) + 'u\n') 64 sids.write("#define " + str(svc['name']) + "_SID " + str(svc['sid'] + '\n')) 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 " + str(irq['signal']) + " " + str(2 ** (irqcount)) + 'u\n') 95 sigcode = sigcode + " signal(" + str(irq['source']) + ", __sig_handler);\n" 96 handlercode = handlercode + " if (signo == " + str(irq['source']) + ") { raise_signal(" + str(2 ** (irqcount)) + 'u);' + " };\n" 97 irqcount = irqcount+1 98 99 handlercode = handlercode + "}\n" 100 101 while (count < 32): 102 qcode = qcode + "\"\"," 103 nsacl = nsacl + "0," 104 versions = versions + "0," 105 policy = policy + "0," 106 count = count + 1 107 108 qcode = qcode + "};\n" 109 nsacl = nsacl + "};\n" 110 versions = versions + "};\n" 111 policy = policy + "};\n" 112 113 pids.close() 114 sids.close() 115 man.close() 116 117 symbols = [] 118 # Go through all the files in the current directory and look for the entrypoint 119 120 for root, directories, filenames in os.walk('.'): 121 for filename in filenames: 122 123 if "psa_ff_bootstrap" in filename or filename == "psa_manifest": 124 continue 125 126 try: 127 fullpath = os.path.join(root,filename) 128 with open(fullpath, encoding='utf-8') as currentFile: 129 text = currentFile.read() 130 if str(entry_point + "(") in text: 131 symbols.append(fullpath) 132 except IOError: 133 print("Couldn't open " + filename) 134 135 except UnicodeDecodeError: 136 pass 137 138 print(str("Number of entrypoints detected: " + str(len(symbols)))) 139 if len(symbols) < 1: 140 print("Couldn't find function " + entry_point) 141 sys.exit(1) 142 elif len(symbols) > 1: 143 print("Duplicate entrypoint symbol detected: " + str(symbols)) 144 sys.exit(2) 145 else: 146 bs = open(str("psa_ff_bootstrap_" + str(partition_name) + ".c"), "w") 147 bs.write("#include <psasim/init.h>\n") 148 bs.write("#include \"" + symbols[0] + "\"\n") 149 bs.write("#include <signal.h>\n") 150 bs.write(qcode) 151 bs.write("\n") 152 bs.write(nsacl + "\n") 153 bs.write(policy + "\n") 154 bs.write(versions + "\n") 155 bs.write(handlercode) 156 bs.write("\n") 157 bs.write("int main() {\n") 158 bs.write(sigcode) 159 bs.write(" __init_psasim(psa_queues, 32, ns_allowed, versions, strict_policy);\n") 160 bs.write(" " + entry_point + "();\nfor(;;);\n}\n") 161 bs.close() 162 163 print("Success")