forked from Mirrors/opensbi
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>
This commit is contained in:
32
include/sbi_utils/mailbox/rpmi_mailbox.h
Normal file
32
include/sbi_utils/mailbox/rpmi_mailbox.h
Normal file
@@ -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__ */
|
255
include/sbi_utils/mailbox/rpmi_msgprot.h
Normal file
255
include/sbi_utils/mailbox/rpmi_msgprot.h
Normal file
@@ -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__ */
|
Reference in New Issue
Block a user