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