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 <apatel@ventanamicro.com>
This commit is contained in:
Anup Patel
2024-08-06 09:38:02 +05:30
committed by Anup Patel
parent b49d67b70f
commit ad846a7cb8
5 changed files with 339 additions and 0 deletions

View File

@@ -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"

View File

@@ -0,0 +1,9 @@
# SPDX-License-Identifier: BSD-2-Clause
menu "Mailbox Support"
config MAILBOX
bool "Mailbox support"
default n
endmenu

138
lib/utils/mailbox/mailbox.c Normal file
View File

@@ -0,0 +1,138 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 Ventana Micro Systems Inc.
*
* Authors:
* Anup Patel <apatel@ventanamicro.com>
*/
#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);
}

View File

@@ -0,0 +1,10 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2024 Ventana Micro Systems Inc.
#
# Authors:
# Anup Patel <apatel@ventanamicro.com>
#
libsbiutils-objs-$(CONFIG_MAILBOX) += mailbox/mailbox.o