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 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.