lib/x86/cpu_features: detect AVX-512BW support

This commit is contained in:
Eric Biggers 2018-12-24 17:36:07 -06:00
parent 6a05e63bbb
commit 4548033845
2 changed files with 33 additions and 7 deletions

View File

@ -63,7 +63,17 @@ read_xcr(u32 index)
return ((u64)edx << 32) | eax;
}
#define IS_SET(reg, bit) ((reg) & ((u32)1 << (bit)))
#undef BIT
#define BIT(nr) (1UL << (nr))
#define XCR0_BIT_SSE BIT(1)
#define XCR0_BIT_AVX BIT(2)
#define XCR0_BIT_OPMASK BIT(5)
#define XCR0_BIT_ZMM_HI256 BIT(6)
#define XCR0_BIT_HI16_ZMM BIT(7)
#define IS_SET(reg, nr) ((reg) & BIT(nr))
#define IS_ALL_SET(reg, mask) (((reg) & (mask)) == (mask))
/* Initialize _cpu_features with bits for interesting processor features. */
void setup_cpu_features(void)
@ -72,7 +82,8 @@ void setup_cpu_features(void)
u32 dummy1, dummy2, dummy3, dummy4;
u32 max_function;
u32 features_1, features_2, features_3, features_4;
bool os_saves_ymm_regs = false;
bool os_avx_support = false;
bool os_avx512_support = false;
/* Get maximum supported function */
cpuid(0, 0, &max_function, &dummy2, &dummy3, &dummy4);
@ -88,11 +99,22 @@ void setup_cpu_features(void)
if (IS_SET(features_2, 1))
features |= X86_CPU_FEATURE_PCLMULQDQ;
if (IS_SET(features_2, 27)) /* OSXSAVE set? */
if ((read_xcr(0) & 0x6) == 0x6)
os_saves_ymm_regs = true;
if (IS_SET(features_2, 27)) { /* OSXSAVE set? */
u64 xcr0 = read_xcr(0);
if (os_saves_ymm_regs && IS_SET(features_2, 28))
os_avx_support = IS_ALL_SET(xcr0,
XCR0_BIT_SSE |
XCR0_BIT_AVX);
os_avx512_support = IS_ALL_SET(xcr0,
XCR0_BIT_SSE |
XCR0_BIT_AVX |
XCR0_BIT_OPMASK |
XCR0_BIT_ZMM_HI256 |
XCR0_BIT_HI16_ZMM);
}
if (os_avx_support && IS_SET(features_2, 28))
features |= X86_CPU_FEATURE_AVX;
if (max_function < 7)
@ -101,12 +123,15 @@ void setup_cpu_features(void)
/* Extended feature flags */
cpuid(7, 0, &dummy1, &features_3, &features_4, &dummy4);
if (os_saves_ymm_regs && IS_SET(features_3, 5))
if (os_avx_support && IS_SET(features_3, 5))
features |= X86_CPU_FEATURE_AVX2;
if (IS_SET(features_3, 8))
features |= X86_CPU_FEATURE_BMI2;
if (os_avx512_support && IS_SET(features_3, 30))
features |= X86_CPU_FEATURE_AVX512BW;
out:
_cpu_features = features | X86_CPU_FEATURES_KNOWN;
}

View File

@ -21,6 +21,7 @@
#define X86_CPU_FEATURE_AVX 0x00000004
#define X86_CPU_FEATURE_AVX2 0x00000008
#define X86_CPU_FEATURE_BMI2 0x00000010
#define X86_CPU_FEATURE_AVX512BW 0x00000020
#define X86_CPU_FEATURES_KNOWN 0x80000000