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