| // Copyright lowRISC contributors. | |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| // SPDX-License-Identifier: Apache-2.0 | |
| ${autogen_banner} | |
| #include "sw/device/lib/testing/autogen/isr_testutils.h" | |
| #include "sw/device/lib/dif/dif_base.h" | |
| #include "sw/device/lib/dif/dif_rv_plic.h" | |
| % for ip in ips_with_difs: | |
| % if ip.irqs: | |
| #include "sw/device/lib/dif/dif_${ip.name_snake}.h" | |
| % endif | |
| % endfor | |
| #include "sw/device/lib/testing/test_framework/check.h" | |
| #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated. | |
| % for ip in ips_with_difs: | |
| % if ip.irqs: | |
| void isr_testutils_${ip.name_snake}_isr( | |
| plic_isr_ctx_t plic_ctx, | |
| ${ip.name_snake}_isr_ctx_t ${ip.name_snake}_ctx, | |
| top_earlgrey_plic_peripheral_t *peripheral_serviced, | |
| dif_${ip.name_snake}_irq_t *irq_serviced) { | |
| // Claim the IRQ at the PLIC. | |
| dif_rv_plic_irq_id_t plic_irq_id; | |
| CHECK_DIF_OK(dif_rv_plic_irq_claim( | |
| plic_ctx.rv_plic, | |
| plic_ctx.hart_id, | |
| &plic_irq_id)); | |
| // Get the peripheral the IRQ belongs to. | |
| *peripheral_serviced = (top_earlgrey_plic_peripheral_t) | |
| top_earlgrey_plic_interrupt_for_peripheral[plic_irq_id]; | |
| // Get the IRQ that was fired from the PLIC IRQ ID. | |
| dif_${ip.name_snake}_irq_t irq = (dif_${ip.name_snake}_irq_t)(plic_irq_id - | |
| ${ip.name_snake}_ctx.plic_${ip.name_snake}_start_irq_id); | |
| *irq_serviced = irq; | |
| // Check if it is supposed to be the only IRQ fired. | |
| if (${ip.name_snake}_ctx.is_only_irq) { | |
| dif_${ip.name_snake}_irq_state_snapshot_t snapshot; | |
| CHECK_DIF_OK(dif_${ip.name_snake}_irq_get_state( | |
| ${ip.name_snake}_ctx.${ip.name_snake}, | |
| % if ip.name_snake == "rv_timer": | |
| plic_ctx.hart_id, | |
| % endif | |
| &snapshot)); | |
| CHECK(snapshot == (dif_${ip.name_snake}_irq_state_snapshot_t)(1 << irq), | |
| "Only ${ip.name_snake} IRQ %d expected to fire. Actual IRQ state = %x", | |
| irq, snapshot); | |
| } | |
| % if ip.name_snake == "adc_ctrl": | |
| // TODO(lowRISC/opentitan:#11354): future releases of the ADC Controller HW should hide | |
| // the need to also clear the cause CSRs. At which point, this can be removed. | |
| CHECK_DIF_OK(dif_${ip.name_snake}_irq_clear_causes( | |
| ${ip.name_snake}_ctx.${ip.name_snake}, | |
| kDifAdcCtrlIrqCauseAll)); | |
| % endif | |
| // Acknowledge the IRQ at the peripheral if IRQ is of the event type. | |
| dif_irq_type_t type; | |
| CHECK_DIF_OK(dif_${ip.name_snake}_irq_get_type( | |
| ${ip.name_snake}_ctx.${ip.name_snake}, irq, &type)); | |
| if (type == kDifIrqTypeEvent) { | |
| CHECK_DIF_OK(dif_${ip.name_snake}_irq_acknowledge( | |
| ${ip.name_snake}_ctx.${ip.name_snake}, | |
| irq)); | |
| } | |
| // Complete the IRQ at the PLIC. | |
| CHECK_DIF_OK(dif_rv_plic_irq_complete( | |
| plic_ctx.rv_plic, | |
| plic_ctx.hart_id, | |
| plic_irq_id)); | |
| } | |
| % endif | |
| % endfor |