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/segment_selector.cpp2
-rw-r--r--arch/x86_64/src/context_switching/syscall/syscall_handler.cpp6
-rw-r--r--arch/x86_64/src/memory/heap/global_heap_allocator.cpp66
-rw-r--r--arch/x86_64/src/user/main.cpp6
4 files changed, 61 insertions, 19 deletions
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 (;;)