diff --git a/Kernel/Arch/x86/CPUID.h b/Kernel/Arch/x86/CPUID.h index d3e6f00394..f510591479 100644 --- a/Kernel/Arch/x86/CPUID.h +++ b/Kernel/Arch/x86/CPUID.h @@ -38,33 +38,88 @@ private: }; AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u128, - NX = CPUFeature(1u) << 0u, - PAE = CPUFeature(1u) << 1u, - PGE = CPUFeature(1u) << 2u, - RDRAND = CPUFeature(1u) << 3u, - RDSEED = CPUFeature(1u) << 4u, - SMAP = CPUFeature(1u) << 5u, - SMEP = CPUFeature(1u) << 6u, - SSE = CPUFeature(1u) << 7u, - TSC = CPUFeature(1u) << 8u, - RDTSCP = CPUFeature(1u) << 9u, - CONSTANT_TSC = CPUFeature(1u) << 10u, - NONSTOP_TSC = CPUFeature(1u) << 11u, - UMIP = CPUFeature(1u) << 12u, - SEP = CPUFeature(1u) << 13u, - SYSCALL = CPUFeature(1u) << 14u, - MMX = CPUFeature(1u) << 15u, - SSE2 = CPUFeature(1u) << 16u, - SSE3 = CPUFeature(1u) << 17u, - SSSE3 = CPUFeature(1u) << 18u, - SSE4_1 = CPUFeature(1u) << 19u, - SSE4_2 = CPUFeature(1u) << 20u, - XSAVE = CPUFeature(1u) << 21u, - AVX = CPUFeature(1u) << 22u, - FXSR = CPUFeature(1u) << 23u, - LM = CPUFeature(1u) << 24u, - HYPERVISOR = CPUFeature(1u) << 25u, - PAT = CPUFeature(1u) << 26u, - __End = CPUFeature(1u) << 27u); + /* EAX=1, ECX */ // + SSE3 = CPUFeature(1u) << 0u, // Streaming SIMD Extensions 3 + PCLMULQDQ = CPUFeature(1u) << 1u, // PCLMULDQ Instruction + DTES64 = CPUFeature(1u) << 2u, // 64-Bit Debug Store + MONITOR = CPUFeature(1u) << 3u, // MONITOR/MWAIT Instructions + DS_CPL = CPUFeature(1u) << 4u, // CPL Qualified Debug Store + VMX = CPUFeature(1u) << 5u, // Virtual Machine Extensions + SMX = CPUFeature(1u) << 6u, // Safer Mode Extensions + EST = CPUFeature(1u) << 7u, // Enhanced Intel SpeedStepĀ® Technology + TM2 = CPUFeature(1u) << 8u, // Thermal Monitor 2 + SSSE3 = CPUFeature(1u) << 9u, // Supplemental Streaming SIMD Extensions 3 + CNXT_ID = CPUFeature(1u) << 10u, // L1 Context ID + SDBG = CPUFeature(1u) << 11u, // Silicon Debug (IA32_DEBUG_INTERFACE MSR) + FMA = CPUFeature(1u) << 12u, // Fused Multiply Add + CX16 = CPUFeature(1u) << 13u, // CMPXCHG16B Instruction + XTPR = CPUFeature(1u) << 14u, // xTPR Update Control + PDCM = CPUFeature(1u) << 15u, // Perfmon and Debug Capability (IA32_PERF_CAPABILITIES MSR) + /* ECX Bit 16 */ // Reserved + PCID = CPUFeature(1u) << 17u, // Process Context Identifiers + DCA = CPUFeature(1u) << 18u, // Direct Cache Access + SSE4_1 = CPUFeature(1u) << 19u, // Streaming SIMD Extensions 4.1 + SSE4_2 = CPUFeature(1u) << 20u, // Streaming SIMD Extensions 4.2 + X2APIC = CPUFeature(1u) << 21u, // Extended xAPIC Support + MOVBE = CPUFeature(1u) << 22u, // MOVBE Instruction + POPCNT = CPUFeature(1u) << 23u, // POPCNT Instruction + TSC_DEADLINE = CPUFeature(1u) << 24u, // Time Stamp Counter Deadline + AES = CPUFeature(1u) << 25u, // AES Instruction Extensions + XSAVE = CPUFeature(1u) << 26u, // XSAVE/XSTOR States + OSXSAVE = CPUFeature(1u) << 27u, // OS-Enabled Extended State Management + AVX = CPUFeature(1u) << 28u, // Advanced Vector Extensions + F16C = CPUFeature(1u) << 29u, // 16-bit floating-point conversion instructions + RDRAND = CPUFeature(1u) << 30u, // RDRAND Instruction + HYPERVISOR = CPUFeature(1u) << 31u, // Hypervisor present (always zero on physical CPUs) + /* EAX=1, EDX */ // + FPU = CPUFeature(1u) << 32u, // Floating-point Unit On-Chip + VME = CPUFeature(1u) << 33u, // Virtual Mode Extension + DE = CPUFeature(1u) << 34u, // Debugging Extension + PSE = CPUFeature(1u) << 35u, // Page Size Extension + TSC = CPUFeature(1u) << 36u, // Time Stamp Counter + MSR = CPUFeature(1u) << 37u, // Model Specific Registers + PAE = CPUFeature(1u) << 38u, // Physical Address Extension + MCE = CPUFeature(1u) << 39u, // Machine-Check Exception + CX8 = CPUFeature(1u) << 40u, // CMPXCHG8 Instruction + APIC = CPUFeature(1u) << 41u, // On-chip APIC Hardware + /* EDX Bit 10 */ // Reserved + SEP = CPUFeature(1u) << 43u, // Fast System Call + MTRR = CPUFeature(1u) << 44u, // Memory Type Range Registers + PGE = CPUFeature(1u) << 45u, // Page Global Enable + MCA = CPUFeature(1u) << 46u, // Machine-Check Architecture + CMOV = CPUFeature(1u) << 47u, // Conditional Move Instruction + PAT = CPUFeature(1u) << 48u, // Page Attribute Table + PSE36 = CPUFeature(1u) << 49u, // 36-bit Page Size Extension + PSN = CPUFeature(1u) << 50u, // Processor serial number is present and enabled + CLFLUSH = CPUFeature(1u) << 51u, // CLFLUSH Instruction + /* EDX Bit 20 */ // Reserved + DS = CPUFeature(1u) << 53u, // CLFLUSH Instruction + ACPI = CPUFeature(1u) << 54u, // CLFLUSH Instruction + MMX = CPUFeature(1u) << 55u, // CLFLUSH Instruction + FXSR = CPUFeature(1u) << 56u, // CLFLUSH Instruction + SSE = CPUFeature(1u) << 57u, // Streaming SIMD Extensions + SSE2 = CPUFeature(1u) << 58u, // Streaming SIMD Extensions 2 + SS = CPUFeature(1u) << 59u, // Self-Snoop + HTT = CPUFeature(1u) << 60u, // Multi-Threading + TM = CPUFeature(1u) << 61u, // Thermal Monitor + IA64 = CPUFeature(1u) << 62u, // IA64 processor emulating x86 + PBE = CPUFeature(1u) << 63u, // Pending Break Enable + /* EAX=7, EBX */ // + SMEP = CPUFeature(1u) << 64u, // Supervisor Mode Execution Protection + RDSEED = CPUFeature(1u) << 65u, // RDSEED Instruction + SMAP = CPUFeature(1u) << 66u, // Supervisor Mode Access Prevention + /* EAX=7, ECX */ // + UMIP = CPUFeature(1u) << 67u, // User-Mode Instruction Prevention + /* EAX=80000001h, EDX */ // + SYSCALL = CPUFeature(1u) << 68u, // SYSCALL/SYSRET Instructions + NX = CPUFeature(1u) << 69u, // NX bit + RDTSCP = CPUFeature(1u) << 70u, // RDTSCP Instruction + LM = CPUFeature(1u) << 71u, // Long Mode + /* EAX=80000007h, EDX */ // + CONSTANT_TSC = CPUFeature(1u) << 72u, // Invariant TSC + NONSTOP_TSC = CPUFeature(1u) << 73u, // Invariant TSC + __End = CPUFeature(1u) << 127u); + +StringView cpu_feature_to_string_view(CPUFeature::Type const&); } diff --git a/Kernel/Arch/x86/common/CPUID.cpp b/Kernel/Arch/x86/common/CPUID.cpp new file mode 100644 index 0000000000..51ef21eeb6 --- /dev/null +++ b/Kernel/Arch/x86/common/CPUID.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Kernel { + +StringView cpu_feature_to_string_view(CPUFeature::Type const& feature) +{ + if (feature == CPUFeature::SSE3) + return "sse3"sv; + if (feature == CPUFeature::PCLMULQDQ) + return "pclmulqdq"sv; + if (feature == CPUFeature::DTES64) + return "dtes64"sv; + if (feature == CPUFeature::MONITOR) + return "monitor"sv; + if (feature == CPUFeature::DS_CPL) + return "ds_cpl"sv; + if (feature == CPUFeature::VMX) + return "vmx"sv; + if (feature == CPUFeature::SMX) + return "smx"sv; + if (feature == CPUFeature::EST) + return "est"sv; + if (feature == CPUFeature::TM2) + return "tm2"sv; + if (feature == CPUFeature::SSSE3) + return "ssse3"sv; + // NOTE: This is called cid on Linux, but CNXT_ID in the Intel manual. + if (feature == CPUFeature::CNXT_ID) + return "cnxt_id"sv; + if (feature == CPUFeature::SDBG) + return "sdbg"sv; + if (feature == CPUFeature::FMA) + return "fma"sv; + if (feature == CPUFeature::CX16) + return "cx16"sv; + if (feature == CPUFeature::XTPR) + return "xtpr"sv; + if (feature == CPUFeature::PDCM) + return "pdcm"sv; + if (feature == CPUFeature::PCID) + return "pcid"sv; + if (feature == CPUFeature::DCA) + return "dca"sv; + if (feature == CPUFeature::SSE4_1) + return "sse4_1"sv; + if (feature == CPUFeature::SSE4_2) + return "sse4_2"sv; + if (feature == CPUFeature::X2APIC) + return "x2apic"sv; + if (feature == CPUFeature::MOVBE) + return "movbe"sv; + if (feature == CPUFeature::POPCNT) + return "popcnt"sv; + // NOTE: This is called tsc_deadline_timer on Linux, but TSC_DEADLINE in the Intel manual. + if (feature == CPUFeature::TSC_DEADLINE) + return "tsc_deadline"sv; + if (feature == CPUFeature::AES) + return "aes"sv; + if (feature == CPUFeature::XSAVE) + return "xsave"sv; + if (feature == CPUFeature::OSXSAVE) + return "osxsave"sv; + if (feature == CPUFeature::AVX) + return "avx"sv; + if (feature == CPUFeature::F16C) + return "f16c"sv; + if (feature == CPUFeature::RDRAND) + return "rdrand"sv; + if (feature == CPUFeature::HYPERVISOR) + return "hypervisor"sv; + if (feature == CPUFeature::FPU) + return "fpu"sv; + if (feature == CPUFeature::VME) + return "vme"sv; + if (feature == CPUFeature::DE) + return "de"sv; + if (feature == CPUFeature::PSE) + return "pse"sv; + if (feature == CPUFeature::TSC) + return "tsc"sv; + if (feature == CPUFeature::MSR) + return "msr"sv; + if (feature == CPUFeature::PAE) + return "pae"sv; + if (feature == CPUFeature::MCE) + return "mce"sv; + if (feature == CPUFeature::CX8) + return "cx8"sv; + if (feature == CPUFeature::APIC) + return "apic"sv; + if (feature == CPUFeature::SEP) + return "sep"sv; + if (feature == CPUFeature::MTRR) + return "mtrr"sv; + if (feature == CPUFeature::PGE) + return "pge"sv; + if (feature == CPUFeature::MCA) + return "mca"sv; + if (feature == CPUFeature::CMOV) + return "cmov"sv; + if (feature == CPUFeature::PAT) + return "pat"sv; + if (feature == CPUFeature::PSE36) + return "pse36"sv; + if (feature == CPUFeature::PSN) + return "psn"sv; + if (feature == CPUFeature::CLFLUSH) + return "clflush"sv; + if (feature == CPUFeature::DS) + return "ds"sv; + if (feature == CPUFeature::ACPI) + return "acpi"sv; + if (feature == CPUFeature::MMX) + return "mmx"sv; + if (feature == CPUFeature::FXSR) + return "fxsr"sv; + if (feature == CPUFeature::SSE) + return "sse"sv; + if (feature == CPUFeature::SSE2) + return "sse2"sv; + if (feature == CPUFeature::SS) + return "ss"sv; + if (feature == CPUFeature::HTT) + return "htt"sv; + if (feature == CPUFeature::TM) + return "tm"sv; + if (feature == CPUFeature::IA64) + return "ia64"sv; + if (feature == CPUFeature::PBE) + return "pbe"sv; + if (feature == CPUFeature::SMEP) + return "smep"sv; + if (feature == CPUFeature::RDSEED) + return "rdseed"sv; + if (feature == CPUFeature::SMAP) + return "smap"sv; + if (feature == CPUFeature::UMIP) + return "umip"sv; + if (feature == CPUFeature::SYSCALL) + return "syscall"sv; + if (feature == CPUFeature::NX) + return "nx"sv; + if (feature == CPUFeature::RDTSCP) + return "rdtscp"sv; + if (feature == CPUFeature::LM) + return "lm"sv; + if (feature == CPUFeature::CONSTANT_TSC) + return "constant_tsc"sv; + if (feature == CPUFeature::NONSTOP_TSC) + return "nonstop_tsc"sv; + VERIFY_NOT_REACHED(); +} + +} diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index 3c1be17643..18186af866 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -89,31 +89,109 @@ UNMAP_AFTER_INIT void Processor::cpu_detect() if (processor_info.ecx() & (1 << 0)) m_features |= CPUFeature::SSE3; + if (processor_info.ecx() & (1 << 1)) + m_features |= CPUFeature::PCLMULQDQ; + if (processor_info.ecx() & (1 << 2)) + m_features |= CPUFeature::DTES64; + if (processor_info.ecx() & (1 << 3)) + m_features |= CPUFeature::MONITOR; + if (processor_info.ecx() & (1 << 4)) + m_features |= CPUFeature::DS_CPL; + if (processor_info.ecx() & (1 << 5)) + m_features |= CPUFeature::VMX; + if (processor_info.ecx() & (1 << 6)) + m_features |= CPUFeature::SMX; + if (processor_info.ecx() & (1 << 7)) + m_features |= CPUFeature::EST; + if (processor_info.ecx() & (1 << 8)) + m_features |= CPUFeature::TM2; if (processor_info.ecx() & (1 << 9)) m_features |= CPUFeature::SSSE3; + if (processor_info.ecx() & (1 << 10)) + m_features |= CPUFeature::CNXT_ID; + if (processor_info.ecx() & (1 << 11)) + m_features |= CPUFeature::SDBG; + if (processor_info.ecx() & (1 << 12)) + m_features |= CPUFeature::FMA; + if (processor_info.ecx() & (1 << 13)) + m_features |= CPUFeature::CX16; + if (processor_info.ecx() & (1 << 14)) + m_features |= CPUFeature::XTPR; + if (processor_info.ecx() & (1 << 15)) + m_features |= CPUFeature::PDCM; + if (processor_info.ecx() & (1 << 17)) + m_features |= CPUFeature::PCID; + if (processor_info.ecx() & (1 << 18)) + m_features |= CPUFeature::DCA; if (processor_info.ecx() & (1 << 19)) m_features |= CPUFeature::SSE4_1; if (processor_info.ecx() & (1 << 20)) m_features |= CPUFeature::SSE4_2; + if (processor_info.ecx() & (1 << 21)) + m_features |= CPUFeature::X2APIC; + if (processor_info.ecx() & (1 << 22)) + m_features |= CPUFeature::MOVBE; + if (processor_info.ecx() & (1 << 23)) + m_features |= CPUFeature::POPCNT; + if (processor_info.ecx() & (1 << 24)) + m_features |= CPUFeature::TSC_DEADLINE; + if (processor_info.ecx() & (1 << 25)) + m_features |= CPUFeature::AES; if (processor_info.ecx() & (1 << 26)) m_features |= CPUFeature::XSAVE; + if (processor_info.ecx() & (1 << 27)) + m_features |= CPUFeature::OSXSAVE; if (processor_info.ecx() & (1 << 28)) m_features |= CPUFeature::AVX; + if (processor_info.ecx() & (1 << 29)) + m_features |= CPUFeature::F16C; if (processor_info.ecx() & (1 << 30)) m_features |= CPUFeature::RDRAND; if (processor_info.ecx() & (1 << 31)) m_features |= CPUFeature::HYPERVISOR; + if (processor_info.edx() & (1 << 0)) + m_features |= CPUFeature::FPU; + if (processor_info.edx() & (1 << 1)) + m_features |= CPUFeature::VME; + if (processor_info.edx() & (1 << 2)) + m_features |= CPUFeature::DE; + if (processor_info.edx() & (1 << 3)) + m_features |= CPUFeature::PSE; if (processor_info.edx() & (1 << 4)) m_features |= CPUFeature::TSC; + if (processor_info.edx() & (1 << 5)) + m_features |= CPUFeature::MSR; if (processor_info.edx() & (1 << 6)) m_features |= CPUFeature::PAE; - if (processor_info.edx() & (1 << 13)) - m_features |= CPUFeature::PGE; + if (processor_info.edx() & (1 << 7)) + m_features |= CPUFeature::MCE; + if (processor_info.edx() & (1 << 8)) + m_features |= CPUFeature::CX8; + if (processor_info.edx() & (1 << 9)) + m_features |= CPUFeature::APIC; if (processor_info.edx() & (1 << 11)) handle_edx_bit_11_feature(); + if (processor_info.edx() & (1 << 12)) + m_features |= CPUFeature::MTRR; + if (processor_info.edx() & (1 << 13)) + m_features |= CPUFeature::PGE; + if (processor_info.edx() & (1 << 14)) + m_features |= CPUFeature::MCA; + if (processor_info.edx() & (1 << 15)) + m_features |= CPUFeature::CMOV; if (processor_info.edx() & (1 << 16)) m_features |= CPUFeature::PAT; + if (processor_info.edx() & (1 << 17)) + m_features |= CPUFeature::PSE36; + if (processor_info.edx() & (1 << 18)) + m_features |= CPUFeature::PSN; + if (processor_info.edx() & (1 << 19)) + m_features |= CPUFeature::CLFLUSH; + if (processor_info.edx() & (1 << 21)) + m_features |= CPUFeature::DS; + if (processor_info.edx() & (1 << 22)) + m_features |= CPUFeature::ACPI; if (processor_info.edx() & (1 << 23)) m_features |= CPUFeature::MMX; if (processor_info.edx() & (1 << 24)) @@ -122,6 +200,16 @@ UNMAP_AFTER_INIT void Processor::cpu_detect() m_features |= CPUFeature::SSE; if (processor_info.edx() & (1 << 26)) m_features |= CPUFeature::SSE2; + if (processor_info.edx() & (1 << 27)) + m_features |= CPUFeature::SS; + if (processor_info.edx() & (1 << 28)) + m_features |= CPUFeature::HTT; + if (processor_info.edx() & (1 << 29)) + m_features |= CPUFeature::TM; + if (processor_info.edx() & (1 << 30)) + m_features |= CPUFeature::IA64; + if (processor_info.edx() & (1 << 31)) + m_features |= CPUFeature::PBE; CPUID extended_features(0x7); if (extended_features.ebx() & (1 << 7)) @@ -290,63 +378,6 @@ UNMAP_AFTER_INIT void Processor::cpu_setup() NonnullOwnPtr Processor::features_string() const { StringBuilder builder; - auto feature_to_str = [](CPUFeature::Type const& feature) -> StringView { - if (feature == CPUFeature::NX) - return "nx"sv; - if (feature == CPUFeature::PAE) - return "pae"sv; - if (feature == CPUFeature::PGE) - return "pge"sv; - if (feature == CPUFeature::RDRAND) - return "rdrand"sv; - if (feature == CPUFeature::RDSEED) - return "rdseed"sv; - if (feature == CPUFeature::SMAP) - return "smap"sv; - if (feature == CPUFeature::SMEP) - return "smep"sv; - if (feature == CPUFeature::SSE) - return "sse"sv; - if (feature == CPUFeature::TSC) - return "tsc"sv; - if (feature == CPUFeature::RDTSCP) - return "rdtscp"sv; - if (feature == CPUFeature::CONSTANT_TSC) - return "constant_tsc"sv; - if (feature == CPUFeature::NONSTOP_TSC) - return "nonstop_tsc"sv; - if (feature == CPUFeature::UMIP) - return "umip"sv; - if (feature == CPUFeature::SEP) - return "sep"sv; - if (feature == CPUFeature::SYSCALL) - return "syscall"sv; - if (feature == CPUFeature::MMX) - return "mmx"sv; - if (feature == CPUFeature::FXSR) - return "fxsr"sv; - if (feature == CPUFeature::SSE2) - return "sse2"sv; - if (feature == CPUFeature::SSE3) - return "sse3"sv; - if (feature == CPUFeature::SSSE3) - return "ssse3"sv; - if (feature == CPUFeature::SSE4_1) - return "sse4.1"sv; - if (feature == CPUFeature::SSE4_2) - return "sse4.2"sv; - if (feature == CPUFeature::XSAVE) - return "xsave"sv; - if (feature == CPUFeature::AVX) - return "avx"sv; - if (feature == CPUFeature::LM) - return "lm"sv; - if (feature == CPUFeature::HYPERVISOR) - return "hypervisor"sv; - if (feature == CPUFeature::PAT) - return "pat"sv; - VERIFY_NOT_REACHED(); - }; bool first = true; for (auto feature = CPUFeature::Type(1u); feature != CPUFeature::__End; feature <<= 1u) { if (has_feature(feature)) { @@ -354,8 +385,7 @@ NonnullOwnPtr Processor::features_string() const first = false; else MUST(builder.try_append(' ')); - auto str = feature_to_str(feature); - MUST(builder.try_append(str)); + MUST(builder.try_append(cpu_feature_to_string_view(feature))); } } return KString::must_create(builder.string_view()); diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index c386ad4cc9..e64e6e3ca4 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -322,6 +322,7 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") ${KERNEL_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/ASM_wrapper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/CPU.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/CPUID.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/Interrupts.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/Processor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Arch/x86/common/ProcessorInfo.cpp diff --git a/Meta/check-debug-flags.sh b/Meta/check-debug-flags.sh index 6cc80b5744..f90e2c530b 100755 --- a/Meta/check-debug-flags.sh +++ b/Meta/check-debug-flags.sh @@ -8,8 +8,8 @@ cd "${script_path}/.." MISSING_FLAGS=n while IFS= read -r FLAG; do - # Ignore ELF_DEBUG because it's not a debug flag. - if [ "$FLAG" = "ELF_DEBUG" ]; then + # Ignore false positives that are not debug flags. + if [ "$FLAG" = "ELF_DEBUG" ] || [ "$FLAG" = "IA32_DEBUG_INTERFACE" ]; then continue fi