3 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU Lesser General Public License 2.1.
7 * Please see the COPYING-LGPL-2.1 file for details.
13 #include <l4/re/error_helper>
14 #include <l4/sys/task>
15 #include <l4/sys/thread>
16 #include <l4/sys/scheduler>
17 #include <l4/sys/factory>
21 struct Remote_app_std_caps
39 struct Remote_app_std_prios
43 Default_thread_prio = 2
47 template< typename Base, typename STD_CAPS = Remote_app_std_caps,
48 typename PRIOS = Remote_app_std_prios >
49 class Remote_app_model : public Base, protected STD_CAPS, protected PRIOS
52 typedef STD_CAPS Caps;
55 virtual ~Remote_app_model() throw() {}
57 template< typename A1, typename A2, typename A3 >
58 Remote_app_model(A1 const &a1, A2 const &a2, A3 const & a3)
61 template< typename A1, typename A2 >
62 Remote_app_model(A1 const &a1, A2 const &a2) : Base(a1, a2) {}
64 template< typename A1 >
65 explicit Remote_app_model(A1 const &a1) : Base(a1) {}
67 Remote_app_model() : Base() {}
72 this->_stack.push(l4re_env_cap_entry_t());
74 l4_cap_idx_t first_free
75 = this->push_initial_caps(Caps::First_free << L4_CAP_SHIFT);
77 l4re_env_cap_entry_t *caps
78 = reinterpret_cast<l4re_env_cap_entry_t*>(this->_stack.ptr());
80 L4Re::Env *env = this->_stack.push(L4Re::Env());
82 env->mem_alloc(L4::Cap<L4Re::Mem_alloc>(Caps::Allocator_cap << L4_CAP_SHIFT));
83 env->parent(L4::Cap<L4Re::Parent>(Caps::Parent_cap << L4_CAP_SHIFT));
84 env->scheduler(L4::Cap<L4::Scheduler>(Caps::Scheduler_cap << L4_CAP_SHIFT));
85 env->rm(L4::Cap<L4Re::Rm>(Caps::External_rm_cap << L4_CAP_SHIFT));
86 env->log(L4::Cap<L4Re::Log>(Caps::Log_cap << L4_CAP_SHIFT));
87 env->main_thread(L4::Cap<L4::Thread>(Caps::Rm_thread_cap << L4_CAP_SHIFT));
88 env->factory(L4::Cap<L4::Factory>(Caps::Factory_cap << L4_CAP_SHIFT));
89 env->first_free_cap(first_free >> L4_CAP_SHIFT);
90 env->utcb_area(l4_fpage(this->_info.utcbs_start, this->_info.utcbs_log2size, 0));
91 env->first_free_utcb(this->_info.utcbs_start + L4_UTCB_OFFSET);
92 env->initial_caps(this->_stack.relocate(caps));
96 L4::Cap<void> prog_kip_ds() const
97 { return L4::Cap<void>(Caps::Kip_cap << L4_CAP_SHIFT); }
99 void const *generate_l4aux(char const *before_vma, char const *name)
101 this->_stack.set_ma_cnt(before_vma);
102 this->_stack.push(l4_umword_t(this->prog_info()->ldr_flags));
103 this->_stack.push(l4_umword_t(this->prog_info()->l4re_dbg));
104 this->_stack.push(l4_umword_t(prog_kip_ds().cap()));
105 return this->_stack.push_local_ptr(name);
108 void prog_reserve_utcb_area()
110 this->prog_attach_ds(this->prog_info()->utcbs_start,
111 1UL << this->prog_info()->utcbs_log2size,
112 this->reserved_area(), 0, 0, "attaching utcb area");
115 void prog_attach_kip()
117 this->prog_attach_ds(this->prog_info()->kip, L4_PAGESIZE,
118 this->local_kip_ds(), 0,
119 L4Re::Rm::Read_only, "attaching KIP segment");
122 void prog_attach_stack(typename Base::Dataspace app_stack)
124 this->prog_attach_ds(this->_stack.target_addr(), this->_stack.stack_size(),
125 app_stack, 0, 0, "attaching stack segment");
128 void start_prog(L4Re::Env const *env)
133 L4::Cap<L4::Task> ntask;
134 L4::Cap<L4::Thread> nthread;
135 L4::Cap<L4::Factory> factory;
137 this->get_task_caps(&factory, &ntask, &nthread);
139 chksys(factory->create_task(ntask, env->utcb_area()));
140 chksys(factory->create_thread(nthread));
142 chksys(ntask->map(L4Re::This_task, ntask.fpage(),
143 Cap<L4::Task>(L4Re::This_task).snd_base()));
144 chksys(ntask->map(L4Re::This_task, this->_info.factory,
145 env->factory().snd_base()));
146 chksys(ntask->map(L4Re::This_task, nthread.fpage(),
147 env->main_thread().snd_base()));
148 chksys(ntask->map(L4Re::This_task, this->_info.scheduler,
149 env->scheduler().snd_base()));
150 chksys(ntask->map(L4Re::This_task, this->_info.parent,
151 env->parent().snd_base()));
152 chksys(ntask->map(L4Re::This_task, this->_info.log,
153 env->log().snd_base()));
154 chksys(ntask->map(L4Re::This_task, this->_info.rm,
155 env->rm().snd_base()));
156 chksys(ntask->map(L4Re::This_task, this->_info.mem_alloc,
157 env->mem_alloc().snd_base()));
158 chksys(ntask->map(L4Re::This_task, this->local_kip_cap().fpage(),
159 prog_kip_ds().snd_base()));
161 this->map_initial_caps(ntask, Caps::First_free << L4_CAP_SHIFT);
163 L4::Thread::Attr th_attr;
165 th_attr.pager(env->rm());
166 th_attr.exc_handler(env->rm());
167 th_attr.bind((l4_utcb_t*)this->_info.utcbs_start, ntask);
169 chksys(nthread->control(th_attr));
171 sp.prio = Prios::Default_thread_prio;
173 sp.affinity = l4_sched_cpu_set(0, ~0);
175 chksys(this->run_thread(nthread, sp));
177 nthread->ex_regs(this->_info.entry, this->_stack.target_ptr(), 0);