diff --git a/kernel/arch/gdt.cc b/kernel/arch/gdt.cc index 4884226..1afc815 100644 --- a/kernel/arch/gdt.cc +++ b/kernel/arch/gdt.cc @@ -1,6 +1,7 @@ #include "gdt.h" #include "core.h" +#include "tss.h" namespace GDT { @@ -30,6 +31,11 @@ alignas(16) constinit SegmentDescriptor long_mode[] = { // Global data segment SegmentDescriptor::Segment64(false, 0), + SegmentDescriptor::Segment64(true , 3), + SegmentDescriptor::Segment64(false, 3), + + //SegmentDescriptor::TSSLow(), + //SegmentDescriptor::TSSHigh(), }; extern "C" constexpr Pointer gdt_long_mode_pointer(long_mode); diff --git a/kernel/arch/gdt.h b/kernel/arch/gdt.h index 35aabe3..db7c38b 100644 --- a/kernel/arch/gdt.h +++ b/kernel/arch/gdt.h @@ -5,6 +5,7 @@ #pragma once #include "../types.h" +#include "./tss.h" /*! \brief Abstracts the GDT that, primarily, contains descriptors to memory * segments. @@ -142,6 +143,28 @@ union SegmentDescriptor { return SegmentDescriptor::Segment(0, 0, code, ring, Size::Bit64); } + static SegmentDescriptor TSSLow (const TSS::Entry &tss){ + return SegmentDescriptor{ + .limit_low = sizeof(tss) & 0xFFFF, + .base_low=(uint64_t)(&tss) & 0xFFFFFF, + .type=0b1001, // dont set busy flag, is this even needed? + .descriptor_type = DescriptorType::System, // TSS descriptor needs this set to 0 + .privilege_level = 0, // ring 0 + .present = true, + .limit_high = 0, // should not be greater than 2^16 - 1 anyways + .available = false, + .custom=0, + .granularity = Granularity::Bytes, + .base_high = ((uint64_t)(&tss) >> 24)&0xFF, + }; + } + + static SegmentDescriptor TSSHigh (const TSS::Entry &tss){ + return SegmentDescriptor{ + .value = ((uint64_t)(&tss) >> 32) & 0xFFFFFFFF, + };; + } + } __attribute__((packed)); static_assert(sizeof(SegmentDescriptor) == 8,