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