Browse Source

Allow multi cluster topology definitions for ARM platforms

The common topology description helper funtions and macros for
ARM Standard platforms assumed a dual cluster system. This is not
flexible enough to scale to multi cluster platforms. This patch does
the following changes for more flexibility in defining topology:

1. The `plat_get_power_domain_tree_desc()` definition is moved from
   `arm_topology.c` to platform specific files, that is `fvp_topology.c`
   and `juno_topology.c`. Similarly the common definition of the porting
   macro `PLATFORM_CORE_COUNT` in `arm_def.h` is moved to platform
   specific `platform_def.h` header.

2. The ARM common layer porting macros which were dual cluster specific
   are now removed and a new macro PLAT_ARM_CLUSTER_COUNT is introduced
   which must be defined by each ARM standard platform.

3. A new mandatory ARM common layer porting API
   `plat_arm_get_cluster_core_count()` is introduced to enable the common
   implementation of `arm_check_mpidr()` to validate MPIDR.

4. For the FVP platforms, a new build option `FVP_NUM_CLUSTERS` has been
   introduced which allows the user to specify the cluster count to be
   used to build the topology tree within Trusted Firmare. This enables
   Trusted Firmware to be built for multi cluster FVP models.

Change-Id: Ie7a2e38e5661fe2fdb2c8fdf5641d2b2614c2b6b
pull/531/head
Soby Mathew 9 years ago
parent
commit
0108047ae4
  1. 5
      docs/user-guide.md
  2. 5
      include/plat/arm/common/arm_def.h
  3. 1
      include/plat/arm/common/plat_arm.h
  4. 6
      plat/arm/board/fvp/fvp_def.h
  5. 54
      plat/arm/board/fvp/fvp_topology.c
  6. 6
      plat/arm/board/fvp/include/platform_def.h
  7. 5
      plat/arm/board/fvp/platform.mk
  8. 9
      plat/arm/board/juno/include/platform_def.h
  9. 7
      plat/arm/board/juno/juno_def.h
  10. 77
      plat/arm/board/juno/juno_topology.c
  11. 1
      plat/arm/board/juno/platform.mk
  12. 5
      plat/arm/board/juno/tsp/tsp-juno.mk
  13. 23
      plat/arm/common/arm_topology.c
  14. 29
      plat/arm/css/common/css_topology.c

5
docs/user-guide.md

@ -486,6 +486,11 @@ map is explained in the [Firmware Design].
Trusted Firmware must be compiled with GICv2 only driver using
`FVP_USE_GIC_DRIVER=FVP_GICV2` build option.
* `FVP_CLUSTER_COUNT` : Configures the cluster count to be used to
build the topology tree within Trusted Firmware. By default the
Trusted Firmware is configured for dual cluster topology and this option
can be used to override the default value.
### Creating a Firmware Image Package
FIPs are automatically created as part of the build instructions described in

5
include/plat/arm/common/arm_def.h

@ -44,7 +44,6 @@
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
#define ARM_CLUSTER_COUNT 2
#define ARM_SYSTEM_COUNT 1
#define ARM_CACHE_WRITEBACK_SHIFT 6
@ -218,10 +217,6 @@
*/
#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF
#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER0_CORE_COUNT + \
PLAT_ARM_CLUSTER1_CORE_COUNT)
/*
* Some data must be aligned on the biggest cache line size in the platform.
* This is known only to the platform as it might have a combination of

1
include/plat/arm/common/plat_arm.h

@ -179,6 +179,7 @@ int arm_io_is_toc_valid(void);
/*
* Mandatory functions required in ARM standard platforms
*/
unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr);
void plat_arm_gic_driver_init(void);
void plat_arm_gic_init(void);
void plat_arm_gic_cpuif_enable(void);

6
plat/arm/board/fvp/fvp_def.h

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
* 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:
@ -33,7 +33,9 @@
#include <arm_def.h>
#ifndef FVP_CLUSTER_COUNT
#define FVP_CLUSTER_COUNT 2
#endif
#define FVP_MAX_CPUS_PER_CLUSTER 4
#define FVP_PRIMARY_CPU 0x0

