3 #include <minix/minlib.h>
4 #include <minix/cpufeature.h>
5 #include <machine/vm.h>
8 int _cpufeature(int cpufeature
)
10 u32_t eax
, ebx
, ecx
, edx
;
11 u32_t ef_eax
= 0, ef_ebx
= 0, ef_ecx
= 0, ef_edx
= 0;
12 unsigned int family
, model
, stepping
;
13 int is_intel
= 0, is_amd
= 0;
15 eax
= ebx
= ecx
= edx
= 0;
17 /* We assume >= pentium for cpuid */
19 _cpuid(&eax
, &ebx
, &ecx
, &edx
);
22 memcpy(vendor
, &ebx
, sizeof(ebx
));
23 memcpy(vendor
+4, &edx
, sizeof(edx
));
24 memcpy(vendor
+8, &ecx
, sizeof(ecx
));
25 if(!strncmp(vendor
, "GenuineIntel", sizeof(vendor
)))
27 if(!strncmp(vendor
, "AuthenticAMD", sizeof(vendor
)))
30 _cpuid(&eax
, &ebx
, &ecx
, &edx
);
34 model
= (eax
>> 4) & 0xf;
36 if(model
== 0xf || model
== 0x6) {
37 model
+= ((eax
>> 16) & 0xf) << 4;
40 family
= (eax
>> 8) & 0xf;
43 family
+= (eax
>> 20) & 0xff;
48 _cpuid(&ef_eax
, &ef_ebx
, &ef_ecx
, &ef_edx
);
53 return edx
& CPUID1_EDX_PSE
;
55 return edx
& CPUID1_EDX_PGE
;
56 case _CPUF_I386_APIC_ON_CHIP
:
57 return edx
& CPUID1_EDX_APIC_ON_CHIP
;
59 return edx
& CPUID1_EDX_TSC
;
61 return edx
& CPUID1_EDX_FPU
;
62 #define SSE_FULL_EDX (CPUID1_EDX_FXSR | CPUID1_EDX_SSE | CPUID1_EDX_SSE2)
63 #define SSE_FULL_ECX (CPUID1_ECX_SSE3 | CPUID1_ECX_SSSE3 | \
64 CPUID1_ECX_SSE4_1 | CPUID1_ECX_SSE4_2)
65 case _CPUF_I386_SSE1234_12
:
66 return (edx
& SSE_FULL_EDX
) == SSE_FULL_EDX
&&
67 (ecx
& SSE_FULL_ECX
) == SSE_FULL_ECX
;
69 return edx
& CPUID1_EDX_FXSR
;
71 return edx
& CPUID1_EDX_SSE
;
73 return edx
& CPUID1_EDX_SSE2
;
75 return ecx
& CPUID1_ECX_SSE3
;
76 case _CPUF_I386_SSSE3
:
77 return ecx
& CPUID1_ECX_SSSE3
;
78 case _CPUF_I386_SSE4_1
:
79 return ecx
& CPUID1_ECX_SSE4_1
;
80 case _CPUF_I386_SSE4_2
:
81 return ecx
& CPUID1_ECX_SSE4_2
;
83 return edx
& CPUID1_EDX_HTT
;
84 case _CPUF_I386_HTT_MAX_NUM
:
85 return (ebx
>> 16) & 0xff;
86 case _CPUF_I386_SYSENTER
:
87 if(!is_intel
) return 0;
88 if(!(edx
& CPUID1_EDX_SYSENTER
)) return 0;
89 if(family
== 6 && model
< 3 && stepping
< 3) return 0;
91 case _CPUF_I386_SYSCALL
:
93 if(!(ef_edx
& CPUID_EF_EDX_SYSENTER
)) return 0;