diff options
-rw-r--r-- | include/plat/arm/common/arm_config.h | 16 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_bl31_setup.c | 8 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_common.c | 102 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_def.h | 1 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_topology.c | 20 | ||||
-rw-r--r-- | plat/arm/board/fvp/include/platform_def.h | 13 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 6 |
7 files changed, 139 insertions, 27 deletions
diff --git a/include/plat/arm/common/arm_config.h b/include/plat/arm/common/arm_config.h index 2ab7bf2e3..02e04fd3b 100644 --- a/include/plat/arm/common/arm_config.h +++ b/include/plat/arm/common/arm_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,14 +7,20 @@ #define __ARM_CONFIG_H__ #include <stdint.h> +#include <utils_def.h> enum arm_config_flags { /* Whether Base memory map is in use */ - ARM_CONFIG_BASE_MMAP = 0x1, - /* Whether interconnect should be enabled */ - ARM_CONFIG_HAS_INTERCONNECT = 0x2, + ARM_CONFIG_BASE_MMAP = BIT(1), /* Whether TZC should be configured */ - ARM_CONFIG_HAS_TZC = 0x4 + ARM_CONFIG_HAS_TZC = BIT(2), + /* FVP model has shifted affinity */ + ARM_CONFIG_FVP_SHIFTED_AFF = BIT(3), + /* FVP model has SMMUv3 affinity */ + ARM_CONFIG_FVP_HAS_SMMUV3 = BIT(4), + /* FVP model has CCI (400 or 500/550) devices */ + ARM_CONFIG_FVP_HAS_CCI400 = BIT(5), + ARM_CONFIG_FVP_HAS_CCI5XX = BIT(6), }; typedef struct arm_config { diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 52a4432df..181c92319 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,10 +1,12 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <arm_config.h> #include <plat_arm.h> +#include <smmu_v3.h> #include "fvp_private.h" #if LOAD_IMAGE_V2 @@ -34,4 +36,8 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, * FVP PSCI code will enable coherency for other clusters. */ fvp_interconnect_enable(); + + /* On FVP RevC, intialize SMMUv3 */ + if (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) + smmuv3_init(PLAT_FVP_SMMUV3_BASE); } diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index eb37f113a..e456cc0be 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -1,11 +1,13 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <arm_config.h> #include <arm_def.h> +#include <assert.h> +#include <cci.h> #include <ccn.h> #include <debug.h> #include <gicv2.h> @@ -109,6 +111,30 @@ const mmap_region_t plat_arm_mmap[] = { ARM_CASSERT_MMAP +#if FVP_INTERCONNECT_DRIVER != FVP_CCN +static const int fvp_cci400_map[] = { + PLAT_FVP_CCI400_CLUS0_SL_PORT, + PLAT_FVP_CCI400_CLUS1_SL_PORT, +}; + +static const int fvp_cci5xx_map[] = { + PLAT_FVP_CCI5XX_CLUS0_SL_PORT, + PLAT_FVP_CCI5XX_CLUS1_SL_PORT, +}; + +static unsigned int get_interconnect_master(void) +{ + unsigned int master; + u_register_t mpidr; + + mpidr = read_mpidr_el1(); + master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ? + MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); + + assert(master < FVP_CLUSTER_COUNT); + return master; +} +#endif /******************************************************************************* * A single boot loader stack is expected to work on both the Foundation FVP @@ -173,8 +199,7 @@ void fvp_config_setup(void) } break; case HBI_BASE_FVP: - arm_config.flags |= ARM_CONFIG_BASE_MMAP | - ARM_CONFIG_HAS_INTERCONNECT | ARM_CONFIG_HAS_TZC; + arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); /* * Check for supported revisions @@ -182,6 +207,12 @@ void fvp_config_setup(void) */ switch (rev) { case REV_BASE_FVP_V0: + arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; + break; + case REV_BASE_FVP_REVC: + arm_config.flags |= (ARM_CONFIG_FVP_SHIFTED_AFF | + ARM_CONFIG_FVP_HAS_SMMUV3 | + ARM_CONFIG_FVP_HAS_CCI5XX); break; default: WARN("Unrecognized Base FVP revision %x\n", rev); @@ -197,26 +228,67 @@ void fvp_config_setup(void) void fvp_interconnect_init(void) { - if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) { #if FVP_INTERCONNECT_DRIVER == FVP_CCN - if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { - ERROR("Unrecognized CCN variant detected. Only CCN-502" - " is supported"); - panic(); - } -#endif - plat_arm_interconnect_init(); + if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { + ERROR("Unrecognized CCN variant detected. Only CCN-502" + " is supported"); + panic(); + } + + plat_arm_interconnect_init(); +#else + uintptr_t cci_base = 0; + const int *cci_map = 0; + unsigned int map_size = 0; + + if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | + ARM_CONFIG_FVP_HAS_CCI5XX))) { + return; + } + + /* Initialize the right interconnect */ + if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) { + cci_base = PLAT_FVP_CCI5XX_BASE; + cci_map = fvp_cci5xx_map; + map_size = ARRAY_SIZE(fvp_cci5xx_map); + } else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) { + cci_base = PLAT_FVP_CCI400_BASE; + cci_map = fvp_cci400_map; + map_size = ARRAY_SIZE(fvp_cci400_map); } + + assert(cci_base); + assert(cci_map); + cci_init(cci_base, cci_map, map_size); +#endif } void fvp_interconnect_enable(void) { - if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) - plat_arm_interconnect_enter_coherency(); +#if FVP_INTERCONNECT_DRIVER == FVP_CCN + plat_arm_interconnect_enter_coherency(); +#else + unsigned int master; + + if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | + ARM_CONFIG_FVP_HAS_CCI5XX)) { + master = get_interconnect_master(); + cci_enable_snoop_dvm_reqs(master); + } +#endif } void fvp_interconnect_disable(void) { - if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) - plat_arm_interconnect_exit_coherency(); +#if FVP_INTERCONNECT_DRIVER == FVP_CCN + plat_arm_interconnect_exit_coherency(); +#else + unsigned int master; + + if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | + ARM_CONFIG_FVP_HAS_CCI5XX)) { + master = get_interconnect_master(); + cci_disable_snoop_dvm_reqs(master); + } +#endif } diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 84e790bf6..a430bcac1 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -78,6 +78,7 @@ /* Constants to distinguish FVP type */ #define HBI_BASE_FVP 0x020 #define REV_BASE_FVP_V0 0x0 +#define REV_BASE_FVP_REVC 0x2 #define HBI_FOUNDATION_FVP 0x010 #define REV_FOUNDATION_FVP_V2_0 0x0 diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 848aaf8c7..cf1492b67 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -56,6 +56,26 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) ******************************************************************************/ int plat_core_pos_by_mpidr(u_register_t mpidr) { + unsigned int clus_id, cpu_id, thread_id; + + /* Validate affinity fields */ + if (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) { + thread_id = MPIDR_AFFLVL0_VAL(mpidr); + cpu_id = MPIDR_AFFLVL1_VAL(mpidr); + clus_id = MPIDR_AFFLVL2_VAL(mpidr); + } else { + thread_id = 0; + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + clus_id = MPIDR_AFFLVL1_VAL(mpidr); + } + + if (clus_id >= FVP_CLUSTER_COUNT) + return -1; + if (cpu_id >= FVP_MAX_CPUS_PER_CLUSTER) + return -1; + if (thread_id >= FVP_MAX_PE_PER_CPU) + return -1; + if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID) return -1; diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 7a7cf9e73..bf038e92a 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -68,10 +68,17 @@ #define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE #define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ +#define PLAT_FVP_SMMUV3_BASE 0x2b400000 + /* CCI related constants */ -#define PLAT_ARM_CCI_BASE 0x2c090000 -#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3 -#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4 +#define PLAT_FVP_CCI400_BASE 0x2c090000 +#define PLAT_FVP_CCI400_CLUS0_SL_PORT 3 +#define PLAT_FVP_CCI400_CLUS1_SL_PORT 4 + +/* CCI-500/CCI-550 on Base platform */ +#define PLAT_FVP_CCI5XX_BASE 0x2a000000 +#define PLAT_FVP_CCI5XX_CLUS0_SL_PORT 5 +#define PLAT_FVP_CCI5XX_CLUS1_SL_PORT 6 /* CCN related constants. Only CCN 502 is currently supported */ #define PLAT_ARM_CCN_BASE 0x2e000000 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index d9c624cd4..0b6e1da54 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -72,8 +72,7 @@ $(error "Incorrect GIC driver chosen on FVP port") endif ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCI) -FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \ - plat/arm/common/arm_cci.c +FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c else ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCN) FVP_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \ plat/arm/common/arm_ccn.c @@ -136,7 +135,8 @@ endif BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ ${FVP_SECURITY_SOURCES} -BL31_SOURCES += plat/arm/board/fvp/fvp_bl31_setup.c \ +BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \ + plat/arm/board/fvp/fvp_bl31_setup.c \ plat/arm/board/fvp/fvp_pm.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ |