xref: /freebsd/sys/compat/linuxkpi/common/include/linux/io.h (revision 2ae0f5a4d0931067c672be9a791909f0e32d5a0e)
18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky  * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Panasas, Inc.
586845417SHans Petter Selasky  * Copyright (c) 2013-2015 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky  * All rights reserved.
78d59ecb2SHans Petter Selasky  *
88d59ecb2SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky  * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky  * are met:
118d59ecb2SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky  *    notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky  *    disclaimer.
148d59ecb2SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky  *
188d59ecb2SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky  */
29307f78f3SVladimir Kondratyev #ifndef	_LINUXKPI_LINUX_IO_H_
30307f78f3SVladimir Kondratyev #define	_LINUXKPI_LINUX_IO_H_
318d59ecb2SHans Petter Selasky 
328d59ecb2SHans Petter Selasky #include <sys/endian.h>
338e7baabcSHans Petter Selasky #include <sys/types.h>
348d59ecb2SHans Petter Selasky 
35588fbadfSHans Petter Selasky #include <machine/vm.h>
36588fbadfSHans Petter Selasky 
37684a5fefSHans Petter Selasky #include <linux/compiler.h>
38af787b8eSVladimir Kondratyev #include <linux/err.h>
39cb564d24SMark Johnston #include <linux/types.h>
40521abc32SEmmanuel Vadot #if !defined(__arm__)
41789dbdbbSEmmanuel Vadot #include <asm/set_memory.h>
42d387a1b4SEmmanuel Vadot #endif
43684a5fefSHans Petter Selasky 
448d59ecb2SHans Petter Selasky /*
458d59ecb2SHans Petter Selasky  * XXX This is all x86 specific.  It should be bus space access.
468d59ecb2SHans Petter Selasky  */
478d59ecb2SHans Petter Selasky 
48937a05baSJustin Hibbits /* rmb and wmb are declared in machine/atomic.h, so should be included first. */
49937a05baSJustin Hibbits #ifndef __io_br
50937a05baSJustin Hibbits #define	__io_br()	__compiler_membar()
51937a05baSJustin Hibbits #endif
52937a05baSJustin Hibbits 
53937a05baSJustin Hibbits #ifndef __io_ar
54937a05baSJustin Hibbits #ifdef rmb
55937a05baSJustin Hibbits #define	__io_ar()	rmb()
56937a05baSJustin Hibbits #else
57937a05baSJustin Hibbits #define	__io_ar()	__compiler_membar()
58937a05baSJustin Hibbits #endif
59937a05baSJustin Hibbits #endif
60937a05baSJustin Hibbits 
61937a05baSJustin Hibbits #ifndef __io_bw
62937a05baSJustin Hibbits #ifdef wmb
63937a05baSJustin Hibbits #define	__io_bw()	wmb()
64937a05baSJustin Hibbits #else
65937a05baSJustin Hibbits #define	__io_bw()	__compiler_membar()
66937a05baSJustin Hibbits #endif
67937a05baSJustin Hibbits #endif
68937a05baSJustin Hibbits 
69937a05baSJustin Hibbits #ifndef __io_aw
70937a05baSJustin Hibbits #define	__io_aw()	__compiler_membar()
71937a05baSJustin Hibbits #endif
72937a05baSJustin Hibbits 
73642909fdSTijl Coosemans /* Access MMIO registers atomically without barriers and byte swapping. */
748d59ecb2SHans Petter Selasky 
75684a5fefSHans Petter Selasky static inline uint8_t
76642909fdSTijl Coosemans __raw_readb(const volatile void *addr)
77684a5fefSHans Petter Selasky {
78642909fdSTijl Coosemans 	return (*(const volatile uint8_t *)addr);
79684a5fefSHans Petter Selasky }
80642909fdSTijl Coosemans #define	__raw_readb(addr)	__raw_readb(addr)
81684a5fefSHans Petter Selasky 
82684a5fefSHans Petter Selasky static inline void
83642909fdSTijl Coosemans __raw_writeb(uint8_t v, volatile void *addr)
84684a5fefSHans Petter Selasky {
85684a5fefSHans Petter Selasky 	*(volatile uint8_t *)addr = v;
86684a5fefSHans Petter Selasky }
87642909fdSTijl Coosemans #define	__raw_writeb(v, addr)	__raw_writeb(v, addr)
88684a5fefSHans Petter Selasky 
89642909fdSTijl Coosemans static inline uint16_t
90642909fdSTijl Coosemans __raw_readw(const volatile void *addr)
91642909fdSTijl Coosemans {
92642909fdSTijl Coosemans 	return (*(const volatile uint16_t *)addr);
93642909fdSTijl Coosemans }
94642909fdSTijl Coosemans #define	__raw_readw(addr)	__raw_readw(addr)
95642909fdSTijl Coosemans 
96684a5fefSHans Petter Selasky static inline void
97642909fdSTijl Coosemans __raw_writew(uint16_t v, volatile void *addr)
98684a5fefSHans Petter Selasky {
99684a5fefSHans Petter Selasky 	*(volatile uint16_t *)addr = v;
100684a5fefSHans Petter Selasky }
101642909fdSTijl Coosemans #define	__raw_writew(v, addr)	__raw_writew(v, addr)
102684a5fefSHans Petter Selasky 
103642909fdSTijl Coosemans static inline uint32_t
104642909fdSTijl Coosemans __raw_readl(const volatile void *addr)
105642909fdSTijl Coosemans {
106642909fdSTijl Coosemans 	return (*(const volatile uint32_t *)addr);
107642909fdSTijl Coosemans }
108642909fdSTijl Coosemans #define	__raw_readl(addr)	__raw_readl(addr)
109642909fdSTijl Coosemans 
110684a5fefSHans Petter Selasky static inline void
111642909fdSTijl Coosemans __raw_writel(uint32_t v, volatile void *addr)
112684a5fefSHans Petter Selasky {
113684a5fefSHans Petter Selasky 	*(volatile uint32_t *)addr = v;
114684a5fefSHans Petter Selasky }
115642909fdSTijl Coosemans #define	__raw_writel(v, addr)	__raw_writel(v, addr)
116684a5fefSHans Petter Selasky 
117642909fdSTijl Coosemans #ifdef __LP64__
118642909fdSTijl Coosemans static inline uint64_t
119642909fdSTijl Coosemans __raw_readq(const volatile void *addr)
1208d59ecb2SHans Petter Selasky {
121642909fdSTijl Coosemans 	return (*(const volatile uint64_t *)addr);
1228d59ecb2SHans Petter Selasky }
123642909fdSTijl Coosemans #define	__raw_readq(addr)	__raw_readq(addr)
124642909fdSTijl Coosemans 
125642909fdSTijl Coosemans static inline void
126642909fdSTijl Coosemans __raw_writeq(uint64_t v, volatile void *addr)
127642909fdSTijl Coosemans {
128642909fdSTijl Coosemans 	*(volatile uint64_t *)addr = v;
129642909fdSTijl Coosemans }
130642909fdSTijl Coosemans #define	__raw_writeq(v, addr)	__raw_writeq(v, addr)
131642909fdSTijl Coosemans #endif
132642909fdSTijl Coosemans 
133642909fdSTijl Coosemans #define	mmiowb()	barrier()
134642909fdSTijl Coosemans 
135642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically with memory barriers. */
1368d59ecb2SHans Petter Selasky 
13786845417SHans Petter Selasky #undef readb
13886845417SHans Petter Selasky static inline uint8_t
13986845417SHans Petter Selasky readb(const volatile void *addr)
14086845417SHans Petter Selasky {
141642909fdSTijl Coosemans 	uint8_t v;
142642909fdSTijl Coosemans 
143937a05baSJustin Hibbits 	__io_br();
144642909fdSTijl Coosemans 	v = *(const volatile uint8_t *)addr;
145937a05baSJustin Hibbits 	__io_ar();
146642909fdSTijl Coosemans 	return (v);
14786845417SHans Petter Selasky }
148642909fdSTijl Coosemans #define	readb(addr)		readb(addr)
149642909fdSTijl Coosemans 
150642909fdSTijl Coosemans #undef writeb
151642909fdSTijl Coosemans static inline void
152642909fdSTijl Coosemans writeb(uint8_t v, volatile void *addr)
153642909fdSTijl Coosemans {
154937a05baSJustin Hibbits 	__io_bw();
155642909fdSTijl Coosemans 	*(volatile uint8_t *)addr = v;
156937a05baSJustin Hibbits 	__io_aw();
157642909fdSTijl Coosemans }
158642909fdSTijl Coosemans #define	writeb(v, addr)		writeb(v, addr)
15986845417SHans Petter Selasky 
16086845417SHans Petter Selasky #undef readw
16186845417SHans Petter Selasky static inline uint16_t
16286845417SHans Petter Selasky readw(const volatile void *addr)
16386845417SHans Petter Selasky {
164642909fdSTijl Coosemans 	uint16_t v;
165642909fdSTijl Coosemans 
166937a05baSJustin Hibbits 	__io_br();
167937a05baSJustin Hibbits 	v = le16toh(__raw_readw(addr));
168937a05baSJustin Hibbits 	__io_ar();
169642909fdSTijl Coosemans 	return (v);
17086845417SHans Petter Selasky }
171642909fdSTijl Coosemans #define	readw(addr)		readw(addr)
172642909fdSTijl Coosemans 
173642909fdSTijl Coosemans #undef writew
174642909fdSTijl Coosemans static inline void
175642909fdSTijl Coosemans writew(uint16_t v, volatile void *addr)
176642909fdSTijl Coosemans {
177937a05baSJustin Hibbits 	__io_bw();
178937a05baSJustin Hibbits 	__raw_writew(htole16(v), addr);
179937a05baSJustin Hibbits 	__io_aw();
180642909fdSTijl Coosemans }
181642909fdSTijl Coosemans #define	writew(v, addr)		writew(v, addr)
18286845417SHans Petter Selasky 
18386845417SHans Petter Selasky #undef readl
18486845417SHans Petter Selasky static inline uint32_t
18586845417SHans Petter Selasky readl(const volatile void *addr)
18686845417SHans Petter Selasky {
187642909fdSTijl Coosemans 	uint32_t v;
188642909fdSTijl Coosemans 
189937a05baSJustin Hibbits 	__io_br();
190937a05baSJustin Hibbits 	v = le32toh(__raw_readl(addr));
191937a05baSJustin Hibbits 	__io_ar();
192642909fdSTijl Coosemans 	return (v);
19386845417SHans Petter Selasky }
194642909fdSTijl Coosemans #define	readl(addr)		readl(addr)
195642909fdSTijl Coosemans 
196642909fdSTijl Coosemans #undef writel
197642909fdSTijl Coosemans static inline void
198642909fdSTijl Coosemans writel(uint32_t v, volatile void *addr)
199642909fdSTijl Coosemans {
200937a05baSJustin Hibbits 	__io_bw();
201937a05baSJustin Hibbits 	__raw_writel(htole32(v), addr);
202937a05baSJustin Hibbits 	__io_aw();
203642909fdSTijl Coosemans }
204642909fdSTijl Coosemans #define	writel(v, addr)		writel(v, addr)
205642909fdSTijl Coosemans 
206642909fdSTijl Coosemans #undef readq
207642909fdSTijl Coosemans #undef writeq
208642909fdSTijl Coosemans #ifdef __LP64__
209642909fdSTijl Coosemans static inline uint64_t
210642909fdSTijl Coosemans readq(const volatile void *addr)
211642909fdSTijl Coosemans {
212642909fdSTijl Coosemans 	uint64_t v;
213642909fdSTijl Coosemans 
214937a05baSJustin Hibbits 	__io_br();
215937a05baSJustin Hibbits 	v = le64toh(__raw_readq(addr));
216937a05baSJustin Hibbits 	__io_ar();
217642909fdSTijl Coosemans 	return (v);
218642909fdSTijl Coosemans }
219642909fdSTijl Coosemans #define	readq(addr)		readq(addr)
220642909fdSTijl Coosemans 
221642909fdSTijl Coosemans static inline void
222642909fdSTijl Coosemans writeq(uint64_t v, volatile void *addr)
223642909fdSTijl Coosemans {
224937a05baSJustin Hibbits 	__io_bw();
225937a05baSJustin Hibbits 	__raw_writeq(htole64(v), addr);
226937a05baSJustin Hibbits 	__io_aw();
227642909fdSTijl Coosemans }
228642909fdSTijl Coosemans #define	writeq(v, addr)		writeq(v, addr)
229642909fdSTijl Coosemans #endif
230642909fdSTijl Coosemans 
231642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically without memory barriers. */
232642909fdSTijl Coosemans 
233642909fdSTijl Coosemans #undef readb_relaxed
234642909fdSTijl Coosemans static inline uint8_t
235642909fdSTijl Coosemans readb_relaxed(const volatile void *addr)
236642909fdSTijl Coosemans {
237937a05baSJustin Hibbits 	return (__raw_readb(addr));
238642909fdSTijl Coosemans }
239642909fdSTijl Coosemans #define	readb_relaxed(addr)	readb_relaxed(addr)
240642909fdSTijl Coosemans 
241642909fdSTijl Coosemans #undef writeb_relaxed
242642909fdSTijl Coosemans static inline void
243642909fdSTijl Coosemans writeb_relaxed(uint8_t v, volatile void *addr)
244642909fdSTijl Coosemans {
245937a05baSJustin Hibbits 	__raw_writeb(v, addr);
246642909fdSTijl Coosemans }
247642909fdSTijl Coosemans #define	writeb_relaxed(v, addr)	writeb_relaxed(v, addr)
248642909fdSTijl Coosemans 
249642909fdSTijl Coosemans #undef readw_relaxed
250642909fdSTijl Coosemans static inline uint16_t
251642909fdSTijl Coosemans readw_relaxed(const volatile void *addr)
252642909fdSTijl Coosemans {
253937a05baSJustin Hibbits 	return (le16toh(__raw_readw(addr)));
254642909fdSTijl Coosemans }
255642909fdSTijl Coosemans #define	readw_relaxed(addr)	readw_relaxed(addr)
256642909fdSTijl Coosemans 
257642909fdSTijl Coosemans #undef writew_relaxed
258642909fdSTijl Coosemans static inline void
259642909fdSTijl Coosemans writew_relaxed(uint16_t v, volatile void *addr)
260642909fdSTijl Coosemans {
261937a05baSJustin Hibbits 	__raw_writew(htole16(v), addr);
262642909fdSTijl Coosemans }
263642909fdSTijl Coosemans #define	writew_relaxed(v, addr)	writew_relaxed(v, addr)
264642909fdSTijl Coosemans 
265642909fdSTijl Coosemans #undef readl_relaxed
266642909fdSTijl Coosemans static inline uint32_t
267642909fdSTijl Coosemans readl_relaxed(const volatile void *addr)
268642909fdSTijl Coosemans {
269937a05baSJustin Hibbits 	return (le32toh(__raw_readl(addr)));
270642909fdSTijl Coosemans }
271642909fdSTijl Coosemans #define	readl_relaxed(addr)	readl_relaxed(addr)
272642909fdSTijl Coosemans 
273642909fdSTijl Coosemans #undef writel_relaxed
274642909fdSTijl Coosemans static inline void
275642909fdSTijl Coosemans writel_relaxed(uint32_t v, volatile void *addr)
276642909fdSTijl Coosemans {
277937a05baSJustin Hibbits 	__raw_writel(htole32(v), addr);
278642909fdSTijl Coosemans }
279642909fdSTijl Coosemans #define	writel_relaxed(v, addr)	writel_relaxed(v, addr)
280642909fdSTijl Coosemans 
281642909fdSTijl Coosemans #undef readq_relaxed
282642909fdSTijl Coosemans #undef writeq_relaxed
283642909fdSTijl Coosemans #ifdef __LP64__
284642909fdSTijl Coosemans static inline uint64_t
285642909fdSTijl Coosemans readq_relaxed(const volatile void *addr)
286642909fdSTijl Coosemans {
287937a05baSJustin Hibbits 	return (le64toh(__raw_readq(addr)));
288642909fdSTijl Coosemans }
289642909fdSTijl Coosemans #define	readq_relaxed(addr)	readq_relaxed(addr)
290642909fdSTijl Coosemans 
291642909fdSTijl Coosemans static inline void
292642909fdSTijl Coosemans writeq_relaxed(uint64_t v, volatile void *addr)
293642909fdSTijl Coosemans {
294937a05baSJustin Hibbits 	__raw_writeq(htole64(v), addr);
295642909fdSTijl Coosemans }
296642909fdSTijl Coosemans #define	writeq_relaxed(v, addr)	writeq_relaxed(v, addr)
297642909fdSTijl Coosemans #endif
298642909fdSTijl Coosemans 
299642909fdSTijl Coosemans /* XXX On Linux ioread and iowrite handle both MMIO and port IO. */
300642909fdSTijl Coosemans 
301642909fdSTijl Coosemans #undef ioread8
302642909fdSTijl Coosemans static inline uint8_t
303642909fdSTijl Coosemans ioread8(const volatile void *addr)
304642909fdSTijl Coosemans {
305642909fdSTijl Coosemans 	return (readb(addr));
306642909fdSTijl Coosemans }
307642909fdSTijl Coosemans #define	ioread8(addr)		ioread8(addr)
308642909fdSTijl Coosemans 
309642909fdSTijl Coosemans #undef ioread16
310642909fdSTijl Coosemans static inline uint16_t
311642909fdSTijl Coosemans ioread16(const volatile void *addr)
312642909fdSTijl Coosemans {
313642909fdSTijl Coosemans 	return (readw(addr));
314642909fdSTijl Coosemans }
315642909fdSTijl Coosemans #define	ioread16(addr)		ioread16(addr)
316642909fdSTijl Coosemans 
317642909fdSTijl Coosemans #undef ioread16be
318642909fdSTijl Coosemans static inline uint16_t
319642909fdSTijl Coosemans ioread16be(const volatile void *addr)
320642909fdSTijl Coosemans {
321937a05baSJustin Hibbits 	uint16_t v;
322937a05baSJustin Hibbits 
323937a05baSJustin Hibbits 	__io_br();
324937a05baSJustin Hibbits 	v = (be16toh(__raw_readw(addr)));
325937a05baSJustin Hibbits 	__io_ar();
326937a05baSJustin Hibbits 
327937a05baSJustin Hibbits 	return (v);
328642909fdSTijl Coosemans }
329642909fdSTijl Coosemans #define	ioread16be(addr)	ioread16be(addr)
330642909fdSTijl Coosemans 
331642909fdSTijl Coosemans #undef ioread32
332642909fdSTijl Coosemans static inline uint32_t
333642909fdSTijl Coosemans ioread32(const volatile void *addr)
334642909fdSTijl Coosemans {
335642909fdSTijl Coosemans 	return (readl(addr));
336642909fdSTijl Coosemans }
337642909fdSTijl Coosemans #define	ioread32(addr)		ioread32(addr)
338642909fdSTijl Coosemans 
339642909fdSTijl Coosemans #undef ioread32be
340642909fdSTijl Coosemans static inline uint32_t
341642909fdSTijl Coosemans ioread32be(const volatile void *addr)
342642909fdSTijl Coosemans {
343937a05baSJustin Hibbits 	uint32_t v;
344937a05baSJustin Hibbits 
345937a05baSJustin Hibbits 	__io_br();
346937a05baSJustin Hibbits 	v = (be32toh(__raw_readl(addr)));
347937a05baSJustin Hibbits 	__io_ar();
348937a05baSJustin Hibbits 
349937a05baSJustin Hibbits 	return (v);
350642909fdSTijl Coosemans }
351642909fdSTijl Coosemans #define	ioread32be(addr)	ioread32be(addr)
352642909fdSTijl Coosemans 
35373ccd188SVladimir Kondratyev #ifdef __LP64__
354dcfc9833SVladimir Kondratyev #undef ioread64
355dcfc9833SVladimir Kondratyev static inline uint64_t
356dcfc9833SVladimir Kondratyev ioread64(const volatile void *addr)
357dcfc9833SVladimir Kondratyev {
358dcfc9833SVladimir Kondratyev 	return (readq(addr));
359dcfc9833SVladimir Kondratyev }
360dcfc9833SVladimir Kondratyev #define	ioread64(addr)		ioread64(addr)
36173ccd188SVladimir Kondratyev #endif
362dcfc9833SVladimir Kondratyev 
363642909fdSTijl Coosemans #undef iowrite8
364642909fdSTijl Coosemans static inline void
365642909fdSTijl Coosemans iowrite8(uint8_t v, volatile void *addr)
366642909fdSTijl Coosemans {
367642909fdSTijl Coosemans 	writeb(v, addr);
368642909fdSTijl Coosemans }
369642909fdSTijl Coosemans #define	iowrite8(v, addr)	iowrite8(v, addr)
370642909fdSTijl Coosemans 
371642909fdSTijl Coosemans #undef iowrite16
372642909fdSTijl Coosemans static inline void
373642909fdSTijl Coosemans iowrite16(uint16_t v, volatile void *addr)
374642909fdSTijl Coosemans {
375642909fdSTijl Coosemans 	writew(v, addr);
376642909fdSTijl Coosemans }
377642909fdSTijl Coosemans #define	iowrite16	iowrite16
378642909fdSTijl Coosemans 
379642909fdSTijl Coosemans #undef iowrite32
380642909fdSTijl Coosemans static inline void
381642909fdSTijl Coosemans iowrite32(uint32_t v, volatile void *addr)
382642909fdSTijl Coosemans {
383642909fdSTijl Coosemans 	writel(v, addr);
384642909fdSTijl Coosemans }
385642909fdSTijl Coosemans #define	iowrite32(v, addr)	iowrite32(v, addr)
386642909fdSTijl Coosemans 
387642909fdSTijl Coosemans #undef iowrite32be
388642909fdSTijl Coosemans static inline void
389642909fdSTijl Coosemans iowrite32be(uint32_t v, volatile void *addr)
390642909fdSTijl Coosemans {
391937a05baSJustin Hibbits 	__io_bw();
392937a05baSJustin Hibbits 	__raw_writel(htobe32(v), addr);
393937a05baSJustin Hibbits 	__io_aw();
394642909fdSTijl Coosemans }
395642909fdSTijl Coosemans #define	iowrite32be(v, addr)	iowrite32be(v, addr)
39686845417SHans Petter Selasky 
39786845417SHans Petter Selasky #if defined(__i386__) || defined(__amd64__)
39894a201beSHans Petter Selasky static inline void
39994a201beSHans Petter Selasky _outb(u_char data, u_int port)
40094a201beSHans Petter Selasky {
40194a201beSHans Petter Selasky 	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
40294a201beSHans Petter Selasky }
40394a201beSHans Petter Selasky #endif
40494a201beSHans Petter Selasky 
40560d962e0SJessica Clarke #if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv)
4068d59ecb2SHans Petter Selasky void *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr);
40786845417SHans Petter Selasky #else
40834dae08eSJohn Baldwin static __inline void *
40934dae08eSJohn Baldwin _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr)
41034dae08eSJohn Baldwin {
41134dae08eSJohn Baldwin 	return (NULL);
41234dae08eSJohn Baldwin }
41386845417SHans Petter Selasky #endif
41486845417SHans Petter Selasky 
4154cbd4277SBjoern A. Zeeb struct device;
4164cbd4277SBjoern A. Zeeb static inline void *
4174cbd4277SBjoern A. Zeeb devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size)
4184cbd4277SBjoern A. Zeeb {
4194cbd4277SBjoern A. Zeeb 	return (NULL);
4204cbd4277SBjoern A. Zeeb }
4214cbd4277SBjoern A. Zeeb 
4224d83500fSHans Petter Selasky #ifdef VM_MEMATTR_DEVICE
4234d83500fSHans Petter Selasky #define	ioremap_nocache(addr, size)					\
4244d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4254d83500fSHans Petter Selasky #define	ioremap_wt(addr, size)						\
4264d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4274d83500fSHans Petter Selasky #define	ioremap(addr, size)						\
4284d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4294d83500fSHans Petter Selasky #else
4308d59ecb2SHans Petter Selasky #define	ioremap_nocache(addr, size)					\
4318d59ecb2SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
432f2dbb750SHans Petter Selasky #define	ioremap_wt(addr, size)						\
433f2dbb750SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH)
43486845417SHans Petter Selasky #define	ioremap(addr, size)						\
43586845417SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
4364d83500fSHans Petter Selasky #endif
4378167c92fSJessica Clarke #ifdef VM_MEMATTR_WRITE_COMBINING
4384d83500fSHans Petter Selasky #define	ioremap_wc(addr, size)						\
4394d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING)
4408167c92fSJessica Clarke #else
4418167c92fSJessica Clarke #define	ioremap_wc(addr, size)	ioremap_nocache(addr, size)
4428167c92fSJessica Clarke #endif
443ed53e350SJean-Sébastien Pédron #define	ioremap_cache(addr, size)					\
4444d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK)
4458d59ecb2SHans Petter Selasky void iounmap(void *addr);
4468d59ecb2SHans Petter Selasky 
4478d59ecb2SHans Petter Selasky #define	memset_io(a, b, c)	memset((a), (b), (c))
4488d59ecb2SHans Petter Selasky #define	memcpy_fromio(a, b, c)	memcpy((a), (b), (c))
4498d59ecb2SHans Petter Selasky #define	memcpy_toio(a, b, c)	memcpy((a), (b), (c))
4508d59ecb2SHans Petter Selasky 
4518d59ecb2SHans Petter Selasky static inline void
452046b8284SBjoern A. Zeeb __iowrite32_copy(void *to, const void *from, size_t count)
45386364964SKevin Lo {
454046b8284SBjoern A. Zeeb 	const uint32_t *src;
45586364964SKevin Lo 	uint32_t *dst;
45686364964SKevin Lo 	int i;
45786364964SKevin Lo 
45886364964SKevin Lo 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
45986364964SKevin Lo 		__raw_writel(*src, dst);
46086364964SKevin Lo }
46186364964SKevin Lo 
46286364964SKevin Lo static inline void
463046b8284SBjoern A. Zeeb __iowrite64_copy(void *to, const void *from, size_t count)
4648d59ecb2SHans Petter Selasky {
4658d59ecb2SHans Petter Selasky #ifdef __LP64__
466046b8284SBjoern A. Zeeb 	const uint64_t *src;
4678d59ecb2SHans Petter Selasky 	uint64_t *dst;
4688d59ecb2SHans Petter Selasky 	int i;
4698d59ecb2SHans Petter Selasky 
4708d59ecb2SHans Petter Selasky 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
4718d59ecb2SHans Petter Selasky 		__raw_writeq(*src, dst);
4728d59ecb2SHans Petter Selasky #else
47386364964SKevin Lo 	__iowrite32_copy(to, from, count * 2);
4748d59ecb2SHans Petter Selasky #endif
4758d59ecb2SHans Petter Selasky }
4768d59ecb2SHans Petter Selasky 
477046b8284SBjoern A. Zeeb static inline void
478046b8284SBjoern A. Zeeb __ioread32_copy(void *to, const void *from, size_t count)
479046b8284SBjoern A. Zeeb {
480046b8284SBjoern A. Zeeb 	const uint32_t *src;
481046b8284SBjoern A. Zeeb 	uint32_t *dst;
482046b8284SBjoern A. Zeeb 	int i;
483046b8284SBjoern A. Zeeb 
484046b8284SBjoern A. Zeeb 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
485046b8284SBjoern A. Zeeb 		*dst = __raw_readl(src);
486046b8284SBjoern A. Zeeb }
487046b8284SBjoern A. Zeeb 
488046b8284SBjoern A. Zeeb static inline void
489046b8284SBjoern A. Zeeb __ioread64_copy(void *to, const void *from, size_t count)
490046b8284SBjoern A. Zeeb {
491046b8284SBjoern A. Zeeb #ifdef __LP64__
492046b8284SBjoern A. Zeeb 	const uint64_t *src;
493046b8284SBjoern A. Zeeb 	uint64_t *dst;
494046b8284SBjoern A. Zeeb 	int i;
495046b8284SBjoern A. Zeeb 
496046b8284SBjoern A. Zeeb 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
497046b8284SBjoern A. Zeeb 		*dst = __raw_readq(src);
498046b8284SBjoern A. Zeeb #else
499046b8284SBjoern A. Zeeb 	__ioread32_copy(to, from, count * 2);
500046b8284SBjoern A. Zeeb #endif
501046b8284SBjoern A. Zeeb }
502046b8284SBjoern A. Zeeb 
503684a5fefSHans Petter Selasky enum {
504684a5fefSHans Petter Selasky 	MEMREMAP_WB = 1 << 0,
505684a5fefSHans Petter Selasky 	MEMREMAP_WT = 1 << 1,
506684a5fefSHans Petter Selasky 	MEMREMAP_WC = 1 << 2,
507684a5fefSHans Petter Selasky };
508684a5fefSHans Petter Selasky 
509684a5fefSHans Petter Selasky static inline void *
510684a5fefSHans Petter Selasky memremap(resource_size_t offset, size_t size, unsigned long flags)
511684a5fefSHans Petter Selasky {
512684a5fefSHans Petter Selasky 	void *addr = NULL;
513684a5fefSHans Petter Selasky 
514684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WB) &&
515ed53e350SJean-Sébastien Pédron 	    (addr = ioremap_cache(offset, size)) != NULL)
516684a5fefSHans Petter Selasky 		goto done;
517684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WT) &&
518f2dbb750SHans Petter Selasky 	    (addr = ioremap_wt(offset, size)) != NULL)
519684a5fefSHans Petter Selasky 		goto done;
520684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WC) &&
521684a5fefSHans Petter Selasky 	    (addr = ioremap_wc(offset, size)) != NULL)
522684a5fefSHans Petter Selasky 		goto done;
523684a5fefSHans Petter Selasky done:
524684a5fefSHans Petter Selasky 	return (addr);
525684a5fefSHans Petter Selasky }
526684a5fefSHans Petter Selasky 
527684a5fefSHans Petter Selasky static inline void
528684a5fefSHans Petter Selasky memunmap(void *addr)
529684a5fefSHans Petter Selasky {
530684a5fefSHans Petter Selasky 	/* XXX May need to check if this is RAM */
531684a5fefSHans Petter Selasky 	iounmap(addr);
532684a5fefSHans Petter Selasky }
5338d59ecb2SHans Petter Selasky 
534af787b8eSVladimir Kondratyev #define	IOMEM_ERR_PTR(err)	(void __iomem *)ERR_PTR(err)
535af787b8eSVladimir Kondratyev 
53698b12978SVladimir Kondratyev #define	__MTRR_ID_BASE	1
53798b12978SVladimir Kondratyev int lkpi_arch_phys_wc_add(unsigned long, unsigned long);
53898b12978SVladimir Kondratyev void lkpi_arch_phys_wc_del(int);
53998b12978SVladimir Kondratyev #define	arch_phys_wc_add(...)	lkpi_arch_phys_wc_add(__VA_ARGS__)
54098b12978SVladimir Kondratyev #define	arch_phys_wc_del(...)	lkpi_arch_phys_wc_del(__VA_ARGS__)
54198b12978SVladimir Kondratyev #define	arch_phys_wc_index(x)	\
54298b12978SVladimir Kondratyev 	(((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE))
54398b12978SVladimir Kondratyev 
544789dbdbbSEmmanuel Vadot static inline int
545789dbdbbSEmmanuel Vadot arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
546789dbdbbSEmmanuel Vadot {
547*2ae0f5a4STijl Coosemans #if defined(__amd64__)
5481e99b2eeSJean-Sébastien Pédron 	vm_offset_t va;
549789dbdbbSEmmanuel Vadot 
5501e99b2eeSJean-Sébastien Pédron 	va = PHYS_TO_DMAP(start);
5511e99b2eeSJean-Sébastien Pédron 	return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
5521e99b2eeSJean-Sébastien Pédron #else
553*2ae0f5a4STijl Coosemans 	return (0);
5541e99b2eeSJean-Sébastien Pédron #endif
555789dbdbbSEmmanuel Vadot }
556789dbdbbSEmmanuel Vadot 
557789dbdbbSEmmanuel Vadot static inline void
558789dbdbbSEmmanuel Vadot arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
559789dbdbbSEmmanuel Vadot {
560*2ae0f5a4STijl Coosemans #if defined(__amd64__)
5611e99b2eeSJean-Sébastien Pédron 	vm_offset_t va;
5621e99b2eeSJean-Sébastien Pédron 
5631e99b2eeSJean-Sébastien Pédron 	va = PHYS_TO_DMAP(start);
5641e99b2eeSJean-Sébastien Pédron 
5651e99b2eeSJean-Sébastien Pédron 	pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
566789dbdbbSEmmanuel Vadot #endif
567*2ae0f5a4STijl Coosemans }
568789dbdbbSEmmanuel Vadot 
569307f78f3SVladimir Kondratyev #endif	/* _LINUXKPI_LINUX_IO_H_ */
570