aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2025-02-27 10:13:35 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2025-02-27 10:13:35 +0000
commitd8a8efe3e8d90ec83069d1c934ff319626e87a2d (patch)
tree1117cde95361e6e9aeac080aa5a53d52592ab4c5 /arch
parent8d14c729c43ee555c240a043e3909617e4fa5043 (diff)
downloadteachos-d8a8efe3e8d90ec83069d1c934ff319626e87a2d.tar.xz
teachos-d8a8efe3e8d90ec83069d1c934ff319626e87a2d.zip
add descriptor_table access_byte
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp87
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/access_bytes.hpp0
-rw-r--r--arch/x86_64/src/boot/boot.s4
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp14
4 files changed, 103 insertions, 2 deletions
diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp
new file mode 100644
index 0000000..b3bce11
--- /dev/null
+++ b/arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp
@@ -0,0 +1,87 @@
+
+#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_POINTERS_HPP
+#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_POINTERS_HPP
+
+#include <bitset>
+#include <cstddef>
+#include <cstdint>
+
+namespace teachos::arch::context_switching::descriptor_table
+{
+ enum class privilege_level
+ {
+ KERNEL = 0,
+ ADMIN = 1,
+ PRIVILEGED_USER = 2,
+ USER = 3
+ };
+
+ /// @brief Defines the access byte of a Descriptor Table
+ struct access_byte
+ {
+ /**
+ * @brief Possible set bits in our underlying std::bitset and the meaning when they are set.
+ */
+ enum bitset : uint8_t
+ {
+ PRESENT = 1U << 0U, ///< Present bit; Allows an entry to refer to a valid segment.
+ ///< Must be set (1) for any valid segment.
+ PRIVILEGE_LEVEL = 1U << 1U | 1 << 2U, ///< Descriptor privilege level field.
+ ///< Contains the CPU Privilege level of the segment.
+ DESCRIPTOR_TYPE = 1U << 3U, ///< Defines a system segment (if 0) or a code/data segment (if 1).
+ EXECUTABLE = 1U << 4U, ///< Defines a data segment (if 0) or a code segment which can be executed from (if 1).
+ CONFORMING = 1U << 5U, ///< For data selectors: Direction bit
+ ///< Grows up (if 0), grows down (if 1)
+ ///< For code selectors: Conforming bit
+ ///< Code can only be executed from the DPL ring (if 0)
+ ///< Code can be executed from equal or lower DPL ring (if 1)
+ READ_WRITE = 1U << 6U, ///< For code segments: Readable bit
+ ///< For data segments: Writeable bit (read is always allowed)
+ ACCESSED = 1U << 7U ///< Set, when the segment is accessed. If GDT descriptor is stored in read only pages and
+ ///< this bit is set to 0, the CPU trying to set this bit will trigger a page fault.
+ };
+
+ /**
+ * @brief Constructor.
+ *
+ * @param flags Actual value read from the elf section header, which should be converted into a std::bitset, to
+ * allow reading the state of single bits more easily.
+ */
+ explicit access_byte(uint8_t flags)
+ : flags(flags)
+ {
+ // Nothing to do
+ }
+
+ /**
+ * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
+ *
+ * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng
+ * std::bitset. Any additional bits that are set are not relevant.
+ *
+ * @param other Flags that we want to compare against and check if the underlying std::bitset has the same bits set.
+ * @return Whether the given flags are a subset or equivalent with the underlying std::bitset.
+ */
+ auto contains_flags(std::bitset<8U> other) const -> bool;
+
+ /**
+ * @brief Returns the privilege level of the current access_byte
+ *
+ * @return privilege_level
+ */
+ auto get_privilege_level() const -> privilege_level;
+
+ /**
+ * @brief Allows to compare the underlying std::bitset of two instances.
+ *
+ * @param other Other instance that we want to compare with.
+ * @return Whether the underlying std::bitset of both types is the same.
+ */
+ auto operator==(access_byte const & other) const -> bool = default;
+
+ private:
+ std::bitset<8U> flags; ///< Underlying bitset used to read the flags from
+ };
+} // namespace teachos::arch::context_switching::descriptor_table
+
+#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_POINTERS_HPP \ No newline at end of file
diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/access_bytes.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/access_bytes.hpp
deleted file mode 100644
index e69de29..0000000
--- a/arch/x86_64/include/arch/context_switching/descriptor_table/access_bytes.hpp
+++ /dev/null
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 2197dce..dbea42a 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -197,10 +197,10 @@ _start:
call enable_paging
call enable_sse
- cli // Clears the interrupt flag during the GDT setup
+ cli /* Clears the interrupt flag during the GDT setup */
lgdt (global_descriptor_table_pointer)
jmp $global_descriptor_table_code,$_transition_to_long_mode
- // The interrupt flag is set in cpp after setting up the GDT
+ /* The interrupt flag is set in cpp after setting up the GDT */
call halt
diff --git a/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp
new file mode 100644
index 0000000..15a0947
--- /dev/null
+++ b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp
@@ -0,0 +1,14 @@
+#include "arch/context_switching/descriptor_table/access_byte.hpp"
+
+#include <bitset>
+
+namespace teachos::arch::context_switching::descriptor_table
+{
+ auto access_byte::contains_flags(std::bitset<8U> other) const -> bool { return (flags & other) == other; }
+
+ auto access_byte::get_privilege_level() const -> privilege_level
+ {
+ constexpr uint8_t PRIVILEGE_MASK = 0b0110'0000;
+ return static_cast<privilege_level>(flags.to_ulong() & PRIVILEGE_MASK);
+ }
+} // namespace teachos::arch::context_switching::descriptor_table