[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) {