1 /*
2  * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef TS_PLATFORM_INTERFACE_MHU_H
8 #define TS_PLATFORM_INTERFACE_MHU_H
9 
10 /*
11  * Interface definition for a platform MHU driver.  A platform provider will
12  * provide concrete implementations of this interface for each alternative
13  * implementation supported.
14  */
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <stdint.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /*
24  * Virtual interface for a platform MHU driver.  A platform will provide
25  * one or more concrete implementations of this interface.
26  */
27 struct platform_mhu_iface {
28     /*
29      * \brief Sends data over MHU.
30      *
31      * \param[in] context         Platform driver context.
32      * \param[in] send_buffer     Pointer to buffer containing the data to be
33      *                            transmitted.
34      * \param[in] size            Size of the data to be transmitted in bytes.
35      *
36      * \return 0 if successful.
37      *
38      * \note The send_buffer must be 4-byte aligned and its length must be at least
39      *       (4 - (size % 4)) bytes bigger than the data size to prevent buffer
40      *       over-reading.
41      */
42 	int (*send)(void *context, unsigned char *send_buffer, size_t size);
43 
44     /*
45      * \brief Receives data from MHU.
46      *
47      * \param[in]     context           Platform driver context.
48      * \param[out]    receive_buffer    Pointer the buffer where to store the
49      *                                  received data.
50      * \param[in,out] size              As input the size of the receive_buffer,
51      *                                  as output the number of bytes received.
52      *                                  As a limitation, the size of the buffer
53      *                                  must be a multiple of 4.
54      *
55      * \return 0 if successful.
56      *
57      * \note The receive_buffer must be 4-byte aligned and its length must be a
58      *       multiple of 4.
59      */
60 	int (*receive)(void *context, unsigned char *receive_buffer, size_t *size);
61 
62     /*
63      * \brief Wait for data from MHU.
64      *
65      * \param[in] context           Platform driver context.
66      *
67      * \return 0 if successful.
68      *
69      * \note This function must be called before mhu_receive_data() if the MHU
70      *       receiver interrupt is not used.
71      */
72 	int (*wait_data)(void *context);
73 
74     /*
75      * \brief Signals an interrupt over the last available channel and wait for the
76      *        values to be cleared by the receiver.
77      *
78      * \param[in]   context           Platform driver context.
79      * \param[in]   value             Value that will be used while signaling.
80      *
81      * \return 0 if successful.
82      */
83 	int (*signal_and_wait_for_clear)(void *context, uint32_t value);
84 
85     /*
86      * \brief Wait for signal on the last available channel in a loop and
87      *        acknowledge the transfer by clearing the status on that channel.
88      *
89      * \param[in]     context          Platform driver context.
90      * \param[in]     value            Value that will be used while waiting.
91      *
92      * \return 0 if successful.
93      */
94 	int (*wait_for_signal_and_clear)(void *context, uint32_t value);
95 };
96 
97 /*
98  * A platform MHU driver instance.
99  */
100 struct platform_mhu_driver {
101 	void *context; /**< Opaque driver context */
102 	const struct platform_mhu_iface *iface; /**< Interface methods */
103 };
104 
105 /*
106  * \brief Factory method to construct a platform specific MHU driver
107  *
108  * \param[out] driver         Pointer to driver structure to initialize on construction.
109  * \param[in]  object_name    Deployment specific name of the instance in the config store.
110  * \param[in]  is_receiver    True if the MHU will be used for receiving data, false if sending.
111  *
112  * \return          0 if successful.
113  */
114 int platform_mhu_create(struct platform_mhu_driver *driver, const char *object_name,
115 			bool is_receiver);
116 
117 /*
118  * \brief Destroy a driver constructed using the factory method
119  *
120  * \param[in] driver    Pointer to driver structure for constructed driver.
121  */
122 void platform_mhu_destroy(struct platform_mhu_driver *driver);
123 
124 #ifdef __cplusplus
125 }
126 #endif
127 
128 #endif /* TS_PLATFORM_INTERFACE_MHU_H */
129