aboutsummaryrefslogtreecommitdiffstats
path: root/lib/pru_rpmsg/include/pru_virtqueue.h
blob: 7290c89ada41d2c12c23e0844b9bc0c5e8bbad69 (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
/*
 * Copyright (C) 2016 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_virtqueue.h
*
*  Summary	:	A virtual queue interface to simplify vring usage.
*
*  Notes	:
*  - This file implements the vring functions needed by the PRU core
*  - The PRU core is considered the slave and the ARM core is considered the
*    host
*  - The ARM host always adds *available* buffers to send/receive, while the
*    PRU slave always adds *used* buffers to send/receive.
*  - The logic for the PRU side is summarized below:
*
*    PRU Slave:
*    - To receive buffer from the ARM host:
*          virtqueue_getAvailBuf(vq_slave);
*              >> empty data from buf <<
*          virtqueue_addUsedBuf(vq_slave);
*          virtqueue_kick(vq_slave);
*    - To send buffer to the host:
*          virtqueue_getAvailBuf(vq_host);
*              >> copy data into buf <<
*          virtqueue_addUsedBuf(vq_host);
*          virtqueue_kick(vq_host);
*/

#ifndef _PRU_VIRTQUEUE_H_
#define _PRU_VIRTQUEUE_H_

#include <rsc_types.h>
#include <pru_virtio_ring.h>

/* Return value indicating no kick was sent */
#define PRU_VIRTQUEUE_NO_KICK			1
/* Return value indicating success */
#define PRU_VIRTQUEUE_SUCCESS			0
/* Return value indicating there were no available buffers */
#define PRU_VIRTQUEUE_NO_BUF_AVAILABLE		-1
/* Return value indicating that an invalid head index was given */
#define PRU_VIRTQUEUE_INVALID_HEAD		-2

/**
 * Summary	:	pru_virtqueue is a structure that encapsulates everything
 *			needed for a 'virtual queue'. This structure wraps a vring
 *			with extra information that is needed by the application
 *			in order to use the vring.
 *
 * Variables	:	id: The notification ID of the vring. 
 *			to_arm_event: The PRU-ICSS system event that signals the ARM.
 *			from_arm_event: The PRU-ICSS system event that the ARM uses to
 *					signal the PRU.
 *			last_avail_idx: A local running counter that is used by the
 *					PRU to determine whether or not a new
 *					available buffer has been added to the
 *					vring.
 *			vring: The underlying virtio structure that is being used
 *			       to pass buffers back and forth between the ARM and
 *			       PRU. See pru_virtio_ring.h.
 */
struct pru_virtqueue {
	uint32_t	id;
	uint32_t	to_arm_event;
	uint32_t	from_arm_event;
	uint16_t 	last_avail_idx;
	struct vring 	vring;
};

/**
* Summary	:	pru_virtqueue_init initializes the pru_virtqueue structure
*			with values from the resource table.
*
* Parameters	:	vq: a pointer to a pru_virtqueue structure that will be
*			    initialized
*			vring: a pointer to a vring that is populated and returned
*			       by the ARM host through the resource table (the id,
*			       number of descriptors, address of the vring, and
*			       alignment information are contained in this vring
*			       pointer's structure
*			to_arm_event: the PRU-ICSS system event to trigger in order to
*				      'kick' the ARM host when sending data
*			from_arm_event: the PRU-ICSS system event to check
*					for data arriving from the ARM host
*
* Description	:	This function initializes the pru_virtqueue (vq) with input
*			values from the vring in the resource table. This function
*			should be called once for each virtqueue/vring. After
*			initialization the pru_virtqueue pointer, vq, should be
*			passed to the other functions in this header file.
*
* Return Value	:	No return value.
*/
void pru_virtqueue_init(
	struct pru_virtqueue 		*vq,
	struct fw_rsc_vdev_vring 	*vring,
	uint32_t 			to_arm_event,
	uint32_t 			from_arm_event
);

/**
* Summary	:	pru_virtqueue_get_avail_buf - gets the next available
*			buffer from the pru_virtqueue specified in vq.
*
* Parameters	:	vq: pointer to the pru_virtqueue from which the available
*			    buffer should be retrieved
*			buf: pointer to be filled with the address of the available
*			     buffer
*			len: pointer to be filled with the length of the available
*			     buffer
*
* Description	:	This function compares our last_avail_idx running counter
*			against the vring.avail->idx value to see if there is a
*			buffer available that we have not used. If our last
*			available index running counter matches the vring.avail->idx
*			value then there have been no new available buffers added
*			by the host. If the two indices do not match then the host
*			has added new buffers and and we can set @buf to point to
*			the available buffer and @len to match the available buffers
*			length. If an available buffer is found we increment out
*			last_avail_idx to show that we used another buffer.
*
* Return Value	:	PRU_VIRTQUEUE_NO_BUF_AVAILABLE if no buffer available.
*			Returns the vring.desc index of the available buffer
*			otherwise.
*/
int16_t pru_virtqueue_get_avail_buf(
    struct pru_virtqueue	*vq,
    void			**buf,
    uint32_t			*len
);

/**
* Summary	:	pru_virtqueue_add_used_buf adds a used buffer to the
*			pru_virtqueue specified in vq.
*
* Parameters	:	vq: pointer to the pru_virtqueue where the used buffer
*			    should be added
*			head: vring.desc[] index of the used buffer
*			len: length of the used buffer being added
*
* Description	:	This function makes sure that the head vring.desc index
*			(head) is a valid index. If the index is valid, then the
*			buffer is added to the used list in the vring contained by
*			the pru_virtqueue (vq).
*
* Return Value	:	PRU_VIRTQUEUE_INVALID_HEAD if head is an invalid index for
*			the vring.desc array. Returns PRU_VIRTQUEUE_SUCCESS
*			otherwise.
*/
int16_t pru_virtqueue_add_used_buf(
    struct pru_virtqueue	*vq,
    int16_t			head,
    uint32_t			len
);

/**
* Summary	:	pru_virtqueue_kick sends a notification to the remote
*			processor that the PRU has added a buffer to the
*			pru_virtqueue.
*
* Parameters	:	vq: pointer to the pru_virtqueue that is to be kicked
*
* Description	:	This function is used by the PRU to notify the ARM host in
*			two situations:
*				1.	That the PRU has consumed a buffer that the ARM
*					host sent through the slave pru_virtqueue
*				2.	That the PRU has sent a buffer to the ARM through
*					the host pru_virtqueue
*			If the pru_virtqueue's VRING_AVAIL_F_NO_INTERRUPT flag is
*			set then the pru does not kick the pru_virtqueue.
*
* Return Value	:	PRU_VIRTQUEUE_NO_KICK if the VRING_AVAIL_F_NO_INTERRUPT
*			flag is set or PRU_VIRTQUEUE_SUCCESS otherwise.
*/
int16_t pru_virtqueue_kick(
    struct pru_virtqueue	*vq
);

#endif /* _PRU_VIRTQUEUE_H_ */