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
__raw_readb(const volatile void * addr)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
__raw_readw(const volatile void * addr)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
__raw_readl(const volatile void * addr)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
__raw_readq(const volatile void * addr)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
__raw_writeb(u8 b,volatile void * addr)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
__raw_writew(u16 b,volatile void * addr)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
__raw_writel(u32 b,volatile void * addr)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
__raw_writeq(u64 b,volatile void * addr)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
__bswap16(u16 x)83 static inline u16 __bswap16(u16 x)
84 {
85 return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
86 }
87 #endif
88
89 #ifndef __bswap32
__bswap32(u32 x)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
__bswap64(u64 x)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
inb(unsigned long port)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
inw(unsigned long port)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
inl(unsigned long port)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
outb(uint8_t value,unsigned long port)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
outw(uint16_t value,unsigned long port)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
outl(uint32_t value,unsigned long port)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
ioremap(phys_addr_t phys_addr,size_t size __unused)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
virt_to_phys(volatile void * address)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
phys_to_virt(unsigned long address)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