aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/pre/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/pre/src')
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/access_byte.cpp20
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/gdt_flags.cpp26
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp109
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp11
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp41
-rw-r--r--arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp30
-rw-r--r--arch/x86_64/pre/src/kernel/cpu/gdtr.cpp19
-rw-r--r--arch/x86_64/pre/src/kernel/cpu/msr.cpp31
-rw-r--r--arch/x86_64/pre/src/kernel/cpu/segment_register.cpp98
9 files changed, 0 insertions, 385 deletions
diff --git a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/access_byte.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/access_byte.cpp
deleted file mode 100644
index fcc72cf..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/access_byte.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/access_byte.hpp"
-
-namespace teachos::arch::context_switching::segment_descriptor_table
-{
- access_byte::access_byte(uint8_t flags)
- : _flags(flags)
- {
- // Nothing to do.
- }
-
- auto access_byte::contains_flags(std::bitset<8U> other) const -> bool
- {
- 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/pre/src/context_switching/segment_descriptor_table/gdt_flags.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/gdt_flags.cpp
deleted file mode 100644
index ad1366a..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/gdt_flags.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/gdt_flags.hpp"
-
-namespace teachos::arch::context_switching::segment_descriptor_table
-{
- gdt_flags::gdt_flags(uint8_t flags, std::bitset<20U> limit)
- : _limit_2(limit.to_ulong() >> 16U)
- , _flags(flags)
- {
- // Nothing to do.
- }
-
- auto gdt_flags::contains_flags(std::bitset<4U> other) const -> bool
- {
- return (std::bitset<4U>{_flags} & other) == other;
- }
-
- 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/pre/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp
deleted file mode 100644
index 1c4729f..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp"
-
-#include "arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp"
-#include "arch/exception_handling/assert.hpp"
-#include "arch/kernel/cpu/gdtr.hpp"
-#include "arch/kernel/cpu/tr.hpp"
-
-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_base
- {
- constexpr uint64_t BASE = 0x0;
- constexpr std::bitset<20U> 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)
- {
- flags |= gdt_flags::LONG_MODE;
- access_level |= access_byte::CODE_SEGMENT | access_byte::READABLE;
- }
- else if (segment_descriptor_type == segment_descriptor_type::DATA_SEGMENT)
- {
- access_level |= access_byte::WRITABLE;
- }
-
- segment_descriptor_base const segment_descriptor_base{access_level, flags, BASE, LIMIT};
- return segment_descriptor_base;
- }
-
- auto create_tss_descriptor(task_state_segment * tss) -> segment_descriptor_extension
- {
- constexpr uint64_t TSS_LIMIT = sizeof(task_state_segment) - 1;
- access_byte const tss_access_byte{access_byte::PRESENT | access_byte::DESCRIPTOR_LEVEL_KERNEL |
- access_byte::TASK_STATE_SEGMENT_AVAILABLE};
- gdt_flags const tss_gdt_flags{0U, TSS_LIMIT};
- segment_descriptor_extension const tss_descriptor{tss_access_byte, tss_gdt_flags, reinterpret_cast<uint64_t>(tss),
- TSS_LIMIT};
- return tss_descriptor;
- }
-
- auto create_gdt() -> global_descriptor_table
- {
- segment_descriptor_base const null_segment{0};
- segment_descriptor_base const kernel_code_segment =
- create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
- segment_descriptor_base const kernel_data_segment =
- create_segment_descriptor(segment_descriptor_type::DATA_SEGMENT, access_byte::DESCRIPTOR_LEVEL_KERNEL);
- segment_descriptor_base const user_code_segment =
- create_segment_descriptor(segment_descriptor_type::CODE_SEGMENT, access_byte::DESCRIPTOR_LEVEL_USER);
- segment_descriptor_base 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
- auto static tss = new task_state_segment();
- segment_descriptor_extension const tss_descriptor = create_tss_descriptor(tss);
-
- global_descriptor_table global_descriptor_table{null_segment,
- kernel_code_segment,
- kernel_data_segment,
- user_code_segment,
- user_data_segment,
- tss_descriptor.get_first_gdt_entry(),
- tss_descriptor.get_second_gdt_entry()};
- return global_descriptor_table;
- }
- } // namespace
-
- auto get_or_create_gdt() -> global_descriptor_table &
- {
- // Global Descriptor Table needs to be kept alive
- global_descriptor_table static gdt = create_gdt();
- return gdt;
- }
-
- auto update_gdtr() -> void
- {
- decltype(auto) gdt = get_or_create_gdt();
-
- // Calculate the size of the gdt in bytes - 1. This subtraction occurs because the maximum value of Size is 65535,
- // while the GDT can be up to 65536 bytes in length (8192 entries). Further, no GDT can have a size of 0 bytes.
- uint16_t gdt_size = static_cast<uint16_t>((gdt.size() * sizeof(segment_descriptor_base)) - 1);
- global_descriptor_table_pointer gdt_pointer{gdt_size, gdt.data()};
- kernel::cpu::load_global_descriptor_table(gdt_pointer);
-
- auto const stored_gdt_pointer = kernel::cpu::store_global_descriptor_table();
- arch::exception_handling::assert(
- gdt_pointer == stored_gdt_pointer,
- "[Global Descriptor Table] Loaded GDTR value is not the same as the stored value.");
- }
-
- auto update_tss_register() -> void
- {
- decltype(auto) gdt = get_or_create_gdt();
-
- // Load task state segment descriptor from the last element in the global descriptor table, done by calculating
- // offset in bytes to the start of the segment descriptor (5 * 8) = 40
- uint16_t tss_selector = (gdt.size() * sizeof(segment_descriptor_base)) - sizeof(segment_descriptor_extension);
- kernel::cpu::load_task_register(tss_selector);
-
- auto const stored_task_register = kernel::cpu::store_task_register();
- arch::exception_handling::assert(tss_selector == stored_task_register,
- "[Global Descriptor Table] Loaded TR value is not the same as the stored value.");
- }
-
-} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp
deleted file mode 100644
index 79088b8..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp"
-
-namespace teachos::arch::context_switching::segment_descriptor_table
-{
- global_descriptor_table_pointer::global_descriptor_table_pointer(uint16_t table_length, uint64_t * address)
- : table_length(table_length)
- , address(address)
- {
- // Nothing to do.
- }
-} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp
deleted file mode 100644
index c3a03fc..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/segment_descriptor_base.hpp"
-
-namespace teachos::arch::context_switching::segment_descriptor_table
-{
- segment_descriptor_base::segment_descriptor_base(uint64_t flags)
- : _limit_1(flags)
- , _base_1(flags >> 16U)
- , _access(flags >> 40U)
- , _flag(flags >> 52U, flags >> 48U)
- , _base_2(flags >> 56U)
- {
- // Nothing to do.
- }
-
- segment_descriptor_base::segment_descriptor_base(access_byte access_byte, gdt_flags flags, uint32_t base,
- std::bitset<20U> limit)
- : _limit_1(limit.to_ulong())
- , _base_1(base)
- , _access(access_byte)
- , _flag(flags)
- , _base_2(base >> 24U)
- {
- // Nothing to do
- }
-
- auto segment_descriptor_base::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.contains_flags(access_byte::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT
- : segment_descriptor_type::DATA_SEGMENT;
- }
-
- segment_descriptor_base::operator uint64_t() const
- {
- return *reinterpret_cast<uint64_t const *>(this);
- }
-
-} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp b/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp
deleted file mode 100644
index 5ea0d8a..0000000
--- a/arch/x86_64/pre/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "arch/context_switching/segment_descriptor_table/segment_descriptor_extension.hpp"
-
-namespace teachos::arch::context_switching::segment_descriptor_table
-{
- segment_descriptor_extension::segment_descriptor_extension(uint128_t flags)
- : _base(flags)
- , _base_3(flags >> 64U)
- {
- // Nothing to do.
- }
-
- segment_descriptor_extension::segment_descriptor_extension(access_byte access_byte, gdt_flags flags, uint64_t base,
- std::bitset<20U> limit)
- : _base(access_byte, flags, base, limit)
- , _base_3(base >> 32U)
- {
- // Nothing to do
- }
-
- auto segment_descriptor_extension::get_first_gdt_entry() const -> segment_descriptor_base
- {
- return _base;
- }
-
- auto segment_descriptor_extension::get_second_gdt_entry() const -> uint64_t
- {
- return _base_3;
- }
-
-} // namespace teachos::arch::context_switching::segment_descriptor_table
diff --git a/arch/x86_64/pre/src/kernel/cpu/gdtr.cpp b/arch/x86_64/pre/src/kernel/cpu/gdtr.cpp
deleted file mode 100644
index 74a4e1c..0000000
--- a/arch/x86_64/pre/src/kernel/cpu/gdtr.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "arch/kernel/cpu/gdtr.hpp"
-
-#include "arch/context_switching/segment_descriptor_table/global_descriptor_table_pointer.hpp"
-
-namespace teachos::arch::kernel::cpu
-{
- auto store_global_descriptor_table() -> context_switching::segment_descriptor_table::global_descriptor_table_pointer
- {
- context_switching::segment_descriptor_table::global_descriptor_table_pointer current_value{};
- asm("sgdt %[output]" : [output] "=m"(current_value));
- return current_value;
- }
-
- auto load_global_descriptor_table(
- context_switching::segment_descriptor_table::global_descriptor_table_pointer const & gdt_pointer) -> void
- {
- asm volatile("lgdt %[input]" : /* no output from call */ : [input] "m"(gdt_pointer));
- }
-} // namespace teachos::arch::kernel::cpu
diff --git a/arch/x86_64/pre/src/kernel/cpu/msr.cpp b/arch/x86_64/pre/src/kernel/cpu/msr.cpp
deleted file mode 100644
index 9d6a318..0000000
--- a/arch/x86_64/pre/src/kernel/cpu/msr.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "arch/kernel/cpu/msr.hpp"
-
-namespace teachos::arch::kernel::cpu
-{
- namespace
- {
- constexpr auto IA32_EFER_ADDRESS = 0xC000'0080;
- }
-
- auto read_msr(uint32_t msr) -> uint64_t
- {
- uint32_t low, high;
- asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
- return (static_cast<uint64_t>(high) << 32) | low;
- }
-
- auto write_msr(uint32_t msr, uint64_t value) -> void
- {
- uint32_t low = value;
- uint32_t high = value >> 32;
- asm volatile("wrmsr"
- : /* no output from call */
- : "c"(msr), "a"(low), "d"(high));
- }
-
- auto set_efer_bit(efer_flags flag) -> void
- {
- auto const efer = read_msr(IA32_EFER_ADDRESS);
- write_msr(IA32_EFER_ADDRESS, static_cast<std::underlying_type<efer_flags>::type>(flag) | efer);
- }
-} // namespace teachos::arch::kernel::cpu
diff --git a/arch/x86_64/pre/src/kernel/cpu/segment_register.cpp b/arch/x86_64/pre/src/kernel/cpu/segment_register.cpp
deleted file mode 100644
index b08c9c4..0000000
--- a/arch/x86_64/pre/src/kernel/cpu/segment_register.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "arch/kernel/cpu/segment_register.hpp"
-
-#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp"
-#include "arch/exception_handling/assert.hpp"
-
-namespace teachos::arch::kernel::cpu
-{
- auto reload_data_segment_registers() -> void
- {
- asm volatile("xor %%rax, %%rax\n"
- "mov %%rax, %%ss\n"
- "mov %%rax, %%ds\n"
- "mov %%rax, %%es\n"
- "mov %%rax, %%fs\n"
- "mov %%rax, %%gs\n"
- : /* no output from call */
- : /* no input to call */
- : "rax");
- }
-
- auto set_data_segment_registers(context_switching::interrupt_descriptor_table::segment_selector data_segment) -> void
- {
- asm volatile("xor %%rax, %%rax\n"
- "mov %[input], %%ax\n"
- "mov %%rax, %%ds\n"
- "mov %%rax, %%es\n"
- "mov %%rax, %%fs\n"
- "mov %%rax, %%gs\n"
- : /* no output from call */
- : [input] "m"(data_segment)
- : "rax");
- }
-
- auto read_code_segment_register() -> context_switching::interrupt_descriptor_table::segment_selector
- {
- context_switching::interrupt_descriptor_table::segment_selector current_value{};
- asm volatile("mov %%cs, %[output]" : [output] "=r"(current_value));
- return current_value;
- }
-
- auto validate_data_segment_registers(context_switching::interrupt_descriptor_table::segment_selector data_segment)
- -> void
- {
- context_switching::interrupt_descriptor_table::segment_selector ss{};
- context_switching::interrupt_descriptor_table::segment_selector ds{};
- context_switching::interrupt_descriptor_table::segment_selector es{};
- context_switching::interrupt_descriptor_table::segment_selector fs{};
- context_switching::interrupt_descriptor_table::segment_selector gs{};
-
- asm volatile(
- "mov %%ss, %[ss_output]\n"
- "mov %%ds, %[ds_output]\n"
- "mov %%es, %[es_output]\n"
- "mov %%fs, %[fs_output]\n"
- "mov %%gs, %[gs_output]\n"
- : [ss_output] "=r"(ss), [ds_output] "=r"(ds), [es_output] "=r"(es), [fs_output] "=r"(fs), [gs_output] "=r"(gs));
-
- auto result = (ss == ds && ss == es && ss == fs && ss == gs);
- exception_handling::assert(result, "[Segment Register] Values in data register are not the same.");
- result = (ss == data_segment);
- exception_handling::assert(
- result, "[Segment Register] Expected Data Segment is not the same as the value in the Stack Segment register.");
- }
-
- auto validate_code_segment_register(context_switching::interrupt_descriptor_table::segment_selector code_segment)
- -> void
- {
- auto const cs = read_code_segment_register();
- exception_handling::assert(
- cs == code_segment,
- "[Segment Register] Expected Code Segment is not the same as the value in the Code Segment register.");
- }
-
- auto validate_segment_registers(context_switching::interrupt_descriptor_table::segment_selector data_segment,
- context_switching::interrupt_descriptor_table::segment_selector code_segment) -> void
- {
- validate_data_segment_registers(data_segment);
- validate_code_segment_register(code_segment);
- }
-
- auto set_code_segment_register(context_switching::interrupt_descriptor_table::segment_selector data_segment,
- context_switching::interrupt_descriptor_table::segment_selector code_segment,
- uint64_t address) -> void
- {
- asm volatile("mov %%rsp, %%rax\n"
- "push %[data_segment]\n"
- "push %%rax\n"
- "pushfq\n"
- "push %[code_segment]\n"
- "mov %[return_function], %%rax\n"
- "push %%rax\n"
- "iretq\n"
- : /* no output from call */
- : [data_segment] "m"(data_segment), [code_segment] "m"(code_segment), [return_function] "r"(address)
- : "rax");
- }
-
-} // namespace teachos::arch::kernel::cpu