diff --git a/plat/juno/aarch64/bl1_plat_helpers.S b/plat/juno/aarch64/bl1_plat_helpers.S
new file mode 100644
index 0000000000000000000000000000000000000000..904d1101d529e217d862f17dcd541334c0cd9a45
--- /dev/null
+++ b/plat/juno/aarch64/bl1_plat_helpers.S
@@ -0,0 +1,174 @@
+/*
+ * 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 <platform.h>
+
+	.globl	platform_get_entrypoint
+	.globl	platform_cold_boot_init
+	.globl	plat_secondary_cold_boot_setup
+
+
+	.section	.text, "ax"; .align 3
+
+
+	/* -----------------------------------------------------
+	 * 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.
+	 * -----------------------------------------------------
+	 */
+plat_secondary_cold_boot_setup: ; .type plat_secondary_cold_boot_setup, %function
+	/* 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
+	 * TODO: PSYSR is a common register and should be
+	 * 	accessed using locks. Since its not possible
+	 * 	to use locks immediately after a cold reset
+	 * 	we are relying on the fact that after a cold
+	 * 	reset all cpus will read the same WK field
+	 * -----------------------------------------------------
+	 */
+platform_get_entrypoint: ; .type platform_get_entrypoint, %function
+	mov	x9, x30 // lr
+	mov	x2, x0
+	ldr	x1, =PWRC_BASE
+	str	w2, [x1, #PSYSR_OFF]
+	ldr	w2, [x1, #PSYSR_OFF]
+	ubfx	w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_MASK
+	cbnz	w2, warm_reset
+	mov	x0, x2
+	b	exit
+warm_reset:
+	/* ---------------------------------------------
+	 * A per-cpu mailbox is maintained in the tru-
+	 * sted DRAM. Its flushed out of the caches
+	 * after every update using normal memory so
+	 * its safe to read it here with SO attributes
+	 * ---------------------------------------------
+	 */
+	ldr	x10, =TZDRAM_BASE + MBOX_OFF
+	bl	platform_get_core_pos
+	lsl	x0, x0, #CACHE_WRITEBACK_SHIFT
+	ldr	x0, [x10, x0]
+	cbz	x0, _panic
+exit:
+	ret	x9
+_panic:	b	_panic
+
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Zero out the mailbox registers in the TZDRAM. The
+	 * mmu is turned off right now and only the primary can
+	 * ever execute this code. Secondaries will read the
+	 * mailboxes using SO accesses. In short, BL31 will
+	 * update the mailboxes after mapping the tzdram as
+	 * normal memory. It will flush its copy after update.
+	 * BL1 will always read the mailboxes with the MMU off
+	 * -----------------------------------------------------
+	 */
+platform_mem_init: ; .type platform_mem_init, %function
+	ldr	x0, =TZDRAM_BASE + MBOX_OFF
+	stp	xzr, xzr, [x0, #0]
+	stp	xzr, xzr, [x0, #0x10]
+	stp	xzr, xzr, [x0, #0x20]
+	stp	xzr, xzr, [x0, #0x30]
+	ret
+
+
+	/* -----------------------------------------------------
+	 * void platform_cold_boot_init (bl1_main function);
+	 *
+	 * Routine called only by the primary cpu after a cold
+	 * boot to perform early platform initialization
+	 * -----------------------------------------------------
+	 */
+platform_cold_boot_init: ; .type platform_cold_boot_init, %function
+	mov	x20, x0
+	bl	platform_mem_init
+	bl	read_mpidr
+	mov	x19, x0
+
+	/* ---------------------------------------------
+	 * Give ourselves a small coherent stack to
+	 * ease the pain of initializing the MMU and
+	 * CCI in assembler
+	 * ---------------------------------------------
+	 */
+	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
+	 * ---------------------------------------------
+	 */
+	mov	x0, x19
+	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/plat_common.c b/plat/juno/aarch64/plat_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..4cd30657fa214387865c0c7582a97e4845d132b0
--- /dev/null
+++ b/plat/juno/aarch64/plat_common.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <string.h>
+#include <assert.h>
+#include <arch_helpers.h>
+#include <platform.h>
+#include <bl_common.h>
+/* Included only for error codes */
+#include <psci.h>
+
+unsigned char platform_normal_stacks[PLATFORM_STACK_SIZE][PLATFORM_CORE_COUNT]
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
+		section("tzfw_normal_stacks")));
+
+/*******************************************************************************
+ * This array holds the characteristics of the differences between the three
+ * FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
+ * boot at each boot stage by the primary before enabling the MMU (to allow cci
+ * configuration) & used thereafter. Each BL will have its own copy to allow
+ * independent operation.
+ ******************************************************************************/
+static unsigned long platform_config[CONFIG_LIMIT];
+
+/*******************************************************************************
+ * An internal global pointer of the level 1 translation tables which should not
+ * change once setup by the primary cpu during a cold boot.
+ *******************************************************************************/
+unsigned long l1_xlation_table __aligned(PLATFORM_CACHE_LINE_SIZE)
+__attribute__ ((section("tzfw_coherent_mem")));
+
+/*******************************************************************************
+ * Enable the MMU assuming that the pagetables have already been created
+ *******************************************************************************/
+void enable_mmu()
+{
+	unsigned long mair, tcr, ttbr, sctlr;
+	unsigned long current_el = read_current_el();
+
+	/* Set the attributes in the right indices of the MAIR */
+	mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+	mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
+				  ATTR_IWBWA_OWBWA_NTR_INDEX);
+	write_mair(mair);
+
+	/*
+	 * Set TCR bits as well. Inner & outer WBWA & shareable + T0SZ = 32
+	 */
+	tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |
+		  TCR_RGN_INNER_WBA | TCR_T0SZ_4GB;
+	if (GET_EL(current_el) == MODE_EL3) {
+		tcr |= TCR_EL3_RES1;
+		/* Invalidate EL3 TLBs */
+		tlbialle3();
+	} else {
+		/* Invalidate EL1 TLBs */
+		tlbivmalle1();
+	}
+
+	write_tcr(tcr);
+
+	/* Set TTBR bits as well */
+	ttbr = (unsigned long) l1_xlation_table;
+	write_ttbr0(ttbr);
+
+	sctlr = read_sctlr();
+	sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT;
+	sctlr |= SCTLR_A_BIT | SCTLR_C_BIT;
+	write_sctlr(sctlr);
+
+	return;
+}
+
+void disable_mmu(void)
+{
+	/* Zero out the MMU related registers */
+	write_mair(0);
+	write_tcr(0);
+	write_ttbr0(0);
+	write_sctlr(0);
+
+	/* Flush the caches */
+	dcsw_op_all(DCCISW);
+
+	return;
+}
+
+/*******************************************************************************
+ * Setup the pagetables as per the platform memory map & initialize the mmu
+ *******************************************************************************/
+void configure_mmu(meminfo *mem_layout,
+		   unsigned long ro_start,
+		   unsigned long ro_limit,
+		   unsigned long coh_start,
+		   unsigned long coh_limit)
+{
+	assert(IS_PAGE_ALIGNED(ro_start));
+	assert(IS_PAGE_ALIGNED(ro_limit));
+	assert(IS_PAGE_ALIGNED(coh_start));
+	assert(IS_PAGE_ALIGNED(coh_limit));
+
+	l1_xlation_table = fill_xlation_tables(mem_layout,
+					       ro_start,
+					       ro_limit,
+					       coh_start,
+					       coh_limit);
+	enable_mmu();
+	return;
+}
+
+/* Simple routine which returns a configuration variable value */
+unsigned long platform_get_cfgvar(unsigned int var_id)
+{
+	assert(var_id < CONFIG_LIMIT);
+	return platform_config[var_id];
+}
+
+unsigned long plat_get_ns_image_entrypoint(void) {
+	return NS_IMAGE_OFFSET;
+}
diff --git a/plat/juno/aarch64/plat_helpers.S b/plat/juno/aarch64/plat_helpers.S
new file mode 100644
index 0000000000000000000000000000000000000000..00e8850608afa6ab0befc87251243c2625fdbe47
--- /dev/null
+++ b/plat/juno/aarch64/plat_helpers.S
@@ -0,0 +1,48 @@
+/*
+ * 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 <platform.h>
+
+	.globl	plat_report_exception
+
+	.section	.text, "ax"
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * On FVP platform, it updates the LEDs
+	 * to indicate where we are
+	 * ---------------------------------------------
+	 */
+plat_report_exception:
+	/* Juno todo: Come up with a way of reporting errors */
+	ret
diff --git a/plat/juno/bl1_plat_setup.c b/plat/juno/bl1_plat_setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..78e5d52e7be025441e842909443bd44638dc2a0a
--- /dev/null
+++ b/plat/juno/bl1_plat_setup.c
@@ -0,0 +1,144 @@
+/*
+ * 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 <assert.h>
+#include <arch_helpers.h>
+#include <platform.h>
+#include <bl1.h>
+#include <console.h>
+#include <cci400.h>
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+extern unsigned long __BL1_RAM_START__;
+extern unsigned long __BL1_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__)
+
+#define BL1_RAM_BASE (unsigned long)(&__BL1_RAM_START__)
+#define BL1_RAM_LIMIT (unsigned long)(&__BL1_RAM_END__)
+
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo bl1_tzram_layout;
+
+meminfo *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	const unsigned long bl1_ram_base = BL1_RAM_BASE;
+	const unsigned long bl1_ram_limit = BL1_RAM_LIMIT;
+	const unsigned long tzram_limit = TZRAM_BASE + TZRAM_SIZE;
+
+	/*
+	 * Calculate how much ram is BL1 using & how much remains free.
+	 * This also includes a rudimentary mechanism to detect whether
+	 * the BL1 data is loaded at the top or bottom of memory.
+	 * TODO: add support for discontigous chunks of free ram if
+	 *       needed. Might need dynamic memory allocation support
+	 *       et al.
+	 */
+	bl1_tzram_layout.total_base = TZRAM_BASE;
+	bl1_tzram_layout.total_size = TZRAM_SIZE;
+
+	if (bl1_ram_limit == tzram_limit) {
+		/* BL1 has been loaded at the top of memory. */
+		bl1_tzram_layout.free_base = TZRAM_BASE;
+		bl1_tzram_layout.free_size = bl1_ram_base - TZRAM_BASE;
+	} else {
+		/* BL1 has been loaded at the bottom of memory. */
+		bl1_tzram_layout.free_base = bl1_ram_limit;
+		bl1_tzram_layout.free_size =
+			tzram_limit - bl1_ram_limit;
+	}
+
+	/* Initialize the console */
+	console_init(PL011_UART0_BASE);
+}
+
+/*******************************************************************************
+ * Function which will evaluate how much of the trusted ram has been gobbled
+ * up by BL1 and return the base and size of whats available for loading BL2.
+ * Its called after coherency and the MMU have been turned on.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+	/* 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_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)
+{
+	unsigned long cci_setup;
+
+	/*
+	 * Enable CCI-400 for this cluster. No need
+	 * for locks as no other cpu is active at the
+	 * moment
+	 */
+	cci_setup = platform_get_cfgvar(CONFIG_HAS_CCI);
+	if (cci_setup) {
+		cci_enable_coherency(read_mpidr());
+	}
+
+	configure_mmu(&bl1_tzram_layout,
+			TZROM_BASE,
+			TZROM_BASE + TZROM_SIZE,
+			BL1_COHERENT_RAM_BASE,
+			BL1_COHERENT_RAM_LIMIT);
+}
diff --git a/plat/juno/bl2_plat_setup.c b/plat/juno/bl2_plat_setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e0b9e8326f8199c5acd40dfcbd93dd37552caa6
--- /dev/null
+++ b/plat/juno/bl2_plat_setup.c
@@ -0,0 +1,145 @@
+/*
+ * 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 <assert.h>
+#include <arch_helpers.h>
+#include <platform.h>
+#include <bl2.h>
+#include <bl_common.h>
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+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__)
+
+/* Pointer to memory visible to both BL2 and BL31 for passing data */
+extern unsigned char **bl2_el_change_mem_ptr;
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
+		section("tzfw_coherent_mem")));
+
+/*******************************************************************************
+ * Reference to structure which holds the arguments which need to be passed
+ * to BL31
+ ******************************************************************************/
+static bl31_args *bl2_to_bl31_args;
+
+meminfo *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the memory that the platform has kept
+ * aside to pass all the information that BL31 could need.
+ ******************************************************************************/
+bl31_args *bl2_get_bl31_args_ptr(void)
+{
+	return bl2_to_bl31_args;
+}
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted SRAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo *mem_layout,
+			      void *data)
+{
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout.total_base = mem_layout->total_base;
+	bl2_tzram_layout.total_size = mem_layout->total_size;
+	bl2_tzram_layout.free_base = mem_layout->free_base;
+	bl2_tzram_layout.free_size = mem_layout->free_size;
+	bl2_tzram_layout.attr = mem_layout->attr;
+	bl2_tzram_layout.next = 0;
+
+	return;
+}
+
+/*******************************************************************************
+ * Perform platform specific setup. For now just initialize the memory location
+ * to use for passing arguments to BL31.
+ ******************************************************************************/
+void bl2_platform_setup()
+{
+	/* Initialise the IO layer and register platform IO devices */
+	io_setup();
+	/* Use the Trusted DRAM for passing args to BL31 */
+	bl2_to_bl31_args = (bl31_args *) TZDRAM_BASE;
+
+	/* Populate the extents of memory available for loading BL33 */
+	bl2_to_bl31_args->bl33_meminfo.total_base = DRAM_BASE;
+	bl2_to_bl31_args->bl33_meminfo.total_size = DRAM_SIZE;
+	bl2_to_bl31_args->bl33_meminfo.free_base = DRAM_BASE;
+	bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE;
+	bl2_to_bl31_args->bl33_meminfo.attr = 0;
+	bl2_to_bl31_args->bl33_meminfo.next = 0;
+
+}
+
+/*******************************************************************************
+ * 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()
+{
+	configure_mmu(&bl2_tzram_layout,
+		      BL2_RO_BASE,
+		      BL2_RO_LIMIT,
+		      BL2_COHERENT_RAM_BASE,
+		      BL2_COHERENT_RAM_LIMIT);
+}
diff --git a/plat/juno/bl31_plat_setup.c b/plat/juno/bl31_plat_setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..ffdfdd4546f70075e262c4be63e543dda4c85b4b
--- /dev/null
+++ b/plat/juno/bl31_plat_setup.c
@@ -0,0 +1,141 @@
+/*
+ * 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 <platform.h>
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+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__)
+
+/*******************************************************************************
+ * Reference to structure which holds the arguments that have been passed to
+ * BL31 from BL2.
+ ******************************************************************************/
+static bl31_args *bl2_to_bl31_args;
+
+meminfo *bl31_plat_sec_mem_layout(void)
+{
+	return &bl2_to_bl31_args->bl31_meminfo;
+}
+
+meminfo *bl31_plat_get_bl32_mem_layout(void)
+{
+	return &bl2_to_bl31_args->bl32_meminfo;
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'el_change_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+el_change_info *bl31_get_next_image_info(uint32_t type)
+{
+	el_change_info *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ?
+		&bl2_to_bl31_args->bl33_image_info :
+		&bl2_to_bl31_args->bl32_image_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->entrypoint)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 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. On the FVP
+ * we know that BL2 has populated the parameters in secure DRAM. So we just use
+ * the reference passed in 'from_bl2' instead of copying. The 'data' parameter
+ * is not used since all the information is contained in 'from_bl2'. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_args *from_bl2,
+			       void *data)
+{
+	bl2_to_bl31_args = from_bl2;
+
+}
+
+/*******************************************************************************
+ * Initialize the gic, configure the CLCD and zero out variables needed by the
+ * secondaries to boot up correctly.
+ ******************************************************************************/
+void bl31_platform_setup()
+{
+	/* Initialize the gic cpu and distributor interfaces */
+	gic_setup();
+
+	/* 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(&bl2_to_bl31_args->bl31_meminfo,
+		      BL31_RO_BASE,
+		      BL31_RO_LIMIT,
+		      BL31_COHERENT_RAM_BASE,
+		      BL31_COHERENT_RAM_LIMIT);
+}
diff --git a/plat/juno/plat_gic.c b/plat/juno/plat_gic.c
new file mode 100644
index 0000000000000000000000000000000000000000..8929172fe17407180222c0d9440eb2861383b9db
--- /dev/null
+++ b/plat/juno/plat_gic.c
@@ -0,0 +1,282 @@
+/*
+ * 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 <stdint.h>
+#include <arch_helpers.h>
+#include <platform.h>
+#include <gic.h>
+#include <debug.h>
+
+
+/*******************************************************************************
+ * TODO: Revisit if priorities are being set such that no non-secure interrupt
+ * can have a higher priority than a secure one as recommended in the GICv2 spec
+ ******************************************************************************/
+
+/*******************************************************************************
+ * This function does some minimal GICv3 configuration. The Firmware itself does
+ * not fully support GICv3 at this time and relies on GICv2 emulation as
+ * provided by GICv3. This function allows software (like Linux) in later stages
+ * to use full GICv3 features.
+ ******************************************************************************/
+void gicv3_cpuif_setup(void)
+{
+	unsigned int scr_val, val;
+	uintptr_t base;
+
+	/*
+	 * When CPUs come out of reset they have their GICR_WAKER.ProcessorSleep
+	 * bit set. In order to allow interrupts to get routed to the CPU we
+	 * need to clear this bit if set and wait for GICR_WAKER.ChildrenAsleep
+	 * to clear (GICv3 Architecture specification 5.4.23).
+	 * GICR_WAKER is NOT banked per CPU, compute the correct base address
+	 * per CPU.
+	 */
+	base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
+	if (base == (uintptr_t)NULL) {
+		/* No re-distributor base address. This interface cannot be
+		 * configured.
+		 */
+		panic();
+	}
+
+	val = gicr_read_waker(base);
+
+	val &= ~WAKER_PS;
+	gicr_write_waker(base, val);
+	dsb();
+
+	/* We need to wait for ChildrenAsleep to clear. */
+	val = gicr_read_waker(base);
+	while (val & WAKER_CA) {
+		val = gicr_read_waker(base);
+	}
+
+	/*
+	 * We need to set SCR_EL3.NS in order to see GICv3 non-secure state.
+	 * Restore SCR_EL3.NS again before exit.
+	 */
+	scr_val = read_scr();
+	write_scr(scr_val | SCR_NS_BIT);
+
+	/*
+	 * By default EL2 and NS-EL1 software should be able to enable GICv3
+	 * System register access without any configuration at EL3. But it turns
+	 * out that GICC PMR as set in GICv2 mode does not affect GICv3 mode. So
+	 * we need to set it here again. In order to do that we need to enable
+	 * register access. We leave it enabled as it should be fine and might
+	 * prevent problems with later software trying to access GIC System
+	 * Registers.
+	 */
+	val = read_icc_sre_el3();
+	write_icc_sre_el3(val | ICC_SRE_EN | ICC_SRE_SRE);
+
+	val = read_icc_sre_el2();
+	write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE);
+
+	write_icc_pmr_el1(GIC_PRI_MASK);
+
+	/* Restore SCR_EL3 */
+	write_scr(scr_val);
+}
+
+/*******************************************************************************
+ * This function does some minimal GICv3 configuration when cores go
+ * down.
+ ******************************************************************************/
+void gicv3_cpuif_deactivate(void)
+{
+	unsigned int val;
+	uintptr_t base;
+
+	/*
+	 * When taking CPUs down we need to set GICR_WAKER.ProcessorSleep and
+	 * wait for GICR_WAKER.ChildrenAsleep to get set.
+	 * (GICv3 Architecture specification 5.4.23).
+	 * GICR_WAKER is NOT banked per CPU, compute the correct base address
+	 * per CPU.
+	 */
+	base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
+	if (base == (uintptr_t)NULL) {
+		/* No re-distributor base address. This interface cannot be
+		 * configured.
+		 */
+		panic();
+	}
+
+	val = gicr_read_waker(base);
+	val |= WAKER_PS;
+	gicr_write_waker(base, val);
+	dsb();
+
+	/* We need to wait for ChildrenAsleep to set. */
+	val = gicr_read_waker(base);
+	while ((val & WAKER_CA) == 0) {
+		val = gicr_read_waker(base);
+	}
+}
+
+
+/*******************************************************************************
+ * 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;
+
+	val = gicc_read_iidr(gicc_base);
+
+	/*
+	 * If GICv3 we need to do a bit of additional setup. We want to
+	 * allow default GICv2 behaviour but allow the next stage to
+	 * enable full gicv3 features.
+	 */
+	if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
+		gicv3_cpuif_setup();
+	}
+
+	val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0;
+	val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
+
+	gicc_write_pmr(gicc_base, GIC_PRI_MASK);
+	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);
+
+	val = gicc_read_iidr(gicc_base);
+
+	/*
+	 * If GICv3 we need to do a bit of additional setup. Make sure the
+	 * RDIST is put to sleep.
+	 */
+	if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
+		gicv3_cpuif_deactivate();
+	}
+}
+
+/*******************************************************************************
+ * 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)
+{
+	gicd_write_igroupr(gicd_base, 0, ~0);
+
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_PHY_TIMER);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_0);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_1);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_2);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_3);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_4);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_5);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_6);
+	gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_7);
+
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY);
+
+	gicd_set_isenabler(gicd_base, IRQ_SEC_PHY_TIMER);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_0);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_1);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_2);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_3);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_4);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_5);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_6);
+	gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_7);
+}
+
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+void gic_distif_setup(unsigned int gicd_base)
+{
+	unsigned int ctr, num_ints, ctlr;
+
+	/* Disable the distributor before going further */
+	ctlr = gicd_read_ctlr(gicd_base);
+	ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+	gicd_write_ctlr(gicd_base, ctlr);
+
+	/*
+	 * Mark out non-secure interrupts. Calculate number of
+	 * IGROUPR registers to consider. Will be equal to the
+	 * number of IT_LINES
+	 */
+	num_ints = gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
+	num_ints++;
+	for (ctr = 0; ctr < num_ints; ctr++)
+		gicd_write_igroupr(gicd_base, ctr << IGROUPR_SHIFT, ~0);
+
+	/* Configure secure interrupts now */
+	gicd_clr_igroupr(gicd_base, IRQ_TZ_WDOG);
+	gicd_set_ipriorityr(gicd_base, IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY);
+	gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
+			   platform_get_core_pos(read_mpidr()));
+	gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
+	gic_pcpu_distif_setup(gicd_base);
+
+	gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
+}
+
+void gic_setup(void)
+{
+	unsigned int gicd_base, gicc_base;
+
+	gicd_base = platform_get_cfgvar(CONFIG_GICD_ADDR);
+	gicc_base = platform_get_cfgvar(CONFIG_GICC_ADDR);
+
+	gic_cpuif_setup(gicc_base);
+	gic_distif_setup(gicd_base);
+}
diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c
new file mode 100644
index 0000000000000000000000000000000000000000..5279f970e45e0599f3f0cfe1d72d329a545e57f3
--- /dev/null
+++ b/plat/juno/plat_io_storage.c
@@ -0,0 +1,207 @@
+/*
+ * 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 <string.h>
+#include "platform.h"
+#include "io_storage.h"
+#include "io_driver.h"
+#include "io_semihosting.h"
+#include "semihosting.h"	/* For FOPEN_MODE_... */
+#include "io_fip.h"
+#include "io_memmap.h"
+#include "debug.h"
+
+/* IO devices */
+static struct io_plat_data io_data;
+static struct io_dev_connector *sh_dev_con;
+static void *const sh_dev_spec;
+static void *const sh_init_params;
+static io_dev_handle sh_dev_handle;
+static struct io_dev_connector *fip_dev_con;
+static void *const fip_dev_spec;
+static io_dev_handle fip_dev_handle;
+static struct io_dev_connector *memmap_dev_con;
+static void *const memmap_dev_spec;
+static void *const memmap_init_params;
+static io_dev_handle memmap_dev_handle;
+
+static io_block_spec fip_block_spec = {
+	.offset = FLASH0_BASE,
+	.length = FLASH0_SIZE
+};
+
+static io_file_spec bl2_file_spec = {
+	.path = BL2_IMAGE_NAME,
+	.mode = FOPEN_MODE_R
+};
+
+static io_file_spec bl31_file_spec = {
+	.path = BL31_IMAGE_NAME,
+	.mode = FOPEN_MODE_R
+};
+
+static io_file_spec bl33_file_spec = {
+	.path = BL33_IMAGE_NAME,
+	.mode = FOPEN_MODE_R
+};
+
+static int open_fip(void* spec);
+static int open_memmap(void* spec);
+
+typedef struct {
+	char * image_name;
+	io_dev_handle* dev_handle;
+	void* image_spec;
+	int (*check)(void* spec);
+} plat_io_policy;
+
+static plat_io_policy policies[] = {
+	{ FIP_IMAGE_NAME,  &memmap_dev_handle, &fip_block_spec, open_memmap },
+	{ BL2_IMAGE_NAME,  &fip_dev_handle,    &bl2_file_spec,  open_fip    },
+	{ BL31_IMAGE_NAME, &fip_dev_handle,    &bl31_file_spec, open_fip    },
+	{ BL33_IMAGE_NAME, &fip_dev_handle,    &bl33_file_spec, open_fip    },
+	{0,0,0}
+};
+
+
+static int open_fip(void *spec)
+{
+	int result = IO_FAIL;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (void *)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(void *spec)
+{
+	int result = IO_FAIL;
+	io_handle 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;
+}
+
+static int open_semihosting(void *spec)
+{
+	int result = IO_FAIL;
+	io_handle local_image_handle;
+
+	/* See if the file exists on semi-hosting.*/
+	result = io_dev_init(sh_dev_handle, sh_init_params);
+	if (result == IO_SUCCESS) {
+		result = io_open(sh_dev_handle, spec, &local_image_handle);
+		if (result == IO_SUCCESS) {
+			INFO("Using Semi-hosting IO\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+void io_setup (void)
+{
+	int io_result = IO_FAIL;
+
+	/* Initialise the IO layer */
+	io_init(&io_data);
+
+	/* Register the IO devices on this platform */
+	io_result = register_io_dev_sh(&sh_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	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(sh_dev_con, sh_dev_spec, &sh_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	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, io_dev_handle *dev_handle,
+			  void **image_spec)
+{
+	int result = IO_FAIL;
+	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) {
+					*(io_file_spec**)image_spec = policy->image_spec;
+					*dev_handle=*(policy->dev_handle);
+					break;
+				} else {
+					result = open_semihosting(policy->image_spec);
+					if (result == IO_SUCCESS) {
+						*dev_handle = sh_dev_handle;
+						*(io_file_spec **)image_spec = policy->image_spec;
+					}
+				}
+			}
+			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
index 0000000000000000000000000000000000000000..8c8f0181f1c37b5a975fb62b9f8241a32b626f08
--- /dev/null
+++ b/plat/juno/plat_pm.c
@@ -0,0 +1,48 @@
+/*
+ * 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 <stdint.h>
+#include <psci.h>
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static plat_pm_ops pm_ops = {
+	0
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops & initialize the fvp power controller
+ ******************************************************************************/
+int platform_setup_pm(plat_pm_ops **plat_ops)
+{
+	*plat_ops = &pm_ops;
+	return 0;
+}
diff --git a/plat/juno/plat_topology.c b/plat/juno/plat_topology.c
new file mode 100644
index 0000000000000000000000000000000000000000..0c8c525963183dc783a22d5790eb34e8513bdc77
--- /dev/null
+++ b/plat/juno/plat_topology.c
@@ -0,0 +1,241 @@
+/*
+ * 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 <string.h>
+#include <assert.h>
+#include <platform.h>
+#include <fvp_pwrc.h>
+/* TODO: Reusing psci error codes & state information. Get our own! */
+#include <psci.h>
+
+/* We treat '255' as an invalid affinity instance */
+#define AFFINST_INVAL	0xff
+
+/*******************************************************************************
+ * We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each
+ * flavour has a different topology. The common bit is that there can be a max.
+ * of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define
+ * a tree like data structure which caters to these maximum bounds. It simply
+ * marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no
+ * cluster 1 on the Foundation FVP. The 'data' field is currently unused.
+ ******************************************************************************/
+typedef struct {
+	unsigned char sibling;
+	unsigned char child;
+	unsigned char state;
+	unsigned int data;
+} affinity_info;
+
+/*******************************************************************************
+ * The following two data structures store the topology tree for the fvp. There
+ * is a separate array for each affinity level i.e. cpus and clusters. The child
+ * and sibling references allow traversal inside and in between the two arrays.
+ ******************************************************************************/
+static affinity_info fvp_aff1_topology_map[PLATFORM_CLUSTER_COUNT];
+static affinity_info fvp_aff0_topology_map[PLATFORM_CORE_COUNT];
+
+/* Simple global variable to safeguard us from stupidity */
+static unsigned int topology_setup_done;
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the platform
+ * topology. psci queries the platform to determine how many affinity instances
+ * are present at a particular level for a given mpidr e.g. consider a dual
+ * cluster platform where each cluster has 4 cpus. A call to this function with
+ * (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4.
+ * Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters.
+ * This is 'cause we are effectively asking how many affinity level 1 instances
+ * are implemented under affinity level 2 instance 0.
+ ******************************************************************************/
+unsigned int plat_get_aff_count(unsigned int aff_lvl,
+				unsigned long mpidr)
+{
+	unsigned int aff_count = 1, ctr;
+	unsigned char parent_aff_id;
+
+	assert(topology_setup_done == 1);
+
+	switch (aff_lvl) {
+	case 3:
+	case 2:
+		/*
+		 * Assert if the parent affinity instance is not 0.
+		 * This also takes care of level 3 in an obfuscated way
+		 */
+		parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id == 0);
+
+		/*
+		 * Report that we implement a single instance of
+		 * affinity levels 2 & 3 which are AFF_ABSENT
+		 */
+		break;
+	case 1:
+		/* Assert if the parent affinity instance is not 0. */
+		parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id == 0);
+
+		/* Fetch the starting index in the aff1 array */
+		for (ctr = 0;
+		     fvp_aff1_topology_map[ctr].sibling != AFFINST_INVAL;
+		     ctr = fvp_aff1_topology_map[ctr].sibling) {
+			aff_count++;
+		}
+
+		break;
+	case 0:
+		/* Assert if the cluster id is anything apart from 0 or 1 */
+		parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id < PLATFORM_CLUSTER_COUNT);
+
+		/* Fetch the starting index in the aff0 array */
+		for (ctr = fvp_aff1_topology_map[parent_aff_id].child;
+		     fvp_aff0_topology_map[ctr].sibling != AFFINST_INVAL;
+		     ctr = fvp_aff0_topology_map[ctr].sibling) {
+			aff_count++;
+		}
+
+		break;
+	default:
+		assert(0);
+	}
+
+	return aff_count;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the state of a
+ * affinity instance in the platform topology. psci queries the platform to
+ * determine whether an affinity instance is present or absent. This caters for
+ * topologies where an intermediate affinity level instance is missing e.g.
+ * consider a platform which implements a single cluster with 4 cpus and there
+ * is another cpu sitting directly on the interconnect along with the cluster.
+ * The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single
+ * cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster
+ * 1 is however missing but needs to be accounted to reach this single cpu in
+ * the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not
+ * applicable to the FVP but depicted as an example.
+ ******************************************************************************/
+unsigned int plat_get_aff_state(unsigned int aff_lvl,
+				unsigned long mpidr)
+{
+	unsigned int aff_state = PSCI_AFF_ABSENT, idx;
+	idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	assert(topology_setup_done == 1);
+
+	switch (aff_lvl) {
+	case 3:
+	case 2:
+		/* Report affinity levels 2 & 3 as absent */
+		break;
+	case 1:
+		aff_state = fvp_aff1_topology_map[idx].state;
+		break;
+	case 0:
+		/*
+		 * First get start index of the aff0 in its array & then add
+		 * to it the affinity id that we want the state of
+		 */
+		idx = fvp_aff1_topology_map[idx].child;
+		idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+		aff_state = fvp_aff0_topology_map[idx].state;
+		break;
+	default:
+		assert(0);
+	}
+
+	return aff_state;
+}
+
+/*******************************************************************************
+ * Handy optimization to prevent the psci implementation from traversing through
+ * affinity levels which are not present while detecting the platform topology.
+ ******************************************************************************/
+int plat_get_max_afflvl()
+{
+	return MPIDR_AFFLVL1;
+}
+
+/*******************************************************************************
+ * This function populates the FVP specific topology information depending upon
+ * the FVP flavour its running on. We construct all the mpidrs we can handle
+ * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried.
+ ******************************************************************************/
+int plat_setup_topology()
+{
+	unsigned char aff0, aff1, aff_state, aff0_offset = 0;
+	unsigned long mpidr;
+
+	topology_setup_done = 0;
+
+	for (aff1 = 0; aff1 < PLATFORM_CLUSTER_COUNT; aff1++) {
+
+		fvp_aff1_topology_map[aff1].child = aff0_offset;
+		fvp_aff1_topology_map[aff1].sibling = aff1 + 1;
+
+		for (aff0 = 0; aff0 < PLATFORM_MAX_CPUS_PER_CLUSTER; aff0++) {
+
+			mpidr = aff1 << MPIDR_AFF1_SHIFT;
+			mpidr |= aff0 << MPIDR_AFF0_SHIFT;
+
+			if (fvp_pwrc_read_psysr(mpidr) != PSYSR_INVALID) {
+				/*
+				 * Presence of even a single aff0 indicates
+				 * presence of parent aff1 on the FVP.
+				 */
+				aff_state = PSCI_AFF_PRESENT;
+				fvp_aff1_topology_map[aff1].state =
+					PSCI_AFF_PRESENT;
+			} else {
+				aff_state = PSCI_AFF_ABSENT;
+			}
+
+			fvp_aff0_topology_map[aff0_offset].child = AFFINST_INVAL;
+			fvp_aff0_topology_map[aff0_offset].state = aff_state;
+			fvp_aff0_topology_map[aff0_offset].sibling =
+				aff0_offset + 1;
+
+			/* Increment the absolute number of aff0s traversed */
+			aff0_offset++;
+		}
+
+		/* Tie-off the last aff0 sibling to -1 to avoid overflow */
+		fvp_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL;
+	}
+
+	/* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */
+	fvp_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL;
+
+	topology_setup_done = 1;
+	return 0;
+}
diff --git a/plat/juno/platform.h b/plat/juno/platform.h
new file mode 100644
index 0000000000000000000000000000000000000000..91dbecfca4d2fd747951b711f51183de143a30eb
--- /dev/null
+++ b/plat/juno/platform.h
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+#include <arch.h>
+#include <mmio.h>
+#include <psci.h>
+#include <bl_common.h>
+#include "io_storage.h"
+
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+#define PLATFORM_STACK_SIZE		0x800
+
+#define FIRMWARE_WELCOME_STR		"Booting trusted firmware boot loader stage 1\n\r"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME			"bl2.bin"
+
+/* EL3 Runtime Firmware BL31 */
+#define BL31_IMAGE_NAME			"bl31.bin"
+
+/* Secure Payload BL32 (Trusted OS) */
+#define BL32_IMAGE_NAME			"bl32.bin"
+
+/* Non-Trusted Firmware BL33 and its load address */
+#define BL33_IMAGE_NAME			"bl33.bin" /* e.g. UEFI */
+#define NS_IMAGE_OFFSET			(DRAM_BASE + 0x8000000) /* DRAM + 128MB */
+
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME			"fip.bin"
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		2ull
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+#define PLATFORM_CLUSTER1_CORE_COUNT	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT + \
+						PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	4
+#define PRIMARY_CPU			0x0
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define TZROM_BASE		0x00000000
+#define TZROM_SIZE		0x04000000
+
+#define TZRAM_BASE		0x04000000
+#define TZRAM_SIZE		0x40000
+
+#define FLASH0_BASE		0x08000000
+#define FLASH0_SIZE		TZROM_SIZE
+
+#define FLASH1_BASE		0x0c000000
+#define FLASH1_SIZE		0x04000000
+
+#define PSRAM_BASE		0x14000000
+#define PSRAM_SIZE		0x04000000
+
+#define VRAM_BASE		0x18000000
+#define VRAM_SIZE		0x02000000
+
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE		0x1a000000
+#define DEVICE0_SIZE		0x12200000
+
+#define DEVICE1_BASE		0x2f000000
+#define DEVICE1_SIZE		0x200000
+
+#define NSRAM_BASE		0x2e000000
+#define NSRAM_SIZE		0x10000
+
+/* Location of trusted dram on the base fvp */
+#define TZDRAM_BASE		0x06000000
+#define TZDRAM_SIZE		0x02000000
+#define MBOX_OFF		0x1000
+#define AFFMAP_OFF		0x1200
+
+#define DRAM_BASE              0x80000000ull
+#define DRAM_SIZE              0x80000000ull
+
+#define PCIE_EXP_BASE		0x40000000
+#define TZRNG_BASE		0x7fe60000
+#define TZNVCTR_BASE		0x7fe70000
+#define TZROOTKEY_BASE		0x7fe80000
+
+/* Memory mapped Generic timer interfaces  */
+#define SYS_CNTCTL_BASE		0x2a430000
+
+/* Counter timer module offsets */
+#define CNTNSAR			0x4
+#define CNTNSAR_NS_SHIFT(x)	x
+
+#define CNTACR_BASE(x)		(0x40 + (x << 2))
+#define CNTACR_RPCT_SHIFT	0x0
+#define CNTACR_RVCT_SHIFT	0x1
+#define CNTACR_RFRQ_SHIFT	0x2
+#define CNTACR_RVOFF_SHIFT	0x3
+#define CNTACR_RWVT_SHIFT	0x4
+#define CNTACR_RWPT_SHIFT	0x5
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+#define BL2_BASE			0x0402D000
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+#define BL31_BASE			0x0400C000
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define EL3_ADDR_SPACE_SIZE		(1ull << 32)
+#define EL3_NUM_PAGETABLES		2
+#define EL3_TROM_PAGETABLE		0
+#define EL3_TRAM_PAGETABLE		1
+
+#define ADDR_SPACE_SIZE			(1ull << 32)
+
+#define NUM_L2_PAGETABLES		2
+#define GB1_L2_PAGETABLE		0
+#define GB2_L2_PAGETABLE		1
+
+#define NUM_L3_PAGETABLES		2
+#define TZRAM_PAGETABLE			0
+#define NSRAM_PAGETABLE			1
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE			0x2c090000
+#define CCI400_SL_IFACE_CLUSTER0	3
+#define CCI400_SL_IFACE_CLUSTER1	4
+#define CCI400_SL_IFACE_INDEX(mpidr)	(mpidr & MPIDR_CLUSTER_MASK ? \
+					 CCI400_SL_IFACE_CLUSTER1 :   \
+					 CCI400_SL_IFACE_CLUSTER0)
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+/* VE compatible GIC memory map */
+#define VE_GICD_BASE			0x2c001000
+#define VE_GICC_BASE			0x2c002000
+#define VE_GICH_BASE			0x2c004000
+#define VE_GICV_BASE			0x2c006000
+
+/* Base FVP compatible GIC memory map */
+#define BASE_GICD_BASE			0x2f000000
+#define BASE_GICR_BASE			0x2f100000
+#define BASE_GICC_BASE			0x2c000000
+#define BASE_GICH_BASE			0x2c010000
+#define BASE_GICV_BASE			0x2c02f000
+
+#define IRQ_TZ_WDOG			56
+#define IRQ_SEC_PHY_TIMER		29
+#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
+ ******************************************************************************/
+#define PL011_UART0_BASE		0x1c090000
+#define PL011_UART1_BASE		0x1c0a0000
+#define PL011_UART2_BASE		0x1c0b0000
+#define PL011_UART3_BASE		0x1c0c0000
+#define PL011_BASE			PL011_UART0_BASE
+
+/*******************************************************************************
+ * 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)
+
+#ifndef __ASSEMBLY__
+
+typedef volatile struct {
+	unsigned long value
+	__attribute__((__aligned__(CACHE_WRITEBACK_GRANULE)));
+} mailbox;
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+extern unsigned long *bl1_normal_ram_base;
+extern unsigned long *bl1_normal_ram_len;
+extern unsigned long *bl1_normal_ram_limit;
+extern unsigned long *bl1_normal_ram_zi_base;
+extern unsigned long *bl1_normal_ram_zi_len;
+
+extern unsigned long *bl1_coherent_ram_base;
+extern unsigned long *bl1_coherent_ram_len;
+extern unsigned long *bl1_coherent_ram_limit;
+extern unsigned long *bl1_coherent_ram_zi_base;
+extern unsigned long *bl1_coherent_ram_zi_len;
+extern unsigned long warm_boot_entrypoint;
+
+extern void bl1_plat_arch_setup(void);
+extern void bl2_plat_arch_setup(void);
+extern void bl31_plat_arch_setup(void);
+extern int platform_setup_pm(plat_pm_ops **);
+extern unsigned int platform_get_core_pos(unsigned long mpidr);
+extern void disable_mmu(void);
+extern void enable_mmu(void);
+extern void configure_mmu(meminfo *,
+			  unsigned long,
+			  unsigned long,
+			  unsigned long,
+			  unsigned long);
+extern void plat_report_exception(unsigned long);
+extern unsigned long plat_get_ns_image_entrypoint(void);
+extern unsigned long platform_get_stack(unsigned long mpidr);
+
+/* Declarations for fvp_gic.c */
+extern void gic_cpuif_deactivate(unsigned int);
+extern void gic_cpuif_setup(unsigned int);
+extern void gic_pcpu_distif_setup(unsigned int);
+extern void gic_setup(void);
+
+/* Declarations for fvp_topology.c */
+extern int plat_setup_topology(void);
+extern int plat_get_max_afflvl(void);
+extern unsigned int plat_get_aff_count(unsigned int, unsigned long);
+extern unsigned int plat_get_aff_state(unsigned int, unsigned long);
+
+/* Declarations for plat_io_storage.c */
+extern void io_setup(void);
+extern int plat_get_image_source(const char *image_name,
+		io_dev_handle *dev_handle, void **image_spec);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __PLATFORM_H__ */
diff --git a/plat/juno/platform.mk b/plat/juno/platform.mk
new file mode 100644
index 0000000000000000000000000000000000000000..6924e81cf8513d2abb9a6599b823b0986ef6f312
--- /dev/null
+++ b/plat/juno/platform.mk
@@ -0,0 +1,87 @@
+#
+# 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		:=	-Idrivers/arm/interconnect/cci-400	\
+				-Idrivers/arm/peripherals/pl011		\
+				-Idrivers/power
+
+PLAT_BL1_C_VPATH	:=	drivers/arm/interconnect/cci-400	\
+				drivers/arm/peripherals/pl011		\
+				lib/semihosting				\
+				lib/stdlib				\
+				drivers/io
+
+PLAT_BL1_S_VPATH	:=	lib/semihosting/${ARCH}
+
+PLAT_BL2_C_VPATH	:=	drivers/arm/interconnect/cci-400	\
+				drivers/arm/peripherals/pl011		\
+				lib/stdlib				\
+				lib/semihosting				\
+				drivers/io
+
+PLAT_BL2_S_VPATH	:=	lib/semihosting/${ARCH}
+
+PLAT_BL31_C_VPATH	:=	drivers/arm/interconnect/cci-400	\
+				drivers/arm/peripherals/pl011		\
+				lib/semihosting				\
+				lib/stdlib				\
+				drivers/power				\
+				drivers/io
+
+PLAT_BL31_S_VPATH	:=	lib/semihosting/${ARCH}
+
+PLAT_BL_COMMON_SOURCES	:=	semihosting_call.S			\
+				mmio.c					\
+				pl011.c					\
+				semihosting.c				\
+				sysreg_helpers.S			\
+				plat_io_storage.c			\
+				io_semihosting.c			\
+				io_fip.c				\
+				io_memmap.c
+
+BL1_SOURCES		+=	bl1_plat_setup.c			\
+				bl1_plat_helpers.S			\
+				plat_helpers.S				\
+				plat_common.c				\
+				cci400.c
+
+BL2_SOURCES		+=	bl2_plat_setup.c			\
+				plat_common.c
+
+BL31_SOURCES		+=	bl31_plat_setup.c			\
+				plat_helpers.S				\
+				plat_common.c				\
+				plat_pm.c				\
+				plat_topology.c				\
+				plat_gic.c				\
+				cci400.c				\
+				gic_v2.c				\
+				gic_v3.c