diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-08-08 20:11:39 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-08-08 20:33:45 -0400 |
commit | 6c70b6fc7b6fc321636a014082d9e32333da1f80 (patch) | |
tree | ff0e52bb7ba43b058b7cbb88b952fd268fbe3ad2 /arch/sparc64/kernel | |
parent | 68c9f9fd336dc7e793cecad25f8ac40ccaa7a256 (diff) |
[SPARC64]: Do not assume sun4v chips have load-twin/store-init support.
Check the cpu type in the OBP device tree before committing to
using the optimized Niagara memcpy and memset implementation.
If we don't recognize the cpu type, use a completely generic
version.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/cpu.c | 42 | ||||
-rw-r--r-- | arch/sparc64/kernel/head.S | 111 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 1 |
3 files changed, 122 insertions, 32 deletions
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c index e4eff878123d..e43db73f2b91 100644 --- a/arch/sparc64/kernel/cpu.c +++ b/arch/sparc64/kernel/cpu.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <asm/fpumacro.h> | 13 | #include <asm/fpumacro.h> |
14 | #include <asm/cpudata.h> | 14 | #include <asm/cpudata.h> |
15 | #include <asm/spitfire.h> | 15 | #include <asm/spitfire.h> |
16 | #include <asm/prom.h> | 16 | #include <asm/oplib.h> |
17 | 17 | ||
18 | DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; | 18 | DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; |
19 | 19 | ||
@@ -69,36 +69,24 @@ unsigned int fsr_storage; | |||
69 | 69 | ||
70 | static void __init sun4v_cpu_probe(void) | 70 | static void __init sun4v_cpu_probe(void) |
71 | { | 71 | { |
72 | struct device_node *dp; | 72 | switch (sun4v_chip_type) { |
73 | const char *compat; | 73 | case SUN4V_CHIP_NIAGARA1: |
74 | int len; | ||
75 | |||
76 | dp = of_find_node_by_name(NULL, "cpu"); | ||
77 | if (!dp) | ||
78 | goto no_compat; | ||
79 | |||
80 | compat = of_get_property(dp, "compatible", &len); | ||
81 | if (!compat) | ||
82 | goto no_compat; | ||
83 | |||
84 | if (of_find_in_proplist(compat, "SUNW,UltraSPARC-T1", len)) { | ||
85 | sparc_cpu_type = "UltraSparc T1 (Niagara)"; | 74 | sparc_cpu_type = "UltraSparc T1 (Niagara)"; |
86 | sparc_fpu_type = "UltraSparc T1 integrated FPU"; | 75 | sparc_fpu_type = "UltraSparc T1 integrated FPU"; |
87 | } else if (of_find_in_proplist(compat, "SUNW,UltraSPARC-T2", len)) { | 76 | break; |
77 | |||
78 | case SUN4V_CHIP_NIAGARA2: | ||
88 | sparc_cpu_type = "UltraSparc T2 (Niagara2)"; | 79 | sparc_cpu_type = "UltraSparc T2 (Niagara2)"; |
89 | sparc_fpu_type = "UltraSparc T2 integrated FPU"; | 80 | sparc_fpu_type = "UltraSparc T2 integrated FPU"; |
90 | } else | 81 | break; |
91 | goto unknown; | 82 | |
92 | 83 | default: | |
93 | return; | 84 | printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", |
94 | 85 | prom_cpu_compatible); | |
95 | no_compat: | 86 | sparc_cpu_type = "Unknown SUN4V CPU"; |
96 | compat = "no property"; | 87 | sparc_fpu_type = "Unknown SUN4V FPU"; |
97 | 88 | break; | |
98 | unknown: | 89 | } |
99 | printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", compat); | ||
100 | sparc_cpu_type = "Unknown SUN4V CPU"; | ||
101 | sparc_fpu_type = "Unknown SUN4V FPU"; | ||
102 | } | 90 | } |
103 | 91 | ||
104 | void __init cpu_probe(void) | 92 | void __init cpu_probe(void) |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 9dbd833d79d6..ac18bd8e273f 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -97,7 +97,8 @@ sparc64_boot: | |||
97 | .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache | 97 | .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache |
98 | .globl prom_boot_mapped_pc, prom_boot_mapping_mode | 98 | .globl prom_boot_mapped_pc, prom_boot_mapping_mode |
99 | .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low | 99 | .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low |
100 | .globl is_sun4v | 100 | .globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible |
101 | .globl is_sun4v, sun4v_chip_type | ||
101 | prom_peer_name: | 102 | prom_peer_name: |
102 | .asciz "peer" | 103 | .asciz "peer" |
103 | prom_compatible_name: | 104 | prom_compatible_name: |
@@ -106,6 +107,8 @@ prom_finddev_name: | |||
106 | .asciz "finddevice" | 107 | .asciz "finddevice" |
107 | prom_chosen_path: | 108 | prom_chosen_path: |
108 | .asciz "/chosen" | 109 | .asciz "/chosen" |
110 | prom_cpu_path: | ||
111 | .asciz "/cpu" | ||
109 | prom_getprop_name: | 112 | prom_getprop_name: |
110 | .asciz "getprop" | 113 | .asciz "getprop" |
111 | prom_mmu_name: | 114 | prom_mmu_name: |
@@ -120,9 +123,13 @@ prom_unmap_name: | |||
120 | .asciz "unmap" | 123 | .asciz "unmap" |
121 | prom_sun4v_name: | 124 | prom_sun4v_name: |
122 | .asciz "sun4v" | 125 | .asciz "sun4v" |
126 | prom_niagara_prefix: | ||
127 | .asciz "SUNW,UltraSPARC-T" | ||
123 | .align 4 | 128 | .align 4 |
124 | prom_root_compatible: | 129 | prom_root_compatible: |
125 | .skip 64 | 130 | .skip 64 |
131 | prom_cpu_compatible: | ||
132 | .skip 64 | ||
126 | prom_root_node: | 133 | prom_root_node: |
127 | .word 0 | 134 | .word 0 |
128 | prom_mmu_ihandle_cache: | 135 | prom_mmu_ihandle_cache: |
@@ -138,6 +145,8 @@ prom_boot_mapping_phys_low: | |||
138 | .xword 0 | 145 | .xword 0 |
139 | is_sun4v: | 146 | is_sun4v: |
140 | .word 0 | 147 | .word 0 |
148 | sun4v_chip_type: | ||
149 | .word SUN4V_CHIP_INVALID | ||
141 | 1: | 150 | 1: |
142 | rd %pc, %l0 | 151 | rd %pc, %l0 |
143 | 152 | ||
@@ -296,13 +305,13 @@ is_sun4v: | |||
296 | sethi %hi(prom_sun4v_name), %g7 | 305 | sethi %hi(prom_sun4v_name), %g7 |
297 | or %g7, %lo(prom_sun4v_name), %g7 | 306 | or %g7, %lo(prom_sun4v_name), %g7 |
298 | mov 5, %g3 | 307 | mov 5, %g3 |
299 | 1: ldub [%g7], %g2 | 308 | 90: ldub [%g7], %g2 |
300 | ldub [%g1], %g4 | 309 | ldub [%g1], %g4 |
301 | cmp %g2, %g4 | 310 | cmp %g2, %g4 |
302 | bne,pn %icc, 2f | 311 | bne,pn %icc, 80f |
303 | add %g7, 1, %g7 | 312 | add %g7, 1, %g7 |
304 | subcc %g3, 1, %g3 | 313 | subcc %g3, 1, %g3 |
305 | bne,pt %xcc, 1b | 314 | bne,pt %xcc, 90b |
306 | add %g1, 1, %g1 | 315 | add %g1, 1, %g1 |
307 | 316 | ||
308 | sethi %hi(is_sun4v), %g1 | 317 | sethi %hi(is_sun4v), %g1 |
@@ -310,7 +319,80 @@ is_sun4v: | |||
310 | mov 1, %g7 | 319 | mov 1, %g7 |
311 | stw %g7, [%g1] | 320 | stw %g7, [%g1] |
312 | 321 | ||
313 | 2: | 322 | /* cpu_node = prom_finddevice("/cpu") */ |
323 | mov (1b - prom_finddev_name), %l1 | ||
324 | mov (1b - prom_cpu_path), %l2 | ||
325 | sub %l0, %l1, %l1 | ||
326 | sub %l0, %l2, %l2 | ||
327 | sub %sp, (192 + 128), %sp | ||
328 | |||
329 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" | ||
330 | mov 1, %l3 | ||
331 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 | ||
332 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
333 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/cpu" | ||
334 | stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 | ||
335 | call %l7 | ||
336 | add %sp, (2047 + 128), %o0 ! argument array | ||
337 | |||
338 | ldx [%sp + 2047 + 128 + 0x20], %l4 ! cpu device node | ||
339 | |||
340 | mov (1b - prom_getprop_name), %l1 | ||
341 | mov (1b - prom_compatible_name), %l2 | ||
342 | mov (1b - prom_cpu_compatible), %l5 | ||
343 | sub %l0, %l1, %l1 | ||
344 | sub %l0, %l2, %l2 | ||
345 | sub %l0, %l5, %l5 | ||
346 | |||
347 | /* prom_getproperty(cpu_node, "compatible", | ||
348 | * &prom_cpu_compatible, 64) | ||
349 | */ | ||
350 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" | ||
351 | mov 4, %l3 | ||
352 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 | ||
353 | mov 1, %l3 | ||
354 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
355 | stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, cpu_node | ||
356 | stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible" | ||
357 | stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_cpu_compatible | ||
358 | mov 64, %l3 | ||
359 | stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size | ||
360 | stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 | ||
361 | call %l7 | ||
362 | add %sp, (2047 + 128), %o0 ! argument array | ||
363 | |||
364 | add %sp, (192 + 128), %sp | ||
365 | |||
366 | sethi %hi(prom_cpu_compatible), %g1 | ||
367 | or %g1, %lo(prom_cpu_compatible), %g1 | ||
368 | sethi %hi(prom_niagara_prefix), %g7 | ||
369 | or %g7, %lo(prom_niagara_prefix), %g7 | ||
370 | mov 17, %g3 | ||
371 | 90: ldub [%g7], %g2 | ||
372 | ldub [%g1], %g4 | ||
373 | cmp %g2, %g4 | ||
374 | bne,pn %icc, 4f | ||
375 | add %g7, 1, %g7 | ||
376 | subcc %g3, 1, %g3 | ||
377 | bne,pt %xcc, 90b | ||
378 | add %g1, 1, %g1 | ||
379 | |||
380 | sethi %hi(prom_cpu_compatible), %g1 | ||
381 | or %g1, %lo(prom_cpu_compatible), %g1 | ||
382 | ldub [%g1 + 17], %g2 | ||
383 | cmp %g2, '1' | ||
384 | be,pt %xcc, 5f | ||
385 | mov SUN4V_CHIP_NIAGARA1, %g4 | ||
386 | cmp %g2, '2' | ||
387 | be,pt %xcc, 5f | ||
388 | mov SUN4V_CHIP_NIAGARA2, %g4 | ||
389 | 4: | ||
390 | mov SUN4V_CHIP_UNKNOWN, %g4 | ||
391 | 5: sethi %hi(sun4v_chip_type), %g2 | ||
392 | or %g2, %lo(sun4v_chip_type), %g2 | ||
393 | stw %g4, [%g2] | ||
394 | |||
395 | 80: | ||
314 | BRANCH_IF_SUN4V(g1, jump_to_sun4u_init) | 396 | BRANCH_IF_SUN4V(g1, jump_to_sun4u_init) |
315 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) | 397 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) |
316 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) | 398 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) |
@@ -414,6 +496,24 @@ niagara_tlb_fixup: | |||
414 | stw %g2, [%g1 + %lo(tlb_type)] | 496 | stw %g2, [%g1 + %lo(tlb_type)] |
415 | 497 | ||
416 | /* Patch copy/clear ops. */ | 498 | /* Patch copy/clear ops. */ |
499 | sethi %hi(sun4v_chip_type), %g1 | ||
500 | lduw [%g1 + %lo(sun4v_chip_type)], %g1 | ||
501 | cmp %g1, SUN4V_CHIP_NIAGARA1 | ||
502 | be,pt %xcc, niagara_patch | ||
503 | cmp %g1, SUN4V_CHIP_NIAGARA2 | ||
504 | be,pt %xcc, niagara_patch | ||
505 | nop | ||
506 | |||
507 | call generic_patch_copyops | ||
508 | nop | ||
509 | call generic_patch_bzero | ||
510 | nop | ||
511 | call generic_patch_pageops | ||
512 | nop | ||
513 | |||
514 | ba,a,pt %xcc, 80f | ||
515 | |||
516 | niagara_patch: | ||
417 | call niagara_patch_copyops | 517 | call niagara_patch_copyops |
418 | nop | 518 | nop |
419 | call niagara_patch_bzero | 519 | call niagara_patch_bzero |
@@ -421,6 +521,7 @@ niagara_tlb_fixup: | |||
421 | call niagara_patch_pageops | 521 | call niagara_patch_pageops |
422 | nop | 522 | nop |
423 | 523 | ||
524 | 80: | ||
424 | /* Patch TLB/cache ops. */ | 525 | /* Patch TLB/cache ops. */ |
425 | call hypervisor_patch_cachetlbops | 526 | call hypervisor_patch_cachetlbops |
426 | nop | 527 | nop |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index d270c2f0be0f..23fad7ebdd0d 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -168,6 +168,7 @@ EXPORT_SYMBOL(change_bit); | |||
168 | EXPORT_SYMBOL(__flushw_user); | 168 | EXPORT_SYMBOL(__flushw_user); |
169 | 169 | ||
170 | EXPORT_SYMBOL(tlb_type); | 170 | EXPORT_SYMBOL(tlb_type); |
171 | EXPORT_SYMBOL(sun4v_chip_type); | ||
171 | EXPORT_SYMBOL(get_fb_unmapped_area); | 172 | EXPORT_SYMBOL(get_fb_unmapped_area); |
172 | EXPORT_SYMBOL(flush_icache_range); | 173 | EXPORT_SYMBOL(flush_icache_range); |
173 | 174 | ||