1238384Sjkim#include <stdio.h> 2238384Sjkim#include <stdlib.h> 3238384Sjkim#include <string.h> 4238384Sjkim#include <setjmp.h> 5238384Sjkim#include <signal.h> 6238384Sjkim#include <crypto.h> 7238384Sjkim 8238384Sjkim#include "arm_arch.h" 9238384Sjkim 10238384Sjkimunsigned int OPENSSL_armcap_P; 11238384Sjkim 12238384Sjkimstatic sigset_t all_masked; 13238384Sjkim 14238384Sjkimstatic sigjmp_buf ill_jmp; 15238384Sjkimstatic void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } 16238384Sjkim 17238384Sjkim/* 18238384Sjkim * Following subroutines could have been inlined, but it's not all 19238384Sjkim * ARM compilers support inline assembler... 20238384Sjkim */ 21238384Sjkimvoid _armv7_neon_probe(void); 22238384Sjkimunsigned int _armv7_tick(void); 23238384Sjkim 24238384Sjkimunsigned int OPENSSL_rdtsc(void) 25238384Sjkim { 26279264Sdelphij if (OPENSSL_armcap_P & ARMV7_TICK) 27238384Sjkim return _armv7_tick(); 28238384Sjkim else 29238384Sjkim return 0; 30238384Sjkim } 31238384Sjkim 32238384Sjkim#if defined(__GNUC__) && __GNUC__>=2 33238384Sjkimvoid OPENSSL_cpuid_setup(void) __attribute__((constructor)); 34238384Sjkim#endif 35238384Sjkimvoid OPENSSL_cpuid_setup(void) 36238384Sjkim { 37238384Sjkim char *e; 38238384Sjkim struct sigaction ill_oact,ill_act; 39238384Sjkim sigset_t oset; 40238384Sjkim static int trigger=0; 41238384Sjkim 42238384Sjkim if (trigger) return; 43238384Sjkim trigger=1; 44238384Sjkim 45238384Sjkim if ((e=getenv("OPENSSL_armcap"))) 46238384Sjkim { 47238384Sjkim OPENSSL_armcap_P=strtoul(e,NULL,0); 48238384Sjkim return; 49238384Sjkim } 50238384Sjkim 51238384Sjkim sigfillset(&all_masked); 52238384Sjkim sigdelset(&all_masked,SIGILL); 53238384Sjkim sigdelset(&all_masked,SIGTRAP); 54238384Sjkim sigdelset(&all_masked,SIGFPE); 55238384Sjkim sigdelset(&all_masked,SIGBUS); 56238384Sjkim sigdelset(&all_masked,SIGSEGV); 57238384Sjkim 58238384Sjkim OPENSSL_armcap_P = 0; 59238384Sjkim 60238384Sjkim memset(&ill_act,0,sizeof(ill_act)); 61238384Sjkim ill_act.sa_handler = ill_handler; 62238384Sjkim ill_act.sa_mask = all_masked; 63238384Sjkim 64238384Sjkim sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); 65238384Sjkim sigaction(SIGILL,&ill_act,&ill_oact); 66238384Sjkim 67238384Sjkim if (sigsetjmp(ill_jmp,1) == 0) 68238384Sjkim { 69238384Sjkim _armv7_neon_probe(); 70238384Sjkim OPENSSL_armcap_P |= ARMV7_NEON; 71238384Sjkim } 72238384Sjkim if (sigsetjmp(ill_jmp,1) == 0) 73238384Sjkim { 74238384Sjkim _armv7_tick(); 75238384Sjkim OPENSSL_armcap_P |= ARMV7_TICK; 76238384Sjkim } 77238384Sjkim 78238384Sjkim sigaction (SIGILL,&ill_oact,NULL); 79238384Sjkim sigprocmask(SIG_SETMASK,&oset,NULL); 80238384Sjkim } 81