From: Raymond Mao <raymondmaoca@gmail.com>
To: opensbi@lists.infradead.org
Cc: anup@brainfault.org, anup.patel@oss.qualcomm.com,
scott@riscstar.com, raymond.mao@riscstar.com,
robin.randhawa@sifive.com, samuel.holland@sifive.com,
peter.lin@sifive.com
Subject: [PATCH v2 10/12] lib: utils: fdt: parse sysirq routing from DT
Date: Thu, 29 Oct 2026 11:59:27 -0400 [thread overview]
Message-ID: <20261029155929.586597-11-raymondmaoca@gmail.com> (raw)
In-Reply-To: <20261029155929.586597-1-raymondmaoca@gmail.com>
From: Raymond Mao <raymond.mao@riscstar.com>
Parse mpxy-sysirq nodes under /chosen/opensbi-domains, pre-size
per-channel VIRQ maps, and add physical interrupt routes from
interrupts-extended. Mark sysirq domains to allow SEIP-based VIRQ
notification.
Initialize VIRQ on demand and register each domain-owned RPMI
SYSTEM_IRQ channel using its channel ID and interrupt entry count.
Store the physical controller, HWIRQ and IRQ flags in each route.
Activate courier handlers during domain finalization after boot HART
selection, setting affinity to the destination domain's final boot HART.
Complete mapping and channel setup before activating physical sources.
Reject malformed phandle argument lists and insufficient IRQ flag
buffers instead of truncating interrupt specifiers. Require one HWIRQ
cell and one flags cell for SYSIRQ sources, and validate scalar
channel and domain properties.
Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
---
include/sbi_utils/fdt/fdt_helper.h | 8 ++
lib/sbi/sbi_domain.c | 3 +
lib/utils/fdt/fdt_domain.c | 116 ++++++++++++++++++++++++++++-
lib/utils/fdt/fdt_helper.c | 57 +++++++++++++-
4 files changed, 179 insertions(+), 5 deletions(-)
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 75a564d1..342cf738 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,13 @@ 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);
+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/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 16df5533..36b64b32 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -930,6 +930,9 @@ int sbi_domain_finalize(struct sbi_scratch *scratch)
/* Select stable boot HARTs before programming physical IRQ targets. */
domain_select_boot_harts();
+ rc = sbi_virq_setup_couriers();
+ if (rc)
+ return rc;
/*
* Set the finalized flag so that the root domain
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index 575fbdf0..4d38d402 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -15,7 +15,9 @@
#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>
@@ -291,7 +293,6 @@ 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;
@@ -488,12 +489,123 @@ 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, num_irqs;
+ struct sbi_domain *dom;
+
+ if (!fdt || nodeoff < 0)
+ return SBI_EINVAL;
+
+ val = fdt_getprop(fdt, nodeoff, "opensbi,mpxy-channel-id", &len);
+ if (!val || len != sizeof(*val))
+ return SBI_EINVAL;
+ channel_id = fdt32_to_cpu(*val);
+
+ val = fdt_getprop(fdt, nodeoff, "opensbi,domain", &len);
+ if (!val || len != sizeof(*val))
+ 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)
+ 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);
+ if (rc)
+ return rc;
+ }
+ rc = sbi_virq_map_ensure_cap(channel_id, index);
+ if (rc)
+ return rc;
+ num_irqs = index;
+
+ for (index = 0; ; index++) {
+ struct sbi_irqchip_device *chip = NULL;
+ u32 hwirq = 0, flags, flags_count = 1;
+
+ rc = fdt_parse_interrupts_extended_entry(fdt, nodeoff, index,
+ &chip, &hwirq,
+ &flags, &flags_count);
+ if (rc == SBI_ENOENT)
+ break;
+ if (rc)
+ return rc;
+ if (!chip)
+ return SBI_ENODEV;
+ if (flags_count != 1)
+ return SBI_ENOTSUPP;
+
+ rc = sbi_virq_map_set(channel_id, chip->id, hwirq, index);
+ if (rc)
+ return rc;
+
+ rc = sbi_virq_route_add(dom, chip->id, hwirq, flags, channel_id);
+ if (rc)
+ return rc;
+ }
+
+ return sbi_virq_sysirq_add_channel(dom, channel_id, num_irqs);
+}
+
+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)
{
+ int err;
+
/* Sanity checks */
if (!fdt)
return SBI_EINVAL;
/* Iterate over each domain in FDT and populate details */
- return fdt_iterate_each_domain_ro(fdt, NULL, __fdt_parse_domain);
+ err = fdt_iterate_each_domain_ro(fdt, NULL, __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 747ba028..21c78279 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>
@@ -47,6 +48,8 @@ int fdt_parse_phandle_with_args(const void *fdt, int nodeoff,
list = fdt_getprop(fdt, nodeoff, prop, &len);
if (!list)
return SBI_ENOENT;
+ if (len % sizeof(*list))
+ return SBI_EINVAL;
list_end = list + (len / sizeof(*list));
while (list < list_end) {
@@ -57,13 +60,13 @@ int fdt_parse_phandle_with_args(const void *fdt, int nodeoff,
list++;
val = fdt_getprop(fdt, pnodeoff, cells_prop, &len);
- if (!val)
- return SBI_ENOENT;
+ if (!val || len != sizeof(*val))
+ return SBI_EINVAL;
pcells = fdt32_to_cpu(*val);
if (FDT_MAX_PHANDLE_ARGS < pcells)
return SBI_EINVAL;
if (list + pcells > list_end)
- return SBI_ENOENT;
+ return SBI_EINVAL;
if (index > 0) {
list += pcells;
@@ -80,6 +83,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;
+ *out_flags_count = flags_cnt;
+ if (out_flags && flags_cap < flags_cnt)
+ return SBI_EBAD_RANGE;
+ if (out_flags) {
+ for (i = 0; i < (int)flags_cnt; i++)
+ out_flags[i] = args.args[i + 1];
+ }
+ }
+
+ 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-10-29 16:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 15:59 [PATCH v2 00/12] Introduce Virtual IRQ (VIRQ) framework Raymond Mao
2026-10-29 15:59 ` [PATCH v2 01/12] lib: utils: add RPMI SYSTEM_IRQ service support Raymond Mao
2026-10-29 15:59 ` [PATCH v2 02/12] lib: sbi: add experimental Yield ECALL extension Raymond Mao
2026-10-29 15:59 ` [PATCH v2 03/12] lib: irqchip: add S-mode notification helpers Raymond Mao
2026-10-29 15:59 ` [PATCH v2 04/12] lib: sbi: domain: support VIRQ couriering domain context switch Raymond Mao
2026-10-29 15:59 ` [PATCH v2 05/12] lib: sbi: domain: ensure boot_hartid is assigned Raymond Mao
2026-10-29 15:59 ` [PATCH v2 06/12] lib: sbi: Add Virtual IRQ (VIRQ) subsystem Raymond Mao
2026-10-29 15:59 ` [PATCH v2 07/12] lib: sbi: domain: add domain lookup by name Raymond Mao
2026-10-29 15:59 ` [PATCH v2 08/12] lib: utils: irqchip: derive APLIC targets from sysirq nodes Raymond Mao
2026-10-29 15:59 ` [PATCH v2 09/12] lib: utils: irqchip: Add helper to register VIRQ courier handler Raymond Mao
2026-10-29 15:59 ` Raymond Mao [this message]
2026-10-29 15:59 ` [PATCH v2 11/12] docs: domain: document sysirq VIRQ mapping and routing rules Raymond Mao
2026-10-29 15:59 ` [PATCH v2 12/12] [NOT-FOR-UPSTREAM] platform: generic: Add sample dts overlays for testing hwirq/domain route 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=20261029155929.586597-11-raymondmaoca@gmail.com \
--to=raymondmaoca@gmail.com \
--cc=anup.patel@oss.qualcomm.com \
--cc=anup@brainfault.org \
--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