[RFC PATCH 1/2] lib: sbi: introduce INTC abstraction for wired interrupts
Raymond Mao
raymondmaoca at gmail.com
Tue Jan 27 07:23:41 PST 2026
From: Raymond Mao <raymond.mao at riscstar.com>
Add a wired interrupt-controller (INTC) abstraction to OpenSBI.
This introduces a small provider interface based on
claim/complete/mask/unmak semantics, allowing to register a wired
interrupt controller as a provider.
Plus, add virtual IRQ number mapping to avoid exposure of hwirq.
Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
sbi_intc.h | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 sbi_intc.h
diff --git a/sbi_intc.h b/sbi_intc.h
new file mode 100644
index 00000000..f51974c9
--- /dev/null
+++ b/sbi_intc.h
@@ -0,0 +1,99 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <raymond.mao at riscstar.com>
+ */
+
+#ifndef __SBI_INTC_H__
+#define __SBI_INTC_H__
+
+#include <sbi/sbi_types.h>
+
+/* Handler for a specified IRQ number */
+typedef int (*sbi_intc_irq_handler_t)(u32 irq, void *priv);
+
+/*
+ * Provider capabilities, at the moment it contains the maximum valid source ID
+ * but extensible in the future
+ */
+struct sbi_intc_provider_caps {
+ /*
+ * Maximum supported wired source ID for this provider.
+ *
+ * For APLIC this corresponds to the highest valid source ID (1..N).
+ * The INTC core treats this as an abstract provider source ID space.
+ */
+ u32 max_src;
+};
+
+/* Provider operations */
+struct sbi_intc_provider_ops {
+ /*
+ * Query provider capabilities.
+ *
+ * This avoids exposing provider-specific limits (such as APLIC
+ * num_source) through the registration API.
+ */
+ int (*get_caps)(void *ctx, struct sbi_intc_provider_caps *caps);
+
+ /*
+ * Claim a pending wired interrupt on current hart.
+ * Returns:
+ * SBI_OK : *hwirq is valid
+ * SBI_ENOENT : no pending wired interrupt
+ * <0 : error
+ */
+ int (*claim)(void *ctx, u32 *irq);
+
+ /*
+ * Complete/acknowledge a previously claimed wired interrupt
+ * (if required by HW).
+ * Some HW may not require an explicit completion.
+ */
+ void (*complete)(void *ctx, u32 irq);
+
+ /*
+ * mask/unmask a wired interrupt line.
+ *
+ * These are required for reliable couriering of level-triggered device
+ * interrupts to S-mode: mask in M-mode before enqueueing, and unmask
+ * after S-mode has cleared the device interrupt source.
+ */
+ void (*mask)(void *ctx, u32 irq);
+ void (*unmask)(void *ctx, u32 irq);
+};
+
+/* Register the active wired interrupt provider, e.g. APLIC, via ops and ctx */
+int sbi_intc_register_provider(const struct sbi_intc_provider_ops *ops,
+ void *ctx);
+
+/*
+ * Optional: map a IRQ number (irq) to a hardware wired IRQ (hwirq).
+ *
+ * If no explicit mapping exists, 'irq==hwirq' is assumed.
+ *
+ * This allows upper layers (e.g. VIRQ courier/emulation) to use stable irq
+ * identifiers without exposing the wired controller's hwirq numbering.
+ */
+int sbi_intc_map_irq(u32 irq, u32 hwirq);
+int sbi_intc_unmap_irq(u32 irq);
+u32 sbi_intc_irq_to_hwirq(u32 irq);
+u32 sbi_intc_hwirq_to_irq(u32 hwirq);
+
+/* Set/clear handler for a specified IRQ number */
+int sbi_intc_set_handler(u32 irq, sbi_intc_irq_handler_t handler, void *priv);
+int sbi_intc_clear_handler(u32 irq);
+
+/*
+ * Platform independent mask/unmak wrappers on top of platform registered
+ * mask/unmask ops functions.
+ */
+void sbi_intc_mask_irq(u32 irq);
+void sbi_intc_unmask_irq(u32 irq);
+
+/* External interrupt handler (for irqchip device hook 'irqchip.irq_handle') */
+int sbi_intc_handle_external_irq(void);
+
+#endif
--
2.25.1
More information about the opensbi
mailing list