11#include <l4/cxx/bitfield>
12#include <l4/cxx/minmax>
13#include <l4/cxx/utils>
19#include "../virtqueue"
100 struct Null_ptr_check;
110 operator Null_ptr_check
const * ()
const
111 {
return reinterpret_cast<Null_ptr_check
const *
>(_d); }
118 struct Request : Head_desc
193 template<
typename ITER>
199 for (
auto elem = begin ; elem != end; ++elem, ++added)
220 template<
typename QUEUE_OBSERVER>
224 o->notify_queue(
this);
242 template<
typename ITER,
typename QUEUE_OBSERVER>
243 void finish(ITER
const &begin, ITER
const &end, QUEUE_OBSERVER *o)
246 o->notify_queue(
this);
280 {
return _desc + idx; }
305 :
pos(reinterpret_cast<char *>(p)),
left(sizeof(T))
320 pos =
reinterpret_cast<char *
>(p);
337 unsigned long bytes = cxx::min(cxx::min(
left, dst->
left), max);
338 memcpy(dst->
pos,
pos, bytes);
358 unsigned long b = cxx::min(
left, bytes);
370 {
return left == 0; }
373class Request_processor;
413 static char const *
const err[] =
415 [
Bad_address] =
"Descriptor address cannot be translated",
416 [
Bad_rights] =
"Insufficient memory access rights",
417 [
Bad_flags] =
"Invalid descriptor flags",
418 [
Bad_next] =
"The descriptor's `next` index is invalid",
419 [
Bad_size] =
"Invalid size of the memory block"
422 if (error >= (
sizeof(err) /
sizeof(err[0])) || !err[error])
423 return "Unknown error";
481 template<
typename DESC_MAN,
typename ...ARGS>
488 dm->load_desc(_current,
this, &_table);
497 _table = ring->
desc(0);
501 dm->load_desc(_current,
this, cxx::forward<ARGS>(args)...);
514 template<
typename DESC_MAN,
typename ...ARGS>
515 Virtqueue::Request
const &
start(DESC_MAN *dm, Virtqueue::Request
const &request, ARGS... args)
517 start(dm, request.ring, request, cxx::forward<ARGS>(args)...);
527 {
return _current.
flags; }
550 template<
typename DESC_MAN,
typename ...ARGS>
551 bool next(DESC_MAN *dm, ARGS... args)
566 dm->load_desc(_current,
this, cxx::forward<ARGS>(args)...);
Encapsulate the state for processing a VIRTIO request.
bool next(DESC_MAN *dm, ARGS... args)
Switch to the next descriptor in a descriptor chain.
Virtqueue::Desc::Flags current_flags() const
Get the flags of the currently processed descriptor.
Virtqueue::Request const & start(DESC_MAN *dm, Virtqueue::Request const &request, ARGS... args)
Start processing a new request.
bool has_more() const
Are there more chained descriptors?
void start(DESC_MAN *dm, Virtqueue *ring, Virtqueue::Head_desc const &request, ARGS... args)
Start processing a new request.
VIRTIO request, essentially a descriptor from the available ring.
Desc const * desc() const
Head_desc()
Make invalid (NULL) request.
Virtqueue implementation for the device.
bool desc_avail() const
Test for available descriptors.
void enable_notify()
Clear the 'no notify' flag for this queue.
void consumed(ITER const &begin, ITER const &end)
Put multiple descriptors into the used ring.
Desc const * desc(unsigned idx) const
Get a descriptor from the descriptor list.
Request next_avail()
Get the next available descriptor from the available ring.
void finish(ITER const &begin, ITER const &end, QUEUE_OBSERVER *o)
Add a range of descriptors to the used ring, and notify an observer once.
void disable_notify()
Set the 'no notify' flag for this queue.
void finish(Head_desc &d, QUEUE_OBSERVER *o, l4_uint32_t len=0)
Add a descriptor to the used ring, and notify an observer.
void consumed(Head_desc const &r, l4_uint32_t len=0)
Put the given descriptor into the used ring.
l4_uint16_t ring[]
array of available descriptor indexes.
l4_uint16_t idx
available index written by guest
Descriptor in the descriptor table.
l4_uint16_t next
Index of the next chained descriptor.
l4_uint32_t len
Length of described buffer.
Flags flags
Descriptor flags.
Used_elem ring[]
array of used descriptors.
l4_uint16_t idx
index of the last entry in the ring.
Flags flags
flags of the used ring.
Used * _used
pointer to used ring.
bool ready() const
Test if this queue is in working state.
l4_uint16_t _idx_mask
mask used for indexing into the descriptor table and the rings.
Desc * _desc
pointer to descriptor table, NULL if queue is off.
Avail * _avail
pointer to available ring.
l4_uint16_t _current_avail
The life counter for the queue.
unsigned int l4_uint32_t
Unsigned 32bit value.
unsigned short int l4_uint16_t
Unsigned 16bit value.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
#define L4_LIKELY(x)
Expression is likely to execute.
Common L4 ABI Data Types.
L4-VIRTIO Transport C++ API.
T access_once(T const *a)
Read the value at an address at most once.
Exception used by Queue to indicate descriptor errors.
Request_processor const * proc
The processor that triggered the exception.
@ Bad_rights
Missing access rights on memory.
@ Bad_address
Address cannot be translated.
@ Bad_flags
Invalid combination of descriptor flags.
@ Bad_next
Invalid next index.
@ Bad_size
Invalid size of memory block.
char const * message() const
Get a human readable description of the error code.
Bad_descriptor(Request_processor const *proc, Error e)
Make a bad descriptor exception.
void set(T *p)
Set buffer for object p.
l4_uint32_t copy_to(Data_buffer *dst, l4_uint32_t max=UINT_MAX)
Copy contents from this buffer to the destination buffer.
l4_uint32_t left
Bytes left in buffer.
char * pos
Current buffer position.
l4_uint32_t skip(l4_uint32_t bytes)
Skip given number of bytes in this buffer.
bool done() const
Check if there are no more bytes left in the buffer.
Data_buffer(T *p)
Create buffer for object p.
Type for device feature bitmap.
l4_uint32_t raw
The raw value of the features bitmap.
constexpr ring_indirect_desc_bfm_t::Val ring_indirect_desc() const
Get the ring_indirect_desc bits ( 28 to 28 ) of raw.
constexpr ring_event_idx_bfm_t::Val ring_event_idx() const
Get the ring_event_idx bits ( 29 to 29 ) of raw.
Dev_features(l4_uint32_t v)
Make Features from a raw bitmap.
Type of the device status register.
constexpr failed_bfm_t::Val failed() const
Get the failed bits ( 7 to 7 ) of raw.
constexpr device_needs_reset_bfm_t::Val device_needs_reset() const
Get the device_needs_reset bits ( 6 to 6 ) of raw.
bool running() const
Check if the device is in running state.
constexpr driver_ok_bfm_t::Val driver_ok() const
Get the driver_ok bits ( 2 to 2 ) of raw.
constexpr acked_bfm_t::Val acked() const
Get the acked bits ( 0 to 0 ) of raw.
Dev_status(l4_uint32_t v)
Make Status from raw value.
constexpr features_ok_bfm_t::Val features_ok() const
Get the features_ok bits ( 3 to 3 ) of raw.
constexpr driver_bfm_t::Val driver() const
Get the driver bits ( 1 to 1 ) of raw.
constexpr fail_state_bfm_t::Val fail_state() const
Get the fail_state bits ( 6 to 7 ) of raw.
unsigned char raw
Raw value of the VIRTIO device status register.
Type for descriptor flags.
constexpr next_bfm_t::Val next() const
Get the next bits ( 0 to 0 ) of raw.
constexpr indirect_bfm_t::Val indirect() const
Get the indirect bits ( 2 to 2 ) of raw.
constexpr no_notify_bfm_t::Val no_notify() const
Get the no_notify bits ( 0 to 0 ) of raw.
Type of an element of the used ring.