diff --git a/Kernel/Arch/aarch64/CPUID.cpp b/Kernel/Arch/aarch64/CPUID.cpp index 4dbc3f29f1..bb2ebbf3dd 100644 --- a/Kernel/Arch/aarch64/CPUID.cpp +++ b/Kernel/Arch/aarch64/CPUID.cpp @@ -8,6 +8,12 @@ namespace Kernel { +CPUFeature::Type detect_cpu_features() +{ + auto features = CPUFeature::Type(0u); + return features; +} + // https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile StringView cpu_feature_to_name(CPUFeature::Type const& feature) { @@ -1004,4 +1010,21 @@ StringView cpu_feature_to_description(CPUFeature::Type const& feature) VERIFY_NOT_REACHED(); } +NonnullOwnPtr build_cpu_feature_names(CPUFeature::Type const& features) +{ + StringBuilder builder; + bool first = true; + for (auto feature = CPUFeature::Type(1u); feature != CPUFeature::__End; feature <<= 1u) { + if (features.has_flag(feature)) { + if (first) + first = false; + else + MUST(builder.try_append(' ')); + auto name = cpu_feature_to_name(feature); + MUST(builder.try_append(name)); + } + } + return KString::must_create(builder.string_view()); +} + } diff --git a/Kernel/Arch/aarch64/CPUID.h b/Kernel/Arch/aarch64/CPUID.h index d82c7e4b78..19fca9f71a 100644 --- a/Kernel/Arch/aarch64/CPUID.h +++ b/Kernel/Arch/aarch64/CPUID.h @@ -7,8 +7,11 @@ #pragma once #include +#include #include #include +#include +#include #include VALIDATE_IS_AARCH64() @@ -250,26 +253,28 @@ AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u256, GICv3 = CPUFeature(1u) << 223u, // Generic Interrupt Controller version 3 GICv3p1 = CPUFeature(1u) << 224u, // Generic Interrupt Controller version 3.1 // Note: cf. https://developer.arm.com/documentation/ihi0069/h/?lang=en - GICv3_LEGACY = CPUFeature(1u) << 225u, // Support for GICv2 legacy operation - GICv3_TDIR = CPUFeature(1u) << 226u, // Trapping Non-secure EL1 writes to ICV_DIR - GICv4 = CPUFeature(1u) << 227u, // Generic Interrupt Controller version 4 - GICv4p1 = CPUFeature(1u) << 228u, // Generic Interrupt Controller version 4.1 - PMUv3 = CPUFeature(1u) << 229u, // PMU extension version 3 - ETE = CPUFeature(1u) << 230u, // Embedded Trace Extension - ETEv1p1 = CPUFeature(1u) << 231u, // Embedded Trace Extension, version 1.1 - SVE2 = CPUFeature(1u) << 232u, // SVE version 2 - SVE_AES = CPUFeature(1u) << 233u, // SVE AES instructions - SVE_PMULL128 = CPUFeature(1u) << 234u, // SVE PMULL instructions; SVE2-AES is split into AES and PMULL support - SVE_BitPerm = CPUFeature(1u) << 235u, // SVE Bit Permute - SVE_SHA3 = CPUFeature(1u) << 236u, // SVE SHA-3 instructions - SVE_SM4 = CPUFeature(1u) << 237u, // SVE SM4 instructions - TME = CPUFeature(1u) << 238u, // Transactional Memory Extension - TRBE = CPUFeature(1u) << 239u, // Trace Buffer Extension - SME = CPUFeature(1u) << 240u, // Scalable Matrix Extension + GICv3_LEGACY = CPUFeature(1u) << 225u, // Support for GICv2 legacy operation + GICv3_TDIR = CPUFeature(1u) << 226u, // Trapping Non-secure EL1 writes to ICV_DIR + GICv4 = CPUFeature(1u) << 227u, // Generic Interrupt Controller version 4 + GICv4p1 = CPUFeature(1u) << 228u, // Generic Interrupt Controller version 4.1 + PMUv3 = CPUFeature(1u) << 229u, // PMU extension version 3 + ETE = CPUFeature(1u) << 230u, // Embedded Trace Extension + ETEv1p1 = CPUFeature(1u) << 231u, // Embedded Trace Extension, version 1.1 + SVE2 = CPUFeature(1u) << 232u, // SVE version 2 + SVE_AES = CPUFeature(1u) << 233u, // SVE AES instructions + SVE_PMULL128 = CPUFeature(1u) << 234u, // SVE PMULL instructions; SVE2-AES is split into AES and PMULL support + SVE_BitPerm = CPUFeature(1u) << 235u, // SVE Bit Permute + SVE_SHA3 = CPUFeature(1u) << 236u, // SVE SHA-3 instructions + SVE_SM4 = CPUFeature(1u) << 237u, // SVE SM4 instructions + TME = CPUFeature(1u) << 238u, // Transactional Memory Extension + TRBE = CPUFeature(1u) << 239u, // Trace Buffer Extension + SME = CPUFeature(1u) << 240u, // Scalable Matrix Extension __End = CPUFeature(1u) << 255u); +CPUFeature::Type detect_cpu_features(); StringView cpu_feature_to_name(CPUFeature::Type const&); StringView cpu_feature_to_description(CPUFeature::Type const&); +NonnullOwnPtr build_cpu_feature_names(CPUFeature::Type const&); } diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp index 6160ae4625..1951611270 100644 --- a/Kernel/Arch/aarch64/Processor.cpp +++ b/Kernel/Arch/aarch64/Processor.cpp @@ -30,6 +30,7 @@ Processor* g_current_processor; void Processor::initialize(u32 cpu) { VERIFY(g_current_processor == nullptr); + m_features = detect_cpu_features(); initialize_exceptions(cpu); diff --git a/Kernel/Arch/aarch64/Processor.h b/Kernel/Arch/aarch64/Processor.h index cc2f2f60e6..b06b3714db 100644 --- a/Kernel/Arch/aarch64/Processor.h +++ b/Kernel/Arch/aarch64/Processor.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -136,6 +137,11 @@ public: return false; } + ALWAYS_INLINE bool has_feature(CPUFeature::Type const& feature) const + { + return m_features.has_flag(feature); + } + ALWAYS_INLINE static FlatPtr current_in_irq() { return current().m_in_irq; @@ -277,6 +283,8 @@ public: private: Processor(Processor const&) = delete; + CPUFeature::Type m_features; + Thread* m_current_thread; Thread* m_idle_thread; u32 m_in_critical { 0 };