Many changes:
[Marmot.git] / cpu.c
blobdfb570c7176441d862d6ec899b83974d487f0d82
1 /*
2 * cpu.c
4 * CPU-specific functionality.
5 */
8 #include <marmot.h>
11 struct {
12 uint64 nStandard;
13 uint64 nHypervisor;
14 uint64 nExtended;
15 struct {
16 UReg eax;
17 UReg ebx;
18 UReg ecx;
19 UReg edx;
20 } features[];
21 } *CPUIDInfo;
24 uint32
25 CPU_GetFeature(uint32 feature)
27 uint32 type, fcn, reg, bl, bh, mask, idx, features = 0;
29 type = (feature & CPUID_TYPE_MASK) >> CPUID_TYPE_SHIFT;
30 fcn = (feature & CPUID_FCN_MASK) >> CPUID_FCN_SHIFT;
31 reg = (feature & CPUID_REG_MASK) >> CPUID_REG_SHIFT;
32 bl = (feature & CPUID_LBIT_MASK) >> CPUID_LBIT_SHIFT;
33 bh = (feature & CPUID_HBIT_MASK) >> CPUID_HBIT_SHIFT;
35 mask = (~((1 << bh) - 1)) - ((1 << bl) - 1);
37 idx = 0;
38 if (type == CPUID_FEATURES_HYPERVISOR) {
39 if (CPUIDInfo->nHypervisor == 0) {
40 return FALSE;
43 idx += CPUIDInfo->nStandard;
44 } else if (type == CPUID_FEATURES_EXTENDED) {
45 idx += CPUIDInfo->nStandard + CPUIDInfo->nHypervisor;
48 switch (reg) {
49 case CPUID_REGISTER_EAX:
50 features = CPUIDInfo->features[idx].eax;
51 break;
52 case CPUID_REGISTER_EBX:
53 features = CPUIDInfo->features[idx].ebx;
54 break;
55 case CPUID_REGISTER_ECX:
56 features = CPUIDInfo->features[idx].ecx;
57 break;
58 case CPUID_REGISTER_EDX:
59 features = CPUIDInfo->features[idx].edx;
60 break;
63 return (features & mask) >> bl;