Skip to content

Commit

Permalink
Kernel/PCI: Add a driver for the PCI VirtIO GPU device
Browse files Browse the repository at this point in the history
  • Loading branch information
supercomputer7 committed Mar 15, 2024
1 parent 8419d79 commit b6433c5
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
81 changes: 81 additions & 0 deletions Kernel/Bus/PCI/Drivers/GPU/VirtIO.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2023, Liav A. <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <Kernel/Bus/PCI/Access.h>
#include <Kernel/Bus/PCI/Drivers/Driver.h>
#include <Kernel/Bus/VirtIO/Transport/PCIe/TransportLink.h>
#include <Kernel/Devices/GPU/VirtIO/GraphicsAdapter.h>

namespace Kernel::PCI {

class VirtIOGPUDriver final : public PCI::Driver {
public:
static void init();

VirtIOGPUDriver()
: PCI::Driver("VirtIOGPUDriver"sv)
{
}

virtual ErrorOr<void> probe(PCI::Device&) override;
virtual void detach(PCI::Device&) override;
virtual ClassID class_id() const override { return PCI::ClassID::Display; }
virtual Span<HardwareIDMatch const> matches() override;

private:
IntrusiveList<&VirtIOGraphicsAdapter::m_driver_list_node> m_devices;
};

ErrorOr<void> VirtIOGPUDriver::probe(PCI::Device& pci_device)
{
auto pci_transport_link = TRY(VirtIO::PCIeTransportLink::create(pci_device));
auto device = TRY(VirtIOGraphicsAdapter::create(move(pci_transport_link)));
m_devices.append(*device);
return {};
}

void VirtIOGPUDriver::detach(PCI::Device&)
{
TODO();
}

const static HardwareIDMatch __matches[] = {
{
.subclass_code = to_underlying(PCI::Display::SubclassID::VGA),
.revision_id = Optional<RevisionID> {},
.hardware_id = {
PCI::VendorID::VirtIO,
0x1050,
},
.subsystem_id_match = Optional<HardwareIDMatch::SubsystemIDMatch> {},
.programming_interface = Optional<ProgrammingInterface> {},
},
{
.subclass_code = to_underlying(PCI::Display::SubclassID::Other),
.revision_id = Optional<RevisionID> {},
.hardware_id = {
PCI::VendorID::VirtIO,
0x1050,
},
.subsystem_id_match = Optional<HardwareIDMatch::SubsystemIDMatch> {},
.programming_interface = Optional<ProgrammingInterface> {},
},
};

Span<HardwareIDMatch const> VirtIOGPUDriver::matches()
{
return __matches;
}

void VirtIOGPUDriver::init()
{
auto driver = MUST(adopt_nonnull_ref_or_enomem(new VirtIOGPUDriver()));
PCI::Access::the().register_driver(driver);
}

PCI_DEVICE_DRIVER(VirtIOGPUDriver);

}
5 changes: 5 additions & 0 deletions Kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ set(KERNEL_SOURCES
Bus/PCI/Drivers/Audio/IntelHDA.cpp
Bus/PCI/Drivers/GPU/BochsDisplay.cpp
Bus/PCI/Drivers/GPU/Intel.cpp
Bus/PCI/Drivers/GPU/VirtIO.cpp
Bus/PCI/Drivers/GPU/VMWare.cpp
Bus/PCI/Drivers/GPU/3dfx.cpp
Bus/PCI/Drivers/Net/E1000.cpp
Expand Down Expand Up @@ -119,6 +120,10 @@ set(KERNEL_SOURCES
Devices/GPU/Intel/DisplayConnectorGroup.cpp
Devices/GPU/Intel/NativeDisplayConnector.cpp
Devices/GPU/Intel/NativeGraphicsAdapter.cpp
Devices/GPU/VirtIO/Console.cpp
Devices/GPU/VirtIO/DisplayConnector.cpp
Devices/GPU/VirtIO/GPU3DDevice.cpp
Devices/GPU/VirtIO/GraphicsAdapter.cpp
Devices/GPU/VMWare/Console.cpp
Devices/GPU/VMWare/DisplayConnector.cpp
Devices/GPU/VMWare/GraphicsAdapter.cpp
Expand Down
16 changes: 15 additions & 1 deletion Kernel/Devices/GPU/VirtIO/GraphicsAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include <AK/BinaryBufferWriter.h>
#include <Kernel/Arch/Delay.h>
#include <Kernel/Bus/PCI/API.h>
#include <Kernel/Bus/PCI/IDs.h>
#include <Kernel/Bus/VirtIO/Transport/PCIe/TransportLink.h>
#include <Kernel/Devices/DeviceManagement.h>
Expand All @@ -23,6 +22,21 @@ namespace Kernel {
#define DEVICE_EVENTS_CLEAR 0x4
#define DEVICE_NUM_SCANOUTS 0x8

ErrorOr<NonnullRefPtr<VirtIOGraphicsAdapter>> VirtIOGraphicsAdapter::create(NonnullOwnPtr<VirtIO::TransportEntity> transport_link)
{
// Setup memory transfer region
auto scratch_space_region = TRY(MM.allocate_contiguous_kernel_region(
32 * PAGE_SIZE,
"VirtGPU Scratch Space"sv,
Memory::Region::Access::ReadWrite));

auto active_context_ids = TRY(Bitmap::create(VREND_MAX_CTX, false));
auto adapter = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) VirtIOGraphicsAdapter(move(transport_link), move(active_context_ids), move(scratch_space_region))));
TRY(adapter->initialize_virtio_resources());
TRY(adapter->initialize_adapter());
return adapter;
}

ErrorOr<void> VirtIOGraphicsAdapter::initialize_adapter()
{
VERIFY(m_num_scanouts <= VIRTIO_GPU_MAX_SCANOUTS);
Expand Down
4 changes: 4 additions & 0 deletions Kernel/Devices/GPU/VirtIO/GraphicsAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <Kernel/Bus/VirtIO/Queue.h>
#include <Kernel/Devices/GPU/GPUDevice.h>
#include <Kernel/Devices/GPU/VirtIO/Protocol.h>
#include <Kernel/Library/Driver.h>

namespace Kernel {

Expand All @@ -36,7 +37,10 @@ class VirtIOGraphicsAdapter final
friend class VirtIODisplayConnector;
friend class VirtIOGPU3DDevice;

KERNEL_MAKE_DRIVER_LISTABLE(VirtIOGraphicsAdapter)
public:
static ErrorOr<NonnullRefPtr<VirtIOGraphicsAdapter>> create(NonnullOwnPtr<VirtIO::TransportEntity> transport_link);

virtual ErrorOr<void> initialize_virtio_resources() override;

ErrorOr<void> mode_set_resolution(Badge<VirtIODisplayConnector>, VirtIODisplayConnector&, size_t width, size_t height);
Expand Down

0 comments on commit b6433c5

Please sign in to comment.