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