summaryrefslogtreecommitdiff
path: root/Kernel/Arch/x86/RegisterState.h
diff options
context:
space:
mode:
authorHendiadyoin1 <leon2002.la@gmail.com>2021-06-21 17:34:09 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-24 00:38:23 +0200
commit7ca3d413f7ec0e0ef83b20c2473d73c747a9b330 (patch)
tree776412b2cbee270195aa515f71ac42da1b2090d8 /Kernel/Arch/x86/RegisterState.h
parent37253ebcae6a9e172903ea1b9fae19c42055a53b (diff)
downloadserenity-7ca3d413f7ec0e0ef83b20c2473d73c747a9b330.zip
Kernel: Pull apart CPU.h
This does not add any functional changes
Diffstat (limited to 'Kernel/Arch/x86/RegisterState.h')
-rw-r--r--Kernel/Arch/x86/RegisterState.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/Kernel/Arch/x86/RegisterState.h b/Kernel/Arch/x86/RegisterState.h
new file mode 100644
index 0000000000..0f0d2f3a5f
--- /dev/null
+++ b/Kernel/Arch/x86/RegisterState.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+#include <LibC/sys/arch/i386/regs.h>
+
+#include <Kernel/Arch/x86/ASM_wrapper.h>
+#include <Kernel/Arch/x86/CPU.h>
+
+namespace Kernel {
+
+struct [[gnu::packed]] RegisterState {
+ FlatPtr ss;
+ FlatPtr gs;
+ FlatPtr fs;
+ FlatPtr es;
+ FlatPtr ds;
+ FlatPtr edi;
+ FlatPtr esi;
+ FlatPtr ebp;
+ FlatPtr esp;
+ FlatPtr ebx;
+ FlatPtr edx;
+ FlatPtr ecx;
+ FlatPtr eax;
+ u16 exception_code;
+ u16 isr_number;
+#if ARCH(X86_64)
+ u32 padding;
+#endif
+ FlatPtr eip;
+ FlatPtr cs;
+ FlatPtr eflags;
+ FlatPtr userspace_esp;
+ FlatPtr userspace_ss;
+};
+
+#if ARCH(I386)
+# define REGISTER_STATE_SIZE (19 * 4)
+#else
+# define REGISTER_STATE_SIZE (19 * 8)
+#endif
+static_assert(REGISTER_STATE_SIZE == sizeof(RegisterState));
+
+inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_regs, const RegisterState& kernel_regs)
+{
+ ptrace_regs.eax = kernel_regs.eax,
+ ptrace_regs.ecx = kernel_regs.ecx,
+ ptrace_regs.edx = kernel_regs.edx,
+ ptrace_regs.ebx = kernel_regs.ebx,
+ ptrace_regs.esp = kernel_regs.userspace_esp,
+ ptrace_regs.ebp = kernel_regs.ebp,
+ ptrace_regs.esi = kernel_regs.esi,
+ ptrace_regs.edi = kernel_regs.edi,
+ ptrace_regs.eip = kernel_regs.eip,
+ ptrace_regs.eflags = kernel_regs.eflags,
+ ptrace_regs.cs = 0;
+ ptrace_regs.ss = 0;
+ ptrace_regs.ds = 0;
+ ptrace_regs.es = 0;
+ ptrace_regs.fs = 0;
+ ptrace_regs.gs = 0;
+}
+
+inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, const PtraceRegisters& ptrace_regs)
+{
+ kernel_regs.eax = ptrace_regs.eax;
+ kernel_regs.ecx = ptrace_regs.ecx;
+ kernel_regs.edx = ptrace_regs.edx;
+ kernel_regs.ebx = ptrace_regs.ebx;
+ kernel_regs.esp = ptrace_regs.esp;
+ kernel_regs.ebp = ptrace_regs.ebp;
+ kernel_regs.esi = ptrace_regs.esi;
+ kernel_regs.edi = ptrace_regs.edi;
+ kernel_regs.eip = ptrace_regs.eip;
+ kernel_regs.eflags = (kernel_regs.eflags & ~safe_eflags_mask) | (ptrace_regs.eflags & safe_eflags_mask);
+}
+
+struct [[gnu::packed]] DebugRegisterState {
+ FlatPtr dr0;
+ FlatPtr dr1;
+ FlatPtr dr2;
+ FlatPtr dr3;
+ FlatPtr dr6;
+ FlatPtr dr7;
+};
+
+inline void read_debug_registers_into(DebugRegisterState& state)
+{
+ state.dr0 = read_dr0();
+ state.dr1 = read_dr1();
+ state.dr2 = read_dr2();
+ state.dr3 = read_dr3();
+ state.dr6 = read_dr6();
+ state.dr7 = read_dr7();
+}
+
+inline void write_debug_registers_from(const DebugRegisterState& state)
+{
+ write_dr0(state.dr0);
+ write_dr1(state.dr1);
+ write_dr2(state.dr2);
+ write_dr3(state.dr3);
+ write_dr6(state.dr6);
+ write_dr7(state.dr7);
+}
+
+inline void clear_debug_registers()
+{
+ write_dr0(0);
+ write_dr1(0);
+ write_dr2(0);
+ write_dr3(0);
+ write_dr7(1 << 10); // Bit 10 is reserved and must be set to 1.
+}
+
+}