diff options
23 files changed, 291 insertions, 991 deletions
diff --git a/arch/x86_64/include/arch/cpu/global_descriptor_table.hpp b/arch/x86_64/include/arch/cpu/global_descriptor_table.hpp new file mode 100644 index 0000000..402c87d --- /dev/null +++ b/arch/x86_64/include/arch/cpu/global_descriptor_table.hpp @@ -0,0 +1,91 @@ +#ifndef TEACHOS_X86_64_GLOBAL_DESCRIPTOR_TABLE_HPP +#define TEACHOS_X86_64_GLOBAL_DESCRIPTOR_TABLE_HPP + +#include "kapi/memory.hpp" + +#include "arch/cpu/segment_descriptor.hpp" + +#include <algorithm> +#include <array> +#include <bit> +#include <concepts> +#include <cstddef> +#include <cstdint> +#include <utility> + +namespace arch::cpu +{ + + template<std::size_t Size> + struct global_descriptor_table; + + struct [[gnu::packed]] global_descriptor_table_pointer + { + template<std::size_t GdtSize> + global_descriptor_table_pointer(global_descriptor_table<GdtSize> const & gdt) + : size{GdtSize * sizeof(segment_descriptor) - 1} + , address{kapi::memory::physical_address{std::bit_cast<std::uintptr_t>(&gdt)}.raw()} + {} + + auto load() -> void + { + asm volatile("lgdt %0" : : "m"(*this)); + } + + std::uint16_t size{}; + std::uint64_t address{}; + }; + + static_assert(sizeof(global_descriptor_table_pointer) == sizeof(std::uint16_t) + sizeof(std::uint64_t)); + + template<std::size_t SizeInBytes> + struct global_descriptor_table + { + template<std::derived_from<segment_descriptor>... SegmentDescriptors> + constexpr global_descriptor_table(SegmentDescriptors const &... descriptors) + : m_descriptors{} + { + auto descriptor_data = std::array{ + std::pair{std::bit_cast<std::byte const *>(&descriptors), sizeof(descriptors)} + ... + }; + auto written_size = 0uz; + std::ranges::for_each(descriptor_data, [&written_size, this](auto entry) { + std::ranges::copy(entry.first, entry.first + entry.second, m_descriptors.begin() + written_size); + written_size += entry.second; + }); + } + + auto load(std::size_t code_segment_index, std::size_t data_segment_index) const -> void + { + auto pointer = global_descriptor_table_pointer{*this}; + pointer.load(); + + asm volatile("push %0\n" + "lea 1f(%%rip), %%rax\n" + "push %%rax\n" + "lretq\n" + "1:\n" + "mov %1, %%rax\n" + "mov %%rax, %%ss\n" + "mov %%rax, %%ds\n" + "mov %%rax, %%es\n" + "mov %%rax, %%fs\n" + "mov %%rax, %%gs\n" + : + : "X"(code_segment_index * sizeof(segment_descriptor)), + "X"(data_segment_index * sizeof(segment_descriptor)) + : "rax"); + } + + private: + std::array<std::byte, SizeInBytes> m_descriptors; + }; + + template<std::derived_from<segment_descriptor>... SegmentDescriptors> + global_descriptor_table(SegmentDescriptors const &... descriptors) + -> global_descriptor_table<(sizeof(SegmentDescriptors) + ...)>; + +} // namespace arch::cpu + +#endif
\ No newline at end of file diff --git a/arch/x86_64/include/arch/cpu/segment_descriptor.hpp b/arch/x86_64/include/arch/cpu/segment_descriptor.hpp new file mode 100644 index 0000000..9570670 --- /dev/null +++ b/arch/x86_64/include/arch/cpu/segment_descriptor.hpp @@ -0,0 +1,61 @@ +#ifndef TEACHOS_X86_64_SEGMENT_DESCRIPTOR_HPP +#define TEACHOS_X86_64_SEGMENT_DESCRIPTOR_HPP + +#include <cstdint> + +namespace arch::cpu +{ + + //! The type of segment described by a segment_descriptor. + enum struct segment_type : std::uint8_t + { + //! A system (TSS or LDT) segment + system = 0, + //! A code or data segment + code_or_data = 1, + }; + + //! The granularity of a segment described by a segment_descriptor + enum struct segment_granularity : std::uint8_t + { + //! The limit of the segment is defined in bytes. + byte = 0, + //! The limit of the segment is defined in pages (4KiB) + page = 1, + }; + + //! An entry in a segment descriptor table + struct segment_descriptor + { + std::uint64_t limit_low : 16; + std::uint64_t base_low : 24; + bool accessed : 1; + bool read_write : 1; + bool direction_or_conforming : 1; + bool executable : 1; + segment_type type : 1; + std::uint64_t privilege_level : 2; + bool present : 1; + std::uint64_t limit_high : 4; + std::uint64_t : 1; + bool long_mode : 1; + bool protected_mode : 1; + segment_granularity granularity : 1; + std::uint64_t base_high : 8; + }; + + static_assert(sizeof(segment_descriptor) == sizeof(std::uint64_t)); + static_assert(alignof(segment_descriptor) == alignof(std::uint64_t)); + + struct system_segment_descriptor : segment_descriptor + { + std::uint64_t base_extended : 32; + std::uint64_t : 32; + }; + + static_assert(sizeof(system_segment_descriptor) == 2 * sizeof(std::uint64_t)); + static_assert(alignof(system_segment_descriptor) == alignof(segment_descriptor)); + +} // namespace arch::cpu + +#endif
\ No newline at end of file diff --git a/arch/x86_64/include/arch/cpu/task_state_segment.hpp b/arch/x86_64/include/arch/cpu/task_state_segment.hpp new file mode 100644 index 0000000..57729dd --- /dev/null +++ b/arch/x86_64/include/arch/cpu/task_state_segment.hpp @@ -0,0 +1,30 @@ +#ifndef TEACHOS_X86_64_TASK_STATE_SEGMENT_HPP +#define TEACHOS_X86_64_TASK_STATE_SEGMENT_HPP + +#include <cstdint> + +namespace arch::cpu +{ + + struct [[gnu::packed]] task_state_segment + { + uint32_t : 32; + uint64_t rsp0 = {}; + uint64_t rsp1 = {}; + uint64_t rsp2 = {}; + uint64_t : 64; + uint64_t ist1 = {}; + uint64_t ist2 = {}; + uint64_t ist3 = {}; + uint64_t ist4 = {}; + uint64_t ist5 = {}; + uint64_t ist6 = {}; + uint64_t ist7 = {}; + uint64_t : 64; + uint16_t : 16; + uint16_t io_map_base_address = {}; + }; + +} // namespace arch::cpu + +#endif
\ No newline at end of file diff --git a/arch/x86_64/kapi/system.cpp b/arch/x86_64/kapi/system.cpp index 5bcae4d..ca4418e 100644 --- a/arch/x86_64/kapi/system.cpp +++ b/arch/x86_64/kapi/system.cpp @@ -1,14 +1,122 @@ #include "kapi/system.hpp" +#include "arch/cpu/global_descriptor_table.hpp" +#include "arch/cpu/segment_descriptor.hpp" +#include "arch/cpu/task_state_segment.hpp" + #include <kstd/print> +#include <bit> +#include <cstdint> + namespace kapi::system { + namespace + { + constexpr auto gdt_null_descriptor = arch::cpu::segment_descriptor{}; + + constexpr auto gdt_kernel_code_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_kernel_data_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = true, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_code_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_data_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + } // namespace + auto memory_initialized() -> void { + auto static tss = arch::cpu::task_state_segment{}; + auto static tss_descriptor = arch::cpu::system_segment_descriptor{ + { + .limit_low = (sizeof(tss) - 1) & 0xffff, // NOLINT(readability-magic-numbers) + .base_low = std::bit_cast<std::uintptr_t>(&tss) & 0xffffff, // NOLINT(readability-magic-numbers) + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::system, + .privilege_level = 0, + .present = true, + .limit_high = ((sizeof(tss) - 1) >> 16) & 0xf, // NOLINT(readability-magic-numbers) + .long_mode = false, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::byte, + .base_high = (std::bit_cast<std::uintptr_t>(&tss) >> 24) & 0xff, // NOLINT(readability-magic-numbers) + }, + (std::bit_cast<std::uintptr_t>(&tss) >> 32) & 0xffff'ffff, // NOLINT(readability-magic-numbers) + }; + + auto static gdt = arch::cpu::global_descriptor_table{ + gdt_null_descriptor, gdt_kernel_code_descriptor, gdt_kernel_data_descriptor, + gdt_user_code_descriptor, gdt_user_data_descriptor, tss_descriptor, + }; + + kstd::println("[x86_64:SYS] Reloading Global Descriptor Table."); + gdt.load(1, 2); + kstd::println("[x86_64:SYS] TODO: initialize Interrupt Descriptor Table."); - kstd::println("[x86_64:SYS] TODO: reload Global Descriptor Table."); } } // namespace kapi::system
\ No newline at end of file diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/access_byte.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/access_byte.hpp deleted file mode 100644 index 7450330..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/access_byte.hpp +++ /dev/null @@ -1,104 +0,0 @@ - -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_ACCESS_BYTE_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_ACCESS_BYTE_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - /** - * @brief Defines helper function for all states that the access byte field of a segment descriptor can - * have. - */ - struct [[gnu::packed]] access_byte - { - /** - * @brief Possible set bits in our underlying bits and the meaning when they are set. - */ - enum bitset : uint8_t - { - ACCESSED = - 1U - << 0U, ///< Whether the segment has been accessed since the last time the operating system has cleared the - ///< flag. If enabled it has been accessed, otherwise it has not been accessed since the last clear. - WRITABLE = 1U << 1U, ///< Indicates if the data segment is writable or not. If enabled the code segment allows - ///< read and write access, otherwise only read access is possible. - READABLE = 1U << 1U, ///< Indicates if the code segment is readable or not. If enabled the code segment allows - ///< read and execute access, otherwise only executable access is possible. - CONFORMING = - 1U << 2U, ///< Indicates if the code is allowed to be executed by different access levels - ///< (higher or lower) in code segments. If enabled the code segment allows access, otherwise - ///< access from different privilege levels with throw a General-Protectione exception. - EXPAND_DOWN = 1U << 2U, ///< Indicates if the expansion direction is up or down in data segments. If enabled the - ///< data segment expands downwards, otherwise it expands upwards. - CODE_SEGMENT = 1U << 3U, ///< Further defines the actual type of the segment. If enabled this segment is a code - ///< segment, otherwise its a data segment. - LOCAL_DESCRIPTOR_TABLE = 2, ///< The actual type of sytem segment is a local descriptor table. - TASK_STATE_SEGMENT_AVAILABLE = - 9, ///< The actual type of sytem segment is a task state segment that is still available. - TASK_STATE_SEGMENT_BUSY = 11, ///< The actual type of sytem segment is a task state segment that is currently in - ///< use and therefore busy. - CALL_GATE = 11, ///< The actual type of sytem segment is a call gate. - INTERRUPT_GATE = 14, ///< The actual type of sytem segment is a interrupt gate. - TRAP_GATE = 15, ///< The actual type of sytem segment is a trap gate. - CODE_OR_DATA_SEGMENT = 1U << 4U, ///< Defines a system segment (if 0) or a code/data segment (if 1). - DESCRIPTOR_LEVEL_KERNEL = - 0U << 5U, ///< Highest privileged level used by the kernel to allow for full access of resources. - DESCRIPTOR_LEVEL_ADMIN = - 1U << 5U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - DESCRIPTOR_LEVEL_PRIVILEGED_USER = - 2U << 5U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - DESCRIPTOR_LEVEL_USER = 3U << 5U, ///< Restricts access to only application and their specific memory. - PRESENT = 1U << 7U, ///< Present bit; Allows an entry to refer to a valid segment. - ///< Must be set (1) for any valid segment. - }; - - /** - * @brief Default Constructor. - */ - access_byte() = default; - - /** - * @brief Constructor. - * - * @param flags Allows to set flags for the access byte field using the unscoped enum contained in this class, used - * to allow for direct integer conversion. This value is saved and can later be used to check whether certain flags - * are enabled or not using contains_flags method. - */ - access_byte(uint8_t flags); - - /** - * @brief Checks if the given std::bitset is a subset or equivalent to the underlying data. - * - * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng - * data. Any additional bits that are set are not relevant. - * - * @param other Flags that we want to compare against and check if the underlying data has the same bits set. - * @return Whether the given flags are a subset or equivalent with the underlying data. - */ - auto contains_flags(std::bitset<8U> other) const -> bool; - - /** - * @brief Allows to compare the underlying data of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying data of both types is the same. - */ - auto operator==(access_byte const & other) const -> bool = default; - - /** - * @brief Combines all bits that are set in the std::bitset flags with the bits already set in the underlying data. - * - * @param other Additional bits that should be set. - */ - auto operator|=(std::bitset<8U> other) -> void; - - private: - uint8_t _flags = {}; ///< Underlying bits used to read the flags from. - }; -} // namespace teachos::arch::context_switching::segment_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_ACCESS_BYTE_HPP
\ No newline at end of file diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp deleted file mode 100644 index e24b988..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GDT_FLAGS_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GDT_FLAGS_HPP - -#include "arch/context_switching/segment_descriptor_table/segment_descriptor_type.hpp" - -#include <bitset> - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - /** - * @brief Defines helper function for all states that the flags field of a segment descriptor can - * have. - */ - struct [[gnu::packed]] gdt_flags - { - /** - * @brief Possible set bits in our underlying bits and the meaning when they are set. - */ - enum bitset : uint8_t - { - LONG_MODE = 1U << 1U, ///< Defines in IA-32e mode (64-bit code and 32-bit compatability mode) if the segment - ///< contains 64-bit code. Otherwise this bit should always be 0. Enable if instructions - ///< are executed in 64-bit code, otherwise they are executed in compatability 32-bit mode. - ///< If this bit is set the 3rd bit needs to be clear (0). - UPPER_BOUND = 1U << 2U, ///< Specifies the upper bound of the segment for expand down data segment. Enable for 4 - ///< GiB, 4 KiB otherwise. - STACK_POINTER_SIZE = 1U << 2U, ///< Specifies the size of the Stack Pointer (SP) for stack segments used for - ///< implicit stack operations. Enable for 32 bit, 16 bit otherwise. - DEFAULT_LENGTH = 1U << 2U, ///< Indicates the default length for code segments with effective addresses and - ///< operands. Enable for 32 bit, 16 bit otherwise. - GRANULARITY = 1U << 3U, ///< Indicates the size the Limit value in the segment descriptor is scaled by 1 Byte - ///< blocks if the bit is not set or by 4 KiB blocks if the bit is set. - }; - - /** - * @brief Default Constructor. - */ - gdt_flags() = default; - - /** - * @brief Constructor. - * - * @param flags Allows to set flags for the flags field using the unscoped enum contained in this class, used to - * allow for direct integer conversion. This value is saved and can later be used to check whether certain flags are - * enabled or not using contains_flags method. - * @param limit Does not necessarily make sense in the gdt flags type, but because the flags alone are only 4 bit - * the type would still require the space for a complete bit. Therefore the 4 bit segment limit field before the - * flags field is included in this type to ensure we actually contain 8 bit of data. - */ - gdt_flags(uint8_t flags, std::bitset<20U> limit); - - /** - * @brief Checks if the given std::bitset is a subset or equivalent to the underlying data. - * - * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng - * data. Any additional bits that are set are not relevant. - * - * @param other Flags that we want to compare against and check if the underlying data has the same bits set. - * @return Whether the given flags are a subset or equivalent with the underlying data. - */ - auto contains_flags(std::bitset<4U> other) const -> bool; - - /** - * @brief Get part of the segment limit that is saved in the gdt flags. This does not necessarily make sense in this - * object, but it has to be included here because a struct can not be smaller than a full byte. Therefore we include - * the 4 bit segment limit field so that it results in a compelte byte with the addtional 4 bit of gdt flags. - * - * @return 4-bit limit segment - */ - auto get_limit() const -> std::bitset<4U>; - - /** - * @brief Allows to compare the underlying set bits of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying set bits of both types are the same. - */ - auto operator==(gdt_flags const & other) const -> bool = default; - - /** - * @brief Combines all bits that are set in the std::bitset flags with the bits already set in the underlying data. - * - * @param other Additional bits that should be set. - */ - auto operator|=(std::bitset<4U> other) -> void; - - private: - uint8_t _limit_2 : 4 = {}; ///< Second part of the limit field. - uint8_t _flags : 4 = {}; ///< Underlying bits used to read the flags from. - }; -} // namespace teachos::arch::context_switching::segment_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GDT_FLAGS_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp deleted file mode 100644 index 44f2692..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP - -#include "arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp" -#include "arch/context_switching/segment_descriptor_table/task_state_segment.hpp" - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - /** - * @brief Creates the global descriptor table, with the minimum required configuration. If this method is called more - * than once, the previously created instance is returned instead. - * - * @return Reference to the created global_descriptor_table. - */ - auto get_or_create_gdt() -> global_descriptor_table &; - - /** - * @brief Updates the GDTR with the created global descriptor table. If it has not been created yet this - * method will create it. - * - * @note This method will only set the GDTR, but for the processor to actually register the change a far jump - * has to be executed. This also has to be done before updating the TR. - */ - auto update_gdtr() -> void; - - /** - * @brief Updates the TR with the created task state segment. If it has not been created yet this - * method will create it. - * - * @note This method should only be called after update_gdtr() and a far jump has been - * executed. Because before that trying to access the segment will cause an exception. - */ - auto update_tss_register() -> void; - -} // namespace teachos::arch::context_switching::segment_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp deleted file mode 100644 index 292ff70..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP - -#include "arch/stl/vector.hpp" - -#include <cstdint> - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - using global_descriptor_table = stl::vector<uint64_t>; - - /** - * @brief Represents a pointer to the Global Descriptor Table (GDT). - * - * This structure is used to store the base address and length of the GDT. - * It is used when loading or modifying the GDT during context switching. - */ - struct [[gnu::packed]] global_descriptor_table_pointer - { - /** - * @brief Default constructor. - */ - global_descriptor_table_pointer() = default; - - /** - * @brief Constructor. - */ - global_descriptor_table_pointer(uint16_t table_length, uint64_t * address); - - /** - * @brief Defaulted three-way comparsion operator. - */ - auto operator<=>(global_descriptor_table_pointer const & other) const -> std::strong_ordering = default; - - private: - uint16_t table_length = {}; ///< The amount of segment descriptor entries in the global descriptor table - 1. - uint64_t * address = {}; ///< Non-owning pointer to the GDT base address. - }; -} // namespace teachos::arch::context_switching::segment_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp deleted file mode 100644 index 933fb4d..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP - -#include "arch/context_switching/segment_descriptor_table/access_byte.hpp" -#include "arch/context_switching/segment_descriptor_table/gdt_flags.hpp" -#include "arch/context_switching/segment_descriptor_table/segment_descriptor_type.hpp" - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - /** - * @brief Defines helper function for all states and the actual data the segment descriptor can have. - */ - struct [[gnu::packed]] segment_descriptor_base - { - /** - * @brief Default Constructor. - */ - segment_descriptor_base() = default; - - /** - * @brief Constructor. - * - * @note Created segment descriptor copies the given bytes into these components requiring the space of one - * segment descriptor entry in the global descriptor table being 64-bit. - * - 8 bit Access Type - * - 4 bit Flags - * - 32 bit Base Address - * - 20 bit Limit - * - * @param flags Copies the bits set from the given data into the individual components of a segment - * descriptor. - */ - explicit segment_descriptor_base(uint64_t flags); - - /** - * @brief Constructor. - * - * @param access_byte, flags, base, limit Copies the bits set from the given data into the individual components of - * a segment descriptor. - */ - segment_descriptor_base(access_byte access_byte, gdt_flags flags, uint32_t base, std::bitset<20U> limit); - - /** - * @brief Calculates the underlying segment type that this segement descriptor is describing. - */ - auto get_segment_type() const -> segment_descriptor_type; - - /** - * @brief Cast the underlying data into a combined 64-bit form, that contains all data. - * - * @return Underlying value combined into it's full size. - */ - operator uint64_t() const; - - /** - * @brief Allows to compare the underlying bits of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying set bits of both types are the same. - */ - auto operator==(segment_descriptor_base const & other) const -> bool = default; - - private: - // The order in private variables starts for the first variable being the rightmost bit. - uint16_t _limit_1 = {}; ///< First part of the limit field (0 - 15) - uint32_t _base_1 : 24 = {}; ///< First part of the base field (16 - 39) - access_byte _access = {}; ///< Access byte field (40 - 47) - gdt_flags _flag = {}; ///< Second part of the limit field + Flags field (48 - 55) - uint8_t _base_2 = {}; ///< Second part of the base field (56 - 63) - }; -} // namespace teachos::arch::context_switching::segment_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_BASE_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp b/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp deleted file mode 100644 index 40bcc8a..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_EXTENSION_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SEGMENT_DESCRIPTOR_TABLE_SEGMENT_DESCRIPTOR_EXTENSION_HPP - -#include "arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp" - -namespace teachos::arch::context_switching::segment_descriptor_table -{ - __extension__ typedef __int128 int128_t; - __extension__ typedef unsigned __int128 uint128_t; - - /** - * @brief Defines helper function for all states and the actual data the segment descriptor can have. - */ - struct [[gnu::packed]] segment_descriptor_extension - { - /** - * @brief Default Constructor. - */ - segment_descriptor_extension() = default; - - /** - * @brief Constructor. - * |
