diff options
| author | miod <> | 2014-05-03 11:39:46 +0000 |
|---|---|---|
| committer | miod <> | 2014-05-03 11:39:46 +0000 |
| commit | e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89 (patch) | |
| tree | 4894a238b9d6f90afcd5e05c9289f12898608e8f /src/lib/libc | |
| parent | 3b20898d344ff6a38978c4f7510cf37c20ab0986 (diff) | |
| download | openbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.tar.gz openbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.tar.bz2 openbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.zip | |
Detect Altivec support with the machdep.altivec sysctl rather than setmp and
a SIGILL handler.
Do not attempt to detect and use a 64-bit FPU yet.
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/ppccap.c | 112 | ||||
| -rwxr-xr-x | src/lib/libcrypto/ppccpuid.pl | 10 |
2 files changed, 20 insertions, 102 deletions
diff --git a/src/lib/libcrypto/ppccap.c b/src/lib/libcrypto/ppccap.c index 4d7dd38dd1..4cedefed2c 100644 --- a/src/lib/libcrypto/ppccap.c +++ b/src/lib/libcrypto/ppccap.c | |||
| @@ -1,124 +1,48 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <setjmp.h> | ||
| 5 | #include <signal.h> | ||
| 6 | #include <unistd.h> | 1 | #include <unistd.h> |
| 2 | #include <sys/param.h> | ||
| 3 | #include <sys/sysctl.h> | ||
| 4 | #include <machine/cpu.h> | ||
| 5 | |||
| 7 | #include <crypto.h> | 6 | #include <crypto.h> |
| 8 | #include <openssl/bn.h> | 7 | #include <openssl/bn.h> |
| 9 | 8 | ||
| 9 | #ifdef unused | ||
| 10 | #define PPC_FPU64 (1<<0) | 10 | #define PPC_FPU64 (1<<0) |
| 11 | #define PPC_ALTIVEC (1<<1) | 11 | #define PPC_ALTIVEC (1<<1) |
| 12 | 12 | ||
| 13 | static int OPENSSL_ppccap_P = 0; | 13 | static int OPENSSL_ppccap_P = 0; |
| 14 | 14 | #endif | |
| 15 | static sigset_t all_masked; | ||
| 16 | 15 | ||
| 17 | #ifdef OPENSSL_BN_ASM_MONT | 16 | #ifdef OPENSSL_BN_ASM_MONT |
| 17 | extern int bn_mul_mont_int(BN_ULONG *, const BN_ULONG *, const BN_ULONG *, | ||
| 18 | const BN_ULONG *, const BN_ULONG *, int); | ||
| 18 | int | 19 | int |
| 19 | bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, | 20 | bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
| 20 | const BN_ULONG *np, const BN_ULONG *n0, int num) | 21 | const BN_ULONG *np, const BN_ULONG *n0, int num) |
| 21 | { | 22 | { |
| 22 | int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); | ||
| 23 | int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); | ||
| 24 | |||
| 25 | if (sizeof(size_t) == 4) { | ||
| 26 | #if (defined(__APPLE__) && defined(__MACH__)) | ||
| 27 | if (num >= 8 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64)) | ||
| 28 | return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); | ||
| 29 | #else | ||
| 30 | /* boundary of 32 was experimentally determined on | ||
| 31 | Linux 2.6.22, might have to be adjusted on AIX... */ | ||
| 32 | if (num >= 32 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64)) { | ||
| 33 | sigset_t oset; | ||
| 34 | int ret; | ||
| 35 | |||
| 36 | sigprocmask(SIG_SETMASK, &all_masked, &oset); | ||
| 37 | ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); | ||
| 38 | sigprocmask(SIG_SETMASK, &oset, NULL); | ||
| 39 | |||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | #endif | ||
| 43 | } else if ((OPENSSL_ppccap_P&PPC_FPU64)) | ||
| 44 | /* this is a "must" on POWER6, but run-time detection | ||
| 45 | * is not implemented yet... */ | ||
| 46 | return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); | ||
| 47 | |||
| 48 | return bn_mul_mont_int(rp, ap, bp, np, n0, num); | 23 | return bn_mul_mont_int(rp, ap, bp, np, n0, num); |
| 49 | } | 24 | } |
| 50 | #endif | 25 | #endif |
| 51 | 26 | ||
| 52 | static sigjmp_buf ill_jmp; | 27 | #ifdef unused |
| 53 | static void ill_handler (int sig) | 28 | void OPENSSL_cpuid_setup(void) __attribute__((constructor)); |
| 54 | { | ||
| 55 | siglongjmp(ill_jmp, sig); | ||
| 56 | } | ||
| 57 | |||
| 58 | void OPENSSL_ppc64_probe(void); | ||
| 59 | void OPENSSL_altivec_probe(void); | ||
| 60 | 29 | ||
| 61 | void | 30 | void |
| 62 | OPENSSL_cpuid_setup(void) | 31 | OPENSSL_cpuid_setup(void) |
| 63 | { | 32 | { |
| 64 | char *e; | 33 | static const int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC }; |
| 65 | struct sigaction ill_oact, ill_act; | ||
| 66 | sigset_t oset; | ||
| 67 | static int trigger = 0; | 34 | static int trigger = 0; |
| 35 | int altivec = 0; | ||
| 36 | size_t size; | ||
| 68 | 37 | ||
| 69 | if (trigger) | 38 | if (trigger) |
| 70 | return; | 39 | return; |
| 71 | trigger = 1; | 40 | trigger = 1; |
| 72 | 41 | ||
| 73 | sigfillset(&all_masked); | 42 | size = sizeof altivec; |
| 74 | sigdelset(&all_masked, SIGILL); | 43 | if (sysctl(mib, 2, &altivec, &size, NULL, 0) != -1) { |
| 75 | sigdelset(&all_masked, SIGTRAP); | 44 | if (altivec != 0) |
| 76 | #ifdef SIGEMT | 45 | OPENSSL_ppccap_P |= PPC_ALTIVEC; |
| 77 | sigdelset(&all_masked, SIGEMT); | ||
| 78 | #endif | ||
| 79 | sigdelset(&all_masked, SIGFPE); | ||
| 80 | sigdelset(&all_masked, SIGBUS); | ||
| 81 | sigdelset(&all_masked, SIGSEGV); | ||
| 82 | |||
| 83 | if ((e = getenv("OPENSSL_ppccap"))) { | ||
| 84 | OPENSSL_ppccap_P = strtoul(e, NULL, 0); | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | |||
| 88 | OPENSSL_ppccap_P = 0; | ||
| 89 | |||
| 90 | #if defined(_AIX) | ||
| 91 | if (sizeof(size_t) == 4 | ||
| 92 | # if defined(_SC_AIX_KERNEL_BITMODE) | ||
| 93 | && sysconf(_SC_AIX_KERNEL_BITMODE) != 64 | ||
| 94 | # endif | ||
| 95 | ) | ||
| 96 | return; | ||
| 97 | #endif | ||
| 98 | |||
| 99 | memset(&ill_act, 0, sizeof(ill_act)); | ||
| 100 | ill_act.sa_handler = ill_handler; | ||
| 101 | ill_act.sa_mask = all_masked; | ||
| 102 | |||
| 103 | sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); | ||
| 104 | sigaction(SIGILL, &ill_act, &ill_oact); | ||
| 105 | |||
| 106 | if (sizeof(size_t) == 4) { | ||
| 107 | if (sigsetjmp(ill_jmp, 1) == 0) { | ||
| 108 | OPENSSL_ppc64_probe(); | ||
| 109 | OPENSSL_ppccap_P |= PPC_FPU64; | ||
| 110 | } | ||
| 111 | } else { | ||
| 112 | /* | ||
| 113 | * Wanted code detecting POWER6 CPU and setting PPC_FPU64 | ||
| 114 | */ | ||
| 115 | } | ||
| 116 | |||
| 117 | if (sigsetjmp(ill_jmp, 1) == 0) { | ||
| 118 | OPENSSL_altivec_probe(); | ||
| 119 | OPENSSL_ppccap_P |= PPC_ALTIVEC; | ||
| 120 | } | 46 | } |
| 121 | |||
| 122 | sigaction (SIGILL, &ill_oact, NULL); | ||
| 123 | sigprocmask(SIG_SETMASK, &oset, NULL); | ||
| 124 | } | 47 | } |
| 48 | #endif | ||
diff --git a/src/lib/libcrypto/ppccpuid.pl b/src/lib/libcrypto/ppccpuid.pl index 37c33c051a..0cef7014b6 100755 --- a/src/lib/libcrypto/ppccpuid.pl +++ b/src/lib/libcrypto/ppccpuid.pl | |||
| @@ -23,6 +23,7 @@ $code=<<___; | |||
| 23 | .machine "any" | 23 | .machine "any" |
| 24 | .text | 24 | .text |
| 25 | 25 | ||
| 26 | #if 0 | ||
| 26 | .globl .OPENSSL_ppc64_probe | 27 | .globl .OPENSSL_ppc64_probe |
| 27 | .align 4 | 28 | .align 4 |
| 28 | .OPENSSL_ppc64_probe: | 29 | .OPENSSL_ppc64_probe: |
| @@ -31,14 +32,7 @@ $code=<<___; | |||
| 31 | blr | 32 | blr |
| 32 | .long 0 | 33 | .long 0 |
| 33 | .byte 0,12,0x14,0,0,0,0,0 | 34 | .byte 0,12,0x14,0,0,0,0,0 |
| 34 | 35 | #endif | |
| 35 | .globl .OPENSSL_altivec_probe | ||
| 36 | .align 4 | ||
| 37 | .OPENSSL_altivec_probe: | ||
| 38 | .long 0x10000484 # vor v0,v0,v0 | ||
| 39 | blr | ||
| 40 | .long 0 | ||
| 41 | .byte 0,12,0x14,0,0,0,0,0 | ||
| 42 | 36 | ||
| 43 | .globl .OPENSSL_wipe_cpu | 37 | .globl .OPENSSL_wipe_cpu |
| 44 | .align 4 | 38 | .align 4 |
