ql-tipc: SMP support

Add trusty_dev_nop that secondary CPUs can call to enter trusty. Add an
argument to the idle callbaks to specify that it is called after
trusty_ipc_poll_for_event returned TRUSTY_EVENT_NONE. In this case the
the idle call needs to abort if a secondary CPU (any CPU other than the
CPU that is waiting for a message) has entered idle since the last such
call.

Bug: 116851819
Change-Id: I59579209e9eb52be345b1284f89676810ab425f0
diff --git a/ql-tipc/arch/arm/trusty_dev.c b/ql-tipc/arch/arm/trusty_dev.c
index b463c5e..d66b9ca 100644
--- a/ql-tipc/arch/arm/trusty_dev.c
+++ b/ql-tipc/arch/arm/trusty_dev.c
@@ -138,7 +138,7 @@
         if ((int)ret != SM_ERR_BUSY)
             break;
 
-        trusty_idle(dev);
+        trusty_idle(dev, false);
     }
 
     return ret;
@@ -166,7 +166,7 @@
         trusty_debug("%s(0x%x 0x%x 0x%x 0x%x) interrupted\n", __func__, smcnr,
                      a0, a1, a2);
         if (ret == SM_ERR_CPU_IDLE) {
-            trusty_idle(dev);
+            trusty_idle(dev, false);
         }
         ret = trusty_std_call_helper(dev, SMC_SC_RESTART_LAST, 0, 0, 0);
     }
@@ -253,3 +253,8 @@
     dev->priv_data = NULL;
     return 0;
 }
+
+int trusty_dev_nop(struct trusty_dev* dev) {
+    int ret = trusty_std_call32(dev, SMC_SC_NOP, 0, 0, 0);
+    return ret == SM_ERR_NOP_DONE ? 0 : -1;
+}
diff --git a/ql-tipc/examples/u-boot/sysdeps_uboot.c b/ql-tipc/examples/u-boot/sysdeps_uboot.c
index 742ea61..140af1a 100644
--- a/ql-tipc/examples/u-boot/sysdeps_uboot.c
+++ b/ql-tipc/examples/u-boot/sysdeps_uboot.c
@@ -42,7 +42,7 @@
     enable_interrupts();
 }
 
-void trusty_idle(struct trusty_dev* dev) {
+void trusty_idle(struct trusty_dev* dev, bool event_poll) {
     wfi();
 }
 
diff --git a/ql-tipc/include/trusty/sysdeps.h b/ql-tipc/include/trusty/sysdeps.h
index f27f618..3ba214b 100644
--- a/ql-tipc/include/trusty/sysdeps.h
+++ b/ql-tipc/include/trusty/sysdeps.h
@@ -70,8 +70,14 @@
  * Put in standby state waiting for interrupt.
  *
  * @dev: Trusty device initialized with trusty_dev_init
+ * @event_poll: If true this function is entered after trusty_ipc_poll_for_event
+ *              returned TRUSTY_EVENT_NONE. In this case this call needs to
+ *              return without waiting for another interrupt if a secondary CPU
+ *              (any CPU other than the CPU that is waiting for a message) has
+ *              entered idle since the last such call. If there is only one CPU
+ *              calling into trusty this argument can be ignored.
  */
-void trusty_idle(struct trusty_dev* dev);
+void trusty_idle(struct trusty_dev* dev, bool event_poll);
 /*
  * Aborts the program or reboots the device.
  */
diff --git a/ql-tipc/include/trusty/trusty_dev.h b/ql-tipc/include/trusty/trusty_dev.h
index 889ea33..2f02087 100644
--- a/ql-tipc/include/trusty/trusty_dev.h
+++ b/ql-tipc/include/trusty/trusty_dev.h
@@ -50,6 +50,11 @@
 int trusty_dev_shutdown(struct trusty_dev* dev);
 
 /*
+ * Enter trusty on cpus that are not in an ipc call
+ */
+int trusty_dev_nop(struct trusty_dev* dev);
+
+/*
  * Invokes creation of queueless Trusty IPC device on the secure side.
  * @buf will be mapped into Trusty's address space.
  *
diff --git a/ql-tipc/include/trusty/trusty_ipc.h b/ql-tipc/include/trusty/trusty_ipc.h
index c112c71..13e1fd7 100644
--- a/ql-tipc/include/trusty/trusty_ipc.h
+++ b/ql-tipc/include/trusty/trusty_ipc.h
@@ -210,7 +210,7 @@
                         const struct trusty_ipc_iovec* iovs,
                         size_t iovs_cnt);
 
-void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev);
+void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev, bool event_poll);
 
 /*
  * Initializes @chan with default values and @dev.
diff --git a/ql-tipc/ipc.c b/ql-tipc/ipc.c
index fbaedce..8447e7a 100644
--- a/ql-tipc/ipc.c
+++ b/ql-tipc/ipc.c
@@ -61,7 +61,7 @@
             break;
 
         if (rc == TRUSTY_EVENT_NONE)
-            trusty_ipc_dev_idle(chan->dev);
+            trusty_ipc_dev_idle(chan->dev, true);
     }
 
     return chan->complete;
@@ -197,7 +197,7 @@
     struct trusty_ipc_event evt;
     struct trusty_ipc_chan* chan;
 
-    trusty_assert(dev);
+    trusty_assert(ipc_dev);
 
     rc = trusty_ipc_dev_get_event(ipc_dev, 0, &evt);
     if (rc) {
diff --git a/ql-tipc/ipc_dev.c b/ql-tipc/ipc_dev.c
index b633085..7a217f9 100644
--- a/ql-tipc/ipc_dev.c
+++ b/ql-tipc/ipc_dev.c
@@ -450,6 +450,6 @@
     return (int)copied;
 }
 
-void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev) {
-    trusty_idle(dev->tdev);
+void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev, bool event_poll) {
+    trusty_idle(dev->tdev, event_poll);
 }