summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-03-15 21:41:22 +0200
committerLinus Groh <mail@linusgroh.de>2022-03-18 09:22:10 +0000
commit0ef1137e8833fdcd7f859ec02cbf7b93f5f0c4f9 (patch)
tree6086b28e41855e4cc707149c1c264d571b683bdd
parentf9bed651300642f910835833ea47d797edf1bdd1 (diff)
downloadserenity-0ef1137e8833fdcd7f859ec02cbf7b93f5f0c4f9.zip
Kernel/Graphics: Move all VGA related methods to GraphicsManagement
This helps solving an issue when we boot with text mode screen so the Kernel initializes an early text mode console, but even after disabling it, that console can still access VGA ports. This wouldn't be a problem for emulated hardware but bare metal hardware might have a "conflict", especially if the native driver explicitly request to disable the VGA emulation.
-rw-r--r--Kernel/Graphics/Console/TextModeConsole.cpp22
-rw-r--r--Kernel/Graphics/Console/TextModeConsole.h2
-rw-r--r--Kernel/Graphics/GraphicsManagement.cpp42
-rw-r--r--Kernel/Graphics/GraphicsManagement.h10
4 files changed, 58 insertions, 18 deletions
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<Graphics::Console> 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<GenericGraphicsAdapter> m_graphics_devices;
@@ -50,7 +55,8 @@ private:
RefPtr<VGACompatibleAdapter> 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 };
};
}