powerpc/powernv: POWER9 support for msgsnd/doorbell IPI
POWER9 requires msgsync for receiver-side synchronization, and a DD1 workaround restricts IPIs to core-local. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> [mpe: Drop no longer needed asm feature macro changes] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
a5adf28246
commit
6b3edefefa
|
@ -51,6 +51,9 @@ static inline void ppc_msgsnd_sync(void)
|
||||||
/* sync after taking message interrupt */
|
/* sync after taking message interrupt */
|
||||||
static inline void ppc_msgsync(void)
|
static inline void ppc_msgsync(void)
|
||||||
{
|
{
|
||||||
|
/* sync is not required when taking messages from the same core */
|
||||||
|
__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSYNC " ; lwsync", "", %0)
|
||||||
|
: : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_PPC_BOOK3S */
|
#else /* CONFIG_PPC_BOOK3S */
|
||||||
|
|
|
@ -161,6 +161,7 @@
|
||||||
#define PPC_INST_MFTMR 0x7c0002dc
|
#define PPC_INST_MFTMR 0x7c0002dc
|
||||||
#define PPC_INST_MSGSND 0x7c00019c
|
#define PPC_INST_MSGSND 0x7c00019c
|
||||||
#define PPC_INST_MSGCLR 0x7c0001dc
|
#define PPC_INST_MSGCLR 0x7c0001dc
|
||||||
|
#define PPC_INST_MSGSYNC 0x7c0006ec
|
||||||
#define PPC_INST_MSGSNDP 0x7c00011c
|
#define PPC_INST_MSGSNDP 0x7c00011c
|
||||||
#define PPC_INST_MTTMR 0x7c0003dc
|
#define PPC_INST_MTTMR 0x7c0003dc
|
||||||
#define PPC_INST_NOP 0x60000000
|
#define PPC_INST_NOP 0x60000000
|
||||||
|
@ -345,6 +346,7 @@
|
||||||
___PPC_RB(b) | __PPC_EH(eh))
|
___PPC_RB(b) | __PPC_EH(eh))
|
||||||
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
|
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
|
||||||
___PPC_RB(b))
|
___PPC_RB(b))
|
||||||
|
#define PPC_MSGSYNC stringify_in_c(.long PPC_INST_MSGSYNC)
|
||||||
#define PPC_MSGCLR(b) stringify_in_c(.long PPC_INST_MSGCLR | \
|
#define PPC_MSGCLR(b) stringify_in_c(.long PPC_INST_MSGCLR | \
|
||||||
___PPC_RB(b))
|
___PPC_RB(b))
|
||||||
#define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \
|
#define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \
|
||||||
|
|
|
@ -257,6 +257,23 @@ static void pnv_cause_ipi(int cpu)
|
||||||
icp_ops->cause_ipi(cpu);
|
icp_ops->cause_ipi(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pnv_p9_dd1_cause_ipi(int cpu)
|
||||||
|
{
|
||||||
|
int this_cpu = get_cpu();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POWER9 DD1 has a global addressed msgsnd, but for now we restrict
|
||||||
|
* IPIs to same core, because it requires additional synchronization
|
||||||
|
* for inter-core doorbells which we do not implement.
|
||||||
|
*/
|
||||||
|
if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu)))
|
||||||
|
doorbell_global_ipi(cpu);
|
||||||
|
else
|
||||||
|
icp_ops->cause_ipi(cpu);
|
||||||
|
|
||||||
|
put_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
static void __init pnv_smp_probe(void)
|
static void __init pnv_smp_probe(void)
|
||||||
{
|
{
|
||||||
if (xive_enabled())
|
if (xive_enabled())
|
||||||
|
@ -264,8 +281,15 @@ static void __init pnv_smp_probe(void)
|
||||||
else
|
else
|
||||||
xics_smp_probe();
|
xics_smp_probe();
|
||||||
|
|
||||||
if (cpu_has_feature(CPU_FTR_DBELL) && !cpu_has_feature(CPU_FTR_ARCH_300)) {
|
if (cpu_has_feature(CPU_FTR_DBELL)) {
|
||||||
smp_ops->cause_ipi = pnv_cause_ipi;
|
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||||
|
if (cpu_has_feature(CPU_FTR_POWER9_DD1))
|
||||||
|
smp_ops->cause_ipi = pnv_p9_dd1_cause_ipi;
|
||||||
|
else
|
||||||
|
smp_ops->cause_ipi = doorbell_global_ipi;
|
||||||
|
} else {
|
||||||
|
smp_ops->cause_ipi = pnv_cause_ipi;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
smp_ops->cause_ipi = icp_ops->cause_ipi;
|
smp_ops->cause_ipi = icp_ops->cause_ipi;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue