]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re_kernel/server/src/main.cc
update
[l4.git] / l4 / pkg / l4re_kernel / server / src / main.cc
1 /*
2  * (c) 2008-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 #include <l4/re/namespace>
11 #include <l4/re/dataspace>
12 #include <l4/re/mem_alloc>
13 #include <l4/re/rm>
14 #include <l4/re/log>
15 #include <l4/re/env>
16 #include <l4/re/error_helper>
17 #include <l4/re/util/env_ns>
18
19 #include <l4/cxx/exceptions>
20 #include <l4/cxx/iostream>
21 #include <l4/cxx/l4iostream>
22 #include <l4/sys/debugger.h>
23 #include <l4/sys/scheduler>
24 #include <l4/sys/thread>
25
26 #include <cstdlib>
27 #include <cstring>
28
29 #include "region.h"
30 #include "page_alloc.h"
31 #include "globals.h"
32 #include "loader_elf.h"
33 #include "debug.h"
34 #include "dispatcher.h"
35
36 #include <l4/re/elf_aux.h>
37
38 L4RE_ELF_AUX_ELEM_T(l4re_elf_aux_mword_t, __stack_addr, L4RE_ELF_AUX_T_STACK_ADDR, 0xb1000000);
39
40 using L4::Cap;
41 using L4Re::Dataspace;
42
43 extern "C" int main(int argc, char const *argv[]);
44
45 static Elf_loader loader;
46 Region_map __local_rm;
47 L4::Cap<void> rcv_cap;
48
49 class Loop_hooks :
50   public L4::Ipc_svr::Ignore_errors,
51   public L4::Ipc_svr::Default_timeout,
52   public L4::Ipc_svr::Compound_reply
53 {
54 public:
55   static void setup_wait(L4::Ipc::Istream &istr, bool)
56   {
57     istr.reset();
58     istr << L4::Ipc::Small_buf(rcv_cap.cap(), L4_RCV_ITEM_LOCAL_ID);
59     l4_utcb_br_u(istr.utcb())->bdr = 0;
60   }
61 };
62
63 extern "C" void *__libc_alloc_initial_tls(unsigned long size);
64
65 void *__libc_alloc_initial_tls(unsigned long size)
66 {
67   using namespace L4;
68   using namespace L4Re;
69   Cap<Dataspace> ds(Env::env()->first_free_cap() << L4_CAP_SHIFT);
70   ::l4re_global_env->first_free_cap += 1;
71   if (Env::env()->mem_alloc()->alloc(size, ds, 0) < 0)
72     return NULL;
73
74   void *addr = (void*)0xb0000000;
75   if(Env::env()->rm()->attach(&addr, size, Rm::Search_addr,
76                               ds, 0, 0) < 0)
77     return NULL;
78
79   return addr;
80 }
81
82 static L4::Server<Loop_hooks> server(l4_utcb());
83
84 static void insert_regions()
85 {
86   using L4Re::Rm;
87   using L4Re::Env;
88   int n;
89   l4_addr_t addr = 0;
90   Rm::Region *rl;
91   while ((n = L4Re::Env::env()->rm()->get_regions(addr, &rl)) > 0)
92     {
93       for (int i = 0; i < n; ++i)
94         {
95           Rm::Region const *r = &rl[i];
96           void *x = __local_rm.attach((void*)r->start, r->end - r->start +1,
97           Region_handler(L4::cap_reinterpret_cast<L4Re::Dataspace>(Env::env()->rm()),
98                          L4_INVALID_CAP, 0, Rm::Pager), 0);
99           if (!x)
100             {
101               L4::cerr << "l4re: error while initializing region mapper\n";
102               exit(1);
103             }
104
105           addr = r->end + 1;
106         }
107
108     }
109
110   Rm::Area *al;
111   while ((n = L4Re::Env::env()->rm()->get_areas(addr, &al)) > 0)
112     {
113       for (int i = 0; i < n; ++i)
114         {
115           Rm::Area const *r = &al[i];
116           l4_addr_t x = __local_rm.attach_area(r->start, r->end - r->start +1);
117           if (!x)
118             {
119               L4::cerr << "l4re: error while initializing region mapper\n";
120               exit(1);
121             }
122
123           addr = r->end + 1;
124         }
125     }
126 }
127
128 int main(int argc, char const *argv[])
129 {
130   Dbg::set_level(Dbg::Info | Dbg::Warn);
131
132   Dbg boot(Dbg::Boot);
133   try
134     {
135
136   l4_umword_t *envp = (l4_umword_t*)&argv[argc] + 1;
137   l4_umword_t *auxp = envp;
138   while (*auxp)
139     ++auxp;
140
141   ++auxp;
142
143   Global::argc = argc;
144   Global::argv = argv;
145   Global::envp = (char const * const*)envp;
146 #if 0
147   L4::cout << "ARGC=" << argc << "\n"
148            << "ARGV=" << argv << "\n"
149            << "ENVP=" << envp << "\n"
150            << "AUXP=" << auxp << "\n";
151
152   for (int i = 0; i < argc; ++i)
153     L4::cout << "  arg: '" << argv[i] << "'\n";
154
155   for (char const *const *e = Global::envp; *e; ++e)
156     L4::cout << "  env: '" << *e << "'\n";
157 #endif
158
159   L4Re::Env *const env = const_cast<L4Re::Env*>(L4Re::Env::env());
160
161   while (*auxp)
162     {
163       if (*auxp == 0xf0)
164         Global::l4re_aux = (l4re_aux_t*)auxp[1];
165       auxp += 2;
166     }
167
168 #if 0
169   L4::cout << "AUX=" << aux << "\n"
170            << "ENV=" << env << "\n";
171 #endif
172
173   //L4::cout << "Binary: " << aux->binary << " " << env << "\n";
174   if (!env || !Global::l4re_aux)
175     {
176       Err(Err::Fatal).printf("invalid AUX vectors...\n");
177       exit(1);
178     }
179
180     {
181       char s[15];
182       char *t = strstr(Global::l4re_aux->binary, "rom/");
183       s[0] = '#';
184       strncpy(s + 1, t ? t + 4 : Global::l4re_aux->binary, sizeof(s)-1);
185       s[sizeof(s)-1] = 0;
186       l4_debugger_set_object_name(L4_BASE_THREAD_CAP, s);
187       l4_debugger_set_object_name(L4_BASE_TASK_CAP, s + 1);
188     }
189
190   Dbg::set_level(Global::l4re_aux->dbg_lvl);
191
192   env->first_free_cap(env->first_free_cap() + Global::Max_local_rm_caps);
193   boot.printf("first free cap for application: 0x%lx\n", env->first_free_cap());
194
195     {
196       Cap<L4Re::Mem_alloc> obj = env->mem_alloc();
197
198       if (!obj.is_valid())
199         {
200           Err(Err::Fatal).printf("could not find the base memory allocator\n");
201           return -1;
202         }
203       Global::allocator = obj;
204     }
205
206   boot.printf("setup page allocator\n");
207   Single_page_alloc_base::init(Global::allocator);
208
209   Global::local_rm = &__local_rm;
210
211   rcv_cap = Global::cap_alloc.alloc<void>();
212
213   boot.printf("setup local region mapping\n");
214   __local_rm.init();
215   boot.printf("adding regions from remote region mapper\n");
216   insert_regions();
217
218   boot.printf("initializing local page allocator\n");
219   Single_page_alloc_base::init_local_rm(Global::local_rm);
220
221
222   L4::Cap<Dataspace> file;
223
224   boot.printf("load binary '%s'\n", Global::l4re_aux->binary);
225
226   file = L4Re_app_model::open_file(Global::l4re_aux->binary);
227
228   loader.start(file, Global::local_rm, Global::l4re_aux);
229
230   // Raise RM prio to its MCP
231   env->scheduler()->run_thread(env->main_thread(), l4_sched_param(L4_SCHED_MAX_PRIO));
232
233   boot.printf("Start server loop\n");
234   server.loop(Dispatcher());
235   } catch (L4::Runtime_error const &e)
236     {
237       Err(Err::Fatal).printf("Exception %s: '%s'\n", e.str(), e.extra_str());
238       L4::cerr << e;
239       return 1;
240     }
241   catch (L4::Base_exception const &e)
242     {
243       Err(Err::Fatal).printf("Exception %s\n", e.str());
244       L4::cerr << e;
245       return 1;
246     }
247
248   return 0;
249 }