blob: e4bea42d715bbefab877d3bceb00c746cb666871 [file] [edit]
/*
* Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <string.h>
#include <sel4/sel4.h>
#include <camkes/tls.h>
#define FFI_SUCCESS 0
void fficamkes_declare_reply_cap(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr slot;
memcpy(&slot, a + 1, sizeof(slot));
camkes_declare_reply_cap(slot);
a[0] = FFI_SUCCESS;
}
void fficlear_tls_reply_cap_in_tcb(unsigned char *c, long clen, unsigned char *a, long alen) {
camkes_tls_t *tls = camkes_get_tls();
if (tls->reply_cap_in_tcb) {
tls->reply_cap_in_tcb = false;
a[1] = 1;
} else {
camkes_unprotect_reply_cap();
a[1] = 0;
}
a[0] = FFI_SUCCESS;
}
void ffiset_tls_cnode_cap(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr cnode;
memcpy(&cnode, a, sizeof(cnode));
camkes_get_tls()->cnode_cap = cnode;
a[0] = FFI_SUCCESS;
}
void ffiseL4_Recv(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr ep;
memcpy(&ep, a + 1, sizeof(ep));
seL4_Word badge;
seL4_MessageInfo_t info = seL4_Recv(ep, &badge);
seL4_Word len = seL4_MessageInfo_get_length(info) * sizeof(seL4_Word);
int offset = 1;
memcpy(a + offset, &len, sizeof(len));
offset += sizeof(len);
memcpy(a + offset, &badge, sizeof(badge));
offset += sizeof(badge);
memcpy(a + offset, &seL4_GetIPCBuffer()->msg[0], len);
a[0] = FFI_SUCCESS;
}
void ffiseL4_ReplyRecv(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr ep;
int offset = 1;
memcpy(&ep, a + offset, sizeof(ep));
offset += sizeof(ep);
seL4_Word len;
memcpy(&len, a + offset, sizeof(len));
offset += sizeof(len);
seL4_Word badge;
memcpy(&seL4_GetIPCBuffer()->msg[0], a + offset, len);
seL4_MessageInfo_t info = seL4_ReplyRecv(
ep,
seL4_MessageInfo_new(0, 0, 0, ROUND_UP_UNSAFE(len, sizeof(seL4_Word)) / sizeof(seL4_Word)),
&badge);
len = seL4_MessageInfo_get_length(info) * sizeof(seL4_Word);
offset = 1;
memcpy(a + offset, &len, sizeof(len));
offset += sizeof(len);
memcpy(a + offset, &badge, sizeof(badge));
offset += sizeof(badge);
memcpy(a + offset, &seL4_GetIPCBuffer()->msg[0], len);
a[0] = FFI_SUCCESS;
}
void ffiseL4_Send(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr ep;
int offset = 1;
memcpy(&ep, a + offset, sizeof(ep));
offset += sizeof(ep);
seL4_Word len;
memcpy(&len, a + offset, sizeof(len));
offset += sizeof(len);
memcpy(&seL4_GetIPCBuffer()->msg[0], a + offset, len);
seL4_Send(
ep,
seL4_MessageInfo_new(0, 0, 0, ROUND_UP_UNSAFE(len, sizeof(seL4_Word)) / sizeof(seL4_Word)));
a[0] = FFI_SUCCESS;
}
// Wait on an seL4 notification or endpoint
void ffiseL4_Wait(unsigned char *c, long clen, unsigned char *a, long alen) {
seL4_CPtr src;
memcpy(&src, a + 1, sizeof(src));
seL4_Word badge;
seL4_Wait(src, &badge);
memcpy(a + 1, &badge, sizeof(badge));
a[0] = FFI_SUCCESS;
}