1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#ifndef __LIBSEL4_SEL4_SEL4_ARCH_SYSCALLS_H_ 14#define __LIBSEL4_SEL4_SEL4_ARCH_SYSCALLS_H_ 15 16#include <autoconf.h> 17#include <sel4/arch/functions.h> 18#include <sel4/types.h> 19 20/* 21 * To simplify the definition of the various seL4 syscalls/syscall-wrappers we define 22 * some helper assembly functions. These functions are designed to cover the different 23 * cases of sending/receiving data in registers to/from the kernel. The most 'complex' 24 * version is arm_sys_send_recv, and all other functions are limited versions that allow 25 * for registers to not be unnecessarily clobbered 26 * 27 * arm_sys_send: Fills all registers into the kernel, expects nothing to be sent back 28 * by the kernel. Used for direction one way sends that contain data (e.g. seL4_Send, 29 * seL4_NBSend) 30 * 31 * arm_sys_send_null: Only fills metadata registers into the kernel (skips message 32 * registers). Expects nothing to be sent back by the kernel. Used by directional 33 * one way sends that do not contain data (e.g. seL4_Notify) 34 * 35 * arm_sys_recv: Sends one register (destination) to the kernel and expects all 36 * registers to be returned by the kernel. Used for directed receives that return 37 * data (e.g. seL4_Recv) 38 * 39 * arm_sys_send_recv: Fills all registers into the kernel and expects all of them 40 * to be filled on return by the kernel. Used for directed send+receives 41 * where data flows both directions (e.g. seL4_Call, seL4_ReplyWait) 42 * 43 * arm_sys_nbsend_recv: Fills all registers into the kernel and expects all of them 44 * to be filled on return by the kernel. Used for directed send+receives 45 * where data flows both directions on separate caps (e.g. seL4_NBSendRecv) 46 * 47 * arm_sys_null: Does not send any registers to the kernel or expect anything to 48 * be returned from the kernel. Used to trigger implicit kernel actions without 49 * any data (e.g. seL4_Yield) 50 */ 51 52static inline void 53arm_sys_send(seL4_Word sys, seL4_Word dest, seL4_Word info_arg, seL4_Word mr0, seL4_Word mr1, seL4_Word mr2, seL4_Word mr3) 54{ 55 register seL4_Word destptr asm("x0") = dest; 56 register seL4_Word info asm("x1") = info_arg; 57 58 /* Load beginning of the message into registers. */ 59 register seL4_Word msg0 asm("x2") = mr0; 60 register seL4_Word msg1 asm("x3") = mr1; 61 register seL4_Word msg2 asm("x4") = mr2; 62 register seL4_Word msg3 asm("x5") = mr3; 63 64 /* Perform the system call. */ 65 register seL4_Word scno asm("x7") = sys; 66 asm volatile ( 67 "svc #0" 68 : "+r" (destptr), "+r" (msg0), "+r" (msg1), "+r" (msg2), 69 "+r" (msg3), "+r" (info) 70 : "r"(scno) 71 ); 72} 73 74static inline void 75arm_sys_send_null(seL4_Word sys, seL4_Word src, seL4_Word info_arg) 76{ 77 register seL4_Word destptr asm("x0") = src; 78 register seL4_Word info asm("x1") = info_arg; 79 80 /* Perform the system call. */ 81 register seL4_Word scno asm("x7") = sys; 82 asm volatile ( 83 "svc #0" 84 : "+r" (destptr), "+r" (info) 85 : "r"(scno) 86 ); 87} 88 89static inline void 90arm_sys_recv(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word *out_info, seL4_Word *out_mr0, seL4_Word *out_mr1, seL4_Word *out_mr2, seL4_Word *out_mr3, seL4_Word reply) 91{ 92 register seL4_Word src_and_badge asm("x0") = src; 93 register seL4_Word info asm("x1"); 94 95 /* Incoming message registers. */ 96 register seL4_Word msg0 asm("x2"); 97 register seL4_Word msg1 asm("x3"); 98 register seL4_Word msg2 asm("x4"); 99 register seL4_Word msg3 asm("x5"); 100 register seL4_Word reply_reg asm("x6") = reply; 101 102 /* Perform the system call. */ 103 register seL4_Word scno asm("x7") = sys; 104 asm volatile ( 105 "svc #0" 106 : "=r" (msg0), "=r" (msg1), "=r" (msg2), "=r" (msg3), 107 "=r" (info), "+r" (src_and_badge) 108 : "r"(scno), "r" (reply_reg) 109 : "memory" 110 ); 111 *out_badge = src_and_badge; 112 *out_info = info; 113 *out_mr0 = msg0; 114 *out_mr1 = msg1; 115 *out_mr2 = msg2; 116 *out_mr3 = msg3; 117} 118 119static inline void 120arm_sys_send_recv(seL4_Word sys, seL4_Word dest, seL4_Word *out_badge, seL4_Word info_arg, seL4_Word *out_info, seL4_Word *in_out_mr0, seL4_Word *in_out_mr1, seL4_Word *in_out_mr2, seL4_Word *in_out_mr3, seL4_Word reply) 121{ 122 register seL4_Word destptr asm("x0") = dest; 123 register seL4_Word info asm("x1") = info_arg; 124 125 /* Load beginning of the message into registers. */ 126 register seL4_Word msg0 asm("x2") = *in_out_mr0; 127 register seL4_Word msg1 asm("x3") = *in_out_mr1; 128 register seL4_Word msg2 asm("x4") = *in_out_mr2; 129 register seL4_Word msg3 asm("x5") = *in_out_mr3; 130 register seL4_Word reply_reg asm("x6") = reply; 131 132 /* Perform the system call. */ 133 register seL4_Word scno asm("x7") = sys; 134 asm volatile ( 135 "svc #0" 136 : "+r" (msg0), "+r" (msg1), "+r" (msg2), "+r" (msg3), 137 "+r" (info), "+r" (destptr) 138 : "r"(scno), "r" (reply_reg) 139 : "memory" 140 ); 141 *out_info = info; 142 *out_badge = destptr; 143 *in_out_mr0 = msg0; 144 *in_out_mr1 = msg1; 145 *in_out_mr2 = msg2; 146 *in_out_mr3 = msg3; 147} 148 149static inline void 150arm_sys_nbsend_recv(seL4_Word sys, seL4_Word dest, seL4_Word src, seL4_Word *out_badge, seL4_Word info_arg, 151 seL4_Word *out_info, seL4_Word *in_out_mr0, seL4_Word *in_out_mr1, seL4_Word *in_out_mr2, 152 seL4_Word *in_out_mr3, seL4_Word reply) 153{ 154 register seL4_Word src_and_badge asm("x0") = src; 155 register seL4_Word info asm("x1") = info_arg; 156 157 /* Load the beginning of the message info registers */ 158 register seL4_Word msg0 asm("x2") = *in_out_mr0; 159 register seL4_Word msg1 asm("x3") = *in_out_mr1; 160 register seL4_Word msg2 asm("x4") = *in_out_mr2; 161 register seL4_Word msg3 asm("x5") = *in_out_mr3; 162 163 register seL4_Word reply_reg asm("x6") = reply; 164 register seL4_Word dest_reg asm("x8") = dest; 165 166 /* Perform the system call. */ 167 register seL4_Word scno asm("x7") = sys; 168 asm volatile ( 169 "svc #0" 170 : "+r" (msg0), "+r" (msg1), "+r" (msg2), "+r" (msg3), 171 "+r" (src_and_badge), "+r" (info) 172 : "r" (scno), "r" (reply_reg), "r" (dest_reg) 173 : "memory" 174 ); 175 176 *out_badge = src_and_badge; 177 *out_info = info; 178 *in_out_mr0 = msg0; 179 *in_out_mr1 = msg1; 180 *in_out_mr2 = msg2; 181 *in_out_mr3 = msg3; 182} 183 184 185static inline void 186arm_sys_null(seL4_Word sys) 187{ 188 register seL4_Word scno asm("x7") = sys; 189 asm volatile ( 190 "svc #0" 191 : /* no outputs */ 192 : "r"(scno) 193 ); 194} 195 196#endif /* __LIBSEL4_SEL4_SEL4_ARCH_SYSCALLS_H_ */ 197