Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause 2 : * Copyright (C) 2015 Intel Corporation. 3 : * All rights reserved. 4 : */ 5 : 6 : /** \file 7 : * Memory-mapped I/O utility functions 8 : */ 9 : 10 : #ifndef SPDK_MMIO_H 11 : #define SPDK_MMIO_H 12 : 13 : #include "spdk/stdinc.h" 14 : 15 : #ifdef __cplusplus 16 : extern "C" { 17 : #endif 18 : 19 : #include "spdk/barrier.h" 20 : 21 : #ifdef __x86_64__ 22 : #define SPDK_MMIO_64BIT 1 /* Can do atomic 64-bit memory read/write (over PCIe) */ 23 : #else 24 : #define SPDK_MMIO_64BIT 0 25 : #endif 26 : 27 : static inline uint8_t 28 0 : spdk_mmio_read_1(const volatile uint8_t *addr) 29 : { 30 0 : spdk_compiler_barrier(); 31 0 : return *addr; 32 : } 33 : 34 : static inline void 35 0 : spdk_mmio_write_1(volatile uint8_t *addr, uint8_t val) 36 : { 37 0 : spdk_compiler_barrier(); 38 0 : *addr = val; 39 0 : } 40 : 41 : static inline uint16_t 42 0 : spdk_mmio_read_2(const volatile uint16_t *addr) 43 : { 44 0 : spdk_compiler_barrier(); 45 0 : return *addr; 46 : } 47 : 48 : static inline void 49 0 : spdk_mmio_write_2(volatile uint16_t *addr, uint16_t val) 50 : { 51 0 : spdk_compiler_barrier(); 52 0 : *addr = val; 53 0 : } 54 : 55 : static inline uint32_t 56 43 : spdk_mmio_read_4(const volatile uint32_t *addr) 57 : { 58 43 : spdk_compiler_barrier(); 59 43 : return *addr; 60 : } 61 : 62 : static inline void 63 49 : spdk_mmio_write_4(volatile uint32_t *addr, uint32_t val) 64 : { 65 49 : spdk_compiler_barrier(); 66 49 : *addr = val; 67 49 : } 68 : 69 : static inline uint64_t 70 11 : spdk_mmio_read_8(volatile uint64_t *addr) 71 : { 72 11 : uint64_t val; 73 11 : volatile uint32_t *addr32 = (volatile uint32_t *)addr; 74 : 75 11 : spdk_compiler_barrier(); 76 : 77 : if (SPDK_MMIO_64BIT) { 78 11 : val = *addr; 79 : } else { 80 : /* 81 : * Read lower 4 bytes before upper 4 bytes. 82 : * This particular order is required by I/OAT. 83 : * If the other order is required, use a pair of spdk_mmio_read_4() calls. 84 : */ 85 : val = addr32[0]; 86 : val |= (uint64_t)addr32[1] << 32; 87 : } 88 : 89 22 : return val; 90 11 : } 91 : 92 : static inline void 93 7 : spdk_mmio_write_8(volatile uint64_t *addr, uint64_t val) 94 : { 95 7 : volatile uint32_t *addr32 = (volatile uint32_t *)addr; 96 : 97 7 : spdk_compiler_barrier(); 98 : 99 : if (SPDK_MMIO_64BIT) { 100 7 : *addr = val; 101 : } else { 102 : addr32[0] = (uint32_t)val; 103 : addr32[1] = (uint32_t)(val >> 32); 104 : } 105 7 : } 106 : 107 : #ifdef __cplusplus 108 : } 109 : #endif 110 : 111 : #endif