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