#pragma once #include "memory/pointer.h" #include "util/optional.h" struct [[gnu::packed]] gdt_register_t { uint16_t limit; uint64_t base; }; static_assert(sizeof(gdt_register_t) == 10); struct Gdt { using selector_t = uint16_t; enum class segment_type_t : uint8_t { code, data, task_state, }; struct flags_t { segment_type_t type; uint8_t privilege_level; bool long_mode; bool default_operand_32bit; bool granularity_4KiB; bool readable_writeable; }; struct segment_t { flags_t flags; uint64_t base; uint32_t limit; }; static Gdt fromCurrent(); static optional allocNew(); void activate(); optional add(segment_t segment); optional get(selector_t selector); paddr_t base; uint16_t limit; }; struct [[gnu::packed]] tss_t { uint32_t reserved0; uint64_t rsp[3]; uint64_t reserved1; uint64_t ist[7]; uint64_t reserved2; uint16_t reserved3; uint16_t iomap_base; }; static_assert(sizeof(tss_t) == 104); void reloadSegments(Gdt::selector_t code_selector, Gdt::selector_t data_selector);