aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2024-10-17 13:12:29 +0200
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-10-17 13:12:29 +0200
commitb865b36b38d951de28cc4df5fa67338b8245a1c3 (patch)
tree694825047086e18855bdb34fc24698292f6258ff /arch/x86_64/src
parentd539ed1f4f26a42959bcae6ea3050b7f99f5f872 (diff)
downloadteachos-b865b36b38d951de28cc4df5fa67338b8245a1c3.tar.xz
teachos-b865b36b38d951de28cc4df5fa67338b8245a1c3.zip
Implement support for `std::terminate` via `::abort`
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/boot/boot.s13
-rw-r--r--arch/x86_64/src/exception_handling/abort.cpp17
-rw-r--r--arch/x86_64/src/exception_handling/assert.cpp16
-rw-r--r--arch/x86_64/src/exception_handling/panic.cpp23
-rw-r--r--arch/x86_64/src/kernel/main.cpp3
-rw-r--r--arch/x86_64/src/video/vga/text.cpp22
6 files changed, 77 insertions, 17 deletions
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 2aa30c6..710d4ce 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -82,6 +82,7 @@ global_descriptor_table_pointer:
* We are going to print some messages in case we panic during boot, so we are
* going to store them here as well
*/
+.global message_prefix_panic
message_prefix_panic:
.string "TeachOS Panic: "
message_not_loaded_by_multiboot2:
@@ -109,6 +110,12 @@ vga_buffer_pointer: .long 0xb8000
.align 16
.code32
+.global halt
+halt:
+1:
+ hlt
+ jmp 1b
+
/**
* Print a given panic message and then halt the machine.
*
@@ -129,7 +136,7 @@ _panic:
call _print
add $8, %esp
- hlt
+ call halt
/**
* Print a message via the VGA buffer.
@@ -189,7 +196,7 @@ _start:
lgdt (global_descriptor_table_pointer)
jmp $global_descriptor_table_code,$_transition_to_long_mode
- hlt
+ call halt
/**
* Assert that the CPU supports going into long mode.
@@ -354,4 +361,4 @@ _transition_to_long_mode:
call _init
call kernel_main
- hlt
+ call halt
diff --git a/arch/x86_64/src/exception_handling/abort.cpp b/arch/x86_64/src/exception_handling/abort.cpp
new file mode 100644
index 0000000..dc40008
--- /dev/null
+++ b/arch/x86_64/src/exception_handling/abort.cpp
@@ -0,0 +1,17 @@
+#include "arch/exception_handling/panic.hpp"
+
+#include <cstdlib>
+
+namespace teachos::arch::exception_handling
+{
+
+ /**
+ * @brief Override for the newlib abort function.
+ *
+ * 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 \ No newline at end of file
diff --git a/arch/x86_64/src/exception_handling/assert.cpp b/arch/x86_64/src/exception_handling/assert.cpp
index b55da49..86696f8 100644
--- a/arch/x86_64/src/exception_handling/assert.cpp
+++ b/arch/x86_64/src/exception_handling/assert.cpp
@@ -1,4 +1,6 @@
-#include "arch/video/vga/text.hpp"
+#include "arch/exception_handling/assert.hpp"
+
+#include "arch/exception_handling/panic.hpp"
namespace teachos::arch::exception_handling
{
@@ -9,16 +11,6 @@ namespace teachos::arch::exception_handling
return;
}
- video::vga::text::write("Assert failed: ", video::vga::text::common_attributes::green_on_black);
- video::vga::text::write(message, video::vga::text::common_attributes::green_on_black);
- for (;;)
- {
- // Trick the compiler into thinking the variable is changes at run time,
- // to prevent the while loop being optimized away
- // See
- // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can
- // for more information.
- asm volatile("" : "+g"(condition));
- }
+ panic("Assertion Violation: ", message);
}
} // namespace teachos::arch::exception_handling \ No newline at end of file
diff --git a/arch/x86_64/src/exception_handling/panic.cpp b/arch/x86_64/src/exception_handling/panic.cpp
new file mode 100644
index 0000000..56edfd5
--- /dev/null
+++ b/arch/x86_64/src/exception_handling/panic.cpp
@@ -0,0 +1,23 @@
+#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 \ No newline at end of file
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 12498d0..babe251 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -165,7 +165,6 @@ namespace teachos::arch::kernel
auto allocator = arch::memory::area_frame_allocator(kernel_start, kernel_end, multiboot_start, multiboot_end,
memory_areas, area_count);
- // WATCH OUT: using optional::value() crashes the build... I think its because of missing exception handling
auto last_allocated = allocator.allocate_frame();
auto allocated = last_allocated;
do
@@ -174,6 +173,6 @@ namespace teachos::arch::kernel
allocated = allocator.allocate_frame();
} while (allocated.has_value());
video::vga::text::write("Allocated Frames", video::vga::text::common_attributes::green_on_black);
- video::vga::text::write_number(allocated->frame_number, video::vga::text::common_attributes::green_on_black);
+ video::vga::text::write_number(allocated.value().frame_number, video::vga::text::common_attributes::green_on_black);
}
} // namespace teachos::arch::kernel
diff --git a/arch/x86_64/src/video/vga/text.cpp b/arch/x86_64/src/video/vga/text.cpp
index a613c3b..c14de16 100644
--- a/arch/x86_64/src/video/vga/text.cpp
+++ b/arch/x86_64/src/video/vga/text.cpp
@@ -13,6 +13,8 @@ namespace teachos::arch::video::vga::text
namespace
{
auto constexpr default_text_buffer_address = 0xb8000;
+ auto constexpr default_text_buffer_width = 80;
+ auto constexpr default_text_buffer_height = 25;
extern "C" std::pair<char, attribute> * vga_buffer_pointer;
auto constinit text_buffer = teachos::memory::asm_pointer{vga_buffer_pointer};
@@ -32,6 +34,26 @@ namespace teachos::arch::video::vga::text
crtc::data_port::write(vga::crtc::data_port::read() | cursor_disable_byte);
}
+ auto newline() -> void
+ {
+ auto base = reinterpret_cast<decltype(text_buffer)::pointer>(default_text_buffer_address);
+ auto & raw_buffer = *text_buffer;
+ auto current_line = (raw_buffer - base) / default_text_buffer_width;
+ auto next_line = current_line + 1;
+
+ if (next_line >= default_text_buffer_height)
+ {
+ auto begin = base + default_text_buffer_width;
+ auto end = base + default_text_buffer_width * default_text_buffer_height;
+ std::ranges::move(begin, end, base);
+ raw_buffer = base + current_line * default_text_buffer_width;
+ }
+ else
+ {
+ raw_buffer = base + next_line * default_text_buffer_width;
+ }
+ }
+
auto write_char(char code_point, attribute attribute) -> void
{
auto & p = *text_buffer;