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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox