aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-07-18 15:42:50 +0100
committerRyan Harkin <ryan.harkin@linaro.org>2017-08-08 12:35:29 +0100
commit569b4abec93271722bfc51a95027eb0a9d3447c1 (patch)
treefd066e26b9ede26bd45d700bdd0bf434d734183c
parent69ee4ebe2546ca7a93cd0456e6b62f3138b0aedb (diff)
FVP: Support Base FVP RevCHEADmaster17.07
Revision C of the Base FVP has the same memory map as earlier revisions, but has the following differences: - Implements CCI550 instead of CCI400, - Has a single instantiation of SMMUv3, - CPU MPIDs are shifted left by one level, and has MT bit set in them. The correct interconnect to program is chosen at run time based on the FVP revision. Therefore, this patch implements FVP functions for interconnect programming, rather than depending on ARM generic ones. The macros used have been renamed to reflect this change. Additionally, this patch initializes SMMUv3 as part of FVP early platform setup. New ARM config flags are introduced for feature queries at run time. Change-Id: Ic7b7f080953a51fceaf62ce7daa6de0573801f09 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
-rw-r--r--include/plat/arm/common/arm_config.h16
-rw-r--r--plat/arm/board/fvp/fvp_bl31_setup.c8
-rw-r--r--plat/arm/board/fvp/fvp_common.c102
-rw-r--r--plat/arm/board/fvp/fvp_def.h1
-rw-r--r--plat/arm/board/fvp/fvp_topology.c20
-rw-r--r--plat/arm/board/fvp/include/platform_def.h13
-rw-r--r--plat/arm/board/fvp/platform.mk6
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 \