xref: /dpdk/lib/eal/x86/include/rte_io.h (revision feb9fd6a9f019b20b1c60ed664b4887592f78032)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2016 Cavium, Inc
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #ifndef _RTE_IO_X86_H_
699a2dd95SBruce Richardson #define _RTE_IO_X86_H_
799a2dd95SBruce Richardson 
81094dd94SDavid Marchand #include <rte_compat.h>
999a2dd95SBruce Richardson #include "rte_cpuflags.h"
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson #define RTE_NATIVE_WRITE32_WC
1299a2dd95SBruce Richardson #include "generic/rte_io.h"
1399a2dd95SBruce Richardson 
14719834a6SMattias Rönnblom #ifdef __cplusplus
15719834a6SMattias Rönnblom extern "C" {
16719834a6SMattias Rönnblom #endif
17719834a6SMattias Rönnblom 
1899a2dd95SBruce Richardson /**
1999a2dd95SBruce Richardson  * @internal
2099a2dd95SBruce Richardson  * MOVDIRI wrapper.
2199a2dd95SBruce Richardson  */
2299a2dd95SBruce Richardson static __rte_always_inline void
2399a2dd95SBruce Richardson __rte_x86_movdiri(uint32_t value, volatile void *addr)
2499a2dd95SBruce Richardson {
25*feb9fd6aSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
26*feb9fd6aSTyler Retzlaff 	_directstoreu_u32((void *)(uintptr_t)addr, value);
27*feb9fd6aSTyler Retzlaff #else
2899a2dd95SBruce Richardson 	asm volatile(
2999a2dd95SBruce Richardson 		/* MOVDIRI */
3041b09d64SBruce Richardson 		".byte 0x0f, 0x38, 0xf9, 0x02"
3199a2dd95SBruce Richardson 		:
3299a2dd95SBruce Richardson 		: "a" (value), "d" (addr));
33*feb9fd6aSTyler Retzlaff #endif
3499a2dd95SBruce Richardson }
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson __rte_experimental
3799a2dd95SBruce Richardson static __rte_always_inline void
3899a2dd95SBruce Richardson rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
3999a2dd95SBruce Richardson {
4099a2dd95SBruce Richardson 	static int _x86_movdiri_flag = -1;
4199a2dd95SBruce Richardson 
4299a2dd95SBruce Richardson 	if (_x86_movdiri_flag == 1) {
4399a2dd95SBruce Richardson 		__rte_x86_movdiri(value, addr);
4499a2dd95SBruce Richardson 	} else if (_x86_movdiri_flag == 0) {
4599a2dd95SBruce Richardson 		rte_write32_relaxed(value, addr);
4699a2dd95SBruce Richardson 	} else {
4799a2dd95SBruce Richardson 		_x86_movdiri_flag =
4899a2dd95SBruce Richardson 			(rte_cpu_get_flag_enabled(RTE_CPUFLAG_MOVDIRI) > 0);
4999a2dd95SBruce Richardson 		if (_x86_movdiri_flag == 1)
5099a2dd95SBruce Richardson 			__rte_x86_movdiri(value, addr);
5199a2dd95SBruce Richardson 		else
5299a2dd95SBruce Richardson 			rte_write32_relaxed(value, addr);
5399a2dd95SBruce Richardson 	}
5499a2dd95SBruce Richardson }
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson __rte_experimental
5799a2dd95SBruce Richardson static __rte_always_inline void
5899a2dd95SBruce Richardson rte_write32_wc(uint32_t value, volatile void *addr)
5999a2dd95SBruce Richardson {
6099a2dd95SBruce Richardson 	/* gcc complains about calling this experimental function even
6199a2dd95SBruce Richardson 	 * when not using it. Hide it with ALLOW_EXPERIMENTAL_API.
6299a2dd95SBruce Richardson 	 */
6399a2dd95SBruce Richardson #ifdef ALLOW_EXPERIMENTAL_API
6499a2dd95SBruce Richardson 	rte_wmb();
6599a2dd95SBruce Richardson 	rte_write32_wc_relaxed(value, addr);
6699a2dd95SBruce Richardson #else
6799a2dd95SBruce Richardson 	rte_write32(value, addr);
6899a2dd95SBruce Richardson #endif
6999a2dd95SBruce Richardson }
7099a2dd95SBruce Richardson 
7199a2dd95SBruce Richardson #ifdef __cplusplus
7299a2dd95SBruce Richardson }
7399a2dd95SBruce Richardson #endif
7499a2dd95SBruce Richardson 
7599a2dd95SBruce Richardson #endif /* _RTE_IO_X86_H_ */
76