aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRahul Pathak <rpathak@ventanamicro.com>2024-08-06 10:07:33 +0530
committerAnup Patel <anup@brainfault.org>2024-12-06 09:26:21 +0530
commit91f46fb47eefb872a7981935fbcc125226e93eca (patch)
tree370ae962582d4741b1947a1da7fcd01b13db2d49 /include
parent2244a34f0d618c6f18c161b6448af1eecc7f72ab (diff)
downloadopensbi-91f46fb47eefb872a7981935fbcc125226e93eca.tar.gz
opensbi-91f46fb47eefb872a7981935fbcc125226e93eca.tar.bz2
opensbi-91f46fb47eefb872a7981935fbcc125226e93eca.zip
lib/utils: Add RPMI messaging protocol and shared memory transport support
The RISC-V Platform Management Interface (RPMI) defines a messaging protocol and shared memory based transport for bi-directional communication with an on-chip or external microcontroller. To support RPMI in OpenSBI, add: 1) The RPMI messaging protocol defines and helper macros 2) A FDT mailbox driver for the RPMI shared memory transport Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com> Co-developed-by: Subrahmanya Lingappa <slingappa@ventanamicro.com> Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com> Co-developed-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Diffstat (limited to 'include')
-rw-r--r--include/sbi_utils/mailbox/rpmi_mailbox.h32
-rw-r--r--include/sbi_utils/mailbox/rpmi_msgprot.h255
2 files changed, 287 insertions, 0 deletions
diff --git a/include/sbi_utils/mailbox/rpmi_mailbox.h b/include/sbi_utils/mailbox/rpmi_mailbox.h
new file mode 100644
index 00000000..61af51a8
--- /dev/null
+++ b/include/sbi_utils/mailbox/rpmi_mailbox.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ * Anup Patel <apatel@ventanamicro.com>
+ */
+
+#ifndef __RPMI_MAILBOX_H__
+#define __RPMI_MAILBOX_H__
+
+#include <sbi/sbi_error.h>
+#include <sbi_utils/mailbox/rpmi_msgprot.h>
+
+#define rpmi_u32_count(__var) (sizeof(__var) / sizeof(u32))
+
+/** Convert RPMI error to SBI error */
+int rpmi_xlate_error(enum rpmi_error error);
+
+/** Typical RPMI normal request with at least status code in response */
+int rpmi_normal_request_with_status(
+ struct mbox_chan *chan, u32 service_id,
+ void *req, u32 req_words, u32 req_endian_words,
+ void *resp, u32 resp_words, u32 resp_endian_words);
+
+/* RPMI posted request which is without any response*/
+int rpmi_posted_request(
+ struct mbox_chan *chan, u32 service_id,
+ void *req, u32 req_words, u32 req_endian_words);
+
+#endif /* !__RPMI_MAILBOX_H__ */
diff --git a/include/sbi_utils/mailbox/rpmi_msgprot.h b/include/sbi_utils/mailbox/rpmi_msgprot.h
new file mode 100644
index 00000000..f9f65447
--- /dev/null
+++ b/include/sbi_utils/mailbox/rpmi_msgprot.h
@@ -0,0 +1,255 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ * Rahul Pathak <rpathak@ventanamicro.com>
+ */
+
+#ifndef __RPMI_MSGPROT_H__
+#define __RPMI_MSGPROT_H__
+
+#include <sbi/sbi_byteorder.h>
+#include <sbi/sbi_error.h>
+
+/*
+ * 31 0
+ * +---------------------+-----------------------+
+ * | FLAGS | SERVICE_ID | SERVICEGROUP_ID |
+ * +---------------------+-----------------------+
+ * | TOKEN | DATA LENGTH |
+ * +---------------------+-----------------------+
+ * | DATA/PAYLOAD |
+ * +---------------------------------------------+
+ */
+
+/** Message Header byte offset */
+#define RPMI_MSG_HDR_OFFSET (0x0)
+/** Message Header Size in bytes */
+#define RPMI_MSG_HDR_SIZE (8)
+
+/** ServiceGroup ID field byte offset */
+#define RPMI_MSG_SERVICEGROUP_ID_OFFSET (0x0)
+/** ServiceGroup ID field size in bytes */
+#define RPMI_MSG_SERVICEGROUP_ID_SIZE (2)
+
+/** Service ID field byte offset */
+#define RPMI_MSG_SERVICE_ID_OFFSET (0x2)
+/** Service ID field size in bytes */
+#define RPMI_MSG_SERVICE_ID_SIZE (1)
+
+/** Flags field byte offset */
+#define RPMI_MSG_FLAGS_OFFSET (0x3)
+/** Flags field size in bytes */
+#define RPMI_MSG_FLAGS_SIZE (1)
+
+#define RPMI_MSG_FLAGS_TYPE_POS (0U)
+#define RPMI_MSG_FLAGS_TYPE_MASK 0x7
+#define RPMI_MSG_FLAGS_TYPE \
+ ((0x7) << RPMI_MSG_FLAGS_TYPE_POS)
+
+#define RPMI_MSG_FLAGS_DOORBELL_POS (3U)
+#define RPMI_MSG_FLAGS_DOORBELL_MASK 0x1
+#define RPMI_MSG_FLAGS_DOORBELL \
+ ((0x1) << RPMI_MSG_FLAGS_DOORBELL_POS)
+
+/** Data length field byte offset */
+#define RPMI_MSG_DATALEN_OFFSET (0x4)
+/** Data length field size in bytes */
+#define RPMI_MSG_DATALEN_SIZE (2)
+
+/** Token field byte offset */
+#define RPMI_MSG_TOKEN_OFFSET (0x6)
+/** Token field size in bytes */
+#define RPMI_MSG_TOKEN_SIZE (2)
+/** Token field mask */
+#define RPMI_MSG_TOKEN_MASK (0xffffU)
+
+/** Data field byte offset */
+#define RPMI_MSG_DATA_OFFSET (RPMI_MSG_HDR_SIZE)
+/** Data field size in bytes */
+#define RPMI_MSG_DATA_SIZE(__slot_size) ((__slot_size) - RPMI_MSG_HDR_SIZE)
+
+/** Minimum slot size in bytes */
+#define RPMI_SLOT_SIZE_MIN (64)
+
+/** Name length of 16 characters */
+#define RPMI_NAME_CHARS_MAX (16)
+
+/** Queue layout */
+#define RPMI_QUEUE_HEAD_SLOT 0
+#define RPMI_QUEUE_TAIL_SLOT 1
+#define RPMI_QUEUE_HEADER_SLOTS 2
+
+/** Default timeout values */
+#define RPMI_DEF_TX_TIMEOUT 20
+#define RPMI_DEF_RX_TIMEOUT 20
+
+/**
+ * Common macro to generate composite version from major
+ * and minor version numbers.
+ *
+ * RPMI has Specification version, Implementation version
+ * Service group versions which follow the same versioning
+ * encoding as below.
+ */
+#define RPMI_VERSION(__major, __minor) (((__major) << 16) | (__minor))
+
+/** RPMI Message Header */
+struct rpmi_message_header {
+ le16_t servicegroup_id;
+ uint8_t service_id;
+ uint8_t flags;
+ le16_t datalen;
+ le16_t token;
+} __packed;
+
+/** RPMI Message */
+struct rpmi_message {
+ struct rpmi_message_header header;
+ u8 data[0];
+} __packed;
+
+/** RPMI Messages Types */
+enum rpmi_message_type {
+ /* Normal request backed with ack */
+ RPMI_MSG_NORMAL_REQUEST = 0x0,
+ /* Request without any ack */
+ RPMI_MSG_POSTED_REQUEST = 0x1,
+ /* Acknowledgment for normal request message */
+ RPMI_MSG_ACKNOWLDGEMENT = 0x2,
+ /* Notification message */
+ RPMI_MSG_NOTIFICATION = 0x3,
+};
+
+/** RPMI Error Types */
+enum rpmi_error {
+ /* Success */
+ RPMI_SUCCESS = 0,
+ /* General failure */
+ RPMI_ERR_FAILED = -1,
+ /* Service or feature not supported */
+ RPMI_ERR_NOTSUPP = -2,
+ /* Invalid Parameter */
+ RPMI_ERR_INVALID_PARAM = -3,
+ /*
+ * Denied to insufficient permissions
+ * or due to unmet prerequisite
+ */
+ RPMI_ERR_DENIED = -4,
+ /* Invalid address or offset */
+ RPMI_ERR_INVALID_ADDR = -5,
+ /*
+ * Operation failed as it was already in
+ * progress or the state has changed already
+ * for which the operation was carried out.
+ */
+ RPMI_ERR_ALREADY = -6,
+ /*
+ * Error in implementation which violates
+ * the specification version
+ */
+ RPMI_ERR_EXTENSION = -7,
+ /* Operation failed due to hardware issues */
+ RPMI_ERR_HW_FAULT = -8,
+ /* System, device or resource is busy */
+ RPMI_ERR_BUSY = -9,
+ /* System or device or resource in invalid state */
+ RPMI_ERR_INVALID_STATE = -10,
+ /* Index, offset or address is out of range */
+ RPMI_ERR_BAD_RANGE = -11,
+ /* Operation timed out */
+ RPMI_ERR_TIMEOUT = -12,
+ /*
+ * Error in input or output or
+ * error in sending or receiving data
+ * through communication medium
+ */
+ RPMI_ERR_IO = -13,
+ /* No data available */
+ RPMI_ERR_NO_DATA = -14,
+ RPMI_ERR_RESERVED_START = -15,
+ RPMI_ERR_RESERVED_END = -127,
+ RPMI_ERR_VENDOR_START = -128,
+};
+
+/** RPMI Message Arguments */
+struct rpmi_message_args {
+ u32 flags;
+#define RPMI_MSG_FLAGS_NO_TX (1U << 0)
+#define RPMI_MSG_FLAGS_NO_RX (1U << 1)
+#define RPMI_MSG_FLAGS_NO_RX_TOKEN (1U << 2)
+ enum rpmi_message_type type;
+ u8 service_id;
+ u32 tx_endian_words;
+ u32 rx_endian_words;
+ u16 rx_token;
+ u32 rx_data_len;
+};
+
+/*
+ * RPMI SERVICEGROUPS AND SERVICES
+ */
+
+/** RPMI ServiceGroups IDs */
+enum rpmi_servicegroup_id {
+ RPMI_SRVGRP_ID_MIN = 0,
+ RPMI_SRVGRP_BASE = 0x0001,
+ RPMI_SRVGRP_ID_MAX_COUNT,
+
+ /* Reserved range for service groups */
+ RPMI_SRVGRP_RESERVE_START = RPMI_SRVGRP_ID_MAX_COUNT,
+ RPMI_SRVGRP_RESERVE_END = 0x7FFF,
+
+ /* Vendor/Implementation-specific service groups range */
+ RPMI_SRVGRP_VENDOR_START = 0x8000,
+ RPMI_SRVGRP_VENDOR_END = 0xFFFF,
+};
+
+/** RPMI enable notification request */
+struct rpmi_enable_notification_req {
+ u32 eventid;
+};
+
+/** RPMI enable notification response */
+struct rpmi_enable_notification_resp {
+ s32 status;
+};
+
+/** RPMI Base ServiceGroup Service IDs */
+enum rpmi_base_service_id {
+ RPMI_BASE_SRV_ENABLE_NOTIFICATION = 0x01,
+ RPMI_BASE_SRV_GET_IMPLEMENTATION_VERSION = 0x02,
+ RPMI_BASE_SRV_GET_IMPLEMENTATION_IDN = 0x03,
+ RPMI_BASE_SRV_GET_SPEC_VERSION = 0x04,
+ RPMI_BASE_SRV_GET_PLATFORM_INFO = 0x05,
+ RPMI_BASE_SRV_PROBE_SERVICE_GROUP = 0x06,
+ RPMI_BASE_SRV_GET_ATTRIBUTES = 0x07,
+ RPMI_BASE_SRV_SET_MSI = 0x08,
+};
+
+#define RPMI_BASE_FLAGS_F0_PRIVILEGE (1U << 2)
+#define RPMI_BASE_FLAGS_F0_EV_NOTIFY (1U << 1)
+#define RPMI_BASE_FLAGS_F0_MSI_EN (1U)
+
+enum rpmi_base_context_priv_level {
+ RPMI_BASE_CONTEXT_PRIV_S_MODE,
+ RPMI_BASE_CONTEXT_PRIV_M_MODE,
+};
+
+struct rpmi_base_get_attributes_resp {
+ s32 status_code;
+ u32 f0;
+ u32 f1;
+ u32 f2;
+ u32 f3;
+};
+
+struct rpmi_base_get_platform_info_resp {
+ s32 status;
+ u32 plat_info_len;
+ char plat_info[];
+};
+
+#endif /* !__RPMI_MSGPROT_H__ */