xref: /freebsd/sys/compat/linuxkpi/common/include/linux/io.h (revision 521abc32e22a74981360aa5883bb383aea9ee243)
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  *
298d59ecb2SHans Petter Selasky  * $FreeBSD$
308d59ecb2SHans Petter Selasky  */
31307f78f3SVladimir Kondratyev #ifndef	_LINUXKPI_LINUX_IO_H_
32307f78f3SVladimir Kondratyev #define	_LINUXKPI_LINUX_IO_H_
338d59ecb2SHans Petter Selasky 
348d59ecb2SHans Petter Selasky #include <sys/endian.h>
358e7baabcSHans Petter Selasky #include <sys/types.h>
368d59ecb2SHans Petter Selasky 
37588fbadfSHans Petter Selasky #include <machine/vm.h>
38588fbadfSHans Petter Selasky 
39684a5fefSHans Petter Selasky #include <linux/compiler.h>
40cb564d24SMark Johnston #include <linux/types.h>
41*521abc32SEmmanuel Vadot #if !defined(__arm__)
42789dbdbbSEmmanuel Vadot #include <asm/set_memory.h>
43d387a1b4SEmmanuel Vadot #endif
44684a5fefSHans Petter Selasky 
458d59ecb2SHans Petter Selasky /*
468d59ecb2SHans Petter Selasky  * XXX This is all x86 specific.  It should be bus space access.
478d59ecb2SHans Petter Selasky  */
488d59ecb2SHans Petter Selasky 
49937a05baSJustin Hibbits /* rmb and wmb are declared in machine/atomic.h, so should be included first. */
50937a05baSJustin Hibbits #ifndef __io_br
51937a05baSJustin Hibbits #define	__io_br()	__compiler_membar()
52937a05baSJustin Hibbits #endif
53937a05baSJustin Hibbits 
54937a05baSJustin Hibbits #ifndef __io_ar
55937a05baSJustin Hibbits #ifdef rmb
56937a05baSJustin Hibbits #define	__io_ar()	rmb()
57937a05baSJustin Hibbits #else
58937a05baSJustin Hibbits #define	__io_ar()	__compiler_membar()
59937a05baSJustin Hibbits #endif
60937a05baSJustin Hibbits #endif
61937a05baSJustin Hibbits 
62937a05baSJustin Hibbits #ifndef __io_bw
63937a05baSJustin Hibbits #ifdef wmb
64937a05baSJustin Hibbits #define	__io_bw()	wmb()
65937a05baSJustin Hibbits #else
66937a05baSJustin Hibbits #define	__io_bw()	__compiler_membar()
67937a05baSJustin Hibbits #endif
68937a05baSJustin Hibbits #endif
69937a05baSJustin Hibbits 
70937a05baSJustin Hibbits #ifndef __io_aw
71937a05baSJustin Hibbits #define	__io_aw()	__compiler_membar()
72937a05baSJustin Hibbits #endif
73937a05baSJustin Hibbits 
74642909fdSTijl Coosemans /* Access MMIO registers atomically without barriers and byte swapping. */
758d59ecb2SHans Petter Selasky 
76684a5fefSHans Petter Selasky static inline uint8_t
77642909fdSTijl Coosemans __raw_readb(const volatile void *addr)
78684a5fefSHans Petter Selasky {
79642909fdSTijl Coosemans 	return (*(const volatile uint8_t *)addr);
80684a5fefSHans Petter Selasky }
81642909fdSTijl Coosemans #define	__raw_readb(addr)	__raw_readb(addr)
82684a5fefSHans Petter Selasky 
83684a5fefSHans Petter Selasky static inline void
84642909fdSTijl Coosemans __raw_writeb(uint8_t v, volatile void *addr)
85684a5fefSHans Petter Selasky {
86684a5fefSHans Petter Selasky 	*(volatile uint8_t *)addr = v;
87684a5fefSHans Petter Selasky }
88642909fdSTijl Coosemans #define	__raw_writeb(v, addr)	__raw_writeb(v, addr)
89684a5fefSHans Petter Selasky 
90642909fdSTijl Coosemans static inline uint16_t
91642909fdSTijl Coosemans __raw_readw(const volatile void *addr)
92642909fdSTijl Coosemans {
93642909fdSTijl Coosemans 	return (*(const volatile uint16_t *)addr);
94642909fdSTijl Coosemans }
95642909fdSTijl Coosemans #define	__raw_readw(addr)	__raw_readw(addr)
96642909fdSTijl Coosemans 
97684a5fefSHans Petter Selasky static inline void
98642909fdSTijl Coosemans __raw_writew(uint16_t v, volatile void *addr)
99684a5fefSHans Petter Selasky {
100684a5fefSHans Petter Selasky 	*(volatile uint16_t *)addr = v;
101684a5fefSHans Petter Selasky }
102642909fdSTijl Coosemans #define	__raw_writew(v, addr)	__raw_writew(v, addr)
103684a5fefSHans Petter Selasky 
104642909fdSTijl Coosemans static inline uint32_t
105642909fdSTijl Coosemans __raw_readl(const volatile void *addr)
106642909fdSTijl Coosemans {
107642909fdSTijl Coosemans 	return (*(const volatile uint32_t *)addr);
108642909fdSTijl Coosemans }
109642909fdSTijl Coosemans #define	__raw_readl(addr)	__raw_readl(addr)
110642909fdSTijl Coosemans 
111684a5fefSHans Petter Selasky static inline void
112642909fdSTijl Coosemans __raw_writel(uint32_t v, volatile void *addr)
113684a5fefSHans Petter Selasky {
114684a5fefSHans Petter Selasky 	*(volatile uint32_t *)addr = v;
115684a5fefSHans Petter Selasky }
116642909fdSTijl Coosemans #define	__raw_writel(v, addr)	__raw_writel(v, addr)
117684a5fefSHans Petter Selasky 
118642909fdSTijl Coosemans #ifdef __LP64__
119642909fdSTijl Coosemans static inline uint64_t
120642909fdSTijl Coosemans __raw_readq(const volatile void *addr)
1218d59ecb2SHans Petter Selasky {
122642909fdSTijl Coosemans 	return (*(const volatile uint64_t *)addr);
1238d59ecb2SHans Petter Selasky }
124642909fdSTijl Coosemans #define	__raw_readq(addr)	__raw_readq(addr)
125642909fdSTijl Coosemans 
126642909fdSTijl Coosemans static inline void
127642909fdSTijl Coosemans __raw_writeq(uint64_t v, volatile void *addr)
128642909fdSTijl Coosemans {
129642909fdSTijl Coosemans 	*(volatile uint64_t *)addr = v;
130642909fdSTijl Coosemans }
131642909fdSTijl Coosemans #define	__raw_writeq(v, addr)	__raw_writeq(v, addr)
132642909fdSTijl Coosemans #endif
133642909fdSTijl Coosemans 
134642909fdSTijl Coosemans #define	mmiowb()	barrier()
135642909fdSTijl Coosemans 
136642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically with memory barriers. */
1378d59ecb2SHans Petter Selasky 
13886845417SHans Petter Selasky #undef readb
13986845417SHans Petter Selasky static inline uint8_t
14086845417SHans Petter Selasky readb(const volatile void *addr)
14186845417SHans Petter Selasky {
142642909fdSTijl Coosemans 	uint8_t v;
143642909fdSTijl Coosemans 
144937a05baSJustin Hibbits 	__io_br();
145642909fdSTijl Coosemans 	v = *(const volatile uint8_t *)addr;
146937a05baSJustin Hibbits 	__io_ar();
147642909fdSTijl Coosemans 	return (v);
14886845417SHans Petter Selasky }
149642909fdSTijl Coosemans #define	readb(addr)		readb(addr)
150642909fdSTijl Coosemans 
151642909fdSTijl Coosemans #undef writeb
152642909fdSTijl Coosemans static inline void
153642909fdSTijl Coosemans writeb(uint8_t v, volatile void *addr)
154642909fdSTijl Coosemans {
155937a05baSJustin Hibbits 	__io_bw();
156642909fdSTijl Coosemans 	*(volatile uint8_t *)addr = v;
157937a05baSJustin Hibbits 	__io_aw();
158642909fdSTijl Coosemans }
159642909fdSTijl Coosemans #define	writeb(v, addr)		writeb(v, addr)
16086845417SHans Petter Selasky 
16186845417SHans Petter Selasky #undef readw
16286845417SHans Petter Selasky static inline uint16_t
16386845417SHans Petter Selasky readw(const volatile void *addr)
16486845417SHans Petter Selasky {
165642909fdSTijl Coosemans 	uint16_t v;
166642909fdSTijl Coosemans 
167937a05baSJustin Hibbits 	__io_br();
168937a05baSJustin Hibbits 	v = le16toh(__raw_readw(addr));
169937a05baSJustin Hibbits 	__io_ar();
170642909fdSTijl Coosemans 	return (v);
17186845417SHans Petter Selasky }
172642909fdSTijl Coosemans #define	readw(addr)		readw(addr)
173642909fdSTijl Coosemans 
174642909fdSTijl Coosemans #undef writew
175642909fdSTijl Coosemans static inline void
176642909fdSTijl Coosemans writew(uint16_t v, volatile void *addr)
177642909fdSTijl Coosemans {
178937a05baSJustin Hibbits 	__io_bw();
179937a05baSJustin Hibbits 	__raw_writew(htole16(v), addr);
180937a05baSJustin Hibbits 	__io_aw();
181642909fdSTijl Coosemans }
182642909fdSTijl Coosemans #define	writew(v, addr)		writew(v, addr)
18386845417SHans Petter Selasky 
18486845417SHans Petter Selasky #undef readl
18586845417SHans Petter Selasky static inline uint32_t
18686845417SHans Petter Selasky readl(const volatile void *addr)
18786845417SHans Petter Selasky {
188642909fdSTijl Coosemans 	uint32_t v;
189642909fdSTijl Coosemans 
190937a05baSJustin Hibbits 	__io_br();
191937a05baSJustin Hibbits 	v = le32toh(__raw_readl(addr));
192937a05baSJustin Hibbits 	__io_ar();
193642909fdSTijl Coosemans 	return (v);
19486845417SHans Petter Selasky }
195642909fdSTijl Coosemans #define	readl(addr)		readl(addr)
196642909fdSTijl Coosemans 
197642909fdSTijl Coosemans #undef writel
198642909fdSTijl Coosemans static inline void
199642909fdSTijl Coosemans writel(uint32_t v, volatile void *addr)
200642909fdSTijl Coosemans {
201937a05baSJustin Hibbits 	__io_bw();
202937a05baSJustin Hibbits 	__raw_writel(htole32(v), addr);
203937a05baSJustin Hibbits 	__io_aw();
204642909fdSTijl Coosemans }
205642909fdSTijl Coosemans #define	writel(v, addr)		writel(v, addr)
206642909fdSTijl Coosemans 
207642909fdSTijl Coosemans #undef readq
208642909fdSTijl Coosemans #undef writeq
209642909fdSTijl Coosemans #ifdef __LP64__
210642909fdSTijl Coosemans static inline uint64_t
211642909fdSTijl Coosemans readq(const volatile void *addr)
212642909fdSTijl Coosemans {
213642909fdSTijl Coosemans 	uint64_t v;
214642909fdSTijl Coosemans 
215937a05baSJustin Hibbits 	__io_br();
216937a05baSJustin Hibbits 	v = le64toh(__raw_readq(addr));
217937a05baSJustin Hibbits 	__io_ar();
218642909fdSTijl Coosemans 	return (v);
219642909fdSTijl Coosemans }
220642909fdSTijl Coosemans #define	readq(addr)		readq(addr)
221642909fdSTijl Coosemans 
222642909fdSTijl Coosemans static inline void
223642909fdSTijl Coosemans writeq(uint64_t v, volatile void *addr)
224642909fdSTijl Coosemans {
225937a05baSJustin Hibbits 	__io_bw();
226937a05baSJustin Hibbits 	__raw_writeq(htole64(v), addr);
227937a05baSJustin Hibbits 	__io_aw();
228642909fdSTijl Coosemans }
229642909fdSTijl Coosemans #define	writeq(v, addr)		writeq(v, addr)
230642909fdSTijl Coosemans #endif
231642909fdSTijl Coosemans 
232642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically without memory barriers. */
233642909fdSTijl Coosemans 
234642909fdSTijl Coosemans #undef readb_relaxed
235642909fdSTijl Coosemans static inline uint8_t
236642909fdSTijl Coosemans readb_relaxed(const volatile void *addr)
237642909fdSTijl Coosemans {
238937a05baSJustin Hibbits 	return (__raw_readb(addr));
239642909fdSTijl Coosemans }
240642909fdSTijl Coosemans #define	readb_relaxed(addr)	readb_relaxed(addr)
241642909fdSTijl Coosemans 
242642909fdSTijl Coosemans #undef writeb_relaxed
243642909fdSTijl Coosemans static inline void
244642909fdSTijl Coosemans writeb_relaxed(uint8_t v, volatile void *addr)
245642909fdSTijl Coosemans {
246937a05baSJustin Hibbits 	__raw_writeb(v, addr);
247642909fdSTijl Coosemans }
248642909fdSTijl Coosemans #define	writeb_relaxed(v, addr)	writeb_relaxed(v, addr)
249642909fdSTijl Coosemans 
250642909fdSTijl Coosemans #undef readw_relaxed
251642909fdSTijl Coosemans static inline uint16_t
252642909fdSTijl Coosemans readw_relaxed(const volatile void *addr)
253642909fdSTijl Coosemans {
254937a05baSJustin Hibbits 	return (le16toh(__raw_readw(addr)));
255642909fdSTijl Coosemans }
256642909fdSTijl Coosemans #define	readw_relaxed(addr)	readw_relaxed(addr)
257642909fdSTijl Coosemans 
258642909fdSTijl Coosemans #undef writew_relaxed
259642909fdSTijl Coosemans static inline void
260642909fdSTijl Coosemans writew_relaxed(uint16_t v, volatile void *addr)
261642909fdSTijl Coosemans {
262937a05baSJustin Hibbits 	__raw_writew(htole16(v), addr);
263642909fdSTijl Coosemans }
264642909fdSTijl Coosemans #define	writew_relaxed(v, addr)	writew_relaxed(v, addr)
265642909fdSTijl Coosemans 
266642909fdSTijl Coosemans #undef readl_relaxed
267642909fdSTijl Coosemans static inline uint32_t
268642909fdSTijl Coosemans readl_relaxed(const volatile void *addr)
269642909fdSTijl Coosemans {
270937a05baSJustin Hibbits 	return (le32toh(__raw_readl(addr)));
271642909fdSTijl Coosemans }
272642909fdSTijl Coosemans #define	readl_relaxed(addr)	readl_relaxed(addr)
273642909fdSTijl Coosemans 
274642909fdSTijl Coosemans #undef writel_relaxed
275642909fdSTijl Coosemans static inline void
276642909fdSTijl Coosemans writel_relaxed(uint32_t v, volatile void *addr)
277642909fdSTijl Coosemans {
278937a05baSJustin Hibbits 	__raw_writel(htole32(v), addr);
279642909fdSTijl Coosemans }
280642909fdSTijl Coosemans #define	writel_relaxed(v, addr)	writel_relaxed(v, addr)
281642909fdSTijl Coosemans 
282642909fdSTijl Coosemans #undef readq_relaxed
283642909fdSTijl Coosemans #undef writeq_relaxed
284642909fdSTijl Coosemans #ifdef __LP64__
285642909fdSTijl Coosemans static inline uint64_t
286642909fdSTijl Coosemans readq_relaxed(const volatile void *addr)
287642909fdSTijl Coosemans {
288937a05baSJustin Hibbits 	return (le64toh(__raw_readq(addr)));
289642909fdSTijl Coosemans }
290642909fdSTijl Coosemans #define	readq_relaxed(addr)	readq_relaxed(addr)
291642909fdSTijl Coosemans 
292642909fdSTijl Coosemans static inline void
293642909fdSTijl Coosemans writeq_relaxed(uint64_t v, volatile void *addr)
294642909fdSTijl Coosemans {
295937a05baSJustin Hibbits 	__raw_writeq(htole64(v), addr);
296642909fdSTijl Coosemans }
297642909fdSTijl Coosemans #define	writeq_relaxed(v, addr)	writeq_relaxed(v, addr)
298642909fdSTijl Coosemans #endif
299642909fdSTijl Coosemans 
300642909fdSTijl Coosemans /* XXX On Linux ioread and iowrite handle both MMIO and port IO. */
301642909fdSTijl Coosemans 
302642909fdSTijl Coosemans #undef ioread8
303642909fdSTijl Coosemans static inline uint8_t
304642909fdSTijl Coosemans ioread8(const volatile void *addr)
305642909fdSTijl Coosemans {
306642909fdSTijl Coosemans 	return (readb(addr));
307642909fdSTijl Coosemans }
308642909fdSTijl Coosemans #define	ioread8(addr)		ioread8(addr)
309642909fdSTijl Coosemans 
310642909fdSTijl Coosemans #undef ioread16
311642909fdSTijl Coosemans static inline uint16_t
312642909fdSTijl Coosemans ioread16(const volatile void *addr)
313642909fdSTijl Coosemans {
314642909fdSTijl Coosemans 	return (readw(addr));
315642909fdSTijl Coosemans }
316642909fdSTijl Coosemans #define	ioread16(addr)		ioread16(addr)
317642909fdSTijl Coosemans 
318642909fdSTijl Coosemans #undef ioread16be
319642909fdSTijl Coosemans static inline uint16_t
320642909fdSTijl Coosemans ioread16be(const volatile void *addr)
321642909fdSTijl Coosemans {
322937a05baSJustin Hibbits 	uint16_t v;
323937a05baSJustin Hibbits 
324937a05baSJustin Hibbits 	__io_br();
325937a05baSJustin Hibbits 	v = (be16toh(__raw_readw(addr)));
326937a05baSJustin Hibbits 	__io_ar();
327937a05baSJustin Hibbits 
328937a05baSJustin Hibbits 	return (v);
329642909fdSTijl Coosemans }
330642909fdSTijl Coosemans #define	ioread16be(addr)	ioread16be(addr)
331642909fdSTijl Coosemans 
332642909fdSTijl Coosemans #undef ioread32
333642909fdSTijl Coosemans static inline uint32_t
334642909fdSTijl Coosemans ioread32(const volatile void *addr)
335642909fdSTijl Coosemans {
336642909fdSTijl Coosemans 	return (readl(addr));
337642909fdSTijl Coosemans }
338642909fdSTijl Coosemans #define	ioread32(addr)		ioread32(addr)
339642909fdSTijl Coosemans 
340642909fdSTijl Coosemans #undef ioread32be
341642909fdSTijl Coosemans static inline uint32_t
342642909fdSTijl Coosemans ioread32be(const volatile void *addr)
343642909fdSTijl Coosemans {
344937a05baSJustin Hibbits 	uint32_t v;
345937a05baSJustin Hibbits 
346937a05baSJustin Hibbits 	__io_br();
347937a05baSJustin Hibbits 	v = (be32toh(__raw_readl(addr)));
348937a05baSJustin Hibbits 	__io_ar();
349937a05baSJustin Hibbits 
350937a05baSJustin Hibbits 	return (v);
351642909fdSTijl Coosemans }
352642909fdSTijl Coosemans #define	ioread32be(addr)	ioread32be(addr)
353642909fdSTijl Coosemans 
354642909fdSTijl Coosemans #undef iowrite8
355642909fdSTijl Coosemans static inline void
356642909fdSTijl Coosemans iowrite8(uint8_t v, volatile void *addr)
357642909fdSTijl Coosemans {
358642909fdSTijl Coosemans 	writeb(v, addr);
359642909fdSTijl Coosemans }
360642909fdSTijl Coosemans #define	iowrite8(v, addr)	iowrite8(v, addr)
361642909fdSTijl Coosemans 
362642909fdSTijl Coosemans #undef iowrite16
363642909fdSTijl Coosemans static inline void
364642909fdSTijl Coosemans iowrite16(uint16_t v, volatile void *addr)
365642909fdSTijl Coosemans {
366642909fdSTijl Coosemans 	writew(v, addr);
367642909fdSTijl Coosemans }
368642909fdSTijl Coosemans #define	iowrite16	iowrite16
369642909fdSTijl Coosemans 
370642909fdSTijl Coosemans #undef iowrite32
371642909fdSTijl Coosemans static inline void
372642909fdSTijl Coosemans iowrite32(uint32_t v, volatile void *addr)
373642909fdSTijl Coosemans {
374642909fdSTijl Coosemans 	writel(v, addr);
375642909fdSTijl Coosemans }
376642909fdSTijl Coosemans #define	iowrite32(v, addr)	iowrite32(v, addr)
377642909fdSTijl Coosemans 
378642909fdSTijl Coosemans #undef iowrite32be
379642909fdSTijl Coosemans static inline void
380642909fdSTijl Coosemans iowrite32be(uint32_t v, volatile void *addr)
381642909fdSTijl Coosemans {
382937a05baSJustin Hibbits 	__io_bw();
383937a05baSJustin Hibbits 	__raw_writel(htobe32(v), addr);
384937a05baSJustin Hibbits 	__io_aw();
385642909fdSTijl Coosemans }
386642909fdSTijl Coosemans #define	iowrite32be(v, addr)	iowrite32be(v, addr)
38786845417SHans Petter Selasky 
38886845417SHans Petter Selasky #if defined(__i386__) || defined(__amd64__)
38994a201beSHans Petter Selasky static inline void
39094a201beSHans Petter Selasky _outb(u_char data, u_int port)
39194a201beSHans Petter Selasky {
39294a201beSHans Petter Selasky 	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
39394a201beSHans Petter Selasky }
39494a201beSHans Petter Selasky #endif
39594a201beSHans Petter Selasky 
39660d962e0SJessica Clarke #if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv)
3978d59ecb2SHans Petter Selasky void *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr);
39886845417SHans Petter Selasky #else
39934dae08eSJohn Baldwin static __inline void *
40034dae08eSJohn Baldwin _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr)
40134dae08eSJohn Baldwin {
40234dae08eSJohn Baldwin 	return (NULL);
40334dae08eSJohn Baldwin }
40486845417SHans Petter Selasky #endif
40586845417SHans Petter Selasky 
4064d83500fSHans Petter Selasky #ifdef VM_MEMATTR_DEVICE
4074d83500fSHans Petter Selasky #define	ioremap_nocache(addr, size)					\
4084d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4094d83500fSHans Petter Selasky #define	ioremap_wt(addr, size)						\
4104d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4114d83500fSHans Petter Selasky #define	ioremap(addr, size)						\
4124d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
4134d83500fSHans Petter Selasky #else
4148d59ecb2SHans Petter Selasky #define	ioremap_nocache(addr, size)					\
4158d59ecb2SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
416f2dbb750SHans Petter Selasky #define	ioremap_wt(addr, size)						\
417f2dbb750SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH)
41886845417SHans Petter Selasky #define	ioremap(addr, size)						\
41986845417SHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
4204d83500fSHans Petter Selasky #endif
4218167c92fSJessica Clarke #ifdef VM_MEMATTR_WRITE_COMBINING
4224d83500fSHans Petter Selasky #define	ioremap_wc(addr, size)						\
4234d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING)
4248167c92fSJessica Clarke #else
4258167c92fSJessica Clarke #define	ioremap_wc(addr, size)	ioremap_nocache(addr, size)
4268167c92fSJessica Clarke #endif
4274d83500fSHans Petter Selasky #define	ioremap_wb(addr, size)						\
4284d83500fSHans Petter Selasky     _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK)
4298d59ecb2SHans Petter Selasky void iounmap(void *addr);
4308d59ecb2SHans Petter Selasky 
4318d59ecb2SHans Petter Selasky #define	memset_io(a, b, c)	memset((a), (b), (c))
4328d59ecb2SHans Petter Selasky #define	memcpy_fromio(a, b, c)	memcpy((a), (b), (c))
4338d59ecb2SHans Petter Selasky #define	memcpy_toio(a, b, c)	memcpy((a), (b), (c))
4348d59ecb2SHans Petter Selasky 
4358d59ecb2SHans Petter Selasky static inline void
43686364964SKevin Lo __iowrite32_copy(void *to, void *from, size_t count)
43786364964SKevin Lo {
43886364964SKevin Lo 	uint32_t *src;
43986364964SKevin Lo 	uint32_t *dst;
44086364964SKevin Lo 	int i;
44186364964SKevin Lo 
44286364964SKevin Lo 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
44386364964SKevin Lo 		__raw_writel(*src, dst);
44486364964SKevin Lo }
44586364964SKevin Lo 
44686364964SKevin Lo static inline void
4478d59ecb2SHans Petter Selasky __iowrite64_copy(void *to, void *from, size_t count)
4488d59ecb2SHans Petter Selasky {
4498d59ecb2SHans Petter Selasky #ifdef __LP64__
4508d59ecb2SHans Petter Selasky 	uint64_t *src;
4518d59ecb2SHans Petter Selasky 	uint64_t *dst;
4528d59ecb2SHans Petter Selasky 	int i;
4538d59ecb2SHans Petter Selasky 
4548d59ecb2SHans Petter Selasky 	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
4558d59ecb2SHans Petter Selasky 		__raw_writeq(*src, dst);
4568d59ecb2SHans Petter Selasky #else
45786364964SKevin Lo 	__iowrite32_copy(to, from, count * 2);
4588d59ecb2SHans Petter Selasky #endif
4598d59ecb2SHans Petter Selasky }
4608d59ecb2SHans Petter Selasky 
461684a5fefSHans Petter Selasky enum {
462684a5fefSHans Petter Selasky 	MEMREMAP_WB = 1 << 0,
463684a5fefSHans Petter Selasky 	MEMREMAP_WT = 1 << 1,
464684a5fefSHans Petter Selasky 	MEMREMAP_WC = 1 << 2,
465684a5fefSHans Petter Selasky };
466684a5fefSHans Petter Selasky 
467684a5fefSHans Petter Selasky static inline void *
468684a5fefSHans Petter Selasky memremap(resource_size_t offset, size_t size, unsigned long flags)
469684a5fefSHans Petter Selasky {
470684a5fefSHans Petter Selasky 	void *addr = NULL;
471684a5fefSHans Petter Selasky 
472684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WB) &&
473684a5fefSHans Petter Selasky 	    (addr = ioremap_wb(offset, size)) != NULL)
474684a5fefSHans Petter Selasky 		goto done;
475684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WT) &&
476f2dbb750SHans Petter Selasky 	    (addr = ioremap_wt(offset, size)) != NULL)
477684a5fefSHans Petter Selasky 		goto done;
478684a5fefSHans Petter Selasky 	if ((flags & MEMREMAP_WC) &&
479684a5fefSHans Petter Selasky 	    (addr = ioremap_wc(offset, size)) != NULL)
480684a5fefSHans Petter Selasky 		goto done;
481684a5fefSHans Petter Selasky done:
482684a5fefSHans Petter Selasky 	return (addr);
483684a5fefSHans Petter Selasky }
484684a5fefSHans Petter Selasky 
485684a5fefSHans Petter Selasky static inline void
486684a5fefSHans Petter Selasky memunmap(void *addr)
487684a5fefSHans Petter Selasky {
488684a5fefSHans Petter Selasky 	/* XXX May need to check if this is RAM */
489684a5fefSHans Petter Selasky 	iounmap(addr);
490684a5fefSHans Petter Selasky }
4918d59ecb2SHans Petter Selasky 
49298b12978SVladimir Kondratyev #define	__MTRR_ID_BASE	1
49398b12978SVladimir Kondratyev int lkpi_arch_phys_wc_add(unsigned long, unsigned long);
49498b12978SVladimir Kondratyev void lkpi_arch_phys_wc_del(int);
49598b12978SVladimir Kondratyev #define	arch_phys_wc_add(...)	lkpi_arch_phys_wc_add(__VA_ARGS__)
49698b12978SVladimir Kondratyev #define	arch_phys_wc_del(...)	lkpi_arch_phys_wc_del(__VA_ARGS__)
49798b12978SVladimir Kondratyev #define	arch_phys_wc_index(x)	\
49898b12978SVladimir Kondratyev 	(((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE))
49998b12978SVladimir Kondratyev 
500789dbdbbSEmmanuel Vadot #if defined(__amd64__) || defined(__i386__) || defined(__aarch64__) || defined(__powerpc__) || defined(__riscv)
501789dbdbbSEmmanuel Vadot static inline int
502789dbdbbSEmmanuel Vadot arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
503789dbdbbSEmmanuel Vadot {
504789dbdbbSEmmanuel Vadot 
505789dbdbbSEmmanuel Vadot 	return (set_memory_wc(start, size >> PAGE_SHIFT));
506789dbdbbSEmmanuel Vadot }
507789dbdbbSEmmanuel Vadot 
508789dbdbbSEmmanuel Vadot static inline void
509789dbdbbSEmmanuel Vadot arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
510789dbdbbSEmmanuel Vadot {
511789dbdbbSEmmanuel Vadot 	set_memory_wb(start, size >> PAGE_SHIFT);
512789dbdbbSEmmanuel Vadot }
513789dbdbbSEmmanuel Vadot #endif
514789dbdbbSEmmanuel Vadot 
515307f78f3SVladimir Kondratyev #endif	/* _LINUXKPI_LINUX_IO_H_ */
516