[PATCH v2 09/12] lib: utils: irqchip: Add helper to register VIRQ courier handler
Raymond Mao
raymondmaoca at gmail.com
Thu Oct 29 08:59:26 PDT 2026
From: Raymond Mao <raymond.mao at riscstar.com>
Add an APLIC helper to register a VIRQ courier handler for a supplied
HWIRQ and IRQ type, using the precomputed per-HWIRQ target hartindex
map.
Translate OpenSBI hart indices to APLIC IDC indices when programming
targets and setting affinity. Reject targets with no matching IDC
instead of directing interrupts to an unrelated fallback IDC.
Reuse the VIRQ registration helper to preserve the selected target
after handler registration, which initially selects the calling hart.
Treat SBI_EALREADY as deferred completion rather than an error when
processing hardware interrupts.
Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
include/sbi_utils/irqchip/aplic.h | 3 ++
lib/utils/irqchip/aplic.c | 57 +++++++++++++++++++++++++++++--
2 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/include/sbi_utils/irqchip/aplic.h b/include/sbi_utils/irqchip/aplic.h
index 76b39099..44bbfcf6 100644
--- a/include/sbi_utils/irqchip/aplic.h
+++ b/include/sbi_utils/irqchip/aplic.h
@@ -53,6 +53,9 @@ struct aplic_data {
int aplic_cold_irqchip_init(struct aplic_data *aplic);
+int aplic_init_virq_courier(struct aplic_data *aplic, u32 hwirq,
+ u32 hwirq_flags);
+
void aplic_reinit_all(void);
#endif
diff --git a/lib/utils/irqchip/aplic.c b/lib/utils/irqchip/aplic.c
index 3da9a717..b9a43115 100644
--- a/lib/utils/irqchip/aplic.c
+++ b/lib/utils/irqchip/aplic.c
@@ -13,6 +13,8 @@
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_heap.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_virq.h>
#include <sbi_utils/irqchip/aplic.h>
#define APLIC_MAX_IDC (1UL << 14)
@@ -426,7 +428,7 @@ static int aplic_process_hwirqs(struct sbi_irqchip_device *chip)
continue;
tmp = sbi_irqchip_process_hwirq(chip, hwirq);
- if (tmp)
+ if (tmp && tmp != SBI_EALREADY)
rc = tmp;
}
@@ -549,6 +551,19 @@ static int aplic_setup_msi(struct aplic_data *aplic, u32 hwirq)
return 0;
}
+static void aplic_set_target(struct sbi_irqchip_device *chip, u32 hwirq,
+ u32 idc_index)
+{
+ struct aplic_data *aplic = container_of(chip, struct aplic_data, irqchip);
+
+ aplic_target_write(aplic, hwirq, APLIC_TARGET_HART_IDX(idc_index) |
+ APLIC_TARGET_IPRIO(APLIC_DEFAULT_PRIORITY));
+ aplic_idc_write(aplic, idc_index, APLIC_IDC_IDELIVERY,
+ APLIC_ENABLE_IDELIVERY);
+ aplic_idc_write(aplic, idc_index, APLIC_IDC_ITHRESHOLD,
+ APLIC_ENABLE_ITHRESHOLD);
+}
+
static int aplic_hwirq_setup(struct sbi_irqchip_device *chip,
u32 hwirq, u32 hwirq_flags)
{
@@ -637,7 +652,7 @@ static int aplic_hwirq_set_affinity(struct sbi_irqchip_device *chip,
return SBI_EINVAL;
aplic_target_write(aplic, hwirq,
- APLIC_TARGET_HART_IDX(hart_index) |
+ APLIC_TARGET_HART_IDX(idc_index) |
APLIC_TARGET_IPRIO(APLIC_DEFAULT_PRIORITY));
return 0;
@@ -676,6 +691,44 @@ static struct sbi_irqchip_device aplic_irqchip_template = {
.hwirq_unmask = aplic_hwirq_unmask,
};
+int aplic_init_virq_courier(struct aplic_data *aplic, u32 hwirq,
+ u32 hwirq_flags)
+{
+ u32 irq, hartindex = current_hartindex();
+ int idc_idx;
+ int rc;
+
+ if (!aplic || !aplic->targets_mmode || !aplic_is_direct_mode(aplic))
+ return SBI_ENOTSUPP;
+ if (!hwirq || hwirq > aplic->num_source)
+ return SBI_EINVAL;
+
+ if (!sbi_virq_is_inited()) {
+ rc = sbi_virq_init(aplic->num_source);
+ if (rc)
+ return rc;
+ }
+
+ for (irq = 1; irq <= aplic->num_source; irq++) {
+ u32 hartidx;
+
+ if (!aplic->hwirq_target_hartindex)
+ break;
+ hartidx = aplic->hwirq_target_hartindex[irq];
+ if (hartidx == -1U)
+ continue;
+ idc_idx = aplic_find_idc_index(aplic, hartidx);
+ if (idc_idx < 0)
+ return SBI_EINVAL;
+ aplic_set_target(&aplic->irqchip, irq, idc_idx);
+ }
+ if (aplic->hwirq_target_hartindex &&
+ aplic->hwirq_target_hartindex[hwirq] != -1U)
+ hartindex = aplic->hwirq_target_hartindex[hwirq];
+ return sbi_virq_register_courier(&aplic->irqchip, hwirq, hwirq_flags,
+ hartindex);
+}
+
int aplic_cold_irqchip_init(struct aplic_data *aplic)
{
int rc;
--
2.25.1
More information about the opensbi
mailing list