nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* ws_cpuid.h
2 * Get the CPU info on x86 processors that support it
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22  
23 /*
24 * Get CPU info on platforms where the cpuid instruction can be used skip 32 bit versions for GCC
25 * Intel has documented the CPUID instruction in the "Intel(r) 64 and IA-32
26 * Architectures Developer's Manual" at http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html
27 * the ws_cpuid() routine will return 0 if cpuinfo isn't available.
28 */
29  
30 #if defined(_MSC_VER) /* MSVC */
31 static gboolean
32 ws_cpuid(guint32 *CPUInfo, guint32 selector)
33 {
34 CPUInfo[0] = CPUInfo[1] = CPUInfo[2] = CPUInfo[3] = 0;
35 __cpuid((int *) CPUInfo, selector);
36 /* XXX, how to check if it's supported on MSVC? just in case clear all flags above */
37 return TRUE;
38 }
39  
40 #elif defined(__GNUC__) /* GCC/clang */
41  
42 #if defined(__x86_64__)
43 static inline gboolean
44 ws_cpuid(guint32 *CPUInfo, int selector)
45 {
46 __asm__ __volatile__("cpuid"
47 : "=a" (CPUInfo[0]),
48 "=b" (CPUInfo[1]),
49 "=c" (CPUInfo[2]),
50 "=d" (CPUInfo[3])
51 : "a"(selector));
52 return TRUE;
53 }
54 #elif defined(__i386__)
55 static gboolean
56 ws_cpuid(guint32 *CPUInfo _U_, int selector _U_)
57 {
58 /*
59 * TODO: need a test if older proccesors have the cpuid instruction.
60 *
61 * The correct way to test for this, according to the Intel64/IA-32
62 * documentation from Intel, in section 17.1 "USING THE CPUID
63 * INSTRUCTION", is to try to change the ID bit (bit 21) in
64 * EFLAGS. If it can be changed, the machine supports CPUID,
65 * otherwise it doesn't.
66 *
67 * Some 486's, and all subsequent processors, support CPUID.
68 *
69 * For those who are curious, the way you distinguish between
70 * an 80386 and an 80486 is to try to set the flag in EFLAGS
71 * that causes unaligned accesses to fault - that's bit 18.
72 * However, if the SMAP bit is set in CR4, that bit controls
73 * whether explicit supervisor-mode access to user-mode pages
74 * are allowed, so that should presumably only be done in a
75 * very controlled environment, such as the system boot process.
76 *
77 * So, if you want to find out what type of CPU the system has,
78 * it's probably best to ask the OS, if it supplies the result
79 * of any CPU type testing it's done.
80 */
81 return FALSE;
82 }
83 #else /* not x86 */
84 static gboolean
85 ws_cpuid(guint32 *CPUInfo _U_, int selector _U_)
86 {
87 /* Not x86, so no cpuid instruction */
88 return FALSE;
89 }
90 #endif
91  
92 #else /* Other compilers */
93  
94 static gboolean
95 ws_cpuid(guint32 *CPUInfo _U_, int selector _U_)
96 {
97 return FALSE;
98 }
99 #endif
100  
101 static int
102 ws_cpuid_sse42(void)
103 {
104 guint32 CPUInfo[4];
105  
106 if (!ws_cpuid(CPUInfo, 1))
107 return 0;
108  
109 /* in ECX bit 20 toggled on */
110 return (CPUInfo[2] & (1 << 20));
111 }