Add support for early Trusted Applications

Early TAs are user-mode Trusted Applications that are embedded at link
time in the TEE binary. A special read-only data section is used to
store them (.rodata.early_ta). A Python script takes care of converting
the TAs into a C source file with the proper linker section attribute.

The feature is disabled by default. To enable it, the paths to the TA
binaries have to be given in $(EARLY_TA_PATHS). They should be ELF
files. Typical build steps:
  $ make ... CFG_EARLY_TA=y ta_dev_kit                    # (1)
  $ # ... build the TAs ...                               # (2)
  $ make ... EARLY_TA_PATHS=path/to/<uuid>.stripped.elf   # (3)
Notes:
- Setting CFG_EARLY_TA=y during the first step (1) is not necessary,
   but it will avoid rebuilding libraries during the third step (3)
- CFG_EARLY_TA is automatically enabled when EARLY_TA_PATHS is non-empty
  in step (3)
- Several TAs may be given in $(EARLY_TA_PATHS) (3)

Early TAs are given a higher load priority than REE FS TAs, since they
should be available even before tee-supplicant is ready.

Suggested-by: Zeng Tao <prime.zeng@hisilicon.com>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/scripts/ta_bin_to_c.py b/scripts/ta_bin_to_c.py
new file mode 100755
index 0000000..13a38c7
--- /dev/null
+++ b/scripts/ta_bin_to_c.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2017, Linaro Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+import argparse
+import array
+import os
+import re
+import uuid
+
+def get_args():
+
+	parser = argparse.ArgumentParser(description='Converts a Trusted '
+		'Application ELF file into a C source file, ready for '
+		'inclusion in the TEE binary as an "early TA".')
+
+	parser.add_argument('--out', required=True,
+		help='Name of the output C file')
+
+	parser.add_argument('--ta', required=True,
+		help='Path to the TA binary. File name has to be: <uuid>.* '
+		'such as: 8aaaf200-2450-11e4-abe2-0002a5d5c51b.stripped.elf')
+
+	return parser.parse_args()
+
+def main():
+
+	args = get_args();
+
+	ta_uuid = uuid.UUID(re.sub('\..*', '', os.path.basename(args.ta)))
+
+	f = open(args.out, 'w')
+	f.write('/* Generated from ' + args.ta + ' by ' +
+		os.path.basename(__file__) + ' */\n\n')
+	f.write('#include <compiler.h>\n');
+        f.write('#include <kernel/early_ta.h>\n\n');
+	f.write('__extension__ const struct early_ta __early_ta_' +
+		ta_uuid.hex +
+		'\n__early_ta __aligned(__alignof__(struct early_ta)) = {\n')
+	f.write('\t.uuid = {\n')
+	f.write('\t\t.timeLow = 0x{:08x},\n'.format(ta_uuid.time_low))
+	f.write('\t\t.timeMid = 0x{:04x},\n'.format(ta_uuid.time_mid))
+	f.write('\t\t.timeHiAndVersion = ' +
+		'0x{:04x},\n'.format(ta_uuid.time_hi_version))
+	f.write('\t\t.clockSeqAndNode = {\n')
+	csn = '{0:02x}{1:02x}{2:012x}'.format(ta_uuid.clock_seq_hi_variant,
+		ta_uuid.clock_seq_low, ta_uuid.node)
+	f.write('\t\t\t')
+	f.write(', '.join('0x' + csn[i:i+2] for i in range(0, len(csn), 2)))
+	f.write('\n\t\t},\n\t},\n')
+	f.write('\t.size = {:d},'.format(os.path.getsize(args.ta)))
+	f.write('\t.ta = {\n')
+	i = 0
+	with open(args.ta, 'rb') as ta:
+		byte = ta.read(1)
+		while byte:
+			if i % 8 == 0:
+				f.write('\t\t');
+			f.write('0x' + '{:02x}'.format(ord(byte)) + ',')
+			i = i + 1
+			byte = ta.read(1)
+			if i % 8 == 0 or not byte:
+				f.write('\n')
+			else:
+				f.write(' ')
+	f.write('\t},\n')
+	f.write('};\n');
+	f.close()
+
+if __name__ == "__main__":
+	main()