diff options
| author | Rahul Pathak <rpathak@ventanamicro.com> | 2024-08-06 10:07:33 +0530 |
|---|---|---|
| committer | Anup Patel <anup@brainfault.org> | 2024-12-06 09:26:21 +0530 |
| commit | 91f46fb47eefb872a7981935fbcc125226e93eca (patch) | |
| tree | 370ae962582d4741b1947a1da7fcd01b13db2d49 /include | |
| parent | 2244a34f0d618c6f18c161b6448af1eecc7f72ab (diff) | |
| download | opensbi-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.h | 32 | ||||
| -rw-r--r-- | include/sbi_utils/mailbox/rpmi_msgprot.h | 255 |
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__ */ |
