TSS setup
This commit is contained in:
+21
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* @author xamidev <xamidev@riseup.net>
|
||||
* @brief Global Descriptor Table (for legacy reasons)
|
||||
* @brief Global Descriptor Table and Task State Segment setup
|
||||
* @license GPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
uint64_t gdt_entries[NUM_GDT_ENTRIES];
|
||||
struct GDTR gdtr;
|
||||
|
||||
struct tss tss = {0};
|
||||
|
||||
/*
|
||||
* gdt_load - Loads Global Descriptor Table
|
||||
*/
|
||||
@@ -85,7 +87,22 @@ static void gdt_set_entry(int num, uint8_t flags, uint8_t access)
|
||||
*/
|
||||
static void gdt_set_tss(int num)
|
||||
{
|
||||
uint64_t tss_base = (uint64_t)&tss;
|
||||
uint64_t tss_limit = sizeof(struct tss) - 1;
|
||||
|
||||
tss.iopb = sizeof(struct tss);
|
||||
|
||||
uint64_t tss_low = 0;
|
||||
tss_low |= (tss_limit & 0xFFFFULL);
|
||||
tss_low |= (tss_base & 0xFFFFFFULL) << 16;
|
||||
tss_low |= 0x89ULL << 40;
|
||||
tss_low |= ((tss_limit >> 16) & 0xFULL) << 48;
|
||||
tss_low |= ((tss_base >> 24) & 0xFFULL) << 56;
|
||||
|
||||
uint64_t tss_high = (tss_base >> 32) & 0xFFFFFFFFULL;
|
||||
|
||||
gdt_entries[num] = tss_low;
|
||||
gdt_entries[num + 1] = tss_high;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,6 +121,7 @@ void gdt_init()
|
||||
gdt_set_entry(2, 0xC, 0x93); // Kernel data (0x10)
|
||||
gdt_set_entry(3, 0xA, 0xFB); // User code (0x18)
|
||||
gdt_set_entry(4, 0xC, 0xF3); // User data (0x20)
|
||||
gdt_set_tss(5); // TSS (0x28)
|
||||
|
||||
// The -1 subtraction is some wizardry explained in the OSDev wiki -> GDT
|
||||
gdtr.limit = NUM_GDT_ENTRIES * sizeof(uint64_t) - 1;
|
||||
@@ -113,7 +131,8 @@ void gdt_init()
|
||||
gdt_load();
|
||||
gdt_flush();
|
||||
|
||||
// Here we should load the task register with TSS selector
|
||||
// Load task register with new TSS
|
||||
asm volatile("ltr %%ax" : : "a"(TSS_SEGMENT) : "memory");
|
||||
|
||||
DEBUG("GDT initialized");
|
||||
}
|
||||
Reference in New Issue
Block a user