forked from Mirrors/opensbi
lib: sbi: Update MPXY framework and SBI extension as per latest spec
The latest SBI 3.0 spec defines a new sbi_mpxy_get_shmem_size() function and simplifies sbi_mpxy_set_shmem() function so update the MPXY framework and SBI extension accordingly. Signed-off-by: Anup Patel <apatel@ventanamicro.com>
This commit is contained in:
@@ -423,13 +423,14 @@ enum sbi_sse_state {
|
|||||||
#define SBI_SSE_EVENT_PLATFORM_BIT (1 << 14)
|
#define SBI_SSE_EVENT_PLATFORM_BIT (1 << 14)
|
||||||
|
|
||||||
/* SBI function IDs for MPXY extension */
|
/* SBI function IDs for MPXY extension */
|
||||||
#define SBI_EXT_MPXY_SET_SHMEM 0x0
|
#define SBI_EXT_MPXY_GET_SHMEM_SIZE 0x0
|
||||||
#define SBI_EXT_MPXY_GET_CHANNEL_IDS 0x1
|
#define SBI_EXT_MPXY_SET_SHMEM 0x1
|
||||||
#define SBI_EXT_MPXY_READ_ATTRS 0x2
|
#define SBI_EXT_MPXY_GET_CHANNEL_IDS 0x2
|
||||||
#define SBI_EXT_MPXY_WRITE_ATTRS 0x3
|
#define SBI_EXT_MPXY_READ_ATTRS 0x3
|
||||||
#define SBI_EXT_MPXY_SEND_MSG_WITH_RESP 0x4
|
#define SBI_EXT_MPXY_WRITE_ATTRS 0x4
|
||||||
#define SBI_EXT_MPXY_SEND_MSG_NO_RESP 0x5
|
#define SBI_EXT_MPXY_SEND_MSG_WITH_RESP 0x5
|
||||||
#define SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS 0x6
|
#define SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP 0x6
|
||||||
|
#define SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS 0x7
|
||||||
|
|
||||||
/* SBI base specification related macros */
|
/* SBI base specification related macros */
|
||||||
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
|
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
|
||||||
|
@@ -153,11 +153,13 @@ int sbi_mpxy_init(struct sbi_scratch *scratch);
|
|||||||
/** Check if some Message proxy channel is available */
|
/** Check if some Message proxy channel is available */
|
||||||
bool sbi_mpxy_channel_available(void);
|
bool sbi_mpxy_channel_available(void);
|
||||||
|
|
||||||
/** Set Message proxy shared memory on the calling HART */
|
/** Get message proxy shared memory size */
|
||||||
int sbi_mpxy_set_shmem(unsigned long shmem_size,
|
unsigned long sbi_mpxy_get_shmem_size(void);
|
||||||
unsigned long shmem_phys_lo,
|
|
||||||
unsigned long shmem_phys_hi,
|
/** Set message proxy shared memory on the calling HART */
|
||||||
unsigned long flags);
|
int sbi_mpxy_set_shmem(unsigned long shmem_phys_lo,
|
||||||
|
unsigned long shmem_phys_hi,
|
||||||
|
unsigned long flags);
|
||||||
|
|
||||||
/** Get channel IDs list */
|
/** Get channel IDs list */
|
||||||
int sbi_mpxy_get_channel_ids(u32 start_index);
|
int sbi_mpxy_get_channel_ids(u32 start_index);
|
||||||
|
@@ -20,8 +20,11 @@ static int sbi_ecall_mpxy_handler(unsigned long extid, unsigned long funcid,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
switch (funcid) {
|
switch (funcid) {
|
||||||
|
case SBI_EXT_MPXY_GET_SHMEM_SIZE:
|
||||||
|
out->value = sbi_mpxy_get_shmem_size();
|
||||||
|
break;
|
||||||
case SBI_EXT_MPXY_SET_SHMEM:
|
case SBI_EXT_MPXY_SET_SHMEM:
|
||||||
ret = sbi_mpxy_set_shmem(regs->a0, regs->a1, regs->a2, regs->a3);
|
ret = sbi_mpxy_set_shmem(regs->a0, regs->a1, regs->a2);
|
||||||
break;
|
break;
|
||||||
case SBI_EXT_MPXY_GET_CHANNEL_IDS:
|
case SBI_EXT_MPXY_GET_CHANNEL_IDS:
|
||||||
ret = sbi_mpxy_get_channel_ids(regs->a0);
|
ret = sbi_mpxy_get_channel_ids(regs->a0);
|
||||||
@@ -36,7 +39,7 @@ static int sbi_ecall_mpxy_handler(unsigned long extid, unsigned long funcid,
|
|||||||
ret = sbi_mpxy_send_message(regs->a0, regs->a1,
|
ret = sbi_mpxy_send_message(regs->a0, regs->a1,
|
||||||
regs->a2, &out->value);
|
regs->a2, &out->value);
|
||||||
break;
|
break;
|
||||||
case SBI_EXT_MPXY_SEND_MSG_NO_RESP:
|
case SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP:
|
||||||
ret = sbi_mpxy_send_message(regs->a0, regs->a1, regs->a2,
|
ret = sbi_mpxy_send_message(regs->a0, regs->a1, regs->a2,
|
||||||
NULL);
|
NULL);
|
||||||
break;
|
break;
|
||||||
|
@@ -19,6 +19,9 @@
|
|||||||
#include <sbi/sbi_console.h>
|
#include <sbi/sbi_console.h>
|
||||||
#include <sbi/sbi_byteorder.h>
|
#include <sbi/sbi_byteorder.h>
|
||||||
|
|
||||||
|
/** Shared memory size across all harts */
|
||||||
|
static unsigned long mpxy_shmem_size = PAGE_SIZE;
|
||||||
|
|
||||||
/** Offset of pointer to MPXY state in scratch space */
|
/** Offset of pointer to MPXY state in scratch space */
|
||||||
static unsigned long mpxy_state_offset;
|
static unsigned long mpxy_state_offset;
|
||||||
|
|
||||||
@@ -73,7 +76,6 @@ static SBI_LIST_HEAD(mpxy_channel_list);
|
|||||||
|
|
||||||
/** Per hart shared memory */
|
/** Per hart shared memory */
|
||||||
struct mpxy_shmem {
|
struct mpxy_shmem {
|
||||||
unsigned long shmem_size;
|
|
||||||
unsigned long shmem_addr_lo;
|
unsigned long shmem_addr_lo;
|
||||||
unsigned long shmem_addr_hi;
|
unsigned long shmem_addr_hi;
|
||||||
};
|
};
|
||||||
@@ -90,7 +92,6 @@ struct mpxy_state {
|
|||||||
/** Disable hart shared memory */
|
/** Disable hart shared memory */
|
||||||
static inline void sbi_mpxy_shmem_disable(struct mpxy_state *ms)
|
static inline void sbi_mpxy_shmem_disable(struct mpxy_state *ms)
|
||||||
{
|
{
|
||||||
ms->shmem.shmem_size = 0;
|
|
||||||
ms->shmem.shmem_addr_lo = INVALID_ADDR;
|
ms->shmem.shmem_addr_lo = INVALID_ADDR;
|
||||||
ms->shmem.shmem_addr_hi = INVALID_ADDR;
|
ms->shmem.shmem_addr_hi = INVALID_ADDR;
|
||||||
}
|
}
|
||||||
@@ -227,6 +228,12 @@ int sbi_mpxy_register_channel(struct sbi_mpxy_channel *channel)
|
|||||||
/* Initialize channel specific attributes */
|
/* Initialize channel specific attributes */
|
||||||
mpxy_std_attrs_init(channel);
|
mpxy_std_attrs_init(channel);
|
||||||
|
|
||||||
|
/* Update shared memory size if required */
|
||||||
|
if (mpxy_shmem_size < channel->attrs.msg_data_maxlen) {
|
||||||
|
mpxy_shmem_size = channel->attrs.msg_data_maxlen;
|
||||||
|
mpxy_shmem_size = (mpxy_shmem_size + (PAGE_SIZE - 1)) / PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
SBI_INIT_LIST_HEAD(&channel->head);
|
SBI_INIT_LIST_HEAD(&channel->head);
|
||||||
sbi_list_add_tail(&channel->head, &mpxy_channel_list);
|
sbi_list_add_tail(&channel->head, &mpxy_channel_list);
|
||||||
|
|
||||||
@@ -254,8 +261,14 @@ int sbi_mpxy_init(struct sbi_scratch *scratch)
|
|||||||
return sbi_platform_mpxy_init(sbi_platform_ptr(scratch));
|
return sbi_platform_mpxy_init(sbi_platform_ptr(scratch));
|
||||||
}
|
}
|
||||||
|
|
||||||
int sbi_mpxy_set_shmem(unsigned long shmem_size, unsigned long shmem_phys_lo,
|
unsigned long sbi_mpxy_get_shmem_size(void)
|
||||||
unsigned long shmem_phys_hi, unsigned long flags)
|
{
|
||||||
|
return mpxy_shmem_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sbi_mpxy_set_shmem(unsigned long shmem_phys_lo,
|
||||||
|
unsigned long shmem_phys_hi,
|
||||||
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
struct mpxy_state *ms = sbi_scratch_thishart_offset_ptr(mpxy_state_offset);
|
struct mpxy_state *ms = sbi_scratch_thishart_offset_ptr(mpxy_state_offset);
|
||||||
unsigned long *ret_buf;
|
unsigned long *ret_buf;
|
||||||
@@ -271,13 +284,12 @@ int sbi_mpxy_set_shmem(unsigned long shmem_size, unsigned long shmem_phys_lo,
|
|||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
/** Check shared memory size and address aligned to 4K Page */
|
/** Check shared memory size and address aligned to 4K Page */
|
||||||
if (!shmem_size || (shmem_size & ~PAGE_MASK) ||
|
if (shmem_phys_lo & ~PAGE_MASK)
|
||||||
(shmem_phys_lo & ~PAGE_MASK))
|
|
||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
if (!sbi_domain_check_addr_range(sbi_domain_thishart_ptr(),
|
if (!sbi_domain_check_addr_range(sbi_domain_thishart_ptr(),
|
||||||
SHMEM_PHYS_ADDR(shmem_phys_hi, shmem_phys_lo),
|
SHMEM_PHYS_ADDR(shmem_phys_hi, shmem_phys_lo),
|
||||||
shmem_size, PRV_S,
|
mpxy_shmem_size, PRV_S,
|
||||||
SBI_DOMAIN_READ | SBI_DOMAIN_WRITE))
|
SBI_DOMAIN_READ | SBI_DOMAIN_WRITE))
|
||||||
return SBI_ERR_INVALID_ADDRESS;
|
return SBI_ERR_INVALID_ADDRESS;
|
||||||
|
|
||||||
@@ -285,15 +297,13 @@ int sbi_mpxy_set_shmem(unsigned long shmem_size, unsigned long shmem_phys_lo,
|
|||||||
if (flags == SBI_EXT_MPXY_SHMEM_FLAG_OVERWRITE_RETURN) {
|
if (flags == SBI_EXT_MPXY_SHMEM_FLAG_OVERWRITE_RETURN) {
|
||||||
ret_buf = (unsigned long *)(ulong)SHMEM_PHYS_ADDR(shmem_phys_hi,
|
ret_buf = (unsigned long *)(ulong)SHMEM_PHYS_ADDR(shmem_phys_hi,
|
||||||
shmem_phys_lo);
|
shmem_phys_lo);
|
||||||
sbi_hart_map_saddr((unsigned long)ret_buf, shmem_size);
|
sbi_hart_map_saddr((unsigned long)ret_buf, mpxy_shmem_size);
|
||||||
ret_buf[0] = cpu_to_lle(ms->shmem.shmem_size);
|
ret_buf[0] = cpu_to_lle(ms->shmem.shmem_addr_lo);
|
||||||
ret_buf[1] = cpu_to_lle(ms->shmem.shmem_addr_lo);
|
ret_buf[1] = cpu_to_lle(ms->shmem.shmem_addr_hi);
|
||||||
ret_buf[2] = cpu_to_lle(ms->shmem.shmem_addr_hi);
|
|
||||||
sbi_hart_unmap_saddr();
|
sbi_hart_unmap_saddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Setup the new shared memory */
|
/** Setup the new shared memory */
|
||||||
ms->shmem.shmem_size = shmem_size;
|
|
||||||
ms->shmem.shmem_addr_lo = shmem_phys_lo;
|
ms->shmem.shmem_addr_lo = shmem_phys_lo;
|
||||||
ms->shmem.shmem_addr_hi = shmem_phys_hi;
|
ms->shmem.shmem_addr_hi = shmem_phys_hi;
|
||||||
|
|
||||||
@@ -319,12 +329,11 @@ int sbi_mpxy_get_channel_ids(u32 start_index)
|
|||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
shmem_base = hart_shmem_base(ms);
|
shmem_base = hart_shmem_base(ms);
|
||||||
sbi_hart_map_saddr((unsigned long)hart_shmem_base(ms),
|
sbi_hart_map_saddr((unsigned long)hart_shmem_base(ms), mpxy_shmem_size);
|
||||||
ms->shmem.shmem_size);
|
|
||||||
|
|
||||||
/** number of channel ids which can be stored in shmem adjusting
|
/** number of channel ids which can be stored in shmem adjusting
|
||||||
* for remaining and returned fields */
|
* for remaining and returned fields */
|
||||||
max_channelids = (ms->shmem.shmem_size / sizeof(u32)) - 2;
|
max_channelids = (mpxy_shmem_size / sizeof(u32)) - 2;
|
||||||
/* total remaining from the start index */
|
/* total remaining from the start index */
|
||||||
remaining = channels_count - start_index;
|
remaining = channels_count - start_index;
|
||||||
/* how many can be returned */
|
/* how many can be returned */
|
||||||
@@ -372,14 +381,13 @@ int sbi_mpxy_read_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count)
|
|||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
/* Sanity check for base_attr_id and attr_count */
|
/* Sanity check for base_attr_id and attr_count */
|
||||||
if (!attr_count || (attr_count > (ms->shmem.shmem_size / ATTR_SIZE)))
|
if (!attr_count || (attr_count > (mpxy_shmem_size / ATTR_SIZE)))
|
||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
shmem_base = hart_shmem_base(ms);
|
shmem_base = hart_shmem_base(ms);
|
||||||
end_id = base_attr_id + attr_count - 1;
|
end_id = base_attr_id + attr_count - 1;
|
||||||
|
|
||||||
sbi_hart_map_saddr((unsigned long)hart_shmem_base(ms),
|
sbi_hart_map_saddr((unsigned long)hart_shmem_base(ms), mpxy_shmem_size);
|
||||||
ms->shmem.shmem_size);
|
|
||||||
|
|
||||||
/* Standard attributes range check */
|
/* Standard attributes range check */
|
||||||
if (mpxy_is_std_attr(base_attr_id)) {
|
if (mpxy_is_std_attr(base_attr_id)) {
|
||||||
@@ -524,13 +532,13 @@ int sbi_mpxy_write_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count)
|
|||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
/* Sanity check for base_attr_id and attr_count */
|
/* Sanity check for base_attr_id and attr_count */
|
||||||
if (!attr_count || (attr_count > (ms->shmem.shmem_size / ATTR_SIZE)))
|
if (!attr_count || (attr_count > (mpxy_shmem_size / ATTR_SIZE)))
|
||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
shmem_base = hart_shmem_base(ms);
|
shmem_base = hart_shmem_base(ms);
|
||||||
end_id = base_attr_id + attr_count - 1;
|
end_id = base_attr_id + attr_count - 1;
|
||||||
|
|
||||||
sbi_hart_map_saddr((unsigned long)shmem_base, ms->shmem.shmem_size);
|
sbi_hart_map_saddr((unsigned long)shmem_base, mpxy_shmem_size);
|
||||||
|
|
||||||
mem_ptr = (u32 *)shmem_base;
|
mem_ptr = (u32 *)shmem_base;
|
||||||
|
|
||||||
@@ -614,16 +622,16 @@ int sbi_mpxy_send_message(u32 channel_id, u8 msg_id,
|
|||||||
if (!resp_data_len && !channel->send_message_without_response)
|
if (!resp_data_len && !channel->send_message_without_response)
|
||||||
return SBI_ERR_NOT_SUPPORTED;
|
return SBI_ERR_NOT_SUPPORTED;
|
||||||
|
|
||||||
if (msg_data_len > ms->shmem.shmem_size ||
|
if (msg_data_len > mpxy_shmem_size ||
|
||||||
msg_data_len > channel->attrs.msg_data_maxlen)
|
msg_data_len > channel->attrs.msg_data_maxlen)
|
||||||
return SBI_ERR_INVALID_PARAM;
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
shmem_base = hart_shmem_base(ms);
|
shmem_base = hart_shmem_base(ms);
|
||||||
sbi_hart_map_saddr((unsigned long)shmem_base, ms->shmem.shmem_size);
|
sbi_hart_map_saddr((unsigned long)shmem_base, mpxy_shmem_size);
|
||||||
|
|
||||||
if (resp_data_len) {
|
if (resp_data_len) {
|
||||||
resp_buf = shmem_base;
|
resp_buf = shmem_base;
|
||||||
resp_bufsize = ms->shmem.shmem_size;
|
resp_bufsize = mpxy_shmem_size;
|
||||||
ret = channel->send_message_with_response(channel, msg_id,
|
ret = channel->send_message_with_response(channel, msg_id,
|
||||||
shmem_base,
|
shmem_base,
|
||||||
msg_data_len,
|
msg_data_len,
|
||||||
@@ -644,7 +652,7 @@ int sbi_mpxy_send_message(u32 channel_id, u8 msg_id,
|
|||||||
return SBI_ERR_FAILED;
|
return SBI_ERR_FAILED;
|
||||||
|
|
||||||
if (resp_data_len &&
|
if (resp_data_len &&
|
||||||
(*resp_data_len > ms->shmem.shmem_size ||
|
(*resp_data_len > mpxy_shmem_size ||
|
||||||
*resp_data_len > channel->attrs.msg_data_maxlen))
|
*resp_data_len > channel->attrs.msg_data_maxlen))
|
||||||
return SBI_ERR_FAILED;
|
return SBI_ERR_FAILED;
|
||||||
|
|
||||||
@@ -666,17 +674,17 @@ int sbi_mpxy_get_notification_events(u32 channel_id, unsigned long *events_len)
|
|||||||
return SBI_ERR_NOT_SUPPORTED;
|
return SBI_ERR_NOT_SUPPORTED;
|
||||||
|
|
||||||
shmem_base = hart_shmem_base(ms);
|
shmem_base = hart_shmem_base(ms);
|
||||||
sbi_hart_map_saddr((unsigned long)shmem_base, ms->shmem.shmem_size);
|
sbi_hart_map_saddr((unsigned long)shmem_base, mpxy_shmem_size);
|
||||||
eventsbuf = shmem_base;
|
eventsbuf = shmem_base;
|
||||||
ret = channel->get_notification_events(channel, eventsbuf,
|
ret = channel->get_notification_events(channel, eventsbuf,
|
||||||
ms->shmem.shmem_size,
|
mpxy_shmem_size,
|
||||||
events_len);
|
events_len);
|
||||||
sbi_hart_unmap_saddr();
|
sbi_hart_unmap_saddr();
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (*events_len > ms->shmem.shmem_size)
|
if (*events_len > (mpxy_shmem_size - 16))
|
||||||
return SBI_ERR_FAILED;
|
return SBI_ERR_FAILED;
|
||||||
|
|
||||||
return SBI_SUCCESS;
|
return SBI_SUCCESS;
|
||||||
|
Reference in New Issue
Block a user