cantrip: add cantripRPCSignalOverMultiSharedData

A variant of cantripRPCOverMultiSharedData that supports signalling.

Change-Id: Idb2b3f053a735cf51e52fb61c03e8d9fdb999619
diff --git a/camkes/templates/cantripRPCSignalOverMultiSharedData-from.template.rs b/camkes/templates/cantripRPCSignalOverMultiSharedData-from.template.rs
new file mode 100644
index 0000000..f205973
--- /dev/null
+++ b/camkes/templates/cantripRPCSignalOverMultiSharedData-from.template.rs
@@ -0,0 +1,62 @@
+/*#
+ *#Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *#
+ *#SPDX-License-Identifier: BSD-2-Clause
+  #*/
+
+/*- set suffix = "_buf" -*/
+
+/*# Assign client ids and badges #*/
+/*- set badges = namespace() -*/
+/*- if client_ids is not undefined -*/
+    /*- set badges.badges = client_ids.badges -*/
+/*- else -*/
+    /*- from 'rpc-connector.c' import allocate_badges with context -*/
+    /*- do allocate_badges(badges) -*/
+/*- endif -*/
+/*- set client_id = badges.badges[me.parent.from_ends.index(me)] -*/
+
+/*- if suffix is not defined -*/
+  /*- set suffix = '' -*/
+/*- endif -*/
+
+/*- set shmem_size = configuration[me.instance.name].get("%s_shmem_size" % me.interface.name, 4096) -*/
+/*- set shmem_section = '%s' % me.interface.name -*/
+/*- set shmem_symbol = '%s_INTERFACE_DATA' % me.interface.name.upper() -*/
+/*- set shmem_name = '%s%s' % (me.interface.name, suffix) -*/
+/*- set page_size = macros.get_page_size(shmem_size, options.architecture) -*/
+/*- if page_size == 0 -*/
+  /*? raise(TemplateError('Setting %s.%s_shmem_size does not meet minimum size and alignment requirements. %d must be at least %d and %d aligned' % (me.instance.name, me.interface.name, size, 4096, 4096))) ?*/
+/*- endif -*/
+
+/*? macros.shared_buffer_symbol(sym=shmem_symbol, shmem_size=shmem_size, page_size=page_size, language='rust') ?*/
+#[no_mangle]
+pub fn /*? me.interface.name ?*/_interface_shared_buffer_mut() -> &'static mut [u8] {
+    unsafe { &mut /*? shmem_symbol ?*/.data[..] }
+}
+#[no_mangle]
+pub fn /*? me.interface.name ?*/_interface_shared_buffer() -> &'static [u8] {
+    unsafe { &/*? shmem_symbol ?*/.data[..] }
+}
+/*? register_shared_variable('%s_%s_data' % (me.parent.name, client_id), shmem_symbol, shmem_size, frame_size=page_size, language='rust') ?*/
+
+/*- from 'rpc-connector.c' import establish_from_rpc with context -*/
+
+/*- set connector = namespace() -*/
+/*- set shmem_size = configuration[me.instance.name].get("%s_shmem_size" % me.interface.name, 4096) -*/
+
+/*- set lock = True -*/
+/*? establish_from_rpc(connector, buffer=('((void*)%s%s)' % (me.interface.name, suffix), shmem_size, lock), language='rust') ?*/
+
+/*- set prefix = me.interface.name.upper() -*/
+#[no_mangle]
+pub static /*? prefix ?*/_INTERFACE_ENDPOINT: sel4_sys::seL4_CPtr = /*? connector.ep ?*/;
+
+/*? assert(isinstance(connector, namespace)) ?*/
+/*- set interface = me.interface.name -*/
+/*- from 'global-endpoint.template.c' import allocate_cap with context -*/
+/*- do allocate_cap(me, is_reader=True) -*/
+#[no_mangle]
+pub static /*? prefix ?*/_INTERFACE_NOTIFICATION: sel4_sys::seL4_CPtr = /*? pop('notification') ?*/;
+#[no_mangle]
+pub static /*? prefix ?*/_INTERFACE_NOTIFICATION_BADGE: sel4_sys::seL4_CPtr = /*? pop('badge') ?*/;
diff --git a/camkes/templates/cantripRPCSignalOverMultiSharedData-to.template.rs b/camkes/templates/cantripRPCSignalOverMultiSharedData-to.template.rs
new file mode 100644
index 0000000..a90ee21
--- /dev/null
+++ b/camkes/templates/cantripRPCSignalOverMultiSharedData-to.template.rs
@@ -0,0 +1,84 @@
+/*#
+ *#Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *#
+ *#SPDX-License-Identifier: BSD-2-Clause
+  #*/
+
+/*# Assign client ids and badges #*/
+/*- set badges = namespace() -*/
+/*- if client_ids is not undefined -*/
+    /*- set badges.badges = client_ids.badges -*/
+/*- else -*/
+    /*- from 'rpc-connector.c' import allocate_badges with context -*/
+    /*- do allocate_badges(badges) -*/
+/*- endif -*/
+/*- set badges = badges.badges -*/
+
+/*- from 'global-endpoint.template.c' import allocate_cap with context -*/
+
+#[no_mangle]
+pub fn /*? me.interface.name ?*/_emit(badge: sel4_sys::seL4_Word) {
+    match badge {
+    /*- for (i, c) in enumerate(me.parent.from_ends) -*/
+        /*- do allocate_cap(c, is_reader=False) -*/
+        /*- set notification = pop('notification') -*/
+        /*? badges[i] ?*/ => unsafe { sel4_sys::seL4_Signal(/*? notification ?*/) },
+    /*- endfor -*/
+        _ => unreachable!(),
+    }
+}
+
+/*# Enumerate all the incoming interfaces #*/
+/*- set shmems = [] -*/
+/*- set client_ids = set() -*/
+/*- for c in me.parent.from_ends -*/
+
+    /*- set client_id = badges[loop.index0] -*/
+
+    /*- if client_id not in client_ids -*/
+        /*- do client_ids.add(client_id) -*/
+
+        /*- set shmem_size = configuration[c.instance.name].get("%s_shmem_size" % c.interface.name, 4096) -*/
+        /*- set shmem_section = '%s_%s' % (me.interface.name.upper(), client_id) -*/
+        /*- set shmem_symbol = '%s_%s_DATA' % (me.interface.name.upper(), client_id) -*/
+        /*- set shmem_name = "%s_buf_%s" % (me.interface.name, client_id) -*/
+        /*- set page_size = macros.get_page_size(shmem_size, options.architecture) -*/
+        /*- if page_size == 0 -*/
+          /*? raise(TemplateError('Setting %s.%s_shmem_size does not meet minimum size and alignment requirements. %d must be at least %d and %d aligned' % (c.instance.name, c.interface.name, size, 4096, 4096))) ?*/
+        /*- endif -*/
+        /*- set page_size_bits = int(math.log(page_size, 2)) -*/
+
+        /*? macros.shared_buffer_symbol(sym=shmem_symbol, shmem_size=shmem_size, page_size=page_size, language='rust') ?*/
+        /*? register_shared_variable('%s_%s_data' % (me.parent.name, client_id), shmem_symbol, shmem_size, frame_size=page_size, language='rust') ?*/
+
+        /*- do shmems.append((shmem_symbol, client_id, shmem_size)) -*/
+    /*- else -*/
+        /* skipping /*? client_id ?*/ */
+    /*- endif -*/
+
+/*- endfor -*/
+
+
+pub fn /*? me.interface.name ?*/_interface_recv_buffer(
+    badge: sel4_sys::seL4_Word,
+) -> &'static mut [u8] {
+    match badge {
+    /*- for symbol, id, _ in shmems -*/
+        /*? id ?*/ => unsafe { &mut /*? symbol.upper() ?*/.data[..] },
+    /*- endfor -*/
+        _ => unreachable!(),
+    }
+}
+
+
+/*- from 'rpc-connector.c' import establish_recv_rpc with context -*/
+
+/*- set connector = namespace() -*/
+
+/*? establish_recv_rpc(connector, me.interface.name, buffer=('(%s_buf(%s_get_sender_id()))' % (me.interface.name,me.interface.name) , '(%s_buf_size(%s_get_sender_id()))' % (me.interface.name,me.interface.name)), language='rust') ?*/
+
+/*- set prefix = me.interface.name.upper() -*/
+#[no_mangle]
+pub static /*? prefix ?*/_INTERFACE_ENDPOINT: sel4_sys::seL4_CPtr = /*? connector.ep ?*/;
+#[no_mangle]
+pub static /*? prefix ?*/_INTERFACE_REPLY: sel4_sys::seL4_CPtr = /*? connector.reply_cap_slot ?*/;
diff --git a/camkes/templates/templates.cmake b/camkes/templates/templates.cmake
index df21c4b..2f95eb4 100644
--- a/camkes/templates/templates.cmake
+++ b/camkes/templates/templates.cmake
@@ -61,6 +61,7 @@
     cantripRPCCall
     cantripRPCCallSignal
     cantripRPCOverMultiSharedData
+    cantripRPCSignalOverMultiSharedData
 )
     DeclareCAmkESConnector(
         ${connector}
diff --git a/include/builtin/std_connector.camkes b/include/builtin/std_connector.camkes
index 0eb252f..6234109 100644
--- a/include/builtin/std_connector.camkes
+++ b/include/builtin/std_connector.camkes
@@ -355,3 +355,14 @@
     from Procedures with 0 threads;
     to Procedure;
 }
+
+/**
+ * cantripRPCSignalOverMultiSharedData connector
+ *
+ * Combination of cantripRPCOverMultiSharedData & cantripRPCCallSignal.
+ */
+connector cantripRPCSignalOverMultiSharedData {
+    from Procedures with 0 threads;
+    to Procedure;
+    attribute bool from_global_endpoint = True;
+}