1 /*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7 #pragma once
8
9 #include <autoconf.h>
10 #include <sel4/functions.h>
11 #include <sel4/types.h>
12
13 /*
14 * A general description of the x86_sys_ functions and what they do can be found in
15 * the ARM aarch32 syscalls.h file (substituting ARM for x86)
16 *
17 * Further there are two version of every function, one that supports Position
18 * Independent Code, and one that does not. The PIC variant works to preserve
19 * EBX, which is used by the compiler, and has to do additional work to save/restore
20 * and juggle the contents of EBX as the kernel ABI uses EBX
21 */
22
23 #ifdef CONFIG_KERNEL_MCS
24 #define MCS_COND(a,b) a
25 #else
26 #define MCS_COND(a,b) b
27 #endif
28
29
30 #if defined(__pic__)
31
32 /* mr2 doesn't get used on CONFIG_KERNEL_MCS */
x86_sys_send(seL4_Word sys,seL4_Word dest,seL4_Word info,seL4_Word mr1,LIBSEL4_UNUSED seL4_Word mr2)33 static inline void x86_sys_send(seL4_Word sys, seL4_Word dest, seL4_Word info, seL4_Word mr1,
34 LIBSEL4_UNUSED seL4_Word mr2)
35 {
36 asm volatile(
37 "pushl %%ebp \n"
38 "pushl %%ebx \n"
39 MCS_COND(, "movl %%ecx, %%ebp \n")
40 "movl %%esp, %%ecx \n"
41 "movl %%edx, %%ebx \n"
42 "leal 1f, %%edx \n"
43 "1: \n"
44 "sysenter \n"
45 "popl %%ebx \n"
46 "popl %%ebp \n"
47 : "+d"(dest)
48 : "a"(sys),
49 "S"(info),
50 "D"(mr1)
51 #ifdef CONFIG_KERNEL_MCS
52 : "%ecx"
53 #else
54 , "c"(mr2)
55 #endif
56 );
57 }
58
59 #ifndef CONFIG_KERNEL_MCS
x86_sys_reply(seL4_Word sys,seL4_Word info,seL4_Word mr1,seL4_Word mr2)60 static inline void x86_sys_reply(seL4_Word sys, seL4_Word info, seL4_Word mr1, seL4_Word mr2)
61 {
62 asm volatile(
63 "pushl %%ebp \n"
64 "pushl %%ebx \n"
65 "movl %%ecx, %%ebp \n"
66 "movl %%esp, %%ecx \n"
67 "leal 1f, %%edx \n"
68 "1: \n"
69 "sysenter \n"
70 "popl %%ebx \n"
71 "popl %%ebp \n"
72 :
73 : "a"(sys),
74 "S"(info),
75 "D"(mr1),
76 "c"(mr2)
77 : "%edx"
78 );
79 }
80 #endif /* !CONFIG_KERNEL_MCS */
81
x86_sys_send_null(seL4_Word sys,seL4_Word src,seL4_Word info)82 static inline void x86_sys_send_null(seL4_Word sys, seL4_Word src, seL4_Word info)
83 {
84 asm volatile(
85 "pushl %%ebp \n"
86 "pushl %%ebx \n"
87 "movl %%esp, %%ecx \n"
88 "movl %%edx, %%ebx \n"
89 "leal 1f, %%edx \n"
90 "1: \n"
91 "sysenter \n"
92 "popl %%ebx \n"
93 "popl %%ebp \n"
94 : "+d"(src)
95 : "a"(sys),
96 "S"(info)
97 : "%ecx"
98 );
99 }
100
x86_sys_recv(seL4_Word sys,seL4_Word src,seL4_Word * out_badge,seL4_Word * out_info,seL4_Word * out_mr1,MCS_COND (seL4_Word reply,seL4_Word * out_mr2))101 static inline void x86_sys_recv(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word *out_info,
102 seL4_Word *out_mr1, MCS_COND(seL4_Word reply, seL4_Word *out_mr2))
103 {
104 asm volatile(
105 "pushl %%ebp \n"
106 "pushl %%ebx \n"
107 MCS_COND("movl %%ecx, %%ebp \n",)
108 "movl %%esp, %%ecx \n"
109 "movl %%edx, %%ebx \n"
110 "leal 1f, %%edx \n"
111 "1: \n"
112 "sysenter \n"
113 "movl %%ebx, %%edx \n"
114 "popl %%ebx \n"
115 "movl %%ebp, %%ecx \n"
116 "popl %%ebp \n"
117 :
118 "=d"(*out_badge),
119 "=S"(*out_info),
120 "=D"(*out_mr1),
121 MCS_COND("+c"(reply), "=c"(*out_mr2))
122 : "a"(sys),
123 "d"(src)
124 : "memory"
125 );
126 }
127
x86_sys_send_recv(seL4_Word sys,seL4_Word dest,seL4_Word * out_badge,seL4_Word info,seL4_Word * out_info,seL4_Word * in_out_mr1,MCS_COND (seL4_Word reply,seL4_Word * in_out_mr2))128 static inline void x86_sys_send_recv(seL4_Word sys, seL4_Word dest, seL4_Word *out_badge, seL4_Word info,
129 seL4_Word *out_info, seL4_Word *in_out_mr1, MCS_COND(seL4_Word reply, seL4_Word *in_out_mr2))
130 {
131 asm volatile(
132 "pushl %%ebp \n"
133 "pushl %%ebx \n"
134 MCS_COND("movl %%ecx, %%ebp \n",)
135 "movl %%esp, %%ecx \n"
136 "movl %%edx, %%ebx \n"
137 "leal 1f, %%edx \n"
138 "1: \n"
139 "sysenter \n"
140 "movl %%ebx, %%edx \n"
141 "popl %%ebx \n"
142 "movl %%ebp, %%ecx \n"
143 "popl %%ebp \n"
144 :
145 "=S"(*out_info),
146 "=D"(*in_out_mr1),
147 "=d"(*out_badge)
148 MCS_COND("+c"(reply), "=c"(*in_out_mr2))
149 : "a"(sys),
150 "S"(info),
151 "D"(*in_out_mr1),
152 #ifndef CONFIG_KERNEL_MCS
153 "c"(*in_out_mr2),
154 #endif
155 "d"(dest)
156 : "memory"
157 );
158 }
159
160 #ifdef CONFIG_KERNEL_MCS
x86_sys_nbsend_wait(seL4_Word sys,seL4_Word src,seL4_Word * out_badge,seL4_Word info,seL4_Word * out_info,seL4_Word * in_out_mr1,seL4_Word reply)161 static inline void x86_sys_nbsend_wait(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word info,
162 seL4_Word *out_info, seL4_Word *in_out_mr1, seL4_Word reply)
163 {
164 asm volatile(
165 "pushl %%ebp \n"
166 "pushl %%ebx \n"
167 "movl %%ecx, %%ebp \n"
168 "movl %%esp, %%ecx \n"
169 "movl %%edx, %%ebx \n"
170 "leal 1f, %%edx \n"
171 "1: \n"
172 "sysenter \n"
173 "movl %%ebx, %%edx \n"
174 "popl %%ebx \n"
175 "movl %%ebp, %%ecx \n"
176 "popl %%ebp \n"
177 :
178 "=S"(*out_info),
179 "=D"(*in_out_mr1),
180 "=d"(*out_badge)
181 , "+c"(reply)
182 : "a"(sys),
183 "S"(info),
184 "D"(*in_out_mr1),
185 "d"(src)
186 : "memory"
187 );
188 }
189 #endif /* CONFIG_KERNEL_MCS */
190
191
192
x86_sys_null(seL4_Word sys)193 static inline void x86_sys_null(seL4_Word sys)
194 {
195 asm volatile(
196 "pushl %%ebp \n"
197 "pushl %%ebx \n"
198 "movl %%esp, %%ecx \n"
199 "leal 1f, %%edx \n"
200 "1: \n"
201 "sysenter \n"
202 "popl %%ebx \n"
203 "popl %%ebp \n"
204 :
205 : "a"(sys)
206 : "%ecx", "%edx"
207 );
208 }
209
210 #else
211
x86_sys_send(seL4_Word sys,seL4_Word dest,seL4_Word info,seL4_Word mr1,seL4_Word mr2)212 static inline void x86_sys_send(seL4_Word sys, seL4_Word dest, seL4_Word info, seL4_Word mr1, seL4_Word mr2)
213 {
214 asm volatile(
215 "pushl %%ebp \n"
216 #ifndef CONFIG_KERNEL_MCS
217 "movl %%ecx, %%ebp \n"
218 #endif
219 "movl %%esp, %%ecx \n"
220 "leal 1f, %%edx \n"
221 "1: \n"
222 "sysenter \n"
223 "popl %%ebp \n"
224 :
225 : "a"(sys),
226 "b"(dest),
227 "S"(info),
228 "D"(mr1)
229 #ifdef CONFIG_KERNEL_MCS
230 : "%ecx",
231 #else
232 , "c"(mr2):
233 #endif
234 "%edx"
235 );
236 }
237
238 #ifndef CONFIG_KERNEL_MCS
x86_sys_reply(seL4_Word sys,seL4_Word info,seL4_Word mr1,seL4_Word mr2)239 static inline void x86_sys_reply(seL4_Word sys, seL4_Word info, seL4_Word mr1, seL4_Word mr2)
240 {
241 asm volatile(
242 "pushl %%ebp \n"
243 "movl %%ecx, %%ebp \n"
244 "movl %%esp, %%ecx \n"
245 "leal 1f, %%edx \n"
246 "1: \n"
247 "sysenter \n"
248 "popl %%ebp \n"
249 :
250 : "a"(sys),
251 "S"(info),
252 "D"(mr1),
253 "c"(mr2)
254 : "%ebx", "%edx"
255 );
256 }
257 #endif
258
x86_sys_send_null(seL4_Word sys,seL4_Word dest,seL4_Word info)259 static inline void x86_sys_send_null(seL4_Word sys, seL4_Word dest, seL4_Word info)
260 {
261 asm volatile(\
262 "pushl %%ebp \n"
263 "movl %%esp, %%ecx \n"
264 "leal 1f, %%edx \n"
265 "1: \n"
266 "sysenter \n"
267 "popl %%ebp \n"
268 :
269 : "a"(sys),
270 "b"(dest),
271 "S"(info)
272 : "%ecx", "edx"
273 );
274 }
275
x86_sys_recv(seL4_Word sys,seL4_Word src,seL4_Word * out_badge,seL4_Word * out_info,seL4_Word * out_mr1,MCS_COND (seL4_Word reply,seL4_Word * out_mr2))276 static inline void x86_sys_recv(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word *out_info,
277 seL4_Word *out_mr1, MCS_COND(seL4_Word reply, seL4_Word *out_mr2))
278 {
279 asm volatile(\
280 "pushl %%ebp \n"
281 MCS_COND("movl %%ecx, %%ebp \n",)
282 "movl %%esp, %%ecx \n"
283 "leal 1f, %%edx \n"
284 "1: \n"
285 "sysenter \n"
286 "movl %%ebp, %%ecx \n"
287 "popl %%ebp \n"
288 : "=b"(*out_badge),
289 "=S"(*out_info),
290 "=D"(*out_mr1),
291 MCS_COND("+c"(reply), "=c"(*out_mr2))
292 : "a"(sys),
293 "b"(src)
294 : "%edx", "memory"
295 );
296 }
297
x86_sys_send_recv(seL4_Word sys,seL4_Word dest,seL4_Word * out_badge,seL4_Word info,seL4_Word * out_info,seL4_Word * in_out_mr1,MCS_COND (seL4_Word reply,seL4_Word * in_out_mr2))298 static inline void x86_sys_send_recv(seL4_Word sys, seL4_Word dest, seL4_Word *out_badge, seL4_Word info,
299 seL4_Word *out_info, seL4_Word *in_out_mr1, MCS_COND(seL4_Word reply, seL4_Word *in_out_mr2))
300 {
301 asm volatile(
302 "pushl %%ebp \n"
303 "movl %%ecx, %%ebp \n"
304 "movl %%esp, %%ecx \n"
305 "leal 1f, %%edx \n"
306 "1: \n"
307 "sysenter \n"
308 "movl %%ebp, %%ecx \n"
309 "popl %%ebp \n"
310 : "=S"(*out_info),
311 "=D"(*in_out_mr1),
312 "=b"(*out_badge),
313 MCS_COND("+c"(reply), "=c"(*in_out_mr2))
314 : "a"(sys),
315 "S"(info),
316 "D"(*in_out_mr1),
317 #ifndef CONFIG_KERNEL_MCS
318 "c"(*in_out_mr2),
319 #endif
320 "b"(dest)
321 : "%edx", "memory"
322 );
323 }
324
325 #ifdef CONFIG_KERNEL_MCS
x86_sys_nbsend_wait(seL4_Word sys,seL4_Word src,seL4_Word * out_badge,seL4_Word info,seL4_Word * out_info,seL4_Word * in_out_mr1,seL4_Word reply)326 static inline void x86_sys_nbsend_wait(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word info,
327 seL4_Word *out_info, seL4_Word *in_out_mr1, seL4_Word reply)
328 {
329 asm volatile(
330 "pushl %%ebp \n"
331 "movl %%ecx, %%ebp \n"
332 "movl %%esp, %%ecx \n"
333 "leal 1f, %%edx \n"
334 "1: \n"
335 "sysenter \n"
336 "movl %%ebp, %%ecx \n"
337 "popl %%ebp \n"
338 : "=S"(*out_info),
339 "=D"(*in_out_mr1),
340 "=b"(*out_badge),
341 "+c"(reply)
342 : "a"(sys),
343 "S"(info),
344 "D"(*in_out_mr1),
345 "b"(src)
346 : "%edx", "memory"
347 );
348 }
349 #endif /* CONFIG_KERNEL_MCS */
350
x86_sys_null(seL4_Word sys)351 static inline void x86_sys_null(seL4_Word sys)
352 {
353 asm volatile(
354 "pushl %%ebp \n"
355 "movl %%esp, %%ecx \n"
356 "leal 1f, %%edx \n"
357 "1: \n"
358 "sysenter \n"
359 "popl %%ebp \n"
360 :
361 : "a"(sys)
362 : "%ebx", "%ecx", "%edx"
363 );
364 }
365
366 #endif /* defined(__pic__) */
367 #ifdef CONFIG_KERNEL_MCS
368 #define GET_MRS seL4_GetMR(0), 0
369 #define MAYBE_GET_MRS mr0 != seL4_Null ? *mr0 : 0
370 #define MR_ARGS seL4_Word *mr0
371 #define RECV_MRS &mr0
372 #define REPLY &mr0
373 #else
374 #define MCS_MAYBE_GET_MR1 seL4_GetMR(1)
375 #define MAYBE_GET_MRS mr0 != seL4_Null ? *mr0 : 0, mr1 != seL4_Null ? *mr1 : 0
376 #define MR_ARGS
377 #define RECV_MRS &mr0, &mr1
378 #endif
379
seL4_Send(seL4_CPtr dest,seL4_MessageInfo_t msgInfo)380 LIBSEL4_INLINE_FUNC void seL4_Send(seL4_CPtr dest, seL4_MessageInfo_t msgInfo)
381 {
382 x86_sys_send(seL4_SysSend, dest, msgInfo.words[0], seL4_GetMR(0), MCS_COND(0, seL4_GetMR(1)));
383 }
384
385 #ifdef CONFIG_KERNEL_MCS
seL4_SendWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word * mr0)386 LIBSEL4_INLINE_FUNC void seL4_SendWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *mr0)
387 #else
388 LIBSEL4_INLINE_FUNC void seL4_SendWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *mr0, seL4_Word *mr1)
389 #endif
390 {
391 x86_sys_send(seL4_SysSend, dest, msgInfo.words[0], mr0 != seL4_Null ? *mr0 : 0, MCS_COND(0,
392 mr1 != seL4_Null ? *mr1 : 0));
393 }
394
seL4_NBSend(seL4_CPtr dest,seL4_MessageInfo_t msgInfo)395 LIBSEL4_INLINE_FUNC void seL4_NBSend(seL4_CPtr dest, seL4_MessageInfo_t msgInfo)
396 {
397 x86_sys_send(seL4_SysNBSend, dest, msgInfo.words[0], seL4_GetMR(0), MCS_COND(0, seL4_GetMR(1)));
398 }
399
400 #ifdef CONFIG_KERNEL_MCS
seL4_NBSendWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word * mr0)401 LIBSEL4_INLINE_FUNC void seL4_NBSendWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *mr0)
402 #else
403 LIBSEL4_INLINE_FUNC void seL4_NBSendWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *mr0, seL4_Word *mr1)
404 #endif
405 {
406 x86_sys_send(seL4_SysNBSend, dest, msgInfo.words[0], mr0 != seL4_Null ? *mr0 : 0, MCS_COND(0,
407 mr1 != seL4_Null ? *mr1 : 0));
408 }
409
410 #ifndef CONFIG_KERNEL_MCS
seL4_Reply(seL4_MessageInfo_t msgInfo)411 LIBSEL4_INLINE_FUNC void seL4_Reply(seL4_MessageInfo_t msgInfo)
412 {
413 x86_sys_reply(seL4_SysReply, msgInfo.words[0], seL4_GetMR(0), seL4_GetMR(1));
414 }
415
seL4_ReplyWithMRs(seL4_MessageInfo_t msgInfo,seL4_Word * mr0,seL4_Word * mr1)416 LIBSEL4_INLINE_FUNC void seL4_ReplyWithMRs(seL4_MessageInfo_t msgInfo,
417 seL4_Word *mr0, seL4_Word *mr1)
418 {
419 x86_sys_reply(seL4_SysReply, msgInfo.words[0], mr0 != seL4_Null ? *mr0 : 0, mr1 != seL4_Null ? *mr1 : 0);
420 }
421 #endif /* !CONFIG_KERNEL_MCS */
422
seL4_Signal(seL4_CPtr dest)423 LIBSEL4_INLINE_FUNC void seL4_Signal(seL4_CPtr dest)
424 {
425 x86_sys_send_null(seL4_SysSend, dest, seL4_MessageInfo_new(0, 0, 0, 0).words[0]);
426 }
427
428 #ifdef CONFIG_KERNEL_MCS
seL4_Recv(seL4_CPtr src,seL4_Word * sender,seL4_CPtr reply)429 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word *sender, seL4_CPtr reply)
430 #else
431 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word *sender)
432 #endif
433 {
434 seL4_MessageInfo_t info;
435 seL4_Word badge;
436 seL4_Word mr0;
437 LIBSEL4_UNUSED seL4_Word mr1;
438
439 x86_sys_recv(seL4_SysRecv, src, &badge, &info.words[0], &mr0, MCS_COND(reply, &mr1));
440
441 seL4_SetMR(0, mr0);
442 #ifndef CONFIG_KERNEL_MCS
443 seL4_SetMR(1, mr1);
444 #endif
445 if (sender) {
446 *sender = badge;
447 }
448
449 return info;
450 }
451
452 #ifdef CONFIG_KERNEL_MCS
seL4_RecvWithMRs(seL4_CPtr src,seL4_Word * sender,seL4_Word * mr0,seL4_CPtr reply)453 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_RecvWithMRs(seL4_CPtr src, seL4_Word *sender,
454 seL4_Word *mr0, seL4_CPtr reply)
455 #else
456 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_RecvWithMRs(seL4_CPtr src, seL4_Word *sender,
457 seL4_Word *mr0, seL4_Word *mr1)
458 #endif
459 {
460 seL4_MessageInfo_t info;
461 seL4_Word badge;
462 seL4_Word msg0 = 0;
463 LIBSEL4_UNUSED seL4_Word msg1 = 0;
464
465 x86_sys_recv(seL4_SysRecv, src, &badge, &info.words[0], &msg0, MCS_COND(reply, &msg1));
466
467 if (mr0 != seL4_Null) {
468 *mr0 = msg0;
469 }
470
471 #ifndef CONFIG_KERNEL_MCS
472 if (mr1 != seL4_Null) {
473 *mr1 = msg1;
474 }
475 #endif
476
477 if (sender) {
478 *sender = badge;
479 }
480
481 return info;
482 }
483
484 #ifdef CONFIG_KERNEL_MCS
seL4_NBRecv(seL4_CPtr src,seL4_Word * sender,seL4_CPtr reply)485 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBRecv(seL4_CPtr src, seL4_Word *sender, seL4_CPtr reply)
486 #else
487 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBRecv(seL4_CPtr src, seL4_Word *sender)
488 #endif
489 {
490 seL4_MessageInfo_t info;
491 seL4_Word badge;
492 seL4_Word mr0;
493 LIBSEL4_UNUSED seL4_Word mr1;
494
495 x86_sys_recv(seL4_SysNBRecv, src, &badge, &info.words[0], &mr0, MCS_COND(reply, &mr1));
496
497 seL4_SetMR(0, mr0);
498 #ifndef CONFIG_KERNEL_MCS
499 seL4_SetMR(1, mr1);
500 #endif
501
502 if (sender) {
503 *sender = badge;
504 }
505
506 return info;
507 }
508
509 #ifdef CONFIG_KERNEL_MCS
seL4_Wait(seL4_CPtr src,seL4_Word * sender)510 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_Wait(seL4_CPtr src, seL4_Word *sender)
511 {
512 seL4_MessageInfo_t info;
513 seL4_Word badge;
514 seL4_Word mr0;
515
516 x86_sys_recv(seL4_SysWait, src, &badge, &info.words[0], &mr0, 0);
517
518 seL4_SetMR(0, mr0);
519
520 if (sender) {
521 *sender = badge;
522 }
523
524 return info;
525 }
526
seL4_WaitWithMRs(seL4_CPtr src,seL4_Word * sender,seL4_Word * mr0)527 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_WaitWithMRs(seL4_CPtr src, seL4_Word *sender,
528 seL4_Word *mr0)
529 {
530 seL4_MessageInfo_t info;
531 seL4_Word badge;
532 seL4_Word msg0 = 0;
533
534 x86_sys_recv(seL4_SysWait, src, &badge, &info.words[0], &msg0, 0);
535
536 if (mr0 != seL4_Null) {
537 *mr0 = msg0;
538 }
539
540 if (sender) {
541 *sender = badge;
542 }
543
544 return info;
545 }
546
seL4_NBWait(seL4_CPtr src,seL4_Word * sender)547 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBWait(seL4_CPtr src, seL4_Word *sender)
548 {
549 seL4_MessageInfo_t info;
550 seL4_Word badge;
551 seL4_Word mr0;
552
553 x86_sys_recv(seL4_SysNBWait, src, &badge, &info.words[0], &mr0, 0);
554
555 seL4_SetMR(0, mr0);
556
557 if (sender) {
558 *sender = badge;
559 }
560
561 return info;
562 }
563 #endif /* CONFIG_KERNEL_MCS */
564
seL4_Call(seL4_CPtr dest,seL4_MessageInfo_t msgInfo)565 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo)
566 {
567 seL4_MessageInfo_t info;
568 seL4_Word mr0 = seL4_GetMR(0);
569 LIBSEL4_UNUSED seL4_Word mr1 = MCS_COND(0, seL4_GetMR(1));
570
571 x86_sys_send_recv(seL4_SysCall, dest, &dest, msgInfo.words[0], &info.words[0], &mr0, MCS_COND(0, &mr1));
572
573 seL4_SetMR(0, mr0);
574 #ifndef CONFIG_KERNEL_MCS
575 seL4_SetMR(1, mr1);
576 #endif
577
578 return info;
579 }
580
581 #ifdef CONFIG_KERNEL_MCS
seL4_CallWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word * mr0)582 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_CallWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo,
583 seL4_Word *mr0)
584 #else
585 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_CallWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo,
586 seL4_Word *mr0, seL4_Word *mr1)
587 #endif
588 {
589 seL4_MessageInfo_t info;
590 seL4_Word msg0 = 0;
591 LIBSEL4_UNUSED seL4_Word msg1 = 0;
592
593 if (mr0 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 0) {
594 msg0 = *mr0;
595 }
596
597 #ifndef CONFIG_KERNEL_MCS
598 if (mr1 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 1) {
599 msg1 = *mr1;
600 }
601 #endif
602
603 x86_sys_send_recv(seL4_SysCall, dest, &dest, msgInfo.words[0], &info.words[0], &msg0, MCS_COND(0, &msg1));
604
605 if (mr0 != seL4_Null) {
606 *mr0 = msg0;
607 }
608 #ifndef CONFIG_KERNEL_MCS
609 if (mr1 != seL4_Null) {
610 *mr1 = msg1;
611 }
612 #endif
613
614 return info;
615 }
616
617 #ifdef CONFIG_KERNEL_MCS
seL4_ReplyRecv(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word * sender,seL4_CPtr reply)618 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender,
619 seL4_CPtr reply)
620 #else
621 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender)
622 #endif
623 {
624 seL4_MessageInfo_t info;
625 seL4_Word badge;
626 seL4_Word mr0 = seL4_GetMR(0);
627 LIBSEL4_UNUSED seL4_Word mr1 = MCS_COND(0, seL4_GetMR(1));
628
629 x86_sys_send_recv(seL4_SysReplyRecv, dest, &badge, msgInfo.words[0], &info.words[0], &mr0,
630 MCS_COND(reply, &mr1));
631
632 seL4_SetMR(0, mr0);
633 #ifndef CONFIG_KERNEL_MCS
634 seL4_SetMR(1, mr1);
635 #endif
636
637 if (sender) {
638 *sender = badge;
639 }
640
641 return info;
642 }
643
644 #ifdef CONFIG_KERNEL_MCS
seL4_ReplyRecvWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word * sender,seL4_Word * mr0,seL4_CPtr reply)645 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_ReplyRecvWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo,
646 seL4_Word *sender,
647 seL4_Word *mr0, seL4_CPtr reply)
648 #else
649 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_ReplyRecvWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo,
650 seL4_Word *sender,
651 seL4_Word *mr0, seL4_Word *mr1)
652 #endif
653 {
654 seL4_MessageInfo_t info;
655 seL4_Word badge;
656 seL4_Word msg0 = 0;
657 LIBSEL4_UNUSED seL4_Word msg1 = 0;
658
659 if (mr0 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 0) {
660 msg0 = *mr0;
661 }
662
663 #ifndef CONFIG_KERNEL_MCS
664 if (mr1 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 1) {
665 msg1 = *mr1;
666 }
667 #endif
668 x86_sys_send_recv(seL4_SysReplyRecv, dest, &badge, msgInfo.words[0], &info.words[0], &msg0, MCS_COND(0, &msg1));
669
670 if (mr0 != seL4_Null) {
671 *mr0 = msg0;
672 }
673 #ifndef CONFIG_KERNEL_MCS
674 if (mr1 != seL4_Null) {
675 *mr1 = msg1;
676 }
677 #endif
678
679 if (sender) {
680 *sender = badge;
681 }
682
683 return info;
684 }
685
686 #ifdef CONFIG_KERNEL_MCS
seL4_NBSendRecv(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word src,seL4_Word * sender,seL4_CPtr reply)687 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBSendRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word src,
688 seL4_Word *sender, seL4_CPtr reply)
689 {
690 seL4_MessageInfo_t info;
691 seL4_Word badge;
692 seL4_Word mr0 = seL4_GetMR(0);
693
694 /* no spare registers on ia32 -> must use ipc buffer */
695 seL4_SetUserData(dest);
696
697 x86_sys_nbsend_wait(seL4_SysNBSendRecv, src, &badge, msgInfo.words[0], &info.words[0], &mr0, reply);
698
699 seL4_SetMR(0, mr0);
700
701 if (sender) {
702 *sender = badge;
703 }
704
705 return info;
706 }
707
seL4_NBSendRecvWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word src,seL4_Word * sender,seL4_Word * mr0,seL4_CPtr reply)708 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBSendRecvWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word src,
709 seL4_Word *sender,
710 seL4_Word *mr0, seL4_CPtr reply)
711 {
712 seL4_MessageInfo_t info;
713 seL4_Word badge;
714 seL4_Word msg0 = 0;
715
716 /* no spare registers on ia32 -> must use ipc buffer */
717 seL4_SetUserData(dest);
718
719 if (mr0 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 0) {
720 msg0 = *mr0;
721 }
722
723 x86_sys_nbsend_wait(seL4_SysNBSendRecv, src, &badge, msgInfo.words[0], &info.words[0], &msg0, reply);
724
725 if (mr0 != seL4_Null) {
726 *mr0 = msg0;
727 }
728
729 if (sender) {
730 *sender = badge;
731 }
732
733 return info;
734 }
735
seL4_NBSendWait(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word src,seL4_Word * sender)736 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBSendWait(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word src,
737 seL4_Word *sender)
738 {
739 seL4_MessageInfo_t info;
740 seL4_Word badge;
741 seL4_Word mr0 = seL4_GetMR(0);
742
743 x86_sys_nbsend_wait(seL4_SysNBSendWait, src, &badge, msgInfo.words[0], &info.words[0], &mr0, dest);
744
745 seL4_SetMR(0, mr0);
746
747 if (sender) {
748 *sender = badge;
749 }
750
751 return info;
752 }
753
seL4_NBSendWaitWithMRs(seL4_CPtr dest,seL4_MessageInfo_t msgInfo,seL4_Word src,seL4_Word * sender,seL4_Word * mr0)754 LIBSEL4_INLINE_FUNC seL4_MessageInfo_t seL4_NBSendWaitWithMRs(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word src,
755 seL4_Word *sender,
756 seL4_Word *mr0)
757 {
758 seL4_MessageInfo_t info;
759 seL4_Word badge;
760 seL4_Word msg0 = 0;
761
762 if (mr0 != seL4_Null && seL4_MessageInfo_get_length(msgInfo) > 0) {
763 msg0 = *mr0;
764 }
765
766 x86_sys_nbsend_wait(seL4_SysReplyRecv, src, &badge, msgInfo.words[0], &info.words[0], &msg0, dest);
767
768 if (mr0 != seL4_Null) {
769 *mr0 = msg0;
770 }
771
772 if (sender) {
773 *sender = badge;
774 }
775
776 return info;
777 }
778 #endif /* CONFIG_KERNEL_MCS */
779
seL4_Yield(void)780 LIBSEL4_INLINE_FUNC void seL4_Yield(void)
781 {
782 x86_sys_null(seL4_SysYield);
783 asm volatile("" :::"%esi", "%edi", "memory");
784 }
785
786 #ifdef CONFIG_VTX
seL4_VMEnter(seL4_Word * sender)787 LIBSEL4_INLINE_FUNC seL4_Word seL4_VMEnter(seL4_Word *sender)
788 {
789 seL4_Word fault;
790 seL4_Word badge;
791 seL4_Word mr0 = seL4_GetMR(0);
792 LIBSEL4_UNUSED seL4_Word mr1 = MCS_COND(0, seL4_GetMR(1));
793
794 x86_sys_send_recv(seL4_SysVMEnter, 0, &badge, 0, &fault, &mr0, MCS_COND(0, &mr1));
795
796 seL4_SetMR(0, mr0);
797 #ifndef CONFIG_KERNEL_MCS
798 seL4_SetMR(1, mr1);
799 #endif
800 if (!fault && sender) {
801 *sender = badge;
802 }
803 return fault;
804 }
805 #endif
806
807 #ifdef CONFIG_PRINTING
seL4_DebugPutChar(char c)808 LIBSEL4_INLINE_FUNC void seL4_DebugPutChar(char c)
809 {
810 seL4_Word unused0 = 0;
811 seL4_Word unused1 = 0;
812 seL4_Word unused2 = 0;
813 LIBSEL4_UNUSED seL4_Word unused3 = 0;
814
815 x86_sys_send_recv(seL4_SysDebugPutChar, c, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
816 }
817
seL4_DebugPutString(char * str)818 LIBSEL4_INLINE_FUNC void seL4_DebugPutString(char *str)
819 {
820 for (char *s = str; *s; s++) {
821 seL4_DebugPutChar(*s);
822 }
823 return;
824 }
825
826
seL4_DebugDumpScheduler(void)827 LIBSEL4_INLINE_FUNC void seL4_DebugDumpScheduler(void)
828 {
829 seL4_Word unused0 = 0;
830 seL4_Word unused1 = 0;
831 seL4_Word unused2 = 0;
832 LIBSEL4_UNUSED seL4_Word unused3 = 0;
833
834 x86_sys_send_recv(seL4_SysDebugDumpScheduler, 0, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
835 }
836 #endif
837
838 #ifdef CONFIG_DEBUG_BUILD
seL4_DebugHalt(void)839 LIBSEL4_INLINE_FUNC void seL4_DebugHalt(void)
840 {
841 x86_sys_null(seL4_SysDebugHalt);
842 asm volatile("" :::"%esi", "%edi", "memory");
843 }
844 #endif
845
846 #if defined(CONFIG_DEBUG_BUILD)
seL4_DebugSnapshot(void)847 LIBSEL4_INLINE_FUNC void seL4_DebugSnapshot(void)
848 {
849 x86_sys_null(seL4_SysDebugSnapshot);
850 asm volatile("" :::"%esi", "%edi", "memory");
851 }
852 #endif
853
854 #ifdef CONFIG_DEBUG_BUILD
seL4_DebugCapIdentify(seL4_CPtr cap)855 LIBSEL4_INLINE_FUNC seL4_Uint32 seL4_DebugCapIdentify(seL4_CPtr cap)
856 {
857 seL4_Word unused0 = 0;
858 seL4_Word unused1 = 0;
859 LIBSEL4_UNUSED seL4_Word unused2 = 0;
860
861 x86_sys_send_recv(seL4_SysDebugCapIdentify, cap, &cap, 0, &unused0, &unused1, MCS_COND(0, &unused2));
862 return (seL4_Uint32)cap;
863 }
864
865 char *strcpy(char *, const char *);
seL4_DebugNameThread(seL4_CPtr tcb,const char * name)866 LIBSEL4_INLINE_FUNC void seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
867 {
868 strcpy((char *)seL4_GetIPCBuffer()->msg, name);
869
870 seL4_Word unused0 = 0;
871 seL4_Word unused1 = 0;
872 seL4_Word unused2 = 0;
873 LIBSEL4_UNUSED seL4_Word unused3 = 0;
874
875 x86_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
876 }
877 #endif
878
879 #if defined(CONFIG_DANGEROUS_CODE_INJECTION)
seL4_DebugRun(void (* userfn)(void *),void * userarg)880 LIBSEL4_INLINE_FUNC void seL4_DebugRun(void (*userfn)(void *), void *userarg)
881 {
882 x86_sys_send_null(seL4_SysDebugRun, (seL4_Word)userfn, (seL4_Word)userarg);
883 asm volatile("" ::: "%edi", "memory");
884 }
885 #endif
886
887 #if defined(CONFIG_KERNEL_X86_DANGEROUS_MSR)
seL4_X86DangerousWRMSR(seL4_Uint32 msr,seL4_Uint64 value)888 LIBSEL4_INLINE_FUNC void seL4_X86DangerousWRMSR(seL4_Uint32 msr, seL4_Uint64 value)
889 {
890 seL4_Uint32 value_low = value & 0xffffffff;
891 seL4_Uint32 value_high = value >> 32;
892 #ifdef CONFIG_KERNEL_MCS
893 /* MR1 doesn't get passed through MRs on CONFIG_KERNEL_MCS */
894 seL4_SetMR(1, value_high);
895 #endif
896 x86_sys_send(seL4_SysX86DangerousWRMSR, msr, 0, value_low, value_high);
897 }
seL4_X86DangerousRDMSR(seL4_Word msr)898 LIBSEL4_INLINE_FUNC seL4_Uint64 seL4_X86DangerousRDMSR(seL4_Word msr)
899 {
900 seL4_Word unused0 = 0;
901 seL4_Word unused1 = 0;
902 seL4_Word low, high;
903 x86_sys_recv(seL4_SysX86DangerousRDMSR, msr, &unused0, &unused1, &low, MCS_COND(0, &high));
904 #ifdef CONFIG_KERNEL_MCS
905 /* MR1 doesn't get passed through MRs on CONFIG_KERNEL_MCS */
906 high = seL4_GetMR(1);
907 #endif
908
909 return ((seL4_Uint64)low) | ((seL4_Uint64)high << 32);
910 }
911 #endif
912
913 #ifdef CONFIG_ENABLE_BENCHMARKS
seL4_BenchmarkResetLog(void)914 LIBSEL4_INLINE_FUNC seL4_Error seL4_BenchmarkResetLog(void)
915 {
916 seL4_Word unused0 = 0;
917 seL4_Word unused1 = 0;
918 LIBSEL4_UNUSED seL4_Word unused2 = 0;
919
920 seL4_Word ret;
921
922 x86_sys_send_recv(seL4_SysBenchmarkResetLog, 0, &ret, 0, &unused0, &unused1, MCS_COND(0, &unused2));
923
924 return (seL4_Error)ret;
925 }
926
seL4_BenchmarkFinalizeLog(void)927 LIBSEL4_INLINE_FUNC seL4_Word seL4_BenchmarkFinalizeLog(void)
928 {
929 seL4_Word unused0 = 0;
930 seL4_Word unused1 = 0;
931 LIBSEL4_UNUSED seL4_Word unused2 = 0;
932 seL4_Word index_ret;
933 x86_sys_send_recv(seL4_SysBenchmarkFinalizeLog, 0, &index_ret, 0, &unused0, &unused1, MCS_COND(0, &unused2));
934
935 return (seL4_Word)index_ret;
936 }
937
seL4_BenchmarkSetLogBuffer(seL4_Word frame_cptr)938 LIBSEL4_INLINE_FUNC seL4_Error seL4_BenchmarkSetLogBuffer(seL4_Word frame_cptr)
939 {
940 seL4_Word unused0 = 0;
941 seL4_Word unused1 = 0;
942 LIBSEL4_UNUSED seL4_Word unused2 = 0;
943
944 x86_sys_send_recv(seL4_SysBenchmarkSetLogBuffer, frame_cptr, &frame_cptr, 0, &unused0, &unused1, MCS_COND(0, &unused2));
945
946 return (seL4_Error) frame_cptr;
947 }
948
949
seL4_BenchmarkNullSyscall(void)950 LIBSEL4_INLINE_FUNC void seL4_BenchmarkNullSyscall(void)
951 {
952 x86_sys_null(seL4_SysBenchmarkNullSyscall);
953 asm volatile("" :::"%esi", "%edi", "memory");
954 }
955
seL4_BenchmarkFlushCaches(void)956 LIBSEL4_INLINE_FUNC void seL4_BenchmarkFlushCaches(void)
957 {
958 x86_sys_null(seL4_SysBenchmarkFlushCaches);
959 asm volatile("" :::"%esi", "%edi", "memory");
960 }
961
962 #ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
seL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr)963 LIBSEL4_INLINE_FUNC void seL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr)
964 {
965 seL4_Word unused0 = 0;
966 seL4_Word unused1 = 0;
967 seL4_Word unused2 = 0;
968 LIBSEL4_UNUSED seL4_Word unused3 = 0;
969
970 x86_sys_send_recv(seL4_SysBenchmarkGetThreadUtilisation, tcb_cptr, &unused0, 0, &unused1, &unused2, MCS_COND(0,
971 &unused3));
972 }
973
seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr)974 LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr)
975 {
976 seL4_Word unused0 = 0;
977 seL4_Word unused1 = 0;
978 seL4_Word unused2 = 0;
979 LIBSEL4_UNUSED seL4_Word unused3 = 0;
980
981 x86_sys_send_recv(seL4_SysBenchmarkResetThreadUtilisation, tcb_cptr, &unused0, 0, &unused1, &unused2, MCS_COND(0,
982 &unused3));
983 }
984
985 #ifdef CONFIG_DEBUG_BUILD
seL4_BenchmarkDumpAllThreadsUtilisation(void)986 LIBSEL4_INLINE_FUNC void seL4_BenchmarkDumpAllThreadsUtilisation(void)
987 {
988 seL4_Word unused0 = 0;
989 seL4_Word unused1 = 0;
990 seL4_Word unused2 = 0;
991 LIBSEL4_UNUSED seL4_Word unused3 = 0;
992
993 x86_sys_send_recv(seL4_SysBenchmarkDumpAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, MCS_COND(0,
994 &unused3));
995 }
996
seL4_BenchmarkResetAllThreadsUtilisation(void)997 LIBSEL4_INLINE_FUNC seL4_Word seL4_BenchmarkResetAllThreadsUtilisation(void)
998 {
999 seL4_Word unused0 = 0;
1000 seL4_Word unused1 = 0;
1001 seL4_Word unused2 = 0;
1002 LIBSEL4_UNUSED seL4_Word unused3 = 0;
1003
1004 x86_sys_send_recv(seL4_SysBenchmarkResetAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, MCS_COND(0,
1005 &unused3));
1006 }
1007
1008 #endif /* CONFIG_DEBUG_BUILD */
1009 #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
1010 #endif /* CONFIG_ENABLE_BENCHMARKS */
1011
1012 #ifdef CONFIG_SET_TLS_BASE_SELF
seL4_SetTLSBase(seL4_Word tls_base)1013 LIBSEL4_INLINE_FUNC void seL4_SetTLSBase(seL4_Word tls_base)
1014 {
1015 x86_sys_send_null(seL4_SysSetTLSBase, tls_base, 0);
1016 asm volatile("" ::: "memory");
1017 }
1018 #endif /* CONFIG_SET_TLS_BASE_SELF */
1019