summaryrefslogtreecommitdiff
path: root/src/hwfeatures.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2012-12-21 17:26:06 +0100
committerWerner Koch <wk@gnupg.org>2012-12-21 17:26:06 +0100
commit09ac5d87d11aa0b1fa0e0a4184ab03b3671a73e2 (patch)
treefdd126ae4b5c2fa2624edac0052619a70c207c1e /src/hwfeatures.c
parentd842eea55e22c05da3959a7a4422b5fcd7884f60 (diff)
downloadlibgcrypt-09ac5d87d11aa0b1fa0e0a4184ab03b3671a73e2.tar.gz
Prepare for hardware feature detection on other platforms.
* configure.ac (GCRYPT_HWF_MODULES): New. (HAVE_CPU_ARCH_X86, HAVE_CPU_ARCH_ALPHA, HAVE_CPU_ARCH_SPARC) (HAVE_CPU_ARCH_MIPS, HAVE_CPU_ARCH_M68K, HAVE_CPU_ARCH_PPC) (HAVE_CPU_ARCH_ARM): New AC_DEFINEs. * mpi/config.links (mpi_cpu_arch): New. * src/global.c (print_config): Print new tag "cpu-arch". * src/Makefile.am (libgcrypt_la_SOURCES): Add hwf-common.h (EXTRA_libgcrypt_la_SOURCES): New. (gcrypt_hwf_modules): New. (libgcrypt_la_DEPENDENCIES, libgcrypt_la_LIBADD): Add that one. * src/hwfeatures.c: Factor most code out to ... * src/hwf-x86.c: New file. (detect_x86_gnuc): Return the feature vector. (_gcry_hwf_detect_x86): New. * src/hwf-common.h: New. * src/hwfeatures.c (_gcry_detect_hw_features): Dispatch using HAVE_CPU_ARCH_ macros. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'src/hwfeatures.c')
-rw-r--r--src/hwfeatures.c188
1 files changed, 6 insertions, 182 deletions
diff --git a/src/hwfeatures.c b/src/hwfeatures.c
index 62600aa9..87d05d83 100644
--- a/src/hwfeatures.c
+++ b/src/hwfeatures.c
@@ -1,5 +1,6 @@
/* hwfeatures.c - Detect hardware features.
* Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2012 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -25,6 +26,8 @@
#include <unistd.h>
#include "g10lib.h"
+#include "hwf-common.h"
+
/* A bit vector describing the hardware features currently
available. */
@@ -40,185 +43,6 @@ _gcry_get_hw_features (void)
}
-#undef HAS_X86_CPUID
-
-#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-#define HAS_X86_CPUID 1
-
-static int
-is_cpuid_available(void)
-{
- int has_cpuid = 0;
-
- /* Detect the CPUID feature by testing some undefined behaviour (16
- vs 32 bit pushf/popf). */
- asm volatile
- ("pushf\n\t" /* Copy flags to EAX. */
- "popl %%eax\n\t"
- "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */
- "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */
- "pushl %%eax\n\t"
- "popf\n\t"
- "pushf\n\t" /* Copy changed flags again to EAX. */
- "popl %%eax\n\t"
- "pushl %%ecx\n\t" /* Restore flags from ECX. */
- "popf\n\t"
- "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */
- "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */
- "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */
- ".Lno_cpuid%=:\n\t"
- : "+r" (has_cpuid)
- :
- : "%eax", "%ecx", "cc"
- );
-
- return has_cpuid;
-}
-
-static void
-get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
- unsigned int *ecx, unsigned int *edx)
-{
- unsigned int regs[4];
-
- asm volatile
- ("pushl %%ebx\n\t" /* Save GOT register. */
- "cpuid\n\t"
- "movl %%ebx, %1\n\t"
- "popl %%ebx\n\t" /* Restore GOT register. */
- : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
- : "0" (in)
- : "cc"
- );
-
- if (eax)
- *eax = regs[0];
- if (ebx)
- *ebx = regs[1];
- if (ecx)
- *ecx = regs[2];
- if (edx)
- *edx = regs[3];
-}
-#endif /* i386 && GNUC */
-
-
-#if defined (__x86_64__) && defined (__GNUC__)
-#define HAS_X86_CPUID 1
-
-static int
-is_cpuid_available(void)
-{
- return 1;
-}
-
-static void
-get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
- unsigned int *ecx, unsigned int *edx)
-{
- unsigned int regs[4];
-
- asm volatile
- ("cpuid\n\t"
- : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
- : "0" (in)
- : "cc"
- );
-
- if (eax)
- *eax = regs[0];
- if (ebx)
- *ebx = regs[1];
- if (ecx)
- *ecx = regs[2];
- if (edx)
- *edx = regs[3];
-}
-#endif /* x86-64 && GNUC */
-
-
-#ifdef HAS_X86_CPUID
-static void
-detect_x86_gnuc (void)
-{
- char vendor_id[12+1];
- unsigned int features;
-
- if (!is_cpuid_available())
- return;
-
- get_cpuid(0, NULL,
- (unsigned int *)&vendor_id[0],
- (unsigned int *)&vendor_id[8],
- (unsigned int *)&vendor_id[4]);
- vendor_id[12] = 0;
-
- if (0)
- ; /* Just to make "else if" and ifdef macros look pretty. */
-#ifdef ENABLE_PADLOCK_SUPPORT
- else if (!strcmp (vendor_id, "CentaurHauls"))
- {
- /* This is a VIA CPU. Check what PadLock features we have. */
-
- /* Check for extended centaur (EAX). */
- get_cpuid(0xC0000000, &features, NULL, NULL, NULL);
-
- /* Has extended centaur features? */
- if (features > 0xC0000000)
- {
- /* Ask for the extended feature flags (EDX). */
- get_cpuid(0xC0000001, NULL, NULL, NULL, &features);
-
- /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */
- if ((features & 0x0C) == 0x0C)
- hw_features |= HWF_PADLOCK_RNG;
-
- /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */
- if ((features & 0xC0) == 0xC0)
- hw_features |= HWF_PADLOCK_AES;
-
- /* Test bits 10 and 11 to see whether the PHE exists and is
- enabled. */
- if ((features & 0xC00) == 0xC00)
- hw_features |= HWF_PADLOCK_SHA;
-
- /* Test bits 12 and 13 to see whether the MONTMUL exists and is
- enabled. */
- if ((features & 0x3000) == 0x3000)
- hw_features |= HWF_PADLOCK_MMUL;
- }
- }
-#endif /*ENABLE_PADLOCK_SUPPORT*/
- else if (!strcmp (vendor_id, "GenuineIntel"))
- {
- /* This is an Intel CPU. */
- }
- else if (!strcmp (vendor_id, "AuthenticAMD"))
- {
- /* This is an AMD CPU. */
- }
-
- /* Detect Intel features, that might also be supported by other
- vendors. */
-
- /* Get CPU info and Intel feature flags (ECX). */
- get_cpuid(1, NULL, NULL, &features, NULL);
-
-#ifdef ENABLE_AESNI_SUPPORT
- /* Test bit 25 for AES-NI. */
- if (features & 0x02000000)
- hw_features |= HWF_INTEL_AESNI;
-#endif /*ENABLE_AESNI_SUPPORT*/
-#ifdef ENABLE_DRNG_SUPPORT
- /* Test bit 30 for RDRAND. */
- if (features & 0x40000000)
- hw_features |= HWF_INTEL_RDRAND;
-#endif /*ENABLE_DRNG_SUPPORT*/
-
-}
-#endif /* HAS_X86_CPUID */
-
-
/* Detect the available hardware features. This function is called
once right at startup and we assume that no other threads are
running. */
@@ -230,11 +54,11 @@ _gcry_detect_hw_features (unsigned int disabled_features)
if (fips_mode ())
return; /* Hardware support is not to be evaluated. */
-#if HAS_X86_CPUID
+#if defined (HAVE_CPU_ARCH_X86)
{
- detect_x86_gnuc ();
+ hw_features = _gcry_hwf_detect_x86 ();
}
-#endif /* HAS_X86_CPUID */
+#endif /* HAVE_CPU_ARCH_X86 */
hw_features &= ~disabled_features;
}