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_32_BARRELFISH_LMP_CHAN_H 16#define ARCH_X86_32_BARRELFISH_LMP_CHAN_H 17 18#include <barrelfish/syscall_arch.h> 19#include <barrelfish/caddr.h> 20#include <barrelfish_kpi/lmp.h> 21 22/** 23 * \brief Send a message on the given LMP channel, if possible 24 * 25 * Non-blocking, may fail if there is no space in the receiver's endpoint. 26 * 27 * \param ep Remote endpoint cap 28 * \param flags LMP send flags 29 * \param send_cap (Optional) capability to send with the message 30 * \param length_words Length of the message in words; payload beyond this 31 * size will not be delivered 32 * \param arg1..N Message payload 33 */ 34static inline errval_t lmp_ep_send(struct capref ep, lmp_send_flags_t flags, 35 struct capref send_cap, uint8_t length_words, 36 uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, 37 uintptr_t arg4) 38{ 39 uint8_t invoke_bits = get_cap_valid_bits(ep); 40 capaddr_t invoke_cptr = get_cap_addr(ep) >> (CPTR_BITS - invoke_bits); 41 42 uint8_t send_bits = get_cap_valid_bits(send_cap); 43 capaddr_t send_cptr = get_cap_addr(send_cap) >> (CPTR_BITS - send_bits); 44 45 assert(length_words <= LMP_MSG_LENGTH); 46 47 return syscall7((length_words << 28) | ((flags & 0xf) << 24) 48 | (invoke_bits << 16) | (send_bits << 8) | SYSCALL_INVOKE, 49 invoke_cptr, send_cptr, arg1, arg2, arg3, arg4).error; 50} 51 52#define lmp_ep_send4(ep, flags, send_cap, a, b, c, d) \ 53 lmp_ep_send((ep), (flags), (send_cap), 4, (a), (b), (c), (d)) 54#define lmp_ep_send3(ep, flags, send_cap, a, b, c) \ 55 lmp_ep_send((ep), (flags), (send_cap), 3, (a), (b), (c), 0) 56#define lmp_ep_send2(ep, flags, send_cap, a, b) \ 57 lmp_ep_send((ep), (flags), (send_cap), 2, (a), (b), 0, 0) 58#define lmp_ep_send1(ep, flags, send_cap, a) \ 59 lmp_ep_send((ep), (flags), (send_cap), 1, (a), 0, 0, 0) 60#define lmp_ep_send0(ep, flags, send_cap) \ 61 lmp_ep_send((ep), (flags), (send_cap), 0, 0, 0, 0, 0) 62 63#define lmp_chan_send(lc, flags, send_cap, len, a, b, c, d) \ 64 lmp_ep_send((lc)->remote_cap, (flags), (send_cap), (len), (a), (b), (c), (d)) 65 66#define lmp_chan_send4(lc, flags, send_cap, a, b, c, d) \ 67 lmp_ep_send4((lc)->remote_cap, (flags), (send_cap), (a), (b), (c), (d)) 68#define lmp_chan_send3(lc, flags, send_cap, a, b, c) \ 69 lmp_ep_send3((lc)->remote_cap, (flags), (send_cap), (a), (b), (c)) 70#define lmp_chan_send2(lc, flags, send_cap, a, b) \ 71 lmp_ep_send2((lc)->remote_cap, (flags), (send_cap), (a), (b)) 72#define lmp_chan_send1(lc, flags, send_cap, a) \ 73 lmp_ep_send1((lc)->remote_cap, (flags), (send_cap), (a)) 74#define lmp_chan_send0(lc, flags, send_cap) \ 75 lmp_ep_send0((lc)->remote_cap, (flags), (send_cap)) 76 77#endif 78