From 7a7c5e433eb74fa19f2e159ca5442fb094ba978e Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 23 Sep 2023 02:28:25 +0300 Subject: [PATCH] Kernel/LibC: add flag to enable/disable sse support SSE support is very experimental and causes GP. I decided to make SSE not default until I get to fixing it :) --- CMakeLists.txt | 3 +++ kernel/arch/x86_64/IDT.cpp | 10 ++++++++-- kernel/include/kernel/Thread.h | 4 ++++ kernel/kernel/Syscall.cpp | 5 +++++ libc/printf_impl.cpp | 4 ++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f31e35f5..f178e01c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,9 @@ if(NOT EXISTS ${CMAKE_CXX_COMPILER}) set(CMAKE_CXX_COMPILER g++) endif() +add_compile_options(-mno-sse -mno-sse2) +add_compile_definitions(__enable_sse=0) + project(banan-os CXX) set(BANAN_BASE_SYSROOT ${CMAKE_SOURCE_DIR}/base-sysroot.tar.gz) diff --git a/kernel/arch/x86_64/IDT.cpp b/kernel/arch/x86_64/IDT.cpp index 6f5ae8a4..9369d933 100644 --- a/kernel/arch/x86_64/IDT.cpp +++ b/kernel/arch/x86_64/IDT.cpp @@ -139,10 +139,11 @@ namespace IDT extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs) { +#if __enable_sse bool from_userspace = (interrupt_stack.cs & 0b11) == 0b11; - if (from_userspace) Kernel::Thread::current().save_sse(); +#endif pid_t tid = Kernel::Scheduler::current_tid(); pid_t pid = tid ? Kernel::Process::current().pid() : 0; @@ -205,19 +206,22 @@ namespace IDT ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated); +#if __enable_sse if (from_userspace) { ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); Kernel::Thread::current().load_sse(); } +#endif } extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack) { +#if __enable_sse bool from_userspace = (interrupt_stack.cs & 0b11) == 0b11; - if (from_userspace) Kernel::Thread::current().save_sse(); +#endif if (Kernel::Scheduler::current_tid()) { @@ -240,11 +244,13 @@ namespace IDT ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated); +#if __enable_sse if (from_userspace) { ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); Kernel::Thread::current().load_sse(); } +#endif } static void flush_idt() diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index d743d078..c4115098 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -82,8 +82,10 @@ namespace Kernel bool is_userspace() const { return m_is_userspace; } +#if __enable_sse void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); } void load_sse() { asm volatile("fxrstor %0" :: "m"(m_sse_storage)); } +#endif private: Thread(pid_t tid, Process*); @@ -114,7 +116,9 @@ namespace Kernel uint64_t m_terminate_blockers { 0 }; +#if __enable_sse alignas(16) uint8_t m_sse_storage[512] {}; +#endif friend class Scheduler; }; diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index 3ea7c3df..d319e0dc 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -32,7 +32,9 @@ namespace Kernel return 0; } +#if __enable_sse Thread::current().save_sse(); +#endif asm volatile("sti"); @@ -205,7 +207,10 @@ namespace Kernel Kernel::panic("Kernel error while returning to userspace {}", ret.error()); ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); + +#if __enable_sse Thread::current().load_sse(); +#endif if (ret.is_error()) return -ret.error().get_error_code(); diff --git a/libc/printf_impl.cpp b/libc/printf_impl.cpp index 99eaa92c..367edc80 100644 --- a/libc/printf_impl.cpp +++ b/libc/printf_impl.cpp @@ -104,6 +104,7 @@ static void integer_to_string(char* buffer, T value, int base, bool upper, forma buffer[offset++] = '\0'; } +#if __enable_sse template static void floating_point_to_string(char* buffer, T value, bool upper, const format_options_t options) { @@ -227,6 +228,7 @@ static void floating_point_to_exponent_string(char* buffer, T value, bool upper, exponent_options.width = 3; integer_to_string(buffer + offset, exponent, 10, upper, exponent_options); } +#endif extern "C" int printf_impl(const char* format, va_list arguments, int (*putc_fun)(int, void*), void* data) { @@ -349,6 +351,7 @@ extern "C" int printf_impl(const char* format, va_list arguments, int (*putc_fun format++; break; } +#if __enable_sse case 'e': case 'E': { @@ -367,6 +370,7 @@ extern "C" int printf_impl(const char* format, va_list arguments, int (*putc_fun format++; break; } +#endif case 'g': case 'G': // TODO