aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-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
7 files changed, 60 insertions, 40 deletions
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