[sca] Add a parameter to sca_init() for disabling peripherals

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/hw/top_englishbreakfast/util/sw_sources.patch b/hw/top_englishbreakfast/util/sw_sources.patch
index 3168022..0359b93 100644
--- a/hw/top_englishbreakfast/util/sw_sources.patch
+++ b/hw/top_englishbreakfast/util/sw_sources.patch
@@ -55,15 +55,12 @@
 index 50bee15fa..8f5976a83 100644
 --- a/sw/device/sca/aes_serial.c
 +++ b/sw/device/sca/aes_serial.c
-@@ -203,21 +203,13 @@ int main(void) {
-   sca_init(kScaTriggerSourceAes);
+@@ -203,18 +203,13 @@ int main(void) {
+   sca_init(kScaTriggerSourceAes, kScaPeripheralAes);
    sca_get_uart(&uart1);
  
 -  LOG_INFO("Running AES serial");
 -
--  LOG_INFO("Disabling entropy complex and unneeded clocks to reduce noise.");
--  sca_reduce_noise();
--
 -  LOG_INFO("Initializing simple serial interface to capture board.");
    simple_serial_init(uart1);
    simple_serial_register_handler('k', aes_serial_set_key);
@@ -81,7 +78,7 @@
 index 1c74eb0ee..cc087c4b9 100644
 --- a/sw/device/sca/lib/sca.c
 +++ b/sw/device/sca/lib/sca.c
-@@ -50,7 +50,6 @@ enum {
+@@ -56,7 +56,6 @@ enum {
    kRvTimerHart = kTopEarlgreyPlicTargetIbex0,
  };
  
@@ -89,7 +86,7 @@
  static dif_uart_t uart1;
  static dif_gpio_t gpio;
  static dif_rv_timer_t timer;
-@@ -72,16 +71,9 @@ static void sca_init_uart(void) {
+@@ -78,16 +77,9 @@ static void sca_init_uart(void) {
        (dif_uart_params_t){
            .base_addr = mmio_region_from_addr(TOP_EARLGREY_UART0_BASE_ADDR),
        },
@@ -107,26 +104,30 @@
  }
  
  /**
-@@ -137,42 +129,16 @@ void sca_init(void) {
- }
- 
- void sca_reduce_noise() {
--  // Disable/stopping functionality not yet provided by EDN and CSRNG DIFs.
--  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
--                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
--  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
--                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
--  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
--                      CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
--
--  // Disable entropy source through DIF.
--  const dif_entropy_src_params_t entropy_params = {
--      .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
--  };
--  dif_entropy_src_t entropy;
--  IGNORE_RESULT(dif_entropy_src_init(entropy_params, &entropy) ==
--                kDifEntropySrcOk);
--  IGNORE_RESULT(dif_entropy_src_disable(&entropy) == kDifEntropySrcOk);
+@@ -147,32 +147,11 @@ void handler_irq_timer(void) {
+  * @param disable Set of peripherals to disable.
+  */
+ void sca_disable_peripherals(sca_peripherals_t disable) {
+-  if (disable & kScaPeripheralEdn) {
+-    // TODO(#5465): Replace with `dif_edn_stop()` when it is implemented.
+-    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
+-                        EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+-    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
+-                        EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+-  }
+-  if (disable & kScaPeripheralCsrng) {
+-    // TODO(#7837): Replace with `dif_csrng_stop()` when it is implemented.
+-    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
+-                        CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
+-  }
+-  if (disable & kScaPeripheralEntropy) {
+-    const dif_entropy_src_params_t entropy_params = {
+-        .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
+-    };
+-    dif_entropy_src_t entropy;
+-    IGNORE_RESULT(dif_entropy_src_init(entropy_params, &entropy));
+-    IGNORE_RESULT(dif_entropy_src_disable(&entropy));
+-  }
 -
    // Disable HMAC, KMAC, OTBN and USB clocks through CLKMGR DIF.
    const dif_clkmgr_params_t clkmgr_params = {
@@ -135,22 +136,28 @@
 -      .last_hintable_clock = CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT};
 +      .last_hintable_clock = CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT};
    dif_clkmgr_t clkmgr;
-   IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr) == kDifClkmgrOk);
-   IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
-                     &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
-                     kDifClkmgrToggleDisabled) == kDifClkmgrOk);
--  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
--                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
--                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
--  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
--                    &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
--                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
--  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
--                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
--                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
-   IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
-                     &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
-                     kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+   IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr));
+
+@@ -182,19 +165,6 @@ void sca_disable_peripherals(sca_peripherals_t disable) {
+         &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
+         kDifClkmgrToggleDisabled));
+   }
+-  if (disable & kScaPeripheralKmac) {
+-    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+-        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
+-        kDifClkmgrToggleDisabled));
+-  }
+-  if (disable & kScaPeripheralOtbn) {
+-    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+-        &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
+-        kDifClkmgrToggleDisabled));
+-    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+-        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
+-        kDifClkmgrToggleDisabled));
+-  }
+   if (disable & kScaPeripheralUsb) {
+     IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
+         &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
 diff --git a/sw/device/tests/dif/dif_aes_smoketest.c b/sw/device/tests/dif/dif_aes_smoketest.c
 index 70c3baaf9..5d69301e2 100644
 --- a/sw/device/tests/dif/dif_aes_smoketest.c
diff --git a/sw/device/sca/aes_serial.c b/sw/device/sca/aes_serial.c
index 3fb4849..901eba8 100644
--- a/sw/device/sca/aes_serial.c
+++ b/sw/device/sca/aes_serial.c
@@ -200,14 +200,11 @@
 int main(void) {
   const dif_uart_t *uart1;
 
-  sca_init(kScaTriggerSourceAes);
+  sca_init(kScaTriggerSourceAes, kScaPeripheralAes);
   sca_get_uart(&uart1);
 
   LOG_INFO("Running AES serial");
 
-  LOG_INFO("Disabling entropy complex and unneeded clocks to reduce noise.");
-  sca_reduce_noise();
-
   LOG_INFO("Initializing simple serial interface to capture board.");
   simple_serial_init(uart1);
   simple_serial_register_handler('k', aes_serial_set_key);
diff --git a/sw/device/sca/lib/sca.c b/sw/device/sca/lib/sca.c
index 3f50ae5..9210f45 100644
--- a/sw/device/sca/lib/sca.c
+++ b/sw/device/sca/lib/sca.c
@@ -143,30 +143,38 @@
       dif_rv_timer_irq_clear(&timer, kRvTimerHart, kRvTimerComparator));
 }
 
