[PATCH v2 03/12] lib: irqchip: add S-mode notification helpers

Raymond Mao raymondmaoca at gmail.com
Thu Oct 29 08:59:20 PDT 2026


From: Raymond Mao <raymond.mao at riscstar.com>

Add irqchip helpers to set/clear S-mode notification (SEIP-based).
In addition to set/clear, expose a get API to read the current
notification state so upper layers can do edge-triggered notification.

Allow raw handlers to return SBI_EALREADY when physical completion is
deferred to the recipient, instead of issuing an immediate EOI. Preserve
ordinary completion behavior for other handler results.

Release handler storage when unregistering an interrupt handler so failed
courier setup can roll back without leaking memory.

Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
 include/sbi/sbi_irqchip.h |  9 +++++++++
 lib/sbi/sbi_irqchip.c     | 21 +++++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/sbi/sbi_irqchip.h b/include/sbi/sbi_irqchip.h
index f5dbf1c7..174fa930 100644
--- a/include/sbi/sbi_irqchip.h
+++ b/include/sbi/sbi_irqchip.h
@@ -172,4 +172,13 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch);
 bool sbi_irqchip_is_hwirq_enabled(struct sbi_irqchip_device *chip,
 				   u32 hwirq);
 
+/** Notify S-mode for a pending virtual interrupt on this hart. */
+int sbi_irqchip_notify_smode_set(void);
+
+/** Clear S-mode notification for virtual interrupts on this hart. */
+void sbi_irqchip_notify_smode_clear(void);
+
+/** Read S-mode notification state for virtual interrupts on this hart. */
+bool sbi_irqchip_notify_smode_get(void);
+
 #endif
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 1664bd2d..f9afadc0 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -14,6 +14,7 @@
 #include <sbi/sbi_list.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
+#include <sbi/riscv_asm.h>
 
 /** Internal irqchip hardware interrupt data */
 struct sbi_irqchip_hwirq_data {
@@ -191,9 +192,8 @@ int sbi_irqchip_raw_handler_default(struct sbi_irqchip_device *chip, u32 hwirq)
 	if (h->callback)
 		rc = h->callback(hwirq, h->priv);
 
-	if (chip->hwirq_eoi)
+	if (chip->hwirq_eoi && rc != SBI_EALREADY)
 		chip->hwirq_eoi(chip, hwirq);
-
 	return rc;
 }
 
@@ -471,6 +471,7 @@ int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
 	}
 
 	sbi_list_del(&fh->node);
+	sbi_free(fh);
 	return 0;
 }
 
@@ -618,3 +619,19 @@ skip_migrate:
 	if (hd && hd->chip && hd->chip->process_hwirqs)
 		csr_clear(CSR_MIE, MIP_MEIP);
 }
+
+int sbi_irqchip_notify_smode_set(void)
+{
+	csr_set(CSR_MIP, MIP_SEIP);
+	return 0;
+}
+
+void sbi_irqchip_notify_smode_clear(void)
+{
+	csr_clear(CSR_MIP, MIP_SEIP);
+}
+
+bool sbi_irqchip_notify_smode_get(void)
+{
+	return !!(csr_read(CSR_MIP) & MIP_SEIP);
+}
-- 
2.25.1




More information about the opensbi mailing list