diff options
author | James King <james.king@arm.com> | 2017-08-01 14:48:53 +0100 |
---|---|---|
committer | Ryan Harkin <ryan.harkin@linaro.org> | 2017-08-01 16:44:44 +0100 |
commit | 9265dd13231c8ae3d53d95a4edc2f0a97f59f9b7 (patch) | |
tree | 3e8ddc47bf3955ed44fb44166aad1278d64b1556 | |
parent | 99e89377ebdcf8b46ae5dcb5f940483760a8a03f (diff) |
ARM Ashbrook Platform SupportashbrookSS-SW-16.4-ashbrook
This patch adds support for the Ashbrook subsystem FVP as released in
the 16.4 Ashbrook software release.
Signed-off-by: James King <james.king@arm.com>
58 files changed, 3402 insertions, 47 deletions
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index c8fd683c1..c315cd8e9 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -39,6 +39,7 @@ #include <platform.h> #include <platform_def.h> #include <stdint.h> +#include <string.h> #include "bl2_private.h" /* @@ -49,6 +50,15 @@ #endif /******************************************************************************* + * List of recognized TEEs + ******************************************************************************/ +#ifdef BL32_BASE +#define TEE_MAGIC_NUM_OPTEE 0x4554504f +static int supported_tee_list[]= {TEE_MAGIC_NUM_OPTEE, + }; +#endif + +/******************************************************************************* * Load the SCP_BL2 image if there's one. * If a platform does not want to attempt to load SCP_BL2 image it must leave * SCP_BL2_BASE undefined. @@ -129,6 +139,40 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params, return e; } + +#ifdef BL32_BASE +/****************************************************************************** + * Determine whether the memory region delimited by 'addr' and 'size' is free, + * given the extents of free memory. + * Return 1 if it is free, 0 otherwise. + *****************************************************************************/ +static int is_mem_in_range(uint64_t free_base, size_t free_size, + uint64_t addr, size_t size) +{ + return (addr >= free_base) && (addr + size <= free_base + free_size); +} + +/****************************************************************************** + * check if it is a valid tee header + * returns 1 if valid + * return 0 if invalid + *****************************************************************************/ +static inline int tee_validate_header(bl32_header_t* bl32_header) +{ + int i; + /* scan through list of supported TEEs */ + for(i=0; i<(sizeof(supported_tee_list)/sizeof(supported_tee_list[0])); i++) + { + if(bl32_header->magic == supported_tee_list[i]) + { + return 1; + } + } + WARN("Not a known TEE, use default loading options \n"); + return 0; +} +#endif + /******************************************************************************* * Load the BL32 image if there's one. * The bl2_to_bl31_params param will be updated with the relevant BL32 @@ -143,6 +187,15 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params) int e = 0; #ifdef BL32_BASE meminfo_t bl32_mem_info; + bl32_header_t* bl32_header ; + uintptr_t init_load_addr; + uintptr_t paged_addr; + size_t init_size; + uintptr_t payload_addr; + uintptr_t paged_part; + size_t payload_paged_size; + size_t payload_arch; + INFO("BL2: Loading BL32\n"); assert(bl2_to_bl31_params != NULL); @@ -152,18 +205,118 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params) * it exists. It could create space in the secure sram or point to a * completely different memory. */ - bl2_plat_get_bl32_meminfo(&bl32_mem_info); + + /* attempt to load directly at target location in TSRAM. + * If that fails, load to TZC protected dram area + */ + bl32_mem_info.total_base = BL32_BASE; + bl32_mem_info.free_base = BL32_BASE; + bl32_mem_info.total_size = BL32_LIMIT-BL32_BASE; + bl32_mem_info.free_size = BL32_LIMIT-BL32_BASE; e = load_auth_image(&bl32_mem_info, - BL32_IMAGE_ID, - BL32_BASE, - bl2_to_bl31_params->bl32_image_info, - bl2_to_bl31_params->bl32_ep_info); + BL32_IMAGE_ID, + BL32_BASE, + bl2_to_bl31_params->bl32_image_info, + bl2_to_bl31_params->bl32_ep_info); + + if (e != 0) { + /* if load fails to tsram, load to large dram carveout area specified by plat */ + bl2_plat_get_bl32_meminfo(&bl32_mem_info); + e = load_auth_image(&bl32_mem_info, + BL32_IMAGE_ID, + BL32_LOAD_BASE, + bl2_to_bl31_params->bl32_image_info, + bl2_to_bl31_params->bl32_ep_info); + + if (e != 0) { + return e; + } + } - if (e == 0) { - bl2_plat_set_bl32_ep_info( - bl2_to_bl31_params->bl32_image_info, - bl2_to_bl31_params->bl32_ep_info); + /* image is loaded, need to separate the paged and non-paged part now */ + bl32_header = (bl32_header_t *) bl2_to_bl31_params->bl32_ep_info->pc; + + /* print the tee header */ + INFO("BL2: BL3-2 ep=0x%x\n", (unsigned int) bl2_to_bl31_params->bl32_ep_info->pc); + INFO("BL2: BL3-2 header info:\n"); + INFO(" magic=0x%x\n", bl32_header->magic); + INFO(" version=0x%x\n", bl32_header->version); + INFO(" arch=0x%x\n", bl32_header->arch); + INFO(" flags=0x%x\n", bl32_header->flags); + INFO(" init_size=0x%x\n", bl32_header->init_size); + INFO(" init_load_addr_hi=0x%x\n", bl32_header->init_load_addr_hi); + INFO(" init_load_addr_lo=0x%x\n", bl32_header->init_load_addr_lo); + INFO(" init_mem_usage=0x%x\n", bl32_header->init_mem_usage); + INFO(" paged_size=0x%x\n", bl32_header->paged_size); + + /* extract info from the payload header, as the header will be overwritten + * when paged part is relocated + */ + + /* need to parse the header only if it is valid */ + if(tee_validate_header(bl32_header)) + { + init_load_addr = ((uint64_t)bl32_header->init_load_addr_hi << 32) | + bl32_header->init_load_addr_lo; + init_size = bl32_header->init_size; + payload_addr = (uintptr_t)(bl32_header + 1); + payload_paged_size = bl32_header->paged_size; + payload_arch = bl32_header->arch; + + /* Check that the requested ram location is within reserved space for bl32 */ + if (!is_mem_in_range(BL32_BASE, (BL32_LIMIT-BL32_BASE), + init_load_addr, init_size)) { + WARN("Failed to reserve memory: %p - %p\n", (void *) init_load_addr, + (void *) (init_load_addr + init_size));{ + return -ENOMEM; + } + } + + /* move the pager to its load address */ + memcpy((void *)init_load_addr, (void *)payload_addr, + init_size); + flush_dcache_range(init_load_addr, init_size); + paged_part = payload_addr + init_size; + + /* if there is a paged part of payload */ + if(0 != payload_paged_size){ + paged_addr = (uint64_t)(((char*)bl32_mem_info.total_base) ); + + /* check boundarries */ + if (!is_mem_in_range(bl32_mem_info.total_base, bl32_mem_info.total_size, + paged_addr, payload_paged_size)) { + WARN("Failed to reserve memory: %p - %p\n", (void *) init_load_addr, + (void *) (init_load_addr + init_size)); + return -ENOMEM; + } + /* move paged part to beginning of DRAM */ + memcpy((void*)paged_addr, (void *)paged_part, + payload_paged_size); + flush_dcache_range(paged_addr, payload_paged_size); + } + + /* change the bl32 entry point to tsram */ + bl2_to_bl31_params->bl32_ep_info->pc = init_load_addr; + /* set optee runtime arch - aarch32/aarch64 */ + if(0 == payload_arch) + bl2_to_bl31_params->bl32_ep_info->args.arg0 = TEE_AARCH32; + else + bl2_to_bl31_params->bl32_ep_info->args.arg0 = TEE_AARCH64; + } + else + { + /* header is not valid, just assume that TEE is placed at the + * right mem location and hope it works. + * This is not as reckless as it sounds, TEE binary is already + * authenticated, so this is not a security hole. This will allow + * TEEs which don't follow the header formatting, a chance to + * still work. + */ } + + bl2_plat_set_bl32_ep_info( + bl2_to_bl31_params->bl32_image_info, + bl2_to_bl31_params->bl32_ep_info); #endif /* BL32_BASE */ return e; diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 0a81c8697..4ce167eb5 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -208,14 +208,28 @@ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) * This function marks the core as awake in the re-distributor and * ensures that the interface is active. *****************************************************************************/ -void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) +void gicv3_rdistif_mark_core_awake(uintptr_t gicd_base, uintptr_t gicr_base) { + unsigned int val = gicd_read_iidr(gicd_base); + /* * The WAKER_PS_BIT should be changed to 0 * only when WAKER_CA_BIT is 1. */ assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); + /* For GIC-600, GICR_PWRR should be initialized */ + if((GICD_GET_IIDR_IMP(val) == GICD_IIDR_IMP_ARM) + && (GICD_GET_IIDR_PID(val) == GICD_IIDR_PID_GIC600) + && (gicr_read_waker(gicr_base) & WAKER_PS_BIT)) { + INFO("Initialize GICR_PWRR for GIC600\n"); + /* Sets the RDPD value to all RDs in the Group */ + gicr_write_pwrr(gicr_base, PWRR_RDAG_BIT); + + /* Wait till the transition is done */ + while(gicr_read_pwrr(gicr_base) & PWRR_RDGPD_BIT); + } + /* Mark the connected core as awake */ gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index d13e2c9c0..79b1a8306 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -182,8 +182,11 @@ void gicv3_rdistif_init(unsigned int proc_num) assert(IS_IN_EL3()); + /* Mark the connected core as awake */ gicr_base = driver_data->rdistif_base_addrs[proc_num]; + gicv3_rdistif_mark_core_awake(driver_data->gicd_base, gicr_base); + /* Set the default attribute of all SGIs and PPIs */ gicv3_ppi_sgi_configure_defaults(gicr_base); @@ -206,7 +209,6 @@ void gicv3_rdistif_init(unsigned int proc_num) ******************************************************************************/ void gicv3_cpuif_enable(unsigned int proc_num) { - uintptr_t gicr_base; unsigned int scr_el3; unsigned int icc_sre_el3; @@ -215,10 +217,6 @@ void gicv3_cpuif_enable(unsigned int proc_num) assert(driver_data->rdistif_base_addrs); assert(IS_IN_EL3()); - /* Mark the connected core as awake */ - gicr_base = driver_data->rdistif_base_addrs[proc_num]; - gicv3_rdistif_mark_core_awake(gicr_base); - /* Disable the legacy interrupt bypass */ icc_sre_el3 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT; diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 1344a885f..f9ee75e20 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -35,6 +35,26 @@ #include <mmio.h> #include <stdint.h> +/* GICD_IIDR bit masks and shifts */ +#define GICD_IIDR_PID_SHIFT 24 +#define GICD_IIDR_VAR_SHIFT 16 +#define GICD_IIDR_REV_SHIFT 12 +#define GICD_IIDR_IMP_SHIFT 0 + +#define GICD_IIDR_PID_MASK 0xff +#define GICD_IIDR_VAR_MASK 0xf +#define GICD_IIDR_REV_MASK 0xf +#define GICD_IIDR_IMP_MASK 0xfff + +#define GICD_IIDR_PID_GIC600 0x2 +#define GICD_IIDR_PID_GIC500 0x0 +#define GICD_IIDR_IMP_ARM 0x43B + +#define GICD_GET_IIDR_IMP(v) ((v >> GICD_IIDR_IMP_SHIFT) \ + & GICD_IIDR_IMP_MASK) +#define GICD_GET_IIDR_PID(v) ((v >> GICD_IIDR_PID_SHIFT) \ + & GICD_IIDR_PID_MASK) + /******************************************************************************* * GICv3 private macro definitions ******************************************************************************/ @@ -132,7 +152,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, unsigned int rdistif_num, uintptr_t gicr_base, mpidr_hash_fn mpidr_to_core_pos); -void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base); +void gicv3_rdistif_mark_core_awake(uintptr_t gicd_base, uintptr_t gicr_base); void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); /******************************************************************************* @@ -198,6 +218,15 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_WAKER, val); } +static inline unsigned int gicr_read_pwrr(uintptr_t base) +{ + return mmio_read_32(base + GICR_PWRR); +} + +static inline void gicr_write_pwrr(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_PWRR, val); +} /******************************************************************************* * GIC Re-distributor functions for accessing entire registers. * Note: The raw register values correspond to multiple interrupt IDs and diff --git a/drivers/arm/tzc/tzc_common_private.c b/drivers/arm/tzc/tzc_common_private.c index 8b1ddf498..9075dc792 100644 --- a/drivers/arm/tzc/tzc_common_private.c +++ b/drivers/arm/tzc/tzc_common_private.c @@ -126,7 +126,8 @@ \ /* Set secure attributes on region 0 */ \ _tzc##fn_name##_write_region_attributes(base, 0, \ - sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ + (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ + (0x1 << TZC_REGION_ATTR_F_EN_SHIFT)); \ \ /***************************************************/ \ /* Specify which non-secure devices have permission*/ \ diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 942843cf1..fa355c995 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -136,6 +136,13 @@ #define FIQ_AARCH32 0xe #define SERROR_AARCH32 0xf +/******************************************************************************* + * constant to indicate tee arch + ******************************************************************************/ +#define TEE_AARCH64 0 +#define TEE_AARCH32 1 + + #ifndef __ASSEMBLY__ #include <cdefs.h> /* For __dead2 */ #include <cassert.h> @@ -286,6 +293,18 @@ typedef struct bl31_params { image_info_t *bl33_image_info; } bl31_params_t; +typedef struct bl32_header { + uint32_t magic; + uint8_t version; + uint8_t arch; + uint16_t flags; + uint32_t init_size; + uint32_t init_load_addr_hi; + uint32_t init_load_addr_lo; + uint32_t init_mem_usage; + uint32_t paged_size; +} bl32_header_t; + /* * Compile time assertions related to the 'entry_point_info' structure to diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index b7ad7785b..6260a7b64 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -101,6 +101,7 @@ #define GICR_CTLR 0x0 #define GICR_TYPER 0x08 #define GICR_WAKER 0x14 +#define GICR_PWRR 0x24 #define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + 0x80) #define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + 0x100) #define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + 0x180) @@ -135,6 +136,12 @@ #define TYPER_LAST_BIT (1 << TYPER_LAST_SHIFT) +/* GICR_PWRR bit definitions */ +#define PWRR_RDGPD_SHIFT 2 +#define PWRR_RDAG_SHIFT 1 + +#define PWRR_RDGPD_BIT (1 << PWRR_RDGPD_SHIFT) +#define PWRR_RDAG_BIT (1 << PWRR_RDAG_SHIFT) /******************************************************************************* * GICv3 CPU interface registers & constants ******************************************************************************/ diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index fb8cbc0b1..58a57ec67 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -47,6 +47,7 @@ /******************************************************************************* * MPIDR macros ******************************************************************************/ +#define MPIDR_MT_MASK 0x1000000 #define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK #define MPIDR_CLUSTER_MASK MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS #define MPIDR_AFFINITY_BITS 8 @@ -408,4 +409,10 @@ #define CNTACR_RWVT_SHIFT 0x4 #define CNTACR_RWPT_SHIFT 0x5 +/* Definitions of the System registers for armv8.2 */ +#define CPUPWRCTLR_EL1 S3_0_C15_C2_7 /* CPU power control */ + +/* Definitions of register field mask in CPUPWR_CTLR_EL1 */ +#define CORE_PWRDN_EN_MASK 0x1 + #endif /* __ARCH_H__ */ diff --git a/include/lib/cpus/aarch64/ananke.h b/include/lib/cpus/aarch64/ananke.h new file mode 100644 index 000000000..5bd070ea5 --- /dev/null +++ b/include/lib/cpus/aarch64/ananke.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, 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 __ANANKE_H__ +#define __ANANKE_H__ + +/* ANANKE midr for revision 0 */ +#define ANANKE_MIDR (0x410FD050) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define CPUECTLR_EL1 S3_0_C15_C1_4 /* Instruction def. */ + +#endif /* __ANANKE_H__ */ diff --git a/include/lib/cpus/aarch64/artemis.h b/include/lib/cpus/aarch64/artemis.h new file mode 100644 index 000000000..39d3ce3de --- /dev/null +++ b/include/lib/cpus/aarch64/artemis.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 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 __ARTEMIS_H__ +#define __ARTEMIS_H__ + +/* Artemis midr for revision 0 */ +#define ARTEMIS_MIDR (0x410FD090) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define CPUECTLR_EL1 S3_1_C15_C2_1 /* Instruction def. */ + +#define CPUECTLR_SMP_BIT (1 << 6) + +#endif /* __ARTEMIS_H__ */ diff --git a/include/lib/cpus/aarch64/prometheus.h b/include/lib/cpus/aarch64/prometheus.h new file mode 100644 index 000000000..f63634c1c --- /dev/null +++ b/include/lib/cpus/aarch64/prometheus.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, 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 __PROMETHEUS_H__ +#define __PROMETHEUS_H__ + +/* prometheus midr */ +#define PROMETHEUS_MIDR (0x410FD0A0) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define CPUECTLR_EL1 S3_0_C15_C1_4 /* Instruction def. */ + +#endif /* __PROMETHEUS_H__ */ diff --git a/include/lib/xlat_tables.h b/include/lib/xlat_tables.h index d2ac6db68..1e3e4ecb5 100644 --- a/include/lib/xlat_tables.h +++ b/include/lib/xlat_tables.h @@ -102,6 +102,11 @@ * enabling the MMU. */ #define DISABLE_DCACHE (1 << 0) +#define TCR_MT_SHIFT 1 +#define TCR_MT_MASK (0x7 << TCR_MT_SHIFT) +#define TCR_MT(_flags) ((_flags) & TCR_MT_MASK) +#define TCR_MT_DEFAULT (0 << TCR_MT_SHIFT) +#define TCR_MT_NON_CACHEABLE (1 << TCR_MT_SHIFT) #ifndef __ASSEMBLY__ #include <stddef.h> diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 4a4dfd40b..46a327c1a 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -105,7 +105,32 @@ ARM_SCP_TZC_DRAM1_SIZE) #define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \ ARM_AP_TZC_DRAM1_SIZE - 1) - +/* +* create a 16 MB carveout from ARM_AP_TZC_DRAM1_BASE for bl32 +*/ +#define BL32_RUNTIME_MEM_SIZE MAKE_ULL(0x1000000) +#define BL32_PAGED_PAYLOAD_SIZE MAKE_ULL(0x100000) + +#define BL32_RUNTIME_MEM_BASE ARM_AP_TZC_DRAM1_BASE +#define BL32_RUNTIME_MEM_LIMIT (BL32_RUNTIME_MEM_BASE + \ + BL32_RUNTIME_MEM_SIZE) +/* + * paged size would be much smaller than 1 MB, however it is part of the + * BL32 runtime mem and should be reclaimed by TEE after bootstrapping + * of paged part +*/ +#define BL32_PAGED_PAYLOAD_BASE (BL32_RUNTIME_MEM_BASE + \ + BL32_RUNTIME_MEM_SIZE - \ + BL32_PAGED_PAYLOAD_SIZE) + +#define BL32_PAGED_PAYLOAD_LIMIT (BL32_PAGED_PAYLOAD_BASE + \ + BL32_PAGED_PAYLOAD_SIZE) + +#define ARM_MAP_TSP_SEC_PAGED_PAYLOAD_MEM MAP_REGION_FLAT( \ + BL32_PAGED_PAYLOAD_BASE,\ + BL32_PAGED_PAYLOAD_SIZE,\ + MT_MEMORY | MT_RW | \ + MT_SECURE) #define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE #define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ @@ -305,18 +330,31 @@ # define TSP_PROGBITS_LIMIT BL2_BASE # define BL32_BASE ARM_BL_RAM_BASE # define BL32_LIMIT BL31_BASE +# define PAGED_BL32_BASE BL32_PAGED_PAYLOAD_BASE +# define PAGED_BL32_SIZE BL32_PAGED_PAYLOAD_SIZE +# define PAGED_BL32_LIMIT BL32_PAGED_PAYLOAD_LIMIT +# define BL32_LOAD_BASE PAGED_BL32_BASE +# define BL32_LOAD_SIZE PAGED_BL32_SIZE + #elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID # define TSP_SEC_MEM_BASE PLAT_ARM_TRUSTED_DRAM_BASE # define TSP_SEC_MEM_SIZE PLAT_ARM_TRUSTED_DRAM_SIZE # define BL32_BASE PLAT_ARM_TRUSTED_DRAM_BASE # define BL32_LIMIT (PLAT_ARM_TRUSTED_DRAM_BASE \ + (1 << 21)) +# define BL32_LOAD_BASE BL32_BASE +# define BL32_LOAD_SIZE (BL32_LIMIT - BL32_BASE) #elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID # define TSP_SEC_MEM_BASE ARM_AP_TZC_DRAM1_BASE # define TSP_SEC_MEM_SIZE ARM_AP_TZC_DRAM1_SIZE -# define BL32_BASE ARM_AP_TZC_DRAM1_BASE -# define BL32_LIMIT (ARM_AP_TZC_DRAM1_BASE + \ - ARM_AP_TZC_DRAM1_SIZE) +# define BL32_BASE BL32_RUNTIME_MEM_BASE +# define BL32_LIMIT BL32_RUNTIME_MEM_LIMIT +# define BL32_LOAD_BASE BL32_BASE +# define BL32_LOAD_SIZE (BL32_LIMIT - \ + BL32_BASE) +# define PAGED_BL32_BASE MAKE_ULL(0) +# define PAGED_BL32_SIZE MAKE_ULL(0) +# define PAGED_BL32_LIMIT MAKE_ULL(0) #else # error "Unsupported ARM_TSP_RAM_LOCATION_ID value" #endif diff --git a/lib/cpus/aarch64/ananke.S b/lib/cpus/aarch64/ananke.S new file mode 100644 index 000000000..8f775dd0e --- /dev/null +++ b/lib/cpus/aarch64/ananke.S @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, 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 <ananke.h> +#include <arch.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <cpu_macros.S> +#include <plat_macros.S> + +func ananke_reset_func + /* --------------------------------------------- + * Disable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + bic x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + ret +endfunc ananke_reset_func + + /* --------------------------------------------- + * HW will do the cache maintenance while powering down + * --------------------------------------------- + */ +func ananke_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + orr x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + ret +endfunc ananke_core_pwr_dwn + +func ananke_cluster_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Disable the optional ACP. + * --------------------------------------------- + */ + bl plat_disable_acp + + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + orr x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + + mov x30, x18 + ret +endfunc ananke_cluster_pwr_dwn + + /* --------------------------------------------- + * This function provides ananke specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ascii and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.ananke_regs, "aS" +ananke_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func ananke_cpu_reg_dump + adr x6, ananke_regs + mrs x8, CPUECTLR_EL1 + ret +endfunc ananke_cpu_reg_dump + +declare_cpu_ops ananke, ANANKE_MIDR diff --git a/lib/cpus/aarch64/artemis.S b/lib/cpus/aarch64/artemis.S new file mode 100644 index 000000000..b035cb875 --- /dev/null +++ b/lib/cpus/aarch64/artemis.S @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015, 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 <artemis.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <cpu_macros.S> +#include <plat_macros.S> + + /* --------------------------------------------- + * Disable L1 data cache + * --------------------------------------------- + */ +func artemis_disable_dcache + mrs x1, sctlr_el3 + bic x1, x1, #SCTLR_C_BIT + msr sctlr_el3, x1 + isb + ret +endfunc artemis_disable_dcache + + /* --------------------------------------------- + * Disable intra-cluster coherency + * --------------------------------------------- + */ +func artemis_disable_smp + mrs x0, CPUECTLR_EL1 + bic x0, x0, #CPUECTLR_SMP_BIT + msr CPUECTLR_EL1, x0 + isb + dsb sy + ret +endfunc artemis_disable_smp + +func artemis_reset_func + /* --------------------------------------------- + * As a bare minimum enable the SMP bit if it is + * not already set. + * Clobbers : x0 + * --------------------------------------------- + */ + mrs x0, CPUECTLR_EL1 + tst x0, #CPUECTLR_SMP_BIT + b.ne skip_smp_setup + orr x0, x0, #CPUECTLR_SMP_BIT + msr CPUECTLR_EL1, x0 + isb +skip_smp_setup: + ret +endfunc artemis_reset_func + +func artemis_core_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl artemis_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + /* --------------------------------------------- + * Come out of intra cluster coherency + * --------------------------------------------- + */ + mov x30, x18 + b artemis_disable_smp +endfunc artemis_core_pwr_dwn + +func artemis_cluster_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl artemis_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + /* --------------------------------------------- + * Disable the optional ACP. + * --------------------------------------------- + */ + bl plat_disable_acp + + /* --------------------------------------------- + * Flush L2 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level2 + + /* --------------------------------------------- + * Come out of intra cluster coherency + * --------------------------------------------- + */ + mov x30, x18 + b artemis_disable_smp +endfunc artemis_cluster_pwr_dwn + + /* --------------------------------------------- + * This function provides artemis specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ascii and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.artemis_regs, "aS" +artemis_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func artemis_cpu_reg_dump + adr x6, artemis_regs + mrs x8, CPUECTLR_EL1 + ret +endfunc artemis_cpu_reg_dump + +declare_cpu_ops artemis, ARTEMIS_MIDR diff --git a/lib/cpus/aarch64/prometheus.S b/lib/cpus/aarch64/prometheus.S new file mode 100644 index 000000000..7b60304cf --- /dev/null +++ b/lib/cpus/aarch64/prometheus.S @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, 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 <cpu_macros.S> +#include <plat_macros.S> +#include <prometheus.h> + +func prometheus_reset_func + /* --------------------------------------------- + * Disable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + bic x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + ret +endfunc prometheus_reset_func + + /* --------------------------------------------- + * HW will do the cache maintenance while powering down + * --------------------------------------------- + */ +func prometheus_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + orr x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + ret +endfunc prometheus_core_pwr_dwn + +func prometheus_cluster_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Disable the optional ACP. + * --------------------------------------------- + */ + bl plat_disable_acp + + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CPUPWRCTLR_EL1 + orr x0, x0, #CORE_PWRDN_EN_MASK + msr CPUPWRCTLR_EL1, x0 + isb + + mov x30, x18 + ret +endfunc prometheus_cluster_pwr_dwn + + /* --------------------------------------------- + * This function provides prometheus specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ascii and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.prometheus_regs, "aS" +prometheus_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func prometheus_cpu_reg_dump + adr x6, prometheus_regs + mrs x8, CPUECTLR_EL1 + ret +endfunc prometheus_cpu_reg_dump + +declare_cpu_ops prometheus, PROMETHEUS_MIDR diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index 20d06352c..3755a812b 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2015, 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: diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index 5b639b7af..a7b7b98be 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -161,11 +161,20 @@ void init_xlat_tables(void) _tlbi_fct(); \ \ /* Set TCR bits as well. */ \ - /* Inner & outer WBWA & shareable. */ \ - /* Set T0SZ to (64 - width of virtual address space) */ \ - tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | \ - TCR_RGN_INNER_WBA | \ - (64 - __builtin_ctzl(ADDR_SPACE_SIZE)); \ + /* T0SZ = 32 */ \ + if (TCR_MT(flags) == TCR_MT_DEFAULT) { \ + /* Inner & outer WBWA & shareable */ \ + tcr = TCR_SH_INNER_SHAREABLE | \ + TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA | \ + (64 - __builtin_ctzl(ADDR_SPACE_SIZE)); \ + } else { \ + /* Inner & outer non-cacheable non-shareable */ \ + assert(TCR_MT(flags) == TCR_MT_NON_CACHEABLE); \ + tcr = TCR_SH_NON_SHAREABLE | \ + TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC | \ + (64 - __builtin_ctzl(ADDR_SPACE_SIZE)); \ + } \ + \ tcr |= _tcr_extra; \ write_tcr_el##_el(tcr); \ \ diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c index 69b744d97..3928b2dbe 100644 --- a/plat/arm/board/common/board_css_common.c +++ b/plat/arm/board/common/board_css_common.c @@ -57,6 +57,7 @@ const mmap_region_t plat_arm_mmap[] = { SOC_CSS_MAP_DEVICE, ARM_MAP_NS_DRAM1, ARM_MAP_TSP_SEC_MEM, + ARM_MAP_TSP_SEC_PAGED_PAYLOAD_MEM, {0} }; #endif diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index fbbe34e60..b17df3c48 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -116,6 +116,7 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_IOFPGA, MAP_DEVICE0, MAP_DEVICE1, + ARM_MAP_TSP_SEC_PAGED_PAYLOAD_MEM, {0} }; #endif diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 2865569aa..31d86dc3b 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -108,7 +108,8 @@ FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ - lib/cpus/aarch64/cortex_a73.S + lib/cpus/aarch64/cortex_a73.S \ + lib/cpus/aarch64/artemis.S endif BL1_SOURCES += drivers/io/io_semihosting.c \ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index c53e938fd..1ca326393 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -88,8 +88,8 @@ #endif #if IMAGE_BL2 -# define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 3 +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 4 #endif #if IMAGE_BL2U diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index b6afaa7f5..32aeeb18a 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -289,12 +289,10 @@ void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) /* * Populate the extents of memory available for loading BL32. */ - 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; + bl32_meminfo->total_base = BL32_LOAD_BASE; + bl32_meminfo->free_base = BL32_LOAD_BASE; + bl32_meminfo->total_size = BL32_LOAD_SIZE; + bl32_meminfo->free_size = BL32_LOAD_SIZE; } #endif /* BL32_BASE */ diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c index 40cfb480d..649e69a28 100644 --- a/plat/arm/common/arm_cci.c +++ b/plat/arm/common/arm_cci.c @@ -61,7 +61,12 @@ void plat_arm_interconnect_init(void) *****************************************************************************/ void plat_arm_interconnect_enter_coherency(void) { - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); + uint64_t mpidr = read_mpidr_el1(); + + if (mpidr & MPIDR_MT_MASK) + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL2_VAL(mpidr)); + else + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); } /****************************************************************************** @@ -69,5 +74,10 @@ void plat_arm_interconnect_enter_coherency(void) *****************************************************************************/ void plat_arm_interconnect_exit_coherency(void) { - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); + uint64_t mpidr = read_mpidr_el1(); + + if (mpidr & MPIDR_MT_MASK) + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL2_VAL(mpidr)); + else + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); } diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c index 2636d1c90..fa1be87f3 100644 --- a/plat/arm/common/arm_gicv2.c +++ b/plat/arm/common/arm_gicv2.c @@ -52,6 +52,11 @@ static const unsigned int g0_interrupt_array[] = { PLAT_ARM_G0_IRQS }; +/* + * Ideally `arm_gic_data` structure definition should be a `const` but it is + * kept as modifiable for overwriting with different GICD and GICC base when + * running on FVP with VE memory map. + */ static const gicv2_driver_data_t arm_gic_data = { .gicd_base = PLAT_ARM_GICD_BASE, .gicc_base = PLAT_ARM_GICC_BASE, diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index ac309f2b6..3009dab88 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -57,7 +57,7 @@ static const unsigned int g0_interrupt_array[] = { PLAT_ARM_G0_IRQS }; -const gicv3_driver_data_t arm_gic_data = { +static const gicv3_driver_data_t arm_gic_data = { .gicd_base = PLAT_ARM_GICD_BASE, .gicr_base = PLAT_ARM_GICR_BASE, .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array), diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c index 4430b1399..cd68380b9 100644 --- a/plat/arm/common/arm_topology.c +++ b/plat/arm/common/arm_topology.c @@ -40,15 +40,23 @@ int arm_check_mpidr(u_register_t mpidr) { unsigned int cluster_id, cpu_id; + uint64_t valid_mask; - mpidr &= MPIDR_AFFINITY_MASK; + if (read_mpidr_el1() & MPIDR_MT_MASK) { + valid_mask = ~(MPIDR_AFFLVL_MASK | + (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | + (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)); + cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + } else { + valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK); + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + } - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + if (mpidr & valid_mask) return -1; - cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; - if (cluster_id >= PLAT_ARM_CLUSTER_COUNT) return -1; diff --git a/plat/arm/rdd/common/aarch64/css_helpers.S b/plat/arm/rdd/common/aarch64/css_helpers.S new file mode 100644 index 000000000..0763a3ec2 --- /dev/null +++ b/plat/arm/rdd/common/aarch64/css_helpers.S @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2016, 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 <cpu_macros.S> +#include <css_def.h> + + .weak plat_secondary_cold_boot_setup + .weak plat_get_my_entrypoint + .globl css_calc_core_pos_swap_cluster + .weak plat_is_my_cpu_primary + + /* --------------------------------------------------------------------- + * void plat_secondary_cold_boot_setup(void); + * + * In the normal boot flow, cold-booting secondary CPUs is not yet + * implemented and they panic. + * + * When booting an EL3 payload, secondary CPUs are placed in a holding + * pen, waiting for their mailbox to be populated. Note that all CPUs + * share the same mailbox ; therefore, populating it will release all + * CPUs from their holding pen. If finer-grained control is needed then + * this should be handled in the code that secondary CPUs jump to. + * --------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup +#ifndef EL3_PAYLOAD_BASE + /* TODO: Implement secondary CPU cold boot setup on CSS platforms */ +cb_panic: + b cb_panic +#else + mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE + + /* Wait until the mailbox gets populated */ +poll_mailbox: + ldr x1, [x0] + cbz x1, 1f + br x1 +1: + wfe + b poll_mailbox +#endif /* EL3_PAYLOAD_BASE */ +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and a warm + * boot. On CSS platforms, this distinction is based on the contents of + * the Trusted Mailbox. It is initialised to zero by the SCP before the + * AP cores are released from reset. Therefore, a zero mailbox means + * it's a cold reset. + * + * This functions returns the contents of the mailbox, i.e.: + * - 0 for a cold boot; + * - the warm boot entrypoint for a warm boot. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE + ldr x0, [x0] + ret +endfunc plat_get_my_entrypoint + + /* ----------------------------------------------------------- + * unsigned int css_calc_core_pos_swap_cluster(uint64_t mpidr) + * Utility function to calculate the core position by + * swapping the cluster order. This is necessary in order to + * match the format of the boot information passed by the SCP + * and read in plat_is_my_cpu_primary below. + * ----------------------------------------------------------- + */ +func css_calc_core_pos_swap_cluster + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) // swap cluster order + add x0, x1, x0, LSR #6 + ret +endfunc css_calc_core_pos_swap_cluster + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu (applicable ony after a cold boot) + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mov x9, x30 + bl plat_my_core_pos + ldr x1, =SCP_BOOT_CFG_ADDR + ldr x1, [x1] + ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \ + #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH + cmp x0, x1 + cset w0, eq + ret x9 +endfunc plat_is_my_cpu_primary diff --git a/plat/arm/rdd/common/aarch64/css_macros.S b/plat/arm/rdd/common/aarch64/css_macros.S new file mode 100644 index 000000000..518867bd1 --- /dev/null +++ b/plat/arm/rdd/common/aarch64/css_macros.S @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 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 __CSS_MACROS_S__ +#define __CSS_MACROS_S__ + +#include <arm_macros.S> +#include <platform_def.h> + + /* --------------------------------------------- + * The below required platform porting macro + * prints out relevant GIC registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro css_print_gic_regs + mov_imm x16, PLAT_ARM_GICD_BASE + mov_imm x17, PLAT_ARM_GICC_BASE + arm_print_gic_regs + .endm + + +#endif /* __CSS_MACROS_S__ */ diff --git a/plat/arm/rdd/common/css_bl1_setup.c b/plat/arm/rdd/common/css_bl1_setup.c new file mode 100644 index 000000000..2abed3b92 --- /dev/null +++ b/plat/arm/rdd/common/css_bl1_setup.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, 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 <bl_common.h> +#include <debug.h> +#include <plat_arm.h> +#include <soc_css.h> + +void bl1_platform_setup(void) +{ + arm_bl1_platform_setup(); + /* + * Do ARM CSS SoC security setup. + * BL1 needs to enable normal world access to memory. + */ + soc_css_security_setup(); +} + diff --git a/plat/arm/rdd/common/css_bl2_setup.c b/plat/arm/rdd/common/css_bl2_setup.c new file mode 100644 index 000000000..15db8d1c2 --- /dev/null +++ b/plat/arm/rdd/common/css_bl2_setup.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015, 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 <bl_common.h> +#include <css_def.h> +#include <debug.h> +#include <mmio.h> +#include <plat_arm.h> +#include <string.h> +#include "css_scp_bootloader.h" + +/* Weak definition may be overridden in specific CSS based platform */ +#pragma weak bl2_plat_handle_scp_bl2 + +/******************************************************************************* + * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. + * Return 0 on success, -1 otherwise. + ******************************************************************************/ +int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + int ret; + + INFO("BL2: Initiating SCP_BL2 transfer to SCP\n"); + + ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base, + scp_bl2_image_info->image_size); + + if (ret == 0) + INFO("BL2: SCP_BL2 transferred to SCP\n"); + else + ERROR("BL2: SCP_BL2 transfer failure\n"); + + return ret; +} + +#ifdef EL3_PAYLOAD_BASE +/* + * We need to override some of the platform functions when booting an EL3 + * payload. + */ + +static unsigned int scp_boot_config; + +void bl2_early_platform_setup(meminfo_t *mem_layout) +{ + arm_bl2_early_platform_setup(mem_layout); + + /* Save SCP Boot config before it gets overwritten by SCP_BL2 loading */ + scp_boot_config = mmio_read_32(SCP_BOOT_CFG_ADDR); + VERBOSE("BL2: Saved SCP Boot config = 0x%x\n", scp_boot_config); +} + +void bl2_platform_setup(void) +{ + arm_bl2_platform_setup(); + + /* + * Before releasing the AP cores out of reset, the SCP writes some data + * at the beginning of the Trusted SRAM. It is is overwritten before + * reaching this function. We need to restore this data, as if the + * target had just come out of reset. This implies: + * - zeroing the first 128 bytes of Trusted SRAM; + * - restoring the SCP boot configuration. + */ + VERBOSE("BL2: Restoring SCP reset data in Trusted SRAM\n"); + memset((void *) ARM_TRUSTED_SRAM_BASE, 0, 128); + mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config); +} +#endif /* EL3_PAYLOAD_BASE */ diff --git a/plat/arm/rdd/common/css_bl2u_setup.c b/plat/arm/rdd/common/css_bl2u_setup.c new file mode 100644 index 000000000..878b6faf8 --- /dev/null +++ b/plat/arm/rdd/common/css_bl2u_setup.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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 <bl_common.h> +#include <debug.h> +#include <plat_arm.h> +#include "css_scp_bootloader.h" + +/* Weak definition may be overridden in specific CSS based platform */ +#pragma weak bl2u_plat_handle_scp_bl2u + +/* Data structure which holds the SCP_BL2U image info for BL2U */ +static image_info_t scp_bl2u_image_info; + +/******************************************************************************* + * BL1 can pass platform dependent information to BL2U in x1. + * In case of ARM CSS platforms x1 contains SCP_BL2U image info. + * In case of ARM FVP platforms x1 is not used. + * In both cases, x0 contains the extents of the memory available to BL2U + ******************************************************************************/ +void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info) +{ + if (!plat_info) + panic(); + + arm_bl2u_early_platform_setup(mem_layout, plat_info); + + scp_bl2u_image_info = *(image_info_t *)plat_info; +} + +/******************************************************************************* + * Transfer SCP_BL2U from Trusted RAM using the SCP Download protocol. + ******************************************************************************/ +int bl2u_plat_handle_scp_bl2u(void) +{ + int ret; + + INFO("BL2U: Initiating SCP_BL2U transfer to SCP\n"); + + ret = scp_bootloader_transfer((void *)scp_bl2u_image_info.image_base, + scp_bl2u_image_info.image_size); + + if (ret == 0) + INFO("BL2U: SCP_BL2U transferred to SCP\n"); + else + ERROR("BL2U: SCP_BL2U transfer failure\n"); + + return ret; +} diff --git a/plat/arm/rdd/common/css_common.mk b/plat/arm/rdd/common/css_common.mk new file mode 100644 index 000000000..60da89a53 --- /dev/null +++ b/plat/arm/rdd/common/css_common.mk @@ -0,0 +1,84 @@ +# +# Copyright (c) 2015-2016, 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. +# + + +# By default, SCP images are needed by CSS platforms. +CSS_COMMON_BASE := plat/arm/rdd/common + +CSS_LOAD_SCP_IMAGES ?= 1 + +PLAT_INCLUDES += -I${CSS_COMMON_BASE}/include \ + -I${CSS_COMMON_BASE}/aarch64 + + +PLAT_BL_COMMON_SOURCES += ${CSS_COMMON_BASE}/aarch64/css_helpers.S + +BL1_SOURCES += ${CSS_COMMON_BASE}/css_bl1_setup.c + +BL2_SOURCES += ${CSS_COMMON_BASE}/css_bl2_setup.c \ + ${CSS_COMMON_BASE}/css_mhu.c \ + ${CSS_COMMON_BASE}/css_scpi.c + +BL2U_SOURCES += ${CSS_COMMON_BASE}/css_bl2u_setup.c \ + ${CSS_COMMON_BASE}/css_mhu.c \ + ${CSS_COMMON_BASE}/css_scpi.c + +BL31_SOURCES += ${CSS_COMMON_BASE}/css_mhu.c \ + ${CSS_COMMON_BASE}/css_pm.c \ + ${CSS_COMMON_BASE}/css_scpi.c \ + ${CSS_COMMON_BASE}/css_topology.c + + +ifneq (${RESET_TO_BL31},0) + $(error "Using BL31 as the reset vector is not supported on CSS platforms. \ + Please set RESET_TO_BL31 to 0.") +endif + +# Process CSS_LOAD_SCP_IMAGES flag +$(eval $(call assert_boolean,CSS_LOAD_SCP_IMAGES)) +$(eval $(call add_define,CSS_LOAD_SCP_IMAGES)) + +ifeq (${CSS_LOAD_SCP_IMAGES},1) + $(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw)) + ifneq (${TRUSTED_BOARD_BOOT},0) + $(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg)) + endif + + BL2U_SOURCES += ${CSS_COMMON_BASE}/css_scp_bootloader.c + BL2_SOURCES += ${CSS_COMMON_BASE}/css_scp_bootloader.c +endif + +# Enable option to detect whether the SCP ROM firmware in use predates version +# 1.7.0 and therefore, is incompatible. +CSS_DETECT_PRE_1_7_0_SCP := 1 + +# Process CSS_DETECT_PRE_1_7_0_SCP flag +$(eval $(call assert_boolean,CSS_DETECT_PRE_1_7_0_SCP)) +$(eval $(call add_define,CSS_DETECT_PRE_1_7_0_SCP)) diff --git a/plat/arm/rdd/common/css_mhu.c b/plat/arm/rdd/common/css_mhu.c new file mode 100644 index 000000000..265d6c25c --- /dev/null +++ b/plat/arm/rdd/common/css_mhu.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014-2016, 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 <bakery_lock.h> +#include <css_def.h> +#include <mmio.h> +#include <platform_def.h> +#include <plat_arm.h> +#include "css_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 + +ARM_INSTANTIATE_LOCK + +/* Weak definition may be overridden in specific CSS based platform */ +#pragma weak plat_arm_pwrc_setup + + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + arm_lock_get(); + + /* Make sure any previous command has finished */ + while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id)) + ; +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))); + + /* Send command to SCP */ + mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response; + while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) + ; + + return response; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); + + arm_lock_release(); +} + +void mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); +} + +void plat_arm_pwrc_setup(void) +{ + mhu_secure_init(); +} diff --git a/plat/arm/rdd/common/css_pm.c b/plat/arm/rdd/common/css_pm.c new file mode 100644 index 000000000..1ae3d348b --- /dev/null +++ b/plat/arm/rdd/common/css_pm.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2015-2016, 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 <cassert.h> +#include <css_pm.h> +#include <debug.h> +#include <errno.h> +#include <plat_arm.h> +#include <platform.h> +#include <platform_def.h> +#include "css_scpi.h" + +/* Macros to read the CSS power domain state */ +#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0] +#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1] +#define CSS_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) ?\ + (state)->pwr_domain_state[ARM_PWR_LVL2] : 0) + +/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */ +#pragma weak plat_arm_psci_pm_ops + +#if ARM_RECOM_STATE_ID_ENC +/* + * The table storing the valid idle power states. Ensure that the + * array entries are populated in ascending order of state-id to + * enable us to use binary search during power state validation. + * The table must be terminated by a NULL entry. + */ +const unsigned int arm_pm_idle_states[] = { + /* State-id - 0x001 */ + arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RUN, + ARM_LOCAL_STATE_RET, ARM_PWR_LVL0, PSTATE_TYPE_STANDBY), + /* State-id - 0x002 */ + arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RUN, + ARM_LOCAL_STATE_OFF, ARM_PWR_LVL0, PSTATE_TYPE_POWERDOWN), + /* State-id - 0x022 */ + arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_OFF, + ARM_LOCAL_STATE_OFF, ARM_PWR_LVL1, PSTATE_TYPE_POWERDOWN), +#if PLAT_MAX_PWR_LVL > ARM_PWR_LVL1 + /* State-id - 0x222 */ + arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF, + ARM_LOCAL_STATE_OFF, ARM_PWR_LVL2, PSTATE_TYPE_POWERDOWN), +#endif + 0, +}; +#endif /* __ARM_RECOM_STATE_ID_ENC__ */ + +/* + * All the power management helpers in this file assume at least cluster power + * level is supported. + */ +CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1, + assert_max_pwr_lvl_supported_mismatch); + +/******************************************************************************* + * Handler called when a power domain is about to be turned on. The + * level and mpidr determine the affinity instance. + ******************************************************************************/ +int css_pwr_domain_on(u_register_t mpidr) +{ + /* + * SCP takes care of powering up parent power domains so we + * only need to care about level 0 + */ + scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); + + return PSCI_E_SUCCESS; +} + +static void css_pwr_domain_on_finisher_common( + const psci_power_state_t *target_state) +{ + assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF); + + /* + * Perform the common cluster specific operations i.e enable coherency + * if this cluster was off. + */ + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { + if (GET_PLAT_PART_NUM != CERNAN_SSC_VER_PART_NUM) + plat_arm_interconnect_enter_coherency(); + } +} + +/******************************************************************************* + * Handler called when a power level has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. This handler would never be invoked with + * the system power domain uninitialized as either the primary would have taken + * care of it as part of cold boot or the first core awakened from system + * suspend would have already initialized it. + ******************************************************************************/ +void css_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* Assert that the system power domain need not be initialized */ + assert(CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_RUN); + + css_pwr_domain_on_finisher_common(target_state); + + /* Program the gic per-cpu distributor or re-distributor interface */ + plat_arm_gic_pcpu_init(); + + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); +} + +/******************************************************************************* + * Common function called while turning a cpu off or suspending it. It is called + * from css_off() or css_suspend() when these functions in turn are called for + * power domain at the highest power level which will be powered down. It + * performs the actions common to the OFF and SUSPEND calls. + ******************************************************************************/ +static void css_power_down_common(const psci_power_state_t *target_state) +{ + uint32_t cluster_state = scpi_power_on; + uint32_t system_state = scpi_power_on; + + /* Prevent interrupts from spuriously waking up this cpu */ + plat_arm_gic_cpuif_disable(); + + /* Check if power down at system power domain level is requested */ + if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) + system_state = scpi_power_retention; + + /* Cluster is to be turned off, so disable coherency */ + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { + if (GET_PLAT_PART_NUM != CERNAN_SSC_VER_PART_NUM) + plat_arm_interconnect_exit_coherency(); + cluster_state = scpi_power_off; + } + + /* + * Ask the SCP to power down the appropriate components depending upon + * their state. + */ + scpi_set_css_power_state(read_mpidr_el1(), + scpi_power_off, + cluster_state, + system_state); +} + +/* CPU dynamic power off function for Ashbrook */ +static void css_power_down_suspend(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_arm_gic_cpuif_disable(); + + /* Cluster is to be turned off, so disable coherency */ + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { + if (GET_PLAT_PART_NUM != CERNAN_SSC_VER_PART_NUM) + plat_arm_interconnect_exit_coherency(); + } +} + +/******************************************************************************* + * Handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +void css_pwr_domain_off(const psci_power_state_t *target_state) +{ + assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF); + css_power_down_common(target_state); +} + +/******************************************************************************* + * Handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +void css_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + /* + * CSS currently supports retention only at cpu level. Just return + * as nothing is to be done for retention. + */ + if (CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET) + return; + + assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF); + if (GET_PLAT_PART_NUM == ASHBROOK_SSC_VER_PART_NUM) + css_power_down_suspend(target_state); + else + css_power_down_common(target_state); +} + +/******************************************************************************* + * Handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ******************************************************************************/ +void css_pwr_domain_suspend_finish( + const psci_power_state_t *target_state) +{ + /* Return as nothing is to be done on waking up from retention. */ + if (CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET) + return; + + /* Perform system domain restore if woken up from system suspend */ + if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) + arm_system_pwr_domain_resume(); + else + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); + + css_pwr_domain_on_finisher_common(target_state); +} + +/******************************************************************************* + * Handlers to shutdown/reboot the system + ******************************************************************************/ +void __dead2 css_system_off(void) +{ + uint32_t response; + + /* Send the power down request to the SCP */ + response = scpi_sys_power_state(scpi_system_shutdown); + + if (response != SCP_OK) { + ERROR("CSS System Off: SCP error %u.\n", response); + panic(); + } + wfi(); + ERROR("CSS System Off: operation not handled.\n"); + panic(); +} + +void __dead2 css_system_reset(void) +{ + uint32_t response; + + /* Send the system reset request to the SCP */ + response = scpi_sys_power_state(scpi_system_reboot); + + if (response != SCP_OK) { + ERROR("CSS System Reset: SCP error %u.\n", response); + panic(); + } + wfi(); + ERROR("CSS System Reset: operation not handled.\n"); + panic(); +} + +/******************************************************************************* + * Handler called when the CPU power domain is about to enter standby. + ******************************************************************************/ +void css_cpu_standby(plat_local_state_t cpu_state) +{ + unsigned int scr; + + assert(cpu_state == ARM_LOCAL_STATE_RET); + + scr = read_scr_el3(); + /* + * Enable the Non secure interrupt to wake the CPU. + * In GICv3 affinity routing mode, the non secure group1 interrupts use + * the PhysicalFIQ at EL3 whereas in GICv2, it uses the PhysicalIRQ. + * Enabling both the bits works for both GICv2 mode and GICv3 affinity + * routing mode. + */ + write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); + isb(); + dsb(); + wfi(); + + /* + * Restore SCR to the original value, synchronisation of scr_el3 is + * done by eret while el3_exit to save some execution cycles. + */ + write_scr_el3(scr); +} + +/******************************************************************************* + * Handler called to return the 'req_state' for system suspend. + ******************************************************************************/ +void css_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + unsigned int i; + + /* + * System Suspend is supported only if the system power domain node + * is implemented. + */ + assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2); + + for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF; +} + +/******************************************************************************* + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform will take care of registering the handlers with PSCI. + ******************************************************************************/ +const plat_psci_ops_t plat_arm_psci_pm_ops = { + .pwr_domain_on = css_pwr_domain_on, + .pwr_domain_on_finish = css_pwr_domain_on_finish, + .pwr_domain_off = css_pwr_domain_off, + .cpu_standby = css_cpu_standby, + .pwr_domain_suspend = css_pwr_domain_suspend, + .pwr_domain_suspend_finish = css_pwr_domain_suspend_finish, + .system_off = css_system_off, + .system_reset = css_system_reset, + .validate_power_state = arm_validate_power_state, + .validate_ns_entrypoint = arm_validate_ns_entrypoint, + .get_sys_suspend_power_state = css_get_sys_suspend_power_state +}; diff --git a/plat/arm/rdd/common/css_scp_bootloader.c b/plat/arm/rdd/common/css_scp_bootloader.c new file mode 100644 index 000000000..d3f671e2c --- /dev/null +++ b/plat/arm/rdd/common/css_scp_bootloader.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2014-2016, 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 <css_def.h> +#include <debug.h> +#include <platform.h> +#include <stdint.h> +#include "css_mhu.h" +#include "css_scp_bootloader.h" +#include "css_scpi.h" + +/* ID of the MHU slot used for the BOM protocol */ +#define BOM_MHU_SLOT_ID 0 + +/* Boot commands sent from AP -> SCP */ +#define BOOT_CMD_INFO 0x00 +#define BOOT_CMD_DATA 0x01 + +/* BOM command header */ +typedef struct { + uint32_t id : 8; + uint32_t reserved : 24; +} bom_cmd_t; + +typedef struct { + uint32_t image_size; + uint32_t checksum; +} cmd_info_payload_t; + +/* + * Unlike the SCPI protocol, the boot protocol uses the same memory region + * for both AP -> SCP and SCP -> AP transfers; define the address of this... + */ +#define BOM_SHARED_MEM PLAT_CSS_SCP_COM_SHARED_MEM_BASE +#define BOM_CMD_HEADER ((bom_cmd_t *) BOM_SHARED_MEM) +#define BOM_CMD_PAYLOAD ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t))) + +typedef struct { + /* Offset from the base address of the Trusted RAM */ + uint32_t offset; + uint32_t block_size; +} cmd_data_payload_t; + +static void scp_boot_message_start(void) +{ + mhu_secure_message_start(BOM_MHU_SLOT_ID); +} + +static void scp_boot_message_send(size_t payload_size) +{ + /* Ensure that any write to the BOM payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data */ + dmbst(); + + /* Send command to SCP */ + mhu_secure_message_send(BOM_MHU_SLOT_ID); +} + +static uint32_t scp_boot_message_wait(size_t size) +{ + uint32_t mhu_status; + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCP Boot Protocol message, reject any other protocol */ + if (mhu_status != (1 << BOM_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* Ensure that any read to the BOM payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data */ + dmbld(); + + return *(uint32_t *) BOM_SHARED_MEM; +} + +static void scp_boot_message_end(void) +{ + mhu_secure_message_end(BOM_MHU_SLOT_ID); +} + +int scp_bootloader_transfer(void *image, unsigned int image_size) +{ + uint32_t response; + uint32_t checksum; + cmd_info_payload_t *cmd_info_payload; + cmd_data_payload_t *cmd_data_payload; + + assert((uintptr_t) image == SCP_BL2_BASE); + + if ((image_size == 0) || (image_size % 4 != 0)) { + ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of " + "4 bytes and not zero (current size = 0x%x)\n", + image_size); + return -1; + } + + /* Extract the checksum from the image */ + checksum = *(uint32_t *) image; + image = (char *) image + sizeof(checksum); + image_size -= sizeof(checksum); + + mhu_secure_init(); + + VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); + + /* + * Send information about the SCP firmware image about to be transferred + * to SCP + */ + scp_boot_message_start(); + + BOM_CMD_HEADER->id = BOOT_CMD_INFO; + cmd_info_payload = BOM_CMD_PAYLOAD; + cmd_info_payload->image_size = image_size; + cmd_info_payload->checksum = checksum; + + scp_boot_message_send(sizeof(*cmd_info_payload)); +#if CSS_DETECT_PRE_1_7_0_SCP + { + const uint32_t deprecated_scp_nack_cmd = 0x404; + uint32_t mhu_status; + + VERBOSE("Detecting SCP version incompatibility\n"); + + mhu_status = mhu_secure_message_wait(); + if (mhu_status == deprecated_scp_nack_cmd) { + ERROR("Detected an incompatible version of the SCP firmware.\n"); + ERROR("Only versions from v1.7.0 onwards are supported.\n"); + ERROR("Please update the SCP firmware.\n"); + return -1; + } + + VERBOSE("SCP version looks OK\n"); + } +#endif /* CSS_DETECT_PRE_1_7_0_SCP */ + response = scp_boot_message_wait(sizeof(response)); + scp_boot_message_end(); + + if (response != 0) { + ERROR("SCP BOOT_CMD_INFO returned error %u\n", response); + return -1; + } + + VERBOSE("Transferring SCP_BL2 image to SCP\n"); + + /* Transfer SCP_BL2 image to SCP */ + scp_boot_message_start(); + + BOM_CMD_HEADER->id = BOOT_CMD_DATA; + cmd_data_payload = BOM_CMD_PAYLOAD; + cmd_data_payload->offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; + cmd_data_payload->block_size = image_size; + + scp_boot_message_send(sizeof(*cmd_data_payload)); + response = scp_boot_message_wait(sizeof(response)); + scp_boot_message_end(); + + if (response != 0) { + ERROR("SCP BOOT_CMD_DATA returned error %u\n", response); + return -1; + } + + VERBOSE("Waiting for SCP to signal it is ready to go on\n"); + + /* Wait for SCP to signal it's ready */ + return scpi_wait_ready(); +} diff --git a/plat/arm/rdd/common/css_scpi.c b/plat/arm/rdd/common/css_scpi.c new file mode 100644 index 000000000..10ade659f --- /dev/null +++ b/plat/arm/rdd/common/css_scpi.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014-2016, 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 <css_def.h> +#include <debug.h> +#include <platform.h> +#include <string.h> +#include "css_mhu.h" +#include "css_scpi.h" + +#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE +#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ + + 0x100) + +#define SCPI_CMD_HEADER_AP_TO_SCP \ + ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) +#define SCPI_CMD_PAYLOAD_AP_TO_SCP \ + ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t))) + +/* ID of the MHU slot used for the SCPI protocol */ +#define SCPI_MHU_SLOT_ID 0 + +static void scpi_secure_message_start(void) +{ + mhu_secure_message_start(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_send(size_t payload_size) +{ + /* Ensure that any write to the SCPI payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data */ + dmbst(); + + mhu_secure_message_send(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_receive(scpi_cmd_t *cmd) +{ + uint32_t mhu_status; + + assert(cmd != NULL); + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCPI message, reject any other protocol */ + if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* Ensure that any read to the SCPI payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data */ + dmbld(); + + memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); +} + +static void scpi_secure_message_end(void) +{ + mhu_secure_message_end(SCPI_MHU_SLOT_ID); +} + +int scpi_wait_ready(void) +{ + scpi_cmd_t scpi_cmd; + + VERBOSE("Waiting for SCP_READY command...\n"); + + /* Get a message from the SCP */ + scpi_secure_message_start(); + scpi_secure_message_receive(&scpi_cmd); + scpi_secure_message_end(); + + /* We are expecting 'SCP Ready', produce correct error if it's not */ + scpi_status_t status = SCP_OK; + if (scpi_cmd.id != SCPI_CMD_SCP_READY) { + ERROR("Unexpected SCP command: expected command #%u, got command #%u\n", + SCPI_CMD_SCP_READY, scpi_cmd.id); + status = SCP_E_SUPPORT; + } else if (scpi_cmd.size != 0) { + ERROR("SCP_READY command has incorrect size: expected 0, got %u\n", + scpi_cmd.size); + status = SCP_E_SIZE; + } + + VERBOSE("Sending response for SCP_READY command\n"); + + /* + * Send our response back to SCP. + * We are using the same SCPI header, just update the status field. + */ + scpi_cmd.status = status; + scpi_secure_message_start(); + memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd)); + scpi_secure_message_send(0); + scpi_secure_message_end(); + + return status == 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) +{ + scpi_cmd_t *cmd; + uint32_t state = 0; + uint32_t *payload_addr; + uint32_t cpu_id, cluster_id; + + if (read_mpidr_el1() & MPIDR_MT_MASK) { + cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & 0xf; + cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & 0xf; + } else { + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & 0xf; + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & 0xf; + } + + state |= cpu_id; /* CPU ID */ + state |= cluster_id << 4; /* Cluster ID */ + state |= cpu_state << 8; + state |= cluster_state << 12; + state |= css_state << 16; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SET_CSS_POWER_STATE; + cmd->set = SCPI_SET_NORMAL; + cmd->sender = 0; + cmd->size = sizeof(state); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = state; + scpi_secure_message_send(sizeof(state)); + /* + * SCP does not reply to this command in order to avoid MHU interrupts + * from the sender, which could interfere with its power state request. + */ + + scpi_secure_message_end(); +} + +uint32_t scpi_sys_power_state(scpi_system_state_t system_state) +{ + scpi_cmd_t *cmd; + uint8_t *payload_addr; + scpi_cmd_t response; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SYS_POWER_STATE; + cmd->set = 0; + cmd->sender = 0; + cmd->size = sizeof(*payload_addr); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = system_state & 0xff; + scpi_secure_message_send(sizeof(*payload_addr)); + + scpi_secure_message_receive(&response); + + scpi_secure_message_end(); + + return response.status; +} diff --git a/plat/arm/rdd/common/css_topology.c b/plat/arm/rdd/common/css_topology.c new file mode 100644 index 000000000..d5f0275a8 --- /dev/null +++ b/plat/arm/rdd/common/css_topology.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015-2016, 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 <plat_arm.h> + +/****************************************************************************** + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is + * returned in case the MPIDR is invalid. + *****************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + if (arm_check_mpidr(mpidr) == 0) + return plat_arm_calc_core_pos(mpidr); + + return -1; +} diff --git a/plat/arm/rdd/common/include/css_def.h b/plat/arm/rdd/common/include/css_def.h new file mode 100644 index 000000000..140dd1f15 --- /dev/null +++ b/plat/arm/rdd/common/include/css_def.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2015-2016, 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 __CSS_DEF_H__ +#define __CSS_DEF_H__ + +#include <arm_def.h> +#include <tzc400.h> + +/************************************************************************* + * Definitions common to all ARM Compute SubSystems (CSS) + *************************************************************************/ +#define NSROM_BASE 0x1f000000 +#define NSROM_SIZE 0x00001000 + +/* Following covers CSS Peripherals excluding NSROM and NSRAM */ +#define CSS_DEVICE_BASE 0x20000000 +#define CSS_DEVICE_SIZE 0x0e000000 + +#define NSRAM_BASE 0x2e000000 +#define NSRAM_SIZE 0x00008000 + +/* System Security Control Registers */ +#define SSC_REG_BASE 0x2a420000 +#define SSC_GPRETN (SSC_REG_BASE + 0x030) + +/* SSC_VERSION values for different CSS */ +#define ARMSTRONG_SSC_VER_PART_NUM 0x0750 +#define BUZZ_SSC_VER_PART_NUM 0x0770 +#define COLLINS_SSC_VER_PART_NUM 0x0775 +#define CERNAN_SSC_VER_PART_NUM 0x0790 +#define ASHBROOK_SSC_VER_PART_NUM 0x0780 + +/* ASHBROOK_VERSION values */ +#define CONF_NUM_ASHBROOK5 5 + +/* The slave_bootsecure controls access to GPU, DMC and CS. */ +#define CSS_NIC400_SLAVE_BOOTSECURE 8 + +/* Interrupt handling constants */ +#define CSS_IRQ_MHU 69 +#define CSS_IRQ_GPU_SMMU_0 71 +#define CSS_IRQ_TZC 80 +#define CSS_IRQ_TZ_WDOG 86 +#define CSS_IRQ_SEC_SYS_TIMER 91 + +/* + * Define a list of Group 1 Secure interrupts as per GICv3 terminology. On a + * GICv2 system or mode, the interrupts will be treated as Group 0 interrupts. + */ +#define CSS_G1S_IRQS CSS_IRQ_MHU, \ + CSS_IRQ_GPU_SMMU_0, \ + CSS_IRQ_TZC, \ + CSS_IRQ_TZ_WDOG, \ + CSS_IRQ_SEC_SYS_TIMER + +/* + * SCP <=> AP boot configuration + * + * The SCP/AP boot configuration is a 32-bit word located at a known offset from + * the start of the Trusted SRAM. + * + * Note that the value stored at this address is only valid at boot time, before + * the SCP_BL2 image is transferred to SCP. + */ +#define SCP_BOOT_CFG_ADDR PLAT_CSS_SCP_COM_SHARED_MEM_BASE + +#define CSS_MAP_DEVICE MAP_REGION_FLAT( \ + CSS_DEVICE_BASE, \ + CSS_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* Platform ID address */ +#define SSC_VERSION_OFFSET 0x040 + +#define SSC_VERSION_CONFIG_SHIFT 28 +#define SSC_VERSION_MAJOR_REV_SHIFT 24 +#define SSC_VERSION_MINOR_REV_SHIFT 20 +#define SSC_VERSION_DESIGNER_ID_SHIFT 12 +#define SSC_VERSION_PART_NUM_SHIFT 0x0 +#define SSC_VERSION_CONFIG_MASK 0xf +#define SSC_VERSION_MAJOR_REV_MASK 0xf +#define SSC_VERSION_MINOR_REV_MASK 0xf +#define SSC_VERSION_DESIGNER_ID_MASK 0xff +#define SSC_VERSION_PART_NUM_MASK 0xfff +#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET) + +#ifndef __ASSEMBLY__ + +/* SSC_VERSION related accessors */ + +/* Returns the part number of the platform */ +#define GET_SSC_VERSION_PART_NUM(val) \ + (((val) >> SSC_VERSION_PART_NUM_SHIFT) & \ + SSC_VERSION_PART_NUM_MASK) + +#define GET_PLAT_PART_NUM \ + GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION)) + +/* Returns the configuration number of the platform */ +#define GET_SSC_VERSION_CONFIG(val) \ + (((val) >> SSC_VERSION_CONFIG_SHIFT) & \ + SSC_VERSION_CONFIG_MASK) + +#define GET_PLAT_CONFIG_NUM \ + GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION)) + +#endif /* __ASSEMBLY__ */ + +/************************************************************************* + * Required platform porting definitions common to all + * ARM Compute SubSystems (CSS) + ************************************************************************/ + +/* + * The loading of SCP images(SCP_BL2 or SCP_BL2U) is done if there + * respective base addresses are defined (i.e SCP_BL2_BASE, SCP_BL2U_BASE). + * Hence, `CSS_LOAD_SCP_IMAGES` needs to be set to 1 if BL2 needs to load + * an SCP_BL2/SCP_BL2U image. + */ +#if CSS_LOAD_SCP_IMAGES +/* + * Load address of SCP_BL2 in CSS platform ports + * SCP_BL2 is loaded to the same place as BL31. Once SCP_BL2 is transferred to the + * SCP, it is discarded and BL31 is loaded over the top. + */ +#define SCP_BL2_BASE BL31_BASE + +#define SCP_BL2U_BASE BL31_BASE +#endif /* CSS_LOAD_SCP_IMAGES */ + +/* Load address of Non-Secure Image for CSS platform ports */ +#define PLAT_ARM_NS_IMAGE_OFFSET 0xE0000000 + +/* TZC related constants */ +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL + +/* Trusted mailbox base address common to all CSS */ +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE + + +#endif /* __CSS_DEF_H__ */ diff --git a/plat/arm/rdd/common/include/css_mhu.h b/plat/arm/rdd/common/include/css_mhu.h new file mode 100644 index 000000000..2175cdf96 --- /dev/null +++ b/plat/arm/rdd/common/include/css_mhu.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014-2015, 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 __CSS_MHU_H__ +#define __CSS_MHU_H__ + +#include <stdint.h> + +void mhu_secure_message_start(unsigned int slot_id); +void mhu_secure_message_send(unsigned int slot_id); +uint32_t mhu_secure_message_wait(void); +void mhu_secure_message_end(unsigned int slot_id); + +void mhu_secure_init(void); + +#endif /* __CSS_MHU_H__ */ diff --git a/plat/arm/rdd/common/include/css_pm.h b/plat/arm/rdd/common/include/css_pm.h new file mode 100644 index 000000000..ea6a5d251 --- /dev/null +++ b/plat/arm/rdd/common/include/css_pm.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015, 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 __CSS_PM_H__ +#define __CSS_PM_H__ + +#include <cdefs.h> +#include <psci.h> +#include <types.h> + +int css_pwr_domain_on(u_register_t mpidr); +void css_pwr_domain_on_finish(const psci_power_state_t *target_state); +void css_pwr_domain_off(const psci_power_state_t *target_state); +void css_pwr_domain_suspend(const psci_power_state_t *target_state); +void css_pwr_domain_suspend_finish( + const psci_power_state_t *target_state); +void __dead2 css_system_off(void); +void __dead2 css_system_reset(void); +void css_cpu_standby(plat_local_state_t cpu_state); +void css_get_sys_suspend_power_state(psci_power_state_t *req_state); + +#endif /* __CSS_PM_H__ */ diff --git a/plat/arm/rdd/common/include/css_scp_bootloader.h b/plat/arm/rdd/common/include/css_scp_bootloader.h new file mode 100644 index 000000000..07b89728f --- /dev/null +++ b/plat/arm/rdd/common/include/css_scp_bootloader.h @@ -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 __CSS_SCP_BOOTLOADER_H__ +#define __CSS_SCP_BOOTLOADER_H__ + +int scp_bootloader_transfer(void *image, unsigned int image_size); + +#endif /* __CSS_SCP_BOOTLOADER_H__ */ diff --git a/plat/arm/rdd/common/include/css_scpi.h b/plat/arm/rdd/common/include/css_scpi.h new file mode 100644 index 000000000..4a601f3ef --- /dev/null +++ b/plat/arm/rdd/common/include/css_scpi.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014-2015, 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 __CSS_SCPI_H__ +#define __CSS_SCPI_H__ + +#include <stddef.h> +#include <stdint.h> + +/* + * An SCPI command consists of a header and a payload. + * The following structure describes the header. It is 64-bit long. + */ +typedef struct { + /* Command ID */ + uint32_t id : 7; + /* Set ID. Identifies whether this is a standard or extended command. */ + uint32_t set : 1; + /* Sender ID to match a reply. The value is sender specific. */ + uint32_t sender : 8; + /* Size of the payload in bytes (0 - 511) */ + uint32_t size : 9; + uint32_t reserved : 7; + /* + * Status indicating the success of a command. + * See the enum below. + */ + uint32_t status; +} scpi_cmd_t; + +typedef enum { + SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ + SCPI_SET_EXTENDED /* Extended SCPI commands */ +} scpi_set_t; + +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 */ + SCPI_E_DEVICE, /* Device error */ + SCPI_E_BUSY, /* Device is busy */ +}; + +typedef uint32_t scpi_status_t; + +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_CSS_POWER_STATE = 0x03, + SCPI_CMD_SYS_POWER_STATE = 0x05 +} scpi_command_t; + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state_t; + +typedef enum { + scpi_system_shutdown = 0, + scpi_system_reboot = 1, + scpi_system_reset = 2 +} scpi_system_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); +uint32_t scpi_sys_power_state(scpi_system_state_t system_state); + + +#endif /* __CSS_SCPI_H__ */ diff --git a/plat/arm/rdd/enterprise/.gitignore b/plat/arm/rdd/enterprise/.gitignore new file mode 100644 index 000000000..126a448f5 --- /dev/null +++ b/plat/arm/rdd/enterprise/.gitignore @@ -0,0 +1,2 @@ +*.swp +*.patch diff --git a/plat/arm/rdd/enterprise/enterprise_gic_config.c b/plat/arm/rdd/enterprise/enterprise_gic_config.c new file mode 100644 index 000000000..84db39304 --- /dev/null +++ b/plat/arm/rdd/enterprise/enterprise_gic_config.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016, 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 <arm_def.h> +#include <arm_gic.h> +#include <bl_common.h> +#include <debug.h> +#include <plat_arm.h> +#include <platform.h> +#include <platform_def.h> +#include <gicv3.h> + +/* The GICv3 driver only needs to be initialized in EL3 */ +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* Array of Group1 secure interrupts to be configured by the gic driver */ +const unsigned int enterprise_g1s_interrupt_array[] = { + PLAT_ARM_G1S_IRQS +}; + +/* Array of Group0 interrupts to be configured by the gic driver */ +const unsigned int enterprise_g0_interrupt_array[] = { + PLAT_ARM_G0_IRQS +}; + +static gicv3_driver_data_t enterprise_gic_data = { + .gicd_base = PLAT_ARM_GICD_BASE, + .gicr_base = PLAT_ARM_GICR_BASE, + .g0_interrupt_num = ARRAY_SIZE(enterprise_g0_interrupt_array), + .g1s_interrupt_num = ARRAY_SIZE(enterprise_g1s_interrupt_array), + .g0_interrupt_array = enterprise_g0_interrupt_array, + .g1s_interrupt_array = enterprise_g1s_interrupt_array, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = plat_arm_calc_core_pos + }; + +void plat_arm_gic_driver_init(void) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + + /* + * The default definitions of GIC base addresses are specific to + * ashbrook2. Override the GICR base addresses in case of ashbrook5. + */ + if ((GET_PLAT_PART_NUM == ASHBROOK_SSC_VER_PART_NUM) && + (GET_PLAT_CONFIG_NUM == CONF_NUM_ASHBROOK5)) + enterprise_gic_data.gicr_base = PLAT_ARM_GICR_BASE_ASH5; + +#if IMAGE_BL31 + gicv3_driver_init(&enterprise_gic_data); +#endif +} diff --git a/plat/arm/rdd/enterprise/enterprise_helper.S b/plat/arm/rdd/enterprise/enterprise_helper.S new file mode 100644 index 000000000..bf8164f0c --- /dev/null +++ b/plat/arm/rdd/enterprise/enterprise_helper.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, 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 <asm_macros.S> +#include <platform_def.h> + + .globl plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu (applicable only after a cold boot) + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mov x9, x30 + bl plat_my_core_pos + ldr x1, =ENTERPRISE_BOOT_CFG_ADDR + ldr x1, [x1] + ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \ + #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH + cmp x0, x1 + cset w0, eq + ret x9 +endfunc plat_is_my_cpu_primary diff --git a/plat/arm/rdd/enterprise/enterprise_plat.c b/plat/arm/rdd/enterprise/enterprise_plat.c new file mode 100644 index 000000000..b30f77982 --- /dev/null +++ b/plat/arm/rdd/enterprise/enterprise_plat.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2016, 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 <arm_def.h> +#include <bl_common.h> +#include <ccn.h> +#include <plat_arm.h> +#include <platform.h> +#include "../../../../bl1/bl1_private.h" +#include "debug.h" + +#define BL31_END (uintptr_t)(&__BL31_END__) + +#if USE_COHERENT_MEM +/* + * 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 BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +#define BL31_COHERENT_RAM_BASE (uintptr_t)(&__COHERENT_RAM_START__) +#define BL31_COHERENT_RAM_LIMIT (uintptr_t)(&__COHERENT_RAM_END__) +#endif + +#define ENTERPRISE_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) +/* + * Table of regions for different BL stages to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * arm_configure_mmu_elx() will give the available subset of that. + * + * Replace or extend the below regions as required + */ +#if IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + ENTERPRISE_MAP_FLASH0_RO, + CSS_ENTERPRISE_MAP_DEVICE, + SOC_CSS_MAP_DEVICE, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + ENTERPRISE_MAP_FLASH0_RO, + CSS_ENTERPRISE_MAP_DEVICE, + SOC_CSS_MAP_DEVICE, + ARM_MAP_NS_DRAM1, +#if ARM_BL31_IN_DRAM + ARM_MAP_BL31_SEC_DRAM, +#endif + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + V2M_MAP_IOFPGA, + CSS_ENTERPRISE_MAP_DEVICE, + SOC_CSS_MAP_DEVICE, + {0} +}; +#endif + +ARM_CASSERT_MMAP + +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - Code section; + * - Read-only data section; + * - Coherent memory region, if applicable. + */ +void arm_enterprise_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , + uintptr_t coh_start, + uintptr_t coh_limit +#endif + ) +{ + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *) total_base, (void *) (total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, + MT_NON_CACHEABLE | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *) code_start, (void *) code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, + (MT_NON_CACHEABLE | MT_RO | MT_EXECUTE | MT_SECURE)); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *) rodata_start, (void *) rodata_limit); + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, + MT_NON_CACHEABLE | MT_RO | MT_EXECUTE_NEVER | MT_SECURE); + +#if USE_COHERENT_MEM + /* Re-map the coherent memory region */ + VERBOSE("Coherent region: %p - %p\n", + (void *) coh_start, (void *) coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, + MT_NON_CACHEABLE | MT_RW | MT_SECURE); +#endif + + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_arm_get_mmap()); + + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} +#if IMAGE_BL1 +void bl1_plat_arch_setup(void) +{ + arm_enterprise_setup_page_tables(ARM_BL_RAM_BASE, + ARM_BL_RAM_SIZE, + BL_CODE_BASE, + BL1_CODE_LIMIT, + BL1_RO_DATA_BASE, + BL1_RO_DATA_LIMIT +#if USE_COHERENT_MEM + , BL1_COHERENT_RAM_BASE, + BL1_COHERENT_RAM_LIMIT +#endif + ); + enable_mmu_el3(TCR_MT_NON_CACHEABLE); +} +#endif + +#if IMAGE_BL2 +void bl2_plat_arch_setup(void) +{ + arm_enterprise_setup_page_tables(BL2_BASE, + BL2_LIMIT-BL2_BASE, + BL_CODE_BASE, + BL_CODE_LIMIT, + BL_RO_DATA_BASE, + BL_RO_DATA_LIMIT +#if USE_COHERENT_MEM + , BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT +#endif + ); + enable_mmu_el1(TCR_MT_NON_CACHEABLE); +} +#endif + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + static meminfo_t bl2_dram_layout + __aligned(CACHE_WRITEBACK_GRANULE) = { + .total_base = BL31_BASE, + .total_size = PLAT_ARM_MAX_BL31_SIZE, + .free_base = BL31_BASE, + .free_size = PLAT_ARM_MAX_BL31_SIZE + }; + + return &bl2_dram_layout; +} diff --git a/plat/arm/rdd/enterprise/enterprise_security.c b/plat/arm/rdd/enterprise/enterprise_security.c new file mode 100644 index 000000000..e9b3594b8 --- /dev/null +++ b/plat/arm/rdd/enterprise/enterprise_security.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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 <arm_config.h> +#include <plat_arm.h> + +/* + * We assume that all security programming is done by the primary core. + */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/rdd/enterprise/enterprise_topology.c b/plat/arm/rdd/enterprise/enterprise_topology.c new file mode 100644 index 000000000..3e857e88f --- /dev/null +++ b/plat/arm/rdd/enterprise/enterprise_topology.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, 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 <plat_arm.h> +#include <platform_def.h> + +/* + * The power domain tree descriptor. The cluster power domains are + * arranged so that when the PSCI generic code creates the power domain tree, + * the indices of the CPU power domain nodes it allocates match the linear + * indices returned by plat_core_pos_by_mpidr(). + */ +unsigned char enterprise_pd_tree_desc[PLAT_ARM_CLUSTER_COUNT + 1]; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + enterprise_pd_tree_desc[0] = PLAT_ARM_CLUSTER_COUNT; + + for (i = 0; i < PLAT_ARM_CLUSTER_COUNT; i++) + enterprise_pd_tree_desc[i + 1] = PLAT_MAX_CORES_PER_CLUSTER; + + return enterprise_pd_tree_desc; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return PLAT_MAX_CORES_PER_CLUSTER; +} diff --git a/plat/arm/rdd/enterprise/include/enterprise_def.h b/plat/arm/rdd/enterprise/include/enterprise_def.h new file mode 100644 index 000000000..a7e232b7d --- /dev/null +++ b/plat/arm/rdd/enterprise/include/enterprise_def.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015-2016, 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 __ENTERPRISE_DEF_H__ +#define __ENTERPRISE_DEF_H__ + +#if ARM_BOARD_OPTIMISE_MEM + +#if IMAGE_BL31 || IMAGE_BL32 +# define PLAT_ARM_MMAP_ENTRIES 6 +# define MAX_XLAT_TABLES 4 +#else +# define PLAT_ARM_MMAP_ENTRIES 10 +# define MAX_XLAT_TABLES 5 +#endif + +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL1_RW_SIZE 0xA000 +#else +# define PLAT_ARM_MAX_BL1_RW_SIZE 0x6000 +#endif + +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL2_SIZE 0x1D000 +#else +# define PLAT_ARM_MAX_BL2_SIZE 0xC000 +#endif + +#endif /* ARM_BOARD_OPTIMISE_MEM */ + +#define PLAT_ARM_NSTIMER_FRAME_ID 0 + +#define PLAT_CSS_MHU_BASE 0x45000000 +#define PLAT_ARM_CCN_BASE 0x32000000 + +#define PLAT_ARM_TRUSTED_ROM_BASE 0x0 +#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */ + +#define PLAT_MAX_PWR_LVL 1 + +#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ + CSS_IRQ_MHU + +#define PLAT_ARM_G0_IRQS ARM_G0_IRQS + +#define CSS_ENTERPRISE_DEVICE_BASE (0x20000000) +#define CSS_ENTERPRISE_DEVICE_SIZE (0x20000000) +#define CSS_ENTERPRISE_MAP_DEVICE MAP_REGION_FLAT( \ + CSS_ENTERPRISE_DEVICE_BASE, \ + CSS_ENTERPRISE_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000 +#define ENTERPRISE_BOOT_CFG_ADDR 0x45410000 +#define PLAT_CSS_PRIMARY_CPU_SHIFT 8 +#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 6 + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE 0x30000000 +#define PLAT_ARM_GICC_BASE 0x2C000000 +#define PLAT_ARM_GICR_BASE 0x30800000 +#define PLAT_ARM_GICR_BASE_ASH5 0x30400000 + +/* Map Ashbrook cluster ID to CCN node ID */ +#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP \ + 0, /* Cluster 0 */ \ + 18, /* Cluster 1 */ \ + 11, /* Cluster 2 */ \ + 29, /* Cluster 3 */ \ + 35, /* Cluster 4 */ \ + 17, /* Cluster 5 */ \ + 12, /* Cluster 6 */ \ + 30, /* Cluster 7 */ \ + 14, /* Cluster 8 */ \ + 32, /* Cluster 9 */ \ + 15, /* Cluster 10 */ \ + 33 /* Cluster 11 */ + +#endif /* __ENTERPRISE_DEF_H__ */ diff --git a/plat/arm/rdd/enterprise/include/plat_macros.S b/plat/arm/rdd/enterprise/include/plat_macros.S new file mode 100644 index 000000000..bc3fc5603 --- /dev/null +++ b/plat/arm/rdd/enterprise/include/plat_macros.S @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, 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 __PLAT_MACROS_S__ +#define __PLAT_MACROS_S__ + +#include <css_macros.S> + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm +#endif /* __PLAT_MACROS_S__ */ diff --git a/plat/arm/rdd/enterprise/include/platform_def.h b/plat/arm/rdd/enterprise/include/platform_def.h new file mode 100644 index 000000000..2a9212cde --- /dev/null +++ b/plat/arm/rdd/enterprise/include/platform_def.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, 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 <arm_def.h> +#include <board_arm_def.h> +#include <board_css_def.h> +#include <common_def.h> +#include <enterprise_def.h> +#include <css_def.h> +#include <soc_css_def.h> + +#define PLAT_MAX_CORES_PER_CLUSTER 4 +#define PLAT_ARM_MAX_BL31_SIZE 0x28000 + +/* CPU topology */ +#define PLAT_ARM_CLUSTER_COUNT 12 +#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ + PLAT_MAX_CORES_PER_CLUSTER) + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/arm/rdd/enterprise/include/platform_oid.h b/plat/arm/rdd/enterprise/include/platform_oid.h new file mode 100644 index 000000000..0ea00f4f3 --- /dev/null +++ b/plat/arm/rdd/enterprise/include/platform_oid.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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 "../../../../../include/plat/arm/board/common/board_arm_oid.h" + +/* + * Required platform OIDs + * (Provided by included header) + */ diff --git a/plat/arm/rdd/enterprise/platform.mk b/plat/arm/rdd/enterprise/platform.mk new file mode 100644 index 000000000..7554eee89 --- /dev/null +++ b/plat/arm/rdd/enterprise/platform.mk @@ -0,0 +1,73 @@ +# +# Copyright (c) 2016, 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. +# + +ENABLE_PLAT_COMPAT := 0 + +CSS_ENT_BASE := plat/arm/rdd/enterprise + +ENT_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \ + plat/arm/common/arm_ccn.c + +PLAT_INCLUDES += -I${CSS_ENT_BASE}/include + +ENT_CPU_SOURCES := lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a72.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/enterprise_plat.c \ + ${CSS_ENT_BASE}/enterprise_helper.S + +BL1_SOURCES += ${ENT_INTERCONNECT_SOURCES} \ + ${ENT_CPU_SOURCES} + +BL2_SOURCES += ${CSS_ENT_BASE}/enterprise_security.c + +BL31_SOURCES += ${ENT_CPU_SOURCES} \ + drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c \ + ${ENT_INTERCONNECT_SOURCES} \ + ${CSS_ENT_BASE}/enterprise_topology.c \ + ${CSS_ENT_BASE}/enterprise_gic_config.c + + +$(eval $(call add_define,ENTERPRISE_PLAT)) + +override CSS_LOAD_SCP_IMAGES := 0 +override NEED_BL2U := no +override ERROR_DEPRECATED := 1 +override ARM_BL31_IN_DRAM := 1 +override ARM_BOARD_OPTIMISE_MEM := 1 + +include plat/arm/common/arm_common.mk +include plat/arm/rdd/common/css_common.mk +include plat/arm/soc/common/soc_css.mk +include plat/arm/board/common/board_common.mk diff --git a/services/spd/opteed/opteed_common.c b/services/spd/opteed/opteed_common.c index 2f20b7cae..237159252 100644 --- a/services/spd/opteed/opteed_common.c +++ b/services/spd/opteed/opteed_common.c @@ -42,6 +42,7 @@ ******************************************************************************/ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point, uint32_t rw, uint64_t pc, + uint64_t paged_part, uint64_t mem_limit, optee_context_t *optee_ctx) { uint32_t ep_attr; @@ -64,7 +65,7 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point, ep_attr |= EP_EE_BIG; SET_PARAM_HEAD(optee_entry_point, PARAM_EP, VERSION_1, ep_attr); optee_entry_point->pc = pc; - if (rw == OPTEE_AARCH64) + if (rw == TEE_AARCH64) optee_entry_point->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); else @@ -74,6 +75,8 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point, DAIF_IRQ_BIT | DAIF_ABT_BIT); memset(&optee_entry_point->args, 0, sizeof(optee_entry_point->args)); + optee_entry_point->args.arg0 = paged_part; + optee_entry_point->args.arg1 = mem_limit; } /******************************************************************************* diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c index 9770fb997..b6589a1ea 100644 --- a/services/spd/opteed/opteed_main.c +++ b/services/spd/opteed/opteed_main.c @@ -148,10 +148,12 @@ int32_t opteed_setup(void) * state i.e whether AArch32 or AArch64. Assuming it's AArch32 * for the time being. */ - opteed_rw = OPTEE_AARCH64; + opteed_rw = optee_ep_info->args.arg0; opteed_init_optee_ep_state(optee_ep_info, opteed_rw, optee_ep_info->pc, + PAGED_BL32_BASE, + PAGED_BL32_LIMIT, &opteed_sp_context[linear_id]); /* diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c index bd3185ce6..50e11e508 100644 --- a/services/spd/opteed/opteed_pm.c +++ b/services/spd/opteed/opteed_pm.c @@ -123,7 +123,7 @@ static void opteed_cpu_on_finish_handler(uint64_t unused) opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw, (uint64_t)&optee_vectors->cpu_on_entry, - optee_ctx); + PAGED_BL32_BASE, PAGED_BL32_SIZE, optee_ctx); /* Initialise this cpu's secure context */ cm_init_my_context(&optee_on_entrypoint); diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h index 357c2ecfb..5376651de 100644 --- a/services/spd/opteed/opteed_private.h +++ b/services/spd/opteed/opteed_private.h @@ -171,6 +171,8 @@ void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret void opteed_init_optee_ep_state(struct entry_point_info *optee_ep, uint32_t rw, uint64_t pc, + uint64_t paged_part, + uint64_t mem_limit, optee_context_t *optee_ctx); extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT]; |