-void sca_init(sca_trigger_source_t trigger) {
-  pinmux_init();
-  sca_init_uart();
-  sca_init_gpio(trigger);
-  sca_init_timer();
-}
-
-void sca_reduce_noise() {
-  // Disable/stopping functionality not yet provided by EDN and CSRNG DIFs.
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
-                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
-                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
-
-  // Disable entropy source through DIF.
-  const dif_entropy_src_params_t entropy_params = {
-      .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
-  };
-  dif_entropy_src_t entropy;
-  IGNORE_RESULT(dif_entropy_src_init(entropy_params, &entropy) ==
-                kDifEntropySrcOk);
-  IGNORE_RESULT(dif_entropy_src_disable(&entropy) == kDifEntropySrcOk);
+/**
+ * Disables the given peripherals to reduce noise during SCA.
+ *
+ * Care must be taken when disabling the entropy complex if a peripheral that
+ * depends on it will be used in SCA. E.g., We can disable the entropy complex
+ * when analyzing AES only because AES features a parameter to skip PRNG
+ * reseeding for SCA experiments. Without this parameter, AES would simply get
+ * stalled with a disabled entropy complex.
+ *
+ * @param disable Set of peripherals to disable.
+ */
+void sca_disable_peripherals(sca_peripherals_t disable) {
+  if (disable & kScaPeripheralEdn) {
+    // TODO(#5465): Replace with `dif_edn_stop()` when it is implemented.
+    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
+                        EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
+                        EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+  }
+  if (disable & kScaPeripheralCsrng) {
+    // TODO(#7837): Replace with `dif_csrng_stop()` when it is implemented.
+    mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
+                        CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
+  }
+  if (disable & kScaPeripheralEntropy) {
+    const dif_entropy_src_params_t entropy_params = {
+        .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
+    };
+    dif_entropy_src_t entropy;
+    IGNORE_RESULT(dif_entropy_src_init(entropy_params, &entropy));
+    IGNORE_RESULT(dif_entropy_src_disable(&entropy));
+  }
 
   // Disable HMAC, KMAC, OTBN and USB clocks through CLKMGR DIF.
   const dif_clkmgr_params_t clkmgr_params = {
@@ -174,22 +182,44 @@
       .last_gateable_clock = CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
       .last_hintable_clock = CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT};
   dif_clkmgr_t clkmgr;
-  IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr) == kDifClkmgrOk);
-  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
-                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
-                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
-  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
-                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
-                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
-  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
-                    &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
-                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
-  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
-                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
-                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
-  IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
-                    &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
-                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr));
+
+  if (disable & kScaPeripheralAes) {
+    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT,
+        kDifClkmgrToggleDisabled));
+  }
+  if (disable & kScaPeripheralHmac) {
+    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
+        kDifClkmgrToggleDisabled));
+  }
+  if (disable & kScaPeripheralKmac) {
+    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
+        kDifClkmgrToggleDisabled));
+  }
+  if (disable & kScaPeripheralOtbn) {
+    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+        &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
+        kDifClkmgrToggleDisabled));
+    IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+        &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
+        kDifClkmgrToggleDisabled));
+  }
+  if (disable & kScaPeripheralUsb) {
+    IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
+        &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
+        kDifClkmgrToggleDisabled));
+  }
+}
+
+void sca_init(sca_trigger_source_t trigger, sca_peripherals_t enable) {
+  pinmux_init();
+  sca_init_uart();
+  sca_init_gpio(trigger);
+  sca_init_timer();
+  sca_disable_peripherals(~enable);
 }
 
 void sca_get_uart(const dif_uart_t **uart_out) { *uart_out = &uart1; }
