From: Raymond Mao <raymondmaoca@gmail.com>
To: opensbi@lists.infradead.org
Cc: scott@riscstar.com, dave.patel@riscstar.com,
raymond.mao@riscstar.com, robin.randhawa@sifive.com,
samuel.holland@sifive.com, anup.patel@qti.qualcomm.com,
anuppate@qti.qualcomm.com, anup@brainfault.org,
dhaval@rivosinc.com, peter.lin@sifive.com
Subject: [PATCH 08/10] lib: irqchip: support deferred completion and per-HWIRQ APLIC targets
Date: Thu, 14 May 2026 18:57:54 -0400 [thread overview]
Message-ID: <20260514225756.2255758-9-raymondmaoca@gmail.com> (raw)
In-Reply-To: <20260514225756.2255758-1-raymondmaoca@gmail.com>
From: Raymond Mao <raymond.mao@riscstar.com>
Lazily resolve the active irqchip provider for each hart when the
scratch-local provider is not yet populated.
Program APLIC target IDCs from the precomputed per-HWIRQ hart map,
and treat SBI_EALREADY as deferred completion so the normal process
path does not complete an interrupt that will be finished later by
the VIRQ flow.
Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
---
lib/sbi/sbi_irqchip.c | 21 ++++++++++++++
lib/utils/irqchip/aplic.c | 60 ++++++++++++++++++++++++++++++---------
2 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index e022d534..45b2992f 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -45,11 +45,28 @@ struct sbi_irqchip_hart_data {
static unsigned long irqchip_hart_data_off;
static SBI_LIST_HEAD(irqchip_list);
+static struct sbi_irqchip_device *sbi_irqchip_find_hart_device(u32 hartindex)
+{
+ struct sbi_irqchip_device *chip;
+
+ sbi_list_for_each_entry(chip, &irqchip_list, node) {
+ if (!chip->process_hwirqs)
+ continue;
+ if (!sbi_hartmask_test_hartindex(hartindex, &chip->target_harts))
+ continue;
+ return chip;
+ }
+
+ return NULL;
+}
+
int sbi_irqchip_process(void)
{
struct sbi_irqchip_hart_data *hd;
hd = sbi_scratch_thishart_offset_ptr(irqchip_hart_data_off);
+ if (hd && !hd->chip)
+ hd->chip = sbi_irqchip_find_hart_device(current_hartindex());
if (!hd || !hd->chip || !hd->chip->process_hwirqs)
return SBI_ENODEV;
@@ -306,6 +323,8 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
}
hd = sbi_scratch_thishart_offset_ptr(irqchip_hart_data_off);
+ if (hd && !hd->chip)
+ hd->chip = sbi_irqchip_find_hart_device(current_hartindex());
if (hd && hd->chip && hd->chip->process_hwirqs)
csr_set(CSR_MIE, MIP_MEIP);
@@ -317,6 +336,8 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch)
struct sbi_irqchip_hart_data *hd;
hd = sbi_scratch_thishart_offset_ptr(irqchip_hart_data_off);
+ if (hd && !hd->chip)
+ hd->chip = sbi_irqchip_find_hart_device(current_hartindex());
if (hd && hd->chip && hd->chip->process_hwirqs)
csr_clear(CSR_MIE, MIP_MEIP);
}
diff --git a/lib/utils/irqchip/aplic.c b/lib/utils/irqchip/aplic.c
index 82efdb71..77743685 100644
--- a/lib/utils/irqchip/aplic.c
+++ b/lib/utils/irqchip/aplic.c
@@ -306,6 +306,8 @@ static inline struct aplic_data *aplic_irqchip_to_data(struct sbi_irqchip_device
return container_of(chip, struct aplic_data, irqchip);
}
+static bool aplic_mmode_direct(const struct aplic_data *aplic);
+
static bool aplic_hwirq_delegated(const struct aplic_data *aplic, u32 hwirq)
{
u32 i;
@@ -441,10 +443,49 @@ static int aplic_hwirq_claim(struct sbi_irqchip_device *chip, u32 *hwirq)
return SBI_OK;
}
+static void aplic_set_target(struct aplic_data *aplic, u32 hwirq, u32 idc_index)
+{
+ unsigned long idc;
+
+ if (!aplic->addr || !hwirq || hwirq > aplic->num_source)
+ return;
+ if (aplic->num_idc <= idc_index)
+ return;
+
+ idc = aplic->addr + APLIC_IDC_BASE +
+ (unsigned long)idc_index * APLIC_IDC_SIZE;
+
+ writel((idc_index << APLIC_TARGET_HART_IDX_SHIFT) |
+ APLIC_DEFAULT_PRIORITY,
+ (void *)(aplic->addr + APLIC_TARGET_BASE + (hwirq - 1) * 4));
+
+ /* IDC delivery */
+ writel(APLIC_ENABLE_IDELIVERY, (void *)(idc + APLIC_IDC_IDELIVERY));
+ writel(APLIC_ENABLE_ITHRESHOLD, (void *)(idc + APLIC_IDC_ITHRESHOLD));
+}
+
+static int aplic_hwirq_setup_target_idc_index(struct aplic_data *aplic,
+ struct sbi_irqchip_device *chip,
+ u32 hwirq)
+{
+ u32 hartindex;
+ int idc_index;
+
+ if (aplic->hwirq_target_hartindex) {
+ hartindex = aplic->hwirq_target_hartindex[hwirq];
+ if (hartindex != -1U) {
+ idc_index = aplic_hartindex_to_idc_index(aplic, hartindex);
+ if (idc_index >= 0)
+ return idc_index;
+ }
+ }
+
+ return aplic_hwirq_target_idc_index(chip);
+}
+
static int aplic_hwirq_setup(struct sbi_irqchip_device *chip, u32 hwirq)
{
struct aplic_data *aplic = aplic_irqchip_to_data(chip);
- unsigned long idc;
int idc_index;
if (!hwirq || hwirq > aplic->num_source)
@@ -454,29 +495,19 @@ static int aplic_hwirq_setup(struct sbi_irqchip_device *chip, u32 hwirq)
if (aplic_hwirq_delegated(aplic, hwirq))
return SBI_ENOTSUPP;
- idc_index = aplic_hwirq_target_idc_index(chip);
+ idc_index = aplic_hwirq_setup_target_idc_index(aplic, chip, hwirq);
if (idc_index < 0)
return idc_index;
- idc = aplic->addr + APLIC_IDC_BASE + idc_index * APLIC_IDC_SIZE;
-
/* APLIC: sourcecfg/target/enable */
writel(APLIC_SOURCECFG_SM_LEVEL_HIGH,
(void *)(aplic->addr + APLIC_SOURCECFG_BASE + (hwirq - 1) * 4));
-
- writel(((u32)idc_index << APLIC_TARGET_HART_IDX_SHIFT) |
- APLIC_DEFAULT_PRIORITY,
- (void *)(aplic->addr + APLIC_TARGET_BASE + (hwirq - 1) * 4));
-
+ aplic_set_target(aplic, hwirq, (u32)idc_index);
writel(hwirq, (void *)(aplic->addr + APLIC_SETIENUM));
/* Direct mode for aia=aplic: DM=0 => don't set DM bit */
writel(aplic_domaincfg_value(), (void *)(aplic->addr + APLIC_DOMAINCFG));
- /* IDC delivery */
- writel(APLIC_ENABLE_IDELIVERY, (void *)(idc + APLIC_IDC_IDELIVERY));
- writel(APLIC_ENABLE_ITHRESHOLD, (void *)(idc + APLIC_IDC_ITHRESHOLD));
-
return SBI_OK;
}
@@ -502,6 +533,9 @@ static int aplic_process_hwirqs(struct sbi_irqchip_device *chip)
}
rc = sbi_irqchip_process_hwirq(chip, hwirq);
+ /* Deferred completion paths consume the IRQ without EOI here. */
+ if (rc == SBI_EALREADY)
+ return SBI_OK;
if (rc)
return rc;
}
--
2.25.1
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
next prev parent reply other threads:[~2026-05-14 22:58 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-14 22:57 [PATCH 00/10] Introduce Virtual IRQ (VIRQ) framework Raymond Mao
2026-05-14 22:57 ` [PATCH 01/10] lib: irqchip: add S-mode notification helpers Raymond Mao
2026-05-14 22:57 ` [PATCH 02/10] lib: sbi: domain: adaptation for supporting VIRQ couriering domain context switch Raymond Mao
2026-05-14 22:57 ` [PATCH 03/10] lib: sbi: Add Virtual IRQ (VIRQ) subsystem Raymond Mao
2026-05-14 22:57 ` [PATCH 04/10] lib: sbi: Add VIRQ ecall extension Raymond Mao
2026-05-14 22:57 ` [PATCH 05/10] lib: sbi: domain: add domain lookup by name Raymond Mao
2026-05-14 22:57 ` [PATCH 06/10] lib: utils: fdt: parse sysirq routing from DT Raymond Mao
2026-05-14 22:57 ` [PATCH 07/10] lib: utils: irqchip: derive APLIC targets from sysirq nodes Raymond Mao
2026-05-14 22:57 ` Raymond Mao [this message]
2026-05-14 22:57 ` [PATCH 09/10] lib: sbi: domain: ensure boot_hartid is assigned Raymond Mao
2026-05-14 22:57 ` [PATCH 10/10] docs: domain: document sysirq VIRQ mapping and routing rules Raymond Mao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260514225756.2255758-9-raymondmaoca@gmail.com \
--to=raymondmaoca@gmail.com \
--cc=anup.patel@qti.qualcomm.com \
--cc=anup@brainfault.org \
--cc=anuppate@qti.qualcomm.com \
--cc=dave.patel@riscstar.com \
--cc=dhaval@rivosinc.com \
--cc=opensbi@lists.infradead.org \
--cc=peter.lin@sifive.com \
--cc=raymond.mao@riscstar.com \
--cc=robin.randhawa@sifive.com \
--cc=samuel.holland@sifive.com \
--cc=scott@riscstar.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.