[PATCH 3/3] sbi_utils: mpxy: add FDT-based MPXY bridge driver

Pawandeep Oza pawandeep.oza at oss.qualcomm.com
Mon Aug 17 12:46:31 PDT 2026


From: Oza Pawandeep <pawandeep.oza at oss.qualcomm.com>

Introduce an FDT-configured MPXY bridge driver that enables
cooperative message passing between two SBI domains sharing the
same physical hart via domain context switching.

MPXY channels are registered at runtime when the named domains
appear via the domain registration notifier:

  - src_ch: used by the source domain to send messages
  - dst_ch: used by the destination domain to retrieve and
    complete forwarded messages via RPMI REQFWD service group

Key design points:
  - bridge_slot_put(): implements sbi_mpxy_send_message_without_response
    stores message pointer and switches to destination domain
  - bridge_src_send(): mplements sbi_mpxy_send_message_with_response
    stores message and response buffer context then switches to destination
  - bridge_dst_retrieve(): REQFWD retrieve path — if slot is
    occupied delivers message immediately, otherwise saves
    response buffer context and yields to source domain to wait
  - bridge_switch_domain(): unified domain switch wrapper —
    enters destination domain from source side or exits back
    to source domain from destination side
  - at present this bridge driver supports domains with same possible_harts.

Signed-off-by: Oza Pawandeep <pawandeep.oza at oss.qualcomm.com>
---
 lib/utils/mpxy/fdt_mpxy_bridge.c | 676 +++++++++++++++++++++++++++++++
 lib/utils/mpxy/objects.mk        |   3 +
 2 files changed, 679 insertions(+)
 create mode 100644 lib/utils/mpxy/fdt_mpxy_bridge.c

