From 594bd38303b489156c005177ccb4af52f942e2f5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 7 Aug 2013 02:01:20 +1000 Subject: powerpc: Wrap MSR macros with parentheses Not having parentheses around a macro is asking for trouble. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/reg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc/include/asm/reg.h') diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a6840e4e24f7..a312e0c8cef4 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -115,10 +115,10 @@ #define MSR_64BIT MSR_SF /* Server variant */ -#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV -#define MSR_KERNEL MSR_ | MSR_64BIT -#define MSR_USER32 MSR_ | MSR_PR | MSR_EE -#define MSR_USER64 MSR_USER32 | MSR_64BIT +#define MSR_ (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV) +#define MSR_KERNEL (MSR_ | MSR_64BIT) +#define MSR_USER32 (MSR_ | MSR_PR | MSR_EE) +#define MSR_USER64 (MSR_USER32 | MSR_64BIT) #elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx) /* Default MSR for kernel mode. */ #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) -- cgit v1.2.3 From d52459ca3047435aa5d7957e50857fc7ba193411 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 23 Jul 2013 20:21:11 -0500 Subject: powerpc/fsl-booke: Work around erratum A-006958 Erratum A-006598 says that 64-bit mftb is not atomic -- it's subject to a similar race condition as doing mftbu/mftbl on 32-bit. The lower half of timebase is updated before the upper half; thus, we can share the workaround for a similar bug on Cell. This workaround involves looping if the lower half of timebase is zero, thus avoiding the need for a scratch register (other than CR0). This workaround must be avoided when the timebase is frozen, such as during the timebase sync code. This deals with kernel and vdso accesses, but other userspace accesses will of course need to be fixed elsewhere. Signed-off-by: Scott Wood --- arch/powerpc/include/asm/cputable.h | 9 +++++++-- arch/powerpc/include/asm/ppc_asm.h | 2 +- arch/powerpc/include/asm/reg.h | 2 +- arch/powerpc/platforms/85xx/smp.c | 23 +++++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) (limited to 'arch/powerpc/include/asm/reg.h') diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 6f3887d884d2..0d4939ba48e7 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -371,14 +371,19 @@ extern const char *powerpc_base_platform; #define CPU_FTRS_E500MC (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) +/* + * e5500/e6500 erratum A-006958 is a timebase bug that can use the + * same workaround as CPU_FTR_CELL_TB_BUG. + */ #define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ - CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) + CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_CELL_TB_BUG) #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ - CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP) + CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \ + CPU_FTR_CELL_TB_BUG) #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) /* 64-bit CPUs */ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 4ebb4f8f4188..8fdd3da134e0 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -431,7 +431,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) #define ISYNC_601 #endif -#ifdef CONFIG_PPC_CELL +#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define MFTB(dest) \ 90: mftb dest; \ BEGIN_FTR_SECTION_NESTED(96); \ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a312e0c8cef4..55b03079d197 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1117,7 +1117,7 @@ : "memory") #ifdef __powerpc64__ -#ifdef CONFIG_PPC_CELL +#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb() ({unsigned long rval; \ asm volatile( \ "90: mftb %0;\n" \ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ea9c6269ead0..ea7e62910891 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -69,7 +69,30 @@ static void mpc85xx_give_timebase(void) tb_req = 0; mpc85xx_timebase_freeze(1); +#ifdef CONFIG_PPC64 + /* + * e5500/e6500 have a workaround for erratum A-006958 in place + * that will reread the timebase until TBL is non-zero. + * That would be a bad thing when the timebase is frozen. + * + * Thus, we read it manually, and instead of checking that + * TBL is non-zero, we ensure that TB does not change. We don't + * do that for the main mftb implementation, because it requires + * a scratch register + */ + { + u64 prev; + + asm volatile("mftb %0" : "=r" (timebase)); + + do { + prev = timebase; + asm volatile("mftb %0" : "=r" (timebase)); + } while (prev != timebase); + } +#else timebase = get_tb(); +#endif mb(); tb_valid = 1; -- cgit v1.2.3 From beb2dc0a7a84be003ce54e98b95d65cc66e6e536 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 20 Aug 2013 19:33:12 -0500 Subject: powerpc: Convert some mftb/mftbu into mfspr Some CPUs (such as e500v1/v2) don't implement mftb and will take a trap. mfspr should work on everything that has a timebase, and is the preferred instruction according to ISA v2.06. Currently we get away with mftb on 85xx because the assembler converts it to mfspr due to -Wa,-me500. However, that flag has other effects that are undesireable for certain targets (e.g. lwsync is converted to sync), and is hostile to multiplatform kernels. Thus we would like to stop setting it for all e500-family builds. mftb/mftbu instances which are in 85xx code or common code are converted. Instances which will never run on 85xx are left alone. Signed-off-by: Scott Wood --- arch/powerpc/boot/ppc_asm.h | 3 +++ arch/powerpc/boot/util.S | 10 +++++----- arch/powerpc/include/asm/ppc_asm.h | 4 ++-- arch/powerpc/include/asm/reg.h | 15 ++++++++++----- arch/powerpc/include/asm/timex.h | 4 ++-- arch/powerpc/kernel/vdso32/gettimeofday.S | 6 +++--- arch/powerpc/platforms/85xx/smp.c | 6 ++++-- 7 files changed, 29 insertions(+), 19 deletions(-) (limited to 'arch/powerpc/include/asm/reg.h') diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index 1c2c2817f9b7..eb0e98be69e0 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h @@ -59,4 +59,7 @@ #define r30 30 #define r31 31 +#define SPRN_TBRL 268 +#define SPRN_TBRU 269 + #endif /* _PPC64_PPC_ASM_H */ diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 427ddfc11991..5143228e3e5f 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -71,18 +71,18 @@ udelay: add r4,r4,r5 addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ -1: mftbu r5 - mftb r6 - mftbu r7 +1: mfspr r5, SPRN_TBRU + mfspr r6, SPRN_TBRL + mfspr r7, SPRN_TBRU cmpw 0,r5,r7 bne 1b /* Get [synced] base time */ addc r9,r6,r4 /* Compute end time */ addze r8,r5 -2: mftbu r5 +2: mfspr r5, SPRN_TBRU cmpw 0,r5,r8 blt 2b bgt 3f - mftb r6 + mfspr r6, SPRN_TBRL cmpw 0,r6,r9 blt 2b 3: blr diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 8fdd3da134e0..599545738af3 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -433,13 +433,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define MFTB(dest) \ -90: mftb dest; \ +90: mfspr dest, SPRN_TBRL; \ BEGIN_FTR_SECTION_NESTED(96); \ cmpwi dest,0; \ beq- 90b; \ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) #else -#define MFTB(dest) mftb dest +#define MFTB(dest) mfspr dest, SPRN_TBRL #endif #ifndef CONFIG_SMP diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 55b03079d197..64264bf601f5 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1120,7 +1120,7 @@ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb() ({unsigned long rval; \ asm volatile( \ - "90: mftb %0;\n" \ + "90: mfspr %0, %2;\n" \ "97: cmpwi %0,0;\n" \ " beq- 90b;\n" \ "99:\n" \ @@ -1134,18 +1134,23 @@ " .llong 0\n" \ " .llong 0\n" \ ".previous" \ - : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;}) + : "=r" (rval) \ + : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL)); \ + rval;}) #else #define mftb() ({unsigned long rval; \ - asm volatile("mftb %0" : "=r" (rval)); rval;}) + asm volatile("mfspr %0, %1" : \ + "=r" (rval) : "i" (SPRN_TBRL)); rval;}) #endif /* !CONFIG_PPC_CELL */ #else /* __powerpc64__ */ #define mftbl() ({unsigned long rval; \ - asm volatile("mftbl %0" : "=r" (rval)); rval;}) + asm volatile("mfspr %0, %1" : "=r" (rval) : \ + "i" (SPRN_TBRL)); rval;}) #define mftbu() ({unsigned long rval; \ - asm volatile("mftbu %0" : "=r" (rval)); rval;}) + asm volatile("mfspr %0, %1" : "=r" (rval) : \ + "i" (SPRN_TBRU)); rval;}) #endif /* !__powerpc64__ */ #define mttbl(v) asm volatile("mttbl %0":: "r"(v)) diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index c55e14f7ef44..18908caa1f3b 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -29,7 +29,7 @@ static inline cycles_t get_cycles(void) ret = 0; __asm__ __volatile__( - "97: mftb %0\n" + "97: mfspr %0, %2\n" "99:\n" ".section __ftr_fixup,\"a\"\n" ".align 2\n" @@ -41,7 +41,7 @@ static inline cycles_t get_cycles(void) " .long 0\n" " .long 0\n" ".previous" - : "=r" (ret) : "i" (CPU_FTR_601)); + : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL)); return ret; #endif } diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 27e2f623210b..6b1f2a6d5517 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -232,9 +232,9 @@ __do_get_tspec: lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) /* Get a stable TB value */ -2: mftbu r3 - mftbl r4 - mftbu r0 +2: mfspr r3, SPRN_TBRU + mfspr r4, SPRN_TBRL + mfspr r0, SPRN_TBRU cmplw cr0,r3,r0 bne- 2b diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ea7e62910891..281b7f01df63 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -83,11 +83,13 @@ static void mpc85xx_give_timebase(void) { u64 prev; - asm volatile("mftb %0" : "=r" (timebase)); + asm volatile("mfspr %0, %1" : "=r" (timebase) : + "i" (SPRN_TBRL)); do { prev = timebase; - asm volatile("mftb %0" : "=r" (timebase)); + asm volatile("mfspr %0, %1" : "=r" (timebase) : + "i" (SPRN_TBRL)); } while (prev != timebase); } #else -- cgit v1.2.3 From 9f24b0c9ef9b6b1292579c9e2cd7ff07ddc372b7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 5 Sep 2013 16:01:16 +1000 Subject: powerpc: Correct FSCR bit definitions Commit 74e400cee6 ("powerpc: Rework setting up H/FSCR bit definitions") ended up with incorrect bit numbers for FSCR_PM_LG and FSCR_BHRB_LG. This fixes them. Signed-off-by: Paul Mackerras Acked-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/include/asm/reg.h') diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index dc10bf549635..10d1ef016bf1 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -258,8 +258,8 @@ #define FSCR_TAR_LG 8 /* Enable Target Address Register */ #define FSCR_EBB_LG 7 /* Enable Event Based Branching */ #define FSCR_TM_LG 5 /* Enable Transactional Memory */ -#define FSCR_PM_LG 4 /* Enable prob/priv access to PMU SPRs */ -#define FSCR_BHRB_LG 3 /* Enable Branch History Rolling Buffer*/ +#define FSCR_BHRB_LG 4 /* Enable Branch History Rolling Buffer*/ +#define FSCR_PM_LG 3 /* Enable prob/priv access to PMU SPRs */ #define FSCR_DSCR_LG 2 /* Enable Data Stream Control Register */ #define FSCR_VECVSX_LG 1 /* Enable VMX/VSX */ #define FSCR_FP_LG 0 /* Enable Floating Point */ -- cgit v1.2.3