]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/examples/libs/l4re/c++/shared_ds/ds_srv.cc
f54cec4bdfc7bb1c29120152a662fe52e6cb8484
[l4.git] / l4 / pkg / examples / libs / l4re / c++ / shared_ds / ds_srv.cc
1 /*
2  * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
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
11 #include <l4/re/env>
12 #include <l4/re/namespace>
13 #include <l4/re/util/cap_alloc>
14 #include <l4/re/util/object_registry>
15 #include <l4/re/dataspace>
16 #include <l4/cxx/ipc_server>
17
18 #include <l4/sys/typeinfo_svr>
19
20 #include <cstring>
21 #include <cstdio>
22 #include <unistd.h>
23
24 #include "interface.h"
25
26 /**
27  * A very simple server object, just providing the
28  * shared memory data space and an IRQ object to send a notification.
29  */
30 class My_server_obj : public L4::Server_object
31 {
32 private:
33   /**
34    * The capability to the shared memory.
35    */
36   L4::Cap<L4Re::Dataspace> _shm;
37   L4::Cap<L4::Irq> _irq;
38
39 public:
40   /**
41    * Create a new object for the given data space.
42    */
43   explicit My_server_obj(L4::Cap<L4Re::Dataspace> shm, L4::Cap<L4::Irq> irq)
44   : _shm(shm), _irq(irq)
45   {}
46
47   /**
48    * Dispatch function, dealing with remote requests.
49    */
50   int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
51 };
52
53
54 int My_server_obj::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
55 {
56   // we don't care about the original object reference, however
57   // we could read out the access rights from the lowest 2 bits
58   (void) obj;
59
60   l4_msgtag_t t;
61   ios >> t; // extract the tag
62
63   switch (t.label())
64     {
65     case L4::Meta::Protocol:
66       // handle the meta protocol requests, implementing the
67       // runtime dynamic type system for L4 objects.
68       return L4::Util::handle_meta_request<My_interface>(ios);
69     case 0:
70       // since we have just one operation we have no opcode dispatch,
71       // and just return the data-space and the notifier IRQ capabilities
72       ios << _shm << _irq;
73       return 0;
74     default:
75       // every other protocol is not supported.
76       return -L4_EBADPROTO;
77     }
78 }
79
80
81 /**
82  * A simple Server object attached to a notifier IRQ.
83  * This provides a kind of interrupt handler integrated in our
84  * server.
85  */
86 class Shm_observer : public L4::Server_object
87 {
88 private:
89   /**
90    * The pointer to the shared memory.
91    */
92   char *_shm;
93
94 public:
95   /**
96    * Create a new object for the given shared memory.
97    */
98   explicit Shm_observer(char *shm)
99   : _shm(shm)
100   {}
101
102   /**
103    * Dispatch function, dealing with remote requests.
104    * This is the ISR.
105    */
106   int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
107 };
108
109 int Shm_observer::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
110 {
111   // we don't care about the original object reference, however
112   // we could read out the access rights from the lowest 2 bits
113   (void) obj;
114
115   l4_msgtag_t t;
116   ios >> t; // extract the tag
117
118   switch (t.label())
119     {
120     case L4::Irq::Protocol:
121       // Got an IRQ so just print the new contents of the
122       // shared memory.
123       printf("Content: %s\n", _shm);
124       return 0;
125     default:
126       // every other protocol is not supported.
127       return -L4_EBADPROTO;
128     }
129 }
130
131 /**
132  * The singleton for implementing the generic server logic for the
133  * main thread. The factory is used for creating IPC gates for new server
134  * objects, however in this example no IPC gate is created, instead an IPC gate
135  * provided by the parent is used.
136  */
137 static L4Re::Util::Registry_server<> server;
138
139 enum
140 {
141   DS_SIZE = 4 << 12,
142 };
143
144 static char *get_ds(L4::Cap<L4Re::Dataspace> *_ds)
145 {
146   *_ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
147   if (!(*_ds).is_valid())
148     {
149       printf("Dataspace allocation failed.\n");
150       return 0;
151     }
152
153   int err =  L4Re::Env::env()->mem_alloc()->alloc(DS_SIZE, *_ds, 0);
154   if (err < 0)
155     {
156       printf("mem_alloc->alloc() failed.\n");
157       L4Re::Util::cap_alloc.free(*_ds);
158       return 0;
159     }
160
161   /*
162    * Attach DS to local address space
163    */
164   char *_addr = 0;
165   err =  L4Re::Env::env()->rm()->attach(&_addr, (*_ds)->size(),
166                                         L4Re::Rm::Search_addr,
167                                         *_ds);
168   if (err < 0)
169     {
170       printf("Error attaching data space: %s\n", l4sys_errtostr(err));
171       L4Re::Util::cap_alloc.free(*_ds);
172       return 0;
173     }
174
175
176   /*
177    * Success! Write something to DS.
178    */
179   printf("Attached DS\n");
180   static char const * const msg = "[DS] Hello from server!";
181   snprintf(_addr, strlen(msg) + 1, msg);
182
183   return _addr;
184 }
185
186 int main()
187 {
188   L4::Cap<L4Re::Dataspace> ds;
189   char *addr;
190
191   if (!(addr = get_ds(&ds)))
192     return 2;
193
194
195   // first the IRQ handler, because we need it in the My_server_obj object
196   Shm_observer observer(addr);
197
198   // Registering the observer as an IRQ handler, this allocates an
199   // IRQ object using the factory of our server.
200   L4::Cap<L4::Irq> irq = server.registry()->register_irq_obj(&observer);
201
202   // now the initial server object shared with the client via our parent.
203   // it provides the data-space and the IRQ capabilies to a client.
204   My_server_obj server_obj(ds, irq);
205
206   // Registering the server object to the capability 'shm' in our the L4Re::Env.
207   // This capability must be provided by the parent. (see the shared_ds.lua)
208   server.registry()->register_obj(&server_obj, "shm");
209
210   // Run our server loop.
211   server.loop();
212   return 0;
213 }
214
215
216