1/*# 2 *#Copyright 2019, 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 <sel4/sel4.h> 14#include <camkes.h> 15#include <camkes/msgqueue.h> 16#include <camkes/msgqueue_template.h> 17#include <camkes/virtqueue_template.h> 18#include <virtqueue.h> 19#include <utils/util.h> 20 21/*- include 'seL4SharedData.template.c' -*/ 22 23/*# Do a sanity check to make sure there are no two senders #*/ 24/*- if len(me.parent.from_ends) != 1 -*/ 25 /*? raise(Exception('MessageQueue for %s.%s is missing a sender or has more than one sender' % (me.instance.me, me.interface.name))) ?*/ 26/*- endif -*/ 27 28/*- set from_instance_name = me.parent.from_ends[0].instance.name -*/ 29/*- set from_interface_name = me.parent.from_ends[0].interface.name -*/ 30 31/*# Grab the notification, that the sender allocated or allocate it for the sender #*/ 32/*- set receiver_ntfn = alloc_obj('%s_%s_receiver_ntfn' % (from_instance_name, from_interface_name), seL4_NotificationObject) -*/ 33/*- 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) -*/ 34 35/*- set type = macros.dataport_type(me.interface.type) -*/ 36/*- set type_size_macro = macros.dataport_size(me.interface.type) -*/ 37 38/*- set queue_id = configuration[me.instance.name].get("%s_id" % me.interface.name) -*/ 39/*- if queue_id is none or not isinstance(queue_id, six.integer_types) -*/ 40 /*? 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))) ?*/ 41/*- endif -*/ 42 43/*- set queue_size = configuration[me.parent.name].get("queue_size", 128) -*/ 44/*- set virtqueue_length = 2 * queue_size -*/ 45 46static int _/*? me.interface.name ?*/_poll() 47{ 48 seL4_Word badge; 49 seL4_Poll(/*? receiver_ntfn_cap ?*/, &badge); 50 if (badge) { 51 return 1; 52 } 53 return 0; 54} 55 56static void _/*? me.interface.name ?*/_wait() 57{ 58 seL4_Wait(/*? receiver_ntfn_cap ?*/, NULL); 59} 60 61void /*? me.interface.name ?*/__init() 62{ 63 int error = 0; 64 error = camkes_msgqueue_channel_register_receiver(/*? queue_id ?*/, 65 /*? me.interface.name ?*/, 66 /*# TODO This isn't so resilient, maybe stash the name of the buffer? #*/ 67 /*? virtqueue_length ?*/, 68 sizeof(/*? 'to_0_%s_data' % me.interface.name ?*/), 69 /*? type_size_macro ?*/, 70 _/*? me.interface.name ?*/_poll, 71 _/*? me.interface.name ?*/_wait); 72 if (error) { 73 assert(!"Failed to initialise the msgqueue for /*? me.instance.name ?*/./*? me.interface.name ?*/"); 74 } 75} 76