diff options
author | Liav A <liavalb@gmail.com> | 2022-09-23 11:06:14 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-09-23 17:22:15 +0100 |
commit | 48f3d762af8694af376dd88264ce7ff38ecd3d41 (patch) | |
tree | ffd2d19ed0247393d898219c14c01770477bf722 | |
parent | 8b9c056c5a3478e071c06403f56dc3eacdb9e24f (diff) | |
download | serenity-48f3d762af8694af376dd88264ce7ff38ecd3d41.zip |
Kernel/Graphics: Move x86-specific support for VGA to Arch/x86 directory
The new VGAIOArbiter class is now responsible to conduct x86-specific
instructions to control VGA hardware from the old ISA ports. This allows
us to ensure the GraphicsManagement code doesn't use x86-specific code,
thus allowing it to be compiled within non-x86 kernel builds.
-rw-r--r-- | Kernel/Arch/x86/VGA/IOArbiter.cpp | 83 | ||||
-rw-r--r-- | Kernel/Arch/x86/VGA/IOArbiter.h | 40 | ||||
-rw-r--r-- | Kernel/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Kernel/Graphics/GraphicsManagement.cpp | 49 | ||||
-rw-r--r-- | Kernel/Graphics/GraphicsManagement.h | 10 |
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 }; } |