21 |
#include <config.h> |
#include <config.h> |
22 |
#endif |
#endif |
23 |
|
|
24 |
|
#include <unistd.h> |
25 |
#include <alloca.h> |
#include <alloca.h> |
26 |
|
|
27 |
#include "wortel.h" |
#include "wortel.h" |
28 |
|
|
29 |
|
|
30 |
/* The program name. */ |
/* The program name. */ |
31 |
char *program_name = "wortel"; |
const char program_name[] = "wortel"; |
32 |
|
|
33 |
|
/* The region of wortel itself. */ |
34 |
|
l4_word_t wortel_start; |
35 |
|
l4_word_t wortel_end; |
36 |
|
|
37 |
|
|
38 |
|
/* Room for the arguments. 1 KB is a cramped half-screen full, which |
39 |
|
should be more than enough. */ |
40 |
|
char mods_args[1024]; |
41 |
|
|
42 |
|
/* The number of bytes in mods_args already consumed. */ |
43 |
|
unsigned mods_args_len; |
44 |
|
|
45 |
const char *mod_names[] = { "physmem-mod", "task-mod", "root-fs-mod" }; |
const char *mod_names[] = { "physmem-mod", "task-mod", "root-fs-mod" }; |
46 |
|
|
52 |
unsigned int mods_count; |
unsigned int mods_count; |
53 |
|
|
54 |
|
|
55 |
|
/* The maximum number of tasks allowed to use the rootserver. */ |
56 |
|
#define MAX_USERS 16 |
57 |
|
|
58 |
|
/* FIXME: Needs to be somewhere else. */ |
59 |
|
typedef l4_word_t hurd_task_id_t; |
60 |
|
#define HURD_TASK_ID_NULL 0 |
61 |
|
|
62 |
|
/* The allowed user tasks. */ |
63 |
|
static hurd_task_id_t cap_list[MAX_USERS]; |
64 |
|
|
65 |
|
/* Register TASK as allowed user and return the capability ID, or -1 |
66 |
|
if there is no space. */ |
67 |
|
static int |
68 |
|
wortel_add_user (hurd_task_id_t task) |
69 |
|
{ |
70 |
|
unsigned int i; |
71 |
|
|
72 |
|
for (i = 0; i < MAX_USERS; i++) |
73 |
|
if (cap_list[i] == HURD_TASK_ID_NULL) |
74 |
|
break; |
75 |
|
|
76 |
|
if (i == MAX_USERS) |
77 |
|
return -1; |
78 |
|
|
79 |
|
cap_list[i] = task; |
80 |
|
return i; |
81 |
|
} |
82 |
|
|
83 |
|
#define WORTEL_CAP_VALID(capnr, task) \ |
84 |
|
(capnr >= 0 && capnr < MAX_USERS && cap_list[capnr] == task) |
85 |
|
|
86 |
|
|
87 |
/* Return the number of memory descriptors. */ |
/* Return the number of memory descriptors. */ |
88 |
l4_word_t |
l4_word_t |
89 |
loader_get_num_memory_desc (void) |
loader_get_num_memory_desc (void) |
101 |
} |
} |
102 |
|
|
103 |
|
|
|
static void |
|
|
load_components (void) |
|
|
{ |
|
|
unsigned int i; |
|
|
|
|
|
for (i = 0; i < mods_count; i++) |
|
|
loader_add_region (mods[i].name, mods[i].start, mods[i].end); |
|
|
|
|
|
if (!mods[MOD_PHYSMEM].start) |
|
|
panic ("No physical memory server found"); |
|
|
|
|
|
loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start, |
|
|
mods[MOD_PHYSMEM].end, |
|
|
&mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end, |
|
|
&mods[MOD_PHYSMEM].ip); |
|
|
loader_remove_region ("physmem-mod"); |
|
|
} |
|
|
|
|
|
|
|
104 |
/* The maximum number of fpages required to cover a page aligned range |
/* The maximum number of fpages required to cover a page aligned range |
105 |
of memory. This is k if the maximum memory range size to cover is |
of memory. This is k if the maximum memory range size to cover is |
106 |
2^(k + min_page_size_log2), which can be easily proved by |
2^(k + min_page_size_log2), which can be easily proved by |
108 |
#define MAX_FPAGES (sizeof (l4_word_t) * 8 - 10) |
#define MAX_FPAGES (sizeof (l4_word_t) * 8 - 10) |
109 |
|
|
110 |
|
|
111 |
/* Determine the fpages required to cover the bytes from START to END, |
/* Determine the fpages required to cover the bytes from START to END |
112 |
which must be aligned to the minimal page size supported by the |
(exclusive). START must be aligned to the minimal page size |
113 |
system. Returns the number of fpages required to cover the range, |
supported by the system. Returns the number of fpages required to |
114 |
and returns that many fpages (with maximum accessibility) in |
cover the range, and returns that many fpages (with maximum |
115 |
FPAGES. At most MAX_FPAGES fpages will be returned. */ |
accessibility) in FPAGES. At most MAX_FPAGES fpages will be |
116 |
unsigned int |
returned. */ |
117 |
make_fpages (l4_word_t start, l4_word_t size, l4_fpage_t *fpages) |
static unsigned int |
118 |
|
make_fpages (l4_word_t start, l4_word_t end, l4_fpage_t *fpages) |
119 |
{ |
{ |
120 |
l4_word_t min_page_size = getpagesize (); |
l4_word_t min_page_size = getpagesize (); |
|
l4_word_t end = start + size; |
|
121 |
unsigned int nr_fpages = 0; |
unsigned int nr_fpages = 0; |
122 |
if (!size) |
|
123 |
|
if (start >= end) |
124 |
return 0; |
return 0; |
125 |
|
|
126 |
if (start & (min_page_size - 1)) |
if (start & (min_page_size - 1)) |
127 |
panic ("make_fpages: START is not aligned to minimum page size"); |
panic ("make_fpages: START is not aligned to minimum page size"); |
|
if (size & (min_page_size - 1)) |
|
|
panic ("make_fpages: SIZE is not aligned to minimum page size"); |
|
128 |
|
|
129 |
debug ("Make fpages from 0x%x (size 0x%x): ", start, size); |
end = (end + min_page_size - 1) & ~(min_page_size - 1); |
130 |
/* END is at least one MIN_PAGE_SIZE larger than START. */ |
/* END is now at least one MIN_PAGE_SIZE larger than START. */ |
131 |
nr_fpages = 0; |
nr_fpages = 0; |
132 |
while (start < end) |
while (start < end) |
133 |
{ |
{ |
134 |
fpages[nr_fpages] = l4_fpage (start, end - start); |
fpages[nr_fpages] = l4_fpage_add_rights (l4_fpage (start, end - start), |
135 |
debug ("0x%x/%u ", start, l4_size_log2 (fpages[nr_fpages])); |
l4_fully_accessible); |
136 |
start += l4_size (fpages[nr_fpages]); |
start += l4_size (fpages[nr_fpages]); |
137 |
nr_fpages++; |
nr_fpages++; |
138 |
} |
} |
|
debug ("\n"); |
|
139 |
return nr_fpages; |
return nr_fpages; |
140 |
} |
} |
141 |
|
|
142 |
|
|
143 |
|
/* Request the fpage FPAGE from sigma0. */ |
144 |
static void |
static void |
145 |
start_components (void) |
sigma0_get_fpage (l4_fpage_t fpage) |
146 |
{ |
{ |
147 |
|
l4_msg_t msg; |
148 |
|
l4_msg_tag_t msg_tag; |
149 |
|
l4_map_item_t map_item; |
150 |
|
|
151 |
|
l4_accept (l4_map_grant_items (l4_complete_address_space)); |
152 |
|
l4_msg_clear (&msg); |
153 |
|
l4_set_msg_label (&msg, 0xffa0); |
154 |
|
l4_msg_append_word (&msg, fpage.raw); |
155 |
|
l4_msg_append_word (&msg, L4_DEFAULT_MEMORY); |
156 |
|
l4_msg_load (&msg); |
157 |
|
msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1)); |
158 |
|
if (l4_ipc_failed (msg_tag)) |
159 |
|
panic ("sigma0 request failed during %s: %u", |
160 |
|
l4_error_code () & 1 ? "receive" : "send", |
161 |
|
(l4_error_code () >> 1) & 0x7); |
162 |
|
if (l4_untyped_words (msg_tag) != 0 |
163 |
|
|| l4_typed_words (msg_tag) != 2) |
164 |
|
panic ("Invalid format of sigma0 reply"); |
165 |
|
l4_msg_store (msg_tag, &msg); |
166 |
|
l4_msg_get_map_item (&msg, 0, &map_item); |
167 |
|
if (map_item.send_fpage.raw == l4_nilpage.raw) |
168 |
|
panic ("sigma0 rejected mapping"); |
169 |
|
} |
170 |
|
|
171 |
|
/* Request an fpage of the size 2^SIZE from sigma0. */ |
172 |
|
static l4_fpage_t |
173 |
|
sigma0_get_any (unsigned int size) |
174 |
|
{ |
175 |
|
l4_msg_t msg; |
176 |
|
l4_msg_tag_t msg_tag; |
177 |
|
l4_map_item_t map_item; |
178 |
|
l4_fpage_t fpage = l4_fpage_add_rights (l4_fpage_log2 (-1, size), |
179 |
|
l4_fully_accessible); |
180 |
|
|
181 |
|
l4_accept (l4_map_grant_items (l4_complete_address_space)); |
182 |
|
l4_msg_clear (&msg); |
183 |
|
l4_set_msg_label (&msg, 0xffa0); |
184 |
|
debug ("Request 0x%x\n", fpage.raw); |
185 |
|
l4_msg_append_word (&msg, fpage.raw); |
186 |
|
l4_msg_append_word (&msg, L4_DEFAULT_MEMORY); |
187 |
|
l4_msg_load (&msg); |
188 |
|
msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1)); |
189 |
|
if (l4_ipc_failed (msg_tag)) |
190 |
|
panic ("sigma0 request failed during %s: %u", |
191 |
|
l4_error_code () & 1 ? "receive" : "send", |
192 |
|
(l4_error_code () >> 1) & 0x7); |
193 |
|
if (l4_untyped_words (msg_tag) != 0 |
194 |
|
|| l4_typed_words (msg_tag) != 2) |
195 |
|
panic ("Invalid format of sigma0 reply"); |
196 |
|
l4_msg_store (msg_tag, &msg); |
197 |
|
l4_msg_get_map_item (&msg, 0, &map_item); |
198 |
|
debug ("Got 0x%x\n", map_item.send_fpage.raw); |
199 |
|
return map_item.send_fpage; |
200 |
|
} |
201 |
|
|
202 |
|
|
203 |
|
static void |
204 |
|
load_components (void) |
205 |
|
{ |
206 |
|
l4_fpage_t fpages[MAX_FPAGES]; |
207 |
|
unsigned int nr_fpages; |
208 |
l4_word_t min_page_size = getpagesize (); |
l4_word_t min_page_size = getpagesize (); |
209 |
l4_word_t ret; |
unsigned int i; |
210 |
l4_word_t control; |
|
211 |
|
/* One issue we have to solve is to make sure that when the physical |
212 |
|
memory server requests all the available physical pages, we know |
213 |
|
which pages we can give to it, and which we can't. This can be |
214 |
|
left to sigma0, as long as we request all pages from sigma0 we |
215 |
|
can't give to the physical memory server up-front. |
216 |
|
|
217 |
|
We do this in several steps: First, we copy all of the startup |
218 |
|
information to memory that is part of the wortel binary image |
219 |
|
itself. This is done by the architecture dependant |
220 |
|
find_components function. Then we request all of our own memory, |
221 |
|
and all the memory needed for the physical memory server image |
222 |
|
(at its destination address), and all the memory for each module |
223 |
|
(at their corresponding load addresses). */ |
224 |
|
|
225 |
|
if (wortel_start & (min_page_size - 1)) |
226 |
|
panic ("%s does not start on a page boundary", program_name); |
227 |
|
loader_add_region (program_name, wortel_start, wortel_end); |
228 |
|
nr_fpages = make_fpages (wortel_start, wortel_end, fpages); |
229 |
|
while (nr_fpages--) |
230 |
|
sigma0_get_fpage (fpages[nr_fpages]); |
231 |
|
|
232 |
|
/* First protect all pages covered by the modules. This will also |
233 |
|
show if each module starts (and ends) on its own page. */ |
234 |
|
for (i = 0; i < mods_count; i++) |
235 |
|
{ |
236 |
|
if (mods[i].start & (min_page_size - 1)) |
237 |
|
panic ("Module %s does not start on a page boundary", mods[i].name); |
238 |
|
loader_add_region (mods[i].name, mods[i].start, mods[i].end); |
239 |
|
} |
240 |
|
|
241 |
|
/* Now load the physical memory server to its destination |
242 |
|
address. */ |
243 |
|
if (!mods[MOD_PHYSMEM].start) |
244 |
|
panic ("No physical memory server found"); |
245 |
|
loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start, |
246 |
|
mods[MOD_PHYSMEM].end, |
247 |
|
&mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end, |
248 |
|
&mods[MOD_PHYSMEM].ip); |
249 |
|
loader_remove_region ("physmem-mod"); |
250 |
|
|
251 |
|
/* Finally we can request all the memory for the physical memory |
252 |
|
server and all other modules from sigma0. This will register the |
253 |
|
memory as taken by us, and the memory will not be returned by any |
254 |
|
future request. */ |
255 |
|
for (i = 0; i < mods_count; i++) |
256 |
|
{ |
257 |
|
nr_fpages = make_fpages (mods[i].start, mods[i].end, fpages); |
258 |
|
while (nr_fpages--) |
259 |
|
sigma0_get_fpage (fpages[nr_fpages]); |
260 |
|
} |
261 |
|
} |
262 |
|
|
263 |
|
|
264 |
|
static void |
265 |
|
start_components (void) |
266 |
|
{ |
267 |
l4_msg_t msg; |
l4_msg_t msg; |
268 |
l4_msg_tag_t msg_tag; |
l4_msg_tag_t msg_tag; |
269 |
|
l4_word_t ret; |
270 |
|
l4_word_t control; |
271 |
|
int cap_id; |
272 |
|
|
|
if (mods[MOD_PHYSMEM].start & (min_page_size - 1)) |
|
|
panic ("physmem is not page aligned on this architecture"); |
|
273 |
if (mods[MOD_PHYSMEM].start > mods[MOD_PHYSMEM].end) |
if (mods[MOD_PHYSMEM].start > mods[MOD_PHYSMEM].end) |
274 |
panic ("physmem has invalid memory range"); |
panic ("physmem has invalid memory range"); |
275 |
if (mods[MOD_PHYSMEM].ip < mods[MOD_PHYSMEM].start |
if (mods[MOD_PHYSMEM].ip < mods[MOD_PHYSMEM].start |
276 |
|| mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end) |
|| mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end) |
277 |
panic ("physmem has invalid IP"); |
panic ("physmem has invalid IP"); |
278 |
|
|
279 |
|
|
280 |
|
cap_id = wortel_add_user (2); |
281 |
|
/* FIXME: Pass cap_id to physmem. */ |
282 |
/* Thread nr is next available after rootserver thread nr, |
/* Thread nr is next available after rootserver thread nr, |
283 |
version part is 2 (rootserver is 1). */ |
version part is 2 (rootserver is 1). */ |
284 |
l4_thread_id_t physmem_server |
l4_thread_id_t physmem_server |
320 |
{ |
{ |
321 |
l4_fpage_t fpages[MAX_FPAGES]; |
l4_fpage_t fpages[MAX_FPAGES]; |
322 |
unsigned int nr_fpages; |
unsigned int nr_fpages; |
|
l4_word_t size = (mods[MOD_PHYSMEM].end - mods[MOD_PHYSMEM].start |
|
|
+ min_page_size - 1) & ~(min_page_size - 1); |
|
323 |
|
|
324 |
/* We want to grant all the memory for the physmem binary image |
/* We want to grant all the memory for the physmem binary image |
325 |
with the first page fault, but we might have to send several |
with the first page fault, but we might have to send several |
326 |
fpages. So we first create a list of all fpages we need, then |
fpages. So we first create a list of all fpages we need, then |
327 |
we serve one after another, providing the one containing the |
we serve one after another, providing the one containing the |
328 |
fault address last. */ |
fault address last. */ |
329 |
nr_fpages = make_fpages (mods[MOD_PHYSMEM].start, size, |
nr_fpages = make_fpages (mods[MOD_PHYSMEM].start, mods[MOD_PHYSMEM].end, |
330 |
fpages); |
fpages); |
331 |
|
|
332 |
/* Now serve page requests. */ |
/* Now serve page requests. */ |
361 |
if (i == nr_fpages) |
if (i == nr_fpages) |
362 |
panic ("Could not find suitable fpage"); |
panic ("Could not find suitable fpage"); |
363 |
|
|
364 |
fpage = l4_fpage_add_rights (fpages[i], l4_fully_accessible); |
fpage = fpages[i]; |
|
debug ("Granting Fpage: 0x%x/%u\n", l4_address (fpage), |
|
|
l4_size_log2 (fpage)); |
|
|
|
|
365 |
if (i != 0) |
if (i != 0) |
366 |
fpages[i] = fpages[nr_fpages - 1]; |
fpages[i] = fpages[nr_fpages - 1]; |
367 |
nr_fpages--; |
nr_fpages--; |
368 |
|
|
369 |
/* First we have to request the fpage from sigma0. */ |
/* The memory was already requested from sigma0 by |
370 |
l4_accept (l4_map_grant_items (l4_complete_address_space)); |
load_components, so grant it right away. */ |
371 |
l4_msg_clear (&msg); |
debug ("Granting fpage: 0x%x/%u\n", l4_address (fpage), |
372 |
l4_set_msg_label (&msg, 0xffa0); |
l4_size_log2 (fpage)); |
|
l4_msg_append_word (&msg, fpage.raw); |
|
|
l4_msg_append_word (&msg, L4_DEFAULT_MEMORY); |
|
|
l4_msg_load (&msg); |
|
|
msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1)); |
|
|
if (l4_ipc_failed (msg_tag)) |
|
|
panic ("sigma0 request failed during %s: %u", |
|
|
l4_error_code () & 1 ? "receive" : "send", |
|
|
(l4_error_code () >> 1) & 0x7); |
|
|
if (l4_untyped_words (msg_tag) != 0 |
|
|
|| l4_typed_words (msg_tag) != 2) |
|
|
panic ("Invalid format of sigma0 reply"); |
|
|
l4_msg_store (msg_tag, &msg); |
|
|
if (l4_msg_word (&msg, 1) == l4_nilpage.raw) |
|
|
panic ("sigma0 rejected mapping"); |
|
|
|
|
|
/* Now we can grant the mapping to the physmem server. |
|
|
FIXME: Should use the fpage returned by sigma0. */ |
|
373 |
l4_msg_clear (&msg); |
l4_msg_clear (&msg); |
374 |
l4_set_msg_label (&msg, 0); |
l4_set_msg_label (&msg, 0); |
375 |
/* FIXME: Keep track of mappings already provided. Possibly |
/* FIXME: Keep track of mappings already provided. Possibly |
381 |
} |
} |
382 |
} |
} |
383 |
|
|
384 |
|
/* Now we have kicked off the boot process. The rest will be done |
385 |
|
in the normal server loop. */ |
386 |
|
} |
387 |
|
|
388 |
|
|
389 |
|
/* Serve rootserver bootstrap requests. */ |
390 |
|
static void |
391 |
|
serve_bootstrap_requests (void) |
392 |
|
{ |
393 |
|
/* The size of the region that we are currently trying to allocate |
394 |
|
for GET_MEM requests. If this is smaller than 2^10, no more |
395 |
|
memory is available. */ |
396 |
|
unsigned int get_mem_size = 12; |
397 |
|
|
398 |
do |
do |
399 |
{ |
{ |
400 |
|
l4_thread_id_t from; |
401 |
l4_word_t label; |
l4_word_t label; |
402 |
|
l4_msg_t msg; |
403 |
|
l4_msg_tag_t msg_tag; |
404 |
|
|
405 |
msg_tag = l4_receive (physmem_server); |
msg_tag = l4_wait (&from); |
406 |
if (l4_ipc_failed (msg_tag)) |
if (l4_ipc_failed (msg_tag)) |
407 |
panic ("Receiving messages from physmemserver thread failed: %u", |
panic ("Receiving message failed: %u", (l4_error_code () >> 1) & 0x7); |
|
(l4_error_code () >> 1) & 0x7); |
|
408 |
|
|
409 |
label = l4_label (msg_tag); |
label = l4_label (msg_tag); |
410 |
l4_msg_store (msg_tag, &msg); |
l4_msg_store (msg_tag, &msg); |
411 |
|
/* We don't do any access control in the bootstrap loop. */ |
412 |
|
|
413 |
#define WORTEL_MSG_PUTCHAR 1 |
#define WORTEL_MSG_PUTCHAR 1 |
414 |
|
#define WORTEL_MSG_GET_MEM 2 |
415 |
if (label == WORTEL_MSG_PUTCHAR) |
if (label == WORTEL_MSG_PUTCHAR) |
416 |
{ |
{ |
417 |
int chr; |
int chr; |
418 |
|
|
419 |
/* This is a putchar() message. */ |
/* This is a putchar() message. */ |
420 |
|
if (l4_untyped_words (msg_tag) != 2 |
421 |
|
|| l4_typed_words (msg_tag) != 0) |
422 |
|
panic ("Invalid format of putchar msg"); |
423 |
|
|
424 |
|
chr = (int) l4_msg_word (&msg, 1); |
425 |
|
putchar (chr); |
426 |
|
/* No reply needed. */ |
427 |
|
continue; |
428 |
|
} |
429 |
|
else if (WORTEL_MSG_GET_MEM) |
430 |
|
{ |
431 |
|
l4_fpage_t fpage; |
432 |
|
l4_grant_item_t grant_item; |
433 |
|
|
434 |
if (l4_untyped_words (msg_tag) != 1 |
if (l4_untyped_words (msg_tag) != 1 |
435 |
|| l4_typed_words (msg_tag) != 0) |
|| l4_typed_words (msg_tag) != 0) |
436 |
|
panic ("Invalid format of get_mem msg"); |
437 |
|
|
438 |
|
if (get_mem_size < 10) |
439 |
|
panic ("physmem server does not stop requesting memory"); |
440 |
|
|
441 |
|
do |
442 |
|
{ |
443 |
|
fpage = sigma0_get_any (get_mem_size); |
444 |
|
if (fpage.raw == l4_nilpage.raw) |
445 |
|
get_mem_size--; |
446 |
|
} |
447 |
|
while (fpage.raw == l4_nilpage.raw && get_mem_size >= 10); |
448 |
|
|
449 |
|
grant_item = l4_grant_item (fpage, l4_address (fpage)); |
450 |
|
l4_msg_clear (&msg); |
451 |
|
l4_msg_append_grant_item (&msg, grant_item); |
452 |
|
l4_msg_load (&msg); |
453 |
|
l4_reply (from); |
454 |
|
} |
455 |
|
else |
456 |
|
panic ("Invalid message with tag 0x%x", msg_tag.raw); |
457 |
|
} |
458 |
|
while (1); |
459 |
|
} |
460 |
|
|
461 |
|
|
462 |
|
/* Serve rootserver requests. */ |
463 |
|
static void |
464 |
|
serve_requests (void) |
465 |
|
{ |
466 |
|
do |
467 |
|
{ |
468 |
|
l4_thread_id_t from; |
469 |
|
l4_word_t label; |
470 |
|
l4_msg_t msg; |
471 |
|
l4_msg_tag_t msg_tag; |
472 |
|
|
473 |
|
msg_tag = l4_wait (&from); |
474 |
|
if (l4_ipc_failed (msg_tag)) |
475 |
|
panic ("Receiving message failed: %u", (l4_error_code () >> 1) & 0x7); |
476 |
|
|
477 |
|
label = l4_label (msg_tag); |
478 |
|
/* FIXME: Shouldn't store the whole msg before checking access |
479 |
|
rights. */ |
480 |
|
l4_msg_store (msg_tag, &msg); |
481 |
|
if (!WORTEL_CAP_VALID (l4_msg_word (&msg, 0), l4_version (from))) |
482 |
|
/* FIXME: Shouldn't be a panic of course. */ |
483 |
|
panic ("Unprivileged user attemps to access wortel rootserver"); |
484 |
|
|
485 |
|
#define WORTEL_MSG_PUTCHAR 1 |
486 |
|
if (label == WORTEL_MSG_PUTCHAR) |
487 |
|
{ |
488 |
|
int chr; |
489 |
|
|
490 |
|
/* This is a putchar() message. */ |
491 |
|
if (l4_untyped_words (msg_tag) != 2 |
492 |
|
|| l4_typed_words (msg_tag) != 0) |
493 |
panic ("Invalid format of putchar msg"); |
panic ("Invalid format of putchar msg"); |
494 |
|
|
495 |
chr = (int) l4_msg_word (&msg, 0); |
chr = (int) l4_msg_word (&msg, 1); |
496 |
putchar (chr); |
putchar (chr); |
497 |
/* No reply needed. */ |
/* No reply needed. */ |
498 |
continue; |
continue; |
499 |
} |
} |
500 |
else |
else |
501 |
panic ("Invalid message with tag 0x%x", msg_tag); |
panic ("Invalid message with tag 0x%x", msg_tag.raw); |
502 |
} |
} |
503 |
while (1); |
while (1); |
504 |
} |
} |
552 |
printf (".\n\n"); |
printf (".\n\n"); |
553 |
} |
} |
554 |
|
|
555 |
printf ("Report bugs to " BUG_ADDRESS ".\n", argv[0]); |
printf ("Report bugs to " BUG_ADDRESS ".\n"); |
556 |
shutdown (); |
shutdown (); |
557 |
} |
} |
558 |
else if (!strcmp (argv[i], "--version")) |
else if (!strcmp (argv[i], "--version")) |
608 |
|
|
609 |
tag = l4_wait (&from); |
tag = l4_wait (&from); |
610 |
debug ("EXCEPTION HANDLER: Received message from: "); |
debug ("EXCEPTION HANDLER: Received message from: "); |
611 |
debug ("0x%x", from); |
debug ("0x%x", from.raw); |
612 |
debug ("\n"); |
debug ("\n"); |
613 |
debug ("Tag: 0x%x", tag.raw); |
debug ("Tag: 0x%x", tag.raw); |
614 |
debug ("Label: %u Untyped: %u Typed: %u\n", |
debug ("Label: %u Untyped: %u Typed: %u\n", |
630 |
debug ("EXCEPTION HANDLER: Too many exceptions.\n"); |
debug ("EXCEPTION HANDLER: Too many exceptions.\n"); |
631 |
|
|
632 |
while (1) |
while (1) |
633 |
l4_yield (); |
l4_sleep (l4_never); |
634 |
} |
} |
635 |
|
|
636 |
|
|
679 |
|
|
680 |
start_components (); |
start_components (); |
681 |
|
|
682 |
while (1) |
serve_bootstrap_requests (); |
|
l4_yield (); |
|
683 |
|
|
684 |
return 0; |
return 0; |
685 |
} |
} |