1/*
2 * Copyright 2018, 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#include <string.h>
14#include <sel4/sel4.h>
15#include <camkes/tls.h>
16
17#define FFI_SUCCESS 0
18
19void fficamkes_declare_reply_cap(unsigned char *c, long clen, unsigned char *a, long alen) {
20    seL4_CPtr slot;
21    memcpy(&slot, a + 1, sizeof(slot));
22    camkes_declare_reply_cap(slot);
23    a[0] = FFI_SUCCESS;
24}
25
26void fficlear_tls_reply_cap_in_tcb(unsigned char *c, long clen, unsigned char *a, long alen) {
27    camkes_tls_t *tls = camkes_get_tls();
28    if (tls->reply_cap_in_tcb) {
29        tls->reply_cap_in_tcb = false;
30        a[1] = 1;
31    } else {
32        camkes_unprotect_reply_cap();
33        a[1] = 0;
34    }
35    a[0] = FFI_SUCCESS;
36}
37
38void ffiset_tls_cnode_cap(unsigned char *c, long clen, unsigned char *a, long alen) {
39    seL4_CPtr cnode;
40    memcpy(&cnode, a, sizeof(cnode));
41    camkes_get_tls()->cnode_cap = cnode;
42    a[0] = FFI_SUCCESS;
43}
44
45void ffiseL4_Recv(unsigned char *c, long clen, unsigned char *a, long alen) {
46    seL4_CPtr ep;
47    memcpy(&ep, a + 1, sizeof(ep));
48    seL4_Word badge;
49    seL4_MessageInfo_t info = seL4_Recv(ep, &badge);
50    seL4_Word len = seL4_MessageInfo_get_length(info) * sizeof(seL4_Word);
51    int offset = 1;
52	memcpy(a + offset, &len, sizeof(len));
53	offset += sizeof(len);
54    memcpy(a + offset, &badge, sizeof(badge));
55	offset += sizeof(badge);
56    memcpy(a + offset, &seL4_GetIPCBuffer()->msg[0], len);
57	a[0] = FFI_SUCCESS;
58}
59
60void ffiseL4_ReplyRecv(unsigned char *c, long clen, unsigned char *a, long alen) {
61    seL4_CPtr ep;
62    int offset = 1;
63    memcpy(&ep, a + offset, sizeof(ep));
64    offset += sizeof(ep);
65    seL4_Word len;
66    memcpy(&len, a + offset, sizeof(len));
67    offset += sizeof(len);
68    seL4_Word badge;
69    memcpy(&seL4_GetIPCBuffer()->msg[0], a + offset, len);
70    seL4_MessageInfo_t info = seL4_ReplyRecv(
71        ep,
72        seL4_MessageInfo_new(0, 0, 0, ROUND_UP_UNSAFE(len, sizeof(seL4_Word)) / sizeof(seL4_Word)),
73        &badge);
74    len = seL4_MessageInfo_get_length(info) * sizeof(seL4_Word);
75    offset = 1;
76    memcpy(a + offset, &len, sizeof(len));
77    offset += sizeof(len);
78    memcpy(a + offset, &badge, sizeof(badge));
79    offset += sizeof(badge);
80    memcpy(a + offset, &seL4_GetIPCBuffer()->msg[0], len);
81    a[0] = FFI_SUCCESS;
82}
83
84void ffiseL4_Send(unsigned char *c, long clen, unsigned char *a, long alen) {
85    seL4_CPtr ep;
86    int offset = 1;
87    memcpy(&ep, a + offset, sizeof(ep));
88    offset += sizeof(ep);
89    seL4_Word len;
90    memcpy(&len, a + offset, sizeof(len));
91    offset += sizeof(len);
92    memcpy(&seL4_GetIPCBuffer()->msg[0], a + offset, len);
93    seL4_Send(
94        ep,
95        seL4_MessageInfo_new(0, 0, 0, ROUND_UP_UNSAFE(len, sizeof(seL4_Word)) / sizeof(seL4_Word)));
96    a[0] = FFI_SUCCESS;
97}
98
99// Wait on an seL4 notification or endpoint
100void ffiseL4_Wait(unsigned char *c, long clen, unsigned char *a, long alen) {
101    seL4_CPtr src;
102    memcpy(&src, a + 1, sizeof(src));
103    seL4_Word badge;
104    seL4_Wait(src, &badge);
105    memcpy(a + 1, &badge, sizeof(badge));
106    a[0] = FFI_SUCCESS;
107}
108