ソースを参照

Kernel/riscv64: Add register state related headers

Sönke Holz 1 年間 前
コミット
24e64cac7e

+ 2 - 0
Kernel/Arch/FPUState.h

@@ -16,6 +16,8 @@ struct FPUState;
 #    include <Kernel/Arch/x86_64/FPUState.h>
 #elif ARCH(AARCH64)
 #    include <Kernel/Arch/aarch64/FPUState.h>
+#elif ARCH(RISCV64)
+#    include <Kernel/Arch/riscv64/FPUState.h>
 #else
 #    error "Unknown architecture"
 #endif

+ 2 - 0
Kernel/Arch/RegisterState.h

@@ -12,6 +12,8 @@
 #    include <Kernel/Arch/x86_64/RegisterState.h>
 #elif ARCH(AARCH64)
 #    include <Kernel/Arch/aarch64/RegisterState.h>
+#elif ARCH(RISCV64)
+#    include <Kernel/Arch/riscv64/RegisterState.h>
 #else
 #    error "Unknown architecture"
 #endif

+ 2 - 0
Kernel/Arch/ThreadRegisters.h

@@ -12,6 +12,8 @@
 #    include <Kernel/Arch/x86_64/ThreadRegisters.h>
 #elif ARCH(AARCH64)
 #    include <Kernel/Arch/aarch64/ThreadRegisters.h>
+#elif ARCH(RISCV64)
+#    include <Kernel/Arch/riscv64/ThreadRegisters.h>
 #else
 #    error "Unknown architecture"
 #endif

+ 2 - 0
Kernel/Arch/TrapFrame.h

@@ -19,6 +19,8 @@
 #    include <Kernel/Arch/x86_64/TrapFrame.h>
 #elif ARCH(AARCH64)
 #    include <Kernel/Arch/aarch64/TrapFrame.h>
+#elif ARCH(RISCV64)
+#    include <Kernel/Arch/riscv64/TrapFrame.h>
 #else
 #    error "Unknown architecture"
 #endif

+ 21 - 0
Kernel/Arch/riscv64/FPUState.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+
+#include <AK/Platform.h>
+VALIDATE_IS_RISCV64()
+
+namespace Kernel {
+
+struct FPUState {
+    u64 f[32];
+    u64 fcsr;
+};
+
+}

+ 85 - 0
Kernel/Arch/riscv64/RegisterState.h

@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <sys/arch/riscv64/regs.h>
+
+#include <Kernel/Arch/riscv64/CSR.h>
+#include <Kernel/Security/ExecutionMode.h>
+
+#include <AK/Platform.h>
+VALIDATE_IS_RISCV64()
+
+namespace Kernel {
+
+struct RegisterState {
+    u64 x[31];
+
+    RISCV64::CSR::SSTATUS sstatus;
+    u64 sepc;
+    u64 scause;
+    u64 stval;
+
+    u64 user_sp;
+
+    FlatPtr userspace_sp() const { return user_sp; }
+    void set_userspace_sp(FlatPtr value) { user_sp = value; }
+
+    FlatPtr ip() const { return sepc; }
+    void set_ip(FlatPtr value) { sepc = value; }
+
+    FlatPtr bp() const { return x[7]; }
+    void set_bp(FlatPtr value) { x[7] = value; }
+
+    ExecutionMode previous_mode() const
+    {
+        switch (sstatus.SPP) {
+        case RISCV64::CSR::SSTATUS::PrivilegeMode::User:
+            return ExecutionMode::User;
+        case RISCV64::CSR::SSTATUS::PrivilegeMode::Supervisor:
+            return ExecutionMode::Kernel;
+        default:
+            VERIFY_NOT_REACHED();
+        }
+    }
+
+    void set_return_reg(FlatPtr value) { x[9] = value; }
+    void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3, FlatPtr& arg4) const
+    {
+        function = x[16];
+        arg1 = x[9];
+        arg2 = x[10];
+        arg3 = x[11];
+        arg4 = x[12];
+    }
+};
+
+#define REGISTER_STATE_SIZE (36 * 8)
+static_assert(AssertSize<RegisterState, REGISTER_STATE_SIZE>());
+
+inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_regs, RegisterState const& kernel_regs)
+{
+    for (auto i = 0; i < 31; i++)
+        ptrace_regs.x[i] = kernel_regs.x[i];
+
+    ptrace_regs.sp = kernel_regs.userspace_sp();
+    ptrace_regs.pc = kernel_regs.ip();
+}
+
+inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, PtraceRegisters const& ptrace_regs)
+{
+    for (auto i = 0; i < 31; i++)
+        kernel_regs.x[i] = ptrace_regs.x[i];
+
+    kernel_regs.set_userspace_sp(ptrace_regs.sp);
+    kernel_regs.set_ip(ptrace_regs.pc);
+}
+
+struct DebugRegisterState {
+};
+
+}

