Commit 92b6e205 authored by Ahmed Samy's avatar Ahmed Samy

cpuid: drop support for testing extended features

For now, we will just test for normal features, later on it'll be added
back.
Signed-off-by: default avatarAhmed Samy <f.fallen45@gmail.com>
parent 715de3cf
......@@ -61,35 +61,6 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
}
#endif
static struct {
uint32_t feature;
uint32_t mask;
bool use_edx; /* ecx will be used if false. */
} features[] = {
{ CF_MMX, 1 << 23, true },
{ CF_SSE, 1 << 25, true },
{ CF_SSE2, 1 << 26, true },
{ CF_SSE3, 1 << 9, false },
{ CF_FPU, 1 << 0, true },
{ CF_TSC, 1 << 4, true },
{ CF_MSR, 1 << 5, true },
{ CF_SSSE3, 1 << 9, false },
{ CF_AVX, 1 << 28, false },
/* Extended ones. */
{ CEF_x64, 1 << 30, true },
{ CEF_FPU, 1 << 0, true },
{ CEF_DE, 1 << 2, true },
{ CEF_SYSCALLRET, 1 << 11, true },
{ CEF_CMOV, 1 << 15, true },
{ CEF_SSE4a, 1 << 6, false },
{ CEF_FMA4, 1 << 16, false },
{ CEF_XOP, 1 << 11, false }
};
bool cpuid_is_supported(void)
{
int ret = 0;
......@@ -179,24 +150,48 @@ bool cpuid_test_feature(cpuid_t feature)
return (feature <= cpuid_highest_ext_func_supported());
}
bool cpuid_has_feature(int feature, bool extended)
bool cpuid_has_ecxfeature(int feature)
{
uint32_t eax, ebx, ecx, edx, i;
if (!extended)
___cpuid(CPU_PROCINFO_AND_FEATUREBITS, &eax, &ebx, &ecx, &edx);
else
___cpuid(CPU_EXTENDED_PROC_INFO_FEATURE_BITS, &eax, &ebx, &ecx, &edx);
for (i = 0; i < sizeof(features) / sizeof(features[0]); ++i) {
if (features[i].feature == feature) {
if (features[i].use_edx)
return (edx & features[i].mask);
else
return (ecx & features[i].mask);
static uint32_t _ecx;
if (_ecx == 0) {
#if defined(__GNUC__) || defined(__clang__)
asm volatile(
"cpuid\n\t"
: "=c" (_ecx)
: "a" (CPU_PROCINFO_AND_FEATUREBITS)
);
#elif defined _MSC_VER
__asm {
mov eax, CPU_PROCINFO_AND_FEATUREBITS
cpuid
mov _ecx, ecx
};
#endif
}
return (_ecx & feature) == feature;
}
bool cpuid_has_edxfeature(int feature)
{
static uint32_t _edx;
if (_edx == 0) {
#if defined(__GNUC__) || defined(__clang__)
asm volatile(
"cpuid\n\t"
: "=d" (_edx)
: "a" (CPU_PROCINFO_AND_FEATUREBITS)
);
#elif defined _MSC_VER
__asm {
mov eax, CPU_PROCINFO_AND_FEATUREBITS
cpuid
mov _edx, edx
};
#endif
}
return false;
return (_edx & feature) == feature;
}
static const char *const cpuids[] = {
......
......@@ -76,25 +76,64 @@ typedef enum cpuid {
CPU_VIRT_PHYS_ADDR_SIZES = 0x80000008
} cpuid_t;
#define CF_MMX 0
#define CF_SSE 1
#define CF_SSE2 2
#define CF_SSE3 3
#define CF_FPU 4
#define CF_TSC 5
#define CF_MSR 6
#define CF_SSSE3 7
#define CF_AVX 8
#define CF_FMA 9
enum {
CPUID_FEAT_ECX_SSE3 = 1 << 0,
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
CPUID_FEAT_ECX_DTES64 = 1 << 2,
CPUID_FEAT_ECX_MONITOR = 1 << 3,
CPUID_FEAT_ECX_DS_CPL = 1 << 4,
CPUID_FEAT_ECX_VMX = 1 << 5,
CPUID_FEAT_ECX_SMX = 1 << 6,
CPUID_FEAT_ECX_EST = 1 << 7,
CPUID_FEAT_ECX_TM2 = 1 << 8,
CPUID_FEAT_ECX_SSSE3 = 1 << 9,
CPUID_FEAT_ECX_CID = 1 << 10,
CPUID_FEAT_ECX_FMA = 1 << 12,
CPUID_FEAT_ECX_CX16 = 1 << 13,
CPUID_FEAT_ECX_ETPRD = 1 << 14,
CPUID_FEAT_ECX_PDCM = 1 << 15,
CPUID_FEAT_ECX_DCA = 1 << 18,
CPUID_FEAT_ECX_SSE4_1 = 1 << 19,
CPUID_FEAT_ECX_SSE4_2 = 1 << 20,
CPUID_FEAT_ECX_x2APIC = 1 << 21,
CPUID_FEAT_ECX_MOVBE = 1 << 22,
CPUID_FEAT_ECX_POPCNT = 1 << 23,
CPUID_FEAT_ECX_AES = 1 << 25,
CPUID_FEAT_ECX_XSAVE = 1 << 26,
CPUID_FEAT_ECX_OSXSAVE = 1 << 27,
CPUID_FEAT_ECX_AVX = 1 << 28,
#define CEF_x64 10
#define CEF_FPU 11
#define CEF_DE 12
#define CEF_SYSCALLRET 13
#define CEF_CMOV 14
#define CEF_SSE4a 15
#define CEF_FMA4 16
#define CEF_XOP 17
CPUID_FEAT_EDX_FPU = 1 << 0,
CPUID_FEAT_EDX_VME = 1 << 1,
CPUID_FEAT_EDX_DE = 1 << 2,
CPUID_FEAT_EDX_PSE = 1 << 3,
CPUID_FEAT_EDX_TSC = 1 << 4,
CPUID_FEAT_EDX_MSR = 1 << 5,
CPUID_FEAT_EDX_PAE = 1 << 6,
CPUID_FEAT_EDX_MCE = 1 << 7,
CPUID_FEAT_EDX_CX8 = 1 << 8,
CPUID_FEAT_EDX_APIC = 1 << 9,
CPUID_FEAT_EDX_SEP = 1 << 11,
CPUID_FEAT_EDX_MTRR = 1 << 12,
CPUID_FEAT_EDX_PGE = 1 << 13,
CPUID_FEAT_EDX_MCA = 1 << 14,
CPUID_FEAT_EDX_CMOV = 1 << 15,
CPUID_FEAT_EDX_PAT = 1 << 16,
CPUID_FEAT_EDX_PSE36 = 1 << 17,
CPUID_FEAT_EDX_PSN = 1 << 18,
CPUID_FEAT_EDX_CLF = 1 << 19,
CPUID_FEAT_EDX_DTES = 1 << 21,
CPUID_FEAT_EDX_ACPI = 1 << 22,
CPUID_FEAT_EDX_MMX = 1 << 23,
CPUID_FEAT_EDX_FXSR = 1 << 24,
CPUID_FEAT_EDX_SSE = 1 << 25,
CPUID_FEAT_EDX_SSE2 = 1 << 26,
CPUID_FEAT_EDX_SS = 1 << 27,
CPUID_FEAT_EDX_HTT = 1 << 28,
CPUID_FEAT_EDX_TM1 = 1 << 29,
CPUID_FEAT_EDX_IA64 = 1 << 30,
CPUID_FEAT_EDX_PBE = 1 << 31
};
typedef enum cputype {
CT_NONE,
......@@ -241,27 +280,13 @@ bool cpuid_test_feature(cpuid_t feature);
* cpuid_has_feature - Test if @feature is supported
*
* Test if the CPU supports MMX/SSE* etc.
* For the extended parameter, usually you want to pass it as
* false if you're not passing CEF_*.
*
* For more information about the CPU extended features, have a look
* at:
* http://en.wikipedia.org/wiki/CPUID
* Use cpuid_has_ecxfeature() for *_ECX* features and
* cpuid_has_edxfeature() for *_EDX* features.
*
* Returns true if the feature is available, false otherwise.
*/
#define cpuid_has_mmx() cpuid_has_feature(CF_MMX, false)
#define cpuid_has_sse() cpuid_has_feature(CF_SSE, false)
#define cpuid_has_sse2() cpuid_has_feature(CF_SSE2, false)
#define cpuid_has_sse3() cpuid_has_feature(CF_SSE3, false)
#define cpuid_has_ssse3() cpuid_has_feature(CF_SSSE3, false)
#define cpuid_has_avx() cpuid_has_feature(CF_AVX, false)
#define cpuid_has_fma() cpuid_has_feature(CF_FMA, false)
#define cpuid_has_x64() cpuid_has_feature(CEF_x64, true)
#define cpuid_has_sse4a() cpuid_has_feature(CEF_SSE4a, true)
#define cpuid_has_fma4() cpuid_has_feature(CEF_FMA4, true)
#define cpuid_has_xop() cpuid_has_feature(CEF_XOP, true)
bool cpuid_has_feature(int feature, bool extended);
bool cpuid_has_ecxfeature(int feature);
bool cpuid_has_edxfeature(int feature);
#else
#include <ccan/build_assert/build_assert.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment