提交 b6769a38 编写于 作者: B Bernd Edlinger

PPC: Try out if mftb works before using it

If this fails try out if mfspr268 works.

Use OPENSSL_ppccap=0x20 for enabling mftb,
OPENSSL_ppccap=0x40 for enabling mfspr268,
and OPENSSL_ppccap=0 for enabling neither.

Fixes #8012
Reviewed-by: NPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8043)

(cherry picked from commit c8f370485c43729db44b680e41e875ddd7f3108c)
上级 492f7064
...@@ -460,4 +460,14 @@ uint32_t OPENSSL_rdtsc(void) ...@@ -460,4 +460,14 @@ uint32_t OPENSSL_rdtsc(void)
{ {
return 0; return 0;
} }
size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
{
return 0;
}
size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
{
return 0;
}
#endif #endif
...@@ -22,5 +22,7 @@ extern unsigned int OPENSSL_ppccap_P; ...@@ -22,5 +22,7 @@ extern unsigned int OPENSSL_ppccap_P;
# define PPC_CRYPTO207 (1<<2) # define PPC_CRYPTO207 (1<<2)
# define PPC_FPU (1<<3) # define PPC_FPU (1<<3)
# define PPC_MADD300 (1<<4) # define PPC_MADD300 (1<<4)
# define PPC_MFTB (1<<5)
# define PPC_MFSPR268 (1<<6)
#endif #endif
...@@ -168,6 +168,45 @@ void OPENSSL_altivec_probe(void); ...@@ -168,6 +168,45 @@ void OPENSSL_altivec_probe(void);
void OPENSSL_crypto207_probe(void); void OPENSSL_crypto207_probe(void);
void OPENSSL_madd300_probe(void); void OPENSSL_madd300_probe(void);
long OPENSSL_rdtsc_mftb(void);
long OPENSSL_rdtsc_mfspr268(void);
uint32_t OPENSSL_rdtsc(void)
{
if (OPENSSL_ppccap_P & PPC_MFTB)
return OPENSSL_rdtsc_mftb();
else if (OPENSSL_ppccap_P & PPC_MFSPR268)
return OPENSSL_rdtsc_mfspr268();
else
return 0;
}
size_t OPENSSL_instrument_bus_mftb(unsigned int *, size_t);
size_t OPENSSL_instrument_bus_mfspr268(unsigned int *, size_t);
size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
{
if (OPENSSL_ppccap_P & PPC_MFTB)
return OPENSSL_instrument_bus_mftb(out, cnt);
else if (OPENSSL_ppccap_P & PPC_MFSPR268)
return OPENSSL_instrument_bus_mfspr268(out, cnt);
else
return 0;
}
size_t OPENSSL_instrument_bus2_mftb(unsigned int *, size_t, size_t);
size_t OPENSSL_instrument_bus2_mfspr268(unsigned int *, size_t, size_t);
size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
{
if (OPENSSL_ppccap_P & PPC_MFTB)
return OPENSSL_instrument_bus2_mftb(out, cnt, max);
else if (OPENSSL_ppccap_P & PPC_MFSPR268)
return OPENSSL_instrument_bus2_mfspr268(out, cnt, max);
else
return 0;
}
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
# if __GLIBC_PREREQ(2, 16) # if __GLIBC_PREREQ(2, 16)
# include <sys/auxv.h> # include <sys/auxv.h>
...@@ -300,8 +339,6 @@ void OPENSSL_cpuid_setup(void) ...@@ -300,8 +339,6 @@ void OPENSSL_cpuid_setup(void)
if (hwcap & HWCAP_ARCH_3_00) { if (hwcap & HWCAP_ARCH_3_00) {
OPENSSL_ppccap_P |= PPC_MADD300; OPENSSL_ppccap_P |= PPC_MADD300;
} }
return;
} }
#endif #endif
...@@ -322,15 +359,16 @@ void OPENSSL_cpuid_setup(void) ...@@ -322,15 +359,16 @@ void OPENSSL_cpuid_setup(void)
sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
sigaction(SIGILL, &ill_act, &ill_oact); sigaction(SIGILL, &ill_act, &ill_oact);
#ifndef OSSL_IMPLEMENT_GETAUXVAL
if (sigsetjmp(ill_jmp,1) == 0) { if (sigsetjmp(ill_jmp,1) == 0) {
OPENSSL_fpu_probe(); OPENSSL_fpu_probe();
OPENSSL_ppccap_P |= PPC_FPU; OPENSSL_ppccap_P |= PPC_FPU;
if (sizeof(size_t) == 4) { if (sizeof(size_t) == 4) {
#ifdef __linux # ifdef __linux
struct utsname uts; struct utsname uts;
if (uname(&uts) == 0 && strcmp(uts.machine, "ppc64") == 0) if (uname(&uts) == 0 && strcmp(uts.machine, "ppc64") == 0)
#endif # endif
if (sigsetjmp(ill_jmp, 1) == 0) { if (sigsetjmp(ill_jmp, 1) == 0) {
OPENSSL_ppc64_probe(); OPENSSL_ppc64_probe();
OPENSSL_ppccap_P |= PPC_FPU64; OPENSSL_ppccap_P |= PPC_FPU64;
...@@ -355,6 +393,15 @@ void OPENSSL_cpuid_setup(void) ...@@ -355,6 +393,15 @@ void OPENSSL_cpuid_setup(void)
OPENSSL_madd300_probe(); OPENSSL_madd300_probe();
OPENSSL_ppccap_P |= PPC_MADD300; OPENSSL_ppccap_P |= PPC_MADD300;
} }
#endif
if (sigsetjmp(ill_jmp, 1) == 0) {
OPENSSL_rdtsc_mftb();
OPENSSL_ppccap_P |= PPC_MFTB;
} else if (sigsetjmp(ill_jmp, 1) == 0) {
OPENSSL_rdtsc_mfspr268();
OPENSSL_ppccap_P |= PPC_MFSPR268;
}
sigaction(SIGILL, &ill_oact, NULL); sigaction(SIGILL, &ill_oact, NULL);
sigprocmask(SIG_SETMASK, &oset, NULL); sigprocmask(SIG_SETMASK, &oset, NULL);
......
...@@ -124,26 +124,23 @@ Ladd: lwarx r5,0,r3 ...@@ -124,26 +124,23 @@ Ladd: lwarx r5,0,r3
.long 0 .long 0
.size .OPENSSL_atomic_add,.-.OPENSSL_atomic_add .size .OPENSSL_atomic_add,.-.OPENSSL_atomic_add
.globl .OPENSSL_rdtsc .globl .OPENSSL_rdtsc_mftb
.align 4 .align 4
.OPENSSL_rdtsc: .OPENSSL_rdtsc_mftb:
___
$code.=<<___ if ($flavour =~ /64/);
mftb r3
___
$code.=<<___ if ($flavour !~ /64/);
Loop_rdtsc:
mftbu r5
mftb r3 mftb r3
mftbu r4
cmplw r4,r5
bne Loop_rdtsc
___
$code.=<<___;
blr blr
.long 0 .long 0
.byte 0,12,0x14,0,0,0,0,0 .byte 0,12,0x14,0,0,0,0,0
.size .OPENSSL_rdtsc,.-.OPENSSL_rdtsc .size .OPENSSL_rdtsc_mftb,.-.OPENSSL_rdtsc_mftb
.globl .OPENSSL_rdtsc_mfspr268
.align 4
.OPENSSL_rdtsc_mfspr268:
mfspr r3,268
blr
.long 0
.byte 0,12,0x14,0,0,0,0,0
.size .OPENSSL_rdtsc_mfspr268,.-.OPENSSL_rdtsc_mfspr268
.globl .OPENSSL_cleanse .globl .OPENSSL_cleanse
.align 4 .align 4
...@@ -210,9 +207,9 @@ my ($tick,$lasttick)=("r6","r7"); ...@@ -210,9 +207,9 @@ my ($tick,$lasttick)=("r6","r7");
my ($diff,$lastdiff)=("r8","r9"); my ($diff,$lastdiff)=("r8","r9");
$code.=<<___; $code.=<<___;
.globl .OPENSSL_instrument_bus .globl .OPENSSL_instrument_bus_mftb
.align 4 .align 4
.OPENSSL_instrument_bus: .OPENSSL_instrument_bus_mftb:
mtctr $cnt mtctr $cnt
mftb $lasttick # collect 1st tick mftb $lasttick # collect 1st tick
...@@ -240,11 +237,11 @@ Loop: mftb $tick ...@@ -240,11 +237,11 @@ Loop: mftb $tick
.long 0 .long 0
.byte 0,12,0x14,0,0,0,2,0 .byte 0,12,0x14,0,0,0,2,0
.long 0 .long 0
.size .OPENSSL_instrument_bus,.-.OPENSSL_instrument_bus .size .OPENSSL_instrument_bus_mftb,.-.OPENSSL_instrument_bus_mftb
.globl .OPENSSL_instrument_bus2 .globl .OPENSSL_instrument_bus2_mftb
.align 4 .align 4
.OPENSSL_instrument_bus2: .OPENSSL_instrument_bus2_mftb:
mr r0,$cnt mr r0,$cnt
slwi $cnt,$cnt,2 slwi $cnt,$cnt,2
...@@ -292,7 +289,91 @@ Ldone2: ...@@ -292,7 +289,91 @@ Ldone2:
.long 0 .long 0
.byte 0,12,0x14,0,0,0,3,0 .byte 0,12,0x14,0,0,0,3,0
.long 0 .long 0
.size .OPENSSL_instrument_bus2,.-.OPENSSL_instrument_bus2 .size .OPENSSL_instrument_bus2_mftb,.-.OPENSSL_instrument_bus2_mftb
.globl .OPENSSL_instrument_bus_mfspr268
.align 4
.OPENSSL_instrument_bus_mfspr268:
mtctr $cnt
mfspr $lasttick,268 # collect 1st tick
li $diff,0
dcbf 0,$out # flush cache line
lwarx $tick,0,$out # load and lock
add $tick,$tick,$diff
stwcx. $tick,0,$out
stwx $tick,0,$out
Loop3: mfspr $tick,268
sub $diff,$tick,$lasttick
mr $lasttick,$tick
dcbf 0,$out # flush cache line
lwarx $tick,0,$out # load and lock
add $tick,$tick,$diff
stwcx. $tick,0,$out
stwx $tick,0,$out
addi $out,$out,4 # ++$out
bdnz Loop3
mr r3,$cnt
blr
.long 0
.byte 0,12,0x14,0,0,0,2,0
.long 0
.size .OPENSSL_instrument_bus_mfspr268,.-.OPENSSL_instrument_bus_mfspr268
.globl .OPENSSL_instrument_bus2_mfspr268
.align 4
.OPENSSL_instrument_bus2_mfspr268:
mr r0,$cnt
slwi $cnt,$cnt,2
mfspr $lasttick,268 # collect 1st tick
li $diff,0
dcbf 0,$out # flush cache line
lwarx $tick,0,$out # load and lock
add $tick,$tick,$diff
stwcx. $tick,0,$out
stwx $tick,0,$out
mfspr $tick,268 # collect 1st diff
sub $diff,$tick,$lasttick
mr $lasttick,$tick
mr $lastdiff,$diff
Loop4:
dcbf 0,$out # flush cache line
lwarx $tick,0,$out # load and lock
add $tick,$tick,$diff
stwcx. $tick,0,$out
stwx $tick,0,$out
addic. $max,$max,-1
beq Ldone4
mfspr $tick,268
sub $diff,$tick,$lasttick
mr $lasttick,$tick
cmplw 7,$diff,$lastdiff
mr $lastdiff,$diff
mfcr $tick # pull cr
not $tick,$tick # flip bits
rlwinm $tick,$tick,1,29,29 # isolate flipped eq bit and scale
sub. $cnt,$cnt,$tick # conditional --$cnt
add $out,$out,$tick # conditional ++$out
bne Loop4
Ldone4:
srwi $cnt,$cnt,2
sub r3,r0,$cnt
blr
.long 0
.byte 0,12,0x14,0,0,0,3,0
.long 0
.size .OPENSSL_instrument_bus2_mfspr268,.-.OPENSSL_instrument_bus2_mfspr268
___ ___
} }
......
...@@ -92,5 +92,7 @@ void *openssl_fopen(const char *filename, const char *mode); ...@@ -92,5 +92,7 @@ void *openssl_fopen(const char *filename, const char *mode);
# endif # endif
uint32_t OPENSSL_rdtsc(void); uint32_t OPENSSL_rdtsc(void);
size_t OPENSSL_instrument_bus(unsigned int *, size_t);
size_t OPENSSL_instrument_bus2(unsigned int *, size_t, size_t);
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册