]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libloader/include/remote_app_model
e422bb8a8dcdd9e31879df2578ce18f7f9a9c704
[l4.git] / l4 / pkg / libloader / include / remote_app_model
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Technische Universität Dresden
4  * This file is part of TUD:OS and distributed under the terms of the
5  * GNU Lesser General Public License 2.1.
6  * Please see the COPYING-LGPL-2.1 file for details.
7  */
8
9 #pragma once
10
11 #include <l4/re/env>
12 #include <l4/re/error_helper>
13 #include <l4/sys/task>
14 #include <l4/sys/thread>
15 #include <l4/sys/scheduler>
16 #include <l4/sys/factory>
17
18 namespace Ldr {
19
20 struct Remote_app_std_caps
21 {
22   enum Base_cap
23   {
24     Task_cap               = 1,
25     Factory_cap            = 2,
26     Rm_thread_cap          = 3,
27     External_rm_cap        = 5,
28     Allocator_cap          = 7,
29     Names_cap,
30     Log_cap,
31     Parent_cap,
32     Kip_cap,
33     Scheduler_cap,
34     First_free,
35   };
36 };
37
38 struct Remote_app_std_prios
39 {
40   enum Prio
41   {
42     Default_thread_prio = 2
43   };
44 };
45
46 template< typename Base, typename STD_CAPS = Remote_app_std_caps,
47           typename PRIOS = Remote_app_std_prios >
48 class Remote_app_model : public Base, protected STD_CAPS, protected PRIOS
49 {
50 public:
51   typedef STD_CAPS Caps;
52   typedef PRIOS Prios;
53
54   virtual ~Remote_app_model() throw() {}
55
56   template< typename A1, typename A2, typename A3 >
57   Remote_app_model(A1 const &a1, A2 const &a2, A3 const & a3)
58   : Base(a1, a2, a3) {}
59
60   template< typename A1, typename A2 >
61   Remote_app_model(A1 const &a1, A2 const &a2) : Base(a1, a2) {}
62
63   template< typename A1 >
64   explicit Remote_app_model(A1 const &a1) : Base(a1) {}
65
66   Remote_app_model() : Base() {}
67
68   L4Re::Env *add_env()
69   {
70     // the terminator
71     this->_stack.push(l4re_env_cap_entry_t());
72
73     l4_cap_idx_t first_free
74       = this->push_initial_caps(Caps::First_free << L4_CAP_SHIFT);
75
76     l4re_env_cap_entry_t *caps
77       = reinterpret_cast<l4re_env_cap_entry_t*>(this->_stack.ptr());
78
79     L4Re::Env *env = this->_stack.push(L4Re::Env());
80
81     env->mem_alloc(L4::Cap<L4Re::Mem_alloc>(Caps::Allocator_cap << L4_CAP_SHIFT));
82     env->parent(L4::Cap<L4Re::Parent>(Caps::Parent_cap << L4_CAP_SHIFT));
83     env->scheduler(L4::Cap<L4::Scheduler>(Caps::Scheduler_cap << L4_CAP_SHIFT));
84     env->rm(L4::Cap<L4Re::Rm>(Caps::External_rm_cap << L4_CAP_SHIFT));
85     env->log(L4::Cap<L4Re::Log>(Caps::Log_cap << L4_CAP_SHIFT));
86     env->main_thread(L4::Cap<L4::Thread>(Caps::Rm_thread_cap << L4_CAP_SHIFT));
87     env->factory(L4::Cap<L4::Factory>(Caps::Factory_cap << L4_CAP_SHIFT));
88     env->first_free_cap(first_free >> L4_CAP_SHIFT);
89     env->utcb_area(l4_fpage(this->_info.utcbs_start, this->_info.utcbs_log2size, 0));
90     env->first_free_utcb(this->_info.utcbs_start + L4_UTCB_OFFSET);
91     env->initial_caps(this->_stack.relocate(caps));
92     return env;
93   }
94
95   L4::Cap<void> prog_kip_ds() const
96   { return L4::Cap<void>(Caps::Kip_cap << L4_CAP_SHIFT); }
97
98   void const *generate_l4aux(char const *before_vma, char const *name)
99   {
100     this->_stack.set_ma_cnt(before_vma);
101     this->_stack.push(l4_umword_t(this->prog_info()->ldr_flags));
102     this->_stack.push(l4_umword_t(this->prog_info()->l4re_dbg));
103     this->_stack.push(l4_umword_t(prog_kip_ds().cap()));
104     return this->_stack.push_local_ptr(name);
105   }
106
107   void prog_reserve_utcb_area()
108   {
109     this->prog_attach_ds(this->prog_info()->utcbs_start,
110                          1UL << this->prog_info()->utcbs_log2size,
111                          this->reserved_area(), 0, 0, "attaching utcb area");
112   }
113
114   void prog_attach_kip()
115   {
116     this->prog_attach_ds(this->prog_info()->kip, L4_PAGESIZE,
117                          this->local_kip_ds(), 0,
118                          L4Re::Rm::Read_only, "attaching KIP segment");
119   }
120
121   void prog_attach_stack(typename Base::Dataspace app_stack)
122   {
123     this->prog_attach_ds(this->_stack.target_addr(), this->_stack.stack_size(),
124                          app_stack, 0, 0, "attaching stack segment");
125   }
126
127   void start_prog(L4Re::Env const *env)
128   {
129     using L4Re::chksys;
130     using L4::Cap;
131
132     L4::Cap<L4::Task> ntask;
133     L4::Cap<L4::Thread> nthread;
134     L4::Cap<L4::Factory> factory;
135
136     this->get_task_caps(&factory, &ntask, &nthread);
137
138     chksys(factory->create_task(ntask, env->utcb_area()));
139     chksys(factory->create_thread(nthread));
140
141     chksys(ntask->map(L4Re::This_task, ntask.fpage(),
142           Cap<L4::Task>(L4Re::This_task).snd_base()));
143     chksys(ntask->map(L4Re::This_task, this->_info.factory,
144           env->factory().snd_base()));
145     chksys(ntask->map(L4Re::This_task, nthread.fpage(),
146           env->main_thread().snd_base()));
147     chksys(ntask->map(L4Re::This_task, this->_info.scheduler,
148           env->scheduler().snd_base()));
149     chksys(ntask->map(L4Re::This_task, this->_info.parent,
150           env->parent().snd_base()));
151     chksys(ntask->map(L4Re::This_task, this->_info.log,
152           env->log().snd_base()));
153     chksys(ntask->map(L4Re::This_task, this->_info.rm,
154           env->rm().snd_base()));
155     chksys(ntask->map(L4Re::This_task, this->_info.mem_alloc,
156           env->mem_alloc().snd_base()));
157     chksys(ntask->map(L4Re::This_task, this->local_kip_cap().fpage(),
158           prog_kip_ds().snd_base()));
159
160     this->map_initial_caps(ntask, Caps::First_free << L4_CAP_SHIFT);
161
162     L4::Thread::Attr th_attr;
163
164     th_attr.pager(env->rm());
165     th_attr.exc_handler(env->rm());
166     th_attr.scheduler(env->rm());
167     th_attr.bind((l4_utcb_t*)this->_info.utcbs_start, ntask);
168
169     chksys(nthread->control(th_attr));
170     l4_sched_param_t sp;
171     sp.prio = Prios::Default_thread_prio;
172     sp.quantum = 0;
173     sp.affinity = l4_sched_cpu_set(0, ~0);
174
175     chksys(this->run_thread(nthread, sp));
176
177     nthread->ex_regs(this->_info.entry, this->_stack.target_ptr(), 0);
178   }
179
180
181 };
182
183 }