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 06/10] lib: utils: fdt: parse sysirq routing from DT
Date: Thu, 14 May 2026 18:57:52 -0400 [thread overview]
Message-ID: <20260514225756.2255758-7-raymondmaoca@gmail.com> (raw)
In-Reply-To: <20260514225756.2255758-1-raymondmaoca@gmail.com>
From: Raymond Mao <raymond.mao@riscstar.com>
Init VIRQ and parse mpxy-sysirq nodes under /chosen/opensbi-domains,
pre-size per-channel VIRQ maps, and add HWIRQ routes from
interrupts-extended.
Mark sysirq domains to allow SEIP-based VIRQ notification.
Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
---
include/sbi_utils/fdt/fdt_helper.h | 17 +++++
lib/utils/fdt/fdt_domain.c | 119 ++++++++++++++++++++++++++++-
lib/utils/fdt/fdt_helper.c | 49 ++++++++++++
3 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 04c850cc..e49a5bca 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -12,6 +12,7 @@
#include <sbi/sbi_types.h>
#include <sbi/sbi_domain.h>
+#include <sbi/sbi_irqchip.h>
struct fdt_match {
const char *compatible;
@@ -38,6 +39,22 @@ int fdt_parse_phandle_with_args(const void *fdt, int nodeoff,
const char *prop, const char *cells_prop,
int index, struct fdt_phandle_args *out_args);
+/*
+ * Parse one entry from "interrupts-extended" and return irqchip device,
+ * hwirq, and optional flags.
+ *
+ * @index: entry index within interrupts-extended
+ * @out_flags_count: in/out, on input capacity of out_flags array;
+ * on output number of flags returned (or total flags
+ * if out_flags is NULL).
+ */
+int fdt_parse_interrupts_extended_entry(const void *fdt, int nodeoff,
+ int index,
+ struct sbi_irqchip_device **out_chip,
+ u32 *out_hwirq,
+ u32 *out_flags,
+ u32 *out_flags_count);
+
int fdt_get_node_addr_size(const void *fdt, int node, int index,
uint64_t *addr, uint64_t *size);
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index b2fa8633..4a75f25a 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -10,11 +10,14 @@
#include <libfdt.h>
#include <libfdt_env.h>
+#include <sbi/sbi_console.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_heap.h>
+#include <sbi/sbi_irqchip.h>
#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_virq.h>
#include <sbi_utils/fdt/fdt_domain.h>
#include <sbi_utils/fdt/fdt_helper.h>
@@ -304,6 +307,7 @@ static int __fdt_parse_region(const void *fdt, int domain_offset,
return 0;
}
+
static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
{
u32 val32;
@@ -511,6 +515,113 @@ fail_free_domain:
return err;
}
+static int __fdt_parse_mpxy_sysirq_node(const void *fdt, int nodeoff)
+{
+ const fdt32_t *val;
+ int len, rc, doff;
+ u32 channel_id;
+ u32 index;
+ struct sbi_domain *dom;
+
+ if (!fdt || nodeoff < 0)
+ return SBI_EINVAL;
+
+ val = fdt_getprop(fdt, nodeoff, "opensbi,mpxy-channel-id", &len);
+ if (!val || len < (int)sizeof(fdt32_t)) {
+ sbi_printf("[SYSIRQ] missing opensbi,mpxy-channel-id\n");
+ return SBI_EINVAL;
+ }
+ channel_id = fdt32_to_cpu(*val);
+
+ val = fdt_getprop(fdt, nodeoff, "opensbi,domain", &len);
+ if (!val || len < (int)sizeof(fdt32_t)) {
+ sbi_printf("[SYSIRQ] missing opensbi,domain\n");
+ return SBI_EINVAL;
+ }
+
+ doff = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*val));
+ if (doff < 0)
+ return doff;
+
+ dom = sbi_domain_find_by_name(fdt_get_name(fdt, doff, NULL));
+ if (!dom) {
+ sbi_printf("[SYSIRQ] domain not found for node %s\n",
+ fdt_get_name(fdt, doff, NULL));
+ return SBI_ENOENT;
+ }
+ dom->virq_seip_notify = true;
+
+ /* Pre-allocate VIRQ map based on interrupts-extended count */
+ for (index = 0; ; index++) {
+ rc = fdt_parse_interrupts_extended_entry(fdt, nodeoff, index,
+ NULL, NULL,
+ NULL, NULL);
+ if (rc == SBI_ENOENT)
+ break;
+ if (rc)
+ return rc;
+ }
+
+ if (!sbi_virq_is_inited())
+ rc = sbi_virq_init(index);
+ else
+ rc = sbi_virq_map_ensure_cap(channel_id, index);
+ if (rc)
+ return rc;
+
+ for (index = 0; ; index++) {
+ struct sbi_irqchip_device *chip = NULL;
+ u32 hwirq = 0;
+
+ rc = fdt_parse_interrupts_extended_entry(fdt, nodeoff, index,
+ &chip, &hwirq,
+ NULL, NULL);
+ if (rc == SBI_ENOENT)
+ break;
+ if (rc)
+ return rc;
+ if (!chip)
+ return SBI_ENODEV;
+
+ rc = sbi_virq_map_set(channel_id, chip->id, hwirq, index);
+ if (rc)
+ return rc;
+
+ rc = sbi_virq_route_add(dom, hwirq, channel_id);
+ if (rc)
+ return rc;
+ }
+
+ return SBI_OK;
+}
+
+static int __fdt_parse_mpxy_sysirq_nodes(const void *fdt)
+{
+ int poffset, noff, rc;
+
+ if (!fdt)
+ return SBI_EINVAL;
+
+ poffset = fdt_path_offset(fdt, "/chosen");
+ if (poffset < 0)
+ return 0;
+ poffset = fdt_node_offset_by_compatible(fdt, poffset,
+ "opensbi,domain,config");
+ if (poffset < 0)
+ return 0;
+
+ fdt_for_each_subnode(noff, fdt, poffset) {
+ if (fdt_node_check_compatible(fdt, noff,
+ "opensbi,mpxy-sysirq"))
+ continue;
+ rc = __fdt_parse_mpxy_sysirq_node(fdt, noff);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
int fdt_domains_populate(const void *fdt)
{
const u32 *val;
@@ -550,6 +661,10 @@ int fdt_domains_populate(const void *fdt)
}
/* Iterate over each domain in FDT and populate details */
- return fdt_iterate_each_domain_ro(fdt, &cold_domain_offset,
- __fdt_parse_domain);
+ err = fdt_iterate_each_domain_ro(fdt, &cold_domain_offset,
+ __fdt_parse_domain);
+ if (err)
+ return err;
+
+ return __fdt_parse_mpxy_sysirq_nodes(fdt);
}
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index b57eae1a..3d7c4eec 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -10,6 +10,7 @@
#include <sbi/riscv_asm.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_irqchip.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_hart.h>
@@ -80,6 +81,54 @@ int fdt_parse_phandle_with_args(const void *fdt, int nodeoff,
return SBI_ENOENT;
}
+int fdt_parse_interrupts_extended_entry(const void *fdt, int nodeoff,
+ int index,
+ struct sbi_irqchip_device **out_chip,
+ u32 *out_hwirq,
+ u32 *out_flags,
+ u32 *out_flags_count)
+{
+ struct fdt_phandle_args args;
+ struct sbi_irqchip_device *chip;
+ u32 flags_cap = 0, flags_cnt = 0;
+ int rc, i;
+
+ if (!fdt || nodeoff < 0)
+ return SBI_EINVAL;
+
+ rc = fdt_parse_phandle_with_args(fdt, nodeoff, "interrupts-extended",
+ "#interrupt-cells", index, &args);
+ if (rc)
+ return rc;
+
+ if (args.args_count < 1)
+ return SBI_EINVAL;
+
+ if (out_hwirq)
+ *out_hwirq = args.args[0];
+
+ if (out_flags_count) {
+ flags_cap = *out_flags_count;
+ flags_cnt = (args.args_count > 1) ? (args.args_count - 1) : 0;
+ if (out_flags && flags_cap < flags_cnt)
+ flags_cnt = flags_cap;
+ if (out_flags) {
+ for (i = 0; i < (int)flags_cnt; i++)
+ out_flags[i] = args.args[i + 1];
+ }
+ *out_flags_count = flags_cnt;
+ }
+
+ if (out_chip) {
+ chip = sbi_irqchip_find_device((u32)args.node_offset);
+ if (!chip)
+ return SBI_ENODEV;
+ *out_chip = chip;
+ }
+
+ return 0;
+}
+
static int fdt_translate_address(const void *fdt, uint64_t reg, int parent,
uint64_t *addr)
{
--
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 ` Raymond Mao [this message]
2026-05-14 22:57 ` [PATCH 07/10] lib: utils: irqchip: derive APLIC targets from sysirq nodes Raymond Mao
2026-05-14 22:57 ` [PATCH 08/10] lib: irqchip: support deferred completion and per-HWIRQ APLIC targets Raymond Mao
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-7-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