aboutsummaryrefslogtreecommitdiffstats
path: root/lib/pru_rpmsg/include/pru_rpmsg.h
blob: 5d6d65e2489032ea8fd87fd903f05b96506c28e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/*
 * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *	* Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 *	* Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the
 *	  distribution.
 *
 *	* Neither the name of Texas Instruments Incorporated nor the names of
 *	  its contributors may be used to endorse or promote products derived
 *	  from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 *  File	:	pru_rpmsg.h
 *
 *  Summary	:	An RPMsg interface for the PRU to use while communicating with
 *			the ARM host.
 *
 *  Notes	:
 *  - This file creates a structure (pru_rpmsg_transport) that contains
 *    pointers to two pru_virtqueue structures. This structure is used as the
 *    underlying transport layer of all RPMsg communication. Only one
 *    pru_rpmsg_transport structure is needed because multiple logical channels
 *    can use the same underlying transport.
 *  - This pru_rpmsg interface is meant to sit on top of the pru_virtqueue
 *    interface and abstract the communication even further away from the
 *    underlying data structures. The goal is to make the communication as
 *    simple as possible at the user application level.
 *  - The logic for the PRU side is summarized below:
 *
 *    PRU Slave:
 *    - To receive buffer from the ARM host:
 *          pru_rpmsg_receive(*transport, *src, *dst, *data, *len);
 *    - To send buffer to the host:
 *          pru_rpmsg_send(*transport, src, dst, *data, len);
 */

#ifndef _PRU_RPMSG_H_
#define _PRU_RPMSG_H_

#include <pru_virtqueue.h>
#include <pru_virtio_ring.h>

/* Return value indicating no kick was sent */
#define PRU_RPMSG_NO_KICK			1
/* Return value indicating success */
#define PRU_RPMSG_SUCCESS			0
/* Return value indicating there were no available buffers */
#define PRU_RPMSG_NO_BUF_AVAILABLE		-1
/* Return value indicating that the buffer from the virtqueue was too small */
#define PRU_RPMSG_BUF_TOO_SMALL			-2
/* Return value indicating that an invalid head index was given */
#define PRU_RPMSG_INVALID_HEAD			-3
/* Return value indication that an invalid event number was given */
#define PRU_RPMSG_INVALID_EVENT			-4

/* Max PRU-ICSS system event number for pru_mst_intr */
#define MAX_VALID_EVENT				31
/* Min PRU-ICSS system event number for pru_mst_intr */
#define MIN_VALID_EVENT				16

/* The maximum size of the channel name and description */
#define RPMSG_NAME_SIZE 			32
/* The maximum size of the buffer (including the header) */
#define RPMSG_BUF_SIZE				512
/* The size of the buffer header */
#define RPMSG_HEADER_SIZE			16
/* The maximum size of the buffer message */
#define RPMSG_MESSAGE_SIZE			496

enum pru_rpmsg_ns_flags {
    RPMSG_NS_CREATE = 0,
    RPMSG_NS_DESTROY = 1
};

/**
 * Summary	:	pru_rpmsg_transport is a structure that groups together the
 *			two pru_virtqueues that are needed for two-way communication
 *			with the ARM. This structure provides a logical wrapper for
 *			the transport layer of the application. NOTE: Multiple
 *			(logical) channels can be implemented on top of the same
 *			transport layer.
 *
 * Variables	:	virtqueue0: contains the pru_virtqueue that is used for the
 *				    PRU->ARM communication
 *			virtqueue1: contains the pru_virtqueue that is used for
 *				    the ARM->PRU communication
 */
struct pru_rpmsg_transport {
	struct pru_virtqueue	virtqueue0;
	struct pru_virtqueue	virtqueue1;
};

/**
 * Summary	:	pru_rpmsg_init initializes the underlying transport layer
 *			data structures.
 *
 * Parameters	:	transport: a pointer to the transport data structure that
 *				   contains the underlying data structures to be
 *				   initialized
 *			vring0: a pointer to vring0 which is provided by the ARM
 *				core through the resource table
 *			vring1: a pointer to vring1 which is provided by the ARM
 *				core through the resource table
 *			to_arm_event: the number of the PRU-ICSS system event
 *				      that is specified in the device tree that
 *				      is used to 'kick' the ARM core
 *			from_arm_event: the number of the PRU-ICSS system event
 *					that is specified in the device tree
 *					that is used to receive 'kicks' from the
 *					ARM core
 *
 * Description	:	pru_rpmsg_init takes the vrings and the events provided
 *			through the resource table and initializes the transport
 *			layer. Once this function call is successful RPMsg
 *			channels can be created and used.
 *
 * Return Value :	Returns PRU_RPMSG_INVALID_EVENT if the values provided
 *			in to_arm_event or from_arm_event are outside of the
 *			allowable range of events. Returns PRU_RPMSG_SUCCESS
 *			if the initialization is successful.
 */
