diff options
Diffstat (limited to 'Kernel/Arch/x86/common/ProcessorInfo.cpp')
-rw-r--r-- | Kernel/Arch/x86/common/ProcessorInfo.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/Kernel/Arch/x86/common/ProcessorInfo.cpp b/Kernel/Arch/x86/common/ProcessorInfo.cpp index 2706a681eb..3743e94c0f 100644 --- a/Kernel/Arch/x86/common/ProcessorInfo.cpp +++ b/Kernel/Arch/x86/common/ProcessorInfo.cpp @@ -36,6 +36,8 @@ ProcessorInfo::ProcessorInfo(Processor const& processor) m_display_family = family; m_display_model = model; } + + populate_cache_sizes(); } static void emit_u32(StringBuilder& builder, u32 value) @@ -110,4 +112,48 @@ NonnullOwnPtr<KString> ProcessorInfo::build_features_string(Processor const& pro return KString::must_create(builder.string_view()); } +void ProcessorInfo::populate_cache_sizes() +{ + u32 max_extended_leaf = CPUID(0x80000000).eax(); + + if (max_extended_leaf < 0x80000005) + return; + + auto l1_cache_info = CPUID(0x80000005); + + // NOTE: Except for L2, these are not available on Intel CPUs in this form and return 0 for each register in that case. + if (l1_cache_info.ecx() != 0) { + m_l1_data_cache = Cache { + .size = ((l1_cache_info.ecx() >> 24) & 0xff) * KiB, + .line_size = l1_cache_info.ecx() & 0xff, + }; + } + + if (l1_cache_info.edx() != 0) { + m_l1_instruction_cache = Cache { + .size = ((l1_cache_info.edx() >> 24) & 0xff) * KiB, + .line_size = l1_cache_info.edx() & 0xff, + }; + } + + if (max_extended_leaf < 0x80000006) + return; + + auto l2_l3_cache_info = CPUID(0x80000006); + + if (l2_l3_cache_info.ecx() != 0) { + m_l2_cache = Cache { + .size = ((l2_l3_cache_info.ecx() >> 16) & 0xffff) * KiB, + .line_size = l2_l3_cache_info.ecx() & 0xff, + }; + } + + if (l2_l3_cache_info.edx() != 0) { + m_l3_cache = Cache { + .size = (static_cast<u64>((l2_l3_cache_info.edx() >> 18)) & 0x3fff) * 512 * KiB, + .line_size = l2_l3_cache_info.edx() & 0xff, + }; + } +} + } |