blob: 2a26bc5b7bdcc662c3d1d75ea8cf85ad1182b7b7 [file] [log] [blame]
/*#
*#Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
*#
*#SPDX-License-Identifier: BSD-2-Clause
#*/
#include <sel4/sel4.h>
#include <camkes.h>
#include <camkes/msgqueue.h>
#include <camkes/msgqueue_template.h>
#include <camkes/virtqueue_template.h>
#include <virtqueue.h>
#include <utils/util.h>
/*- include 'seL4SharedData.template.c' -*/
/*# Do a sanity check to make sure there are no two senders #*/
/*- if len(me.parent.from_ends) != 1 -*/
/*? raise(Exception('MessageQueue for %s.%s is missing a sender or has more than one sender' % (me.instance.me, me.interface.name))) ?*/
/*- endif -*/
/*- set from_instance_name = me.parent.from_ends[0].instance.name -*/
/*- set from_interface_name = me.parent.from_ends[0].interface.name -*/
/*# Grab the notification, that the sender allocated or allocate it for the sender #*/
/*- set receiver_ntfn = alloc_obj('%s_%s_receiver_ntfn' % (from_instance_name, from_interface_name), seL4_NotificationObject) -*/
/*- set receiver_ntfn_cap = alloc_cap('%s_%s_receiver_ntfn_cap' % (from_instance_name, from_interface_name), receiver_ntfn, read=True, write=True, badge=1) -*/
/*- set type = macros.dataport_type(me.interface.type) -*/
/*- set type_size_macro = macros.dataport_size(me.interface.type) -*/
/*- set queue_id = configuration[me.instance.name].get("%s_id" % me.interface.name) -*/
/*- if queue_id is none or not isinstance(queue_id, six.integer_types) -*/
/*? raise(Exception('%s.%s_id must be set to a number and should be unique across seL4MessageQueue connections in an instance ' % (me.instance.name, me.interface.name))) ?*/
/*- endif -*/
/*- set queue_size = configuration[me.parent.name].get("queue_size", 128) -*/
/*- set virtqueue_length = 2 * queue_size -*/
static int _/*? me.interface.name ?*/_poll()
{
seL4_Word badge;
seL4_Poll(/*? receiver_ntfn_cap ?*/, &badge);
if (badge) {
return 1;
}
return 0;
}
static void _/*? me.interface.name ?*/_wait()
{
seL4_Wait(/*? receiver_ntfn_cap ?*/, NULL);
}
void /*? me.interface.name ?*/__init()
{
int error = 0;
error = camkes_msgqueue_channel_register_receiver(/*? queue_id ?*/,
/*? me.interface.name ?*/,
/*# TODO This isn't so resilient, maybe stash the name of the buffer? #*/
/*? virtqueue_length ?*/,
sizeof(/*? 'to_0_%s_data' % me.interface.name ?*/),
/*? type_size_macro ?*/,
_/*? me.interface.name ?*/_poll,
_/*? me.interface.name ?*/_wait);
if (error) {
assert(!"Failed to initialise the msgqueue for /*? me.instance.name ?*/./*? me.interface.name ?*/");
}
}