#!/usr/bin/env python3 """This hacky script generates a partition from a manifest file""" # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later import json import os import sys from os import listdir if len(sys.argv) != 2: print("Usage: psa_autogen ") sys.exit(1) FILENAME = str(sys.argv[1]) SCRIPT_PATH = os.path.dirname(__file__) GENERATED_H_PATH = os.path.join(SCRIPT_PATH, "..", "include", "psa_manifest") GENERATED_C_PATH = os.path.join(SCRIPT_PATH, "..", "src") MANIFEST_FILE = os.path.join(GENERATED_H_PATH, "manifest.h") PID_FILE = os.path.join(GENERATED_H_PATH, "pid.h") SID_FILE = os.path.join(GENERATED_H_PATH, "sid.h") with open(str(FILENAME), "r") as read_file: data = json.load(read_file) FILENAME = os.path.basename(FILENAME) FILENAME = FILENAME.split('.')[0] print("Base filename is " + str(FILENAME)) if str(data['psa_framework_version'] == "1.0"): entry_point = str(data['entry_point']) partition_name = str(data['name']) services = data['services'] try: irqs = data['irqs'] except KeyError: irqs = [] try: os.mkdir(GENERATED_H_PATH) print("Generating psa_manifest directory") except OSError: print("PSA manifest directory already exists") manifest_content = [] pids_content = [] sids_content = [] if len(services) > 28: print ("Unsupported number of services") count = 4 # For creating SID array nsacl = "const int ns_allowed[32] = { " policy = "const int strict_policy[32] = { " qcode = "const char *psa_queues[] = { " versions = "const uint32_t versions[32] = { " queue_path = "psa_service_" start = False for x in range(0, count): qcode = qcode + "\"\", " nsacl = nsacl + "0, " policy = policy + "0, " versions = versions + "0, " # Go through all the services to make sid.h and pid.h for svc in services: manifest_content.append("#define {}_SIGNAL 0x{:08x}".format(svc['signal'], 2**count)) sids_content.append("#define {}_SID {}".format(svc['name'], svc['sid'])) qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\"," ns_clients = svc['non_secure_clients'] print(str(svc)) if ns_clients == "true": nsacl = nsacl + "1, " else: nsacl = nsacl + "0, " try: versions = versions + str(svc['minor_version']) + ", " except KeyError: versions = versions + "1, " strict = 0 try: if str(svc['minor_policy']).lower() == "strict": strict = 1 policy = policy + "1, " else: policy = policy + "0, " except KeyError: strict = 0 policy = policy + "0, " count = count+1 sigcode = "" handlercode = "void __sig_handler(int signo) {\n" irqcount = count for irq in irqs: manifest_content.append("#define {} 0x{:08x}".format(irq['signal'], 2**irqcount)) sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source']) handlercode = handlercode + \ " if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount) irqcount = irqcount+1 handlercode = handlercode + "}\n" while (count < 32): qcode = qcode + "\"\", " nsacl = nsacl + "0, " versions = versions + "0, " policy = policy + "0, " count = count + 1 qcode = qcode + "};\n" nsacl = nsacl + "};\n" versions = versions + "};\n" policy = policy + "};\n" with open(MANIFEST_FILE, "wt") as output: output.write("\n".join(manifest_content)) with open(SID_FILE, "wt") as output: output.write("\n".join(sids_content)) with open(PID_FILE, "wt") as output: output.write("\n".join(pids_content)) symbols = [] # Go through source files and look for the entrypoint for root, directories, filenames in os.walk(GENERATED_C_PATH): for filename in filenames: if "psa_ff_bootstrap" in filename or filename == "psa_manifest": continue try: fullpath = os.path.join(root,filename) with open(fullpath, encoding='utf-8') as currentFile: text = currentFile.read() if str(entry_point + "(") in text: symbols.append(filename) except IOError: print("Couldn't open " + filename) except UnicodeDecodeError: pass print(str("Number of entrypoints detected: " + str(len(symbols)))) if len(symbols) < 1: print("Couldn't find function " + entry_point) sys.exit(1) elif len(symbols) > 1: print("Duplicate entrypoint symbol detected: " + str(symbols)) sys.exit(2) else: C_FILENAME = os.path.join(GENERATED_C_PATH, "psa_ff_bootstrap_" + partition_name + ".c") c_content = [] c_content.append("#include ") c_content.append("#include \"" + symbols[0] + "\"") c_content.append("#include ") c_content.append(qcode) c_content.append(nsacl) c_content.append(policy) c_content.append(versions) c_content.append(handlercode) c_content.append("int main(int argc, char *argv[]) {") c_content.append(" (void) argc;") c_content.append(sigcode) c_content.append(" __init_psasim(psa_queues, 32, ns_allowed, versions," "strict_policy);") c_content.append(" " + entry_point + "(argc, argv);") c_content.append("}") with open(C_FILENAME, "wt") as output: output.write("\n".join(c_content)) print("Success")