arch/arm64: send sgi with correct aff and target list
armv8r and armv8a have different process affinity, and sgi affinity needs to be able to adapt all of them. Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
parent
ea98e5a92e
commit
f8b5fd2a9a
@ -69,6 +69,8 @@
|
||||
|
||||
#define CONFIG_LOAD_BASE 0x00000000
|
||||
|
||||
#define MPID_TO_CLUSTER_ID(mpid) ((mpid) & ~0xff)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM64_INCLUDE_FVP_V8R_CHIP_H */
|
||||
|
@ -59,6 +59,8 @@
|
||||
|
||||
#define CONFIG_LOAD_BASE 0x40280000
|
||||
|
||||
#define MPID_TO_CLUSTER_ID(mpid) ((mpid) & ~0xff)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM64_INCLUDE_QEMU_CHIP_H */
|
||||
|
@ -150,6 +150,7 @@
|
||||
/* MPIDR_EL1, Multiprocessor Affinity Register */
|
||||
|
||||
#define MPIDR_AFFLVL_MASK (0xff)
|
||||
#define MPIDR_ID_MASK (0xff00ffffff)
|
||||
|
||||
#define MPIDR_AFF0_SHIFT (0)
|
||||
#define MPIDR_AFF1_SHIFT (8)
|
||||
@ -180,7 +181,13 @@
|
||||
(((mpid) >> MPIDR_AFF ## aff_level ## _SHIFT) & MPIDR_AFFLVL_MASK)
|
||||
|
||||
#define CORE_TO_MPID(core, aff_level) \
|
||||
(((core) << MPIDR_AFF ## aff_level ## _SHIFT))
|
||||
({ \
|
||||
uint64_t __mpidr = GET_MPIDR(); \
|
||||
__mpidr &= ~(MPIDR_AFFLVL_MASK << MPIDR_AFF ## aff_level ## _SHIFT); \
|
||||
__mpidr |= (cpu << MPIDR_AFF ## aff_level ## _SHIFT); \
|
||||
__mpidr &= MPIDR_ID_MASK; \
|
||||
__mpidr; \
|
||||
})
|
||||
|
||||
/* System register interface to GICv3 */
|
||||
|
||||
@ -561,6 +568,8 @@ void arm64_cpu_enable(void);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
uint64_t arm64_get_mpid(int cpu);
|
||||
#else
|
||||
# define arm64_get_mpid(cpu) GET_MPIDR()
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -30,8 +30,16 @@
|
||||
#include "arm64_internal.h"
|
||||
#include "arm64_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern void *_vector_table[];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -247,7 +247,6 @@ int arm64_pause_handler(int irq, void *context, void *arg)
|
||||
int up_cpu_pause(int cpu)
|
||||
{
|
||||
int ret;
|
||||
uint64_t mpidr = GET_MPIDR();
|
||||
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||
|
||||
@ -273,7 +272,7 @@ int up_cpu_pause(int cpu)
|
||||
|
||||
/* Execute SGI2 */
|
||||
|
||||
ret = arm64_gic_raise_sgi(SGI_CPU_PAUSE, mpidr, (1 << cpu));
|
||||
ret = arm64_gic_raise_sgi(SGI_CPU_PAUSE, (1 << cpu));
|
||||
if (ret < 0)
|
||||
{
|
||||
/* What happened? Unlock the g_cpu_wait spinlock */
|
||||
|
@ -307,8 +307,7 @@ int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags);
|
||||
|
||||
uint64_t * arm64_decodeirq(uint64_t *regs);
|
||||
|
||||
int arm64_gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
|
||||
uint16_t target_list);
|
||||
int arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
|
@ -303,7 +303,7 @@ void arm64_gic_eoi(unsigned int intid)
|
||||
write_sysreg(intid, ICC_EOIR1_EL1);
|
||||
}
|
||||
|
||||
int arm64_gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
|
||||
static int arm64_gic_send_sgi(unsigned int sgi_id, uint64_t target_aff,
|
||||
uint16_t target_list)
|
||||
{
|
||||
uint32_t aff3;
|
||||
@ -329,6 +329,41 @@ int arm64_gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list)
|
||||
{
|
||||
uint64_t pre_cluster_id = UINT64_MAX;
|
||||
uint64_t curr_cluster_id;
|
||||
uint64_t curr_mpidr;
|
||||
uint16_t tlist = 0;
|
||||
uint16_t cpu = 0;
|
||||
uint16_t i;
|
||||
|
||||
while ((i = ffs(target_list)))
|
||||
{
|
||||
cpu += (i - 1);
|
||||
|
||||
target_list >>= i;
|
||||
|
||||
curr_mpidr = arm64_get_mpid(cpu);
|
||||
curr_cluster_id = MPID_TO_CLUSTER_ID(curr_mpidr);
|
||||
|
||||
if (pre_cluster_id != UINT64_MAX &&
|
||||
pre_cluster_id != curr_cluster_id)
|
||||
{
|
||||
arm64_gic_send_sgi(sgi_id, pre_cluster_id, tlist);
|
||||
}
|
||||
|
||||
tlist |= 1 << (curr_mpidr & MPIDR_AFFLVL_MASK);
|
||||
|
||||
cpu += i;
|
||||
pre_cluster_id = curr_cluster_id;
|
||||
}
|
||||
|
||||
arm64_gic_send_sgi(sgi_id, pre_cluster_id, tlist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wake up GIC redistributor.
|
||||
* clear ProcessorSleep and wait till ChildAsleep is cleared.
|
||||
* ProcessSleep to be cleared only when ChildAsleep is set
|
||||
@ -597,13 +632,12 @@ void up_affinity_irq(int irq, cpu_set_t cpuset)
|
||||
|
||||
void up_trigger_irq(int irq, cpu_set_t cpuset)
|
||||
{
|
||||
uint64_t mpidr = GET_MPIDR();
|
||||
uint32_t mask = BIT(irq & (GIC_NUM_INTR_PER_REG - 1));
|
||||
uint32_t idx = irq / GIC_NUM_INTR_PER_REG;
|
||||
|
||||
if (GIC_IS_SGI(irq))
|
||||
{
|
||||
arm64_gic_raise_sgi(irq, mpidr, cpuset);
|
||||
arm64_gic_raise_sgi(irq, cpuset);
|
||||
}
|
||||
else if (irq >= 0 && irq < NR_IRQS)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user