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/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
new file mode 100644
index 0000000..a23fc50
--- /dev/null
+++ b/include/plat/arm/common/arm_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ARM_DEF_H__
+#define __ARM_DEF_H__
+
+/******************************************************************************
+ * Definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Location of the memory buffer shared between Normal World (i.e. TFTF) and the
+ * Secure Partition (e.g. Cactus) to pass data associated to secure service
+ * requests.
+ * Note: This address has to match the one used in TF (see ARM_SP_IMAGE_NS_BUF_*
+ * macros).
+ ******************************************************************************/
+#define ARM_SECURE_SERVICE_BUFFER_BASE	0xff600000ull
+#define ARM_SECURE_SERVICE_BUFFER_SIZE	0x10000ull
+
+#endif /* __ARM_DEF_H__ */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
new file mode 100644
index 0000000..3b0b5a6
--- /dev/null
+++ b/include/plat/arm/common/plat_arm.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_ARM_H__
+#define __PLAT_ARM_H__
+
+/*
+ * Initialises the IO
+ * Returns: IO_SUCCESS
+ *          IO_FAIL
+ *          IO_NOT_SUPPORTED
+ *          IO_RESOURCES_EXHAUSTED
+ */
+int arm_io_setup(void);
+
+/* Initialises the IO and the GIC. */
+void arm_platform_setup(void);
+
+/*******************************************************************************
+ * ARM platforms porting interfaces are located below.
+ ******************************************************************************/
+
+/* Initialises the Generic Interrupt Controller (GIC). */
+void plat_arm_gic_init(void);
+
+#endif /* __PLAT_ARM_H__ */
diff --git a/include/plat/common/plat_topology.h b/include/plat/common/plat_topology.h
new file mode 100644
index 0000000..1846b91
--- /dev/null
+++ b/include/plat/common/plat_topology.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_TOPOLOGY_H__
+#define __PLAT_TOPOLOGY_H__
+
+#include <arch.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*
+ * This is the initial value of the power domain index when used
+ * as argument to the tftf topology helpers. They are also used
+ * to indicate the end of iterative topology navigation when returned
+ * by the tftf topology helpers.
+ */
+#define PWR_DOMAIN_INIT		((unsigned int) -1)
+
+/*
+ * Return the total number of clusters in the system.
+ * Currently there is correspondence between power level and affinity
+ * level and hence cluster power level corresponds to affinity level 1.
+ */
+#define tftf_get_total_clusters_count()		tftf_get_total_aff_count(1)
+
+/*
+ * Return the total number of CPUs in the system (across all clusters).
+ * Currently there is correspondence between power level and affinity
+ * level and hence CPU power level correspond to affinity level 0.
+ */
+#define tftf_get_total_cpus_count()		tftf_get_total_aff_count(0)
+
+/*
+ * Converts a 'core_pos' into an MPIDR. The 'core_pos' is a unique number
+ * corresponding to a CPU as returned by platform_get_core_pos() API
+ */
+#define tftf_core_pos_to_mpidr(core_pos)	\
+			tftf_get_mpidr_from_node(core_pos + tftf_pwr_domain_start_idx[0])
+
+/*
+ * The following array stores the start index of each level in the power
+ * domain topology tree.
+ */
+extern unsigned int tftf_pwr_domain_start_idx[PLATFORM_MAX_AFFLVL + 1];
+
+/*
+ * The following data structure represents a TFTF power domain node.
+ */
+typedef struct tftf_pwr_domain_node {
+	/*
+	 * Array index of the first CPU in the topology array for which this
+	 * power domain is the parent. If this power domain is a CPU, then
+	 * `cpu_start_node` will be its own index in the power domain
+	 * topology array.
+	 */
+	unsigned int cpu_start_node;
+
+	/*
+	 * Number of CPU power domains which belong to this power domain.
+	 * i.e. all the CPUs in the range 'cpu_start_node
+	 * -> cpu_start_node + ncpus - 1 ' will belong to this power domain.
+	 * If this power domain is a CPU then 'ncpus' will be 1.
+	 */
+	unsigned int ncpus;
+
+	/* Valid only for CPU power domains */
+	unsigned int mpidr;
+
+	/* Index of the parent power domain node */
+	unsigned int parent_node;
+
+	/*
+	 * The level of this power domain node in the power domain topology
+	 * tree. It could correspond to the affinity level but the platform
+	 * could have power levels which do not match affinity levels.
+	 */
+	unsigned int level;
+
+	/*
+	 * The 'is_present' field is used to cater for power domains
+	 * which are absent.
+	 */
+	unsigned char is_present;
+} tftf_pwr_domain_node_t;
+
+/*
+ * Detect and store the platform topology so that test cases can query it later.
+ */
+void tftf_init_topology(void);
+
+/*
+ * Return the number of affinity instances implemented at the affinity level
+ * passed as an argument. This function returns 0 for any other affinity
+ * level higher than that supported by the platform.
+ */
+unsigned int tftf_get_total_aff_count(unsigned int aff_lvl);
+
+/*
+ * Returns the index of the next power domain after `pwr_domain_idx`
+ * in the topology tree at the same `aff_lvl`. The `pwr_domain_idx`
+ * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
+ * It returns PWR_DOMAIN_INIT if none is found.
+ */
+unsigned int tftf_get_next_peer_domain(unsigned int pwr_domain_idx,
+				      unsigned int pwr_lvl);
+
+/*
+ * Returns the index of the next CPU after the current CPU `cpu_node`
+ * which belongs to the power domain `pwr_domain_idx`. The `cpu_node`
+ * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
+ * It returns PWR_DOMAIN_INIT if none is found.
+ */
+unsigned int tftf_get_next_cpu_in_pwr_domain(unsigned int pwr_domain_idx,
+				      unsigned int cpu_node);
+
+/*
+ * Return the node index of the next CPU after 'cpu_node' in the topology tree.
+ * Skip absent CPUs.
+ * cpu_node: Node index of the current CPU.
+ */
+unsigned int tftf_topology_next_cpu(unsigned int cpu_node);
+
+/*
+ * Iterate over every CPU. Skip absent CPUs.
+ * cpu: unsigned integer corresponding to the index of the cpu in
+ * the topology array. After the loop, cpu is equal to PWR_DOMAIN_INIT.
+ */
+#define for_each_cpu(cpu)				\
+	for ((cpu) = PWR_DOMAIN_INIT;			\
+		(cpu) = tftf_topology_next_cpu(cpu),	\
+		(cpu) != PWR_DOMAIN_INIT;)
+
+/*
+ * Iterate over every power domain idx for a given level.
+ * - idx: unsigned integer corresponding to the power domain index. After the
+ *   loop, idx is equal to PWR_DOMAIN_INIT.
+ * - lvl: level
+ */
+#define for_each_power_domain_idx(idx, lvl)		\
+	for (idx = PWR_DOMAIN_INIT;			\
+	     idx = tftf_get_next_peer_domain(idx, lvl),	\
+		idx != PWR_DOMAIN_INIT;)
+
+/*
+ * Iterate over every CPU in a power domain idx.
+ * - pwr_domain_idx: unsigned integer corresponding to the power domain index.
+ *   After the loop, idx is equal to PWR_DOMAIN_INIT.
+ * - cpu_idx: CPU index
+ */
+#define for_each_cpu_in_power_domain(pwr_domain_idx, cpu_idx)			\
+	for (cpu_idx = PWR_DOMAIN_INIT;						\
+	     cpu_idx = tftf_get_next_cpu_in_pwr_domain(pwr_domain_idx, cpu_idx),\
+		cpu_idx != PWR_DOMAIN_INIT;)
+
+/*
+ * Returns the MPIDR of the CPU power domain node indexed by `cpu_node`
+ * or INVALID_MPID if it is absent.
+ */
+unsigned int tftf_get_mpidr_from_node(unsigned int cpu_node);
+
+/*
+ * Query the platform topology to find another CPU than the one specified
+ * as an argument.
+ * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
+ */
+unsigned int tftf_find_any_cpu_other_than(unsigned int exclude_mpid);
+
+/*
+ * Query the platform topology to find a random CPU other than the one specified
+ * as an argument.
+ * The difference between this function and tftf_find_any_cpu_other_than is
+ * the randomness in selecting a CPU.
+ * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
+ */
+unsigned int tftf_find_random_cpu_other_than(unsigned int exclude_mpid);
+
+#endif /* __PLAT_TOPOLOGY_H__ */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
new file mode 100644
index 0000000..d3a486c
--- /dev/null
+++ b/include/plat/common/platform.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+#include <stdint.h>
+#include <timer.h>
+#include <xlat_tables_v2.h>
+
+#define PLAT_PSCI_DUMMY_STATE_ID		0xF
+
+#define PWR_STATE_INIT_INDEX			(-1)
+
+#define INIT_PWR_LEVEL_INDEX(array_name)					\
+	do {									\
+		unsigned int var;						\
+		assert(ARRAY_SIZE(array_name) == (PLAT_MAX_PWR_LEVEL + 1));	\
+		for (var = 0; var <= PLAT_MAX_PWR_LEVEL; var++)			\
+			array_name[var] = PWR_STATE_INIT_INDEX;			\
+	} while (0)
+
+/*
+ * The platform structure to represent the valid local power state
+ * properties for a particular affinity level. The platform needs to
+ * export the array of valid local low power states for each affinity level
+ * it supports which can be queried by TFTF tests to construct the required
+ * composite power state.
+ *
+ * TODO: Currently the power levels are identity mapped to affinity level in
+ * TFTF which need to be decoupled.
+ */
+typedef struct plat_state_prop {
+	/*
+	 * This field has a value in the increasing order of the suspend
+	 * depth. Deeper the suspend state, higher the value.
+	 */
+	unsigned int suspend_depth;
+	/* The local state ID for the idle state at this level. */
+	unsigned int state_ID;
+	/* Flag which indicates whether is a retention or power down state */
+	unsigned int is_pwrdown;
+} plat_state_prop_t;
+
+void tftf_plat_arch_setup(void);
+void tftf_early_platform_setup(void);
+void tftf_platform_setup(void);
+
+void tftf_plat_enable_mmu(void);
+void tftf_plat_configure_mmu(void);
+
+void tftf_platform_end(void);
+void tftf_platform_watchdog_set(void);
+void tftf_platform_watchdog_reset(void);
+
+/* Gets a handle for the initialised IO entity */
+void plat_get_nvm_handle(uintptr_t *handle);
+
+/*
+ * Returns the platform topology description array. The size of this
+ * array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
+ */
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void);
+
+/*
+ * Function to query the MPIDR of a CPU identified by 'core_pos' which is
+ * the number returned by platform_get_core() API.
+ * In case the CPU is absent, then this API returns INVALID_MPID. This
+ * function will be queried only during topology setup in TFTF and thereafter
+ * the internal node data will be used to get the MPIDR corresponding
+ * to the 'core_pos'.
+ */
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos);
+
+/*
+ * Get the state property array for all the valid states from platform for
+ * a specified 'level'. The array is expected to be NULL terminated after the
+ * last entry.
+ */
+const plat_state_prop_t *plat_get_state_prop(unsigned int level);
+
+/*
+ * Initialises state info data structures for generating various combinations
+ * of state ID's. It also calls tftf_detect_pstate_format() which detects the
+ * PSTATE format accepted by EL3 firmware.
+ * This function needs to be invoked once during cold boot prior to the
+ * invocation of any PSCI power state helper functions.
+ */
+void tftf_init_pstate_framework(void);
+
+/*
+ * This function is used to generate all possible combinations of composite
+ * state ID's possible for a given set of power states at each level.
+ * Ex: If a system implements 4 levels and each level has 3 local power states.
+ * Then, the total combinations of composite power down states possible are:
+ *                                                       3 * 3 * 3 * 3 = 81
+ *
+ * A single call to set_next_state_id_pointers(), sets pointer to pstate_id_idx
+ * at all levels for a possible combination out of 81.
+ *
+ * A caller can confirm when all combinations are completed by checking if
+ * pwr_lvel_state_indexes for power_level 0 is PWR_STATE_INIT_INDEX
+ */
+void tftf_set_next_state_id_idx(unsigned int power_level,
+					unsigned int pstate_id_idx[]);
+
+/*
+ * This function sets the index for the next state ID of the given power level
+ */
+void tftf_set_next_local_state_id_idx(unsigned int power_level,
+					unsigned int pstate_id_idx[]);
+
+/*
+ * This function sets the index corresponding to the deepest power state at
+ * a given power level.
+ */
+void tftf_set_deepest_pstate_idx(unsigned int power_level,
+				unsigned int pstate_id_idx[]);
+
+/*
+ * Helper function to get the state ID, state type, power level in power_state
+ * parameter of CPU_SUSPEND. The generated values are based on the
+ * pstate_id_idx values of a core.
+ *
+ * This helper expects a valid pstate_id_idx till the max valid levels
+ * and it detects the max valid level to be terminated by PWR_STATE_INIT value
+ *
+ * It returns the expected PSCI return value of a suspend request
+ */
+int tftf_get_pstate_vars(unsigned int *test_power_level,
+				unsigned int *test_suspend_type,
+				unsigned int *suspend_state_id,
+				unsigned int pstate_id_idx[]);
+
+/*
+ * This function gets the platform specific timer driver information and
+ * initialises platform specific drivers.
+ * Returns 0 on success.
+ */
+int plat_initialise_timer_ops(const plat_timer_t **timer_ops);
+
+struct mem_region {
+	uintptr_t addr;
+	size_t size;
+};
+
+typedef struct mem_region mem_region_t;
+
+/*******************************************************************************
+ * Optional functions. A default, weak implementation of those functions is
+ * provided, it may be overridden by platform code.
+ ******************************************************************************/
+unsigned int platform_get_core_pos(unsigned long mpid);
+unsigned long platform_get_stack(unsigned long mpidr);
+int plat_crash_console_init(void);
+int plat_crash_console_putc(int c);
+int plat_crash_console_flush(void);
+/*
+ * plat_get_prot_regions: It returns a pointer to a
+ * set of regions used to test mem_protect_check.
+ * The number of elements are stored in the variable
+ *  pointed by nelem.
+ */
+const mem_region_t *plat_get_prot_regions(int *nelem);
+
+void tftf_plat_reset(void);
+
+const mmap_region_t *tftf_platform_get_mmap(void);
+
+/*
+ * Return an IO device handle and specification which can be used
+ * to access an image. Use this to enforce platform load policy.
+ */
+int plat_get_image_source(unsigned int image_id,
+		uintptr_t *dev_handle,
+		uintptr_t *image_spec);
+
+void plat_fwu_io_setup(void);
+
+#endif /* __PLATFORM_H__ */