From 94090214322c553a7957f80f74b2be64efee8c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 21 Dec 2017 22:56:59 +0100 Subject: [PATCH] kernel: x86: add cpuid feature 7 flags. --- headers/private/kernel/arch/x86/arch_cpu.h | 60 ++++++++++++++++++ src/system/kernel/arch/x86/arch_cpu.cpp | 71 +++++++++++++++++++++- 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 7f1731f645..d27f8e3dc1 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -1,4 +1,5 @@ /* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. @@ -206,6 +207,62 @@ #define IA32_FEATURE_APERFMPERF (1 << 0) //IA32_APERF, IA32_MPERF #define IA32_FEATURE_EPB (1 << 3) //IA32_ENERGY_PERF_BIAS +// x86 features from cpuid eax 7, ebx register +// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) +#define IA32_FEATURE_TSC_ADJUST (1 << 1) // IA32_TSC_ADJUST MSR supported +#define IA32_FEATURE_SGX (1 << 2) // Software Guard Extensions +#define IA32_FEATURE_BMI1 (1 << 3) // Bit Manipulation Instruction Set 1 +#define IA32_FEATURE_HLE (1 << 4) // Hardware Lock Elision +#define IA32_FEATURE_AVX2 (1 << 5) // Advanced Vector Extensions 2 +#define IA32_FEATURE_SMEP (1 << 7) // Supervisor-Mode Execution Prevention +#define IA32_FEATURE_BMI2 (1 << 8) // Bit Manipulation Instruction Set 2 +#define IA32_FEATURE_ERMS (1 << 9) // Enhanced REP MOVSB/STOSB +#define IA32_FEATURE_INVPCID (1 << 10) // INVPCID instruction +#define IA32_FEATURE_RTM (1 << 11) // Transactional Synchronization Extensions +#define IA32_FEATURE_CQM (1 << 12) // Platform Quality of Service Monitoring +#define IA32_FEATURE_MPX (1 << 14) // Memory Protection Extensions +#define IA32_FEATURE_RDT_A (1 << 15) // Resource Director Technology Allocation +#define IA32_FEATURE_AVX512F (1 << 16) // AVX-512 Foundation +#define IA32_FEATURE_AVX512DQ (1 << 17) // AVX-512 Doubleword and Quadword Instructions +#define IA32_FEATURE_RDSEED (1 << 18) // RDSEED instruction +#define IA32_FEATURE_ADX (1 << 19) // ADX (Multi-Precision Add-Carry Instruction Extensions) +#define IA32_FEATURE_SMAP (1 << 20) // Supervisor Mode Access Prevention +#define IA32_FEATURE_AVX512IFMA (1 << 21) // AVX-512 Integer Fused Multiply-Add Instructions +#define IA32_FEATURE_PCOMMIT (1 << 22) // PCOMMIT instruction +#define IA32_FEATURE_CLFLUSHOPT (1 << 23) // CLFLUSHOPT instruction +#define IA32_FEATURE_CLWB (1 << 24) // CLWB instruction +#define IA32_FEATURE_INTEL_PT (1 << 25) // Intel Processor Trace +#define IA32_FEATURE_AVX512PF (1 << 26) // AVX-512 Prefetch Instructions +#define IA32_FEATURE_AVX512ER (1 << 27) // AVX-512 Exponential and Reciprocal Instructions +#define IA32_FEATURE_AVX512CD (1 << 28) // AVX-512 Conflict Detection Instructions +#define IA32_FEATURE_SHA_NI (1 << 29) // SHA extensions +#define IA32_FEATURE_AVX512BW (1 << 30) // AVX-512 Byte and Word Instructions +#define IA32_FEATURE_AVX512VI (1 << 31) // AVX-512 Vector Length Extensions + +// x86 features from cpuid eax 7, ecx register +// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) +// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features +#define IA32_FEATURE_AVX512VMBI (1 << 1) // AVX-512 Vector Bit Manipulation Instructions +#define IA32_FEATURE_UMIP (1 << 2) // User-mode Instruction Prevention +#define IA32_FEATURE_PKU (1 << 3) // Memory Protection Keys for User-mode pages +#define IA32_FEATURE_OSPKE (1 << 4) // PKU enabled by OS +#define IA32_FEATURE_AVX512VMBI2 (1 << 6) // AVX-512 Vector Bit Manipulation Instructions 2 +#define IA32_FEATURE_GFNI (1 << 8) // Galois Field instructions +#define IA32_FEATURE_VAES (1 << 9) // AES instruction set (VEX-256/EVEX) +#define IA32_FEATURE_VPCLMULQDQ (1 << 10) // CLMUL instruction set (VEX-256/EVEX) +#define IA32_FEATURE_AVX512_VNNI (1 << 11) // AVX-512 Vector Neural Network Instructions +#define IA32_FEATURE_AVX512_BITALG (1 << 12) // AVX-512 BITALG instructions +#define IA32_FEATURE_AVX512_VPOPCNTDQ (1 << 14) // AVX-512 Vector Population Count D/Q +#define IA32_FEATURE_LA57 (1 << 16) // 5-level page tables +#define IA32_FEATURE_RDPID (1 << 22) // RDPID Instruction +#define IA32_FEATURE_SGX_LC (1 << 30) // SGX Launch Configuration + +// x86 features from cpuid eax 7, edx register +// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features +#define IA32_FEATURE_AVX512_4VNNIW (1 << 2) // AVX-512 4-register Neural Network Instructions +#define IA32_FEATURE_AVX512_4FMAPS (1 << 3) // AVX-512 4-register Multiply Accumulation Single precision + + // x86 defined features from cpuid eax 0x80000007, edx register #define IA32_FEATURE_INVARIANT_TSC (1 << 8) @@ -294,6 +351,9 @@ enum x86_feature_type { FEATURE_5_ECX, // cpuid eax=5, ecx register FEATURE_6_EAX, // cpuid eax=6, eax registers FEATURE_6_ECX, // cpuid eax=6, ecx registers + FEATURE_7_EBX, // cpuid eax=7, ebx registers + FEATURE_7_ECX, // cpuid eax=7, ecx registers + FEATURE_7_EDX, // cpuid eax=7, edx registers FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register FEATURE_NUM diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 930144d57b..53de951a20 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org. * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. @@ -326,7 +327,7 @@ x86_init_fpu(void) static void dump_feature_string(int currentCPU, cpu_ent* cpu) { - char features[384]; + char features[512]; features[0] = 0; if (cpu->arch.feature[FEATURE_COMMON] & IA32_FEATURE_FPU) @@ -477,6 +478,64 @@ dump_feature_string(int currentCPU, cpu_ent* cpu) strlcat(features, "aperfmperf ", sizeof(features)); if (cpu->arch.feature[FEATURE_6_ECX] & IA32_FEATURE_EPB) strlcat(features, "epb ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_TSC_ADJUST) + strlcat(features, "tsc_adjust ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_SGX) + strlcat(features, "sgx ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_BMI1) + strlcat(features, "bmi1 ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_HLE) + strlcat(features, "hle ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX2) + strlcat(features, "avx2 ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_SMEP) + strlcat(features, "smep ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_BMI2) + strlcat(features, "bmi2 ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_ERMS) + strlcat(features, "erms ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_INVPCID) + strlcat(features, "invpcid ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_RTM) + strlcat(features, "rtm ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_CQM) + strlcat(features, "cqm ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_MPX) + strlcat(features, "mpx ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_RDT_A) + strlcat(features, "rdt_a ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512F) + strlcat(features, "avx512f ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512DQ) + strlcat(features, "avx512dq ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_RDSEED) + strlcat(features, "rdseed ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_ADX) + strlcat(features, "adx ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_SMAP) + strlcat(features, "smap ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512IFMA) + strlcat(features, "avx512ifma ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_PCOMMIT) + strlcat(features, "pcommit ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_CLFLUSHOPT) + strlcat(features, "cflushopt ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_CLWB) + strlcat(features, "clwb ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_INTEL_PT) + strlcat(features, "intel_pt ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512PF) + strlcat(features, "avx512pf ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512ER) + strlcat(features, "avx512er ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512CD) + strlcat(features, "avx512cd ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_SHA_NI) + strlcat(features, "sha_ni ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512BW) + strlcat(features, "avx512bw ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_AVX512VI) + strlcat(features, "avx512vi ", sizeof(features)); dprintf("CPU %d: features: %s\n", currentCPU, features); } @@ -806,6 +865,9 @@ detect_cpu(int currentCPU) cpu->arch.feature[FEATURE_COMMON] = 0; cpu->arch.feature[FEATURE_EXT] = 0; cpu->arch.feature[FEATURE_EXT_AMD] = 0; + cpu->arch.feature[FEATURE_7_EBX] = 0; + cpu->arch.feature[FEATURE_7_ECX] = 0; + cpu->arch.feature[FEATURE_7_EDX] = 0; cpu->arch.model_name[0] = 0; // print some fun data @@ -915,6 +977,13 @@ detect_cpu(int currentCPU) cpu->arch.feature[FEATURE_6_ECX] = cpuid.regs.ecx; } + if (maxBasicLeaf >= 7) { + get_current_cpuid(&cpuid, 7, 0); + cpu->arch.feature[FEATURE_7_EBX] = cpuid.regs.ebx; + cpu->arch.feature[FEATURE_7_ECX] = cpuid.regs.ecx; + cpu->arch.feature[FEATURE_7_EDX] = cpuid.regs.edx; + } + if (maxExtendedLeaf >= 0x80000007) { get_current_cpuid(&cpuid, 0x80000007, 0); cpu->arch.feature[FEATURE_EXT_7_EDX] = cpuid.regs.edx;