2 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
10 #include "app_model.h"
12 #include <l4/re/error_helper>
13 #include <l4/re/util/env_ns>
19 App_model::alloc_ds(unsigned long size) const
21 Dataspace mem = chkcap(L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>(),
22 "allocate capability");
23 L4::Cap<L4Re::Mem_alloc> _ma(prog_info()->mem_alloc.raw & L4_FPAGE_ADDR_MASK);
24 chksys(_ma->alloc(size, mem.get()), "allocate writable program segment");
28 App_model::Const_dataspace
29 App_model::open_file(char const *name)
31 L4Re::Util::Env_ns ens;
32 return L4Re::chkcap(ens.query<L4Re::Dataspace>(name), name, 0);
36 App_model::prog_attach_ds(l4_addr_t addr, unsigned long size,
37 Const_dataspace ds, unsigned long offset,
38 unsigned flags, char const *what)
40 unsigned rh_flags = flags;
43 printf("%s:%s: from ds:%lx+%lx... @%lx+%lx\n",
44 __func__, what, ds.cap(), offset, addr, size);
47 rh_flags |= L4Re::Rm::Reserved;
49 l4_addr_t _addr = addr;
50 L4Re::chksys(_task->rm()->attach(&_addr, size, rh_flags,
51 L4::Ipc::make_cap(ds.get(), (flags & L4Re::Rm::Read_only)
58 App_model::prog_reserve_area(l4_addr_t *start, unsigned long size,
59 unsigned flags, unsigned char align)
61 return _task->rm()->reserve_area(start, size, flags, align);
66 App_model::copy_ds(Dataspace dst, unsigned long dst_offs,
67 Const_dataspace src, unsigned long src_offs,
70 L4Re::chksys(dst->copy_in(dst_offs, src.get(), src_offs, size),
71 "Ned program launch: copy failed");
76 App_model::local_attach_ds(Const_dataspace ds, unsigned long size,
77 unsigned long offset) const
79 L4::Cap<L4Re::Rm> rm = L4Re::Env::env()->rm();
80 l4_addr_t pg_offset = l4_trunc_page(offset);
81 l4_addr_t in_pg_offset = offset - pg_offset;
82 unsigned long pg_size = l4_round_page(size + in_pg_offset);
84 chksys(rm->attach(&vaddr, pg_size,
85 L4Re::Rm::Search_addr | L4Re::Rm::Read_only,
86 ds.get(), pg_offset), "attach temporary VMA");
87 return vaddr + in_pg_offset;
91 App_model::local_detach_ds(l4_addr_t addr, unsigned long /*size*/) const
93 L4::Cap<L4Re::Rm> rm = L4Re::Env::env()->rm();
94 l4_addr_t pg_addr = l4_trunc_page(addr);
95 chksys(rm->detach(pg_addr, 0), "detach temporary VMA");
99 App_model::App_model()
102 // set default values for utcb area, values may be changed by loader
103 _info.utcbs_start = Utcb_area_start;
104 _info.utcbs_log2size = L4_PAGESHIFT;
106 // set default values for the application stack
107 extern char __L4_KIP_ADDR__[];
108 _info.kip = (l4_addr_t)__L4_KIP_ADDR__;
113 App_model::alloc_app_stack()
115 L4Re::Util::Ref_cap<L4Re::Dataspace>::Cap stack
116 = chkcap(L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>(),
117 "allocate stack capability");
118 L4::Cap<L4Re::Mem_alloc> _ma(prog_info()->mem_alloc.raw & L4_FPAGE_ADDR_MASK);
119 chksys(_ma->alloc(_stack.stack_size(), stack.get()),
122 _stack.set_stack(stack, _stack.stack_size());
124 return stack.release();
128 App_model::init_prog()
135 _info.mem_alloc = _ma.fpage();
136 _info.names = _ns.fpage();
137 _info.log = _log.fpage();
138 _info.factory = _factory.fpage();
139 _info.scheduler = _sched.fpage();
143 _info.ldr_flags = parser.ldr_flags.data;
144 _info.l4re_dbg = parser.l4re_dbg.data;
146 if (parser.cpu_affinity.data != ~0UL || parser.base_prio.data != Default_base_prio
147 || parser.max_prio.data != Default_max_prio)
149 info.printf(" base_prio = 0x%x max_prio = 0x%x\n",
150 parser.base_prio.data, parser.max_prio.data);
151 _task->_sched.set_prio(parser.base_prio.data, parser.max_prio.data);
152 _task->_sched.restrict_cpus(parser.cpu_affinity.data);
153 Gate_alloc::alloc(&_task->_sched);
154 _info.scheduler = _task->_sched.obj_cap().fpage();
155 scheduler_if = &_task->_sched;
158 info.printf("loading '%s'\n", argv.a0);
162 App_model::get_task_caps(L4::Cap<L4::Factory> *factory,
163 L4::Cap<L4::Task> *task,
164 L4::Cap<L4::Thread> *thread)
166 prog_info()->rm = _task->rm().fpage();
167 prog_info()->parent = _task->obj_cap().fpage();
168 Dbg(Dbg::Info).printf("parent cap is %lx\n", prog_info()->parent.raw);
169 *task = _task->task_cap();
170 *thread = _task->thread_cap();
171 *factory = L4::Cap<L4::Factory>(prog_info()->factory.raw & L4_FPAGE_ADDR_MASK);