summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorkonrad <konrad@serenityos.org>2023-01-08 00:01:25 +0100
committerJelle Raaijmakers <jelle@gmta.nl>2023-01-18 22:58:42 +0100
commit97dce5d00114c3630b7e090f739f4912a372ddd8 (patch)
treed3f621984cad812f42686feb4855e2f05ec7ca4d /Kernel
parent9f736d782c051f6d6dbe7cb472d4794a28f74551 (diff)
downloadserenity-97dce5d00114c3630b7e090f739f4912a372ddd8.zip
Kernel: Add Aarch64 CPU feature detection
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Arch/aarch64/CPUID.cpp23
-rw-r--r--Kernel/Arch/aarch64/CPUID.h37
-rw-r--r--Kernel/Arch/aarch64/Processor.cpp1
-rw-r--r--Kernel/Arch/aarch64/Processor.h8
4 files changed, 53 insertions, 16 deletions
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<KString> 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 <AK/ArbitrarySizedEnum.h>
+#include <AK/NonnullOwnPtr.h>
#include <AK/Types.h>
#include <AK/UFixedBigInt.h>
+#include <Kernel/Arch/aarch64/Registers.h>
+#include <Kernel/KString.h>
#include <AK/Platform.h>
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<KString> 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 <AK/Types.h>
#include <Kernel/Arch/ProcessorSpecificDataID.h>
+#include <Kernel/Arch/aarch64/CPUID.h>
#include <Kernel/Arch/aarch64/Registers.h>
#include <Kernel/VirtualAddress.h>
@@ -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 };