From 3c6ad4c7db054257af4bbeec407a06b4f9497489 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 12 Sep 2021 09:42:27 -0400 Subject: [PATCH] Kernel: Add a class to wrap aarch64 MIDR_EL1 We'll need part_num() to determine the MMIO address base. It's 0x3F000000 on rpi3 but 0xFE000000 on rpi4. --- .../Prekernel/Arch/aarch64/MainIdRegister.cpp | 19 ++++++++++ .../Prekernel/Arch/aarch64/MainIdRegister.h | 36 +++++++++++++++++++ Kernel/Prekernel/Arch/aarch64/init.cpp | 3 ++ Kernel/Prekernel/CMakeLists.txt | 1 + 4 files changed, 59 insertions(+) create mode 100644 Kernel/Prekernel/Arch/aarch64/MainIdRegister.cpp create mode 100644 Kernel/Prekernel/Arch/aarch64/MainIdRegister.h diff --git a/Kernel/Prekernel/Arch/aarch64/MainIdRegister.cpp b/Kernel/Prekernel/Arch/aarch64/MainIdRegister.cpp new file mode 100644 index 0000000000..377d5c8e27 --- /dev/null +++ b/Kernel/Prekernel/Arch/aarch64/MainIdRegister.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Nico Weber + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Prekernel { + +MainIdRegister::MainIdRegister() +{ + unsigned int mrs; + asm volatile("mrs %x0, MIDR_EL1" + : "=r"(mrs)); + m_value = mrs; +} + +} diff --git a/Kernel/Prekernel/Arch/aarch64/MainIdRegister.h b/Kernel/Prekernel/Arch/aarch64/MainIdRegister.h new file mode 100644 index 0000000000..5f8d775acb --- /dev/null +++ b/Kernel/Prekernel/Arch/aarch64/MainIdRegister.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, Nico Weber + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Prekernel { + +class MainIdRegister { +public: + MainIdRegister(); + + enum Implementer { + ArmLimited = 0x41, + }; + unsigned implementer() const { return (m_value >> 24) & 0xFF; } + unsigned variant() const { return (m_value >> 20) & 0xF; } + unsigned architecture() const { return (m_value >> 16) & 0xF; } + + enum PartNum { + RaspberryPi1 = 0xB76, + RaspberryPi2 = 0xC07, + RaspberryPi3 = 0xD03, + RaspberryPi4 = 0xD08, + }; + unsigned part_num() const { return (m_value >> 4) & 0xFFF; } + + unsigned revision() const { return m_value & 0xF; } + +private: + unsigned int m_value; +}; + +} diff --git a/Kernel/Prekernel/Arch/aarch64/init.cpp b/Kernel/Prekernel/Arch/aarch64/init.cpp index a5f96edf24..5771575aa4 100644 --- a/Kernel/Prekernel/Arch/aarch64/init.cpp +++ b/Kernel/Prekernel/Arch/aarch64/init.cpp @@ -5,10 +5,13 @@ */ #include +#include extern "C" [[noreturn]] void init(); extern "C" [[noreturn]] void init() { + Prekernel::MainIdRegister id; + [[maybe_unused]] unsigned part_num = id.part_num(); for (;;) { } } diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt index 183367a74b..1da2421bae 100644 --- a/Kernel/Prekernel/CMakeLists.txt +++ b/Kernel/Prekernel/CMakeLists.txt @@ -12,6 +12,7 @@ if ("${SERENITY_ARCH}" STREQUAL "aarch64") Arch/aarch64/boot.S ${SOURCES} + Arch/aarch64/MainIdRegister.cpp Arch/aarch64/init.cpp ) else()