aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-07-01 11:16:40 -0400
committerPaul Mackerras <paulus@samba.org>2008-07-03 02:58:10 -0400
commit2d1b2027626d5151fff8ef7c06ca8e7876a1a510 (patch)
tree6ecc861f4f45a5d26309bf12683aa0372358ef7c /include/asm-powerpc
parent5888da18765ca9af7f10015263d8bc8e3057f128 (diff)
powerpc: Fixup lwsync at runtime
To allow for a single kernel image on e500 v1/v2/mc we need to fixup lwsync at runtime. On e500v1/v2 lwsync causes an illop so we need to patch up the code. We default to 'sync' since that is always safe and if the cpu is capable we will replace 'sync' with 'lwsync'. We introduce CPU_FTR_LWSYNC as a way to determine at runtime if this is needed. This flag could be moved elsewhere since we dont really use it for the normal CPU_FTR purpose. Finally we only store the relative offset in the fixup section to keep it as small as possible rather than using a full fixup_entry. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/code-patching.h3
-rw-r--r--include/asm-powerpc/cputable.h21
-rw-r--r--include/asm-powerpc/feature-fixups.h10
-rw-r--r--include/asm-powerpc/synch.h38
4 files changed, 46 insertions, 26 deletions
diff --git a/include/asm-powerpc/code-patching.h b/include/asm-powerpc/code-patching.h
index ef3a5d156dba..107d9b915e33 100644
--- a/include/asm-powerpc/code-patching.h
+++ b/include/asm-powerpc/code-patching.h
@@ -12,7 +12,8 @@
12 12
13#include <asm/types.h> 13#include <asm/types.h>
14 14
15#define PPC_NOP_INSTR 0x60000000 15#define PPC_NOP_INSTR 0x60000000
16#define PPC_LWSYNC_INSTR 0x7c2004ac
16 17
17/* Flags for create_branch: 18/* Flags for create_branch:
18 * "b" == create_branch(addr, target, 0); 19 * "b" == create_branch(addr, target, 0);
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4e4491cb9d3b..3171ac904b91 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -156,6 +156,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
156#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000) 156#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)
157#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) 157#define CPU_FTR_SPE ASM_CONST(0x0000000002000000)
158#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000) 158#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000)
159#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
159 160
160/* 161/*
161 * Add the 64-bit processor unique features in the top half of the word; 162 * Add the 64-bit processor unique features in the top half of the word;
@@ -369,43 +370,43 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
369 CPU_FTR_NODSISRALIGN) 370 CPU_FTR_NODSISRALIGN)
370#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ 371#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
371 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \ 372 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \
372 CPU_FTR_L2CSR) 373 CPU_FTR_L2CSR | CPU_FTR_LWSYNC)
373#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 374#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
374 375
375/* 64-bit CPUs */ 376/* 64-bit CPUs */
376#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | \ 377#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
377 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE) 378 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE)
378#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | \ 379#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
379 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \ 380 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
380 CPU_FTR_MMCRA | CPU_FTR_CTRL) 381 CPU_FTR_MMCRA | CPU_FTR_CTRL)
381#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | \ 382#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
382 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 383 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
383 CPU_FTR_MMCRA) 384 CPU_FTR_MMCRA)
384#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | \ 385#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
385 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 386 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
386 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA) 387 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
387#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | \ 388#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
388 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 389 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
389 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 390 CPU_FTR_MMCRA | CPU_FTR_SMT | \
390 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 391 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
391 CPU_FTR_PURR) 392 CPU_FTR_PURR)
392#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | \ 393#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
393 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 394 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
394 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 395 CPU_FTR_MMCRA | CPU_FTR_SMT | \
395 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 396 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
396 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ 397 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
397 CPU_FTR_DSCR) 398 CPU_FTR_DSCR)
398#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | \ 399#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
399 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 400 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
400 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 401 CPU_FTR_MMCRA | CPU_FTR_SMT | \
401 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 402 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
402 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ 403 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
403 CPU_FTR_DSCR) 404 CPU_FTR_DSCR)
404#define CPU_FTRS_CELL (CPU_FTR_USE_TB | \ 405#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
405 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 406 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
406 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 407 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
407 CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG) 408 CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
408#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \ 409#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
409 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 410 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
410 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ 411 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
411 CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B) 412 CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
diff --git a/include/asm-powerpc/feature-fixups.h b/include/asm-powerpc/feature-fixups.h
index ab30129dced7..a1029967620b 100644
--- a/include/asm-powerpc/feature-fixups.h
+++ b/include/asm-powerpc/feature-fixups.h
@@ -113,4 +113,14 @@ label##5: \
113 113
114#endif /* __ASSEMBLY__ */ 114#endif /* __ASSEMBLY__ */
115 115
116/* LWSYNC feature sections */
117#define START_LWSYNC_SECTION(label) label##1:
118#define MAKE_LWSYNC_SECTION_ENTRY(label, sect) \
119label##2: \
120 .pushsection sect,"a"; \
121 .align 2; \
122label##3: \
123 .long label##1b-label##3b; \
124 .popsection;
125
116#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */ 126#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
index 42a1ef590690..45963e80f557 100644
--- a/include/asm-powerpc/synch.h
+++ b/include/asm-powerpc/synch.h
@@ -3,34 +3,42 @@
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/stringify.h> 5#include <linux/stringify.h>
6#include <asm/feature-fixups.h>
6 7
7#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) 8#ifndef __ASSEMBLY__
8#define __SUBARCH_HAS_LWSYNC 9extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
9#endif 10extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
11 void *fixup_end);
12
13static inline void eieio(void)
14{
15 __asm__ __volatile__ ("eieio" : : : "memory");
16}
17
18static inline void isync(void)
19{
20 __asm__ __volatile__ ("isync" : : : "memory");
21}
22#endif /* __ASSEMBLY__ */
10 23
11#ifdef __SUBARCH_HAS_LWSYNC 24#if defined(__powerpc64__)
12# define LWSYNC lwsync 25# define LWSYNC lwsync
26#elif defined(CONFIG_E500)
27# define LWSYNC \
28 START_LWSYNC_SECTION(96); \
29 sync; \
30 MAKE_LWSYNC_SECTION_ENTRY(96, __lwsync_fixup);
13#else 31#else
14# define LWSYNC sync 32# define LWSYNC sync
15#endif 33#endif
16 34
17#ifdef CONFIG_SMP 35#ifdef CONFIG_SMP
18#define ISYNC_ON_SMP "\n\tisync\n" 36#define ISYNC_ON_SMP "\n\tisync\n"
19#define LWSYNC_ON_SMP __stringify(LWSYNC) "\n" 37#define LWSYNC_ON_SMP stringify_in_c(LWSYNC) "\n"
20#else 38#else
21#define ISYNC_ON_SMP 39#define ISYNC_ON_SMP
22#define LWSYNC_ON_SMP 40#define LWSYNC_ON_SMP
23#endif 41#endif
24 42
25static inline void eieio(void)
26{
27 __asm__ __volatile__ ("eieio" : : : "memory");
28}
29
30static inline void isync(void)
31{
32 __asm__ __volatile__ ("isync" : : : "memory");
33}
34
35#endif /* __KERNEL__ */ 43#endif /* __KERNEL__ */
36#endif /* _ASM_POWERPC_SYNCH_H */ 44#endif /* _ASM_POWERPC_SYNCH_H */