+ 66 - 0
Kernel/Arch/riscv64/ThreadRegisters.h

@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+#include <Kernel/Arch/riscv64/CSR.h>
+#include <Kernel/Library/StdLib.h>
+#include <Kernel/Memory/AddressSpace.h>
+
+#include <AK/Platform.h>
+VALIDATE_IS_RISCV64()
+
+namespace Kernel {
+
+struct ThreadRegisters {
+    u64 x[31];
+    RISCV64::CSR::SSTATUS sstatus;
+    RISCV64::CSR::SATP satp;
+    u64 pc;
+
+    u64 kernel_sp;
+
+    FlatPtr ip() const { return pc; }
+    void set_ip(FlatPtr value) { pc = value; }
+
+    FlatPtr sp() const { return x[1]; }
+    void set_sp(FlatPtr value) { x[1] = value; }
+
+    void set_initial_state(bool is_kernel_process, Memory::AddressSpace& space, FlatPtr kernel_stack_top)
+    {
+        set_sp(kernel_stack_top);
+        satp = space.page_directory().satp();
+        set_sstatus(is_kernel_process);
+    }
+
+    void set_entry_function(FlatPtr entry_ip, FlatPtr entry_data)
+    {
+        set_ip(entry_ip);
+        x[9] = entry_data; // a0
+    }
+
+    void set_exec_state(FlatPtr entry_ip, FlatPtr userspace_sp, Memory::AddressSpace& space)
+    {
+        set_ip(entry_ip);
+        set_sp(userspace_sp);
+        satp = space.page_directory().satp();
+        set_sstatus(false);
+    }
+
+    void set_sstatus(bool is_kernel_process)
+    {
+        // Enable interrupts
+        sstatus.SPIE = 1;
+
+        sstatus.FS = RISCV64::CSR::SSTATUS::FloatingPointStatus::Initial;
+
+        sstatus.SPP = is_kernel_process ? RISCV64::CSR::SSTATUS::PrivilegeMode::Supervisor : RISCV64::CSR::SSTATUS::PrivilegeMode::User;
+        sstatus.UXL = RISCV64::CSR::SSTATUS::XLEN::Bits64;
+    }
+};
+
+}

+ 32 - 0
Kernel/Arch/riscv64/TrapFrame.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <Kernel/Arch/RegisterState.h>
+
+#include <AK/Platform.h>
+VALIDATE_IS_RISCV64()
+
+namespace Kernel {
+
+struct TrapFrame {
+    TrapFrame* next_trap;
+    RegisterState* regs;
+
+    TrapFrame() = delete;
+    TrapFrame(TrapFrame const&) = delete;
+    TrapFrame(TrapFrame&&) = delete;
+    TrapFrame& operator=(TrapFrame const&) = delete;
+    TrapFrame& operator=(TrapFrame&&) = delete;
+};
+
+#define TRAP_FRAME_SIZE (2 * 8)
+static_assert(AssertSize<TrapFrame, TRAP_FRAME_SIZE>());
+
+extern "C" void exit_trap(TrapFrame*) __attribute__((used));
+
+}

+ 2 - 0
Userland/Libraries/LibC/sys/arch/regs.h

@@ -12,4 +12,6 @@
 #    include "x86_64/regs.h"
 #elif ARCH(AARCH64)
 #    include "aarch64/regs.h"
+#elif ARCH(RISCV64)
+#    include "riscv64/regs.h"
 #endif

+ 46 - 0
Userland/Libraries/LibC/sys/arch/riscv64/regs.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Platform.h>
+
+#if defined(__cplusplus) && defined(__cpp_concepts)
+#    include <AK/Types.h>
+#else
+#    include <sys/types.h>
+#endif
+
+#include <Kernel/Arch/mcontext.h>
+
+#ifdef __cplusplus
+struct [[gnu::packed]] PtraceRegisters : public __mcontext {
+#    if defined(__cplusplus) && defined(__cpp_concepts)
+    FlatPtr ip() const
+    {
+        return pc;
+    }
+
+    void set_ip(FlatPtr ip)
+    {
+        pc = ip;
+    }
+
+    FlatPtr bp() const
+    {
+        return x[7];
+    }
+
+    void set_bp(FlatPtr bp)
+    {
+        x[7] = bp;
+    }
+#    endif
+};
+
+#else
+typedef struct __mcontext PthreadRegisters;
+#endif