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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef ARCH_ARM_BARRELFISH_LMP_CHAN_H
16#define ARCH_ARM_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    uintptr_t arg5,
46    uintptr_t arg6,
47    uintptr_t arg7,
48    uintptr_t arg8,
49    uintptr_t arg9
50    )
51{
52    enum cnode_type invoke_level = get_cap_level(ep);
53    capaddr_t invoke_cptr = get_cap_addr(ep);
54
55    enum cnode_type send_level = get_cap_level(send_cap);
56    capaddr_t send_cptr = get_cap_addr(send_cap);
57
58    assert(length_words <= LMP_MSG_LENGTH);
59
60    return syscall12((length_words << 28) | ((flags & 0xf) << 24) |
61                     (invoke_level << 16) | (send_level << 8) | SYSCALL_INVOKE,
62                     invoke_cptr, send_cptr,
63                     arg1, arg2, arg3,
64                     arg4, arg5, arg6,
65                     arg7, arg8, arg9).error;
66}
67
68#define lmp_ep_send9(ep, flags, send_cap, a, b, c, d, e, f, g, h, i)   \
69    lmp_ep_send((ep),(flags),(send_cap),9,(a),(b),(c),(d),(e),(f),(g),(h),(i))
70#define lmp_ep_send8(ep, flags, send_cap, a, b, c, d, e, f, g, h, i)    \
71    lmp_ep_send((ep),(flags),(send_cap),8,(a),(b),(c),(d),(e),(f),(g),(h),0)
72#define lmp_ep_send7(ep, flags, send_cap, a, b, c, d, e, f, g)          \
73    lmp_ep_send((ep),(flags),(send_cap),7,(a),(b),(c),(d),(e),(f),(g),0,0)
74#define lmp_ep_send6(ep,flags,send_cap,a,b,c,d,e,f)                     \
75    lmp_ep_send((ep),(flags),(send_cap),6,(a),(b),(c),(d),(e),(f),0,0,0)
76#define lmp_ep_send5(ep,flags,send_cap,a,b,c,d,e)                       \
77    lmp_ep_send((ep),(flags),(send_cap),5,(a),(b),(c),(d),(e),0,0,0,0)
78#define lmp_ep_send4(ep,flags,send_cap,a,b,c,d)                         \
79    lmp_ep_send((ep),(flags),(send_cap),4,(a),(b),(c),(d),0,0,0,0,0)
80#define lmp_ep_send3(ep,flags,send_cap,a,b,c)                           \
81    lmp_ep_send((ep),(flags),(send_cap),3,(a),(b),(c),0,0,0,0,0,0)
82#define lmp_ep_send2(ep,flags,send_cap,a,b)                             \
83    lmp_ep_send((ep),(flags),(send_cap),2,(a),(b),0,0,0,0,0,0,0)
84#define lmp_ep_send1(ep,flags,send_cap,a)                               \
85    lmp_ep_send((ep),(flags),(send_cap),1,(a),0,0,0,0,0,0,0,0)
86#define lmp_ep_send0(ep,flags,send_cap)                                 \
87    lmp_ep_send((ep),(flags),(send_cap),0,0,0,0,0,0,0,0,0,0)
88
89#define lmp_chan_send(lc,flags,send_cap,len,a,b,c,d,e,f,g,h,i)          \
90    lmp_ep_send((lc)->remote_cap,(flags),(send_cap),(len),              \
91                (a),(b),(c),(d),(e),(f),(g),(h),(i))
92
93#define lmp_chan_send9(lc,flags,send_cap,a,b,c,d,e,f,g,h,i)             \
94    lmp_ep_send9((lc)->remote_cap,(flags),(send_cap),                   \
95                 (a),(b),(c),(d),(e),(f),(g),(h),(i))
96#define lmp_chan_send8(lc,flags,send_cap,a,b,c,d,e,f,g,h)               \
97    lmp_ep_send8((lc)->remote_cap,(flags),(send_cap),                   \
98                 (a),(b),(c),(d),(e),(f),(g),(h))
99#define lmp_chan_send7(lc,flags,send_cap,a,b,c,d,e,f,g)                 \
100    lmp_ep_send7((lc)->remote_cap,(flags),(send_cap),                   \
101                 (a),(b),(c),(d),(e),(f),(g))
102#define lmp_chan_send6(lc,flags,send_cap,a,b,c,d,e,f)                   \
103    lmp_ep_send6((lc)->remote_cap,(flags),(send_cap),                   \
104                 (a),(b),(c),(d),(e),(f))
105#define lmp_chan_send5(lc,flags,send_cap,a,b,c,d,e)                     \
106    lmp_ep_send5((lc)->remote_cap,(flags),(send_cap),                   \
107                 (a),(b),(c),(d),(e))
108#define lmp_chan_send4(lc,flags,send_cap,a,b,c,d)                       \
109    lmp_ep_send4((lc)->remote_cap,(flags),(send_cap), (a),(b),(c),(d))
110#define lmp_chan_send3(lc,flags,send_cap,a,b,c)                         \
111    lmp_ep_send3((lc)->remote_cap,(flags),(send_cap), (a),(b),(c))
112#define lmp_chan_send2(lc,flags,send_cap,a,b)                           \
113    lmp_ep_send2((lc)->remote_cap,(flags),(send_cap), (a),(b))
114#define lmp_chan_send1(lc,flags,send_cap,a)                             \
115    lmp_ep_send1((lc)->remote_cap,(flags),(send_cap),(a))
116#define lmp_chan_send0(lc,flags,send_cap)                               \
117    lmp_ep_send0((lc)->remote_cap,(flags),(send_cap))
118
119#endif
120