FVP: Support Base FVP RevC
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Tue, 18 Jul 2017 14:42:50 +0000 (15:42 +0100)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Wed, 2 Aug 2017 13:10:35 +0000 (14:10 +0100)
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>
include/plat/arm/common/arm_config.h
plat/arm/board/fvp/fvp_bl31_setup.c
plat/arm/board/fvp/fvp_common.c
plat/arm/board/fvp/fvp_def.h
plat/arm/board/fvp/fvp_topology.c
plat/arm/board/fvp/include/platform_def.h
plat/arm/board/fvp/platform.mk

index 2ab7bf2e391e5d67a4191bbf1f2990ff6d79e9ed..02e04fd3be215e4912506d565f2980a6cb788d7f 100644 (file)
@@ -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 {
index 52a4432dfe0e2bcce708aad0fa79f5aa0fe7a676..181c92319be5f7a7e70599e8457f3f0732bc14b1 100644 (file)
@@ -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);
 }
index 2f5d7fcf5f64407ab8d13c50e695aaacfeef2d90..c1dcc02c60cab221bd0017438e981cbb9f862942 100644 (file)
@@ -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>
@@ -118,6 +120,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
@@ -182,8 +208,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
@@ -191,6 +216,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);
@@ -206,26 +237,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
 }
index 84e790bf6db996a1c6ce44c0763a0f5405206624..a430bcac1ac772bfa1547ece5d4fcd4194cb61dc 100644 (file)
@@ -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
index 848aaf8c7f4cd9f5a12c9c5e6fd17a2f4619b592..cf1492b676a7ab60eac9991d310c58ad035e8bc2 100644 (file)
@@ -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;
 
index 7a7cf9e73d58d2780ed899900645b49988986235..bf038e92a665de32bd30d65ee76b6f0fd70ffc1a 100644 (file)
 #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
index d9c624cd40a35a2be0c42c2a26dfcd903dad29be..0b6e1da54ae983b8805a1aa0deaa357a7eb64df3 100644 (file)
@@ -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        \