Convert virtio to use Platform::Session::dma_addr

Issue 
This commit is contained in:
Stefan Kalkowski 2022-02-03 15:15:05 +01:00 committed by Norman Feske
parent 7e26d3ef3f
commit bb285bf758
12 changed files with 81 additions and 87 deletions
repos/os
include/virtio
recipes/raw
drivers_interactive-virt_qemu
drivers_nic-virt_qemu
src/drivers

@ -14,6 +14,7 @@
#ifndef _INCLUDE__VIRTIO__MMIO_DEVICE_H_
#define _INCLUDE__VIRTIO__MMIO_DEVICE_H_
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <virtio/queue.h>

@ -17,6 +17,7 @@
#include <os/attached_mmio.h>
#include <irq_session/client.h>
#include <legacy/x86/platform_device/client.h>
#include <legacy/x86/platform_session/connection.h>
#include <virtio/queue.h>
namespace Virtio {

@ -14,7 +14,7 @@
#ifndef _INCLUDE__VIRTIO__QUEUE_H_
#define _INCLUDE__VIRTIO__QUEUE_H_
#include <base/attached_ram_dataspace.h>
#include <base/attached_dataspace.h>
#include <base/stdint.h>
#include <dataspace/client.h>
#include <util/misc_math.h>
@ -81,6 +81,10 @@ class Virtio::Queue
Queue(Queue const &) = delete;
Queue &operator = (Queue const &) = delete;
static addr_t _dma_addr(Platform::Connection & p,
Dataspace_capability c) {
return p.dma_addr(static_cap_cast<Ram_dataspace>(c)); }
protected:
typedef HEADER_TYPE Header_type;
@ -134,21 +138,14 @@ class Virtio::Queue
Buffer_pool(Buffer_pool const &) = delete;
Buffer_pool &operator = (Buffer_pool const &) = delete;
Attached_ram_dataspace _ram_ds;
uint16_t const _buffer_count;
uint16_t const _buffer_size;
addr_t const _phys_base;
uint8_t *_local_base;
Attached_dataspace _ds;
uint16_t const _buffer_count;
uint16_t const _buffer_size;
addr_t const _phys_base;
static size_t _ds_size(uint16_t buffer_count, uint16_t buffer_size) {
return buffer_count * align_natural(buffer_size); }
static addr_t _phys_addr(Attached_ram_dataspace &ram_ds)
{
Dataspace_client client(ram_ds.cap());
return client.phys_addr();
}
public:
struct Buffer
@ -158,21 +155,25 @@ class Virtio::Queue
uint16_t size;
};
Buffer_pool(Ram_allocator &ram,
Region_map &rm,
uint16_t const buffer_count,
uint16_t const buffer_size)
: _ram_ds(ram, rm, _ds_size(buffer_count, buffer_size))
, _buffer_count(buffer_count)
, _buffer_size(buffer_size)
, _phys_base(_phys_addr(_ram_ds))
, _local_base(_ram_ds.local_addr<uint8_t>()) {}
Buffer_pool(Platform::Connection & plat,
Region_map & rm,
uint16_t const buffer_count,
uint16_t const buffer_size)
:
_ds(rm, plat.alloc_dma_buffer(buffer_count *
align_natural(buffer_size),
CACHED)),
_buffer_count(buffer_count),
_buffer_size(buffer_size),
_phys_base(_dma_addr(plat, _ds.cap())) {}
const Buffer get(uint16_t descriptor_idx) const {
const Buffer get(uint16_t descriptor_idx) const
{
descriptor_idx %= _buffer_count;
return {
_local_base + descriptor_idx * align_natural(_buffer_size),
_phys_base + descriptor_idx * align_natural(_buffer_size),
(uint8_t*)((addr_t)_ds.local_addr<uint8_t>() +
descriptor_idx * align_natural(_buffer_size)),
_phys_base + descriptor_idx * align_natural(_buffer_size),
_buffer_size
};
}
@ -210,7 +211,7 @@ class Virtio::Queue
uint16_t const _queue_size;
Attached_ram_dataspace _ram_ds;
Attached_dataspace _ds;
Buffer_pool _buffers;
Avail volatile * const _avail;
Used volatile * const _used;
@ -247,15 +248,13 @@ class Virtio::Queue
return align_natural(size);
}
static Queue_description _init_description(
uint16_t queue_size,
Ram_dataspace_capability cap)
static Queue_description _init_description(uint16_t queue_size,
addr_t phys_addr)
{
Dataspace_client ram_ds_client(cap);
uint8_t const *base_phys = (uint8_t *)ram_ds_client.phys_addr();
uint8_t const *base_phys = (uint8_t *)phys_addr;
size_t const avail_offset = _desc_size(queue_size);
size_t const used_offset = align_natural(avail_offset + _avail_size(queue_size));
size_t const used_offset =
align_natural(avail_offset + _avail_size(queue_size));
return {
(addr_t)base_phys,
@ -566,17 +565,18 @@ class Virtio::Queue
print(output, _queue_size);
}
Queue(Ram_allocator &ram,
Region_map &rm,
uint16_t queue_size,
uint16_t buffer_size)
Queue(Region_map & rm,
Platform::Connection & plat,
uint16_t queue_size,
uint16_t buffer_size)
: _queue_size(queue_size),
_ram_ds(ram, rm, _ds_size(queue_size), UNCACHED),
_buffers(ram, rm, queue_size, _check_buffer_size(buffer_size)),
_avail(_init_avail(_ram_ds.local_addr<uint8_t>(), queue_size)),
_used(_init_used(_ram_ds.local_addr<uint8_t>(), queue_size)),
_descriptors(_ram_ds.local_addr<uint8_t>(), queue_size),
_description(_init_description(queue_size, _ram_ds.cap()))
_ds(rm, plat.alloc_dma_buffer(_ds_size(queue_size), UNCACHED)),
_buffers(plat, rm, queue_size, _check_buffer_size(buffer_size)),
_avail(_init_avail(_ds.local_addr<uint8_t>(), queue_size)),
_used(_init_used(_ds.local_addr<uint8_t>(), queue_size)),
_descriptors(_ds.local_addr<uint8_t>(), queue_size),
_description(_init_description(queue_size,
_dma_addr(plat, _ds.cap())))
{
_fill_descriptor_table();
}

@ -30,7 +30,7 @@
</config>
</start>
<start name="platform_drv">
<start name="platform_drv" managing_system="yes">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Platform"/> </provides>
<route>

@ -24,7 +24,7 @@
</config>
</start>
<start name="platform_drv">
<start name="platform_drv" managing_system="yes">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Platform"/> </provides>
<route>

@ -180,7 +180,7 @@ class Virtio_fb::Driver
typedef Virtio::Queue<Control_header, Control_queue_traits> Control_queue;
class Fb_memory_resource
class Fb_memory_resource : public Platform::Dma_buffer
{
private:
@ -190,40 +190,20 @@ class Virtio_fb::Driver
Fb_memory_resource(Fb_memory_resource const &) = delete;
Fb_memory_resource &operator = (Fb_memory_resource const &) = delete;
Platform::Connection &_platform;
Attached_dataspace _attachement;
static size_t _fb_size(Capture::Area const &area) {
return area.w() * area.h() * 4; }
public:
addr_t phys_addr()
{
Dataspace_client client(_attachement.cap());
return client.phys_addr();
}
Capture::Pixel *local_addr() { return _attachement.local_addr<Capture::Pixel>(); }
size_t size() const { return _attachement.size(); };
Fb_memory_resource(Region_map &rm,
Platform::Connection &platform,
Fb_memory_resource(Platform::Connection &platform,
Capture::Area const &area)
: _platform(platform)
, _attachement(rm, _platform.alloc_dma_buffer(_fb_size(area), UNCACHED)) { }
~Fb_memory_resource()
{
_platform.free_dma_buffer(static_cap_cast<Ram_dataspace>(_attachement.cap()));
_attachement.invalidate();
}
: Platform::Dma_buffer(platform, _fb_size(area), UNCACHED) {}
};
Env &_env;
Platform::Connection &_platform;
Virtio::Device &_device;
Control_queue _ctrl_vq { _env.ram(), _env.rm(), 4, 512 };
Control_queue _ctrl_vq { _env.rm(), _platform, 4, 512 };
uint32_t const _num_scanouts;
Signal_handler<Driver> _irq_handler { _env.ep(), *this, &Driver::_handle_irq };
@ -343,7 +323,7 @@ class Virtio_fb::Driver
}
try {
_fb_res.construct(_env.rm(), _platform, _display_area);
_fb_res.construct(_platform, _display_area);
} catch (...) {
error("Failed to allocate framebuffer!");
throw;
@ -352,7 +332,7 @@ class Virtio_fb::Driver
{
Control_header attach_cmd { Control_header::CMD_RESOURCE_ATTACH_BACKING };
Attach_backing attach_data {
.addr = _fb_res->phys_addr(),
.addr = _fb_res->dma_addr(),
.length = static_cast<uint32_t>(_fb_res->size())
};
@ -445,7 +425,8 @@ class Virtio_fb::Driver
if (!_captured_screen.constructed())
return;
Capture::Surface<Pixel> surface(_fb_res->local_addr(), _display_area);
Capture::Surface<Pixel> surface(_fb_res->local_addr<Pixel>(),
_display_area);
_captured_screen->apply_to_surface(surface);
_update_fb();

@ -13,6 +13,7 @@
#include <base/component.h>
#include <platform_session/connection.h>
#include <platform_session/dma_buffer.h>
#include <virtio/mmio_device.h>
#include "component.h"

@ -129,6 +129,7 @@ class Virtio_input::Driver
Driver &operator = (Driver const &);
Env &_env;
Platform::Connection &_plat;
::Event::Connection _event_session { _env };
Virtio::Device &_device;
Event _last_sent_key_event { 0, 0, 0 };
@ -136,9 +137,9 @@ class Virtio_input::Driver
Input::Absolute_motion _abs_motion { -1, -1 };
Abs_config _abs_config { { 0, 0 }, { 0, 0 }, 0, 0 };
Signal_handler<Driver> _irq_handler {_env.ep(), *this, &Driver::_handle_irq};
Events_virtqueue _events_vq { _env.ram(), _env.rm(),
Events_virtqueue _events_vq { _env.rm(), _plat,
QUEUE_SIZE, QUEUE_ELM_SIZE };
Status_virtqueue _status_vq { _env.ram(), _env.rm(),
Status_virtqueue _status_vq { _env.rm(), _plat,
QUEUE_SIZE, QUEUE_ELM_SIZE };
@ -441,11 +442,12 @@ class Virtio_input::Driver
public:
Driver(Env &env,
Virtio::Device &device,
Xml_node const &config)
Driver(Env & env,
Platform::Connection & plat,
Virtio::Device & device,
Xml_node const & config)
:
_env(env), _device(device)
_env(env), _plat(plat), _device(device)
{
_init_driver(config);
_abs_config = _read_abs_config(_device, config);

@ -31,7 +31,8 @@ struct Virtio_mmio_input::Main
Platform::Device::Type { "input" } };
Virtio::Device virtio_device { platform_device };
Attached_rom_dataspace config { env, "config" };
Virtio_input::Driver driver { env, virtio_device, config.xml() };
Virtio_input::Driver driver { env, platform, virtio_device,
config.xml() };
Main(Env &env)
try : env(env) { log("--- VirtIO MMIO input driver started ---"); }

@ -292,15 +292,16 @@ class Virtio_nic::Device : Noncopyable
Device(Genode::Env &env,
Virtio::Device &device,
Platform::Connection &plat,
Genode::Xml_node const &xml)
try :
_verbose { xml.attribute_value("verbose", false) },
_device { device },
_hw_features { _init_hw_features(xml) },
_rx_vq { env.ram(), env.rm(),
_rx_vq { env.rm(), plat,
_vq_size(RX_VQ, xml, "rx_queue_size"),
_buf_size(RX_VQ, xml, "rx_buffer_size") },
_tx_vq { env.ram(), env.rm(),
_tx_vq { env.rm(), plat,
_vq_size(TX_VQ, xml, "tx_queue_size"),
_buf_size(TX_VQ, xml, "tx_buffer_size") }
{ }
@ -534,13 +535,14 @@ class Virtio_nic::Session_component : public Nic::Session_component,
Session_component(Genode::Env &env,
Genode::Allocator &rx_block_md_alloc,
Virtio::Device &device,
Platform::Connection &plat,
Genode::Xml_node const &xml,
Genode::size_t const tx_buf_size,
Genode::size_t const rx_buf_size)
:
Nic::Session_component { tx_buf_size, rx_buf_size, Genode::CACHED,
rx_block_md_alloc, env },
Device { env, device, xml },
Device { env, device, plat, xml },
_irq_handler { env.ep(), *this, &Session_component::_handle_irq },
_link_up { link_state() }
{
@ -566,6 +568,7 @@ class Virtio_nic::Root : public Genode::Root_component<Session_component, Genode
Genode::Env &_env;
Virtio::Device &_device;
Platform::Connection &_plat;
Attached_rom_dataspace &_config_rom;
Session_component *_create_session(const char *args) override
@ -587,7 +590,7 @@ class Virtio_nic::Root : public Genode::Root_component<Session_component, Genode
try {
return new (md_alloc()) Session_component(
_env, *md_alloc(), _device, _config_rom.xml(),
_env, *md_alloc(), _device, _plat, _config_rom.xml(),
tx_buf_size, rx_buf_size);
} catch (...) { throw Service_denied(); }
}
@ -597,12 +600,14 @@ class Virtio_nic::Root : public Genode::Root_component<Session_component, Genode
Root(Env &env,
Allocator &md_alloc,
Virtio::Device &device,
Platform::Connection &plat,
Attached_rom_dataspace &config_rom)
:
Root_component<Session_component,
Genode::Single_client> { env.ep(), md_alloc },
_env { env },
_device { device },
_plat { plat },
_config_rom { config_rom }
{ }
};
@ -687,9 +692,10 @@ class Genode::Uplink_client : public Virtio_nic::Device,
Uplink_client(Env &env,
Allocator &alloc,
Virtio::Device &device,
Platform::Connection &plat,
Genode::Xml_node const &xml)
:
Device { env, device, xml },
Device { env, device, plat, xml },
Uplink_client_base { env, alloc, read_mac_address() },
_irq_handler { env.ep(), *this, &Uplink_client::_handle_irq }
{

@ -53,13 +53,14 @@ struct Virtio_mmio_nic::Main
switch (mode) {
case Nic_driver_mode::NIC_SERVER:
root.construct( env, heap, device, config_rom);
root.construct(env, heap, device, platform, config_rom);
env.parent().announce(env.ep().manage(*root));
break;
case Nic_driver_mode::UPLINK_CLIENT:
uplink_client.construct( env, heap, device, config_rom.xml());
uplink_client.construct(env, heap, device, platform,
config_rom.xml());
break;
}
}

@ -62,7 +62,7 @@ struct Virtio_pci_nic::Main
switch (mode) {
case Nic_driver_mode::NIC_SERVER:
root.construct(env, heap, virtio_device, config_rom);
root.construct(env, heap, virtio_device, pci, config_rom);
env.parent().announce(env.ep().manage(*root));
break;
@ -70,7 +70,7 @@ struct Virtio_pci_nic::Main
case Nic_driver_mode::UPLINK_CLIENT:
uplink_client.construct(
env, heap, virtio_device, config_rom.xml());
env, heap, virtio_device, pci, config_rom.xml());
break;
}