21 |
#include <config.h> |
#include <config.h> |
22 |
#endif |
#endif |
23 |
|
|
24 |
|
#include <alloca.h> |
25 |
|
|
26 |
#include "wortel.h" |
#include "wortel.h" |
27 |
|
|
28 |
|
|
65 |
static void |
static void |
66 |
start_components (void) |
start_components (void) |
67 |
{ |
{ |
68 |
|
l4_word_t min_page_size = getpagesize (); |
69 |
l4_word_t ret; |
l4_word_t ret; |
70 |
l4_word_t control; |
l4_word_t control; |
71 |
l4_msg_t msg; |
l4_msg_t msg; |
72 |
l4_msg_tag_t msg_tag; |
l4_msg_tag_t msg_tag; |
73 |
unsigned int io_map = 0; |
|
74 |
|
if (physmem.low & (min_page_size - 1)) |
75 |
|
panic ("physmem is not page aligned on this architecture"); |
76 |
|
if (physmem.low > physmem.high) |
77 |
|
panic ("physmem has invalid memory range"); |
78 |
|
if (physmem.ip < physmem.low || physmem.ip > physmem.high) |
79 |
|
panic ("physmem has invalid IP"); |
80 |
|
|
81 |
/* Thread nr is next available after rootserver thread nr, |
/* Thread nr is next available after rootserver thread nr, |
82 |
version part is 2 (rootserver is 1). */ |
version part is 2 (rootserver is 1). */ |
114 |
l4_msg_load (&msg); |
l4_msg_load (&msg); |
115 |
msg_tag = l4_send (physmem_server); |
msg_tag = l4_send (physmem_server); |
116 |
if (l4_ipc_failed (msg_tag)) |
if (l4_ipc_failed (msg_tag)) |
117 |
panic ("Sending startup message to physmemserver thread failed: %u", |
panic ("Sending startup message to physmem thread failed: %u", |
118 |
l4_error_code ()); |
l4_error_code ()); |
119 |
|
|
120 |
|
{ |
121 |
|
l4_fpage_t *fpages; |
122 |
|
unsigned int nr_fpages = 0; |
123 |
|
l4_word_t start = physmem.low; |
124 |
|
l4_word_t end = (physmem.high + min_page_size) & ~(min_page_size - 1); |
125 |
|
l4_word_t region; |
126 |
|
|
127 |
|
/* We want to grant all the memory for the physmem binary image |
128 |
|
with the first page fault, but we might have to send several |
129 |
|
fpages. So we first create a list of all fpages we need, then |
130 |
|
we serve one after another, providing the one containing the |
131 |
|
fault address last. */ |
132 |
|
|
133 |
|
/* A page-aligned region of size up to 2^k * min_page_size can be |
134 |
|
covered by k fpages at most (proof by induction). At this |
135 |
|
point, END is at least one MIN_PAGE_SIZE larger than START. */ |
136 |
|
region = (end - start) / min_page_size; |
137 |
|
while (region > 0) |
138 |
|
{ |
139 |
|
nr_fpages++; |
140 |
|
region >>= 1; |
141 |
|
} |
142 |
|
fpages = alloca (sizeof (l4_fpage_t) * nr_fpages); |
143 |
|
|
144 |
|
nr_fpages = 0; |
145 |
|
while (start < end) |
146 |
|
{ |
147 |
|
fpages[nr_fpages] = l4_fpage (start, end - start); |
148 |
|
start += l4_size (fpages[nr_fpages]); |
149 |
|
nr_fpages++; |
150 |
|
} |
151 |
|
|
152 |
|
/* Now serve page requests. */ |
153 |
|
while (nr_fpages) |
154 |
|
{ |
155 |
|
l4_grant_item_t grant_item; |
156 |
|
l4_fpage_t fpage; |
157 |
|
l4_word_t addr; |
158 |
|
unsigned int i; |
159 |
|
|
160 |
|
msg_tag = l4_receive (physmem_server); |
161 |
|
if (l4_ipc_failed (msg_tag)) |
162 |
|
panic ("Receiving messages from physmem thread failed: %u", |
163 |
|
(l4_error_code () >> 1) & 0x7); |
164 |
|
if ((l4_label (msg_tag) >> 4) != 0xffe) |
165 |
|
panic ("Message from physmem thread is not a page fault"); |
166 |
|
l4_msg_store (msg_tag, &msg); |
167 |
|
if (l4_untyped_words (msg_tag) != 2 || l4_typed_words (msg_tag) != 0) |
168 |
|
panic ("Invalid format of page fault message"); |
169 |
|
addr = l4_msg_word (&msg, 0); |
170 |
|
if (addr != physmem.ip) |
171 |
|
panic ("Page fault at unexpected address 0x%x (expected 0x%x)", |
172 |
|
addr, physmem.ip); |
173 |
|
|
174 |
|
if (nr_fpages == 1) |
175 |
|
i = 0; |
176 |
|
else |
177 |
|
for (i = 0; i < nr_fpages; i++) |
178 |
|
if (addr < l4_address (fpages[i]) |
179 |
|
|| addr >= l4_address (fpages[i]) + l4_size (fpages[i])) |
180 |
|
break; |
181 |
|
if (i == nr_fpages) |
182 |
|
panic ("Could not find suitable fpage"); |
183 |
|
|
184 |
|
fpage = l4_fpage_add_rights (fpages[i], l4_fully_accessible); |
185 |
|
debug ("Granting Fpage: 0x%x - 0x%x\n", l4_address (fpage), |
186 |
|
l4_address (fpage) + l4_size (fpage)); |
187 |
|
|
188 |
|
if (i != 0) |
189 |
|
fpages[i] = fpages[nr_fpages - 1]; |
190 |
|
nr_fpages--; |
191 |
|
|
192 |
|
/* First we have to request the fpage from sigma0. */ |
193 |
|
l4_accept (l4_map_grant_items (l4_complete_address_space)); |
194 |
|
l4_msg_clear (&msg); |
195 |
|
l4_set_msg_label (&msg, 0xffa0); |
196 |
|
l4_msg_append_word (&msg, fpage.raw); |
197 |
|
l4_msg_append_word (&msg, L4_DEFAULT_MEMORY); |
198 |
|
l4_msg_load (&msg); |
199 |
|
msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1)); |
200 |
|
if (l4_ipc_failed (msg_tag)) |
201 |
|
panic ("sigma0 request failed during %s: %u", |
202 |
|
l4_error_code () & 1 ? "receive" : "send", |
203 |
|
(l4_error_code () >> 1) & 0x7); |
204 |
|
if (l4_untyped_words (msg_tag) != 0 |
205 |
|
|| l4_typed_words (msg_tag) != 2) |
206 |
|
panic ("Invalid format of sigma0 reply"); |
207 |
|
l4_msg_store (msg_tag, &msg); |
208 |
|
if (l4_msg_word (&msg, 1) == l4_nilpage.raw) |
209 |
|
panic ("sigma0 rejected mapping"); |
210 |
|
|
211 |
|
/* Now we can grant the mapping to the physmem server. |
212 |
|
FIXME: Should use the fpage returned by sigma0. */ |
213 |
|
l4_msg_clear (&msg); |
214 |
|
l4_set_msg_label (&msg, 0); |
215 |
|
/* FIXME: Keep track of mappings already provided. Possibly |
216 |
|
map text section rx and data rw. */ |
217 |
|
grant_item = l4_grant_item (fpage, l4_address (fpage)); |
218 |
|
l4_msg_append_grant_item (&msg, grant_item); |
219 |
|
l4_msg_load (&msg); |
220 |
|
l4_reply (physmem_server); |
221 |
|
} |
222 |
|
} |
223 |
|
|
224 |
do |
do |
225 |
{ |
{ |
226 |
l4_word_t label; |
l4_word_t label; |
230 |
panic ("Receiving messages from physmemserver thread failed: %u", |
panic ("Receiving messages from physmemserver thread failed: %u", |
231 |
(l4_error_code () >> 1) & 0x7); |
(l4_error_code () >> 1) & 0x7); |
232 |
|
|
|
/* FIXME: Check sender, etc. */ |
|
|
|
|
233 |
label = l4_label (msg_tag); |
label = l4_label (msg_tag); |
234 |
l4_msg_store (msg_tag, &msg); |
l4_msg_store (msg_tag, &msg); |
|
if ((label >> 4) == 0xffe) |
|
|
{ |
|
|
l4_grant_item_t grant_item; |
|
|
l4_fpage_t fpage; |
|
|
l4_word_t addr; |
|
235 |
|
|
|
/* This is a page fault. */ |
|
|
if (l4_untyped_words (msg_tag) != 2 |
|
|
|| l4_typed_words (msg_tag) != 0) |
|
|
panic ("Invalid format of page fault msg"); |
|
|
|
|
|
if (!io_map) |
|
|
{ |
|
|
l4_map_item_t map_item; |
|
|
|
|
|
/* FIXME: This is a hack. The first time we map the I/O |
|
|
ports into the task. The kernel will repeat the page |
|
|
fault. */ |
|
|
io_map = 1; |
|
|
|
|
|
/* Now we can grant the mapping to the physmem server. |
|
|
FIXME: Should use the fpage returned by sigma0. */ |
|
|
l4_msg_clear (&msg); |
|
|
l4_set_msg_label (&msg, 0); |
|
|
/* FIXME: Try to use largest fpage possible for the image. |
|
|
Keep track of mappings already provided. Possibly map |
|
|
text section rx and data rw. */ |
|
|
map_item = l4_map_item (l4_fpage_add_rights |
|
|
(l4_io_fpage (0, 10), |
|
|
l4_fully_accessible), 0); |
|
|
l4_msg_append_map_item (&msg, map_item); |
|
|
l4_msg_load (&msg); |
|
|
l4_reply (physmem_server); |
|
|
continue; |
|
|
} |
|
|
|
|
|
addr = l4_msg_word (&msg, 0) & ~((1 << 12) - 1); |
|
|
fpage = l4_fpage_add_rights (l4_fpage_log2 (addr, 12), |
|
|
l4_fully_accessible); |
|
|
debug ("Serving Page Fault: %c%c%c at 0x%x (IP: 0x%x)\n", |
|
|
label & 4 ? 'x' : '-', label & 2 ? 'w' : '-', |
|
|
label & 1 ? 'r' : '-', addr, |
|
|
l4_msg_word (&msg, 1)); |
|
|
|
|
|
/* First we have to request the fpage from sigma0. */ |
|
|
l4_accept (l4_map_grant_items (l4_complete_address_space)); |
|
|
l4_msg_clear (&msg); |
|
|
l4_set_msg_label (&msg, 0xffa0); |
|
|
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. */ |
|
|
l4_msg_clear (&msg); |
|
|
l4_set_msg_label (&msg, 0); |
|
|
/* FIXME: Try to use largest fpage possible for the image. |
|
|
Keep track of mappings already provided. Possibly map |
|
|
text section rx and data rw. */ |
|
|
grant_item = l4_grant_item (fpage, addr); |
|
|
l4_msg_append_grant_item (&msg, grant_item); |
|
|
l4_msg_load (&msg); |
|
|
} |
|
236 |
#define WORTEL_MSG_PUTCHAR 1 |
#define WORTEL_MSG_PUTCHAR 1 |
237 |
else if (label == WORTEL_MSG_PUTCHAR) |
if (label == WORTEL_MSG_PUTCHAR) |
238 |
{ |
{ |
239 |
int chr; |
int chr; |
240 |
|
|
250 |
} |
} |
251 |
else |
else |
252 |
panic ("Invalid message with tag 0x%x", msg_tag); |
panic ("Invalid message with tag 0x%x", msg_tag); |
|
|
|
|
l4_reply (physmem_server); |
|
253 |
} |
} |
254 |
while (1); |
while (1); |
255 |
} |
} |