L4Re Operating System Framework
Interface and Usage Documentation
|
Client-side implementation for a general virtio device. More...
#include <l4virtio>
Public Member Functions | |
void | driver_connect (L4::Cap< L4virtio::Device > srvcap, bool manage_notify=true) |
Contacts the device and starts the initial handshake. | |
int | bind_notification_irq (unsigned index, L4::Cap< L4::Triggerable > irq) const |
Register a triggerable to receive notifications from the device. | |
bool | fail_state () const |
Return true if the device is in a fail state. | |
bool | feature_negotiated (unsigned int feat) const |
Check if a particular feature bit was negotiated with the device. | |
int | driver_acknowledge () |
Finalize handshake with the device. | |
int | register_ds (L4::Cap< L4Re::Dataspace > ds, l4_umword_t offset, l4_umword_t size, l4_uint64_t *devaddr) |
Share a dataspace with the device. | |
int | config_queue (int num, unsigned size, l4_uint64_t desc_addr, l4_uint64_t avail_addr, l4_uint64_t used_addr) |
Send the virtqueue configuration to the device. | |
int | max_queue_size (int num) const |
Maximum queue size allowed by the device. | |
int | send_and_wait (Virtqueue &queue, l4_uint16_t descno) |
Send a request to the device and wait for it to be processed. | |
int | wait (int index) const |
Wait for a notification from the device. | |
int | wait_for_next_used (Virtqueue &queue, l4_uint32_t *len=nullptr) const |
Wait for the next item to arrive in the used queue and return it. | |
void | send (Virtqueue &queue, l4_uint16_t descno) |
Send a request to the device. | |
|
inline |
Register a triggerable to receive notifications from the device.
index | Index of the interrupt. | |
[out] | irq | Triggerable to register for notifications. |
Definition at line 129 of file l4virtio.
References L4::Icu::bind(), and l4_error().
|
inline |
Send the virtqueue configuration to the device.
num | Number of queue to configure. |
size | Size of rings in the queue, must be a power of 2) |
desc_addr | Address of descriptor table (device address) |
avail_addr | Address of available ring (device address) |
used_addr | Address of used ring (device address) |
Definition at line 212 of file l4virtio.
References L4virtio::Device::config_queue().
Referenced by L4virtio::Driver::Virtio_net_device::setup_device(), and L4virtio::Driver::Block_device::setup_device().
|
inline |
Finalize handshake with the device.
Must be called after all queues have been set up and before the first request is sent. It is still possible to add more shared dataspaces after the handshake has been finished.
Definition at line 156 of file l4virtio.
References L4Re::chksys(), L4_EINVAL, L4_EIO, L4_ENODEV, L4_EOK, L4VIRTIO_FEATURE_VERSION_1, l4virtio_get_feature(), L4VIRTIO_STATUS_DRIVER_OK, L4VIRTIO_STATUS_FEATURES_OK, and L4virtio::Device::set_status().
Referenced by L4virtio::Driver::Virtio_net_device::setup_device(), and L4virtio::Driver::Block_device::setup_device().
|
inline |
Contacts the device and starts the initial handshake.
srvcap | Capability for device communication. |
manage_notify | Set up a semaphore for notifications from the device. See below. |
L4::Runtime_error | if the initialisation fails |
This function contacts the server, sets up the notification channels and the configuration dataspace. After this is done, the caller can set up any dataspaces it needs. The initialisation then needs to be finished by calling driver_acknowledge().
Per default this function creates and registers a semaphore for receiving notification from the device. This semaphore is used in the blocking functions send_and_wait(), wait() and next_used().
When manage_notify
is false, then the caller may manually register and handle notification interrupts from the device. This is for example useful, when the client runs in an application with a server loop.
Definition at line 56 of file l4virtio.
References L4::Icu::bind(), L4Re::chkcap(), L4Re::chksys(), L4virtio::Device::device_config(), L4virtio::Device::device_notification_irq(), L4Re::Env::env(), L4_EINVAL, L4_EIO, L4_ENODEV, l4_error(), L4_PAGEMASK, L4_PAGESHIFT, L4_PAGESIZE, L4_SUPERPAGESIZE, L4VIRTIO_STATUS_ACKNOWLEDGE, L4VIRTIO_STATUS_DRIVER, L4::Ipc::make_cap_rw(), L4Re::Rm::F::RW, L4Re::Rm::F::Search_addr, and L4virtio::Device::set_status().
Referenced by L4virtio::Driver::Virtio_net_device::setup_device(), and L4virtio::Driver::Block_device::setup_device().
|
inline |
Check if a particular feature bit was negotiated with the device.
The result is only valid after driver_acknowledge() was called (when the handshake with the device was completed).
feat | The feature bit. |
true | The feature is supported by both driver and device. |
false | The feature is not supported by the driver and/or device. |
Definition at line 145 of file l4virtio.
References l4virtio_get_feature().
|
inline |
Maximum queue size allowed by the device.
num | Number of queue for which to determine the maximum size. |
Definition at line 230 of file l4virtio.
Referenced by L4virtio::Driver::Virtio_net_device::rx_queue_size(), L4virtio::Driver::Block_device::setup_device(), and L4virtio::Driver::Virtio_net_device::tx_queue_size().
|
inline |
Share a dataspace with the device.
ds | Dataspace to share with the device. |
offset | Offset in dataspace where the shared part starts. |
size | Total size in bytes of the shared space. |
devaddr | Start of shared space in the device address space. |
Although this function allows to share only a part of the given dataspace for convenience, the granularity of sharing is always the dataspace level. Thus, the remainder of the dataspace is not protected from the device.
When communicating with the device, addresses must be given with respect to the device address space. This is not the same as the virtual address space of the client in order to not leak information about the address space layout.
Definition at line 196 of file l4virtio.
References L4::Ipc::make_cap_rw(), and L4virtio::Device::register_ds().
Referenced by L4virtio::Driver::Virtio_net_device::setup_device(), and L4virtio::Driver::Block_device::setup_device().
|
inline |
Send a request to the device.
queue | Queue that contains the request in its descriptor table |
descno | Index of first entry in descriptor table where |
Definition at line 312 of file l4virtio.
References L4virtio::Driver::Virtqueue::enqueue_descriptor().
Referenced by send_and_wait(), L4virtio::Driver::Block_device::send_request(), and L4virtio::Driver::Virtio_net_device::tx().
|
inline |
Send a request to the device and wait for it to be processed.
queue | Queue that contains the request in its descriptor table |
descno | Index of first entry in descriptor table where |
This function provides a simple mechanism to send requests synchronously. It must not be used with other requests at the same time as it directly waits for a notification on the device irq cap.
Definition at line 247 of file l4virtio.
References L4_EINVAL, L4_EOK, send(), and wait_for_next_used().
Referenced by L4virtio::Driver::Block_device::process_request().
|
inline |
Wait for a notification from the device.
index | Notification slot to wait for. |
Definition at line 268 of file l4virtio.
References L4_EEXIST, l4_ipc_error(), and l4_utcb().
Referenced by wait_for_next_used().
|
inline |
Wait for the next item to arrive in the used queue and return it.
queue | A queue. | |
[out] | len | (optional) Size of valid data in finished block. Note that this is the value reported by the device, which may set it to a value that is larger than the original buffer size. |
>=0 | Descriptor number of item removed from used queue. |
<0 | IPC error while waiting for notification. |
The call blocks until the next item is available in the used queue.
Definition at line 291 of file l4virtio.
References L4virtio::Driver::Virtqueue::find_next_used(), and wait().
Referenced by send_and_wait(), and L4virtio::Driver::Virtio_net_device::wait_rx().