aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-08-08 20:11:39 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-08-08 20:33:45 -0400
commit6c70b6fc7b6fc321636a014082d9e32333da1f80 (patch)
treeff0e52bb7ba43b058b7cbb88b952fd268fbe3ad2 /arch/sparc64/kernel
parent68c9f9fd336dc7e793cecad25f8ac40ccaa7a256 (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.c42
-rw-r--r--arch/sparc64/kernel/head.S111
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
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
18DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; 18DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
19 19
@@ -69,36 +69,24 @@ unsigned int fsr_storage;
69 69
70static void __init sun4v_cpu_probe(void) 70static 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);
95no_compat: 86 sparc_cpu_type = "Unknown SUN4V CPU";
96 compat = "no property"; 87 sparc_fpu_type = "Unknown SUN4V FPU";
97 88 break;
98unknown: 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
104void __init cpu_probe(void) 92void __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
101prom_peer_name: 102prom_peer_name:
102 .asciz "peer" 103 .asciz "peer"
103prom_compatible_name: 104prom_compatible_name:
@@ -106,6 +107,8 @@ prom_finddev_name:
106 .asciz "finddevice" 107 .asciz "finddevice"
107prom_chosen_path: 108prom_chosen_path:
108 .asciz "/chosen" 109 .asciz "/chosen"
110prom_cpu_path:
111 .asciz "/cpu"
109prom_getprop_name: 112prom_getprop_name:
110 .asciz "getprop" 113 .asciz "getprop"
111prom_mmu_name: 114prom_mmu_name:
@@ -120,9 +123,13 @@ prom_unmap_name:
120 .asciz "unmap" 123 .asciz "unmap"
121prom_sun4v_name: 124prom_sun4v_name:
122 .asciz "sun4v" 125 .asciz "sun4v"
126prom_niagara_prefix:
127 .asciz "SUNW,UltraSPARC-T"
123 .align 4 128 .align 4
124prom_root_compatible: 129prom_root_compatible:
125 .skip 64 130 .skip 64
131prom_cpu_compatible:
132 .skip 64
126prom_root_node: 133prom_root_node:
127 .word 0 134 .word 0
128prom_mmu_ihandle_cache: 135prom_mmu_ihandle_cache:
@@ -138,6 +145,8 @@ prom_boot_mapping_phys_low:
138 .xword 0 145 .xword 0
139is_sun4v: 146is_sun4v:
140 .word 0 147 .word 0
148sun4v_chip_type:
149 .word SUN4V_CHIP_INVALID
1411: 1501:
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
2991: ldub [%g7], %g2 30890: 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
3132: 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
37190: 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
3894:
390 mov SUN4V_CHIP_UNKNOWN, %g4
3915: sethi %hi(sun4v_chip_type), %g2
392 or %g2, %lo(sun4v_chip_type), %g2
393 stw %g4, [%g2]
394
39580:
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
516niagara_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
52480:
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);
168EXPORT_SYMBOL(__flushw_user); 168EXPORT_SYMBOL(__flushw_user);
169 169
170EXPORT_SYMBOL(tlb_type); 170EXPORT_SYMBOL(tlb_type);
171EXPORT_SYMBOL(sun4v_chip_type);
171EXPORT_SYMBOL(get_fb_unmapped_area); 172EXPORT_SYMBOL(get_fb_unmapped_area);
172EXPORT_SYMBOL(flush_icache_range); 173EXPORT_SYMBOL(flush_icache_range);
173 174