1/** 2 * \file 3 * \brief 4 */ 5 6/* 7 * Copyright (c) 2015, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#ifndef ARCH_AARCH64_BARRELFISH_LMP_CHAN_H 16#define ARCH_AARCH64_BARRELFISH_LMP_CHAN_H 17 18#include <barrelfish/syscall_arch.h> 19#include <barrelfish/caddr.h> 20#include <barrelfish_kpi/lmp.h> 21#include <barrelfish_kpi/syscalls.h> 22 23/** 24 * \brief Send a message on the given LMP channel, if possible 25 * 26 * Non-blocking, may fail if there is no space in the receiver's endpoint. 27 * 28 * \param ep Remote endpoint cap 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 36lmp_ep_send( 37 struct capref ep, 38 lmp_send_flags_t flags, 39 struct capref send_cap, 40 uint8_t length_words, 41 uintptr_t arg1, 42 uintptr_t arg2, 43 uintptr_t arg3, 44 uintptr_t arg4 45 ) 46{ 47 uint8_t invoke_level = get_cap_level(ep); 48 capaddr_t invoke_cptr = get_cap_addr(ep); 49 50 uint8_t send_level = get_cap_level(send_cap); 51 capaddr_t send_cptr = get_cap_addr(send_cap); 52 53 assert(length_words <= LMP_MSG_LENGTH); 54 55 return syscall7((length_words << 28) | ((flags & 0xf) << 24) | 56 (invoke_level << 16) | (send_level << 8) | SYSCALL_INVOKE, 57 invoke_cptr, send_cptr, 58 arg1, arg2, arg3, arg4).error; 59} 60 61#define lmp_ep_send4(ep, flags, send_cap, a, b, c, d) \ 62 lmp_ep_send((ep), (flags), (send_cap), 4, (a), (b), (c), (d)) 63#define lmp_ep_send3(ep, flags, send_cap, a, b, c) \ 64 lmp_ep_send((ep), (flags), (send_cap), 3, (a), (b), (c), 0) 65#define lmp_ep_send2(ep, flags, send_cap, a, b) \ 66 lmp_ep_send((ep), (flags), (send_cap), 2, (a), (b), 0, 0) 67#define lmp_ep_send1(ep, flags, send_cap, a) \ 68 lmp_ep_send((ep), (flags), (send_cap), 1, (a), 0, 0, 0) 69#define lmp_ep_send0(ep, flags, send_cap) \ 70 lmp_ep_send((ep), (flags), (send_cap), 0, 0, 0, 0, 0) 71 72#define lmp_chan_send(lc, flags, send_cap, len, a, b, c, d) \ 73 lmp_ep_send((lc)->remote_cap, (flags), (send_cap), (len), (a), (b), (c), (d)) 74 75#define lmp_chan_send4(lc, flags, send_cap, a, b, c, d) \ 76 lmp_ep_send4((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d)) 77#define lmp_chan_send3(lc, flags, send_cap, a, b, c) \ 78 lmp_ep_send3((lc)->remote_cap, (flags), (send_cap), (a), (b), (c)) 79#define lmp_chan_send2(lc, flags, send_cap, a, b) \ 80 lmp_ep_send2((lc)->remote_cap, (flags), (send_cap), (a), (b)) 81#define lmp_chan_send1(lc, flags, send_cap, a) \ 82 lmp_ep_send1((lc)->remote_cap, (flags), (send_cap), (a)) 83#define lmp_chan_send0(lc, flags, send_cap) \ 84 lmp_ep_send0((lc)->remote_cap, (flags), (send_cap)) 85 86#endif 87