Patchwork [1/7] powerpc: Define differences between doorbells on book3e and book3s

login
register
mail settings
Submitter Ian Munsie
Date Nov. 15, 2012, 4:49 a.m.
Message ID <1352954990-2858-2-git-send-email-imunsie@au1.ibm.com>
Download mbox | patch
Permalink /patch/199128/
State Accepted, archived
Commit 42d02b81f265b77be39262666c888d50cb488fc5
Delegated to: Benjamin Herrenschmidt
Headers show

Comments

Ian Munsie - Nov. 15, 2012, 4:49 a.m.
From: Ian Munsie <imunsie@au1.ibm.com>

There are a few key differences between doorbells on server compared
with embedded that we care about on Linux, namely:

- We have a new msgsndp instruction for directed privileged doorbells.
  msgsnd is used for directed hypervisor doorbells.
- The tag we use in the instruction is the Thread Identification
  Register of the recipient thread (since server doorbells can only
  occur between threads within a single core), and is only 7 bits wide.
- A new message type is introduced for server doorbells (none of the
  existing book3e message types are currently supported on book3s).

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/dbell.h      |   15 +++++++++++++++
 arch/powerpc/include/asm/ppc-opcode.h |    3 +++
 arch/powerpc/include/asm/reg.h        |    1 +
 arch/powerpc/kernel/dbell.c           |    4 ++--
 4 files changed, 21 insertions(+), 2 deletions(-)

Patch

diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index 607e4ee..3b33856 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -28,8 +28,23 @@  enum ppc_dbell {
 	PPC_G_DBELL = 2,	/* guest doorbell */
 	PPC_G_DBELL_CRIT = 3,	/* guest critical doorbell */
 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
+	PPC_DBELL_SERVER = 5,	/* doorbell on server */
 };
 
+#ifdef CONFIG_PPC_BOOK3S
+
+#define PPC_DBELL_MSGTYPE		PPC_DBELL_SERVER
+#define SPRN_DOORBELL_CPUTAG		SPRN_TIR
+#define PPC_DBELL_TAG_MASK		0x7f
+
+#else /* CONFIG_PPC_BOOK3S */
+
+#define PPC_DBELL_MSGTYPE		PPC_DBELL
+#define SPRN_DOORBELL_CPUTAG		SPRN_PIR
+#define PPC_DBELL_TAG_MASK		0x3fff
+
+#endif /* CONFIG_PPC_BOOK3S */
+
 extern void doorbell_cause_ipi(int cpu, unsigned long data);
 extern void doorbell_exception(struct pt_regs *regs);
 extern void doorbell_setup_this_cpu(void);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index e434d8b..45fd394 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -100,6 +100,7 @@ 
 #define PPC_INST_MFSPR_PVR		0x7c1f42a6
 #define PPC_INST_MFSPR_PVR_MASK		0xfc1fffff
 #define PPC_INST_MSGSND			0x7c00019c
+#define PPC_INST_MSGSNDP		0x7c00011c
 #define PPC_INST_NOP			0x60000000
 #define PPC_INST_POPCNTB		0x7c0000f4
 #define PPC_INST_POPCNTB_MASK		0xfc0007fe
@@ -224,6 +225,8 @@ 
 					___PPC_RB(b) | __PPC_EH(eh))
 #define PPC_MSGSND(b)		stringify_in_c(.long PPC_INST_MSGSND | \
 					___PPC_RB(b))
+#define PPC_MSGSNDP(b)		stringify_in_c(.long PPC_INST_MSGSNDP | \
+					___PPC_RB(b))
 #define PPC_POPCNTB(a, s)	stringify_in_c(.long PPC_INST_POPCNTB | \
 					__PPC_RA(a) | __PPC_RS(s))
 #define PPC_POPCNTD(a, s)	stringify_in_c(.long PPC_INST_POPCNTD | \
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1b853f7..736c6af 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -483,6 +483,7 @@ 
 #ifndef SPRN_PIR
 #define SPRN_PIR	0x3FF	/* Processor Identification Register */
 #endif
+#define SPRN_TIR	0x1BE	/* Thread Identification Register */
 #define SPRN_PTEHI	0x3D5	/* 981 7450 PTE HI word (S/W TLB load) */
 #define SPRN_PTELO	0x3D6	/* 982 7450 PTE LO word (S/W TLB load) */
 #define SPRN_PURR	0x135	/* Processor Utilization of Resources Reg */
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index a892680..9ebbc24 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -21,7 +21,7 @@ 
 #ifdef CONFIG_SMP
 void doorbell_setup_this_cpu(void)
 {
-	unsigned long tag = mfspr(SPRN_PIR) & 0x3fff;
+	unsigned long tag = mfspr(SPRN_DOORBELL_CPUTAG) & PPC_DBELL_TAG_MASK;
 
 	smp_muxed_ipi_set_data(smp_processor_id(), tag);
 }
@@ -30,7 +30,7 @@  void doorbell_cause_ipi(int cpu, unsigned long data)
 {
 	/* Order previous accesses vs. msgsnd, which is treated as a store */
 	mb();
-	ppc_msgsnd(PPC_DBELL, 0, data);
+	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, data);
 }
 
 void doorbell_exception(struct pt_regs *regs)