1/*-
2 * Copyright (c) 2009 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include <sys/types.h>
31#include <machine/bus.h>
32#include <vm/vm.h>
33#include <vm/pmap.h>
34
35extern u_long ia64_port_base;
36
37#define __PIO_ADDR(port)        \
38        (void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF))
39
40int
41bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size,
42    int flags __unused, bus_space_handle_t *bshp)
43{
44
45        *bshp = (__predict_false(bst == IA64_BUS_SPACE_IO))
46            ? addr : (uintptr_t)pmap_mapdev(addr, size);
47        return (0);
48}
49
50
51void
52bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
53    bus_size_t size)
54{
55
56	pmap_unmapdev(bsh, size);
57}
58
59uint8_t
60bus_space_read_io_1(u_long port)
61{
62	uint8_t v;
63
64	ia64_mf();
65	v = ia64_ld1(__PIO_ADDR(port));
66	ia64_mf_a();
67	ia64_mf();
68	return (v);
69}
70
71uint16_t
72bus_space_read_io_2(u_long port)
73{
74	uint16_t v;
75
76	ia64_mf();
77	v = ia64_ld2(__PIO_ADDR(port));
78	ia64_mf_a();
79	ia64_mf();
80	return (v);
81}
82
83uint32_t
84bus_space_read_io_4(u_long port)
85{
86	uint32_t v;
87
88	ia64_mf();
89	v = ia64_ld4(__PIO_ADDR(port));
90	ia64_mf_a();
91	ia64_mf();
92	return (v);
93}
94
95#if 0
96uint64_t
97bus_space_read_io_8(u_long port)
98{
99}
100#endif
101
102void
103bus_space_write_io_1(u_long port, uint8_t val)
104{
105
106	ia64_mf();
107	ia64_st1(__PIO_ADDR(port), val);
108	ia64_mf_a();
109	ia64_mf();
110}
111
112void
113bus_space_write_io_2(u_long port, uint16_t val)
114{
115
116	ia64_mf();
117	ia64_st2(__PIO_ADDR(port), val);
118	ia64_mf_a();
119	ia64_mf();
120}
121
122void
123bus_space_write_io_4(u_long port, uint32_t val)
124{
125
126	ia64_mf();
127	ia64_st4(__PIO_ADDR(port), val);
128	ia64_mf_a();
129	ia64_mf();
130}
131
132#if 0
133void
134bus_space_write_io_8(u_long port, uint64_t val)
135{
136}
137#endif
138
139void
140bus_space_read_multi_io_1(u_long port, uint8_t *ptr, size_t count)
141{
142
143	while (count-- > 0)
144		*ptr++ = bus_space_read_io_1(port);
145}
146
147void
148bus_space_read_multi_io_2(u_long port, uint16_t *ptr, size_t count)
149{
150
151	while (count-- > 0)
152		*ptr++ = bus_space_read_io_2(port);
153}
154
155void
156bus_space_read_multi_io_4(u_long port, uint32_t *ptr, size_t count)
157{
158
159	while (count-- > 0)
160		*ptr++ = bus_space_read_io_4(port);
161}
162
163#if 0
164void
165bus_space_read_multi_io_8(u_long port, uint64_t *ptr, size_t count)
166{
167}
168#endif
169
170void
171bus_space_write_multi_io_1(u_long port, const uint8_t *ptr, size_t count)
172{
173
174	while (count-- > 0)
175		bus_space_write_io_1(port, *ptr++);
176}
177
178void
179bus_space_write_multi_io_2(u_long port, const uint16_t *ptr, size_t count)
180{
181
182	while (count-- > 0)
183		bus_space_write_io_2(port, *ptr++);
184}
185
186void
187bus_space_write_multi_io_4(u_long port, const uint32_t *ptr, size_t count)
188{
189
190	while (count-- > 0)
191		bus_space_write_io_4(port, *ptr++);
192}
193
194#if 0
195void
196bus_space_write_multi_io_8(u_long port, const uint64_t *ptr, size_t count)
197{
198}
199#endif
200
201void
202bus_space_read_region_io_1(u_long port, uint8_t *ptr, size_t count)
203{
204
205	while (count-- > 0) {
206		*ptr++ = bus_space_read_io_1(port);
207		port += 1;
208	}
209}
210
211void
212bus_space_read_region_io_2(u_long port, uint16_t *ptr, size_t count)
213{
214
215	while (count-- > 0) {
216		*ptr++ = bus_space_read_io_2(port);
217		port += 2;
218	}
219}
220
221void
222bus_space_read_region_io_4(u_long port, uint32_t *ptr, size_t count)
223{
224
225	while (count-- > 0) {
226		*ptr++ = bus_space_read_io_4(port);
227		port += 4;
228	}
229}
230
231#if 0
232void bus_space_read_region_io_8(u_long, uint64_t *, size_t);
233#endif
234
235void
236bus_space_write_region_io_1(u_long port, const uint8_t *ptr, size_t count)
237{
238
239	while (count-- > 0) {
240		bus_space_write_io_1(port, *ptr++);
241		port += 1;
242	}
243}
244
245void
246bus_space_write_region_io_2(u_long port, const uint16_t *ptr, size_t count)
247{
248
249	while (count-- > 0) {
250		bus_space_write_io_2(port, *ptr++);
251		port += 2;
252	}
253}
254
255void
256bus_space_write_region_io_4(u_long port, const uint32_t *ptr, size_t count)
257{
258
259	while (count-- > 0) {
260		bus_space_write_io_4(port, *ptr++);
261		port += 4;
262	}
263}
264
265#if 0
266void
267bus_space_write_region_io_8(u_long port, const uint64_t *ptr, size_t count)
268{
269}
270#endif
271
272void
273bus_space_set_region_io_1(u_long port, uint8_t val, size_t count)
274{
275
276	while (count-- > 0) {
277		bus_space_write_io_1(port, val);
278		port += 1;
279	}
280}
281
282void
283bus_space_set_region_io_2(u_long port, uint16_t val, size_t count)
284{
285
286	while (count-- > 0) {
287		bus_space_write_io_2(port, val);
288		port += 2;
289	}
290}
291
292void
293bus_space_set_region_io_4(u_long port, uint32_t val, size_t count)
294{
295
296	while (count-- > 0) {
297		bus_space_write_io_4(port, val);
298		port += 4;
299	}
300}
301
302#if 0
303void
304bus_space_set_region_io_8(u_long port, uint64_t val, size_t count)
305{
306}
307#endif
308
309void
310bus_space_copy_region_io_1(u_long src, u_long dst, size_t count)
311{
312	long delta;
313	uint8_t val;
314
315	if (src < dst) {
316		src += count - 1;
317		dst += count - 1;
318		delta = -1;
319	} else
320		delta = 1;
321
322	while (count-- > 0) {
323		val = bus_space_read_io_1(src);
324		bus_space_write_io_1(dst, val);
325		src += delta;
326		dst += delta;
327	}
328}
329
330void
331bus_space_copy_region_io_2(u_long src, u_long dst, size_t count)
332{
333	long delta;
334	uint16_t val;
335
336	if (src < dst) {
337		src += 2 * (count - 1);
338		dst += 2 * (count - 1);
339		delta = -2;
340	} else
341		delta = 2;
342
343	while (count-- > 0) {
344		val = bus_space_read_io_2(src);
345		bus_space_write_io_2(dst, val);
346		src += delta;
347		dst += delta;
348	}
349}
350
351void
352bus_space_copy_region_io_4(u_long src, u_long dst, size_t count)
353{
354	long delta;
355	uint32_t val;
356
357	if (src < dst) {
358		src += 4 * (count - 1);
359		dst += 4 * (count - 1);
360		delta = -4;
361	} else
362		delta = 4;
363
364	while (count-- > 0) {
365		val = bus_space_read_io_4(src);
366		bus_space_write_io_4(dst, val);
367		src += delta;
368		dst += delta;
369	}
370}
371
372#if 0
373void
374bus_space_copy_region_io_8(u_long src, u_long dst, size_t count)
375{
376}
377#endif
378