From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EBFF4DDF00 for ; Tue, 24 Feb 2009 03:23:50 +1100 (EST) Message-Id: <4D5EBD87-688D-4447-A52C-0494B9B9CC4A@kernel.crashing.org> From: Kumar Gala To: Benjamin Herrenschmidt In-Reply-To: <1235357031.8805.222.camel@pasglop> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Mime-Version: 1.0 (Apple Message framework v930.3) Subject: Re: [PATCH] powerpc: Add support for using doorbells for SMP IPI Date: Mon, 23 Feb 2009 10:23:40 -0600 References: <1234482893-17712-1-git-send-email-galak@kernel.crashing.org> <1235357031.8805.222.camel@pasglop> Cc: linuxppc-dev@ozlabs.org List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Feb 22, 2009, at 8:43 PM, Benjamin Herrenschmidt wrote: > On Thu, 2009-02-12 at 17:54 -0600, Kumar Gala wrote: >> The e500mc supports the new msgsnd/doorbell mechanisms that were >> added in >> the Power ISA 2.05 architecture. We use the normal level doorbell >> for >> doing SMP IPIs at this point. > > Any reason why you don't use the tag ? I'm not too familiar with the > doorbell stuff just yet but can't you use that instead of doing those > atomics ? tag just conveys the type of doorbell (normal, critical, etc.). So for the 4 IPI msgs we support we need software to keep track. > On thing we also need to look at is change our low level msg send to > take a CPU mask. > > This will be better generically and we need a good cpu mask based IPI > for the TLB stuff anyway. Volunteer ? :-) yeah.. It something on the list :) - k >> Signed-off-by: Kumar Gala >> --- >> arch/powerpc/include/asm/cputable.h | 4 ++- >> arch/powerpc/include/asm/dbell.h | 43 ++++++++++++++++++++++++ >> +++++++++ >> arch/powerpc/kernel/Makefile | 2 +- >> arch/powerpc/kernel/dbell.c | 44 ++++++++++++++++++++++++ >> ++++++++++ >> arch/powerpc/kernel/head_fsl_booke.S | 6 ++++- >> arch/powerpc/kernel/traps.c | 21 ++++++++++++++++ >> 6 files changed, 117 insertions(+), 3 deletions(-) >> create mode 100644 arch/powerpc/include/asm/dbell.h >> create mode 100644 arch/powerpc/kernel/dbell.c >> >> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/ >> include/asm/cputable.h >> index 4911104..fca1611 100644 >> --- a/arch/powerpc/include/asm/cputable.h >> +++ b/arch/powerpc/include/asm/cputable.h >> @@ -145,6 +145,7 @@ extern const char *powerpc_base_platform; >> #define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040) >> #define CPU_FTR_L2CSR ASM_CONST(0x0000000000000080) >> #define CPU_FTR_601 ASM_CONST(0x0000000000000100) >> +#define CPU_FTR_DBELL ASM_CONST(0x0000000000000200) >> #define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400) >> #define CPU_FTR_L3CR ASM_CONST(0x0000000000000800) >> #define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000) >> @@ -373,7 +374,8 @@ extern const char *powerpc_base_platform; >> CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) >> #define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ >> CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \ >> - CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE) >> + CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ >> + CPU_FTR_DBELL) >> #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) >> >> /* 64-bit CPUs */ >> diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/ >> include/asm/dbell.h >> new file mode 100644 >> index 0000000..501189a >> --- /dev/null >> +++ b/arch/powerpc/include/asm/dbell.h >> @@ -0,0 +1,43 @@ >> +/* >> + * Copyright 2009 Freescale Semicondutor, Inc. >> + * >> + * This program is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU General Public License >> + * as published by the Free Software Foundation; either version >> + * 2 of the License, or (at your option) any later version. >> + * >> + * provides masks and opcode images for use by code generation, >> emulation >> + * and for instructions that older assemblers might not know about >> + */ >> +#ifndef _ASM_POWERPC_DBELL_H >> +#define _ASM_POWERPC_DBELL_H >> + >> +#include >> +#include >> + >> +#include >> + >> +#define PPC_DBELL_MSG_BRDCAST (0x04000000) >> +#define PPC_DBELL_TYPE(x) (((x) & 0xf) << 28) >> +enum ppc_dbell { >> + PPC_DBELL = 0, /* doorbell */ >> + PPC_DBELL_CRIT = 1, /* critical doorbell */ >> + PPC_G_DBELL = 2, /* guest doorbell */ >> + PPC_G_DBELL_CRIT = 3, /* guest critical doorbell */ >> + PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ >> +}; >> + >> +#ifdef CONFIG_SMP >> +extern unsigned long dbell_smp_message[NR_CPUS]; >> +extern void smp_dbell_message_pass(int target, int msg); >> +#endif >> + >> +static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 >> tag) >> +{ >> + u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) | >> + (tag & 0x07ffffff); >> + >> + __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg)); >> +} >> + >> +#endif /* _ASM_POWERPC_DBELL_H */ >> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/ >> Makefile >> index d159921..f420844 100644 >> --- a/arch/powerpc/kernel/Makefile >> +++ b/arch/powerpc/kernel/Makefile >> @@ -61,7 +61,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ >> obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o >> obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o >> obj-$(CONFIG_44x) += cpu_setup_44x.o >> -obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o >> +obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o >> >> extra-$(CONFIG_PPC_STD_MMU) := head_32.o >> extra-$(CONFIG_PPC64) := head_64.o >> diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/ >> dbell.c >> new file mode 100644 >> index 0000000..1493734 >> --- /dev/null >> +++ b/arch/powerpc/kernel/dbell.c >> @@ -0,0 +1,44 @@ >> +/* >> + * Author: Kumar Gala >> + * >> + * Copyright 2009 Freescale Semiconductor Inc. >> + * >> + * This program is free software; you can redistribute it and/or >> modify it >> + * under the terms of the GNU General Public License as >> published by the >> + * Free Software Foundation; either version 2 of the License, or >> (at your >> + * option) any later version. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#ifdef CONFIG_SMP >> +unsigned long dbell_smp_message[NR_CPUS]; >> + >> +void smp_dbell_message_pass(int target, int msg) >> +{ >> + int i; >> + >> + if(target < NR_CPUS) { >> + set_bit(msg, &dbell_smp_message[target]); >> + ppc_msgsnd(PPC_DBELL, 0, target); >> + } >> + else if(target == MSG_ALL_BUT_SELF) { >> + for_each_online_cpu(i) { >> + if (i == smp_processor_id()) >> + continue; >> + set_bit(msg, &dbell_smp_message[i]); >> + ppc_msgsnd(PPC_DBELL, 0, i); >> + } >> + } >> + else { /* target == MSG_ALL */ >> + for_each_online_cpu(i) >> + set_bit(msg, &dbell_smp_message[i]); >> + ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); >> + } >> +} >> +#endif >> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/ >> kernel/head_fsl_booke.S >> index 4ea6e1a..4c22620 100644 >> --- a/arch/powerpc/kernel/head_fsl_booke.S >> +++ b/arch/powerpc/kernel/head_fsl_booke.S >> @@ -698,7 +698,9 @@ interrupt_base: >> /* Performance Monitor */ >> EXCEPTION(0x2060, PerformanceMonitor, >> performance_monitor_exception, EXC_XFER_STD) >> >> - EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD) >> + EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD) >> + >> + CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception) >> >> /* Debug Interrupt */ >> DEBUG_DEBUG_EXCEPTION >> @@ -921,6 +923,8 @@ _GLOBAL(__setup_e500mc_ivors) >> mtspr SPRN_IVOR35,r3 >> li r3,Doorbell@l >> mtspr SPRN_IVOR36,r3 >> + li r3,CriticalDoorbell@l >> + mtspr SPRN_IVOR37,r3 >> sync >> blr >> >> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/ >> traps.c >> index 970d66e..678fbff 100644 >> --- a/arch/powerpc/kernel/traps.c >> +++ b/arch/powerpc/kernel/traps.c >> @@ -53,6 +53,9 @@ >> #endif >> #include >> #include >> +#ifdef CONFIG_FSL_BOOKE >> +#include >> +#endif >> >> #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) >> int (*__debugger)(struct pt_regs *regs); >> @@ -1122,6 +1125,24 @@ void vsx_assist_exception(struct pt_regs >> *regs) >> #endif /* CONFIG_VSX */ >> >> #ifdef CONFIG_FSL_BOOKE >> + >> +void doorbell_exception(struct pt_regs *regs) >> +{ >> +#ifdef CONFIG_SMP >> + int cpu = smp_processor_id(); >> + int msg; >> + >> + if (num_online_cpus() < 2) >> + return; >> + >> + for (msg = 0; msg < 4; msg++) >> + if (test_and_clear_bit(msg, &dbell_smp_message[cpu])) >> + smp_message_recv(msg); >> +#else >> + printk(KERN_WARNING "Received doorbell on non-smp system\n"); >> +#endif >> +} >> + >> void CacheLockingException(struct pt_regs *regs, unsigned long >> address, >> unsigned long error_code) >> {