From e40da55691ad2c36b349ace7cd368394976a1d6d Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sat, 6 Mar 2021 16:01:29 +0200 Subject: GDT: flush segment registers on lgdt --- src/gdt.h | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src/gdt.h') diff --git a/src/gdt.h b/src/gdt.h index bb7181b..6aeaa33 100644 --- a/src/gdt.h +++ b/src/gdt.h @@ -27,11 +27,6 @@ class GDT { public: - GDT(); - ~GDT() = default; - - uint16_t codeDescriptor() const; - struct Pointer { uint16_t limit; uint32_t base; @@ -41,18 +36,24 @@ public: public: enum Ring : unsigned int { Ring0 = 0x0, Ring1 = 0x1, Ring2 = 0x2, Ring3 = 0x3 }; struct Access { - bool accessed : 1 = false; // if 0, is set by processor when accessed - bool r_w : 1 = false; // on code segment: read toggle - // on data segment: write toggle - bool direction_conforming : 1 = false; // TODO - bool exe : 1 = false; // true for code segment, false for data segment - bool segment : 1 = false; // segment bit: 1 for code/data segments - // 0 for gates and tss - Ring privilege : 2 = Ring0; // descriptor privilege level - bool present : 1 = true; // must be 1 for every active segment + bool accessed : 1 = false; // if 0, is set by processor when accessed + bool r_w : 1 = false; // on code segment: read toggle + // on data segment: write toggle + bool direction : 1 = false; // TODO + bool exe : 1 = false; // true for code segment, false for data segment + bool segment : 1 = false; // segment bit: 1 for code/data segments + // 0 for gates and tss + Ring privilege : 2 = Ring0; // descriptor privilege level + bool present : 1 = false; // must be 1 for every active segment + + constexpr operator uint8_t() const { + return static_cast(accessed) | static_cast(r_w << 1) | static_cast(direction << 2) | + static_cast(exe << 3) | static_cast(segment << 4) | + static_cast(privilege << 5) | static_cast(present << 7); + } } __attribute__((packed)); - SegmentDescriptor() { access.present = false; }; + constexpr SegmentDescriptor() { access.present = false; }; template static SegmentDescriptor make(uint32_t base, Access type) { @@ -94,11 +95,11 @@ public: unsigned int base_31_24 : 8 = 0; // high bits of segment address } __attribute__((packed)); + enum SegmentMap { null0, kcode, kdata }; + + GDT(); + ~GDT() = default; -private: - SegmentDescriptor segments[256]; + uint16_t descriptor(SegmentMap) const; }; -static_assert(sizeof(GDT::Pointer) == 6); -static_assert(sizeof(GDT::SegmentDescriptor) == 8); -static_assert(sizeof(GDT::SegmentDescriptor::Access) == 1); -- cgit v1.2.1