mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 13:57:35 +00:00
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.
This commit is contained in:
parent
8b9c056c5a
commit
48f3d762af
5 changed files with 154 additions and 30 deletions
83
Kernel/Arch/x86/VGA/IOArbiter.cpp
Normal file
83
Kernel/Arch/x86/VGA/IOArbiter.cpp
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
Kernel/Arch/x86/VGA/IOArbiter.h
Normal file
40
Kernel/Arch/x86/VGA/IOArbiter.h
Normal file
|
@ -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 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -344,6 +344,8 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64")
|
||||||
Arch/x86/PCI/Controller/HostBridge.cpp
|
Arch/x86/PCI/Controller/HostBridge.cpp
|
||||||
Arch/x86/PCI/IDELegacyModeController.cpp
|
Arch/x86/PCI/IDELegacyModeController.cpp
|
||||||
Arch/x86/PCI/Initializer.cpp
|
Arch/x86/PCI/Initializer.cpp
|
||||||
|
|
||||||
|
Arch/x86/VGA/IOArbiter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(KERNEL_SOURCES
|
set(KERNEL_SOURCES
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <AK/Singleton.h>
|
#include <AK/Singleton.h>
|
||||||
#include <Kernel/Arch/Delay.h>
|
#include <Kernel/Arch/Delay.h>
|
||||||
#include <Kernel/Arch/x86/IO.h>
|
|
||||||
#if ARCH(I386) || ARCH(X86_64)
|
#if ARCH(I386) || ARCH(X86_64)
|
||||||
# include <Kernel/Arch/x86/Hypervisor/BochsDisplayConnector.h>
|
# include <Kernel/Arch/x86/Hypervisor/BochsDisplayConnector.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,44 +44,38 @@ UNMAP_AFTER_INIT GraphicsManagement::GraphicsManagement()
|
||||||
|
|
||||||
void GraphicsManagement::disable_vga_emulation_access_permanently()
|
void GraphicsManagement::disable_vga_emulation_access_permanently()
|
||||||
{
|
{
|
||||||
SpinlockLocker locker(m_main_vga_lock);
|
#if ARCH(I386) || ARCH(X86_64)
|
||||||
disable_vga_text_mode_console_cursor();
|
if (!m_vga_arbiter)
|
||||||
IO::out8(0x3c4, 1);
|
return;
|
||||||
u8 sr1 = IO::in8(0x3c5);
|
m_vga_arbiter->disable_vga_emulation_access_permanently({});
|
||||||
IO::out8(0x3c5, sr1 | 1 << 5);
|
#endif
|
||||||
microseconds_delay(1000);
|
|
||||||
m_vga_access_is_disabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsManagement::enable_vga_text_mode_console_cursor()
|
void GraphicsManagement::enable_vga_text_mode_console_cursor()
|
||||||
{
|
{
|
||||||
SpinlockLocker locker(m_main_vga_lock);
|
#if ARCH(I386) || ARCH(X86_64)
|
||||||
if (m_vga_access_is_disabled)
|
if (!m_vga_arbiter)
|
||||||
return;
|
return;
|
||||||
IO::out8(0x3D4, 0xA);
|
m_vga_arbiter->enable_vga_text_mode_console_cursor({});
|
||||||
IO::out8(0x3D5, 0);
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsManagement::disable_vga_text_mode_console_cursor()
|
void GraphicsManagement::disable_vga_text_mode_console_cursor()
|
||||||
{
|
{
|
||||||
SpinlockLocker locker(m_main_vga_lock);
|
#if ARCH(I386) || ARCH(X86_64)
|
||||||
if (m_vga_access_is_disabled)
|
if (!m_vga_arbiter)
|
||||||
return;
|
return;
|
||||||
IO::out8(0x3D4, 0xA);
|
m_vga_arbiter->disable_vga_text_mode_console_cursor({});
|
||||||
IO::out8(0x3D5, 0x20);
|
#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 ARCH(I386) || ARCH(X86_64)
|
||||||
if (m_vga_access_is_disabled)
|
if (!m_vga_arbiter)
|
||||||
return;
|
return;
|
||||||
enable_vga_text_mode_console_cursor();
|
m_vga_arbiter->set_vga_text_mode_cursor({}, console_width, x, y);
|
||||||
u16 value = y * console_width + x;
|
#endif
|
||||||
IO::out8(0x3d4, 0x0e);
|
|
||||||
IO::out8(0x3d5, MSB(value));
|
|
||||||
IO::out8(0x3d4, 0x0f);
|
|
||||||
IO::out8(0x3d5, LSB(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsManagement::deactivate_graphical_mode()
|
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();
|
auto graphics_subsystem_mode = kernel_command_line().graphics_subsystem_mode();
|
||||||
if (graphics_subsystem_mode == CommandLine::GraphicsSubsystemMode::Disabled) {
|
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());
|
MUST(vga_isa_bochs_display_connector->set_safe_mode_setting());
|
||||||
m_platform_board_specific_display_connector = vga_isa_bochs_display_connector;
|
m_platform_board_specific_display_connector = vga_isa_bochs_display_connector;
|
||||||
dmesgln("Graphics: Invoking manual blanking with VGA ISA ports");
|
dmesgln("Graphics: Invoking manual blanking with VGA ISA ports");
|
||||||
SpinlockLocker locker(m_main_vga_lock);
|
m_vga_arbiter->unblank_screen({});
|
||||||
IO::out8(0x3c0, 0x20);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/NonnullOwnPtr.h>
|
#include <AK/NonnullOwnPtr.h>
|
||||||
|
#include <AK/Platform.h>
|
||||||
#include <AK/Types.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/Bus/PCI/Definitions.h>
|
||||||
#include <Kernel/Graphics/Console/Console.h>
|
#include <Kernel/Graphics/Console/Console.h>
|
||||||
#include <Kernel/Graphics/DisplayConnector.h>
|
#include <Kernel/Graphics/DisplayConnector.h>
|
||||||
|
@ -61,9 +65,9 @@ private:
|
||||||
unsigned m_current_minor_number { 0 };
|
unsigned m_current_minor_number { 0 };
|
||||||
|
|
||||||
SpinlockProtected<IntrusiveList<&DisplayConnector::m_list_node>> m_display_connector_nodes { LockRank::None };
|
SpinlockProtected<IntrusiveList<&DisplayConnector::m_list_node>> m_display_connector_nodes { LockRank::None };
|
||||||
|
#if ARCH(I386) || ARCH(X86_64)
|
||||||
RecursiveSpinlock m_main_vga_lock { LockRank::None };
|
OwnPtr<VGAIOArbiter> m_vga_arbiter;
|
||||||
bool m_vga_access_is_disabled { false };
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue