23 #include <l4/cxx/bitfield> 24 #include <l4/cxx/minmax> 25 #include <l4/cxx/utils> 31 #include "../virtqueue" 52 CXX_BITFIELD_MEMBER( 0, 0,
acked, raw);
53 CXX_BITFIELD_MEMBER( 1, 1,
driver, raw);
56 CXX_BITFIELD_MEMBER( 7, 7,
failed, raw);
83 CXX_BITFIELD_MEMBER(28, 28, ring_indirect_desc, raw);
84 CXX_BITFIELD_MEMBER(29, 29, ring_event_idx, raw);
107 struct Null_ptr_check;
117 operator Null_ptr_check
const * ()
const 118 {
return reinterpret_cast<Null_ptr_check
const *
>(_d); }
146 if (
L4_LIKELY(_current_avail != _avail->idx))
149 unsigned head = _current_avail & _idx_mask;
151 return Request(
this, _avail->ring[head]);
163 return _current_avail != _avail->idx;
176 _used->ring[i] =
Used_elem(r._d - _desc, len);
181 template<
typename ITER>
182 void consumed(ITER
const &begin, ITER
const &end)
187 for (
auto elem = begin ; elem != end; ++elem, ++added)
188 _used->ring[(idx + added) & _idx_mask]
189 =
Used_elem(elem->first._d - _desc, elem->second);
195 template<
typename QUEUE_OBSERVER>
199 o->notify_queue(
this);
203 template<
typename ITER,
typename QUEUE_OBSERVER>
204 void finish(ITER
const &begin, ITER
const &end, QUEUE_OBSERVER *o)
206 consumed(begin, end);
207 o->notify_queue(
this);
218 _used->flags.no_notify() = 1;
229 _used->flags.no_notify() = 0;
239 {
return _desc + idx; }
263 : pos(reinterpret_cast<char *>(p)), left(sizeof(T))
277 pos =
reinterpret_cast<char *
>(p);
294 memcpy(dst->
pos, pos, bytes);
313 unsigned long b =
cxx::min(left, bytes);
324 {
return left == 0; }
356 : proc(proc), error(e)
366 char const *
const err[] = {
367 [Bad_address] =
"Descriptor address cannot be translated",
368 [Bad_rights] =
"Insufficient memory access rights",
369 [Bad_flags] =
"Invalid descriptor flags",
370 [Bad_next] =
"The descriptor's `next` index is invalid",
371 [Bad_size] =
"Invalid size of the memory block" 374 if (error >= (
sizeof(err) /
sizeof(err[0])))
375 return "Unknown error";
433 template<
typename DESC_MAN,
typename ...ARGS>
436 _current = cxx::access_once(request.
desc());
440 dm->load_desc(_current,
this, &_table);
445 _current = cxx::access_once(_table);
449 _table = ring->
desc(0);
453 dm->load_desc(_current,
this, cxx::forward<ARGS>(args)...);
464 template<
typename DESC_MAN,
typename ...ARGS>
465 Virtqueue::Request
const &
start(DESC_MAN *dm, Virtqueue::Request
const &request, ARGS... args)
467 start(dm, request.ring, request, cxx::forward<ARGS>(args)...);
476 {
return _current.
flags; }
498 template<
typename DESC_MAN,
typename ...ARGS>
499 bool next(DESC_MAN *dm, ARGS... args)
507 _current = cxx::access_once(_table + _current.
next);
514 dm->load_desc(_current,
this, cxx::forward<ARGS>(args)...);
l4_uint32_t raw
The raw value of the features bitmap.
bool has_more() const
Are there more chained descriptors ?
Virtqueue::Desc::Flags current_flags() const
Get the flags of the currently processed descriptor.
Head_desc()
Make invalid (NULL) request.
Descriptor in the descriptor table.
char const * message() const
Get a human readable description of the error code.
Virtqueue implementation for the device.
void disable_notify()
Set the 'no notify' flag for this queue.
Missing access rights on memory.
unsigned short int l4_uint16_t
Unsigned 16bit value.
Common L4 ABI Data Types.
l4_uint16_t next
Index of the next chained descriptor.
Address cannot be translated.
bool desc_avail() const
Test for available descriptors.
Exception used by Queue to indicate descriptor errors.
l4_uint32_t left
Bytes left in buffer.
void start(DESC_MAN *dm, Virtqueue *ring, Virtqueue::Head_desc const &request, ARGS... args)
Start processing a new request.
Type of the device status register.
void consumed(Head_desc const &r, l4_uint32_t len=0)
Put the given descriptor into the used ring.
Dev_features(l4_uint32_t v)
Make Features from a raw bitmap.
Request next_avail()
Get the next available descriptor from the available ring.
l4_uint32_t copy_to(Data_buffer *dst, l4_uint32_t max=UINT_MAX)
Copy contents from this buffer to the destination buffer.
Encapsulate the state for processing a VIRTIO request.
next_bfm_t::Val next() const
Get the next bits ( 0 to 0 ) of raw .
char * pos
Current buffer position.
indirect_bfm_t::Val indirect() const
Get the indirect bits ( 2 to 2 ) of raw .
T1 max(T1 a, T1 b)
Get the maximum of a and b.
Data_buffer(T *p)
Create buffer for object p.
driver_bfm_t::Val driver() const
Get the driver bits ( 1 to 1 ) of raw .
bool running() const
Check if the device is in running state.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
features_ok_bfm_t::Val features_ok() const
Get the features_ok bits ( 3 to 3 ) of raw .
bool next(DESC_MAN *dm, ARGS... args)
Switch to the next descriptor in a descriptor chain.
driver_ok_bfm_t::Val driver_ok() const
Get the driver_ok bits ( 2 to 2 ) of raw .
Invalid combination of descriptor flags.
#define L4_LIKELY(x)
Expression is likely to execute.
unsigned char raw
Raw value of the VIRTIO device status register.
Desc const * desc(unsigned idx) const
Get a descriptor from the descriptor list.
void enable_notify()
Clear the 'no notify' flag for this queue.
Type for descriptor flags.
failed_bfm_t::Val failed() const
Get the failed bits ( 7 to 7 ) of raw .
Flags flags
Descriptor flags.
Type for device feature bitmap.
Dev_status(l4_uint32_t v)
Make Status from raw value.
Desc const * desc() const
Type of an element of the used ring.
Request_processor const * proc
The processor that triggered the exception.
Invalid size of memory block.
VIRTIO request, essentially a descriptor from the available ring.
L4-VIRTIO Transport C++ API.
l4_uint32_t len
Length of described buffer.
acked_bfm_t::Val acked() const
Get the acked bits ( 0 to 0 ) of raw .
Bad_descriptor(Request_processor const *proc, Error e)
Make a bad descriptor exception.
l4_uint32_t skip(l4_uint32_t bytes)
Skip given number of bytes in this buffer.
Virtqueue::Request const & start(DESC_MAN *dm, Virtqueue::Request const &request, ARGS... args)
Start processing a new request.
unsigned int l4_uint32_t
Unsigned 32bit value.
T1 min(T1 a, T1 b)
Get the minimum of a and b.
bool done() const
Check if there are no more bytes left in the buffer.