diff --git a/Kernel/Graphics/Console/TextModeConsole.cpp b/Kernel/Graphics/Console/TextModeConsole.cpp index 759be9ba78..d7ad8b2e1b 100644 --- a/Kernel/Graphics/Console/TextModeConsole.cpp +++ b/Kernel/Graphics/Console/TextModeConsole.cpp @@ -87,27 +87,19 @@ enum VGAColor : u8 { void TextModeConsole::set_cursor(size_t x, size_t y) { - SpinlockLocker main_lock(GraphicsManagement::the().main_vga_lock()); SpinlockLocker lock(m_vga_lock); - u16 value = y * width() + x; - IO::out8(0x3d4, 0x0e); - IO::out8(0x3d5, MSB(value)); - IO::out8(0x3d4, 0x0f); - IO::out8(0x3d5, LSB(value)); + GraphicsManagement::the().set_vga_text_mode_cursor(width(), x, y); + m_cursor_x = x; + m_cursor_y = y; } void TextModeConsole::hide_cursor() { - SpinlockLocker main_lock(GraphicsManagement::the().main_vga_lock()); SpinlockLocker lock(m_vga_lock); - IO::out8(0x3D4, 0xA); - IO::out8(0x3D5, 0x20); + GraphicsManagement::the().disable_vga_text_mode_console_cursor(); } void TextModeConsole::show_cursor() { - SpinlockLocker main_lock(GraphicsManagement::the().main_vga_lock()); - SpinlockLocker lock(m_vga_lock); - IO::out8(0x3D4, 0xA); - IO::out8(0x3D5, 0x20); + set_cursor(m_cursor_x, m_cursor_y); } void TextModeConsole::clear(size_t x, size_t y, size_t length) @@ -130,9 +122,7 @@ void TextModeConsole::write(size_t x, size_t y, char ch, Color background, Color // because there's no other responsible object to do that in the print call path if (critical && (ch == '\r' || ch == '\n')) { // Disable hardware VGA cursor - SpinlockLocker main_lock(GraphicsManagement::the().main_vga_lock()); - IO::out8(0x3D4, 0xA); - IO::out8(0x3D5, 0x20); + GraphicsManagement::the().disable_vga_text_mode_console_cursor(); m_x = 0; m_y += 1; diff --git a/Kernel/Graphics/Console/TextModeConsole.h b/Kernel/Graphics/Console/TextModeConsole.h index 1b4947653e..d9fa839176 100644 --- a/Kernel/Graphics/Console/TextModeConsole.h +++ b/Kernel/Graphics/Console/TextModeConsole.h @@ -39,6 +39,8 @@ private: TextModeConsole(); mutable Spinlock m_vga_lock; + size_t m_cursor_x { 0 }; + size_t m_cursor_y { 0 }; VirtualAddress m_current_vga_window; }; diff --git a/Kernel/Graphics/GraphicsManagement.cpp b/Kernel/Graphics/GraphicsManagement.cpp index a3c6ec67f0..b5cf05f5c9 100644 --- a/Kernel/Graphics/GraphicsManagement.cpp +++ b/Kernel/Graphics/GraphicsManagement.cpp @@ -51,6 +51,48 @@ bool GraphicsManagement::framebuffer_devices_console_only() const return kernel_command_line().are_framebuffer_devices_enabled() == CommandLine::FrameBufferDevices::ConsoleOnly; } +void GraphicsManagement::disable_vga_emulation_access_permanently() +{ + SpinlockLocker locker(m_main_vga_lock); + disable_vga_text_mode_console_cursor(); + IO::out8(0x3c4, 1); + u8 sr1 = IO::in8(0x3c5); + IO::out8(0x3c5, sr1 | 1 << 5); + IO::delay(1000); + m_vga_access_is_disabled = true; +} + +void GraphicsManagement::enable_vga_text_mode_console_cursor() const +{ + SpinlockLocker locker(m_main_vga_lock); + if (m_vga_access_is_disabled) + return; + IO::out8(0x3D4, 0xA); + IO::out8(0x3D5, 0); +} + +void GraphicsManagement::disable_vga_text_mode_console_cursor() const +{ + SpinlockLocker locker(m_main_vga_lock); + if (m_vga_access_is_disabled) + return; + IO::out8(0x3D4, 0xA); + IO::out8(0x3D5, 0x20); +} + +void GraphicsManagement::set_vga_text_mode_cursor(size_t console_width, size_t x, size_t y) const +{ + SpinlockLocker locker(m_main_vga_lock); + if (m_vga_access_is_disabled) + return; + enable_vga_text_mode_console_cursor(); + u16 value = y * console_width + x; + IO::out8(0x3d4, 0x0e); + IO::out8(0x3d5, MSB(value)); + IO::out8(0x3d4, 0x0f); + IO::out8(0x3d5, LSB(value)); +} + void GraphicsManagement::deactivate_graphical_mode() { for (auto& graphics_device : m_graphics_devices) { diff --git a/Kernel/Graphics/GraphicsManagement.h b/Kernel/Graphics/GraphicsManagement.h index 75684fe1cc..341e5c5eb1 100644 --- a/Kernel/Graphics/GraphicsManagement.h +++ b/Kernel/Graphics/GraphicsManagement.h @@ -33,7 +33,10 @@ public: bool framebuffer_devices_use_bootloader_framebuffer() const; bool framebuffer_devices_exist() const; - Spinlock& main_vga_lock() { return m_main_vga_lock; } + void set_vga_text_mode_cursor(size_t console_width, size_t x, size_t y) const; + void disable_vga_text_mode_console_cursor() const; + void disable_vga_emulation_access_permanently(); + RefPtr console() const { return m_console; } void set_console(Graphics::Console&); @@ -41,6 +44,8 @@ public: void activate_graphical_mode(); private: + void enable_vga_text_mode_console_cursor() const; + bool determine_and_initialize_graphics_device(PCI::DeviceIdentifier const&); bool determine_and_initialize_isa_graphics_device(); NonnullRefPtrVector m_graphics_devices; @@ -50,7 +55,8 @@ private: RefPtr m_vga_adapter; unsigned m_current_minor_number { 0 }; - Spinlock m_main_vga_lock; + mutable RecursiveSpinlock m_main_vga_lock; + bool m_vga_access_is_disabled { false }; }; }