diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-02-27 10:13:35 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-02-27 10:13:35 +0000 |
| commit | d8a8efe3e8d90ec83069d1c934ff319626e87a2d (patch) | |
| tree | 1117cde95361e6e9aeac080aa5a53d52592ab4c5 /arch | |
| parent | 8d14c729c43ee555c240a043e3909617e4fa5043 (diff) | |
| download | teachos-d8a8efe3e8d90ec83069d1c934ff319626e87a2d.tar.xz teachos-d8a8efe3e8d90ec83069d1c934ff319626e87a2d.zip | |
add descriptor_table access_byte
Diffstat (limited to 'arch')
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 |
