xref: /dpdk/lib/eal/x86/include/rte_io.h (revision feb9fd6a9f019b20b1c60ed664b4887592f78032)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Cavium, Inc
3  */
4 
5 #ifndef _RTE_IO_X86_H_
6 #define _RTE_IO_X86_H_
7 
8 #include <rte_compat.h>
9 #include "rte_cpuflags.h"
10 
11 #define RTE_NATIVE_WRITE32_WC
12 #include "generic/rte_io.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * @internal
20  * MOVDIRI wrapper.
21  */
22 static __rte_always_inline void
23 __rte_x86_movdiri(uint32_t value, volatile void *addr)
24 {
25 #ifdef RTE_TOOLCHAIN_MSVC
26 	_directstoreu_u32((void *)(uintptr_t)addr, value);
27 #else
28 	asm volatile(
29 		/* MOVDIRI */
30 		".byte 0x0f, 0x38, 0xf9, 0x02"
31 		:
32 		: "a" (value), "d" (addr));
33 #endif
34 }
35 
36 __rte_experimental
37 static __rte_always_inline void
38 rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
39 {
40 	static int _x86_movdiri_flag = -1;
41 
42 	if (_x86_movdiri_flag == 1) {
43 		__rte_x86_movdiri(value, addr);
44 	} else if (_x86_movdiri_flag == 0) {
45 		rte_write32_relaxed(value, addr);
46 	} else {
47 		_x86_movdiri_flag =
48 			(rte_cpu_get_flag_enabled(RTE_CPUFLAG_MOVDIRI) > 0);
49 		if (_x86_movdiri_flag == 1)
50 			__rte_x86_movdiri(value, addr);
51 		else
52 			rte_write32_relaxed(value, addr);
53 	}
54 }
55 
56 __rte_experimental
57 static __rte_always_inline void
58 rte_write32_wc(uint32_t value, volatile void *addr)
59 {
60 	/* gcc complains about calling this experimental function even
61 	 * when not using it. Hide it with ALLOW_EXPERIMENTAL_API.
62 	 */
63 #ifdef ALLOW_EXPERIMENTAL_API
64 	rte_wmb();
65 	rte_write32_wc_relaxed(value, addr);
66 #else
67 	rte_write32(value, addr);
68 #endif
69 }
70 
71 #ifdef __cplusplus
72 }
73 #endif
74 
75 #endif /* _RTE_IO_X86_H_ */
76