1 /*
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 ivshmem reference API
12 * @defgroup ivshmem ivshmem reference API
13 * @{
14 */
15
16 #include <zephyr/types.h>
17 #include <stddef.h>
18 #include <device.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 typedef size_t (*ivshmem_get_mem_f)(const struct device *dev,
25 uintptr_t *memmap);
26
27 typedef uint32_t (*ivshmem_get_id_f)(const struct device *dev);
28
29 typedef uint16_t (*ivshmem_get_vectors_f)(const struct device *dev);
30
31 typedef int (*ivshmem_int_peer_f)(const struct device *dev,
32 uint32_t peer_id, uint16_t vector);
33
34 typedef int (*ivshmem_register_handler_f)(const struct device *dev,
35 struct k_poll_signal *signal,
36 uint16_t vector);
37
38 __subsystem struct ivshmem_driver_api {
39 ivshmem_get_mem_f get_mem;
40 ivshmem_get_id_f get_id;
41 ivshmem_get_vectors_f get_vectors;
42 ivshmem_int_peer_f int_peer;
43 ivshmem_register_handler_f register_handler;
44 };
45
46 /**
47 * @brief Get the inter-VM shared memory
48 *
49 * @param dev Pointer to the device structure for the driver instance
50 * @param memmap A pointer to fill in with the memory address
51 *
52 * @return the size of the memory mapped, or 0
53 */
54 __syscall size_t ivshmem_get_mem(const struct device *dev,
55 uintptr_t *memmap);
56
z_impl_ivshmem_get_mem(const struct device * dev,uintptr_t * memmap)57 static inline size_t z_impl_ivshmem_get_mem(const struct device *dev,
58 uintptr_t *memmap)
59 {
60 const struct ivshmem_driver_api *api =
61 (const struct ivshmem_driver_api *)dev->api;
62
63 return api->get_mem(dev, memmap);
64 }
65
66 /**
67 * @brief Get our VM ID
68 *
69 * @param dev Pointer to the device structure for the driver instance
70 *
71 * @return our VM ID or 0 if we are not running on doorbell version
72 */
73 __syscall uint32_t ivshmem_get_id(const struct device *dev);
74
z_impl_ivshmem_get_id(const struct device * dev)75 static inline uint32_t z_impl_ivshmem_get_id(const struct device *dev)
76 {
77 const struct ivshmem_driver_api *api =
78 (const struct ivshmem_driver_api *)dev->api;
79
80 return api->get_id(dev);
81 }
82
83 /**
84 * @brief Get the number of interrupt vectors we can use
85 *
86 * @param dev Pointer to the device structure for the driver instance
87 *
88 * @return the number of available interrupt vectors
89 */
90 __syscall uint16_t ivshmem_get_vectors(const struct device *dev);
91
z_impl_ivshmem_get_vectors(const struct device * dev)92 static inline uint16_t z_impl_ivshmem_get_vectors(const struct device *dev)
93 {
94 const struct ivshmem_driver_api *api =
95 (const struct ivshmem_driver_api *)dev->api;
96
97 return api->get_vectors(dev);
98 }
99
100 /**
101 * @brief Interrupt another VM
102 *
103 * @param dev Pointer to the device structure for the driver instance
104 * @param peer_id The VM ID to interrupt
105 * @param vector The interrupt vector to use
106 *
107 * @return 0 on success, a negative errno otherwise
108 */
109 __syscall int ivshmem_int_peer(const struct device *dev,
110 uint32_t peer_id, uint16_t vector);
111
z_impl_ivshmem_int_peer(const struct device * dev,uint32_t peer_id,uint16_t vector)112 static inline int z_impl_ivshmem_int_peer(const struct device *dev,
113 uint32_t peer_id, uint16_t vector)
114 {
115 const struct ivshmem_driver_api *api =
116 (const struct ivshmem_driver_api *)dev->api;
117
118 return api->int_peer(dev, peer_id, vector);
119 }
120
121 /**
122 * @brief Register a vector notification (interrupt) handler
123 *
124 * @param dev Pointer to the device structure for the driver instance
125 * @param signal A pointer to a valid and ready to be signaled
126 * struct k_poll_signal. Or NULL to unregister any handler
127 * registered for the given vector.
128 * @param vector The interrupt vector to get notification from
129 *
130 * Note: The returned status, if positive, to a raised signal is the vector
131 * that generated the signal. This lets the possibility to the user
132 * to have one signal for all vectors, or one per-vector.
133 *
134 * @return 0 on success, a negative errno otherwise
135 */
136 __syscall int ivshmem_register_handler(const struct device *dev,
137 struct k_poll_signal *signal,
138 uint16_t vector);
139
z_impl_ivshmem_register_handler(const struct device * dev,struct k_poll_signal * signal,uint16_t vector)140 static inline int z_impl_ivshmem_register_handler(const struct device *dev,
141 struct k_poll_signal *signal,
142 uint16_t vector)
143 {
144 const struct ivshmem_driver_api *api =
145 (const struct ivshmem_driver_api *)dev->api;
146
147 return api->register_handler(dev, signal, vector);
148 }
149
150 #ifdef __cplusplus
151 }
152 #endif
153
154 /**
155 * @}
156 */
157
158 #include <syscalls/ivshmem.h>
159
160 #endif /* ZEPHYR_INCLUDE_DRIVERS_VIRTUALIZATION_IVSHMEM_H_ */
161