summaryrefslogtreecommitdiff
path: root/Kernel/Arch
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/Arch')
-rw-r--r--Kernel/Arch/i386/CPU.cpp20
-rw-r--r--Kernel/Arch/i386/InterruptEntry.cpp (renamed from Kernel/Arch/i386/Interrupts.h)42
-rw-r--r--Kernel/Arch/i386/ProcessorInfo.cpp4
-rw-r--r--Kernel/Arch/i386/SafeMem.cpp4
-rw-r--r--Kernel/Arch/x86/CPU.h (renamed from Kernel/Arch/i386/CPU.h)88
-rw-r--r--Kernel/Arch/x86/DescriptorTable.h (renamed from Kernel/Arch/x86_64/CPU.h)38
-rw-r--r--Kernel/Arch/x86/ISRStubs.h (renamed from Kernel/Arch/i386/ISRStubs.h)2
-rw-r--r--Kernel/Arch/x86/Interrupts.h52
-rw-r--r--Kernel/Arch/x86/PageDirectory.h170
-rw-r--r--Kernel/Arch/x86/ProcessorInfo.h (renamed from Kernel/Arch/i386/ProcessorInfo.h)0
-rw-r--r--Kernel/Arch/x86/SafeMem.h (renamed from Kernel/Arch/i386/SafeMem.h)0
-rw-r--r--Kernel/Arch/x86/SmapDisabler.h2
-rw-r--r--Kernel/Arch/x86/TSS.h88
13 files changed, 354 insertions, 156 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp
index 9be852f6de..a26debf3ba 100644
--- a/Kernel/Arch/i386/CPU.cpp
+++ b/Kernel/Arch/i386/CPU.cpp
@@ -29,10 +29,10 @@
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/Types.h>
-#include <Kernel/Arch/i386/CPU.h>
-#include <Kernel/Arch/i386/ISRStubs.h>
-#include <Kernel/Arch/i386/ProcessorInfo.h>
-#include <Kernel/Arch/i386/SafeMem.h>
+#include <Kernel/Arch/x86/CPU.h>
+#include <Kernel/Arch/x86/ISRStubs.h>
+#include <Kernel/Arch/x86/ProcessorInfo.h>
+#include <Kernel/Arch/x86/SafeMem.h>
#include <Kernel/Debug.h>
#include <Kernel/IO.h>
#include <Kernel/Interrupts/APIC.h>
@@ -2309,8 +2309,8 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
tls_descriptor.dpl = 3;
tls_descriptor.segment_present = 1;
tls_descriptor.granularity = 0;
- tls_descriptor.zero = 0;
- tls_descriptor.operation_size = 1;
+ tls_descriptor.operation_size64 = 0;
+ tls_descriptor.operation_size32 = 1;
tls_descriptor.descriptor_type = 1;
tls_descriptor.type = 2;
write_gdt_entry(GDT_SELECTOR_TLS, tls_descriptor); // tls3
@@ -2321,8 +2321,8 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
fs_descriptor.dpl = 0;
fs_descriptor.segment_present = 1;
fs_descriptor.granularity = 0;
- fs_descriptor.zero = 0;
- fs_descriptor.operation_size = 1;
+ fs_descriptor.operation_size64 = 0;
+ fs_descriptor.operation_size32 = 1;
fs_descriptor.descriptor_type = 1;
fs_descriptor.type = 2;
write_gdt_entry(GDT_SELECTOR_PROC, fs_descriptor); // fs0
@@ -2333,8 +2333,8 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
tss_descriptor.dpl = 0;
tss_descriptor.segment_present = 1;
tss_descriptor.granularity = 0;
- tss_descriptor.zero = 0;
- tss_descriptor.operation_size = 1;
+ tss_descriptor.operation_size64 = 0;
+ tss_descriptor.operation_size32 = 1;
tss_descriptor.descriptor_type = 0;
tss_descriptor.type = 9;
write_gdt_entry(GDT_SELECTOR_TSS, tss_descriptor); // tss
diff --git a/Kernel/Arch/i386/Interrupts.h b/Kernel/Arch/i386/InterruptEntry.cpp
index cfa457da16..a86267b32e 100644
--- a/Kernel/Arch/i386/Interrupts.h
+++ b/Kernel/Arch/i386/InterruptEntry.cpp
@@ -24,24 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
-
-#include <AK/Assertions.h>
-#include <AK/Types.h>
-#include <Kernel/Arch/i386/CPU.h>
-
-extern "C" void interrupt_common_asm_entry();
-
-#if ARCH(I386)
-
-# define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(isr_number) \
- extern "C" void interrupt_##isr_number##_asm_entry(); \
- asm(".globl interrupt_" #isr_number "_asm_entry\n" \
- "interrupt_" #isr_number "_asm_entry:\n" \
- " pushw $" #isr_number "\n" \
- " pushw $0\n" \
- " jmp interrupt_common_asm_entry\n");
-
+#include <Kernel/Arch/x86/CPU.h>
+#include <Kernel/Arch/x86/DescriptorTable.h>
// clang-format off
asm(
".globl interrupt_common_asm_entry\n"
@@ -68,9 +52,9 @@ asm(
" movl %ebx, 0(%esp) \n" // push pointer to TrapFrame
".globl common_trap_exit \n"
"common_trap_exit: \n"
- // another thread may have handled this trap at this point, so don't
- // make assumptions about the stack other than there's a TrapFrame
- // and a pointer to it.
+ // another thread may have handled this trap at this point, so don't
+ // make assumptions about the stack other than there's a TrapFrame
+ // and a pointer to it.
" call exit_trap \n"
" addl $" __STRINGIFY(TRAP_FRAME_SIZE + 4) ", %esp\n" // pop TrapFrame and pointer to it
".globl interrupt_common_asm_exit \n"
@@ -85,19 +69,3 @@ asm(
" iret\n"
);
// clang-format on
-
-#elif ARCH(X86_64)
-
-# define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(isr_number) \
- extern "C" void interrupt_##isr_number##_asm_entry(); \
- asm(".globl interrupt_" #isr_number "_asm_entry\n" \
- "interrupt_" #isr_number "_asm_entry:\n" \
- " cli\n" \
- " hlt\n");
-
-asm(
- ".globl common_trap_exit\n"
- "common_trap_exit:\n"
- " cli;hlt\n");
-
-#endif
diff --git a/Kernel/Arch/i386/ProcessorInfo.cpp b/Kernel/Arch/i386/ProcessorInfo.cpp
index a7f8f4ec4d..b5f5196a35 100644
--- a/Kernel/Arch/i386/ProcessorInfo.cpp
+++ b/Kernel/Arch/i386/ProcessorInfo.cpp
@@ -26,8 +26,8 @@
#include <AK/StringBuilder.h>
#include <AK/Types.h>
-#include <Kernel/Arch/i386/CPU.h>
-#include <Kernel/Arch/i386/ProcessorInfo.h>
+#include <Kernel/Arch/x86/CPU.h>
+#include <Kernel/Arch/x86/ProcessorInfo.h>
namespace Kernel {
diff --git a/Kernel/Arch/i386/SafeMem.cpp b/Kernel/Arch/i386/SafeMem.cpp
index a4be13e1d9..2e2eff662b 100644
--- a/Kernel/Arch/i386/SafeMem.cpp
+++ b/Kernel/Arch/i386/SafeMem.cpp
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <Kernel/Arch/i386/CPU.h>
-#include <Kernel/Arch/i386/SafeMem.h>
+#include <Kernel/Arch/x86/CPU.h>
+#include <Kernel/Arch/x86/SafeMem.h>
#define CODE_SECTION(section_name) __attribute__((section(section_name)))
diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/x86/CPU.h
index 54a61eb8dc..34c5b43fa3 100644
--- a/Kernel/Arch/i386/CPU.h
+++ b/Kernel/Arch/x86/CPU.h
@@ -30,6 +30,10 @@
#include <AK/Badge.h>
#include <AK/Noncopyable.h>
#include <AK/Vector.h>
+
+#include <Kernel/Arch/x86/DescriptorTable.h>
+#include <Kernel/Arch/x86/TSS.h>
+
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
#include <LibC/sys/arch/i386/regs.h>
@@ -55,90 +59,6 @@ inline u32 get_iopl_from_eflags(u32 eflags)
return (eflags & iopl_mask) >> 12;
}
-struct [[gnu::packed]] DescriptorTablePointer {
- u16 limit;
- void* address;
-};
-
-struct [[gnu::packed]] TSS32 {
- u16 backlink, __blh;
- u32 esp0;
- u16 ss0, __ss0h;
- u32 esp1;
- u16 ss1, __ss1h;
- u32 esp2;
- u16 ss2, __ss2h;
- u32 cr3, eip, eflags;
- u32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
- u16 es, __esh;
- u16 cs, __csh;
- u16 ss, __ssh;
- u16 ds, __dsh;
- u16 fs, __fsh;
- u16 gs, __gsh;
- u16 ldt, __ldth;
- u16 trace, iomapbase;
-};
-
-union [[gnu::packed]] Descriptor {
- struct {
- u16 limit_lo;
- u16 base_lo;
- u8 base_hi;
- u8 type : 4;
- u8 descriptor_type : 1;
- u8 dpl : 2;
- u8 segment_present : 1;
- u8 limit_hi : 4;
- u8 : 1;
- u8 zero : 1;
- u8 operation_size : 1;
- u8 granularity : 1;
- u8 base_hi2;
- };
- struct {
- u32 low;
- u32 high;
- };
-
- enum Type {
- Invalid = 0,
- AvailableTSS_16bit = 0x1,
- LDT = 0x2,
- BusyTSS_16bit = 0x3,
- CallGate_16bit = 0x4,
- TaskGate = 0x5,
- InterruptGate_16bit = 0x6,
- TrapGate_16bit = 0x7,
- AvailableTSS_32bit = 0x9,
- BusyTSS_32bit = 0xb,
- CallGate_32bit = 0xc,
- InterruptGate_32bit = 0xe,
- TrapGate_32bit = 0xf,
- };
-
- VirtualAddress base() const
- {
- FlatPtr base = base_lo;
- base |= base_hi << 16u;
- base |= base_hi2 << 24u;
- return VirtualAddress { base };
- }
-
- void set_base(VirtualAddress base)
- {
- base_lo = base.get() & 0xffffu;
- base_hi = (base.get() >> 16u) & 0xffu;
- base_hi2 = (base.get() >> 24u) & 0xffu;
- }
-
- void set_limit(u32 length)
- {
- limit_lo = length & 0xffff;
- limit_hi = (length >> 16) & 0xf;
- }
-};
-
class PageDirectoryEntry {
public:
const PageTableEntry* page_table_base() const { return reinterpret_cast<PageTableEntry*>(m_raw & 0xfffff000u); }
diff --git a/Kernel/Arch/x86_64/CPU.h b/Kernel/Arch/x86/DescriptorTable.h
index e307ab606f..990da3dbac 100644
--- a/Kernel/Arch/x86_64/CPU.h
+++ b/Kernel/Arch/x86/DescriptorTable.h
@@ -30,29 +30,29 @@
#include <AK/Types.h>
#include <Kernel/VirtualAddress.h>
+#define GDT_SELECTOR_CODE0 0x08
+#define GDT_SELECTOR_DATA0 0x10
+#define GDT_SELECTOR_CODE3 0x18
+#define GDT_SELECTOR_DATA3 0x20
+#define GDT_SELECTOR_TLS 0x28
+#define GDT_SELECTOR_PROC 0x30
+#define GDT_SELECTOR_TSS 0x38
+
+// SYSENTER makes certain assumptions on how the GDT is structured:
+static_assert(GDT_SELECTOR_CODE0 + 8 == GDT_SELECTOR_DATA0); // SS0 = CS0 + 8
+
+// SYSEXIT makes certain assumptions on how the GDT is structured:
+static_assert(GDT_SELECTOR_CODE0 + 16 == GDT_SELECTOR_CODE3); // CS3 = CS0 + 16
+static_assert(GDT_SELECTOR_CODE0 + 24 == GDT_SELECTOR_DATA3); // SS3 = CS0 + 32
+
namespace Kernel {
-struct [[gnu::packed]] TSS64
-{
- u32 __1; // Link?
- u64 rsp0;
- u64 rsp1;
- u64 rsp2;
- u64 __2; // IST0 -> empty?
- u64 ist1;
- u64 ist2;
- u64 ist3;
- u64 ist4;
- u64 ist5;
- u64 ist6;
- u64 ist7;
- u64 __3;
- u16 __4;
- u16 iomapbase;
+struct [[gnu::packed]] DescriptorTablePointer {
+ u16 limit;
+ void* address;
};
-union [[gnu::packed]] Descriptor
-{
+union [[gnu::packed]] Descriptor {
struct {
u16 limit_lo;
u16 base_lo;
diff --git a/Kernel/Arch/i386/ISRStubs.h b/Kernel/Arch/x86/ISRStubs.h
index 86db4644a1..94714d315e 100644
--- a/Kernel/Arch/i386/ISRStubs.h
+++ b/Kernel/Arch/x86/ISRStubs.h
@@ -26,7 +26,7 @@
#pragma once
-#include <Kernel/Arch/i386/Interrupts.h>
+#include <Kernel/Arch/x86/Interrupts.h>
GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(80)
GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(81)
diff --git a/Kernel/Arch/x86/Interrupts.h b/Kernel/Arch/x86/Interrupts.h
new file mode 100644
index 0000000000..70e53d043e
--- /dev/null
+++ b/Kernel/Arch/x86/Interrupts.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Leon Albrecht <leon2002.la@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+
+namespace Kernel {
+
+class GenericInterruptHandeler;
+
+extern "C" void interrupt_common_asm_entry();
+
+#define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(isr_number) \
+ extern "C" void interrupt_##isr_number##_asm_entry(); \
+ asm(".globl interrupt_" #isr_number "_asm_entry\n" \
+ "interrupt_" #isr_number "_asm_entry:\n" \
+ " pushw $" #isr_number "\n" \
+ " pushw $0\n" \
+ " jmp interrupt_common_asm_entry\n");
+
+void register_interrupt_handler(u8 number, void (*handler)());
+void register_user_callable_interrupt_handler(u8 number, void (*handler)());
+GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number);
+void register_generic_interrupt_handler(u8 number, GenericInterruptHandler&);
+void unregister_generic_interrupt_handler(u8 number, GenericInterruptHandler&);
+
+}
diff --git a/Kernel/Arch/x86/PageDirectory.h b/Kernel/Arch/x86/PageDirectory.h
new file mode 100644
index 0000000000..2a83fb6b40
--- /dev/null
+++ b/Kernel/Arch/x86/PageDirectory.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Badge.h>
+#include <AK/Types.h>
+
+namespace Kernel {
+
+class PageDirectory;
+class PageTableEntry;
+
+class PageDirectoryEntry {
+public:
+ const PageTableEntry* page_table_base() const { return reinterpret_cast<PageTableEntry*>(m_raw & 0xfffff000u); }
+ PageTableEntry* page_table_base() { return reinterpret_cast<PageTableEntry*>(m_raw & 0xfffff000u); }
+ void set_page_table_base(u32 value)
+ {
+ m_raw &= 0x8000000000000fffULL;
+ m_raw |= value & 0xfffff000;
+ }
+
+ bool is_null() const { return m_raw == 0; }
+ void clear() { m_raw = 0; }
+
+ u64 raw() const { return m_raw; }
+ void copy_from(Badge<PageDirectory>, const PageDirectoryEntry& other) { m_raw = other.m_raw; }
+
+ enum Flags {
+ Present = 1 << 0,
+ ReadWrite = 1 << 1,
+ UserSupervisor = 1 << 2,
+ WriteThrough = 1 << 3,
+ CacheDisabled = 1 << 4,
+ Huge = 1 << 7,
+ Global = 1 << 8,
+ NoExecute = 0x8000000000000000ULL,
+ };
+
+ bool is_present() const { return raw() & Present; }
+ void set_present(bool b) { set_bit(Present, b); }
+
+ bool is_user_allowed() const { return raw() & UserSupervisor; }
+ void set_user_allowed(bool b) { set_bit(UserSupervisor, b); }
+
+ bool is_huge() const { return raw() & Huge; }
+ void set_huge(bool b) { set_bit(Huge, b); }
+
+ bool is_writable() const { return raw() & ReadWrite; }
+ void set_writable(bool b) { set_bit(ReadWrite, b); }
+
+ bool is_write_through() const { return raw() & WriteThrough; }
+ void set_write_through(bool b) { set_bit(WriteThrough, b); }
+
+ bool is_cache_disabled() const { return raw() & CacheDisabled; }
+ void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
+
+ bool is_global() const { return raw() & Global; }
+ void set_global(bool b) { set_bit(Global, b); }
+
+ bool is_execute_disabled() const { return raw() & NoExecute; }
+ void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
+
+ void set_bit(u64 bit, bool value)
+ {
+ if (value)
+ m_raw |= bit;
+ else
+ m_raw &= ~bit;
+ }
+
+private:
+ u64 m_raw;
+};
+
+class PageTableEntry {
+public:
+ void* physical_page_base() { return reinterpret_cast<void*>(m_raw & 0xfffff000u); }
+ void set_physical_page_base(u32 value)
+ {
+ m_raw &= 0x8000000000000fffULL;
+ m_raw |= value & 0xfffff000;
+ }
+
+ u64 raw() const { return (u32)m_raw; }
+
+ enum Flags {
+ Present = 1 << 0,
+ ReadWrite = 1 << 1,
+ UserSupervisor = 1 << 2,
+ WriteThrough = 1 << 3,
+ CacheDisabled = 1 << 4,
+ Global = 1 << 8,
+ NoExecute = 0x8000000000000000ULL,
+ };
+
+ bool is_present() const { return raw() & Present; }
+ void set_present(bool b) { set_bit(Present, b); }
+
+ bool is_user_allowed() const { return raw() & UserSupervisor; }
+ void set_user_allowed(bool b) { set_bit(UserSupervisor, b); }
+
+ bool is_writable() const { return raw() & ReadWrite; }
+ void set_writable(bool b) { set_bit(ReadWrite, b); }
+
+ bool is_write_through() const { return raw() & WriteThrough; }
+ void set_write_through(bool b) { set_bit(WriteThrough, b); }
+
+ bool is_cache_disabled() const { return raw() & CacheDisabled; }
+ void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
+
+ bool is_global() const { return raw() & Global; }
+ void set_global(bool b) { set_bit(Global, b); }
+
+ bool is_execute_disabled() const { return raw() & NoExecute; }
+ void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
+
+ bool is_null() const { return m_raw == 0; }
+ void clear() { m_raw = 0; }
+
+ void set_bit(u64 bit, bool value)
+ {
+ if (value)
+ m_raw |= bit;
+ else
+ m_raw &= ~bit;
+ }
+
+private:
+ u64 m_raw;
+};
+
+static_assert(sizeof(PageDirectoryEntry) == 8);
+static_assert(sizeof(PageTableEntry) == 8);
+
+class PageDirectoryPointerTable {
+public:
+ PageDirectoryEntry* directory(size_t index)
+ {
+ return (PageDirectoryEntry*)(raw[index] & ~0xfffu);
+ }
+
+ u64 raw[4];
+};
+
+}
diff --git a/Kernel/Arch/i386/ProcessorInfo.h b/Kernel/Arch/x86/ProcessorInfo.h
index 7169184650..7169184650 100644
--- a/Kernel/Arch/i386/ProcessorInfo.h
+++ b/Kernel/Arch/x86/ProcessorInfo.h
diff --git a/Kernel/Arch/i386/SafeMem.h b/Kernel/Arch/x86/SafeMem.h
index f66844ce4a..f66844ce4a 100644
--- a/Kernel/Arch/i386/SafeMem.h
+++ b/Kernel/Arch/x86/SafeMem.h
diff --git a/Kernel/Arch/x86/SmapDisabler.h b/Kernel/Arch/x86/SmapDisabler.h
index 3574dc733f..3fdfd1b0ea 100644
--- a/Kernel/Arch/x86/SmapDisabler.h
+++ b/Kernel/Arch/x86/SmapDisabler.h
@@ -26,7 +26,7 @@
#pragma once
-#include <Kernel/Arch/i386/CPU.h>
+#include <Kernel/Arch/x86/CPU.h>
namespace Kernel {
diff --git a/Kernel/Arch/x86/TSS.h b/Kernel/Arch/x86/TSS.h
new file mode 100644
index 0000000000..3b0178a059
--- /dev/null
+++ b/Kernel/Arch/x86/TSS.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Leon Albrecht <leon2002.la@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+
+namespace Kernel {
+
+struct [[gnu::packed]] TSS32 {
+ u16 backlink, __blh;
+ u32 esp0;
+ u16 ss0, __ss0h;
+ u32 esp1;
+ u16 ss1, __ss1h;
+ u32 esp2;
+ u16 ss2, __ss2h;
+ u32 cr3, eip, eflags;
+ u32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
+ u16 es, __esh;
+ u16 cs, __csh;
+ u16 ss, __ssh;
+ u16 ds, __dsh;
+ u16 fs, __fsh;
+ u16 gs, __gsh;
+ u16 ldt, __ldth;
+ u16 trace, iomapbase;
+};
+
+struct [[gnu::packed]] TSS64 {
+ u32 __1; // Link?
+ u32 rsp0l;
+ u32 rsp0h;
+ u32 rsp1l;
+ u32 rsp1h;
+ u32 rsp2l;
+ u32 rsp2h;
+ u64 __2; //probably CR3 and EIP?
+ u32 ist1l;
+ u32 ist1h;
+ u32 ist2l;
+ u32 ist2h;
+ u32 ist3l;
+ u32 ist3h;
+ u32 ist4l;
+ u32 ist4h;
+ u32 ist5l;
+ u32 ist5h;
+ u32 ist6l;
+ u32 ist6h;
+ u32 ist7l;
+ u32 ist7h;
+ u64 __3; // GS and LDTR?
+ u16 __4;
+ u16 iomapbase;
+};
+
+#if ARCH(I386)
+using TSS = TSS32;
+#elif ARCH(X86_64)
+using TSS = TSS64;
+#endif
+
+}