From 8a2fd0e43629acd652c8da2c979688ed60080ba5 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 31 Aug 2020 14:27:38 +0100 Subject: [PATCH] Kernel: Fix Processor::features_string() stopping too early and detect more features The exit condition for the loop was sizeof(m_features) * 8, which was 32. Presumably this was supposed to mean 32 bits, but it actually made it stop as soon as it reached the 6th bit. Also add detection for more SIMD CPU features. --- Kernel/Arch/i386/CPU.cpp | 30 +++++++++++++++++++++++++++--- Kernel/Arch/i386/CPU.h | 9 ++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 99ff67a368..6b414e0a73 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -785,14 +785,26 @@ void Processor::cpu_detect() m_features = static_cast(0); CPUID processor_info(0x1); + if (processor_info.edx() & (1 << 4)) + set_feature(CPUFeature::TSC); if (processor_info.edx() & (1 << 6)) set_feature(CPUFeature::PAE); if (processor_info.edx() & (1 << 13)) set_feature(CPUFeature::PGE); + if (processor_info.edx() & (1 << 23)) + set_feature(CPUFeature::MMX); if (processor_info.edx() & (1 << 25)) set_feature(CPUFeature::SSE); - if (processor_info.edx() & (1 << 4)) - set_feature(CPUFeature::TSC); + if (processor_info.edx() & (1 << 26)) + set_feature(CPUFeature::SSE2); + if (processor_info.ecx() & (1 << 0)) + set_feature(CPUFeature::SSE3); + if (processor_info.ecx() & (1 << 9)) + set_feature(CPUFeature::SSSE3); + if (processor_info.ecx() & (1 << 19)) + set_feature(CPUFeature::SSE4_1); + if (processor_info.ecx() & (1 << 20)) + set_feature(CPUFeature::SSE4_2); if (processor_info.ecx() & (1 << 30)) set_feature(CPUFeature::RDRAND); if (processor_info.edx() & (1 << 11)) { @@ -916,6 +928,18 @@ String Processor::features_string() const return "sep"; case CPUFeature::SYSCALL: return "syscall"; + case CPUFeature::MMX: + return "mmx"; + case CPUFeature::SSE2: + return "sse2"; + case CPUFeature::SSE3: + return "sse3"; + case CPUFeature::SSSE3: + return "ssse3"; + case CPUFeature::SSE4_1: + return "sse4.1"; + case CPUFeature::SSE4_2: + return "sse4.2"; // no default statement here intentionally so that we get // a warning if a new feature is forgotten to be added here } @@ -923,7 +947,7 @@ String Processor::features_string() const return "???"; }; bool first = true; - for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) { + for (u32 flag = 1; flag != 0; flag <<= 1) { if ((static_cast(m_features) & flag) != 0) { if (first) first = false; diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index f159f01a5a..44bbcfb4c5 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -591,6 +591,7 @@ private: SplitQword m_start; }; +// FIXME: This can't hold every CPU feature as-is. enum class CPUFeature : u32 { NX = (1 << 0), PAE = (1 << 1), @@ -603,7 +604,13 @@ enum class CPUFeature : u32 { TSC = (1 << 8), UMIP = (1 << 9), SEP = (1 << 10), - SYSCALL = (1 << 11) + SYSCALL = (1 << 11), + MMX = (1 << 12), + SSE2 = (1 << 13), + SSE3 = (1 << 14), + SSSE3 = (1 << 15), + SSE4_1 = (1 << 16), + SSE4_2 = (1 << 17) }; class Thread;