aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/access_byte.hpp4
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp7
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp5
-rw-r--r--arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp8
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp18
-rw-r--r--arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp21
6 files changed, 30 insertions, 33 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
index c510170..d1b579d 100644
--- 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
@@ -28,8 +28,8 @@ namespace teachos::arch::context_switching::descriptor_table
ACCESS_LEVEL_PRIVILEGED_USER =
4, ///< 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.
- ACCESS_LEVEL_USER = 6, ///< Restricts access to only application and their specific memory.
- DESCRIPTOR_TYPE = 1U << 3U, ///< Defines a system segment (if 0) or a code/data segment (if 1).
+ ACCESS_LEVEL_USER = 6, ///< Restricts access to only application and their specific memory.
+ CODE_OR_DATA_SEGMENT = 1U << 3U, ///< Defines a system segment (if 0) or a code/data segment (if 1).
};
/**
diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp
index ef8f2fa..bc6ecb7 100644
--- a/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp
+++ b/arch/x86_64/include/arch/context_switching/descriptor_table/gdt_flags.hpp
@@ -38,13 +38,8 @@ namespace teachos::arch::context_switching::descriptor_table
* @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. Only the rightmost 3 bit of the value will actually be
* converted into the std::bitset, because the leftmost 4 bit are irrelevant and the 4th bit is reserved.
- *
- * @param type Depending on the segment descriptor type some of the passed bits are ignored. For system segment only
- * the first bit Granularity is relevant, for the data segment the 3rd bit Length is irrelevant and for the code
- * segment all bits are relevant. Bits that are not relevant will simply not be read and saved into the underlying
- * flags std::bitset.
*/
- gdt_flags(uint8_t flags, segment_descriptor_type type);
+ gdt_flags(uint8_t flags);
/**
* @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp
index 59f99f6..364e546 100644
--- a/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp
+++ b/arch/x86_64/include/arch/context_switching/descriptor_table/segment_descriptor.hpp
@@ -32,6 +32,11 @@ namespace teachos::arch::context_switching::descriptor_table
*/
explicit segment_descriptor(uint128_t flags);
+ /**
+ * @brief Calculates the underlying segment type that this segement descriptor is describing.
+ */
+ auto get_segment_type() const -> segment_descriptor_type;
+
private:
uint32_t _reserved;
access_byte _access;
diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp
index 88e25cf..da61d38 100644
--- a/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp
+++ b/arch/x86_64/include/arch/context_switching/descriptor_table/type_field.hpp
@@ -18,10 +18,10 @@ namespace teachos::arch::context_switching::descriptor_table
*/
enum bitset : uint8_t
{
- TYPE = 1U << 0U, ///< Further defines the actual type of the segment. If enabled this segment is a code segment,
- ///< otherwise its a data segment.
- EXPAND_UP = 1U << 1U, ///< 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 << 0U, ///< Further defines the actual type of the segment. If enabled this segment is a code
+ ///< segment, otherwise its a data segment.
+ EXPAND_UP = 1U << 1U, ///< Indicates if the expansion direction is up or down in data segments. If enabled the
+ ///< data segment expands downwards, otherwise it expands upwards.
CONFORMING =
1U << 1U, ///< 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
diff --git a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp
index 8e1e939..8fbf869 100644
--- a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp
+++ b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp
@@ -4,24 +4,10 @@
namespace teachos::arch::context_switching::descriptor_table
{
- gdt_flags::gdt_flags(uint8_t flags, segment_descriptor_type type)
+ gdt_flags::gdt_flags(uint8_t flags)
: _flags(flags << 5U)
{
- switch (type)
- {
- case segment_descriptor_type::SYSTEM_SEGMENT:
- _flags.set(2, false);
- _flags.set(3, false);
- break;
- case segment_descriptor_type::DATA_SEGMENT:
- _flags.set(3, false);
- break;
- case segment_descriptor_type::CODE_SEGMENT:
- exception_handling::assert((contains_flags(LENGTH) && !contains_flags(DEFAULT_LENGTH)) ||
- !contains_flags(LENGTH),
- "[GDT] Flags of code segment descriptor has both ");
- break;
- }
+ // Nothing to do.
}
auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool { return (_flags & other) == other; }
diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp
index fb9c034..57564f2 100644
--- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp
+++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp
@@ -3,11 +3,22 @@
namespace teachos::arch::context_switching::descriptor_table
{
segment_descriptor::segment_descriptor(uint128_t flags)
- : _reserved(flags)
- , _access(flags)
- , _flag(flags, segment_descriptor_type::SYSTEM_SEGMENT)
- , _base(flags)
- , _limit(flags)
+ : _reserved(flags >> 96U)
+ , _access((flags >> 40U) << 80U)
+ , _flag((flags >> 52U) << 72U)
+ , _base(((flags >> 64U) << 32U) << 32U | ((flags >> 56U) << 64U) << 24U | (flags >> 16U) << 88U)
+ , _limit(((flags >> 48U) << 72U) << 16U | flags << 112U)
{
+ // Nothing to do.
+ }
+
+ auto segment_descriptor::get_segment_type() const -> segment_descriptor_type
+ {
+ if (!_access.contains_flags(access_byte::CODE_OR_DATA_SEGMENT))
+ {
+ return segment_descriptor_type::SYSTEM_SEGMENT;
+ }
+ return _access.get_type_field().contains_flags(type_field::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT
+ : segment_descriptor_type::DATA_SEGMENT;
}
} // namespace teachos::arch::context_switching::descriptor_table