source: grub-pc/trunk/fuentes/grub-core/lib/libgcrypt/src/hwfeatures.c @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 6.5 KB
Line 
1/* hwfeatures.c - Detect hardware features.
2 * Copyright (C) 2007, 2011  Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <config.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <unistd.h>
26
27#include "g10lib.h"
28
29/* A bit vector describing the hardware features currently
30   available. */
31static unsigned int hw_features;
32
33
34/* Return a bit vector describing the available hardware features.
35   The HWF_ constants are used to test for them. */
36unsigned int
37_gcry_get_hw_features (void)
38{
39  return hw_features;
40}
41
42
43#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
44static void
45detect_ia32_gnuc (void)
46{
47  /* The code here is only useful for the PadLock engine thus we don't
48     build it if that support has been disabled.  */
49  int has_cpuid = 0;
50  char vendor_id[12+1];
51
52  /* Detect the CPUID feature by testing some undefined behaviour (16
53     vs 32 bit pushf/popf). */
54  asm volatile
55    ("pushf\n\t"                 /* Copy flags to EAX.  */
56     "popl %%eax\n\t"
57     "movl %%eax, %%ecx\n\t"     /* Save flags into ECX.  */
58     "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags.  */
59     "pushl %%eax\n\t"
60     "popf\n\t"
61     "pushf\n\t"                 /* Copy changed flags again to EAX.  */
62     "popl %%eax\n\t"
63     "pushl %%ecx\n\t"           /* Restore flags from ECX.  */
64     "popf\n\t"
65     "xorl %%eax, %%ecx\n\t"     /* Compare flags against saved flags.  */
66     "jz .Lno_cpuid%=\n\t"       /* Toggling did not work, thus no CPUID.  */
67     "movl $1, %0\n"             /* Worked. true -> HAS_CPUID.  */
68     ".Lno_cpuid%=:\n\t"
69     : "+r" (has_cpuid)
70     :
71     : "%eax", "%ecx", "cc"
72     );
73
74  if (!has_cpuid)
75    return;  /* No way.  */
76
77  asm volatile
78    ("pushl %%ebx\n\t"           /* Save GOT register.  */
79     "xorl  %%eax, %%eax\n\t"    /* 0 -> EAX.  */
80     "cpuid\n\t"                 /* Get vendor ID.  */
81     "movl  %%ebx, (%0)\n\t"     /* EBX,EDX,ECX -> VENDOR_ID.  */
82     "movl  %%edx, 4(%0)\n\t"
83     "movl  %%ecx, 8(%0)\n\t"
84     "popl  %%ebx\n"
85     :
86     : "S" (&vendor_id[0])
87     : "%eax", "%ecx", "%edx", "cc"
88     );
89  vendor_id[12] = 0;
90
91  if (0)
92    ; /* Just to make "else if" and ifdef macros look pretty.  */
93#ifdef ENABLE_PADLOCK_SUPPORT
94  else if (!strcmp (vendor_id, "CentaurHauls"))
95    {
96      /* This is a VIA CPU.  Check what PadLock features we have.  */
97      asm volatile
98        ("pushl %%ebx\n\t"              /* Save GOT register.  */
99         "movl $0xC0000000, %%eax\n\t"  /* Check for extended centaur  */
100         "cpuid\n\t"                    /* feature flags.              */
101         "popl %%ebx\n\t"               /* Restore GOT register. */
102         "cmpl $0xC0000001, %%eax\n\t"
103         "jb .Lready%=\n\t"             /* EAX < 0xC0000000 => no padlock.  */
104
105         "pushl %%ebx\n\t"              /* Save GOT register. */
106         "movl $0xC0000001, %%eax\n\t"  /* Ask for the extended */
107         "cpuid\n\t"                    /* feature flags.       */
108         "popl %%ebx\n\t"               /* Restore GOT register. */
109
110         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
111         "andl $0x0C, %%eax\n\t"        /* Test bits 2 and 3 to see whether */
112         "cmpl $0x0C, %%eax\n\t"        /* the RNG exists and is enabled.   */
113         "jnz .Lno_rng%=\n\t"
114         "orl $1, %0\n"                 /* Set our HWF_PADLOCK_RNG bit.  */
115
116         ".Lno_rng%=:\n\t"
117         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
118         "andl $0xC0, %%eax\n\t"        /* Test bits 6 and 7 to see whether */
119         "cmpl $0xC0, %%eax\n\t"        /* the ACE exists and is enabled.   */
120         "jnz .Lno_ace%=\n\t"
121         "orl $2, %0\n"                 /* Set our HWF_PADLOCK_AES bit.  */
122
123         ".Lno_ace%=:\n\t"
124         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
125         "andl $0xC00, %%eax\n\t"       /* Test bits 10, 11 to see whether  */
126         "cmpl $0xC00, %%eax\n\t"       /* the PHE exists and is enabled.   */
127         "jnz .Lno_phe%=\n\t"
128         "orl $4, %0\n"                 /* Set our HWF_PADLOCK_SHA bit.  */
129
130         ".Lno_phe%=:\n\t"
131         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
132         "andl $0x3000, %%eax\n\t"      /* Test bits 12, 13 to see whether  */
133         "cmpl $0x3000, %%eax\n\t"      /* MONTMUL exists and is enabled.   */
134         "jnz .Lready%=\n\t"
135         "orl $8, %0\n"                 /* Set our HWF_PADLOCK_MMUL bit.  */
136
137         ".Lready%=:\n"
138         : "+r" (hw_features)
139         :
140         : "%eax", "%edx", "cc"
141         );
142    }
143#endif /*ENABLE_PADLOCK_SUPPORT*/
144  else if (!strcmp (vendor_id, "GenuineIntel"))
145    {
146      /* This is an Intel CPU.  */
147      asm volatile
148        ("pushl %%ebx\n\t"              /* Save GOT register.  */
149         "movl $1, %%eax\n\t"           /* Get CPU info and feature flags.  */
150         "cpuid\n"
151         "popl %%ebx\n\t"               /* Restore GOT register. */
152         "testl $0x02000000, %%ecx\n\t" /* Test bit 25.  */
153         "jz .Lno_aes%=\n\t"            /* No AES support.  */
154         "orl $256, %0\n"               /* Set our HWF_INTEL_AES bit.  */
155
156         ".Lno_aes%=:\n"
157         : "+r" (hw_features)
158         :
159         : "%eax", "%ecx", "%edx", "cc"
160         );
161    }
162  else if (!strcmp (vendor_id, "AuthenticAMD"))
163    {
164      /* This is an AMD CPU.  */
165
166    }
167}
168#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */
169
170
171/* Detect the available hardware features.  This function is called
172   once right at startup and we assume that no other threads are
173   running.  */
174void
175_gcry_detect_hw_features (unsigned int disabled_features)
176{
177  hw_features = 0;
178
179  if (fips_mode ())
180    return; /* Hardware support is not to be evaluated.  */
181
182#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4
183#ifdef __GNUC__
184  detect_ia32_gnuc ();
185#endif
186#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8
187#ifdef __GNUC__
188#endif
189#endif
190
191  hw_features &= ~disabled_features;
192}
Note: See TracBrowser for help on using the repository browser.