diff options
-rw-r--r-- | docs/user-guide.md | 6 | ||||
-rw-r--r-- | include/lib/aarch32/arch.h | 1 | ||||
-rw-r--r-- | include/lib/aarch64/arch.h | 1 | ||||
-rw-r--r-- | include/plat/arm/common/plat_arm.h | 4 | ||||
-rw-r--r-- | plat/arm/common/arm_common.mk | 5 | ||||
-rw-r--r-- | plat/arm/common/arm_topology.c | 27 | ||||
-rw-r--r-- | plat/arm/css/common/css_topology.c | 17 | ||||
-rw-r--r-- | plat/arm/css/drivers/scpi/css_scpi.c | 10 |
8 files changed, 65 insertions, 6 deletions
diff --git a/docs/user-guide.md b/docs/user-guide.md index c6c8e19b..2770b2cd 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -197,6 +197,12 @@ performed. by the interrupt management framework. Default is 2 (that is, version 2.0). This build option is deprecated. +* `ARM_PLAT_MT`: This flag determines whether the ARM platform layer has to + cater for the multi-threading `MT` bit when accessing MPIDR. When this + flag is set, the functions which deal with MPIDR assume that the `MT` bit + in MPIDR is set and access the bit-fields in MPIDR accordingly. Default + value of this flag is 0. + * `ASM_ASSERTION`: This flag determines whether the assertion checks within assembly source files are enabled or not. This option defaults to the value of `DEBUG` - that is, by default this is only enabled for a debug diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index bc492b28..234ceeba 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -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 diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index f1ad9bb4..a2c736c9 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -50,6 +50,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 diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 0b57ba81..b24af78d 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -203,6 +203,10 @@ void plat_arm_interconnect_init(void); void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_exit_coherency(void); +#if ARM_PLAT_MT +unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); +#endif + #if LOAD_IMAGE_V2 /* * This function is called after loading SCP_BL2 image and it is used to perform diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index e918e306..891e2fbd 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -90,6 +90,11 @@ ARM_BL31_IN_DRAM := 0 $(eval $(call assert_boolean,ARM_BL31_IN_DRAM)) $(eval $(call add_define,ARM_BL31_IN_DRAM)) +# Process ARM_PLAT_MT flag +ARM_PLAT_MT := 0 +$(eval $(call assert_boolean,ARM_PLAT_MT)) +$(eval $(call add_define,ARM_PLAT_MT)) + # Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms ENABLE_PSCI_STAT := 1 ENABLE_PMF := 1 diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c index 4430b139..3c952636 100644 --- a/plat/arm/common/arm_topology.c +++ b/plat/arm/common/arm_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -40,14 +40,26 @@ int arm_check_mpidr(u_register_t mpidr) { unsigned int cluster_id, cpu_id; + uint64_t valid_mask; - mpidr &= MPIDR_AFFINITY_MASK; - - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) - return -1; +#if ARM_PLAT_MT + unsigned int pe_id; + valid_mask = ~(MPIDR_AFFLVL_MASK | + (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | + (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)); + cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + pe_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; +#else + valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK); cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; +#endif /* ARM_PLAT_MT */ + + mpidr &= MPIDR_AFFINITY_MASK; + if (mpidr & valid_mask) + return -1; if (cluster_id >= PLAT_ARM_CLUSTER_COUNT) return -1; @@ -57,5 +69,10 @@ int arm_check_mpidr(u_register_t mpidr) if (cpu_id >= plat_arm_get_cluster_core_count(mpidr)) return -1; +#if ARM_PLAT_MT + if (pe_id >= plat_arm_get_cpu_pe_count(mpidr)) + return -1; +#endif /* ARM_PLAT_MT */ + return 0; } diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c index d5f0275a..9c86f893 100644 --- a/plat/arm/css/common/css_topology.c +++ b/plat/arm/css/common/css_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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,6 +30,10 @@ #include <plat_arm.h> +#if ARM_PLAT_MT +#pragma weak plat_arm_get_cpu_pe_count +#endif + /****************************************************************************** * 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 @@ -43,3 +47,14 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) return -1; } + +#if ARM_PLAT_MT +/****************************************************************************** + * This function returns the PE count within the physical cpu corresponding to + * `mpidr`. Now one cpu only have one thread, so just return 1. + *****************************************************************************/ +unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr) +{ + return 1; +} +#endif /* ARM_PLAT_MT */ diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c index 65ae978f..7c5c5789 100644 --- a/plat/arm/css/drivers/scpi/css_scpi.c +++ b/plat/arm/css/drivers/scpi/css_scpi.c @@ -150,8 +150,18 @@ void scpi_set_css_power_state(unsigned int mpidr, uint32_t state = 0; uint32_t *payload_addr; +#if ARM_PLAT_MT + /* + * The current SCPI driver only caters for single-threaded platforms. + * Hence we ignore the thread ID (which is always 0) for such platforms. + */ + state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */ + state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */ +#else state |= mpidr & 0x0f; /* CPU ID */ state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ +#endif /* ARM_PLAT_MT */ + state |= cpu_state << 8; state |= cluster_state << 12; state |= css_state << 16; |