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