소스 검색

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.
Liav A 4 년 전
부모
커밋
47c1a31f89

+ 3 - 3
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() { }
 

+ 9 - 6
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);
 }
 
 }

+ 3 - 3
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;

+ 19 - 12
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
+{
+    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, 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()) {
+    // 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 = y + 1;
+        m_y += 1;
         if (m_y >= max_row())
             m_y = 0;
+        return;
     }
-}
 
-void TextModeConsole::write(size_t x, size_t y, char ch, Color background, Color foreground) const
-{
-    ScopedSpinLock lock(m_vga_lock);
     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);
 }
 
 }

+ 3 - 3
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(); }

+ 1 - 1
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);
     }
 }