1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014-2019, Linaro Limited 4 */ 5 #ifndef IO_H 6 #define IO_H 7 8 #include <compiler.h> 9 #include <stdint.h> 10 #include <types_ext.h> 11 #include <utee_defines.h> 12 13 /* 14 * Make sure that compiler reads/writes given variable only once. This is needed 15 * in cases when we have normal shared memory, and this memory can be changed 16 * at any moment. Compiler does not knows about this, so it can optimize memory 17 * access in any way, including repeated accesses from the same address. 18 * These macro enforce compiler to access memory only once. 19 */ 20 #define READ_ONCE(p) __compiler_atomic_load(&(p)) 21 #define WRITE_ONCE(p, v) __compiler_atomic_store(&(p), (v)) 22 23 static inline void io_write8(vaddr_t addr, uint8_t val) 24 { 25 *(volatile uint8_t *)addr = val; 26 } 27 28 static inline void io_write16(vaddr_t addr, uint16_t val) 29 { 30 *(volatile uint16_t *)addr = val; 31 } 32 33 static inline void io_write32(vaddr_t addr, uint32_t val) 34 { 35 *(volatile uint32_t *)addr = val; 36 } 37 38 static inline uint8_t io_read8(vaddr_t addr) 39 { 40 return *(volatile uint8_t *)addr; 41 } 42 43 static inline uint16_t io_read16(vaddr_t addr) 44 { 45 return *(volatile uint16_t *)addr; 46 } 47 48 static inline uint32_t io_read32(vaddr_t addr) 49 { 50 return *(volatile uint32_t *)addr; 51 } 52 53 static inline void io_mask8(vaddr_t addr, uint8_t val, uint8_t mask) 54 { 55 io_write8(addr, (io_read8(addr) & ~mask) | (val & mask)); 56 } 57 58 static inline void io_mask16(vaddr_t addr, uint16_t val, uint16_t mask) 59 { 60 io_write16(addr, (io_read16(addr) & ~mask) | (val & mask)); 61 } 62 63 static inline void io_mask32(vaddr_t addr, uint32_t val, uint32_t mask) 64 { 65 io_write32(addr, (io_read32(addr) & ~mask) | (val & mask)); 66 } 67 68 static inline uint64_t get_be64(const void *p) 69 { 70 return TEE_U64_FROM_BIG_ENDIAN(*(const uint64_t *)p); 71 } 72 73 static inline void put_be64(void *p, uint64_t val) 74 { 75 *(uint64_t *)p = TEE_U64_TO_BIG_ENDIAN(val); 76 } 77 78 static inline uint32_t get_be32(const void *p) 79 { 80 return TEE_U32_FROM_BIG_ENDIAN(*(const uint32_t *)p); 81 } 82 83 static inline void put_be32(void *p, uint32_t val) 84 { 85 *(uint32_t *)p = TEE_U32_TO_BIG_ENDIAN(val); 86 } 87 88 static inline uint16_t get_be16(const void *p) 89 { 90 return TEE_U16_FROM_BIG_ENDIAN(*(const uint16_t *)p); 91 } 92 93 static inline void put_be16(void *p, uint16_t val) 94 { 95 *(uint16_t *)p = TEE_U16_TO_BIG_ENDIAN(val); 96 } 97 98 static inline void put_le32(const void *p, uint32_t val) 99 { 100 *(uint32_t *)p = val; 101 } 102 103 static inline uint32_t get_le32(const void *p) 104 { 105 return *(const uint32_t *)p; 106 } 107 108 static inline void put_le64(const void *p, uint64_t val) 109 { 110 *(uint64_t *)p = val; 111 } 112 113 static inline uint64_t get_le64(const void *p) 114 { 115 return *(const uint64_t *)p; 116 } 117 118 /* 119 * Set and clear bits helpers. 120 * 121 * @addr is the address of the memory cell accessed 122 * @set_mask represents the bit mask of the bit(s) to set, aka set to 1 123 * @clear_mask represents the bit mask of the bit(s) to clear, aka reset to 0 124 * 125 * io_clrsetbits32() clears then sets the target bits in this order. If a bit 126 * position is defined by both @set_mask and @clear_mask, the bit will be set. 127 */ 128 static inline void io_setbits32(vaddr_t addr, uint32_t set_mask) 129 { 130 io_write32(addr, io_read32(addr) | set_mask); 131 } 132 133 static inline void io_clrbits32(vaddr_t addr, uint32_t clear_mask) 134 { 135 io_write32(addr, io_read32(addr) & ~clear_mask); 136 } 137 138 static inline void io_clrsetbits32(vaddr_t addr, uint32_t clear_mask, 139 uint32_t set_mask) 140 { 141 io_write32(addr, (io_read32(addr) & ~clear_mask) | set_mask); 142 } 143 144 static inline void io_setbits16(vaddr_t addr, uint16_t set_mask) 145 { 146 io_write16(addr, io_read16(addr) | set_mask); 147 } 148 149 static inline void io_clrbits16(vaddr_t addr, uint16_t clear_mask) 150 { 151 io_write16(addr, io_read16(addr) & ~clear_mask); 152 } 153 154 static inline void io_clrsetbits16(vaddr_t addr, uint16_t clear_mask, 155 uint16_t set_mask) 156 { 157 io_write16(addr, (io_read16(addr) & ~clear_mask) | set_mask); 158 } 159 160 static inline void io_setbits8(vaddr_t addr, uint8_t set_mask) 161 { 162 io_write8(addr, io_read8(addr) | set_mask); 163 } 164 165 static inline void io_clrbits8(vaddr_t addr, uint8_t clear_mask) 166 { 167 io_write8(addr, io_read8(addr) & ~clear_mask); 168 } 169 170 static inline void io_clrsetbits8(vaddr_t addr, uint8_t clear_mask, 171 uint8_t set_mask) 172 { 173 io_write8(addr, (io_read8(addr) & ~clear_mask) | set_mask); 174 } 175 176 #endif /*IO_H*/ 177