From 47c1a31f89a83f9120ab2d7994f5c207cade8b2a Mon Sep 17 00:00:00 2001 From: Liav A Date: Thu, 3 Jun 2021 17:41:27 +0300 Subject: [PATCH] Kernel: Support new lines when doing critical printing If we are printing strings in the critical path, handling new lines require us to break abstraction a bit to print new lines. Fixes #7562. --- Kernel/Graphics/Console/Console.h | 6 ++-- .../Graphics/Console/FramebufferConsole.cpp | 15 ++++---- Kernel/Graphics/Console/FramebufferConsole.h | 6 ++-- Kernel/Graphics/Console/TextModeConsole.cpp | 35 +++++++++++-------- Kernel/Graphics/Console/TextModeConsole.h | 6 ++-- Kernel/kprintf.cpp | 2 +- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/Kernel/Graphics/Console/Console.h b/Kernel/Graphics/Console/Console.h index 67d7ef2407e..9c3b7ec3504 100644 --- a/Kernel/Graphics/Console/Console.h +++ b/Kernel/Graphics/Console/Console.h @@ -55,9 +55,9 @@ public: virtual void show_cursor() = 0; virtual void clear(size_t x, size_t y, size_t length) const = 0; - virtual void write(size_t x, size_t y, char ch, Color background, Color foreground) const = 0; - virtual void write(size_t x, size_t y, char ch) const = 0; - virtual void write(char ch) const = 0; + virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) const = 0; + virtual void write(size_t x, size_t y, char ch, bool critical = false) const = 0; + virtual void write(char ch, bool critical = false) const = 0; virtual ~Console() { } diff --git a/Kernel/Graphics/Console/FramebufferConsole.cpp b/Kernel/Graphics/Console/FramebufferConsole.cpp index 041e605ad0d..7990993d82b 100644 --- a/Kernel/Graphics/Console/FramebufferConsole.cpp +++ b/Kernel/Graphics/Console/FramebufferConsole.cpp @@ -294,12 +294,15 @@ void FramebufferConsole::disable() m_enabled.store(false); } -void FramebufferConsole::write(size_t x, size_t y, char ch, Color background, Color foreground) const +void FramebufferConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical) const { ScopedSpinLock lock(m_lock); if (!m_enabled.load()) return; - if (ch == '\r' || ch == '\n') { + + // If we are in critical printing mode, we need to handle new lines here + // because there's no other responsible object to do that in the print call path + if (critical && (ch == '\r' || ch == '\n')) { m_x = 0; m_y += 1; if (m_y >= max_row()) @@ -339,14 +342,14 @@ void FramebufferConsole::write(size_t x, size_t y, char ch, Color background, Co } } -void FramebufferConsole::write(size_t x, size_t y, char ch) const +void FramebufferConsole::write(size_t x, size_t y, char ch, bool critical) const { - write(x, y, ch, m_default_background_color, m_default_foreground_color); + write(x, y, ch, m_default_background_color, m_default_foreground_color, critical); } -void FramebufferConsole::write(char ch) const +void FramebufferConsole::write(char ch, bool critical) const { - write(m_x, m_y, ch, m_default_background_color, m_default_foreground_color); + write(m_x, m_y, ch, m_default_background_color, m_default_foreground_color, critical); } } diff --git a/Kernel/Graphics/Console/FramebufferConsole.h b/Kernel/Graphics/Console/FramebufferConsole.h index b1ec3b98dcd..13665af1a51 100644 --- a/Kernel/Graphics/Console/FramebufferConsole.h +++ b/Kernel/Graphics/Console/FramebufferConsole.h @@ -32,9 +32,9 @@ public: virtual void show_cursor() override; virtual void clear(size_t x, size_t y, size_t length) const override; - virtual void write(size_t x, size_t y, char ch, Color background, Color foreground) const override; - virtual void write(size_t x, size_t y, char ch) const override; - virtual void write(char ch) const override; + virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) const override; + virtual void write(size_t x, size_t y, char ch, bool critical = false) const override; + virtual void write(char ch, bool critical = false) const override; virtual void enable() override; virtual void disable() override; diff --git a/Kernel/Graphics/Console/TextModeConsole.cpp b/Kernel/Graphics/Console/TextModeConsole.cpp index 68e0860f72b..25bce279c96 100644 --- a/Kernel/Graphics/Console/TextModeConsole.cpp +++ b/Kernel/Graphics/Console/TextModeConsole.cpp @@ -119,26 +119,33 @@ void TextModeConsole::clear(size_t x, size_t y, size_t length) const buf[index] = 0x0720; } } -void TextModeConsole::write(size_t x, size_t y, char ch) const +void TextModeConsole::write(size_t x, size_t y, char ch, bool critical) const { - ScopedSpinLock lock(m_vga_lock); - auto* buf = (u16*)(m_current_vga_window + (x * 2) + (y * width() * 2)); - *buf = (m_default_foreground_color << 8) | (m_default_background_color << 12) | ch; - m_x = x + 1; - if (m_x >= max_column()) { - m_x = 0; - m_y = y + 1; - if (m_y >= max_row()) - m_y = 0; - } + write(x, y, ch, m_default_background_color, m_default_foreground_color, critical); } -void TextModeConsole::write(size_t x, size_t y, char ch, Color background, Color foreground) const +void TextModeConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical) const { ScopedSpinLock lock(m_vga_lock); + // If we are in critical printing mode, we need to handle new lines here + // 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 + ScopedSpinLock main_lock(GraphicsManagement::the().main_vga_lock()); + IO::out8(0x3D4, 0xA); + IO::out8(0x3D5, 0x20); + + m_x = 0; + m_y += 1; + if (m_y >= max_row()) + m_y = 0; + return; + } + auto* buf = (u16*)(m_current_vga_window + (x * 2) + (y * width() * 2)); *buf = foreground << 8 | background << 12 | ch; m_x = x + 1; + if (m_x >= max_column()) { m_x = 0; m_y = y + 1; @@ -164,9 +171,9 @@ void TextModeConsole::set_vga_start_row(u16 row) IO::out8(0x3d5, LSB(m_current_vga_start_address)); } -void TextModeConsole::write(char ch) const +void TextModeConsole::write(char ch, bool critical) const { - write(m_x, m_y, ch); + write(m_x, m_y, ch, critical); } } diff --git a/Kernel/Graphics/Console/TextModeConsole.h b/Kernel/Graphics/Console/TextModeConsole.h index 7366f739875..9f1c567beee 100644 --- a/Kernel/Graphics/Console/TextModeConsole.h +++ b/Kernel/Graphics/Console/TextModeConsole.h @@ -25,9 +25,9 @@ public: virtual void hide_cursor() override; virtual void show_cursor() override; virtual void clear(size_t x, size_t y, size_t length) const override; - virtual void write(size_t x, size_t y, char ch) const override; - virtual void write(size_t x, size_t y, char ch, Color background, Color foreground) const override; - virtual void write(char ch) const override; + virtual void write(size_t x, size_t y, char ch, bool critical = false) const override; + virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) const override; + virtual void write(char ch, bool critical = false) const override; virtual void enable() override { } virtual void disable() override { VERIFY_NOT_REACHED(); } diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp index 9e3e3e0cc53..96a43455528 100644 --- a/Kernel/kprintf.cpp +++ b/Kernel/kprintf.cpp @@ -77,7 +77,7 @@ static void critical_console_out(char ch) // We emit chars directly to the string. this is necessary in few cases, // especially when we want to avoid any memory allocations... if (GraphicsManagement::is_initialized() && GraphicsManagement::the().console()) { - GraphicsManagement::the().console()->write(ch); + GraphicsManagement::the().console()->write(ch, true); } }