diff --git a/lib/utils/mpxy/fdt_mpxy_bridge.c b/lib/utils/mpxy/fdt_mpxy_bridge.c
new file mode 100644
index 00000000..1d8f7c63
--- /dev/null
+++ b/lib/utils/mpxy/fdt_mpxy_bridge.c
@@ -0,0 +1,676 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Qualcomm, Inc
+ *
+ * Authors:
+ *   Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
+ */
+
+#include <libfdt.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <sbi/riscv_asm.h>
+#include <sbi/sbi_byteorder.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_domain.h>
+#include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_list.h>
+#include <sbi/sbi_mpxy.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_string.h>
+#include <sbi/sbi_types.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_driver.h>
+#include <sbi_utils/mailbox/rpmi_msgprot.h>
+
+#define SBI_MPXY_BRIDGE_COMPATIBLE          "opensbi,mpxy-bridge"
+#define SBI_MPXY_BRIDGE_PROP_SRC_DOMAIN_NAME "opensbi,source-domain-name"
+#define SBI_MPXY_BRIDGE_PROP_DST_DOMAIN_NAME "opensbi,destination-domain-name"
+#define SBI_MPXY_BRIDGE_PROP_SRC_CHAN        "opensbi,source-channel-id"
+#define SBI_MPXY_BRIDGE_PROP_DST_CHAN        "opensbi,destination-channel-id"
+
+#define SBI_MPXY_BRIDGE_DEFAULT_MSG_DATA_MAXLEN  256U
+#define SBI_MPXY_BRIDGE_DOMAIN_NAME_MAXLEN       64
+
+struct mpxy_bridge_dst_ctx {
+    void          *respbuf;
+    u32            resp_bufsize;
+    unsigned long *resp_len_ptr;
+    u32            start_index;
+};
+
+struct mpxy_bridge_src_ctx {
+    void          *msgbuf;
+    void          *respbuf;
+    u32            msg_len;
+    u32            resp_bufsize;
+    unsigned long *resp_len_ptr;
+};
+
+struct mpxy_bridge_hart_slot {
+    bool                       occupied;
+    bool                       retrieved;
+    u32                        msg_id;
+    struct mpxy_bridge_src_ctx src_resp;
+    struct mpxy_bridge_dst_ctx dst_resp;
+};
+
+struct mpxy_bridge_slot_store {
+    struct mpxy_bridge_hart_slot *slots;
+    u32                           hart_count;
+    u32                           lost;
+};
+
+struct mpxy_bridge {
+    struct sbi_dlist  node;
+
+    char src_domain_name[SBI_MPXY_BRIDGE_DOMAIN_NAME_MAXLEN];
+    char dst_domain_name[SBI_MPXY_BRIDGE_DOMAIN_NAME_MAXLEN];
+
+    u32 src_channel_id;
+    u32 dst_channel_id;
+
+    struct sbi_domain      *src_dom;
+    struct sbi_domain      *dst_dom;
+
+    struct sbi_mpxy_channel src_ch;
+    struct sbi_mpxy_channel dst_ch;
+
+    struct mpxy_bridge_slot_store store;
+};
+
+static SBI_LIST_HEAD(mpxy_bridge_list);
+static bool mpxy_bridge_notifier_registered;
+
+static inline struct mpxy_bridge *bridge_from_channel(struct sbi_mpxy_channel *ch)
+{
+    struct mpxy_bridge *br;
+
+    sbi_list_for_each_entry(br, &mpxy_bridge_list, node) {
+        if (&br->src_ch == ch || &br->dst_ch == ch)
+            return br;
+    }
+    return NULL;
+}
+
+static bool bridge_name_match(const char *a, const char *b)
+{
+    if (!a || !b)
+        return false;
+
+    return !sbi_strcmp(a, b);
+}
+
+static int bridge_get_string_prop(const void *fdt, int nodeoff,
+                                  const char *propname,
+                                  char *out, size_t outsz)
+{
+    const char *val;
+    int len;
+
+    val = fdt_getprop(fdt, nodeoff, propname, &len);
+    if (!val || len <= 0)
+        return SBI_ENODEV;
+
+    if ((size_t)len >= outsz)
+        len = (int)outsz - 1;
+
+    sbi_memcpy(out, val, len);
+    out[len] = '\0';
+    return SBI_OK;
+}
+
+static int bridge_get_u32_prop(const void *fdt, int nodeoff,
+                               const char *propname, u32 *out)
+{
+    const fdt32_t *val;
+    int len;
+
+    val = fdt_getprop(fdt, nodeoff, propname, &len);
+    if (!val || len < (int)sizeof(*val))
+        return SBI_ENODEV;
+
+    *out = fdt32_to_cpu(*val);
+    return SBI_OK;
+}
+
+static void bridge_switch_domain(struct mpxy_bridge *br,
+                                 struct sbi_mpxy_channel *channel)
+{
+    bool is_src = (channel == &br->src_ch);
+    struct sbi_domain *peer = br->dst_ch.owner_domain;
+
+    if (is_src)
+        sbi_domain_context_enter(peer);
+    else
+        sbi_domain_context_exit();
+}
+
+static int bridge_slot_occupy(struct mpxy_bridge *br,
+                              struct mpxy_bridge_hart_slot *slot)
+{
+    if (slot->occupied) {
+        br->store.lost++;
+        return SBI_ERR_FAILED;
+    }
+    slot->occupied  = true;
+    slot->retrieved = false;
+    return SBI_OK;
+}
+
+static void bridge_fill_forward_resp(struct mpxy_bridge_hart_slot *slot,
+                                     void *msgbuf, u32 msg_len)
+{
+    struct rpmi_request_forward_resp *resp;
+    u32 offset, remaining;
+
+    if (slot->dst_resp.respbuf) {
+        resp = (struct rpmi_request_forward_resp *)slot->dst_resp.respbuf;
+        if (slot->dst_resp.resp_bufsize >= msg_len) {
+            offset    = slot->dst_resp.start_index;
+            remaining = slot->dst_resp.resp_bufsize >= msg_len ?
+                        0 : msg_len - slot->dst_resp.resp_bufsize;
+            resp->status = RPMI_SUCCESS;
+            resp->remaining = remaining;
+            resp->returned = msg_len;
+            sbi_memcpy(resp->data, msgbuf + offset, msg_len);
+            *slot->dst_resp.resp_len_ptr = msg_len;
+        } else {
+            resp->status = RPMI_ERR_INVALID_PARAM;
+            resp->remaining = 0;
+            resp->returned = 0;
+            *slot->dst_resp.resp_len_ptr = 0;
+        }
+    } else {
+        slot->src_resp.msgbuf  = msgbuf;
+        slot->src_resp.msg_len = msg_len;
+    }
+}
+
+static int bridge_slot_put(struct mpxy_bridge *br,
+                           void *msgbuf,
+                           u32 msg_len)
+{
+    struct mpxy_bridge_hart_slot *slot;
+    u32 hartindex = current_hartindex();
+    int rc;
+
+    if (hartindex >= br->store.hart_count)
+        return SBI_ERR_INVALID_PARAM;
+
+    slot = &br->store.slots[hartindex];
+
+    rc = bridge_slot_occupy(br, slot);
+    if (rc)
+        return rc;
+
+    bridge_fill_forward_resp(slot, msgbuf, msg_len);
+    bridge_switch_domain(br, &br->src_ch);
+
+    return SBI_OK;
+}
+
+static int bridge_src_send(struct mpxy_bridge *br,
+                           struct mpxy_bridge_hart_slot *slot,
+                           void *msgbuf,
+                           u32 msg_len,
+                           void *respbuf,
+                           u32 resp_bufsize,
+                           unsigned long *resp_len)
+{
+    int rc;
+
+    rc = bridge_slot_occupy(br, slot);
+    if (rc)
+        return rc;
+
+    slot->src_resp.respbuf      = respbuf;
+    slot->src_resp.resp_bufsize = resp_bufsize;
+    slot->src_resp.resp_len_ptr = resp_len;
+
+    bridge_fill_forward_resp(slot, msgbuf, msg_len);
+    bridge_switch_domain(br, &br->src_ch);
+
+    return SBI_OK;
+}
+
+static void bridge_save_dst_ctx(struct mpxy_bridge_hart_slot *slot,
+                                void *respbuf, u32 resp_bufsize,
+                                unsigned long *resp_len, void *msgbuf)
+{
+    slot->dst_resp.respbuf      = respbuf;
+    slot->dst_resp.resp_bufsize = resp_bufsize;
+    slot->dst_resp.resp_len_ptr = resp_len;
+    slot->dst_resp.start_index  = ((u32 *)msgbuf)[0];
+}
+
+static void bridge_slot_release(struct mpxy_bridge_hart_slot *slot)
+{
+    slot->occupied  = false;
+    slot->retrieved = false;
+    slot->src_resp  = (struct mpxy_bridge_src_ctx){ 0 };
+    slot->dst_resp  = (struct mpxy_bridge_dst_ctx){ 0 };
+}
+
+static void bridge_build_retrieve_resp(struct mpxy_bridge_hart_slot *slot,
+                                       void *respbuf, u32 resp_bufsize,
+                                       unsigned long *resp_len)
+{
+    struct rpmi_request_forward_resp *resp;
+    u32 src_msg_len = slot->src_resp.msg_len;
+    u32 remaining;
+
+    resp = (struct rpmi_request_forward_resp *)respbuf;
+
+    if (resp_bufsize >= sizeof(*resp) + src_msg_len) {
+        remaining       = 0;
+        resp->status    = RPMI_SUCCESS;
+        resp->remaining = remaining;
+        resp->returned  = src_msg_len;
+        sbi_memcpy(resp->data, slot->src_resp.msgbuf, src_msg_len);
+        *resp_len = sizeof(*resp) + src_msg_len;
+    } else {
+        resp->status    = RPMI_ERR_INVALID_PARAM;
+        resp->remaining = 0;
+        resp->returned  = 0;
+        *resp_len = sizeof(*resp);
+    }
+
+    slot->retrieved = true;
+}
+
+static int bridge_dst_retrieve(struct mpxy_bridge *br,
+                               struct mpxy_bridge_hart_slot *slot,
+                               void *msgbuf, u32 msg_len,
+                               void *respbuf, u32 resp_bufsize,
+                               unsigned long *resp_len)
+{
+    struct rpmi_request_forward_resp *resp = (struct rpmi_request_forward_resp *)respbuf;
+
+    if (!slot->occupied) {
+        bridge_save_dst_ctx(slot, respbuf, resp_bufsize, resp_len, msgbuf);
+        bridge_switch_domain(br, &br->dst_ch);
+    } else if (slot->src_resp.respbuf) {
+        if (!respbuf) {
+            if (resp_len)
+                *resp_len = 0;
+            return SBI_OK;
+        }
+        bridge_build_retrieve_resp(slot, respbuf, resp_bufsize, resp_len);
+    } else{
+        resp->status    = RPMI_ERR_NO_DATA;
+        resp->remaining = 0;
+        resp->returned  = 0;
+        *resp_len = sizeof(*resp);
+    }
+
+    return SBI_OK;
+}
+
+static int bridge_dst_complete(struct mpxy_bridge *br,
+                               struct mpxy_bridge_hart_slot *slot,
+                               void *msgbuf, u32 msg_len,
+                               void *respbuf, u32 resp_max_len,
+                               unsigned long *resp_len)
+{
+    struct rpmi_request_complete_resp *resp = (struct rpmi_request_complete_resp *) respbuf;
+    u32 num_messages = 0;
+
+    if (!slot->retrieved || !slot->src_resp.respbuf) {
+        resp->status          = RPMI_ERR_NO_DATA;
+        resp->num_of_messages = 0;
+        *resp_len = 8;
+    } else {
+        sbi_memcpy(slot->src_resp.respbuf, msgbuf, msg_len);
+    }
+
+    resp->status          = RPMI_SUCCESS;
+    resp->num_of_messages = num_messages;
+    *resp_len = sizeof(struct rpmi_request_complete_resp);
+
+    bridge_slot_release(slot);
+    bridge_switch_domain(br, &br->dst_ch);
+
+    return SBI_OK;
+}
+
+static int bridge_send_message_with_response(struct sbi_mpxy_channel *channel,
+                                             u32 msg_id,
+                                             void *msgbuf,
+                                             u32 msg_len,
+                                             void *respbuf,
+                                             u32 resp_bufsize,
+                                             unsigned long *resp_len)
+{
+    struct mpxy_bridge *br = bridge_from_channel(channel);
+    u32 hartindex;
+    struct mpxy_bridge_hart_slot *slot;
+    bool is_src;
+
+    if (!br)
+        return SBI_ERR_NOT_SUPPORTED;
+
+    hartindex = current_hartindex();
+    slot      = &br->store.slots[hartindex];
+    is_src    = (channel == &br->src_ch);
+
+    if (is_src)
+        return bridge_src_send(br, slot,
+                               msgbuf, msg_len,
+                               respbuf, resp_bufsize, resp_len);
+
+    if (msg_id == REQFWD_RETRIEVE_CURRENT_MESSAGE)
+        return bridge_dst_retrieve(br, slot,
+                                   msgbuf, msg_len,
+                                   respbuf, resp_bufsize, resp_len);
+
+    if (msg_id == REQFWD_COMPLETE_CURRENT_MESSAGE)
+        return bridge_dst_complete(br, slot,
+                                   msgbuf, msg_len,
+                                   respbuf, resp_bufsize, resp_len);
+
+    return SBI_ERR_NOT_SUPPORTED;
+}
+
+static int bridge_post_message(struct sbi_mpxy_channel *channel,
+                               u32 msg_id,
+                               void *msgbuf,
+                               u32 msg_len)
+{
+    struct mpxy_bridge *br = bridge_from_channel(channel);
+
+    if (!br->dst_dom)
+        return SBI_ERR_NOT_SUPPORTED;
+
+    return bridge_slot_put(br, msgbuf, msg_len);
+}
+
+static int bridge_send_message_without_response(struct sbi_mpxy_channel *channel,
+                                                u32 msg_id,
+                                                void *msgbuf,
+                                                u32 msg_len)
+{
+    return bridge_post_message(channel, msg_id, msgbuf, msg_len);
+}
+
+static void bridge_init_channel(struct sbi_mpxy_channel *ch,
+                                struct sbi_domain *dom,
+                                u32 channel_id)
+{
+    sbi_memset(ch, 0, sizeof(*ch));
+    ch->owner_domain                  = dom;
+    ch->channel_id                    = channel_id;
+    ch->attrs.msg_data_maxlen         = SBI_MPXY_BRIDGE_DEFAULT_MSG_DATA_MAXLEN;
+    ch->attrs.msi_control             = 0;
+    ch->attrs.eventsstate_ctrl        = 0;
+    ch->send_message_with_response    = bridge_send_message_with_response;
+    ch->send_message_without_response = bridge_send_message_without_response;
+    ch->get_notification_events       = NULL;
+}
+
+static int bridge_register_source(struct mpxy_bridge *br,
+                                  struct sbi_domain *dom)
+{
+    int ret;
+
+    if (br->src_dom)
+        return SBI_OK;
+
+    bridge_init_channel(&br->src_ch, dom, br->src_channel_id);
+
+    ret = sbi_mpxy_register_channel(&br->src_ch);
+    if (ret) {
+        sbi_printf("%s: src channel register failed ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    br->src_dom = dom;
+    return SBI_OK;
+}
+
+static int bridge_register_destination(struct mpxy_bridge *br,
+                                       struct sbi_domain *dom)
+{
+    int ret;
+
+    if (br->dst_dom)
+        return SBI_OK;
+
+    bridge_init_channel(&br->dst_ch, dom, br->dst_channel_id);
+
+    ret = sbi_mpxy_register_channel(&br->dst_ch);
+    if (ret) {
+        sbi_printf("%s: dst channel register failed ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    br->dst_dom = dom;
+    return SBI_OK;
+}
+
+static bool sbi_hartmask_equal(const struct sbi_hartmask *a,
+                               const struct sbi_hartmask *b)
+{
+    u32 hartindex;
+
+    sbi_hartmask_for_each_hartindex(hartindex, a)
+        if (!sbi_hartmask_test_hartindex(hartindex, b))
+            return false;
+
+    sbi_hartmask_for_each_hartindex(hartindex, b)
+        if (!sbi_hartmask_test_hartindex(hartindex, a))
+            return false;
+
+    return true;
+}
+
+static void bridge_try_bind_domain(struct mpxy_bridge *br,
+                                   const struct sbi_domain *dom)
+{
+    int match_src, match_dst;
+
+    if (!br || !dom)
+        return;
+
+    match_src = bridge_name_match(dom->name, br->src_domain_name);
+    match_dst = bridge_name_match(dom->name, br->dst_domain_name);
+
+    if (!br->src_dom && match_src)
+        bridge_register_source(br, (struct sbi_domain *)dom);
+
+    if (!br->dst_dom && match_dst)
+        bridge_register_destination(br, (struct sbi_domain *)dom);
+
+    if (br->src_dom && br->dst_dom) {
+    if (!sbi_hartmask_equal(br->src_dom->possible_harts,
+                            br->dst_dom->possible_harts)) {
+        sbi_printf("%s: src='%s' dst='%s'"
+                   "Error!: bridge suuports only domains with the same possible harts.\n",
+                   __func__,
+                   br->src_dom->name,
+                   br->dst_dom->name);
+        br->src_dom = NULL;
+        br->dst_dom = NULL;
+    }
+}
+}
+
+static void bridge_domain_notifier(const struct sbi_domain *dom, void *priv)
+{
+    struct mpxy_bridge *br;
+
+    (void)priv;
+
+    sbi_list_for_each_entry(br, &mpxy_bridge_list, node)
+        bridge_try_bind_domain(br, dom);
+}
+
+static struct mpxy_bridge *bridge_alloc(u32 hart_count)
+{
+    struct mpxy_bridge *br;
+
+    br = sbi_zalloc(sizeof(*br));
+    if (!br)
+        return NULL;
+
+    br->store.slots = sbi_zalloc(sizeof(*br->store.slots) * hart_count);
+    if (!br->store.slots) {
+        sbi_printf("%s: failed to alloc %u hart slots\n",
+                   __func__, hart_count);
+        sbi_free(br);
+        return NULL;
+    }
+
+    br->store.hart_count = hart_count;
+    br->store.lost = 0;
+    return br;
+}
+
+static int bridge_parse_fdt(const void *fdt, int nodeoff,
+                            struct mpxy_bridge *br)
+{
+    int ret;
+
+    ret = bridge_get_string_prop(fdt, nodeoff,
+                                 SBI_MPXY_BRIDGE_PROP_SRC_DOMAIN_NAME,
+                                 br->src_domain_name,
+                                 sizeof(br->src_domain_name));
+    if (ret) {
+        sbi_printf("%s: failed to read src-domain ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    ret = bridge_get_string_prop(fdt, nodeoff,
+                                 SBI_MPXY_BRIDGE_PROP_DST_DOMAIN_NAME,
+                                 br->dst_domain_name,
+                                 sizeof(br->dst_domain_name));
+    if (ret) {
+        sbi_printf("%s: failed to read dst-domain ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    ret = bridge_get_u32_prop(fdt, nodeoff,
+                              SBI_MPXY_BRIDGE_PROP_SRC_CHAN,
+                              &br->src_channel_id);
+    if (ret) {
+        sbi_printf("%s: failed to read src-channel-id ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    ret = bridge_get_u32_prop(fdt, nodeoff,
+                              SBI_MPXY_BRIDGE_PROP_DST_CHAN,
+                              &br->dst_channel_id);
+    if (ret) {
+        sbi_printf("%s: failed to read dst-channel-id ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    return SBI_OK;
+}
+
+static int bridge_validate(struct mpxy_bridge *br)
+{
+    if (!br->src_domain_name[0] || !br->dst_domain_name[0]) {
+        sbi_printf("%s: empty domain name\n", __func__);
+        return SBI_EINVAL;
+    }
+
+    if (!sbi_strcmp(br->src_domain_name, br->dst_domain_name)) {
+        sbi_printf("%s: src and dst domain names identical\n", __func__);
+        return SBI_EINVAL;
+    }
+
+    if (br->src_channel_id == br->dst_channel_id) {
+        sbi_printf("%s: src and dst channel IDs identical\n", __func__);
+        return SBI_EINVAL;
+    }
+
+    return SBI_OK;
+}
+
+static int bridge_register_notifier(struct mpxy_bridge *br)
+{
+    int ret;
+
+    if (mpxy_bridge_notifier_registered)
+        return SBI_OK;
+
+    ret = sbi_domain_register_notifier(bridge_domain_notifier, NULL);
+    if (ret) {
+        sbi_printf("%s: notifier register failed ret=%d\n",
+                   __func__, ret);
+        return ret;
+    }
+
+    mpxy_bridge_notifier_registered = true;
+    return SBI_OK;
+}
+
+static int bridge_init(const void *fdt, int nodeoff,
+                       const struct fdt_match *match)
+{
+    struct mpxy_bridge *br;
+    struct sbi_scratch *scratch;
+    u32 hart_count;
+    u32 hartindex = current_hartindex();
+    int i, ret;
+
+    (void)match;
+
+    scratch = sbi_hartindex_to_scratch(hartindex);
+    if (!scratch)
+        return SBI_EINVAL;
+
+    hart_count = sbi_platform_hart_count(sbi_platform_ptr(scratch));
+
+    br = bridge_alloc(hart_count);
+    if (!br)
+        return SBI_ENOMEM;
+
+    ret = bridge_parse_fdt(fdt, nodeoff, br);
+    if (ret)
+        goto fail_free;
+
+    ret = bridge_validate(br);
+    if (ret)
+        goto fail_free;
+
+    for (i = 0; i < hart_count; i++)
+        bridge_slot_release(&br->store.slots[i]);
+
+    sbi_list_add_tail(&br->node, &mpxy_bridge_list);
+
+    ret = bridge_register_notifier(br);
+    if (ret) {
+        sbi_list_del(&br->node);
+        goto fail_free;
+    }
+
+    return SBI_OK;
+
+fail_free:
+    sbi_free(br->store.slots);
+    sbi_free(br);
+    return ret;
+}
+
+static const struct fdt_match bridge_match[] = {
+    { .compatible = SBI_MPXY_BRIDGE_COMPATIBLE },
+    { }
+};
+
+const struct fdt_driver fdt_mpxy_bridge = {   
+    .match_table  = bridge_match,
+    .init         = bridge_init,
+};
diff --git a/lib/utils/mpxy/objects.mk b/lib/utils/mpxy/objects.mk
index 1f1bf0a0..4683ccf9 100644
--- a/lib/utils/mpxy/objects.mk
+++ b/lib/utils/mpxy/objects.mk
@@ -32,3 +32,6 @@ libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_MM) += mpxy/fdt_mpxy_rpmi_mm.o
 
 carray-fdt_mpxy_drivers-$(CONFIG_FDT_MPXY_RPMI_LOGGING) += fdt_mpxy_rpmi_logging
 libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_LOGGING) += mpxy/fdt_mpxy_rpmi_logging.o
+
+carray-fdt_mpxy_drivers-y += fdt_mpxy_bridge
+libsbiutils-objs-y += mpxy/fdt_mpxy_bridge.o
-- 
2.43.0




More information about the opensbi mailing list