1 |
/* l4/ipc.h - Public interface to the L4 IPC primitive. |
/* l4/ipc.h - Public interface to the L4 IPC primitive. |
2 |
Copyright (C) 2003, 2004 Free Software Foundation, Inc. |
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. |
3 |
Written by Marcus Brinkmann <marcus@gnu.org>. |
Written by Marcus Brinkmann <marcus@gnu.org>. |
4 |
|
|
5 |
This file is part of the GNU L4 library. |
This file is part of the GNU L4 library. |
74 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
75 |
_L4_label (_L4_msg_tag_t tag) |
_L4_label (_L4_msg_tag_t tag) |
76 |
{ |
{ |
77 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
78 |
|
|
|
_tag.raw = tag; |
|
79 |
return _tag.label; |
return _tag.label; |
80 |
} |
} |
81 |
|
|
84 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
85 |
_L4_untyped_words (_L4_msg_tag_t tag) |
_L4_untyped_words (_L4_msg_tag_t tag) |
86 |
{ |
{ |
87 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
88 |
|
|
|
_tag.raw = tag; |
|
89 |
return _tag.untyped; |
return _tag.untyped; |
90 |
} |
} |
91 |
|
|
94 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
95 |
_L4_typed_words (_L4_msg_tag_t tag) |
_L4_typed_words (_L4_msg_tag_t tag) |
96 |
{ |
{ |
97 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
98 |
|
|
|
_tag.raw = tag; |
|
99 |
return _tag.typed; |
return _tag.typed; |
100 |
} |
} |
101 |
|
|
104 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
105 |
_L4_msg_tag_add_label (_L4_msg_tag_t tag, _L4_word_t label) |
_L4_msg_tag_add_label (_L4_msg_tag_t tag, _L4_word_t label) |
106 |
{ |
{ |
107 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
108 |
|
|
|
_tag.raw = tag; |
|
109 |
_tag.label = label; |
_tag.label = label; |
110 |
return _tag.raw; |
return _tag.raw; |
111 |
} |
} |
115 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
116 |
_L4_msg_tag_add_label_to (_L4_msg_tag_t *tag, _L4_word_t label) |
_L4_msg_tag_add_label_to (_L4_msg_tag_t *tag, _L4_word_t label) |
117 |
{ |
{ |
118 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = *tag }; |
119 |
|
|
|
_tag.raw = *tag; |
|
120 |
_tag.label = label; |
_tag.label = label; |
121 |
*tag = _tag.raw; |
*tag = _tag.raw; |
122 |
} |
} |
131 |
return tag; |
return tag; |
132 |
} |
} |
133 |
|
|
134 |
|
|
135 |
static inline void |
static inline void |
136 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
137 |
_L4_set_msg_tag (_L4_msg_tag_t tag) |
_L4_set_msg_tag (_L4_msg_tag_t tag) |
140 |
} |
} |
141 |
|
|
142 |
|
|
143 |
|
/* All items. */ |
144 |
|
|
145 |
|
/* Get the continuation flag. */ |
146 |
|
static inline _L4_word_t |
147 |
|
_L4_attribute_always_inline |
148 |
|
_L4_item_not_last (void *item) |
149 |
|
{ |
150 |
|
_L4_word_t _item; |
151 |
|
__builtin_memcpy (&_item, item, sizeof (_L4_word_t)); |
152 |
|
|
153 |
|
/* The not_last flag is always the lowest bit in the item. */ |
154 |
|
return _item & 1; |
155 |
|
} |
156 |
|
|
157 |
|
|
158 |
|
/* Get the continuation flag. */ |
159 |
|
static inline void |
160 |
|
_L4_attribute_always_inline |
161 |
|
_L4_set_item_not_last (void *item, _L4_word_t val) |
162 |
|
{ |
163 |
|
_L4_word_t _item; |
164 |
|
__builtin_memcpy (&_item, item, sizeof (_L4_word_t)); |
165 |
|
|
166 |
|
/* The not_last flag is always the lowest bit in the item. */ |
167 |
|
_item = (_item & ~0) | !!val; |
168 |
|
|
169 |
|
__builtin_memcpy (item, &_item, sizeof (_L4_word_t)); |
170 |
|
} |
171 |
|
|
172 |
|
|
173 |
/* Map items. */ |
/* Map items. */ |
174 |
|
|
175 |
typedef _L4_dword_t _L4_map_item_t; |
typedef _L4_dword_t _L4_map_item_t; |
213 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
214 |
_L4_is_map_item (_L4_map_item_t map_item) |
_L4_is_map_item (_L4_map_item_t map_item) |
215 |
{ |
{ |
216 |
__L4_map_item_t _map_item; |
__L4_map_item_t _map_item = { .raw = map_item }; |
217 |
|
|
|
_map_item.raw = map_item; |
|
218 |
return _map_item._four == 4; |
return _map_item._four == 4; |
219 |
} |
} |
220 |
|
|
223 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
224 |
_L4_map_item_snd_fpage (_L4_map_item_t map_item) |
_L4_map_item_snd_fpage (_L4_map_item_t map_item) |
225 |
{ |
{ |
226 |
__L4_map_item_t _map_item; |
__L4_map_item_t _map_item = { .raw = map_item }; |
227 |
|
|
|
_map_item.raw = map_item; |
|
228 |
return _map_item.send_fpage; |
return _map_item.send_fpage; |
229 |
} |
} |
230 |
|
|
233 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
234 |
_L4_map_item_snd_base (_L4_map_item_t map_item) |
_L4_map_item_snd_base (_L4_map_item_t map_item) |
235 |
{ |
{ |
236 |
__L4_map_item_t _map_item; |
__L4_map_item_t _map_item = { .raw = map_item }; |
237 |
|
|
|
_map_item.raw = map_item; |
|
238 |
return _map_item.send_base << 10; |
return _map_item.send_base << 10; |
239 |
} |
} |
240 |
|
|
282 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
283 |
_L4_is_grant_item (_L4_grant_item_t grant_item) |
_L4_is_grant_item (_L4_grant_item_t grant_item) |
284 |
{ |
{ |
285 |
__L4_grant_item_t _grant_item; |
__L4_grant_item_t _grant_item = { .raw = grant_item }; |
286 |
_grant_item.raw = grant_item; |
|
287 |
return _grant_item._five == 5; |
return _grant_item._five == 5; |
288 |
} |
} |
289 |
|
|
292 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
293 |
_L4_grant_item_snd_fpage (_L4_grant_item_t grant_item) |
_L4_grant_item_snd_fpage (_L4_grant_item_t grant_item) |
294 |
{ |
{ |
295 |
__L4_grant_item_t _grant_item; |
__L4_grant_item_t _grant_item = { .raw = grant_item }; |
296 |
|
|
|
_grant_item.raw = grant_item; |
|
297 |
return _grant_item.send_fpage; |
return _grant_item.send_fpage; |
298 |
} |
} |
299 |
|
|
302 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
303 |
_L4_grant_item_snd_base (_L4_grant_item_t grant_item) |
_L4_grant_item_snd_base (_L4_grant_item_t grant_item) |
304 |
{ |
{ |
305 |
__L4_grant_item_t _grant_item; |
__L4_grant_item_t _grant_item = { .raw = grant_item }; |
306 |
|
|
|
_grant_item.raw = grant_item; |
|
307 |
return _grant_item.send_base << 10; |
return _grant_item.send_base << 10; |
308 |
} |
} |
309 |
|
|
357 |
|
|
358 |
static inline _L4_word_t |
static inline _L4_word_t |
359 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
360 |
_L4_is_string_item (_L4_string_item_t *string_item) |
_L4_is_string_item (void *string_item) |
361 |
{ |
{ |
362 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t _string_item; |
363 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
364 |
|
|
365 |
return _string_item->_zero == 0; |
return _string_item._zero == 0; |
366 |
} |
} |
367 |
|
|
368 |
|
|
369 |
static inline _L4_word_t |
static inline _L4_word_t |
370 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
371 |
_L4_compound_string (_L4_string_item_t *string_item) |
_L4_compound_string (void *string_item) |
372 |
{ |
{ |
373 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t _string_item; |
374 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
375 |
|
|
376 |
return _string_item->cont; |
return _string_item.cont; |
377 |
|
} |
378 |
|
|
379 |
|
|
380 |
|
static inline void |
381 |
|
_L4_attribute_always_inline |
382 |
|
_L4_set_compound_string (void *string_item, _L4_word_t cont) |
383 |
|
{ |
384 |
|
__L4_string_item_t _string_item; |
385 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
386 |
|
|
387 |
|
_string_item.cont = !!cont; |
388 |
|
|
389 |
|
__builtin_memcpy (string_item, &_string_item.raw, sizeof (_string_item.raw)); |
390 |
} |
} |
391 |
|
|
392 |
|
|
393 |
static inline _L4_word_t |
static inline _L4_word_t |
394 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
395 |
_L4_substrings (_L4_string_item_t *string_item) |
_L4_substrings (void *string_item) |
396 |
{ |
{ |
397 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t _string_item; |
398 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
399 |
|
|
400 |
|
return _string_item.nr_substrings + 1; |
401 |
|
} |
402 |
|
|
403 |
|
|
404 |
return _string_item->nr_substrings + 1; |
static inline void |
405 |
|
_L4_attribute_always_inline |
406 |
|
_L4_set_substrings (void *string_item, _L4_word_t substrings) |
407 |
|
{ |
408 |
|
__L4_string_item_t _string_item; |
409 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
410 |
|
|
411 |
|
_string_item.nr_substrings = substrings - 1; |
412 |
|
|
413 |
|
__builtin_memcpy (string_item, &_string_item, sizeof (_string_item.raw)); |
414 |
} |
} |
415 |
|
|
416 |
|
|
417 |
static inline void * |
static inline void * |
418 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
419 |
_L4_substring (_L4_string_item_t *string_item, _L4_word_t nr) |
_L4_substring (void *string_item, _L4_word_t nr) |
420 |
{ |
{ |
421 |
|
/* This does not break strict aliasing, see below. */ |
422 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
423 |
return (void *) _string_item->string[nr]; |
_L4_word_t string; |
424 |
|
|
425 |
|
/* To avoid breaking strict aliasing rules, we must not actually use |
426 |
|
_string_item for anything but pointer arithmetics, as we don't |
427 |
|
know the type of the underlying storage. To be safe, we have to |
428 |
|
actually copy the memory through a char pointer. */ |
429 |
|
__builtin_memcpy (&string, &_string_item->string[nr - 1], sizeof (_L4_word_t)); |
430 |
|
|
431 |
|
return (void *) string; |
432 |
|
} |
433 |
|
|
434 |
|
|
435 |
|
/* Count the number of all words used by the string item STRING_ITEM. |
436 |
|
If ALL_ITEMS is true, words used by following string items (until |
437 |
|
NOT_LAST is not set) will also be counted. */ |
438 |
|
static inline _L4_word_t |
439 |
|
_L4_attribute_always_inline |
440 |
|
_L4_string_item_words (void *string_item, _L4_word_t all_items) |
441 |
|
{ |
442 |
|
/* We do not break any strict aliasing rules here, as we only use |
443 |
|
the pointers for pointer arithmetic. */ |
444 |
|
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
445 |
|
int cont; |
446 |
|
int count = 0; |
447 |
|
|
448 |
|
do |
449 |
|
{ |
450 |
|
int nr = 1 + _L4_substrings (_string_item); |
451 |
|
|
452 |
|
cont = _L4_compound_string (_string_item); |
453 |
|
if (all_items) |
454 |
|
cont = cont || _L4_item_not_last (_string_item); |
455 |
|
|
456 |
|
/* Remember how many words are used by all string items. */ |
457 |
|
count += nr; |
458 |
|
|
459 |
|
/* Skip over the current string item. */ |
460 |
|
_string_item = (__L4_string_item_t *) |
461 |
|
(((_L4_word_t *) _string_item) + nr); |
462 |
|
} |
463 |
|
while (cont); |
464 |
|
|
465 |
|
return count; |
466 |
} |
} |
467 |
|
|
468 |
|
|
469 |
/* Append the string described by string item SOURCE to the string |
/* Append the string described by string item SOURCE to the string |
470 |
described by string item STRING_ITEM. */ |
described by string item STRING_ITEM. */ |
471 |
static inline _L4_string_item_t * |
static inline void * |
472 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
473 |
_L4_add_substring_to (_L4_string_item_t *string_item, |
_L4_add_substring_to (void *string_item, void *source) |
|
_L4_string_item_t *source) |
|
474 |
{ |
{ |
475 |
|
/* We do not break any strict aliasing rules here, as we only use |
476 |
|
the pointers for pointer arithmetic. */ |
477 |
__L4_string_item_t *target = (__L4_string_item_t *) string_item; |
__L4_string_item_t *target = (__L4_string_item_t *) string_item; |
478 |
__L4_string_item_t *_source = (__L4_string_item_t *) source; |
__L4_string_item_t *_source = (__L4_string_item_t *) source; |
479 |
int cont; |
int cont; |
480 |
|
int count; |
481 |
|
|
482 |
/* First search for end of target string item. */ |
/* First search for end of target string item. */ |
483 |
do |
do |
484 |
{ |
{ |
485 |
cont = target->cont; |
cont = _L4_compound_string (target); |
486 |
if (!cont) |
if (!cont) |
487 |
target->cont = 1; |
_L4_set_compound_string (target, 1); |
488 |
target = (__L4_string_item_t *) |
target = (__L4_string_item_t *) |
489 |
(((_L4_word_t *) target) + 1 + target->nr_substrings + 1); |
(((_L4_word_t *) target) + 1 + _L4_substrings (target)); |
490 |
} |
} |
491 |
while (cont); |
while (cont); |
492 |
|
|
493 |
/* Now copy the source string item. */ |
/* Now copy the source string item. */ |
494 |
do |
count = _L4_string_item_words (_source, 0); |
495 |
|
while (count--) |
496 |
{ |
{ |
497 |
int nr = 1 + _source->nr_substrings + 1; |
__builtin_memcpy (target, _source, sizeof (_L4_word_t)); |
498 |
cont = _source->cont; |
target = (__L4_string_item_t *) (((_L4_word_t *) target) + 1); |
499 |
while (nr--) |
_source = (__L4_string_item_t *) (((_L4_word_t *) source) + 1); |
|
*(target++) = *(_source++); |
|
500 |
} |
} |
|
while (cont); |
|
501 |
|
|
502 |
return string_item; |
return string_item; |
503 |
} |
} |
504 |
|
|
505 |
|
|
506 |
/* Append the string described by string item SOURCE as a substring |
/* Append the string pointed to by SOURCE as a substring (of the same |
507 |
(of the same length) to the string item STRING_ITEM. */ |
length) to the string item STRING_ITEM. */ |
508 |
static inline _L4_string_item_t * |
static inline void * |
509 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
510 |
_L4_add_substring_address_to (_L4_string_item_t *string_item, void *source) |
_L4_add_substring_address_to (void *string_item, void *source) |
511 |
{ |
{ |
512 |
|
/* We do not break any strict aliasing rules here, as we only use |
513 |
|
the pointers for pointer arithmetic. */ |
514 |
__L4_string_item_t *target = (__L4_string_item_t *) string_item; |
__L4_string_item_t *target = (__L4_string_item_t *) string_item; |
515 |
|
|
516 |
/* First search for end of target string item. */ |
/* First search for end of target string item. */ |
517 |
while (target->cont) |
while (_L4_compound_string (target)) |
518 |
target = (__L4_string_item_t *) |
target = (__L4_string_item_t *) |
519 |
(((_L4_word_t *) target) + 1 + target->nr_substrings + 1); |
(((_L4_word_t *) target) + 1 + _L4_substrings (target)); |
520 |
|
|
521 |
/* Now add the source substring. */ |
/* Now add the source substring. */ |
522 |
target->nr_substrings++; |
_L4_set_substrings (target, _L4_substrings (target) + 1); |
523 |
target->string[target->nr_substrings] = (_L4_word_t) source; |
__builtin_memcpy (&target->string[_L4_substrings (target) - 1], source, |
524 |
|
sizeof (_L4_word_t)); |
525 |
|
|
526 |
return string_item; |
return string_item; |
527 |
} |
} |
531 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
532 |
_L4_cache_allocation_hint (_L4_string_item_t string_item) |
_L4_cache_allocation_hint (_L4_string_item_t string_item) |
533 |
{ |
{ |
534 |
__L4_string_item_t _string_item; |
__L4_string_item_t _string_item = { .raw = string_item }; |
535 |
|
|
|
_string_item.raw = string_item; |
|
536 |
return _string_item.cache_hint; |
return _string_item.cache_hint; |
537 |
} |
} |
538 |
|
|
542 |
_L4_add_cache_allocation_hint (_L4_string_item_t string_item, |
_L4_add_cache_allocation_hint (_L4_string_item_t string_item, |
543 |
_L4_cache_allocation_hint_t hint) |
_L4_cache_allocation_hint_t hint) |
544 |
{ |
{ |
545 |
__L4_string_item_t _string_item; |
__L4_string_item_t _string_item = { .raw = string_item }; |
546 |
|
|
|
_string_item.raw = string_item; |
|
547 |
_string_item.cache_hint = hint; |
_string_item.cache_hint = hint; |
548 |
return _string_item.raw; |
return _string_item.raw; |
549 |
} |
} |
550 |
|
|
551 |
|
|
552 |
static inline _L4_string_item_t * |
static inline void * |
553 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
554 |
_L4_add_cache_allocation_hint_to (_L4_string_item_t *string_item, |
_L4_add_cache_allocation_hint_to (void *string_item, |
555 |
_L4_cache_allocation_hint_t hint) |
_L4_cache_allocation_hint_t hint) |
556 |
{ |
{ |
557 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t _string_item; |
558 |
|
__builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw)); |
559 |
|
|
560 |
_string_item->cache_hint = hint; |
_string_item.cache_hint = hint; |
561 |
|
|
562 |
|
__builtin_memcpy (string_item, &_string_item.raw, sizeof (_string_item.raw)); |
563 |
return string_item; |
return string_item; |
564 |
} |
} |
565 |
|
|
582 |
|
|
583 |
typedef _L4_word_t _L4_msg_buffer_t[_L4_NUM_BRS - 1]; |
typedef _L4_word_t _L4_msg_buffer_t[_L4_NUM_BRS - 1]; |
584 |
|
|
585 |
|
|
586 |
|
static inline _L4_fpage_t |
587 |
|
_L4_attribute_always_inline |
588 |
|
_L4_rcv_window (_L4_acceptor_t acceptor) |
589 |
|
{ |
590 |
|
__L4_acceptor_t _acceptor = { .raw = acceptor }; |
591 |
|
|
592 |
|
/* The acceptor looks just like a receive window fpage, just that |
593 |
|
the lower bits have a different meaning. So we just clear |
594 |
|
them. */ |
595 |
|
_acceptor.string_items = 0; |
596 |
|
|
597 |
|
return (_L4_fpage_t) _acceptor.raw; |
598 |
|
} |
599 |
|
|
600 |
|
|
601 |
|
static inline _L4_word_t |
602 |
|
_L4_attribute_always_inline |
603 |
|
_L4_has_map_grant_items (_L4_acceptor_t acceptor) |
604 |
|
{ |
605 |
|
/* FIXME: 0 is _L4_nilpage. */ |
606 |
|
return _L4_rcv_window (acceptor) != 0; |
607 |
|
} |
608 |
|
|
609 |
|
|
610 |
static inline _L4_acceptor_t |
static inline _L4_acceptor_t |
611 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
612 |
_L4_map_grant_items (_L4_fpage_t rcv_window) |
_L4_map_grant_items (_L4_fpage_t rcv_window) |
613 |
{ |
{ |
614 |
__L4_acceptor_t acceptor; |
__L4_acceptor_t acceptor = { .raw = rcv_window }; |
615 |
acceptor.raw = rcv_window; |
|
616 |
acceptor.string_items = 0; |
acceptor.string_items = 0; |
617 |
acceptor._zero = 0; |
acceptor._zero = 0; |
618 |
return acceptor.raw; |
return acceptor.raw; |
623 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
624 |
_L4_add_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2) |
_L4_add_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2) |
625 |
{ |
{ |
626 |
__L4_acceptor_t _acceptor1; |
__L4_acceptor_t _acceptor1 = { .raw = acceptor1 }; |
627 |
__L4_acceptor_t _acceptor2; |
__L4_acceptor_t _acceptor2 = { .raw = acceptor2 }; |
628 |
|
|
|
_acceptor1.raw = acceptor1; |
|
|
_acceptor2.raw = acceptor2; |
|
629 |
_acceptor1.string_items |= _acceptor2.string_items; |
_acceptor1.string_items |= _acceptor2.string_items; |
630 |
if (_acceptor2.rcv_window) |
if (_L4_has_map_grant_items (acceptor2)) |
631 |
_acceptor1.rcv_window = _acceptor2.rcv_window; |
_acceptor1.rcv_window = _acceptor2.rcv_window; |
632 |
return _acceptor1.raw; |
return _acceptor1.raw; |
633 |
} |
} |
637 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
638 |
_L4_add_acceptor_to (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2) |
_L4_add_acceptor_to (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2) |
639 |
{ |
{ |
640 |
__L4_acceptor_t *_acceptor1 = (__L4_acceptor_t *) acceptor1; |
__L4_acceptor_t _acceptor1 = { .raw = *acceptor1 }; |
641 |
__L4_acceptor_t _acceptor2; |
__L4_acceptor_t _acceptor2 = { .raw = acceptor2 }; |
642 |
|
|
643 |
_acceptor2.raw = acceptor2; |
_acceptor1.string_items |= _acceptor2.string_items; |
644 |
_acceptor1->string_items |= _acceptor2.string_items; |
if (_L4_has_map_grant_items (acceptor2)) |
645 |
if (_acceptor2.rcv_window) |
_acceptor1.rcv_window = _acceptor2.rcv_window; |
646 |
_acceptor1->rcv_window = _acceptor2.rcv_window; |
|
647 |
|
*acceptor1 = _acceptor1.raw; |
648 |
return acceptor1; |
return acceptor1; |
649 |
} |
} |
650 |
|
|
653 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
654 |
_L4_remove_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2) |
_L4_remove_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2) |
655 |
{ |
{ |
656 |
__L4_acceptor_t _acceptor1; |
__L4_acceptor_t _acceptor1 = { .raw = acceptor1 }; |
657 |
__L4_acceptor_t _acceptor2; |
__L4_acceptor_t _acceptor2 = { .raw = acceptor2 }; |
658 |
|
|
|
_acceptor1.raw = acceptor1; |
|
|
_acceptor2.raw = acceptor2; |
|
659 |
_acceptor1.string_items &= ~_acceptor2.string_items; |
_acceptor1.string_items &= ~_acceptor2.string_items; |
660 |
if (_acceptor2.rcv_window) |
if (_L4_has_map_grant_items (acceptor2)) |
661 |
_acceptor1.rcv_window = 0; |
_acceptor1.rcv_window = 0; |
662 |
return _acceptor1.raw; |
return _acceptor1.raw; |
663 |
} |
} |
667 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
668 |
_L4_remove_acceptor_from (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2) |
_L4_remove_acceptor_from (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2) |
669 |
{ |
{ |
670 |
__L4_acceptor_t *_acceptor1 = (__L4_acceptor_t *) acceptor1; |
__L4_acceptor_t _acceptor1 = { .raw = *acceptor1 }; |
671 |
__L4_acceptor_t _acceptor2; |
__L4_acceptor_t _acceptor2 = { .raw = acceptor2 }; |
672 |
|
|
673 |
_acceptor2.raw = acceptor2; |
_acceptor1.string_items &= ~_acceptor2.string_items; |
674 |
_acceptor1->string_items &= ~_acceptor2.string_items; |
if (_L4_has_map_grant_items (acceptor2)) |
675 |
if (_acceptor2.rcv_window) |
_acceptor1.rcv_window = 0; |
676 |
_acceptor1->rcv_window = 0; |
|
677 |
|
*acceptor1 = _acceptor1.raw; |
678 |
return acceptor1; |
return acceptor1; |
679 |
} |
} |
680 |
|
|
683 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
684 |
_L4_has_string_items (_L4_acceptor_t acceptor) |
_L4_has_string_items (_L4_acceptor_t acceptor) |
685 |
{ |
{ |
686 |
__L4_acceptor_t _acceptor; |
__L4_acceptor_t _acceptor = { .raw = acceptor }; |
687 |
|
|
|
_acceptor.raw = acceptor; |
|
688 |
return _acceptor.string_items; |
return _acceptor.string_items; |
689 |
} |
} |
690 |
|
|
691 |
|
|
|
static inline _L4_word_t |
|
|
_L4_attribute_always_inline |
|
|
_L4_has_map_grant_items (_L4_acceptor_t acceptor) |
|
|
{ |
|
|
__L4_acceptor_t _acceptor; |
|
|
|
|
|
_acceptor.raw = acceptor; |
|
|
return _acceptor.rcv_window; |
|
|
} |
|
|
|
|
|
|
|
|
static inline _L4_fpage_t |
|
|
_L4_attribute_always_inline |
|
|
_L4_rcv_window (_L4_acceptor_t acceptor) |
|
|
{ |
|
|
__L4_acceptor_t _acceptor; |
|
|
|
|
|
_acceptor.raw = acceptor; |
|
|
_acceptor.string_items = 0; |
|
|
return (_L4_fpage_t) _acceptor.rcv_window; |
|
|
} |
|
|
|
|
|
|
|
692 |
static inline void |
static inline void |
693 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
694 |
_L4_accept (_L4_acceptor_t acceptor) |
_L4_accept (_L4_acceptor_t acceptor) |
701 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
702 |
_L4_accept_strings (_L4_acceptor_t acceptor, _L4_msg_buffer_t msg_buffer) |
_L4_accept_strings (_L4_acceptor_t acceptor, _L4_msg_buffer_t msg_buffer) |
703 |
{ |
{ |
704 |
|
/* We do not break any strict aliasing rules here, as we only use |
705 |
|
the pointers for pointer arithmetic. */ |
706 |
__L4_string_item_t *string_item = (__L4_string_item_t *) msg_buffer; |
__L4_string_item_t *string_item = (__L4_string_item_t *) msg_buffer; |
707 |
int br = 1; |
int count; |
|
int cont; |
|
708 |
|
|
709 |
_L4_load_br (0, acceptor); |
_L4_load_br (0, acceptor); |
710 |
do |
|
711 |
{ |
/* We do not check if the message buffer is empty. If the user |
712 |
int nr = 1 + string_item->nr_substrings + 1; |
accepts string items, he better adds at least one string item |
713 |
cont = string_item->cont || string_item->not_last; |
buffer. In any case, if he doesn't, we will only add a harmless |
714 |
_L4_load_brs (br, nr, (_L4_word_t *) string_item); |
simple string item of length 0 with a random address. */ |
715 |
br += nr; |
count = _L4_string_item_words (string_item, 1); |
716 |
string_item = (__L4_string_item_t *) (((_L4_word_t *) string_item) + nr); |
|
717 |
} |
/* Load the string item buffers. */ |
718 |
while (cont); |
_L4_load_brs (1, count, msg_buffer); |
719 |
} |
} |
720 |
|
|
721 |
|
|
734 |
_L4_msg_buffer_clear (_L4_msg_buffer_t msg_buffer) |
_L4_msg_buffer_clear (_L4_msg_buffer_t msg_buffer) |
735 |
{ |
{ |
736 |
msg_buffer[0] = 0; |
msg_buffer[0] = 0; |
737 |
|
|
738 |
|
/* The first word being not 0 is a sufficient, but not necessary |
739 |
|
indicator for a non-empty message buffer: A message with a simple |
740 |
|
string item of length 0 can also have a first word 0 (depending |
741 |
|
on the cache allocation hint). The second word has only the |
742 |
|
pointer address, which is arbitrary, so it can't be used for |
743 |
|
differentiation either (0 is a valid pointer as far as L4 is |
744 |
|
concerned). |
745 |
|
|
746 |
|
So, we use the third word as an indicator if the message buffer |
747 |
|
is empty (in this case the first and the third word are 0), or if |
748 |
|
there is a single simple string item of length 0 in it (in this |
749 |
|
case the first word is 0, but the third word will be set to ~0 by |
750 |
|
_L4_msg_buffer_prepare_append). |
751 |
|
|
752 |
|
In all other cases (simple string item with length not 0, |
753 |
|
compound string items, more than one simple string item) the |
754 |
|
first word will not be 0. |
755 |
|
|
756 |
|
All this boils down to a simple rule: If the first and the third |
757 |
|
word are 0, then the message buffer is clear. Otherwise, if at |
758 |
|
least one of them is not 0, then the message buffer contains some |
759 |
|
string items (you can determine how many by looking at the |
760 |
|
continuation flags and substring numbers). */ |
761 |
|
msg_buffer[2] = 0; |
762 |
} |
} |
763 |
|
|
764 |
|
|
765 |
static inline void |
/* Search for the end of the message buffer, and set the not_last bit |
766 |
|
in the last existing item (thus preparing the message buffer for |
767 |
|
adding a new item). */ |
768 |
|
static inline __L4_string_item_t * |
769 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
770 |
_L4_msg_buffer_append_simple_rcv_string (_L4_msg_buffer_t msg_buffer, |
_L4_msg_buffer_prepare_append (_L4_msg_buffer_t msg_buffer) |
|
_L4_string_item_t string_item) |
|
771 |
{ |
{ |
772 |
|
/* We do not break any strict aliasing rules here, as we only use |
773 |
|
the pointers for pointer arithmetic. */ |
774 |
__L4_string_item_t *target = (__L4_string_item_t *) msg_buffer; |
__L4_string_item_t *target = (__L4_string_item_t *) msg_buffer; |
775 |
__L4_string_item_t _string_item; |
int found_last = 0; |
776 |
int cont; |
int cont; |
777 |
|
|
778 |
_string_item.raw = string_item; |
/* Check if this is an empty message buffer (see comment in |
779 |
|
_L4_msg_buffer_clear). */ |
780 |
|
if (msg_buffer[0] == 0 && msg_buffer[2] == 0) |
781 |
|
{ |
782 |
|
/* It doesn't hurt to set the not-empty indicator here even if |
783 |
|
we are not going to add a simple string item of length zero, |
784 |
|
but something more complex. */ |
785 |
|
|
786 |
|
msg_buffer[2] = ~0; |
787 |
|
return target; |
788 |
|
} |
789 |
|
|
790 |
|
/* This is not an empty message buffer, so walk down the string |
791 |
|
items. */ |
792 |
do |
do |
793 |
{ |
{ |
794 |
int nr = 1 + target->nr_substrings + 1; |
int nr = 1 + _L4_substrings (target); |
795 |
cont = target->cont | target->not_last; |
cont = _L4_compound_string (target); |
796 |
if (!cont) |
|
797 |
target->not_last = 1; |
/* Set the not_last bit in the last item. */ |
798 |
|
if (!_L4_item_not_last (target)) |
799 |
|
{ |
800 |
|
_L4_set_item_not_last (target, 1); |
801 |
|
found_last = 1; |
802 |
|
} |
803 |
|
|
804 |
|
/* Skip over this item. */ |
805 |
target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr); |
target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr); |
806 |
} |
} |
807 |
while (cont); |
while (!found_last || cont); |
808 |
|
|
809 |
|
return target; |
810 |
|
} |
811 |
|
|
812 |
|
|
813 |
|
static inline void |
814 |
|
_L4_attribute_always_inline |
815 |
|
_L4_msg_buffer_append_simple_rcv_string (_L4_msg_buffer_t msg_buffer, |
816 |
|
_L4_string_item_t string_item) |
817 |
|
{ |
818 |
|
__L4_string_item_t *target; |
819 |
|
__L4_string_item_t _string_item = { .raw = string_item }; |
820 |
|
|
821 |
_string_item.not_last = 0; |
_string_item.not_last = 0; |
822 |
_string_item.nr_substrings = 0; |
_string_item.nr_substrings = 0; |
823 |
*target = _string_item; |
|
824 |
|
target = _L4_msg_buffer_prepare_append (msg_buffer); |
825 |
|
__builtin_memcpy (target, &_string_item, sizeof (__L4_string_item_t)); |
826 |
} |
} |
827 |
|
|
828 |
|
|
829 |
static inline void |
static inline void |
830 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
831 |
_L4_msg_buffer_append_rcv_string (_L4_msg_buffer_t msg_buffer, |
_L4_msg_buffer_append_rcv_string (_L4_msg_buffer_t msg_buffer, |
832 |
_L4_string_item_t *string_item) |
void *string_item) |
833 |
{ |
{ |
834 |
__L4_string_item_t *target = (__L4_string_item_t *) msg_buffer; |
/* We do not break any strict aliasing rules here, as we only use |
835 |
|
the pointers for pointer arithmetic. */ |
836 |
|
__L4_string_item_t *target; |
837 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
|
_L4_word_t *brp; |
|
838 |
int cont; |
int cont; |
839 |
|
|
840 |
/* Find the end of the message buffer. */ |
target = _L4_msg_buffer_prepare_append (msg_buffer); |
841 |
do |
__builtin_memcpy (target, &_string_item, sizeof (__L4_string_item_t)); |
|
{ |
|
|
int nr = 1 + target->nr_substrings + 1; |
|
|
cont = target->cont | target->not_last; |
|
|
if (!cont) |
|
|
target->not_last = 1; |
|
|
target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr); |
|
|
} |
|
|
while (cont); |
|
842 |
|
|
843 |
brp = (_L4_word_t *) target; |
_L4_set_item_not_last (_string_item, 0); |
844 |
|
|
845 |
/* Copy the source string. */ |
/* Copy the source string. */ |
846 |
do |
do |
847 |
{ |
{ |
848 |
int nr = _string_item->nr_substrings; |
int nr = _L4_substrings (_string_item) + 1; |
849 |
_L4_word_t *substrings = &_string_item->string[1]; |
cont = _L4_compound_string (_string_item); |
850 |
|
|
|
cont = _string_item->cont; |
|
|
*((__L4_string_item_t *) brp) = *_string_item; |
|
|
brp += 2; |
|
|
|
|
851 |
while (nr-- > 0) |
while (nr-- > 0) |
852 |
*(brp++) = *(substrings++); |
{ |
853 |
_string_item = (__L4_string_item_t *) substrings; |
__builtin_memcpy (target, _string_item, sizeof (_L4_word_t)); |
854 |
|
|
855 |
|
target = (__L4_string_item_t *) (((_L4_word_t *) target) + 1); |
856 |
|
_string_item = (__L4_string_item_t *) |
857 |
|
(((_L4_word_t *) _string_item) + 1); |
858 |
|
} |
859 |
} |
} |
860 |
while (cont); |
while (cont); |
861 |
} |
} |
863 |
|
|
864 |
/* Message composition. */ |
/* Message composition. */ |
865 |
typedef _L4_word_t _L4_msg_t[_L4_NUM_MRS]; |
typedef _L4_word_t _L4_msg_t[_L4_NUM_MRS]; |
866 |
typedef union |
|
867 |
|
|
868 |
|
static inline _L4_msg_tag_t |
869 |
|
_L4_attribute_always_inline |
870 |
|
_L4_msg_msg_tag (_L4_msg_t msg) |
871 |
{ |
{ |
872 |
_L4_msg_t _msg; |
return msg[0]; |
873 |
__L4_msg_tag_t tag; |
} |
874 |
} __L4_msg_t; |
|
875 |
|
|
876 |
|
static inline void |
877 |
|
_L4_attribute_always_inline |
878 |
|
_L4_set_msg_msg_tag (_L4_msg_t msg, _L4_msg_tag_t tag) |
879 |
|
{ |
880 |
|
msg[0] = tag; |
881 |
|
} |
882 |
|
|
883 |
|
|
884 |
static inline void |
static inline void |
886 |
_L4_msg_put (_L4_msg_t msg, _L4_word_t label, int untyped_nr, |
_L4_msg_put (_L4_msg_t msg, _L4_word_t label, int untyped_nr, |
887 |
_L4_word_t *untyped, int typed_nr, void *any_typed) |
_L4_word_t *untyped, int typed_nr, void *any_typed) |
888 |
{ |
{ |
889 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag; |
890 |
_L4_word_t *mrs = msg; |
_L4_word_t *mrs = &msg[1]; |
891 |
_L4_word_t *typed = (_L4_word_t *) any_typed; |
|
892 |
|
tag.untyped = untyped_nr; |
893 |
_msg->tag.untyped = untyped_nr; |
tag.typed = typed_nr; |
894 |
_msg->tag.typed = typed_nr; |
tag.propagated = 0; |
895 |
_msg->tag.propagated = 0; |
tag.redirected = 0; |
896 |
_msg->tag.redirected = 0; |
tag.cross_cpu = 0; |
897 |
_msg->tag.cross_cpu = 0; |
tag.error = 0; |
898 |
_msg->tag.error = 0; |
tag.label = label; |
899 |
_msg->tag.label = label; |
_L4_set_msg_msg_tag (msg, tag.raw); |
900 |
|
|
901 |
while (untyped_nr--) |
while (untyped_nr--) |
902 |
*(mrs++) = *(untyped++); |
*(mrs++) = *(untyped++); |
903 |
|
|
904 |
|
/* We can't cast ANY_TYPED to anything useful and dereference it, as |
905 |
|
that would break strict aliasing rules. This is why we use |
906 |
|
__builtin_memcpy, but only for known, small, fixed sizes, so that it is |
907 |
|
optimized away. We know that sizeof (_L4_word_t) == sizeof (void *). */ |
908 |
while (typed_nr--) |
while (typed_nr--) |
909 |
*(mrs++) = *(typed++); |
__builtin_memcpy (mrs++, any_typed++, sizeof (void *)); |
910 |
} |
} |
911 |
|
|
912 |
|
|
914 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
915 |
_L4_msg_get (_L4_msg_t msg, _L4_word_t *untyped, void *any_typed) |
_L4_msg_get (_L4_msg_t msg, _L4_word_t *untyped, void *any_typed) |
916 |
{ |
{ |
917 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
918 |
int untyped_nr = _msg->tag.untyped; |
int untyped_nr = tag.untyped; |
919 |
int typed_nr = _msg->tag.typed; |
int typed_nr = tag.typed; |
920 |
_L4_word_t *mrs = msg; |
_L4_word_t *mrs = &msg[1]; |
|
_L4_word_t *typed = (_L4_word_t *) any_typed; |
|
921 |
|
|
922 |
while (untyped_nr--) |
while (untyped_nr--) |
923 |
*(untyped++) = *(mrs++); |
*(untyped++) = *(mrs++); |
924 |
|
|
925 |
|
/* We can't cast ANY_TYPED to anything useful and dereference it, as |
926 |
|
that would break strict aliasing rules. This is why we use |
927 |
|
__builtin_memcpy, but only for known, small, fixed sizes, so that it is |
928 |
|
optimized away. We know that sizeof (_L4_word_t) == sizeof (void *). */ |
929 |
while (typed_nr--) |
while (typed_nr--) |
930 |
*(typed++) = *(mrs++); |
__builtin_memcpy (any_typed++, mrs++, sizeof (_L4_word_t)); |
|
} |
|
|
|
|
|
|
|
|
static inline _L4_msg_tag_t |
|
|
_L4_attribute_always_inline |
|
|
_L4_msg_msg_tag (_L4_msg_t msg) |
|
|
{ |
|
|
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
|
|
return _msg->tag.raw; |
|
|
} |
|
|
|
|
|
|
|
|
static inline void |
|
|
_L4_attribute_always_inline |
|
|
_L4_set_msg_msg_tag (_L4_msg_t msg, _L4_msg_tag_t tag) |
|
|
{ |
|
|
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
|
|
_msg->tag.raw = tag; |
|
931 |
} |
} |
932 |
|
|
933 |
|
|
935 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
936 |
_L4_msg_msg_label (_L4_msg_t msg) |
_L4_msg_msg_label (_L4_msg_t msg) |
937 |
{ |
{ |
938 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
939 |
return _msg->tag.label; |
return tag.label; |
940 |
} |
} |
941 |
|
|
942 |
|
|
944 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
945 |
_L4_set_msg_msg_label (_L4_msg_t msg, _L4_word_t label) |
_L4_set_msg_msg_label (_L4_msg_t msg, _L4_word_t label) |
946 |
{ |
{ |
947 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
948 |
_msg->tag.label = label; |
tag.label = label; |
949 |
|
_L4_set_msg_msg_tag (msg, tag.raw); |
950 |
} |
} |
951 |
|
|
952 |
|
|
954 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
955 |
_L4_msg_load (_L4_msg_t msg) |
_L4_msg_load (_L4_msg_t msg) |
956 |
{ |
{ |
957 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
958 |
_L4_load_mrs (0, 1 + _msg->tag.untyped + _msg->tag.typed, msg); |
_L4_load_mrs (0, 1 + tag.untyped + tag.typed, msg); |
959 |
} |
} |
960 |
|
|
961 |
|
|
963 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
964 |
_L4_msg_store (_L4_msg_tag_t tag, _L4_msg_t msg) |
_L4_msg_store (_L4_msg_tag_t tag, _L4_msg_t msg) |
965 |
{ |
{ |
966 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t _tag = { .raw = tag }; |
967 |
_msg->tag.raw = tag; |
_L4_set_msg_msg_tag (msg, tag); |
968 |
_L4_store_mrs (1, _msg->tag.untyped + _msg->tag.typed, &msg[1]); |
_L4_store_mrs (1, _tag.untyped + _tag.typed, &msg[1]); |
969 |
} |
} |
970 |
|
|
971 |
|
|
973 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
974 |
_L4_msg_clear (_L4_msg_t msg) |
_L4_msg_clear (_L4_msg_t msg) |
975 |
{ |
{ |
976 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
_L4_set_msg_msg_tag (msg, _L4_niltag); |
|
_msg->tag.raw = _L4_niltag; |
|
977 |
} |
} |
978 |
|
|
979 |
|
|
981 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
982 |
_L4_msg_append_word (_L4_msg_t msg, _L4_word_t data) |
_L4_msg_append_word (_L4_msg_t msg, _L4_word_t data) |
983 |
{ |
{ |
984 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
985 |
_L4_word_t new_untyped_nr = ++_msg->tag.untyped; |
_L4_word_t untyped_nr; |
986 |
_L4_word_t typed_nr = _msg->tag.typed; |
_L4_word_t typed_nr; |
987 |
|
|
988 |
if (typed_nr) |
untyped_nr = tag.untyped; |
989 |
{ |
typed_nr = tag.typed; |
990 |
_L4_word_t *mrs = &msg[new_untyped_nr + typed_nr]; |
|
991 |
while (typed_nr--) |
while (typed_nr) |
992 |
{ |
__builtin_memcpy (&msg[untyped_nr + typed_nr + 1], &msg[untyped_nr + typed_nr], |
993 |
*(mrs) = *(mrs - 1); |
sizeof (_L4_word_t)); |
994 |
mrs--; |
|
995 |
} |
tag.untyped++; |
996 |
*mrs = data; |
msg[tag.untyped] = data; |
997 |
} |
_L4_set_msg_msg_tag (msg, tag.raw); |
|
else |
|
|
msg[new_untyped_nr] = data; |
|
998 |
} |
} |
999 |
|
|
1000 |
|
|
1002 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1003 |
_L4_msg_append_map_item (_L4_msg_t msg, _L4_map_item_t map_item) |
_L4_msg_append_map_item (_L4_msg_t msg, _L4_map_item_t map_item) |
1004 |
{ |
{ |
1005 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1006 |
/* The "not last" bit is ignored for sending. */ |
/* The "not last" bit is ignored for sending. */ |
1007 |
int pos = 1 + _msg->tag.untyped + _msg->tag.typed; |
int pos = 1 + tag.untyped + tag.typed; |
1008 |
|
|
1009 |
((__L4_map_item_t *) &msg[pos])->raw = map_item; |
__builtin_memcpy (&msg[pos], &map_item, sizeof (_L4_map_item_t)); |
1010 |
_msg->tag.typed += 2; |
tag.typed += sizeof (_L4_map_item_t) / sizeof (_L4_word_t); |
1011 |
|
_L4_set_msg_msg_tag (msg, tag.raw); |
1012 |
} |
} |
1013 |
|
|
1014 |
|
|
1016 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1017 |
_L4_msg_append_grant_item (_L4_msg_t msg, _L4_grant_item_t grant_item) |
_L4_msg_append_grant_item (_L4_msg_t msg, _L4_grant_item_t grant_item) |
1018 |
{ |
{ |
1019 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1020 |
/* The "not last" bit is ignored for sending. */ |
/* The "not last" bit is ignored for sending. */ |
1021 |
int pos = 1 + _msg->tag.untyped + _msg->tag.typed; |
int pos = 1 + tag.untyped + tag.typed; |
1022 |
|
|
1023 |
((__L4_grant_item_t *) &msg[pos])->raw = grant_item; |
__builtin_memcpy (&msg[pos], &grant_item, sizeof (_L4_grant_item_t)); |
1024 |
_msg->tag.typed += 2; |
tag.typed += sizeof (_L4_grant_item_t) / sizeof (_L4_word_t); |
1025 |
|
_L4_set_msg_msg_tag (msg, tag.raw); |
1026 |
} |
} |
1027 |
|
|
1028 |
|
|
1031 |
_L4_msg_append_simple_string_item (_L4_msg_t msg, |
_L4_msg_append_simple_string_item (_L4_msg_t msg, |
1032 |
_L4_string_item_t string_item) |
_L4_string_item_t string_item) |
1033 |
{ |
{ |
1034 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1035 |
__L4_string_item_t _string_item; |
__L4_string_item_t _string_item = { .raw = string_item }; |
1036 |
/* The "not last" bit is ignored for sending. */ |
/* The "not last" bit is ignored for sending. */ |
1037 |
int pos = 1 + _msg->tag.untyped + _msg->tag.typed; |
int pos = 1 + tag.untyped + tag.typed; |
1038 |
|
|
1039 |
_string_item.raw = string_item; |
_string_item.raw = string_item; |
1040 |
_string_item.cont = 0; |
_string_item.cont = 0; |
1041 |
_string_item.nr_substrings = 0; |
_string_item.nr_substrings = 0; |
1042 |
|
|
1043 |
((__L4_string_item_t *) &msg[pos])->raw = string_item; |
__builtin_memcpy (&msg[pos], &_string_item, sizeof (__L4_string_item_t)); |
1044 |
_msg->tag.typed += 2; |
tag.typed += sizeof (_L4_string_item_t) / sizeof (_L4_word_t); |
1045 |
|
_L4_set_msg_msg_tag (msg, tag.raw); |
1046 |
} |
} |
1047 |
|
|
1048 |
|
|
1049 |
static inline void |
static inline void |
1050 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1051 |
_L4_msg_append_string_item (_L4_msg_t msg, _L4_string_item_t *string_item) |
_L4_msg_append_string_item (_L4_msg_t msg, void *string_item) |
1052 |
{ |
{ |
1053 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1054 |
|
/* We do not break any strict aliasing rules here, as we only use |
1055 |
|
the pointers for pointer arithmetic. */ |
1056 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
1057 |
/* The "not last" bit is ignored for sending. */ |
/* The "not last" bit is ignored for sending. */ |
1058 |
int pos = 1 + _msg->tag.untyped + _msg->tag.typed; |
int pos = 1 + tag.untyped + tag.typed; |
1059 |
int cont; |
int count; |
1060 |
|
|
1061 |
do |
count = _L4_string_item_words (_string_item, 0); |
1062 |
|
tag.typed += count; |
1063 |
|
while (count--) |
1064 |
{ |
{ |
1065 |
int nr = _string_item->nr_substrings; |
__builtin_memcpy (&msg[pos++], _string_item, sizeof (_L4_word_t)); |
1066 |
_L4_word_t *substrings = &_string_item->string[1]; |
_string_item = (__L4_string_item_t *) |
1067 |
|
(((_L4_word_t *) _string_item) + 1); |
|
cont = _string_item->cont; |
|
|
msg[pos++] = _string_item->mr[0]; |
|
|
msg[pos++] = _string_item->mr[1]; |
|
|
|
|
|
while (nr-- > 0) |
|
|
msg[pos++] = *(substrings++); |
|
|
_string_item = (__L4_string_item_t *) substrings; |
|
1068 |
} |
} |
1069 |
while (cont); |
_L4_set_msg_msg_tag (msg, tag.raw); |
|
|
|
|
_msg->tag.typed += pos - 1 - _msg->tag.untyped; |
|
1070 |
} |
} |
1071 |
|
|
1072 |
|
|
1082 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1083 |
_L4_msg_put_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t map_item) |
_L4_msg_put_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t map_item) |
1084 |
{ |
{ |
1085 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1086 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1087 |
|
|
1088 |
((__L4_map_item_t *) &msg[pos])->raw = map_item; |
__builtin_memcpy (&msg[pos], &map_item, sizeof (_L4_map_item_t)); |
1089 |
} |
} |
1090 |
|
|
1091 |
|
|
1094 |
_L4_msg_put_grant_item (_L4_msg_t msg, _L4_word_t nr, |
_L4_msg_put_grant_item (_L4_msg_t msg, _L4_word_t nr, |
1095 |
_L4_grant_item_t grant_item) |
_L4_grant_item_t grant_item) |
1096 |
{ |
{ |
1097 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1098 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1099 |
|
|
1100 |
((__L4_grant_item_t *) &msg[pos])->raw = grant_item; |
__builtin_memcpy (&msg[pos], &grant_item, sizeof (_L4_grant_item_t)); |
1101 |
} |
} |
1102 |
|
|
1103 |
|
|
1106 |
_L4_msg_put_simple_string_item (_L4_msg_t msg, _L4_word_t nr, |
_L4_msg_put_simple_string_item (_L4_msg_t msg, _L4_word_t nr, |
1107 |
_L4_string_item_t string_item) |
_L4_string_item_t string_item) |
1108 |
{ |
{ |
1109 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1110 |
__L4_string_item_t _string_item; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1111 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
__L4_string_item_t _string_item = { .raw = string_item }; |
1112 |
|
|
|
_string_item.raw = string_item; |
|
1113 |
_string_item.cont = 0; |
_string_item.cont = 0; |
1114 |
_string_item.nr_substrings = 0; |
_string_item.nr_substrings = 0; |
1115 |
|
|
1116 |
((__L4_string_item_t *) &msg[pos])->raw = string_item; |
__builtin_memcpy (&msg[pos], &_string_item, sizeof (__L4_string_item_t)); |
1117 |
} |
} |
1118 |
|
|
1119 |
|
|
1120 |
static inline void |
static inline void |
1121 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1122 |
_L4_msg_put_string_item (_L4_msg_t msg, _L4_word_t nr, |
_L4_msg_put_string_item (_L4_msg_t msg, _L4_word_t nr, void *string_item) |
|
_L4_string_item_t *string_item) |
|
1123 |
{ |
{ |
1124 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1125 |
|
/* We do not break any strict aliasing rules here, as we only use |
1126 |
|
the pointers for pointer arithmetic. */ |
1127 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
1128 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1129 |
int cont; |
int count; |
1130 |
|
|
1131 |
do |
count = _L4_string_item_words (_string_item, 0); |
1132 |
|
while (count--) |
1133 |
{ |
{ |
1134 |
int nr = _string_item->nr_substrings; |
__builtin_memcpy (&msg[pos++], _string_item, sizeof (_L4_word_t)); |
1135 |
_L4_word_t *substrings = &_string_item->string[1]; |
_string_item = (__L4_string_item_t *) |
1136 |
|
(((_L4_word_t *) _string_item) + 1); |
|
cont = _string_item->cont; |
|
|
msg[pos++] = _string_item->mr[0]; |
|
|
msg[pos++] = _string_item->mr[1]; |
|
|
|
|
|
while (nr-- > 0) |
|
|
msg[pos++] = *(substrings++); |
|
|
_string_item = (__L4_string_item_t *) substrings; |
|
1137 |
} |
} |
|
while (cont); |
|
1138 |
} |
} |
1139 |
|
|
1140 |
|
|
1158 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1159 |
_L4_msg_get_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t *map_item) |
_L4_msg_get_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t *map_item) |
1160 |
{ |
{ |
1161 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1162 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1163 |
|
|
1164 |
*map_item = ((__L4_map_item_t *) &msg[pos])->raw; |
__builtin_memcpy (map_item, &msg[pos], sizeof (_L4_map_item_t)); |
1165 |
return sizeof (_L4_map_item_t) / sizeof (_L4_word_t); |
return sizeof (_L4_map_item_t) / sizeof (_L4_word_t); |
1166 |
} |
} |
1167 |
|
|
1171 |
_L4_msg_get_grant_item (_L4_msg_t msg, _L4_word_t nr, |
_L4_msg_get_grant_item (_L4_msg_t msg, _L4_word_t nr, |
1172 |
_L4_grant_item_t *grant_item) |
_L4_grant_item_t *grant_item) |
1173 |
{ |
{ |
1174 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1175 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1176 |
|
|
1177 |
*grant_item = ((__L4_grant_item_t *) &msg[pos])->raw; |
__builtin_memcpy (grant_item, &msg[pos], sizeof (_L4_grant_item_t)); |
1178 |
return sizeof (_L4_grant_item_t) / sizeof (_L4_word_t); |
return sizeof (_L4_grant_item_t) / sizeof (_L4_word_t); |
1179 |
} |
} |
1180 |
|
|
1181 |
|
|
1182 |
static inline _L4_word_t |
static inline _L4_word_t |
1183 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1184 |
_L4_msg_get_string_item (_L4_msg_t msg, _L4_word_t nr, |
_L4_msg_get_string_item (_L4_msg_t msg, _L4_word_t nr, void *string_item) |
|
_L4_string_item_t *string_item) |
|
1185 |
{ |
{ |
1186 |
__L4_msg_t *_msg = (__L4_msg_t *) msg; |
__L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) }; |
1187 |
__L4_string_item_t *_string_item = (__L4_string_item_t *) string_item; |
/* We do not break any strict aliasing rules here, as we only use |
1188 |
_L4_word_t pos = 1 + _msg->tag.untyped + nr; |
the pointers for pointer arithmetic. */ |
1189 |
int cont; |
_L4_word_t pos = 1 + tag.untyped + nr; |
1190 |
|
__L4_string_item_t *_string_item = (__L4_string_item_t *) &msg[pos]; |
1191 |
do |
int count; |
1192 |
|
int i; |
1193 |
|
|
1194 |
|
count = _L4_string_item_words (_string_item, 0); |
1195 |
|
i = count; |
1196 |
|
while (i--) |
1197 |
{ |
{ |
1198 |
int nr = _string_item->nr_substrings; |
__builtin_memcpy (_string_item, &msg[pos++], sizeof (_L4_word_t)); |
1199 |
_L4_word_t *substrings = &_string_item->string[1]; |
_string_item = (__L4_string_item_t *) |
1200 |
|
(((_L4_word_t *) _string_item) + 1); |
|
cont = _string_item->cont; |
|
|
*((__L4_string_item_t *) &msg[pos]) = *_string_item; |
|
|
pos += 2; |
|
|
|
|
|
while (nr-- > 0) |
|
|
*(substrings++) = msg[pos++]; |
|
|
_string_item = (__L4_string_item_t *) substrings; |
|
1201 |
} |
} |
1202 |
while (cont); |
return count; |
|
|
|
|
return ((_L4_word_t *) _string_item) - ((_L4_word_t *) string_item); |
|
1203 |
} |
} |
1204 |
|
|
1205 |
|
|
1206 |
/* l4_ipc convenience interface. */ |
/* _L4_ipc convenience interface. */ |
1207 |
|
|
1208 |
static inline _L4_word_t |
static inline _L4_word_t |
1209 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1342 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1343 |
_L4_ipc_succeeded (_L4_msg_tag_t tag) |
_L4_ipc_succeeded (_L4_msg_tag_t tag) |
1344 |
{ |
{ |
1345 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
1346 |
|
|
|
_tag.raw = tag; |
|
1347 |
return !_tag.error; |
return !_tag.error; |
1348 |
} |
} |
1349 |
|
|
1352 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1353 |
_L4_ipc_failed (_L4_msg_tag_t tag) |
_L4_ipc_failed (_L4_msg_tag_t tag) |
1354 |
{ |
{ |
1355 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
1356 |
|
|
|
_tag.raw = tag; |
|
1357 |
return _tag.error; |
return _tag.error; |
1358 |
} |
} |
1359 |
|
|
1362 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1363 |
_L4_ipc_propagated (_L4_msg_tag_t tag) |
_L4_ipc_propagated (_L4_msg_tag_t tag) |
1364 |
{ |
{ |
1365 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
1366 |
|
|
|
_tag.raw = tag; |
|
1367 |
return _tag.propagated; |
return _tag.propagated; |
1368 |
} |
} |
1369 |
|
|
1372 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1373 |
_L4_ipc_redirected (_L4_msg_tag_t tag) |
_L4_ipc_redirected (_L4_msg_tag_t tag) |
1374 |
{ |
{ |
1375 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
1376 |
|
|
|
_tag.raw = tag; |
|
1377 |
return _tag.redirected; |
return _tag.redirected; |
1378 |
} |
} |
1379 |
|
|
1382 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1383 |
_L4_ipc_xcpu (_L4_msg_tag_t tag) |
_L4_ipc_xcpu (_L4_msg_tag_t tag) |
1384 |
{ |
{ |
1385 |
__L4_msg_tag_t _tag; |
__L4_msg_tag_t _tag = { .raw = tag }; |
1386 |
|
|
|
_tag.raw = tag; |
|
1387 |
return _tag.cross_cpu; |
return _tag.cross_cpu; |
1388 |
} |
} |
1389 |
|
|
1392 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1393 |
_L4_set_propagation (_L4_msg_tag_t *tag) |
_L4_set_propagation (_L4_msg_tag_t *tag) |
1394 |
{ |
{ |
1395 |
__L4_msg_tag_t *_tag = (__L4_msg_tag_t *) tag; |
__L4_msg_tag_t _tag = { .raw = *tag }; |
1396 |
|
|
1397 |
|
_tag.propagated = 1; |
1398 |
|
|
1399 |
_tag->propagated = 1; |
*tag = _tag.raw; |
1400 |
} |
} |
1401 |
|
|
1402 |
|
|
1404 |
_L4_attribute_always_inline |
_L4_attribute_always_inline |
1405 |
_L4_clear_propagation (_L4_msg_tag_t *tag) |
_L4_clear_propagation (_L4_msg_tag_t *tag) |
1406 |
{ |
{ |
1407 |
__L4_msg_tag_t *_tag = (__L4_msg_tag_t *) tag; |
__L4_msg_tag_t _tag = { .raw = *tag }; |
1408 |
|
|
1409 |
|
_tag.propagated = 0; |
1410 |
|
|
1411 |
_tag->propagated = 0; |
*tag = _tag.raw; |
1412 |
} |
} |
1413 |
|
|
1414 |
|
|