1// vi:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \file
4 * \brief IPC server loop
5 */
6/*
7 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8 *               Alexander Warg <warg@os.inf.tu-dresden.de>,
9 *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
10 *     economic rights: Technische Universität Dresden (Germany)
11 *
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
15 *
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction.  Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License.  This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
24 */
25#pragma once
26
27#include <l4/sys/capability>
28#include <l4/sys/typeinfo_svr>
29#include <l4/sys/err.h>
30#include <l4/cxx/ipc_stream>
31#include <l4/sys/cxx/ipc_epiface>
32#include <l4/sys/cxx/ipc_server_loop>
33#include <l4/cxx/type_traits>
34#include <l4/cxx/exceptions>
35
36namespace L4 {
37
38/**
39 * \ingroup cxx_ipc_server
40 * \brief Abstract server object to be used with L4::Server and
41 *        L4::Basic_registry.
42 * \note Usually L4::Server_object_t is used as a base class when writing
43 *       server objects.
44 *
45 * This server object provides an abstract interface that is used by the
46 * L4::Registry_dispatcher model. You can derive subclasses from this
47 * interface and implement application specific server objects.
48 */
49class Server_object : public Epiface
50{
51public:
52  /**
53   * \brief The abstract handler for client requests to the object.
54   * \param rights The rights bits in the invoked capability.
55   * \param ios The Ipc::Iostream for reading the request and writing the reply.
56   * \retval -L4_ENOREPLY  Instructs the server loop to not send a reply.
57   * \retval <0            Error, reply with error code.
58   * \retval >=0           Success, reply with return value.
59   *
60   * This function must be implemented by application specific server
61   * objects. The implementation must unmarshall data from the stream (`ios`)
62   * and create a reply by marshalling to the stream (`ios`). For details
63   * about the IPC stream see [IPC stream operators](\ref ipc_stream).
64   *
65   * \note You need to extract the complete message from the \a ios stream
66   *       before inserting any reply data or before doing any function call
67   *       that may use the UTCB. Otherwise, the incoming message may get lost.
68   */
69  virtual int dispatch(unsigned long rights, Ipc::Iostream &ios) = 0;
70
71  l4_msgtag_t dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb)
72  {
73    L4::Ipc::Iostream ios(utcb);
74    ios.tag() = tag;
75    int r = dispatch(rights, ios);
76    return ios.prepare_ipc(r);
77  }
78
79  Cap<Kobject> obj_cap() const
80  { return cap_cast<Kobject>(Epiface::obj_cap()); }
81};
82
83/**
84 * \ingroup cxx_ipc_server
85 * Base class (template) for server implementing server objects.
86 * \tparam IFACE  The IPC interface class that defines the interface that shall
87 *                be implemented.
88 * \tparam BASE   The server object base class (usually L4::Server_object).
89 */
90template<typename IFACE, typename BASE = L4::Server_object>
91struct Server_object_t : BASE
92{
93  /// Data type of the IPC interface definition
94  typedef IFACE Interface;
95
96  /// \return the server-side buffer demand based in \a IFACE.
97  typename BASE::Demand get_buffer_demand() const
98  { return typename L4::Kobject_typeid<IFACE>::Demand(); }
99
100  /**
101   * Implementation of the meta protocol based on \a IFACE.
102   * \param ios  The IO stream used for receiving the message.
103   *
104   * This function can be used to handle incoming #L4_PROTO_META protcol
105   * requests.  The implementation uses the L4::Type_info of \a IFACE
106   * to handle the requests.  Call this function in the implementation of
107   * Server_object::dispatch() when the received message tag has protocol
108   * #L4_PROTO_META (L4::Meta::Protocol).
109   */
110  int dispatch_meta_request(L4::Ipc::Iostream &ios)
111  { return L4::Util::handle_meta_request<IFACE>(ios); }
112
113  /**
114   * Implementation of protocol-based dispatch for this server object.
115   * \param self    The this pointer for the object (inherits from
116   *                Server_object_t).
117   * \param rights  The rights from the received IPC (forwarded to p_dispatch()).
118   * \param ios     The message stream for the incoming and the reply message.
119   *
120   * Server objects may call this function from their dispatch() function.
121   * This function reads the protocol ID from the message tag and uses the
122   * p_dispatch code to dispatch to overloaded p_dispatch functions of self.
123   */
124  template<typename THIS>
125  static int proto_dispatch(THIS *self, l4_umword_t rights, L4::Ipc::Iostream &ios)
126  {
127    l4_msgtag_t t;
128    ios >> t;
129    return Kobject_typeid<IFACE>::proto_dispatch(self, t.label(), rights, ios);
130  }
131};
132
133/**
134 * \ingroup cxx_ipc_server
135 * Helper class to implement p_dispatch based server objects.
136 * \tparam Derived  The data type of your server object class.
137 * \tparam IFACE    The data type providing the interface definition
138 *                  for the object.
139 * \tparam BASE     Optional data-type of the base server object (usually
140 *                  L4::Server_object)
141 * \implements L4::Server_object
142 *
143 * This class implements the standard dispatch() function of L4::Server_object
144 * and forwards incoming messages to a set of overloaded p_dispatch() functions.
145 * There must be a p_dispatch() function in Derived for each interface provided
146 * by IFACE with the signature
147 * \code int p_dispatch(Iface *, unsigned rights, L4::Ipc::Iostream &) \endcode
148 * that is called for messages with protocol == Iface::Protocol.
149 *
150 * Example signature for L4Re::Dataspace is:
151 * \code int p_dispatch(L4Re::Dataspace *, unsigned, L4::Ipc::Iostream &) \endcode
152 */
153template<typename Derived, typename IFACE, typename BASE = L4::Server_object>
154struct Server_object_x : Server_object_t<IFACE, BASE>
155{
156  /// Implementation forwarding to p_dispatch().
157  int dispatch(l4_umword_t r, L4::Ipc::Iostream &ios)
158  {
159    return Server_object_t<IFACE, BASE>::proto_dispatch(static_cast<Derived *>(this),
160                                                        r, ios);
161  }
162};
163
164/**
165 * \ingroup cxx_ipc_server
166 * Server object base class for handling IRQ messages.
167 *
168 * This server object base class implements the empty interface
169 * (L4::Kobject). The implementation of Server_object::dispatch() must
170 * return -#L4_ENOREPLY, because IRQ messages do not handle replies.
171 */
172struct Irq_handler_object : Server_object_t<Kobject> {};
173
174}
175