Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+50 -4
+4 -2
arch/sparc/include/asm/elf_64.h
··· 177 177 cap |= HWCAP_SPARC_ULTRA3; 178 178 else if (tlb_type == hypervisor) { 179 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 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 185 cap |= HWCAP_SPARC_N2; 184 186 } 185 187
+2 -1
arch/sparc/include/asm/xor_64.h
··· 65 65 #define XOR_SELECT_TEMPLATE(FASTEST) \ 66 66 ((tlb_type == hypervisor && \ 67 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 70 &xor_block_niagara : \ 70 71 &xor_block_VIS)
+6
arch/sparc/kernel/cpu.c
··· 474 474 sparc_pmu_type = "niagara2"; 475 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 483 default: 478 484 printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", 479 485 prom_cpu_compatible);
+1
arch/sparc/kernel/cpumap.c
··· 324 324 switch (sun4v_chip_type) { 325 325 case SUN4V_CHIP_NIAGARA1: 326 326 case SUN4V_CHIP_NIAGARA2: 327 + case SUN4V_CHIP_NIAGARA3: 327 328 rover_inc_table = niagara_iterate_method; 328 329 break; 329 330 default:
+31
arch/sparc/kernel/head_64.S
··· 132 132 .asciz "sun4v" 133 133 prom_niagara_prefix: 134 134 .asciz "SUNW,UltraSPARC-T" 135 + prom_sparc_prefix: 136 + .asciz "SPARC-T" 135 137 .align 4 136 138 prom_root_compatible: 137 139 .skip 64 ··· 384 382 90: ldub [%g7], %g2 385 383 ldub [%g1], %g4 386 384 cmp %g2, %g4 385 + bne,pn %icc, 89f 386 + add %g7, 1, %g7 387 + subcc %g3, 1, %g3 388 + bne,pt %xcc, 90b 389 + add %g1, 1, %g1 390 + ba,pt %xcc, 91f 391 + nop 392 + 393 + 89: sethi %hi(prom_cpu_compatible), %g1 394 + or %g1, %lo(prom_cpu_compatible), %g1 395 + sethi %hi(prom_sparc_prefix), %g7 396 + or %g7, %lo(prom_sparc_prefix), %g7 397 + mov 7, %g3 398 + 90: ldub [%g7], %g2 399 + ldub [%g1], %g4 400 + cmp %g2, %g4 387 401 bne,pn %icc, 4f 388 402 add %g7, 1, %g7 389 403 subcc %g3, 1, %g3 ··· 408 390 409 391 sethi %hi(prom_cpu_compatible), %g1 410 392 or %g1, %lo(prom_cpu_compatible), %g1 393 + ldub [%g1 + 7], %g2 394 + cmp %g2, '3' 395 + be,pt %xcc, 5f 396 + mov SUN4V_CHIP_NIAGARA3, %g4 397 + ba,pt %xcc, 4f 398 + nop 399 + 400 + 91: sethi %hi(prom_cpu_compatible), %g1 401 + or %g1, %lo(prom_cpu_compatible), %g1 411 402 ldub [%g1 + 17], %g2 412 403 cmp %g2, '1' 413 404 be,pt %xcc, 5f ··· 424 397 cmp %g2, '2' 425 398 be,pt %xcc, 5f 426 399 mov SUN4V_CHIP_NIAGARA2, %g4 400 + 427 401 4: 428 402 mov SUN4V_CHIP_UNKNOWN, %g4 429 403 5: sethi %hi(sun4v_chip_type), %g2 ··· 540 512 cmp %g1, SUN4V_CHIP_NIAGARA1 541 513 be,pt %xcc, niagara_patch 542 514 cmp %g1, SUN4V_CHIP_NIAGARA2 515 + be,pt %xcc, niagara2_patch 516 + nop 517 + cmp %g1, SUN4V_CHIP_NIAGARA3 543 518 be,pt %xcc, niagara2_patch 544 519 nop 545 520
+4
arch/sparc/kernel/pcr.c
··· 109 109 perf_hsvc_group = HV_GRP_N2_CPU; 110 110 break; 111 111 112 + case SUN4V_CHIP_NIAGARA3: 113 + perf_hsvc_group = HV_GRP_KT_CPU; 114 + break; 115 + 112 116 default: 113 117 return -ENODEV; 114 118 }
+2 -1
arch/sparc/kernel/perf_event.c
··· 1343 1343 sparc_pmu = &niagara1_pmu; 1344 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 1348 sparc_pmu = &niagara2_pmu; 1348 1349 return true; 1349 1350 }