From 6e2de52aa973045de64e80bbef7ed1915fc8988b Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 13 Mar 2016 12:51:42 -0400 Subject: [PATCH] Clean up descriptor generation code --- src/Descriptors.cc | 52 ++++++++++++++++++++++++++-------------------- src/Descriptors.hh | 6 +++--- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Descriptors.cc b/src/Descriptors.cc index 5f9416f..c987986 100644 --- a/src/Descriptors.cc +++ b/src/Descriptors.cc @@ -54,24 +54,30 @@ GDT::DescriptorSpec::descriptor() { Descriptor descriptor = 0; - const auto g = uint8_t(hasCoarseGranularity); - const auto db = uint8_t(has32BitOperations); - const auto l = uint8_t(hasNative64BitCode); - const auto avl = uint8_t(hasNative64BitCode); - const auto p = uint8_t(isPresent); - const auto dpl = uint8_t(privilegeLevel); - const auto s = uint8_t(isCodeDataSegment); - const auto typ = uint8_t(type); + const auto dpl = uint8_t(privilegeLevel) & 0x3; + const auto typ = uint8_t(type) & 0xF; descriptor = base & 0xFF000000; // Bits 31:24 of the base address. - descriptor |= (g << 23); // Granularity field - descriptor |= (db << 22); // D/B field - descriptor |= (l << 21); // L field - descriptor |= (avl << 20); // AVL field + if (hasCoarseGranularity) { + descriptor |= (1 << 23); // Granularity field + } + if (has32BitOperations) { + descriptor |= (1 << 22); // D/B field + } + if (hasNative64BitCode) { + descriptor |= (1 << 21); // L field + } + if (available) { + descriptor |= (1 << 20); // AVL field + } descriptor |= limit & 0x000F0000; // Bits 19:16 of the segment limit. - descriptor |= (p << 15); // P field + if (isPresent) { + descriptor |= (1 << 15); // P field + } descriptor |= (dpl << 13); // DPL field - descriptor |= (s << 12); // S field + if (isCodeDataSegment) { + descriptor |= (1 << 12); // S field + } descriptor |= (typ << 8); // Type field: see Type descriptor |= (base >> 16) & 0x000000FF; // Bits 23:16 of the base address. @@ -162,14 +168,16 @@ IDT::DescriptorSpec::descriptor() descriptor = offset & 0xFFFF0000; } - const auto p = uint8_t(isPresent); - const auto dpl = uint8_t(privilegeLevel); - const auto d = uint8_t((type == Type::Task) ? 0 : is32BitGate); - const auto typ = uint8_t(type); + const auto dpl = uint8_t(privilegeLevel) & 0x3; + const auto typ = uint8_t(type) & 0x7; - descriptor |= p << 15; + if (isPresent) { + descriptor |= 1 << 15; + } descriptor |= dpl << 13; - descriptor |= d << 11; + if (type != Type::Task && is32BitGate) { + descriptor |= 1 << 11; + } descriptor |= typ << 8; // Shift everything up by 32 to make room for the lower 4 bytes @@ -216,9 +224,7 @@ IDT::load() const { PseudoDescriptor idt{Size * sizeof(Descriptor) - 1, uint32_t(&mTable)}; - asm volatile( - "lidt %0\n" - : : "m" (idt) :); + asm volatile("lidt %0\n" : : "m" (idt)); } } /* namespace x86 */ diff --git a/src/Descriptors.hh b/src/Descriptors.hh index 1c8d0e9..4271a5e 100644 --- a/src/Descriptors.hh +++ b/src/Descriptors.hh @@ -24,7 +24,7 @@ typedef uint64_t Descriptor; /** Descriptor privilege level. */ -enum class DPL { +enum class DPL : uint8_t { Ring0 = 0x0, Ring1 = 0x1, Ring2 = 0x2, @@ -41,7 +41,7 @@ enum class DPL { struct GDT { /** A four bit value describing the type of the segment. */ - enum class Type { + enum class Type : uint8_t { // Data segment types DataRO = 0x0, // Read-only DataROA = 0x1, // Read-only, accessed @@ -116,7 +116,7 @@ private: */ struct IDT { - enum class Type { + enum class Type : uint8_t { Task = 0x5, Interrupt = 0x6, Trap = 0x7,