[dif] Add DIFs to acknowledge a snapshot of IRQs
In issue #17349, alees24 identified a deficiency in the available
functions for acknowledging IRQs: The choices were a single IRQ or all
of them.
Add a set of DIFs for acknowledging the precise set of IRQs that were
retrieved at the time of calling dif_<IP>_irq_get_state() so multiple
IRQs may be acknowledged at once, but IRQs that were not observed do not
get inadvertently cleared.
Signed-off-by: Alexander Williams <awill@opentitan.org>
diff --git a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.c
index 0680470..f265a8c 100644
--- a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.c
@@ -95,6 +95,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_adc_ctrl_irq_acknowledge_state(
+ const dif_adc_ctrl_t *adc_ctrl,
+ dif_adc_ctrl_irq_state_snapshot_t snapshot) {
+ if (adc_ctrl == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(adc_ctrl->base_addr, ADC_CTRL_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_adc_ctrl_irq_is_pending(const dif_adc_ctrl_t *adc_ctrl,
dif_adc_ctrl_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.h
index 5bb7446..7af546f 100644
--- a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.h
@@ -86,7 +86,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_adc_ctrl_irq_get_state()`
- * function.
+ * and `dif_adc_ctrl_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_adc_ctrl_irq_state_snapshot_t;
@@ -129,6 +129,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param adc_ctrl A adc_ctrl handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_adc_ctrl_irq_acknowledge_state(
+ const dif_adc_ctrl_t *adc_ctrl, dif_adc_ctrl_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen_unittest.cc
index 94d25ae..a52b81d 100644
--- a/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_adc_ctrl_autogen_unittest.cc
@@ -150,6 +150,35 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public AdcCtrlTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_adc_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_adc_ctrl_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_adc_ctrl_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(ADC_CTRL_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_adc_ctrl_irq_acknowledge_state(&adc_ctrl_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_adc_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(ADC_CTRL_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_adc_ctrl_irq_get_state(&adc_ctrl_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public AdcCtrlTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_alert_handler_autogen.c b/sw/device/lib/dif/autogen/dif_alert_handler_autogen.c
index 98aa6a3..37fa6b9 100644
--- a/sw/device/lib/dif/autogen/dif_alert_handler_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_alert_handler_autogen.c
@@ -86,6 +86,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_alert_handler_irq_acknowledge_state(
+ const dif_alert_handler_t *alert_handler,
+ dif_alert_handler_irq_state_snapshot_t snapshot) {
+ if (alert_handler == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(alert_handler->base_addr,
+ ALERT_HANDLER_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_alert_handler_irq_is_pending(
const dif_alert_handler_t *alert_handler, dif_alert_handler_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_alert_handler_autogen.h b/sw/device/lib/dif/autogen/dif_alert_handler_autogen.h
index 8cece9a..d3540a0 100644
--- a/sw/device/lib/dif/autogen/dif_alert_handler_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_alert_handler_autogen.h
@@ -80,7 +80,8 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the
- * `dif_alert_handler_irq_get_state()` function.
+ * `dif_alert_handler_irq_get_state()` and
+ * `dif_alert_handler_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_alert_handler_irq_state_snapshot_t;
@@ -123,6 +124,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param alert_handler A alert_handler handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_alert_handler_irq_acknowledge_state(
+ const dif_alert_handler_t *alert_handler,
+ dif_alert_handler_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_alert_handler_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_alert_handler_autogen_unittest.cc
index 6995596..a1b1e6e 100644
--- a/sw/device/lib/dif/autogen/dif_alert_handler_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_alert_handler_autogen_unittest.cc
@@ -141,6 +141,38 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public AlertHandlerTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_alert_handler_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_alert_handler_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 4;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_alert_handler_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(ALERT_HANDLER_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_alert_handler_irq_acknowledge_state(&alert_handler_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_alert_handler_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(ALERT_HANDLER_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(
+ dif_alert_handler_irq_get_state(&alert_handler_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public AlertHandlerTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_aon_timer_autogen.c b/sw/device/lib/dif/autogen/dif_aon_timer_autogen.c
index f15a357..211f913 100644
--- a/sw/device/lib/dif/autogen/dif_aon_timer_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_aon_timer_autogen.c
@@ -108,6 +108,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_aon_timer_irq_acknowledge_state(
+ const dif_aon_timer_t *aon_timer,
+ dif_aon_timer_irq_state_snapshot_t snapshot) {
+ if (aon_timer == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(aon_timer->base_addr, AON_TIMER_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_aon_timer_irq_is_pending(const dif_aon_timer_t *aon_timer,
dif_aon_timer_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_aon_timer_autogen.h b/sw/device/lib/dif/autogen/dif_aon_timer_autogen.h
index 65ef415..b5d5c0d 100644
--- a/sw/device/lib/dif/autogen/dif_aon_timer_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_aon_timer_autogen.h
@@ -91,7 +91,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_aon_timer_irq_get_state()`
- * function.
+ * and `dif_aon_timer_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_aon_timer_irq_state_snapshot_t;
@@ -134,6 +134,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param aon_timer A aon_timer handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_aon_timer_irq_acknowledge_state(
+ const dif_aon_timer_t *aon_timer,
+ dif_aon_timer_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_aon_timer_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_aon_timer_autogen_unittest.cc
index 7b12ab4..519ec39 100644
--- a/sw/device/lib/dif/autogen/dif_aon_timer_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_aon_timer_autogen_unittest.cc
@@ -159,6 +159,36 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public AonTimerTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_aon_timer_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_aon_timer_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_aon_timer_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(AON_TIMER_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_aon_timer_irq_acknowledge_state(&aon_timer_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_aon_timer_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(AON_TIMER_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_aon_timer_irq_get_state(&aon_timer_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public AonTimerTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_csrng_autogen.c b/sw/device/lib/dif/autogen/dif_csrng_autogen.c
index cee1b5b..05d5874 100644
--- a/sw/device/lib/dif/autogen/dif_csrng_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_csrng_autogen.c
@@ -106,6 +106,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_csrng_irq_acknowledge_state(
+ const dif_csrng_t *csrng, dif_csrng_irq_state_snapshot_t snapshot) {
+ if (csrng == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(csrng->base_addr, CSRNG_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_csrng_irq_is_pending(const dif_csrng_t *csrng,
dif_csrng_irq_t irq, bool *is_pending) {
if (csrng == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_csrng_autogen.h b/sw/device/lib/dif/autogen/dif_csrng_autogen.h
index 7683b6d..1cbdb9a 100644
--- a/sw/device/lib/dif/autogen/dif_csrng_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_csrng_autogen.h
@@ -105,7 +105,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_csrng_irq_get_state()`
- * function.
+ * and `dif_csrng_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_csrng_irq_state_snapshot_t;
@@ -145,6 +145,18 @@
dif_csrng_irq_t irq, bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param csrng A csrng handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_csrng_irq_acknowledge_state(
+ const dif_csrng_t *csrng, dif_csrng_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_csrng_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_csrng_autogen_unittest.cc
index be67563..edb3bc3 100644
--- a/sw/device/lib/dif/autogen/dif_csrng_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_csrng_autogen_unittest.cc
@@ -161,6 +161,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public CsrngTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_csrng_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_csrng_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 4;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_csrng_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(CSRNG_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_csrng_irq_acknowledge_state(&csrng_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_csrng_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(CSRNG_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_csrng_irq_get_state(&csrng_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public CsrngTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_edn_autogen.c b/sw/device/lib/dif/autogen/dif_edn_autogen.c
index 1bff568..eed57b5 100644
--- a/sw/device/lib/dif/autogen/dif_edn_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_edn_autogen.c
@@ -97,6 +97,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_edn_irq_acknowledge_state(
+ const dif_edn_t *edn, dif_edn_irq_state_snapshot_t snapshot) {
+ if (edn == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(edn->base_addr, EDN_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_edn_irq_is_pending(const dif_edn_t *edn, dif_edn_irq_t irq,
bool *is_pending) {
if (edn == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_edn_autogen.h b/sw/device/lib/dif/autogen/dif_edn_autogen.h
index 024a5e7..e8cea11 100644
--- a/sw/device/lib/dif/autogen/dif_edn_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_edn_autogen.h
@@ -93,7 +93,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_edn_irq_get_state()`
- * function.
+ * and `dif_edn_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_edn_irq_state_snapshot_t;
@@ -133,6 +133,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param edn A edn handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_edn_irq_acknowledge_state(
+ const dif_edn_t *edn, dif_edn_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_edn_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_edn_autogen_unittest.cc
index 80a628a..b3264f4 100644
--- a/sw/device/lib/dif/autogen/dif_edn_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_edn_autogen_unittest.cc
@@ -159,6 +159,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public EdnTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_edn_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_edn_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_edn_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(EDN_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_edn_irq_acknowledge_state(&edn_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_edn_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(EDN_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_edn_irq_get_state(&edn_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public EdnTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_entropy_src_autogen.c b/sw/device/lib/dif/autogen/dif_entropy_src_autogen.c
index 1931113..d9fc7d8 100644
--- a/sw/device/lib/dif/autogen/dif_entropy_src_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_entropy_src_autogen.c
@@ -111,6 +111,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_entropy_src_irq_acknowledge_state(
+ const dif_entropy_src_t *entropy_src,
+ dif_entropy_src_irq_state_snapshot_t snapshot) {
+ if (entropy_src == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(entropy_src->base_addr, ENTROPY_SRC_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_entropy_src_irq_is_pending(
const dif_entropy_src_t *entropy_src, dif_entropy_src_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_entropy_src_autogen.h b/sw/device/lib/dif/autogen/dif_entropy_src_autogen.h
index a69a1b1..880234a 100644
--- a/sw/device/lib/dif/autogen/dif_entropy_src_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_entropy_src_autogen.h
@@ -106,7 +106,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_entropy_src_irq_get_state()`
- * function.
+ * and `dif_entropy_src_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_entropy_src_irq_state_snapshot_t;
@@ -149,6 +149,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param entropy_src A entropy_src handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_entropy_src_irq_acknowledge_state(
+ const dif_entropy_src_t *entropy_src,
+ dif_entropy_src_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_entropy_src_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_entropy_src_autogen_unittest.cc
index 333c8f6..509687d 100644
--- a/sw/device/lib/dif/autogen/dif_entropy_src_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_entropy_src_autogen_unittest.cc
@@ -165,6 +165,37 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public EntropySrcTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_entropy_src_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_entropy_src_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 4;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_entropy_src_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(ENTROPY_SRC_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_entropy_src_irq_acknowledge_state(&entropy_src_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_entropy_src_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(ENTROPY_SRC_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_entropy_src_irq_get_state(&entropy_src_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public EntropySrcTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.c
index 2a76903..818dcb8 100644
--- a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.c
@@ -124,6 +124,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_flash_ctrl_irq_acknowledge_state(
+ const dif_flash_ctrl_t *flash_ctrl,
+ dif_flash_ctrl_irq_state_snapshot_t snapshot) {
+ if (flash_ctrl == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(flash_ctrl->base_addr, FLASH_CTRL_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_flash_ctrl_irq_is_pending(const dif_flash_ctrl_t *flash_ctrl,
dif_flash_ctrl_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.h
index 91f064c..b6acb47 100644
--- a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.h
@@ -123,7 +123,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_flash_ctrl_irq_get_state()`
- * function.
+ * and `dif_flash_ctrl_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_flash_ctrl_irq_state_snapshot_t;
@@ -166,6 +166,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param flash_ctrl A flash_ctrl handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_flash_ctrl_irq_acknowledge_state(
+ const dif_flash_ctrl_t *flash_ctrl,
+ dif_flash_ctrl_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen_unittest.cc
index ae43795..47b01d4 100644
--- a/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_flash_ctrl_autogen_unittest.cc
@@ -164,6 +164,37 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public FlashCtrlTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_flash_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_flash_ctrl_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 6;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_flash_ctrl_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(FLASH_CTRL_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_flash_ctrl_irq_acknowledge_state(&flash_ctrl_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_flash_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(FLASH_CTRL_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_flash_ctrl_irq_get_state(&flash_ctrl_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public FlashCtrlTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_gpio_autogen.c b/sw/device/lib/dif/autogen/dif_gpio_autogen.c
index 14e8ed6..5f95a75 100644
--- a/sw/device/lib/dif/autogen/dif_gpio_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_gpio_autogen.c
@@ -191,6 +191,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_gpio_irq_acknowledge_state(
+ const dif_gpio_t *gpio, dif_gpio_irq_state_snapshot_t snapshot) {
+ if (gpio == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(gpio->base_addr, GPIO_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_gpio_irq_is_pending(const dif_gpio_t *gpio, dif_gpio_irq_t irq,
bool *is_pending) {
if (gpio == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_gpio_autogen.h b/sw/device/lib/dif/autogen/dif_gpio_autogen.h
index e73cfeb..4ac7163 100644
--- a/sw/device/lib/dif/autogen/dif_gpio_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_gpio_autogen.h
@@ -116,7 +116,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_gpio_irq_get_state()`
- * function.
+ * and `dif_gpio_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_gpio_irq_state_snapshot_t;
@@ -156,6 +156,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param gpio A gpio handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_gpio_irq_acknowledge_state(
+ const dif_gpio_t *gpio, dif_gpio_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_gpio_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_gpio_autogen_unittest.cc
index b349ad5..9e2644b 100644
--- a/sw/device/lib/dif/autogen/dif_gpio_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_gpio_autogen_unittest.cc
@@ -146,6 +146,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public GpioTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_gpio_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_gpio_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 32;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_gpio_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(GPIO_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_gpio_irq_acknowledge_state(&gpio_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_gpio_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(GPIO_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_gpio_irq_get_state(&gpio_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public GpioTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_hmac_autogen.c b/sw/device/lib/dif/autogen/dif_hmac_autogen.c
index 11ec824..f5718eb 100644
--- a/sw/device/lib/dif/autogen/dif_hmac_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_hmac_autogen.c
@@ -99,6 +99,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_hmac_irq_acknowledge_state(
+ const dif_hmac_t *hmac, dif_hmac_irq_state_snapshot_t snapshot) {
+ if (hmac == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_hmac_irq_is_pending(const dif_hmac_t *hmac, dif_hmac_irq_t irq,
bool *is_pending) {
if (hmac == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_hmac_autogen.h b/sw/device/lib/dif/autogen/dif_hmac_autogen.h
index c88b1c7..aea7add 100644
--- a/sw/device/lib/dif/autogen/dif_hmac_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_hmac_autogen.h
@@ -93,7 +93,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_hmac_irq_get_state()`
- * function.
+ * and `dif_hmac_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_hmac_irq_state_snapshot_t;
@@ -133,6 +133,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param hmac A hmac handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_hmac_irq_acknowledge_state(
+ const dif_hmac_t *hmac, dif_hmac_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_hmac_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_hmac_autogen_unittest.cc
index 5334a38..5fbf475 100644
--- a/sw/device/lib/dif/autogen/dif_hmac_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_hmac_autogen_unittest.cc
@@ -153,6 +153,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public HmacTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_hmac_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_hmac_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 3;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_hmac_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(HMAC_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_hmac_irq_acknowledge_state(&hmac_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_hmac_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(HMAC_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_hmac_irq_get_state(&hmac_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public HmacTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_i2c_autogen.c b/sw/device/lib/dif/autogen/dif_i2c_autogen.c
index 910d4ad..8c337ff 100644
--- a/sw/device/lib/dif/autogen/dif_i2c_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_i2c_autogen.c
@@ -135,6 +135,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_i2c_irq_acknowledge_state(
+ const dif_i2c_t *i2c, dif_i2c_irq_state_snapshot_t snapshot) {
+ if (i2c == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(i2c->base_addr, I2C_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_i2c_irq_is_pending(const dif_i2c_t *i2c, dif_i2c_irq_t irq,
bool *is_pending) {
if (i2c == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_i2c_autogen.h b/sw/device/lib/dif/autogen/dif_i2c_autogen.h
index fb8b9b9..e977a22 100644
--- a/sw/device/lib/dif/autogen/dif_i2c_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_i2c_autogen.h
@@ -153,7 +153,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_i2c_irq_get_state()`
- * function.
+ * and `dif_i2c_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_i2c_irq_state_snapshot_t;
@@ -193,6 +193,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param i2c A i2c handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_i2c_irq_acknowledge_state(
+ const dif_i2c_t *i2c, dif_i2c_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_i2c_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_i2c_autogen_unittest.cc
index 3d21c3a..9ec9adb 100644
--- a/sw/device/lib/dif/autogen/dif_i2c_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_i2c_autogen_unittest.cc
@@ -154,6 +154,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public I2cTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_i2c_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_i2c_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 15;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_i2c_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(I2C_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_i2c_irq_acknowledge_state(&i2c_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_i2c_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(I2C_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_i2c_irq_get_state(&i2c_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public I2cTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_keymgr_autogen.c b/sw/device/lib/dif/autogen/dif_keymgr_autogen.c
index ac6f1e8..a1ab67a 100644
--- a/sw/device/lib/dif/autogen/dif_keymgr_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_keymgr_autogen.c
@@ -96,6 +96,19 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_keymgr_irq_acknowledge_state(
+ const dif_keymgr_t *keymgr, dif_keymgr_irq_state_snapshot_t snapshot) {
+ if (keymgr == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(keymgr->base_addr, KEYMGR_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_irq_is_pending(const dif_keymgr_t *keymgr,
dif_keymgr_irq_t irq, bool *is_pending) {
if (keymgr == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_keymgr_autogen.h b/sw/device/lib/dif/autogen/dif_keymgr_autogen.h
index 179c6e4..05a14a2 100644
--- a/sw/device/lib/dif/autogen/dif_keymgr_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_keymgr_autogen.h
@@ -89,7 +89,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_keymgr_irq_get_state()`
- * function.
+ * and `dif_keymgr_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_keymgr_irq_state_snapshot_t;
@@ -130,6 +130,18 @@
dif_keymgr_irq_t irq, bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param keymgr A keymgr handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_keymgr_irq_acknowledge_state(
+ const dif_keymgr_t *keymgr, dif_keymgr_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_keymgr_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_keymgr_autogen_unittest.cc
index fea67c7..ecca5e1 100644
--- a/sw/device/lib/dif/autogen/dif_keymgr_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_keymgr_autogen_unittest.cc
@@ -153,6 +153,35 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public KeymgrTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_keymgr_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_keymgr_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_keymgr_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(KEYMGR_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_keymgr_irq_acknowledge_state(&keymgr_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_keymgr_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(KEYMGR_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_keymgr_irq_get_state(&keymgr_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public KeymgrTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_kmac_autogen.c b/sw/device/lib/dif/autogen/dif_kmac_autogen.c
index 9167899..cc0e34c 100644
--- a/sw/device/lib/dif/autogen/dif_kmac_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_kmac_autogen.c
@@ -102,6 +102,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_kmac_irq_acknowledge_state(
+ const dif_kmac_t *kmac, dif_kmac_irq_state_snapshot_t snapshot) {
+ if (kmac == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(kmac->base_addr, KMAC_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_kmac_irq_is_pending(const dif_kmac_t *kmac, dif_kmac_irq_t irq,
bool *is_pending) {
if (kmac == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_kmac_autogen.h b/sw/device/lib/dif/autogen/dif_kmac_autogen.h
index acee223..5550025 100644
--- a/sw/device/lib/dif/autogen/dif_kmac_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_kmac_autogen.h
@@ -102,7 +102,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_kmac_irq_get_state()`
- * function.
+ * and `dif_kmac_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_kmac_irq_state_snapshot_t;
@@ -142,6 +142,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param kmac A kmac handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_kmac_irq_acknowledge_state(
+ const dif_kmac_t *kmac, dif_kmac_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_kmac_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_kmac_autogen_unittest.cc
index 4507e78..13f7045 100644
--- a/sw/device/lib/dif/autogen/dif_kmac_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_kmac_autogen_unittest.cc
@@ -159,6 +159,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public KmacTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_kmac_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_kmac_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 3;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_kmac_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(KMAC_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_kmac_irq_acknowledge_state(&kmac_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_kmac_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(KMAC_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_kmac_irq_get_state(&kmac_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public KmacTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_otbn_autogen.c b/sw/device/lib/dif/autogen/dif_otbn_autogen.c
index 5b7b45f..010be29 100644
--- a/sw/device/lib/dif/autogen/dif_otbn_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_otbn_autogen.c
@@ -94,6 +94,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_otbn_irq_acknowledge_state(
+ const dif_otbn_t *otbn, dif_otbn_irq_state_snapshot_t snapshot) {
+ if (otbn == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(otbn->base_addr, OTBN_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_otbn_irq_is_pending(const dif_otbn_t *otbn, dif_otbn_irq_t irq,
bool *is_pending) {
if (otbn == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_otbn_autogen.h b/sw/device/lib/dif/autogen/dif_otbn_autogen.h
index 3756262..45defe6 100644
--- a/sw/device/lib/dif/autogen/dif_otbn_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_otbn_autogen.h
@@ -89,7 +89,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_otbn_irq_get_state()`
- * function.
+ * and `dif_otbn_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_otbn_irq_state_snapshot_t;
@@ -129,6 +129,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param otbn A otbn handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_otbn_irq_acknowledge_state(
+ const dif_otbn_t *otbn, dif_otbn_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_otbn_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_otbn_autogen_unittest.cc
index 4f73b13..1c603a2 100644
--- a/sw/device/lib/dif/autogen/dif_otbn_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_otbn_autogen_unittest.cc
@@ -144,6 +144,35 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public OtbnTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_otbn_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_otbn_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_otbn_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(OTBN_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_otbn_irq_acknowledge_state(&otbn_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_otbn_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(OTBN_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_otbn_irq_get_state(&otbn_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public OtbnTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.c
index b6eca4b..720e1b8 100644
--- a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.c
@@ -111,6 +111,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_otp_ctrl_irq_acknowledge_state(
+ const dif_otp_ctrl_t *otp_ctrl,
+ dif_otp_ctrl_irq_state_snapshot_t snapshot) {
+ if (otp_ctrl == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(otp_ctrl->base_addr, OTP_CTRL_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_otp_ctrl_irq_is_pending(const dif_otp_ctrl_t *otp_ctrl,
dif_otp_ctrl_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h
index af72f23..cdac8f9 100644
--- a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h
@@ -110,7 +110,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_otp_ctrl_irq_get_state()`
- * function.
+ * and `dif_otp_ctrl_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_otp_ctrl_irq_state_snapshot_t;
@@ -153,6 +153,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param otp_ctrl A otp_ctrl handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_otp_ctrl_irq_acknowledge_state(
+ const dif_otp_ctrl_t *otp_ctrl, dif_otp_ctrl_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen_unittest.cc
index ad03425..ddedbf3 100644
--- a/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_otp_ctrl_autogen_unittest.cc
@@ -164,6 +164,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public OtpCtrlTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_otp_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_otp_ctrl_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_otp_ctrl_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(OTP_CTRL_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_otp_ctrl_irq_acknowledge_state(&otp_ctrl_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_otp_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(OTP_CTRL_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_otp_ctrl_irq_get_state(&otp_ctrl_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public OtpCtrlTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_pattgen_autogen.c b/sw/device/lib/dif/autogen/dif_pattgen_autogen.c
index d76a9d3..b1b93c5 100644
--- a/sw/device/lib/dif/autogen/dif_pattgen_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_pattgen_autogen.c
@@ -97,6 +97,19 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_pattgen_irq_acknowledge_state(
+ const dif_pattgen_t *pattgen, dif_pattgen_irq_state_snapshot_t snapshot) {
+ if (pattgen == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(pattgen->base_addr, PATTGEN_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_pattgen_irq_is_pending(const dif_pattgen_t *pattgen,
dif_pattgen_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_pattgen_autogen.h b/sw/device/lib/dif/autogen/dif_pattgen_autogen.h
index cab64b4..d169813 100644
--- a/sw/device/lib/dif/autogen/dif_pattgen_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_pattgen_autogen.h
@@ -89,7 +89,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_pattgen_irq_get_state()`
- * function.
+ * and `dif_pattgen_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_pattgen_irq_state_snapshot_t;
@@ -131,6 +131,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param pattgen A pattgen handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_pattgen_irq_acknowledge_state(
+ const dif_pattgen_t *pattgen, dif_pattgen_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_pattgen_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_pattgen_autogen_unittest.cc
index 55aa08a..83cd631 100644
--- a/sw/device/lib/dif/autogen/dif_pattgen_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_pattgen_autogen_unittest.cc
@@ -157,6 +157,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public PattgenTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_pattgen_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_pattgen_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_pattgen_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(PATTGEN_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_pattgen_irq_acknowledge_state(&pattgen_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_pattgen_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(PATTGEN_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_pattgen_irq_get_state(&pattgen_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public PattgenTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.c b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.c
index 311a5fa..aad1b97 100644
--- a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.c
@@ -93,6 +93,19 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_pwrmgr_irq_acknowledge_state(
+ const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_irq_state_snapshot_t snapshot) {
+ if (pwrmgr == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(pwrmgr->base_addr, PWRMGR_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_pwrmgr_irq_is_pending(const dif_pwrmgr_t *pwrmgr,
dif_pwrmgr_irq_t irq, bool *is_pending) {
if (pwrmgr == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.h b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.h
index 7cdca36..af78fff 100644
--- a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen.h
@@ -85,7 +85,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_pwrmgr_irq_get_state()`
- * function.
+ * and `dif_pwrmgr_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_pwrmgr_irq_state_snapshot_t;
@@ -126,6 +126,18 @@
dif_pwrmgr_irq_t irq, bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param pwrmgr A pwrmgr handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_pwrmgr_irq_acknowledge_state(
+ const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen_unittest.cc
index bed7de1..c75e794 100644
--- a/sw/device/lib/dif/autogen/dif_pwrmgr_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_pwrmgr_autogen_unittest.cc
@@ -146,6 +146,35 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public PwrmgrTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_pwrmgr_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_pwrmgr_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_pwrmgr_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(PWRMGR_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_pwrmgr_irq_acknowledge_state(&pwrmgr_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_pwrmgr_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(PWRMGR_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_pwrmgr_irq_get_state(&pwrmgr_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public PwrmgrTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_rv_timer_autogen.c b/sw/device/lib/dif/autogen/dif_rv_timer_autogen.c
index f7ce78a..f52a477 100644
--- a/sw/device/lib/dif/autogen/dif_rv_timer_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_rv_timer_autogen.c
@@ -153,6 +153,27 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_rv_timer_irq_acknowledge_state(
+ const dif_rv_timer_t *rv_timer, uint32_t hart_id,
+ dif_rv_timer_irq_state_snapshot_t snapshot) {
+ if (rv_timer == NULL) {
+ return kDifBadArg;
+ }
+
+ switch (hart_id) {
+ case 0:
+ mmio_region_write32(rv_timer->base_addr, RV_TIMER_INTR_STATE0_REG_OFFSET,
+ snapshot);
+
+ break;
+ default:
+ return kDifBadArg;
+ }
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_rv_timer_irq_is_pending(const dif_rv_timer_t *rv_timer,
dif_rv_timer_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_rv_timer_autogen.h b/sw/device/lib/dif/autogen/dif_rv_timer_autogen.h
index 4c0575f..c2ffc47 100644
--- a/sw/device/lib/dif/autogen/dif_rv_timer_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_rv_timer_autogen.h
@@ -86,7 +86,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_rv_timer_irq_get_state()`
- * function.
+ * and `dif_rv_timer_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_rv_timer_irq_state_snapshot_t;
@@ -130,6 +130,20 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param rv_timer A rv_timer handle.
+ * @param hart_id The hart to manipulate.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_rv_timer_irq_acknowledge_state(
+ const dif_rv_timer_t *rv_timer, uint32_t hart_id,
+ dif_rv_timer_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_rv_timer_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_rv_timer_autogen_unittest.cc
index 71241c6..e1822af 100644
--- a/sw/device/lib/dif/autogen/dif_rv_timer_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_rv_timer_autogen_unittest.cc
@@ -151,6 +151,37 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public RvTimerTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_rv_timer_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_rv_timer_irq_acknowledge_state(nullptr, 0, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_rv_timer_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(RV_TIMER_INTR_STATE0_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_rv_timer_irq_acknowledge_state(&rv_timer_, 0, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_rv_timer_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(RV_TIMER_INTR_STATE0_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_rv_timer_irq_get_state(&rv_timer_, 0, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public RvTimerTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.c
index 74046a4..34c81b0 100644
--- a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.c
@@ -103,6 +103,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_sensor_ctrl_irq_acknowledge_state(
+ const dif_sensor_ctrl_t *sensor_ctrl,
+ dif_sensor_ctrl_irq_state_snapshot_t snapshot) {
+ if (sensor_ctrl == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_sensor_ctrl_irq_is_pending(
const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.h
index 532a3ca..ebd6410 100644
--- a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen.h
@@ -94,7 +94,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_sensor_ctrl_irq_get_state()`
- * function.
+ * and `dif_sensor_ctrl_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_sensor_ctrl_irq_state_snapshot_t;
@@ -137,6 +137,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param sensor_ctrl A sensor_ctrl handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_sensor_ctrl_irq_acknowledge_state(
+ const dif_sensor_ctrl_t *sensor_ctrl,
+ dif_sensor_ctrl_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen_unittest.cc
index 04c92a6..545ef9c 100644
--- a/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_sensor_ctrl_autogen_unittest.cc
@@ -165,6 +165,37 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public SensorCtrlTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_sensor_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_sensor_ctrl_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_sensor_ctrl_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(SENSOR_CTRL_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_sensor_ctrl_irq_acknowledge_state(&sensor_ctrl_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_sensor_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(SENSOR_CTRL_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_sensor_ctrl_irq_get_state(&sensor_ctrl_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public SensorCtrlTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen.c b/sw/device/lib/dif/autogen/dif_spi_device_autogen.c
index d9530b2..ca01fc4 100644
--- a/sw/device/lib/dif/autogen/dif_spi_device_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen.c
@@ -131,6 +131,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_spi_device_irq_acknowledge_state(
+ const dif_spi_device_t *spi_device,
+ dif_spi_device_irq_state_snapshot_t snapshot) {
+ if (spi_device == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(spi_device->base_addr, SPI_DEVICE_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_device_irq_is_pending(const dif_spi_device_t *spi_device,
dif_spi_device_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen.h b/sw/device/lib/dif/autogen/dif_spi_device_autogen.h
index 47b8990..b00c88f 100644
--- a/sw/device/lib/dif/autogen/dif_spi_device_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen.h
@@ -136,7 +136,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_spi_device_irq_get_state()`
- * function.
+ * and `dif_spi_device_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_spi_device_irq_state_snapshot_t;
@@ -179,6 +179,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param spi_device A spi_device handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_spi_device_irq_acknowledge_state(
+ const dif_spi_device_t *spi_device,
+ dif_spi_device_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc
index 79f6f54..14048a4 100644
--- a/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc
@@ -159,6 +159,37 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public SpiDeviceTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_spi_device_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_spi_device_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 12;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_spi_device_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(SPI_DEVICE_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_spi_device_irq_acknowledge_state(&spi_device_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_spi_device_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_spi_device_irq_get_state(&spi_device_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public SpiDeviceTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_spi_host_autogen.c b/sw/device/lib/dif/autogen/dif_spi_host_autogen.c
index b0bd395..95efb9b 100644
--- a/sw/device/lib/dif/autogen/dif_spi_host_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_spi_host_autogen.c
@@ -99,6 +99,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_spi_host_irq_acknowledge_state(
+ const dif_spi_host_t *spi_host,
+ dif_spi_host_irq_state_snapshot_t snapshot) {
+ if (spi_host == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(spi_host->base_addr, SPI_HOST_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_irq_is_pending(const dif_spi_host_t *spi_host,
dif_spi_host_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_spi_host_autogen.h b/sw/device/lib/dif/autogen/dif_spi_host_autogen.h
index 002248e..52773b2 100644
--- a/sw/device/lib/dif/autogen/dif_spi_host_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_spi_host_autogen.h
@@ -90,7 +90,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_spi_host_irq_get_state()`
- * function.
+ * and `dif_spi_host_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_spi_host_irq_state_snapshot_t;
@@ -133,6 +133,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param spi_host A spi_host handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_spi_host_irq_acknowledge_state(
+ const dif_spi_host_t *spi_host, dif_spi_host_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_spi_host_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_spi_host_autogen_unittest.cc
index e35bccb..65d1cca 100644
--- a/sw/device/lib/dif/autogen/dif_spi_host_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_spi_host_autogen_unittest.cc
@@ -158,6 +158,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public SpiHostTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_spi_host_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_spi_host_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 2;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_spi_host_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(SPI_HOST_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_spi_host_irq_acknowledge_state(&spi_host_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_spi_host_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(SPI_HOST_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_spi_host_irq_get_state(&spi_host_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public SpiHostTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.c
index bfadde8..6f5c2f5 100644
--- a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.c
@@ -96,6 +96,20 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_sysrst_ctrl_irq_acknowledge_state(
+ const dif_sysrst_ctrl_t *sysrst_ctrl,
+ dif_sysrst_ctrl_irq_state_snapshot_t snapshot) {
+ if (sysrst_ctrl == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(sysrst_ctrl->base_addr, SYSRST_CTRL_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_sysrst_ctrl_irq_is_pending(
const dif_sysrst_ctrl_t *sysrst_ctrl, dif_sysrst_ctrl_irq_t irq,
bool *is_pending) {
diff --git a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.h
index 050aa2c..5e253c5 100644
--- a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen.h
@@ -87,7 +87,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_sysrst_ctrl_irq_get_state()`
- * function.
+ * and `dif_sysrst_ctrl_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_sysrst_ctrl_irq_state_snapshot_t;
@@ -130,6 +130,19 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param sysrst_ctrl A sysrst_ctrl handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_sysrst_ctrl_irq_acknowledge_state(
+ const dif_sysrst_ctrl_t *sysrst_ctrl,
+ dif_sysrst_ctrl_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen_unittest.cc
index 026a27f..6d53283 100644
--- a/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_sysrst_ctrl_autogen_unittest.cc
@@ -151,6 +151,37 @@
EXPECT_TRUE(irq_state);
}
+class AcknowledgeStateTest : public SysrstCtrlTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_sysrst_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(
+ dif_sysrst_ctrl_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 1;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_sysrst_ctrl_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(SYSRST_CTRL_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(
+ dif_sysrst_ctrl_irq_acknowledge_state(&sysrst_ctrl_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_sysrst_ctrl_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(SYSRST_CTRL_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_sysrst_ctrl_irq_get_state(&sysrst_ctrl_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public SysrstCtrlTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_uart_autogen.c b/sw/device/lib/dif/autogen/dif_uart_autogen.c
index fd393d9..d68d85b 100644
--- a/sw/device/lib/dif/autogen/dif_uart_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_uart_autogen.c
@@ -113,6 +113,18 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_uart_irq_acknowledge_state(
+ const dif_uart_t *uart, dif_uart_irq_state_snapshot_t snapshot) {
+ if (uart == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(uart->base_addr, UART_INTR_STATE_REG_OFFSET, snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_uart_irq_is_pending(const dif_uart_t *uart, dif_uart_irq_t irq,
bool *is_pending) {
if (uart == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_uart_autogen.h b/sw/device/lib/dif/autogen/dif_uart_autogen.h
index 1366d9c..68d75f8 100644
--- a/sw/device/lib/dif/autogen/dif_uart_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_uart_autogen.h
@@ -114,7 +114,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_uart_irq_get_state()`
- * function.
+ * and `dif_uart_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_uart_irq_state_snapshot_t;
@@ -154,6 +154,18 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param uart A uart handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_uart_irq_acknowledge_state(
+ const dif_uart_t *uart, dif_uart_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_uart_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_uart_autogen_unittest.cc
index 99b152b..9775485 100644
--- a/sw/device/lib/dif/autogen/dif_uart_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_uart_autogen_unittest.cc
@@ -154,6 +154,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public UartTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_uart_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_uart_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 8;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_uart_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(UART_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_uart_irq_acknowledge_state(&uart_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_uart_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(UART_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_uart_irq_get_state(&uart_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public UartTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/sw/device/lib/dif/autogen/dif_usbdev_autogen.c b/sw/device/lib/dif/autogen/dif_usbdev_autogen.c
index 1582aa7..47b8e0a 100644
--- a/sw/device/lib/dif/autogen/dif_usbdev_autogen.c
+++ b/sw/device/lib/dif/autogen/dif_usbdev_autogen.c
@@ -145,6 +145,19 @@
}
OT_WARN_UNUSED_RESULT
+dif_result_t dif_usbdev_irq_acknowledge_state(
+ const dif_usbdev_t *usbdev, dif_usbdev_irq_state_snapshot_t snapshot) {
+ if (usbdev == NULL) {
+ return kDifBadArg;
+ }
+
+ mmio_region_write32(usbdev->base_addr, USBDEV_INTR_STATE_REG_OFFSET,
+ snapshot);
+
+ return kDifOk;
+}
+
+OT_WARN_UNUSED_RESULT
dif_result_t dif_usbdev_irq_is_pending(const dif_usbdev_t *usbdev,
dif_usbdev_irq_t irq, bool *is_pending) {
if (usbdev == NULL || is_pending == NULL) {
diff --git a/sw/device/lib/dif/autogen/dif_usbdev_autogen.h b/sw/device/lib/dif/autogen/dif_usbdev_autogen.h
index 2897282..293587c 100644
--- a/sw/device/lib/dif/autogen/dif_usbdev_autogen.h
+++ b/sw/device/lib/dif/autogen/dif_usbdev_autogen.h
@@ -170,7 +170,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_usbdev_irq_get_state()`
- * function.
+ * and `dif_usbdev_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_usbdev_irq_state_snapshot_t;
@@ -211,6 +211,18 @@
dif_usbdev_irq_t irq, bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param usbdev A usbdev handle.
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_usbdev_irq_acknowledge_state(
+ const dif_usbdev_t *usbdev, dif_usbdev_irq_state_snapshot_t snapshot);
+
+/**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/sw/device/lib/dif/autogen/dif_usbdev_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_usbdev_autogen_unittest.cc
index 0e549ab..ad3e952 100644
--- a/sw/device/lib/dif/autogen/dif_usbdev_autogen_unittest.cc
+++ b/sw/device/lib/dif/autogen/dif_usbdev_autogen_unittest.cc
@@ -156,6 +156,35 @@
EXPECT_FALSE(irq_state);
}
+class AcknowledgeStateTest : public UsbdevTest {};
+
+TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_usbdev_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_usbdev_irq_acknowledge_state(nullptr, irq_snapshot));
+}
+
+TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ const uint32_t num_irqs = 17;
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_usbdev_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ EXPECT_WRITE32(USBDEV_INTR_STATE_REG_OFFSET, irq_snapshot);
+ EXPECT_DIF_OK(dif_usbdev_irq_acknowledge_state(&usbdev_, irq_snapshot));
+ }
+}
+
+TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_usbdev_irq_state_snapshot_t irq_snapshot = 0;
+
+ EXPECT_READ32(USBDEV_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_DIF_OK(dif_usbdev_irq_get_state(&usbdev_, &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+}
+
class AcknowledgeAllTest : public UsbdevTest {};
TEST_F(AcknowledgeAllTest, NullArgs) {
diff --git a/util/make_new_dif/templates/dif_autogen.c.tpl b/util/make_new_dif/templates/dif_autogen.c.tpl
index 94a2ad5..cd859d5 100644
--- a/util/make_new_dif/templates/dif_autogen.c.tpl
+++ b/util/make_new_dif/templates/dif_autogen.c.tpl
@@ -248,6 +248,34 @@
}
OT_WARN_UNUSED_RESULT
+ dif_result_t dif_${ip.name_snake}_irq_acknowledge_state(
+ const dif_${ip.name_snake}_t *${ip.name_snake},
+ % if ip.name_snake == "rv_timer":
+ uint32_t hart_id,
+ % endif
+ dif_${ip.name_snake}_irq_state_snapshot_t snapshot) {
+ if (${ip.name_snake} == NULL) {
+ return kDifBadArg;
+ }
+
+ % if ip.name_snake == "rv_timer":
+ switch (hart_id) {
+ % for hart_id in range(int(ip.parameters["N_HARTS"].default)):
+ case ${hart_id}:
+ ${mmio_region_write32("RV_TIMER_INTR_STATE%d_REG_OFFSET" % hart_id, "snapshot")}
+ break;
+ % endfor
+ default:
+ return kDifBadArg;
+ }
+ % else:
+ ${mmio_region_write32(ip.name_upper + "_INTR_STATE_REG_OFFSET", "snapshot")}
+ % endif
+
+ return kDifOk;
+ }
+
+ OT_WARN_UNUSED_RESULT
dif_result_t dif_${ip.name_snake}_irq_is_pending(
const dif_${ip.name_snake}_t *${ip.name_snake},
dif_${ip.name_snake}_irq_t irq,
diff --git a/util/make_new_dif/templates/dif_autogen.h.tpl b/util/make_new_dif/templates/dif_autogen.h.tpl
index 28696a9..4451ed6 100644
--- a/util/make_new_dif/templates/dif_autogen.h.tpl
+++ b/util/make_new_dif/templates/dif_autogen.h.tpl
@@ -120,7 +120,7 @@
* A snapshot of the state of the interrupts for this IP.
*
* This is an opaque type, to be used with the `dif_${ip.name_snake}_irq_get_state()`
- * function.
+ * and `dif_${ip.name_snake}_irq_acknowledge_state()` functions.
*/
typedef uint32_t dif_${ip.name_snake}_irq_state_snapshot_t;
@@ -171,6 +171,25 @@
bool *is_pending);
/**
+ * Acknowledges all interrupts that were pending at the time of the state
+ * snapshot.
+ *
+ * @param ${ip.name_snake} A ${ip.name_snake} handle.
+ % if ip.name_snake == "rv_timer":
+ * @param hart_id The hart to manipulate.
+ % endif
+ * @param snapshot Interrupt state snapshot.
+ * @return The result of the operation.
+ */
+ OT_WARN_UNUSED_RESULT
+ dif_result_t dif_${ip.name_snake}_irq_acknowledge_state(
+ const dif_${ip.name_snake}_t *${ip.name_snake},
+ % if ip.name_snake == "rv_timer":
+ uint32_t hart_id,
+ % endif
+ dif_${ip.name_snake}_irq_state_snapshot_t snapshot);
+
+ /**
* Acknowledges all interrupts, indicating to the hardware that all
* interrupts have been successfully serviced.
*
diff --git a/util/make_new_dif/templates/dif_autogen_unittest.cc.tpl b/util/make_new_dif/templates/dif_autogen_unittest.cc.tpl
index 8549865..70596be 100644
--- a/util/make_new_dif/templates/dif_autogen_unittest.cc.tpl
+++ b/util/make_new_dif/templates/dif_autogen_unittest.cc.tpl
@@ -306,6 +306,65 @@
% endif
}
+ class AcknowledgeStateTest : public ${ip.name_camel}Test {};
+
+ TEST_F(AcknowledgeStateTest, NullArgs) {
+ dif_${ip.name_snake}_irq_state_snapshot_t irq_snapshot = 0;
+ EXPECT_DIF_BADARG(dif_${ip.name_snake}_irq_acknowledge_state(
+ nullptr,
+ % if ip.name_snake == "rv_timer":
+ 0,
+ % endif
+ irq_snapshot
+ ));
+ }
+
+ TEST_F(AcknowledgeStateTest, AckSnapshot) {
+ <%
+ num_irqs = 0
+ for irq in ip.irqs:
+ num_irqs += irq.width
+ %>
+ const uint32_t num_irqs = ${num_irqs};
+ const uint32_t irq_mask = (1u << num_irqs) - 1;
+ dif_${ip.name_snake}_irq_state_snapshot_t irq_snapshot = 1;
+
+ // Test a few snapshots.
+ for (size_t i = 0; i < num_irqs; ++i) {
+ irq_snapshot = ~irq_snapshot & irq_mask;
+ irq_snapshot |= (1u << i);
+ % if ip.name_snake == "rv_timer":
+ EXPECT_WRITE32(${ip.name_upper}_INTR_STATE0_REG_OFFSET,
+ % else:
+ EXPECT_WRITE32(${ip.name_upper}_INTR_STATE_REG_OFFSET,
+ % endif
+ irq_snapshot);
+ EXPECT_DIF_OK(dif_${ip.name_snake}_irq_acknowledge_state(
+ &${ip.name_snake}_,
+ % if ip.name_snake == "rv_timer":
+ 0,
+ % endif
+ irq_snapshot));
+ }
+ }
+
+ TEST_F(AcknowledgeStateTest, SuccessNoneRaised) {
+ dif_${ip.name_snake}_irq_state_snapshot_t irq_snapshot = 0;
+
+ % if ip.name_snake == "rv_timer":
+ EXPECT_READ32(${ip.name_upper}_INTR_STATE0_REG_OFFSET, 0);
+ % else:
+ EXPECT_READ32(${ip.name_upper}_INTR_STATE_REG_OFFSET, 0);
+ % endif
+ EXPECT_DIF_OK(dif_${ip.name_snake}_irq_get_state(
+ &${ip.name_snake}_,
+ % if ip.name_snake == "rv_timer":
+ 0,
+ % endif
+ &irq_snapshot));
+ EXPECT_EQ(irq_snapshot, 0);
+ }
+
class AcknowledgeAllTest : public ${ip.name_camel}Test {};
TEST_F(AcknowledgeAllTest, NullArgs) {