armcap.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <setjmp.h>
  5. #include <signal.h>
  6. #include <crypto.h>
  7. #include "arm_arch.h"
  8. unsigned int OPENSSL_armcap_P;
  9. static sigset_t all_masked;
  10. static sigjmp_buf ill_jmp;
  11. static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
  12. /*
  13. * Following subroutines could have been inlined, but it's not all
  14. * ARM compilers support inline assembler...
  15. */
  16. void _armv7_neon_probe(void);
  17. unsigned int _armv7_tick(void);
  18. unsigned int OPENSSL_rdtsc(void)
  19. {
  20. if (OPENSSL_armcap_P|ARMV7_TICK)
  21. return _armv7_tick();
  22. else
  23. return 0;
  24. }
  25. void OPENSSL_cpuid_setup(void)
  26. {
  27. char *e;
  28. struct sigaction ill_oact,ill_act;
  29. sigset_t oset;
  30. static int trigger=0;
  31. if (trigger) return;
  32. trigger=1;
  33. if ((e=getenv("OPENSSL_armcap")))
  34. {
  35. OPENSSL_armcap_P=strtoul(e,NULL,0);
  36. return;
  37. }
  38. sigfillset(&all_masked);
  39. sigdelset(&all_masked,SIGILL);
  40. sigdelset(&all_masked,SIGTRAP);
  41. sigdelset(&all_masked,SIGFPE);
  42. sigdelset(&all_masked,SIGBUS);
  43. sigdelset(&all_masked,SIGSEGV);
  44. OPENSSL_armcap_P = 0;
  45. memset(&ill_act,0,sizeof(ill_act));
  46. ill_act.sa_handler = ill_handler;
  47. ill_act.sa_mask = all_masked;
  48. sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
  49. sigaction(SIGILL,&ill_act,&ill_oact);
  50. if (sigsetjmp(ill_jmp,1) == 0)
  51. {
  52. _armv7_neon_probe();
  53. OPENSSL_armcap_P |= ARMV7_NEON;
  54. }
  55. if (sigsetjmp(ill_jmp,1) == 0)
  56. {
  57. _armv7_tick();
  58. OPENSSL_armcap_P |= ARMV7_TICK;
  59. }
  60. sigaction (SIGILL,&ill_oact,NULL);
  61. sigprocmask(SIG_SETMASK,&oset,NULL);
  62. }