soundstream: replace wfi busy loops

Add api's to wait for certain events rather than busy-waiting. Raise
the priority of the interrupt threads to minimize scheduling latency
(just a guess).

Bug: 330741645

Bypass-Presubmit-Reason: no sencha CI tests

Change-Id: Ic492294b0e19129943f3e0408321ea203be7686e
diff --git a/sw/device/cheriot/soundstream/compat.h b/sw/device/cheriot/soundstream/compat.h
index 70b1193..5d28227 100644
--- a/sw/device/cheriot/soundstream/compat.h
+++ b/sw/device/cheriot/soundstream/compat.h
@@ -83,7 +83,4 @@
     }                                                                \
   } while (false)
 
-// TODO(sleffler): need a scheduler yield kinda call
-inline void wait_for_interrupt(void) { asm volatile("wfi"); }
-
 #endif  // EXAMPLES_SOUNDSTREAM_COMPAT_H_
diff --git a/sw/device/cheriot/soundstream/i2s.cc b/sw/device/cheriot/soundstream/i2s.cc
index e5a5efb..e20358f 100644
--- a/sw/device/cheriot/soundstream/i2s.cc
+++ b/sw/device/cheriot/soundstream/i2s.cc
@@ -87,6 +87,16 @@
   return was_seen;
 }
 
