diff options
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 20 | ||||
-rw-r--r-- | Kernel/Arch/i386/InterruptEntry.cpp (renamed from Kernel/Arch/i386/Interrupts.h) | 42 | ||||
-rw-r--r-- | Kernel/Arch/i386/ProcessorInfo.cpp | 4 | ||||
-rw-r--r-- | Kernel/Arch/i386/SafeMem.cpp | 4 | ||||
-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.h | 52 | ||||
-rw-r--r-- | Kernel/Arch/x86/PageDirectory.h | 170 | ||||
-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.h | 2 | ||||
-rw-r--r-- | Kernel/Arch/x86/TSS.h | 88 |
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 + +} |