xref: /dpdk/lib/eal/include/generic/rte_io.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Cavium, Inc
3  */
4 
5 #ifndef _RTE_IO_H_
6 #define _RTE_IO_H_
7 
8 /**
9  * @file
10  * I/O device memory operations
11  *
12  * This file defines the generic API for I/O device memory read/write operations
13  */
14 
15 #include <stdint.h>
16 #include <rte_common.h>
17 #include <rte_compat.h>
18 #include <rte_atomic.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #ifdef __DOXYGEN__
25 
26 /**
27  * Read a 8-bit value from I/O device memory address *addr*.
28  *
29  * The relaxed version does not have additional I/O memory barrier, useful in
30  * accessing the device registers of integrated controllers which implicitly
31  * strongly ordered with respect to memory access.
32  *
33  * @param addr
34  *  I/O memory address to read the value from
35  * @return
36  *  read value
37  */
38 static inline uint8_t
39 rte_read8_relaxed(const volatile void *addr);
40 
41 /**
42  * Read a 16-bit value from I/O device memory address *addr*.
43  *
44  * The relaxed version does not have additional I/O memory barrier, useful in
45  * accessing the device registers of integrated controllers which implicitly
46  * strongly ordered with respect to memory access.
47  *
48  * @param addr
49  *  I/O memory address to read the value from
50  * @return
51  *  read value
52  */
53 static inline uint16_t
54 rte_read16_relaxed(const volatile void *addr);
55 
56 /**
57  * Read a 32-bit value from I/O device memory address *addr*.
58  *
59  * The relaxed version does not have additional I/O memory barrier, useful in
60  * accessing the device registers of integrated controllers which implicitly
61  * strongly ordered with respect to memory access.
62  *
63  * @param addr
64  *  I/O memory address to read the value from
65  * @return
66  *  read value
67  */
68 static inline uint32_t
69 rte_read32_relaxed(const volatile void *addr);
70 
71 /**
72  * Read a 64-bit value from I/O device memory address *addr*.
73  *
74  * The relaxed version does not have additional I/O memory barrier, useful in
75  * accessing the device registers of integrated controllers which implicitly
76  * strongly ordered with respect to memory access.
77  *
78  * @param addr
79  *  I/O memory address to read the value from
80  * @return
81  *  read value
82  */
83 static inline uint64_t
84 rte_read64_relaxed(const volatile void *addr);
85 
86 /**
87  * Write a 8-bit value to I/O device memory address *addr*.
88  *
89  * The relaxed version does not have additional I/O memory barrier, useful in
90  * accessing the device registers of integrated controllers which implicitly
91  * strongly ordered with respect to memory access.
92  *
93  * @param value
94  *  Value to write
95  * @param addr
96  *  I/O memory address to write the value to
97  */
98 
99 static inline void
100 rte_write8_relaxed(uint8_t value, volatile void *addr);
101 
102 /**
103  * Write a 16-bit value to I/O device memory address *addr*.
104  *
105  * The relaxed version does not have additional I/O memory barrier, useful in
106  * accessing the device registers of integrated controllers which implicitly
107  * strongly ordered with respect to memory access.
108  *
109  * @param value
110  *  Value to write
111  * @param addr
112  *  I/O memory address to write the value to
113  */
114 static inline void
115 rte_write16_relaxed(uint16_t value, volatile void *addr);
116 
117 /**
118  * Write a 32-bit value to I/O device memory address *addr*.
119  *
120  * The relaxed version does not have additional I/O memory barrier, useful in
121  * accessing the device registers of integrated controllers which implicitly
122  * strongly ordered with respect to memory access.
123  *
124  * @param value
125  *  Value to write
126  * @param addr
127  *  I/O memory address to write the value to
128  */
129 static inline void
130 rte_write32_relaxed(uint32_t value, volatile void *addr);
131 
132 /**
133  * Write a 64-bit value to I/O device memory address *addr*.
134  *
135  * The relaxed version does not have additional I/O memory barrier, useful in
136  * accessing the device registers of integrated controllers which implicitly
137  * strongly ordered with respect to memory access.
138  *
139  * @param value
140  *  Value to write
141  * @param addr
142  *  I/O memory address to write the value to
143  */
144 static inline void
145 rte_write64_relaxed(uint64_t value, volatile void *addr);
146 
147 /**
148  * Read a 8-bit value from I/O device memory address *addr*.
149  *
150  * @param addr
151  *  I/O memory address to read the value from
152  * @return
153  *  read value
154  */
155 static inline uint8_t
156 rte_read8(const volatile void *addr);
157 
158 /**
159  * Read a 16-bit value from I/O device memory address *addr*.
160  *
161  *
162  * @param addr
163  *  I/O memory address to read the value from
164  * @return
165  *  read value
166  */
167 static inline uint16_t
168 rte_read16(const volatile void *addr);
169 
170 /**
171  * Read a 32-bit value from I/O device memory address *addr*.
172  *
173  * @param addr
174  *  I/O memory address to read the value from
175  * @return
176  *  read value
177  */
178 static inline uint32_t
179 rte_read32(const volatile void *addr);
180 
181 /**
182  * Read a 64-bit value from I/O device memory address *addr*.
183  *
184  * @param addr
185  *  I/O memory address to read the value from
186  * @return
187  *  read value
188  */
189 static inline uint64_t
190 rte_read64(const volatile void *addr);
191 
192 /**
193  * Write a 8-bit value to I/O device memory address *addr*.
194  *
195  * @param value
196  *  Value to write
197  * @param addr
198  *  I/O memory address to write the value to
199  */
200 
201 static inline void
202 rte_write8(uint8_t value, volatile void *addr);
203 
204 /**
205  * Write a 16-bit value to I/O device memory address *addr*.
206  *
207  * @param value
208  *  Value to write
209  * @param addr
210  *  I/O memory address to write the value to
211  */
212 static inline void
213 rte_write16(uint16_t value, volatile void *addr);
214 
215 /**
216  * Write a 32-bit value to I/O device memory address *addr*.
217  *
218  * @param value
219  *  Value to write
220  * @param addr
221  *  I/O memory address to write the value to
222  */
223 static inline void
224 rte_write32(uint32_t value, volatile void *addr);
225 
226 /**
227  * Write a 64-bit value to I/O device memory address *addr*.
228  *
229  * @param value
230  *  Value to write
231  * @param addr
232  *  I/O memory address to write the value to
233  */
234 static inline void
235 rte_write64(uint64_t value, volatile void *addr);
236 
237 /**
238  * Write a 32-bit value to I/O device memory address addr using write
239  * combining memory write protocol. Depending on the platform write combining
240  * may not be available and/or may be treated as a hint and the behavior may
241  * fallback to a regular store.
242  *
243  * @param value
244  *  Value to write
245  * @param addr
246  *  I/O memory address to write the value to
247  */
248 __rte_experimental
249 static inline void
250 rte_write32_wc(uint32_t value, volatile void *addr);
251 
252 /**
253  * Write a 32-bit value to I/O device memory address addr using write
254  * combining memory write protocol. Depending on the platform write combining
255  * may not be available and/or may be treated as a hint and the behavior may
256  * fallback to a regular store.
257  *
258  * The relaxed version does not have additional I/O memory barrier, useful in
259  * accessing the device registers of integrated controllers which implicitly
260  * strongly ordered with respect to memory access.
261  *
262  * @param value
263  *  Value to write
264  * @param addr
265  *  I/O memory address to write the value to
266  */
267 __rte_experimental
268 static inline void
269 rte_write32_wc_relaxed(uint32_t value, volatile void *addr);
270 
271 #endif /* __DOXYGEN__ */
272 
273 #ifndef RTE_OVERRIDE_IO_H
274 
275 static __rte_always_inline uint8_t
276 rte_read8_relaxed(const volatile void *addr)
277 {
278 	return *(const volatile uint8_t *)addr;
279 }
280 
281 static __rte_always_inline uint16_t
282 rte_read16_relaxed(const volatile void *addr)
283 {
284 	return *(const volatile uint16_t *)addr;
285 }
286 
287 static __rte_always_inline uint32_t
288 rte_read32_relaxed(const volatile void *addr)
289 {
290 	return *(const volatile uint32_t *)addr;
291 }
292 
293 static __rte_always_inline uint64_t
294 rte_read64_relaxed(const volatile void *addr)
295 {
296 	return *(const volatile uint64_t *)addr;
297 }
298 
299 static __rte_always_inline void
300 rte_write8_relaxed(uint8_t value, volatile void *addr)
301 {
302 	*(volatile uint8_t *)addr = value;
303 }
304 
305 static __rte_always_inline void
306 rte_write16_relaxed(uint16_t value, volatile void *addr)
307 {
308 	*(volatile uint16_t *)addr = value;
309 }
310 
311 static __rte_always_inline void
312 rte_write32_relaxed(uint32_t value, volatile void *addr)
313 {
314 	*(volatile uint32_t *)addr = value;
315 }
316 
317 static __rte_always_inline void
318 rte_write64_relaxed(uint64_t value, volatile void *addr)
319 {
320 	*(volatile uint64_t *)addr = value;
321 }
322 
323 static __rte_always_inline uint8_t
324 rte_read8(const volatile void *addr)
325 {
326 	uint8_t val;
327 	val = rte_read8_relaxed(addr);
328 	rte_io_rmb();
329 	return val;
330 }
331 
332 static __rte_always_inline uint16_t
333 rte_read16(const volatile void *addr)
334 {
335 	uint16_t val;
336 	val = rte_read16_relaxed(addr);
337 	rte_io_rmb();
338 	return val;
339 }
340 
341 static __rte_always_inline uint32_t
342 rte_read32(const volatile void *addr)
343 {
344 	uint32_t val;
345 	val = rte_read32_relaxed(addr);
346 	rte_io_rmb();
347 	return val;
348 }
349 
350 static __rte_always_inline uint64_t
351 rte_read64(const volatile void *addr)
352 {
353 	uint64_t val;
354 	val = rte_read64_relaxed(addr);
355 	rte_io_rmb();
356 	return val;
357 }
358 
359 static __rte_always_inline void
360 rte_write8(uint8_t value, volatile void *addr)
361 {
362 	rte_io_wmb();
363 	rte_write8_relaxed(value, addr);
364 }
365 
366 static __rte_always_inline void
367 rte_write16(uint16_t value, volatile void *addr)
368 {
369 	rte_io_wmb();
370 	rte_write16_relaxed(value, addr);
371 }
372 
373 static __rte_always_inline void
374 rte_write32(uint32_t value, volatile void *addr)
375 {
376 	rte_io_wmb();
377 	rte_write32_relaxed(value, addr);
378 }
379 
380 static __rte_always_inline void
381 rte_write64(uint64_t value, volatile void *addr)
382 {
383 	rte_io_wmb();
384 	rte_write64_relaxed(value, addr);
385 }
386 
387 #ifndef RTE_NATIVE_WRITE32_WC
388 static __rte_always_inline void
389 rte_write32_wc(uint32_t value, volatile void *addr)
390 {
391 	rte_write32(value, addr);
392 }
393 
394 static __rte_always_inline void
395 rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
396 {
397 	rte_write32_relaxed(value, addr);
398 }
399 #endif /* RTE_NATIVE_WRITE32_WC */
400 
401 #endif /* RTE_OVERRIDE_IO_H */
402 
403 #ifdef __cplusplus
404 }
405 #endif
406 
407 #endif /* _RTE_IO_H_ */
408