aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-07-28 00:06:16 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-28 01:10:10 -0400
commit4ba991d3eb379fbaa22049e7002341e97a673685 (patch)
tree31671a735930aa2e9e3f13ba31e59236e770c954
parent314ff52727fe94dfbe07f3a9a489ab3ca8d8df5a (diff)
sparc: Detect and handle UltraSPARC-T3 cpu types.
The cpu compatible string we look for is "SPARC-T3". As far as memset/memcpy optimizations go, we treat this chip the same as Niagara-T2/T2+. Use cache initializing stores for memset, and use perfetch, FPU block loads, cache initializing stores, and block stores for copies. We use the Niagara-T2 perf support, since T3 is a close relative in this regard. Later we'll add support for the new events T3 can report, plus enable T3's new "sample" mode. For now I haven't added any new ELF hwcap flags. We probably need to add a couple, for example: T2 and T3 both support the population count instruction in hardware. T3 supports VIS3 instructions, including support (finally) for partitioned shift. One can also now move directly between float and integer registers. T3 supports instructions meant to help with Galois Field and other HPC calculations, such as XOR multiply. Also there are "OP and negate" instructions, for example "fnmul" which is multiply-and-negate. T3 recognizes the transactional memory opcodes, however since transactional memory isn't supported: 1) 'commit' behaves as a NOP and 2) 'chkpt' always branches 3) 'rdcps' returns all zeros and 4) 'wrcps' behaves as a NOP. So we'll need about 3 new elf capability flags in the end to represent all of these things. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/include/asm/elf_64.h6
-rw-r--r--arch/sparc/include/asm/xor_64.h3
-rw-r--r--arch/sparc/kernel/cpu.c6
-rw-r--r--arch/sparc/kernel/cpumap.c1
-rw-r--r--arch/sparc/kernel/head_64.S31
-rw-r--r--arch/sparc/kernel/pcr.c4
-rw-r--r--arch/sparc/kernel/perf_event.c3
7 files changed, 50 insertions, 4 deletions
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index cfa9cd2e5519..64f7a00b3747 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -177,9 +177,11 @@ static inline unsigned int sparc64_elf_hwcap(void)
177 cap |= HWCAP_SPARC_ULTRA3; 177 cap |= HWCAP_SPARC_ULTRA3;
178 else if (tlb_type == hypervisor) { 178 else if (tlb_type == hypervisor) {
179 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || 179 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
180 sun4v_chip_type == SUN4V_CHIP_NIAGARA2) 180 sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
181 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
181 cap |= HWCAP_SPARC_BLKINIT; 182 cap |= HWCAP_SPARC_BLKINIT;
182 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) 183 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
184 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
183 cap |= HWCAP_SPARC_N2; 185 cap |= HWCAP_SPARC_N2;
184 } 186 }
185 187
diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h
index bee4bf4be3af..9ed6ff679ab7 100644
--- a/arch/sparc/include/asm/xor_64.h
+++ b/arch/sparc/include/asm/xor_64.h
@@ -65,6 +65,7 @@ static struct xor_block_template xor_block_niagara = {
65#define XOR_SELECT_TEMPLATE(FASTEST) \ 65#define XOR_SELECT_TEMPLATE(FASTEST) \
66 ((tlb_type == hypervisor && \ 66 ((tlb_type == hypervisor && \
67 (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ 67 (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \
68 sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ 68 sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \
69 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \
69 &xor_block_niagara : \ 70 &xor_block_niagara : \
70 &xor_block_VIS) 71 &xor_block_VIS)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 70f035c86c03..17cf290dc2bc 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -474,6 +474,12 @@ static void __init sun4v_cpu_probe(void)
474 sparc_pmu_type = "niagara2"; 474 sparc_pmu_type = "niagara2";
475 break; 475 break;
476 476
477 case SUN4V_CHIP_NIAGARA3:
478 sparc_cpu_type = "UltraSparc T3 (Niagara3)";
479 sparc_fpu_type = "UltraSparc T3 integrated FPU";
480 sparc_pmu_type = "niagara3";
481 break;
482
477 default: 483 default:
478 printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", 484 printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
479 prom_cpu_compatible); 485 prom_cpu_compatible);
diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c
index d91fd782743a..4197e8d62d4c 100644
--- a/arch/sparc/kernel/cpumap.c
+++ b/arch/sparc/kernel/cpumap.c
@@ -324,6 +324,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index)
324 switch (sun4v_chip_type) { 324 switch (sun4v_chip_type) {
325 case SUN4V_CHIP_NIAGARA1: 325 case SUN4V_CHIP_NIAGARA1:
326 case SUN4V_CHIP_NIAGARA2: 326 case SUN4V_CHIP_NIAGARA2:
327 case SUN4V_CHIP_NIAGARA3:
327 rover_inc_table = niagara_iterate_method; 328 rover_inc_table = niagara_iterate_method;
328 break; 329 break;
329 default: 330 default:
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index aa594c792d19..c752603a7c0d 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -132,6 +132,8 @@ prom_sun4v_name:
132 .asciz "sun4v" 132 .asciz "sun4v"
133prom_niagara_prefix: 133prom_niagara_prefix:
134 .asciz "SUNW,UltraSPARC-T" 134 .asciz "SUNW,UltraSPARC-T"
135prom_sparc_prefix:
136 .asciz "SPARC-T"
135 .align 4 137 .align 4
136prom_root_compatible: 138prom_root_compatible:
137 .skip 64 139 .skip 64
@@ -382,6 +384,22 @@ sun4v_chip_type:
38290: ldub [%g7], %g2 38490: ldub [%g7], %g2
383 ldub [%g1], %g4 385 ldub [%g1], %g4
384 cmp %g2, %g4 386 cmp %g2, %g4
387 bne,pn %icc, 89f
388 add %g7, 1, %g7
389 subcc %g3, 1, %g3
390 bne,pt %xcc, 90b
391 add %g1, 1, %g1
392 ba,pt %xcc, 91f
393 nop
394
39589: sethi %hi(prom_cpu_compatible), %g1
396 or %g1, %lo(prom_cpu_compatible), %g1
397 sethi %hi(prom_sparc_prefix), %g7
398 or %g7, %lo(prom_sparc_prefix), %g7
399 mov 7, %g3
40090: ldub [%g7], %g2
401 ldub [%g1], %g4
402 cmp %g2, %g4
385 bne,pn %icc, 4f 403 bne,pn %icc, 4f
386 add %g7, 1, %g7 404 add %g7, 1, %g7
387 subcc %g3, 1, %g3 405 subcc %g3, 1, %g3
@@ -390,6 +408,15 @@ sun4v_chip_type:
390 408
391 sethi %hi(prom_cpu_compatible), %g1 409 sethi %hi(prom_cpu_compatible), %g1
392 or %g1, %lo(prom_cpu_compatible), %g1 410 or %g1, %lo(prom_cpu_compatible), %g1
411 ldub [%g1 + 7], %g2
412 cmp %g2, '3'
413 be,pt %xcc, 5f
414 mov SUN4V_CHIP_NIAGARA3, %g4
415 ba,pt %xcc, 4f
416 nop
417
41891: sethi %hi(prom_cpu_compatible), %g1
419 or %g1, %lo(prom_cpu_compatible), %g1
393 ldub [%g1 + 17], %g2 420 ldub [%g1 + 17], %g2
394 cmp %g2, '1' 421 cmp %g2, '1'
395 be,pt %xcc, 5f 422 be,pt %xcc, 5f
@@ -397,6 +424,7 @@ sun4v_chip_type:
397 cmp %g2, '2' 424 cmp %g2, '2'
398 be,pt %xcc, 5f 425 be,pt %xcc, 5f
399 mov SUN4V_CHIP_NIAGARA2, %g4 426 mov SUN4V_CHIP_NIAGARA2, %g4
427
4004: 4284:
401 mov SUN4V_CHIP_UNKNOWN, %g4 429 mov SUN4V_CHIP_UNKNOWN, %g4
4025: sethi %hi(sun4v_chip_type), %g2 4305: sethi %hi(sun4v_chip_type), %g2
@@ -514,6 +542,9 @@ niagara_tlb_fixup:
514 cmp %g1, SUN4V_CHIP_NIAGARA2 542 cmp %g1, SUN4V_CHIP_NIAGARA2
515 be,pt %xcc, niagara2_patch 543 be,pt %xcc, niagara2_patch
516 nop 544 nop
545 cmp %g1, SUN4V_CHIP_NIAGARA3
546 be,pt %xcc, niagara2_patch
547 nop
517 548
518 call generic_patch_copyops 549 call generic_patch_copyops
519 nop 550 nop
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index 878c6824c732..343b0f9e2e7b 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -109,6 +109,10 @@ static int __init register_perf_hsvc(void)
109 perf_hsvc_group = HV_GRP_N2_CPU; 109 perf_hsvc_group = HV_GRP_N2_CPU;
110 break; 110 break;
111 111
112 case SUN4V_CHIP_NIAGARA3:
113 perf_hsvc_group = HV_GRP_KT_CPU;
114 break;
115
112 default: 116 default:
113 return -ENODEV; 117 return -ENODEV;
114 } 118 }
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 171e8d84dc3f..614da624330c 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1343,7 +1343,8 @@ static bool __init supported_pmu(void)
1343 sparc_pmu = &niagara1_pmu; 1343 sparc_pmu = &niagara1_pmu;
1344 return true; 1344 return true;
1345 } 1345 }
1346 if (!strcmp(sparc_pmu_type, "niagara2")) { 1346 if (!strcmp(sparc_pmu_type, "niagara2") ||
1347 !strcmp(sparc_pmu_type, "niagara3")) {
1347 sparc_pmu = &niagara2_pmu; 1348 sparc_pmu = &niagara2_pmu;
1348 return true; 1349 return true;
1349 } 1350 }