1201269Smarcel/*-
2201269Smarcel * Copyright (c) 2009 Marcel Moolenaar
3201269Smarcel * All rights reserved.
4201269Smarcel *
5201269Smarcel * Redistribution and use in source and binary forms, with or without
6201269Smarcel * modification, are permitted provided that the following conditions
7201269Smarcel * are met:
8201269Smarcel * 1. Redistributions of source code must retain the above copyright
9201269Smarcel *    notice, this list of conditions and the following disclaimer.
10201269Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11201269Smarcel *    notice, this list of conditions and the following disclaimer in the
12201269Smarcel *    documentation and/or other materials provided with the distribution.
13201269Smarcel *
14201269Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15201269Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16201269Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17201269Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18201269Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19201269Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20201269Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21201269Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22201269Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23201269Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24201269Smarcel * SUCH DAMAGE.
25201269Smarcel */
26201269Smarcel
27201269Smarcel#include <sys/cdefs.h>
28201269Smarcel__FBSDID("$FreeBSD$");
29201269Smarcel
30201269Smarcel#include <sys/types.h>
31201269Smarcel#include <machine/bus.h>
32203883Smarcel#include <vm/vm.h>
33203883Smarcel#include <vm/pmap.h>
34201269Smarcel
35201269Smarcelextern u_long ia64_port_base;
36201269Smarcel
37201269Smarcel#define __PIO_ADDR(port)        \
38201269Smarcel        (void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF))
39201269Smarcel
40203883Smarcelint
41203883Smarcelbus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size,
42203883Smarcel    int flags __unused, bus_space_handle_t *bshp)
43203883Smarcel{
44203883Smarcel
45203883Smarcel        *bshp = (__predict_false(bst == IA64_BUS_SPACE_IO))
46203883Smarcel            ? addr : (uintptr_t)pmap_mapdev(addr, size);
47203883Smarcel        return (0);
48203883Smarcel}
49203883Smarcel
50203883Smarcel
51203883Smarcelvoid
52203883Smarcelbus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
53203883Smarcel    bus_size_t size)
54203883Smarcel{
55203883Smarcel
56203883Smarcel	pmap_unmapdev(bsh, size);
57203883Smarcel}
58203883Smarcel
59201269Smarceluint8_t
60201269Smarcelbus_space_read_io_1(u_long port)
61201269Smarcel{
62201269Smarcel	uint8_t v;
63201269Smarcel
64201269Smarcel	ia64_mf();
65201269Smarcel	v = ia64_ld1(__PIO_ADDR(port));
66201269Smarcel	ia64_mf_a();
67201269Smarcel	ia64_mf();
68201269Smarcel	return (v);
69201269Smarcel}
70201269Smarcel
71201269Smarceluint16_t
72201269Smarcelbus_space_read_io_2(u_long port)
73201269Smarcel{
74201269Smarcel	uint16_t v;
75201269Smarcel
76201269Smarcel	ia64_mf();
77201269Smarcel	v = ia64_ld2(__PIO_ADDR(port));
78201269Smarcel	ia64_mf_a();
79201269Smarcel	ia64_mf();
80201269Smarcel	return (v);
81201269Smarcel}
82201269Smarcel
83201269Smarceluint32_t
84201269Smarcelbus_space_read_io_4(u_long port)
85201269Smarcel{
86201269Smarcel	uint32_t v;
87201269Smarcel
88201269Smarcel	ia64_mf();
89201269Smarcel	v = ia64_ld4(__PIO_ADDR(port));
90201269Smarcel	ia64_mf_a();
91201269Smarcel	ia64_mf();
92201269Smarcel	return (v);
93201269Smarcel}
94201269Smarcel
95201269Smarcel#if 0
96201269Smarceluint64_t
97201269Smarcelbus_space_read_io_8(u_long port)
98201269Smarcel{
99201269Smarcel}
100201269Smarcel#endif
101201269Smarcel
102201269Smarcelvoid
103201269Smarcelbus_space_write_io_1(u_long port, uint8_t val)
104201269Smarcel{
105201269Smarcel
106201269Smarcel	ia64_mf();
107201269Smarcel	ia64_st1(__PIO_ADDR(port), val);
108201269Smarcel	ia64_mf_a();
109201269Smarcel	ia64_mf();
110201269Smarcel}
111201269Smarcel
112201269Smarcelvoid
113201269Smarcelbus_space_write_io_2(u_long port, uint16_t val)
114201269Smarcel{
115201269Smarcel
116201269Smarcel	ia64_mf();
117201269Smarcel	ia64_st2(__PIO_ADDR(port), val);
118201269Smarcel	ia64_mf_a();
119201269Smarcel	ia64_mf();
120201269Smarcel}
121201269Smarcel
122201269Smarcelvoid
123201269Smarcelbus_space_write_io_4(u_long port, uint32_t val)
124201269Smarcel{
125201269Smarcel
126201269Smarcel	ia64_mf();
127201269Smarcel	ia64_st4(__PIO_ADDR(port), val);
128201269Smarcel	ia64_mf_a();
129201269Smarcel	ia64_mf();
130201269Smarcel}
131201269Smarcel
132201269Smarcel#if 0
133201269Smarcelvoid
134201269Smarcelbus_space_write_io_8(u_long port, uint64_t val)
135201269Smarcel{
136201269Smarcel}
137201269Smarcel#endif
138201269Smarcel
139201269Smarcelvoid
140201269Smarcelbus_space_read_multi_io_1(u_long port, uint8_t *ptr, size_t count)
141201269Smarcel{
142201269Smarcel
143201269Smarcel	while (count-- > 0)
144201269Smarcel		*ptr++ = bus_space_read_io_1(port);
145201269Smarcel}
146201269Smarcel
147201269Smarcelvoid
148201269Smarcelbus_space_read_multi_io_2(u_long port, uint16_t *ptr, size_t count)
149201269Smarcel{
150201269Smarcel
151201269Smarcel	while (count-- > 0)
152201269Smarcel		*ptr++ = bus_space_read_io_2(port);
153201269Smarcel}
154201269Smarcel
155201269Smarcelvoid
156201269Smarcelbus_space_read_multi_io_4(u_long port, uint32_t *ptr, size_t count)
157201269Smarcel{
158201269Smarcel
159201269Smarcel	while (count-- > 0)
160201269Smarcel		*ptr++ = bus_space_read_io_4(port);
161201269Smarcel}
162201269Smarcel
163201269Smarcel#if 0
164201269Smarcelvoid
165201269Smarcelbus_space_read_multi_io_8(u_long port, uint64_t *ptr, size_t count)
166201269Smarcel{
167201269Smarcel}
168201269Smarcel#endif
169201269Smarcel
170201269Smarcelvoid
171201269Smarcelbus_space_write_multi_io_1(u_long port, const uint8_t *ptr, size_t count)
172201269Smarcel{
173201269Smarcel
174201269Smarcel	while (count-- > 0)
175201269Smarcel		bus_space_write_io_1(port, *ptr++);
176201269Smarcel}
177201269Smarcel
178201269Smarcelvoid
179201269Smarcelbus_space_write_multi_io_2(u_long port, const uint16_t *ptr, size_t count)
180201269Smarcel{
181201269Smarcel
182201269Smarcel	while (count-- > 0)
183201269Smarcel		bus_space_write_io_2(port, *ptr++);
184201269Smarcel}
185201269Smarcel
186201269Smarcelvoid
187201269Smarcelbus_space_write_multi_io_4(u_long port, const uint32_t *ptr, size_t count)
188201269Smarcel{
189201269Smarcel
190201269Smarcel	while (count-- > 0)
191201269Smarcel		bus_space_write_io_4(port, *ptr++);
192201269Smarcel}
193201269Smarcel
194201269Smarcel#if 0
195201269Smarcelvoid
196201269Smarcelbus_space_write_multi_io_8(u_long port, const uint64_t *ptr, size_t count)
197201269Smarcel{
198201269Smarcel}
199201269Smarcel#endif
200201269Smarcel
201201269Smarcelvoid
202201269Smarcelbus_space_read_region_io_1(u_long port, uint8_t *ptr, size_t count)
203201269Smarcel{
204201269Smarcel
205201269Smarcel	while (count-- > 0) {
206201269Smarcel		*ptr++ = bus_space_read_io_1(port);
207201269Smarcel		port += 1;
208201269Smarcel	}
209201269Smarcel}
210201269Smarcel
211201269Smarcelvoid
212201269Smarcelbus_space_read_region_io_2(u_long port, uint16_t *ptr, size_t count)
213201269Smarcel{
214201269Smarcel
215201269Smarcel	while (count-- > 0) {
216201269Smarcel		*ptr++ = bus_space_read_io_2(port);
217201269Smarcel		port += 2;
218201269Smarcel	}
219201269Smarcel}
220201269Smarcel
221201269Smarcelvoid
222201269Smarcelbus_space_read_region_io_4(u_long port, uint32_t *ptr, size_t count)
223201269Smarcel{
224201269Smarcel
225201269Smarcel	while (count-- > 0) {
226201269Smarcel		*ptr++ = bus_space_read_io_4(port);
227201269Smarcel		port += 4;
228201269Smarcel	}
229201269Smarcel}
230201269Smarcel
231201269Smarcel#if 0
232201269Smarcelvoid bus_space_read_region_io_8(u_long, uint64_t *, size_t);
233201269Smarcel#endif
234201269Smarcel
235201269Smarcelvoid
236201269Smarcelbus_space_write_region_io_1(u_long port, const uint8_t *ptr, size_t count)
237201269Smarcel{
238201269Smarcel
239201269Smarcel	while (count-- > 0) {
240201269Smarcel		bus_space_write_io_1(port, *ptr++);
241201269Smarcel		port += 1;
242201269Smarcel	}
243201269Smarcel}
244201269Smarcel
245201269Smarcelvoid
246201269Smarcelbus_space_write_region_io_2(u_long port, const uint16_t *ptr, size_t count)
247201269Smarcel{
248201269Smarcel
249201269Smarcel	while (count-- > 0) {
250201269Smarcel		bus_space_write_io_2(port, *ptr++);
251201269Smarcel		port += 2;
252201269Smarcel	}
253201269Smarcel}
254201269Smarcel
255201269Smarcelvoid
256201269Smarcelbus_space_write_region_io_4(u_long port, const uint32_t *ptr, size_t count)
257201269Smarcel{
258201269Smarcel
259201269Smarcel	while (count-- > 0) {
260201269Smarcel		bus_space_write_io_4(port, *ptr++);
261201269Smarcel		port += 4;
262201269Smarcel	}
263201269Smarcel}
264201269Smarcel
265201269Smarcel#if 0
266201269Smarcelvoid
267201269Smarcelbus_space_write_region_io_8(u_long port, const uint64_t *ptr, size_t count)
268201269Smarcel{
269201269Smarcel}
270201269Smarcel#endif
271201269Smarcel
272201269Smarcelvoid
273201269Smarcelbus_space_set_region_io_1(u_long port, uint8_t val, size_t count)
274201269Smarcel{
275201269Smarcel
276201269Smarcel	while (count-- > 0) {
277201269Smarcel		bus_space_write_io_1(port, val);
278201269Smarcel		port += 1;
279201269Smarcel	}
280201269Smarcel}
281201269Smarcel
282201269Smarcelvoid
283201269Smarcelbus_space_set_region_io_2(u_long port, uint16_t val, size_t count)
284201269Smarcel{
285201269Smarcel
286201269Smarcel	while (count-- > 0) {
287201269Smarcel		bus_space_write_io_2(port, val);
288201269Smarcel		port += 2;
289201269Smarcel	}
290201269Smarcel}
291201269Smarcel
292201269Smarcelvoid
293201269Smarcelbus_space_set_region_io_4(u_long port, uint32_t val, size_t count)
294201269Smarcel{
295201269Smarcel
296201269Smarcel	while (count-- > 0) {
297201269Smarcel		bus_space_write_io_4(port, val);
298201269Smarcel		port += 4;
299201269Smarcel	}
300201269Smarcel}
301201269Smarcel
302201269Smarcel#if 0
303201269Smarcelvoid
304201269Smarcelbus_space_set_region_io_8(u_long port, uint64_t val, size_t count)
305201269Smarcel{
306201269Smarcel}
307201269Smarcel#endif
308201269Smarcel
309201269Smarcelvoid
310201269Smarcelbus_space_copy_region_io_1(u_long src, u_long dst, size_t count)
311201269Smarcel{
312201269Smarcel	long delta;
313201269Smarcel	uint8_t val;
314201269Smarcel
315201269Smarcel	if (src < dst) {
316201269Smarcel		src += count - 1;
317201269Smarcel		dst += count - 1;
318201269Smarcel		delta = -1;
319201269Smarcel	} else
320201269Smarcel		delta = 1;
321201269Smarcel
322201269Smarcel	while (count-- > 0) {
323201269Smarcel		val = bus_space_read_io_1(src);
324201269Smarcel		bus_space_write_io_1(dst, val);
325201269Smarcel		src += delta;
326201269Smarcel		dst += delta;
327201269Smarcel	}
328201269Smarcel}
329201269Smarcel
330201269Smarcelvoid
331201269Smarcelbus_space_copy_region_io_2(u_long src, u_long dst, size_t count)
332201269Smarcel{
333201269Smarcel	long delta;
334201269Smarcel	uint16_t val;
335201269Smarcel
336201269Smarcel	if (src < dst) {
337201269Smarcel		src += 2 * (count - 1);
338201269Smarcel		dst += 2 * (count - 1);
339201269Smarcel		delta = -2;
340201269Smarcel	} else
341201269Smarcel		delta = 2;
342201269Smarcel
343201269Smarcel	while (count-- > 0) {
344201269Smarcel		val = bus_space_read_io_2(src);
345201269Smarcel		bus_space_write_io_2(dst, val);
346201269Smarcel		src += delta;
347201269Smarcel		dst += delta;
348201269Smarcel	}
349201269Smarcel}
350201269Smarcel
351201269Smarcelvoid
352201269Smarcelbus_space_copy_region_io_4(u_long src, u_long dst, size_t count)
353201269Smarcel{
354201269Smarcel	long delta;
355201269Smarcel	uint32_t val;
356201269Smarcel
357201269Smarcel	if (src < dst) {
358201269Smarcel		src += 4 * (count - 1);
359201269Smarcel		dst += 4 * (count - 1);
360201269Smarcel		delta = -4;
361201269Smarcel	} else
362201269Smarcel		delta = 4;
363201269Smarcel
364201269Smarcel	while (count-- > 0) {
365201269Smarcel		val = bus_space_read_io_4(src);
366201269Smarcel		bus_space_write_io_4(dst, val);
367201269Smarcel		src += delta;
368201269Smarcel		dst += delta;
369201269Smarcel	}
370201269Smarcel}
371201269Smarcel
372201269Smarcel#if 0
373201269Smarcelvoid
374201269Smarcelbus_space_copy_region_io_8(u_long src, u_long dst, size_t count)
375201269Smarcel{
376201269Smarcel}
377201269Smarcel#endif
378