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/plat/arm/board/fvp/aarch32/plat_helpers.S b/plat/arm/board/fvp/aarch32/plat_helpers.S
new file mode 100644
index 0000000..2dcc6e9
--- /dev/null
+++ b/plat/arm/board/fvp/aarch32/plat_helpers.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include "../fvp_def.h"
+
+ .globl platform_get_core_pos
+
+/*----------------------------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on FVP.
+ *
+ * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +
+ * (CPUId * FVP_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func platform_get_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation
+ */
+ tst r0, #MPIDR_MT_MASK
+ mov r3, r0
+ lsleq r3, r0, #MPIDR_AFFINITY_BITS
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov r3, #FVP_MAX_CPUS_PER_CLUSTER
+ mla r1, r2, r3, r1
+ mov r3, #FVP_MAX_PE_PER_CPU
+ mla r0, r1, r3, r0
+
+ bx lr
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/fvp/aarch64/plat_helpers.S b/plat/arm/board/fvp/aarch64/plat_helpers.S
new file mode 100644
index 0000000..bc9f60d
--- /dev/null
+++ b/plat/arm/board/fvp/aarch64/plat_helpers.S
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include "../fvp_def.h"
+
+ .globl platform_get_core_pos
+
+/*----------------------------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on FVP.
+ *
+ * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +
+ * (CPUId * FVP_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func platform_get_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x3, #FVP_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x3, x1
+ mov x3, #FVP_MAX_PE_PER_CPU
+ madd x0, x1, x3, x0
+ ret
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
new file mode 100644
index 0000000..a47287f
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*******************************************************************************
+ * FVP specific definitions. Used only by FVP specific code.
+ ******************************************************************************/
+
+#ifndef __FVP_DEF_H__
+#define __FVP_DEF_H__
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Cluster Topology definitions
+ ******************************************************************************/
+#define FVP_MAX_CPUS_PER_CLUSTER 4
+/* Currently the highest cluster count on the FVP is 4 (Quad cluster) */
+#define FVP_CLUSTER_COUNT 4
+/* Currently multi-threaded CPUs only have a single thread */
+#define FVP_MAX_PE_PER_CPU 1
+
+/*******************************************************************************
+ * FVP memory map related constants
+ ******************************************************************************/
+
+#define DEVICE0_BASE 0x1a000000
+#define DEVICE0_SIZE 0x12200000
+
+#define DEVICE1_BASE 0x2f000000
+#define DEVICE1_SIZE 0x400000
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+/* Base FVP compatible GIC memory map */
+#define GICD_BASE 0x2f000000
+#define GICR_BASE 0x2f100000
+#define GICC_BASE 0x2c000000
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+#define PL011_UART0_BASE 0x1c090000
+#define PL011_UART0_CLK_IN_HZ 24000000
+
+#define PLAT_ARM_UART_BASE PL011_UART0_BASE
+#define PLAT_ARM_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
+
+#endif /* __FVP_DEF_H__ */
diff --git a/plat/arm/board/fvp/fvp_mem_prot.c b/plat/arm/board/fvp/fvp_mem_prot.c
new file mode 100644
index 0000000..6a7d651
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_mem_prot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+#include <psci.h>
+#include <utils_def.h>
+#include <xlat_tables_v2.h>
+
+#define NS_IMAGE_OFFSET TFTF_BASE
+#define NS_IMAGE_LIMIT (NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
+
+static const mem_region_t fvp_ram_ranges[] = {
+ {NS_IMAGE_LIMIT, 1 << ONE_GB_SHIFT},
+#ifdef AARCH64
+ {FVP_DRAM2_BASE, 1 << ONE_GB_SHIFT},
+#endif
+};
+
+const mem_region_t *plat_get_prot_regions(int *nelem)
+{
+ *nelem = ARRAY_SIZE(fvp_ram_ranges);
+ return fvp_ram_ranges;
+}
diff --git a/plat/arm/board/fvp/fvp_pwr_state.c b/plat/arm/board/fvp/fvp_pwr_state.c
new file mode 100644
index 0000000..394818b
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_pwr_state.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform.h>
+#include <psci.h>
+#include <stddef.h>
+
+/*
+ * State IDs for local power states on the FVP.
+ */
+#define FVP_RUN_STATE_ID 0 /* Valid for CPUs and Clusters */
+#define FVP_RETENTION_STATE_ID 1 /* Valid for only CPUs */
+#define FVP_OFF_STATE_ID 2 /* Valid for CPUs and Clusters */
+
+/*
+ * Suspend depth definitions for each power state
+ */
+typedef enum {
+ FVP_RUN_DEPTH = 0,
+ FVP_RETENTION_DEPTH,
+ FVP_OFF_DEPTH,
+} suspend_depth_t;
+
+/* The state property array with details of idle state possible for the core */
+static const plat_state_prop_t core_state_prop[] = {
+ {FVP_RETENTION_DEPTH, FVP_RETENTION_STATE_ID, PSTATE_TYPE_STANDBY},
+ {FVP_OFF_DEPTH, FVP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+/* The state property array with details of idle state possible
+ for the cluster */
+static const plat_state_prop_t cluster_state_prop[] = {
+ {FVP_OFF_DEPTH, FVP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+/* The state property array with details of idle state possible
+ for the system level */
+static const plat_state_prop_t system_state_prop[] = {
+ {FVP_OFF_DEPTH, FVP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+const plat_state_prop_t *plat_get_state_prop(unsigned int level)
+{
+ switch (level) {
+ case MPIDR_AFFLVL0:
+ return core_state_prop;
+ case MPIDR_AFFLVL1:
+ return cluster_state_prop;
+ case MPIDR_AFFLVL2:
+ return system_state_prop;
+ default:
+ return NULL;
+ }
+}
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
new file mode 100644
index 0000000..348f8ef
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <mmio.h>
+#include <plat_topology.h>
+#include <platform_def.h>
+#include <stddef.h>
+#include <tftf_lib.h>
+
+/* FVP Power controller based defines */
+#define PWRC_BASE 0x1c100000
+#define PSYSR_OFF 0x10
+#define PSYSR_INVALID 0xffffffff
+
+static const struct {
+ unsigned int cluster_id;
+ unsigned int cpu_id;
+} fvp_base_aemv8a_aemv8a_cores[] = {
+ /* Cluster 0 */
+ { 0, 0 },
+ { 0, 1 },
+ { 0, 2 },
+ { 0, 3 },
+ /* Cluster 1 */
+ { 1, 0 },
+ { 1, 1 },
+ { 1, 2 },
+ { 1, 3 },
+ /* Cluster 2 */
+ { 2, 0 },
+ { 2, 1 },
+ { 2, 2 },
+ { 2, 3 },
+ /* Cluster 3 */
+ { 3, 0 },
+ { 3, 1 },
+ { 3, 2 },
+ { 3, 3 },
+};
+
+/*
+ * The FVP power domain tree descriptor. We always construct a topology
+ * with the maximum number of cluster nodes possible for FVP. During
+ * TFTF initialization, the actual number of nodes present on the model
+ * will be queried dynamically using `tftf_plat_get_mpidr()`.
+ * The FVP power domain tree does not have a single system level power domain
+ * i.e. a single root node. The first entry in the power domain descriptor
+ * specifies the number of power domains at the highest power level which
+ * is equal to FVP_CLUSTER_COUNT.
+ */
+static const unsigned char fvp_power_domain_tree_desc[] = {
+ /* Number of system nodes */
+ 1,
+ /* Number of cluster nodes */
+ FVP_CLUSTER_COUNT,
+ /* Number of children for the first node */
+ FVP_MAX_CPUS_PER_CLUSTER,
+ /* Number of children for the second node */
+ FVP_MAX_CPUS_PER_CLUSTER,
+ /* Number of children for the third node */
+ FVP_MAX_CPUS_PER_CLUSTER,
+ /* Number of children for the fourth node */
+ FVP_MAX_CPUS_PER_CLUSTER
+};
+
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
+{
+ return fvp_power_domain_tree_desc;
+}
+
+static unsigned int fvp_pwrc_read_psysr(unsigned long mpidr)
+{
+ unsigned int rc;
+ mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
+ rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
+ return rc;
+}
+
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
+{
+ unsigned int mpid;
+
+ assert(core_pos < PLATFORM_CORE_COUNT);
+
+ mpid = make_mpid(
+ fvp_base_aemv8a_aemv8a_cores[core_pos].cluster_id,
+ fvp_base_aemv8a_aemv8a_cores[core_pos].cpu_id);
+
+ if (fvp_pwrc_read_psysr(mpid) != PSYSR_INVALID)
+ return mpid;
+
+ return INVALID_MPID;
+}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
new file mode 100644
index 0000000..f09b6b5
--- /dev/null
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arm_def.h>
+#include "../fvp_def.h"
+
+/*******************************************************************************
+ * Platform definitions used by common code
+ ******************************************************************************/
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#ifndef AARCH32
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+#else
+#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
+#define PLATFORM_LINKER_ARCH arm
+#endif
+
+/*******************************************************************************
+ * Run-time address of the TFTF image.
+ * It has to match the location where the Trusted Firmware-A loads the BL33
+ * image.
+ ******************************************************************************/
+#define TFTF_BASE 0x88000000
+
+/* Base address of non-trusted watchdog (SP805) */
+#define SP805_WDOG_BASE 0x1C0F0000
+
+/*******************************************************************************
+ * Base address and size of external NVM flash
+ ******************************************************************************/
+#define FLASH_BASE 0x08000000
+
+/*
+ * The flash memory in FVP resembles as a SCSP package of 2-die's and
+ * of a total size of 512Mb, we are using only the main blocks of size
+ * 128KB for storing results. Also the FVP performs data striping and
+ * splits the word into half to each flash die's which leads to a
+ * virtual block size of 256KB to software.
+ */
+#define NOR_FLASH_BLOCK_SIZE 0x40000 /* 256KB */
+#define NOR_FLASH_BLOCKS_COUNT 255
+#define FLASH_SIZE (NOR_FLASH_BLOCK_SIZE * NOR_FLASH_BLOCKS_COUNT)
+
+/*******************************************************************************
+ * Base address and size for the FIP that contains FWU images.
+ ******************************************************************************/
+#define PLAT_ARM_FWU_FIP_BASE (FLASH_BASE + 0x400000)
+#define PLAT_ARM_FWU_FIP_SIZE (0x100000)
+
+/*******************************************************************************
+ * Base address and size for non-trusted SRAM.
+ ******************************************************************************/
+#define NSRAM_BASE (0x2e000000)
+#define NSRAM_SIZE (0x00010000)
+
+/*******************************************************************************
+ * Corresponds to the function ID of the BL1 SMC handler for FWU process.
+ ******************************************************************************/
+#define BL1_SMC_CALL_COUNT 0x0
+#define BL1_SMC_UID 0x1
+/* SMC #0x2 reserved */
+#define BL1_SMC_VERSION 0x3
+#define FWU_SMC_IMAGE_COPY 0x10
+#define FWU_SMC_IMAGE_AUTH 0x11
+#define FWU_SMC_IMAGE_EXECUTE 0x12
+#define FWU_SMC_IMAGE_RESUME 0x13
+#define FWU_SMC_SEC_IMAGE_DONE 0x14
+#define FWU_SMC_UPDATE_DONE 0x15
+#define FWU_SMC_IMAGE_RESET 0x16
+
+
+/*******************************************************************************
+ * NS_BL1U specific defines.
+ * NS_BL1U RW data is relocated from NS-ROM to NS-RAM at runtime so we
+ * need 2 sets of addresses.
+ ******************************************************************************/
+#define NS_BL1U_RO_BASE (0x08000000 + 0x03EB8000)
+#define NS_BL1U_RO_LIMIT (NS_BL1U_RO_BASE + 0xC000)
+
+/*******************************************************************************
+ * Put NS_BL1U RW at the top of the Non-Trusted SRAM. NS_BL1U_RW_BASE is
+ * calculated using the current NS_BL1U RW debug size plus a little space
+ * for growth.
+ ******************************************************************************/
+#define NS_BL1U_RW_SIZE (0x7000)
+#define NS_BL1U_RW_BASE (NSRAM_BASE)
+#define NS_BL1U_RW_LIMIT (NS_BL1U_RW_BASE + NS_BL1U_RW_SIZE)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define FVP_DRAM1_BASE 0x80000000
+#define FVP_DRAM2_BASE 0x880000000
+#define DRAM_BASE FVP_DRAM1_BASE
+#define DRAM_SIZE 0x80000000
+
+/*******************************************************************************
+ * Base address and limit for NS_BL2U image.
+ ******************************************************************************/
+#define NS_BL2U_BASE DRAM_BASE
+#define NS_BL2U_LIMIT (NS_BL2U_BASE + 0x4D000)
+
+/******************************************************************************
+ * Memory mapped Generic timer interfaces
+ ******************************************************************************/
+/* REFCLK CNTControl, Generic Timer. Secure Access only. */
+#define SYS_CNT_CONTROL_BASE 0x2a430000
+/* REFCLK CNTRead, Generic Timer. */
+#define SYS_CNT_READ_BASE 0x2a800000
+/* AP_REFCLK CNTBase1, Generic Timer. */
+#define SYS_CNT_BASE1 0x2a830000
+
+/* V2M motherboard system registers & offsets */
+#define VE_SYSREGS_BASE 0x1c010000
+#define V2M_SYS_LED 0x8
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if IMAGE_NS_BL1U || IMAGE_NS_BL2U
+#define PLATFORM_STACK_SIZE 0x1000
+#else
+#define PLATFORM_STACK_SIZE 0x1400
+#endif
+
+/* Size of coherent stacks for debug and release builds */
+#if DEBUG
+#define PCPU_DV_MEM_STACK_SIZE 0x600
+#else
+#define PCPU_DV_MEM_STACK_SIZE 0x500
+#endif
+
+#define PLATFORM_CORE_COUNT (FVP_CLUSTER_COUNT * \
+ FVP_MAX_CPUS_PER_CLUSTER)
+#define PLATFORM_NUM_AFFS (1 + FVP_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
+
+/* TODO : Migrate complete TFTF from affinity level to power levels */
+#define PLAT_MAX_PWR_LEVEL PLATFORM_MAX_AFFLVL
+#define PLAT_MAX_PWR_STATES_PER_LVL 2
+
+#if IMAGE_NS_BL1U
+#define MAX_IO_DEVICES 2
+#define MAX_IO_HANDLES 2
+#else
+#define MAX_IO_DEVICES 1
+#define MAX_IO_HANDLES 1
+#endif
+
+/* Local state bit width for each level in the state-ID field of power state */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+
+#if USE_NVM
+/*
+ * The Flash memory is used to store the TFTF data on FVP.
+ * However, it might contain other data that must not be overwritten.
+ * For example, when using the Trusted Firmware-A, the FIP image
+ * (containing the bootloader images) is also stored in Flash.
+ * Hence, consider the first 40MB of Flash as reserved for firmware usage.
+ * The TFTF can use the rest of the Flash memory.
+ */
+#define TFTF_NVM_OFFSET 0x2800000 /* 40 MB */
+#define TFTF_NVM_SIZE (FLASH_SIZE - TFTF_NVM_OFFSET)
+#else
+/*
+ * If you want to run without support for non-volatile memory (due to
+ * e.g. unavailability of a flash driver), DRAM can be used instead as
+ * a workaround. The TFTF binary itself is loaded at 0x88000000 so the
+ * first 128MB can be used
+ * Please note that this won't be suitable for all test scenarios and
+ * for this reason some tests will be disabled in this configuration.
+ */
+#define TFTF_NVM_OFFSET 0x0
+#define TFTF_NVM_SIZE (TFTF_BASE - DRAM_BASE - TFTF_NVM_OFFSET)
+#endif
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
+#if IMAGE_TFTF
+#define MAX_XLAT_TABLES 6
+#define MAX_MMAP_REGIONS 16
+#else
+#define MAX_XLAT_TABLES 5
+#define MAX_MMAP_REGIONS 16
+#endif
+
+/*******************************************************************************
+ * Used to align variables on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * Non-Secure Software Generated Interupts IDs
+ ******************************************************************************/
+#define IRQ_NS_SGI_0 0
+#define IRQ_NS_SGI_1 1
+#define IRQ_NS_SGI_2 2
+#define IRQ_NS_SGI_3 3
+#define IRQ_NS_SGI_4 4
+#define IRQ_NS_SGI_5 5
+#define IRQ_NS_SGI_6 6
+#define IRQ_NS_SGI_7 7
+
+/*
+ * On FVP, consider that the last SPI is the Trusted Random Number Generator
+ * interrupt.
+ */
+#define PLAT_MAX_SPI_OFFSET_ID 107
+
+/* AP_REFCLK, Generic Timer, CNTPSIRQ1. */
+#define IRQ_CNTPSIRQ1 58
+/* Per-CPU Hypervisor Timer Interrupt ID */
+#define IRQ_PCPU_HP_TIMER 26
+/* Per-CPU Non-Secure Timer Interrupt ID */
+#define IRQ_PCPU_NS_TIMER 30
+
+
+/* Times(in ms) used by test code for completion of different events */
+#define PLAT_SUSPEND_ENTRY_TIME 15
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME 30
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/fvp/plat_setup.c b/plat/arm/board/fvp/plat_setup.c
new file mode 100644
index 0000000..0d81686
--- /dev/null
+++ b/plat/arm/board/fvp/plat_setup.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_gic.h>
+#include <plat_arm.h>
+#include <platform.h>
+
+/*
+ * Table of regions to map using the MMU.
+ */
+#if IMAGE_NS_BL1U
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_MEMORY | MT_RO | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+ };
+#elif IMAGE_NS_BL2U
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+#elif IMAGE_TFTF
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS),
+#if USE_NVM
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_DEVICE | MT_RW | MT_NS),
+#endif
+ MAP_REGION_FLAT(DRAM_BASE, TFTF_BASE - DRAM_BASE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+#endif /* IMAGE_NS_BL1U */
+
+const mmap_region_t *tftf_platform_get_mmap(void)
+{
+ return mmap;
+}
+
+void plat_arm_gic_init(void)
+{
+ arm_gic_init(GICC_BASE, GICD_BASE, GICR_BASE);
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
new file mode 100644
index 0000000..281a5f3
--- /dev/null
+++ b/plat/arm/board/fvp/platform.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES := -Iplat/arm/board/fvp/include/
+
+PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
+ drivers/arm/gic/gic_v2.c \
+ drivers/arm/gic/gic_v3.c \
+ drivers/arm/sp805/sp805.c \
+ drivers/arm/timer/private_timer.c \
+ drivers/arm/timer/system_timer.c \
+ lib/semihosting/${ARCH}/semihosting_call.S \
+ lib/semihosting/semihosting.c \
+ plat/arm/board/fvp/${ARCH}/plat_helpers.S \
+ plat/arm/board/fvp/fvp_pwr_state.c \
+ plat/arm/board/fvp/fvp_topology.c \
+ plat/arm/board/fvp/fvp_mem_prot.c \
+ plat/arm/board/fvp/plat_setup.c
+
+# Firmware update is implemented on FVP.
+FIRMWARE_UPDATE := 1
+
+include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/juno/aarch32/plat_helpers.S b/plat/arm/board/juno/aarch32/plat_helpers.S
new file mode 100644
index 0000000..6f252c0
--- /dev/null
+++ b/plat/arm/board/juno/aarch32/plat_helpers.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+ .globl platform_get_core_pos
+
+ /*
+ * Return 0 to 3 for the Cortex-A53 cores and 4 to 5 for the Cortex-A57
+ * cores.
+ */
+func platform_get_core_pos
+ and r1, r0, #MPIDR_CPU_MASK
+ and r0, r0, #MPIDR_CLUSTER_MASK
+ /* Swap Cortex-A53/Cortex-A57 order. */
+ eor r0, r0, #(1 << MPIDR_AFF1_SHIFT)
+ add r0, r1, r0, LSR #6
+ bx lr
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/juno/aarch64/plat_helpers.S b/plat/arm/board/juno/aarch64/plat_helpers.S
new file mode 100644
index 0000000..c51a4d9
--- /dev/null
+++ b/plat/arm/board/juno/aarch64/plat_helpers.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+ .globl platform_get_core_pos
+
+ /*
+ * Return 0 to 3 for the Cortex-A53 cores and 4 to 5 for the Cortex-A57
+ * cores.
+ */
+func platform_get_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ /* Swap Cortex-A53/Cortex-A57 order. */
+ eor x0, x0, #(1 << MPIDR_AFF1_SHIFT)
+ add x0, x1, x0, LSR #6
+ ret
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
new file mode 100644
index 0000000..37b419f
--- /dev/null
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arm_def.h>
+#include "../juno_def.h"
+
+/*******************************************************************************
+ * Platform definitions used by common code
+ ******************************************************************************/
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#ifndef AARCH32
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+#else
+#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
+#define PLATFORM_LINKER_ARCH arm
+#endif
+
+/*******************************************************************************
+ * Run-time address of the TFTF image.
+ * It has to match the location where the Trusted Firmware-A loads the BL33
+ * image.
+ ******************************************************************************/
+#define TFTF_BASE 0xE0000000
+
+#define JUNO_DRAM1_BASE 0x80000000
+#define JUNO_DRAM2_BASE 0x880000000
+#define DRAM_BASE JUNO_DRAM1_BASE
+#define DRAM_SIZE 0x80000000
+
+/* Base address of non-trusted watchdog (SP805) */
+#define SP805_WDOG_BASE 0x1C0F0000
+
+/* Memory mapped Generic timer interfaces */
+#define SYS_CNT_BASE1 0x2a830000
+
+/* V2M motherboard system registers & offsets */
+#define VE_SYSREGS_BASE 0x1c010000
+#define V2M_SYS_LED 0x8
+
+/*******************************************************************************
+ * Base address and size of external NVM flash
+ ******************************************************************************/
+#define FLASH_BASE 0x08000000
+
+/*
+ * The flash chip on Juno is a SCSP package of 2-die's and of a total size of
+ * 512Mb, we are using only the main blocks of size 128KB for storing results.
+ * The SMC controller performs data striping and splits the word into half to
+ * each flash die's which leads to a virtual block size of 256KB to software.
+ */
+#define NOR_FLASH_BLOCK_SIZE 0x40000
+#define NOR_FLASH_BLOCKS_COUNT 255
+#define FLASH_SIZE (NOR_FLASH_BLOCK_SIZE * NOR_FLASH_BLOCKS_COUNT)
+
+/*******************************************************************************
+ * Base address and size for the FIP that contains FWU images.
+ ******************************************************************************/
+#define PLAT_ARM_FWU_FIP_BASE (FLASH_BASE + 0x400000)
+#define PLAT_ARM_FWU_FIP_SIZE (0x100000)
+
+/*******************************************************************************
+ * Base address and size for non-trusted SRAM.
+ ******************************************************************************/
+#define NSRAM_BASE (0x2e000000)
+#define NSRAM_SIZE (0x00008000)
+
+/*******************************************************************************
+ * Corresponds to the function ID of the BL1 SMC handler for FWU process.
+ ******************************************************************************/
+#define BL1_SMC_CALL_COUNT 0x0
+#define BL1_SMC_UID 0x1
+/* SMC #0x2 reserved */
+#define BL1_SMC_VERSION 0x3
+#define FWU_SMC_IMAGE_COPY 0x10
+#define FWU_SMC_IMAGE_AUTH 0x11
+#define FWU_SMC_IMAGE_EXECUTE 0x12
+#define FWU_SMC_IMAGE_RESUME 0x13
+#define FWU_SMC_SEC_IMAGE_DONE 0x14
+#define FWU_SMC_UPDATE_DONE 0x15
+#define FWU_SMC_IMAGE_RESET 0x16
+
+/*******************************************************************************
+ * NS_BL1U specific defines.
+ * NS_BL1U RW data is relocated from NS-ROM to NS-RAM at runtime so we
+ * need 2 sets of addresses.
+ ******************************************************************************/
+#define NS_BL1U_RO_BASE (0x08000000 + 0x03EB8000)
+#define NS_BL1U_RO_LIMIT (NS_BL1U_RO_BASE + 0xC000)
+
+/*******************************************************************************
+ * Put NS_BL1U RW at the top of the Non-Trusted SRAM. NS_BL1U_RW_BASE is
+ * calculated using the current NS_BL1U RW debug size plus a little space
+ * for growth.
+ ******************************************************************************/
+#define NS_BL1U_RW_SIZE (0x7000)
+#define NS_BL1U_RW_BASE (NSRAM_BASE)
+#define NS_BL1U_RW_LIMIT (NS_BL1U_RW_BASE + NS_BL1U_RW_SIZE)
+
+/*******************************************************************************
+ * Base address and limit for NS_BL2U image.
+ ******************************************************************************/
+#define NS_BL2U_BASE DRAM_BASE
+#define NS_BL2U_LIMIT (NS_BL2U_BASE + 0x4D000)
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if IMAGE_NS_BL1U
+#define PLATFORM_STACK_SIZE 0x1000
+#elif IMAGE_NS_BL2U
+#define PLATFORM_STACK_SIZE 0x1000
+#elif IMAGE_TFTF
+#define PLATFORM_STACK_SIZE 0x1400
+#endif
+
+/* Size of coherent stacks for debug and release builds */
+#if DEBUG
+#define PCPU_DV_MEM_STACK_SIZE 0x600
+#else
+#define PCPU_DV_MEM_STACK_SIZE 0x500
+#endif
+
+#define PLATFORM_SYSTEM_COUNT 1
+#define PLATFORM_CLUSTER_COUNT 2
+#define PLATFORM_CLUSTER1_CORE_COUNT 4 /* Cortex-A53 Cluster */
+#define PLATFORM_CLUSTER0_CORE_COUNT 2 /* Cortex-A57 Cluster */
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
+ PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
+ PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LEVEL PLATFORM_MAX_AFFLVL
+#define PLAT_MAX_PWR_STATES_PER_LVL 2
+
+/* Local state bit width for each level in the state-ID field of power state */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+
+#if IMAGE_NS_BL1U
+#define MAX_IO_DEVICES 2
+#define MAX_IO_HANDLES 2
+#else
+#define MAX_IO_DEVICES 1
+#define MAX_IO_HANDLES 1
+#endif
+
+#if USE_NVM
+/*
+ * The Flash memory is used to store TFTF data on Juno.
+ * However, it might contain other data that must not be overwritten.
+ * For example, when using the Trusted Firmware-A, the FIP image
+ * (containing the bootloader images) is also stored in Flash.
+ * Hence, consider the first 40MB of Flash as reserved for firmware usage.
+ * The TFTF can use the rest of the Flash memory.
+ */
+#define TFTF_NVM_OFFSET 0x2800000 /* 40MB */
+#define TFTF_NVM_SIZE (FLASH_SIZE - TFTF_NVM_OFFSET)
+#else
+/*
+ * If you want to run without support for non-volatile memory (due to e.g.
+ * unavailability of a flash driver), DRAM can be used instead as workaround.
+ * The TFTF binary itself is loaded at 0xE0000000 so we have plenty of free
+ * memory at the beginning of the DRAM. Let's use the first 128MB.
+ *
+ * Please note that this won't be suitable for all test scenarios and
+ * for this reason some tests will be disabled in this configuration.
+ */
+#define TFTF_NVM_OFFSET 0x0
+#define TFTF_NVM_SIZE 0x8000000 /* 128 MB */
+#endif
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
+#define MAX_XLAT_TABLES 5
+#define MAX_MMAP_REGIONS 16
+
+/*******************************************************************************
+ * Used to align variables on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * Non-Secure Software Generated Interupts IDs
+ ******************************************************************************/
+#define IRQ_NS_SGI_0 0
+#define IRQ_NS_SGI_1 1
+#define IRQ_NS_SGI_2 2
+#define IRQ_NS_SGI_3 3
+#define IRQ_NS_SGI_4 4
+#define IRQ_NS_SGI_5 5
+#define IRQ_NS_SGI_6 6
+#define IRQ_NS_SGI_7 7
+
+#define PLAT_MAX_SPI_OFFSET_ID 220
+
+/* The IRQ generated by Ethernet controller */
+#define IRQ_ETHERNET 192
+
+#define IRQ_CNTPSIRQ1 92
+/* Per-CPU Hypervisor Timer Interrupt ID */
+#define IRQ_PCPU_HP_TIMER 26
+/* Per-CPU Non-Secure Timer Interrupt ID */
+#define IRQ_PCPU_NS_TIMER 30
+
+/*
+ * Times(in ms) used by test code for completion of different events.
+ * Suspend entry time for debug build is high due to the time taken
+ * by the VERBOSE/INFO prints. The value considers the worst case scenario
+ * where all CPUs are going and coming out of suspend continuously.
+ */
+#if DEBUG
+#define PLAT_SUSPEND_ENTRY_TIME 0x100
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME 0x200
+#else
+#define PLAT_SUSPEND_ENTRY_TIME 10
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME 20
+#endif
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/juno/juno32_tests_to_skip.txt b/plat/arm/board/juno/juno32_tests_to_skip.txt
new file mode 100644
index 0000000..078e363
--- /dev/null
+++ b/plat/arm/board/juno/juno32_tests_to_skip.txt
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# System suspend is not supported on AArch32 Juno.
+PSCI System Suspend Validation
+PSCI STAT/Stats test cases after system suspend
+IRQ support in TSP/Resume preempted STD SMC after PSCI SYSTEM SUSPEND
+PSCI SYSTEM SUSPEND stress tests
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
new file mode 100644
index 0000000..930332f
--- /dev/null
+++ b/plat/arm/board/juno/juno_def.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __JUNO_DEF_H__
+#define __JUNO_DEF_H__
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Juno memory map related constants
+ ******************************************************************************/
+/* First peripherals region excluding Non-Trusted ROM and Non-Trusted RAM */
+#define DEVICE0_BASE 0x20000000
+#define DEVICE0_SIZE 0x0e000000
+
+/* PCIe expansion region and 2nd peripherals region */
+#define DEVICE1_BASE 0x40000000
+#define DEVICE1_SIZE 0x40000000
+
+#define IOFPGA_PERIPHERALS_BASE 0x1c000000
+#define IOFPGA_PERIPHERALS_SIZE 0x3000000
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+#define GICD_BASE 0x2c010000
+#define GICC_BASE 0x2c02f000
+/* Juno doesn't support GIC Redistributor, it's a GICv3 feature */
+#define GICR_BASE 0
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+/* SoC UART0 */
+#define PL011_UART2_BASE 0x7ff80000
+#define PL011_UART2_CLK_IN_HZ 7273800
+
+#define PLAT_ARM_UART_BASE PL011_UART2_BASE
+#define PLAT_ARM_UART_CLK_IN_HZ PL011_UART2_CLK_IN_HZ
+
+/*******************************************************************************
+ * Motherboard timer related constants
+ ******************************************************************************/
+#define MB_TIMER1_BASE 0x1C120000
+#define MB_TIMER1_IRQ 198
+#define MB_TIMER1_FREQ 32000
+
+/*******************************************************************************
+ * Ethernet controller related constants
+ ******************************************************************************/
+#define ETHERNET_BASE 0x18000000
+#define ETHERNET_SIZE 0x04000000
+#define ETHERNET_IRQ_CFG_OFFSET 0x54
+#define ETHERNET_IRQ_CFG_VAL 0x11
+
+#endif /* __JUNO_DEF_H__ */
+
diff --git a/plat/arm/board/juno/juno_mem_prot.c b/plat/arm/board/juno/juno_mem_prot.c
new file mode 100644
index 0000000..f0e3506
--- /dev/null
+++ b/plat/arm/board/juno/juno_mem_prot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+#include <psci.h>
+#include <utils_def.h>
+#include <xlat_tables_v2.h>
+
+#define NS_IMAGE_OFFSET TFTF_BASE
+#define NS_IMAGE_LIMIT (NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
+
+static const mem_region_t juno_ram_ranges[] = {
+ {NS_IMAGE_LIMIT, 128 << TWO_MB_SHIFT},
+#ifdef AARCH64
+ {JUNO_DRAM2_BASE, 1 << ONE_GB_SHIFT},
+#endif
+};
+
+const mem_region_t *plat_get_prot_regions(int *nelem)
+{
+ *nelem = ARRAY_SIZE(juno_ram_ranges);
+ return juno_ram_ranges;
+}
diff --git a/plat/arm/board/juno/juno_pwr_state.c b/plat/arm/board/juno/juno_pwr_state.c
new file mode 100644
index 0000000..1e067c2
--- /dev/null
+++ b/plat/arm/board/juno/juno_pwr_state.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform.h>
+#include <psci.h>
+#include <stddef.h>
+
+/*
+ * State IDs for local power states on Juno.
+ */
+#define JUNO_RUN_STATE_ID 0 /* Valid for CPUs and Clusters */
+#define JUNO_RETENTION_STATE_ID 1 /* Valid for only CPUs */
+#define JUNO_OFF_STATE_ID 2 /* Valid for CPUs and Clusters */
+
+/*
+ * Suspend depth definitions for each power state
+ */
+typedef enum {
+ JUNO_RUN_DEPTH = 0,
+ JUNO_RETENTION_DEPTH,
+ JUNO_OFF_DEPTH,
+} suspend_depth_t;
+
+/* The state property array with details of idle state possible for the core */
+static const plat_state_prop_t core_state_prop[] = {
+ {JUNO_RETENTION_DEPTH, JUNO_RETENTION_STATE_ID, PSTATE_TYPE_STANDBY},
+ {JUNO_OFF_DEPTH, JUNO_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+/*
+ * The state property array with details of idle state possible
+ * for the cluster
+ */
+static const plat_state_prop_t cluster_state_prop[] = {
+ {JUNO_OFF_DEPTH, JUNO_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+/*
+ * The state property array with details of idle state possible
+ * for the system. Currently Juno does not support CPU SUSPEND
+ * at system power level.
+ */
+static const plat_state_prop_t system_state_prop[] = {
+ {JUNO_OFF_DEPTH, JUNO_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+const plat_state_prop_t *plat_get_state_prop(unsigned int level)
+{
+ switch (level) {
+ case MPIDR_AFFLVL0:
+ return core_state_prop;
+ case MPIDR_AFFLVL1:
+ return cluster_state_prop;
+ case MPIDR_AFFLVL2:
+ return system_state_prop;
+ default:
+ return NULL;
+ }
+}
diff --git a/plat/arm/board/juno/juno_timers.c b/plat/arm/board/juno/juno_timers.c
new file mode 100644
index 0000000..1d1ce48
--- /dev/null
+++ b/plat/arm/board/juno/juno_timers.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <sp804.h>
+#include <stddef.h>
+#include <timer.h>
+
+static const plat_timer_t plat_timers = {
+ .program = sp804_timer_program,
+ .cancel = sp804_timer_cancel,
+ .handler = sp804_timer_handler,
+ .timer_step_value = 2,
+ .timer_irq = MB_TIMER1_IRQ /* Motherboard SP804 timer1 IRQ */
+};
+
+int plat_initialise_timer_ops(const plat_timer_t **timer_ops)
+{
+ assert(timer_ops != NULL);
+ *timer_ops = &plat_timers;
+
+ /* Initialise the system timer */
+ sp804_timer_init(MB_TIMER1_BASE, MB_TIMER1_FREQ);
+
+ return 0;
+}
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
new file mode 100644
index 0000000..f7e0044
--- /dev/null
+++ b/plat/arm/board/juno/juno_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <plat_topology.h>
+#include <platform_def.h>
+#include <stddef.h>
+#include <tftf_lib.h>
+
+static const struct {
+ unsigned cluster_id;
+ unsigned cpu_id;
+} juno_cores[] = {
+ /* Cortex-A53 Cluster: 4 cores*/
+ { 1, 0 },
+ { 1, 1 },
+ { 1, 2 },
+ { 1, 3 },
+ /* Cortex-A57 Cluster: 2 cores */
+ { 0, 0 },
+ { 0, 1 },
+};
+
+/*
+ * The Juno power domain tree descriptor. Juno implements a system
+ * power domain at the level 2. The first entry in the power domain descriptor
+ * specifies the number of power domains at the highest power level. For Juno
+ * this is 1 i.e. the number of system power domain.
+ */
+static const unsigned char juno_power_domain_tree_desc[] = {
+ /* Number of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* Number of children of root node */
+ PLATFORM_CLUSTER_COUNT,
+ /* Number of children for the first cluster */
+ PLATFORM_CLUSTER1_CORE_COUNT,
+ /* Number of children for the second cluster */
+ PLATFORM_CLUSTER0_CORE_COUNT
+};
+
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
+{
+ return juno_power_domain_tree_desc;
+}
+
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
+{
+ assert(core_pos < PLATFORM_CORE_COUNT);
+
+ return make_mpid(juno_cores[core_pos].cluster_id,
+ juno_cores[core_pos].cpu_id);
+}
diff --git a/plat/arm/board/juno/plat_setup.c b/plat/arm/board/juno/plat_setup.c
new file mode 100644
index 0000000..8792cb3
--- /dev/null
+++ b/plat/arm/board/juno/plat_setup.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_gic.h>
+#include <mmio.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <xlat_tables_v2.h>
+
+/*
+ * Table of regions to map using the MMU.
+ */
+#if IMAGE_NS_BL1U
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_MEMORY | MT_RO | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+#elif IMAGE_NS_BL2U
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(IOFPGA_PERIPHERALS_BASE, IOFPGA_PERIPHERALS_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+#elif IMAGE_TFTF
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(ETHERNET_BASE, ETHERNET_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(IOFPGA_PERIPHERALS_BASE, IOFPGA_PERIPHERALS_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS),
+#if USE_NVM
+ MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_DEVICE | MT_RW | MT_NS),
+#endif
+ MAP_REGION_FLAT(DRAM_BASE, TFTF_BASE - DRAM_BASE, MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+#endif /* IMAGE_NS_BL1U */
+
+const mmap_region_t *tftf_platform_get_mmap(void)
+{
+ return mmap;
+}
+
+void tftf_platform_setup(void)
+{
+ arm_platform_setup();
+
+#if !IMAGE_NS_BL2U
+ /*
+ * The Ethernet IRQ line is high by default which prevents Juno
+ * from entering system suspend. Configure it to be low.
+ *
+ * Interrupts are disabled in NS_BL2U so there's no need to fix this
+ * as we are not going to suspend the system.
+ *
+ * TODO: Currently this needs to be done in a loop for the write
+ * to IRQ_CFG register to take effect. Need to find the reason for
+ * this behavior.
+ */
+ int val;
+
+ do {
+ mmio_write_32(ETHERNET_BASE + ETHERNET_IRQ_CFG_OFFSET,
+ ETHERNET_IRQ_CFG_VAL);
+
+ val = mmio_read_8(ETHERNET_BASE + ETHERNET_IRQ_CFG_OFFSET);
+ } while (val != ETHERNET_IRQ_CFG_VAL);
+#endif /* IMAGE_NS_BL2U */
+}
+
+void plat_arm_gic_init(void)
+{
+ arm_gic_init(GICC_BASE, GICD_BASE, GICR_BASE);
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
new file mode 100644
index 0000000..97172b5
--- /dev/null
+++ b/plat/arm/board/juno/platform.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES := -Iplat/arm/board/juno/include/
+
+PLAT_SOURCES := drivers/arm/gic/arm_gic_v2.c \
+ drivers/arm/gic/gic_v2.c \
+ drivers/arm/sp805/sp805.c \
+ drivers/arm/timer/private_timer.c \
+ drivers/arm/timer/sp804.c \
+ plat/arm/board/juno/${ARCH}/plat_helpers.S \
+ plat/arm/board/juno/juno_pwr_state.c \
+ plat/arm/board/juno/juno_timers.c \
+ plat/arm/board/juno/juno_topology.c \
+ plat/arm/board/juno/juno_mem_prot.c \
+ plat/arm/board/juno/plat_setup.c
+
+TESTS_SOURCES += tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
+
+# Some tests are not supported on Juno AArch32.
+ifeq (${ARCH},aarch32)
+PLAT_TESTS_SKIP_LIST := plat/arm/board/juno/juno32_tests_to_skip.txt
+endif
+
+PLAT_SUPPORTS_NS_RESET := 1
+
+# Process PLAT_SUPPORTS_NS_RESET flag
+$(eval $(call assert_boolean,PLAT_SUPPORTS_NS_RESET))
+$(eval $(call add_define,TFTF_DEFINES,PLAT_SUPPORTS_NS_RESET))
+
+ifeq (${ARCH},aarch32)
+ifeq (${FIRMWARE_UPDATE},1)
+$(error "FIRMWARE_UPDATE is not supported on Juno aarch32")
+endif
+else
+FIRMWARE_UPDATE := 1
+endif
+
+include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/juno/tests.xml b/plat/arm/board/juno/tests.xml
new file mode 100644
index 0000000..8e679c3
--- /dev/null
+++ b/plat/arm/board/juno/tests.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2018, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<!-- External references to all individual tests files. -->
+<!DOCTYPE testsuites [
+ <!ENTITY tests-tftf-validation SYSTEM "../../../../tftf/tests/tests-tftf-validation.xml">
+ <!ENTITY tests-boot-req SYSTEM "../../../../tftf/tests/tests-boot-req.xml">
+ <!ENTITY tests-psci SYSTEM "../../../../tftf/tests/tests-psci.xml">
+ <!ENTITY tests-sdei SYSTEM "../../../../tftf/tests/tests-sdei.xml">
+ <!ENTITY tests-rt-instr SYSTEM "../../../../tftf/tests/tests-runtime-instrumentation.xml">
+ <!ENTITY tests-tsp SYSTEM "../../../../tftf/tests/tests-tsp.xml">
+ <!ENTITY tests-el3-pstate SYSTEM "../../../../tftf/tests/tests-el3-power-state.xml">
+ <!ENTITY tests-state-switch SYSTEM "../../../../tftf/tests/tests-arm-state-switch.xml">
+ <!ENTITY tests-cpu-extensions SYSTEM "../../../../tftf/tests/tests-cpu-extensions.xml">
+ <!ENTITY tests-performance SYSTEM "../../../../tftf/tests/tests-performance.xml">
+]>
+
+<testsuites>
+
+ &tests-tftf-validation;
+ &tests-boot-req;
+ &tests-psci;
+ &tests-sdei;
+ &tests-rt-instr;
+ &tests-tsp;
+ &tests-el3-pstate;
+ &tests-state-switch;
+ &tests-cpu-extensions;
+ &tests-performance;
+
+ <testsuite name="Juno - IRQ support in TSP" description="Test the normal IRQ preemption support in TSP.">
+ <testcase name="Juno - Multicore spurious interrupt test" function="test_juno_multicore_spurious_interrupt" />
+ </testsuite>
+
+</testsuites>
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
new file mode 100644
index 0000000..73b4690
--- /dev/null
+++ b/plat/arm/common/arm_common.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES += -Iinclude/plat/arm/common/
+
+PLAT_SOURCES += drivers/arm/gic/gic_common.c \
+ drivers/arm/pl011/${ARCH}/pl011_console.S \
+ plat/arm/common/arm_setup.c \
+ plat/arm/common/arm_timers.c
+
+# Flash driver sources.
+PLAT_SOURCES += drivers/io/io_storage.c \
+ drivers/io/vexpress_nor/io_vexpress_nor_ops.c \
+ drivers/io/vexpress_nor/io_vexpress_nor_hw.c \
+ plat/arm/common/arm_io_storage.c
diff --git a/plat/arm/common/arm_fwu_io_storage.c b/plat/arm/common/arm_fwu_io_storage.c
new file mode 100644
index 0000000..184f2af
--- /dev/null
+++ b/plat/arm/common/arm_fwu_io_storage.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <image_loader.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <tftf_lib.h>
+
+/* May be overridden in specific ARM standard platform */
+#pragma weak plat_arm_fwu_io_setup
+
+/* IO devices */
+static const io_dev_connector_t *fwu_fip_dev_con;
+static uintptr_t fwu_fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fwu_fip_block_spec = {
+ .offset = PLAT_ARM_FWU_FIP_BASE,
+ .length = PLAT_ARM_FWU_FIP_SIZE
+};
+static const io_uuid_spec_t fwu_cert_uuid_spec = {
+ .uuid = UUID_FIRMWARE_UPDATE_FWU_CERT,
+};
+static const io_uuid_spec_t scp_bl2u_uuid_spec = {
+ .uuid = UUID_FIRMWARE_UPDATE_SCP_BL2U,
+};
+static const io_uuid_spec_t bl2u_uuid_spec = {
+ .uuid = UUID_FIRMWARE_UPDATE_BL2U,
+};
+static const io_uuid_spec_t ns_bl2u_uuid_spec = {
+ .uuid = UUID_FIRMWARE_UPDATE_NS_BL2U,
+};
+
+static int open_fwu_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+ [FWU_FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fwu_fip_block_spec,
+ open_memmap
+ },
+ [FWU_CERT_ID] = {
+ &fwu_fip_dev_handle,
+ (uintptr_t)&fwu_cert_uuid_spec,
+ open_fwu_fip
+ },
+ [SCP_BL2U_IMAGE_ID] = {
+ &fwu_fip_dev_handle,
+ (uintptr_t)&scp_bl2u_uuid_spec,
+ open_fwu_fip
+ },
+ [BL2U_IMAGE_ID] = {
+ &fwu_fip_dev_handle,
+ (uintptr_t)&bl2u_uuid_spec,
+ open_fwu_fip
+ },
+ [NS_BL2U_IMAGE_ID] = {
+ &fwu_fip_dev_handle,
+ (uintptr_t)&ns_bl2u_uuid_spec,
+ open_fwu_fip
+ },
+};
+
+
+/* Weak definitions may be overridden in each specific platform */
+#pragma weak plat_get_image_source
+
+static int open_fwu_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fwu_fip_dev_handle,
+ (uintptr_t)FWU_FIP_IMAGE_ID);
+ if (result == IO_SUCCESS) {
+ result = io_open(fwu_fip_dev_handle, spec,
+ &local_image_handle);
+ if (result == IO_SUCCESS) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == IO_SUCCESS) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == IO_SUCCESS) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+void plat_arm_fwu_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fwu_fip_dev_con);
+ assert(io_result == IO_SUCCESS);
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ assert(io_result == IO_SUCCESS);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fwu_fip_dev_con, (uintptr_t)NULL,
+ &fwu_fip_dev_handle);
+ assert(io_result == IO_SUCCESS);
+
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+ assert(io_result == IO_SUCCESS);
+
+ /* Ignore improbable errors in release builds */
+ (void)io_result;
+}
+
+
+/* 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)
+{
+ int result = IO_FAIL;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ policy = &policies[image_id];
+ result = policy->check(policy->image_spec);
+ if (result == IO_SUCCESS) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+
+ return result;
+}
+
+void plat_fwu_io_setup(void)
+{
+ plat_arm_fwu_io_setup();
+}
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
new file mode 100644
index 0000000..d9d8a38
--- /dev/null
+++ b/plat/arm/common/arm_io_storage.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <io_driver.h>
+#include <io_nor_flash.h>
+#include <io_storage.h>
+#include <platform.h>
+#include <tftf.h>
+#include "platform_def.h"
+
+#pragma weak plat_get_nvm_handle
+
+/* IO devices */
+static const io_dev_connector_t *flash_dev_con;
+static uintptr_t flash_dev_spec;
+static uintptr_t flash_init_params;
+static uintptr_t flash_dev_handle;
+static uintptr_t flash_handle;
+static unsigned int flash_init;
+
+static const io_nor_flash_spec_t flash_main_block_spec = {
+ .device_address = FLASH_BASE,
+ .region_address = FLASH_BASE,
+ .block_size = NOR_FLASH_BLOCK_SIZE,
+ .block_count = FLASH_SIZE / NOR_FLASH_BLOCK_SIZE
+};
+
+int arm_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_nor_flash(&flash_dev_con);
+ if (io_result != IO_SUCCESS)
+ return io_result;
+
+ io_result = io_dev_open(flash_dev_con, flash_dev_spec,
+ &flash_dev_handle);
+ if (io_result != IO_SUCCESS)
+ return io_result;
+
+ io_result = io_dev_init(flash_dev_handle, flash_init_params);
+ if (io_result != IO_SUCCESS)
+ return io_result;
+
+ io_result = io_open(flash_dev_handle,
+ (uintptr_t)&flash_main_block_spec,
+ &flash_handle);
+
+ if (io_result == IO_SUCCESS)
+ flash_init = 1;
+ return io_result;
+}
+
+void plat_get_nvm_handle(uintptr_t *handle)
+{
+ assert(handle);
+ assert(flash_init);
+
+ *handle = flash_handle;
+}
+
diff --git a/plat/arm/common/arm_setup.c b/plat/arm/common/arm_setup.c
new file mode 100644
index 0000000..79f4631
--- /dev/null
+++ b/plat/arm/common/arm_setup.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_gic.h>
+#include <console.h>
+#include <debug.h>
+#include <io_storage.h>
+#include <pl011.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <platform_def.h>
+
+#pragma weak tftf_platform_setup
+
+void arm_platform_setup(void)
+{
+#if USE_NVM
+ int ret;
+
+ ret = arm_io_setup();
+ if (ret != IO_SUCCESS)
+ WARN("IO setup failed : 0x%x\n", ret);
+#endif
+
+#if IMAGE_NS_BL2U
+ /* NS_BL2U is not expecting interrupts. */
+ return;
+#endif
+
+ plat_arm_gic_init();
+
+ arm_gic_setup_global();
+ arm_gic_setup_local();
+}
+
+void tftf_platform_setup(void)
+{
+ arm_platform_setup();
+}
+
+void tftf_plat_arch_setup(void)
+{
+ tftf_plat_configure_mmu();
+}
+
+void tftf_early_platform_setup(void)
+{
+ console_init(PLAT_ARM_UART_BASE, PLAT_ARM_UART_CLK_IN_HZ,
+ PL011_BAUDRATE);
+}
diff --git a/plat/arm/common/arm_timers.c b/plat/arm/common/arm_timers.c
new file mode 100644
index 0000000..c84cb84
--- /dev/null
+++ b/plat/arm/common/arm_timers.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform.h>
+#include <stddef.h>
+#include <system_timer.h>
+#include <timer.h>
+
+#pragma weak plat_initialise_timer_ops
+
+static const plat_timer_t plat_timers = {
+ .program = program_systimer,
+ .cancel = cancel_systimer,
+ .handler = handler_systimer,
+ .timer_step_value = 2,
+ .timer_irq = IRQ_CNTPSIRQ1
+};
+
+int plat_initialise_timer_ops(const plat_timer_t **timer_ops)
+{
+ assert(timer_ops != NULL);
+ *timer_ops = &plat_timers;
+
+ /* Initialise the system timer */
+ init_systimer(SYS_CNT_BASE1);
+
+ return 0;
+}