diff options
8 files changed, 79 insertions, 19 deletions
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 5be449f..82719bc 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 @@ -67,6 +67,14 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table auto contains_flags(std::bitset<3U> other) const -> bool; /** + * @brief Gets the index into the global descriptor table this segment selector is pointing too. + * + * @return Underlying value of the index field, bit 3 - 16. + */ + [[gnu::section(".user_text")]] + auto get_index() const -> uint16_t; + + /** * @brief Defaulted three-way comparsion operator. */ auto operator<=>(segment_selector const & other) const -> std::strong_ordering = default; diff --git a/arch/x86_64/include/arch/context_switching/syscall/main.hpp b/arch/x86_64/include/arch/context_switching/syscall/main.hpp index 9d61f97..e391c1f 100644 --- a/arch/x86_64/include/arch/context_switching/syscall/main.hpp +++ b/arch/x86_64/include/arch/context_switching/syscall/main.hpp @@ -19,6 +19,9 @@ namespace teachos::arch::context_switching::syscall /// parameters and uses them as out parameters instead, where arg_0 is the start of the newly /// mapped heap area and arg_1 is the size of the entire area. Can be less than 100 KiB if less /// space remains. + ASSERT = 3U, /// Loads the arg_0 parameter as a boolean which needs to be true or it will print the message in + /// arg_1 parameter onto the VGA buffer screen, keep it as a nullptr if it shouldn't print anything + /// and then it halts the further execution of the application. }; /** diff --git a/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp b/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp index 36ada23..a236452 100644 --- a/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp +++ b/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp @@ -31,6 +31,7 @@ namespace teachos::arch::kernel::cpu * * @return Segment Selector pointing to the currently loaded Code Segment. */ + [[gnu::section(".user_text")]] auto read_code_segment_register() -> context_switching::interrupt_descriptor_table::segment_selector; /** diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index 6fcab6f..c98c130 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -97,16 +97,22 @@ namespace teachos::arch::memory::heap }; } // namespace teachos::arch::memory::heap +[[gnu::section(".user_text")]] auto operator new(std::size_t size) -> void *; +[[gnu::section(".user_text")]] auto operator delete(void * pointer) noexcept -> void; +[[gnu::section(".user_text")]] auto operator delete(void * pointer, std::size_t size) noexcept -> void; +[[gnu::section(".user_text")]] auto operator new[](std::size_t size) -> void *; +[[gnu::section(".user_text")]] auto operator delete[](void * pointer) noexcept -> void; +[[gnu::section(".user_text")]] auto operator delete[](void * pointer, std::size_t size) noexcept -> void; #endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP 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 8568447..27f0a3b 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 @@ -7,6 +7,8 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table 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<uint16_t const *>(this); } diff --git a/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp b/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp index 9cc6edf..cd1c8a2 100644 --- a/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp +++ b/arch/x86_64/src/context_switching/syscall/syscall_handler.cpp @@ -60,6 +60,12 @@ namespace teachos::arch::context_switching::syscall case type::EXPAND_HEAP: result = expand_user_heap(); break; + case type::ASSERT: + if (!arg_0) + { + teachos::arch::exception_handling::panic(reinterpret_cast<const char *>(arg_1)); + } + break; default: teachos::arch::exception_handling::panic("[Syscall Handler] Invalid syscall number"); break; diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index e6c268a..35cd623 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -1,12 +1,29 @@ #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; @@ -47,53 +64,72 @@ namespace teachos::arch::memory::heap auto global_heap_allocator::kernel() -> heap_allocator & { - exception_handling::assert(kernel_allocator_instance != nullptr, - "Attempted to allocate or deallocate using the global_heap_allocator before " - "register_heap_allocation_type was called."); + exception_handling::assert(kernel_allocator_instance != nullptr, NOT_REGISTRED_ERROR_MESSAGE); return *kernel_allocator_instance; } auto global_heap_allocator::user() -> user_heap_allocator & { - // TODO: Assert Method does not exist in .user_text meaning this causes a Page Fault when accessed, Make it into a - // syscall instead - // exception_handling::assert(user_allocator_instance != nullptr, - // "Attempted to allocate or deallocate using the global_heap_allocator before " - // "register_heap_allocation_type was called."); - + context_switching::syscall::syscall( + context_switching::syscall::type::ASSERT, + {user_allocator_instance != nullptr, reinterpret_cast<uint64_t>(&NOT_REGISTRED_ERROR_MESSAGE)}); return *user_allocator_instance; } } // namespace teachos::arch::memory::heap auto operator new(std::size_t size) -> void * { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); + 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 { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); + 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; - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); + 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 * { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); + 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 { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); + 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; - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); + 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/user/main.cpp b/arch/x86_64/src/user/main.cpp index e621327..8b07e4a 100644 --- a/arch/x86_64/src/user/main.cpp +++ b/arch/x86_64/src/user/main.cpp @@ -12,8 +12,7 @@ namespace teachos::arch::user { auto main() -> void { - // Test writing to VGA Buffer - char constexpr syscall_message[] = "Successfully entered user mode and wrote to VGA buffer via syscall!"; + constexpr char syscall_message[] = "Successfully entered user mode and wrote to VGA buffer via syscall!"; context_switching::syscall::syscall(context_switching::syscall::type::WRITE, {reinterpret_cast<uint64_t>(&syscall_message)}); @@ -26,8 +25,7 @@ namespace teachos::arch::user item.exchange(max_value + 2); }); - // Test user heap - auto address = memory::heap::global_heap_allocator::malloc(8U); + auto address = new uint64_t{10U}; (void)address; for (;;) |
