diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2024-09-27 06:02:49 -0400 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2024-09-27 06:02:49 -0400 |
commit | d43d7caf15a01dd9c2ef1d9e975df3ef7c4e9204 (patch) | |
tree | aaf1f0f3a18b6f7b3fc25022e06941a9fb4fa612 /gdt.cpp |
wip: initial commit
Diffstat (limited to 'gdt.cpp')
-rw-r--r-- | gdt.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
@@ -0,0 +1,81 @@ +#include <array> +#include <cstdint> + +struct gdt_entry_bits { + std::uint32_t limit_low : 16; + std::uint32_t base_low : 24; + std::uint32_t accessed : 1; + std::uint32_t read_write : 1; // readable for code, writable for data + std::uint32_t conforming_expand_down : 1; // conforming for code, expand down for data + std::uint32_t code : 1; // 1 for code, 0 for data + std::uint32_t code_data_segment : 1; // should be 1 for everything but TSS and LDT + std::uint32_t DPL : 2; // privilege level + std::uint32_t present : 1; + std::uint32_t limit_high : 4; + std::uint32_t available : 1; // only used in software; has no effect on hardware + std::uint32_t long_mode : 1; + std::uint32_t big : 1; // 32-bit opcodes for code, uint32_t stack for data + std::uint32_t gran : 1; // 1 to use 4k page addressing, 0 for byte addressing + std::uint32_t base_high : 8; +} __attribute__((packed)); + +constinit static const std::array<gdt_entry_bits, 3> gdt {{ + {}, + /* kernel_code = */ { + .limit_low = 0xFFFF, + .base_low = 0x0000, + .accessed = 0, + .read_write = 1, + .conforming_expand_down = 0, + .code = 1, + .code_data_segment = 1, + .DPL = 0, + .present = 1, + .limit_high = 0xF, + .available = 0, + .long_mode = 0, + .big = 1, + .gran = 1, + .base_high = 0x00 + }, + /* kernel_data = */ { + .limit_low = 0xFFFF, + .base_low = 0x0000, + .accessed = 0, + .read_write = 1, + .conforming_expand_down = 0, + .code = 0, + .code_data_segment = 1, + .DPL = 0, + .present = 1, + .limit_high = 0xF, + .available = 0, + .long_mode = 0, + .big = 1, + .gran = 1, + .base_high = 0x00 + } +}}; + +void gdt_initialize() +{ + auto gdtr = reinterpret_cast<std::uint64_t>(gdt.data()); + gdtr <<= 16; + gdtr |= gdt.size() * sizeof(gdt[0]); + + asm volatile(R"( + lgdt %0 + pushl $0x8 + push $.setcs + ljmp *(%%esp) + .setcs: + add $8, %%esp + mov $0x10, %%eax + mov %%eax, %%ds + mov %%eax, %%es + mov %%eax, %%fs + mov %%eax, %%gs + mov %%eax, %%ss + )" :: "m"(gdtr)); +} + |