HPCToolkit
cpuid.c
Go to the documentation of this file.
1
// -*-Mode: C++;-*- // technically C99
2
3
// * BeginRiceCopyright *****************************************************
4
//
5
// $HeadURL$
6
// $Id$
7
//
8
// --------------------------------------------------------------------------
9
// Part of HPCToolkit (hpctoolkit.org)
10
//
11
// Information about sources of support for research and development of
12
// HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13
// --------------------------------------------------------------------------
14
//
15
// Copyright ((c)) 2002-2018, Rice University
16
// All rights reserved.
17
//
18
// Redistribution and use in source and binary forms, with or without
19
// modification, are permitted provided that the following conditions are
20
// met:
21
//
22
// * Redistributions of source code must retain the above copyright
23
// notice, this list of conditions and the following disclaimer.
24
//
25
// * Redistributions in binary form must reproduce the above copyright
26
// notice, this list of conditions and the following disclaimer in the
27
// documentation and/or other materials provided with the distribution.
28
//
29
// * Neither the name of Rice University (RICE) nor the names of its
30
// contributors may be used to endorse or promote products derived from
31
// this software without specific prior written permission.
32
//
33
// This software is provided by RICE and contributors "as is" and any
34
// express or implied warranties, including, but not limited to, the
35
// implied warranties of merchantability and fitness for a particular
36
// purpose are disclaimed. In no event shall RICE or contributors be
37
// liable for any direct, indirect, incidental, special, exemplary, or
38
// consequential damages (including, but not limited to, procurement of
39
// substitute goods or services; loss of use, data, or profits; or
40
// business interruption) however caused and on any theory of liability,
41
// whether in contract, strict liability, or tort (including negligence
42
// or otherwise) arising in any way out of the use of this software, even
43
// if advised of the possibility of such damage.
44
//
45
// ******************************************************* EndRiceCopyright *
46
47
// Note:
48
// Some of the code is adapted from Linux Perf source code:
49
// https://github.com/torvalds/linux/blob/master/tools/perf/arch/x86/util/header.c
50
51
#include <stdlib.h>
52
#include <stdio.h>
53
#include <string.h>
54
55
#include <
utilities/arch/cpuid.h
>
56
57
58
static
inline
void
59
asm_cpuid
(
unsigned
int
op,
unsigned
int
*a,
unsigned
int
*b,
unsigned
int
*c,
60
unsigned
int
*d)
61
{
62
// this assembly code is taken from Linux kernel
63
// the code is gpl, so I assume it's okay to put it here
64
__asm__ __volatile__ (
".byte 0x53\n\tcpuid\n\t"
65
"movl %%ebx, %%esi\n\t.byte 0x5b"
66
:
"=a"
(*a),
67
"=S"
(*b),
68
"=c"
(*c),
69
"=d"
(*d)
70
:
"a"
(op));
71
}
72
73
/* return cpu type based on the cpu model */
74
/* see https://en.wikichip.org/wiki/intel/cpuid */
75
static
cpu_type_t
76
get_intel_cpu_type
(
struct
cpuid_type_s
*cpuid)
77
{
78
cpu_type_t
type =
CPU_UNSUP
;
79
80
if
(cpuid->
family
== 6) {
81
switch
(cpuid->
model
) {
82
83
case
26:
84
type =
INTEL_NHM_EP
;
85
break
;
86
case
42:
87
type =
INTEL_SNB
;
88
break
;
89
case
44:
90
type =
INTEL_WSM_EP
;
91
break
;
92
case
45:
93
type =
INTEL_SNB_EP
;
94
break
;
95
case
46:
96
type =
INTEL_NHM_EX
;
97
break
;
98
case
47:
99
type =
INTEL_WSM_EX
;
100
break
;
101
case
62:
102
type =
INTEL_IVB_EX
;
103
break
;
104
case
63:
105
type =
INTEL_HSX
;
106
break
;
107
case
79:
108
type =
INTEL_BDX
;
109
break
;
110
case
85:
111
type =
INTEL_SKX
;
112
break
;
113
case
87:
114
type =
INTEL_KNL
;
115
break
;
116
case
0x7e:
117
type =
INTEL_ICL
;
118
break
;
119
120
}
121
}
122
return
type;
123
}
124
125
static
cpu_type_t
126
get_amd_cpu_type
(
struct
cpuid_type_s
*cpuid)
127
{
128
cpu_type_t
type =
CPU_UNSUP
;
129
130
if
(cpuid->
family
== 16) {
131
switch
(cpuid->
model
) {
132
case
9:
133
type =
AMD_MGN_CRS
;
134
break
;
135
}
136
}
137
return
type;
138
}
139
140
static
cpu_type_t
141
__get_cpuid
(
struct
cpuid_type_s
*cpuid)
142
{
143
unsigned
int
a, b, c, d, lvl;
144
145
asm_cpuid
(0, &lvl, &b, &c, &d);
146
147
strncpy(&cpuid->
vendor
[0], (
char
*)(&b), 4);
148
strncpy(&cpuid->
vendor
[4], (
char
*)(&d), 4);
149
strncpy(&cpuid->
vendor
[8], (
char
*)(&c), 4);
150
151
cpuid->
vendor
[12] =
'\0'
;
152
153
if
(lvl >= 1) {
154
asm_cpuid
(1, &a, &b, &c, &d);
155
156
cpuid->
family
= (a >> 8) & 0xf;
/* bits 11 - 8 */
157
cpuid->
model
= (a >> 4) & 0xf;
/* Bits 7 - 4 */
158
cpuid->
step
= a & 0xf;
159
160
/* extended family */
161
if
(cpuid->
family
== 0xf)
162
cpuid->
family
+= (a >> 20) & 0xff;
163
164
/* extended model */
165
if
(cpuid->
family
>= 0x6)
166
cpuid->
model
+= ((a >> 16) & 0xf) << 4;
167
}
168
169
/* look for end marker to ensure the entire data fit */
170
if
(strncmp(cpuid->
vendor
,
VENDOR_INTEL
, 12) == 0) {
171
// intel
172
return
get_intel_cpu_type
(cpuid);
173
}
else
if
(strncmp(cpuid->
vendor
,
VENDOR_AMD
, 12) == 0) {
174
// amd
175
return
get_amd_cpu_type
(cpuid);
176
}
177
return
CPU_UNSUP
;
178
}
179
180
181
182
cpu_type_t
183
get_cpuid
()
184
{
185
struct
cpuid_type_s
cpuid;
186
memset(&cpuid, 0,
sizeof
(cpuid));
187
188
cpu_type_t
type =
__get_cpuid
(&cpuid);
189
#if UNIT_TEST_CPUID
190
printf(
"vendor:\t%s\nfamily:\t%d\nmodel:\t%d\nstep:\t%d\n"
, cpuid.
vendor
, cpuid.
family
, cpuid.
model
, cpuid.
step
);
191
#endif
192
return
type;
193
}
194
195
196
#if UNIT_TEST_CPUID
197
198
int
main
(
void
)
199
{
200
cpu_type_t
type =
get_cpuid
();
201
printf(
"\ncpu type: %d\n"
, type);
202
}
203
#endif
INTEL_SNB
Definition:
cpuid.h:68
cpuid_type_s::vendor
char vendor[13]
Definition:
cpuid.h:56
AMD_MGN_CRS
Definition:
cpuid.h:81
cpuid_type_s::model
int model
Definition:
cpuid.h:58
cpuid_type_s
Definition:
cpuid.h:55
CPU_UNSUP
Definition:
cpuid.h:63
INTEL_KNL
Definition:
cpuid.h:79
INTEL_WSM_EX
Definition:
cpuid.h:65
INTEL_IVB_EX
Definition:
cpuid.h:73
__get_cpuid
static cpu_type_t __get_cpuid(struct cpuid_type_s *cpuid)
Definition:
cpuid.c:141
INTEL_NHM_EP
Definition:
cpuid.h:71
INTEL_NHM_EX
Definition:
cpuid.h:70
INTEL_SNB_EP
Definition:
cpuid.h:69
INTEL_HSX
Definition:
cpuid.h:75
cpuid_type_s::family
int family
Definition:
cpuid.h:57
cpu_type_t
cpu_type_t
Definition:
cpuid.h:62
cpuid.h
get_cpuid
cpu_type_t get_cpuid()
Definition:
cpuid.c:52
get_intel_cpu_type
static cpu_type_t get_intel_cpu_type(struct cpuid_type_s *cpuid)
Definition:
cpuid.c:76
main
int main(int argc, char *argv[])
Definition:
main.cpp:125
cpuid_type_s::step
int step
Definition:
cpuid.h:59
asm_cpuid
static void asm_cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)
Definition:
cpuid.c:59
VENDOR_INTEL
#define VENDOR_INTEL
Definition:
cpuid.h:52
get_amd_cpu_type
static cpu_type_t get_amd_cpu_type(struct cpuid_type_s *cpuid)
Definition:
cpuid.c:126
INTEL_SKX
Definition:
cpuid.h:77
VENDOR_AMD
#define VENDOR_AMD
Definition:
cpuid.h:53
INTEL_BDX
Definition:
cpuid.h:76
INTEL_WSM_EP
Definition:
cpuid.h:66
INTEL_ICL
Definition:
cpuid.h:78
src
tool
hpcrun
utilities
arch
x86-family
cpuid.c
Generated by
1.8.13