io.h revision 299364
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: head/sys/compat/linuxkpi/common/include/linux/io.h 299364 2016-05-10 12:04:57Z 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>
39299364Shselasky
40219820Sjeffstatic inline uint32_t
41219820Sjeff__raw_readl(const volatile void *addr)
42219820Sjeff{
43219820Sjeff	return *(const volatile uint32_t *)addr;
44219820Sjeff}
45219820Sjeff
46219820Sjeffstatic inline void
47219820Sjeff__raw_writel(uint32_t b, volatile void *addr)
48219820Sjeff{
49219820Sjeff	*(volatile uint32_t *)addr = b;
50219820Sjeff}
51219820Sjeff
52219820Sjeffstatic inline uint64_t
53219820Sjeff__raw_readq(const volatile void *addr)
54219820Sjeff{
55219820Sjeff	return *(const volatile uint64_t *)addr;
56219820Sjeff}
57219820Sjeff
58219820Sjeffstatic inline void
59219820Sjeff__raw_writeq(uint64_t b, volatile void *addr)
60219820Sjeff{
61219820Sjeff	*(volatile uint64_t *)addr = b;
62219820Sjeff}
63219820Sjeff
64219820Sjeff/*
65219820Sjeff * XXX This is all x86 specific.  It should be bus space access.
66219820Sjeff */
67299364Shselasky#define	mmiowb()	barrier()
68219820Sjeff
69219820Sjeff#undef writel
70219820Sjeffstatic inline void
71219820Sjeffwritel(uint32_t b, void *addr)
72219820Sjeff{
73219820Sjeff        *(volatile uint32_t *)addr = b;
74219820Sjeff}
75219820Sjeff
76219820Sjeff#undef writeq
77219820Sjeffstatic inline void
78219820Sjeffwriteq(uint64_t b, void *addr)
79219820Sjeff{
80219820Sjeff        *(volatile uint64_t *)addr = b;
81219820Sjeff}
82219820Sjeff
83219820Sjeff#undef writeb
84219820Sjeffstatic inline void
85219820Sjeffwriteb(uint8_t b, void *addr)
86219820Sjeff{
87219820Sjeff        *(volatile uint8_t *)addr = b;
88219820Sjeff}
89219820Sjeff
90219820Sjeff#undef writew
91219820Sjeffstatic inline void
92219820Sjeffwritew(uint16_t b, void *addr)
93219820Sjeff{
94219820Sjeff        *(volatile uint16_t *)addr = b;
95219820Sjeff}
96219820Sjeff
97299364Shselasky#undef ioread8
98299364Shselaskystatic inline uint8_t
99299364Shselaskyioread8(const volatile void *addr)
100299364Shselasky{
101299364Shselasky	return *(const volatile uint8_t *)addr;
102299364Shselasky}
103299364Shselasky
104299364Shselasky#undef ioread16
105299364Shselaskystatic inline uint16_t
106299364Shselaskyioread16(const volatile void *addr)
107299364Shselasky{
108299364Shselasky	return *(const volatile uint16_t *)addr;
109299364Shselasky}
110299364Shselasky
111299364Shselasky#undef ioread32
112299364Shselaskystatic inline uint32_t
113299364Shselaskyioread32(const volatile void *addr)
114299364Shselasky{
115299364Shselasky	return *(const volatile uint32_t *)addr;
116299364Shselasky}
117299364Shselasky
118277396Shselasky#undef ioread32be
119277396Shselaskystatic inline uint32_t
120277396Shselaskyioread32be(const volatile void *addr)
121277396Shselasky{
122277396Shselasky	return be32toh(*(const volatile uint32_t *)addr);
123277396Shselasky}
124277396Shselasky
125299364Shselasky#undef iowrite8
126299364Shselaskystatic inline void
127299364Shselaskyiowrite8(uint8_t v, volatile void *addr)
128299364Shselasky{
129299364Shselasky	*(volatile uint8_t *)addr = v;
130299364Shselasky}
131299364Shselasky
132299364Shselasky#undef iowrite16
133299364Shselaskystatic inline void
134299364Shselaskyiowrite16(uint16_t v, volatile void *addr)
135299364Shselasky{
136299364Shselasky	*(volatile uint16_t *)addr = v;
137299364Shselasky}
138299364Shselasky
139299364Shselasky#undef iowrite32
140299364Shselaskystatic inline void
141299364Shselaskyiowrite32(uint32_t v, volatile void *addr)
142299364Shselasky{
143299364Shselasky	*(volatile uint32_t *)addr = v;
144299364Shselasky}
145299364Shselasky
146277396Shselasky#undef iowrite32be
147277396Shselaskystatic inline void
148277396Shselaskyiowrite32be(uint32_t v, volatile void *addr)
149277396Shselasky{
150277396Shselasky	*(volatile uint32_t *)addr = htobe32(v);
151277396Shselasky}
152277396Shselasky
153290706Shselasky#undef readb
154290706Shselaskystatic inline uint8_t
155290706Shselaskyreadb(const volatile void *addr)
156290706Shselasky{
157290706Shselasky	return *(const volatile uint8_t *)addr;
158290706Shselasky}
159290706Shselasky
160290706Shselasky#undef readw
161290706Shselaskystatic inline uint16_t
162290706Shselaskyreadw(const volatile void *addr)
163290706Shselasky{
164290706Shselasky	return *(const volatile uint16_t *)addr;
165290706Shselasky}
166290706Shselasky
167290706Shselasky#undef readl
168290706Shselaskystatic inline uint32_t
169290706Shselaskyreadl(const volatile void *addr)
170290706Shselasky{
171290706Shselasky	return *(const volatile uint32_t *)addr;
172290706Shselasky}
173290706Shselasky
174290706Shselasky#if defined(__i386__) || defined(__amd64__)
175219820Sjeffvoid *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr);
176290706Shselasky#else
177290706Shselasky#define	_ioremap_attr(...) NULL
178290706Shselasky#endif
179290706Shselasky
180219820Sjeff#define	ioremap_nocache(addr, size)					\
181233547Sjhb    _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
182219820Sjeff#define	ioremap_wc(addr, size)						\
183219820Sjeff    _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING)
184299364Shselasky#define	ioremap_wb(addr, size)						\
185299364Shselasky    _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK)
186290706Shselasky#define	ioremap(addr, size)						\
187290706Shselasky    _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE)
188219820Sjeffvoid iounmap(void *addr);
189219820Sjeff
190219820Sjeff#define	memset_io(a, b, c)	memset((a), (b), (c))
191219820Sjeff#define	memcpy_fromio(a, b, c)	memcpy((a), (b), (c))
192219820Sjeff#define	memcpy_toio(a, b, c)	memcpy((a), (b), (c))
193219820Sjeff
194219820Sjeffstatic inline void
195219820Sjeff__iowrite64_copy(void *to, void *from, size_t count)
196219820Sjeff{
197219820Sjeff#ifdef __LP64__
198219820Sjeff	uint64_t *src;
199219820Sjeff	uint64_t *dst;
200219820Sjeff	int i;
201219820Sjeff
202219820Sjeff	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
203219820Sjeff		__raw_writeq(*src, dst);
204219820Sjeff#else
205219820Sjeff	uint32_t *src;
206219820Sjeff	uint32_t *dst;
207219820Sjeff	int i;
208219820Sjeff
209219820Sjeff	count *= 2;
210219820Sjeff	for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
211219820Sjeff		__raw_writel(*src, dst);
212219820Sjeff#endif
213219820Sjeff}
214219820Sjeff
215299364Shselaskyenum {
216299364Shselasky	MEMREMAP_WB = 1 << 0,
217299364Shselasky	MEMREMAP_WT = 1 << 1,
218299364Shselasky	MEMREMAP_WC = 1 << 2,
219299364Shselasky};
220219820Sjeff
221299364Shselaskystatic inline void *
222299364Shselaskymemremap(resource_size_t offset, size_t size, unsigned long flags)
223299364Shselasky{
224299364Shselasky	void *addr = NULL;
225299364Shselasky
226299364Shselasky	if ((flags & MEMREMAP_WB) &&
227299364Shselasky	    (addr = ioremap_wb(offset, size)) != NULL)
228299364Shselasky		goto done;
229299364Shselasky	if ((flags & MEMREMAP_WT) &&
230299364Shselasky	    (addr = ioremap_nocache(offset, size)) != NULL)
231299364Shselasky		goto done;
232299364Shselasky	if ((flags & MEMREMAP_WC) &&
233299364Shselasky	    (addr = ioremap_wc(offset, size)) != NULL)
234299364Shselasky		goto done;
235299364Shselaskydone:
236299364Shselasky	return (addr);
237299364Shselasky}
238299364Shselasky
239299364Shselaskystatic inline void
240299364Shselaskymemunmap(void *addr)
241299364Shselasky{
242299364Shselasky	/* XXX May need to check if this is RAM */
243299364Shselasky	iounmap(addr);
244299364Shselasky}
245299364Shselasky
246219820Sjeff#endif	/* _LINUX_IO_H_ */
247