io.h revision 330857
1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5290706Shselasky * Copyright (c) 2013-2015 Mellanox Technologies, Ltd.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * Redistribution and use in source and binary forms, with or without
9219820Sjeff * modification, are permitted provided that the following conditions
10219820Sjeff * are met:
11219820Sjeff * 1. Redistributions of source code must retain the above copyright
12219820Sjeff *    notice unmodified, this list of conditions, and the following
13219820Sjeff *    disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28289644Shselasky *
29289644Shselasky * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/io.h 330857 2018-03-13 16:25:28Z hselasky $
30219820Sjeff */
31219820Sjeff#ifndef	_LINUX_IO_H_
32219820Sjeff#define	_LINUX_IO_H_
33219820Sjeff
34219820Sjeff#include <machine/vm.h>
35277396Shselasky#include <sys/endian.h>
36290335Shselasky#include <sys/types.h>
37219820Sjeff
38299364Shselasky#include <linux/compiler.h>
39328653Shselasky#include <linux/types.h>
40299364Shselasky
41219820Sjeffstatic inline uint32_t
42219820Sjeff__raw_readl(const volatile void *addr)
43219820Sjeff{
44219820Sjeff	return *(const volatile uint32_t *)addr;
45219820Sjeff}
46219820Sjeff
47219820Sjeffstatic inline void
48219820Sjeff__raw_writel(uint32_t b, volatile void *addr)
49219820Sjeff{
50219820Sjeff	*(volatile uint32_t *)addr = b;
51219820Sjeff}
52219820Sjeff
53219820Sjeffstatic inline uint64_t
54219820Sjeff__raw_readq(const volatile void *addr)
55219820Sjeff{
56219820Sjeff	return *(const volatile uint64_t *)addr;
57219820Sjeff}
58219820Sjeff
59219820Sjeffstatic inline void
60219820Sjeff__raw_writeq(uint64_t b, volatile void *addr)
61219820Sjeff{
62219820Sjeff	*(volatile uint64_t *)addr = b;
63219820Sjeff}
64219820Sjeff
65219820Sjeff/*
66219820Sjeff * XXX This is all x86 specific.  It should be bus space access.
67219820Sjeff */
68299364Shselasky#define	mmiowb()	barrier()
69219820Sjeff
70219820Sjeff#undef writel
71219820Sjeffstatic inline void
72219820Sjeffwritel(uint32_t b, void *addr)
73219820Sjeff{
74219820Sjeff        *(volatile uint32_t *)addr = b;
75219820Sjeff}
76219820Sjeff
77330857Shselasky#undef writel_relaxed
78330857Shselaskystatic inline void
79330857Shselaskywritel_relaxed(uint32_t b, void *addr)
80330857Shselasky{
81330857Shselasky	*(volatile uint32_t *)addr = b;
82330857Shselasky}
83330857Shselasky
84219820Sjeff#undef writeq
85219820Sjeffstatic inline void
86219820Sjeffwriteq(uint64_t b, void *addr)
87219820Sjeff{
88219820Sjeff        *(volatile uint64_t *)addr = b;
89219820Sjeff}
90219820Sjeff
91219820Sjeff#undef writeb
92219820Sjeffstatic inline void
93219820Sjeffwriteb(uint8_t b, void *addr)
94219820Sjeff{
95219820Sjeff        *(volatile uint8_t *)addr = b;
96219820Sjeff}
97219820Sjeff
98219820Sjeff#undef writew
99219820Sjeffstatic inline void
100219820Sjeffwritew(uint16_t b, void *addr)
101219820Sjeff{
102219820Sjeff        *(volatile uint16_t *)addr = b;
103219820Sjeff}
104219820Sjeff
105299364Shselasky#undef ioread8
106299364Shselaskystatic inline uint8_t
107299364Shselaskyioread8(const volatile void *addr)
108299364Shselasky{
109299364Shselasky	return *(const volatile uint8_t *)addr;
110299364Shselasky}
111299364Shselasky
112299364Shselasky#undef ioread16
113299364Shselaskystatic inline uint16_t
114299364Shselaskyioread16(const volatile void *addr)
115299364Shselasky{
116299364Shselasky	return *(const volatile uint16_t *)addr;
117299364Shselasky}
118299364Shselasky
119328653Shselasky#undef ioread16be
120328653Shselaskystatic inline uint16_t
121328653Shselaskyioread16be(const volatile void *addr)
122328653Shselasky{
123328653Shselasky	return be16toh(*(const volatile uint16_t *)addr);
124328653Shselasky}
125328653Shselasky
126299364Shselasky#undef ioread32
127299364Shselaskystatic inline uint32_t
128299364Shselaskyioread32(const volatile void *addr)
129299364Shselasky{
130299364Shselasky	return *(const volatile uint32_t *)addr;
131299364Shselasky}
132299364Shselasky
133277396Shselasky#undef ioread32be
134277396Shselaskystatic inline uint32_t
135277396Shselaskyioread32be(const volatile void *addr)
136277396Shselasky{
137277396Shselasky	return be32toh(*(const volatile uint32_t *)addr);
138277396Shselasky}
139277396Shselasky
140299364Shselasky#undef iowrite8
141299364Shselaskystatic inline void
142299364Shselaskyiowrite8(uint8_t v, volatile void *addr)
143299364Shselasky{
144299364Shselasky	*(volatile uint8_t *)addr = v;
145299364Shselasky}
146299364Shselasky
147299364Shselasky#undef iowrite16
148299364Shselaskystatic inline void
149299364Shselaskyiowrite16(uint16_t v, volatile void *addr)
150299364Shselasky{
151299364Shselasky	*(volatile uint16_t *)addr = v;
152299364Shselasky}
153299364Shselasky
154299364Shselasky#undef iowrite32
155299364Shselaskystatic inline void
156299364Shselaskyiowrite32(uint32_t v, volatile void *addr)
157299364Shselasky{
158299364Shselasky	*(volatile uint32_t *)addr = v;
159299364Shselasky}
160299364Shselasky
161277396Shselasky#undef iowrite32be
162277396Shselaskystatic inline void
163277396Shselaskyiowrite32be(uint32_t v, volatile void *addr)
164277396Shselasky{
165277396Shselasky	*(volatile uint32_t *)addr = htobe32(v);
166277396Shselasky}
167277396Shselasky
168290706Shselasky#undef readb
169290706Shselaskystatic inline uint8_t
170290706Shselaskyreadb(const volatile void *addr)
171290706Shselasky{
172290706Shselasky	return *(const volatile uint8_t *)addr;
173290706Shselasky}
174290706Shselasky
175290706Shselasky#undef readw
176290706Shselaskystatic inline uint16_t
177290706Shselaskyreadw(const volatile void *addr)
178290706Shselasky{
179290706Shselasky	return *(const volatile uint16_t *)addr;
180290706Shselasky}
181290706Shselasky
182290706Shselasky#undef readl
183290706Shselaskystatic inline uint32_t
184290706Shselaskyreadl(const volatile void *addr)
185290706Shselasky{
186290706Shselasky	return *(const volatile uint32_t *)addr;
187290706Shselasky}
188290706Shselasky
189290706Shselasky#if defined(__i386__) || defined(__amd64__)
190300494Shselaskystatic inline void
191300494Shselasky_outb(u_char data, u_int port)
192300494Shselasky{
193300494Shselasky	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
194300494Shselasky}
195300494Shselasky#endif
196300494Shselasky
197328653Shselasky#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__)
198219820Sjeffvoid *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr);
199290706Shselasky#else
200290706Shselasky#define	_ioremap_attr(...) NULL
201290706Shselasky#endif
202290706Shselasky
203219820Sjeff#define	ioremap_nocache(addr, size)					\
204233547Sjhb    _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
205219820Sjeff#define	ioremap_wc(addr, size)						\
206219820Sjeff    _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING)
207299364Shselasky#define	ioremap_wb(addr, size)						\
208299364Shselasky    _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK)
209299379Shselasky#define	ioremap_wt(addr, size)						\
210299379Shselasky    _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH)
211290706Shselasky#define	ioremap(addr, size)						\
212290706Shselasky    _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
213219820Sjeffvoid iounmap(void *addr);
214219820Sjeff
215219820Sjeff#define	memset_io(a, b, c)	memset((a), (b), (c))
216219820Sjeff#define	memcpy_fromio(a, b, c)	memcpy((a), (b), (c))
217219820Sjeff#define	memcpy_toio(a, b, c)	memcpy((a), (b), (c))
218219820Sjeff
219219820Sjeffstatic inline void
220300594Skevlo__iowrite32_copy(void *to, void *from, size_t count)
221300594Skevlo{
222300594Skevlo	uint32_t *src;
223300594Skevlo	uint32_t *dst;
224300594Skevlo	int i;
225300594Skevlo
226300594Skevlo	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
227300594Skevlo		__raw_writel(*src, dst);
228300594Skevlo}
229300594Skevlo
230300594Skevlostatic inline void
231219820Sjeff__iowrite64_copy(void *to, void *from, size_t count)
232219820Sjeff{
233219820Sjeff#ifdef __LP64__
234219820Sjeff	uint64_t *src;
235219820Sjeff	uint64_t *dst;
236219820Sjeff	int i;
237219820Sjeff
238219820Sjeff	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
239219820Sjeff		__raw_writeq(*src, dst);
240219820Sjeff#else
241300594Skevlo	__iowrite32_copy(to, from, count * 2);
242219820Sjeff#endif
243219820Sjeff}
244219820Sjeff
245299364Shselaskyenum {
246299364Shselasky	MEMREMAP_WB = 1 << 0,
247299364Shselasky	MEMREMAP_WT = 1 << 1,
248299364Shselasky	MEMREMAP_WC = 1 << 2,
249299364Shselasky};
250219820Sjeff
251299364Shselaskystatic inline void *
252299364Shselaskymemremap(resource_size_t offset, size_t size, unsigned long flags)
253299364Shselasky{
254299364Shselasky	void *addr = NULL;
255299364Shselasky
256299364Shselasky	if ((flags & MEMREMAP_WB) &&
257299364Shselasky	    (addr = ioremap_wb(offset, size)) != NULL)
258299364Shselasky		goto done;
259299364Shselasky	if ((flags & MEMREMAP_WT) &&
260299379Shselasky	    (addr = ioremap_wt(offset, size)) != NULL)
261299364Shselasky		goto done;
262299364Shselasky	if ((flags & MEMREMAP_WC) &&
263299364Shselasky	    (addr = ioremap_wc(offset, size)) != NULL)
264299364Shselasky		goto done;
265299364Shselaskydone:
266299364Shselasky	return (addr);
267299364Shselasky}
268299364Shselasky
269299364Shselaskystatic inline void
270299364Shselaskymemunmap(void *addr)
271299364Shselasky{
272299364Shselasky	/* XXX May need to check if this is RAM */
273299364Shselasky	iounmap(addr);
274299364Shselasky}
275299364Shselasky
276219820Sjeff#endif	/* _LINUX_IO_H_ */
277