Line data Source code
1 0 : /*
2 : * Copyright (c) 2020 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_DRIVERS_VIRTUALIZATION_IVSHMEM_H_
8 : #define ZEPHYR_INCLUDE_DRIVERS_VIRTUALIZATION_IVSHMEM_H_
9 :
10 : /**
11 : * @brief Inter-VM Shared Memory (ivshmem) reference API
12 : * @defgroup ivshmem Inter-VM Shared Memory (ivshmem) reference API
13 : * @ingroup io_interfaces
14 : * @{
15 : */
16 :
17 : #include <zephyr/types.h>
18 : #include <stddef.h>
19 : #include <zephyr/device.h>
20 : #include <zephyr/kernel.h>
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 :
26 0 : #define IVSHMEM_V2_PROTO_UNDEFINED 0x0000
27 0 : #define IVSHMEM_V2_PROTO_NET 0x0001
28 :
29 0 : typedef size_t (*ivshmem_get_mem_f)(const struct device *dev,
30 : uintptr_t *memmap);
31 :
32 0 : typedef uint32_t (*ivshmem_get_id_f)(const struct device *dev);
33 :
34 0 : typedef uint16_t (*ivshmem_get_vectors_f)(const struct device *dev);
35 :
36 0 : typedef int (*ivshmem_int_peer_f)(const struct device *dev,
37 : uint32_t peer_id, uint16_t vector);
38 :
39 0 : typedef int (*ivshmem_register_handler_f)(const struct device *dev,
40 : struct k_poll_signal *signal,
41 : uint16_t vector);
42 :
43 : #ifdef CONFIG_IVSHMEM_V2
44 :
45 : typedef size_t (*ivshmem_get_rw_mem_section_f)(const struct device *dev,
46 : uintptr_t *memmap);
47 :
48 : typedef size_t (*ivshmem_get_output_mem_section_f)(const struct device *dev,
49 : uint32_t peer_id,
50 : uintptr_t *memmap);
51 :
52 : typedef uint32_t (*ivshmem_get_state_f)(const struct device *dev,
53 : uint32_t peer_id);
54 :
55 : typedef int (*ivshmem_set_state_f)(const struct device *dev,
56 : uint32_t state);
57 :
58 : typedef uint32_t (*ivshmem_get_max_peers_f)(const struct device *dev);
59 :
60 : typedef uint16_t (*ivshmem_get_protocol_f)(const struct device *dev);
61 :
62 : typedef int (*ivshmem_enable_interrupts_f)(const struct device *dev,
63 : bool enable);
64 :
65 : #endif /* CONFIG_IVSHMEM_V2 */
66 :
67 0 : __subsystem struct ivshmem_driver_api {
68 0 : ivshmem_get_mem_f get_mem;
69 0 : ivshmem_get_id_f get_id;
70 0 : ivshmem_get_vectors_f get_vectors;
71 0 : ivshmem_int_peer_f int_peer;
72 0 : ivshmem_register_handler_f register_handler;
73 : #ifdef CONFIG_IVSHMEM_V2
74 : ivshmem_get_rw_mem_section_f get_rw_mem_section;
75 : ivshmem_get_output_mem_section_f get_output_mem_section;
76 : ivshmem_get_state_f get_state;
77 : ivshmem_set_state_f set_state;
78 : ivshmem_get_max_peers_f get_max_peers;
79 : ivshmem_get_protocol_f get_protocol;
80 : ivshmem_enable_interrupts_f enable_interrupts;
81 : #endif
82 : };
83 :
84 : /**
85 : * @brief Get the inter-VM shared memory
86 : *
87 : * Note: This API is not supported for ivshmem-v2, as
88 : * the R/W and R/O areas may not be mapped contiguously.
89 : * For ivshmem-v2, use the ivshmem_get_rw_mem_section,
90 : * ivshmem_get_output_mem_section and ivshmem_get_state
91 : * APIs to access the shared memory.
92 : *
93 : * @param dev Pointer to the device structure for the driver instance
94 : * @param memmap A pointer to fill in with the memory address
95 : *
96 : * @return the size of the memory mapped, or 0
97 : */
98 1 : __syscall size_t ivshmem_get_mem(const struct device *dev,
99 : uintptr_t *memmap);
100 :
101 : static inline size_t z_impl_ivshmem_get_mem(const struct device *dev,
102 : uintptr_t *memmap)
103 : {
104 : const struct ivshmem_driver_api *api =
105 : (const struct ivshmem_driver_api *)dev->api;
106 :
107 : return api->get_mem(dev, memmap);
108 : }
109 :
110 : /**
111 : * @brief Get our VM ID
112 : *
113 : * @param dev Pointer to the device structure for the driver instance
114 : *
115 : * @return our VM ID or 0 if we are not running on doorbell version
116 : */
117 1 : __syscall uint32_t ivshmem_get_id(const struct device *dev);
118 :
119 : static inline uint32_t z_impl_ivshmem_get_id(const struct device *dev)
120 : {
121 : const struct ivshmem_driver_api *api =
122 : (const struct ivshmem_driver_api *)dev->api;
123 :
124 : return api->get_id(dev);
125 : }
126 :
127 : /**
128 : * @brief Get the number of interrupt vectors we can use
129 : *
130 : * @param dev Pointer to the device structure for the driver instance
131 : *
132 : * @return the number of available interrupt vectors
133 : */
134 1 : __syscall uint16_t ivshmem_get_vectors(const struct device *dev);
135 :
136 : static inline uint16_t z_impl_ivshmem_get_vectors(const struct device *dev)
137 : {
138 : const struct ivshmem_driver_api *api =
139 : (const struct ivshmem_driver_api *)dev->api;
140 :
141 : return api->get_vectors(dev);
142 : }
143 :
144 : /**
145 : * @brief Interrupt another VM
146 : *
147 : * @param dev Pointer to the device structure for the driver instance
148 : * @param peer_id The VM ID to interrupt
149 : * @param vector The interrupt vector to use
150 : *
151 : * @return 0 on success, a negative errno otherwise
152 : */
153 1 : __syscall int ivshmem_int_peer(const struct device *dev,
154 : uint32_t peer_id, uint16_t vector);
155 :
156 : static inline int z_impl_ivshmem_int_peer(const struct device *dev,
157 : uint32_t peer_id, uint16_t vector)
158 : {
159 : const struct ivshmem_driver_api *api =
160 : (const struct ivshmem_driver_api *)dev->api;
161 :
162 : return api->int_peer(dev, peer_id, vector);
163 : }
164 :
165 : /**
166 : * @brief Register a vector notification (interrupt) handler
167 : *
168 : * @param dev Pointer to the device structure for the driver instance
169 : * @param signal A pointer to a valid and ready to be signaled
170 : * struct k_poll_signal. Or NULL to unregister any handler
171 : * registered for the given vector.
172 : * @param vector The interrupt vector to get notification from
173 : *
174 : * Note: The returned status, if positive, to a raised signal is the vector
175 : * that generated the signal. This lets the possibility to the user
176 : * to have one signal for all vectors, or one per-vector.
177 : *
178 : * @return 0 on success, a negative errno otherwise
179 : */
180 1 : __syscall int ivshmem_register_handler(const struct device *dev,
181 : struct k_poll_signal *signal,
182 : uint16_t vector);
183 :
184 : static inline int z_impl_ivshmem_register_handler(const struct device *dev,
185 : struct k_poll_signal *signal,
186 : uint16_t vector)
187 : {
188 : const struct ivshmem_driver_api *api =
189 : (const struct ivshmem_driver_api *)dev->api;
190 :
191 : return api->register_handler(dev, signal, vector);
192 : }
193 :
194 : #ifdef CONFIG_IVSHMEM_V2
195 :
196 : /**
197 : * @brief Get the ivshmem read/write section (ivshmem-v2 only)
198 : *
199 : * @param dev Pointer to the device structure for the driver instance
200 : * @param memmap A pointer to fill in with the memory address
201 : *
202 : * @return the size of the memory mapped, or 0
203 : */
204 : __syscall size_t ivshmem_get_rw_mem_section(const struct device *dev,
205 : uintptr_t *memmap);
206 :
207 : static inline size_t z_impl_ivshmem_get_rw_mem_section(const struct device *dev,
208 : uintptr_t *memmap)
209 : {
210 : const struct ivshmem_driver_api *api =
211 : (const struct ivshmem_driver_api *)dev->api;
212 :
213 : return api->get_rw_mem_section(dev, memmap);
214 : }
215 :
216 : /**
217 : * @brief Get the ivshmem output section for a peer (ivshmem-v2 only)
218 : *
219 : * @param dev Pointer to the device structure for the driver instance
220 : * @param peer_id The VM ID whose output memory section to get
221 : * @param memmap A pointer to fill in with the memory address
222 : *
223 : * @return the size of the memory mapped, or 0
224 : */
225 : __syscall size_t ivshmem_get_output_mem_section(const struct device *dev,
226 : uint32_t peer_id,
227 : uintptr_t *memmap);
228 :
229 : static inline size_t z_impl_ivshmem_get_output_mem_section(const struct device *dev,
230 : uint32_t peer_id,
231 : uintptr_t *memmap)
232 : {
233 : const struct ivshmem_driver_api *api =
234 : (const struct ivshmem_driver_api *)dev->api;
235 :
236 : return api->get_output_mem_section(dev, peer_id, memmap);
237 : }
238 :
239 : /**
240 : * @brief Get the state value of a peer (ivshmem-v2 only)
241 : *
242 : * @param dev Pointer to the device structure for the driver instance
243 : * @param peer_id The VM ID whose state to get
244 : *
245 : * @return the state value of the peer
246 : */
247 : __syscall uint32_t ivshmem_get_state(const struct device *dev,
248 : uint32_t peer_id);
249 :
250 : static inline uint32_t z_impl_ivshmem_get_state(const struct device *dev,
251 : uint32_t peer_id)
252 : {
253 : const struct ivshmem_driver_api *api =
254 : (const struct ivshmem_driver_api *)dev->api;
255 :
256 : return api->get_state(dev, peer_id);
257 : }
258 :
259 : /**
260 : * @brief Set our state (ivshmem-v2 only)
261 : *
262 : * @param dev Pointer to the device structure for the driver instance
263 : * @param state The state value to set
264 : *
265 : * @return 0 on success, a negative errno otherwise
266 : */
267 : __syscall int ivshmem_set_state(const struct device *dev,
268 : uint32_t state);
269 :
270 : static inline int z_impl_ivshmem_set_state(const struct device *dev,
271 : uint32_t state)
272 : {
273 : const struct ivshmem_driver_api *api =
274 : (const struct ivshmem_driver_api *)dev->api;
275 :
276 : return api->set_state(dev, state);
277 : }
278 :
279 : /**
280 : * @brief Get the maximum number of peers supported (ivshmem-v2 only)
281 : *
282 : * @param dev Pointer to the device structure for the driver instance
283 : *
284 : * @return the maximum number of peers supported, or 0
285 : */
286 : __syscall uint32_t ivshmem_get_max_peers(const struct device *dev);
287 :
288 : static inline uint32_t z_impl_ivshmem_get_max_peers(const struct device *dev)
289 : {
290 : const struct ivshmem_driver_api *api =
291 : (const struct ivshmem_driver_api *)dev->api;
292 :
293 : return api->get_max_peers(dev);
294 : }
295 :
296 : /**
297 : * @brief Get the protocol used by this ivshmem instance (ivshmem-v2 only)
298 : *
299 : * @param dev Pointer to the device structure for the driver instance
300 : *
301 : * @return the protocol
302 : */
303 : __syscall uint16_t ivshmem_get_protocol(const struct device *dev);
304 :
305 : static inline uint16_t z_impl_ivshmem_get_protocol(const struct device *dev)
306 : {
307 : const struct ivshmem_driver_api *api =
308 : (const struct ivshmem_driver_api *)dev->api;
309 :
310 : return api->get_protocol(dev);
311 : }
312 :
313 : /**
314 : * @brief Set the interrupt enablement for our VM (ivshmem-v2 only)
315 : *
316 : * @param dev Pointer to the device structure for the driver instance
317 : * @param enable True to enable interrupts, false to disable
318 : *
319 : * @return 0 on success, a negative errno otherwise
320 : */
321 : __syscall int ivshmem_enable_interrupts(const struct device *dev,
322 : bool enable);
323 :
324 : static inline int z_impl_ivshmem_enable_interrupts(const struct device *dev,
325 : bool enable)
326 : {
327 : const struct ivshmem_driver_api *api =
328 : (const struct ivshmem_driver_api *)dev->api;
329 :
330 : return api->enable_interrupts(dev, enable);
331 : }
332 :
333 : #endif /* CONFIG_IVSHMEM_V2 */
334 :
335 : #ifdef __cplusplus
336 : }
337 : #endif
338 :
339 : /**
340 : * @}
341 : */
342 :
343 : #include <zephyr/syscalls/ivshmem.h>
344 :
345 : #endif /* ZEPHYR_INCLUDE_DRIVERS_VIRTUALIZATION_IVSHMEM_H_ */
|