diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2012-11-14 13:49:44 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-01-09 23:09:05 -0500 |
commit | 42d02b81f265b77be39262666c888d50cb488fc5 (patch) | |
tree | 057869a84883845ac91f536a683a0b9e9829e45c /arch/powerpc | |
parent | 41c7b401b9c131a53823673a788d73e340ce4d2a (diff) |
powerpc: Define differences between doorbells on book3e and book3s
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>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/dbell.h | 15 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc-opcode.h | 3 | ||||
-rw-r--r-- | arch/powerpc/include/asm/reg.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/dbell.c | 4 |
4 files changed, 21 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h index 607e4eeeb694..3b338565f992 100644 --- a/arch/powerpc/include/asm/dbell.h +++ b/arch/powerpc/include/asm/dbell.h | |||
@@ -28,8 +28,23 @@ enum ppc_dbell { | |||
28 | PPC_G_DBELL = 2, /* guest doorbell */ | 28 | PPC_G_DBELL = 2, /* guest doorbell */ |
29 | PPC_G_DBELL_CRIT = 3, /* guest critical doorbell */ | 29 | PPC_G_DBELL_CRIT = 3, /* guest critical doorbell */ |
30 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ | 30 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ |
31 | PPC_DBELL_SERVER = 5, /* doorbell on server */ | ||
31 | }; | 32 | }; |
32 | 33 | ||
34 | #ifdef CONFIG_PPC_BOOK3S | ||
35 | |||
36 | #define PPC_DBELL_MSGTYPE PPC_DBELL_SERVER | ||
37 | #define SPRN_DOORBELL_CPUTAG SPRN_TIR | ||
38 | #define PPC_DBELL_TAG_MASK 0x7f | ||
39 | |||
40 | #else /* CONFIG_PPC_BOOK3S */ | ||
41 | |||
42 | #define PPC_DBELL_MSGTYPE PPC_DBELL | ||
43 | #define SPRN_DOORBELL_CPUTAG SPRN_PIR | ||
44 | #define PPC_DBELL_TAG_MASK 0x3fff | ||
45 | |||
46 | #endif /* CONFIG_PPC_BOOK3S */ | ||
47 | |||
33 | extern void doorbell_cause_ipi(int cpu, unsigned long data); | 48 | extern void doorbell_cause_ipi(int cpu, unsigned long data); |
34 | extern void doorbell_exception(struct pt_regs *regs); | 49 | extern void doorbell_exception(struct pt_regs *regs); |
35 | extern void doorbell_setup_this_cpu(void); | 50 | 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 51fb00a20d7e..0fd1928efb93 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -100,6 +100,7 @@ | |||
100 | #define PPC_INST_MFSPR_PVR 0x7c1f42a6 | 100 | #define PPC_INST_MFSPR_PVR 0x7c1f42a6 |
101 | #define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff | 101 | #define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff |
102 | #define PPC_INST_MSGSND 0x7c00019c | 102 | #define PPC_INST_MSGSND 0x7c00019c |
103 | #define PPC_INST_MSGSNDP 0x7c00011c | ||
103 | #define PPC_INST_NOP 0x60000000 | 104 | #define PPC_INST_NOP 0x60000000 |
104 | #define PPC_INST_POPCNTB 0x7c0000f4 | 105 | #define PPC_INST_POPCNTB 0x7c0000f4 |
105 | #define PPC_INST_POPCNTB_MASK 0xfc0007fe | 106 | #define PPC_INST_POPCNTB_MASK 0xfc0007fe |
@@ -227,6 +228,8 @@ | |||
227 | ___PPC_RB(b) | __PPC_EH(eh)) | 228 | ___PPC_RB(b) | __PPC_EH(eh)) |
228 | #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ | 229 | #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ |
229 | ___PPC_RB(b)) | 230 | ___PPC_RB(b)) |
231 | #define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \ | ||
232 | ___PPC_RB(b)) | ||
230 | #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ | 233 | #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ |
231 | __PPC_RA(a) | __PPC_RS(s)) | 234 | __PPC_RA(a) | __PPC_RS(s)) |
232 | #define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \ | 235 | #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 3d5c9dc8917a..af88486b0c23 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -483,6 +483,7 @@ | |||
483 | #ifndef SPRN_PIR | 483 | #ifndef SPRN_PIR |
484 | #define SPRN_PIR 0x3FF /* Processor Identification Register */ | 484 | #define SPRN_PIR 0x3FF /* Processor Identification Register */ |
485 | #endif | 485 | #endif |
486 | #define SPRN_TIR 0x1BE /* Thread Identification Register */ | ||
486 | #define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ | 487 | #define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ |
487 | #define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ | 488 | #define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ |
488 | #define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */ | 489 | #define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */ |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index a892680668d8..9ebbc24bb23c 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #ifdef CONFIG_SMP | 21 | #ifdef CONFIG_SMP |
22 | void doorbell_setup_this_cpu(void) | 22 | void doorbell_setup_this_cpu(void) |
23 | { | 23 | { |
24 | unsigned long tag = mfspr(SPRN_PIR) & 0x3fff; | 24 | unsigned long tag = mfspr(SPRN_DOORBELL_CPUTAG) & PPC_DBELL_TAG_MASK; |
25 | 25 | ||
26 | smp_muxed_ipi_set_data(smp_processor_id(), tag); | 26 | smp_muxed_ipi_set_data(smp_processor_id(), tag); |
27 | } | 27 | } |
@@ -30,7 +30,7 @@ void doorbell_cause_ipi(int cpu, unsigned long data) | |||
30 | { | 30 | { |
31 | /* Order previous accesses vs. msgsnd, which is treated as a store */ | 31 | /* Order previous accesses vs. msgsnd, which is treated as a store */ |
32 | mb(); | 32 | mb(); |
33 | ppc_msgsnd(PPC_DBELL, 0, data); | 33 | ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, data); |
34 | } | 34 | } |
35 | 35 | ||
36 | void doorbell_exception(struct pt_regs *regs) | 36 | void doorbell_exception(struct pt_regs *regs) |