1 /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.13 2001/09/04 16:14:49 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
42  * All rights reserved.
43  *
44  * Author: Chris G. Demetriou
45  *
46  * Permission to use, copy, modify and distribute this software and
47  * its documentation is hereby granted, provided that both the copyright
48  * notice and this permission notice appear in all copies of the
49  * software, derivative works or modified versions, and any portions
50  * thereof, and that both notices appear in supporting documentation.
51  *
52  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
53  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
54  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
55  *
56  * Carnegie Mellon requests users of this software to return to
57  *
58  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
59  *  School of Computer Science
60  *  Carnegie Mellon University
61  *  Pittsburgh PA 15213-3890
62  *
63  * any improvements or extensions that they make and grant Carnegie the
64  * rights to redistribute these changes.
65  */
66 
67 /*
68  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
69  * deal with only a single PCI interface chip in a machine.
70  *
71  * uses:
72  *	CHIP		name of the 'chip' it's being compiled for.
73  *	CHIP_IO_BASE	I/O space base to use.
74  *	CHIP_IO_EX_STORE
75  *			If defined, device-provided static storage area
76  *			for the I/O space extent.  If this is defined,
77  *			CHIP_IO_EX_STORE_SIZE must also be defined.  If
78  *			this is not defined, a static area will be
79  *			declared.
80  *	CHIP_IO_EX_STORE_SIZE
81  *			Size of the device-provided static storage area
82  *			for the I/O memory space extent.
83  */
84 
85 #include <sys/extent.h>
86 
87 #include <machine/bwx.h>
88 
89 #define	__C(A,B)	__CONCAT(A,B)
90 #define	__S(S)		__STRING(S)
91 
92 /* mapping/unmapping */
93 int		__C(CHIP,_io_map) __P((void *, bus_addr_t, bus_size_t, int,
94 		    bus_space_handle_t *, int));
95 void		__C(CHIP,_io_unmap) __P((void *, bus_space_handle_t,
96 		    bus_size_t, int));
97 int		__C(CHIP,_io_subregion) __P((void *, bus_space_handle_t,
98 		    bus_size_t, bus_size_t, bus_space_handle_t *));
99 
100 int		__C(CHIP,_io_translate) __P((void *, bus_addr_t, bus_size_t,
101 		    int, struct alpha_bus_space_translation *));
102 int		__C(CHIP,_io_get_window) __P((void *, int,
103 		    struct alpha_bus_space_translation *));
104 
105 /* allocation/deallocation */
106 int		__C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t,
107 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
108                     bus_space_handle_t *));
109 void		__C(CHIP,_io_free) __P((void *, bus_space_handle_t,
110 		    bus_size_t));
111 
112 /* get kernel virtual address */
113 void *		__C(CHIP,_io_vaddr) __P((void *, bus_space_handle_t));
114 
115 /* mmap for user */
116 paddr_t		__C(CHIP,_io_mmap) __P((void *, bus_addr_t, off_t, int, int));
117 
118 /* barrier */
119 inline void	__C(CHIP,_io_barrier) __P((void *, bus_space_handle_t,
120 		    bus_size_t, bus_size_t, int));
121 
122 /* read (single) */
123 inline u_int8_t	__C(CHIP,_io_read_1) __P((void *, bus_space_handle_t,
124 		    bus_size_t));
125 inline u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t,
126 		    bus_size_t));
127 inline u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t,
128 		    bus_size_t));
129 inline u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t,
130 		    bus_size_t));
131 
132 /* read multiple */
133 void		__C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t,
134 		    bus_size_t, u_int8_t *, bus_size_t));
135 void		__C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t,
136 		    bus_size_t, u_int16_t *, bus_size_t));
137 void		__C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t,
138 		    bus_size_t, u_int32_t *, bus_size_t));
139 void		__C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t,
140 		    bus_size_t, u_int64_t *, bus_size_t));
141 
142 /* read region */
143 void		__C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t,
144 		    bus_size_t, u_int8_t *, bus_size_t));
145 void		__C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t,
146 		    bus_size_t, u_int16_t *, bus_size_t));
147 void		__C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t,
148 		    bus_size_t, u_int32_t *, bus_size_t));
149 void		__C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t,
150 		    bus_size_t, u_int64_t *, bus_size_t));
151 
152 /* write (single) */
153 inline void	__C(CHIP,_io_write_1) __P((void *, bus_space_handle_t,
154 		    bus_size_t, u_int8_t));
155 inline void	__C(CHIP,_io_write_2) __P((void *, bus_space_handle_t,
156 		    bus_size_t, u_int16_t));
157 inline void	__C(CHIP,_io_write_4) __P((void *, bus_space_handle_t,
158 		    bus_size_t, u_int32_t));
159 inline void	__C(CHIP,_io_write_8) __P((void *, bus_space_handle_t,
160 		    bus_size_t, u_int64_t));
161 
162 /* write multiple */
163 void		__C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t,
164 		    bus_size_t, const u_int8_t *, bus_size_t));
165 void		__C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t,
166 		    bus_size_t, const u_int16_t *, bus_size_t));
167 void		__C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t,
168 		    bus_size_t, const u_int32_t *, bus_size_t));
169 void		__C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t,
170 		    bus_size_t, const u_int64_t *, bus_size_t));
171 
172 /* write region */
173 void		__C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t,
174 		    bus_size_t, const u_int8_t *, bus_size_t));
175 void		__C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t,
176 		    bus_size_t, const u_int16_t *, bus_size_t));
177 void		__C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t,
178 		    bus_size_t, const u_int32_t *, bus_size_t));
179 void		__C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t,
180 		    bus_size_t, const u_int64_t *, bus_size_t));
181 
182 /* set multiple */
183 void		__C(CHIP,_io_set_multi_1) __P((void *, bus_space_handle_t,
184 		    bus_size_t, u_int8_t, bus_size_t));
185 void		__C(CHIP,_io_set_multi_2) __P((void *, bus_space_handle_t,
186 		    bus_size_t, u_int16_t, bus_size_t));
187 void		__C(CHIP,_io_set_multi_4) __P((void *, bus_space_handle_t,
188 		    bus_size_t, u_int32_t, bus_size_t));
189 void		__C(CHIP,_io_set_multi_8) __P((void *, bus_space_handle_t,
190 		    bus_size_t, u_int64_t, bus_size_t));
191 
192 /* set region */
193 void		__C(CHIP,_io_set_region_1) __P((void *, bus_space_handle_t,
194 		    bus_size_t, u_int8_t, bus_size_t));
195 void		__C(CHIP,_io_set_region_2) __P((void *, bus_space_handle_t,
196 		    bus_size_t, u_int16_t, bus_size_t));
197 void		__C(CHIP,_io_set_region_4) __P((void *, bus_space_handle_t,
198 		    bus_size_t, u_int32_t, bus_size_t));
199 void		__C(CHIP,_io_set_region_8) __P((void *, bus_space_handle_t,
200 		    bus_size_t, u_int64_t, bus_size_t));
201 
202 /* copy */
203 void		__C(CHIP,_io_copy_region_1) __P((void *, bus_space_handle_t,
204 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
205 void		__C(CHIP,_io_copy_region_2) __P((void *, bus_space_handle_t,
206 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
207 void		__C(CHIP,_io_copy_region_4) __P((void *, bus_space_handle_t,
208 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
209 void		__C(CHIP,_io_copy_region_8) __P((void *, bus_space_handle_t,
210 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
211 
212 #ifndef	CHIP_IO_EX_STORE
213 static long
214     __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
215 #define	CHIP_IO_EX_STORE(v)		(__C(CHIP, _io_ex_storage))
216 #define	CHIP_IO_EX_STORE_SIZE(v)	(sizeof __C(CHIP, _io_ex_storage))
217 #endif
218 
219 void
220 __C(CHIP,_bus_io_init)(t, v)
221 	bus_space_tag_t t;
222 	void *v;
223 {
224 	struct extent *ex;
225 
226 	/*
227 	 * Initialize the bus space tag.
228 	 */
229 
230 	/* cookie */
231 	t->abs_cookie =		v;
232 
233 	/* mapping/unmapping */
234 	t->abs_map =		__C(CHIP,_io_map);
235 	t->abs_unmap =		__C(CHIP,_io_unmap);
236 	t->abs_subregion =	__C(CHIP,_io_subregion);
237 
238 	t->abs_translate =	__C(CHIP,_io_translate);
239 	t->abs_get_window =	__C(CHIP,_io_get_window);
240 
241 	/* allocation/deallocation */
242 	t->abs_alloc =		__C(CHIP,_io_alloc);
243 	t->abs_free = 		__C(CHIP,_io_free);
244 
245 	/* get kernel virtual address */
246 	t->abs_vaddr =		__C(CHIP,_io_vaddr);
247 
248 	/* mmap for user */
249 	t->abs_mmap =		__C(CHIP,_io_mmap);
250 
251 	/* barrier */
252 	t->abs_barrier =	__C(CHIP,_io_barrier);
253 
254 	/* read (single) */
255 	t->abs_r_1 =		__C(CHIP,_io_read_1);
256 	t->abs_r_2 =		__C(CHIP,_io_read_2);
257 	t->abs_r_4 =		__C(CHIP,_io_read_4);
258 	t->abs_r_8 =		__C(CHIP,_io_read_8);
259 
260 	/* read multiple */
261 	t->abs_rm_1 =		__C(CHIP,_io_read_multi_1);
262 	t->abs_rm_2 =		__C(CHIP,_io_read_multi_2);
263 	t->abs_rm_4 =		__C(CHIP,_io_read_multi_4);
264 	t->abs_rm_8 =		__C(CHIP,_io_read_multi_8);
265 
266 	/* read region */
267 	t->abs_rr_1 =		__C(CHIP,_io_read_region_1);
268 	t->abs_rr_2 =		__C(CHIP,_io_read_region_2);
269 	t->abs_rr_4 =		__C(CHIP,_io_read_region_4);
270 	t->abs_rr_8 =		__C(CHIP,_io_read_region_8);
271 
272 	/* write (single) */
273 	t->abs_w_1 =		__C(CHIP,_io_write_1);
274 	t->abs_w_2 =		__C(CHIP,_io_write_2);
275 	t->abs_w_4 =		__C(CHIP,_io_write_4);
276 	t->abs_w_8 =		__C(CHIP,_io_write_8);
277 
278 	/* write multiple */
279 	t->abs_wm_1 =		__C(CHIP,_io_write_multi_1);
280 	t->abs_wm_2 =		__C(CHIP,_io_write_multi_2);
281 	t->abs_wm_4 =		__C(CHIP,_io_write_multi_4);
282 	t->abs_wm_8 =		__C(CHIP,_io_write_multi_8);
283 
284 	/* write region */
285 	t->abs_wr_1 =		__C(CHIP,_io_write_region_1);
286 	t->abs_wr_2 =		__C(CHIP,_io_write_region_2);
287 	t->abs_wr_4 =		__C(CHIP,_io_write_region_4);
288 	t->abs_wr_8 =		__C(CHIP,_io_write_region_8);
289 
290 	/* set multiple */
291 	t->abs_sm_1 =		__C(CHIP,_io_set_multi_1);
292 	t->abs_sm_2 =		__C(CHIP,_io_set_multi_2);
293 	t->abs_sm_4 =		__C(CHIP,_io_set_multi_4);
294 	t->abs_sm_8 =		__C(CHIP,_io_set_multi_8);
295 
296 	/* set region */
297 	t->abs_sr_1 =		__C(CHIP,_io_set_region_1);
298 	t->abs_sr_2 =		__C(CHIP,_io_set_region_2);
299 	t->abs_sr_4 =		__C(CHIP,_io_set_region_4);
300 	t->abs_sr_8 =		__C(CHIP,_io_set_region_8);
301 
302 	/* copy */
303 	t->abs_c_1 =		__C(CHIP,_io_copy_region_1);
304 	t->abs_c_2 =		__C(CHIP,_io_copy_region_2);
305 	t->abs_c_4 =		__C(CHIP,_io_copy_region_4);
306 	t->abs_c_8 =		__C(CHIP,_io_copy_region_8);
307 
308 	ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL,
309 	    M_DEVBUF, (caddr_t)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v),
310 	    EX_NOWAIT|EX_NOCOALESCE);
311 
312 	CHIP_IO_EXTENT(v) = ex;
313 }
314 
315 int
316 __C(CHIP,_io_translate)(v, ioaddr, iolen, flags, abst)
317 	void *v;
318 	bus_addr_t ioaddr;
319 	bus_size_t iolen;
320 	int flags;
321 	struct alpha_bus_space_translation *abst;
322 {
323 	int linear = flags & BUS_SPACE_MAP_LINEAR;
324 
325 	/*
326 	 * Can't map i/o space linearly.
327 	 */
328 	if (linear)
329 		return (EOPNOTSUPP);
330 
331 	return (__C(CHIP,_io_get_window)(v, 0, abst));
332 }
333 
334 int
335 __C(CHIP,_io_get_window)(v, window, abst)
336 	void *v;
337 	int window;
338 	struct alpha_bus_space_translation *abst;
339 {
340 
341 	switch (window) {
342 	case 0:
343 		abst->abst_bus_start = 0;
344 		abst->abst_bus_end = 0xffffffffUL;
345 		abst->abst_sys_start = CHIP_IO_SYS_START(v);
346 		abst->abst_sys_end = CHIP_IO_SYS_START(v) + abst->abst_bus_end;
347 		abst->abst_addr_shift = 0;
348 		abst->abst_size_shift = 0;
349 		abst->abst_flags = ABST_DENSE|ABST_BWX;
350 		break;
351 
352 	default:
353 		panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d",
354 		    window);
355 	}
356 
357 	return (0);
358 }
359 
360 int
361 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct)
362 	void *v;
363 	bus_addr_t ioaddr;
364 	bus_size_t iosize;
365 	int flags;
366 	bus_space_handle_t *iohp;
367 	int acct;
368 {
369 	struct alpha_bus_space_translation abst;
370 	int error;
371 
372 	/*
373 	 * Get the translation for this address.
374 	 */
375 	error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst);
376 	if (error)
377 		return (error);
378 
379 	if (acct == 0)
380 		goto mapit;
381 
382 #ifdef EXTENT_DEBUG
383 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
384 #endif
385         error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
386             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
387 	if (error) {
388 #ifdef EXTENT_DEBUG
389 		printf("io: allocation failed (%d)\n", error);
390 		extent_print(CHIP_IO_EXTENT(v));
391 #endif
392 		return (error);
393 	}
394 
395  mapit:
396 	*iohp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
397 
398 	return (0);
399 }
400 
401 void
402 __C(CHIP,_io_unmap)(v, ioh, iosize, acct)
403 	void *v;
404 	bus_space_handle_t ioh;
405 	bus_size_t iosize;
406 	int acct;
407 {
408 	bus_addr_t ioaddr;
409 	int error;
410 
411 	if (acct == 0)
412 		return;
413 
414 #ifdef EXTENT_DEBUG
415 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
416 #endif
417 
418 	ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v));
419 
420 #ifdef EXTENT_DEBUG
421 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
422 #endif
423         error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
424             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
425 	if (error) {
426 		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
427 		   __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
428 		   error);
429 #ifdef EXTENT_DEBUG
430 		extent_print(CHIP_IO_EXTENT(v));
431 #endif
432 	}
433 }
434 
435 int
436 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
437 	void *v;
438 	bus_space_handle_t ioh, *nioh;
439 	bus_size_t offset, size;
440 {
441 
442 	*nioh = ioh + offset;
443 	return (0);
444 }
445 
446 int
447 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags,
448     addrp, bshp)
449 	void *v;
450 	bus_addr_t rstart, rend, *addrp;
451 	bus_size_t size, align, boundary;
452 	int flags;
453 	bus_space_handle_t *bshp;
454 {
455 	struct alpha_bus_space_translation abst;
456 	int linear = flags & BUS_SPACE_MAP_LINEAR;
457 	bus_addr_t ioaddr;
458 	int error;
459 
460 	/*
461 	 * Can't map i/o space linearly.
462 	 */
463 	if (linear)
464 		return (EOPNOTSUPP);
465 
466 	/*
467 	 * Do the requested allocation.
468 	 */
469 #ifdef EXTENT_DEBUG
470 	printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend);
471 #endif
472 	error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend,
473 	    size, align, boundary,
474 	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
475 	    &ioaddr);
476 	if (error) {
477 #ifdef EXTENT_DEBUG
478 		printf("io: allocation failed (%d)\n", error);
479 		extent_print(CHIP_IO_EXTENT(v));
480 #endif
481 		return (error);
482 	}
483 
484 #ifdef EXTENT_DEBUG
485 	printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1);
486 #endif
487 
488 	error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst);
489 	if (error) {
490 		(void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size,
491 		    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
492 		return (error);
493 	}
494 
495 	*addrp = ioaddr;
496 	*bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
497 
498 	return (0);
499 }
500 
501 void
502 __C(CHIP,_io_free)(v, bsh, size)
503 	void *v;
504 	bus_space_handle_t bsh;
505 	bus_size_t size;
506 {
507 
508 	/* Unmap does all we need to do. */
509 	__C(CHIP,_io_unmap)(v, bsh, size, 1);
510 }
511 
512 void *
513 __C(CHIP,_io_vaddr)(v, bsh)
514 	void *v;
515 	bus_space_handle_t bsh;
516 {
517 	/*
518 	 * _io_translate() catches BUS_SPACE_MAP_LINEAR,
519 	 * so we shouldn't get here
520 	 */
521 	panic("_io_vaddr");
522 }
523 
524 paddr_t
525 __C(CHIP,_io_mmap)(v, addr, off, prot, flags)
526 	void *v;
527 	bus_addr_t addr;
528 	off_t off;
529 	int prot;
530 	int flags;
531 {
532 
533 	/* Not supported for I/O space. */
534 	return (-1);
535 }
536 
537 inline void
538 __C(CHIP,_io_barrier)(v, h, o, l, f)
539 	void *v;
540 	bus_space_handle_t h;
541 	bus_size_t o, l;
542 	int f;
543 {
544 
545 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
546 		alpha_mb();
547 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
548 		alpha_wmb();
549 }
550 
551 inline u_int8_t
552 __C(CHIP,_io_read_1)(v, ioh, off)
553 	void *v;
554 	bus_space_handle_t ioh;
555 	bus_size_t off;
556 {
557 	bus_addr_t addr;
558 
559 	addr = ioh + off;
560 	alpha_mb();
561 	return (alpha_ldbu((u_int8_t *)addr));
562 }
563 
564 inline u_int16_t
565 __C(CHIP,_io_read_2)(v, ioh, off)
566 	void *v;
567 	bus_space_handle_t ioh;
568 	bus_size_t off;
569 {
570 	bus_addr_t addr;
571 
572 	addr = ioh + off;
573 #ifdef DIAGNOSTIC
574 	if (addr & 1)
575 		panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned",
576 		    addr);
577 #endif
578 	alpha_mb();
579 	return (alpha_ldwu((u_int16_t *)addr));
580 }
581 
582 inline u_int32_t
583 __C(CHIP,_io_read_4)(v, ioh, off)
584 	void *v;
585 	bus_space_handle_t ioh;
586 	bus_size_t off;
587 {
588 	bus_addr_t addr;
589 
590 	addr = ioh + off;
591 #ifdef DIAGNOSTIC
592 	if (addr & 3)
593 		panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned",
594 		    addr);
595 #endif
596 	alpha_mb();
597 	return (*(u_int32_t *)addr);
598 }
599 
600 inline u_int64_t
601 __C(CHIP,_io_read_8)(v, ioh, off)
602 	void *v;
603 	bus_space_handle_t ioh;
604 	bus_size_t off;
605 {
606 
607 	/* XXX XXX XXX */
608 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
609 }
610 
611 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
612 void									\
613 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
614 	void *v;							\
615 	bus_space_handle_t h;						\
616 	bus_size_t o, c;						\
617 	TYPE *a;							\
618 {									\
619 									\
620 	while (c-- > 0) {						\
621 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
622 		    BUS_SPACE_BARRIER_READ);				\
623 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
624 	}								\
625 }
626 CHIP_io_read_multi_N(1,u_int8_t)
627 CHIP_io_read_multi_N(2,u_int16_t)
628 CHIP_io_read_multi_N(4,u_int32_t)
629 CHIP_io_read_multi_N(8,u_int64_t)
630 
631 #define CHIP_io_read_region_N(BYTES,TYPE)				\
632 void									\
633 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
634 	void *v;							\
635 	bus_space_handle_t h;						\
636 	bus_size_t o, c;						\
637 	TYPE *a;							\
638 {									\
639 									\
640 	while (c-- > 0) {						\
641 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
642 		o += sizeof *a;						\
643 	}								\
644 }
645 CHIP_io_read_region_N(1,u_int8_t)
646 CHIP_io_read_region_N(2,u_int16_t)
647 CHIP_io_read_region_N(4,u_int32_t)
648 CHIP_io_read_region_N(8,u_int64_t)
649 
650 inline void
651 __C(CHIP,_io_write_1)(v, ioh, off, val)
652 	void *v;
653 	bus_space_handle_t ioh;
654 	bus_size_t off;
655 	u_int8_t val;
656 {
657 	bus_addr_t addr;
658 
659 	addr = ioh + off;
660 	alpha_stb((u_int8_t *)addr, val);
661 	alpha_mb();
662 }
663 
664 inline void
665 __C(CHIP,_io_write_2)(v, ioh, off, val)
666 	void *v;
667 	bus_space_handle_t ioh;
668 	bus_size_t off;
669 	u_int16_t val;
670 {
671 	bus_addr_t addr;
672 
673 	addr = ioh + off;
674 #ifdef DIAGNOSTIC
675 	if (addr & 1)
676 		panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned",
677 		    addr);
678 #endif
679 	alpha_stw((u_int16_t *)addr, val);
680 	alpha_mb();
681 }
682 
683 inline void
684 __C(CHIP,_io_write_4)(v, ioh, off, val)
685 	void *v;
686 	bus_space_handle_t ioh;
687 	bus_size_t off;
688 	u_int32_t val;
689 {
690 	bus_addr_t addr;
691 
692 	addr = ioh + off;
693 #ifdef DIAGNOSTIC
694 	if (addr & 3)
695 		panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned",
696 		    addr);
697 #endif
698 	*(u_int32_t *)addr = val;
699 	alpha_mb();
700 }
701 
702 inline void
703 __C(CHIP,_io_write_8)(v, ioh, off, val)
704 	void *v;
705 	bus_space_handle_t ioh;
706 	bus_size_t off;
707 	u_int64_t val;
708 {
709 
710 	/* XXX XXX XXX */
711 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
712 	alpha_mb();
713 }
714 
715 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
716 void									\
717 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
718 	void *v;							\
719 	bus_space_handle_t h;						\
720 	bus_size_t o, c;						\
721 	const TYPE *a;							\
722 {									\
723 									\
724 	while (c-- > 0) {						\
725 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
726 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
727 		    BUS_SPACE_BARRIER_WRITE);				\
728 	}								\
729 }
730 CHIP_io_write_multi_N(1,u_int8_t)
731 CHIP_io_write_multi_N(2,u_int16_t)
732 CHIP_io_write_multi_N(4,u_int32_t)
733 CHIP_io_write_multi_N(8,u_int64_t)
734 
735 #define CHIP_io_write_region_N(BYTES,TYPE)				\
736 void									\
737 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
738 	void *v;							\
739 	bus_space_handle_t h;						\
740 	bus_size_t o, c;						\
741 	const TYPE *a;							\
742 {									\
743 									\
744 	while (c-- > 0) {						\
745 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
746 		o += sizeof *a;						\
747 	}								\
748 }
749 CHIP_io_write_region_N(1,u_int8_t)
750 CHIP_io_write_region_N(2,u_int16_t)
751 CHIP_io_write_region_N(4,u_int32_t)
752 CHIP_io_write_region_N(8,u_int64_t)
753 
754 #define CHIP_io_set_multi_N(BYTES,TYPE)					\
755 void									\
756 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c)			\
757 	void *v;							\
758 	bus_space_handle_t h;						\
759 	bus_size_t o, c;						\
760 	TYPE val;							\
761 {									\
762 									\
763 	while (c-- > 0) {						\
764 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
765 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
766 		    BUS_SPACE_BARRIER_WRITE);				\
767 	}								\
768 }
769 CHIP_io_set_multi_N(1,u_int8_t)
770 CHIP_io_set_multi_N(2,u_int16_t)
771 CHIP_io_set_multi_N(4,u_int32_t)
772 CHIP_io_set_multi_N(8,u_int64_t)
773 
774 #define CHIP_io_set_region_N(BYTES,TYPE)				\
775 void									\
776 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c)			\
777 	void *v;							\
778 	bus_space_handle_t h;						\
779 	bus_size_t o, c;						\
780 	TYPE val;							\
781 {									\
782 									\
783 	while (c-- > 0) {						\
784 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
785 		o += sizeof val;					\
786 	}								\
787 }
788 CHIP_io_set_region_N(1,u_int8_t)
789 CHIP_io_set_region_N(2,u_int16_t)
790 CHIP_io_set_region_N(4,u_int32_t)
791 CHIP_io_set_region_N(8,u_int64_t)
792 
793 #define	CHIP_io_copy_region_N(BYTES)					\
794 void									\
795 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c)		\
796 	void *v;							\
797 	bus_space_handle_t h1, h2;					\
798 	bus_size_t o1, o2, c;						\
799 {									\
800 	bus_size_t o;							\
801 									\
802 	if ((h1 + o1) >= (h2 + o2)) {					\
803 		/* src after dest: copy forward */			\
804 		for (o = 0; c != 0; c--, o += BYTES) {			\
805 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
806 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
807 		}							\
808 	} else {							\
809 		/* dest after src: copy backwards */			\
810 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) {	\
811 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
812 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
813 		}							\
814 	}								\
815 }
816 CHIP_io_copy_region_N(1)
817 CHIP_io_copy_region_N(2)
818 CHIP_io_copy_region_N(4)
819 CHIP_io_copy_region_N(8)
820