Juno: Implement initial platform port
authorSandrine Bailleux <sandrine.bailleux@arm.com>
Thu, 17 Jul 2014 15:06:39 +0000 (16:06 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Thu, 21 Aug 2014 13:53:48 +0000 (14:53 +0100)
This patch adds the initial port of the ARM Trusted Firmware on the Juno
development platform. This port does not support a BL3-2 image or any PSCI APIs
apart from PSCI_VERSION and PSCI_CPU_ON. It enables workarounds for selected
Cortex-A57 (#806969 & #813420) errata and implements the workaround for a Juno
platform errata (Defect id 831273).

Change-Id: Ib3d92df3af53820cfbb2977582ed0d7abf6ef893

23 files changed:
include/lib/aarch64/arch.h
include/lib/cpus/aarch64/cortex_a57.h
plat/juno/aarch64/bl1_plat_helpers.S [new file with mode: 0644]
plat/juno/aarch64/juno_common.c [new file with mode: 0644]
plat/juno/aarch64/plat_helpers.S [new file with mode: 0644]
plat/juno/bl1_plat_setup.c [new file with mode: 0644]
plat/juno/bl2_plat_setup.c [new file with mode: 0644]
plat/juno/bl31_plat_setup.c [new file with mode: 0644]
plat/juno/include/plat_macros.S [new file with mode: 0644]
plat/juno/include/platform_def.h [new file with mode: 0644]
plat/juno/juno_def.h [new file with mode: 0644]
plat/juno/juno_private.h [new file with mode: 0644]
plat/juno/mhu.c [new file with mode: 0644]
plat/juno/mhu.h [new file with mode: 0644]
plat/juno/plat_gic.c [new file with mode: 0644]
plat/juno/plat_io_storage.c [new file with mode: 0644]
plat/juno/plat_pm.c [new file with mode: 0644]
plat/juno/plat_topology.c [new file with mode: 0644]
plat/juno/platform.mk [new file with mode: 0644]
plat/juno/scp_bootloader.c [new file with mode: 0644]
plat/juno/scp_bootloader.h [new file with mode: 0644]
plat/juno/scpi.c [new file with mode: 0644]
plat/juno/scpi.h [new file with mode: 0644]

index b2aac2fb70271d16d3c4af8ab848ebfb5dc95a84..405626077982d8e1f0040d1e79d417999d4674d8 100644 (file)
 #define EL0VTEN_BIT            (1 << 8)
 #define EL0PCTEN_BIT           (1 << 0)
 #define EL0VCTEN_BIT           (1 << 1)
+#define EVNTEN_BIT             (1 << 2)
+#define EVNTDIR_BIT            (1 << 3)
+#define EVNTI_SHIFT            4
+#define EVNTI_MASK             0xf
 
 /* CPTR_EL3 definitions */
 #define TCPAC_BIT              (1 << 31)
index 9cf8780d014afb4bafbeed55a665c3547dba69d7..6128b1694e17ddabc4cc181695f227b712cf5f76 100644 (file)
 #define CPUACTLR_NO_ALLOC_WBWA         (1 << 49)
 #define CPUACTLR_DCC_AS_DCCI           (1 << 44)
 
+/*******************************************************************************
+ * L2 Control register specific definitions.
+ ******************************************************************************/
+#define L2CTLR_EL1                     S3_1_C11_C0_2   /* Instruction def. */
+
+#define L2CTLR_DATA_RAM_LATENCY_SHIFT  0
+#define L2CTLR_TAG_RAM_LATENCY_SHIFT   6
+
+#define L2_DATA_RAM_LATENCY_3_CYCLES   0x2
+#define L2_TAG_RAM_LATENCY_3_CYCLES    0x2
+
 #endif /* __CORTEX_A57_H__ */
diff --git a/plat/juno/aarch64/bl1_plat_helpers.S b/plat/juno/aarch64/bl1_plat_helpers.S
new file mode 100644 (file)
index 0000000..785aa15
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include "../juno_def.h"
+
+       .globl  platform_get_entrypoint
+       .globl  platform_cold_boot_init
+       .globl  plat_secondary_cold_boot_setup
+
+
+       /* -----------------------------------------------------
+        * void plat_secondary_cold_boot_setup (void);
+        *
+        * This function performs any platform specific actions
+        * needed for a secondary cpu after a cold reset e.g
+        * mark the cpu's presence, mechanism to place it in a
+        * holding pen etc.
+        * -----------------------------------------------------
+        */
+func plat_secondary_cold_boot_setup
+       /* Juno todo: Implement secondary CPU cold boot setup on Juno */
+cb_panic:
+       b       cb_panic
+
+
+       /* -----------------------------------------------------
+        * void platform_get_entrypoint (unsigned int mpid);
+        *
+        * Main job of this routine is to distinguish between
+        * a cold and warm boot.
+        * On a cold boot the secondaries first wait for the
+        * platform to be initialized after which they are
+        * hotplugged in. The primary proceeds to perform the
+        * platform initialization.
+        * On a warm boot, each cpu jumps to the address in its
+        * mailbox.
+        *
+        * TODO: Not a good idea to save lr in a temp reg
+        * -----------------------------------------------------
+        */
+func platform_get_entrypoint
+       mov     x9, x30 // lr
+       bl      platform_get_core_pos
+       ldr     x1, =TRUSTED_MAILBOXES_BASE
+       lsl     x0, x0, #TRUSTED_MAILBOX_SHIFT
+       ldr     x0, [x1, x0]
+       ret     x9
+
+
+       /* -----------------------------------------------------
+        * void platform_cold_boot_init (bl1_main function);
+        *
+        * Routine called only by the primary cpu after a cold
+        * boot to perform early platform initialization
+        * -----------------------------------------------------
+        */
+func platform_cold_boot_init
+       mov     x20, x0
+
+       /* ---------------------------------------------
+        * Give ourselves a small coherent stack to
+        * ease the pain of initializing the MMU and
+        * CCI in assembler
+        * ---------------------------------------------
+        */
+       mrs     x0, mpidr_el1
+       bl      platform_set_coherent_stack
+
+       /* ---------------------------------------------
+        * Architectural init. can be generic e.g.
+        * enabling stack alignment and platform spec-
+        * ific e.g. MMU & page table setup as per the
+        * platform memory map. Perform the latter here
+        * and the former in bl1_main.
+        * ---------------------------------------------
+        */
+       bl      bl1_early_platform_setup
+       bl      bl1_plat_arch_setup
+
+       /* ---------------------------------------------
+        * Give ourselves a stack allocated in Normal
+        * -IS-WBWA memory
+        * ---------------------------------------------
+        */
+       mrs     x0, mpidr_el1
+       bl      platform_set_stack
+
+       /* ---------------------------------------------
+        * Jump to the main function. Returning from it
+        * is a terminal error.
+        * ---------------------------------------------
+        */
+       blr     x20
+
+cb_init_panic:
+       b       cb_init_panic
diff --git a/plat/juno/aarch64/juno_common.c b/plat/juno/aarch64/juno_common.c
new file mode 100644 (file)
index 0000000..5ba38c1
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_tables.h>
+#include "../juno_def.h"
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+static const mmap_region_t juno_mmap[] = {
+       { TZROM_BASE,           TZROM_BASE,             TZROM_SIZE,             MT_MEMORY | MT_RO | MT_SECURE },
+       { MHU_SECURE_BASE,      MHU_SECURE_BASE,        MHU_SECURE_SIZE,        (MHU_PAYLOAD_CACHED ? MT_MEMORY : MT_DEVICE) | MT_RW | MT_SECURE },
+       { FLASH_BASE,           FLASH_BASE,             FLASH_SIZE,             MT_MEMORY | MT_RO | MT_SECURE },
+       { EMMC_BASE,            EMMC_BASE,              EMMC_SIZE,              MT_MEMORY | MT_RO | MT_SECURE },
+       { PSRAM_BASE,           PSRAM_BASE,             PSRAM_SIZE,             MT_MEMORY | MT_RW | MT_SECURE }, /* Used for 'TZDRAM' */
+       { IOFPGA_BASE,          IOFPGA_BASE,            IOFPGA_SIZE,            MT_DEVICE | MT_RW | MT_SECURE },
+       { DEVICE0_BASE,         DEVICE0_BASE,           DEVICE0_SIZE,           MT_DEVICE | MT_RW | MT_SECURE },
+       { DEVICE1_BASE,         DEVICE1_BASE,           DEVICE1_SIZE,           MT_DEVICE | MT_RW | MT_SECURE },
+       { DRAM_BASE,            DRAM_BASE,              DRAM_SIZE,              MT_MEMORY | MT_RW | MT_NS },
+       {0}
+};
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+#define DEFINE_CONFIGURE_MMU_EL(_el)                           \
+       void configure_mmu_el##_el(unsigned long total_base,    \
+                                 unsigned long total_size,     \
+                                 unsigned long ro_start,       \
+                                 unsigned long ro_limit,       \
+                                 unsigned long coh_start,      \
+                                 unsigned long coh_limit)      \
+       {                                                       \
+              mmap_add_region(total_base, total_base,          \
+                              total_size,                      \
+                              MT_MEMORY | MT_RW | MT_SECURE);  \
+              mmap_add_region(ro_start, ro_start,              \
+                              ro_limit - ro_start,             \
+                              MT_MEMORY | MT_RO | MT_SECURE);  \
+              mmap_add_region(coh_start, coh_start,            \
+                              coh_limit - coh_start,           \
+                              MT_DEVICE | MT_RW | MT_SECURE);  \
+              mmap_add(juno_mmap);                             \
+              init_xlat_tables();                              \
+                                                               \
+              enable_mmu_el##_el(0);                           \
+       }
+
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+DEFINE_CONFIGURE_MMU_EL(1)
+DEFINE_CONFIGURE_MMU_EL(3)
+
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+       return NS_IMAGE_OFFSET;
+}
+
+uint64_t plat_get_syscnt_freq(void)
+{
+       uint64_t counter_base_frequency;
+
+       /* Read the frequency from Frequency modes table */
+       counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+       /* The first entry of the frequency modes table must not be 0 */
+       if (counter_base_frequency == 0)
+               panic();
+
+       return counter_base_frequency;
+}
diff --git a/plat/juno/aarch64/plat_helpers.S b/plat/juno/aarch64/plat_helpers.S
new file mode 100644 (file)
index 0000000..0354162
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_a57.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#include "../juno_def.h"
+
+       .globl  plat_crash_console_init
+       .globl  plat_crash_console_putc
+       .globl  plat_report_exception
+       .globl  plat_reset_handler
+       .globl  platform_get_core_pos
+       .globl  platform_is_primary_cpu
+       .globl  platform_mem_init
+
+       /* Define a crash console for the plaform */
+#define JUNO_CRASH_CONSOLE_BASE                PL011_UART0_BASE
+
+       /* ---------------------------------------------
+        * int plat_crash_console_init(void)
+        * Function to initialize the crash console
+        * without a C Runtime to print crash report.
+        * Clobber list : x0, x1, x2
+        * ---------------------------------------------
+        */
+func plat_crash_console_init
+       mov_imm x0, JUNO_CRASH_CONSOLE_BASE
+       mov_imm x1, PL011_UART0_CLK_IN_HZ
+       mov_imm x2, PL011_BAUDRATE
+       b       console_core_init
+
+       /* ---------------------------------------------
+        * int plat_crash_console_putc(int c)
+        * Function to print a character on the crash
+        * console without a C Runtime.
+        * Clobber list : x1, x2
+        * ---------------------------------------------
+        */
+func plat_crash_console_putc
+       mov_imm x1, JUNO_CRASH_CONSOLE_BASE
+       b       console_core_putc
+
+       /* ---------------------------------------------
+        * void plat_report_exception(unsigned int type)
+        * Function to report an unhandled exception
+        * with platform-specific means.
+        * On Juno platform, it updates the LEDs
+        * to indicate where we are
+        * ---------------------------------------------
+        */
+func plat_report_exception
+       mrs     x1, CurrentEl
+       lsr     x1, x1, #MODE_EL_SHIFT
+       lsl     x1, x1, #SYS_LED_EL_SHIFT
+       lsl     x0, x0, #SYS_LED_EC_SHIFT
+       mov     x2, #(SECURE << SYS_LED_SS_SHIFT)
+       orr     x0, x0, x2
+       orr     x0, x0, x1
+       mov     x1, #VE_SYSREGS_BASE
+       add     x1, x1, #V2M_SYS_LED
+       str     w0, [x1]
+       ret
+
+       /*
+        * Return 0 to 3 for the A53s and 4 or 5 for the A57s
+        */
+func platform_get_core_pos
+       and     x1, x0, #MPIDR_CPU_MASK
+       and     x0, x0, #MPIDR_CLUSTER_MASK
+       eor     x0, x0, #(1 << MPIDR_AFFINITY_BITS)  // swap A53/A57 order
+       add     x0, x1, x0, LSR #6
+       ret
+
+
+       /* -----------------------------------------------------
+        * unsigned int platform_is_primary_cpu(unsigned long mpid);
+        *
+        * Given the mpidr say whether this cpu is the primary
+        * cpu (applicable only after a cold boot)
+        * -----------------------------------------------------
+        */
+func platform_is_primary_cpu
+       /* Juno todo: allow configuration of primary CPU using SCC */
+       and     x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+       cmp     x0, #JUNO_PRIMARY_CPU
+       cset    x0, eq
+       ret
+
+
+       /* -----------------------------------------------------
+        * void platform_mem_init(void);
+        *
+        * We don't need to carry out any memory initialization
+        * on Juno. The Secure RAM is accessible straight away.
+        * -----------------------------------------------------
+        */
+func platform_mem_init
+       ret
+
+       /* -----------------------------------------------------
+        * void plat_reset_handler(void);
+        *
+        * Implement workaround for defect id 831273 by enabling
+        * an event stream every 65536 cycles and set the L2 RAM
+        * latencies for Cortex-A57.
+        * -----------------------------------------------------
+        */
+func plat_reset_handler
+       /* Read the MIDR_EL1 */
+       mrs     x0, midr_el1
+       ubfx    x1, x0, MIDR_PN_SHIFT, #12
+       cmp     w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+       b.ne    1f
+
+       /* Change the L2 Data and Tag Ram latency to 3 cycles */
+       mov     x0, #(L2_DATA_RAM_LATENCY_3_CYCLES |    \
+                       (L2_TAG_RAM_LATENCY_3_CYCLES << \
+                        L2CTLR_TAG_RAM_LATENCY_SHIFT))
+       msr     L2CTLR_EL1, x0
+
+1:
+       /* ---------------------------------------------
+       * Enable the event stream every 65536 cycles
+       * ---------------------------------------------
+       */
+       mov     x0, #(0xf << EVNTI_SHIFT)
+       orr     x0, x0, #EVNTEN_BIT
+       msr     CNTKCTL_EL1, x0
+       isb
+       ret
diff --git a/plat/juno/bl1_plat_setup.c b/plat/juno/bl1_plat_setup.c
new file mode 100644 (file)
index 0000000..d2f2ab4
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <tzc400.h>
+#include "../../bl1/bl1_private.h"
+#include "juno_def.h"
+#include "juno_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL1 */
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+       return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+       const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+       /* Initialize the console to provide early debug support */
+       console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+       /*
+        * Enable CCI-400 for this cluster. No need for locks as no other cpu is
+        * active at the moment
+        */
+       cci_init(CCI400_BASE,
+                CCI400_SL_IFACE3_CLUSTER_IX,
+                CCI400_SL_IFACE4_CLUSTER_IX);
+       cci_enable_cluster_coherency(read_mpidr());
+
+       /* Allow BL1 to see the whole Trusted RAM */
+       bl1_tzram_layout.total_base = TZRAM_BASE;
+       bl1_tzram_layout.total_size = TZRAM_SIZE;
+
+       /* Calculate how much RAM BL1 is using and how much remains free */
+       bl1_tzram_layout.free_base = TZRAM_BASE;
+       bl1_tzram_layout.free_size = TZRAM_SIZE;
+       reserve_mem(&bl1_tzram_layout.free_base,
+                   &bl1_tzram_layout.free_size,
+                   BL1_RAM_BASE,
+                   bl1_size);
+
+       INFO("BL1: 0x%lx - 0x%lx [size = %u]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
+            bl1_size);
+}
+
+
+/*
+ * Address of slave 'n' security setting in the NIC-400 address region
+ * control
+ * TODO: Ideally this macro should be moved in a "nic-400.h" header file but
+ * it would be the only thing in there so it's not worth it at the moment.
+ */
+#define NIC400_ADDR_CTRL_SECURITY_REG(n)       (0x8 + (n) * 4)
+
+static void init_nic400(void)
+{
+       /*
+        * NIC-400 Access Control Initialization
+        *
+        * Define access privileges by setting each corresponding bit to:
+        *   0 = Secure access only
+        *   1 = Non-secure access allowed
+        */
+
+       /*
+        * Allow non-secure access to some SOC regions, excluding UART1, which
+        * remains secure.
+        * Note: This is the NIC-400 device on the SOC
+        */
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_EHCI), ~0);
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_TLX_MASTER), ~0);
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_OHCI), ~0);
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_PL354_SMC), ~0);
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_APB4_BRIDGE), ~0);
+       mmio_write_32(SOC_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_BOOTSEC_BRIDGE),
+                     ~SOC_NIC400_BOOTSEC_BRIDGE_UART1);
+
+       /*
+        * Allow non-secure access to some CSS regions.
+        * Note: This is the NIC-400 device on the CSS
+        */
+       mmio_write_32(CSS_NIC400_BASE +
+                     NIC400_ADDR_CTRL_SECURITY_REG(CSS_NIC400_SLAVE_BOOTSECURE),
+                     ~0);
+}
+
+
+static void init_tzc400(void)
+{
+       /* Enable all filter units available */
+       mmio_write_32(TZC400_BASE + GATE_KEEPER_OFF, 0x0000000f);
+
+       /*
+        * Secure read and write are enabled for region 0, and the background
+        * region (region 0) is enabled for all four filter units
+        */
+       mmio_write_32(TZC400_BASE + REGION_ATTRIBUTES_OFF, 0xc0000000);
+
+       /*
+        * Enable Non-secure read/write accesses for the Soc Devices from the
+        * Non-Secure World
+        */
+       mmio_write_32(TZC400_BASE + REGION_ID_ACCESS_OFF,
+               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_SCP)        |
+               TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT)
+               );
+}
+
+#define PCIE_SECURE_REG                0x3000
+#define PCIE_SEC_ACCESS_MASK   ((1 << 0) | (1 << 1)) /* REG and MEM access bits */
+
+static void init_pcie(void)
+{
+       /*
+        * PCIE Root Complex Security settings to enable non-secure
+        * access to config registers.
+        */
+       mmio_write_32(PCIE_CONTROL_BASE + PCIE_SECURE_REG, PCIE_SEC_ACCESS_MASK);
+}
+
+
+/*******************************************************************************
+ * Function which will perform any remaining platform-specific setup that can
+ * occur after the MMU and data cache have been enabled.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+       init_nic400();
+       init_tzc400();
+       init_pcie();
+
+       /* Initialise the IO layer and register platform IO devices */
+       io_setup();
+
+       /* Enable and initialize the System level generic timer */
+       mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+}
+
+
+/*******************************************************************************
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ ******************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+       configure_mmu_el3(bl1_tzram_layout.total_base,
+                         bl1_tzram_layout.total_size,
+                         TZROM_BASE,
+                         TZROM_BASE + TZROM_SIZE,
+                         BL1_COHERENT_RAM_BASE,
+                         BL1_COHERENT_RAM_LIMIT);
+}
+
+/*******************************************************************************
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
+                             entry_point_info_t *bl2_ep)
+{
+       SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
+       bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/plat/juno/bl2_plat_setup.c b/plat/juno/bl2_plat_setup.c
new file mode 100644 (file)
index 0000000..0441cf6
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "scp_bootloader.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL2 */
+static meminfo_t bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
+               section("tzfw_coherent_mem")));
+
+/*******************************************************************************
+ * Structure which holds the arguments which need to be passed to BL3-1
+ ******************************************************************************/
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+       return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ ******************************************************************************/
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+       bl31_params_t *bl2_to_bl31_params;
+
+       /*
+        * Initialise the memory for all the arguments that needs to
+        * be passed to BL3-1
+        */
+       memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+       /* Assign memory for TF related information */
+       bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+       SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+       /* Fill BL3-1 related information */
+       bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+       SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+               VERSION_1, 0);
+
+       /* Fill BL3-2 related information if it exists */
+#if BL32_BASE
+       bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+       SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
+               VERSION_1, 0);
+       bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+       SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
+               VERSION_1, 0);
+#endif
+
+       /* Fill BL3-3 related information */
+       bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+       SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+               PARAM_EP, VERSION_1, 0);
+
+       /* BL3-3 expects to receive the primary CPU MPID (through x0) */
+       bl2_to_bl31_params->bl33_ep_info->args.arg0 = JUNO_PRIMARY_CPU;
+
+       bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+       SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+               VERSION_1, 0);
+
+       return bl2_to_bl31_params;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ ******************************************************************************/
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+#if DEBUG
+       bl31_params_mem.bl31_ep_info.args.arg1 = JUNO_BL31_PLAT_PARAM_VAL;
+#endif
+
+       return &bl31_params_mem.bl31_ep_info;
+}
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted RAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted RAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+       /* Initialize the console to provide early debug support */
+       console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+       /* Setup the BL2 memory layout */
+       bl2_tzram_layout = *mem_layout;
+}
+
+/*******************************************************************************
+ * Perform platform specific setup, i.e. initialize the IO layer, load BL3-0
+ * image and initialise the memory location to use for passing arguments to
+ * BL3-1.
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+       /* Initialise the IO layer and register platform IO devices */
+       io_setup();
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+       flush_dcache_range((unsigned long)&bl31_params_mem,
+                       sizeof(bl2_to_bl31_params_mem_t));
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl2_plat_arch_setup(void)
+{
+       configure_mmu_el1(bl2_tzram_layout.total_base,
+                         bl2_tzram_layout.total_size,
+                         BL2_RO_BASE,
+                         BL2_RO_LIMIT,
+                         BL2_COHERENT_RAM_BASE,
+                         BL2_COHERENT_RAM_LIMIT);
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-0, i.e. anywhere
+ * in trusted RAM as long as it doesn't overwrite BL2.
+ ******************************************************************************/
+void bl2_plat_get_bl30_meminfo(meminfo_t *bl30_meminfo)
+{
+       *bl30_meminfo = bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * Transfer BL3-0 from Trusted RAM using the SCP Download protocol.
+ * Return 0 on success, -1 otherwise.
+ ******************************************************************************/
+int bl2_plat_handle_bl30(image_info_t *bl30_image_info)
+{
+       int ret;
+
+       ret = scp_bootloader_transfer((void *)bl30_image_info->image_base,
+               bl30_image_info->image_size);
+
+       if (ret == 0)
+               INFO("BL2: BL3-0 transferred to SCP\n\r");
+       else
+               ERROR("BL2: BL3-0 transfer failure\n\r");
+
+       return ret;
+}
+
+/*******************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+                              entry_point_info_t *bl31_ep_info)
+{
+       SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+       bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+                                      DISABLE_ALL_EXCEPTIONS);
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+                              entry_point_info_t *bl32_ep_info)
+{
+       SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+       /*
+       * The Secure Payload Dispatcher service is responsible for
+       * setting the SPSR prior to entry into the BL32 image.
+       */
+       bl32_ep_info->spsr = 0;
+}
+
+/*******************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+                                      entry_point_info_t *bl33_ep_info)
+{
+       unsigned long el_status;
+       unsigned int mode;
+
+       /* Figure out what mode we enter the non-secure world in */
+       el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+       el_status &= ID_AA64PFR0_ELX_MASK;
+
+       if (el_status)
+               mode = MODE_EL2;
+       else
+               mode = MODE_EL1;
+
+       /*
+        * TODO: Consider the possibility of specifying the SPSR in
+        * the FIP ToC and allowing the platform to have a say as
+        * well.
+        */
+       bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
+                                      DISABLE_ALL_EXCEPTIONS);
+       SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-2
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+       /*
+        * Populate the extents of memory available for loading BL3-2.
+        */
+       bl32_meminfo->total_base = BL32_BASE;
+       bl32_meminfo->free_base = BL32_BASE;
+       bl32_meminfo->total_size =
+                      (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+       bl32_meminfo->free_size =
+                      (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-3
+ ******************************************************************************/
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+       bl33_meminfo->total_base = DRAM_BASE;
+       bl33_meminfo->total_size = DRAM_SIZE;
+       bl33_meminfo->free_base = DRAM_BASE;
+       bl33_meminfo->free_size = DRAM_SIZE;
+}
diff --git a/plat/juno/bl31_plat_setup.c b/plat/juno/bl31_plat_setup.c
new file mode 100644 (file)
index 0000000..131a1b1
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <bl31.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "mhu.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/******************************************************************************
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL3-1 from BL2.
+ ******************************************************************************/
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL3-3 corresponds to the non-secure image type
+ * while BL3-2 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+       entry_point_info_t *next_image_info;
+
+       next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+
+       /* None of the images on this platform can have 0x0 as the entrypoint */
+       if (next_image_info->pc)
+               return next_image_info;
+       else
+               return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+                              void *plat_params_from_bl2)
+{
+       /* Initialize the console to provide early debug support */
+       console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+       /*
+        * Initialise the CCI-400 driver for BL31 so that it is accessible after
+        * a warm boot. BL1 should have already enabled CCI coherency for this
+        * cluster during cold boot.
+        */
+       cci_init(CCI400_BASE,
+                CCI400_SL_IFACE3_CLUSTER_IX,
+                CCI400_SL_IFACE4_CLUSTER_IX);
+
+       /*
+        * Check params passed from BL2 should not be NULL,
+        */
+       assert(from_bl2 != NULL);
+       assert(from_bl2->h.type == PARAM_BL31);
+       assert(from_bl2->h.version >= VERSION_1);
+       /*
+        * In debug builds, we pass a special value in 'plat_params_from_bl2'
+        * to verify platform parameters from BL2 to BL3-1.
+        * In release builds, it's not used.
+        */
+       assert(((unsigned long long)plat_params_from_bl2) ==
+               JUNO_BL31_PLAT_PARAM_VAL);
+
+       /*
+        * Copy BL3-2 and BL3-3 entry point information.
+        * They are stored in Secure RAM, in BL2's address space.
+        */
+       bl32_ep_info = *from_bl2->bl32_ep_info;
+       bl33_ep_info = *from_bl2->bl33_ep_info;
+}
+
+/*******************************************************************************
+ * Initialize the MHU and the GIC.
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+       unsigned int reg_val;
+
+       mhu_secure_init();
+
+       /* Initialize the gic cpu and distributor interfaces */
+       gic_setup();
+
+       /* Enable and initialize the System level generic timer */
+       mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+
+       /* Allow access to the System counter timer module */
+       reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
+       reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
+       reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
+       mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val);
+
+       reg_val = (1 << CNTNSAR_NS_SHIFT(1));
+       mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val);
+
+       /* Topologies are best known to the platform. */
+       plat_setup_topology();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup()
+{
+       configure_mmu_el3(BL31_RO_BASE,
+                         BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE,
+                         BL31_RO_BASE,
+                         BL31_RO_LIMIT,
+                         BL31_COHERENT_RAM_BASE,
+                         BL31_COHERENT_RAM_LIMIT);
+}
diff --git a/plat/juno/include/plat_macros.S b/plat/juno/include/plat_macros.S
new file mode 100644 (file)
index 0000000..0e08834
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cci400.h>
+#include <gic_v2.h>
+#include "platform_def.h"
+#include "../juno_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+gic_regs:
+       .asciz "gic_hppir", "gic_ahppir", "gic_ctlr", ""
+gicd_pend_reg:
+       .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+       .asciz "\n"
+spacer:
+       .asciz ":\t\t0x"
+
+
+       /* ---------------------------------------------
+        * The below macro prints out relevant GIC
+        * registers whenever an unhandled exception is
+        * taken in BL3-1.
+        * Clobbers: x0 - x10, x16, sp
+        * ---------------------------------------------
+        */
+       .macro plat_print_gic_regs
+       ldr     x16, =GICC_BASE
+       /* Load the gic reg list to x6 */
+       adr     x6, gic_regs
+       /* Load the gic regs to gp regs used by str_in_crash_buf_print */
+       ldr     w8, [x16, #GICC_HPPIR]
+       ldr     w9, [x16, #GICC_AHPPIR]
+       ldr     w10, [x16, #GICC_CTLR]
+       /* Store to the crash buf and print to console */
+       bl      str_in_crash_buf_print
+
+       /* Print the GICD_ISPENDR regs */
+       add     x7, x16, #GICD_ISPENDR
+       adr     x4, gicd_pend_reg
+       bl      asm_print_str
+gicd_ispendr_loop:
+       sub     x4, x7, x16
+       cmp     x4, #0x280
+       b.eq    exit_print_gic_regs
+       bl      asm_print_hex
+
+       adr     x4, spacer
+       bl      asm_print_str
+
+       ldr     x4, [x7], #8
+       bl      asm_print_hex
+
+       adr     x4, newline
+       bl      asm_print_str
+       b       gicd_ispendr_loop
+exit_print_gic_regs:
+       .endm
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+       .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+       /* ------------------------------------------------
+        * The below macro prints out relevant interconnect
+        * registers whenever an unhandled exception is
+        * taken in BL3-1.
+        * Clobbers: x0 - x9, sp
+        * ------------------------------------------------
+        */
+       .macro plat_print_interconnect_regs
+       adr     x6, cci_iface_regs
+       /* Store in x7 the base address of the first interface */
+       mov_imm x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
+       ldr     w8, [x7, #SNOOP_CTRL_REG]
+       /* Store in x7 the base address of the second interface */
+       mov_imm x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
+       ldr     w9, [x7, #SNOOP_CTRL_REG]
+       /* Store to the crash buf and print to console */
+       bl      str_in_crash_buf_print
+       .endm
diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h
new file mode 100644 (file)
index 0000000..2678efc
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE    0x800
+
+#define FIRMWARE_WELCOME_STR           "Booting Trusted Firmware\n"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME                 "bl2.bin"
+
+/* EL3 Runtime Firmware BL3-1 */
+#define BL31_IMAGE_NAME                        "bl31.bin"
+
+/* SCP Firmware BL3-0 */
+#define BL30_IMAGE_NAME                        "bl30.bin"
+
+/* Secure Payload BL3-2 (Trusted OS) */
+#define BL32_IMAGE_NAME                        "bl32.bin"
+
+/* Non-Trusted Firmware BL3-3 */
+#define BL33_IMAGE_NAME                        "bl33.bin" /* e.g. UEFI */
+
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME                 "fip.bin"
+
+#define PLATFORM_CACHE_LINE_SIZE       64
+#define PLATFORM_CLUSTER_COUNT         2
+#define PLATFORM_CORE_COUNT             6
+#define PLATFORM_NUM_AFFS              (PLATFORM_CLUSTER_COUNT + \
+                                        PLATFORM_CORE_COUNT)
+#define MAX_IO_DEVICES                 3
+#define MAX_IO_HANDLES                 4
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define FLASH_BASE             0x08000000
+#define FLASH_SIZE             0x04000000
+
+/* Bypass offset from start of NOR flash */
+#define BL1_ROM_BYPASS_OFFSET  0x03EC0000
+
+#ifndef TZROM_BASE
+/* Use the bypass address */
+#define TZROM_BASE             FLASH_BASE + BL1_ROM_BYPASS_OFFSET
+#endif
+#define TZROM_SIZE             0x00010000
+
+#define TZRAM_BASE             0x04001000
+#define TZRAM_SIZE             0x0003F000
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base
+ * addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE                    TZROM_BASE
+#define BL1_RO_LIMIT                   (TZROM_BASE + TZROM_SIZE)
+#define BL1_RW_BASE                    TZRAM_BASE
+#define BL1_RW_LIMIT                   BL31_BASE
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+#define BL2_BASE                       (TZRAM_BASE + TZRAM_SIZE - 0xd000)
+#define BL2_LIMIT                      (TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Load address of BL3-0 in the Juno port
+ * BL3-0 is loaded to the same place as BL3-1.  Once BL3-0 is transferred to the
+ * SCP, it is discarded and BL3-1 is loaded over the top.
+ ******************************************************************************/
+#define BL30_BASE                      BL31_BASE
+
+/*******************************************************************************
+ * BL3-1 specific defines.
+ ******************************************************************************/
+#define BL31_BASE                      (TZRAM_BASE + 0x8000)
+#define BL31_LIMIT                     BL32_BASE
+
+/*******************************************************************************
+ * BL3-2 specific defines.
+ ******************************************************************************/
+#define TSP_SEC_MEM_BASE               TZRAM_BASE
+#define TSP_SEC_MEM_SIZE               TZRAM_SIZE
+#define BL32_BASE                      (TZRAM_BASE + TZRAM_SIZE - 0x1d000)
+#define BL32_LIMIT                     BL2_BASE
+
+/*******************************************************************************
+ * Load address of BL3-3 in the Juno port
+ ******************************************************************************/
+#define NS_IMAGE_OFFSET                        0xE0000000
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define ADDR_SPACE_SIZE                        (1ull << 32)
+#define MAX_XLAT_TABLES                        2
+#define MAX_MMAP_REGIONS               16
+
+/*******************************************************************************
+ * ID of the secure physical generic timer interrupt.
+ ******************************************************************************/
+#define IRQ_SEC_PHY_TIMER              29
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned 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. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT   6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/juno/juno_def.h b/plat/juno/juno_def.h
new file mode 100644 (file)
index 0000000..b099e97
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __JUNO_DEF_H__
+#define __JUNO_DEF_H__
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define JUNO_BL31_PLAT_PARAM_VAL       0x0f1e2d3c4b5a6978ULL
+
+#define JUNO_PRIMARY_CPU               0x100
+
+/*******************************************************************************
+ * Juno memory map related constants
+ ******************************************************************************/
+#define MHU_SECURE_BASE                0x04000000
+#define MHU_SECURE_SIZE                0x00001000
+
+#define MHU_PAYLOAD_CACHED     0
+
+#define TRUSTED_MAILBOXES_BASE MHU_SECURE_BASE
+#define TRUSTED_MAILBOX_SHIFT  4
+
+#define EMMC_BASE              0x0c000000
+#define EMMC_SIZE              0x04000000
+
+#define PSRAM_BASE             0x14000000
+#define PSRAM_SIZE             0x02000000
+
+#define IOFPGA_BASE            0x1c000000
+#define IOFPGA_SIZE            0x03000000
+
+#define NSROM_BASE             0x1f000000
+#define NSROM_SIZE             0x00001000
+
+/* Following covers Columbus Peripherals excluding NSROM and NSRAM  */
+#define DEVICE0_BASE           0x20000000
+#define DEVICE0_SIZE           0x0e000000
+#define MHU_BASE               0x2b1f0000
+
+#define NSRAM_BASE             0x2e000000
+#define NSRAM_SIZE             0x00008000
+
+/* Following covers Juno Peripherals and PCIe expansion area */
+#define DEVICE1_BASE           0x40000000
+#define DEVICE1_SIZE           0x40000000
+#define PCIE_CONTROL_BASE      0x7ff20000
+
+#define DRAM_BASE              0x80000000
+#define DRAM_SIZE              0x80000000
+
+/* Memory mapped Generic timer interfaces  */
+#define SYS_CNTCTL_BASE                0x2a430000
+#define SYS_CNTREAD_BASE       0x2a800000
+#define SYS_TIMCTL_BASE                0x2a810000
+
+/* V2M motherboard system registers & offsets */
+#define VE_SYSREGS_BASE                0x1c010000
+#define V2M_SYS_LED            0x8
+
+/*
+ * V2M sysled bit definitions. The values written to this
+ * register are defined in arch.h & runtime_svc.h. Only
+ * used by the primary cpu to diagnose any cold boot issues.
+ *
+ * SYS_LED[0]   - Security state (S=0/NS=1)
+ * SYS_LED[2:1] - Exception Level (EL3-EL0)
+ * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
+ *
+ */
+#define SYS_LED_SS_SHIFT               0x0
+#define SYS_LED_EL_SHIFT               0x1
+#define SYS_LED_EC_SHIFT               0x3
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+#define GICD_BASE                      0x2c010000
+#define GICC_BASE                      0x2c02f000
+#define GICH_BASE                      0x2c04f000
+#define GICV_BASE                      0x2c06f000
+
+#define IRQ_MHU                        69
+#define IRQ_GPU_SMMU_0         71
+#define IRQ_GPU_SMMU_1         73
+#define IRQ_ETR_SMMU           75
+#define IRQ_TZC400             80
+#define IRQ_TZ_WDOG            86
+
+#define IRQ_SEC_SGI_0                  8
+#define IRQ_SEC_SGI_1                  9
+#define IRQ_SEC_SGI_2                  10
+#define IRQ_SEC_SGI_3                  11
+#define IRQ_SEC_SGI_4                  12
+#define IRQ_SEC_SGI_5                  13
+#define IRQ_SEC_SGI_6                  14
+#define IRQ_SEC_SGI_7                  15
+#define IRQ_SEC_SGI_8                  16
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+/* FPGA UART0 */
+#define PL011_UART0_BASE               0x1c090000
+/* FPGA UART1 */
+#define PL011_UART1_BASE               0x1c0a0000
+/* SoC UART0 */
+#define PL011_UART2_BASE               0x7ff80000
+/* SoC UART1 */
+#define PL011_UART3_BASE               0x7ff70000
+
+#define PL011_BAUDRATE                 115200
+
+#define PL011_UART0_CLK_IN_HZ          24000000
+#define PL011_UART1_CLK_IN_HZ          24000000
+
+/*******************************************************************************
+ * NIC-400 related constants
+ ******************************************************************************/
+
+/* CSS NIC-400 Global Programmers View (GPV) */
+#define CSS_NIC400_BASE                0x2a000000
+
+/* The slave_bootsecure controls access to GPU, DMC and CS. */
+#define CSS_NIC400_SLAVE_BOOTSECURE            8
+
+/* SoC NIC-400 Global Programmers View (GPV) */
+#define SOC_NIC400_BASE                0x7fd00000
+
+#define SOC_NIC400_USB_EHCI    0
+#define SOC_NIC400_TLX_MASTER  1
+#define SOC_NIC400_USB_OHCI    2
+#define SOC_NIC400_PL354_SMC   3
+/*
+ * The apb4_bridge controls access to:
+ *   - the PCIe configuration registers
+ *   - the MMU units for USB, HDLCD and DMA
+ */
+#define SOC_NIC400_APB4_BRIDGE 4
+/*
+ * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
+ */
+#define SOC_NIC400_BOOTSEC_BRIDGE              5
+#define SOC_NIC400_BOOTSEC_BRIDGE_UART1         (1 << 12)
+
+/*******************************************************************************
+ * TZC-400 related constants
+ ******************************************************************************/
+#define TZC400_BASE            0x2a4a0000
+
+#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
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE                    0x2c090000
+#define CCI400_SL_IFACE3_CLUSTER_IX    1
+#define CCI400_SL_IFACE4_CLUSTER_IX    0
+
+#endif /* __JUNO_DEF_H__ */
diff --git a/plat/juno/juno_private.h b/plat/juno/juno_private.h
new file mode 100644 (file)
index 0000000..0dac03a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __JUNO_PRIVATE_H__
+#define __JUNO_PRIVATE_H__
+
+#include <bl_common.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct plat_pm_ops;
+struct meminfo;
+struct bl31_params;
+struct image_info;
+struct entry_point_info;
+
+/*******************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL3-1 e.g. while passing control to it from BL2 which is bl31_params
+ * and other platform specific params
+ ******************************************************************************/
+typedef struct bl2_to_bl31_params_mem {
+       struct bl31_params bl31_params;
+       struct image_info bl31_image_info;
+       struct image_info bl32_image_info;
+       struct image_info bl33_image_info;
+       struct entry_point_info bl33_ep_info;
+       struct entry_point_info bl32_ep_info;
+       struct entry_point_info bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void bl1_plat_arch_setup(void);
+void bl2_plat_arch_setup(void);
+void bl31_plat_arch_setup(void);
+int platform_setup_pm(const struct plat_pm_ops **plat_ops);
+unsigned int platform_get_core_pos(unsigned long mpidr);
+void configure_mmu_el1(unsigned long total_base,
+                      unsigned long total_size,
+                      unsigned long ro_start,
+                      unsigned long ro_limit,
+                      unsigned long coh_start,
+                      unsigned long coh_limit);
+void configure_mmu_el3(unsigned long total_base,
+                      unsigned long total_size,
+                      unsigned long ro_start,
+                      unsigned long ro_limit,
+                      unsigned long coh_start,
+                      unsigned long coh_limit);
+void plat_report_exception(unsigned long type);
+unsigned long plat_get_ns_image_entrypoint(void);
+unsigned long platform_get_stack(unsigned long mpidr);
+uint64_t plat_get_syscnt_freq(void);
+
+/* Declarations for plat_gic.c */
+uint32_t ic_get_pending_interrupt_id(void);
+uint32_t ic_get_pending_interrupt_type(void);
+uint32_t ic_acknowledge_interrupt(void);
+uint32_t ic_get_interrupt_type(uint32_t id);
+void ic_end_of_interrupt(uint32_t id);
+void gic_cpuif_deactivate(unsigned int gicc_base);
+void gic_cpuif_setup(unsigned int gicc_base);
+void gic_pcpu_distif_setup(unsigned int gicd_base);
+void gic_setup(void);
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state);
+
+/* Declarations for plat_topology.c */
+int plat_setup_topology(void);
+int plat_get_max_afflvl(void);
+unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr);
+unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr);
+
+/* Declarations for plat_io_storage.c */
+void io_setup(void);
+int plat_get_image_source(const char *image_name,
+                         uintptr_t *dev_handle,
+                         uintptr_t *image_spec);
+
+/*
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl1_plat_set_bl2_ep_info(struct image_info *image,
+                             struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-1 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-1 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl31_ep_info(struct image_info *image,
+                              struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl32_ep_info(struct image_info *image,
+                              struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-3 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-3 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl33_ep_info(struct image_info *image,
+                              struct entry_point_info *ep);
+
+/* Gets the memory layout for BL3-2 */
+void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
+
+/* Gets the memory layout for BL3-3 */
+void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info);
+
+#endif /* __JUNO_PRIVATE_H__ */
diff --git a/plat/juno/mhu.c b/plat/juno/mhu.c
new file mode 100644 (file)
index 0000000..b6541a8
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <bakery_lock.h>
+#include <mmio.h>
+#include "juno_def.h"
+#include "mhu.h"
+
+/* SCP MHU secure channel registers */
+#define SCP_INTR_S_STAT                0x200
+#define SCP_INTR_S_SET         0x208
+#define SCP_INTR_S_CLEAR       0x210
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT                0x300
+#define CPU_INTR_S_SET         0x308
+#define CPU_INTR_S_CLEAR       0x310
+
+
+static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem")));
+
+
+void mhu_secure_message_start(void)
+{
+       bakery_lock_get(&mhu_secure_lock);
+
+       /* Make sure any previous command has finished */
+       while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+               ;
+}
+
+void mhu_secure_message_send(uint32_t command)
+{
+       /* Send command to SCP and wait for it to pick it up */
+       mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command);
+       while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+               ;
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+       /* Wait for response from SCP */
+       uint32_t response;
+       while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT)))
+               ;
+
+       return response;
+}
+
+void mhu_secure_message_end(void)
+{
+       /* Clear any response we got by writing all ones to the CLEAR register */
+       mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
+
+       bakery_lock_release(&mhu_secure_lock);
+}
+
+void mhu_secure_init(void)
+{
+       bakery_lock_init(&mhu_secure_lock);
+
+       /*
+        * Clear the CPU's INTR register to make sure we don't see a stale
+        * or garbage value and think it's a message we've already sent.
+        */
+       mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu);
+}
diff --git a/plat/juno/mhu.h b/plat/juno/mhu.h
new file mode 100644 (file)
index 0000000..5149c82
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MHU_H__
+#define __MHU_H__
+
+#include <stdint.h>
+
+extern void mhu_secure_message_start(void);
+extern void mhu_secure_message_send(uint32_t command);
+extern uint32_t mhu_secure_message_wait(void);
+extern void mhu_secure_message_end(void);
+
+extern void mhu_secure_init(void);
+
+#endif /* __MHU_H__ */
diff --git a/plat/juno/plat_gic.c b/plat/juno/plat_gic.c
new file mode 100644 (file)
index 0000000..9001519
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <gic_v2.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include "juno_def.h"
+#include "juno_private.h"
+
+
+/* Value used to initialise Non-Secure irq priorities four at a time */
+#define DEFAULT_NS_PRIORITY_X4 \
+       (GIC_HIGHEST_NS_PRIORITY | \
+       (GIC_HIGHEST_NS_PRIORITY << 8) | \
+       (GIC_HIGHEST_NS_PRIORITY << 16) | \
+       (GIC_HIGHEST_NS_PRIORITY << 24))
+
+
+/*******************************************************************************
+ * Enable secure interrupts and use FIQs to route them. Disable legacy bypass
+ * and set the priority mask register to allow all interrupts to trickle in.
+ ******************************************************************************/
+void gic_cpuif_setup(unsigned int gicc_base)
+{
+       unsigned int val;
+
+       gicc_write_pmr(gicc_base, GIC_PRI_MASK);
+
+       val = ENABLE_GRP0 | FIQ_EN;
+       val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0;
+       val |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
+       gicc_write_ctlr(gicc_base, val);
+}
+
+/*******************************************************************************
+ * Place the cpu interface in a state where it can never make a cpu exit wfi as
+ * as result of an asserted interrupt. This is critical for powering down a cpu
+ ******************************************************************************/
+void gic_cpuif_deactivate(unsigned int gicc_base)
+{
+       unsigned int val;
+
+       /* Disable secure, non-secure interrupts and disable their bypass */
+       val = gicc_read_ctlr(gicc_base);
+       val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+       val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
+       val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
+       gicc_write_ctlr(gicc_base, val);
+}
+
+static void gic_set_secure(unsigned int gicd_base, unsigned id)
+{
+       /* Set interrupt as Group 0 */
+       gicd_clr_igroupr(gicd_base, id);
+
+       /* Set priority to max */
+       gicd_set_ipriorityr(gicd_base, id, GIC_HIGHEST_SEC_PRIORITY);
+}
+
+/*******************************************************************************
+ * Per cpu gic distributor setup which will be done by all cpus after a cold
+ * boot/hotplug. This marks out the secure interrupts & enables them.
+ ******************************************************************************/
+void gic_pcpu_distif_setup(unsigned int gicd_base)
+{
+       unsigned i;
+
+       /* Mark all 32 PPI interrupts as Group 1 (non-secure) */
+       mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu);
+
+       /* Setup PPI priorities doing four at a time */
+       for (i = 0; i < 32; i += 4)
+               mmio_write_32(gicd_base + GICD_IPRIORITYR + i, DEFAULT_NS_PRIORITY_X4);
+
+       /* Configure those PPIs we want as secure, and enable them. */
+       static const char sec_irq[] = {
+               IRQ_SEC_PHY_TIMER,
+               IRQ_SEC_SGI_0,
+               IRQ_SEC_SGI_1,
+               IRQ_SEC_SGI_2,
+               IRQ_SEC_SGI_3,
+               IRQ_SEC_SGI_4,
+               IRQ_SEC_SGI_5,
+               IRQ_SEC_SGI_6,
+               IRQ_SEC_SGI_7
+       };
+       for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) {
+               gic_set_secure(gicd_base, sec_irq[i]);
+               gicd_set_isenabler(gicd_base, sec_irq[i]);
+       }
+}
+
+/*******************************************************************************
+ * Global gic distributor setup which will be done by the primary cpu after a
+ * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
+ * then enables the secure GIC distributor interface.
+ ******************************************************************************/
+static void gic_distif_setup(unsigned int gicd_base)
+{
+       unsigned int i, ctlr;
+       const unsigned int ITLinesNumber =
+                               gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
+
+       /* Disable the distributor before going further */
+       ctlr = gicd_read_ctlr(gicd_base);
+       ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+       gicd_write_ctlr(gicd_base, ctlr);
+
+       /* Mark all lines of SPIs as Group 1 (non-secure) */
+       for (i = 0; i < ITLinesNumber; i++)
+               mmio_write_32(gicd_base + GICD_IGROUPR + 4 + i * 4, 0xffffffffu);
+
+       /* Setup SPI priorities doing four at a time */
+       for (i = 0; i < ITLinesNumber * 32; i += 4)
+               mmio_write_32(gicd_base + GICD_IPRIORITYR + 32 + i, DEFAULT_NS_PRIORITY_X4);
+
+       /* Configure the SPIs we want as secure */
+       static const char sec_irq[] = {
+               IRQ_MHU,
+               IRQ_GPU_SMMU_0,
+               IRQ_GPU_SMMU_1,
+               IRQ_ETR_SMMU,
+               IRQ_TZC400,
+               IRQ_TZ_WDOG
+       };
+       for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++)
+               gic_set_secure(gicd_base, sec_irq[i]);
+
+       /* Route watchdog interrupt to this CPU and enable it. */
+       gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
+                          platform_get_core_pos(read_mpidr()));
+       gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
+
+       /* Now setup the PPIs */
+       gic_pcpu_distif_setup(gicd_base);
+
+       /* Enable Group 0 (secure) interrupts */
+       gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
+}
+
+void gic_setup(void)
+{
+       gic_cpuif_setup(GICC_BASE);
+       gic_distif_setup(GICD_BASE);
+}
+
+/*******************************************************************************
+ * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
+ * The interrupt controller knows which pin/line it uses to signal a type of
+ * interrupt. The platform knows which interrupt controller type is being used
+ * in a particular security state e.g. with an ARM GIC, normal world could use
+ * the GICv2 features while the secure world could use GICv3 features and vice
+ * versa.
+ * This function is exported by the platform to let the interrupt management
+ * framework determine for a type of interrupt and security state, which line
+ * should be used in the SCR_EL3 to control its routing to EL3. The interrupt
+ * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3.
+ ******************************************************************************/
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
+{
+       assert(type == INTR_TYPE_S_EL1 ||
+              type == INTR_TYPE_EL3 ||
+              type == INTR_TYPE_NS);
+
+       assert(sec_state_is_valid(security_state));
+
+       /*
+        * We ignore the security state parameter because Juno is GICv2 only
+        * so both normal and secure worlds are using ARM GICv2.
+        */
+       return gicv2_interrupt_type_to_line(GICC_BASE, type);
+}
+
+/*******************************************************************************
+ * This function returns the type of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+       uint32_t id;
+
+       id = gicc_read_hppir(GICC_BASE);
+
+       /* Assume that all secure interrupts are S-EL1 interrupts */
+       if (id < 1022)
+               return INTR_TYPE_S_EL1;
+
+       if (id == GIC_SPURIOUS_INTERRUPT)
+               return INTR_TYPE_INVAL;
+
+       return INTR_TYPE_NS;
+}
+
+/*******************************************************************************
+ * This function returns the id of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t plat_ic_get_pending_interrupt_id(void)
+{
+       uint32_t id;
+
+       id = gicc_read_hppir(GICC_BASE);
+
+       if (id < 1022)
+               return id;
+
+       if (id == 1023)
+               return INTR_ID_UNAVAILABLE;
+
+       /*
+        * Find out which non-secure interrupt it is under the assumption that
+        * the GICC_CTLR.AckCtl bit is 0.
+        */
+       return gicc_read_ahppir(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions reads the GIC cpu interface Interrupt Acknowledge register
+ * to start handling the pending interrupt. It returns the contents of the IAR.
+ ******************************************************************************/
+uint32_t plat_ic_acknowledge_interrupt(void)
+{
+       return gicc_read_IAR(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions writes the GIC cpu interface End Of Interrupt register with
+ * the passed value to finish handling the active interrupt
+ ******************************************************************************/
+void plat_ic_end_of_interrupt(uint32_t id)
+{
+       gicc_write_EOIR(GICC_BASE, id);
+}
+
+/*******************************************************************************
+ * This function returns the type of the interrupt id depending upon the group
+ * this interrupt has been configured under by the interrupt controller i.e.
+ * group0 or group1.
+ ******************************************************************************/
+uint32_t plat_ic_get_interrupt_type(uint32_t id)
+{
+       uint32_t group;
+
+       group = gicd_get_igroupr(GICD_BASE, id);
+
+       /* Assume that all secure interrupts are S-EL1 interrupts */
+       if (group == GRP0)
+               return INTR_TYPE_S_EL1;
+       else
+               return INTR_TYPE_NS;
+}
diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c
new file mode 100644 (file)
index 0000000..b297400
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <platform_def.h>
+#include <semihosting.h>       /* For FOPEN_MODE_... */
+#include <string.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_spec;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_spec;
+static uintptr_t memmap_init_params;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+       .offset = FLASH_BASE,
+       .length = FLASH_SIZE
+};
+
+static const io_file_spec_t bl2_file_spec = {
+       .path = BL2_IMAGE_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_file_spec = {
+       .path = BL30_IMAGE_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_file_spec = {
+       .path = BL31_IMAGE_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_file_spec = {
+       .path = BL33_IMAGE_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+       const char *image_name;
+       uintptr_t *dev_handle;
+       uintptr_t image_spec;
+       int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+       {
+               FIP_IMAGE_NAME,
+               &memmap_dev_handle,
+               (uintptr_t)&fip_block_spec,
+               open_memmap
+       }, {
+               BL2_IMAGE_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl2_file_spec,
+               open_fip
+       }, {
+               BL30_IMAGE_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl30_file_spec,
+               open_fip
+       }, {
+               BL31_IMAGE_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl31_file_spec,
+               open_fip
+       }, {
+               BL33_IMAGE_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl33_file_spec,
+               open_fip
+       }, {
+               0, 0, 0
+       }
+};
+
+
+static int open_fip(const uintptr_t spec)
+{
+       int result = IO_FAIL;
+
+       /* See if a Firmware Image Package is available */
+       result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
+       if (result == IO_SUCCESS) {
+               INFO("Using FIP\n");
+               /*TODO: Check image defined in spec is present in FIP. */
+       }
+       return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+       int result = IO_FAIL;
+       uintptr_t local_image_handle;
+
+       result = io_dev_init(memmap_dev_handle, memmap_init_params);
+       if (result == IO_SUCCESS) {
+               result = io_open(memmap_dev_handle, spec, &local_image_handle);
+               if (result == IO_SUCCESS) {
+                       /* INFO("Using Memmap IO\n"); */
+                       io_close(local_image_handle);
+               }
+       }
+       return result;
+}
+
+void io_setup(void)
+{
+       int io_result = IO_FAIL;
+
+       /* Register the IO devices on this platform */
+       io_result = register_io_dev_fip(&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(fip_dev_con, fip_dev_spec, &fip_dev_handle);
+       assert(io_result == IO_SUCCESS);
+
+       io_result = io_dev_open(memmap_dev_con, memmap_dev_spec,
+                               &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(const char *image_name, uintptr_t *dev_handle,
+                         uintptr_t *image_spec)
+{
+       int result = IO_FAIL;
+       const struct plat_io_policy *policy;
+
+       if ((image_name != NULL) && (dev_handle != NULL) &&
+           (image_spec != NULL)) {
+               policy = policies;
+               while (policy->image_name != NULL) {
+                       if (strcmp(policy->image_name, image_name) == 0) {
+                               result = policy->check(policy->image_spec);
+                               if (result == IO_SUCCESS) {
+                                       *image_spec = policy->image_spec;
+                                       *dev_handle = *(policy->dev_handle);
+                                       break;
+                               }
+                       }
+                       policy++;
+               }
+       } else {
+               result = IO_FAIL;
+       }
+       return result;
+}
diff --git a/plat/juno/plat_pm.c b/plat/juno/plat_pm.c
new file mode 100644 (file)
index 0000000..61dc13e
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <cci400.h>
+#include <errno.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "scpi.h"
+
+/*******************************************************************************
+ * Private Juno function to program the mailbox for a cpu before it is released
+ * from reset.
+ ******************************************************************************/
+static void juno_program_mailbox(uint64_t mpidr, uint64_t address)
+{
+       uint64_t linear_id;
+       uint64_t mbox;
+
+       linear_id = platform_get_core_pos(mpidr);
+       mbox = TRUSTED_MAILBOXES_BASE + (linear_id << TRUSTED_MAILBOX_SHIFT);
+       *((uint64_t *) mbox) = address;
+       flush_dcache_range(mbox, sizeof(mbox));
+}
+
+/*******************************************************************************
+ * Private Juno function which is used to determine if any platform actions
+ * should be performed for the specified affinity instance given its
+ * state. Nothing needs to be done if the 'state' is not off or if this is not
+ * the highest affinity level which will enter the 'state'.
+ ******************************************************************************/
+static int32_t juno_do_plat_actions(uint32_t afflvl, uint32_t state)
+{
+       uint32_t max_phys_off_afflvl;
+
+       assert(afflvl <= MPIDR_AFFLVL1);
+
+       if (state != PSCI_STATE_OFF)
+               return -EAGAIN;
+
+       /*
+        * Find the highest affinity level which will be suspended and postpone
+        * all the platform specific actions until that level is hit.
+        */
+       max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
+       assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+       assert(psci_get_suspend_afflvl() >= max_phys_off_afflvl);
+       if (afflvl != max_phys_off_afflvl)
+               return -EAGAIN;
+
+       return 0;
+}
+
+/*******************************************************************************
+ * Juno handler called when an affinity instance is about to be turned on. The
+ * level and mpidr determine the affinity instance.
+ ******************************************************************************/
+int32_t juno_on(uint64_t mpidr,
+               uint64_t sec_entrypoint,
+               uint64_t ns_entrypoint,
+               uint32_t afflvl,
+               uint32_t state)
+{
+       /*
+        * SCP takes care of powering up higher affinity levels so we
+        * only need to care about level 0
+        */
+       if (afflvl != MPIDR_AFFLVL0)
+               return PSCI_E_SUCCESS;
+
+       /*
+        * Setup mailbox with address for CPU entrypoint when it next powers up
+        */
+       juno_program_mailbox(mpidr, sec_entrypoint);
+
+       scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on,
+                                scpi_power_on);
+
+       return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Juno handler called when an affinity instance has just been powered on after
+ * being turned off earlier. The level and mpidr determine the affinity
+ * instance. The 'state' arg. allows the platform to decide whether the cluster
+ * was turned off prior to wakeup and do what's necessary to setup it up
+ * correctly.
+ ******************************************************************************/
+int32_t juno_on_finish(uint64_t mpidr, uint32_t afflvl, uint32_t state)
+{
+       /* Determine if any platform actions need to be executed. */
+       if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
+               return PSCI_E_SUCCESS;
+
+       /*
+        * Perform the common cluster specific operations i.e enable coherency
+        * if this cluster was off.
+        */
+       if (afflvl != MPIDR_AFFLVL0)
+               cci_enable_cluster_coherency(mpidr);
+
+
+       /* Enable the gic cpu interface */
+       gic_cpuif_setup(GICC_BASE);
+
+       /* Juno todo: Is this setup only needed after a cold boot? */
+       gic_pcpu_distif_setup(GICD_BASE);
+
+       /* Clear the mailbox for this cpu. */
+       juno_program_mailbox(mpidr, 0);
+
+       return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static const plat_pm_ops_t juno_ops = {
+       .affinst_on             = juno_on,
+       .affinst_on_finish      = juno_on_finish,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
+{
+       *plat_ops = &juno_ops;
+       return 0;
+}
diff --git a/plat/juno/plat_topology.c b/plat/juno/plat_topology.c
new file mode 100644 (file)
index 0000000..39d4dab
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+#include <psci.h>
+
+unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
+{
+       /* Report 1 (absent) instance at levels higher that the cluster level */
+       if (aff_lvl > MPIDR_AFFLVL1)
+               return 1;
+
+       if (aff_lvl == MPIDR_AFFLVL1)
+               return 2; /* We have two clusters */
+
+       return mpidr & 0x100 ? 4 : 2; /* 4 cpus in cluster 1, 2 in cluster 0 */
+}
+
+unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
+{
+       return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
+}
+
+int plat_get_max_afflvl()
+{
+       return MPIDR_AFFLVL1;
+}
+
+int plat_setup_topology()
+{
+       /* Juno todo: Make topology configurable via SCC */
+       return 0;
+}
diff --git a/plat/juno/platform.mk b/plat/juno/platform.mk
new file mode 100644 (file)
index 0000000..4746536
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+PLAT_INCLUDES          :=      -Iplat/juno/include/
+
+PLAT_BL_COMMON_SOURCES :=      drivers/arm/pl011/pl011_console.S       \
+                               drivers/io/io_fip.c                     \
+                               drivers/io/io_memmap.c                  \
+                               drivers/io/io_storage.c                 \
+                               lib/aarch64/xlat_tables.c               \
+                               plat/common/aarch64/plat_common.c       \
+                               plat/juno/plat_io_storage.c
+
+BL1_SOURCES            +=      drivers/arm/cci400/cci400.c             \
+                               lib/cpus/aarch64/cortex_a53.S           \
+                               lib/cpus/aarch64/cortex_a57.S           \
+                               plat/common/aarch64/platform_up_stack.S \
+                               plat/juno/bl1_plat_setup.c              \
+                               plat/juno/aarch64/bl1_plat_helpers.S    \
+                               plat/juno/aarch64/plat_helpers.S        \
+                               plat/juno/aarch64/juno_common.c
+
+BL2_SOURCES            +=      lib/locks/bakery/bakery_lock.c          \
+                               plat/common/aarch64/platform_up_stack.S \
+                               plat/juno/bl2_plat_setup.c              \
+                               plat/juno/mhu.c                         \
+                               plat/juno/aarch64/plat_helpers.S        \
+                               plat/juno/aarch64/juno_common.c         \
+                               plat/juno/scp_bootloader.c              \
+                               plat/juno/scpi.c
+
+BL31_SOURCES           +=      drivers/arm/cci400/cci400.c             \
+                               drivers/arm/gic/gic_v2.c                \
+                               lib/cpus/aarch64/cortex_a53.S           \
+                               lib/cpus/aarch64/cortex_a57.S           \
+                               plat/common/aarch64/platform_mp_stack.S \
+                               plat/juno/bl31_plat_setup.c             \
+                               plat/juno/mhu.c                         \
+                               plat/juno/aarch64/plat_helpers.S        \
+                               plat/juno/aarch64/juno_common.c         \
+                               plat/juno/plat_pm.c                     \
+                               plat/juno/plat_topology.c               \
+                               plat/juno/plat_gic.c                    \
+                               plat/juno/scpi.c
+
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL3-1 as the reset vector is not supported on Juno. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
+NEED_BL30              :=      yes
+
+# Enable workarounds for selected Cortex-A57 erratas.
+ERRATA_A57_806969      :=      1
+ERRATA_A57_813420      :=      1
diff --git a/plat/juno/scp_bootloader.c b/plat/juno/scp_bootloader.c
new file mode 100644 (file)
index 0000000..a6d25d4
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include "juno_def.h"
+#include "mhu.h"
+#include "scp_bootloader.h"
+#include "scpi.h"
+
+/* Boot commands sent from AP -> SCP */
+#define BOOT_CMD_START 0x01
+#define BOOT_CMD_DATA  0x02
+
+typedef struct {
+       uint32_t image_size;
+} cmd_start_payload;
+
+typedef struct {
+       uint32_t sequence_num;
+       uint32_t offset;
+       uint32_t size;
+} cmd_data_payload;
+
+#define BOOT_DATA_MAX_SIZE  0x1000
+
+/* Boot commands sent from SCP -> AP */
+#define BOOT_CMD_ACK   0x03
+#define BOOT_CMD_NACK  0x04
+
+typedef struct {
+       uint32_t sequence_num;
+} cmd_ack_payload;
+
+/*
+ * Unlike the runtime protocol, the boot protocol uses the same memory region
+ * for both AP -> SCP and SCP -> AP transfers; define the address of this...
+ */
+static void * const cmd_payload = (void *)(MHU_SECURE_BASE + 0x0080);
+
+static void *scp_boot_message_start(void)
+{
+       mhu_secure_message_start();
+
+       return cmd_payload;
+}
+
+static void scp_boot_message_send(unsigned command, size_t size)
+{
+       /* Make sure payload can be seen by SCP */
+       if (MHU_PAYLOAD_CACHED)
+               flush_dcache_range((unsigned long)cmd_payload, size);
+
+       /* Send command to SCP */
+       mhu_secure_message_send(command | (size << 8));
+}
+
+static uint32_t scp_boot_message_wait(size_t size)
+{
+       uint32_t response =  mhu_secure_message_wait();
+
+       /* Make sure we see the reply from the SCP and not any stale data */
+       if (MHU_PAYLOAD_CACHED)
+               inv_dcache_range((unsigned long)cmd_payload, size);
+
+       return response & 0xff;
+}
+
+static void scp_boot_message_end(void)
+{
+       mhu_secure_message_end();
+}
+
+static int transfer_block(uint32_t sequence_num, uint32_t offset, uint32_t size)
+{
+       cmd_data_payload *cmd_data = scp_boot_message_start();
+       cmd_data->sequence_num = sequence_num;
+       cmd_data->offset = offset;
+       cmd_data->size = size;
+
+       scp_boot_message_send(BOOT_CMD_DATA, sizeof(*cmd_data));
+
+       cmd_ack_payload *cmd_ack = cmd_payload;
+       int ok = scp_boot_message_wait(sizeof(*cmd_ack)) == BOOT_CMD_ACK
+                && cmd_ack->sequence_num == sequence_num;
+
+       scp_boot_message_end();
+
+       return ok;
+}
+
+int scp_bootloader_transfer(void *image, unsigned int image_size)
+{
+       uintptr_t offset = (uintptr_t)image - MHU_SECURE_BASE;
+       uintptr_t end = offset + image_size;
+       uint32_t response;
+
+       mhu_secure_init();
+
+       /* Initiate communications with SCP */
+       do {
+               cmd_start_payload *cmd_start = scp_boot_message_start();
+               cmd_start->image_size = image_size;
+
+               scp_boot_message_send(BOOT_CMD_START, sizeof(*cmd_start));
+
+               response = scp_boot_message_wait(0);
+
+               scp_boot_message_end();
+       } while (response != BOOT_CMD_ACK);
+
+       /* Transfer image to SCP a block at a time */
+       uint32_t sequence_num = 1;
+       size_t size;
+       while ((size = end - offset) != 0) {
+               if (size > BOOT_DATA_MAX_SIZE)
+                       size = BOOT_DATA_MAX_SIZE;
+               while (!transfer_block(sequence_num, offset, size))
+                       ; /* Retry forever */
+               offset += size;
+               sequence_num++;
+       }
+
+       /* Wait for SCP to signal it's ready */
+       return scpi_wait_ready();
+}
diff --git a/plat/juno/scp_bootloader.h b/plat/juno/scp_bootloader.h
new file mode 100644 (file)
index 0000000..e872513
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCP_BOOTLOADER_H__
+#define __SCP_BOOTLOADER_H__
+
+int scp_bootloader_transfer(void *image, unsigned int image_size);
+
+#endif
diff --git a/plat/juno/scpi.c b/plat/juno/scpi.c
new file mode 100644 (file)
index 0000000..c1677aa
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include "juno_def.h"
+#include "mhu.h"
+#include "scpi.h"
+
+#define MHU_SECURE_SCP_TO_AP_PAYLOAD   (MHU_SECURE_BASE+0x0080)
+#define MHU_SECURE_AP_TO_SCP_PAYLOAD   (MHU_SECURE_BASE+0x0280)
+
+#define SIZE_SHIFT     20      /* Bit position for size value in MHU header */
+#define SIZE_MASK      0x1ff   /* Mask to extract size value in MHU header*/
+
+
+void *scpi_secure_message_start(void)
+{
+       mhu_secure_message_start();
+
+       /* Return address of payload area. */
+       return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD;
+}
+
+void scpi_secure_message_send(unsigned command, size_t size)
+{
+       /* Make sure payload can be seen by SCP */
+       if (MHU_PAYLOAD_CACHED)
+               flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size);
+
+       mhu_secure_message_send(command | (size << SIZE_SHIFT));
+}
+
+unsigned scpi_secure_message_receive(void **message_out, size_t *size_out)
+{
+       uint32_t response =  mhu_secure_message_wait();
+
+       /* Get size of payload */
+       size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
+
+       /* Clear size from response */
+       response &= ~(SIZE_MASK << SIZE_SHIFT);
+
+       /* Make sure we don't read stale data */
+       if (MHU_PAYLOAD_CACHED)
+               inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size);
+
+       if (size_out)
+               *size_out = size;
+
+       if (message_out)
+               *message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD;
+
+       return response;
+}
+
+void scpi_secure_message_end(void)
+{
+       mhu_secure_message_end();
+}
+
+static void scpi_secure_send32(unsigned command, uint32_t message)
+{
+       *(__typeof__(message) *)scpi_secure_message_start() = message;
+       scpi_secure_message_send(command, sizeof(message));
+       scpi_secure_message_end();
+}
+
+int scpi_wait_ready(void)
+{
+       /* Get a message from the SCP */
+       scpi_secure_message_start();
+       size_t size;
+       unsigned command = scpi_secure_message_receive(NULL, &size);
+       scpi_secure_message_end();
+
+       /* We are expecting 'SCP Ready', produce correct error if it's not */
+       scpi_status_t response = SCP_OK;
+       if (command != SCPI_CMD_SCP_READY)
+               response = SCP_E_SUPPORT;
+       else if (size != 0)
+               response = SCP_E_SIZE;
+
+       /* Send our response back to SCP */
+       scpi_secure_send32(command, response);
+
+       return response == SCP_OK ? 0 : -1;
+}
+
+void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+               scpi_power_state_t cluster_state, scpi_power_state_t css_state)
+{
+       uint32_t state = mpidr & 0x0f;  /* CPU ID */
+       state |= (mpidr & 0xf00) >> 4;  /* Cluster ID */
+       state |= cpu_state << 8;
+       state |= cluster_state << 12;
+       state |= css_state << 16;
+       scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state);
+}
diff --git a/plat/juno/scpi.h b/plat/juno/scpi.h
new file mode 100644 (file)
index 0000000..1112980
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCPI_H__
+#define __SCPI_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern void *scpi_secure_message_start(void);
+extern void scpi_secure_message_send(unsigned command, size_t size);
+extern unsigned scpi_secure_message_receive(void **message_out, size_t *size_out);
+extern void scpi_secure_message_end(void);
+
+
+enum {
+       SCP_OK = 0,     /* Success */
+       SCP_E_PARAM,    /* Invalid parameter(s) */
+       SCP_E_ALIGN,    /* Invalid alignment */
+       SCP_E_SIZE,     /* Invalid size */
+       SCP_E_HANDLER,  /* Invalid handler or callback */
+       SCP_E_ACCESS,   /* Invalid access or permission denied */
+       SCP_E_RANGE,    /* Value out of range */
+       SCP_E_TIMEOUT,  /* Time out has ocurred */
+       SCP_E_NOMEM,    /* Invalid memory area or pointer */
+       SCP_E_PWRSTATE, /* Invalid power state */
+       SCP_E_SUPPORT,  /* Feature not supported or disabled */
+};
+
+typedef uint32_t scpi_status_t;
+
+typedef enum {
+       SCPI_CMD_SCP_READY = 0x01,
+       SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
+} scpi_command_t;
+
+typedef enum {
+       scpi_power_on = 0,
+       scpi_power_retention = 1,
+       scpi_power_off = 3,
+} scpi_power_state_t;
+
+extern int scpi_wait_ready(void);
+extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+               scpi_power_state_t cluster_state, scpi_power_state_t css_state);
+
+#endif /* __SCPI_H__ */