armcap.c revision 31cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895
131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <stdio.h> 231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <stdlib.h> 331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <string.h> 431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <setjmp.h> 531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <signal.h> 631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <crypto.h> 731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include "arm_arch.h" 931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootunsigned int OPENSSL_armcap_P; 1131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic sigset_t all_masked; 1331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic sigjmp_buf ill_jmp; 1531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } 1631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root/* 1831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root * Following subroutines could have been inlined, but it's not all 1931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root * ARM compilers support inline assembler... 2031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root */ 2131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid _armv7_neon_probe(void); 2231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootunsigned int _armv7_tick(void); 2331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 2431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootunsigned int OPENSSL_rdtsc(void) 2531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 2631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (OPENSSL_armcap_P & ARMV7_TICK) 2731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return _armv7_tick(); 2831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root else 2931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return 0; 3031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 3131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 3231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#if defined(__GNUC__) && __GNUC__>=2 3331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid OPENSSL_cpuid_setup(void) __attribute__((constructor)); 3431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#endif 3531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid OPENSSL_cpuid_setup(void) 3631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 3731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root char *e; 3831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root struct sigaction ill_oact,ill_act; 3931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigset_t oset; 4031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root static int trigger=0; 4131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 4231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (trigger) return; 4331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root trigger=1; 4431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 4531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if ((e=getenv("OPENSSL_armcap"))) 4631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 4731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P=strtoul(e,NULL,0); 4831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return; 4931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 5031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 5131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigfillset(&all_masked); 5231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGILL); 5331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGTRAP); 5431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGFPE); 5531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGBUS); 5631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGSEGV); 5731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 5831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P = 0; 5931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 6031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root memset(&ill_act,0,sizeof(ill_act)); 6131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root ill_act.sa_handler = ill_handler; 6231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root ill_act.sa_mask = all_masked; 6331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 6431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); 6531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigaction(SIGILL,&ill_act,&ill_oact); 6631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 6731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 6831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 6931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root _armv7_neon_probe(); 7031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P |= ARMV7_NEON; 7131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 7231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 7331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 7431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root _armv7_tick(); 7531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P |= ARMV7_TICK; 7631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 7731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 7831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigaction (SIGILL,&ill_oact,NULL); 7931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigprocmask(SIG_SETMASK,&oset,NULL); 8031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 81