int16_t pru_rpmsg_init(
	struct pru_rpmsg_transport	*transport,
	struct fw_rsc_vdev_vring 	*vring0,
	struct fw_rsc_vdev_vring 	*vring1,
	uint32_t 			to_arm_event,
	uint32_t 			from_arm_event
);

/**
* Summary	:	pru_rpmsg_receive receives a message, if available, from
*			the ARM host.
*
* Parameters	:	transport: a pointer to the transport layer from which the
*				   message should be received
*			src: a pointer that is populated with the source address
*			     where the message originated
*			dst: a pointer that is populated with the destination
*			     address where the message was sent (can help determine
*			     for which channel the message is intended on the PRU)
*			data: a pointer that is populated with a local data buffer
*			      containing the message payload
*			len: a pointer that is populated with the length of the
*			     message payload
*
* Description	:	pru_rpmsg_receive uses the pru_virtqueue interface to get
*			an available buffer, copy the buffer into local memory,
*			add the buffer as a used buffer to the vring, and then kick
*			the remote processor if necessary. The src, dst, data, and
*			len pointers are populated with the information about the
*			message and local buffer data if the reception is
*			successful.
*
* Return Value	:	Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
*			buffer available for receive. Returns PRU_RPMSG_INVALID_HEAD
*			if the head index returned for the available buffer is
*			invalid. Returns PRU_RPMSG_SUCCESS if the message is
*			successfully received.
*/
int16_t pru_rpmsg_receive(
    struct pru_rpmsg_transport	*transport,
    uint16_t			*src,
    uint16_t			*dst,
    void			*data,
    uint16_t			*len
);

/**
* Summary	:	pru_rpmsg_send sends a message to the ARM host using the
*			virtqueues in the pru_rpmsg_transport structure. The
*			source and destination address of the message are passed
*			in as parameters to the function. The data to be sent and
*			its length are passed in the data and len parameters.
*
* Parameters	:	transport: a pointer to the transport layer from which the
*				   message should be sent
*			src: the source address where this message will originate
*			dst: the destination address where the message will be sent
*			data: a pointer to a local data buffer containing the
*			      message payload
*			len: the length of the message payload
*
* Description	:	pru_rpmsg_send sends a message to the src parameter and
*			from the dst parameter. The transport structure defines the
*			underlying transport mechanism that will be used. The
*			data parameter is a pointer to a local buffer that should
*			be sent to the destination address and the len parameter is
*			the length of that buffer.
*
* Return Value	:	Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
*			buffer available for send. Returns PRU_RPMSG_BUF_TOO_SMALL
*			if the buffer from the vring is too small to hold the
*			message payload being sent. Returns PRU_RPMSG_INVALID_HEAD
*			if the head index returned for the send buffer is invalid.
*			Returns PRU_RPMSG_SUCCESS if the message is successfully
*			sent.
*/
int16_t pru_rpmsg_send(
    struct pru_rpmsg_transport	*transport,
    uint32_t			src,
    uint32_t			dst,
    void			*data,
    uint16_t			len
);

/**
* Summary	:	pru_rpmsg_channel uses an RPMsg Name Service Announcment
*			to either create or destroy an RPMsg channel depending on
*			the pru_rpmsg_ns_flags parameter that is specified.
*
* Parameters	:	flags: an enum that is used to create (RPMSG_NS_CREATE) or
*			       destroy (RPMSG_NS_DESTROY) an RPMsg channel
*			transport: a pointer to the transport layer on which this
*				   Name Service Announcement will be sent
*			name: the name of the channel being created or destroyed
*			      ******* The name of the channel is very important as
*			      ******* it is the method that Linux on the ARM uses
*			      ******* to connect a PRU firmware with a corresponding
*			      ******* Linux driver
*			desc: the description of the RPMsg channel being created
*			      or destroyed
*			port: the local source address of the RPMsg channel. This
*			      is the address where PRU messages destined for the
*			      ARM host will originate
*
* Description	:	pru_rpmsg_channel sends a message letting the ARM
*			host know that a channel is to be created or destroyed. If
*			a channel is to be created then this message will notify
*			the name server on the ARM host to create a new channel. If
*			a channel is to be destroyed this will tear down this
*			logical channel of communication between the PRU and the
*			ARM host.
*
* Return Value	:	Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
*			buffer available for send. Returns PRU_RPMSG_BUF_TOO_SMALL
*			if the buffer from the vring is too small to hold the
*			message payload being sent. Returns PRU_RPMSG_INVALID_HEAD
*			if the head index returned for the send buffer is invalid.
*			Returns PRU_RPMSG_SUCCESS if the message is successfully
*			sent.
*/
int16_t pru_rpmsg_channel(
    enum pru_rpmsg_ns_flags	flags,
    struct pru_rpmsg_transport	*transport,
    char			*name,
    char			*desc,
    int32_t			port
);

#endif /* _PRU_RPMSG_H_ */