f2e814a35199ac49ef60a456f60e83ead62406cb
1 /*
2 * Copyright (c) 2014, Mentor Graphics Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. Neither the name of Mentor Graphics Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
30 #ifndef _RPMSG_CORE_H_
31 #define _RPMSG_CORE_H_
33 #include "openamp/compiler.h"
34 #include "openamp/env.h"
35 #include "openamp/virtio.h"
36 #include "openamp/hil.h"
37 #include "openamp/sh_mem.h"
38 #include "openamp/llist.h"
39 #include "openamp/rpmsg.h"
40 #include "metal/mutex.h"
41 #include "metal/list.h"
43 /* Configurable parameters */
44 #define RPMSG_BUFFER_SIZE 512
45 #define RPMSG_MAX_VQ_PER_RDEV 2
46 #define RPMSG_NS_EPT_ADDR 0x35
47 #define RPMSG_ADDR_BMP_SIZE 4
49 /* Definitions for device types , null pointer, etc.*/
50 #define RPMSG_SUCCESS 0
51 #define RPMSG_NULL (void *)0
52 #define RPMSG_REMOTE 0
53 #define RPMSG_MASTER 1
54 #define RPMSG_TRUE 1
55 #define RPMSG_FALSE 0
57 /* RPMSG channel states. */
58 #define RPMSG_CHNL_STATE_IDLE 0
59 #define RPMSG_CHNL_STATE_NS 1
60 #define RPMSG_CHNL_STATE_ACTIVE 2
62 /* Remote processor/device states. */
63 #define RPMSG_DEV_STATE_IDLE 0
64 #define RPMSG_DEV_STATE_ACTIVE 1
66 /* Total tick count for 15secs - 1msec tick. */
67 #define RPMSG_TICK_COUNT 15000
69 /* Time to wait - In multiple of 10 msecs. */
70 #define RPMSG_TICKS_PER_INTERVAL 10
72 /* Error macros. */
73 #define RPMSG_ERROR_BASE -2000
74 #define RPMSG_ERR_NO_MEM (RPMSG_ERROR_BASE - 1)
75 #define RPMSG_ERR_NO_BUFF (RPMSG_ERROR_BASE - 2)
76 #define RPMSG_ERR_MAX_VQ (RPMSG_ERROR_BASE - 3)
77 #define RPMSG_ERR_PARAM (RPMSG_ERROR_BASE - 4)
78 #define RPMSG_ERR_DEV_STATE (RPMSG_ERROR_BASE - 5)
79 #define RPMSG_ERR_BUFF_SIZE (RPMSG_ERROR_BASE - 6)
80 #define RPMSG_ERR_DEV_ID (RPMSG_ERROR_BASE - 7)
81 #define RPMSG_ERR_DEV_ADDR (RPMSG_ERROR_BASE - 8)
83 #if (RPMSG_DEBUG == true)
84 #define RPMSG_ASSERT(_exp, _msg) do{ \
85 if (!(_exp)){ printf("%s - "_msg, __func__); while(1);} \
86 } while(0)
87 #else
88 #define RPMSG_ASSERT(_exp, _msg) if (!(_exp)) while(1)
89 #endif
91 struct rpmsg_channel;
92 typedef void (*rpmsg_rx_cb_t) (struct rpmsg_channel *, void *, int, void *,
93 unsigned long);
94 typedef void (*rpmsg_chnl_cb_t) (struct rpmsg_channel * rp_chl);
95 /**
96 * remote_device
97 *
98 * This structure is maintained by RPMSG driver to represent remote device/core.
99 *
100 * @virtd_dev - virtio device for remote core
101 * @rvq - Rx virtqueue for virtio device
102 * @tvq - Tx virtqueue for virtio device
103 * @proc - reference to remote processor
104 * @rp_channels - rpmsg channels list for the device
105 * @rp_endpoints - rpmsg endpoints list for the device
106 * @mem_pool - shared memory pool
107 * @bitmap - bitmap for channels addresses
108 * @channel_created - create channel callback
109 * @channel_destroyed - delete channel callback
110 * @default_cb - default callback handler for RX data on channel
111 * @lock - remote device mutex
112 * @role - role of the remote device, RPMSG_MASTER/RPMSG_REMOTE
113 * @state - remote device state, IDLE/ACTIVE
114 * @support_ns - if device supports name service announcement
115 *
116 */
117 struct remote_device {
118 struct virtio_device virt_dev;
119 struct virtqueue *rvq;
120 struct virtqueue *tvq;
121 struct hil_proc *proc;
122 struct metal_list rp_channels;
123 struct metal_list rp_endpoints;
124 struct sh_mem_pool *mem_pool;
125 unsigned long bitmap[RPMSG_ADDR_BMP_SIZE];
126 rpmsg_chnl_cb_t channel_created;
127 rpmsg_chnl_cb_t channel_destroyed;
128 rpmsg_rx_cb_t default_cb;
129 metal_mutex_t lock;
130 unsigned int role;
131 unsigned int state;
132 int support_ns;
133 };
135 /* Core functions */
136 int rpmsg_start_ipc(struct remote_device *rdev);
137 struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,
138 char *name, unsigned long src,
139 unsigned long dst);
140 void _rpmsg_delete_channel(struct rpmsg_channel *rp_chnl);
141 struct rpmsg_endpoint *_create_endpoint(struct remote_device *rdev,
142 rpmsg_rx_cb_t cb, void *priv,
143 unsigned long addr);
144 void _destroy_endpoint(struct remote_device *rdev,
145 struct rpmsg_endpoint *rp_ept);
146 void rpmsg_send_ns_message(struct remote_device *rdev,
147 struct rpmsg_channel *rp_chnl, unsigned long flags);
148 int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,
149 unsigned long len, unsigned short idx);
150 void rpmsg_return_buffer(struct remote_device *rdev, void *buffer,
151 unsigned long len, unsigned short idx);
152 void *rpmsg_get_tx_buffer(struct remote_device *rdev, unsigned long *len,
153 unsigned short *idx);
154 void rpmsg_free_buffer(struct remote_device *rdev, void *buffer);
155 void rpmsg_free_channel(struct rpmsg_channel *rp_chnl);
156 void *rpmsg_get_rx_buffer(struct remote_device *rdev, unsigned long *len,
157 unsigned short *idx);
158 int rpmsg_get_address(unsigned long *bitmap, int size);
159 int rpmsg_release_address(unsigned long *bitmap, int size, int addr);
160 int rpmsg_is_address_set(unsigned long *bitmap, int size, int addr);
161 int rpmsg_set_address(unsigned long *bitmap, int size, int addr);
162 void rpmsg_ns_callback(struct rpmsg_channel *server_chnl,
163 void *data, int len, void *priv, unsigned long src);
165 /* Remote device functions */
166 int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
167 rpmsg_chnl_cb_t channel_created,
168 rpmsg_chnl_cb_t channel_destroyed,
169 rpmsg_rx_cb_t default_cb);
170 void rpmsg_rdev_deinit(struct remote_device *rdev);
171 struct rpmsg_channel *rpmsg_rdev_get_chnl_from_id(struct remote_device *rdev,
172 char *rp_chnl_id);
173 struct rpmsg_endpoint *rpmsg_rdev_get_endpoint_from_addr(
174 struct remote_device *rdev,
175 unsigned long addr);
176 int rpmsg_rdev_notify(struct remote_device *rdev);
177 int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
178 const char *names[], vq_callback * callbacks[],
179 struct virtqueue *vqs[]);
180 unsigned char rpmsg_rdev_get_status(struct virtio_device *dev);
182 void rpmsg_rdev_set_status(struct virtio_device *dev, unsigned char status);
184 uint32_t rpmsg_rdev_get_feature(struct virtio_device *dev);
186 void rpmsg_rdev_set_feature(struct virtio_device *dev, uint32_t feature);
188 uint32_t rpmsg_rdev_negotiate_feature(struct virtio_device *dev,
189 uint32_t features);
190 /*
191 * Read/write a variable amount from the device specific (ie, network)
192 * configuration region. This region is encoded in the same endian as
193 * the guest.
194 */
195 void rpmsg_rdev_read_config(struct virtio_device *dev, uint32_t offset,
196 void *dst, int length);
197 void rpmsg_rdev_write_config(struct virtio_device *dev, uint32_t offset,
198 void *src, int length);
199 void rpmsg_rdev_reset(struct virtio_device *dev);
201 #endif /* _RPMSG_CORE_H_ */