diff options
author | Hendiadyoin1 <leon2002.la@gmail.com> | 2021-06-21 17:34:09 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-24 00:38:23 +0200 |
commit | 7ca3d413f7ec0e0ef83b20c2473d73c747a9b330 (patch) | |
tree | 776412b2cbee270195aa515f71ac42da1b2090d8 /Kernel/Arch/x86/RegisterState.h | |
parent | 37253ebcae6a9e172903ea1b9fae19c42055a53b (diff) | |
download | serenity-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.h | 122 |
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. +} + +} |