diff options
-rw-r--r-- | arch/powerpc/kernel/module.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso32/vdso32.lds.S | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso64/vdso64.lds.S | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/vmlinux.lds.S | 6 | ||||
-rw-r--r-- | arch/powerpc/lib/feature-fixups-test.S | 15 | ||||
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 36 | ||||
-rw-r--r-- | include/asm-powerpc/code-patching.h | 3 | ||||
-rw-r--r-- | include/asm-powerpc/cputable.h | 21 | ||||
-rw-r--r-- | include/asm-powerpc/feature-fixups.h | 10 | ||||
-rw-r--r-- | include/asm-powerpc/synch.h | 38 |
13 files changed, 131 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 40dd52d81c18..af07003573c4 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c | |||
@@ -86,6 +86,12 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
86 | (void *)sect->sh_addr + sect->sh_size); | 86 | (void *)sect->sh_addr + sect->sh_size); |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | sect = find_section(hdr, sechdrs, "__lwsync_fixup"); | ||
90 | if (sect != NULL) | ||
91 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | ||
92 | (void *)sect->sh_addr, | ||
93 | (void *)sect->sh_addr + sect->sh_size); | ||
94 | |||
89 | return 0; | 95 | return 0; |
90 | } | 96 | } |
91 | 97 | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 9e83add54290..0109e7f0ccf9 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -101,6 +101,10 @@ unsigned long __init early_init(unsigned long dt_ptr) | |||
101 | PTRRELOC(&__start___ftr_fixup), | 101 | PTRRELOC(&__start___ftr_fixup), |
102 | PTRRELOC(&__stop___ftr_fixup)); | 102 | PTRRELOC(&__stop___ftr_fixup)); |
103 | 103 | ||
104 | do_lwsync_fixups(spec->cpu_features, | ||
105 | PTRRELOC(&__start___lwsync_fixup), | ||
106 | PTRRELOC(&__stop___lwsync_fixup)); | ||
107 | |||
104 | return KERNELBASE + offset; | 108 | return KERNELBASE + offset; |
105 | } | 109 | } |
106 | 110 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 098fd96a394a..04d8de9f0fc6 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -363,6 +363,8 @@ void __init setup_system(void) | |||
363 | &__start___ftr_fixup, &__stop___ftr_fixup); | 363 | &__start___ftr_fixup, &__stop___ftr_fixup); |
364 | do_feature_fixups(powerpc_firmware_features, | 364 | do_feature_fixups(powerpc_firmware_features, |
365 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); | 365 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); |
366 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | ||
367 | &__start___lwsync_fixup, &__stop___lwsync_fixup); | ||
366 | 368 | ||
367 | /* | 369 | /* |
368 | * Unflatten the device-tree passed by prom_init or kexec | 370 | * Unflatten the device-tree passed by prom_init or kexec |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index ce245a850db2..f177c60ea766 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -571,6 +571,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32, | |||
571 | if (start64) | 571 | if (start64) |
572 | do_feature_fixups(powerpc_firmware_features, | 572 | do_feature_fixups(powerpc_firmware_features, |
573 | start64, start64 + size64); | 573 | start64, start64 + size64); |
574 | |||
575 | start64 = find_section64(v64->hdr, "__lwsync_fixup", &size64); | ||
576 | if (start64) | ||
577 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | ||
578 | start64, start64 + size64); | ||
574 | #endif /* CONFIG_PPC64 */ | 579 | #endif /* CONFIG_PPC64 */ |
575 | 580 | ||
576 | start32 = find_section32(v32->hdr, "__ftr_fixup", &size32); | 581 | start32 = find_section32(v32->hdr, "__ftr_fixup", &size32); |
@@ -585,6 +590,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32, | |||
585 | start32, start32 + size32); | 590 | start32, start32 + size32); |
586 | #endif /* CONFIG_PPC64 */ | 591 | #endif /* CONFIG_PPC64 */ |
587 | 592 | ||
593 | start32 = find_section32(v32->hdr, "__lwsync_fixup", &size32); | ||
594 | if (start32) | ||
595 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | ||
596 | start32, start32 + size32); | ||
597 | |||
588 | return 0; | 598 | return 0; |
589 | } | 599 | } |
590 | 600 | ||
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 271793577cdc..be3b6a41dc09 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S | |||
@@ -33,6 +33,9 @@ SECTIONS | |||
33 | . = ALIGN(8); | 33 | . = ALIGN(8); |
34 | __ftr_fixup : { *(__ftr_fixup) } | 34 | __ftr_fixup : { *(__ftr_fixup) } |
35 | 35 | ||
36 | . = ALIGN(8); | ||
37 | __lwsync_fixup : { *(__lwsync_fixup) } | ||
38 | |||
36 | #ifdef CONFIG_PPC64 | 39 | #ifdef CONFIG_PPC64 |
37 | . = ALIGN(8); | 40 | . = ALIGN(8); |
38 | __fw_ftr_fixup : { *(__fw_ftr_fixup) } | 41 | __fw_ftr_fixup : { *(__fw_ftr_fixup) } |
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index e608d1bd3bff..d0b2526dd38d 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S | |||
@@ -35,6 +35,9 @@ SECTIONS | |||
35 | __ftr_fixup : { *(__ftr_fixup) } | 35 | __ftr_fixup : { *(__ftr_fixup) } |
36 | 36 | ||
37 | . = ALIGN(8); | 37 | . = ALIGN(8); |
38 | __lwsync_fixup : { *(__lwsync_fixup) } | ||
39 | |||
40 | . = ALIGN(8); | ||
38 | __fw_ftr_fixup : { *(__fw_ftr_fixup) } | 41 | __fw_ftr_fixup : { *(__fw_ftr_fixup) } |
39 | 42 | ||
40 | /* | 43 | /* |
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 3c07811989fc..6856f6c15727 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -127,6 +127,12 @@ SECTIONS | |||
127 | *(__ftr_fixup) | 127 | *(__ftr_fixup) |
128 | __stop___ftr_fixup = .; | 128 | __stop___ftr_fixup = .; |
129 | } | 129 | } |
130 | . = ALIGN(8); | ||
131 | __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { | ||
132 | __start___lwsync_fixup = .; | ||
133 | *(__lwsync_fixup) | ||
134 | __stop___lwsync_fixup = .; | ||
135 | } | ||
130 | #ifdef CONFIG_PPC64 | 136 | #ifdef CONFIG_PPC64 |
131 | . = ALIGN(8); | 137 | . = ALIGN(8); |
132 | __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { | 138 | __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { |
diff --git a/arch/powerpc/lib/feature-fixups-test.S b/arch/powerpc/lib/feature-fixups-test.S index 0549be04399c..cb737484c5aa 100644 --- a/arch/powerpc/lib/feature-fixups-test.S +++ b/arch/powerpc/lib/feature-fixups-test.S | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <asm/feature-fixups.h> | 11 | #include <asm/feature-fixups.h> |
12 | #include <asm/ppc_asm.h> | 12 | #include <asm/ppc_asm.h> |
13 | #include <asm/synch.h> | ||
13 | 14 | ||
14 | .text | 15 | .text |
15 | 16 | ||
@@ -725,3 +726,17 @@ MAKE_MACRO_TEST_EXPECTED(FTR); | |||
725 | MAKE_MACRO_TEST(FW_FTR); | 726 | MAKE_MACRO_TEST(FW_FTR); |
726 | MAKE_MACRO_TEST_EXPECTED(FW_FTR); | 727 | MAKE_MACRO_TEST_EXPECTED(FW_FTR); |
727 | #endif | 728 | #endif |
729 | |||
730 | globl(lwsync_fixup_test) | ||
731 | 1: or 1,1,1 | ||
732 | LWSYNC | ||
733 | globl(end_lwsync_fixup_test) | ||
734 | |||
735 | globl(lwsync_fixup_test_expected_LWSYNC) | ||
736 | 1: or 1,1,1 | ||
737 | lwsync | ||
738 | |||
739 | globl(lwsync_fixup_test_expected_SYNC) | ||
740 | 1: or 1,1,1 | ||
741 | sync | ||
742 | |||
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 48e1ed89052d..4e43702b9813 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c | |||
@@ -110,6 +110,22 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) | ||
114 | { | ||
115 | unsigned int *start, *end, *dest; | ||
116 | |||
117 | if (!(value & CPU_FTR_LWSYNC)) | ||
118 | return ; | ||
119 | |||
120 | start = fixup_start; | ||
121 | end = fixup_end; | ||
122 | |||
123 | for (; start < end; start++) { | ||
124 | dest = (void *)start + *start; | ||
125 | patch_instruction(dest, PPC_LWSYNC_INSTR); | ||
126 | } | ||
127 | } | ||
128 | |||
113 | #ifdef CONFIG_FTR_FIXUP_SELFTEST | 129 | #ifdef CONFIG_FTR_FIXUP_SELFTEST |
114 | 130 | ||
115 | #define check(x) \ | 131 | #define check(x) \ |
@@ -295,6 +311,25 @@ static void test_fw_macros(void) | |||
295 | #endif | 311 | #endif |
296 | } | 312 | } |
297 | 313 | ||
314 | static void test_lwsync_macros(void) | ||
315 | { | ||
316 | extern void lwsync_fixup_test; | ||
317 | extern void end_lwsync_fixup_test; | ||
318 | extern void lwsync_fixup_test_expected_LWSYNC; | ||
319 | extern void lwsync_fixup_test_expected_SYNC; | ||
320 | unsigned long size = &end_lwsync_fixup_test - | ||
321 | &lwsync_fixup_test; | ||
322 | |||
323 | /* The fixups have already been done for us during boot */ | ||
324 | if (cur_cpu_spec->cpu_features & CPU_FTR_LWSYNC) { | ||
325 | check(memcmp(&lwsync_fixup_test, | ||
326 | &lwsync_fixup_test_expected_LWSYNC, size) == 0); | ||
327 | } else { | ||
328 | check(memcmp(&lwsync_fixup_test, | ||
329 | &lwsync_fixup_test_expected_SYNC, size) == 0); | ||
330 | } | ||
331 | } | ||
332 | |||
298 | static int __init test_feature_fixups(void) | 333 | static int __init test_feature_fixups(void) |
299 | { | 334 | { |
300 | printk(KERN_DEBUG "Running feature fixup self-tests ...\n"); | 335 | printk(KERN_DEBUG "Running feature fixup self-tests ...\n"); |
@@ -307,6 +342,7 @@ static int __init test_feature_fixups(void) | |||
307 | test_alternative_case_with_external_branch(); | 342 | test_alternative_case_with_external_branch(); |
308 | test_cpu_macros(); | 343 | test_cpu_macros(); |
309 | test_fw_macros(); | 344 | test_fw_macros(); |
345 | test_lwsync_macros(); | ||
310 | 346 | ||
311 | return 0; | 347 | return 0; |
312 | } | 348 | } |
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) \ | ||
119 | label##2: \ | ||
120 | .pushsection sect,"a"; \ | ||
121 | .align 2; \ | ||
122 | label##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 | 9 | extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; |
9 | #endif | 10 | extern void do_lwsync_fixups(unsigned long value, void *fixup_start, |
11 | void *fixup_end); | ||
12 | |||
13 | static inline void eieio(void) | ||
14 | { | ||
15 | __asm__ __volatile__ ("eieio" : : : "memory"); | ||
16 | } | ||
17 | |||
18 | static 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 | ||
25 | static inline void eieio(void) | ||
26 | { | ||
27 | __asm__ __volatile__ ("eieio" : : : "memory"); | ||
28 | } | ||
29 | |||
30 | static 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 */ |