54
plat/arm/board/fvp/fvp_topology.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
* 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:
@ -29,27 +29,47 @@
*/
#include <arch.h>
#include <cassert.h>
#include <plat_arm.h>
#include <platform_def.h>
#include "drivers/pwrc/fvp_pwrc.h"
/*
* The FVP power domain tree does not have a single system level power domain
* i.e. a single root node. The first entry in the power domain descriptor
* specifies the number of power domains at the highest power level. For the FVP
* this is 2 i.e. the number of cluster power domains.
*/
#define FVP_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_CLUSTER_COUNT
/* The FVP power domain tree descriptor */
const unsigned char arm_power_domain_tree_desc[] = {
/* No of root nodes */
FVP_PWR_DOMAINS_AT_MAX_PWR_LVL,
/* No of children for the first node */
PLAT_ARM_CLUSTER0_CORE_COUNT,
/* No of children for the second node */
PLAT_ARM_CLUSTER1_CORE_COUNT
};
unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1];
CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count);
/*******************************************************************************
* This function dynamically constructs the topology according to
* FVP_CLUSTER_COUNT and returns it.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
int i;
/*
* The FVP power domain tree does not have a single system level power domain
* i.e. a single root node. The first entry in the power domain descriptor
* specifies the number of power domains at the highest power level. For the FVP
* this is the number of cluster power domains.
*/
fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT;
for (i = 0; i < FVP_CLUSTER_COUNT; i++)
fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER;
return fvp_power_domain_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 FVP_MAX_CPUS_PER_CLUSTER;
}
/*******************************************************************************
* This function implements a part of the critical interface between the psci

6
plat/arm/board/fvp/include/platform_def.h

@ -39,9 +39,10 @@
#include "../fvp_def.h"
/* Required platform porting definitions */
#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \
#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
#define PLATFORM_CORE_COUNT (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER)
/*
* Other platform porting definitions are provided by included headers
@ -50,8 +51,7 @@
/*
* Required ARM standard platform porting definitions
*/
#define PLAT_ARM_CLUSTER0_CORE_COUNT 4
#define PLAT_ARM_CLUSTER1_CORE_COUNT 4
#define PLAT_ARM_CLUSTER_COUNT FVP_CLUSTER_COUNT
#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x04000000 /* 64 MB */

5
plat/arm/board/fvp/platform.mk

@ -34,6 +34,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3_LEGACY
# The FVP platform depends on this macro to build with correct GIC driver.
$(eval $(call add_define,FVP_USE_GIC_DRIVER))
# If FVP_CLUSTER_COUNT has been defined, pass it into the build system.
ifdef FVP_CLUSTER_COUNT
$(eval $(call add_define,FVP_CLUSTER_COUNT))
endif
# Choose the GIC sources depending upon the how the FVP will be invoked
ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \

9
plat/arm/board/juno/include/platform_def.h

@ -41,11 +41,15 @@
#include <v2m_def.h>
#include "../juno_def.h"
/* Required platform porting definitions */
/* Juno supports system power domain */
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
ARM_CLUSTER_COUNT + \
JUNO_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PLATFORM_CORE_COUNT (JUNO_CLUSTER0_CORE_COUNT + \
JUNO_CLUSTER1_CORE_COUNT)
/*
* Other platform porting definitions are provided by included headers
*/
@ -53,8 +57,7 @@
/*
* Required ARM standard platform porting definitions
*/
#define PLAT_ARM_CLUSTER0_CORE_COUNT 2
#define PLAT_ARM_CLUSTER1_CORE_COUNT 4
#define PLAT_ARM_CLUSTER_COUNT JUNO_CLUSTER_COUNT
/* Use the bypass address */
#define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET

7
plat/arm/board/juno/juno_def.h

@ -52,6 +52,13 @@
#define JUNO_SSC_VER_PART_NUM 0x030
/*******************************************************************************
* Juno topology related constants
******************************************************************************/
#define JUNO_CLUSTER_COUNT 2
#define JUNO_CLUSTER0_CORE_COUNT 2
#define JUNO_CLUSTER1_CORE_COUNT 4
/*******************************************************************************
* TZC-400 related constants
******************************************************************************/

