1 #ifndef _ASM_GENERIC_IO_H_ 2 #define _ASM_GENERIC_IO_H_ 3 /* 4 * asm-generic/io.h 5 * adapted from the Linux kernel's include/asm-generic/io.h 6 * and arch/arm/include/asm/io.h 7 * 8 * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2. 11 */ 12 #include "libcflat.h" 13 #include "asm/page.h" 14 #include "asm/barrier.h" 15 16 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 17 #define __cpu_is_be() (0) 18 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 19 #define __cpu_is_be() (1) 20 #else 21 #error Undefined byte order 22 #endif 23 24 #ifndef __raw_readb 25 static inline u8 __raw_readb(const volatile void *addr) 26 { 27 return *(const volatile u8 *)addr; 28 } 29 #endif 30 31 #ifndef __raw_readw 32 static inline u16 __raw_readw(const volatile void *addr) 33 { 34 return *(const volatile u16 *)addr; 35 } 36 #endif 37 38 #ifndef __raw_readl 39 static inline u32 __raw_readl(const volatile void *addr) 40 { 41 return *(const volatile u32 *)addr; 42 } 43 #endif 44 45 #ifndef __raw_readq 46 static inline u64 __raw_readq(const volatile void *addr) 47 { 48 assert(sizeof(unsigned long) == sizeof(u64)); 49 return *(const volatile u64 *)addr; 50 } 51 #endif 52 53 #ifndef __raw_writeb 54 static inline void __raw_writeb(u8 b, volatile void *addr) 55 { 56 *(volatile u8 *)addr = b; 57 } 58 #endif 59 60 #ifndef __raw_writew 61 static inline void __raw_writew(u16 b, volatile void *addr) 62 { 63 *(volatile u16 *)addr = b; 64 } 65 #endif 66 67 #ifndef __raw_writel 68 static inline void __raw_writel(u32 b, volatile void *addr) 69 { 70 *(volatile u32 *)addr = b; 71 } 72 #endif 73 74 #ifndef __raw_writeq 75 static inline void __raw_writeq(u64 b, volatile void *addr) 76 { 77 assert(sizeof(unsigned long) == sizeof(u64)); 78 *(volatile u64 *)addr = b; 79 } 80 #endif 81 82 #ifndef __bswap16 83 static inline u16 __bswap16(u16 x) 84 { 85 return ((x >> 8) & 0xff) | ((x & 0xff) << 8); 86 } 87 #endif 88 89 #ifndef __bswap32 90 static inline u32 __bswap32(u32 x) 91 { 92 return ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) | 93 ((x & 0x0000ff00) << 8) | ((x & 0x000000ff) << 24); 94 } 95 #endif 96 97 #ifndef __bswap64 98 static inline u64 __bswap64(u64 x) 99 { 100 return ((x & 0x00000000000000ffULL) << 56) | 101 ((x & 0x000000000000ff00ULL) << 40) | 102 ((x & 0x0000000000ff0000ULL) << 24) | 103 ((x & 0x00000000ff000000ULL) << 8) | 104 ((x & 0x000000ff00000000ULL) >> 8) | 105 ((x & 0x0000ff0000000000ULL) >> 24) | 106 ((x & 0x00ff000000000000ULL) >> 40) | 107 ((x & 0xff00000000000000ULL) >> 56); 108 } 109 #endif 110 111 #define le16_to_cpu(x) \ 112 ({ u16 __r = __cpu_is_be() ? __bswap16(x) : ((u16)x); __r; }) 113 #define cpu_to_le16 le16_to_cpu 114 115 #define le32_to_cpu(x) \ 116 ({ u32 __r = __cpu_is_be() ? __bswap32(x) : ((u32)x); __r; }) 117 #define cpu_to_le32 le32_to_cpu 118 119 #define le64_to_cpu(x) \ 120 ({ u64 __r = __cpu_is_be() ? __bswap64(x) : ((u64)x); __r; }) 121 #define cpu_to_le64 le64_to_cpu 122 123 #define be16_to_cpu(x) \ 124 ({ u16 __r = !__cpu_is_be() ? __bswap16(x) : ((u16)x); __r; }) 125 #define cpu_to_be16 be16_to_cpu 126 127 #define be32_to_cpu(x) \ 128 ({ u32 __r = !__cpu_is_be() ? __bswap32(x) : ((u32)x); __r; }) 129 #define cpu_to_be32 be32_to_cpu 130 131 #define be64_to_cpu(x) \ 132 ({ u64 __r = !__cpu_is_be() ? __bswap64(x) : ((u64)x); __r; }) 133 #define cpu_to_be64 be64_to_cpu 134 135 #define readb(addr) \ 136 ({ u8 __r = __raw_readb(addr); rmb(); __r; }) 137 #define readw(addr) \ 138 ({ u16 __r = le16_to_cpu(__raw_readw(addr)); rmb(); __r; }) 139 #define readl(addr) \ 140 ({ u32 __r = le32_to_cpu(__raw_readl(addr)); rmb(); __r; }) 141 #define readq(addr) \ 142 ({ u64 __r = le64_to_cpu(__raw_readq(addr)); rmb(); __r; }) 143 144 #define writeb(b, addr) \ 145 ({ wmb(); __raw_writeb(b, addr); }) 146 #define writew(b, addr) \ 147 ({ wmb(); __raw_writew(cpu_to_le16(b), addr); }) 148 #define writel(b, addr) \ 149 ({ wmb(); __raw_writel(cpu_to_le32(b), addr); }) 150 #define writeq(b, addr) \ 151 ({ wmb(); __raw_writeq(cpu_to_le64(b), addr); }) 152 153 #ifndef inb 154 static inline uint8_t inb(unsigned long port) 155 { 156 return readb((const volatile void __iomem *)port); 157 } 158 #endif 159 160 #ifndef inw 161 static inline uint16_t inw(unsigned long port) 162 { 163 return readw((const volatile void __iomem *)port); 164 } 165 #endif 166 167 #ifndef inl 168 static inline uint32_t inl(unsigned long port) 169 { 170 return readl((const volatile void __iomem *)port); 171 } 172 #endif 173 174 #ifndef outb 175 static inline void outb(uint8_t value, unsigned long port) 176 { 177 writeb(value, (volatile void __iomem *)port); 178 } 179 #endif 180 181 #ifndef outw 182 static inline void outw(uint16_t value, unsigned long port) 183 { 184 writew(value, (volatile void __iomem *)port); 185 } 186 #endif 187 188 #ifndef outl 189 static inline void outl(uint32_t value, unsigned long port) 190 { 191 writel(value, (volatile void __iomem *)port); 192 } 193 #endif 194 195 #ifndef ioremap 196 static inline void __iomem *ioremap(phys_addr_t phys_addr, size_t size __unused) 197 { 198 assert(sizeof(long) == 8 || !(phys_addr >> 32)); 199 return (void __iomem *)(unsigned long)phys_addr; 200 } 201 #endif 202 203 #ifndef virt_to_phys 204 static inline unsigned long virt_to_phys(volatile void *address) 205 { 206 return __pa((unsigned long)address); 207 } 208 #endif 209 210 #ifndef phys_to_virt 211 static inline void *phys_to_virt(unsigned long address) 212 { 213 return __va(address); 214 } 215 #endif 216 217 #endif /* _ASM_GENERIC_IO_H_ */ 218