[sw/sca] Refactor common sca code in preparation for a new library

This change refactors some device init and handling code that is
expected to be shared between different SCA targets:
- Initialization of pinmux, UART, GPIO, and timer,
- IRQ handling,
- Trigger handling, and
- Sleeping during encryption operations.

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/sca/aes_serial/aes_serial.c b/sw/device/sca/aes_serial/aes_serial.c
index c9d0366..26f2077 100644
--- a/sw/device/sca/aes_serial/aes_serial.c
+++ b/sw/device/sca/aes_serial/aes_serial.c
@@ -90,6 +90,116 @@
   } while (false)
 
 /**
+ * Initializes the UART peripheral.
+ */
+static void sca_init_uart() {
+  (void)dif_uart_init(
+      (dif_uart_params_t){
+          .base_addr = mmio_region_from_addr(TOP_EARLGREY_UART_BASE_ADDR),
+      },
+      &uart);
+  (void)dif_uart_configure(&uart, (dif_uart_config_t){
+                                      .baudrate = kUartBaudrate,
+                                      .clk_freq_hz = kClockFreqPeripheralHz,
+                                      .parity_enable = kDifUartToggleDisabled,
+                                      .parity = kDifUartParityEven,
+                                  });
+  dif_uart_fifo_reset(&uart, kDifUartFifoResetAll);
+  base_uart_stdout(&uart);
+}
+
+/**
+ * Initializes the GPIO peripheral.
+ */
+static void sca_init_gpio() {
+  dif_gpio_params_t gpio_params = {
+      .base_addr = mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR)};
+  (void)dif_gpio_init(gpio_params, &gpio);
+  (void)dif_gpio_output_set_enabled_all(&gpio, kGpioCaptureTriggerHigh);
+}
+
+/**
+ * Initializes the timer peripheral.
+ */
+static void sca_init_timer() {
+  (void)dif_rv_timer_init(
+      mmio_region_from_addr(TOP_EARLGREY_RV_TIMER_BASE_ADDR),
+      (dif_rv_timer_config_t){.hart_count = 1, .comparator_count = 1}, &timer);
+  dif_rv_timer_tick_params_t tick_params;
+  (void)dif_rv_timer_approximate_tick_params(kClockFreqPeripheralHz,
+                                             kClockFreqCpuHz, &tick_params);
+  (void)dif_rv_timer_set_tick_params(&timer, kRvTimerHart, tick_params);
+  (void)dif_rv_timer_irq_enable(&timer, kRvTimerHart, kRvTimerComparator,
+                                kDifRvTimerEnabled);
+  irq_timer_ctrl(true);
+  irq_global_ctrl(true);
+}
+
+/**
+ * Timer IRQ handler.
+ *
+ * Disables the counter and clears pending interrupts.
+ */
+void handler_irq_timer(void) {
+  // Return values of below functions are ignored to improve capture
+  // performance.
+  (void)dif_rv_timer_counter_set_enabled(&timer, kRvTimerHart,
+                                         kDifRvTimerDisabled);
+  (void)dif_rv_timer_irq_clear(&timer, kRvTimerHart, kRvTimerComparator);
+}
+
+/**
+ * Initializes the peripherals (pinmux, uart, gpio, and timer) used by SCA code.
+ */
+static void sca_init(void) {
+  pinmux_init();
+  sca_init_uart();
+  sca_init_gpio();
+  sca_init_timer();
+}
+
+/**
+ * Sets capture trigger high.
+ *
+ * The actual trigger signal used for capture is a combination (logical AND) of:
+ * - GPIO15 enabled here, and
+ * - the busy signal of the AES unit. This signal will go high 40 cycles
+ *   after aes_manual_trigger() is executed below and remain high until
+ *   the operation has finished.
+ */
+static void sca_set_trigger_high() {
+  (void)dif_gpio_write_all(&gpio, kGpioCaptureTriggerHigh);
+}
+
+/**
+ * Sets capture trigger low.
+ */
+static void sca_set_trigger_low() {
+  (void)dif_gpio_write_all(&gpio, kGpioCaptureTriggerLow);
+}
+
+/**
+ * Functions called by `sca_call_and_sleep()` must conform to this prototype.
+ */
+typedef void (*sca_callee)(void);
+
+static void sca_call_and_sleep(sca_callee callee, uint32_t sleep_cycles) {
+  // Start timer to wake Ibex after AES is done.
+  uint64_t current_time;
+  // Return values of below functions are ignored to improve capture
+  // performance.
+  (void)dif_rv_timer_counter_read(&timer, kRvTimerHart, &current_time);
+  (void)dif_rv_timer_arm(&timer, kRvTimerHart, kRvTimerComparator,
+                         current_time + sleep_cycles);
+  (void)dif_rv_timer_counter_set_enabled(&timer, kRvTimerHart,
+                                         kDifRvTimerEnabled);
+
+  callee();
+
+  wait_for_interrupt();
+}
+
+/**
  * Convert `from` binary `to` hex.
  *
  * @param from input value in binary format.
@@ -201,33 +311,15 @@
   // Provide input data to AES.
   aes_data_put_wait(plaintext);
 
-  // Arm capture trigger. The actual trigger signal used for capture is a
-  // combination (logical AND) of:
-  // - GPIO15 enabled here, and
-  // - the busy signal of the AES unit. This signal will go high 40 cycles
-  //   after aes_manual_trigger() is executed below and remain high until
-  //   the operation has finished.
-  SS_CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerHigh) == kDifGpioOk);
-
-  // Start timer to wake up Ibex after AES is done.
-  uint64_t current_time;
-  SS_CHECK(dif_rv_timer_counter_read(&timer, kRvTimerHart, &current_time) ==
-           kDifRvTimerOk);
-  SS_CHECK(dif_rv_timer_arm(&timer, kRvTimerHart, kRvTimerComparator,
-                            current_time + kIbexAesSleepCycles) ==
-           kDifRvTimerOk);
-  SS_CHECK(dif_rv_timer_counter_set_enabled(
-               &timer, kRvTimerHart, kDifRvTimerEnabled) == kDifRvTimerOk);
+  sca_set_trigger_high();
 
   // Start AES operation (this triggers the capture) and go to sleep.
   // Using the SecAesStartTriggerDelay hardware parameter, the AES unit is
   // configured to start operation 40 cycles after receiving the start trigger.
   // This allows Ibex to go to sleep in order to not disturb the capture.
-  aes_manual_trigger();
-  wait_for_interrupt();
+  sca_call_and_sleep(aes_manual_trigger, kIbexAesSleepCycles);
 
-  // Disable capture trigger.
-  SS_CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerLow) == kDifGpioOk);
+  sca_set_trigger_low();
 
   // Retrieve output data from AES.
   aes_data_get_wait(ciphertext);
@@ -282,42 +374,7 @@
 }
 
 int main(void) {
-  CHECK(dif_uart_init(
-            (dif_uart_params_t){
-                .base_addr = mmio_region_from_addr(TOP_EARLGREY_UART_BASE_ADDR),
-            },
-            &uart) == kDifUartOk);
-  CHECK(dif_uart_configure(&uart, (dif_uart_config_t){
-                                      .baudrate = kUartBaudrate,
-                                      .clk_freq_hz = kClockFreqPeripheralHz,
-                                      .parity_enable = kDifUartToggleDisabled,
-                                      .parity = kDifUartParityEven,
-                                  }) == kDifUartConfigOk);
-  base_uart_stdout(&uart);
-
-  pinmux_init();
-
-  irq_global_ctrl(true);
-  irq_timer_ctrl(true);
-
-  CHECK(dif_rv_timer_init(
-            mmio_region_from_addr(TOP_EARLGREY_RV_TIMER_BASE_ADDR),
-            (dif_rv_timer_config_t){.hart_count = 1, .comparator_count = 1},
-            &timer) == kDifRvTimerOk);
-  dif_rv_timer_tick_params_t tick_params;
-  CHECK(dif_rv_timer_approximate_tick_params(kClockFreqPeripheralHz,
-                                             kClockFreqCpuHz, &tick_params) ==
-        kDifRvTimerApproximateTickParamsOk);
-  CHECK(dif_rv_timer_set_tick_params(&timer, kRvTimerHart, tick_params) ==
-        kDifRvTimerOk);
-  CHECK(dif_rv_timer_irq_enable(&timer, kRvTimerHart, kRvTimerComparator,
-                                kDifRvTimerEnabled) == kDifRvTimerOk);
-
-  dif_gpio_params_t gpio_params = {
-      .base_addr = mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR)};
-  CHECK(dif_gpio_init(gpio_params, &gpio) == kDifGpioOk);
-  CHECK(dif_gpio_output_set_enabled_all(&gpio, 0x08200) == kDifGpioOk);
-  CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerLow) == kDifGpioOk);
+  sca_init();
 
   aes_cfg_t aes_cfg;
   aes_cfg.key_len = kAes128;
@@ -351,15 +408,3 @@
     }
   }
 }
-
-void handler_irq_timer(void) {
-  bool irq_flag;
-  CHECK(dif_rv_timer_irq_get(&timer, kRvTimerHart, kRvTimerComparator,
-                             &irq_flag) == kDifRvTimerOk);
-  CHECK(irq_flag, "Entered IRQ handler but the expected IRQ flag wasn't set!");
-
-  CHECK(dif_rv_timer_counter_set_enabled(&timer, kRvTimerHart,
-                                         kDifRvTimerDisabled) == kDifRvTimerOk);
-  CHECK(dif_rv_timer_irq_clear(&timer, kRvTimerHart, kRvTimerComparator) ==
-        kDifRvTimerOk);
-}