mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-11 13:22:33 +00:00
parent
7e26d3ef3f
commit
bb285bf758
repos/os
include/virtio
recipes/raw
src/drivers
framebuffer/virtio
input/virtio
nic/virtio
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user