[PATCH 11/13] powerpc/476: Software workaround to fix dcr read/write sequencing.
Dave Kleikamp
shaggy at linux.vnet.ibm.com
Sat Mar 6 07:43:59 EST 2010
powerpc/476: Software workaround to fix dcr read/write sequencing.
From: Dave Kleikamp <shaggy at linux.vnet.ibm.com>
Copy the register containing the dcr address to a spr before mfdcrx or
mtdcrx instruction. SPRN_SPRG_WSCRATCH_CRIT seems safe enough to use
as a dummy register, as it is only otherwise used by critical interrupts,
and we don't care if what we write is overwritten.
Ideally, would only do this when CPU_FTR_476_DD1_1 is set, but I'm not
getting the feature macros working in inlined assembler. The dummy store
is pretty cheap though, so I'm doing it unconditionally for 47x.
Signed-off-by: Dave Kleikamp <shaggy at linux.vnet.ibm.com>
---
arch/powerpc/include/asm/dcr-native.h | 24 ++++++++++++++++++++++--
1 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/dcr-native.h b/arch/powerpc/include/asm/dcr-native.h
index 7d2e623..768ce50 100644
--- a/arch/powerpc/include/asm/dcr-native.h
+++ b/arch/powerpc/include/asm/dcr-native.h
@@ -50,14 +50,34 @@ extern unsigned int __mfdcr(unsigned int reg);
static inline unsigned int mfdcrx(unsigned int reg)
{
unsigned int ret;
- asm volatile(".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
+ asm volatile(
+#ifdef CONFIG_PPC_47x
+ /*
+ * Workaround: move reg to an spr prior to mfdcrx instruction
+ */
+ /* __stringify(BEGIN_FTR_SECTION) */
+ "mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;"
+ /* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */
+#endif
+ ".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
: "=r" (ret) : "r" (reg));
return ret;
}
static inline void mtdcrx(unsigned int reg, unsigned int val)
{
- asm volatile(".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
+ asm volatile(
+#ifdef CONFIG_PPC_47x
+ /*
+ * Workaround: move reg to an spr prior to mtdcrx instruction.
+ * (Would love to get the FTR_SECTION macros working for
+ * inlined assembler -- shaggy)
+ */
+ /* __stringify(BEGIN_FTR_SECTION) */
+ "mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;"
+ /* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */
+#endif
+ ".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
: : "r" (val), "r" (reg));
}
--
Dave Kleikamp
IBM Linux Technology Center
More information about the Linuxppc-dev
mailing list