On 1/6/26 5:05 AM, Jay Chang wrote:
When software clears CMD_ILL or CQMF error bits by writing 1 to CQCSR,
the IOMMU should re-check the command queue and continue processing
pending commands if head != tail.

Per RISC-V IOMMU specification, the software error recovery sequence:

   1. Read the head pointer
   2. Software has two options:
      - Option 1: Set tail = head to re-start from an empty queue
      - Option 2: Overwrite the illegal command with a valid one
   3. Re-enable the command queue by writing 1 to cqcsr.cmd_ill

   "At this point, IOMMU will start working on the first command
    in the queue."

Signed-off-by: Jay Chang <[email protected]>
Reviewed-by: Frank Chang <[email protected]>
---

Reviewed-by: Daniel Henrique Barboza <[email protected]>

  hw/riscv/riscv-iommu.c | 10 ++++++++++
  1 file changed, 10 insertions(+)

diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index b46b337375..e89a262a63 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -1992,6 +1992,16 @@ static void 
riscv_iommu_process_cq_control(RISCVIOMMUState *s)
      }
riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, ctrl_set, ctrl_clr);
+
+    /*
+     * After clearing error bits (CMD_ILL, CQMF), if queue is still active,
+     * re-process pending command.
+     */
+    ctrl_set = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_CQCSR);
+    if ((ctrl_set & RISCV_IOMMU_CQCSR_CQON) &&
+        !(ctrl_set & (RISCV_IOMMU_CQCSR_CMD_ILL | RISCV_IOMMU_CQCSR_CQMF))) {
+        riscv_iommu_process_cq_tail(s);
+    }
  }
static void riscv_iommu_process_fq_control(RISCVIOMMUState *s)


Reply via email to