forked from pepper-org/pepperOS
TSS setup
This commit is contained in:
+14
-1
@@ -13,19 +13,32 @@
|
||||
// we'll only use this as a requirement for paging, not more.
|
||||
// This means base 0 and no limit (whole address space)
|
||||
|
||||
#define NUM_GDT_ENTRIES 5
|
||||
#define NUM_GDT_ENTRIES 7
|
||||
|
||||
#define NULL_SELECTOR 0x00
|
||||
#define KERNEL_CODE_SEGMENT 0x08
|
||||
#define KERNEL_DATA_SEGMENT 0x10
|
||||
#define USER_CODE_SEGMENT 0x18
|
||||
#define USER_DATA_SEGMENT 0x20
|
||||
#define TSS_SEGMENT 0x28
|
||||
|
||||
struct GDTR {
|
||||
uint16_t limit;
|
||||
uint64_t address;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tss {
|
||||
uint32_t reserved0;
|
||||
uint64_t rsp0;
|
||||
uint64_t rsp1;
|
||||
uint64_t rsp2;
|
||||
uint64_t reserved1;
|
||||
uint64_t ist[7];
|
||||
uint64_t reserved2;
|
||||
uint16_t reserved3;
|
||||
uint16_t iopb;
|
||||
} __attribute__((packed));
|
||||
|
||||
void gdt_init(void);
|
||||
|
||||
#endif
|
||||
+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