Use the ARM CPUID functions

This allows us to use CPU-specific clean, rdtsc, and capability
settings.

Change-Id: I0f2792f37c2c0d4c4ec0c35d76e447bd6565d276
diff --git a/Crypto-config-host.mk b/Crypto-config-host.mk
index aa5a419..606d169 100644
--- a/Crypto-config-host.mk
+++ b/Crypto-config-host.mk
@@ -549,6 +549,7 @@
   -DGHASH_ASM \
   -DOPENSSL_BN_ASM_GF2m \
   -DOPENSSL_BN_ASM_MONT \
+  -DOPENSSL_CPUID_OBJ \
   -DSHA1_ASM \
   -DSHA256_ASM \
   -DSHA512_ASM \
@@ -556,6 +557,8 @@
 arm_src_files := \
   crypto/aes/asm/aes-armv4.S \
   crypto/aes/asm/bsaes-armv7.S \
+  crypto/armcap.c \
+  crypto/armv4cpuid.S \
   crypto/bn/asm/armv4-gf2m.S \
   crypto/bn/asm/armv4-mont.S \
   crypto/modes/asm/ghash-armv4.S \
@@ -565,6 +568,7 @@
 
 arm_exclude_files := \
   crypto/aes/aes_core.c \
+  crypto/mem_clr.c \
 
 arm64_cflags := \
   -DOPENSSL_NO_ASM \
diff --git a/Crypto-config-target.mk b/Crypto-config-target.mk
index ec8a240..d4a938d 100644
--- a/Crypto-config-target.mk
+++ b/Crypto-config-target.mk
@@ -549,6 +549,7 @@
   -DGHASH_ASM \
   -DOPENSSL_BN_ASM_GF2m \
   -DOPENSSL_BN_ASM_MONT \
+  -DOPENSSL_CPUID_OBJ \
   -DSHA1_ASM \
   -DSHA256_ASM \
   -DSHA512_ASM \
@@ -556,6 +557,8 @@
 arm_src_files := \
   crypto/aes/asm/aes-armv4.S \
   crypto/aes/asm/bsaes-armv7.S \
+  crypto/armcap.c \
+  crypto/armv4cpuid.S \
   crypto/bn/asm/armv4-gf2m.S \
   crypto/bn/asm/armv4-mont.S \
   crypto/modes/asm/ghash-armv4.S \
@@ -565,6 +568,7 @@
 
 arm_exclude_files := \
   crypto/aes/aes_core.c \
+  crypto/mem_clr.c \
 
 arm64_cflags := \
   -DOPENSSL_NO_ASM \
diff --git a/crypto/armcap.c b/crypto/armcap.c
new file mode 100644
index 0000000..9abaf39
--- /dev/null
+++ b/crypto/armcap.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <crypto.h>
+
+#include "arm_arch.h"
+
+unsigned int OPENSSL_armcap_P;
+
+static sigset_t all_masked;
+
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+/*
+ * Following subroutines could have been inlined, but it's not all
+ * ARM compilers support inline assembler...
+ */
+void _armv7_neon_probe(void);
+unsigned int _armv7_tick(void);
+
+unsigned int OPENSSL_rdtsc(void)
+	{
+	if (OPENSSL_armcap_P & ARMV7_TICK)
+		return _armv7_tick();
+	else
+		return 0;
+	}
+
+#if defined(__GNUC__) && __GNUC__>=2
+void OPENSSL_cpuid_setup(void) __attribute__((constructor));
+#endif
+void OPENSSL_cpuid_setup(void)
+	{
+	char *e;
+	struct sigaction	ill_oact,ill_act;
+	sigset_t		oset;
+	static int trigger=0;
+
+	if (trigger) return;
+	trigger=1;
+ 
+	if ((e=getenv("OPENSSL_armcap")))
+		{
+		OPENSSL_armcap_P=strtoul(e,NULL,0);
+		return;
+		}
+
+	sigfillset(&all_masked);
+	sigdelset(&all_masked,SIGILL);
+	sigdelset(&all_masked,SIGTRAP);
+	sigdelset(&all_masked,SIGFPE);
+	sigdelset(&all_masked,SIGBUS);
+	sigdelset(&all_masked,SIGSEGV);
+
+	OPENSSL_armcap_P = 0;
+
+	memset(&ill_act,0,sizeof(ill_act));
+	ill_act.sa_handler = ill_handler;
+	ill_act.sa_mask    = all_masked;
+
+	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
+	sigaction(SIGILL,&ill_act,&ill_oact);
+
+	if (sigsetjmp(ill_jmp,1) == 0)
+		{
+		_armv7_neon_probe();
+		OPENSSL_armcap_P |= ARMV7_NEON;
+		}
+	if (sigsetjmp(ill_jmp,1) == 0)
+		{
+		_armv7_tick();
+		OPENSSL_armcap_P |= ARMV7_TICK;
+		}
+
+	sigaction (SIGILL,&ill_oact,NULL);
+	sigprocmask(SIG_SETMASK,&oset,NULL);
+	}
diff --git a/openssl.config b/openssl.config
index 08bd3d3..ef3bd00 100644
--- a/openssl.config
+++ b/openssl.config
@@ -107,7 +107,6 @@
 crypto/Makefile.save \
 crypto/aes/Makefile \
 crypto/aes/Makefile.save \
-crypto/armcap.c \
 crypto/asn1/Makefile \
 crypto/asn1/Makefile.save \
 crypto/bf/INSTALL \
@@ -288,6 +287,7 @@
 OPENSSL_CRYPTO_DEFINES_arm="\
 OPENSSL_BN_ASM_GF2m \
 OPENSSL_BN_ASM_MONT \
+OPENSSL_CPUID_OBJ \
 GHASH_ASM \
 AES_ASM \
 BSAES_ASM \
@@ -869,6 +869,8 @@
 OPENSSL_CRYPTO_SOURCES_arm="\
 crypto/aes/asm/aes-armv4.S \
 crypto/aes/asm/bsaes-armv7.S \
+crypto/armcap.c \
+crypto/armv4cpuid.S \
 crypto/bn/asm/armv4-gf2m.S \
 crypto/bn/asm/armv4-mont.S \
 crypto/modes/asm/ghash-armv4.S \
@@ -879,6 +881,7 @@
 
 OPENSSL_CRYPTO_SOURCES_EXCLUDES_arm="\
 crypto/aes/aes_core.c \
+crypto/mem_clr.c \
 "
 
 OPENSSL_CRYPTO_SOURCES_arm64="\