aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-18 14:45:05 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-18 14:46:17 +0000
commit8d39f3f67734bf39cada370c39243e6ef33bf4a0 (patch)
tree50493df40018c2ea9587280ac8d7bc3fb42a4990 /arch
parent1b5a771a34743a2973a82de5ebdfd22da030b841 (diff)
downloadteachos-8d39f3f67734bf39cada370c39243e6ef33bf4a0.tar.xz
teachos-8d39f3f67734bf39cada370c39243e6ef33bf4a0.zip
Make new usable for both kernel and user calls
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp8
-rw-r--r--arch/x86_64/include/arch/context_switching/syscall/main.hpp3
-rw-r--r--arch/x86_64/include/arch/kernel/cpu/segment_register.hpp1
-rw-r--r--arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp6
-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
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 (;;)