1 /*
2  * Copyright (c) 2020 Intel Corporation
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_
7 #define ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_
8 
9 #include <zephyr/drivers/pcie/msi.h>
10 
11 typedef int (*vtd_alloc_entries_f)(const struct device *dev,
12 				   uint8_t n_entries);
13 
14 typedef uint32_t (*vtd_remap_msi_f)(const struct device *dev,
15 				    msi_vector_t *vector,
16 				    uint8_t n_vector);
17 
18 typedef int (*vtd_remap_f)(const struct device *dev,
19 			   uint8_t irte_idx,
20 			   uint16_t vector,
21 			   uint32_t flags,
22 			   uint16_t src_id);
23 
24 typedef int (*vtd_set_irte_vector_f)(const struct device *dev,
25 				     uint8_t irte_idx,
26 				     uint16_t vector);
27 
28 typedef int (*vtd_get_irte_by_vector_f)(const struct device *dev,
29 					uint16_t vector);
30 
31 typedef uint16_t (*vtd_get_irte_vector_f)(const struct device *dev,
32 					  uint8_t irte_idx);
33 
34 typedef int (*vtd_set_irte_irq_f)(const struct device *dev,
35 				  uint8_t irte_idx,
36 				  unsigned int irq);
37 
38 typedef int (*vtd_get_irte_by_irq_f)(const struct device *dev,
39 				     unsigned int irq);
40 
41 typedef void (*vtd_set_irte_msi_f)(const struct device *dev,
42 				   uint8_t irte_idx,
43 				   bool msi);
44 
45 typedef bool (*vtd_irte_is_msi_f)(const struct device *dev,
46 				  uint8_t irte_idx);
47 
48 struct vtd_driver_api {
49 	vtd_alloc_entries_f allocate_entries;
50 	vtd_remap_msi_f remap_msi;
51 	vtd_remap_f remap;
52 	vtd_set_irte_vector_f set_irte_vector;
53 	vtd_get_irte_by_vector_f get_irte_by_vector;
54 	vtd_get_irte_vector_f get_irte_vector;
55 	vtd_set_irte_irq_f set_irte_irq;
56 	vtd_get_irte_by_irq_f get_irte_by_irq;
57 	vtd_set_irte_msi_f set_irte_msi;
58 	vtd_irte_is_msi_f irte_is_msi;
59 };
60 
61 /**
62  * @brief Allocate contiguous IRTEs
63  *
64  * @param dev Pointer to the device structure for the driver instance
65  * @param n_entries How many IRTE to allocate
66  *
67  * Note: It will try to allocate all, or it will fail.
68  *
69  * @return The first allocated IRTE index, or -EBUSY on failure
70  */
vtd_allocate_entries(const struct device * dev,uint8_t n_entries)71 static inline int vtd_allocate_entries(const struct device *dev,
72 				       uint8_t n_entries)
73 {
74 	const struct vtd_driver_api *api =
75 		(const struct vtd_driver_api *)dev->api;
76 
77 	return api->allocate_entries(dev, n_entries);
78 }
79 
80 /**
81  * @brief Generate the MSI Message Address data for the given vector
82  *
83  * @param dev Pointer to the device structure for the driver instance
84  * @param vector A valid allocated MSI vector array
85  * @param n_vector the size of the vector array
86  *
87  * @return The MSI Message Address value
88  */
vtd_remap_msi(const struct device * dev,msi_vector_t * vector,uint8_t n_vector)89 static inline uint32_t vtd_remap_msi(const struct device *dev,
90 				     msi_vector_t *vector,
91 				     uint8_t n_vector)
92 {
93 	const struct vtd_driver_api *api =
94 		(const struct vtd_driver_api *)dev->api;
95 
96 	return api->remap_msi(dev, vector, n_vector);
97 }
98 
99 /**
100  * @brief Remap the given vector
101  *
102  * @param dev Pointer to the device structure for the driver instance
103  * @param irte_idx A previously allocated irte entry index number
104  * @param vector An allocated interrupt vector
105  * @param flags interrupt flags
106  * @param src_id a valid source ID or USHRT_MAX if none
107  *
108  * @return 0 on success, a negative errno otherwise
109  */
vtd_remap(const struct device * dev,uint8_t irte_idx,uint16_t vector,uint32_t flags,uint16_t src_id)110 static inline int vtd_remap(const struct device *dev,
111 			    uint8_t irte_idx,
112 			    uint16_t vector,
113 			    uint32_t flags,
114 			    uint16_t src_id)
115 {
116 	const struct vtd_driver_api *api =
117 		(const struct vtd_driver_api *)dev->api;
118 
119 	return api->remap(dev, irte_idx, vector, flags, src_id);
120 }
121 
122 /**
123  * @brief Set the vector on the allocated irte
124  *
125  * @param dev Pointer to the device structure for the driver instance
126  * @param irte_idx A previously allocated irte entry index number
127  * @param vector An allocated interrupt vector
128  *
129  * @return 0, a negative errno otherwise
130  */
vtd_set_irte_vector(const struct device * dev,uint8_t irte_idx,uint16_t vector)131 static inline int vtd_set_irte_vector(const struct device *dev,
132 				      uint8_t irte_idx,
133 				      uint16_t vector)
134 {
135 	const struct vtd_driver_api *api =
136 		(const struct vtd_driver_api *)dev->api;
137 
138 	return api->set_irte_vector(dev, irte_idx, vector);
139 }
140 
141 /**
142  * @brief Get the irte allocated for the given vector
143  *
144  * @param dev Pointer to the device structure for the driver instance
145  * @param vector An allocated interrupt vector
146  *
147  * @return 0 or positive value on success, a negative errno otherwise
148  */
vtd_get_irte_by_vector(const struct device * dev,uint16_t vector)149 static inline int vtd_get_irte_by_vector(const struct device *dev,
150 					 uint16_t vector)
151 {
152 	const struct vtd_driver_api *api =
153 		(const struct vtd_driver_api *)dev->api;
154 
155 	return api->get_irte_by_vector(dev, vector);
156 }
157 
158 /**
159  * @brief Get the vector given to the IRTE
160  *
161  * @param dev Pointer to the device structure for the driver instance
162  * @param irte_idx A previously allocated irte entry index number
163  *
164  * @return the vector set to this IRTE
165  */
vtd_get_irte_vector(const struct device * dev,uint8_t irte_idx)166 static inline uint16_t vtd_get_irte_vector(const struct device *dev,
167 					   uint8_t irte_idx)
168 {
169 	const struct vtd_driver_api *api =
170 		(const struct vtd_driver_api *)dev->api;
171 
172 	return api->get_irte_vector(dev, irte_idx);
173 }
174 
175 /**
176  * @brief Set the irq on the allocated irte
177  *
178  * @param dev Pointer to the device structure for the driver instance
179  * @param irte_idx A previously allocated irte entry index number
180  * @param irq A valid IRQ number
181  *
182  * @return 0, a negative errno otherwise
183  */
vtd_set_irte_irq(const struct device * dev,uint8_t irte_idx,unsigned int irq)184 static inline int vtd_set_irte_irq(const struct device *dev,
185 				   uint8_t irte_idx,
186 				   unsigned int irq)
187 {
188 	const struct vtd_driver_api *api =
189 		(const struct vtd_driver_api *)dev->api;
190 
191 	return api->set_irte_irq(dev, irte_idx, irq);
192 }
193 
194 /**
195  * @brief Get the irte allocated for the given irq
196  *
197  * @param dev Pointer to the device structure for the driver instance
198  * @param irq A valid IRQ number
199  *
200  * @return 0 or positive value on success, a negative errno otherwise
201  */
vtd_get_irte_by_irq(const struct device * dev,unsigned int irq)202 static inline int vtd_get_irte_by_irq(const struct device *dev,
203 				      unsigned int irq)
204 {
205 	const struct vtd_driver_api *api =
206 		(const struct vtd_driver_api *)dev->api;
207 
208 	return api->get_irte_by_irq(dev, irq);
209 }
210 
vtd_set_irte_msi(const struct device * dev,uint8_t irte_idx,bool msi)211 static inline void vtd_set_irte_msi(const struct device *dev,
212 				    uint8_t irte_idx,
213 				    bool msi)
214 {
215 	const struct vtd_driver_api *api =
216 		(const struct vtd_driver_api *)dev->api;
217 
218 	return api->set_irte_msi(dev, irte_idx, msi);
219 }
220 
vtd_irte_is_msi(const struct device * dev,uint8_t irte_idx)221 static inline bool vtd_irte_is_msi(const struct device *dev,
222 				   uint8_t irte_idx)
223 {
224 	const struct vtd_driver_api *api =
225 		(const struct vtd_driver_api *)dev->api;
226 
227 	return api->irte_is_msi(dev, irte_idx);
228 }
229 
230 
231 #endif /* ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_ */
232