diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/entry.h | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/setup_64.c | 27 | ||||
-rw-r--r-- | arch/sparc/kernel/sparc_ksyms_64.c | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/vmlinux.lds.S | 6 |
4 files changed, 46 insertions, 1 deletions
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index d1f1361c416..16d1545d84f 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
@@ -42,6 +42,13 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, | |||
42 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); | 42 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
43 | 43 | ||
44 | #else /* CONFIG_SPARC32 */ | 44 | #else /* CONFIG_SPARC32 */ |
45 | struct popc_3insn_patch_entry { | ||
46 | unsigned int addr; | ||
47 | unsigned int insns[3]; | ||
48 | }; | ||
49 | extern struct popc_3insn_patch_entry __popc_3insn_patch, | ||
50 | __popc_3insn_patch_end; | ||
51 | |||
45 | extern void __init per_cpu_patch(void); | 52 | extern void __init per_cpu_patch(void); |
46 | extern void __init sun4v_patch(void); | 53 | extern void __init sun4v_patch(void); |
47 | extern void __init boot_cpu_id_too_large(int cpu); | 54 | extern void __init boot_cpu_id_too_large(int cpu); |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 242dbb3f31d..26d114187e1 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -272,6 +272,30 @@ void __init sun4v_patch(void) | |||
272 | sun4v_hvapi_init(); | 272 | sun4v_hvapi_init(); |
273 | } | 273 | } |
274 | 274 | ||
275 | static void __init popc_patch(void) | ||
276 | { | ||
277 | struct popc_3insn_patch_entry *p3; | ||
278 | |||
279 | p3 = &__popc_3insn_patch; | ||
280 | while (p3 < &__popc_3insn_patch_end) { | ||
281 | unsigned long addr = p3->addr; | ||
282 | |||
283 | *(unsigned int *) (addr + 0) = p3->insns[0]; | ||
284 | wmb(); | ||
285 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); | ||
286 | |||
287 | *(unsigned int *) (addr + 4) = p3->insns[1]; | ||
288 | wmb(); | ||
289 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | ||
290 | |||
291 | *(unsigned int *) (addr + 8) = p3->insns[2]; | ||
292 | wmb(); | ||
293 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | ||
294 | |||
295 | p3++; | ||
296 | } | ||
297 | } | ||
298 | |||
275 | #ifdef CONFIG_SMP | 299 | #ifdef CONFIG_SMP |
276 | void __init boot_cpu_id_too_large(int cpu) | 300 | void __init boot_cpu_id_too_large(int cpu) |
277 | { | 301 | { |
@@ -424,6 +448,9 @@ static void __init init_sparc64_elf_hwcap(void) | |||
424 | sparc64_elf_hwcap = cap | mdesc_caps; | 448 | sparc64_elf_hwcap = cap | mdesc_caps; |
425 | 449 | ||
426 | report_hwcaps(sparc64_elf_hwcap); | 450 | report_hwcaps(sparc64_elf_hwcap); |
451 | |||
452 | if (sparc64_elf_hwcap & AV_SPARC_POPC) | ||
453 | popc_patch(); | ||
427 | } | 454 | } |
428 | 455 | ||
429 | void __init setup_arch(char **cmdline_p) | 456 | void __init setup_arch(char **cmdline_p) |
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 372ad59c4cb..d0ee65aced0 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/bitops.h> | ||
11 | 12 | ||
12 | #include <asm/system.h> | 13 | #include <asm/system.h> |
13 | #include <asm/cpudata.h> | 14 | #include <asm/cpudata.h> |
@@ -38,5 +39,11 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); | |||
38 | EXPORT_SYMBOL(sun4v_niagara2_getperf); | 39 | EXPORT_SYMBOL(sun4v_niagara2_getperf); |
39 | EXPORT_SYMBOL(sun4v_niagara2_setperf); | 40 | EXPORT_SYMBOL(sun4v_niagara2_setperf); |
40 | 41 | ||
42 | /* from hweight.S */ | ||
43 | EXPORT_SYMBOL(__arch_hweight8); | ||
44 | EXPORT_SYMBOL(__arch_hweight16); | ||
45 | EXPORT_SYMBOL(__arch_hweight32); | ||
46 | EXPORT_SYMBOL(__arch_hweight64); | ||
47 | |||
41 | /* Exporting a symbol from /init/main.c */ | 48 | /* Exporting a symbol from /init/main.c */ |
42 | EXPORT_SYMBOL(saved_command_line); | 49 | EXPORT_SYMBOL(saved_command_line); |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index c0220759003..de20c14625e 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -107,7 +107,11 @@ SECTIONS | |||
107 | *(.sun4v_2insn_patch) | 107 | *(.sun4v_2insn_patch) |
108 | __sun4v_2insn_patch_end = .; | 108 | __sun4v_2insn_patch_end = .; |
109 | } | 109 | } |
110 | 110 | .popc_3insn_patch : { | |
111 | __popc_3insn_patch = .; | ||
112 | *(.popc_3insn_patch) | ||
113 | __popc_3insn_patch_end = .; | ||
114 | } | ||
111 | PERCPU_SECTION(SMP_CACHE_BYTES) | 115 | PERCPU_SECTION(SMP_CACHE_BYTES) |
112 | 116 | ||
113 | . = ALIGN(PAGE_SIZE); | 117 | . = ALIGN(PAGE_SIZE); |