summaryrefslogtreecommitdiff
path: root/lib/utils
diff options
context:
space:
mode:
authorAnup Patel <[email protected]>2024-08-06 09:38:02 +0530
committerAnup Patel <[email protected]>2024-12-06 09:26:13 +0530
commitad846a7cb8cdb98870e42539087f2bc4e786fd22 (patch)
treee1de100cb93da6d708f107b169cdc9abd0ff7daa /lib/utils
parentb49d67b70f09149016afbfa07c8f65df1626a157 (diff)
lib: utils/mailbox: Add generic mailbox library
Add generic mailbox library which is independent of hardware description format. The OpenSBI platform support or mailbox drivers can register mailbox controller instances which can be discovered and used by different mailbox client drivers. Each mailbox controller instance has a unique ID which can be used by mailbox client drivers for find the mailbox controller instance. The mailbox client drivers will typically request a mailbox channel from the mailbox controller and use it to do data transfer with the remote end of mailbox channel. Signed-off-by: Anup Patel <[email protected]>
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/Kconfig2
-rw-r--r--lib/utils/mailbox/Kconfig9
-rw-r--r--lib/utils/mailbox/mailbox.c138
-rw-r--r--lib/utils/mailbox/objects.mk10
4 files changed, 159 insertions, 0 deletions
diff --git a/lib/utils/Kconfig b/lib/utils/Kconfig
index de8b4eb9..6aa7843c 100644
--- a/lib/utils/Kconfig
+++ b/lib/utils/Kconfig
@@ -14,6 +14,8 @@ source "$(OPENSBI_SRC_DIR)/lib/utils/irqchip/Kconfig"
source "$(OPENSBI_SRC_DIR)/lib/utils/libfdt/Kconfig"
+source "$(OPENSBI_SRC_DIR)/lib/utils/mailbox/Kconfig"
+
source "$(OPENSBI_SRC_DIR)/lib/utils/regmap/Kconfig"
source "$(OPENSBI_SRC_DIR)/lib/utils/reset/Kconfig"
diff --git a/lib/utils/mailbox/Kconfig b/lib/utils/mailbox/Kconfig
new file mode 100644
index 00000000..f91a9bb9
--- /dev/null
+++ b/lib/utils/mailbox/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+menu "Mailbox Support"
+
+config MAILBOX
+ bool "Mailbox support"
+ default n
+
+endmenu
diff --git a/lib/utils/mailbox/mailbox.c b/lib/utils/mailbox/mailbox.c
new file mode 100644
index 00000000..2ea7a005
--- /dev/null
+++ b/lib/utils/mailbox/mailbox.c
@@ -0,0 +1,138 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ * Anup Patel <[email protected]>
+ */
+
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_string.h>
+#include <sbi_utils/mailbox/mailbox.h>
+
+static SBI_LIST_HEAD(mbox_list);
+
+struct mbox_controller *mbox_controller_find(unsigned int id)
+{
+ struct sbi_dlist *pos;
+
+ sbi_list_for_each(pos, &mbox_list) {
+ struct mbox_controller *mbox = to_mbox_controller(pos);
+
+ if (mbox->id == id)
+ return mbox;
+ }
+
+ return NULL;
+}
+
+int mbox_controller_add(struct mbox_controller *mbox)
+{
+ if (!mbox || !mbox->max_xfer_len)
+ return SBI_EINVAL;
+ if (mbox_controller_find(mbox->id))
+ return SBI_EALREADY;
+
+ SBI_INIT_LIST_HEAD(&mbox->node);
+ ATOMIC_INIT(&mbox->xfer_next_seq, 0);
+ SBI_INIT_LIST_HEAD(&mbox->chan_list);
+ sbi_list_add(&mbox->node, &mbox_list);
+
+ return 0;
+}
+
+void mbox_controller_remove(struct mbox_controller *mbox)
+{
+ struct mbox_chan *chan;
+
+ if (!mbox)
+ return;
+
+ while (!sbi_list_empty(&mbox->chan_list)) {
+ chan = sbi_list_first_entry(&mbox->chan_list,
+ struct mbox_chan, node);
+ if (mbox->free_chan)
+ mbox->free_chan(mbox, chan);
+ sbi_list_del(&chan->node);
+ }
+
+ sbi_list_del(&mbox->node);
+}
+
+struct mbox_chan *mbox_controller_request_chan(struct mbox_controller *mbox,
+ u32 *chan_args)
+{
+ struct mbox_chan *ret;
+ struct sbi_dlist *pos;
+
+ if (!chan_args || !mbox || !mbox->request_chan)
+ return NULL;
+
+ sbi_list_for_each(pos, &mbox->chan_list) {
+ ret = to_mbox_chan(pos);
+ if (!sbi_memcmp(ret->chan_args, chan_args,
+ sizeof(ret->chan_args)))
+ return ret;
+ }
+
+ ret = mbox->request_chan(mbox, chan_args);
+ if (!ret)
+ return NULL;
+
+ SBI_INIT_LIST_HEAD(&ret->node);
+ ret->mbox = mbox;
+ sbi_memcpy(ret->chan_args, chan_args, sizeof(ret->chan_args));
+ sbi_list_add(&ret->node, &mbox->chan_list);
+ return ret;
+}
+
+void mbox_controller_free_chan(struct mbox_chan *chan)
+{
+ if (!chan || !chan->mbox)
+ return;
+
+ if (chan->mbox->free_chan)
+ chan->mbox->free_chan(chan->mbox, chan);
+ sbi_list_del(&chan->node);
+}
+
+int mbox_chan_xfer(struct mbox_chan *chan, struct mbox_xfer *xfer)
+{
+ if (!xfer || !chan || !chan->mbox || !chan->mbox->xfer)
+ return SBI_EINVAL;
+
+ if (xfer->tx && (xfer->tx_len > chan->mbox->max_xfer_len))
+ return SBI_EINVAL;
+
+ if (xfer->rx && (xfer->rx_len > chan->mbox->max_xfer_len))
+ return SBI_EINVAL;
+
+ if (!(xfer->flags & MBOX_XFER_SEQ))
+ mbox_xfer_set_sequence(xfer,
+ atomic_add_return(&chan->mbox->xfer_next_seq, 1));
+
+ return chan->mbox->xfer(chan, xfer);
+}
+
+int mbox_chan_get_attribute(struct mbox_chan *chan, int attr_id, void *out_value)
+{
+ if (!chan || !chan->mbox || !out_value)
+ return SBI_EINVAL;
+
+ if (!chan->mbox->get_attribute)
+ return SBI_ENOTSUPP;
+
+ return chan->mbox->get_attribute(chan, attr_id, out_value);
+}
+
+int mbox_chan_set_attribute(struct mbox_chan *chan, int attr_id, void *new_value)
+{
+ if (!chan || !chan->mbox || !new_value)
+ return SBI_EINVAL;
+
+ if (!chan->mbox->set_attribute)
+ return SBI_ENOTSUPP;
+
+ return chan->mbox->set_attribute(chan, attr_id, new_value);
+}
diff --git a/lib/utils/mailbox/objects.mk b/lib/utils/mailbox/objects.mk
new file mode 100644
index 00000000..79b27e4c
--- /dev/null
+++ b/lib/utils/mailbox/objects.mk
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 Ventana Micro Systems Inc.
+#
+# Authors:
+# Anup Patel <[email protected]>
+#
+
+libsbiutils-objs-$(CONFIG_MAILBOX) += mailbox/mailbox.o