summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Cunado <david.cunado@arm.com>2018-02-15 09:42:41 +0000
committerDavid Cunado <david.cunado@arm.com>2018-02-23 17:03:21 +0000
commit7c7d1a486005c3742d4da1a65ab1f0c153906cb2 (patch)
treebcffa34b2bb357e811a593fc57363450ba05a154
parent818f7d99e77d673d5196f378ceabcc081b4f1f88 (diff)
Support shifted affinities
This patch add a strong implementation of platform_get_core_pos that supports CPUs that are multi-threaded. It checks the MT field of the MPIDR value and shifts the affinities accordingly so that the correect PE index is provided. NOTE the code has hardcoded the number of PEs per CPU as 1 but this may change when truly multi-threaded CPUs are made available. Change-Id: I18174a65e9e089848943310b63fee916362cad13 Signed-off-by: David Cunado <david.cunado@arm.com>
-rw-r--r--framework/main.c10
-rw-r--r--include/lib/aarch32/arch.h8
-rw-r--r--include/lib/aarch64/arch.h9
-rw-r--r--include/lib/tftf_lib.h17
-rw-r--r--plat/arm/board/fvp/aarch32/plat_helpers.S67
-rw-r--r--plat/arm/board/fvp/aarch64/plat_helpers.S67
-rw-r--r--plat/arm/board/fvp/fvp_def.h4
-rw-r--r--plat/arm/board/fvp/platform.mk3
-rw-r--r--plat/common/aarch32/platform_mp_stack.S14
-rw-r--r--plat/common/aarch64/platform_mp_stack.S6
10 files changed, 180 insertions, 25 deletions
diff --git a/framework/main.c b/framework/main.c
index 580d2f3..ea69192 100644
--- a/framework/main.c
+++ b/framework/main.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2013-2016, ARM Limited. All rights reserved.
+* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -314,7 +314,7 @@ static unsigned int close_test(void)
static void __dead2 hand_over_to_lead_cpu(void)
{
int ret;
- unsigned int mpid = read_mpidr_el1() & 0xFFFFFF;
+ unsigned int mpid = read_mpidr_el1() & MPID_MASK;
unsigned int core_pos = platform_get_core_pos(mpid);
VERBOSE("CPU%u: Hand over to lead CPU%u\n", core_pos,
@@ -348,7 +348,7 @@ static void __dead2 hand_over_to_lead_cpu(void)
void __dead2 run_tests(void)
{
- unsigned int mpid = read_mpidr_el1() & 0xFFFFFF;
+ unsigned int mpid = read_mpidr_el1() & MPID_MASK;
unsigned int core_pos = platform_get_core_pos(mpid);
unsigned int test_session_finished;
unsigned int cpus_cnt;
@@ -581,7 +581,7 @@ void __dead2 tftf_cold_boot_main(void)
* Each test should be able to specify its lead CPU in the tests.xml
* file. For now, hard-code the lead CPU to always be the primary core.
*/
- lead_cpu_mpid = read_mpidr_el1() & 0xFFFFFF;
+ lead_cpu_mpid = read_mpidr_el1() & MPID_MASK;
/*
* Hand over to lead CPU if required.
@@ -589,7 +589,7 @@ void __dead2 tftf_cold_boot_main(void)
* 1) Power on the lead CPU
* 2) Power down the primary CPU
*/
- if ((read_mpidr_el1() & MPIDR_AFFINITY_MASK) != lead_cpu_mpid) {
+ if ((read_mpidr_el1() & MPID_MASK) != lead_cpu_mpid) {
hand_over_to_lead_cpu();
bug_unreachable();
}
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 16a6cf1..d292537 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, 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:
@@ -46,6 +46,7 @@
/*******************************************************************************
* MPIDR macros
******************************************************************************/
+#define MPIDR_MT_MASK (1 << 24)
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
#define MPIDR_AFFINITY_BITS 8
@@ -77,7 +78,10 @@
/* Constant to highlight the assumption that MPIDR allocation starts from 0 */
#define FIRST_MPIDR 0
-#define MPID_MASK (MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+#define MPID_MASK (MPIDR_MT_MASK |\
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)|\
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)|\
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT))
/*
* An invalid MPID. This value can be used by functions that return an MPID to
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 20cb089..a2c0fc8 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, 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:
@@ -44,8 +44,10 @@
/*******************************************************************************
* MPIDR macros
******************************************************************************/
+#define MPIDR_MT_MASK (1 << 24)
#define MPIDR_CPU_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)
+#define MPIDR_AFFINITY_BITS 8
#define MPIDR_AFFLVL_MASK 0xff
#define MPIDR_AFF0_SHIFT 0
#define MPIDR_AFF1_SHIFT 8
@@ -64,8 +66,9 @@
/* Constant to highlight the assumption that MPIDR allocation starts from 0 */
#define FIRST_MPIDR 0
-#define MPID_MASK ((MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) | \
- (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | \
+#define MPID_MASK (MPIDR_MT_MASK |\
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)|\
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)|\
(MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT))
#define MPIDR_AFF_ID(mpid, n) \
diff --git a/include/lib/tftf_lib.h b/include/lib/tftf_lib.h
index 54466ac..95982bf 100644
--- a/include/lib/tftf_lib.h
+++ b/include/lib/tftf_lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#ifndef __ASSEMBLY__
#include <arch.h>
+#include <arch_helpers.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
@@ -199,8 +200,18 @@ unsigned int tftf_is_rebooted(void);
static inline unsigned int make_mpid(unsigned int clusterid,
unsigned int coreid)
{
- return ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT) |
- ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT);
+ /*
+ * If MT bit is set then need to shift the affinities and also set the
+ * MT bit.
+ */
+ if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0)
+ return MPIDR_MT_MASK |
+ ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF2_SHIFT) |
+ ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT);
+ else
+ return ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT) |
+ ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT);
+
}
#endif /* __ASSEMBLY__ */
diff --git a/plat/arm/board/fvp/aarch32/plat_helpers.S b/plat/arm/board/fvp/aarch32/plat_helpers.S
new file mode 100644
index 0000000..5b4f91a
--- /dev/null
+++ b/plat/arm/board/fvp/aarch32/plat_helpers.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, 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 <arch.h>
+#include <asm_macros.S>
+#include "../fvp_def.h"
+
+ .globl platform_get_core_pos
+
+/*-----------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on FVP.
+ *
+ * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
+ * (CPUId * FVP_MAX_PE_PER_CPU) +
+ * ThreadId
+ * -----------------------------------------------------
+ */
+func platform_get_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation
+ */
+ tst r0, #MPIDR_MT_MASK
+ mov r3, r0
+ lsleq r3, r0, #MPIDR_AFFINITY_BITS
+
+ /* Extract individual affinity fields from MPIDR */
+ mov r2, #FVP_MAX_PE_PER_CPU
+ ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ mla r0, r1, r2, r0
+
+ mov r1, #FVP_MAX_CPUS_PER_CLUSTER
+ ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ mla r0, r1, r2, r0
+
+ bx lr
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/fvp/aarch64/plat_helpers.S b/plat/arm/board/fvp/aarch64/plat_helpers.S
new file mode 100644
index 0000000..f4c60fb
--- /dev/null
+++ b/plat/arm/board/fvp/aarch64/plat_helpers.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, 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 <arch.h>
+#include <asm_macros.S>
+#include "../fvp_def.h"
+
+ .globl platform_get_core_pos
+
+/*-----------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on FVP.
+ *
+ * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
+ * (CPUId * FVP_MAX_PE_PER_CPU) +
+ * ThreadId
+ * -----------------------------------------------------
+ */
+func platform_get_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x3, #FVP_MAX_PE_PER_CPU
+ madd x0, x1, x3, x0
+ mov x3, #FVP_MAX_CPUS_PER_CLUSTER
+ madd x0, x2, x3, x0
+ ret
+endfunc platform_get_core_pos
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index b5e309c..2ac2862 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/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-2018, 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:
@@ -43,6 +43,8 @@
#define FVP_MAX_CPUS_PER_CLUSTER 4
/* Currently the highest cluster count on the FVP is 4 (Quad cluster) */
#define FVP_CLUSTER_COUNT 4
+/* Currently multi-threaded CPUs only have a single thread */
+#define FVP_MAX_PE_PER_CPU 1
/*******************************************************************************
* FVP memory map related constants
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 5bdb7ad..1920b58 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2018, 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:
@@ -38,6 +38,7 @@ PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
drivers/arm/timer/system_timer.c \
lib/semihosting/${ARCH}/semihosting_call.S \
lib/semihosting/semihosting.c \
+ plat/arm/board/fvp/${ARCH}/plat_helpers.S \
plat/arm/board/fvp/fvp_pwr_state.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/plat_setup.c
diff --git a/plat/common/aarch32/platform_mp_stack.S b/plat/common/aarch32/platform_mp_stack.S
index 497828f..94ef15d 100644
--- a/plat/common/aarch32/platform_mp_stack.S
+++ b/plat/common/aarch32/platform_mp_stack.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, 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:
@@ -49,10 +49,10 @@
* -----------------------------------------------------
*/
func platform_set_coherent_stack
- mov r3, lr
+ mov r9, lr
get_mp_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE
mov sp, r0
- bx r3
+ bx r9
endfunc platform_set_coherent_stack
/* -----------------------------------------------------
@@ -63,9 +63,9 @@ endfunc platform_set_coherent_stack
* -----------------------------------------------------
*/
func platform_get_stack
- mov r3, lr
+ mov r9, lr
get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
- bx r3
+ bx r9
endfunc platform_get_stack
/* -----------------------------------------------------
@@ -76,10 +76,10 @@ endfunc platform_get_stack
* -----------------------------------------------------
*/
func platform_set_stack
- mov r3, lr
+ mov r9, lr
get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
mov sp, r0
- bx r3
+ bx r9
endfunc platform_set_stack
/* -----------------------------------------------------
diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S
index 8571b17..c560838 100644
--- a/plat/common/aarch64/platform_mp_stack.S
+++ b/plat/common/aarch64/platform_mp_stack.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, 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:
@@ -50,10 +50,10 @@
* -----------------------------------------------------
*/
func platform_set_coherent_stack
- mov x5, x30 // lr
+ mov x9, x30 // lr
get_mp_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE
mov sp, x0
- ret x5
+ ret x9
endfunc platform_set_coherent_stack
/* -----------------------------------------------------