From 2d3399ab6072acd85811a54fce8eff50628888b6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 24 Jul 2025 16:35:34 +0000 Subject: x86_64: move files out of the way --- .../interrupt_descriptor_table/gate_descriptor.cpp | 24 --- .../interrupt_descriptor_table/idt_flags.cpp | 17 -- .../interrupt_descriptor_table.cpp | 53 ------ .../interrupt_descriptor_table_pointer.cpp | 13 -- .../interrupt_descriptor_table/ist_offset.cpp | 10 -- .../segment_selector.cpp | 15 -- arch/x86_64/src/context_switching/main.cpp | 63 ------- .../segment_descriptor_table/access_byte.cpp | 17 -- .../segment_descriptor_table/gdt_flags.cpp | 20 --- .../global_descriptor_table.cpp | 109 ----------- .../global_descriptor_table_pointer.cpp | 11 -- .../segment_descriptor_base.cpp | 38 ---- .../segment_descriptor_extension.cpp | 24 --- arch/x86_64/src/context_switching/syscall/main.cpp | 35 ---- .../context_switching/syscall/syscall_enable.cpp | 32 ---- .../context_switching/syscall/syscall_handler.cpp | 118 ------------ arch/x86_64/src/exception_handling/abort.cpp | 15 -- arch/x86_64/src/exception_handling/assert.cpp | 15 -- arch/x86_64/src/exception_handling/panic.cpp | 22 --- .../x86_64/src/exception_handling/pure_virtual.cpp | 6 - .../generic_interrupt_handler.cpp | 13 -- arch/x86_64/src/kernel/cpu/call.cpp | 9 - arch/x86_64/src/kernel/cpu/gdtr.cpp | 19 -- arch/x86_64/src/kernel/cpu/idtr.cpp | 18 -- arch/x86_64/src/kernel/cpu/if.cpp | 7 - arch/x86_64/src/kernel/cpu/msr.cpp | 31 ---- arch/x86_64/src/kernel/cpu/segment_register.cpp | 98 ---------- arch/x86_64/src/kernel/cpu/tr.cpp | 16 -- arch/x86_64/src/kernel/main.cpp | 71 -------- .../src/memory/allocator/area_frame_allocator.cpp | 85 --------- .../src/memory/allocator/tiny_frame_allocator.cpp | 34 ---- arch/x86_64/src/memory/heap/bump_allocator.cpp | 54 ------ .../src/memory/heap/global_heap_allocator.cpp | 135 -------------- .../src/memory/heap/linked_list_allocator.cpp | 177 ------------------ arch/x86_64/src/memory/heap/memory_block.cpp | 15 -- .../x86_64/src/memory/heap/user_heap_allocator.cpp | 200 --------------------- arch/x86_64/src/memory/main.cpp | 77 -------- .../src/memory/multiboot/elf_symbols_section.cpp | 13 -- arch/x86_64/src/memory/multiboot/reader.cpp | 135 -------------- .../x86_64/src/memory/paging/active_page_table.cpp | 98 ---------- .../src/memory/paging/inactive_page_table.cpp | 20 --- arch/x86_64/src/memory/paging/page_entry.cpp | 63 ------- arch/x86_64/src/memory/paging/page_table.cpp | 128 ------------- arch/x86_64/src/memory/paging/temporary_page.cpp | 29 --- arch/x86_64/src/memory/paging/virtual_page.cpp | 33 ---- arch/x86_64/src/user/main.cpp | 35 ---- 46 files changed, 2270 deletions(-) delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/ist_offset.cpp delete mode 100644 arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp delete mode 100644 arch/x86_64/src/context_switching/main.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp delete mode 100644 arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp delete mode 100644 arch/x86_64/src/context_switching/syscall/main.cpp delete mode 100644 arch/x86_64/src/context_switching/syscall/syscall_enable.cpp delete mode 100644 arch/x86_64/src/context_switching/syscall/syscall_handler.cpp delete mode 100644 arch/x86_64/src/exception_handling/abort.cpp delete mode 100644 arch/x86_64/src/exception_handling/assert.cpp delete mode 100644 arch/x86_64/src/exception_handling/panic.cpp delete mode 100644 arch/x86_64/src/exception_handling/pure_virtual.cpp delete mode 100644 arch/x86_64/src/interrupt_handling/generic_interrupt_handler.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/call.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/gdtr.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/idtr.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/if.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/msr.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/segment_register.cpp delete mode 100644 arch/x86_64/src/kernel/cpu/tr.cpp delete mode 100644 arch/x86_64/src/kernel/main.cpp delete mode 100644 arch/x86_64/src/memory/allocator/area_frame_allocator.cpp delete mode 100644 arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp delete mode 100644 arch/x86_64/src/memory/heap/bump_allocator.cpp delete mode 100644 arch/x86_64/src/memory/heap/global_heap_allocator.cpp delete mode 100644 arch/x86_64/src/memory/heap/linked_list_allocator.cpp delete mode 100644 arch/x86_64/src/memory/heap/memory_block.cpp delete mode 100644 arch/x86_64/src/memory/heap/user_heap_allocator.cpp delete mode 100644 arch/x86_64/src/memory/main.cpp delete mode 100644 arch/x86_64/src/memory/multiboot/elf_symbols_section.cpp delete mode 100644 arch/x86_64/src/memory/multiboot/reader.cpp delete mode 100644 arch/x86_64/src/memory/paging/active_page_table.cpp delete mode 100644 arch/x86_64/src/memory/paging/inactive_page_table.cpp delete mode 100644 arch/x86_64/src/memory/paging/page_entry.cpp delete mode 100644 arch/x86_64/src/memory/paging/page_table.cpp delete mode 100644 arch/x86_64/src/memory/paging/temporary_page.cpp delete mode 100644 arch/x86_64/src/memory/paging/virtual_page.cpp delete mode 100644 arch/x86_64/src/user/main.cpp (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp deleted file mode 100644 index 28f289c..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - gate_descriptor::gate_descriptor(uint128_t flags) - : _offset_1(flags) - , _selector(flags >> 19U, flags >> 16U) - , _ist(flags >> 32U) - , _flags(flags >> 40U) - , _offset_2(flags >> 48U) - { - // Nothing to do. - } - - gate_descriptor::gate_descriptor(segment_selector selector, ist_offset ist, idt_flags flags, uint64_t offset) - : _offset_1(offset) - , _selector(selector) - , _ist(ist) - , _flags(flags) - , _offset_2(offset >> 16U) - { - // Nothing to do. - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table 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 deleted file mode 100644 index d36a4c1..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/idt_flags.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/idt_flags.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - idt_flags::idt_flags(uint8_t flags) - : _flags(flags) - { - // Nothing to do. - } - - auto idt_flags::contains_flags(std::bitset<8U> other) const -> bool - { - 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 deleted file mode 100644 index 7aa0859..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp" - -#include "arch/exception_handling/assert.hpp" -#include "arch/interrupt_handling/generic_interrupt_handler.hpp" -#include "arch/kernel/cpu/idtr.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - namespace - { - /// @brief Amount of currently reserved interrupt indicies. - /// See https://wiki.osdev.org/Interrupt_Descriptor_Table#IDT_items for more information. - constexpr uint16_t RESERVED_INTERRUPT_COUNT = 256U; - - auto create_interrupt_descriptor_table() -> interrupt_descriptor_table - { - interrupt_descriptor_table interrupt_descriptor_table{RESERVED_INTERRUPT_COUNT}; - - uint64_t offset = reinterpret_cast(interrupt_handling::generic_interrupt_handler); - segment_selector selector{1U, segment_selector::REQUEST_LEVEL_KERNEL}; - ist_offset ist{0U}; - idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL | idt_flags::INTERRUPT_GATE | idt_flags::PRESENT}; - - for (std::size_t i = 0; i < interrupt_descriptor_table.size(); i++) - { - interrupt_descriptor_table.at(i) = {selector, ist, flags, offset}; - } - - 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 idt = create_interrupt_descriptor_table(); - return idt; - } - - auto update_interrupt_descriptor_table_register() -> void - { - decltype(auto) idt = get_or_create_interrupt_descriptor_table(); - - interrupt_descriptor_table_pointer idt_pointer{static_cast((idt.size() * sizeof(gate_descriptor)) - 1), - idt.data()}; - kernel::cpu::load_interrupt_descriptor_table(idt_pointer); - - auto const stored_gdt_pointer = kernel::cpu::store_interrupt_descriptor_table(); - arch::exception_handling::assert( - idt_pointer == stored_gdt_pointer, - "[Interrupt Descriptor Table] Loaded IDTR value is not the same as the stored value."); - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp deleted file mode 100644 index 7bcbae6..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - interrupt_descriptor_table_pointer::interrupt_descriptor_table_pointer(uint16_t table_length, - gate_descriptor * address) - : table_length(table_length) - , address(address) - { - // Nothing to do. - } - -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/src/context_switching/interrupt_descriptor_table/ist_offset.cpp b/arch/x86_64/src/context_switching/interrupt_descriptor_table/ist_offset.cpp deleted file mode 100644 index a70e75d..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/ist_offset.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/ist_offset.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - ist_offset::ist_offset(uint8_t index) - : _ist(index) - { - // Nothing to do. - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table 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 deleted file mode 100644 index 27f0a3b..0000000 --- a/arch/x86_64/src/context_switching/interrupt_descriptor_table/segment_selector.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - auto segment_selector::contains_flags(std::bitset<3U> other) const -> bool - { - return (std::bitset<3U>{_flags} & other) == other; - } - - auto segment_selector::get_index() const -> uint16_t { return _index; } - - auto segment_selector::operator|=(std::bitset<3U> other) -> void { _flags |= other.to_ulong(); } - - segment_selector::operator uint16_t() const { return *reinterpret_cast(this); } -} // 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 deleted file mode 100644 index 9539428..0000000 --- a/arch/x86_64/src/context_switching/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "arch/context_switching/main.hpp" - -#include "arch/boot/pointers.hpp" -#include "arch/context_switching/syscall/syscall_enable.hpp" -#include "arch/kernel/cpu/call.hpp" -#include "arch/kernel/cpu/if.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/kernel/cpu/tr.hpp" -#include "arch/user/main.hpp" - -namespace teachos::arch::context_switching -{ - namespace - { - constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ - 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; - constexpr kernel::cpu::far_pointer KERNEL_CODE_POINTER{&kernel::cpu::reload_data_segment_registers, - KERNEL_CODE_SEGMENT_SELECTOR}; - constexpr context_switching::interrupt_descriptor_table::segment_selector USER_CODE_SEGMENT_SELECTOR{ - 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - constexpr context_switching::interrupt_descriptor_table::segment_selector USER_DATA_SEGMENT_SELECTOR{ - 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - - auto reload_gdtr() -> void { kernel::cpu::call(KERNEL_CODE_POINTER); } - } // namespace - - auto initialize_descriptor_tables() -> descriptor_tables - { - static bool initalized = false; - - if (!initalized) - { - kernel::cpu::clear_interrupt_flag(); - - segment_descriptor_table::update_gdtr(); - interrupt_descriptor_table::update_interrupt_descriptor_table_register(); - - reload_gdtr(); - segment_descriptor_table::update_tss_register(); - - kernel::cpu::set_interrupt_flag(); - initalized = true; - } - - descriptor_tables tables = {segment_descriptor_table::get_or_create_gdt(), - interrupt_descriptor_table::get_or_create_interrupt_descriptor_table()}; - return tables; - } - - auto switch_to_user_mode() -> void - { - syscall::enable_syscall(); - switch_context(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR, user::main); - } - - auto switch_context(interrupt_descriptor_table::segment_selector data_segment, - interrupt_descriptor_table::segment_selector code_segment, void (*return_function)()) -> void - { - (void)initialize_descriptor_tables(); - kernel::cpu::set_data_segment_registers(data_segment); - kernel::cpu::set_code_segment_register(data_segment, code_segment, reinterpret_cast(return_function)); - } -} // namespace teachos::arch::context_switching 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 deleted file mode 100644 index e31e021..0000000 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/access_byte.cpp +++ /dev/null @@ -1,17 +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/src/context_switching/segment_descriptor_table/gdt_flags.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp deleted file mode 100644 index e444a24..0000000 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/gdt_flags.cpp +++ /dev/null @@ -1,20 +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/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table.cpp deleted file mode 100644 index bbcee31..0000000 --- a/arch/x86_64/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 - { - uint64_t constexpr BASE = 0x0; - std::bitset<20U> constexpr 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 - { - uint64_t constexpr 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(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 - static auto 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 - static global_descriptor_table 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((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/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/global_descriptor_table_pointer.cpp deleted file mode 100644 index 79088b8..0000000 --- a/arch/x86_64/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/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp deleted file mode 100644 index 04804d9..0000000 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_base.cpp +++ /dev/null @@ -1,38 +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(this); } - -} // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp b/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp deleted file mode 100644 index a28ec9b..0000000 --- a/arch/x86_64/src/context_switching/segment_descriptor_table/segment_descriptor_extension.cpp +++ /dev/null @@ -1,24 +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/src/context_switching/syscall/main.cpp b/arch/x86_64/src/context_switching/syscall/main.cpp deleted file mode 100644 index b4ab468..0000000 --- a/arch/x86_64/src/context_switching/syscall/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "arch/context_switching/syscall/main.hpp" - -namespace teachos::arch::context_switching::syscall -{ - auto syscall(type syscall_number, arguments args) -> response - { - asm volatile("mov %[input], %%rax" - : /* no output from call */ - : [input] "m"(syscall_number) - : "memory"); - - asm volatile("mov %[input], %%rdi " : /* no output from call */ : [input] "m"(args.arg_0) : "memory"); - asm volatile("mov %[input], %%rsi" : /* no output from call */ : [input] "m"(args.arg_1) : "memory"); - asm volatile("mov %[input], %%rdx" : /* no output from call */ : [input] "m"(args.arg_2) : "memory"); - asm volatile("mov %[input], %%r10" : /* no output from call */ : [input] "m"(args.arg_3) : "memory"); - asm volatile("mov %[input], %%r8" : /* no output from call */ : [input] "m"(args.arg_4) : "memory"); - asm volatile("mov %[input], %%r9" : /* no output from call */ : [input] "m"(args.arg_5) : "memory"); - - asm volatile("syscall"); - - arguments values{}; - asm volatile("mov %%rdi, %[output]" : [output] "=m"(values.arg_0)); - asm volatile("mov %%rsi, %[output]" : [output] "=m"(values.arg_1)); - asm volatile("mov %%rdx, %[output]" : [output] "=m"(values.arg_2)); - asm volatile("mov %%r10, %[output]" : [output] "=m"(values.arg_3)); - asm volatile("mov %%r8, %[output]" : [output] "=m"(values.arg_4)); - asm volatile("mov %%r9, %[output]" : [output] "=m"(values.arg_5)); - - error error_code{}; - asm volatile("mov %%al, %[output]" : [output] "=m"(error_code)); - - return {error_code, values}; - } - -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/src/context_switching/syscall/syscall_enable.cpp b/arch/x86_64/src/context_switching/syscall/syscall_enable.cpp deleted file mode 100644 index 3c43336..0000000 --- a/arch/x86_64/src/context_switching/syscall/syscall_enable.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "arch/context_switching/syscall/syscall_enable.hpp" - -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" -#include "arch/context_switching/syscall/syscall_handler.hpp" -#include "arch/kernel/cpu/msr.hpp" - -namespace teachos::arch::context_switching::syscall -{ - namespace - { - interrupt_descriptor_table::segment_selector constexpr KERNEL_CODE_SEGMENT_SELECTOR{ - 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; - - auto constexpr IA32_STAR_ADDRESS = 0xC0000081; - auto constexpr IA32_LSTAR_ADDRESS = 0xC0000082; - auto constexpr IA32_FMASK_ADDRESS = 0xC0000084; - - } // namespace - - auto enable_syscall() -> void - { - uint64_t const syscall_function = reinterpret_cast(syscall_handler); - kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function); - kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); - - uint64_t const kernel_cs = KERNEL_CODE_SEGMENT_SELECTOR; - uint64_t const star_value = (kernel_cs << 32) | (kernel_cs << 48); - kernel::cpu::write_msr(IA32_STAR_ADDRESS, star_value); - - kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE); - } -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp b/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp deleted file mode 100644 index 84dbe5f..0000000 --- a/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "arch/context_switching/syscall/syscall_handler.hpp" - -#include "arch/context_switching/syscall/main.hpp" -#include "arch/exception_handling/assert.hpp" -#include "arch/exception_handling/panic.hpp" -#include "arch/memory/heap/global_heap_allocator.hpp" -#include "arch/memory/main.hpp" -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::context_switching::syscall -{ - - namespace - { - auto write_to_vga_buffer(uint64_t buffer) -> response - { - video::vga::text::write(reinterpret_cast(buffer), - video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - return {error::OK}; - } - - auto expand_user_heap() -> response - { - static auto current_heap_end = memory::heap::USER_HEAP_START; - uint64_t const heap_start = current_heap_end; - memory::remap_heap(heap_start, memory::heap::USER_HEAP_SIZE, memory::paging::entry::USER_ACCESSIBLE); - current_heap_end += memory::heap::USER_HEAP_SIZE; - return {error::OK, {heap_start, memory::heap::USER_HEAP_SIZE}}; - } - } // namespace - - auto syscall_handler() -> void - { - // Saving state of rcx and r11 because it is required by sysretq to function. - // Calls to other functions potentially overwrite these registers, because of - // callee saved calling convention. - uint64_t return_instruction_pointer, rflags = {}; - asm volatile("mov %%rcx, %[output]" : [output] "=m"(return_instruction_pointer)); - asm volatile("mov %%r11, %[output]" : [output] "=m"(rflags)); - - uint64_t syscall_number, arg_0, arg_1, arg_2, arg_3, arg_4, arg_5 = {}; - asm volatile("mov %%rdi, %[output]" : [output] "=m"(arg_0)); - asm volatile("mov %%rsi, %[output]" : [output] "=m"(arg_1)); - asm volatile("mov %%rdx, %[output]" : [output] "=m"(arg_2)); - asm volatile("mov %%r10, %[output]" : [output] "=m"(arg_3)); - asm volatile("mov %%r8, %[output]" : [output] "=m"(arg_4)); - asm volatile("mov %%r9, %[output]" : [output] "=m"(arg_5)); - - // RAX is read last, because paired with our type enum, we can use it to check - // if the register has been written by the compiled code between executing the syscall - // and now. - asm volatile("mov %%rax, %[output]" : [output] "=m"(syscall_number)); - - response result; - switch (static_cast(syscall_number)) - { - case type::WRITE: - result = write_to_vga_buffer(arg_0); - break; - case type::EXPAND_HEAP: - result = expand_user_heap(); - break; - case type::ASSERT: - teachos::arch::exception_handling::assert(arg_0, reinterpret_cast(arg_1)); - break; - default: - teachos::arch::exception_handling::panic("[Syscall Handler] Invalid syscall number"); - break; - } - - asm volatile("mov %[input], %%rax" - : /* no output from call */ - : [input] "m"(result.error_code) - : "memory"); - - asm volatile("mov %[input], %%rdi" - : /* no output from call */ - : [input] "m"(result.values.arg_0) - : "memory"); - asm volatile("mov %[input], %%rsi" - : /* no output from call */ - : [input] "m"(result.values.arg_1) - : "memory"); - asm volatile("mov %[input], %%rdx" - : /* no output from call */ - : [input] "m"(result.values.arg_2) - : "memory"); - asm volatile("mov %[input], %%r10" - : /* no output from call */ - : [input] "m"(result.values.arg_3) - : "memory"); - asm volatile("mov %[input], %%r8" - : /* no output from call */ - : [input] "m"(result.values.arg_4) - : "memory"); - asm volatile("mov %[input], %%r9" - : /* no output from call */ - : [input] "m"(result.values.arg_5) - : "memory"); - - asm volatile("mov %[input], %%rcx" - : /* no output from call */ - : [input] "m"(return_instruction_pointer) - : "memory"); - asm volatile("mov %[input], %%r11" - : /* no output from call */ - : [input] "m"(rflags) - : "memory"); - - // Additionally call leave, because x86 allocates stack space for the internal variables. If we do not clean up this - // newly created stack frame the syscall instruction that landed in this syscall_handler, will never return to the - // method that originally called it, because the RIP has not been restored from the previous stack frame. - asm volatile("leave\n" - "sysretq"); - } - -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/src/exception_handling/abort.cpp b/arch/x86_64/src/exception_handling/abort.cpp deleted file mode 100644 index e12e4cb..0000000 --- a/arch/x86_64/src/exception_handling/abort.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "arch/exception_handling/panic.hpp" - -#include - -namespace teachos::arch::exception_handling -{ - /** - * @brief Override for the newlib abort function. - * - * @note newlib defines @p ::abort as a weak symbol, thus allowing implementations to override it by simply providing - * a matching implementation. Since the default implemenatation calls a number of functions the kernel does not - * currently implement, @p ::abort gets overridden to simply panic. - */ - extern "C" auto abort() -> void { panic("Terminate was called, possibly due to an unhandled exception"); } -} // namespace teachos::arch::exception_handling diff --git a/arch/x86_64/src/exception_handling/assert.cpp b/arch/x86_64/src/exception_handling/assert.cpp deleted file mode 100644 index b2963de..0000000 --- a/arch/x86_64/src/exception_handling/assert.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "arch/exception_handling/assert.hpp" - -#include "arch/exception_handling/panic.hpp" - -namespace teachos::arch::exception_handling -{ - auto assert(bool condition, char const * message) -> void - { - if (condition) - { - return; - } - panic("Assertion Violation: ", message); - } -} // namespace teachos::arch::exception_handling diff --git a/arch/x86_64/src/exception_handling/panic.cpp b/arch/x86_64/src/exception_handling/panic.cpp deleted file mode 100644 index 8e3802a..0000000 --- a/arch/x86_64/src/exception_handling/panic.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "arch/exception_handling/panic.hpp" - -#include "arch/kernel/halt.hpp" -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::exception_handling -{ - extern "C" char const message_prefix_panic[]; - - auto panic(char const * reason) -> void { panic(message_prefix_panic, reason); } - - auto panic(char const * prefix, char const * reason) -> void - { - using video::vga::text::common_attributes::white_on_red; - - video::vga::text::newline(); - video::vga::text::write(prefix, white_on_red); - video::vga::text::write(reason, white_on_red); - - kernel::halt(); - }; -} // namespace teachos::arch::exception_handling diff --git a/arch/x86_64/src/exception_handling/pure_virtual.cpp b/arch/x86_64/src/exception_handling/pure_virtual.cpp deleted file mode 100644 index 67772f7..0000000 --- a/arch/x86_64/src/exception_handling/pure_virtual.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "arch/exception_handling/panic.hpp" - -extern "C" auto __cxa_pure_virtual() -> void -{ - teachos::arch::exception_handling::panic("Runtime", "Tried to call a pure virtual function!"); -} diff --git a/arch/x86_64/src/interrupt_handling/generic_interrupt_handler.cpp b/arch/x86_64/src/interrupt_handling/generic_interrupt_handler.cpp deleted file mode 100644 index 9d061a8..0000000 --- a/arch/x86_64/src/interrupt_handling/generic_interrupt_handler.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "arch/interrupt_handling/generic_interrupt_handler.hpp" - -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::interrupt_handling -{ - auto generic_interrupt_handler(interrupt_frame * frame) -> void - { - (void)frame; - video::vga::text::write("An Interrupt occurred.", video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - } -} // namespace teachos::arch::interrupt_handling diff --git a/arch/x86_64/src/kernel/cpu/call.cpp b/arch/x86_64/src/kernel/cpu/call.cpp deleted file mode 100644 index 98fa248..0000000 --- a/arch/x86_64/src/kernel/cpu/call.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "arch/kernel/cpu/call.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto call(far_pointer pointer) -> void - { - asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/gdtr.cpp b/arch/x86_64/src/kernel/cpu/gdtr.cpp deleted file mode 100644 index 74a4e1c..0000000 --- a/arch/x86_64/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/src/kernel/cpu/idtr.cpp b/arch/x86_64/src/kernel/cpu/idtr.cpp deleted file mode 100644 index 7aa20c1..0000000 --- a/arch/x86_64/src/kernel/cpu/idtr.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "arch/kernel/cpu/idtr.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto store_interrupt_descriptor_table() - -> context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer - { - context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer current_value{}; - asm("sidt %[output]" : [output] "=m"(current_value)); - return current_value; - } - - auto load_interrupt_descriptor_table( - context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void - { - asm volatile("lidt %[input]" : /* no output from call */ : [input] "m"(idt_pointer)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/if.cpp b/arch/x86_64/src/kernel/cpu/if.cpp deleted file mode 100644 index 60a90a3..0000000 --- a/arch/x86_64/src/kernel/cpu/if.cpp +++ /dev/null @@ -1,7 +0,0 @@ -namespace teachos::arch::kernel::cpu -{ - auto set_interrupt_flag() -> void { asm volatile("sti"); } - - auto clear_interrupt_flag() -> void { asm volatile("cli"); } - -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp deleted file mode 100644 index 9c474a1..0000000 --- a/arch/x86_64/src/kernel/cpu/msr.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "arch/kernel/cpu/msr.hpp" - -namespace teachos::arch::kernel::cpu -{ - namespace - { - auto constexpr IA32_EFER_ADDRESS = 0xC0000080; - } - - auto read_msr(uint32_t msr) -> uint64_t - { - uint32_t low, high; - asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); - return (static_cast(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::type>(flag) | efer); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp deleted file mode 100644 index b08c9c4..0000000 --- a/arch/x86_64/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 diff --git a/arch/x86_64/src/kernel/cpu/tr.cpp b/arch/x86_64/src/kernel/cpu/tr.cpp deleted file mode 100644 index a435540..0000000 --- a/arch/x86_64/src/kernel/cpu/tr.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "arch/kernel/cpu/tr.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto store_task_register() -> uint16_t - { - uint16_t current_value{}; - asm("str %[output]" : [output] "=r"(current_value)); - return current_value; - } - - auto load_task_register(uint16_t gdt_offset) -> void - { - asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(gdt_offset)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp deleted file mode 100644 index 43b5f90..0000000 --- a/arch/x86_64/src/kernel/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "arch/kernel/main.hpp" - -#include "arch/boot/pointers.hpp" -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" -#include "arch/context_switching/main.hpp" -#include "arch/kernel/cpu/if.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/global_heap_allocator.hpp" -#include "arch/memory/main.hpp" -#include "arch/memory/multiboot/reader.hpp" -#include "arch/stl/vector.hpp" -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::kernel -{ - auto stack_overflow_test(int count) -> int - { - int test[5000] = {}; - if (test[0] == 0xFFFF) - { - return count; - } - count = stack_overflow_test(count); - return count++; - } - - auto heap_test() -> void - { - auto test2 = new memory::multiboot::memory_information{}; - auto test3 = new memory::multiboot::memory_information{}; - auto test4 = *test2; - auto test5 = *test3; - test4.kernel_end = 5000; - test5.kernel_end = 3000; - auto test6 = test4.kernel_end; - auto test7 = test5.kernel_end; - auto test8 = memory::multiboot::read_multiboot2(); - if (test6 && test7 && test8.kernel_end) - { - video::vga::text::write("Heap test successful", video::vga::text::common_attributes::green_on_black); - } - test2->kernel_end = 2000; - test2->kernel_start = 1000; - test2->multiboot_start = 2000; - delete test2; - delete test3; - - auto test9 = new int(50); - delete test9; - } - - auto main() -> void - { - video::vga::text::clear(); - video::vga::text::cursor(false); - video::vga::text::write("TeachOS is starting up...", video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - - memory::initialize_memory_management(); - // stack_overflow_test(0); - - memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); - // heap_test(); - - auto address = memory::heap::global_heap_allocator::kmalloc(8U); - (void)address; - - context_switching::switch_to_user_mode(); - } -} // namespace teachos::arch::kernel diff --git a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp deleted file mode 100644 index a5a1b49..0000000 --- a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "arch/memory/allocator/area_frame_allocator.hpp" - -#include "arch/exception_handling/assert.hpp" - -#include -#include -#include - -namespace teachos::arch::memory::allocator -{ - area_frame_allocator::area_frame_allocator(multiboot::memory_information const & mem_info) - : next_free_frame() - , current_area(std::nullopt) - , memory_areas(mem_info.areas) - , kernel_start(physical_frame::containing_address(mem_info.kernel_start)) - , kernel_end(physical_frame::containing_address(mem_info.kernel_end)) - , multiboot_start(physical_frame::containing_address(mem_info.multiboot_start)) - , multiboot_end(physical_frame::containing_address(mem_info.multiboot_end)) - { - choose_next_area(); - } - - auto area_frame_allocator::choose_next_area() -> void - { - current_area = std::nullopt; - auto next_area_with_free_frames = memory_areas | std::views::filter([this](auto const & area) { - auto address = area.base_address + area.area_length - 1; - return physical_frame::containing_address(address) >= next_free_frame; - }); - - auto const lowest_area_with_free_frames = std::ranges::min_element( - next_area_with_free_frames, [](auto const & a, auto const & b) { return a.base_address < b.base_address; }); - - if (lowest_area_with_free_frames != next_area_with_free_frames.end()) - { - current_area = *lowest_area_with_free_frames; - // Update the `next_free_frame` according to the new memory area - auto const start_frame = physical_frame::containing_address(current_area.value().base_address); - if (next_free_frame < start_frame) - { - next_free_frame = start_frame; - } - } - } - - auto area_frame_allocator::allocate_frame() -> std::optional - { - // Only try to allocate memory if current_area is not null, because - // the current_area is null if there is no more available memory. - if (!current_area.has_value()) - { - return std::nullopt; - } - - auto const address = current_area.value().base_address + current_area.value().area_length - 1; - physical_frame current_area_last_frame = physical_frame::containing_address(address); - - if (next_free_frame > current_area_last_frame) - { - // All frames of current area are used, switch to next area. - choose_next_area(); - } - else if (next_free_frame >= kernel_start && next_free_frame <= kernel_end) - { - // `physical_frame` is used by the kernel or multiboot information structure. - next_free_frame = allocator::physical_frame{kernel_end.frame_number + 1}; - } - else if (next_free_frame >= multiboot_start && next_free_frame <= multiboot_end) - { - // `physical_frame` is used by the kernel or multiboot information structure. - next_free_frame = allocator::physical_frame{multiboot_end.frame_number + 1}; - } - else - { - // Frame is unused, increment `next_free_frame` and return it. - next_free_frame.frame_number += 1; - return next_free_frame; - } - - // `physical_frame` was not valid, try it again with the updated `next_free_frame`. - return allocate_frame(); - } - - auto area_frame_allocator::deallocate_frame(physical_frame const & physical_frame) -> void { (void)physical_frame; } -} // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp deleted file mode 100644 index 3cdf9c7..0000000 --- a/arch/x86_64/src/memory/allocator/tiny_frame_allocator.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "arch/memory/allocator/tiny_frame_allocator.hpp" - -#include "arch/exception_handling/panic.hpp" - -namespace teachos::arch::memory::allocator -{ - auto tiny_frame_allocator::allocate_frame() -> std::optional - { - for (auto & frame_option : frames) - { - if (frame_option.has_value()) - { - auto value = frame_option; - frame_option.reset(); - return value; - } - } - return std::nullopt; - } - - auto tiny_frame_allocator::deallocate_frame(physical_frame const & physical_frame) -> void - { - for (auto & frame_option : frames) - { - if (!frame_option.has_value()) - { - frame_option.emplace(physical_frame); - return; - } - } - exception_handling::panic( - "[Tiny Frame Allocator] Attempted to deallocate more than the 3 frames, that can be held"); - } -} // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/src/memory/heap/bump_allocator.cpp b/arch/x86_64/src/memory/heap/bump_allocator.cpp deleted file mode 100644 index 525f45c..0000000 --- a/arch/x86_64/src/memory/heap/bump_allocator.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "arch/memory/heap/bump_allocator.hpp" - -#include "arch/exception_handling/assert.hpp" - -#include -#include - -namespace teachos::arch::memory::heap -{ - namespace - { - template - auto saturating_add(T x, T y) -> T - requires std::is_unsigned_v - { - if (x > std::numeric_limits::max() - y) - { - return std::numeric_limits::max(); - } - T result = x + y; - return result; - } - } // namespace - - auto bump_allocator::allocate(std::size_t size) -> void * - { - // Reading the value only has to be done once, because compare_exchange_weak updates the value as well if the - // exchange failed, becuase the value was not the expected one. - auto alloc_start = next.load(std::memory_order::relaxed); - // Repeat allocation until it succeeds, has to be done, because another allocator could overtake it at any time - // causing the value to differ and the calculation to have to be redone. - for (;;) - { - auto const alloc_end = saturating_add(alloc_start, size); - arch::exception_handling::assert(alloc_end <= heap_end, "[Heap Allocator] Out of memory"); - // Check if the atomic value is still the one initally loaded, if it isn't we have been overtaken by another - // thread and need to redo the calculation. Spurious failure by weak can be ignored, because the whole allocation - // is wrapped in an infinite for loop so a failure that wasn't actually one will simply be retried until it works. - auto const updated = next.compare_exchange_weak(alloc_start, alloc_end, std::memory_order::relaxed); - if (updated) - { - return reinterpret_cast(alloc_start); - } - } - } - - auto bump_allocator::deallocate(void * pointer) noexcept -> void - { - if (pointer) - { - } - } - -} // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp deleted file mode 100644 index 35cd623..0000000 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "arch/memory/heap/global_heap_allocator.hpp" - -#include "arch/context_switching/syscall/main.hpp" -#include "arch/exception_handling/assert.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/linked_list_allocator.hpp" -#include "arch/memory/heap/user_heap_allocator.hpp" - -namespace teachos::arch::memory::heap -{ - namespace - { - constexpr char NOT_REGISTRED_ERROR_MESSAGE[] = - "Attempted to allocate or deallocate using the global_heap_allocator before " - "register_heap_allocation_type was called."; - constexpr uint16_t KERNEL_CODE_INDEX = 1U; - - [[gnu::section(".user_text")]] - auto os_in_kernel_mode() -> bool - { - auto const cs = teachos::arch::kernel::cpu::read_code_segment_register(); - return cs.get_index() == KERNEL_CODE_INDEX; - } - } // namespace - - heap_allocator * global_heap_allocator::kernel_allocator_instance = nullptr; - user_heap_allocator * global_heap_allocator::user_allocator_instance = nullptr; - - auto global_heap_allocator::kmalloc(std::size_t size) -> void * { return kernel().allocate(size); } - - auto global_heap_allocator::kfree(void * pointer) noexcept -> void { kernel().deallocate(pointer); } - - auto global_heap_allocator::malloc(std::size_t size) -> void * { return user().allocate(size); } - - auto global_heap_allocator::free(void * pointer) noexcept -> void { user().deallocate(pointer); } - - auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void - { - exception_handling::assert(kernel_allocator_instance == nullptr, - "Calling register_heap_allocator_type can only be done once."); - - switch (new_type) - { - case heap_allocator_type::NONE: - // Nothing to do - break; - case heap_allocator_type::BUMP: { - static bump_allocator kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; - kernel_allocator_instance = &kernel_allocator; - break; - } - case heap_allocator_type::LINKED_LIST: { - static linked_list_allocator kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; - kernel_allocator_instance = &kernel_allocator; - break; - } - } - - [[gnu::section(".user_data")]] - static user_heap_allocator user_allocator{}; - user_allocator_instance = &user_allocator; - } - - auto global_heap_allocator::kernel() -> heap_allocator & - { - exception_handling::assert(kernel_allocator_instance != nullptr, NOT_REGISTRED_ERROR_MESSAGE); - - return *kernel_allocator_instance; - } - - auto global_heap_allocator::user() -> user_heap_allocator & - { - context_switching::syscall::syscall( - context_switching::syscall::type::ASSERT, - {user_allocator_instance != nullptr, reinterpret_cast(&NOT_REGISTRED_ERROR_MESSAGE)}); - return *user_allocator_instance; - } -} // namespace teachos::arch::memory::heap - -auto operator new(std::size_t size) -> void * -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); - } - return teachos::arch::memory::heap::global_heap_allocator::malloc(size); -} - -auto operator delete(void * pointer) noexcept -> void -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator delete(void * pointer, std::size_t size) noexcept -> void -{ - (void)size; - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator new[](std::size_t size) -> void * -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); - } - return teachos::arch::memory::heap::global_heap_allocator::malloc(size); -} - -auto operator delete[](void * pointer) noexcept -> void -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator delete[](void * pointer, std::size_t size) noexcept -> void -{ - (void)size; - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} diff --git a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp deleted file mode 100644 index 00ca366..0000000 --- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "arch/memory/heap/linked_list_allocator.hpp" - -#include "arch/exception_handling/assert.hpp" -#include "arch/exception_handling/panic.hpp" - -#include - -namespace teachos::arch::memory::heap -{ - linked_list_allocator::linked_list_allocator(std::size_t heap_start, std::size_t heap_end) - : first(nullptr) - , mutex{kstd::mutex{}} - { - auto const heap_size = heap_end - heap_start; - exception_handling::assert( - heap_size > min_allocatable_size(), - "[Linked List Allocator] Total heap size can not be smaller than minimum of 16 bytes to hold " - "atleast one memory hole entry"); - first = new (reinterpret_cast(heap_start)) memory_block(heap_size, nullptr); - } - - auto linked_list_alloc