diff options
author | Liav A <liavalb@gmail.com> | 2022-04-30 14:35:22 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-05-05 20:55:57 +0200 |
commit | f15b93c9a1b32a362d40448c52dfd3e838aced68 (patch) | |
tree | dcccd8499998b57ad80886a077317da46c59b43e | |
parent | c27c414ed1728a16b7ee3c1ebf1353127a700569 (diff) | |
download | serenity-f15b93c9a1b32a362d40448c52dfd3e838aced68.zip |
Kernel/Graphics: Use DisplayConnector design with generic framebuffers
-rw-r--r-- | Kernel/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Kernel/Graphics/Console/VGAConsole.h | 2 | ||||
-rw-r--r-- | Kernel/Graphics/GraphicsManagement.cpp | 2 | ||||
-rw-r--r-- | Kernel/Graphics/GraphicsManagement.h | 2 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/DisplayConnector.cpp | 78 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/DisplayConnector.h | 53 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/ISAAdapter.cpp | 24 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/ISAAdapter.h | 14 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/PCIAdapter.cpp | 51 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/PCIAdapter.h | 19 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/VGACompatibleAdapter.cpp | 20 | ||||
-rw-r--r-- | Kernel/Graphics/VGA/VGACompatibleAdapter.h | 40 | ||||
-rw-r--r-- | Kernel/Graphics/VGACompatibleAdapter.h | 35 |
13 files changed, 203 insertions, 139 deletions
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index c2418966b6..94358be3fa 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -87,8 +87,10 @@ set(KERNEL_SOURCES Graphics/GraphicsManagement.cpp Graphics/Intel/NativeDisplayConnector.cpp Graphics/Intel/NativeGraphicsAdapter.cpp + Graphics/VGA/DisplayConnector.cpp Graphics/VGA/ISAAdapter.cpp Graphics/VGA/PCIAdapter.cpp + Graphics/VGA/VGACompatibleAdapter.cpp Graphics/VirtIOGPU/DisplayConnector.cpp Graphics/VirtIOGPU/Console.cpp Graphics/VirtIOGPU/GPU3DDevice.cpp diff --git a/Kernel/Graphics/Console/VGAConsole.h b/Kernel/Graphics/Console/VGAConsole.h index f9ff5a2438..0b297163e9 100644 --- a/Kernel/Graphics/Console/VGAConsole.h +++ b/Kernel/Graphics/Console/VGAConsole.h @@ -9,7 +9,7 @@ #include <AK/RefCounted.h> #include <AK/Types.h> #include <Kernel/Graphics/Console/Console.h> -#include <Kernel/Graphics/VGACompatibleAdapter.h> +#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> namespace Kernel::Graphics { class VGAConsole : public Console { diff --git a/Kernel/Graphics/GraphicsManagement.cpp b/Kernel/Graphics/GraphicsManagement.cpp index f8c526f496..1d2cf0516c 100644 --- a/Kernel/Graphics/GraphicsManagement.cpp +++ b/Kernel/Graphics/GraphicsManagement.cpp @@ -15,7 +15,7 @@ #include <Kernel/Graphics/Intel/NativeGraphicsAdapter.h> #include <Kernel/Graphics/VGA/ISAAdapter.h> #include <Kernel/Graphics/VGA/PCIAdapter.h> -#include <Kernel/Graphics/VGACompatibleAdapter.h> +#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> #include <Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h> #include <Kernel/Memory/AnonymousVMObject.h> #include <Kernel/Multiboot.h> diff --git a/Kernel/Graphics/GraphicsManagement.h b/Kernel/Graphics/GraphicsManagement.h index b730d4012a..0bbbb6fc25 100644 --- a/Kernel/Graphics/GraphicsManagement.h +++ b/Kernel/Graphics/GraphicsManagement.h @@ -14,7 +14,7 @@ #include <Kernel/Graphics/Console/Console.h> #include <Kernel/Graphics/DisplayConnector.h> #include <Kernel/Graphics/GenericGraphicsAdapter.h> -#include <Kernel/Graphics/VGACompatibleAdapter.h> +#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> #include <Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h> #include <Kernel/Memory/Region.h> diff --git a/Kernel/Graphics/VGA/DisplayConnector.cpp b/Kernel/Graphics/VGA/DisplayConnector.cpp new file mode 100644 index 0000000000..c83f3fbc4c --- /dev/null +++ b/Kernel/Graphics/VGA/DisplayConnector.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Arch/x86/IO.h> +#include <Kernel/Debug.h> +#include <Kernel/Devices/DeviceManagement.h> +#include <Kernel/Graphics/Console/ContiguousFramebufferConsole.h> +#include <Kernel/Graphics/GraphicsManagement.h> +#include <Kernel/Graphics/VGA/DisplayConnector.h> + +namespace Kernel { + +NonnullRefPtr<GenericDisplayConnector> GenericDisplayConnector::must_create_with_preset_resolution(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch) +{ + auto device_or_error = DeviceManagement::try_create_device<GenericDisplayConnector>(framebuffer_address, width, height, pitch); + VERIFY(!device_or_error.is_error()); + auto connector = device_or_error.release_value(); + MUST(connector->create_attached_framebuffer_console()); + MUST(connector->initialize_edid_for_generic_monitor()); + return connector; +} + +GenericDisplayConnector::GenericDisplayConnector(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch) + : DisplayConnector() + , m_framebuffer_address(framebuffer_address) +{ + m_current_mode_setting.horizontal_active = width; + m_current_mode_setting.vertical_active = height; + m_current_mode_setting.horizontal_stride = pitch; +} + +ErrorOr<void> GenericDisplayConnector::create_attached_framebuffer_console() +{ + auto width = m_current_mode_setting.horizontal_active; + auto height = m_current_mode_setting.vertical_active; + auto pitch = m_current_mode_setting.horizontal_stride; + + auto rounded_size = TRY(Memory::page_round_up(pitch * height)); + m_framebuffer_region = TRY(MM.allocate_kernel_region(m_framebuffer_address.page_base(), rounded_size, "Framebuffer"sv, Memory::Region::Access::ReadWrite)); + [[maybe_unused]] auto result = m_framebuffer_region->set_write_combine(true); + m_framebuffer_data = m_framebuffer_region->vaddr().offset(m_framebuffer_address.offset_in_page()).as_ptr(); + m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(m_framebuffer_address, width, height, pitch); + GraphicsManagement::the().set_console(*m_framebuffer_console); + return {}; +} + +ErrorOr<size_t> GenericDisplayConnector::write_to_first_surface(u64 offset, UserOrKernelBuffer const& buffer, size_t length) +{ + VERIFY(m_control_lock.is_locked()); + if (offset + length > m_framebuffer_region->size()) + return Error::from_errno(EOVERFLOW); + TRY(buffer.read(m_framebuffer_data + offset, 0, length)); + return length; +} + +void GenericDisplayConnector::enable_console() +{ + VERIFY(m_control_lock.is_locked()); + VERIFY(m_framebuffer_console); + m_framebuffer_console->enable(); +} + +void GenericDisplayConnector::disable_console() +{ + VERIFY(m_control_lock.is_locked()); + VERIFY(m_framebuffer_console); + m_framebuffer_console->disable(); +} + +ErrorOr<void> GenericDisplayConnector::flush_first_surface() +{ + return Error::from_errno(ENOTSUP); +} + +} diff --git a/Kernel/Graphics/VGA/DisplayConnector.h b/Kernel/Graphics/VGA/DisplayConnector.h new file mode 100644 index 0000000000..e2c7a7e3f6 --- /dev/null +++ b/Kernel/Graphics/VGA/DisplayConnector.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/RefPtr.h> +#include <AK/Try.h> +#include <Kernel/Graphics/Console/GenericFramebufferConsole.h> +#include <Kernel/Graphics/DisplayConnector.h> +#include <Kernel/Locking/Spinlock.h> +#include <Kernel/Memory/TypedMapping.h> + +namespace Kernel { + +class GenericDisplayConnector + : public DisplayConnector { + friend class DeviceManagement; + +public: + static NonnullRefPtr<GenericDisplayConnector> must_create_with_preset_resolution(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch); + +protected: + ErrorOr<void> create_attached_framebuffer_console(); + + GenericDisplayConnector(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch); + + virtual bool mutable_mode_setting_capable() const override final { return false; } + virtual bool double_framebuffering_capable() const override { return false; } + virtual ErrorOr<void> set_mode_setting(ModeSetting const&) override { return Error::from_errno(ENOTSUP); } + virtual ErrorOr<void> set_safe_mode_setting() override { return {}; } + virtual ErrorOr<void> set_y_offset(size_t) override { return Error::from_errno(ENOTSUP); } + virtual ErrorOr<void> unblank() override { return Error::from_errno(ENOTSUP); } + + virtual bool partial_flush_support() const override final { return false; } + virtual bool flush_support() const override final { return false; } + // Note: This is possibly a paravirtualized hardware, but since we don't know, we assume there's no refresh rate... + virtual bool refresh_rate_support() const override final { return false; } + + virtual ErrorOr<size_t> write_to_first_surface(u64 offset, UserOrKernelBuffer const&, size_t length) override final; + virtual ErrorOr<void> flush_first_surface() override final; + + virtual void enable_console() override final; + virtual void disable_console() override final; + + const PhysicalAddress m_framebuffer_address; + RefPtr<Graphics::GenericFramebufferConsole> m_framebuffer_console; + OwnPtr<Memory::Region> m_framebuffer_region; + u8* m_framebuffer_data {}; +}; +} diff --git a/Kernel/Graphics/VGA/ISAAdapter.cpp b/Kernel/Graphics/VGA/ISAAdapter.cpp index 04796bc579..a7345e7fdd 100644 --- a/Kernel/Graphics/VGA/ISAAdapter.cpp +++ b/Kernel/Graphics/VGA/ISAAdapter.cpp @@ -23,28 +23,4 @@ UNMAP_AFTER_INIT ISAVGAAdapter::ISAVGAAdapter() GraphicsManagement::the().set_console(*m_framebuffer_console); } -void ISAVGAAdapter::enable_consoles() -{ - VERIFY(m_framebuffer_console); - m_framebuffer_console->enable(); -} -void ISAVGAAdapter::disable_consoles() -{ - VERIFY(m_framebuffer_console); - m_framebuffer_console->disable(); -} - -void ISAVGAAdapter::initialize_framebuffer_devices() -{ -} - -bool ISAVGAAdapter::try_to_set_resolution(size_t, size_t, size_t) -{ - return false; -} -bool ISAVGAAdapter::set_y_offset(size_t, size_t) -{ - return false; -} - } diff --git a/Kernel/Graphics/VGA/ISAAdapter.h b/Kernel/Graphics/VGA/ISAAdapter.h index 184ded11a1..8ca0623c14 100644 --- a/Kernel/Graphics/VGA/ISAAdapter.h +++ b/Kernel/Graphics/VGA/ISAAdapter.h @@ -11,6 +11,7 @@ #include <Kernel/Graphics/Console/Console.h> #include <Kernel/Graphics/FramebufferDevice.h> #include <Kernel/Graphics/GenericGraphicsAdapter.h> +#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> #include <Kernel/PhysicalAddress.h> namespace Kernel { @@ -21,21 +22,8 @@ class ISAVGAAdapter final : public VGACompatibleAdapter { public: static NonnullRefPtr<ISAVGAAdapter> initialize(); - // Note: We simply don't support old VGA framebuffer modes (like the 320x200 256-colors one) - virtual bool framebuffer_devices_initialized() const override { return false; } - - virtual bool try_to_set_resolution(size_t output_port_index, size_t width, size_t height) override; - virtual bool set_y_offset(size_t output_port_index, size_t y) override; - private: ISAVGAAdapter(); - - // ^GenericGraphicsAdapter - virtual void initialize_framebuffer_devices() override; - - virtual void enable_consoles() override; - virtual void disable_consoles() override; - RefPtr<Graphics::Console> m_framebuffer_console; }; } diff --git a/Kernel/Graphics/VGA/PCIAdapter.cpp b/Kernel/Graphics/VGA/PCIAdapter.cpp index d9aa117555..98f53a85e9 100644 --- a/Kernel/Graphics/VGA/PCIAdapter.cpp +++ b/Kernel/Graphics/VGA/PCIAdapter.cpp @@ -12,61 +12,22 @@ namespace Kernel { -UNMAP_AFTER_INIT NonnullRefPtr<PCIVGACompatibleAdapter> PCIVGACompatibleAdapter::initialize_with_preset_resolution(PCI::DeviceIdentifier const& pci_device_identifier, PhysicalAddress m_framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch) +UNMAP_AFTER_INIT NonnullRefPtr<PCIVGACompatibleAdapter> PCIVGACompatibleAdapter::initialize_with_preset_resolution(PCI::DeviceIdentifier const& pci_device_identifier, PhysicalAddress framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch) { - return adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address(), m_framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch)); + auto adapter = adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address())); + adapter->initialize_display_connector_with_preset_resolution(framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch); + return adapter; } UNMAP_AFTER_INIT NonnullRefPtr<PCIVGACompatibleAdapter> PCIVGACompatibleAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier) { - return adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address())); -} - -UNMAP_AFTER_INIT void PCIVGACompatibleAdapter::initialize_framebuffer_devices() -{ - // We might not have any pre-set framebuffer, so if that's the case - don't try to initialize one. - if (m_framebuffer_address.is_null()) - return; - VERIFY(m_framebuffer_width); - VERIFY(m_framebuffer_width != 0); - VERIFY(m_framebuffer_height != 0); - VERIFY(m_framebuffer_pitch != 0); - m_framebuffer_device = FramebufferDevice::create(*this, m_framebuffer_address, m_framebuffer_width, m_framebuffer_height, m_framebuffer_pitch); - // FIXME: Would be nice to be able to return ErrorOr<void> here. - VERIFY(!m_framebuffer_device->try_to_initialize().is_error()); + auto adapter = adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address())); + return adapter; } UNMAP_AFTER_INIT PCIVGACompatibleAdapter::PCIVGACompatibleAdapter(PCI::Address address) : PCI::Device(address) { - m_framebuffer_console = Graphics::TextModeConsole::initialize(); - GraphicsManagement::the().set_console(*m_framebuffer_console); -} - -UNMAP_AFTER_INIT PCIVGACompatibleAdapter::PCIVGACompatibleAdapter(PCI::Address address, PhysicalAddress framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch) - : PCI::Device(address) - , m_framebuffer_address(framebuffer_address) - , m_framebuffer_width(framebuffer_width) - , m_framebuffer_height(framebuffer_height) - , m_framebuffer_pitch(framebuffer_pitch) -{ - m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch); - GraphicsManagement::the().set_console(*m_framebuffer_console); -} - -void PCIVGACompatibleAdapter::enable_consoles() -{ - VERIFY(m_framebuffer_console); - if (m_framebuffer_device) - m_framebuffer_device->deactivate_writes(); - m_framebuffer_console->enable(); -} -void PCIVGACompatibleAdapter::disable_consoles() -{ - VERIFY(m_framebuffer_device); - VERIFY(m_framebuffer_console); - m_framebuffer_console->disable(); - m_framebuffer_device->activate_writes(); } } diff --git a/Kernel/Graphics/VGA/PCIAdapter.h b/Kernel/Graphics/VGA/PCIAdapter.h index 68ced2e3b0..94241faf25 100644 --- a/Kernel/Graphics/VGA/PCIAdapter.h +++ b/Kernel/Graphics/VGA/PCIAdapter.h @@ -21,26 +21,7 @@ public: static NonnullRefPtr<PCIVGACompatibleAdapter> initialize_with_preset_resolution(PCI::DeviceIdentifier const&, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch); static NonnullRefPtr<PCIVGACompatibleAdapter> initialize(PCI::DeviceIdentifier const&); - virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); } - protected: explicit PCIVGACompatibleAdapter(PCI::Address); - -private: - PCIVGACompatibleAdapter(PCI::Address, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch); - - // ^GenericGraphicsAdapter - virtual void initialize_framebuffer_devices() override; - - virtual void enable_consoles() override; - virtual void disable_consoles() override; - -protected: - PhysicalAddress m_framebuffer_address; - size_t m_framebuffer_width { 0 }; - size_t m_framebuffer_height { 0 }; - size_t m_framebuffer_pitch { 0 }; - - RefPtr<FramebufferDevice> m_framebuffer_device; }; } diff --git a/Kernel/Graphics/VGA/VGACompatibleAdapter.cpp b/Kernel/Graphics/VGA/VGACompatibleAdapter.cpp new file mode 100644 index 0000000000..2c4e1dccae --- /dev/null +++ b/Kernel/Graphics/VGA/VGACompatibleAdapter.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Graphics/Console/ContiguousFramebufferConsole.h> +#include <Kernel/Graphics/Console/TextModeConsole.h> +#include <Kernel/Graphics/GraphicsManagement.h> +#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> +#include <Kernel/Sections.h> + +namespace Kernel { + +void VGACompatibleAdapter::initialize_display_connector_with_preset_resolution(PhysicalAddress framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch) +{ + m_generic_display_connector = GenericDisplayConnector::must_create_with_preset_resolution(framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch); +} + +} diff --git a/Kernel/Graphics/VGA/VGACompatibleAdapter.h b/Kernel/Graphics/VGA/VGACompatibleAdapter.h new file mode 100644 index 0000000000..1525729e36 --- /dev/null +++ b/Kernel/Graphics/VGA/VGACompatibleAdapter.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Types.h> +#include <Kernel/Bus/PCI/Device.h> +#include <Kernel/Graphics/Console/Console.h> +#include <Kernel/Graphics/GenericGraphicsAdapter.h> +#include <Kernel/Graphics/VGA/DisplayConnector.h> +#include <Kernel/PhysicalAddress.h> + +namespace Kernel { + +class VGACompatibleAdapter : public GenericGraphicsAdapter { +public: + virtual bool vga_compatible() const override final { return true; } + +protected: + void initialize_display_connector_with_preset_resolution(PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch); + + VGACompatibleAdapter() = default; + + // ^GenericGraphicsAdapter + virtual bool modesetting_capable() const override { VERIFY_NOT_REACHED(); } + virtual bool double_framebuffering_capable() const override { VERIFY_NOT_REACHED(); } + virtual bool framebuffer_devices_initialized() const override { return false; } + virtual void initialize_framebuffer_devices() override { } + virtual void enable_consoles() override { } + virtual void disable_consoles() override { } + virtual bool try_to_set_resolution(size_t, size_t, size_t) override { VERIFY_NOT_REACHED(); } + virtual bool set_y_offset(size_t, size_t) override { VERIFY_NOT_REACHED(); } + ErrorOr<ByteBuffer> get_edid(size_t) const override { return Error::from_errno(ENOTSUP); } + + RefPtr<GenericDisplayConnector> m_generic_display_connector; +}; +} diff --git a/Kernel/Graphics/VGACompatibleAdapter.h b/Kernel/Graphics/VGACompatibleAdapter.h deleted file mode 100644 index 7e64d700ac..0000000000 --- a/Kernel/Graphics/VGACompatibleAdapter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <AK/Types.h> -#include <Kernel/Bus/PCI/Device.h> -#include <Kernel/Graphics/Console/Console.h> -#include <Kernel/Graphics/FramebufferDevice.h> -#include <Kernel/Graphics/GenericGraphicsAdapter.h> -#include <Kernel/PhysicalAddress.h> - -namespace Kernel { - -class VGACompatibleAdapter : public GenericGraphicsAdapter { -public: - virtual bool modesetting_capable() const override { return false; } - virtual bool double_framebuffering_capable() const override { return false; } - - virtual bool vga_compatible() const override final { return true; } - - virtual bool try_to_set_resolution(size_t, size_t, size_t) override { return false; } - virtual bool set_y_offset(size_t, size_t) override { return false; } - - ErrorOr<ByteBuffer> get_edid(size_t) const override { return Error::from_errno(ENOTSUP); } - -protected: - VGACompatibleAdapter() = default; - - RefPtr<Graphics::Console> m_framebuffer_console; -}; -} |