1/** 2 * \file 3 * \brief 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#ifndef ARCH_X86_64_BARRELFISH_LMP_CHAN_H 16#define ARCH_X86_64_BARRELFISH_LMP_CHAN_H 17 18#include <barrelfish/syscall_arch.h> 19#include <barrelfish/caddr.h> 20#include <barrelfish/cspace.h> 21#include <barrelfish_kpi/lmp.h> 22 23/** 24 * \brief Send a message on the given LMP endpoint, if possible 25 * 26 * Non-blocking, may fail if there is no space in the receiver's endpoint. 27 * 28 * \param ep Remote endpoint 29 * \param flags LMP send flags 30 * \param send_cap (Optional) capability to send with the message 31 * \param length_words Length of the message in words; payload beyond this 32 * size will not be delivered 33 * \param arg1..N Message payload 34 */ 35static inline errval_t lmp_ep_send(struct capref ep, lmp_send_flags_t flags, 36 struct capref send_cap, uint8_t length_words, 37 uint64_t arg1, uint64_t arg2, uint64_t arg3, 38 uint64_t arg4, uint64_t arg5, uint64_t arg6, 39 uint64_t arg7, uint64_t arg8, uint64_t arg9, 40 uint64_t arg10) 41{ 42 uint8_t send_level = get_cap_level(send_cap); 43 capaddr_t send_cptr = get_cap_addr(send_cap); 44 45 if(debug_notify_syscall) { 46 printf("memcached: lmp_ep_send while forbidden from %p, %p, %p\n", 47 __builtin_return_address(0), 48 __builtin_return_address(1), 49 __builtin_return_address(2)); 50 } 51 52#ifndef TRACE_DISABLE_LRPC 53 // Do an LRPC if possible 54 if (send_cptr == 0 && send_level == 0 // Not sending a cap 55 && (flags & LMP_FLAG_SYNC) != 0 // sync option 56 && length_words <= LRPC_MSG_LENGTH) { // Check length 57 58 assert(LRPC_MSG_LENGTH == 4); 59 assert(get_croot_addr(ep) == CPTR_ROOTCN); 60 return syscall6(SYSCALL_LRPC, get_cap_addr(ep), arg1, arg2, arg3, arg4).error; 61 } 62#endif 63 64 uint8_t invoke_level = get_cap_level(ep); 65 capaddr_t invoke_cptr = get_cap_addr(ep); 66 67 return syscall(SYSCALL_INVOKE, 68 (uint64_t)invoke_cptr << 32 | (uint64_t)send_level << 24 | 69 (uint64_t)invoke_level << 16 | (uint64_t)length_words << 8 | 70 flags, send_cptr, 71 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 72 arg10).error; 73} 74 75#define lmp_ep_send10(ep, flags, send_cap, a, b, c, d, e, f, g, h, i, j) \ 76 lmp_ep_send((ep), (flags), (send_cap), 10, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)) 77#define lmp_ep_send9(ep, flags, send_cap, a, b, c, d, e, f, g, h, i) \ 78 lmp_ep_send((ep), (flags), (send_cap), 9, (a), (b), (c), (d), (e), (f), (g), (h), (i), 0) 79#define lmp_ep_send8(ep, flags, send_cap, a, b, c, d, e, f, g, h) \ 80 lmp_ep_send((ep), (flags), (send_cap), 8, (a), (b), (c), (d), (e), (f), (g), (h), 0, 0) 81#define lmp_ep_send7(ep, flags, send_cap, a, b, c, d, e, f, g) \ 82 lmp_ep_send((ep), (flags), (send_cap), 7, (a), (b), (c), (d), (e), (f), (g), 0, 0, 0) 83#define lmp_ep_send6(ep, flags, send_cap, a, b, c, d, e, f) \ 84 lmp_ep_send((ep), (flags), (send_cap), 6, (a), (b), (c), (d), (e), (f), 0, 0, 0, 0) 85#define lmp_ep_send5(ep, flags, send_cap, a, b, c, d, e) \ 86 lmp_ep_send((ep), (flags), (send_cap), 5, (a), (b), (c), (d), (e), 0, 0, 0, 0, 0) 87#define lmp_ep_send4(ep, flags, send_cap, a, b, c, d) \ 88 lmp_ep_send((ep), (flags), (send_cap), 4, (a), (b), (c), (d), 0, 0, 0, 0, 0, 0) 89#define lmp_ep_send3(ep, flags, send_cap, a, b, c) \ 90 lmp_ep_send((ep), (flags), (send_cap), 3, (a), (b), (c), 0, 0, 0, 0, 0, 0, 0) 91#define lmp_ep_send2(ep, flags, send_cap, a, b) \ 92 lmp_ep_send((ep), (flags), (send_cap), 2, (a), (b), 0, 0, 0, 0, 0, 0, 0, 0) 93#define lmp_ep_send1(ep, flags, send_cap, a) \ 94 lmp_ep_send((ep), (flags), (send_cap), 1, (a), 0, 0, 0, 0, 0, 0, 0, 0, 0) 95#define lmp_ep_send0(ep, flags, send_cap) \ 96 lmp_ep_send((ep), (flags), (send_cap), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 97 98#define lmp_chan_send(lc, flags, send_cap, len, a, b, c, d, e, f, g, h, i, j) \ 99 lmp_ep_send((lc)->remote_cap, (flags), (send_cap), (len), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)) 100 101#define lmp_chan_send10(lc, flags, send_cap, a, b, c, d, e, f, g, h, i, j) \ 102 lmp_ep_send10((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)) 103#define lmp_chan_send9(lc, flags, send_cap, a, b, c, d, e, f, g, h, i) \ 104 lmp_ep_send9((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e), (f), (g), (h), (i)) 105#define lmp_chan_send8(lc, flags, send_cap, a, b, c, d, e, f, g, h) \ 106 lmp_ep_send8((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e), (f), (g), (h)) 107#define lmp_chan_send7(lc, flags, send_cap, a, b, c, d, e, f, g) \ 108 lmp_ep_send7((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e), (f), (g)) 109#define lmp_chan_send6(lc, flags, send_cap, a, b, c, d, e, f) \ 110 lmp_ep_send6((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e), (f)) 111#define lmp_chan_send5(lc, flags, send_cap, a, b, c, d, e) \ 112 lmp_ep_send5((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d), (e)) 113#define lmp_chan_send4(lc, flags, send_cap, a, b, c, d) \ 114 lmp_ep_send4((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d)) 115#define lmp_chan_send3(lc, flags, send_cap, a, b, c) \ 116 lmp_ep_send3((lc)->remote_cap, (flags), (send_cap), (a), (b), (c)) 117#define lmp_chan_send2(lc, flags, send_cap, a, b) \ 118 lmp_ep_send2((lc)->remote_cap, (flags), (send_cap), (a), (b)) 119#define lmp_chan_send1(lc, flags, send_cap, a) \ 120 lmp_ep_send1((lc)->remote_cap, (flags), (send_cap), (a)) 121#define lmp_chan_send0(lc, flags, send_cap) \ 122 lmp_ep_send0((lc)->remote_cap, (flags), (send_cap)) 123 124#endif // ARCH_X86_64_BARRELFISH_LMP_CHAN_H 125