summaryrefslogtreecommitdiff
path: root/Kernel/Arch/x86/common/Processor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/Arch/x86/common/Processor.cpp')
-rw-r--r--Kernel/Arch/x86/common/Processor.cpp25
1 files changed, 22 insertions, 3 deletions
diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp
index cb84c12ac7..5647b4ec2d 100644
--- a/Kernel/Arch/x86/common/Processor.cpp
+++ b/Kernel/Arch/x86/common/Processor.cpp
@@ -19,6 +19,7 @@
#include <Kernel/Arch/x86/CPUID.h>
#include <Kernel/Arch/x86/Interrupts.h>
+#include <Kernel/Arch/x86/MSR.h>
#include <Kernel/Arch/x86/Processor.h>
#include <Kernel/Arch/x86/ProcessorInfo.h>
#include <Kernel/Arch/x86/SafeMem.h>
@@ -1056,11 +1057,17 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
m_gdtr.limit = 0;
write_raw_gdt_entry(0x0000, 0x00000000, 0x00000000);
+#if ARCH(I386)
write_raw_gdt_entry(GDT_SELECTOR_CODE0, 0x0000ffff, 0x00cf9a00); // code0
write_raw_gdt_entry(GDT_SELECTOR_DATA0, 0x0000ffff, 0x00cf9200); // data0
write_raw_gdt_entry(GDT_SELECTOR_CODE3, 0x0000ffff, 0x00cffa00); // code3
write_raw_gdt_entry(GDT_SELECTOR_DATA3, 0x0000ffff, 0x00cff200); // data3
+#else
+ write_raw_gdt_entry(GDT_SELECTOR_CODE0, 0x0000ffff, 0x00ef9a00); // code0
+ write_raw_gdt_entry(GDT_SELECTOR_CODE3, 0x0000ffff, 0x00effa00); // code3
+#endif
+#if ARCH(I386)
Descriptor tls_descriptor {};
tls_descriptor.low = tls_descriptor.high = 0;
tls_descriptor.dpl = 3;
@@ -1083,10 +1090,11 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
fs_descriptor.descriptor_type = 1;
fs_descriptor.type = 2;
write_gdt_entry(GDT_SELECTOR_PROC, fs_descriptor); // fs0
+#endif
Descriptor tss_descriptor {};
- tss_descriptor.set_base(VirtualAddress { &m_tss });
- tss_descriptor.set_limit(sizeof(TSS32) - 1);
+ tss_descriptor.set_base(VirtualAddress { (size_t)&m_tss & 0xffffffff });
+ tss_descriptor.set_limit(sizeof(TSS) - 1);
tss_descriptor.dpl = 0;
tss_descriptor.segment_present = 1;
tss_descriptor.granularity = 0;
@@ -1096,9 +1104,21 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
tss_descriptor.type = 9;
write_gdt_entry(GDT_SELECTOR_TSS, tss_descriptor); // tss
+#if ARCH(X86_64)
+ Descriptor tss_descriptor_part2 {};
+ tss_descriptor_part2.low = (size_t)&m_tss >> 32;
+ write_gdt_entry(GDT_SELECTOR_TSS_PART2, tss_descriptor_part2);
+#endif
+
flush_gdt();
load_task_register(GDT_SELECTOR_TSS);
+#if ARCH(X86_64)
+ MSR fs_base(MSR_FS_BASE);
+ fs_base.set((size_t)this & 0xffffffff, (size_t)this >> 32);
+#endif
+
+#if ARCH(I386)
asm volatile(
"mov %%ax, %%ds\n"
"mov %%ax, %%es\n"
@@ -1107,7 +1127,6 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
: "memory");
set_fs(GDT_SELECTOR_PROC);
-#if ARCH(I386)
// Make sure CS points to the kernel code descriptor.
// clang-format off
asm volatile(