199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2016 Cavium, Inc 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _RTE_IO_H_ 699a2dd95SBruce Richardson #define _RTE_IO_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson /** 999a2dd95SBruce Richardson * @file 1099a2dd95SBruce Richardson * I/O device memory operations 1199a2dd95SBruce Richardson * 1299a2dd95SBruce Richardson * This file defines the generic API for I/O device memory read/write operations 1399a2dd95SBruce Richardson */ 1499a2dd95SBruce Richardson 1599a2dd95SBruce Richardson #include <stdint.h> 1699a2dd95SBruce Richardson #include <rte_common.h> 1799a2dd95SBruce Richardson #include <rte_compat.h> 1899a2dd95SBruce Richardson #include <rte_atomic.h> 1999a2dd95SBruce Richardson 20*719834a6SMattias Rönnblom #ifdef __cplusplus 21*719834a6SMattias Rönnblom extern "C" { 22*719834a6SMattias Rönnblom #endif 23*719834a6SMattias Rönnblom 2499a2dd95SBruce Richardson #ifdef __DOXYGEN__ 2599a2dd95SBruce Richardson 2699a2dd95SBruce Richardson /** 2799a2dd95SBruce Richardson * Read a 8-bit value from I/O device memory address *addr*. 2899a2dd95SBruce Richardson * 2999a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 3099a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 3199a2dd95SBruce Richardson * strongly ordered with respect to memory access. 3299a2dd95SBruce Richardson * 3399a2dd95SBruce Richardson * @param addr 3499a2dd95SBruce Richardson * I/O memory address to read the value from 3599a2dd95SBruce Richardson * @return 3699a2dd95SBruce Richardson * read value 3799a2dd95SBruce Richardson */ 3899a2dd95SBruce Richardson static inline uint8_t 3999a2dd95SBruce Richardson rte_read8_relaxed(const volatile void *addr); 4099a2dd95SBruce Richardson 4199a2dd95SBruce Richardson /** 4299a2dd95SBruce Richardson * Read a 16-bit value from I/O device memory address *addr*. 4399a2dd95SBruce Richardson * 4499a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 4599a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 4699a2dd95SBruce Richardson * strongly ordered with respect to memory access. 4799a2dd95SBruce Richardson * 4899a2dd95SBruce Richardson * @param addr 4999a2dd95SBruce Richardson * I/O memory address to read the value from 5099a2dd95SBruce Richardson * @return 5199a2dd95SBruce Richardson * read value 5299a2dd95SBruce Richardson */ 5399a2dd95SBruce Richardson static inline uint16_t 5499a2dd95SBruce Richardson rte_read16_relaxed(const volatile void *addr); 5599a2dd95SBruce Richardson 5699a2dd95SBruce Richardson /** 5799a2dd95SBruce Richardson * Read a 32-bit value from I/O device memory address *addr*. 5899a2dd95SBruce Richardson * 5999a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 6099a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 6199a2dd95SBruce Richardson * strongly ordered with respect to memory access. 6299a2dd95SBruce Richardson * 6399a2dd95SBruce Richardson * @param addr 6499a2dd95SBruce Richardson * I/O memory address to read the value from 6599a2dd95SBruce Richardson * @return 6699a2dd95SBruce Richardson * read value 6799a2dd95SBruce Richardson */ 6899a2dd95SBruce Richardson static inline uint32_t 6999a2dd95SBruce Richardson rte_read32_relaxed(const volatile void *addr); 7099a2dd95SBruce Richardson 7199a2dd95SBruce Richardson /** 7299a2dd95SBruce Richardson * Read a 64-bit value from I/O device memory address *addr*. 7399a2dd95SBruce Richardson * 7499a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 7599a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 7699a2dd95SBruce Richardson * strongly ordered with respect to memory access. 7799a2dd95SBruce Richardson * 7899a2dd95SBruce Richardson * @param addr 7999a2dd95SBruce Richardson * I/O memory address to read the value from 8099a2dd95SBruce Richardson * @return 8199a2dd95SBruce Richardson * read value 8299a2dd95SBruce Richardson */ 8399a2dd95SBruce Richardson static inline uint64_t 8499a2dd95SBruce Richardson rte_read64_relaxed(const volatile void *addr); 8599a2dd95SBruce Richardson 8699a2dd95SBruce Richardson /** 8799a2dd95SBruce Richardson * Write a 8-bit value to I/O device memory address *addr*. 8899a2dd95SBruce Richardson * 8999a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 9099a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 9199a2dd95SBruce Richardson * strongly ordered with respect to memory access. 9299a2dd95SBruce Richardson * 9399a2dd95SBruce Richardson * @param value 9499a2dd95SBruce Richardson * Value to write 9599a2dd95SBruce Richardson * @param addr 9699a2dd95SBruce Richardson * I/O memory address to write the value to 9799a2dd95SBruce Richardson */ 9899a2dd95SBruce Richardson 9999a2dd95SBruce Richardson static inline void 10099a2dd95SBruce Richardson rte_write8_relaxed(uint8_t value, volatile void *addr); 10199a2dd95SBruce Richardson 10299a2dd95SBruce Richardson /** 10399a2dd95SBruce Richardson * Write a 16-bit value to I/O device memory address *addr*. 10499a2dd95SBruce Richardson * 10599a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 10699a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 10799a2dd95SBruce Richardson * strongly ordered with respect to memory access. 10899a2dd95SBruce Richardson * 10999a2dd95SBruce Richardson * @param value 11099a2dd95SBruce Richardson * Value to write 11199a2dd95SBruce Richardson * @param addr 11299a2dd95SBruce Richardson * I/O memory address to write the value to 11399a2dd95SBruce Richardson */ 11499a2dd95SBruce Richardson static inline void 11599a2dd95SBruce Richardson rte_write16_relaxed(uint16_t value, volatile void *addr); 11699a2dd95SBruce Richardson 11799a2dd95SBruce Richardson /** 11899a2dd95SBruce Richardson * Write a 32-bit value to I/O device memory address *addr*. 11999a2dd95SBruce Richardson * 12099a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 12199a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 12299a2dd95SBruce Richardson * strongly ordered with respect to memory access. 12399a2dd95SBruce Richardson * 12499a2dd95SBruce Richardson * @param value 12599a2dd95SBruce Richardson * Value to write 12699a2dd95SBruce Richardson * @param addr 12799a2dd95SBruce Richardson * I/O memory address to write the value to 12899a2dd95SBruce Richardson */ 12999a2dd95SBruce Richardson static inline void 13099a2dd95SBruce Richardson rte_write32_relaxed(uint32_t value, volatile void *addr); 13199a2dd95SBruce Richardson 13299a2dd95SBruce Richardson /** 13399a2dd95SBruce Richardson * Write a 64-bit value to I/O device memory address *addr*. 13499a2dd95SBruce Richardson * 13599a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 13699a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 13799a2dd95SBruce Richardson * strongly ordered with respect to memory access. 13899a2dd95SBruce Richardson * 13999a2dd95SBruce Richardson * @param value 14099a2dd95SBruce Richardson * Value to write 14199a2dd95SBruce Richardson * @param addr 14299a2dd95SBruce Richardson * I/O memory address to write the value to 14399a2dd95SBruce Richardson */ 14499a2dd95SBruce Richardson static inline void 14599a2dd95SBruce Richardson rte_write64_relaxed(uint64_t value, volatile void *addr); 14699a2dd95SBruce Richardson 14799a2dd95SBruce Richardson /** 14899a2dd95SBruce Richardson * Read a 8-bit value from I/O device memory address *addr*. 14999a2dd95SBruce Richardson * 15099a2dd95SBruce Richardson * @param addr 15199a2dd95SBruce Richardson * I/O memory address to read the value from 15299a2dd95SBruce Richardson * @return 15399a2dd95SBruce Richardson * read value 15499a2dd95SBruce Richardson */ 15599a2dd95SBruce Richardson static inline uint8_t 15699a2dd95SBruce Richardson rte_read8(const volatile void *addr); 15799a2dd95SBruce Richardson 15899a2dd95SBruce Richardson /** 15999a2dd95SBruce Richardson * Read a 16-bit value from I/O device memory address *addr*. 16099a2dd95SBruce Richardson * 16199a2dd95SBruce Richardson * 16299a2dd95SBruce Richardson * @param addr 16399a2dd95SBruce Richardson * I/O memory address to read the value from 16499a2dd95SBruce Richardson * @return 16599a2dd95SBruce Richardson * read value 16699a2dd95SBruce Richardson */ 16799a2dd95SBruce Richardson static inline uint16_t 16899a2dd95SBruce Richardson rte_read16(const volatile void *addr); 16999a2dd95SBruce Richardson 17099a2dd95SBruce Richardson /** 17199a2dd95SBruce Richardson * Read a 32-bit value from I/O device memory address *addr*. 17299a2dd95SBruce Richardson * 17399a2dd95SBruce Richardson * @param addr 17499a2dd95SBruce Richardson * I/O memory address to read the value from 17599a2dd95SBruce Richardson * @return 17699a2dd95SBruce Richardson * read value 17799a2dd95SBruce Richardson */ 17899a2dd95SBruce Richardson static inline uint32_t 17999a2dd95SBruce Richardson rte_read32(const volatile void *addr); 18099a2dd95SBruce Richardson 18199a2dd95SBruce Richardson /** 18299a2dd95SBruce Richardson * Read a 64-bit value from I/O device memory address *addr*. 18399a2dd95SBruce Richardson * 18499a2dd95SBruce Richardson * @param addr 18599a2dd95SBruce Richardson * I/O memory address to read the value from 18699a2dd95SBruce Richardson * @return 18799a2dd95SBruce Richardson * read value 18899a2dd95SBruce Richardson */ 18999a2dd95SBruce Richardson static inline uint64_t 19099a2dd95SBruce Richardson rte_read64(const volatile void *addr); 19199a2dd95SBruce Richardson 19299a2dd95SBruce Richardson /** 19399a2dd95SBruce Richardson * Write a 8-bit value to I/O device memory address *addr*. 19499a2dd95SBruce Richardson * 19599a2dd95SBruce Richardson * @param value 19699a2dd95SBruce Richardson * Value to write 19799a2dd95SBruce Richardson * @param addr 19899a2dd95SBruce Richardson * I/O memory address to write the value to 19999a2dd95SBruce Richardson */ 20099a2dd95SBruce Richardson 20199a2dd95SBruce Richardson static inline void 20299a2dd95SBruce Richardson rte_write8(uint8_t value, volatile void *addr); 20399a2dd95SBruce Richardson 20499a2dd95SBruce Richardson /** 20599a2dd95SBruce Richardson * Write a 16-bit value to I/O device memory address *addr*. 20699a2dd95SBruce Richardson * 20799a2dd95SBruce Richardson * @param value 20899a2dd95SBruce Richardson * Value to write 20999a2dd95SBruce Richardson * @param addr 21099a2dd95SBruce Richardson * I/O memory address to write the value to 21199a2dd95SBruce Richardson */ 21299a2dd95SBruce Richardson static inline void 21399a2dd95SBruce Richardson rte_write16(uint16_t value, volatile void *addr); 21499a2dd95SBruce Richardson 21599a2dd95SBruce Richardson /** 21699a2dd95SBruce Richardson * Write a 32-bit value to I/O device memory address *addr*. 21799a2dd95SBruce Richardson * 21899a2dd95SBruce Richardson * @param value 21999a2dd95SBruce Richardson * Value to write 22099a2dd95SBruce Richardson * @param addr 22199a2dd95SBruce Richardson * I/O memory address to write the value to 22299a2dd95SBruce Richardson */ 22399a2dd95SBruce Richardson static inline void 22499a2dd95SBruce Richardson rte_write32(uint32_t value, volatile void *addr); 22599a2dd95SBruce Richardson 22699a2dd95SBruce Richardson /** 22799a2dd95SBruce Richardson * Write a 64-bit value to I/O device memory address *addr*. 22899a2dd95SBruce Richardson * 22999a2dd95SBruce Richardson * @param value 23099a2dd95SBruce Richardson * Value to write 23199a2dd95SBruce Richardson * @param addr 23299a2dd95SBruce Richardson * I/O memory address to write the value to 23399a2dd95SBruce Richardson */ 23499a2dd95SBruce Richardson static inline void 23599a2dd95SBruce Richardson rte_write64(uint64_t value, volatile void *addr); 23699a2dd95SBruce Richardson 23799a2dd95SBruce Richardson /** 23899a2dd95SBruce Richardson * Write a 32-bit value to I/O device memory address addr using write 23999a2dd95SBruce Richardson * combining memory write protocol. Depending on the platform write combining 24099a2dd95SBruce Richardson * may not be available and/or may be treated as a hint and the behavior may 24199a2dd95SBruce Richardson * fallback to a regular store. 24299a2dd95SBruce Richardson * 24399a2dd95SBruce Richardson * @param value 24499a2dd95SBruce Richardson * Value to write 24599a2dd95SBruce Richardson * @param addr 24699a2dd95SBruce Richardson * I/O memory address to write the value to 24799a2dd95SBruce Richardson */ 24899a2dd95SBruce Richardson __rte_experimental 24999a2dd95SBruce Richardson static inline void 25099a2dd95SBruce Richardson rte_write32_wc(uint32_t value, volatile void *addr); 25199a2dd95SBruce Richardson 25299a2dd95SBruce Richardson /** 25399a2dd95SBruce Richardson * Write a 32-bit value to I/O device memory address addr using write 25499a2dd95SBruce Richardson * combining memory write protocol. Depending on the platform write combining 25599a2dd95SBruce Richardson * may not be available and/or may be treated as a hint and the behavior may 25699a2dd95SBruce Richardson * fallback to a regular store. 25799a2dd95SBruce Richardson * 25899a2dd95SBruce Richardson * The relaxed version does not have additional I/O memory barrier, useful in 25999a2dd95SBruce Richardson * accessing the device registers of integrated controllers which implicitly 26099a2dd95SBruce Richardson * strongly ordered with respect to memory access. 26199a2dd95SBruce Richardson * 26299a2dd95SBruce Richardson * @param value 26399a2dd95SBruce Richardson * Value to write 26499a2dd95SBruce Richardson * @param addr 26599a2dd95SBruce Richardson * I/O memory address to write the value to 26699a2dd95SBruce Richardson */ 26799a2dd95SBruce Richardson __rte_experimental 26899a2dd95SBruce Richardson static inline void 26999a2dd95SBruce Richardson rte_write32_wc_relaxed(uint32_t value, volatile void *addr); 27099a2dd95SBruce Richardson 27199a2dd95SBruce Richardson #endif /* __DOXYGEN__ */ 27299a2dd95SBruce Richardson 27399a2dd95SBruce Richardson #ifndef RTE_OVERRIDE_IO_H 27499a2dd95SBruce Richardson 27599a2dd95SBruce Richardson static __rte_always_inline uint8_t 27699a2dd95SBruce Richardson rte_read8_relaxed(const volatile void *addr) 27799a2dd95SBruce Richardson { 27899a2dd95SBruce Richardson return *(const volatile uint8_t *)addr; 27999a2dd95SBruce Richardson } 28099a2dd95SBruce Richardson 28199a2dd95SBruce Richardson static __rte_always_inline uint16_t 28299a2dd95SBruce Richardson rte_read16_relaxed(const volatile void *addr) 28399a2dd95SBruce Richardson { 28499a2dd95SBruce Richardson return *(const volatile uint16_t *)addr; 28599a2dd95SBruce Richardson } 28699a2dd95SBruce Richardson 28799a2dd95SBruce Richardson static __rte_always_inline uint32_t 28899a2dd95SBruce Richardson rte_read32_relaxed(const volatile void *addr) 28999a2dd95SBruce Richardson { 29099a2dd95SBruce Richardson return *(const volatile uint32_t *)addr; 29199a2dd95SBruce Richardson } 29299a2dd95SBruce Richardson 29399a2dd95SBruce Richardson static __rte_always_inline uint64_t 29499a2dd95SBruce Richardson rte_read64_relaxed(const volatile void *addr) 29599a2dd95SBruce Richardson { 29699a2dd95SBruce Richardson return *(const volatile uint64_t *)addr; 29799a2dd95SBruce Richardson } 29899a2dd95SBruce Richardson 29999a2dd95SBruce Richardson static __rte_always_inline void 30099a2dd95SBruce Richardson rte_write8_relaxed(uint8_t value, volatile void *addr) 30199a2dd95SBruce Richardson { 30299a2dd95SBruce Richardson *(volatile uint8_t *)addr = value; 30399a2dd95SBruce Richardson } 30499a2dd95SBruce Richardson 30599a2dd95SBruce Richardson static __rte_always_inline void 30699a2dd95SBruce Richardson rte_write16_relaxed(uint16_t value, volatile void *addr) 30799a2dd95SBruce Richardson { 30899a2dd95SBruce Richardson *(volatile uint16_t *)addr = value; 30999a2dd95SBruce Richardson } 31099a2dd95SBruce Richardson 31199a2dd95SBruce Richardson static __rte_always_inline void 31299a2dd95SBruce Richardson rte_write32_relaxed(uint32_t value, volatile void *addr) 31399a2dd95SBruce Richardson { 31499a2dd95SBruce Richardson *(volatile uint32_t *)addr = value; 31599a2dd95SBruce Richardson } 31699a2dd95SBruce Richardson 31799a2dd95SBruce Richardson static __rte_always_inline void 31899a2dd95SBruce Richardson rte_write64_relaxed(uint64_t value, volatile void *addr) 31999a2dd95SBruce Richardson { 32099a2dd95SBruce Richardson *(volatile uint64_t *)addr = value; 32199a2dd95SBruce Richardson } 32299a2dd95SBruce Richardson 32399a2dd95SBruce Richardson static __rte_always_inline uint8_t 32499a2dd95SBruce Richardson rte_read8(const volatile void *addr) 32599a2dd95SBruce Richardson { 32699a2dd95SBruce Richardson uint8_t val; 32799a2dd95SBruce Richardson val = rte_read8_relaxed(addr); 32899a2dd95SBruce Richardson rte_io_rmb(); 32999a2dd95SBruce Richardson return val; 33099a2dd95SBruce Richardson } 33199a2dd95SBruce Richardson 33299a2dd95SBruce Richardson static __rte_always_inline uint16_t 33399a2dd95SBruce Richardson rte_read16(const volatile void *addr) 33499a2dd95SBruce Richardson { 33599a2dd95SBruce Richardson uint16_t val; 33699a2dd95SBruce Richardson val = rte_read16_relaxed(addr); 33799a2dd95SBruce Richardson rte_io_rmb(); 33899a2dd95SBruce Richardson return val; 33999a2dd95SBruce Richardson } 34099a2dd95SBruce Richardson 34199a2dd95SBruce Richardson static __rte_always_inline uint32_t 34299a2dd95SBruce Richardson rte_read32(const volatile void *addr) 34399a2dd95SBruce Richardson { 34499a2dd95SBruce Richardson uint32_t val; 34599a2dd95SBruce Richardson val = rte_read32_relaxed(addr); 34699a2dd95SBruce Richardson rte_io_rmb(); 34799a2dd95SBruce Richardson return val; 34899a2dd95SBruce Richardson } 34999a2dd95SBruce Richardson 35099a2dd95SBruce Richardson static __rte_always_inline uint64_t 35199a2dd95SBruce Richardson rte_read64(const volatile void *addr) 35299a2dd95SBruce Richardson { 35399a2dd95SBruce Richardson uint64_t val; 35499a2dd95SBruce Richardson val = rte_read64_relaxed(addr); 35599a2dd95SBruce Richardson rte_io_rmb(); 35699a2dd95SBruce Richardson return val; 35799a2dd95SBruce Richardson } 35899a2dd95SBruce Richardson 35999a2dd95SBruce Richardson static __rte_always_inline void 36099a2dd95SBruce Richardson rte_write8(uint8_t value, volatile void *addr) 36199a2dd95SBruce Richardson { 36299a2dd95SBruce Richardson rte_io_wmb(); 36399a2dd95SBruce Richardson rte_write8_relaxed(value, addr); 36499a2dd95SBruce Richardson } 36599a2dd95SBruce Richardson 36699a2dd95SBruce Richardson static __rte_always_inline void 36799a2dd95SBruce Richardson rte_write16(uint16_t value, volatile void *addr) 36899a2dd95SBruce Richardson { 36999a2dd95SBruce Richardson rte_io_wmb(); 37099a2dd95SBruce Richardson rte_write16_relaxed(value, addr); 37199a2dd95SBruce Richardson } 37299a2dd95SBruce Richardson 37399a2dd95SBruce Richardson static __rte_always_inline void 37499a2dd95SBruce Richardson rte_write32(uint32_t value, volatile void *addr) 37599a2dd95SBruce Richardson { 37699a2dd95SBruce Richardson rte_io_wmb(); 37799a2dd95SBruce Richardson rte_write32_relaxed(value, addr); 37899a2dd95SBruce Richardson } 37999a2dd95SBruce Richardson 38099a2dd95SBruce Richardson static __rte_always_inline void 38199a2dd95SBruce Richardson rte_write64(uint64_t value, volatile void *addr) 38299a2dd95SBruce Richardson { 38399a2dd95SBruce Richardson rte_io_wmb(); 38499a2dd95SBruce Richardson rte_write64_relaxed(value, addr); 38599a2dd95SBruce Richardson } 38699a2dd95SBruce Richardson 38799a2dd95SBruce Richardson #ifndef RTE_NATIVE_WRITE32_WC 38899a2dd95SBruce Richardson static __rte_always_inline void 38999a2dd95SBruce Richardson rte_write32_wc(uint32_t value, volatile void *addr) 39099a2dd95SBruce Richardson { 39199a2dd95SBruce Richardson rte_write32(value, addr); 39299a2dd95SBruce Richardson } 39399a2dd95SBruce Richardson 39499a2dd95SBruce Richardson static __rte_always_inline void 39599a2dd95SBruce Richardson rte_write32_wc_relaxed(uint32_t value, volatile void *addr) 39699a2dd95SBruce Richardson { 39799a2dd95SBruce Richardson rte_write32_relaxed(value, addr); 39899a2dd95SBruce Richardson } 39999a2dd95SBruce Richardson #endif /* RTE_NATIVE_WRITE32_WC */ 40099a2dd95SBruce Richardson 40199a2dd95SBruce Richardson #endif /* RTE_OVERRIDE_IO_H */ 40299a2dd95SBruce Richardson 403*719834a6SMattias Rönnblom #ifdef __cplusplus 404*719834a6SMattias Rönnblom } 405*719834a6SMattias Rönnblom #endif 406*719834a6SMattias Rönnblom 40799a2dd95SBruce Richardson #endif /* _RTE_IO_H_ */ 408