+void i2s_wait_for_rx_watermark(void) {
+  const uint32_t *rxWatermarkFutex = interrupt_futex_get(
+      STATIC_SEALED_VALUE(i2sRxWatermarkInterruptCapability));
+  uint32_t last = *rxWatermarkFutex;
+  while (!i2s_rx_watermark_seen()) {
+    Debug::Assert(futex_wait(rxWatermarkFutex, last) == 0, "futex_wait");
+    last = *rxWatermarkFutex;
+  }
+}
+
 static void i2s_irq_acknowledge(i2s_irq_t irq_id) {
   CHECK_INIT();
   CHECK_DIF_OK(dif_i2s_irq_acknowledge(&i2s, irq_id));
diff --git a/sw/device/cheriot/soundstream/i2s.h b/sw/device/cheriot/soundstream/i2s.h
index 08f6565..a920ad1 100644
--- a/sw/device/cheriot/soundstream/i2s.h
+++ b/sw/device/cheriot/soundstream/i2s.h
@@ -32,6 +32,7 @@
 void __cheri_compartment("i2s")
     i2s_irq_set_enabled(i2s_irq_t irq_id, bool enabled);
 bool __cheri_compartment("i2s") i2s_rx_watermark_seen(void);
+void __cheri_compartment("i2s") i2s_wait_for_rx_watermark(void);
 void __cheri_compartment("i2s") i2s_rxfifo_clear(void);
 bool __cheri_compartment("i2s") i2s_rxfifo_is_empty(void);
 void __cheri_compartment("i2s") i2s_record_begin(void);
diff --git a/sw/device/cheriot/soundstream/mailbox.cc b/sw/device/cheriot/soundstream/mailbox.cc
index 8861bbc..5f15111 100644
--- a/sw/device/cheriot/soundstream/mailbox.cc
+++ b/sw/device/cheriot/soundstream/mailbox.cc
@@ -93,6 +93,17 @@
 // XXX temp until gpio's on the SEC can be used (either in simulation or for real)
 void mailbox_set_button_pressed(bool pressed) { button_pressed = pressed; }
 
+// Wait until the record switch is pushed
+void mailbox_wait_for_button_pressed(void) {
+  const uint32_t *mailboxRtFutex =
+      interrupt_futex_get(STATIC_SEALED_VALUE(mailboxRtInterruptCapability));
+  uint32_t last = *mailboxRtFutex;
+  while (!mailbox_button_pressed()) {
+    Debug::Assert(futex_wait(mailboxRtFutex, last) == 0, "futex_wait");
+    last = *mailboxRtFutex;
+  }
+}
+
 void mailbox_set_led(bool enabled) {
   CHECK_INIT();
   // NB: this is not the TockOS mailbox protocol.
diff --git a/sw/device/cheriot/soundstream/mailbox.h b/sw/device/cheriot/soundstream/mailbox.h
index 6663fca..3220187 100644
--- a/sw/device/cheriot/soundstream/mailbox.h
+++ b/sw/device/cheriot/soundstream/mailbox.h
@@ -27,6 +27,7 @@
 void __cheri_compartment("mailbox") mailbox_init(void);
 void __cheri_compartment("mailbox") mailbox_isr(void);
 bool __cheri_compartment("mailbox") mailbox_button_pressed(void);
+void __cheri_compartment("mailbox") mailbox_wait_for_button_pressed(void);
 // XXX temp
 void __cheri_compartment("mailbox") mailbox_set_button_pressed(bool);
 void __cheri_compartment("mailbox") mailbox_set_led(bool enabled);
diff --git a/sw/device/cheriot/soundstream/ml_top.cc b/sw/device/cheriot/soundstream/ml_top.cc
index 38d51bf..bd30f55 100644
--- a/sw/device/cheriot/soundstream/ml_top.cc
+++ b/sw/device/cheriot/soundstream/ml_top.cc
@@ -111,6 +111,16 @@
   return was_done;
 }
 
+void ml_top_wait_for_finish(void) {
+  const uint32_t* mlTopFinishFutex =
+      interrupt_futex_get(STATIC_SEALED_VALUE(mlTopFinishInterruptCapability));
+  uint32_t last = *mlTopFinishFutex;
+  while (!ml_top_finish_done()) {
+    Debug::Assert(futex_wait(mlTopFinishFutex, last) == 0, "futex_wait");
+    last = *mlTopFinishFutex;
+  }
+}
+
 void ml_top_irq_acknowledge_all() {
   CHECK_INIT();
   CHECK_DIF_OK(dif_ml_top_irq_acknowledge_all(&ml_top));
diff --git a/sw/device/cheriot/soundstream/ml_top.h b/sw/device/cheriot/soundstream/ml_top.h
index b860d5f..be93516 100644
--- a/sw/device/cheriot/soundstream/ml_top.h
+++ b/sw/device/cheriot/soundstream/ml_top.h
@@ -38,6 +38,7 @@
 void __cheri_compartment("ml_top")
     ml_top_irq_set_enabled(ml_top_irq_t irq_id, bool enabled);
 bool __cheri_compartment("ml_top") ml_top_finish_done(void);
+void __cheri_compartment("ml_top") ml_top_wait_for_finish(void);
 void __cheri_compartment("ml_top") ml_top_resume_ctrl_en(uint32_t resume_pc);
 void __cheri_compartment("ml_top")
     ml_top_set_input(void* const data, size_t data_len_bytes);
diff --git a/sw/device/cheriot/soundstream/soundstream.cc b/sw/device/cheriot/soundstream/soundstream.cc
index 897a921..45dd2a9 100644
--- a/sw/device/cheriot/soundstream/soundstream.cc
+++ b/sw/device/cheriot/soundstream/soundstream.cc
@@ -89,9 +89,7 @@
 
     // Wait until the record switch is pushed
     Debug::log("Wait for button press...");
-    while (!mailbox_button_pressed()) {
-      wait_for_interrupt();
-    }
+    mailbox_wait_for_button_pressed();
 
     mailbox_set_led(/*enabled=*/true);
     Debug::log("Start recording (max {} samples)...", kSamples);
@@ -101,9 +99,8 @@
     int sample = 0;
     while (sample < kSamples && mailbox_button_pressed()) {
       i2s_irq_set_enabled(kI2sIrqRxWatermark, /*enabled=*/true);
-      while (!i2s_rx_watermark_seen()) {
-        wait_for_interrupt();
-      }
+
+      i2s_wait_for_rx_watermark();
 
       while (!i2s_rxfifo_is_empty()) {
         uint32_t reg_val = i2s_get_rdata();
@@ -190,10 +187,7 @@
       (void) ml_top_finish_done();  // NB: reset state
       ml_top_resume_ctrl_en(header.resume_pc);
 
-      // wfi
-      while (!ml_top_finish_done()) {
-        wait_for_interrupt();
-      }
+      ml_top_wait_for_finish();
 
       ml_top_get_output_header(&header);
       CHECK(header.length == sizeof(result_buffer), "Unexpected ML result size");
diff --git a/sw/device/cheriot/soundstream/xmake.lua b/sw/device/cheriot/soundstream/xmake.lua
index 3d2d1da..5ab5325 100644
--- a/sw/device/cheriot/soundstream/xmake.lua
+++ b/sw/device/cheriot/soundstream/xmake.lua
@@ -88,21 +88,21 @@
             -- NB: stack sizes bumped for logging
             {
                 compartment = "i2s",
-                priority = 1,
+                priority = 10,
                 entry_point = "i2s_isr",
                 stack_size = 0x400, -- 512B
                 trusted_stack_frames = 3
             },
             {
                 compartment = "ml_top",
-                priority = 1,
+                priority = 10,
                 entry_point = "ml_top_isr",
                 stack_size = 0x400, -- 512B
                 trusted_stack_frames = 3
             },
             {
                 compartment = "mailbox",
-                priority = 1,
+                priority = 10,
                 entry_point = "mailbox_isr",
                 stack_size = 0x400, -- 512B
                 trusted_stack_frames = 3