77
plat/arm/board/juno/juno_topology.c

@ -0,0 +1,77 @@
/*
* 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 <plat_arm.h>
#include "juno_def.h"
/*
* On Juno, the system power level is the highest power level.
* The first entry in the power domain descriptor specifies the
* number of system power domains i.e. 1.
*/
#define JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
/*
* The Juno 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()
* i.e. CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher
* indices for CLUSTER0 CPUs.
*/
const unsigned char juno_power_domain_tree_desc[] = {
/* No of root nodes */
JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL,
/* No of children for the root node */
JUNO_CLUSTER_COUNT,
/* No of children for the first cluster node */
JUNO_CLUSTER1_CORE_COUNT,
/* No of children for the second cluster node */
JUNO_CLUSTER0_CORE_COUNT
};
/*******************************************************************************
* This function returns the Juno topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return juno_power_domain_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 (((mpidr) & 0x100) ? JUNO_CLUSTER1_CORE_COUNT :\
JUNO_CLUSTER0_CORE_COUNT);
}

1
plat/arm/board/juno/platform.mk

@ -62,6 +62,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
plat/arm/board/juno/juno_pm.c \
plat/arm/board/juno/juno_topology.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}

5
plat/arm/board/juno/tsp/tsp-juno.mk

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
# 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:
@ -28,7 +28,8 @@
# POSSIBILITY OF SUCH DAMAGE.
#
BL32_SOURCES += plat/arm/css/common/css_topology.c \
BL32_SOURCES += plat/arm/board/juno/juno_topology.c \
plat/arm/css/common/css_topology.c \
${JUNO_GIC_SOURCES}
include plat/arm/common/tsp/arm_tsp.mk

23
plat/arm/common/arm_topology.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* 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:
@ -29,26 +29,9 @@
*/
#include <arch.h>
#include <psci.h>
#include <plat_arm.h>
#include <platform_def.h>
#define get_arm_cluster_core_count(mpidr)\
(((mpidr) & 0x100) ? PLAT_ARM_CLUSTER1_CORE_COUNT :\
PLAT_ARM_CLUSTER0_CORE_COUNT)
/* The power domain tree descriptor which need to be exported by ARM platforms */
extern const unsigned char arm_power_domain_tree_desc[];
/*******************************************************************************
* This function returns the ARM default topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return arm_power_domain_tree_desc;
}
/*******************************************************************************
* This function validates an MPIDR by checking whether it falls within the
* acceptable bounds. An error code (-1) is returned if an incorrect mpidr
@ -66,12 +49,12 @@ int arm_check_mpidr(u_register_t mpidr)
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
if (cluster_id >= ARM_CLUSTER_COUNT)
if (cluster_id >= PLAT_ARM_CLUSTER_COUNT)
return -1;
/* Validate cpu_id by checking whether it represents a CPU in
one of the two clusters present on the platform. */
if (cpu_id >= get_arm_cluster_core_count(mpidr))
if (cpu_id >= plat_arm_get_cluster_core_count(mpidr))
return -1;
return 0;

29
plat/arm/css/common/css_topology.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* 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:
@ -30,33 +30,6 @@
#include <plat_arm.h>
/*
* On ARM CSS platforms, by default, the system power level is treated as the
* highest. The first entry in the power domain descriptor specifies the
* number of system power domains i.e. 1.
*/
#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
/*
* The CSS power domain tree descriptor for dual cluster CSS platforms.
* 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() i.e. CLUSTER1 CPUs are allocated indices
* from 0 to 3 and the higher indices for CLUSTER0 CPUs.
*/
const unsigned char arm_power_domain_tree_desc[] = {
/* No of root nodes */
CSS_PWR_DOMAINS_AT_MAX_PWR_LVL,
/* No of children for the root node */
ARM_CLUSTER_COUNT,
/* No of children for the first cluster node */
PLAT_ARM_CLUSTER1_CORE_COUNT,
/* No of children for the second cluster node */
PLAT_ARM_CLUSTER0_CORE_COUNT
};
/******************************************************************************
* 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

Loading…
Cancel
Save