FVP: Support Base FVP RevC

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>
This commit is contained in:
Jeenu Viswambharan 2017-07-18 15:42:50 +01:00
parent 1154586b71
commit 955242d8ff
7 changed files with 139 additions and 27 deletions

View 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 {

View 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);
}

View 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
}

View 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

View 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;

View File

@ -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

View 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 \