[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC V2 1/4] Use Aff1 with mpidr
From: |
shlomopongratz |
Subject: |
[Qemu-devel] [PATCH RFC V2 1/4] Use Aff1 with mpidr |
Date: |
Wed, 6 May 2015 17:04:39 +0300 |
From: Shlomo Pongratz <address@hidden>
In order to support up to 128 cores with GIC-500 (GICv3 implementation)
affinity1 must be used. GIC-500 support up to 32 clusters with up to
8 cores in a cluster. So for example, if one wishes to have 16 cores,
the options are: 2 clusters of 8 cores each, 4 clusters with 4 cores each
Currently only the first option is supported.
In order to have more flexible scheme the virt machine must pass the
desired scheme.
Signed-off-by: Shlomo Pongratz <address@hidden>
---
target-arm/helper.c | 12 ++++++++++--
target-arm/psci.c | 18 ++++++++++++++++--
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f8f8d76..f555c0b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2035,11 +2035,19 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
CPUState *cs = CPU(arm_env_get_cpu(env));
- uint32_t mpidr = cs->cpu_index;
- /* We don't support setting cluster ID ([8..11]) (known as Aff1
+ uint32_t mpidr, aff0, aff1;
+ uint32_t cpuid = cs->cpu_index;
+ /* We don't support setting cluster ID ([16..23]) (known as Aff2
* in later ARM ARM versions), or any of the higher affinity level fields,
* so these bits always RAZ.
*/
+ /* Currently GIC-500 code supports 64 cores in 16 clusters with 8 cores
each
+ * Future code will remove this limitation.
+ * This code is valid for GIC-400 too.
+ */
+ aff0 = cpuid % 8;
+ aff1 = cpuid / 8;
+ mpidr = (aff1 << 8) | aff0;
if (arm_feature(env, ARM_FEATURE_V7MP)) {
mpidr |= (1U << 31);
/* Cores which are uniprocessor (non-coherent)
diff --git a/target-arm/psci.c b/target-arm/psci.c
index d8fafab..64fbe61 100644
--- a/target-arm/psci.c
+++ b/target-arm/psci.c
@@ -86,6 +86,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
CPUARMState *env = &cpu->env;
uint64_t param[4];
uint64_t context_id, mpidr;
+ uint32_t core, Aff1, Aff0;
target_ulong entry;
int32_t ret = 0;
int i;
@@ -121,7 +122,16 @@ void arm_handle_psci_call(ARMCPU *cpu)
switch (param[2]) {
case 0:
- target_cpu_state = qemu_get_cpu(mpidr & 0xff);
+ /* MPIDR_EL1 [RES0:affinity-3:RES1:U:RES0:MT:affinity-1:affinity-0]
+ * GIC 500 code currently supports 32 clusters with 8 cores each
+ * but no more than 128 cores. Future version will have flexible
+ * affinity selection
+ * GIC 400 supports 8 cores so 0x7 for Aff0 is O.K. too
+ */
+ Aff1 = (mpidr & 0xff00) >> (8 - 3); /* Shift by 8 multiply by 8 */
+ Aff0 = mpidr & 0x7;
+ core = Aff1 + Aff0;
+ target_cpu_state = qemu_get_cpu(core);
if (!target_cpu_state) {
ret = QEMU_PSCI_RET_INVALID_PARAMS;
break;
@@ -153,7 +163,11 @@ void arm_handle_psci_call(ARMCPU *cpu)
context_id = param[3];
/* change to the cpu we are powering up */
- target_cpu_state = qemu_get_cpu(mpidr & 0xff);
+ /* Currently supports 64 cores in 16 clusters with 8 cores each */
+ Aff1 = (mpidr & 0xff00) >> (8 - 3); /* Shift by 8 multiply by 8 */
+ Aff0 = mpidr & 0x7;
+ core = Aff1 + Aff0;
+ target_cpu_state = qemu_get_cpu(core);
if (!target_cpu_state) {
ret = QEMU_PSCI_RET_INVALID_PARAMS;
break;
--
1.9.1