Commit d8d6cf24 authored by Summer Qin's avatar Summer Qin
Browse files

ARM platforms: Add support for MT bit in MPIDR



This patch modifies some of the functions in ARM platform layer to cater
for the case when multi-threading `MT` is set in MPIDR. A new build flag
`ARM_PLAT_MT` is added, and when enabled, the functions accessing MPIDR
now assume that the `MT` bit is set for the platform and access the bit
fields accordingly.

Also, a new API plat_arm_get_cpu_pe_count is added when `ARM_PLAT_MT` is
enabled, returning the PE count within the physical cpu corresponding to
`mpidr`.

Change-Id: I04ccf212ac3054a60882761f4087bae299af13cb
Signed-off-by: default avatarSummer Qin <summer.qin@arm.com>
parent d6845d3d
...@@ -197,6 +197,12 @@ performed. ...@@ -197,6 +197,12 @@ performed.
by the interrupt management framework. Default is 2 (that is, version 2.0). by the interrupt management framework. Default is 2 (that is, version 2.0).
This build option is deprecated. 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 * `ASM_ASSERTION`: This flag determines whether the assertion checks within
assembly source files are enabled or not. This option defaults to the 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 value of `DEBUG` - that is, by default this is only enabled for a debug
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
/******************************************************************************* /*******************************************************************************
* MPIDR macros * MPIDR macros
******************************************************************************/ ******************************************************************************/
#define MPIDR_MT_MASK (1 << 24)
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK #define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS) #define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
#define MPIDR_AFFINITY_BITS 8 #define MPIDR_AFFINITY_BITS 8
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
/******************************************************************************* /*******************************************************************************
* MPIDR macros * MPIDR macros
******************************************************************************/ ******************************************************************************/
#define MPIDR_MT_MASK (1 << 24)
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK #define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
#define MPIDR_CLUSTER_MASK MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS #define MPIDR_CLUSTER_MASK MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS
#define MPIDR_AFFINITY_BITS 8 #define MPIDR_AFFINITY_BITS 8
......
/* /*
* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -203,6 +203,10 @@ void plat_arm_interconnect_init(void); ...@@ -203,6 +203,10 @@ void plat_arm_interconnect_init(void);
void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_enter_coherency(void);
void plat_arm_interconnect_exit_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 #if LOAD_IMAGE_V2
/* /*
* This function is called after loading SCP_BL2 image and it is used to perform * This function is called after loading SCP_BL2 image and it is used to perform
......
...@@ -90,6 +90,11 @@ ARM_BL31_IN_DRAM := 0 ...@@ -90,6 +90,11 @@ ARM_BL31_IN_DRAM := 0
$(eval $(call assert_boolean,ARM_BL31_IN_DRAM)) $(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
$(eval $(call add_define,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_COUNT/RESIDENCY APIs on ARM platforms
ENABLE_PSCI_STAT := 1 ENABLE_PSCI_STAT := 1
ENABLE_PMF := 1 ENABLE_PMF := 1
......
/* /*
* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -40,14 +40,26 @@ ...@@ -40,14 +40,26 @@
int arm_check_mpidr(u_register_t mpidr) int arm_check_mpidr(u_register_t mpidr)
{ {
unsigned int cluster_id, cpu_id; unsigned int cluster_id, cpu_id;
uint64_t valid_mask;
mpidr &= MPIDR_AFFINITY_MASK; #if ARM_PLAT_MT
unsigned int pe_id;
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
return -1;
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; cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF0_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) if (cluster_id >= PLAT_ARM_CLUSTER_COUNT)
return -1; return -1;
...@@ -57,5 +69,10 @@ int arm_check_mpidr(u_register_t mpidr) ...@@ -57,5 +69,10 @@ int arm_check_mpidr(u_register_t mpidr)
if (cpu_id >= plat_arm_get_cluster_core_count(mpidr)) if (cpu_id >= plat_arm_get_cluster_core_count(mpidr))
return -1; return -1;
#if ARM_PLAT_MT
if (pe_id >= plat_arm_get_cpu_pe_count(mpidr))
return -1;
#endif /* ARM_PLAT_MT */
return 0; return 0;
} }
/* /*
* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#include <plat_arm.h> #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 * 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 * 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) ...@@ -43,3 +47,14 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
return -1; 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 */
...@@ -150,8 +150,18 @@ void scpi_set_css_power_state(unsigned int mpidr, ...@@ -150,8 +150,18 @@ void scpi_set_css_power_state(unsigned int mpidr,
uint32_t state = 0; uint32_t state = 0;
uint32_t *payload_addr; 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 & 0x0f; /* CPU ID */
state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ state |= (mpidr & 0xf00) >> 4; /* Cluster ID */
#endif /* ARM_PLAT_MT */
state |= cpu_state << 8; state |= cpu_state << 8;
state |= cluster_state << 12; state |= cluster_state << 12;
state |= css_state << 16; state |= css_state << 16;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment