From 401fc6afae46a96e2502f3abbeff8e533af664a4 Mon Sep 17 00:00:00 2001 From: konrad Date: Sun, 8 Jan 2023 12:21:40 +0100 Subject: [PATCH] Kernel: Detect Aarch64 physical address bit width with CPU ID registers --- Kernel/Arch/aarch64/CPUID.cpp | 26 ++++++++++++++++++++++++++ Kernel/Arch/aarch64/CPUID.h | 2 ++ Kernel/Arch/aarch64/Processor.cpp | 2 ++ Kernel/Arch/aarch64/Processor.h | 4 ++-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Kernel/Arch/aarch64/CPUID.cpp b/Kernel/Arch/aarch64/CPUID.cpp index 2c177436d6..d0376e876a 100644 --- a/Kernel/Arch/aarch64/CPUID.cpp +++ b/Kernel/Arch/aarch64/CPUID.cpp @@ -1478,4 +1478,30 @@ NonnullOwnPtr build_cpu_feature_names(CPUFeature::Type const& features) return KString::must_create(builder.string_view()); } +u8 detect_physical_address_bit_width() +{ + auto memory_model_feature_register_0 = Aarch64::ID_AA64MMFR0_EL1::read(); + + switch (memory_model_feature_register_0.PARange) { + case 0b0000: + return 32; // 4GB + case 0b0001: + return 36; // 64GB + case 0b0010: + return 40; // 1TB + case 0b0011: + return 42; // 4TB + case 0b0100: + return 44; // 16TB + case 0b0101: + return 48; // 256TB + case 0b0110: + return 52; // 4PB (applies for FEAT_LPA or FEAT_LPA2) + case 0b0111: + return 56; // 64PB (applies for FEAT_D128) + default: + VERIFY_NOT_REACHED(); + } +} + } diff --git a/Kernel/Arch/aarch64/CPUID.h b/Kernel/Arch/aarch64/CPUID.h index 702c774899..4c914c78bc 100644 --- a/Kernel/Arch/aarch64/CPUID.h +++ b/Kernel/Arch/aarch64/CPUID.h @@ -277,4 +277,6 @@ StringView cpu_feature_to_name(CPUFeature::Type const&); StringView cpu_feature_to_description(CPUFeature::Type const&); NonnullOwnPtr build_cpu_feature_names(CPUFeature::Type const&); +u8 detect_physical_address_bit_width(); + } diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp index c287084b34..471e77b2db 100644 --- a/Kernel/Arch/aarch64/Processor.cpp +++ b/Kernel/Arch/aarch64/Processor.cpp @@ -33,6 +33,7 @@ void Processor::install(u32 cpu) VERIFY(g_current_processor == nullptr); m_cpu = cpu; m_features = detect_cpu_features(); + m_physical_address_bit_width = detect_physical_address_bit_width(); initialize_exceptions(cpu); @@ -42,6 +43,7 @@ void Processor::install(u32 cpu) void Processor::initialize() { dmesgln("CPU[{}]: Supports {}", m_cpu, build_cpu_feature_names(m_features)); + dmesgln("CPU[{}]: Physical address bit width: {}", m_cpu, m_physical_address_bit_width); } [[noreturn]] void Processor::halt() diff --git a/Kernel/Arch/aarch64/Processor.h b/Kernel/Arch/aarch64/Processor.h index f315f2da40..2111369f02 100644 --- a/Kernel/Arch/aarch64/Processor.h +++ b/Kernel/Arch/aarch64/Processor.h @@ -84,8 +84,7 @@ public: ALWAYS_INLINE u8 physical_address_bit_width() const { - TODO_AARCH64(); - return 0; + return m_physical_address_bit_width; } ALWAYS_INLINE u8 virtual_address_bit_width() const @@ -286,6 +285,7 @@ private: u32 m_cpu; CPUFeature::Type m_features; + u8 m_physical_address_bit_width; Thread* m_current_thread; Thread* m_idle_thread;