-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcpuid.cc
65 lines (53 loc) · 1.92 KB
/
cpuid.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "cpuid.hh"
#include <string.h>
cpuid cpuid::instance_;
cpuid::cpuid() : basic_{}, extended_{}
{
// Leaf 0 tells us how many leafs there are
basic_[(int)leafid::basic] = read_leaf((int)leafid::basic);
// Cache all basic leafs
for (int i = 1; i < MAX_BASIC && i <= basic_[0].a; ++i)
basic_[i] = read_leaf(i);
// Leaf 0x80000000 tells us how many extended leafs there are
extended_[0] = read_leaf((uint32_t)leafid::extended_info);
// Cache extended leafs
for (int i = 1; i < MAX_EXTENDED &&
i <= extended_[0].a - (uint32_t)leafid::extended_info; ++i)
extended_[i] = read_leaf((uint32_t)leafid::extended_info + i);
// Decode vendor_
leaf l = get_leaf(leafid::basic);
uint32_t name[3] = {l.b, l.d, l.c};
memmove(vendor_, name, sizeof name);
vendor_[12] = 0;
// Decode features
l = get_leaf(leafid::features);
features_.mwait = l.c & (1<<3);
features_.pdcm = l.c & (1<<15);
features_.pcid = l.c & (1<<17);
features_.x2apic = l.c & (1<<21);
features_.xsave = l.c & (1<<26);
features_.hypervisor = l.c & (1<<31);
features_.apic = l.d & (1<<9);
features_.ds = l.d & (1<<21);
l = get_leaf(leafid::ext_features);
features_.fsgsbase = l.b & (1<<0);
features_.invpcid = l.b & (1<<10);
features_.intel_pt = l.b & (1<<25);
features_.md_clear = l.d & (1<<10);
features_.spec_ctrl = l.d & (1<<26);
l = get_leaf(leafid::ext_state, 1);
features_.xsaveopt = l.a & (1<<0);
if(features_.hypervisor) {
// We can't use get_leaf because the hypervisor leaf will be rejected by the
// maximum leaf check.
l = read_leaf((uint32_t)leafid::hypervisor);
*(uint32_t*)features_.hypervisor_id = l.b;
*(uint32_t*)(features_.hypervisor_id+4) = l.c;
*(uint32_t*)(features_.hypervisor_id+8) = l.d;
features_.hypervisor_id[12] = '\0';
} else {
features_.hypervisor_id[0] = '\0';
}
l = get_leaf(leafid::extended_features);
features_.page1GB = l.d & (1<<26);
}