summaryrefslogtreecommitdiffstats
path: root/plat/arm/board/juno
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:13:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:13:47 +0000
commit102b0d2daa97dae68d3eed54d8fe37a9cc38a892 (patch)
treebcf648efac40ca6139842707f0eba5a4496a6dd2 /plat/arm/board/juno
parentInitial commit. (diff)
downloadarm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.tar.xz
arm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.zip
Adding upstream version 2.8.0+dfsg.upstream/2.8.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--plat/arm/board/juno/aarch32/juno_helpers.S176
-rw-r--r--plat/arm/board/juno/aarch64/juno_helpers.S275
-rw-r--r--plat/arm/board/juno/fdts/juno_fw_config.dts27
-rw-r--r--plat/arm/board/juno/fdts/juno_tb_fw_config.dts26
-rw-r--r--plat/arm/board/juno/include/plat_macros.S24
-rw-r--r--plat/arm/board/juno/include/platform_def.h313
-rw-r--r--plat/arm/board/juno/jmptbl.i62
-rw-r--r--plat/arm/board/juno/juno_bl1_setup.c122
-rw-r--r--plat/arm/board/juno/juno_bl2_setup.c73
-rw-r--r--plat/arm/board/juno/juno_bl31_setup.c60
-rw-r--r--plat/arm/board/juno/juno_common.c134
-rw-r--r--plat/arm/board/juno/juno_def.h99
-rw-r--r--plat/arm/board/juno/juno_err.c27
-rw-r--r--plat/arm/board/juno/juno_pm.c17
-rw-r--r--plat/arm/board/juno/juno_security.c166
-rw-r--r--plat/arm/board/juno/juno_stack_protector.c27
-rw-r--r--plat/arm/board/juno/juno_topology.c78
-rw-r--r--plat/arm/board/juno/juno_trng.c108
-rw-r--r--plat/arm/board/juno/juno_trusted_boot.c126
-rw-r--r--plat/arm/board/juno/juno_tzmp1_def.h83
-rw-r--r--plat/arm/board/juno/platform.mk201
-rw-r--r--plat/arm/board/juno/sp_min/sp_min-juno.mk22
-rw-r--r--plat/arm/board/juno/tsp/tsp-juno.mk12
23 files changed, 2258 insertions, 0 deletions
diff --git a/plat/arm/board/juno/aarch32/juno_helpers.S b/plat/arm/board/juno/aarch32/juno_helpers.S
new file mode 100644
index 0000000..8f9561c
--- /dev/null
+++ b/plat/arm/board/juno/aarch32/juno_helpers.S
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+
+ .globl plat_reset_handler
+ .globl plat_arm_calc_core_pos
+
+#define JUNO_REVISION(rev) REV_JUNO_R##rev
+#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev
+#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \
+ jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
+
+ /* --------------------------------------------------------------------
+ * Helper macro to jump to the given handler if the board revision
+ * matches.
+ * Expects the Juno board revision in x0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_to_handler _revision, _handler
+ cmp r0, #\_revision
+ beq \_handler
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R0.
+ *
+ * Juno R0 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Implement workaround for defect id 831273 by enabling an event
+ * stream every 65536 cycles.
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(0)
+ /* --------------------------------------------------------------------
+ * Enable the event stream every 65536 cycles
+ * --------------------------------------------------------------------
+ */
+ mov r0, #(0xf << EVNTI_SHIFT)
+ orr r0, r0, #EVNTEN_BIT
+ stcopr r0, CNTKCTL
+
+ /* --------------------------------------------------------------------
+ * Nothing else to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A53_MIDR, 1f
+
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #((CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (CORTEX_A57_L2_TAG_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ stcopr r0, CORTEX_A57_L2CTLR
+1:
+ isb
+ bx lr
+endfunc JUNO_HANDLER(0)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R1.
+ *
+ * Juno R1 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ *
+ * Note that:
+ * - The default value for the L2 Tag RAM latency for Cortex-A57 is
+ * suitable.
+ * - Defect #831273 doesn't affect Juno R1.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(1)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A57_MIDR, A57
+ bx lr
+
+A57:
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #(CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT)
+ stcopr r0, CORTEX_A57_L2CTLR
+ isb
+ bx lr
+endfunc JUNO_HANDLER(1)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R2.
+ *
+ * Juno R2 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A72 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72
+ * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72
+ *
+ * Note that:
+ * - Defect #831273 doesn't affect Juno R2.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(2)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A72_MIDR, A72
+ bx lr
+
+A72:
+ /* --------------------------------------------------------------------
+ * Cortex-A72 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES << CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ stcopr r0, CORTEX_A72_L2CTLR
+ isb
+ bx lr
+endfunc JUNO_HANDLER(2)
+
+ /* --------------------------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the Juno board revision and call the appropriate reset
+ * handler.
+ * --------------------------------------------------------------------
+ */
+func plat_reset_handler
+ /* Read the V2M SYS_ID register */
+ ldr r0, =(V2M_SYSREGS_BASE + V2M_SYS_ID)
+ ldr r1, [r0]
+ /* Extract board revision from the SYS_ID */
+ ubfx r0, r1, #V2M_SYS_ID_REV_SHIFT, #4
+
+ JUMP_TO_HANDLER_IF_JUNO_R(0)
+ JUMP_TO_HANDLER_IF_JUNO_R(1)
+ JUMP_TO_HANDLER_IF_JUNO_R(2)
+
+ /* Board revision is not supported */
+ no_ret plat_panic_handler
+
+endfunc plat_reset_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * -----------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ b css_calc_core_pos_swap_cluster
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
new file mode 100644
index 0000000..c94fa3e
--- /dev/null
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+
+ .globl plat_reset_handler
+ .globl plat_arm_calc_core_pos
+#if JUNO_AARCH32_EL3_RUNTIME
+ .globl plat_get_my_entrypoint
+ .globl juno_reset_to_aarch32_state
+#endif
+
+#define JUNO_REVISION(rev) REV_JUNO_R##rev
+#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev
+#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \
+ jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
+
+ /* --------------------------------------------------------------------
+ * Helper macro to jump to the given handler if the board revision
+ * matches.
+ * Expects the Juno board revision in x0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_to_handler _revision, _handler
+ cmp x0, #\_revision
+ b.eq \_handler
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R0.
+ *
+ * Juno R0 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Implement workaround for defect id 831273 by enabling an event
+ * stream every 65536 cycles.
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(0)
+ /* --------------------------------------------------------------------
+ * Enable the event stream every 65536 cycles
+ * --------------------------------------------------------------------
+ */
+ mov x0, #(0xf << EVNTI_SHIFT)
+ orr x0, x0, #EVNTEN_BIT
+ msr CNTKCTL_EL1, x0
+
+ /* --------------------------------------------------------------------
+ * Nothing else to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A53_MIDR, 1f
+
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov x0, #((CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (CORTEX_A57_L2_TAG_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ msr CORTEX_A57_L2CTLR_EL1, x0
+1:
+ isb
+ ret
+endfunc JUNO_HANDLER(0)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R1.
+ *
+ * Juno R1 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ *
+ * Note that:
+ * - The default value for the L2 Tag RAM latency for Cortex-A57 is
+ * suitable.
+ * - Defect #831273 doesn't affect Juno R1.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(1)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A57_MIDR, A57
+ ret
+
+A57:
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov x0, #(CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT)
+ msr CORTEX_A57_L2CTLR_EL1, x0
+ isb
+ ret
+endfunc JUNO_HANDLER(1)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R2.
+ *
+ * Juno R2 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A72 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72
+ * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72
+ *
+ * Note that:
+ * - Defect #831273 doesn't affect Juno R2.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(2)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A72_MIDR, A72
+ ret
+
+A72:
+ /* --------------------------------------------------------------------
+ * Cortex-A72 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov x0, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES << CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ msr CORTEX_A57_L2CTLR_EL1, x0
+ isb
+ ret
+endfunc JUNO_HANDLER(2)
+
+ /* --------------------------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the Juno board revision and call the appropriate reset
+ * handler.
+ * --------------------------------------------------------------------
+ */
+func plat_reset_handler
+ /* Read the V2M SYS_ID register */
+ mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
+ ldr w1, [x0]
+ /* Extract board revision from the SYS_ID */
+ ubfx x0, x1, #V2M_SYS_ID_REV_SHIFT, #4
+
+ JUMP_TO_HANDLER_IF_JUNO_R(0)
+ JUMP_TO_HANDLER_IF_JUNO_R(1)
+ JUMP_TO_HANDLER_IF_JUNO_R(2)
+
+ /* Board revision is not supported */
+ no_ret plat_panic_handler
+
+endfunc plat_reset_handler
+
+ /* -----------------------------------------------------
+ * void juno_do_reset_to_aarch32_state(void);
+ *
+ * Request warm reset to AArch32 mode.
+ * -----------------------------------------------------
+ */
+func juno_do_reset_to_aarch32_state
+ mov x0, #RMR_EL3_RR_BIT
+ dsb sy
+ msr rmr_el3, x0
+ isb
+ wfi
+ b plat_panic_handler
+endfunc juno_do_reset_to_aarch32_state
+
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * -----------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ b css_calc_core_pos_swap_cluster
+endfunc plat_arm_calc_core_pos
+
+#if JUNO_AARCH32_EL3_RUNTIME
+ /* ---------------------------------------------------------------------
+ * uintptr_t plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish between a cold and a warm
+ * boot. On JUNO platform, this distinction is based on the contents of
+ * the Trusted Mailbox. It is initialised to zero by the SCP before the
+ * AP cores are released from reset. Therefore, a zero mailbox means
+ * it's a cold reset. If it is a warm boot then a request to reset to
+ * AArch32 state is issued. This is the only way to reset to AArch32
+ * in EL3 on Juno. A trampoline located at the high vector address
+ * has already been prepared by BL1.
+ *
+ * This functions returns the contents of the mailbox, i.e.:
+ * - 0 for a cold boot;
+ * - request warm reset in AArch32 state for warm boot case;
+ * ---------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+ ldr x0, [x0]
+ cbz x0, return
+ b juno_do_reset_to_aarch32_state
+return:
+ ret
+endfunc plat_get_my_entrypoint
+
+/*
+ * Emit a "movw r0, #imm16" which moves the lower
+ * 16 bits of `_val` into r0.
+ */
+.macro emit_movw _reg_d, _val
+ mov_imm \_reg_d, (0xe3000000 | \
+ ((\_val & 0xfff) | \
+ ((\_val & 0xf000) << 4)))
+.endm
+
+/*
+ * Emit a "movt r0, #imm16" which moves the upper
+ * 16 bits of `_val` into r0.
+ */
+.macro emit_movt _reg_d, _val
+ mov_imm \_reg_d, (0xe3400000 | \
+ (((\_val & 0x0fff0000) >> 16) | \
+ ((\_val & 0xf0000000) >> 12)))
+.endm
+
+/*
+ * This function writes the trampoline code at HI-VEC (0xFFFF0000)
+ * address which loads r0 with the entrypoint address for
+ * BL32 (a.k.a SP_MIN) when EL3 is in AArch32 mode. A warm reset
+ * to AArch32 mode is then requested by writing into RMR_EL3.
+ */
+func juno_reset_to_aarch32_state
+ /*
+ * Invalidate all caches before the warm reset to AArch32 state.
+ * This is required on the Juno AArch32 boot flow because the L2
+ * unified cache may contain code and data from when the processor
+ * was still executing in AArch64 state. This code only runs on
+ * the primary core, all other cores are powered down.
+ */
+ mov x0, #DCISW
+ bl dcsw_op_all
+
+ emit_movw w0, BL32_BASE
+ emit_movt w1, BL32_BASE
+ /* opcode "bx r0" to branch using r0 in AArch32 mode */
+ mov_imm w2, 0xe12fff10
+
+ /* Write the above opcodes at HI-VECTOR location */
+ mov_imm x3, HI_VECTOR_BASE
+ str w0, [x3], #4
+ str w1, [x3], #4
+ str w2, [x3]
+
+ b juno_do_reset_to_aarch32_state
+endfunc juno_reset_to_aarch32_state
+
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
new file mode 100644
index 0000000..4b88efe
--- /dev/null
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x8000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
new file mode 100644
index 0000000..80cfa3e
--- /dev/null
+++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/juno/include/plat_macros.S b/plat/arm/board/juno/include/plat_macros.S
new file mode 100644
index 0000000..ec94a4f
--- /dev/null
+++ b/plat/arm/board/juno/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <cci_macros.S>
+#include <css_macros.S>
+
+ /* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ css_print_gic_regs
+ print_cci_regs
+ .endm
+
+#endif /* PLAT_MACROS_S */
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..409d7a6
--- /dev/null
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <drivers/arm/tzc400.h>
+#if TRUSTED_BOARD_BOOT
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+
+#include "../juno_def.h"
+
+/* Required platform porting definitions */
+/* Juno supports system power domain */
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
+#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
+ JUNO_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+#define PLATFORM_CORE_COUNT (JUNO_CLUSTER0_CORE_COUNT + \
+ JUNO_CLUSTER1_CORE_COUNT)
+
+/* Cryptocell HW Base address */
+#define PLAT_CRYPTOCELL_BASE UL(0x60050000)
+
+/*
+ * Other platform porting definitions are provided by included headers
+ */
+
+/*
+ * Required ARM standard platform porting definitions
+ */
+#define PLAT_ARM_CLUSTER_COUNT JUNO_CLUSTER_COUNT
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */
+
+/* Use the bypass address */
+#define PLAT_ARM_TRUSTED_ROM_BASE (V2M_FLASH0_BASE + \
+ BL1_ROM_BYPASS_OFFSET)
+
+#define NSRAM_BASE UL(0x2e000000)
+#define NSRAM_SIZE UL(0x00008000) /* 32KB */
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
+/* Range of kernel DTB load address */
+#define JUNO_DTB_DRAM_MAP_START ULL(0x82000000)
+#define JUNO_DTB_DRAM_MAP_SIZE ULL(0x00008000) /* 32KB */
+
+#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
+ JUNO_DTB_DRAM_MAP_START, \
+ JUNO_DTB_DRAM_MAP_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
+
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000)
+#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0x8000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0)
+#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0)
+#endif
+
+/*
+ * Actual ROM size on Juno is 64 KB, but TBB currently requires at least 80 KB
+ * in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of
+ * flash
+ */
+
+#if TRUSTED_BOARD_BOOT
+#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x00020000)
+#else
+#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x00010000)
+#endif /* TRUSTED_BOARD_BOOT */
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#ifdef IMAGE_BL1
+# define PLAT_ARM_MMAP_ENTRIES 7
+# define MAX_XLAT_TABLES 4
+#endif
+
+#ifdef IMAGE_BL2
+#ifdef SPD_opteed
+# define PLAT_ARM_MMAP_ENTRIES 11
+# define MAX_XLAT_TABLES 5
+#else
+# define PLAT_ARM_MMAP_ENTRIES 10
+# define MAX_XLAT_TABLES 4
+#endif
+#endif
+
+#ifdef IMAGE_BL2U
+# define PLAT_ARM_MMAP_ENTRIES 5
+# define MAX_XLAT_TABLES 3
+#endif
+
+#ifdef IMAGE_BL31
+# define PLAT_ARM_MMAP_ENTRIES 7
+# define MAX_XLAT_TABLES 5
+#endif
+
+#ifdef IMAGE_BL32
+# define PLAT_ARM_MMAP_ENTRIES 6
+# define MAX_XLAT_TABLES 4
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xB000)
+#else
+# define PLAT_ARM_MAX_BL1_RW_SIZE UL(0x6000)
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1F000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
+#elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
+#else
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
+#endif
+#else
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL31 -> BL2_BASE.
+ * Hence the BL31 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE.
+ */
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000)
+
+#if JUNO_AARCH32_EL3_RUNTIME
+/*
+ * Since BL32 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL32_SIZE is
+ * calculated using the current BL32 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL32 -> BL2_BASE.
+ * Hence the BL32 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE.
+ */
+#define PLAT_ARM_MAX_BL32_SIZE UL(0x3D000)
+#endif
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE UL(0x1000)
+# else
+# define PLATFORM_STACK_SIZE UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE UL(0x1000)
+# else
+# define PLATFORM_STACK_SIZE UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE UL(0x400)
+#elif defined(IMAGE_BL31)
+# if PLAT_XLAT_TABLES_DYNAMIC
+# define PLATFORM_STACK_SIZE UL(0x800)
+# else
+# define PLATFORM_STACK_SIZE UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE UL(0x440)
+#endif
+
+/* CCI related constants */
+#define PLAT_ARM_CCI_BASE UL(0x2c090000)
+#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 4
+#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 3
+
+/* System timer related constants */
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+
+/* TZC related constants */
+#define PLAT_ARM_TZC_BASE UL(0x2a4a0000)
+#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | \
+ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT))
+
+/* TZC related constants */
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
+
+/*
+ * Required ARM CSS based platform porting definitions
+ */
+
+/* GIC related constants (no GICR in GIC-400) */
+#define PLAT_ARM_GICD_BASE UL(0x2c010000)
+#define PLAT_ARM_GICC_BASE UL(0x2c02f000)
+#define PLAT_ARM_GICH_BASE UL(0x2c04f000)
+#define PLAT_ARM_GICV_BASE UL(0x2c06f000)
+
+/* MHU related constants */
+#define PLAT_CSS_MHU_BASE UL(0x2b1f0000)
+
+/*
+ * Base address of the first memory region used for communication between AP
+ * and SCP. Used by the BOM and SCPI protocols.
+ */
+#if !CSS_USE_SCMI_SDS_DRIVER
+/*
+ * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
+ * means the SCP/AP configuration data gets overwritten when the AP initiates
+ * communication with the SCP. The configuration data is expected to be a
+ * 32-bit word on all CSS platforms. On Juno, part of this configuration is
+ * which CPU is the primary, according to the shift and mask definitions below.
+ */
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + UL(0x80))
+#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
+#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4
+#endif
+
+/*
+ * SCP_BL2 uses up whatever remaining space is available as it is loaded before
+ * anything else in this memory region and is handed over to the SCP before
+ * BL31 is loaded over the top.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE \
+ ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
+
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+ CSS_G1S_IRQ_PROPS(grp), \
+ ARM_G1S_IRQ_PROPS(grp), \
+ INTR_PROP_DESC(JUNO_IRQ_DMA_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_HDLCD0_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_HDLCD1_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_USB_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_THIN_LINKS_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_SEC_I2C, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_GPU_SMMU_1, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(JUNO_IRQ_ETR_SMMU, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+
+/*
+ * Required ARM CSS SoC based platform porting definitions
+ */
+
+/* CSS SoC NIC-400 Global Programmers View (GPV) */
+#define PLAT_SOC_CSS_NIC400_BASE UL(0x2a000000)
+
+#define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS
+#define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS
+
+/* System power domain level */
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#endif
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
new file mode 100644
index 0000000..8932aa0
--- /dev/null
+++ b/plat/arm/board/juno/jmptbl.i
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform specific romlib functions can be added or included here.
+# The index in the output file will be generated cumulatively in the same
+# order as it is given in this file.
+# Output file can be found at: $BUILD_DIR/jmptbl.i
+#
+# Format:
+# lib function [patch]
+# Example:
+# rom rom_lib_init
+# fdt fdt_getprop_namelen patch
+
+rom rom_lib_init
+fdt fdt_getprop
+fdt fdt_get_property
+fdt fdt_getprop_namelen
+fdt fdt_setprop_inplace
+fdt fdt_check_header
+fdt fdt_node_offset_by_compatible
+fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
+fdt fdt_parent_offset
+fdt fdt_stringlist_search
+fdt fdt_get_alias_namelen
+fdt fdt_path_offset
+fdt fdt_path_offset_namelen
+fdt fdt_address_cells
+fdt fdt_size_cells
+fdt fdt_get_name
+fdt fdt_get_alias
+fdt fdt_node_offset_by_phandle
+fdt fdt_subnode_offset
+fdt fdt_add_subnode
+mbedtls mbedtls_asn1_get_alg
+mbedtls mbedtls_asn1_get_alg_null
+mbedtls mbedtls_asn1_get_bitstring_null
+mbedtls mbedtls_asn1_get_bool
+mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_tag
+mbedtls mbedtls_free
+mbedtls mbedtls_md
+mbedtls mbedtls_md_get_size
+mbedtls mbedtls_memory_buffer_alloc_init
+mbedtls mbedtls_oid_get_md_alg
+mbedtls mbedtls_oid_get_numeric_string
+mbedtls mbedtls_oid_get_pk_alg
+mbedtls mbedtls_oid_get_sig_alg
+mbedtls mbedtls_pk_free
+mbedtls mbedtls_pk_init
+mbedtls mbedtls_pk_parse_subpubkey
+mbedtls mbedtls_pk_verify_ext
+mbedtls mbedtls_platform_set_snprintf
+mbedtls mbedtls_x509_get_rsassa_pss_params
+mbedtls mbedtls_x509_get_sig_alg
+mbedtls mbedtls_md_info_from_type
+c exit
+c atexit
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
new file mode 100644
index 0000000..a9d5cc3
--- /dev/null
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/sp805.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+void juno_reset_to_aarch32_state(void);
+
+static int is_watchdog_reset(void)
+{
+#if !CSS_USE_SCMI_SDS_DRIVER
+ #define RESET_REASON_WDOG_RESET (0x2)
+ const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN;
+
+ if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0)
+ return 1;
+
+ return 0;
+#else
+ int ret;
+ uint32_t scp_reset_synd_flags;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SCP SDS initialization failed\n");
+ panic();
+ }
+
+ ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID,
+ SDS_RESET_SYNDROME_OFFSET,
+ &scp_reset_synd_flags,
+ SDS_RESET_SYNDROME_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Getting reset reason from SDS failed\n");
+ panic();
+ }
+
+ /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */
+ if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT)
+ return 1;
+
+ return 0;
+#endif
+}
+
+/*******************************************************************************
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or watchdog reset happened.
+ ******************************************************************************/
+bool plat_arm_bl1_fwu_needed(void)
+{
+ int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR);
+
+ /* Check if TOC is invalid or watchdog reset happened. */
+ return (!arm_io_is_toc_valid() || (((nv_flags == -EAUTH) ||
+ (nv_flags == -ENOENT)) && is_watchdog_reset()));
+}
+
+/*******************************************************************************
+ * On JUNO update the arg2 with address of SCP_BL2U image info.
+ ******************************************************************************/
+void bl1_plat_set_ep_info(unsigned int image_id,
+ entry_point_info_t *ep_info)
+{
+ if (image_id == BL2U_IMAGE_ID) {
+ image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID);
+ ep_info->args.arg2 = (unsigned long)&image_desc->image_info;
+ }
+}
+
+/*******************************************************************************
+ * On Juno clear SYS_NVFLAGS and wait for watchdog reset.
+ ******************************************************************************/
+__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
+{
+ uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR);
+
+ /* Clear the NV flags register. */
+ mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR),
+ nv_flags);
+
+ /* Setup the watchdog to reset the system as soon as possible */
+ sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
+
+ while (true)
+ wfi();
+}
+
+#if JUNO_AARCH32_EL3_RUNTIME
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#if !ARM_DISABLE_TRUSTED_WDOG
+ /* Disable watchdog before leaving BL1 */
+ sp805_stop(ARM_SP805_TWDG_BASE);
+#endif
+
+ juno_reset_to_aarch32_state();
+}
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
new file mode 100644
index 0000000..849acd6
--- /dev/null
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-2017,2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+#if JUNO_AARCH32_EL3_RUNTIME
+/*******************************************************************************
+ * This function changes the spsr for BL32 image to bypass
+ * the check in BL1 AArch64 exception handler. This is needed in the aarch32
+ * boot flow as the core comes up in aarch64 and to enter the BL32 image a warm
+ * reset in aarch32 state is required.
+ ******************************************************************************/
+int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = arm_bl2_handle_post_image_load(image_id);
+
+ if (!err && (image_id == BL32_IMAGE_ID)) {
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ assert(bl_mem_params);
+ bl_mem_params->ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+ }
+
+ return err;
+}
+
+#else
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+ struct bl_params *arm_bl_params = arm_get_next_bl_params();
+
+#if __aarch64__
+ const struct dyn_cfg_dtb_info_t *fw_config_info;
+ bl_mem_params_node_t *param_node;
+ uintptr_t fw_config_base = 0U;
+ entry_point_info_t *ep_info;
+
+ /* Get BL31 image node */
+ param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* Get fw_config load address */
+ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+ assert(fw_config_info != NULL);
+
+ fw_config_base = fw_config_info->config_addr;
+ assert(fw_config_base != 0U);
+
+ /*
+ * Get the entry point info of BL31 image and override
+ * arg1 of entry point info with fw_config base address
+ */
+ ep_info = &param_node->ep_info;
+ ep_info->args.arg1 = (uint32_t)fw_config_base;
+#endif /* __aarch64__ */
+
+ return arm_bl_params;
+}
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/juno_bl31_setup.c b/plat/arm/board/juno/juno_bl31_setup.c
new file mode 100644
index 0000000..7a0a6d9
--- /dev/null
+++ b/plat/arm/board/juno/juno_bl31_setup.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+void __init bl31_early_platform_setup2(u_register_t arg0,
+ u_register_t arg1, u_register_t arg2, u_register_t arg3)
+{
+ const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
+
+ INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
+
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
+
+ soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID);
+ if (soc_fw_config_info != NULL) {
+ arg1 = soc_fw_config_info->config_addr;
+ }
+
+ arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ plat_arm_interconnect_init();
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ * Earlier bootloader stages might already do this (e.g. Trusted
+ * Firmware's BL1 does it) but we can't assume so. There is no harm in
+ * executing this code twice anyway.
+ * Platform specific PSCI code will enable coherency for other
+ * clusters.
+ */
+ plat_arm_interconnect_enter_coherency();
+}
+
+void __init bl31_plat_arch_setup(void)
+{
+ arm_bl31_plat_arch_setup();
+
+ /* HW_CONFIG was also loaded by BL2 */
+ const struct dyn_cfg_dtb_info_t *hw_config_info;
+
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+}
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
new file mode 100644
index 0000000..038f604
--- /dev/null
+++ b/plat/arm/board/juno/juno_common.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/smccc.h>
+#include <platform_def.h>
+#include <services/arm_arch_svc.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Table of memory regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
+ */
+#ifdef IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_FLASH0_RW,
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+ /* Map DRAM to authenticate NS_BL2U image. */
+ ARM_MAP_NS_DRAM1,
+#endif
+ {0}
+};
+#endif
+#ifdef IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_FLASH0_RW,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ ARM_MAP_NS_DRAM1,
+#ifdef __aarch64__
+ ARM_MAP_DRAM2,
+#endif
+#ifdef SPD_tspd
+ ARM_MAP_TSP_SEC_MEM,
+#endif
+#ifdef SPD_opteed
+ ARM_MAP_OPTEE_CORE_MEM,
+ ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+ ARM_MAP_BL1_RW,
+#endif
+ {0}
+};
+#endif
+#ifdef IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ CSS_MAP_DEVICE,
+ CSS_MAP_SCP_BL2U,
+ V2M_MAP_IOFPGA,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
+ SOC_CSS_MAP_DEVICE,
+ ARM_DTB_DRAM_NS,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL32
+const mmap_region_t plat_arm_mmap[] = {
+#ifndef __aarch64__
+ ARM_MAP_SHARED_RAM,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
+#endif
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+#endif
+
+ARM_CASSERT_MMAP
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+ return (int32_t)
+ (SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE,
+ ARM_SOC_IDENTIFICATION_CODE) |
+ (JUNO_SOC_ID & SOC_ID_IMPL_DEF_MASK));
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+ unsigned int sys_id;
+
+ sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+ return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+ V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
+}
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
new file mode 100644
index 0000000..ddf99dc
--- /dev/null
+++ b/plat/arm/board/juno/juno_def.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_DEF_H
+#define JUNO_DEF_H
+
+#include <lib/utils_def.h>
+
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define JUNO_SOC_ID 1
+
+/*******************************************************************************
+ * Juno memory map related constants
+ ******************************************************************************/
+
+/* Board revisions */
+#define REV_JUNO_R0 U(0x1) /* Rev B */
+#define REV_JUNO_R1 U(0x2) /* Rev C */
+#define REV_JUNO_R2 U(0x3) /* Rev D */
+
+/* Bypass offset from start of NOR flash */
+#define BL1_ROM_BYPASS_OFFSET UL(0x03EC0000)
+
+#define EMMC_BASE UL(0x0c000000)
+#define EMMC_SIZE UL(0x04000000)
+
+#define PSRAM_BASE UL(0x14000000)
+#define PSRAM_SIZE UL(0x02000000)
+
+#define JUNO_SSC_VER_PART_NUM U(0x030)
+
+/*******************************************************************************
+ * Juno topology related constants
+ ******************************************************************************/
+#define JUNO_CLUSTER_COUNT U(2)
+#define JUNO_CLUSTER0_CORE_COUNT U(2)
+#define JUNO_CLUSTER1_CORE_COUNT U(4)
+
+/*******************************************************************************
+ * TZC-400 related constants
+ ******************************************************************************/
+#define TZC400_NSAID_CCI400 0 /* Note: Same as default NSAID!! */
+#define TZC400_NSAID_PCIE 1
+#define TZC400_NSAID_HDLCD0 2
+#define TZC400_NSAID_HDLCD1 3
+#define TZC400_NSAID_USB 4
+#define TZC400_NSAID_DMA330 5
+#define TZC400_NSAID_THINLINKS 6
+#define TZC400_NSAID_AP 9
+#define TZC400_NSAID_GPU 10
+#define TZC400_NSAID_SCP 11
+#define TZC400_NSAID_CORESIGHT 12
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE UL(0x7FE60000)
+#define TRNG_NOUTPUTS 4
+#define TRNG_STATUS UL(0x10)
+#define TRNG_INTMASK UL(0x14)
+#define TRNG_CONFIG UL(0x18)
+#define TRNG_CONTROL UL(0x1C)
+#define TRNG_NBYTES 16 /* Number of bytes generated per round. */
+
+/*******************************************************************************
+ * MMU-401 related constants
+ ******************************************************************************/
+#define MMU401_SSD_OFFSET UL(0x4000)
+#define MMU401_DMA330_BASE UL(0x7fb00000)
+
+/*******************************************************************************
+ * Interrupt handling constants
+ ******************************************************************************/
+#define JUNO_IRQ_DMA_SMMU 126
+#define JUNO_IRQ_HDLCD0_SMMU 128
+#define JUNO_IRQ_HDLCD1_SMMU 130
+#define JUNO_IRQ_USB_SMMU 132
+#define JUNO_IRQ_THIN_LINKS_SMMU 134
+#define JUNO_IRQ_SEC_I2C 137
+#define JUNO_IRQ_GPU_SMMU_1 73
+#define JUNO_IRQ_ETR_SMMU 75
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
+ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#endif /* JUNO_DEF_H */
diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c
new file mode 100644
index 0000000..02d751e
--- /dev/null
+++ b/plat/arm/board/juno/juno_err.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <drivers/arm/sp805.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/*
+ * Juno error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ /* Propagate the err code in the NV-flags register */
+ mmio_write_32(V2M_SYS_NVFLAGS_ADDR, (uint32_t)err);
+
+ /* Setup the watchdog to reset the system as soon as possible */
+ sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
+
+ for (;;)
+ wfi();
+}
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
new file mode 100644
index 0000000..cc80651
--- /dev/null
+++ b/plat/arm/board/juno/juno_pm.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+#if CSS_USE_SCMI_SDS_DRIVER
+ return css_scmi_override_pm_ops(ops);
+#else
+ return ops;
+#endif /* CSS_USE_SCMI_SDS_DRIVER */
+}
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
new file mode 100644
index 0000000..654a7f1
--- /dev/null
+++ b/plat/arm/board/juno/juno_security.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/arm/nic_400.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
+#include <plat/common/platform.h>
+
+#include "juno_tzmp1_def.h"
+
+#ifdef JUNO_TZMP1
+/*
+ * Protect buffer for VPU/GPU/DPU memory usage with hardware protection
+ * enabled. Propose 224MB video output, 96 MB video input and 32MB video
+ * private.
+ *
+ * Ind Memory Range Caption S_ATTR NS_ATTR
+ * 1 0x080000000 - 0x0E7FFFFFF ARM_NS_DRAM1 NONE RDWR | MEDIA_RW
+ * 2 0x0E8000000 - 0x0F5FFFFFF JUNO_MEDIA_TZC_PROT_DRAM1 NONE MEDIA_RW | AP_WR
+ * 3 0x0F6000000 - 0x0FBFFFFFF JUNO_VPU_TZC_PROT_DRAM1 RDWR VPU_PROT_RW
+ * 4 0x0FC000000 - 0x0FDFFFFFF JUNO_VPU_TZC_PRIV_DRAM1 RDWR VPU_PRIV_RW
+ * 5 0x0FE000000 - 0x0FEFFFFFF JUNO_AP_TZC_SHARE_DRAM1 NONE RDWR | MEDIA_RW
+ * 6 0x0FF000000 - 0x0FFFFFFFF ARM_AP_TZC_DRAM1 RDWR NONE
+ * 7 0x880000000 - 0x9FFFFFFFF ARM_DRAM2 NONE RDWR | MEDIA_RW
+ *
+ * Memory regions are neighbored to save limited TZC regions. Calculation
+ * started from ARM_TZC_SHARE_DRAM1 since it is known and fixed for both
+ * protected-enabled and protected-disabled settings.
+ *
+ * Video private buffer aheads of ARM_TZC_SHARE_DRAM1
+ */
+
+static const arm_tzc_regions_info_t juno_tzmp1_tzc_regions[] = {
+ {ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},
+ {JUNO_NS_DRAM1_PT1_BASE, JUNO_NS_DRAM1_PT1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {JUNO_MEDIA_TZC_PROT_DRAM1_BASE, JUNO_MEDIA_TZC_PROT_DRAM1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_PROT_ACCESS},
+ {JUNO_VPU_TZC_PROT_DRAM1_BASE, JUNO_VPU_TZC_PROT_DRAM1_END,
+ TZC_REGION_S_RDWR, JUNO_VPU_TZC_PROT_ACCESS},
+ {JUNO_VPU_TZC_PRIV_DRAM1_BASE, JUNO_VPU_TZC_PRIV_DRAM1_END,
+ TZC_REGION_S_RDWR, JUNO_VPU_TZC_PRIV_ACCESS},
+ {JUNO_AP_TZC_SHARE_DRAM1_BASE, JUNO_AP_TZC_SHARE_DRAM1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {ARM_DRAM2_BASE, ARM_DRAM2_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {},
+};
+
+/*******************************************************************************
+ * Program dp650 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_dp650(void)
+{
+ mmio_write_32(DP650_BASE + DP650_PROT_NSAID_OFFSET,
+ DP650_PROT_NSAID_CONFIG);
+}
+
+/*******************************************************************************
+ * Program v550 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_v550(void)
+{
+ /*
+ * bits[31:28] is for PRIVATE,
+ * bits[27:24] is for OUTBUF,
+ * bits[23:20] is for PROTECTED.
+ */
+ mmio_write_32(V550_BASE + V550_PROTCTRL_OFFSET, V550_PROTCTRL_CONFIG);
+}
+
+#endif /* JUNO_TZMP1 */
+
+/*******************************************************************************
+ * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs
+ * assigned to Non-Secure except some for the DMA-330. Assign those back to the
+ * Non-Secure world as well, otherwise EL1 may end up erroneously generating
+ * (untranslated) Secure transactions if it turns the SMMU on.
+ ******************************************************************************/
+static void init_mmu401(void)
+{
+ uint32_t reg = mmio_read_32(MMU401_DMA330_BASE + MMU401_SSD_OFFSET);
+ reg |= 0x1FF;
+ mmio_write_32(MMU401_DMA330_BASE + MMU401_SSD_OFFSET, reg);
+}
+
+/*******************************************************************************
+ * Program CSS-NIC400 to allow non-secure access to some CSS regions.
+ ******************************************************************************/
+static void css_init_nic400(void)
+{
+ /* Note: This is the NIC-400 device on the CSS */
+ mmio_write_32(PLAT_SOC_CSS_NIC400_BASE +
+ NIC400_ADDR_CTRL_SECURITY_REG(CSS_NIC400_SLAVE_BOOTSECURE),
+ ~0);
+}
+
+/*******************************************************************************
+ * Initialize debug configuration.
+ ******************************************************************************/
+static void init_debug_cfg(void)
+{
+#if !DEBUG
+ /* Set internal drive selection for SPIDEN. */
+ mmio_write_32(SSC_REG_BASE + SSC_DBGCFG_SET,
+ 1U << SPIDEN_SEL_SET_SHIFT);
+
+ /* Drive SPIDEN LOW to disable invasive debug of secure state. */
+ mmio_write_32(SSC_REG_BASE + SSC_DBGCFG_CLR,
+ 1U << SPIDEN_INT_CLR_SHIFT);
+
+ /* Set internal drive selection for SPNIDEN. */
+ mmio_write_32(SSC_REG_BASE + SSC_DBGCFG_SET,
+ 1U << SPNIDEN_SEL_SET_SHIFT);
+
+ /* Drive SPNIDEN LOW to disable non-invasive debug of secure state. */
+ mmio_write_32(SSC_REG_BASE + SSC_DBGCFG_CLR,
+ 1U << SPNIDEN_INT_CLR_SHIFT);
+#endif
+}
+
+/*******************************************************************************
+ * Initialize the secure environment.
+ ******************************************************************************/
+void plat_arm_security_setup(void)
+{
+ /* Initialize debug configuration */
+ init_debug_cfg();
+ /* Initialize the TrustZone Controller */
+#ifdef JUNO_TZMP1
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_tzmp1_tzc_regions);
+ INFO("TZC protected shared memory base address for TZMP usecase: %p\n",
+ (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
+ INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
+ (void *)JUNO_AP_TZC_SHARE_DRAM1_END);
+#else
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
+#endif
+ /* Do ARM CSS internal NIC setup */
+ css_init_nic400();
+ /* Do ARM CSS SoC security setup */
+ soc_css_security_setup();
+ /* Initialize the SMMU SSD tables */
+ init_mmu401();
+#ifdef JUNO_TZMP1
+ init_dp650();
+ init_v550();
+#endif
+}
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c
new file mode 100644
index 0000000..3924af8
--- /dev/null
+++ b/plat/arm/board/juno/juno_stack_protector.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/utils.h>
+#include <plat/common/plat_trng.h>
+#include <platform_def.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ uint64_t entropy;
+
+ if (!plat_get_entropy(&entropy)) {
+ ERROR("Not enough entropy to initialize canary value\n");
+ panic();
+ }
+
+ if (sizeof(entropy) == sizeof(u_register_t)) {
+ return entropy;
+ }
+
+ return (entropy & 0xffffffffULL) ^ (entropy >> 32);
+}
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
new file mode 100644
index 0000000..075f512
--- /dev/null
+++ b/plat/arm/board/juno/juno_topology.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#if CSS_USE_SCMI_SDS_DRIVER
+static scmi_channel_plat_info_t juno_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhu_ring_doorbell,
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+{
+ return &juno_scmi_plat_info;
+}
+
+#endif
+/*
+ * On Juno, the system power level is the highest power level.
+ * The first entry in the power domain descriptor specifies the
+ * number of system power domains i.e. 1.
+ */
+#define JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
+
+/*
+ * The Juno power domain tree descriptor. The cluster power domains
+ * are arranged so that when the PSCI generic code creates the power
+ * domain tree, the indices of the CPU power domain nodes it allocates
+ * match the linear indices returned by plat_core_pos_by_mpidr()
+ * i.e. CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher
+ * indices for CLUSTER0 CPUs.
+ */
+static const unsigned char juno_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL,
+ /* No of children for the root node */
+ JUNO_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ JUNO_CLUSTER1_CORE_COUNT,
+ /* No of children for the second cluster node */
+ JUNO_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the Juno topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return juno_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return (((mpidr & (u_register_t) 0x100) != 0U) ?
+ JUNO_CLUSTER1_CORE_COUNT : JUNO_CLUSTER0_CORE_COUNT);
+}
+
+/*
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ */
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+ 2, 3, 4, 5, 0, 1 };
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
new file mode 100644
index 0000000..09552a6
--- /dev/null
+++ b/plat/arm/board/juno/juno_trng.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_acle.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#include <lib/smccc.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include <plat/common/platform.h>
+
+#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */
+#define NRETRIES 5
+
+/* initialised to false */
+static bool juno_trng_initialized;
+
+static bool output_valid(void)
+{
+ int i;
+
+ for (i = 0; i < NRETRIES; i++) {
+ uint32_t val;
+
+ val = mmio_read_32(TRNG_BASE + TRNG_STATUS);
+ if (val & 1U)
+ return true;
+ }
+ return false; /* No output data available. */
+}
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+ 0x23523c58, 0x7448, 0x4083, 0x9d, 0x16,
+ 0xe3, 0xfa, 0xb9, 0xf1, 0x73, 0xbc
+);
+uuid_t plat_trng_uuid;
+
+static uint32_t crc_value = ~0U;
+
+/*
+ * Uses the Trusted Entropy Source peripheral on Juno to return 8 bytes of
+ * entropy. Returns 'true' when done successfully, 'false' otherwise.
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+ uint64_t ret;
+
+ assert(out);
+ assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+ if (!juno_trng_initialized) {
+ /* Disable interrupt mode. */
+ mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
+ /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
+ mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+ /* Abort any potentially pending sampling. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 2);
+ /* Reset TRNG outputs. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+
+ juno_trng_initialized = true;
+ }
+
+ if (!output_valid()) {
+ /* Start TRNG. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
+
+ if (!output_valid())
+ return false;
+ }
+
+ /* CRC each two 32-bit registers together, combine the pairs */
+ crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 0));
+ crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 4));
+ ret = (uint64_t)crc_value << 32;
+
+ crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 8));
+ crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 12));
+ *out = ret | crc_value;
+
+ /* Acknowledge current cycle, clear output registers. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+ /* Trigger next TRNG cycle. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
+
+ return true;
+}
+
+void plat_entropy_setup(void)
+{
+ uint64_t dummy;
+
+ plat_trng_uuid = _plat_trng_uuid;
+
+ /* Initialise the entropy source and trigger RNG generation */
+ plat_get_entropy(&dummy);
+}
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
new file mode 100644
index 0000000..25a7470
--- /dev/null
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+
+extern unsigned char arm_rotpk_header[];
+
+/*
+ * Return the ROTPK hash stored in the registers of Juno board.
+ */
+static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+
+
+ /*
+ * Append the hash from Trusted Root-Key Storage registers. The hash has
+ * not been written linearly into the registers, so we have to do a bit
+ * of byte swapping:
+ *
+ * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
+ * +---------------------------------------------------------------+
+ * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
+ * +---------------------------------------------------------------+
+ * | ... ... | | ... ... |
+ * | +--------------------+ | +-------+
+ * | | | |
+ * +----------------------------+ +----------------------------+
+ * | | | |
+ * +-------+ | +--------------------+ |
+ * | | | |
+ * v v v v
+ * +---------------------------------------------------------------+
+ * | | |
+ * +---------------------------------------------------------------+
+ * 0 15 16 31
+ *
+ * Additionally, we have to access the registers in 32-bit words
+ */
+ words = ARM_ROTPK_HASH_LEN >> 3;
+
+ /* Swap bytes 0-15 (first four registers) */
+ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ /* Words are read in little endian */
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ /* Swap bytes 16-31 (last four registers) */
+ src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2);
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ *key_ptr = (void *)rotpk_hash_der;
+ *key_len = (unsigned int)sizeof(rotpk_hash_der);
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+
+#endif
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return juno_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
diff --git a/plat/arm/board/juno/juno_tzmp1_def.h b/plat/arm/board/juno/juno_tzmp1_def.h
new file mode 100644
index 0000000..4186d02
--- /dev/null
+++ b/plat/arm/board/juno/juno_tzmp1_def.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef JUNO_TZMP1_DEF_H
+#define JUNO_TZMP1_DEF_H
+
+/*
+ * Public memory regions for both protected and non-protected mode
+ *
+ * OPTEE shared memory 0xFEE00000 - 0xFEFFFFFF
+ */
+#define JUNO_AP_TZC_SHARE_DRAM1_SIZE ULL(0x02000000)
+#define JUNO_AP_TZC_SHARE_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \
+ JUNO_AP_TZC_SHARE_DRAM1_SIZE)
+#define JUNO_AP_TZC_SHARE_DRAM1_END (ARM_AP_TZC_DRAM1_BASE - 1)
+
+/* ARM_MEDIA_FEATURES for MEDIA GPU Protect Mode Test */
+#define JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE 8 /* GPU/DPU protected, VPU outbuf */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED 7 /* VPU protected */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE 10 /* VPU private (firmware) */
+
+#define JUNO_VPU_TZC_PRIV_DRAM1_SIZE ULL(0x02000000)
+#define JUNO_VPU_TZC_PRIV_DRAM1_BASE (JUNO_AP_TZC_SHARE_DRAM1_BASE - \
+ JUNO_VPU_TZC_PRIV_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PRIV_DRAM1_END (JUNO_AP_TZC_SHARE_DRAM1_BASE - 1)
+
+/* Video input protected buffer follows upper item */
+#define JUNO_VPU_TZC_PROT_DRAM1_SIZE ULL(0x06000000)
+#define JUNO_VPU_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PRIV_DRAM1_BASE - \
+ JUNO_VPU_TZC_PROT_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PRIV_DRAM1_BASE - 1)
+
+/* Video, graphics and display shares same NSAID and same protected buffer */
+#define JUNO_MEDIA_TZC_PROT_DRAM1_SIZE ULL(0x0e000000)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PROT_DRAM1_BASE - \
+ JUNO_MEDIA_TZC_PROT_DRAM1_SIZE)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PROT_DRAM1_BASE - 1)
+
+/* Rest of DRAM1 are Non-Secure public buffer */
+#define JUNO_NS_DRAM1_PT1_BASE ARM_DRAM1_BASE
+#define JUNO_NS_DRAM1_PT1_END (JUNO_MEDIA_TZC_PROT_DRAM1_BASE - 1)
+#define JUNO_NS_DRAM1_PT1_SIZE (JUNO_NS_DRAM1_PT1_END - \
+ JUNO_NS_DRAM1_PT1_BASE + 1)
+
+/* TZC filter flags */
+#define JUNO_MEDIA_TZC_NS_DEV_ACCESS (PLAT_ARM_TZC_NS_DEV_ACCESS | \
+ TZC_REGION_ACCESS_RD(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE))
+
+/* VPU / GPU /DPU protected access */
+#define JUNO_MEDIA_TZC_PROT_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE) | \
+ TZC_REGION_ACCESS_WR(TZC400_NSAID_AP))
+
+#define JUNO_VPU_TZC_PROT_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED))
+
+#define JUNO_VPU_TZC_PRIV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE))
+
+/*******************************************************************************
+ * Mali-DP650 related constants
+ ******************************************************************************/
+/* Base address of DP650 */
+#define DP650_BASE 0x6f200000
+/* offset to PROT_NSAID register */
+#define DP650_PROT_NSAID_OFFSET 0x10004
+/* config to PROT_NSAID register */
+#define DP650_PROT_NSAID_CONFIG 0x08008888
+
+/*******************************************************************************
+ * Mali-V550 related constants
+ ******************************************************************************/
+/* Base address of V550 */
+#define V550_BASE 0x6f030000
+/* offset to PROTCTRL register */
+#define V550_PROTCTRL_OFFSET 0x0040
+/* config to PROTCTRL register */
+#define V550_PROTCTRL_CONFIG 0xa8700000
+
+#endif /* JUNO_TZMP1_DEF_H */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
new file mode 100644
index 0000000..2c84eb3
--- /dev/null
+++ b/plat/arm/board/juno/platform.mk
@@ -0,0 +1,201 @@
+#
+# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include common/fdt_wrappers.mk
+
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+JUNO_GIC_SOURCES := ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c \
+ plat/arm/common/arm_gicv2.c
+
+JUNO_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \
+ plat/arm/common/arm_cci.c
+
+JUNO_SECURITY_SOURCES := drivers/arm/tzc/tzc400.c \
+ plat/arm/board/juno/juno_security.c \
+ plat/arm/board/juno/juno_trng.c \
+ plat/arm/common/arm_tzc400.c
+
+ifneq (${ENABLE_STACK_PROTECTOR}, 0)
+JUNO_SECURITY_SOURCES += plat/arm/board/juno/juno_stack_protector.c
+endif
+
+# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the
+# SCP during power management operations and for SCP RAM Firmware transfer.
+CSS_USE_SCMI_SDS_DRIVER := 1
+
+PLAT_INCLUDES := -Iplat/arm/board/juno/include
+
+PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S \
+ plat/arm/board/juno/juno_common.c
+
+# Flag to enable support for AArch32 state on JUNO
+JUNO_AARCH32_EL3_RUNTIME := 0
+$(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
+$(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
+
+# Flag to enable support for TZMP1 on JUNO
+JUNO_TZMP1 := 0
+$(eval $(call assert_boolean,JUNO_TZMP1))
+ifeq (${JUNO_TZMP1}, 1)
+$(eval $(call add_define,JUNO_TZMP1))
+endif
+
+TRNG_SUPPORT := 1
+
+ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+# Include BL32 in FIP
+NEED_BL32 := yes
+# BL31 is not required
+override BL31_SOURCES =
+
+# The BL32 needs to be built separately invoking the AARCH32 compiler and
+# be specifed via `BL32` build option.
+ ifneq (${ARCH}, aarch32)
+ override BL32_SOURCES =
+ endif
+endif
+
+ifeq (${ARCH},aarch64)
+BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ lib/cpus/aarch64/cortex_a72.S \
+ plat/arm/board/juno/juno_err.c \
+ plat/arm/board/juno/juno_bl1_setup.c \
+ drivers/arm/sp805/sp805.c \
+ ${JUNO_INTERCONNECT_SOURCES} \
+ ${JUNO_SECURITY_SOURCES}
+
+BL2_SOURCES += drivers/arm/sp805/sp805.c \
+ lib/utils/mem_region.c \
+ plat/arm/board/juno/juno_err.c \
+ plat/arm/board/juno/juno_bl2_setup.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
+ ${JUNO_SECURITY_SOURCES}
+
+BL2U_SOURCES += ${JUNO_SECURITY_SOURCES}
+
+BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
+ lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ lib/cpus/aarch64/cortex_a72.S \
+ lib/utils/mem_region.c \
+ lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ plat/arm/board/juno/juno_bl31_setup.c \
+ plat/arm/board/juno/juno_pm.c \
+ plat/arm/board/juno/juno_topology.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
+ ${JUNO_GIC_SOURCES} \
+ ${JUNO_INTERCONNECT_SOURCES} \
+ ${JUNO_SECURITY_SOURCES}
+
+BL31_SOURCES += ${FDT_WRAPPERS_SOURCES}
+
+ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
+BL1_SOURCES += drivers/arm/css/sds/sds.c
+endif
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+endif
+
+endif
+
+ifneq (${RESET_TO_BL31},0)
+ $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+ Please set RESET_TO_BL31 to 0.")
+endif
+
+ifeq ($(USE_ROMLIB),1)
+all : bl1_romlib.bin
+endif
+
+bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
+ @echo "Building combined BL1 and ROMLIB binary for Juno $@"
+ ./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
+
+# Errata workarounds for Cortex-A53:
+ERRATA_A53_819472 := 1
+ERRATA_A53_824069 := 1
+ERRATA_A53_826319 := 1
+ERRATA_A53_827319 := 1
+ERRATA_A53_835769 := 1
+ERRATA_A53_836870 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+# Errata workarounds for Cortex-A57:
+ERRATA_A57_806969 := 0
+ERRATA_A57_813419 := 1
+ERRATA_A57_813420 := 1
+ERRATA_A57_814670 := 1
+ERRATA_A57_817169 := 1
+ERRATA_A57_826974 := 1
+ERRATA_A57_826977 := 1
+ERRATA_A57_828024 := 1
+ERRATA_A57_829520 := 1
+ERRATA_A57_833471 := 1
+ERRATA_A57_859972 := 0
+
+# Errata workarounds for Cortex-A72:
+ERRATA_A72_859971 := 0
+
+# Enable option to skip L1 data cache flush during the Cortex-A57 cluster
+# power down sequence
+SKIP_A57_L1_FLUSH_PWR_DWN := 1
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS := 0
+
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+ ifeq (${RESET_TO_SP_MIN},1)
+ BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+ endif
+else
+ ifeq (${RESET_TO_BL31},1)
+ BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+ endif
+endif
+
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+ BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ else
+ BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ endif
+endif
+
+BL1_CPPFLAGS += -march=armv8-a+crc
+BL2_CPPFLAGS += -march=armv8-a+crc
+BL2U_CPPFLAGS += -march=armv8-a+crc
+BL31_CPPFLAGS += -march=armv8-a+crc
+BL32_CPPFLAGS += -march=armv8-a+crc
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \
+ plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts \
+ fdts/${PLAT}.dts
+
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
+
+include plat/arm/board/common/board_common.mk
+include plat/arm/common/arm_common.mk
+include plat/arm/soc/common/soc_css.mk
+include plat/arm/css/common/css_common.mk
diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk
new file mode 100644
index 0000000..b3471c1
--- /dev/null
+++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SP_MIN source files specific to JUNO platform
+BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \
+ lib/cpus/aarch32/cortex_a53.S \
+ lib/cpus/aarch32/cortex_a57.S \
+ lib/cpus/aarch32/cortex_a72.S \
+ lib/utils/mem_region.c \
+ plat/arm/board/juno/juno_pm.c \
+ plat/arm/board/juno/juno_topology.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
+ plat/arm/soc/common/soc_css_security.c \
+ ${JUNO_GIC_SOURCES} \
+ ${JUNO_INTERCONNECT_SOURCES} \
+ ${JUNO_SECURITY_SOURCES}
+
+include plat/arm/common/sp_min/arm_sp_min.mk
+include plat/arm/css/common/sp_min/css_sp_min.mk
diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk
new file mode 100644
index 0000000..be75c4d
--- /dev/null
+++ b/plat/arm/board/juno/tsp/tsp-juno.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES += plat/arm/board/juno/juno_topology.c \
+ plat/arm/css/common/css_topology.c \
+ ${JUNO_GIC_SOURCES} \
+ ${JUNO_SECURITY_SOURCES}
+
+include plat/arm/common/tsp/arm_tsp.mk