refactor(rse): put MHU code in a dedicated file

To be able to use RSE comms without MHU, a first step is to disentangle
the rse_comms.c file with MHU code direct calls. This is done with the
creation of a new file rse_comms_mhu.c. New APIs are created to
initialize the mailbox, get max message size and send and receive data.

Signed-off-by: Yann Gautier <yann.gautier@st.com>
Change-Id: I75dda77e1886beaa6ced6f92c311617125918cfa
This commit is contained in:
Yann Gautier 2024-09-23 14:00:01 +02:00
parent 5b46aaccec
commit 36416b1e76
6 changed files with 117 additions and 18 deletions

View file

@ -25,9 +25,15 @@ RSE communication layer
----------------------- -----------------------
The communication between RSE and other subsystems are primarily relying on the The communication between RSE and other subsystems are primarily relying on the
Message Handling Unit (MHU) module. The number of MHU interfaces between RSE Message Handling Unit (MHU) module.
and other cores is IMPDEF. Besides MHU other modules also could take part in
the communication. RSE is capable of mapping the AP memory to its address space. However, this is possible to use this communication protocol with a different
mailbox than MHU, by setting the flag ``PLAT_MHU=NO_MHU`` and implementing the
APIs given in the file: ``include/drivers/arm/rse_comms.h``.
The number of MHU interfaces between RSE and other cores is IMPDEF. Besides MHU
other modules also could take part in the communication. RSE is capable of
mapping the AP memory to its address space.
Thereby either RSE core itself or a DMA engine if it is present, can move the Thereby either RSE core itself or a DMA engine if it is present, can move the
data between memory belonging to RSE or AP. In this way, a bigger amount of data data between memory belonging to RSE or AP. In this way, a bigger amount of data
can be transferred in a short time. can be transferred in a short time.
@ -812,3 +818,4 @@ References
*Copyright (c) 2023-2024, Arm Limited. All rights reserved.* *Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
*Copyright (c) 2024, Linaro Limited. All rights reserved.* *Copyright (c) 2024, Linaro Limited. All rights reserved.*
*Copyright (c) 2025, STMicroelectronics - All Rights Reserved*

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022-2024, Arm Limited. All rights reserved. * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -24,7 +24,7 @@ union __packed __attribute__((aligned(4))) rse_comms_io_buffer_t {
static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len, static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
const psa_outvec *out_vec, size_t out_len) const psa_outvec *out_vec, size_t out_len)
{ {
size_t comms_mhu_msg_size; size_t comms_mbx_msg_size;
size_t comms_embed_msg_min_size; size_t comms_embed_msg_min_size;
size_t comms_embed_reply_min_size; size_t comms_embed_reply_min_size;
size_t in_size_total = 0; size_t in_size_total = 0;
@ -38,7 +38,7 @@ static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
out_size_total += out_vec[i].len; out_size_total += out_vec[i].len;
} }
comms_mhu_msg_size = mhu_get_max_message_size(); comms_mbx_msg_size = rse_mbx_get_max_message_size();
comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) + comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
sizeof(struct rse_embed_msg_t) - sizeof(struct rse_embed_msg_t) -
@ -49,9 +49,9 @@ static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE; PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
/* Use embed if we can pack into one message and reply, else use /* Use embed if we can pack into one message and reply, else use
* pointer_access. The underlying MHU transport protocol uses a * pointer_access. The underlying mailbox transport protocol uses a
* single uint32_t to track the length, so the amount of data that * single uint32_t to track the length, so the amount of data that
* can be in a message is 4 bytes less than mhu_get_max_message_size * can be in a message is 4 bytes less than rse_mbx_get_max_message_size
* reports. * reports.
* *
* TODO tune this with real performance numbers, it's possible a * TODO tune this with real performance numbers, it's possible a
@ -60,9 +60,9 @@ static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
* pointers. * pointers.
*/ */
if ((comms_embed_msg_min_size + in_size_total > if ((comms_embed_msg_min_size + in_size_total >
comms_mhu_msg_size - sizeof(uint32_t)) || comms_mbx_msg_size - sizeof(uint32_t)) ||
(comms_embed_reply_min_size + out_size_total > (comms_embed_reply_min_size + out_size_total >
comms_mhu_msg_size - sizeof(uint32_t))) { comms_mbx_msg_size - sizeof(uint32_t))) {
return RSE_COMMS_PROTOCOL_POINTER_ACCESS; return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
} else { } else {
return RSE_COMMS_PROTOCOL_EMBED; return RSE_COMMS_PROTOCOL_EMBED;
@ -76,7 +76,7 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
* functions not being reentrant becomes a problem. * functions not being reentrant becomes a problem.
*/ */
static union rse_comms_io_buffer_t io_buf; static union rse_comms_io_buffer_t io_buf;
enum mhu_error_t err; int err;
psa_status_t status; psa_status_t status;
static uint8_t seq_num = 1U; static uint8_t seq_num = 1U;
size_t msg_size; size_t msg_size;
@ -109,8 +109,8 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base); VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base);
} }
err = mhu_send_data((uint8_t *)&io_buf.msg, msg_size); err = rse_mbx_send_data((uint8_t *)&io_buf.msg, msg_size);
if (err != MHU_ERR_NONE) { if (err != 0) {
return PSA_ERROR_COMMUNICATION_FAILURE; return PSA_ERROR_COMMUNICATION_FAILURE;
} }
@ -122,8 +122,8 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
memset(&io_buf.msg, 0xA5, msg_size); memset(&io_buf.msg, 0xA5, msg_size);
#endif #endif
err = mhu_receive_data((uint8_t *)&io_buf.reply, &reply_size); err = rse_mbx_receive_data((uint8_t *)&io_buf.reply, &reply_size);
if (err != MHU_ERR_NONE) { if (err != 0) {
return PSA_ERROR_COMMUNICATION_FAILURE; return PSA_ERROR_COMMUNICATION_FAILURE;
} }
@ -144,7 +144,7 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base); VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base);
} }
/* Clear the MHU message buffer to remove assets from memory */ /* Clear the mailbox message buffer to remove assets from memory */
memset(&io_buf, 0x0, sizeof(io_buf)); memset(&io_buf, 0x0, sizeof(io_buf));
seq_num++; seq_num++;

