1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016 Cavium, Inc 3 */ 4 5 #ifndef _RTE_IO_H_ 6 #define _RTE_IO_H_ 7 8 /** 9 * @file 10 * I/O device memory operations 11 * 12 * This file defines the generic API for I/O device memory read/write operations 13 */ 14 15 #include <stdint.h> 16 #include <rte_common.h> 17 #include <rte_compat.h> 18 #include <rte_atomic.h> 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #ifdef __DOXYGEN__ 25 26 /** 27 * Read a 8-bit value from I/O device memory address *addr*. 28 * 29 * The relaxed version does not have additional I/O memory barrier, useful in 30 * accessing the device registers of integrated controllers which implicitly 31 * strongly ordered with respect to memory access. 32 * 33 * @param addr 34 * I/O memory address to read the value from 35 * @return 36 * read value 37 */ 38 static inline uint8_t 39 rte_read8_relaxed(const volatile void *addr); 40 41 /** 42 * Read a 16-bit value from I/O device memory address *addr*. 43 * 44 * The relaxed version does not have additional I/O memory barrier, useful in 45 * accessing the device registers of integrated controllers which implicitly 46 * strongly ordered with respect to memory access. 47 * 48 * @param addr 49 * I/O memory address to read the value from 50 * @return 51 * read value 52 */ 53 static inline uint16_t 54 rte_read16_relaxed(const volatile void *addr); 55 56 /** 57 * Read a 32-bit value from I/O device memory address *addr*. 58 * 59 * The relaxed version does not have additional I/O memory barrier, useful in 60 * accessing the device registers of integrated controllers which implicitly 61 * strongly ordered with respect to memory access. 62 * 63 * @param addr 64 * I/O memory address to read the value from 65 * @return 66 * read value 67 */ 68 static inline uint32_t 69 rte_read32_relaxed(const volatile void *addr); 70 71 /** 72 * Read a 64-bit value from I/O device memory address *addr*. 73 * 74 * The relaxed version does not have additional I/O memory barrier, useful in 75 * accessing the device registers of integrated controllers which implicitly 76 * strongly ordered with respect to memory access. 77 * 78 * @param addr 79 * I/O memory address to read the value from 80 * @return 81 * read value 82 */ 83 static inline uint64_t 84 rte_read64_relaxed(const volatile void *addr); 85 86 /** 87 * Write a 8-bit value to I/O device memory address *addr*. 88 * 89 * The relaxed version does not have additional I/O memory barrier, useful in 90 * accessing the device registers of integrated controllers which implicitly 91 * strongly ordered with respect to memory access. 92 * 93 * @param value 94 * Value to write 95 * @param addr 96 * I/O memory address to write the value to 97 */ 98 99 static inline void 100 rte_write8_relaxed(uint8_t value, volatile void *addr); 101 102 /** 103 * Write a 16-bit value to I/O device memory address *addr*. 104 * 105 * The relaxed version does not have additional I/O memory barrier, useful in 106 * accessing the device registers of integrated controllers which implicitly 107 * strongly ordered with respect to memory access. 108 * 109 * @param value 110 * Value to write 111 * @param addr 112 * I/O memory address to write the value to 113 */ 114 static inline void 115 rte_write16_relaxed(uint16_t value, volatile void *addr); 116 117 /** 118 * Write a 32-bit value to I/O device memory address *addr*. 119 * 120 * The relaxed version does not have additional I/O memory barrier, useful in 121 * accessing the device registers of integrated controllers which implicitly 122 * strongly ordered with respect to memory access. 123 * 124 * @param value 125 * Value to write 126 * @param addr 127 * I/O memory address to write the value to 128 */ 129 static inline void 130 rte_write32_relaxed(uint32_t value, volatile void *addr); 131 132 /** 133 * Write a 64-bit value to I/O device memory address *addr*. 134 * 135 * The relaxed version does not have additional I/O memory barrier, useful in 136 * accessing the device registers of integrated controllers which implicitly 137 * strongly ordered with respect to memory access. 138 * 139 * @param value 140 * Value to write 141 * @param addr 142 * I/O memory address to write the value to 143 */ 144 static inline void 145 rte_write64_relaxed(uint64_t value, volatile void *addr); 146 147 /** 148 * Read a 8-bit value from I/O device memory address *addr*. 149 * 150 * @param addr 151 * I/O memory address to read the value from 152 * @return 153 * read value 154 */ 155 static inline uint8_t 156 rte_read8(const volatile void *addr); 157 158 /** 159 * Read a 16-bit value from I/O device memory address *addr*. 160 * 161 * 162 * @param addr 163 * I/O memory address to read the value from 164 * @return 165 * read value 166 */ 167 static inline uint16_t 168 rte_read16(const volatile void *addr); 169 170 /** 171 * Read a 32-bit value from I/O device memory address *addr*. 172 * 173 * @param addr 174 * I/O memory address to read the value from 175 * @return 176 * read value 177 */ 178 static inline uint32_t 179 rte_read32(const volatile void *addr); 180 181 /** 182 * Read a 64-bit value from I/O device memory address *addr*. 183 * 184 * @param addr 185 * I/O memory address to read the value from 186 * @return 187 * read value 188 */ 189 static inline uint64_t 190 rte_read64(const volatile void *addr); 191 192 /** 193 * Write a 8-bit value to I/O device memory address *addr*. 194 * 195 * @param value 196 * Value to write 197 * @param addr 198 * I/O memory address to write the value to 199 */ 200 201 static inline void 202 rte_write8(uint8_t value, volatile void *addr); 203 204 /** 205 * Write a 16-bit value to I/O device memory address *addr*. 206 * 207 * @param value 208 * Value to write 209 * @param addr 210 * I/O memory address to write the value to 211 */ 212 static inline void 213 rte_write16(uint16_t value, volatile void *addr); 214 215 /** 216 * Write a 32-bit value to I/O device memory address *addr*. 217 * 218 * @param value 219 * Value to write 220 * @param addr 221 * I/O memory address to write the value to 222 */ 223 static inline void 224 rte_write32(uint32_t value, volatile void *addr); 225 226 /** 227 * Write a 64-bit value to I/O device memory address *addr*. 228 * 229 * @param value 230 * Value to write 231 * @param addr 232 * I/O memory address to write the value to 233 */ 234 static inline void 235 rte_write64(uint64_t value, volatile void *addr); 236 237 /** 238 * Write a 32-bit value to I/O device memory address addr using write 239 * combining memory write protocol. Depending on the platform write combining 240 * may not be available and/or may be treated as a hint and the behavior may 241 * fallback to a regular store. 242 * 243 * @param value 244 * Value to write 245 * @param addr 246 * I/O memory address to write the value to 247 */ 248 __rte_experimental 249 static inline void 250 rte_write32_wc(uint32_t value, volatile void *addr); 251 252 /** 253 * Write a 32-bit value to I/O device memory address addr using write 254 * combining memory write protocol. Depending on the platform write combining 255 * may not be available and/or may be treated as a hint and the behavior may 256 * fallback to a regular store. 257 * 258 * The relaxed version does not have additional I/O memory barrier, useful in 259 * accessing the device registers of integrated controllers which implicitly 260 * strongly ordered with respect to memory access. 261 * 262 * @param value 263 * Value to write 264 * @param addr 265 * I/O memory address to write the value to 266 */ 267 __rte_experimental 268 static inline void 269 rte_write32_wc_relaxed(uint32_t value, volatile void *addr); 270 271 #endif /* __DOXYGEN__ */ 272 273 #ifndef RTE_OVERRIDE_IO_H 274 275 static __rte_always_inline uint8_t 276 rte_read8_relaxed(const volatile void *addr) 277 { 278 return *(const volatile uint8_t *)addr; 279 } 280 281 static __rte_always_inline uint16_t 282 rte_read16_relaxed(const volatile void *addr) 283 { 284 return *(const volatile uint16_t *)addr; 285 } 286 287 static __rte_always_inline uint32_t 288 rte_read32_relaxed(const volatile void *addr) 289 { 290 return *(const volatile uint32_t *)addr; 291 } 292 293 static __rte_always_inline uint64_t 294 rte_read64_relaxed(const volatile void *addr) 295 { 296 return *(const volatile uint64_t *)addr; 297 } 298 299 static __rte_always_inline void 300 rte_write8_relaxed(uint8_t value, volatile void *addr) 301 { 302 *(volatile uint8_t *)addr = value; 303 } 304 305 static __rte_always_inline void 306 rte_write16_relaxed(uint16_t value, volatile void *addr) 307 { 308 *(volatile uint16_t *)addr = value; 309 } 310 311 static __rte_always_inline void 312 rte_write32_relaxed(uint32_t value, volatile void *addr) 313 { 314 *(volatile uint32_t *)addr = value; 315 } 316 317 static __rte_always_inline void 318 rte_write64_relaxed(uint64_t value, volatile void *addr) 319 { 320 *(volatile uint64_t *)addr = value; 321 } 322 323 static __rte_always_inline uint8_t 324 rte_read8(const volatile void *addr) 325 { 326 uint8_t val; 327 val = rte_read8_relaxed(addr); 328 rte_io_rmb(); 329 return val; 330 } 331 332 static __rte_always_inline uint16_t 333 rte_read16(const volatile void *addr) 334 { 335 uint16_t val; 336 val = rte_read16_relaxed(addr); 337 rte_io_rmb(); 338 return val; 339 } 340 341 static __rte_always_inline uint32_t 342 rte_read32(const volatile void *addr) 343 { 344 uint32_t val; 345 val = rte_read32_relaxed(addr); 346 rte_io_rmb(); 347 return val; 348 } 349 350 static __rte_always_inline uint64_t 351 rte_read64(const volatile void *addr) 352 { 353 uint64_t val; 354 val = rte_read64_relaxed(addr); 355 rte_io_rmb(); 356 return val; 357 } 358 359 static __rte_always_inline void 360 rte_write8(uint8_t value, volatile void *addr) 361 { 362 rte_io_wmb(); 363 rte_write8_relaxed(value, addr); 364 } 365 366 static __rte_always_inline void 367 rte_write16(uint16_t value, volatile void *addr) 368 { 369 rte_io_wmb(); 370 rte_write16_relaxed(value, addr); 371 } 372 373 static __rte_always_inline void 374 rte_write32(uint32_t value, volatile void *addr) 375 { 376 rte_io_wmb(); 377 rte_write32_relaxed(value, addr); 378 } 379 380 static __rte_always_inline void 381 rte_write64(uint64_t value, volatile void *addr) 382 { 383 rte_io_wmb(); 384 rte_write64_relaxed(value, addr); 385 } 386 387 #ifndef RTE_NATIVE_WRITE32_WC 388 static __rte_always_inline void 389 rte_write32_wc(uint32_t value, volatile void *addr) 390 { 391 rte_write32(value, addr); 392 } 393 394 static __rte_always_inline void 395 rte_write32_wc_relaxed(uint32_t value, volatile void *addr) 396 { 397 rte_write32_relaxed(value, addr); 398 } 399 #endif /* RTE_NATIVE_WRITE32_WC */ 400 401 #endif /* RTE_OVERRIDE_IO_H */ 402 403 #ifdef __cplusplus 404 } 405 #endif 406 407 #endif /* _RTE_IO_H_ */ 408