L4Re - L4 Runtime Environment
l4virtio
1 // vi:ft=cpp
2 /*
3  * (c) 2013-2014 Alexander Warg <warg@os.inf.tu-dresden.de>
4  * Matthias Lange <matthias.lange@kernkonzept.com>
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  *
10  * As a special exception, you may use this file as part of a free software
11  * library without restriction. Specifically, if other files instantiate
12  * templates or use macros or inline functions from this file, or you compile
13  * this file and link it with other files to produce an executable, this
14  * file does not by itself cause the resulting executable to be covered by
15  * the GNU General Public License. This exception does not however
16  * invalidate any other reasons why the executable file might be covered by
17  * the GNU General Public License.
18  */
19 
20 #pragma once
21 
22 #include "virtio.h"
23 #include <l4/sys/capability>
24 #include <l4/sys/cxx/ipc_client>
25 #include <l4/re/dataspace>
26 #include <l4/sys/irq>
27 #include <l4/cxx/utils>
28 
29 namespace L4virtio {
50 class Device :
51  public L4::Kobject_t<Device, L4::Icu, L4VIRTIO_PROTOCOL,
52  L4::Type_info::Demand_t<1> >
53 {
54 public:
56  struct Config_hdr : l4virtio_config_hdr_t
57  {
58  Config_queue *queues() const
59  { return l4virtio_config_queues(this); }
60 
61  template <typename T>
62  T *device_config() const
63  {
64  return static_cast<T*>(l4virtio_device_config(this));
65  }
66 
67  int config_queue(unsigned num, L4::Cap<L4::Triggerable> out_notify,
68  L4::Cap<L4::Triggerable> in_notify,
70  {
71  return send_cmd(L4VIRTIO_CMD_CFG_QUEUE | num,
72  out_notify, in_notify, to);
73  }
74 
75  int set_status(unsigned new_status, L4::Cap<L4::Triggerable> out_notify,
76  L4::Cap<L4::Triggerable> in_notify,
78  {
79  return send_cmd(L4VIRTIO_CMD_SET_STATUS | new_status,
80  out_notify, in_notify, to);
81  }
82 
83  int send_cmd(unsigned command, L4::Cap<L4::Triggerable> out_notify,
84  L4::Cap<L4::Triggerable> in_notify,
86  {
87  cxx::write_now(&cmd, command);
88 
89  if (out_notify)
90  out_notify->trigger();
91 
92  auto utcb = l4_utcb();
93  auto ipc_to = l4_timeout(L4_IPC_TIMEOUT_0, to);
94 
95  do
96  {
97  if (in_notify)
98  if (l4_ipc_error(l4_ipc_receive(in_notify.cap(), utcb, ipc_to),
99  utcb) == L4_IPC_RETIMEOUT)
100  break;
101  }
102  while (cxx::access_once(&cmd));
103 
104  return cxx::access_once(&cmd) ? -L4_EBUSY : L4_EOK;
105  }
106  };
107 
117  L4_INLINE_RPC(long, set_status, (unsigned status));
118 
134  L4_INLINE_RPC(long, config_queue, (unsigned queue));
135 
150  l4_uint64_t base, l4_umword_t offset,
151  l4_umword_t size));
152 
173 
183  l4_addr_t *ds_offset));
184 
204  (unsigned index, L4::Ipc::Out<L4::Cap<L4::Triggerable> > irq));
205 
206 
207  typedef L4::Typeid::Rpcs<set_status_t, config_queue_t, register_iface_t,
208  register_ds_t, device_config_t,
209  device_notification_irq_t> Rpcs;
210 };
211 
212 }
Timeout during receive operation.
Definition: ipc.h:83
Capability type for RPC interfaces (see L4::Cap<T>).
Definition: ipc_types:541
Set the status register.
Definition: virtio.h:119
l4_timeout_t l4_timeout(l4_timeout_s snd, l4_timeout_s rcv) L4_NOTHROW
Combine send and receive timeout in a timeout.
Definition: __timeout.h:221
long device_config(L4::Ipc::Out< L4::Cap< L4Re::Dataspace > > config_ds, l4_addr_t *ds_offset)
Get the dataspace with the L4virtio configuration page.
Standard list of RPCs of an interface.
Definition: __typeinfo.h:438
l4_umword_t l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
Get the error code for an object invocation.
Definition: ipc.h:500
l4virtio_config_queue_t * l4virtio_config_queues(l4virtio_config_hdr_t const *cfg)
Get the pointer to the first queue config.
Definition: virtio.h:237
Mark an argument as a output value in an RPC signature.
Definition: ipc_types:42
L4::Cap related definitions.
long config_queue(unsigned queue)
Trigger queue configuration of the given queue.
long set_status(unsigned status)
Write the VIRTIO status register.
long register_ds(L4::Ipc::Cap< L4Re::Dataspace > ds_cap, l4_uint64_t base, l4_umword_t offset, l4_umword_t size)
Register a shared data space with VIRTIO host.
l4_msgtag_t trigger(l4_utcb_t *utcb=l4_utcb())
Trigger.
Definition: irq:93
Object currently busy, try later.
Definition: err.h:53
void * l4virtio_device_config(l4virtio_config_hdr_t const *cfg)
Get the pointer to the device configuration.
Definition: virtio.h:248
Basic timeout specification.
Definition: __timeout.h:45
IPC interface for virtio over L4 IPC.
Definition: l4virtio:50
#define L4_INLINE_RPC(res, name, args, attr...)
Define an inline RPC call (type and callable).
Definition: ipc_iface:458
Ok.
Definition: err.h:43
Configure a queue.
Definition: virtio.h:120
L4-VIRTIO config header, provided in shared data space.
Definition: virtio.h:127
l4_cap_idx_t cap() const
Return capability selector.
Definition: capability.h:52
unsigned long l4_umword_t
Unsigned machine word.
Definition: l4int.h:52
#define L4_IPC_TIMEOUT_NEVER
never timeout
Definition: __timeout.h:78
C++ Irq interface.
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition: utcb.h:340
Queue configuration entry.
Definition: virtio.h:208
Helper class to create an L4Re interface class that is derived from a single base class...
Definition: __typeinfo.h:759
l4_msgtag_t l4_ipc_receive(l4_cap_idx_t object, l4_utcb_t *utcb, l4_timeout_t timeout) L4_NOTHROW
Wait for a message from a specific source.
Definition: ipc.h:487
Dataspace interface.
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition: l4int.h:42
L4-VIRTIO Transport C++ API.
Definition: l4virtio:29
#define L4_IPC_TIMEOUT_0
Timeout constants.
Definition: __timeout.h:77
C++ interface for capabilities.
Definition: capability.h:13
long device_notification_irq(unsigned index, L4::Ipc::Out< L4::Cap< L4::Triggerable > > irq)
Get the notification interrupt corresponding to the given index.
unsigned long l4_addr_t
Address type.
Definition: l4int.h:45
long register_iface(L4::Ipc::Cap< L4::Triggerable > guest_irq, L4::Ipc::Out< L4::Cap< L4::Triggerable > > host_irq, L4::Ipc::Out< L4::Cap< L4Re::Dataspace > > config_ds)
Register client to the L4-VIRTIO device.