Trusted Firmware-A Tests, version 2.0

This is the first public version of the tests for the Trusted
Firmware-A project. Please see the documentation provided in the
source tree for more details.

Change-Id: I6f3452046a1351ac94a71b3525c30a4ca8db7867
Signed-off-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Co-authored-by: amobal01 <amol.balasokamble@arm.com>
Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Co-authored-by: Asha R <asha.r@arm.com>
Co-authored-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Co-authored-by: David Cunado <david.cunado@arm.com>
Co-authored-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
Co-authored-by: Douglas Raillard <douglas.raillard@arm.com>
Co-authored-by: dp-arm <dimitris.papastamos@arm.com>
Co-authored-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Co-authored-by: Jonathan Wright <jonathan.wright@arm.com>
Co-authored-by: Kévin Petit <kevin.petit@arm.com>
Co-authored-by: Roberto Vargas <roberto.vargas@arm.com>
Co-authored-by: Sathees Balya <sathees.balya@arm.com>
Co-authored-by: Shawon Roy <Shawon.Roy@arm.com>
Co-authored-by: Soby Mathew <soby.mathew@arm.com>
Co-authored-by: Thomas Abraham <thomas.abraham@arm.com>
Co-authored-by: Vikram Kanigiri <vikram.kanigiri@arm.com>
Co-authored-by: Yatharth Kochar <yatharth.kochar@arm.com>
diff --git a/tftf/framework/include/nvm.h b/tftf/framework/include/nvm.h
new file mode 100644
index 0000000..3544c2a
--- /dev/null
+++ b/tftf/framework/include/nvm.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __NVM_H__
+#define __NVM_H__
+
+#ifndef __ASSEMBLY__
+#include <stddef.h>
+#include <tftf.h>
+#include "tests_list.h"
+
+#define TEST_BUFFER_SIZE 0x80
+
+typedef struct {
+	/*
+	 * @brief Last executed TFTF build message which consists of date and
+	 * time when TFTF is built.
+	 *
+	 * A mismatch with the build message of currently executing binary will
+	 * determine whether TFTF data structures stored in NVM needs to be
+	 * initialised or not.
+	 */
+	char build_message[BUILD_MESSAGE_SIZE];
+
+	/*
+	 * The following 2 fields track the progress in the test session. They
+	 * indicate which test case we are dealing with and the progress of this
+	 * test, i.e. whether it hasn't started yet, or it is being executed
+	 * right now, ...
+	 */
+	test_ref_t		test_to_run;
+	test_progress_t		test_progress;
+
+	/*
+	 * @brief Scratch buffer for test internal use.
+	 *
+	 * A buffer that the test can use as a scratch area for whatever it is
+	 * doing.
+	 */
+	char testcase_buffer[TEST_BUFFER_SIZE];
+
+	/*
+	 * @brief Results of tests.
+	 *
+	 * @note TESTCASE_RESULT_COUNT is defined in tests_list.h
+	 * (auto-generated file).
+	 */
+	TESTCASE_RESULT testcase_results[TESTCASE_RESULT_COUNT];
+
+	/*
+	 * @brief Size of \a result_buffer.
+	 */
+	unsigned result_buffer_size;
+
+	/*
+	 * Buffer containing the output of all tests.
+	 * Each test appends its output to the end of \a result_buffer.
+	 * Tests which produce no output write nothing in \a result_buffer.
+	 */
+	 char *result_buffer;
+} tftf_state_t;
+
+/*
+ * Helper macros to access fields of \a tftf_state_t structure.
+ */
+#define TFTF_STATE_OFFSET(_field)		offsetof(tftf_state_t, _field)
+
+/*
+ * Return 1 if we need to start a new test session;
+ *        0 if we need to resume an interrupted session.
+ */
+unsigned int new_test_session(void);
+
+/*
+ * @brief Initialize NVM if necessary.
+ *
+ * When TFTF is launched on the target, its data structures need
+ * to be initialised in NVM. However if some test resets the board
+ * (as part of its normal behaviour or because it crashed) then
+ * TFTF data structure must be left unchanged in order to resume
+ * the test session where it has been left.
+ *
+ * This function detects whether TFTF has just been launched and if so
+ * initialises its data structures. If TFTF has just reset then it does
+ * nothing.
+ *
+ * @return STATUS_SUCCESS on success, another status code on failure.
+ */
+STATUS tftf_init_nvm(void);
+
+/*
+ * @brief Clean NVM.
+ *
+ * Clean TFTF data structures in NVM.
+ * This function must be called when all tests have completed.
+ *
+ * @return STATUS_SUCCESS on success, another status code on failure.
+ */
+STATUS tftf_clean_nvm(void);
+
+/* Writes the buffer to the flash at offset with length equal to
+ * size
+ * Returns: STATUS_FAIL, STATUS_SUCCESS, STATUS_OUT_OF_RESOURCES
+ */
+STATUS tftf_nvm_write(unsigned long long offset, const void *buffer, size_t size);
+
+/* Reads the flash into buffer at offset with length equal to
+ * size
+ * Returns: STATUS_FAIL, STATUS_SUCCESS, STATUS_OUT_OF_RESOURCES
+ */
+STATUS tftf_nvm_read(unsigned long long offset, void *buffer, size_t size);
+#endif /*__ASSEMBLY__*/
+
+#endif
diff --git a/tftf/framework/include/tftf.h b/tftf/framework/include/tftf.h
new file mode 100644
index 0000000..8231e28
--- /dev/null
+++ b/tftf/framework/include/tftf.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TFTF_H__
+#define __TFTF_H__
+
+#ifndef __ASSEMBLY__
+#include <status.h>
+#include <stddef.h>
+#include <tftf_lib.h>
+
+#define TFTF_WELCOME_STR	"Booting trusted firmware test framework"
+
+/* Maximum size of test output (in bytes) */
+#define TESTCASE_OUTPUT_MAX_SIZE	512
+
+/* Size of build message used to differentiate different TFTF binaries */
+#define BUILD_MESSAGE_SIZE 		0x20
+
+extern const char build_message[];
+
+typedef test_result_t (*test_function_t)(void);
+
+typedef struct {
+	/* Test result (success, crashed, failed, ...). */
+	test_result_t		result;
+	unsigned long long	duration;
+	/*
+	 * Offset of test output string from TEST_NVM_RESULT_BUFFER_OFFSET.
+	 * Only relevant if test has an output, i.e. if \a output_size is not
+	 * zero.
+	 */
+	unsigned		output_offset;
+	/* Size of test output string, excluding final \0. */
+	unsigned		output_size;
+} TESTCASE_RESULT;
+
+typedef struct {
+	unsigned		index;
+	const char		*name;
+	const char		*description;
+	test_function_t		test;
+} test_case_t;
+
+typedef struct {
+	const char		*name;
+	const char		*description;
+	const test_case_t	*testcases;
+} test_suite_t;
+
+/*
+ * Reference to a specific test.
+ */
+typedef struct {
+	unsigned int		testsuite_idx;
+	unsigned int		testcase_idx;
+} test_ref_t;
+
+/*
+ * The progress in the execution of a test.
+ * This is used to implement the following state machine.
+ *
+ *  +-> TEST_READY (initial state of the test)                  <--------------+
+ *  |        |                                                                 |
+ *  |        |  Test framework prepares the test environment.                  |
+ *  |        |                                                                 |
+ *  |        v                                                                 |
+ *  |   TEST_IN_PROGRESS                                                       |
+ *  |        |                                                                 |
+ *  |        |  Hand over to the test function.                                |
+ *  |        |  If the test wants to reboot the platform  ---> TEST_REBOOTING  |
+ *  |        |  Test function returns into framework.                |         |
+ *  |        |                                                       | Reboot  |
+ *  |        |                                                       |         |
+ *  |        |                                                       +---------+
+ *  |        v
+ *  |   TEST_COMPLETE
+ *  |        |
+ *  |        |  Do some framework management.
+ *  |        |  Move to next test.
+ *  +--------+
+ */
+typedef enum {
+	TEST_PROGRESS_MIN = 0,
+	TEST_READY = TEST_PROGRESS_MIN,
+	TEST_IN_PROGRESS,
+	TEST_COMPLETE,
+	TEST_REBOOTING,
+
+	TEST_PROGRESS_MAX,
+} test_progress_t;
+
+#define TEST_PROGRESS_IS_VALID(_progress)	\
+	((_progress >= TEST_PROGRESS_MIN) && (_progress < TEST_PROGRESS_MAX))
+
+/*
+ * The definition of this global variable is generated by the script
+ * 'tftf_generate_test_list' during the build process
+ */
+extern const test_suite_t testsuites[];
+
+extern TESTCASE_RESULT testcase_results[];
+
+/* Set/Get the test to run in NVM */
+STATUS tftf_set_test_to_run(const test_ref_t test_to_run);
+STATUS tftf_get_test_to_run(test_ref_t *test_to_run);
+/* Set/Get the progress of the current test in NVM */
+STATUS tftf_set_test_progress(test_progress_t test_progress);
+STATUS tftf_get_test_progress(test_progress_t *test_progress);
+
+/**
+** Save test result into NVM.
+*/
+STATUS tftf_testcase_set_result(const test_case_t *testcase,
+				test_result_t result,
+				unsigned long long duration);
+/**
+** Get a testcase result from NVM.
+**
+** @param[in]  testcase The targeted testcase.
+** @param[out] result Testcase result. Only \a result.result and
+**   \a result.duration are of interest for the caller and the 2 other fields
+**   should be ignored (they correspond to a location in NVM).
+** @param[out] test_output Buffer to store the test output, if any.
+**   \a test_output must be big enough to hold the whole test output.
+**   Test output will be \a TESTCASE_OUTPUT_MAX_SIZE bytes maximum.
+*/
+STATUS tftf_testcase_get_result(const test_case_t *testcase, TESTCASE_RESULT *result, char *test_output);
+
+void tftf_report_generate(void);
+
+/*
+ * Exit the TFTF.
+ * This function can be used when a fatal error is encountered or as part of the
+ * normal termination process. It does the necessary cleanups then put the
+ * core in a low-power state.
+ */
+void __dead2 tftf_exit(void);
+
+void tftf_arch_setup(void);
+
+/*
+ * This function detects the power state format used by PSCI which can
+ * be either extended or original format. For the Original format,
+ * the State-ID can either be NULL or can be using the recommended encoding.
+ * This function needs to be invoked once during cold boot prior to the
+ * invocation of any PSCI power state helper functions.
+ */
+void tftf_detect_psci_pstate_format(void);
+
+/*
+ * Run the next test on the calling CPU.
+ * Once the test is complete, if the calling CPU is the last one to exit the
+ * test then do the necessary bookkeeping, report the overall test result and
+ * move on to the next test. Otherwise, shut down the calling CPU.
+ *
+ * This function never returns.
+ */
+void __dead2 run_tests(void);
+
+/* Entry point for a CPU that has just been powered up */
+void tftf_hotplug_entry(void);
+
+#endif /*__ASSEMBLY__*/
+
+#endif