aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-31 13:18:56 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-31 13:18:56 +0000
commite8fb1d771d9aa4d1cb5b18cd0483c7e5731aeecc (patch)
tree2746d6ba794fd4ee40a8da55aaca962587524858 /arch
parentabe7bd7480c8f4e1e30b9f0f3b98966222817f3e (diff)
downloadteachos-e8fb1d771d9aa4d1cb5b18cd0483c7e5731aeecc.tar.xz
teachos-e8fb1d771d9aa4d1cb5b18cd0483c7e5731aeecc.zip
Improve create_segment readability
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp15
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp15
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/access_byte.hpp19
-rw-r--r--arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp15
-rw-r--r--arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp2
-rw-r--r--arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp28
-rw-r--r--arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp2
-rw-r--r--arch/x86_64/src/context_switching/main.cpp2
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp2
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp2
-rw-r--r--arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp62
11 files changed, 106 insertions, 58 deletions
diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp
index f153e36..2f8e61d 100644
--- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp
+++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp
@@ -48,13 +48,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
idt_flags(uint8_t flags);
/**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
+ * @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
- * std::bitset. Any additional bits that are set are not relevant.
+ * data. 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.
+ * @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;
@@ -66,6 +66,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
*/
auto operator==(idt_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<8U> other) -> void;
+
private:
uint8_t _flags = {}; ///< Underlying bits used to read the flags from.
};
diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
index 73cd176..2c90152 100644
--- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
+++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
@@ -51,13 +51,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
segment_selector(uint16_t index, uint8_t flags);
/**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
+ * @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
- * std::bitset. Any additional bits that are set are not relevant.
+ * data. 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.
+ * @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<3U> other) const -> bool;
@@ -66,6 +66,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
*/
auto operator<=>(segment_selector const & other) const -> std::strong_ordering = 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<3U> other) -> void;
+
private:
uint8_t _flags : 3 = {}; ///< Underlying bits used to read the flags from.
uint16_t _index : 13 =
diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/access_byte.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/access_byte.hpp
index 3d7862c..621b570 100644
--- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/access_byte.hpp
+++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/access_byte.hpp
@@ -71,24 +71,31 @@ namespace teachos::arch::context_switching::segment_descriptor_table
access_byte(uint8_t flags);
/**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
+ * @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
- * std::bitset. Any additional bits that are set are not relevant.
+ * data. 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.
+ * @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 std::bitset of two instances.
+ * @brief Allows to compare the underlying data 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.
+ * @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.
};
diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp
index d8c3cd1..4b84035 100644
--- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp
+++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp
@@ -50,13 +50,13 @@ namespace teachos::arch::context_switching::segment_descriptor_table
gdt_flags(uint8_t flags, std::bitset<20U> limit);
/**
- * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset.
+ * @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
- * std::bitset. Any additional bits that are set are not relevant.
+ * data. 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.
+ * @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;
@@ -77,6 +77,13 @@ namespace teachos::arch::context_switching::segment_descriptor_table
*/
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.
diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp
index e7379ef..d36a4c1 100644
--- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp
+++ b/arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp
@@ -12,4 +12,6 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
{
return (std::bitset<8U>{_flags} & other) == other;
}
+
+ auto idt_flags::operator|=(std::bitset<8U> other) -> void { _flags |= other.to_ulong(); }
} // namespace teachos::arch::context_switching::interrupt_descriptor_table
diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
index 62b116b..db3351e 100644
--- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
+++ b/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp
@@ -6,18 +6,28 @@
namespace teachos::arch::context_switching::interrupt_descriptor_table
{
- auto get_or_create_interrupt_descriptor_table() -> interrupt_descriptor_table &
+ namespace
{
- // @MTO: This address resolution is most certainly wrong -> numbers in dbg seem off (offset_3 = 0)
- uint64_t offset = reinterpret_cast<uint64_t>(&interrupt_handling::generic_interrupt_handler);
- segment_selector selector{0U, segment_selector::REQUEST_LEVEL_KERNEL};
- ist_offset ist{0U};
- idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL | idt_flags::PRESENT};
- gate_descriptor descriptor{selector, ist, flags, offset};
+ auto create_interrupt_descriptor_table() -> interrupt_descriptor_table
+ {
+ // @MTO: This address resolution is most certainly wrong -> numbers in dbg seem off (offset_3 = 0)
+ uint64_t offset = reinterpret_cast<uint64_t>(&interrupt_handling::generic_interrupt_handler);
+ segment_selector selector{0U, segment_selector::REQUEST_LEVEL_KERNEL};
+ ist_offset ist{0U};
+ idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL | idt_flags::PRESENT};
+ gate_descriptor descriptor{selector, ist, flags, offset};
+
+ // Interrupt Descriptor Table needs to be kept alive
+ static interrupt_descriptor_table interrupt_descriptor_table{descriptor};
+ return interrupt_descriptor_table;
+ }
+ } // namespace
+ auto get_or_create_interrupt_descriptor_table() -> interrupt_descriptor_table &
+ {
// Interrupt Descriptor Table needs to be kept alive
- static interrupt_descriptor_table interrupt_descriptor_table{descriptor};
- return interrupt_descriptor_table;
+ static interrupt_descriptor_table idt = create_interrupt_descriptor_table();
+ return idt;
}
auto update_interrupt_descriptor_table_register() -> void
diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp
index 494e50f..62aed9b 100644
--- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp
+++ b/arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp
@@ -13,4 +13,6 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
{
return (std::bitset<3U>{_flags} & other) == other;
}
+
+ auto segment_selector::operator|=(std::bitset<3U> other) -> void { _flags |= other.to_ulong(); }
} // namespace teachos::arch::context_switching::interrupt_descriptor_table
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp
index db04b52..2b853ec 100644
--- a/arch/x86_64/src/context_switching/main.cpp
+++ b/arch/x86_64/src/context_switching/main.cpp
@@ -24,8 +24,6 @@ namespace teachos::arch::context_switching
// FIXME: We currently cannot enable interrupts, since for some reason, we will later run into what looks like a GP
// and triple fault.
- // @MTO: SOMETIMES i get past a breakpoint here???? seems to happen when i actually pause before (f.e. inside the
- // idt). NEVER happened when stepping through quickly. Can you reproduce this?
kernel::cpu::set_interrupt_flag();
descriptor_tables tables = {segment_descriptor_table::get_or_create_global_descriptor_table(),
diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp
index 34a10f1..e31e021 100644
--- a/arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp
+++ b/arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp
@@ -12,4 +12,6 @@ namespace teachos::arch::context_switching::segment_descriptor_table
{
return (std::bitset<8U>{_flags} & other) == other;
}
+
+ auto access_byte::operator|=(std::bitset<8U> other) -> void { _flags |= other.to_ulong(); }
} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp
index 9885bda..e444a24 100644
--- a/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp
+++ b/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp
@@ -15,4 +15,6 @@ namespace teachos::arch::context_switching::segment_descriptor_table
}
auto gdt_flags::get_limit() const -> std::bitset<4U> { return std::bitset<4U>{_limit_2}; }
+
+ auto gdt_flags::operator|=(std::bitset<4U> other) -> void { _flags |= other.to_ulong(); }
} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp
index 346db9e..a497632 100644
--- a/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp
+++ b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp
@@ -11,28 +11,26 @@ namespace teachos::arch::context_switching::segment_descriptor_table
{
namespace
{
-
auto create_segment_descriptor(segment_descriptor_type segment_descriptor_type, access_byte access_level)
-> segment_descriptor
{
- uint8_t access_level_bits =
- access_byte::PRESENT | access_byte::CODE_OR_DATA_SEGMENT | *reinterpret_cast<uint8_t *>(&access_level);
- uint8_t gdt_flags_bits = gdt_flags::GRANULARITY | gdt_flags::LONG_MODE;
+ uint64_t const base = 0x0;
+ std::bitset<20U> const limit{0xFFFFF};
+ gdt_flags flags{gdt_flags::GRANULARITY, limit};
+
+ access_level |= access_byte::PRESENT | access_byte::CODE_OR_DATA_SEGMENT;
if (segment_descriptor_type == segment_descriptor_type::CODE_SEGMENT)
{
- access_level_bits |= access_byte::CODE_SEGMENT | access_byte::READABLE;
+ flags |= gdt_flags::LONG_MODE;
+ access_level |= access_byte::CODE_SEGMENT | access_byte::READABLE;
}
else if (segment_descriptor_type == segment_descriptor_type::DATA_SEGMENT)
{
- gdt_flags_bits |= gdt_flags::UPPER_BOUND;
- access_level_bits |= access_byte::WRITABLE;
+ flags |= gdt_flags::UPPER_BOUND;
+ access_level |= access_byte::WRITABLE;
}
- uint64_t const base = 0x0;
- std::bitset<20U> const limit{0xFFFFF};
- access_byte const access_byte{access_level_bits};
- gdt_flags const gdt_flags{gdt_flags_bits, limit};
- segment_descriptor const segment_descriptor{access_byte, gdt_flags, base, limit};
+ segment_descriptor const segment_descriptor{access_level, flags, base, limit};
return segment_descriptor;
}
@@ -46,28 +44,34 @@ namespace teachos::arch::context_switching::segment_descriptor_table
TSS_LIMIT};
return tss_descriptor;
}
+
+ auto create_global_descriptor_table() -> global_descriptor_table
+ {
+ segment_descriptor const null_segment{0};
+ segment_descriptor const kernel_code_segment =
+ create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
+ segment_descriptor const kernel_data_segment =
+ create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
+ segment_descriptor const user_code_segment =
+ create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER);
+ segment_descriptor const user_data_segment =
+ create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER);
+
+ // Task State Segment needs to be kept alive
+ static auto tss = new task_state_segment();
+ segment_descriptor const tss_descriptor = create_task_state_segment_descriptor(tss);
+
+ global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment,
+ user_code_segment, user_data_segment, tss_descriptor};
+ return global_descriptor_table;
+ }
} // namespace
auto get_or_create_global_descriptor_table() -> global_descriptor_table &
{
- segment_descriptor const null_segment{0};
- segment_descriptor const kernel_code_segment =
- create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
- segment_descriptor const kernel_data_segment =
- create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
- segment_descriptor const user_code_segment =
- create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER);
- segment_descriptor const user_data_segment =
- create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER);
-
- // Task State Segment needs to be kept alive
- static auto tss = new task_state_segment();
- segment_descriptor const tss_descriptor = create_task_state_segment_descriptor(tss);
-
// Global Descriptor Table needs to be kept alive
- static global_descriptor_table global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment,
- user_code_segment, user_data_segment, tss_descriptor};
- return global_descriptor_table;
+ static global_descriptor_table gdt = create_global_descriptor_table();
+ return gdt;
}
auto update_global_descriptor_table_register() -> void