Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42d02b81 authored by Ian Munsie's avatar Ian Munsie Committed by Benjamin Herrenschmidt
Browse files

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: default avatarIan Munsie <imunsie@au1.ibm.com>
Tested-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 41c7b401
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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
@@ -227,6 +228,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 | \
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+2 −2
Original line number Diff line number Diff line
@@ -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)