mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-13 18:00:40 +00:00
Kernel/VirtIO: Move everything into the VirtIO namespace
Before of this change, many specific classes to VirtIO were in the Kernel namespace, which polluted it. Everything should be more organized now, but there's still room for improvement later.
This commit is contained in:
parent
9a03c00f45
commit
e418740645
Notes:
sideshowbarker
2024-07-18 04:59:55 +09:00
Author: https://github.com/supercomputer7 Commit: https://github.com/SerenityOS/serenity/commit/e418740645c Pull-request: https://github.com/SerenityOS/serenity/pull/9631 Reviewed-by: https://github.com/IdanHo Reviewed-by: https://github.com/ccapitalK ✅
12 changed files with 170 additions and 171 deletions
|
@ -11,9 +11,9 @@
|
|||
#include <Kernel/CommandLine.h>
|
||||
#include <Kernel/Sections.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
UNMAP_AFTER_INIT void VirtIO::detect()
|
||||
UNMAP_AFTER_INIT void detect()
|
||||
{
|
||||
if (kernel_command_line().disable_virtio())
|
||||
return;
|
||||
|
@ -25,11 +25,11 @@ UNMAP_AFTER_INIT void VirtIO::detect()
|
|||
return;
|
||||
switch (id.device_id) {
|
||||
case PCI::DeviceID::VirtIOConsole: {
|
||||
[[maybe_unused]] auto& unused = adopt_ref(*new VirtIOConsole(address)).leak_ref();
|
||||
[[maybe_unused]] auto& unused = adopt_ref(*new Console(address)).leak_ref();
|
||||
break;
|
||||
}
|
||||
case PCI::DeviceID::VirtIOEntropy: {
|
||||
[[maybe_unused]] auto& unused = adopt_ref(*new VirtIORNG(address)).leak_ref();
|
||||
[[maybe_unused]] auto& unused = adopt_ref(*new RNG(address)).leak_ref();
|
||||
break;
|
||||
}
|
||||
case PCI::DeviceID::VirtIOGPU: {
|
||||
|
@ -43,7 +43,7 @@ UNMAP_AFTER_INIT void VirtIO::detect()
|
|||
});
|
||||
}
|
||||
|
||||
StringView VirtIO::determine_device_class(const PCI::Address& address)
|
||||
StringView determine_device_class(const PCI::Address& address)
|
||||
{
|
||||
auto subsystem_device_id = PCI::get_subsystem_id(address);
|
||||
switch (subsystem_device_id) {
|
||||
|
@ -60,7 +60,7 @@ StringView VirtIO::determine_device_class(const PCI::Address& address)
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT VirtIODevice::VirtIODevice(PCI::Address address)
|
||||
UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::Address address)
|
||||
: PCI::Device(address)
|
||||
, IRQHandler(PCI::get_interrupt_line(address))
|
||||
, m_io_base(IOAddress(PCI::get_BAR0(pci_address()) & ~1))
|
||||
|
@ -116,11 +116,11 @@ UNMAP_AFTER_INIT VirtIODevice::VirtIODevice(PCI::Address address)
|
|||
set_status_bit(DEVICE_STATUS_DRIVER);
|
||||
}
|
||||
|
||||
VirtIODevice::~VirtIODevice()
|
||||
Device::~Device()
|
||||
{
|
||||
}
|
||||
|
||||
auto VirtIODevice::mapping_for_bar(u8 bar) -> MappedMMIO&
|
||||
auto Device::mapping_for_bar(u8 bar) -> MappedMMIO&
|
||||
{
|
||||
VERIFY(m_use_mmio);
|
||||
auto& mapping = m_mmio[bar];
|
||||
|
@ -133,7 +133,7 @@ auto VirtIODevice::mapping_for_bar(u8 bar) -> MappedMMIO&
|
|||
return mapping;
|
||||
}
|
||||
|
||||
void VirtIODevice::notify_queue(u16 queue_index)
|
||||
void Device::notify_queue(u16 queue_index)
|
||||
{
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: notifying about queue change at idx: {}", VirtIO::determine_device_class(pci_address()), queue_index);
|
||||
if (!m_notify_cfg)
|
||||
|
@ -142,49 +142,49 @@ void VirtIODevice::notify_queue(u16 queue_index)
|
|||
config_write16(*m_notify_cfg, get_queue(queue_index).notify_offset() * m_notify_multiplier, queue_index);
|
||||
}
|
||||
|
||||
u8 VirtIODevice::config_read8(const Configuration& config, u32 offset)
|
||||
u8 Device::config_read8(const Configuration& config, u32 offset)
|
||||
{
|
||||
return mapping_for_bar(config.bar).read<u8>(config.offset + offset);
|
||||
}
|
||||
|
||||
u16 VirtIODevice::config_read16(const Configuration& config, u32 offset)
|
||||
u16 Device::config_read16(const Configuration& config, u32 offset)
|
||||
{
|
||||
return mapping_for_bar(config.bar).read<u16>(config.offset + offset);
|
||||
}
|
||||
|
||||
u32 VirtIODevice::config_read32(const Configuration& config, u32 offset)
|
||||
u32 Device::config_read32(const Configuration& config, u32 offset)
|
||||
{
|
||||
return mapping_for_bar(config.bar).read<u32>(config.offset + offset);
|
||||
}
|
||||
|
||||
void VirtIODevice::config_write8(const Configuration& config, u32 offset, u8 value)
|
||||
void Device::config_write8(const Configuration& config, u32 offset, u8 value)
|
||||
{
|
||||
mapping_for_bar(config.bar).write(config.offset + offset, value);
|
||||
}
|
||||
|
||||
void VirtIODevice::config_write16(const Configuration& config, u32 offset, u16 value)
|
||||
void Device::config_write16(const Configuration& config, u32 offset, u16 value)
|
||||
{
|
||||
mapping_for_bar(config.bar).write(config.offset + offset, value);
|
||||
}
|
||||
|
||||
void VirtIODevice::config_write32(const Configuration& config, u32 offset, u32 value)
|
||||
void Device::config_write32(const Configuration& config, u32 offset, u32 value)
|
||||
{
|
||||
mapping_for_bar(config.bar).write(config.offset + offset, value);
|
||||
}
|
||||
|
||||
void VirtIODevice::config_write64(const Configuration& config, u32 offset, u64 value)
|
||||
void Device::config_write64(const Configuration& config, u32 offset, u64 value)
|
||||
{
|
||||
mapping_for_bar(config.bar).write(config.offset + offset, value);
|
||||
}
|
||||
|
||||
u8 VirtIODevice::read_status_bits()
|
||||
u8 Device::read_status_bits()
|
||||
{
|
||||
if (!m_common_cfg)
|
||||
return in<u8>(REG_DEVICE_STATUS);
|
||||
return config_read8(*m_common_cfg, COMMON_CFG_DEVICE_STATUS);
|
||||
}
|
||||
|
||||
void VirtIODevice::mask_status_bits(u8 status_mask)
|
||||
void Device::mask_status_bits(u8 status_mask)
|
||||
{
|
||||
m_status &= status_mask;
|
||||
if (!m_common_cfg)
|
||||
|
@ -193,7 +193,7 @@ void VirtIODevice::mask_status_bits(u8 status_mask)
|
|||
config_write8(*m_common_cfg, COMMON_CFG_DEVICE_STATUS, m_status);
|
||||
}
|
||||
|
||||
void VirtIODevice::set_status_bit(u8 status_bit)
|
||||
void Device::set_status_bit(u8 status_bit)
|
||||
{
|
||||
m_status |= status_bit;
|
||||
if (!m_common_cfg)
|
||||
|
@ -202,7 +202,7 @@ void VirtIODevice::set_status_bit(u8 status_bit)
|
|||
config_write8(*m_common_cfg, COMMON_CFG_DEVICE_STATUS, m_status);
|
||||
}
|
||||
|
||||
u64 VirtIODevice::get_device_features()
|
||||
u64 Device::get_device_features()
|
||||
{
|
||||
if (!m_common_cfg)
|
||||
return in<u32>(REG_DEVICE_FEATURES);
|
||||
|
@ -213,7 +213,7 @@ u64 VirtIODevice::get_device_features()
|
|||
return upper_bits | lower_bits;
|
||||
}
|
||||
|
||||
bool VirtIODevice::accept_device_features(u64 device_features, u64 accepted_features)
|
||||
bool Device::accept_device_features(u64 device_features, u64 accepted_features)
|
||||
{
|
||||
VERIFY(!m_did_accept_features);
|
||||
m_did_accept_features = true;
|
||||
|
@ -260,7 +260,7 @@ bool VirtIODevice::accept_device_features(u64 device_features, u64 accepted_feat
|
|||
return true;
|
||||
}
|
||||
|
||||
void VirtIODevice::reset_device()
|
||||
void Device::reset_device()
|
||||
{
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: Reset device", VirtIO::determine_device_class(pci_address()));
|
||||
if (!m_common_cfg) {
|
||||
|
@ -276,7 +276,7 @@ void VirtIODevice::reset_device()
|
|||
}
|
||||
}
|
||||
|
||||
bool VirtIODevice::setup_queue(u16 queue_index)
|
||||
bool Device::setup_queue(u16 queue_index)
|
||||
{
|
||||
if (!m_common_cfg)
|
||||
return false;
|
||||
|
@ -290,7 +290,7 @@ bool VirtIODevice::setup_queue(u16 queue_index)
|
|||
|
||||
u16 queue_notify_offset = config_read16(*m_common_cfg, COMMON_CFG_QUEUE_NOTIFY_OFF);
|
||||
|
||||
auto queue = make<VirtIOQueue>(queue_size, queue_notify_offset);
|
||||
auto queue = make<Queue>(queue_size, queue_notify_offset);
|
||||
if (queue->is_null())
|
||||
return false;
|
||||
|
||||
|
@ -304,7 +304,7 @@ bool VirtIODevice::setup_queue(u16 queue_index)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VirtIODevice::activate_queue(u16 queue_index)
|
||||
bool Device::activate_queue(u16 queue_index)
|
||||
{
|
||||
if (!m_common_cfg)
|
||||
return false;
|
||||
|
@ -316,7 +316,7 @@ bool VirtIODevice::activate_queue(u16 queue_index)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VirtIODevice::setup_queues(u16 requested_queue_count)
|
||||
bool Device::setup_queues(u16 requested_queue_count)
|
||||
{
|
||||
VERIFY(!m_did_setup_queues);
|
||||
m_did_setup_queues = true;
|
||||
|
@ -348,7 +348,7 @@ bool VirtIODevice::setup_queues(u16 requested_queue_count)
|
|||
return true;
|
||||
}
|
||||
|
||||
void VirtIODevice::finish_init()
|
||||
void Device::finish_init()
|
||||
{
|
||||
VERIFY(m_did_accept_features); // ensure features were negotiated
|
||||
VERIFY(m_did_setup_queues); // ensure queues were set-up
|
||||
|
@ -358,14 +358,14 @@ void VirtIODevice::finish_init()
|
|||
dbgln_if(VIRTIO_DEBUG, "{}: Finished initialization", VirtIO::determine_device_class(pci_address()));
|
||||
}
|
||||
|
||||
u8 VirtIODevice::isr_status()
|
||||
u8 Device::isr_status()
|
||||
{
|
||||
if (!m_isr_cfg)
|
||||
return in<u8>(REG_ISR_STATUS);
|
||||
return config_read8(*m_isr_cfg, 0);
|
||||
}
|
||||
|
||||
bool VirtIODevice::handle_irq(const RegisterState&)
|
||||
bool Device::handle_irq(const RegisterState&)
|
||||
{
|
||||
u8 isr_type = isr_status();
|
||||
if ((isr_type & (QUEUE_INTERRUPT | DEVICE_CONFIG_INTERRUPT)) == 0) {
|
||||
|
@ -392,7 +392,7 @@ bool VirtIODevice::handle_irq(const RegisterState&)
|
|||
return true;
|
||||
}
|
||||
|
||||
void VirtIODevice::supply_chain_and_notify(u16 queue_index, VirtIOQueueChain& chain)
|
||||
void Device::supply_chain_and_notify(u16 queue_index, QueueChain& chain)
|
||||
{
|
||||
auto& queue = get_queue(queue_index);
|
||||
VERIFY(&chain.queue() == &queue);
|
||||
|
|
|
@ -64,6 +64,8 @@ namespace Kernel {
|
|||
#define QUEUE_INTERRUPT 0x1
|
||||
#define DEVICE_CONFIG_INTERRUPT 0x2
|
||||
|
||||
namespace VirtIO {
|
||||
|
||||
enum class ConfigurationType : u8 {
|
||||
Common = 1,
|
||||
Notify = 2,
|
||||
|
@ -79,22 +81,18 @@ struct Configuration {
|
|||
u32 length;
|
||||
};
|
||||
|
||||
class VirtIO {
|
||||
public:
|
||||
static void detect();
|
||||
static StringView determine_device_class(const PCI::Address& address);
|
||||
};
|
||||
void detect();
|
||||
StringView determine_device_class(const PCI::Address& address);
|
||||
|
||||
class VirtIODevice
|
||||
class Device
|
||||
: public PCI::Device
|
||||
, public IRQHandler {
|
||||
public:
|
||||
virtual ~VirtIODevice() override;
|
||||
virtual ~Device() override;
|
||||
|
||||
protected:
|
||||
explicit VirtIODevice(PCI::Address);
|
||||
|
||||
virtual StringView class_name() const = 0;
|
||||
explicit Device(PCI::Address);
|
||||
struct MappedMMIO {
|
||||
OwnPtr<Memory::Region> base;
|
||||
size_t size { 0 };
|
||||
|
@ -166,13 +164,13 @@ protected:
|
|||
bool setup_queues(u16 requested_queue_count = 0);
|
||||
void finish_init();
|
||||
|
||||
VirtIOQueue& get_queue(u16 queue_index)
|
||||
Queue& get_queue(u16 queue_index)
|
||||
{
|
||||
VERIFY(queue_index < m_queue_count);
|
||||
return m_queues[queue_index];
|
||||
}
|
||||
|
||||
const VirtIOQueue& get_queue(u16 queue_index) const
|
||||
const Queue& get_queue(u16 queue_index) const
|
||||
{
|
||||
VERIFY(queue_index < m_queue_count);
|
||||
return m_queues[queue_index];
|
||||
|
@ -198,7 +196,7 @@ protected:
|
|||
return is_feature_set(m_accepted_features, feature);
|
||||
}
|
||||
|
||||
void supply_chain_and_notify(u16 queue_index, VirtIOQueueChain& chain);
|
||||
void supply_chain_and_notify(u16 queue_index, QueueChain& chain);
|
||||
|
||||
virtual bool handle_device_config_change() = 0;
|
||||
virtual void handle_queue_update(u16 queue_index) = 0;
|
||||
|
@ -227,7 +225,7 @@ private:
|
|||
u8 isr_status();
|
||||
virtual bool handle_irq(const RegisterState&) override;
|
||||
|
||||
NonnullOwnPtrVector<VirtIOQueue> m_queues;
|
||||
NonnullOwnPtrVector<Queue> m_queues;
|
||||
NonnullOwnPtrVector<Configuration> m_configs;
|
||||
const Configuration* m_common_cfg { nullptr }; // Cached due to high usage
|
||||
const Configuration* m_notify_cfg { nullptr }; // Cached due to high usage
|
||||
|
@ -243,4 +241,5 @@ private:
|
|||
bool m_did_setup_queues { false };
|
||||
u32 m_notify_multiplier { 0 };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
#include <Kernel/Bus/VirtIO/VirtIOConsole.h>
|
||||
#include <Kernel/Sections.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
unsigned VirtIOConsole::next_device_id = 0;
|
||||
unsigned Console::next_device_id = 0;
|
||||
|
||||
UNMAP_AFTER_INIT VirtIOConsole::VirtIOConsole(PCI::Address address)
|
||||
: VirtIODevice(address)
|
||||
UNMAP_AFTER_INIT Console::Console(PCI::Address address)
|
||||
: VirtIO::Device(address)
|
||||
, m_device_id(next_device_id++)
|
||||
{
|
||||
if (auto cfg = get_config(ConfigurationType::Device)) {
|
||||
bool success = negotiate_features([&](u64 supported_features) {
|
||||
u64 negotiated = 0;
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_SIZE))
|
||||
dbgln("VirtIOConsole: Console size is not yet supported!");
|
||||
dbgln("VirtIO::Console: Console size is not yet supported!");
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_MULTIPORT))
|
||||
negotiated |= VIRTIO_CONSOLE_F_MULTIPORT;
|
||||
return negotiated;
|
||||
|
@ -38,7 +38,7 @@ UNMAP_AFTER_INIT VirtIOConsole::VirtIOConsole(PCI::Address address)
|
|||
m_ports.resize(max_nr_ports);
|
||||
}
|
||||
});
|
||||
dbgln("VirtIOConsole: cols: {}, rows: {}, max nr ports {}", cols, rows, max_nr_ports);
|
||||
dbgln("VirtIO::Console: cols: {}, rows: {}, max nr ports {}", cols, rows, max_nr_ports);
|
||||
// Base receiveq/transmitq for port0 + optional control queues and 2 per every additional port
|
||||
success = setup_queues(2 + max_nr_ports > 0 ? 2 + 2 * max_nr_ports : 0);
|
||||
}
|
||||
|
@ -48,27 +48,27 @@ UNMAP_AFTER_INIT VirtIOConsole::VirtIOConsole(PCI::Address address)
|
|||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT))
|
||||
setup_multiport();
|
||||
else
|
||||
m_ports.append(new VirtIOConsolePort(0u, *this));
|
||||
m_ports.append(new VirtIO::ConsolePort(0u, *this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtIOConsole::handle_device_config_change()
|
||||
bool Console::handle_device_config_change()
|
||||
{
|
||||
dbgln("VirtIOConsole: Handle device config change");
|
||||
dbgln("VirtIO::Console: Handle device config change");
|
||||
return true;
|
||||
}
|
||||
|
||||
void VirtIOConsole::handle_queue_update(u16 queue_index)
|
||||
void Console::handle_queue_update(u16 queue_index)
|
||||
{
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIOConsole: Handle queue update {}", queue_index);
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIO::Console: Handle queue update {}", queue_index);
|
||||
|
||||
if (queue_index == CONTROL_RECEIVEQ) {
|
||||
SpinlockLocker ringbuffer_lock(m_control_receive_buffer->lock());
|
||||
auto& queue = get_queue(CONTROL_RECEIVEQ);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
size_t used;
|
||||
VirtIOQueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
QueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
|
||||
while (!popped_chain.is_empty()) {
|
||||
popped_chain.for_each([&](auto addr, auto) {
|
||||
|
@ -85,7 +85,7 @@ void VirtIOConsole::handle_queue_update(u16 queue_index)
|
|||
auto& queue = get_queue(CONTROL_TRANSMITQ);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
size_t used;
|
||||
VirtIOQueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
QueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
auto number_of_messages = 0;
|
||||
do {
|
||||
popped_chain.for_each([this](PhysicalAddress address, size_t length) {
|
||||
|
@ -106,14 +106,14 @@ void VirtIOConsole::handle_queue_update(u16 queue_index)
|
|||
}
|
||||
}
|
||||
|
||||
void VirtIOConsole::setup_multiport()
|
||||
void Console::setup_multiport()
|
||||
{
|
||||
m_control_receive_buffer = make<Memory::RingBuffer>("VirtIOConsole control receive queue", CONTROL_BUFFER_SIZE);
|
||||
m_control_transmit_buffer = make<Memory::RingBuffer>("VirtIOConsole control transmit queue", CONTROL_BUFFER_SIZE);
|
||||
|
||||
auto& queue = get_queue(CONTROL_RECEIVEQ);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
VirtIOQueueChain chain(queue);
|
||||
QueueChain chain(queue);
|
||||
auto offset = 0ul;
|
||||
|
||||
while (offset < CONTROL_BUFFER_SIZE) {
|
||||
|
@ -132,7 +132,7 @@ void VirtIOConsole::setup_multiport()
|
|||
write_control_message(ready_event);
|
||||
}
|
||||
|
||||
void VirtIOConsole::process_control_message(ControlMessage message)
|
||||
void Console::process_control_message(ControlMessage message)
|
||||
{
|
||||
switch (message.event) {
|
||||
case (u16)ControlEvent::DeviceAdd: {
|
||||
|
@ -145,7 +145,7 @@ void VirtIOConsole::process_control_message(ControlMessage message)
|
|||
return;
|
||||
}
|
||||
|
||||
m_ports.at(id) = new VirtIOConsolePort(id, *this);
|
||||
m_ports.at(id) = new VirtIO::ConsolePort(id, *this);
|
||||
ControlMessage ready_event {
|
||||
.id = static_cast<u32>(id),
|
||||
.event = (u16)ControlEvent::PortReady,
|
||||
|
@ -182,7 +182,7 @@ void VirtIOConsole::process_control_message(ControlMessage message)
|
|||
dbgln("Unhandled message event {}!", message.event);
|
||||
}
|
||||
}
|
||||
void VirtIOConsole::write_control_message(ControlMessage message)
|
||||
void Console::write_control_message(ControlMessage message)
|
||||
{
|
||||
SpinlockLocker ringbuffer_lock(m_control_transmit_buffer->lock());
|
||||
|
||||
|
@ -198,7 +198,7 @@ void VirtIOConsole::write_control_message(ControlMessage message)
|
|||
|
||||
auto& queue = get_queue(CONTROL_TRANSMITQ);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
VirtIOQueueChain chain(queue);
|
||||
QueueChain chain(queue);
|
||||
|
||||
bool did_add_buffer = chain.add_buffer_to_chain(start_of_chunk, length_of_chunk, BufferType::DeviceReadable);
|
||||
VERIFY(did_add_buffer);
|
||||
|
@ -206,7 +206,7 @@ void VirtIOConsole::write_control_message(ControlMessage message)
|
|||
supply_chain_and_notify(CONTROL_TRANSMITQ, chain);
|
||||
}
|
||||
|
||||
void VirtIOConsole::send_open_control_message(unsigned port_number, bool open)
|
||||
void Console::send_open_control_message(unsigned port_number, bool open)
|
||||
{
|
||||
ControlMessage port_open {
|
||||
.id = static_cast<u32>(port_number),
|
||||
|
|
|
@ -11,15 +11,15 @@
|
|||
#include <Kernel/Bus/VirtIO/VirtIOConsolePort.h>
|
||||
#include <Kernel/Memory/RingBuffer.h>
|
||||
|
||||
namespace Kernel {
|
||||
class VirtIOConsole
|
||||
: public VirtIODevice
|
||||
, public RefCounted<VirtIOConsole> {
|
||||
friend VirtIOConsolePort;
|
||||
namespace Kernel::VirtIO {
|
||||
class Console
|
||||
: public VirtIO::Device
|
||||
, public RefCounted<Console> {
|
||||
friend VirtIO::ConsolePort;
|
||||
|
||||
public:
|
||||
VirtIOConsole(PCI::Address);
|
||||
virtual ~VirtIOConsole() override = default;
|
||||
Console(PCI::Address);
|
||||
virtual ~Console() override = default;
|
||||
|
||||
virtual StringView purpose() const override { return class_name(); }
|
||||
|
||||
|
@ -61,7 +61,7 @@ private:
|
|||
virtual bool handle_device_config_change() override;
|
||||
virtual void handle_queue_update(u16 queue_index) override;
|
||||
|
||||
Vector<RefPtr<VirtIOConsolePort>> m_ports;
|
||||
Vector<RefPtr<ConsolePort>> m_ports;
|
||||
void setup_multiport();
|
||||
void process_control_message(ControlMessage message);
|
||||
void write_control_message(ControlMessage message);
|
||||
|
|
|
@ -8,27 +8,27 @@
|
|||
#include <Kernel/Bus/VirtIO/VirtIOConsole.h>
|
||||
#include <Kernel/Bus/VirtIO/VirtIOConsolePort.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
unsigned VirtIOConsolePort::next_device_id = 0;
|
||||
unsigned ConsolePort::next_device_id = 0;
|
||||
|
||||
VirtIOConsolePort::VirtIOConsolePort(unsigned port, VirtIOConsole& console)
|
||||
ConsolePort::ConsolePort(unsigned port, VirtIO::Console& console)
|
||||
: CharacterDevice(229, next_device_id++)
|
||||
, m_console(console)
|
||||
, m_port(port)
|
||||
{
|
||||
m_receive_buffer = make<Memory::RingBuffer>("VirtIOConsolePort Receive", RINGBUFFER_SIZE);
|
||||
m_transmit_buffer = make<Memory::RingBuffer>("VirtIOConsolePort Transmit", RINGBUFFER_SIZE);
|
||||
m_receive_buffer = make<Memory::RingBuffer>("VirtIO::ConsolePort Receive", RINGBUFFER_SIZE);
|
||||
m_transmit_buffer = make<Memory::RingBuffer>("VirtIO::ConsolePort Transmit", RINGBUFFER_SIZE);
|
||||
m_receive_queue = m_port == 0 ? 0 : m_port * 2 + 2;
|
||||
m_transmit_queue = m_port == 0 ? 1 : m_port * 2 + 3;
|
||||
init_receive_buffer();
|
||||
}
|
||||
|
||||
void VirtIOConsolePort::init_receive_buffer()
|
||||
void ConsolePort::init_receive_buffer()
|
||||
{
|
||||
auto& queue = m_console.get_queue(m_receive_queue);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
VirtIOQueueChain chain(queue);
|
||||
QueueChain chain(queue);
|
||||
|
||||
auto buffer_start = m_receive_buffer->start_of_region();
|
||||
auto did_add_buffer = chain.add_buffer_to_chain(buffer_start, RINGBUFFER_SIZE, BufferType::DeviceWritable);
|
||||
|
@ -36,15 +36,15 @@ void VirtIOConsolePort::init_receive_buffer()
|
|||
m_console.supply_chain_and_notify(m_receive_queue, chain);
|
||||
}
|
||||
|
||||
void VirtIOConsolePort::handle_queue_update(Badge<VirtIOConsole>, u16 queue_index)
|
||||
void ConsolePort::handle_queue_update(Badge<VirtIO::Console>, u16 queue_index)
|
||||
{
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIOConsolePort: Handle queue update for port {}", m_port);
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIO::ConsolePort: Handle queue update for port {}", m_port);
|
||||
VERIFY(queue_index == m_transmit_queue || queue_index == m_receive_queue);
|
||||
if (queue_index == m_receive_queue) {
|
||||
auto& queue = m_console.get_queue(m_receive_queue);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
size_t used;
|
||||
VirtIOQueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
QueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
|
||||
SpinlockLocker ringbuffer_lock(m_receive_buffer->lock());
|
||||
auto used_space = m_receive_buffer->reserve_space(used).value();
|
||||
|
@ -55,7 +55,7 @@ void VirtIOConsolePort::handle_queue_update(Badge<VirtIOConsole>, u16 queue_inde
|
|||
VERIFY(!queue.new_data_available());
|
||||
popped_chain.release_buffer_slots_to_queue();
|
||||
|
||||
VirtIOQueueChain new_chain(queue);
|
||||
QueueChain new_chain(queue);
|
||||
if (remaining_space != 0) {
|
||||
new_chain.add_buffer_to_chain(used_space.offset(used), remaining_space, BufferType::DeviceWritable);
|
||||
m_console.supply_chain_and_notify(m_receive_queue, new_chain);
|
||||
|
@ -69,7 +69,7 @@ void VirtIOConsolePort::handle_queue_update(Badge<VirtIOConsole>, u16 queue_inde
|
|||
auto& queue = m_console.get_queue(m_transmit_queue);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
size_t used;
|
||||
VirtIOQueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
QueueChain popped_chain = queue.pop_used_buffer_chain(used);
|
||||
do {
|
||||
popped_chain.for_each([this](PhysicalAddress address, size_t length) {
|
||||
m_transmit_buffer->reclaim_space(address, length);
|
||||
|
@ -82,12 +82,12 @@ void VirtIOConsolePort::handle_queue_update(Badge<VirtIOConsole>, u16 queue_inde
|
|||
}
|
||||
}
|
||||
|
||||
bool VirtIOConsolePort::can_read(const FileDescription&, size_t) const
|
||||
bool ConsolePort::can_read(const FileDescription&, size_t) const
|
||||
{
|
||||
return m_receive_buffer->used_bytes() > 0;
|
||||
}
|
||||
|
||||
KResultOr<size_t> VirtIOConsolePort::read(FileDescription& desc, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||
KResultOr<size_t> ConsolePort::read(FileDescription& desc, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return 0;
|
||||
|
@ -103,7 +103,7 @@ KResultOr<size_t> VirtIOConsolePort::read(FileDescription& desc, u64, UserOrKern
|
|||
if (m_receive_buffer_exhausted && m_receive_buffer->used_bytes() == 0) {
|
||||
auto& queue = m_console.get_queue(m_receive_queue);
|
||||
SpinlockLocker queue_lock(queue.lock());
|
||||
VirtIOQueueChain new_chain(queue);
|
||||
QueueChain new_chain(queue);
|
||||
new_chain.add_buffer_to_chain(m_receive_buffer->start_of_region(), RINGBUFFER_SIZE, BufferType::DeviceWritable);
|
||||
m_console.supply_chain_and_notify(m_receive_queue, new_chain);
|
||||
m_receive_buffer_exhausted = false;
|
||||
|
@ -112,12 +112,12 @@ KResultOr<size_t> VirtIOConsolePort::read(FileDescription& desc, u64, UserOrKern
|
|||
return bytes_copied;
|
||||
}
|
||||
|
||||
bool VirtIOConsolePort::can_write(const FileDescription&, size_t) const
|
||||
bool ConsolePort::can_write(const FileDescription&, size_t) const
|
||||
{
|
||||
return m_console.get_queue(m_transmit_queue).has_free_slots() && m_transmit_buffer->has_space();
|
||||
}
|
||||
|
||||
KResultOr<size_t> VirtIOConsolePort::write(FileDescription& desc, u64, const UserOrKernelBuffer& data, size_t size)
|
||||
KResultOr<size_t> ConsolePort::write(FileDescription& desc, u64, const UserOrKernelBuffer& data, size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return 0;
|
||||
|
@ -129,7 +129,7 @@ KResultOr<size_t> VirtIOConsolePort::write(FileDescription& desc, u64, const Use
|
|||
if (!can_write(desc, size))
|
||||
return EAGAIN;
|
||||
|
||||
VirtIOQueueChain chain(queue);
|
||||
QueueChain chain(queue);
|
||||
|
||||
size_t total_bytes_copied = 0;
|
||||
do {
|
||||
|
@ -151,12 +151,12 @@ KResultOr<size_t> VirtIOConsolePort::write(FileDescription& desc, u64, const Use
|
|||
return total_bytes_copied;
|
||||
}
|
||||
|
||||
String VirtIOConsolePort::device_name() const
|
||||
String ConsolePort::device_name() const
|
||||
{
|
||||
return String::formatted("hvc{}p{}", m_console.device_id(), m_port);
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<FileDescription>> VirtIOConsolePort::open(int options)
|
||||
KResultOr<NonnullRefPtr<FileDescription>> ConsolePort::open(int options)
|
||||
{
|
||||
if (!m_open)
|
||||
m_console.send_open_control_message(m_port, true);
|
||||
|
|
|
@ -12,21 +12,21 @@
|
|||
#include <Kernel/FileSystem/FileDescription.h>
|
||||
#include <Kernel/Memory/RingBuffer.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
class VirtIOConsole;
|
||||
class Console;
|
||||
|
||||
#define VIRTIO_CONSOLE_F_SIZE (1 << 0)
|
||||
#define VIRTIO_CONSOLE_F_MULTIPORT (1 << 1)
|
||||
#define VIRTIO_CONSOLE_F_EMERG_WRITE (1 << 2)
|
||||
|
||||
class VirtIOConsolePort
|
||||
class ConsolePort
|
||||
: public CharacterDevice {
|
||||
public:
|
||||
explicit VirtIOConsolePort(unsigned port, VirtIOConsole&);
|
||||
void handle_queue_update(Badge<VirtIOConsole>, u16 queue_index);
|
||||
explicit ConsolePort(unsigned port, VirtIO::Console&);
|
||||
void handle_queue_update(Badge<VirtIO::Console>, u16 queue_index);
|
||||
|
||||
void set_open(Badge<VirtIOConsole>, bool state) { m_open = state; }
|
||||
void set_open(Badge<VirtIO::Console>, bool state) { m_open = state; }
|
||||
bool is_open() const { return m_open; }
|
||||
|
||||
private:
|
||||
|
@ -53,7 +53,7 @@ private:
|
|||
OwnPtr<Memory::RingBuffer> m_receive_buffer;
|
||||
OwnPtr<Memory::RingBuffer> m_transmit_buffer;
|
||||
|
||||
VirtIOConsole& m_console;
|
||||
VirtIO::Console& m_console;
|
||||
unsigned m_port;
|
||||
|
||||
bool m_open { false };
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
#include <AK/Atomic.h>
|
||||
#include <Kernel/Bus/VirtIO/VirtIOQueue.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
VirtIOQueue::VirtIOQueue(u16 queue_size, u16 notify_offset)
|
||||
Queue::Queue(u16 queue_size, u16 notify_offset)
|
||||
: m_queue_size(queue_size)
|
||||
, m_notify_offset(notify_offset)
|
||||
, m_free_buffers(queue_size)
|
||||
{
|
||||
size_t size_of_descriptors = sizeof(VirtIOQueueDescriptor) * queue_size;
|
||||
size_t size_of_driver = sizeof(VirtIOQueueDriver) + queue_size * sizeof(u16);
|
||||
size_t size_of_device = sizeof(VirtIOQueueDevice) + queue_size * sizeof(VirtIOQueueDeviceItem);
|
||||
size_t size_of_descriptors = sizeof(QueueDescriptor) * queue_size;
|
||||
size_t size_of_driver = sizeof(QueueDriver) + queue_size * sizeof(u16);
|
||||
size_t size_of_device = sizeof(QueueDevice) + queue_size * sizeof(QueueDeviceItem);
|
||||
auto queue_region_size = Memory::page_round_up(size_of_descriptors + size_of_driver + size_of_device);
|
||||
if (queue_region_size <= PAGE_SIZE)
|
||||
m_queue_region = MM.allocate_kernel_region(queue_region_size, "VirtIO Queue", Memory::Region::Access::ReadWrite);
|
||||
|
@ -26,9 +26,9 @@ VirtIOQueue::VirtIOQueue(u16 queue_size, u16 notify_offset)
|
|||
// TODO: ensure alignment!!!
|
||||
u8* ptr = m_queue_region->vaddr().as_ptr();
|
||||
memset(ptr, 0, m_queue_region->size());
|
||||
m_descriptors = adopt_own_if_nonnull(reinterpret_cast<VirtIOQueueDescriptor*>(ptr));
|
||||
m_driver = adopt_own_if_nonnull(reinterpret_cast<VirtIOQueueDriver*>(ptr + size_of_descriptors));
|
||||
m_device = adopt_own_if_nonnull(reinterpret_cast<VirtIOQueueDevice*>(ptr + size_of_descriptors + size_of_driver));
|
||||
m_descriptors = adopt_own_if_nonnull(reinterpret_cast<QueueDescriptor*>(ptr));
|
||||
m_driver = adopt_own_if_nonnull(reinterpret_cast<QueueDriver*>(ptr + size_of_descriptors));
|
||||
m_device = adopt_own_if_nonnull(reinterpret_cast<QueueDevice*>(ptr + size_of_descriptors + size_of_driver));
|
||||
|
||||
for (auto i = 0; i + 1 < queue_size; i++) {
|
||||
m_descriptors[i].next = i + 1; // link all of the descriptors in a line
|
||||
|
@ -37,35 +37,35 @@ VirtIOQueue::VirtIOQueue(u16 queue_size, u16 notify_offset)
|
|||
enable_interrupts();
|
||||
}
|
||||
|
||||
VirtIOQueue::~VirtIOQueue()
|
||||
Queue::~Queue()
|
||||
{
|
||||
}
|
||||
|
||||
void VirtIOQueue::enable_interrupts()
|
||||
void Queue::enable_interrupts()
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
m_driver->flags = 0;
|
||||
}
|
||||
|
||||
void VirtIOQueue::disable_interrupts()
|
||||
void Queue::disable_interrupts()
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
m_driver->flags = 1;
|
||||
}
|
||||
|
||||
bool VirtIOQueue::new_data_available() const
|
||||
bool Queue::new_data_available() const
|
||||
{
|
||||
const auto index = AK::atomic_load(&m_device->index, AK::MemoryOrder::memory_order_relaxed);
|
||||
const auto used_tail = AK::atomic_load(&m_used_tail, AK::MemoryOrder::memory_order_relaxed);
|
||||
return index != used_tail;
|
||||
}
|
||||
|
||||
VirtIOQueueChain VirtIOQueue::pop_used_buffer_chain(size_t& used)
|
||||
QueueChain Queue::pop_used_buffer_chain(size_t& used)
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
if (!new_data_available()) {
|
||||
used = 0;
|
||||
return VirtIOQueueChain(*this);
|
||||
return QueueChain(*this);
|
||||
}
|
||||
|
||||
full_memory_barrier();
|
||||
|
@ -85,10 +85,10 @@ VirtIOQueueChain VirtIOQueue::pop_used_buffer_chain(size_t& used)
|
|||
// We are now done with this buffer chain
|
||||
m_used_tail++;
|
||||
|
||||
return VirtIOQueueChain(*this, descriptor_index, last_index, length_of_chain);
|
||||
return QueueChain(*this, descriptor_index, last_index, length_of_chain);
|
||||
}
|
||||
|
||||
void VirtIOQueue::discard_used_buffers()
|
||||
void Queue::discard_used_buffers()
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
size_t used;
|
||||
|
@ -97,7 +97,7 @@ void VirtIOQueue::discard_used_buffers()
|
|||
}
|
||||
}
|
||||
|
||||
void VirtIOQueue::reclaim_buffer_chain(u16 chain_start_index, u16 chain_end_index, size_t length_of_chain)
|
||||
void Queue::reclaim_buffer_chain(u16 chain_start_index, u16 chain_end_index, size_t length_of_chain)
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
m_descriptors[chain_end_index].next = m_free_head;
|
||||
|
@ -105,13 +105,13 @@ void VirtIOQueue::reclaim_buffer_chain(u16 chain_start_index, u16 chain_end_inde
|
|||
m_free_buffers += length_of_chain;
|
||||
}
|
||||
|
||||
bool VirtIOQueue::has_free_slots() const
|
||||
bool Queue::has_free_slots() const
|
||||
{
|
||||
const auto free_buffers = AK::atomic_load(&m_free_buffers, AK::MemoryOrder::memory_order_relaxed);
|
||||
return free_buffers > 0;
|
||||
}
|
||||
|
||||
Optional<u16> VirtIOQueue::take_free_slot()
|
||||
Optional<u16> Queue::take_free_slot()
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
if (has_free_slots()) {
|
||||
|
@ -124,14 +124,14 @@ Optional<u16> VirtIOQueue::take_free_slot()
|
|||
}
|
||||
}
|
||||
|
||||
bool VirtIOQueue::should_notify() const
|
||||
bool Queue::should_notify() const
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
auto device_flags = m_device->flags;
|
||||
return !(device_flags & VIRTQ_USED_F_NO_NOTIFY);
|
||||
}
|
||||
|
||||
bool VirtIOQueueChain::add_buffer_to_chain(PhysicalAddress buffer_start, size_t buffer_length, BufferType buffer_type)
|
||||
bool QueueChain::add_buffer_to_chain(PhysicalAddress buffer_start, size_t buffer_length, BufferType buffer_type)
|
||||
{
|
||||
VERIFY(m_queue.lock().is_locked());
|
||||
|
||||
|
@ -148,7 +148,7 @@ bool VirtIOQueueChain::add_buffer_to_chain(PhysicalAddress buffer_start, size_t
|
|||
// Set start of chain if it hasn't been set
|
||||
m_start_of_chain_index = descriptor_index.value();
|
||||
} else {
|
||||
// Link from previous element in VirtIOQueueChain
|
||||
// Link from previous element in QueueChain
|
||||
m_queue.m_descriptors[m_end_of_chain_index.value()].flags |= VIRTQ_DESC_F_NEXT;
|
||||
m_queue.m_descriptors[m_end_of_chain_index.value()].next = descriptor_index.value();
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ bool VirtIOQueueChain::add_buffer_to_chain(PhysicalAddress buffer_start, size_t
|
|||
return true;
|
||||
}
|
||||
|
||||
void VirtIOQueueChain::submit_to_queue()
|
||||
void QueueChain::submit_to_queue()
|
||||
{
|
||||
VERIFY(m_queue.lock().is_locked());
|
||||
VERIFY(m_start_of_chain_index.has_value());
|
||||
|
@ -183,7 +183,7 @@ void VirtIOQueueChain::submit_to_queue()
|
|||
m_chain_length = 0;
|
||||
}
|
||||
|
||||
void VirtIOQueueChain::release_buffer_slots_to_queue()
|
||||
void QueueChain::release_buffer_slots_to_queue()
|
||||
{
|
||||
VERIFY(m_queue.lock().is_locked());
|
||||
if (m_start_of_chain_index.has_value()) {
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
#include <Kernel/Memory/MemoryManager.h>
|
||||
#include <Kernel/Memory/ScatterGatherList.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
class Device;
|
||||
class QueueChain;
|
||||
|
||||
#define VIRTQ_DESC_F_NEXT 1
|
||||
#define VIRTQ_DESC_F_INDIRECT 4
|
||||
|
@ -23,13 +26,10 @@ enum class BufferType {
|
|||
DeviceWritable = 2
|
||||
};
|
||||
|
||||
class VirtIODevice;
|
||||
class VirtIOQueueChain;
|
||||
|
||||
class VirtIOQueue {
|
||||
class Queue {
|
||||
public:
|
||||
VirtIOQueue(u16 queue_size, u16 notify_offset);
|
||||
~VirtIOQueue();
|
||||
Queue(u16 queue_size, u16 notify_offset);
|
||||
~Queue();
|
||||
|
||||
bool is_null() const { return !m_queue_region; }
|
||||
u16 notify_offset() const { return m_notify_offset; }
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
bool new_data_available() const;
|
||||
bool has_free_slots() const;
|
||||
Optional<u16> take_free_slot();
|
||||
VirtIOQueueChain pop_used_buffer_chain(size_t& used);
|
||||
QueueChain pop_used_buffer_chain(size_t& used);
|
||||
void discard_used_buffers();
|
||||
|
||||
Spinlock<u8>& lock() { return m_lock; }
|
||||
|
@ -59,28 +59,28 @@ private:
|
|||
auto offset = FlatPtr(ptr) - m_queue_region->vaddr().get();
|
||||
return m_queue_region->physical_page(0)->paddr().offset(offset);
|
||||
}
|
||||
struct [[gnu::packed]] VirtIOQueueDescriptor {
|
||||
struct [[gnu::packed]] QueueDescriptor {
|
||||
u64 address;
|
||||
u32 length;
|
||||
u16 flags;
|
||||
u16 next;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] VirtIOQueueDriver {
|
||||
struct [[gnu::packed]] QueueDriver {
|
||||
u16 flags;
|
||||
u16 index;
|
||||
u16 rings[];
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] VirtIOQueueDeviceItem {
|
||||
struct [[gnu::packed]] QueueDeviceItem {
|
||||
u32 index;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] VirtIOQueueDevice {
|
||||
struct [[gnu::packed]] QueueDevice {
|
||||
u16 flags;
|
||||
u16 index;
|
||||
VirtIOQueueDeviceItem rings[];
|
||||
QueueDeviceItem rings[];
|
||||
};
|
||||
|
||||
const u16 m_queue_size;
|
||||
|
@ -90,23 +90,23 @@ private:
|
|||
u16 m_used_tail { 0 };
|
||||
u16 m_driver_index_shadow { 0 };
|
||||
|
||||
OwnPtr<VirtIOQueueDescriptor> m_descriptors { nullptr };
|
||||
OwnPtr<VirtIOQueueDriver> m_driver { nullptr };
|
||||
OwnPtr<VirtIOQueueDevice> m_device { nullptr };
|
||||
OwnPtr<QueueDescriptor> m_descriptors { nullptr };
|
||||
OwnPtr<QueueDriver> m_driver { nullptr };
|
||||
OwnPtr<QueueDevice> m_device { nullptr };
|
||||
OwnPtr<Memory::Region> m_queue_region;
|
||||
Spinlock<u8> m_lock;
|
||||
|
||||
friend class VirtIOQueueChain;
|
||||
friend class QueueChain;
|
||||
};
|
||||
|
||||
class VirtIOQueueChain {
|
||||
class QueueChain {
|
||||
public:
|
||||
VirtIOQueueChain(VirtIOQueue& queue)
|
||||
QueueChain(Queue& queue)
|
||||
: m_queue(queue)
|
||||
{
|
||||
}
|
||||
|
||||
VirtIOQueueChain(VirtIOQueue& queue, u16 start_index, u16 end_index, size_t chain_length)
|
||||
QueueChain(Queue& queue, u16 start_index, u16 end_index, size_t chain_length)
|
||||
: m_queue(queue)
|
||||
, m_start_of_chain_index(start_index)
|
||||
, m_end_of_chain_index(end_index)
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
VirtIOQueueChain(VirtIOQueueChain&& other)
|
||||
QueueChain(QueueChain&& other)
|
||||
: m_queue(other.m_queue)
|
||||
, m_start_of_chain_index(other.m_start_of_chain_index)
|
||||
, m_end_of_chain_index(other.m_end_of_chain_index)
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
other.m_chain_has_writable_pages = false;
|
||||
}
|
||||
|
||||
VirtIOQueueChain& operator=(VirtIOQueueChain&& other)
|
||||
QueueChain& operator=(QueueChain&& other)
|
||||
{
|
||||
VERIFY(&m_queue == &other.m_queue);
|
||||
ensure_chain_is_empty();
|
||||
|
@ -142,12 +142,12 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
~VirtIOQueueChain()
|
||||
~QueueChain()
|
||||
{
|
||||
ensure_chain_is_empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] VirtIOQueue& queue() const { return m_queue; }
|
||||
[[nodiscard]] Queue& queue() const { return m_queue; }
|
||||
[[nodiscard]] bool is_empty() const { return m_chain_length == 0; }
|
||||
[[nodiscard]] size_t length() const { return m_chain_length; }
|
||||
bool add_buffer_to_chain(PhysicalAddress buffer_start, size_t buffer_length, BufferType buffer_type);
|
||||
|
@ -176,7 +176,7 @@ private:
|
|||
VERIFY(m_chain_length == 0);
|
||||
}
|
||||
|
||||
VirtIOQueue& m_queue;
|
||||
Queue& m_queue;
|
||||
Optional<u16> m_start_of_chain_index {};
|
||||
Optional<u16> m_end_of_chain_index {};
|
||||
size_t m_chain_length {};
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
#include <Kernel/Bus/VirtIO/VirtIORNG.h>
|
||||
#include <Kernel/Sections.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
UNMAP_AFTER_INIT VirtIORNG::VirtIORNG(PCI::Address address)
|
||||
: VirtIODevice(address)
|
||||
UNMAP_AFTER_INIT RNG::RNG(PCI::Address address)
|
||||
: VirtIO::Device(address)
|
||||
{
|
||||
bool success = negotiate_features([&](auto) {
|
||||
return 0;
|
||||
|
@ -20,7 +20,7 @@ UNMAP_AFTER_INIT VirtIORNG::VirtIORNG(PCI::Address address)
|
|||
}
|
||||
if (success) {
|
||||
finish_init();
|
||||
m_entropy_buffer = MM.allocate_contiguous_kernel_region(PAGE_SIZE, "VirtIORNG", Memory::Region::Access::ReadWrite);
|
||||
m_entropy_buffer = MM.allocate_contiguous_kernel_region(PAGE_SIZE, "VirtIO::RNG", Memory::Region::Access::ReadWrite);
|
||||
if (m_entropy_buffer) {
|
||||
memset(m_entropy_buffer->vaddr().as_ptr(), 0, m_entropy_buffer->size());
|
||||
request_entropy_from_host();
|
||||
|
@ -28,16 +28,16 @@ UNMAP_AFTER_INIT VirtIORNG::VirtIORNG(PCI::Address address)
|
|||
}
|
||||
}
|
||||
|
||||
VirtIORNG::~VirtIORNG()
|
||||
RNG::~RNG()
|
||||
{
|
||||
}
|
||||
|
||||
bool VirtIORNG::handle_device_config_change()
|
||||
bool RNG::handle_device_config_change()
|
||||
{
|
||||
VERIFY_NOT_REACHED(); // Device has no config
|
||||
}
|
||||
|
||||
void VirtIORNG::handle_queue_update(u16 queue_index)
|
||||
void RNG::handle_queue_update(u16 queue_index)
|
||||
{
|
||||
VERIFY(queue_index == REQUESTQ);
|
||||
size_t available_entropy = 0, used;
|
||||
|
@ -53,18 +53,18 @@ void VirtIORNG::handle_queue_update(u16 queue_index)
|
|||
});
|
||||
chain.release_buffer_slots_to_queue();
|
||||
}
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIORNG: received {} bytes of entropy!", available_entropy);
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIO::RNG: received {} bytes of entropy!", available_entropy);
|
||||
for (auto i = 0u; i < available_entropy; i++) {
|
||||
m_entropy_source.add_random_event(m_entropy_buffer->vaddr().as_ptr()[i]);
|
||||
}
|
||||
// TODO: When should we get some more entropy?
|
||||
}
|
||||
|
||||
void VirtIORNG::request_entropy_from_host()
|
||||
void RNG::request_entropy_from_host()
|
||||
{
|
||||
auto& queue = get_queue(REQUESTQ);
|
||||
SpinlockLocker lock(queue.lock());
|
||||
VirtIOQueueChain chain(queue);
|
||||
QueueChain chain(queue);
|
||||
chain.add_buffer_to_chain(m_entropy_buffer->physical_page(0)->paddr(), PAGE_SIZE, BufferType::DeviceWritable);
|
||||
supply_chain_and_notify(REQUESTQ, chain);
|
||||
}
|
||||
|
|
|
@ -11,18 +11,18 @@
|
|||
#include <Kernel/Devices/CharacterDevice.h>
|
||||
#include <Kernel/Random.h>
|
||||
|
||||
namespace Kernel {
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
#define REQUESTQ 0
|
||||
|
||||
class VirtIORNG final
|
||||
: public RefCounted<VirtIORNG>
|
||||
, public VirtIODevice {
|
||||
class RNG final
|
||||
: public RefCounted<RNG>
|
||||
, public VirtIO::Device {
|
||||
public:
|
||||
virtual StringView purpose() const override { return class_name(); }
|
||||
|
||||
VirtIORNG(PCI::Address);
|
||||
virtual ~VirtIORNG() override;
|
||||
RNG(PCI::Address);
|
||||
virtual ~RNG() override;
|
||||
|
||||
private:
|
||||
virtual StringView class_name() const override { return "VirtIOConsole"; }
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
namespace Kernel::Graphics::VirtIOGPU {
|
||||
|
||||
GPU::GPU(PCI::Address address)
|
||||
: VirtIODevice(address)
|
||||
: VirtIO::Device(address)
|
||||
, m_scratch_space(MM.allocate_contiguous_kernel_region(32 * PAGE_SIZE, "VirtGPU Scratch Space", Memory::Region::Access::ReadWrite))
|
||||
{
|
||||
VERIFY(!!m_scratch_space);
|
||||
if (auto cfg = get_config(ConfigurationType::Device)) {
|
||||
if (auto cfg = get_config(VirtIO::ConfigurationType::Device)) {
|
||||
m_device_configuration = cfg;
|
||||
bool success = negotiate_features([&](u64 supported_features) {
|
||||
u64 negotiated = 0;
|
||||
|
@ -65,7 +65,7 @@ bool GPU::handle_device_config_change()
|
|||
auto events = get_pending_events();
|
||||
if (events & VIRTIO_GPU_EVENT_DISPLAY) {
|
||||
// The host window was resized, in SerenityOS we completely ignore this event
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIOGPU: Ignoring virtio gpu display resize event");
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIO::GPU: Ignoring virtio gpu display resize event");
|
||||
clear_pending_events(VIRTIO_GPU_EVENT_DISPLAY);
|
||||
}
|
||||
if (events & ~VIRTIO_GPU_EVENT_DISPLAY) {
|
||||
|
@ -243,9 +243,9 @@ void GPU::synchronous_virtio_gpu_command(PhysicalAddress buffer_start, size_t re
|
|||
auto& queue = get_queue(CONTROLQ);
|
||||
{
|
||||
SpinlockLocker lock(queue.lock());
|
||||
VirtIOQueueChain chain { queue };
|
||||
chain.add_buffer_to_chain(buffer_start, request_size, BufferType::DeviceReadable);
|
||||
chain.add_buffer_to_chain(buffer_start.offset(request_size), response_size, BufferType::DeviceWritable);
|
||||
VirtIO::QueueChain chain { queue };
|
||||
chain.add_buffer_to_chain(buffer_start, request_size, VirtIO::BufferType::DeviceReadable);
|
||||
chain.add_buffer_to_chain(buffer_start.offset(request_size), response_size, VirtIO::BufferType::DeviceWritable);
|
||||
supply_chain_and_notify(CONTROLQ, chain);
|
||||
full_memory_barrier();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ TYPEDEF_DISTINCT_ORDERED_ID(u32, ResourceID);
|
|||
TYPEDEF_DISTINCT_ORDERED_ID(u32, ScanoutID);
|
||||
|
||||
class GPU final
|
||||
: public VirtIODevice
|
||||
: public VirtIO::Device
|
||||
, public RefCounted<GPU> {
|
||||
friend class FrameBufferDevice;
|
||||
|
||||
|
@ -114,7 +114,7 @@ private:
|
|||
size_t m_num_scanouts { 0 };
|
||||
Scanout m_scanouts[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
|
||||
Configuration const* m_device_configuration { nullptr };
|
||||
VirtIO::Configuration const* m_device_configuration { nullptr };
|
||||
ResourceID m_resource_id_counter { 0 };
|
||||
|
||||
// Synchronous commands
|
||||
|
|
Loading…
Reference in a new issue