View file

@ -16,6 +16,7 @@ RSE_COMMS_SOURCES := $(addprefix drivers/arm/rse/, \
# Default to MHUv2 if PLAT_MHU undefined # Default to MHUv2 if PLAT_MHU undefined
PLAT_MHU ?= MHUv2 PLAT_MHU ?= MHUv2
ifneq (${PLAT_MHU}, NO_MHU)
ifeq (${PLAT_MHU}, MHUv3) ifeq (${PLAT_MHU}, MHUv3)
RSE_COMMS_SOURCES += $(addprefix drivers/arm/mhu/, \ RSE_COMMS_SOURCES += $(addprefix drivers/arm/mhu/, \
mhu_v3_x.c \ mhu_v3_x.c \
@ -30,6 +31,12 @@ else
$(error Unsupported MHU version) $(error Unsupported MHU version)
endif endif
RSE_COMMS_SOURCES += $(addprefix drivers/arm/rse/, \
rse_comms_mhu.c \
)
PLAT_INCLUDES += -Idrivers/arm/mhu
endif
PLAT_INCLUDES += -Idrivers/arm/rse \ PLAT_INCLUDES += -Idrivers/arm/rse \
-Idrivers/arm/mhu \
-Iinclude/lib/psa -Iinclude/lib/psa

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <string.h>
#include <common/debug.h>
#include <drivers/arm/mhu.h>
#include <drivers/arm/rse_comms.h>
size_t rse_mbx_get_max_message_size(void)
{
return mhu_get_max_message_size();
}
int rse_mbx_send_data(const uint8_t *send_buffer, size_t size)
{
enum mhu_error_t err = mhu_send_data(send_buffer, size);
if (err != MHU_ERR_NONE) {
ERROR("mhu_send_data err=%d\n", err);
return -1;
}
return 0;
}
int rse_mbx_receive_data(uint8_t *receive_buffer, size_t *size)
{
enum mhu_error_t err = mhu_receive_data(receive_buffer, size);
if (err != MHU_ERR_NONE) {
ERROR("mhu_receive_data err=%d\n", err);
return -1;
}
return 0;
}
int rse_mbx_init(const void *init_data)
{
enum mhu_error_t err;
const struct mhu_addr *mbx_addr = (const struct mhu_addr *)init_data;
err = mhu_init_sender(mbx_addr->sender_base);
if (err != MHU_ERR_NONE) {
if (err == MHU_ERR_ALREADY_INIT) {
INFO("[RSE-COMMS] Host to RSE MHU driver already initialized\n");
} else {
ERROR("[RSE-COMMS] Host to RSE MHU driver initialization failed: %d\n",
err);
return -1;
}
}
err = mhu_init_receiver(mbx_addr->receiver_base);
if (err != MHU_ERR_NONE) {
if (err == MHU_ERR_ALREADY_INIT) {
INFO("[RSE-COMMS] RSE to Host MHU driver already initialized\n");
} else {
ERROR("[RSE-COMMS] RSE to Host MHU driver initialization failed: %d\n",
err);
return -1;
}
}
return 0;
}

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2022, Arm Limited. All rights reserved. * Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -24,6 +25,14 @@ enum mhu_error_t {
MHU_ERR_GENERAL = -7, MHU_ERR_GENERAL = -7,
}; };
/**
* Structure used by RSE comms
*/
struct mhu_addr {
uintptr_t sender_base;
uintptr_t receiver_base;
};
/** /**
* Initializes sender MHU. * Initializes sender MHU.
* *

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Arm Limited. All rights reserved. * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
@ -8,8 +8,13 @@
#ifndef RSE_COMMS_H #ifndef RSE_COMMS_H
#define RSE_COMMS_H #define RSE_COMMS_H
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
size_t rse_mbx_get_max_message_size(void);
int rse_mbx_send_data(const uint8_t *send_buffer, size_t size);
int rse_mbx_receive_data(uint8_t *receive_buffer, size_t *size);
int rse_mbx_init(const void *init_data);
int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base); int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
#endif /* RSE_COMMS_H */ #endif /* RSE_COMMS_H */