1 /* $OpenBSD: pci_bwx_bus_io_chipdep.c,v 1.9 2009/12/25 20:52:34 miod Exp $ */
2 /* $NetBSD: pcs_bus_io_common.c,v 1.14 1996/12/02 22:19:35 cgd Exp $ */
3 
4 /*
5  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 /*
32  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
33  * deal with only a single PCI interface chip in a machine.
34  *
35  * uses:
36  *	CHIP		name of the 'chip' it's being compiled for.
37  *	CHIP_IO_BASE	Sparse I/O space base to use.
38  */
39 
40 #include <sys/extent.h>
41 
42 #include <machine/bwx.h>
43 
44 #define	__C(A,B)	__CONCAT(A,B)
45 #define	__S(S)		__STRING(S)
46 
47 #ifndef	CHIP_EXTENT_NAME
48 #define	CHIP_EXTENT_NAME(v)	__S(__C(CHIP,_bus_io))
49 #endif
50 
51 #ifndef	CHIP_EXTENT_STORAGE
52 #define CHIP_EXTENT_STORAGE(v)	__C(CHIP,_io_ex_storage)
53 static long
54     __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
55 #endif
56 
57 /* mapping/unmapping */
58 int		__C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int,
59 		    bus_space_handle_t *);
60 void		__C(CHIP,_io_unmap)(void *, bus_space_handle_t,
61 		    bus_size_t);
62 int		__C(CHIP,_io_subregion)(void *, bus_space_handle_t,
63 		    bus_size_t, bus_size_t, bus_space_handle_t *);
64 
65 /* allocation/deallocation */
66 int		__C(CHIP,_io_alloc)(void *, bus_addr_t, bus_addr_t,
67 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
68                     bus_space_handle_t *);
69 void		__C(CHIP,_io_free)(void *, bus_space_handle_t,
70 		    bus_size_t);
71 
72 /* get kernel virtual address */
73 void *		__C(CHIP,_io_vaddr)(void *, bus_space_handle_t);
74 
75 /* barrier */
76 inline void	__C(CHIP,_io_barrier)(void *, bus_space_handle_t,
77 		    bus_size_t, bus_size_t, int);
78 
79 /* read (single) */
80 inline u_int8_t	__C(CHIP,_io_read_1)(void *, bus_space_handle_t,
81 		    bus_size_t);
82 inline u_int16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t,
83 		    bus_size_t);
84 inline u_int32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t,
85 		    bus_size_t);
86 inline u_int64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t,
87 		    bus_size_t);
88 
89 /* read multiple */
90 void		__C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t,
91 		    bus_size_t, u_int8_t *, bus_size_t);
92 void		__C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t,
93 		    bus_size_t, u_int16_t *, bus_size_t);
94 void		__C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t,
95 		    bus_size_t, u_int32_t *, bus_size_t);
96 void		__C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t,
97 		    bus_size_t, u_int64_t *, bus_size_t);
98 
99 /* read region */
100 void		__C(CHIP,_io_read_region_1)(void *, bus_space_handle_t,
101 		    bus_size_t, u_int8_t *, bus_size_t);
102 void		__C(CHIP,_io_read_region_2)(void *, bus_space_handle_t,
103 		    bus_size_t, u_int16_t *, bus_size_t);
104 void		__C(CHIP,_io_read_region_4)(void *, bus_space_handle_t,
105 		    bus_size_t, u_int32_t *, bus_size_t);
106 void		__C(CHIP,_io_read_region_8)(void *, bus_space_handle_t,
107 		    bus_size_t, u_int64_t *, bus_size_t);
108 
109 /* write (single) */
110 inline void	__C(CHIP,_io_write_1)(void *, bus_space_handle_t,
111 		    bus_size_t, u_int8_t);
112 inline void	__C(CHIP,_io_write_2)(void *, bus_space_handle_t,
113 		    bus_size_t, u_int16_t);
114 inline void	__C(CHIP,_io_write_4)(void *, bus_space_handle_t,
115 		    bus_size_t, u_int32_t);
116 inline void	__C(CHIP,_io_write_8)(void *, bus_space_handle_t,
117 		    bus_size_t, u_int64_t);
118 
119 /* write multiple */
120 void		__C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t,
121 		    bus_size_t, const u_int8_t *, bus_size_t);
122 void		__C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t,
123 		    bus_size_t, const u_int16_t *, bus_size_t);
124 void		__C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t,
125 		    bus_size_t, const u_int32_t *, bus_size_t);
126 void		__C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t,
127 		    bus_size_t, const u_int64_t *, bus_size_t);
128 
129 /* write region */
130 void		__C(CHIP,_io_write_region_1)(void *, bus_space_handle_t,
131 		    bus_size_t, const u_int8_t *, bus_size_t);
132 void		__C(CHIP,_io_write_region_2)(void *, bus_space_handle_t,
133 		    bus_size_t, const u_int16_t *, bus_size_t);
134 void		__C(CHIP,_io_write_region_4)(void *, bus_space_handle_t,
135 		    bus_size_t, const u_int32_t *, bus_size_t);
136 void		__C(CHIP,_io_write_region_8)(void *, bus_space_handle_t,
137 		    bus_size_t, const u_int64_t *, bus_size_t);
138 
139 /* set multiple */
140 void		__C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t,
141 		    bus_size_t, u_int8_t, bus_size_t);
142 void		__C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t,
143 		    bus_size_t, u_int16_t, bus_size_t);
144 void		__C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t,
145 		    bus_size_t, u_int32_t, bus_size_t);
146 void		__C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t,
147 		    bus_size_t, u_int64_t, bus_size_t);
148 
149 /* set region */
150 void		__C(CHIP,_io_set_region_1)(void *, bus_space_handle_t,
151 		    bus_size_t, u_int8_t, bus_size_t);
152 void		__C(CHIP,_io_set_region_2)(void *, bus_space_handle_t,
153 		    bus_size_t, u_int16_t, bus_size_t);
154 void		__C(CHIP,_io_set_region_4)(void *, bus_space_handle_t,
155 		    bus_size_t, u_int32_t, bus_size_t);
156 void		__C(CHIP,_io_set_region_8)(void *, bus_space_handle_t,
157 		    bus_size_t, u_int64_t, bus_size_t);
158 
159 /* copy */
160 void		__C(CHIP,_io_copy_1)(void *, bus_space_handle_t,
161 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
162 void		__C(CHIP,_io_copy_2)(void *, bus_space_handle_t,
163 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
164 void		__C(CHIP,_io_copy_4)(void *, bus_space_handle_t,
165 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
166 void		__C(CHIP,_io_copy_8)(void *, bus_space_handle_t,
167 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
168 
169 /* read multiple raw */
170 void		__C(CHIP,_io_read_raw_multi_2)(void *, bus_space_handle_t,
171 		    bus_size_t, u_int8_t *, bus_size_t);
172 void		__C(CHIP,_io_read_raw_multi_4)(void *, bus_space_handle_t,
173 		    bus_size_t, u_int8_t *, bus_size_t);
174 void		__C(CHIP,_io_read_raw_multi_8)(void *, bus_space_handle_t,
175 		    bus_size_t, u_int8_t *, bus_size_t);
176 
177 /* write multiple raw */
178 void		__C(CHIP,_io_write_raw_multi_2)(void *,
179 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
180 		    bus_size_t);
181 void		__C(CHIP,_io_write_raw_multi_4)(void *,
182 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
183 		    bus_size_t);
184 void		__C(CHIP,_io_write_raw_multi_8)(void *,
185 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
186 		    bus_size_t);
187 
188 void
189 __C(CHIP,_bus_io_init)(t, v)
190 	bus_space_tag_t t;
191 	void *v;
192 {
193 	struct extent *ex;
194 
195 	/*
196 	 * Initialize the bus space tag.
197 	 */
198 
199 	/* cookie */
200 	t->abs_cookie =		v;
201 
202 	/* mapping/unmapping */
203 	t->abs_map =		__C(CHIP,_io_map);
204 	t->abs_unmap =		__C(CHIP,_io_unmap);
205 	t->abs_subregion =	__C(CHIP,_io_subregion);
206 
207 	/* allocation/deallocation */
208 	t->abs_alloc =		__C(CHIP,_io_alloc);
209 	t->abs_free = 		__C(CHIP,_io_free);
210 
211 	/* get kernel virtual address */
212 	t->abs_vaddr =		__C(CHIP,_io_vaddr);
213 
214 	/* barrier */
215 	t->abs_barrier =	__C(CHIP,_io_barrier);
216 
217 	/* read (single) */
218 	t->abs_r_1 =		__C(CHIP,_io_read_1);
219 	t->abs_r_2 =		__C(CHIP,_io_read_2);
220 	t->abs_r_4 =		__C(CHIP,_io_read_4);
221 	t->abs_r_8 =		__C(CHIP,_io_read_8);
222 
223 	/* read multiple */
224 	t->abs_rm_1 =		__C(CHIP,_io_read_multi_1);
225 	t->abs_rm_2 =		__C(CHIP,_io_read_multi_2);
226 	t->abs_rm_4 =		__C(CHIP,_io_read_multi_4);
227 	t->abs_rm_8 =		__C(CHIP,_io_read_multi_8);
228 
229 	/* read region */
230 	t->abs_rr_1 =		__C(CHIP,_io_read_region_1);
231 	t->abs_rr_2 =		__C(CHIP,_io_read_region_2);
232 	t->abs_rr_4 =		__C(CHIP,_io_read_region_4);
233 	t->abs_rr_8 =		__C(CHIP,_io_read_region_8);
234 
235 	/* write (single) */
236 	t->abs_w_1 =		__C(CHIP,_io_write_1);
237 	t->abs_w_2 =		__C(CHIP,_io_write_2);
238 	t->abs_w_4 =		__C(CHIP,_io_write_4);
239 	t->abs_w_8 =		__C(CHIP,_io_write_8);
240 
241 	/* write multiple */
242 	t->abs_wm_1 =		__C(CHIP,_io_write_multi_1);
243 	t->abs_wm_2 =		__C(CHIP,_io_write_multi_2);
244 	t->abs_wm_4 =		__C(CHIP,_io_write_multi_4);
245 	t->abs_wm_8 =		__C(CHIP,_io_write_multi_8);
246 
247 	/* write region */
248 	t->abs_wr_1 =		__C(CHIP,_io_write_region_1);
249 	t->abs_wr_2 =		__C(CHIP,_io_write_region_2);
250 	t->abs_wr_4 =		__C(CHIP,_io_write_region_4);
251 	t->abs_wr_8 =		__C(CHIP,_io_write_region_8);
252 
253 	/* set multiple */
254 	t->abs_sm_1 =		__C(CHIP,_io_set_multi_1);
255 	t->abs_sm_2 =		__C(CHIP,_io_set_multi_2);
256 	t->abs_sm_4 =		__C(CHIP,_io_set_multi_4);
257 	t->abs_sm_8 =		__C(CHIP,_io_set_multi_8);
258 
259 	/* set region */
260 	t->abs_sr_1 =		__C(CHIP,_io_set_region_1);
261 	t->abs_sr_2 =		__C(CHIP,_io_set_region_2);
262 	t->abs_sr_4 =		__C(CHIP,_io_set_region_4);
263 	t->abs_sr_8 =		__C(CHIP,_io_set_region_8);
264 
265 	/* copy */
266 	t->abs_c_1 =		__C(CHIP,_io_copy_1);
267 	t->abs_c_2 =		__C(CHIP,_io_copy_2);
268 	t->abs_c_4 =		__C(CHIP,_io_copy_4);
269 	t->abs_c_8 =		__C(CHIP,_io_copy_8);
270 
271 	/* read multiple raw */
272 	t->abs_rrm_2 =		__C(CHIP,_io_read_raw_multi_2);
273 	t->abs_rrm_4 =		__C(CHIP,_io_read_raw_multi_4);
274 	t->abs_rrm_8 =		__C(CHIP,_io_read_raw_multi_8);
275 
276 	/* write multiple raw*/
277 	t->abs_wrm_2 =		__C(CHIP,_io_write_raw_multi_2);
278 	t->abs_wrm_4 =		__C(CHIP,_io_write_raw_multi_4);
279 	t->abs_wrm_8 =		__C(CHIP,_io_write_raw_multi_8);
280 
281 	ex = extent_create(CHIP_EXTENT_NAME(v), 0x0UL, 0xffffffffUL,
282 	    M_DEVBUF, (caddr_t)CHIP_EXTENT_STORAGE(v),
283 	    sizeof(CHIP_EXTENT_STORAGE(v)), EX_NOWAIT|EX_NOCOALESCE);
284 
285 	CHIP_IO_EXTENT(v) = ex;
286 }
287 
288 int
289 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp)
290 	void *v;
291 	bus_addr_t ioaddr;
292 	bus_size_t iosize;
293 	int flags;
294 	bus_space_handle_t *iohp;
295 {
296 	int error;
297 
298 	/*
299 	 * Can't map i/o space linearly.
300 	 */
301 	if (flags & BUS_SPACE_MAP_LINEAR)
302 		return (EOPNOTSUPP);
303 
304 #ifdef EXTENT_DEBUG
305 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
306 #endif
307         error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
308             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
309 	if (error) {
310 #ifdef EXTENT_DEBUG
311 		printf("io: allocation failed (%d)\n", error);
312 		extent_print(CHIP_IO_EXTENT(v));
313 #endif
314 		return (error);
315 	}
316 
317 	*iohp = ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v)) + ioaddr;
318 
319 	return (0);
320 }
321 
322 void
323 __C(CHIP,_io_unmap)(v, ioh, iosize)
324 	void *v;
325 	bus_space_handle_t ioh;
326 	bus_size_t iosize;
327 {
328 	bus_addr_t ioaddr;
329 	int error;
330 
331 #ifdef EXTENT_DEBUG
332 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
333 #endif
334 
335 	ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v));
336 
337 #ifdef EXTENT_DEBUG
338 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
339 #endif
340         error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
341             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
342 	if (error) {
343 		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
344 		   __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
345 		   error);
346 #ifdef EXTENT_DEBUG
347 		extent_print(CHIP_IO_EXTENT(v));
348 #endif
349 	}
350 }
351 
352 int
353 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
354 	void *v;
355 	bus_space_handle_t ioh, *nioh;
356 	bus_size_t offset, size;
357 {
358 
359 	*nioh = ioh + offset;
360 	return (0);
361 }
362 
363 int
364 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags,
365     addrp, bshp)
366 	void *v;
367 	bus_addr_t rstart, rend, *addrp;
368 	bus_size_t size, align, boundary;
369 	int flags;
370 	bus_space_handle_t *bshp;
371 {
372 
373 	/* XXX XXX XXX XXX XXX XXX */
374 	panic("%s not implemented", __S(__C(CHIP,_io_alloc)));
375 }
376 
377 void
378 __C(CHIP,_io_free)(v, bsh, size)
379 	void *v;
380 	bus_space_handle_t bsh;
381 	bus_size_t size;
382 {
383 
384 	/* XXX XXX XXX XXX XXX XXX */
385 	panic("%s not implemented", __S(__C(CHIP,_io_free)));
386 }
387 
388 void *
389 __C(CHIP,_io_vaddr)(v, bsh)
390 	void *v;
391 	bus_space_handle_t bsh;
392 {
393 	/*
394 	 * _io_map() catches BUS_SPACE_MAP_LINEAR,
395 	 * so we shouldn't get here
396 	 */
397 	panic("_io_vaddr");
398 }
399 
400 inline void
401 __C(CHIP,_io_barrier)(v, h, o, l, f)
402 	void *v;
403 	bus_space_handle_t h;
404 	bus_size_t o, l;
405 	int f;
406 {
407 
408 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
409 		alpha_mb();
410 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
411 		alpha_wmb();
412 }
413 
414 inline u_int8_t
415 __C(CHIP,_io_read_1)(v, ioh, off)
416 	void *v;
417 	bus_space_handle_t ioh;
418 	bus_size_t off;
419 {
420 	bus_addr_t addr;
421 
422 	addr = ioh + off;
423 	alpha_mb();
424 	return (alpha_ldbu((u_int8_t *)addr));
425 }
426 
427 inline u_int16_t
428 __C(CHIP,_io_read_2)(v, ioh, off)
429 	void *v;
430 	bus_space_handle_t ioh;
431 	bus_size_t off;
432 {
433 	bus_addr_t addr;
434 
435 	addr = ioh + off;
436 #ifdef DIAGNOSTIC
437 	if (addr & 1)
438 		panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned",
439 		    addr);
440 #endif
441 	alpha_mb();
442 	return (alpha_ldwu((u_int16_t *)addr));
443 }
444 
445 inline u_int32_t
446 __C(CHIP,_io_read_4)(v, ioh, off)
447 	void *v;
448 	bus_space_handle_t ioh;
449 	bus_size_t off;
450 {
451 	bus_addr_t addr;
452 
453 	addr = ioh + off;
454 #ifdef DIAGNOSTIC
455 	if (addr & 3)
456 		panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned",
457 		    addr);
458 #endif
459 	alpha_mb();
460 	return (*(u_int32_t *)addr);
461 }
462 
463 inline u_int64_t
464 __C(CHIP,_io_read_8)(v, ioh, off)
465 	void *v;
466 	bus_space_handle_t ioh;
467 	bus_size_t off;
468 {
469 
470 	/* XXX XXX XXX */
471 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
472 }
473 
474 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
475 void									\
476 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
477 	void *v;							\
478 	bus_space_handle_t h;						\
479 	bus_size_t o, c;						\
480 	TYPE *a;							\
481 {									\
482 									\
483 	while (c-- > 0) {						\
484 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
485 		    BUS_SPACE_BARRIER_READ);				\
486 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
487 	}								\
488 }
489 CHIP_io_read_multi_N(1,u_int8_t)
490 CHIP_io_read_multi_N(2,u_int16_t)
491 CHIP_io_read_multi_N(4,u_int32_t)
492 CHIP_io_read_multi_N(8,u_int64_t)
493 
494 #define CHIP_io_read_region_N(BYTES,TYPE)				\
495 void									\
496 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
497 	void *v;							\
498 	bus_space_handle_t h;						\
499 	bus_size_t o, c;						\
500 	TYPE *a;							\
501 {									\
502 									\
503 	while (c-- > 0) {						\
504 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
505 		o += sizeof *a;						\
506 	}								\
507 }
508 CHIP_io_read_region_N(1,u_int8_t)
509 CHIP_io_read_region_N(2,u_int16_t)
510 CHIP_io_read_region_N(4,u_int32_t)
511 CHIP_io_read_region_N(8,u_int64_t)
512 
513 inline void
514 __C(CHIP,_io_write_1)(v, ioh, off, val)
515 	void *v;
516 	bus_space_handle_t ioh;
517 	bus_size_t off;
518 	u_int8_t val;
519 {
520 	bus_addr_t addr;
521 
522 	addr = ioh + off;
523 	alpha_stb((u_int8_t *)addr, val);
524         alpha_mb();
525 }
526 
527 inline void
528 __C(CHIP,_io_write_2)(v, ioh, off, val)
529 	void *v;
530 	bus_space_handle_t ioh;
531 	bus_size_t off;
532 	u_int16_t val;
533 {
534 	bus_addr_t addr;
535 
536 	addr = ioh + off;
537 #ifdef DIAGNOSTIC
538 	if (addr & 1)
539 		panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned",
540 		    addr);
541 #endif
542 	alpha_stw((u_int16_t *)addr, val);
543 	alpha_mb();
544 }
545 
546 inline void
547 __C(CHIP,_io_write_4)(v, ioh, off, val)
548 	void *v;
549 	bus_space_handle_t ioh;
550 	bus_size_t off;
551 	u_int32_t val;
552 {
553 	bus_addr_t addr;
554 
555 	addr = ioh + off;
556 #ifdef DIAGNOSTIC
557 	if (addr & 3)
558 		panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned",
559 		    addr);
560 #endif
561 	*(u_int32_t *)addr = val;
562 	alpha_mb();
563 }
564 
565 inline void
566 __C(CHIP,_io_write_8)(v, ioh, off, val)
567 	void *v;
568 	bus_space_handle_t ioh;
569 	bus_size_t off;
570 	u_int64_t val;
571 {
572 
573 	/* XXX XXX XXX */
574 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
575 	alpha_mb();
576 }
577 
578 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
579 void									\
580 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
581 	void *v;							\
582 	bus_space_handle_t h;						\
583 	bus_size_t o, c;						\
584 	const TYPE *a;							\
585 {									\
586 									\
587 	while (c-- > 0) {						\
588 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
589 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
590 		    BUS_SPACE_BARRIER_WRITE);				\
591 	}								\
592 }
593 CHIP_io_write_multi_N(1,u_int8_t)
594 CHIP_io_write_multi_N(2,u_int16_t)
595 CHIP_io_write_multi_N(4,u_int32_t)
596 CHIP_io_write_multi_N(8,u_int64_t)
597 
598 #define CHIP_io_write_region_N(BYTES,TYPE)				\
599 void									\
600 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
601 	void *v;							\
602 	bus_space_handle_t h;						\
603 	bus_size_t o, c;						\
604 	const TYPE *a;							\
605 {									\
606 									\
607 	while (c-- > 0) {						\
608 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
609 		o += sizeof *a;						\
610 	}								\
611 }
612 CHIP_io_write_region_N(1,u_int8_t)
613 CHIP_io_write_region_N(2,u_int16_t)
614 CHIP_io_write_region_N(4,u_int32_t)
615 CHIP_io_write_region_N(8,u_int64_t)
616 
617 #define CHIP_io_set_multi_N(BYTES,TYPE)					\
618 void									\
619 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c)			\
620 	void *v;							\
621 	bus_space_handle_t h;						\
622 	bus_size_t o, c;						\
623 	TYPE val;							\
624 {									\
625 									\
626 	while (c-- > 0) {						\
627 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
628 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
629 		    BUS_SPACE_BARRIER_WRITE);				\
630 	}								\
631 }
632 CHIP_io_set_multi_N(1,u_int8_t)
633 CHIP_io_set_multi_N(2,u_int16_t)
634 CHIP_io_set_multi_N(4,u_int32_t)
635 CHIP_io_set_multi_N(8,u_int64_t)
636 
637 #define CHIP_io_set_region_N(BYTES,TYPE)				\
638 void									\
639 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c)			\
640 	void *v;							\
641 	bus_space_handle_t h;						\
642 	bus_size_t o, c;						\
643 	TYPE val;							\
644 {									\
645 									\
646 	while (c-- > 0) {						\
647 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
648 		o += sizeof val;					\
649 	}								\
650 }
651 CHIP_io_set_region_N(1,u_int8_t)
652 CHIP_io_set_region_N(2,u_int16_t)
653 CHIP_io_set_region_N(4,u_int32_t)
654 CHIP_io_set_region_N(8,u_int64_t)
655 
656 #define	CHIP_io_copy_N(BYTES)						\
657 void									\
658 __C(__C(CHIP,_io_copy_),BYTES)(v, h1, o1, h2, o2, c)			\
659 	void *v;							\
660 	bus_space_handle_t h1, h2;					\
661 	bus_size_t o1, o2, c;						\
662 {									\
663 	bus_size_t i, o;						\
664 									\
665 	for (i = 0, o = 0; i < c; i++, o += BYTES)			\
666 		__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,		\
667 		    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o));	\
668 }
669 CHIP_io_copy_N(1)
670 CHIP_io_copy_N(2)
671 CHIP_io_copy_N(4)
672 CHIP_io_copy_N(8)
673 
674 #define CHIP_io_read_raw_multi_N(BYTES,TYPE)				\
675 void									\
676 __C(__C(CHIP,_io_read_raw_multi_),BYTES)(v, h, o, a, c)			\
677 	void *v;							\
678 	bus_space_handle_t h;						\
679 	bus_size_t o, c;						\
680 	u_int8_t *a;							\
681 {									\
682 	TYPE temp;							\
683 	int i;								\
684 									\
685 	while (c > 0) {							\
686 		__C(CHIP,_io_barrier)(v, h, o, BYTES,			\
687 		    BUS_SPACE_BARRIER_READ);				\
688 		temp = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
689 		i = MIN(c, BYTES);					\
690 		c -= i;							\
691 		while (i--) {						\
692 			*a++ = temp & 0xff;				\
693 			temp >>= 8;					\
694 		}							\
695 	}								\
696 }
697 CHIP_io_read_raw_multi_N(2,u_int16_t)
698 CHIP_io_read_raw_multi_N(4,u_int32_t)
699 CHIP_io_read_raw_multi_N(8,u_int64_t)
700 
701 #define CHIP_io_write_raw_multi_N(BYTES,TYPE)				\
702 void									\
703 __C(__C(CHIP,_io_write_raw_multi_),BYTES)(v, h, o, a, c)		\
704 	void *v;							\
705 	bus_space_handle_t h;						\
706 	bus_size_t o, c;						\
707 	const u_int8_t *a;						\
708 {									\
709 	TYPE temp;							\
710 	int i;								\
711 									\
712 	while (c > 0) {							\
713 		temp = 0;						\
714 		for (i = BYTES - 1; i >= 0; i--) {			\
715 			temp <<= 8;					\
716 			if (i < c)					\
717 				temp |= *(a + i);			\
718 		}							\
719 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, temp);		\
720 		__C(CHIP,_io_barrier)(v, h, o, BYTES,			\
721 		    BUS_SPACE_BARRIER_WRITE);				\
722 		i = MIN(c, BYTES); 					\
723 		c -= i;							\
724 		a += i;							\
725 	}								\
726 }
727 CHIP_io_write_raw_multi_N(2,u_int16_t)
728 CHIP_io_write_raw_multi_N(4,u_int32_t)
729 CHIP_io_write_raw_multi_N(8,u_int64_t)
730