summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Arch/x86/VGA/IOArbiter.cpp83
-rw-r--r--Kernel/Arch/x86/VGA/IOArbiter.h40
-rw-r--r--Kernel/CMakeLists.txt2
-rw-r--r--Kernel/Graphics/GraphicsManagement.cpp49
-rw-r--r--Kernel/Graphics/GraphicsManagement.h10
5 files changed, 154 insertions, 30 deletions
diff --git a/Kernel/Arch/x86/VGA/IOArbiter.cpp b/Kernel/Arch/x86/VGA/IOArbiter.cpp
new file mode 100644
index 0000000000..3b6fc3c60b
--- /dev/null
+++ b/Kernel/Arch/x86/VGA/IOArbiter.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Try.h>
+#include <Kernel/Arch/Delay.h>
+#include <Kernel/Arch/x86/CPU.h>
+#include <Kernel/Arch/x86/IO.h>
+#include <Kernel/Arch/x86/VGA/IOArbiter.h>
+
+namespace Kernel {
+
+NonnullOwnPtr<VGAIOArbiter> VGAIOArbiter::must_create(Badge<GraphicsManagement>)
+{
+ return MUST(adopt_nonnull_own_or_enomem(new (nothrow) VGAIOArbiter()));
+}
+
+VGAIOArbiter::~VGAIOArbiter() = default;
+VGAIOArbiter::VGAIOArbiter() = default;
+
+void VGAIOArbiter::disable_vga_emulation_access_permanently(Badge<GraphicsManagement>)
+{
+ 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);
+ microseconds_delay(1000);
+ m_vga_access_is_disabled = true;
+}
+
+void VGAIOArbiter::enable_vga_text_mode_console_cursor(Badge<GraphicsManagement>)
+{
+ enable_vga_text_mode_console_cursor();
+}
+
+void VGAIOArbiter::enable_vga_text_mode_console_cursor()
+{
+ SpinlockLocker locker(m_main_vga_lock);
+ if (m_vga_access_is_disabled)
+ return;
+ IO::out8(0x3D4, 0xA);
+ IO::out8(0x3D5, 0);
+}
+
+void VGAIOArbiter::disable_vga_text_mode_console_cursor(Badge<GraphicsManagement>)
+{
+ disable_vga_text_mode_console_cursor();
+}
+
+void VGAIOArbiter::disable_vga_text_mode_console_cursor()
+{
+ SpinlockLocker locker(m_main_vga_lock);
+ if (m_vga_access_is_disabled)
+ return;
+ IO::out8(0x3D4, 0xA);
+ IO::out8(0x3D5, 0x20);
+}
+
+void VGAIOArbiter::unblank_screen(Badge<GraphicsManagement>)
+{
+ SpinlockLocker locker(m_main_vga_lock);
+ if (m_vga_access_is_disabled)
+ return;
+ IO::out8(0x3c0, 0x20);
+}
+
+void VGAIOArbiter::set_vga_text_mode_cursor(Badge<GraphicsManagement>, size_t console_width, size_t x, size_t y)
+{
+ 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));
+}
+
+}
diff --git a/Kernel/Arch/x86/VGA/IOArbiter.h b/Kernel/Arch/x86/VGA/IOArbiter.h
new file mode 100644
index 0000000000..711f8324d8
--- /dev/null
+++ b/Kernel/Arch/x86/VGA/IOArbiter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/NonnullOwnPtr.h>
+#include <AK/Platform.h>
+#include <AK/Types.h>
+#include <Kernel/Locking/Spinlock.h>
+
+namespace Kernel {
+
+class GraphicsManagement;
+class VGAIOArbiter {
+public:
+ static NonnullOwnPtr<VGAIOArbiter> must_create(Badge<GraphicsManagement>);
+
+ void disable_vga_emulation_access_permanently(Badge<GraphicsManagement>);
+ void enable_vga_text_mode_console_cursor(Badge<GraphicsManagement>);
+ void disable_vga_text_mode_console_cursor(Badge<GraphicsManagement>);
+ void set_vga_text_mode_cursor(Badge<GraphicsManagement>, size_t console_width, size_t x, size_t y);
+
+ void unblank_screen(Badge<GraphicsManagement>);
+
+ ~VGAIOArbiter();
+
+private:
+ VGAIOArbiter();
+
+ void disable_vga_text_mode_console_cursor();
+ void enable_vga_text_mode_console_cursor();
+
+ RecursiveSpinlock m_main_vga_lock { LockRank::None };
+ bool m_vga_access_is_disabled { false };
+};
+
+}
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index 47ec90127e..6960f979b2 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -344,6 +344,8 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64")
Arch/x86/PCI/Controller/HostBridge.cpp
Arch/x86/PCI/IDELegacyModeController.cpp
Arch/x86/PCI/Initializer.cpp
+
+ Arch/x86/VGA/IOArbiter.cpp
)
set(KERNEL_SOURCES
diff --git a/Kernel/Graphics/GraphicsManagement.cpp b/Kernel/Graphics/GraphicsManagement.cpp
index 6659b02b6f..d1e7a046ea 100644
--- a/Kernel/Graphics/GraphicsManagement.cpp
+++ b/Kernel/Graphics/GraphicsManagement.cpp
@@ -6,7 +6,6 @@
#include <AK/Singleton.h>
#include <Kernel/Arch/Delay.h>
-#include <Kernel/Arch/x86/IO.h>
#if ARCH(I386) || ARCH(X86_64)
# include <Kernel/Arch/x86/Hypervisor/BochsDisplayConnector.h>
#endif
@@ -45,44 +44,38 @@ UNMAP_AFTER_INIT GraphicsManagement::GraphicsManagement()
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);
- microseconds_delay(1000);
- m_vga_access_is_disabled = true;
+#if ARCH(I386) || ARCH(X86_64)
+ if (!m_vga_arbiter)
+ return;
+ m_vga_arbiter->disable_vga_emulation_access_permanently({});
+#endif
}
void GraphicsManagement::enable_vga_text_mode_console_cursor()
{
- SpinlockLocker locker(m_main_vga_lock);
- if (m_vga_access_is_disabled)
+#if ARCH(I386) || ARCH(X86_64)
+ if (!m_vga_arbiter)
return;
- IO::out8(0x3D4, 0xA);
- IO::out8(0x3D5, 0);
+ m_vga_arbiter->enable_vga_text_mode_console_cursor({});
+#endif
}
void GraphicsManagement::disable_vga_text_mode_console_cursor()
{
- SpinlockLocker locker(m_main_vga_lock);
- if (m_vga_access_is_disabled)
+#if ARCH(I386) || ARCH(X86_64)
+ if (!m_vga_arbiter)
return;
- IO::out8(0x3D4, 0xA);
- IO::out8(0x3D5, 0x20);
+ m_vga_arbiter->disable_vga_text_mode_console_cursor({});
+#endif
}
-void GraphicsManagement::set_vga_text_mode_cursor(size_t console_width, size_t x, size_t y)
+void GraphicsManagement::set_vga_text_mode_cursor([[maybe_unused]] size_t console_width, [[maybe_unused]] size_t x, [[maybe_unused]] size_t y)
{
- SpinlockLocker locker(m_main_vga_lock);
- if (m_vga_access_is_disabled)
+#if ARCH(I386) || ARCH(X86_64)
+ if (!m_vga_arbiter)
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));
+ m_vga_arbiter->set_vga_text_mode_cursor({}, console_width, x, y);
+#endif
}
void GraphicsManagement::deactivate_graphical_mode()
@@ -202,6 +195,9 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
}
}
});
+#if ARCH(I386) || ARCH(X86_64)
+ m_vga_arbiter = VGAIOArbiter::must_create({});
+#endif
auto graphics_subsystem_mode = kernel_command_line().graphics_subsystem_mode();
if (graphics_subsystem_mode == CommandLine::GraphicsSubsystemMode::Disabled) {
@@ -221,8 +217,7 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
MUST(vga_isa_bochs_display_connector->set_safe_mode_setting());
m_platform_board_specific_display_connector = vga_isa_bochs_display_connector;
dmesgln("Graphics: Invoking manual blanking with VGA ISA ports");
- SpinlockLocker locker(m_main_vga_lock);
- IO::out8(0x3c0, 0x20);
+ m_vga_arbiter->unblank_screen({});
return true;
}
#endif
diff --git a/Kernel/Graphics/GraphicsManagement.h b/Kernel/Graphics/GraphicsManagement.h
index 842c837d75..111f40e5ee 100644
--- a/Kernel/Graphics/GraphicsManagement.h
+++ b/Kernel/Graphics/GraphicsManagement.h
@@ -7,7 +7,11 @@
#pragma once
#include <AK/NonnullOwnPtr.h>
+#include <AK/Platform.h>
#include <AK/Types.h>
+#if ARCH(I386) || ARCH(X86_64)
+# include <Kernel/Arch/x86/VGA/IOArbiter.h>
+#endif
#include <Kernel/Bus/PCI/Definitions.h>
#include <Kernel/Graphics/Console/Console.h>
#include <Kernel/Graphics/DisplayConnector.h>
@@ -61,9 +65,9 @@ private:
unsigned m_current_minor_number { 0 };
SpinlockProtected<IntrusiveList<&DisplayConnector::m_list_node>> m_display_connector_nodes { LockRank::None };
-
- RecursiveSpinlock m_main_vga_lock { LockRank::None };
- bool m_vga_access_is_disabled { false };
+#if ARCH(I386) || ARCH(X86_64)
+ OwnPtr<VGAIOArbiter> m_vga_arbiter;
+#endif
};
}