]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/ARCH-arm/L4API-l4f/ipc.h
73c46106b39cb92bb2b6640731a5ae83af9aec40
[l4.git] / l4 / pkg / l4sys / include / ARCH-arm / L4API-l4f / ipc.h
1 /**
2  * \file
3  * \brief   L4 IPC System Calls, ARM
4  * \ingroup api_calls
5  */
6 /*
7  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8  *               Alexander Warg <warg@os.inf.tu-dresden.de>
9  *     economic rights: Technische Universität Dresden (Germany)
10  *
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  *
15  * As a special exception, you may use this file as part of a free software
16  * library without restriction.  Specifically, if other files instantiate
17  * templates or use macros or inline functions from this file, or you compile
18  * this file and link it with other files to produce an executable, this
19  * file does not by itself cause the resulting executable to be covered by
20  * the GNU General Public License.  This exception does not however
21  * invalidate any other reasons why the executable file might be covered by
22  * the GNU General Public License.
23  */
24 #pragma once
25
26 #include_next <l4/sys/ipc.h>
27
28 #ifdef __GNUC__
29
30 #include <l4/sys/compiler.h>
31 #include <l4/sys/syscall_defs.h>
32
33 L4_INLINE l4_msgtag_t
34 l4_ipc_call(l4_cap_idx_t dest, l4_utcb_t *utcb,
35             l4_msgtag_t tag,
36             l4_timeout_t timeout) L4_NOTHROW
37 {
38   register l4_umword_t _dest     __asm__("r2") = dest | L4_SYSF_CALL;
39   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
40   register l4_umword_t _flags    __asm__("r4") = 0;
41   register l4_msgtag_t _tag      __asm__("r0") = tag;
42   (void)utcb;
43   __asm__ __volatile__
44     ("@ l4_ipc_call(start) \n\t"
45      "mov     lr, pc       \n\t"
46      "mov     pc, %[sc]    \n\t"
47      "@ l4_ipc_call(end)   \n\t"
48      :
49      "=r" (_dest),
50      "=r" (_timeout),
51      "=r" (_flags),
52      "=r" (_tag)
53      :
54      [sc] "i" (L4_SYSCALL_INVOKE),
55      "0" (_dest),
56      "1" (_timeout),
57      "2" (_flags),
58      "3" (_tag)
59      : "cc", "memory", "lr");
60   tag.raw = _tag.raw; // because gcc doesn't return out of registers variables
61   return tag;
62 }
63
64 L4_INLINE l4_msgtag_t
65 l4_ipc_reply_and_wait(l4_utcb_t *utcb, l4_msgtag_t tag,
66                       l4_umword_t *label,
67                       l4_timeout_t timeout) L4_NOTHROW
68 {
69   register l4_umword_t _dest     __asm__("r2") = L4_INVALID_CAP | L4_SYSF_REPLY_AND_WAIT;
70   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
71   register l4_msgtag_t _tag      __asm__("r0") = tag;
72   register l4_umword_t _flags    __asm__("r4") = 0;
73   (void)utcb;
74
75   __asm__ __volatile__
76     ("@ l4_ipc_reply_and_wait(start) \n\t"
77      "mov     lr, pc                 \n\t"
78      "mov     pc, %[sc]              \n\t"
79      "@ l4_ipc_reply_and_wait(end)   \n\t"
80      :
81      "=r" (_dest),
82      "=r" (_timeout),
83      "=r" (_flags),
84      "=r" (_tag)
85      :
86      [sc] "i" (L4_SYSCALL_INVOKE),
87      "0" (_dest),
88      "1" (_timeout),
89      "2" (_flags),
90      "3" (_tag)
91      :
92      "cc", "memory", "lr");
93   *label = _flags;
94   tag.raw = _tag.raw; // because gcc doesn't return out of registers variables
95   return tag;
96 }
97
98
99 L4_INLINE l4_msgtag_t
100 l4_ipc_send_and_wait(l4_cap_idx_t dest, l4_utcb_t *utcb,
101                      l4_msgtag_t tag,
102                      l4_umword_t *src,
103                      l4_timeout_t timeout) L4_NOTHROW
104 {
105   register l4_umword_t _dest     __asm__("r2") = dest | L4_SYSF_SEND_AND_WAIT;
106   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
107   register l4_msgtag_t _tag      __asm__("r0") = tag;
108   register l4_umword_t _flags    __asm__("r4") = 0;
109   (void)utcb;
110
111   __asm__ __volatile__
112     ("@ l4_ipc_reply_and_wait(start) \n\t"
113      "mov     lr, pc                 \n\t"
114      "mov     pc, %[sc]              \n\t"
115      "@ l4_ipc_reply_and_wait(end)   \n\t"
116      :
117      "=r" (_dest),
118      "=r" (_timeout),
119      "=r" (_flags),
120      "=r" (_tag)
121      :
122      [sc] "i" (L4_SYSCALL_INVOKE),
123      "0" (_dest),
124      "1" (_timeout),
125      "2" (_flags),
126      "3" (_tag)
127      :
128      "cc", "memory", "lr");
129   *src = _flags;
130   tag.raw = _tag.raw; // because gcc doesn't return out of registers variables
131   return tag;
132 }
133
134 L4_INLINE l4_msgtag_t
135 l4_ipc_send(l4_cap_idx_t dest, l4_utcb_t *utcb,
136             l4_msgtag_t tag,
137             l4_timeout_t timeout) L4_NOTHROW
138 {
139   register l4_umword_t _dest     __asm__("r2") = dest | L4_SYSF_SEND;
140   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
141   register l4_umword_t _flags    __asm__("r4") = 0;
142   register l4_msgtag_t _tag      __asm__("r0") = tag;
143   (void)utcb;
144
145   __asm__ __volatile__
146     ("@  l4_ipc_send(start) \n\t"
147      "mov     lr, pc          \n\t"
148      "mov     pc, %[sc]       \n\t"
149      "@  l4_ipc_send(end)   \n\t"
150      :
151      "=r" (_dest),
152      "=r" (_timeout),
153      "=r" (_flags),
154      "=r" (_tag)
155      :
156      [sc] "i" (L4_SYSCALL_INVOKE),
157      "0" (_dest),
158      "1" (_timeout),
159      "2" (_flags),
160      "3" (_tag)
161      :
162      "cc", "memory", "lr");
163   tag.raw = _tag.raw; // because gcc doesn't return out of registers variables
164   return tag;
165 }
166
167 L4_INLINE l4_msgtag_t
168 l4_ipc_wait(l4_utcb_t *utcb, l4_umword_t *src,
169             l4_timeout_t timeout) L4_NOTHROW
170 {
171   l4_msgtag_t rtag;
172   register l4_umword_t _r        __asm__("r2") = L4_INVALID_CAP | L4_SYSF_WAIT;
173   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
174   register l4_msgtag_t _tag      __asm__("r0");
175   register l4_umword_t _flags    __asm__("r4") = 0;
176   (void)utcb;
177   _tag.raw = 0;
178
179   __asm__ __volatile__
180     ("@ l4_ipc_wait(start) \n\t"
181      "mov     lr, pc       \n\t"
182      "mov     pc, %[sc]    \n\t"
183      "@ l4_ipc_wait(end)   \n\t"
184      :
185      "=r"(_r),
186      "=r"(_timeout),
187      "=r"(_flags),
188      "=r"(_tag)
189      :
190      [sc] "i"(L4_SYSCALL_INVOKE),
191      "0"(_r),
192      "1"(_timeout),
193      "2"(_flags),
194      "3"(_tag)
195
196      :
197      "cc", "memory", "lr");
198   *src     = _flags;
199   rtag.raw = _tag.raw; // because gcc doesn't return out of registers variables
200   return rtag;
201 }
202
203 L4_INLINE l4_msgtag_t
204 l4_ipc_receive(l4_cap_idx_t src, l4_utcb_t *utcb,
205                l4_timeout_t timeout) L4_NOTHROW
206 {
207   l4_msgtag_t rtag;
208   register l4_umword_t _r        __asm__("r2") = src | L4_SYSF_RECV;
209   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
210   register l4_msgtag_t _tag      __asm__("r0");
211   register l4_umword_t _flags    __asm__("r4") = 0;
212   (void)utcb;
213
214   _tag.raw = 0;
215
216   __asm__ __volatile__
217     ("@ l4_ipc_receive(start)  \n\t"
218      "mov     lr, pc           \n\t"
219      "mov     pc, %[sc]        \n\t"
220      "@ l4_ipc_receive(end)    \n\t"
221      :
222      "=r"(_r),
223      "=r"(_timeout),
224      "=r"(_flags),
225      "=r"(_tag)
226      :
227      [sc] "i"(L4_SYSCALL_INVOKE),
228      "0"(_r),
229      "1"(_timeout),
230      "2"(_flags),
231      "3"(_tag)
232      :
233      "cc", "memory", "lr");
234   rtag.raw = _tag.raw; // because gcc doesn't return out of registers variables
235   return rtag;
236 }
237
238 // todo: let all calls above use this single call
239 L4_INLINE l4_msgtag_t
240 l4_ipc(l4_cap_idx_t dest, l4_utcb_t *utcb,
241        l4_umword_t flags,
242        l4_umword_t slabel,
243        l4_msgtag_t tag,
244        l4_umword_t *rlabel,
245        l4_timeout_t timeout) L4_NOTHROW
246 {
247   register l4_umword_t _dest     __asm__("r2") = dest | flags;
248   register l4_umword_t _timeout  __asm__("r3") = timeout.raw;
249   register l4_msgtag_t _tag      __asm__("r0") = tag;
250   register l4_umword_t _lab      __asm__("r4") = slabel;
251   (void)utcb;
252
253   __asm__ __volatile__
254     ("@ l4_ipc_reply_and_wait(start) \n\t"
255      "mov     lr, pc                 \n\t"
256      "mov     pc, %[sc]              \n\t"
257      "@ l4_ipc_reply_and_wait(end)   \n\t"
258      :
259      "=r" (_dest),
260      "=r" (_timeout),
261      "=r" (_lab),
262      "=r" (_tag)
263      :
264      [sc] "i" (L4_SYSCALL_INVOKE),
265      "0" (_dest),
266      "1" (_timeout),
267      "2" (_lab),
268      "3" (_tag)
269      :
270      "cc", "memory", "lr");
271   *rlabel = _lab;
272   tag.raw = _tag.raw; // because gcc doesn't return out of registers variables
273   return tag;
274 }
275
276
277 #include <l4/sys/ipc-impl.h>
278
279 #endif //__GNUC__
280