diff options
author | Luke <luke.wilde@live.co.uk> | 2020-08-31 14:27:38 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-31 18:57:54 +0200 |
commit | 8a2fd0e43629acd652c8da2c979688ed60080ba5 (patch) | |
tree | 04743ff67cfe2b00074899663b81c6877857bd2e /Kernel/Arch | |
parent | 259f8541fcd6bc147c9fb4c57b16cd840700af59 (diff) | |
download | serenity-8a2fd0e43629acd652c8da2c979688ed60080ba5.zip |
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.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 30 | ||||
-rw-r--r-- | 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<CPUFeature>(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<u32>(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; |