From 4843406bf3537de4a43d7a154d44cd847970a7fe Mon Sep 17 00:00:00 2001 From: DualFroz Date: Mon, 24 Aug 2026 16:24:42 +0200 Subject: [PATCH] feat(cpu): add GDT and TSS for ring 0 and ring 3 segments --- include/gdt.h | 15 ++++++++++++++ include/tss.h | 9 +++++++++ src/gdt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/tss.c | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 include/gdt.h create mode 100644 include/tss.h create mode 100644 src/gdt.c create mode 100644 src/tss.c diff --git a/include/gdt.h b/include/gdt.h new file mode 100644 index 0000000..0a87bcd --- /dev/null +++ b/include/gdt.h @@ -0,0 +1,15 @@ +#ifndef FROSTBYTE_GDT_H +#define FROSTBYTE_GDT_H + +#include "types.h" + +#define kernelCodeSelector 0x08 +#define kernelDataSelector 0x10 +#define userCodeSelector 0x18 +#define userDataSelector 0x20 +#define tssSelector 0x28 + +void gdtInit(void); +void gdtInstallTss(uint64 base, uint32 limit); + +#endif diff --git a/include/tss.h b/include/tss.h new file mode 100644 index 0000000..a668a50 --- /dev/null +++ b/include/tss.h @@ -0,0 +1,9 @@ +#ifndef FROSTBYTE_TSS_H +#define FROSTBYTE_TSS_H + +#include "types.h" + +void tssInit(uint64 rsp0); +void tssSetRsp0(uint64 rsp0); + +#endif diff --git a/src/gdt.c b/src/gdt.c new file mode 100644 index 0000000..642bf2d --- /dev/null +++ b/src/gdt.c @@ -0,0 +1,55 @@ +#include "gdt.h" +#include "types.h" + +typedef struct GdtPointer { + uint16 limit; + uint64 base; +} __attribute__((packed)) GdtPointer; + +static uint64 gdtEntries[7]; +static GdtPointer gdtPointer; + +void gdtInit(void) +{ + gdtEntries[0] = 0x0000000000000000ull; + gdtEntries[1] = 0x00AF9A000000FFFFull; + gdtEntries[2] = 0x00CF92000000FFFFull; + gdtEntries[3] = 0x00AFFA000000FFFFull; + gdtEntries[4] = 0x00CFF2000000FFFFull; + gdtEntries[5] = 0x0000000000000000ull; + gdtEntries[6] = 0x0000000000000000ull; + + gdtPointer.limit = (uint16)(sizeof(gdtEntries) - 1); + gdtPointer.base = (uint64)&gdtEntries; + + __asm__ volatile( + "lgdt %0\n" + "pushq $0x08\n" + "leaq 1f(%%rip), %%rax\n" + "pushq %%rax\n" + "lretq\n" + "1:\n" + "movw $0x10, %%ax\n" + "movw %%ax, %%ds\n" + "movw %%ax, %%es\n" + "movw %%ax, %%ss\n" + "movw %%ax, %%fs\n" + "movw %%ax, %%gs\n" + : + : "m"(gdtPointer) + : "rax", "memory"); +} + +void gdtInstallTss(uint64 base, uint32 limit) +{ + uint64 low = 0; + low |= (uint64)(limit & 0xFFFF); + low |= (base & 0xFFFFull) << 16; + low |= ((base >> 16) & 0xFFull) << 32; + low |= (uint64)0x89 << 40; + low |= (uint64)((limit >> 16) & 0xF) << 48; + low |= ((base >> 24) & 0xFFull) << 56; + + gdtEntries[5] = low; + gdtEntries[6] = (base >> 32) & 0xFFFFFFFFull; +} diff --git a/src/tss.c b/src/tss.c new file mode 100644 index 0000000..10952f9 --- /dev/null +++ b/src/tss.c @@ -0,0 +1,38 @@ +#include "tss.h" +#include "gdt.h" +#include "string.h" + +typedef struct Tss { + uint32 reserved0; + uint64 rsp0; + uint64 rsp1; + uint64 rsp2; + uint64 reserved1; + uint64 ist1; + uint64 ist2; + uint64 ist3; + uint64 ist4; + uint64 ist5; + uint64 ist6; + uint64 ist7; + uint64 reserved2; + uint16 reserved3; + uint16 iomapBase; +} __attribute__((packed)) Tss; + +static Tss tss; + +void tssInit(uint64 rsp0) +{ + memset(&tss, 0, sizeof(tss)); + tss.rsp0 = rsp0; + tss.iomapBase = sizeof(Tss); + + gdtInstallTss((uint64)&tss, sizeof(Tss) - 1); + __asm__ volatile("ltr %w0" : : "r"((uint16)tssSelector)); +} + +void tssSetRsp0(uint64 rsp0) +{ + tss.rsp0 = rsp0; +}