diff --git a/sw/device/sca/lib/sca.h b/sw/device/sca/lib/sca.h
index 5414b21..9adf452f 100644
--- a/sw/device/sca/lib/sca.h
+++ b/sw/device/sca/lib/sca.h
@@ -47,21 +47,67 @@
 } sca_trigger_source_t;
 
 /**
+ * Peripherals.
+ *
+ * Constants below are bitmasks that can be used to specify a set of
+ * peripherals.
+ *
+ * See also: `sca_peripherals_t`.
+ */
+typedef enum sca_peripheral {
+  /**
+   * EDN.
+   */
+  kScaPeripheralEdn = 1 << 0,
+  /**
+   * CSRNG.
+   */
+  kScaPeripheralCsrng = 1 << 1,
+  /**
+   * Entropy source.
+   */
+  kScaPeripheralEntropy = 1 << 2,
+  /**
+   * AES.
+   */
+  kScaPeripheralAes = 1 << 3,
+  /**
+   * HMAC.
+   */
+  kScaPeripheralHmac = 1 << 4,
+  /**
+   * KMAC.
+   */
+  kScaPeripheralKmac = 1 << 5,
+  /**
+   * OTBN.
+   */
+  kScaPeripheralOtbn = 1 << 6,
+  /**
+   * USB.
+   */
+  kScaPeripheralUsb = 1 << 7,
+} sca_peripheral_t;
+
+/**
+ * A set of peripherals.
+ *
+ * This type is used for specifying which peripherals should be enabled when
+ * calling `sca_init()`. Remaining peripherals will be disabled to reduce noise
+ * during SCA.
+ *
+ * See also: `sca_peripheral_t`, `sca_init()`.
+ */
+typedef uint32_t sca_peripherals_t;
+
+/**
  * Initializes the peripherals (pinmux, uart, gpio, and timer) used by SCA code.
  *
  * @param trigger Peripheral to use for the trigger signal.
+ * @param enable Set of peripherals to enable. Remaining peripherals will
+ * be disabled to reduce noise during SCA.
  */
-void sca_init(sca_trigger_source_t trigger);
-
-/**
- * Disables the entropy complex and clocks of IPs not needed for SCA to reduce
- * noise in the power traces.
- *
- * We can only disable the entropy complex as AES features a parameter to skip
- * PRNG reseeding for SCA experiments. Without this parameter, AES would simply
- * get stalled with a disabled entropy complex.
- */
-void sca_reduce_noise(void);
+void sca_init(sca_trigger_source_t trigger, sca_peripherals_t enable);
 
 /**
  * Returns a handle to the intialized UART device.