diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-03-18 14:39:53 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-03-18 14:39:53 +0000 |
| commit | 7a98b1dcb1f4436664a8f1a5d6e71ab2c65378f0 (patch) | |
| tree | 11da77c10c6a642f1aab8a6e687ccfa775b2f383 /arch/x86_64 | |
| parent | fd557fb19c4ad25fbcb1368a73fddd91921496fd (diff) | |
| download | teachos-7a98b1dcb1f4436664a8f1a5d6e71ab2c65378f0.tar.xz teachos-7a98b1dcb1f4436664a8f1a5d6e71ab2c65378f0.zip | |
Attempt to add calls that Reload code segment and data segment register
Diffstat (limited to 'arch/x86_64')
| -rw-r--r-- | arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp index 578e264..dccce6b 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/global_descriptor_table.cpp @@ -94,4 +94,35 @@ namespace teachos::arch::context_switching::descriptor_table "[Global Descriptor Table] Loaded TR value is not the same as the stored value."); return gdt; } + + auto reload_cs_register(uint16_t gdt_data_offset) -> void + { + asm volatile("mov %[input], %%ax\n" + "mov %%ax %%ds\n" // Data Segment + "mov %%ax %%es\n" // Extra Segment (used for string operations) + "mov %%ax %%fs\n" // General-purpose Segment + "mov %%ax %%gs\n" // General-purpose Segment + "mov %%ax %%ss\n" // Stack Segment + : /* no output from call */ + : [input] "r"(gdt_data_offset) + : "ax"); + } + + auto reload_segment_register(uint16_t gdt_code_offset, uint16_t gdt_data_offset) -> void + { + /* + Whatever you do with the GDT has no effect on the CPU until you load new Segment Selectors into Segment Registers. + For most of these registers, the process is as simple as using MOV instructions, but changing the CS register + requires code resembling a jump or call to elsewhere, as this is the only way its value is meant to be changed. + */ + auto function = [gdt_data_offset] { reload_cs_register(gdt_data_offset); }; + + asm volatile("push %[input]\n" + "lea %[func], %%rax\n" + "push %%rax\n" + "retfq\n" + : /* no output from call */ + : [input] "r"(gdt_code_offset), [func] "r"(&function) + : "rax"); + } } // namespace teachos::arch::context_switching::descriptor_table |
