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