1 // vi:ft=cpp
2 /**
3  * \internal
4  * \file
5  * \brief
6  */
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
9  *     economic rights: Technische Universität Dresden (Germany)
10  *
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  *
15  * As a special exception, you may use this file as part of a free software
16  * library without restriction.  Specifically, if other files instantiate
17  * templates or use macros or inline functions from this file, or you compile
18  * this file and link it with other files to produce an executable, this
19  * file does not by itself cause the resulting executable to be covered by
20  * the GNU General Public License.  This exception does not however
21  * invalidate any other reasons why the executable file might be covered by
22  * the GNU General Public License.
23  */
24 #include <l4/libkproxy/factory_svr>
25 #include <l4/cxx/ipc_stream>
26 
27 namespace L4kproxy {
28 
29 class Factory_hndl
30 {
31 public:
handle_factory(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)32   static int handle_factory(Factory_svr *svr, Factory_interface *fi,
33                             L4::Ipc::Iostream &ios)
34     {
35       unsigned long limit;
36       L4::Cap<L4::Factory> f = svr->cap_alloc<L4::Factory>();
37       if (!f.is_valid())
38         return -L4_ENOMEM;
39       ios >> limit;
40       int r = fi->create_factory(f, limit);
41       if (r == 0)
42         ios << f;
43       return r;
44     }
45 
handle_task(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)46   static int handle_task(Factory_svr *svr, Factory_interface *fi,
47                          L4::Ipc::Iostream &ios)
48     {
49       l4_fpage_t utcb_area;
50       L4::Cap<L4::Task> t = svr->cap_alloc<L4::Task>();
51       if (!t.is_valid())
52         return -L4_ENOMEM;
53       ios >> utcb_area.raw;
54       int r = fi->create_task(t, utcb_area);
55       if (r == 0)
56         ios << t;
57       return r;
58     }
59 
handle_thread(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)60   static int handle_thread(Factory_svr *svr, Factory_interface *fi,
61                            L4::Ipc::Iostream &ios)
62     {
63       L4::Cap<L4::Thread> t = svr->cap_alloc<L4::Thread>();
64       if (!t.is_valid())
65         return -L4_ENOMEM;
66       int r = fi->create_thread(t);
67       if (r == 0)
68         ios << t;
69       return r;
70     }
71 
handle_gate(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)72   static int handle_gate(Factory_svr *svr, Factory_interface *fi,
73                          L4::Ipc::Iostream &ios)
74     {
75       l4_umword_t label;
76       L4::Ipc::Snd_fpage f;
77       L4::Cap<void> g = svr->cap_alloc<void>();
78       if (!g.is_valid())
79         return -L4_ENOMEM;
80 
81       ios >> label >> f;
82 
83       int r = fi->create_gate(g, svr->received_thread(f), label);
84 
85       if (r == 0)
86         ios << g;
87       return r;
88     }
89 
handle_irq(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)90   static int handle_irq(Factory_svr *svr, Factory_interface *fi,
91                         L4::Ipc::Iostream &ios)
92     {
93       L4::Cap<L4::Irq> i = svr->cap_alloc<L4::Irq>();
94       if (!i.is_valid())
95         return -L4_ENOMEM;
96       int r = fi->create_irq(i);
97       if (r == 0)
98         ios << i;
99       return r;
100     }
101 
handle_vm(Factory_svr * svr,Factory_interface * fi,L4::Ipc::Iostream & ios)102   static int handle_vm(Factory_svr *svr, Factory_interface *fi,
103                        L4::Ipc::Iostream &ios)
104     {
105       L4::Cap<L4::Vm> i = svr->cap_alloc<L4::Vm>();
106       if (!i.is_valid())
107         return -L4_ENOMEM;
108       int r = fi->create_vm(i);
109       if (r == 0)
110         ios << i;
111       return r;
112     }
113 };
114 
factory_dispatch(l4_umword_t,L4::Ipc::Iostream & ios)115 int Factory_svr::factory_dispatch(l4_umword_t, L4::Ipc::Iostream &ios)
116 {
117   L4::Opcode op;
118   ios >> op;
119   switch (op)
120     {
121     case L4_PROTO_FACTORY:
122       return Factory_hndl::handle_factory(this, _factory, ios);
123     case L4_PROTO_THREAD:
124       return Factory_hndl::handle_thread(this, _factory, ios);
125     case L4_PROTO_TASK:
126       return Factory_hndl::handle_task(this, _factory, ios);
127     case 0:
128       return Factory_hndl::handle_gate(this, _factory, ios);
129     case L4_PROTO_IRQ:
130       return Factory_hndl::handle_irq(this, _factory, ios);
131     case L4_PROTO_VM:
132       return Factory_hndl::handle_vm(this, _factory, ios);
133     default:
134       return -L4_ENOSYS;
135     };
136 }
137 
138 }
139