1 /*	$OpenBSD: pci_swiz_bus_io_chipdep.c,v 1.5 2008/07/19 17:10:03 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 #define	__C(A,B)	__CONCAT(A,B)
43 #define	__S(S)		__STRING(S)
44 
45 #ifndef	CHIP_EXTENT_NAME
46 #define	CHIP_EXTENT_NAME(v)	__S(__C(CHIP,_bus_io))
47 #endif
48 
49 #ifndef	CHIP_EXTENT_STORAGE
50 #define CHIP_EXTENT_STORAGE(v)	__C(CHIP,_io_ex_storage)
51 static long
52     __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
53 #endif
54 
55 /* mapping/unmapping */
56 int		__C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int,
57 		    bus_space_handle_t *);
58 void		__C(CHIP,_io_unmap)(void *, bus_space_handle_t,
59 		    bus_size_t);
60 int		__C(CHIP,_io_subregion)(void *, bus_space_handle_t,
61 		    bus_size_t, bus_size_t, bus_space_handle_t *);
62 
63 /* allocation/deallocation */
64 int		__C(CHIP,_io_alloc)(void *, bus_addr_t, bus_addr_t,
65 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
66                     bus_space_handle_t *);
67 void		__C(CHIP,_io_free)(void *, bus_space_handle_t,
68 		    bus_size_t);
69 
70 /* barrier */
71 inline void	__C(CHIP,_io_barrier)(void *, bus_space_handle_t,
72 		    bus_size_t, bus_size_t, int);
73 
74 /* read (single) */
75 inline u_int8_t	__C(CHIP,_io_read_1)(void *, bus_space_handle_t,
76 		    bus_size_t);
77 inline u_int16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t,
78 		    bus_size_t);
79 inline u_int32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t,
80 		    bus_size_t);
81 inline u_int64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t,
82 		    bus_size_t);
83 
84 /* read multiple */
85 void		__C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t,
86 		    bus_size_t, u_int8_t *, bus_size_t);
87 void		__C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t,
88 		    bus_size_t, u_int16_t *, bus_size_t);
89 void		__C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t,
90 		    bus_size_t, u_int32_t *, bus_size_t);
91 void		__C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t,
92 		    bus_size_t, u_int64_t *, bus_size_t);
93 
94 /* read region */
95 void		__C(CHIP,_io_read_region_1)(void *, bus_space_handle_t,
96 		    bus_size_t, u_int8_t *, bus_size_t);
97 void		__C(CHIP,_io_read_region_2)(void *, bus_space_handle_t,
98 		    bus_size_t, u_int16_t *, bus_size_t);
99 void		__C(CHIP,_io_read_region_4)(void *, bus_space_handle_t,
100 		    bus_size_t, u_int32_t *, bus_size_t);
101 void		__C(CHIP,_io_read_region_8)(void *, bus_space_handle_t,
102 		    bus_size_t, u_int64_t *, bus_size_t);
103 
104 /* write (single) */
105 inline void	__C(CHIP,_io_write_1)(void *, bus_space_handle_t,
106 		    bus_size_t, u_int8_t);
107 inline void	__C(CHIP,_io_write_2)(void *, bus_space_handle_t,
108 		    bus_size_t, u_int16_t);
109 inline void	__C(CHIP,_io_write_4)(void *, bus_space_handle_t,
110 		    bus_size_t, u_int32_t);
111 inline void	__C(CHIP,_io_write_8)(void *, bus_space_handle_t,
112 		    bus_size_t, u_int64_t);
113 
114 /* write multiple */
115 void		__C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t,
116 		    bus_size_t, const u_int8_t *, bus_size_t);
117 void		__C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t,
118 		    bus_size_t, const u_int16_t *, bus_size_t);
119 void		__C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t,
120 		    bus_size_t, const u_int32_t *, bus_size_t);
121 void		__C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t,
122 		    bus_size_t, const u_int64_t *, bus_size_t);
123 
124 /* write region */
125 void		__C(CHIP,_io_write_region_1)(void *, bus_space_handle_t,
126 		    bus_size_t, const u_int8_t *, bus_size_t);
127 void		__C(CHIP,_io_write_region_2)(void *, bus_space_handle_t,
128 		    bus_size_t, const u_int16_t *, bus_size_t);
129 void		__C(CHIP,_io_write_region_4)(void *, bus_space_handle_t,
130 		    bus_size_t, const u_int32_t *, bus_size_t);
131 void		__C(CHIP,_io_write_region_8)(void *, bus_space_handle_t,
132 		    bus_size_t, const u_int64_t *, bus_size_t);
133 
134 /* set multiple */
135 void		__C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t,
136 		    bus_size_t, u_int8_t, bus_size_t);
137 void		__C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t,
138 		    bus_size_t, u_int16_t, bus_size_t);
139 void		__C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t,
140 		    bus_size_t, u_int32_t, bus_size_t);
141 void		__C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t,
142 		    bus_size_t, u_int64_t, bus_size_t);
143 
144 /* set region */
145 void		__C(CHIP,_io_set_region_1)(void *, bus_space_handle_t,
146 		    bus_size_t, u_int8_t, bus_size_t);
147 void		__C(CHIP,_io_set_region_2)(void *, bus_space_handle_t,
148 		    bus_size_t, u_int16_t, bus_size_t);
149 void		__C(CHIP,_io_set_region_4)(void *, bus_space_handle_t,
150 		    bus_size_t, u_int32_t, bus_size_t);
151 void		__C(CHIP,_io_set_region_8)(void *, bus_space_handle_t,
152 		    bus_size_t, u_int64_t, bus_size_t);
153 
154 /* copy */
155 void		__C(CHIP,_io_copy_1)(void *, bus_space_handle_t,
156 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
157 void		__C(CHIP,_io_copy_2)(void *, bus_space_handle_t,
158 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
159 void		__C(CHIP,_io_copy_4)(void *, bus_space_handle_t,
160 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
161 void		__C(CHIP,_io_copy_8)(void *, bus_space_handle_t,
162 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
163 
164 /* read multiple raw */
165 void		__C(CHIP,_io_read_raw_multi_2)(void *, bus_space_handle_t,
166 		    bus_size_t, u_int8_t *, bus_size_t);
167 void		__C(CHIP,_io_read_raw_multi_4)(void *, bus_space_handle_t,
168 		    bus_size_t, u_int8_t *, bus_size_t);
169 void		__C(CHIP,_io_read_raw_multi_8)(void *, bus_space_handle_t,
170 		    bus_size_t, u_int8_t *, bus_size_t);
171 
172 /* write multiple raw */
173 void		__C(CHIP,_io_write_raw_multi_2)(void *,
174 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
175 		    bus_size_t);
176 void		__C(CHIP,_io_write_raw_multi_4)(void *,
177 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
178 		    bus_size_t);
179 void		__C(CHIP,_io_write_raw_multi_8)(void *,
180 		    bus_space_handle_t, bus_size_t, const u_int8_t *,
181 		    bus_size_t);
182 
183 void
184 __C(CHIP,_bus_io_init)(t, v)
185 	bus_space_tag_t t;
186 	void *v;
187 {
188 	struct extent *ex;
189 
190 	/*
191 	 * Initialize the bus space tag.
192 	 */
193 
194 	/* cookie */
195 	t->abs_cookie = v;
196 
197 	/* mapping/unmapping */
198 	t->abs_map =		__C(CHIP,_io_map);
199 	t->abs_unmap =		__C(CHIP,_io_unmap);
200 	t->abs_subregion =	__C(CHIP,_io_subregion);
201 
202 	/* allocation/deallocation */
203 	t->abs_alloc =		__C(CHIP,_io_alloc);
204 	t->abs_free =		__C(CHIP,_io_free);
205 
206 	/* barrier */
207 	t->abs_barrier =	__C(CHIP,_io_barrier);
208 
209 	/* read (single) */
210 	t->abs_r_1 =		__C(CHIP,_io_read_1);
211 	t->abs_r_2 =		__C(CHIP,_io_read_2);
212 	t->abs_r_4 =		__C(CHIP,_io_read_4);
213 	t->abs_r_8 =		__C(CHIP,_io_read_8);
214 
215 	/* read multiple */
216 	t->abs_rm_1 =		__C(CHIP,_io_read_multi_1);
217 	t->abs_rm_2 =		__C(CHIP,_io_read_multi_2);
218 	t->abs_rm_4 =		__C(CHIP,_io_read_multi_4);
219 	t->abs_rm_8 =		__C(CHIP,_io_read_multi_8);
220 
221 	/* read region */
222 	t->abs_rr_1 =		__C(CHIP,_io_read_region_1);
223 	t->abs_rr_2 =		__C(CHIP,_io_read_region_2);
224 	t->abs_rr_4 =		__C(CHIP,_io_read_region_4);
225 	t->abs_rr_8 =		__C(CHIP,_io_read_region_8);
226 
227 	/* write (single) */
228 	t->abs_w_1 =		__C(CHIP,_io_write_1);
229 	t->abs_w_2 =		__C(CHIP,_io_write_2);
230 	t->abs_w_4 =		__C(CHIP,_io_write_4);
231 	t->abs_w_8 =		__C(CHIP,_io_write_8);
232 
233 	/* write multiple */
234 	t->abs_wm_1 =		__C(CHIP,_io_write_multi_1);
235 	t->abs_wm_2 =		__C(CHIP,_io_write_multi_2);
236 	t->abs_wm_4 =		__C(CHIP,_io_write_multi_4);
237 	t->abs_wm_8 =		__C(CHIP,_io_write_multi_8);
238 
239 	/* write region */
240 	t->abs_wr_1 =		__C(CHIP,_io_write_region_1);
241 	t->abs_wr_2 =		__C(CHIP,_io_write_region_2);
242 	t->abs_wr_4 =		__C(CHIP,_io_write_region_4);
243 	t->abs_wr_8 =		__C(CHIP,_io_write_region_8);
244 
245 	/* set multiple */
246 	t->abs_sm_1 =		__C(CHIP,_io_set_multi_1);
247 	t->abs_sm_2 =		__C(CHIP,_io_set_multi_2);
248 	t->abs_sm_4 =		__C(CHIP,_io_set_multi_4);
249 	t->abs_sm_8 =		__C(CHIP,_io_set_multi_8);
250 
251 	/* set region */
252 	t->abs_sr_1 =		__C(CHIP,_io_set_region_1);
253 	t->abs_sr_2 =		__C(CHIP,_io_set_region_2);
254 	t->abs_sr_4 =		__C(CHIP,_io_set_region_4);
255 	t->abs_sr_8 =		__C(CHIP,_io_set_region_8);
256 
257 	/* copy */
258 	t->abs_c_1 =		__C(CHIP,_io_copy_1);
259 	t->abs_c_2 =		__C(CHIP,_io_copy_2);
260 	t->abs_c_4 =		__C(CHIP,_io_copy_4);
261 	t->abs_c_8 =		__C(CHIP,_io_copy_8);
262 
263 	/* read multiple raw */
264 	t->abs_rrm_2 =		__C(CHIP,_io_read_raw_multi_2);
265 	t->abs_rrm_4 =		__C(CHIP,_io_read_raw_multi_4);
266 	t->abs_rrm_8 =		__C(CHIP,_io_read_raw_multi_8);
267 
268 	/* write multiple raw*/
269 	t->abs_wrm_2 =		__C(CHIP,_io_write_raw_multi_2);
270 	t->abs_wrm_4 =		__C(CHIP,_io_write_raw_multi_4) ;
271 	t->abs_wrm_8 =		__C(CHIP,_io_write_raw_multi_8);
272 
273 
274 	/* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */
275 	ex = extent_create(CHIP_EXTENT_NAME(v), 0x0UL, 0xffffffffUL,
276 	    M_DEVBUF, (caddr_t)CHIP_EXTENT_STORAGE(v),
277 	    sizeof(CHIP_EXTENT_STORAGE(v)), EX_NOWAIT);
278 	extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT);
279 
280 #ifdef CHIP_IO_W1_BUS_START
281 #ifdef EXTENT_DEBUG
282 	printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W1_BUS_START(v),
283 	    CHIP_IO_W1_BUS_END(v));
284 #endif
285 	extent_free(ex, CHIP_IO_W1_BUS_START(v),
286 	    CHIP_IO_W1_BUS_END(v) - CHIP_IO_W1_BUS_START(v) + 1, EX_NOWAIT);
287 #endif
288 #ifdef CHIP_IO_W2_BUS_START
289 #ifdef EXTENT_DEBUG
290 	printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W2_BUS_START(v),
291 	    CHIP_IO_W2_BUS_END(v));
292 #endif
293 	extent_free(ex, CHIP_IO_W2_BUS_START(v),
294 	    CHIP_IO_W2_BUS_END(v) - CHIP_IO_W2_BUS_START(v) + 1, EX_NOWAIT);
295 #endif
296 
297 #ifdef EXTENT_DEBUG
298 	extent_print(ex);
299 #endif
300 	CHIP_IO_EXTENT(v) = ex;
301 }
302 
303 int
304 __C(CHIP,_io_map)(v, ioaddr, iosize, cacheable, iohp)
305 	void *v;
306 	bus_addr_t ioaddr;
307 	bus_size_t iosize;
308 	int cacheable;
309 	bus_space_handle_t *iohp;
310 {
311 	bus_addr_t ioend = ioaddr + (iosize - 1);
312 	int error;
313 
314 #ifdef EXTENT_DEBUG
315 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
316 #endif
317         error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
318             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
319 	if (error) {
320 #ifdef EXTENT_DEBUG
321 		printf("io: allocation failed (%d)\n", error);
322 		extent_print(CHIP_IO_EXTENT(v));
323 #endif
324 		return (error);
325 	}
326 
327 #ifdef CHIP_IO_W1_BUS_START
328 	if (ioaddr >= CHIP_IO_W1_BUS_START(v) &&
329 	    ioend <= CHIP_IO_W1_BUS_END(v)) {
330 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_SYS_START(v)) >> 5) +
331 		    (ioaddr - CHIP_IO_W1_BUS_START(v));
332 	} else
333 #endif
334 #ifdef CHIP_IO_W2_BUS_START
335 	if (ioaddr >= CHIP_IO_W2_BUS_START(v) &&
336 	    ioend <= CHIP_IO_W2_BUS_END(v)) {
337 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_SYS_START(v)) >> 5) +
338 		    (ioaddr - CHIP_IO_W2_BUS_START(v));
339 	} else
340 #endif
341 	{
342 #ifdef EXTENT_DEBUG
343 		printf("\n");
344 #ifdef CHIP_IO_W1_BUS_START
345 		printf("%s: window[1]=0x%lx-0x%lx\n",
346 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v),
347 		    CHIP_IO_W1_BUS_END(v));
348 #endif
349 #ifdef CHIP_IO_W2_BUS_START
350 		printf("%s: window[2]=0x%lx-0x%lx\n",
351 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v),
352 		    CHIP_IO_W2_BUS_END(v));
353 #endif
354 		panic("%s: don't know how to map %lx",
355 		    __S(__C(CHIP,_io_map)), ioaddr);
356 #endif
357 		return (EINVAL);
358 	}
359 
360 	return (0);
361 }
362 
363 void
364 __C(CHIP,_io_unmap)(v, ioh, iosize)
365 	void *v;
366 	bus_space_handle_t ioh;
367 	bus_size_t iosize;
368 {
369 	bus_addr_t ioaddr;
370 	int error;
371 
372 #ifdef EXTENT_DEBUG
373 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
374 #endif
375 
376 	ioh = ALPHA_K0SEG_TO_PHYS(ioh << 5) >> 5;
377 
378 #ifdef CHIP_IO_W1_BUS_START
379 	if ((ioh << 5) >= CHIP_IO_W1_SYS_START(v) &&
380 	    (ioh << 5) <= CHIP_IO_W1_SYS_END(v)) {
381 		ioaddr = CHIP_IO_W1_BUS_START(v) +
382 		    (ioh - (CHIP_IO_W1_SYS_START(v) >> 5));
383 	} else
384 #endif
385 #ifdef CHIP_IO_W2_BUS_START
386 	if ((ioh << 5) >= CHIP_IO_W2_SYS_START(v) &&
387 	    (ioh << 5) <= CHIP_IO_W2_SYS_END(v)) {
388 		ioaddr = CHIP_IO_W2_BUS_START(v) +
389 		    (ioh - (CHIP_IO_W2_SYS_START(v) >> 5));
390 	} else
391 #endif
392 	{
393 		printf("\n");
394 #ifdef CHIP_IO_W1_BUS_START
395 		printf("%s: sys window[1]=0x%lx-0x%lx\n",
396 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v),
397 		    CHIP_IO_W1_SYS_END(v));
398 #endif
399 #ifdef CHIP_IO_W2_BUS_START
400 		printf("%s: sys window[2]=0x%lx-0x%lx\n",
401 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v),
402 		    CHIP_IO_W2_SYS_END(v));
403 #endif
404 		panic("%s: don't know how to unmap %lx",
405 		    __S(__C(CHIP,_io_unmap)), (ioh << 5));
406 	}
407 
408 #ifdef EXTENT_DEBUG
409 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
410 #endif
411         error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
412             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
413 	if (error) {
414 		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
415 		   __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
416 		   error);
417 #ifdef EXTENT_DEBUG
418 		extent_print(CHIP_IO_EXTENT(v));
419 #endif
420 	}
421 }
422 
423 int
424 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
425 	void *v;
426 	bus_space_handle_t ioh, *nioh;
427 	bus_size_t offset, size;
428 {
429 
430 	*nioh = ioh + offset;
431 	return (0);
432 }
433 
434 int
435 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, cacheable,
436     addrp, bshp)
437 	void *v;
438 	bus_addr_t rstart, rend, *addrp;
439 	bus_size_t size, align, boundary;
440 	int cacheable;
441 	bus_space_handle_t *bshp;
442 {
443 
444 	/* XXX XXX XXX XXX XXX XXX */
445 	panic("%s not implemented", __S(__C(CHIP,_io_alloc)));
446 }
447 
448 void
449 __C(CHIP,_io_free)(v, bsh, size)
450 	void *v;
451 	bus_space_handle_t bsh;
452 	bus_size_t size;
453 {
454 
455 	/* XXX XXX XXX XXX XXX XXX */
456 	panic("%s not implemented", __S(__C(CHIP,_io_free)));
457 }
458 
459 inline void
460 __C(CHIP,_io_barrier)(v, h, o, l, f)
461 	void *v;
462 	bus_space_handle_t h;
463 	bus_size_t o, l;
464 	int f;
465 {
466 
467 	if ((f & BUS_BARRIER_READ) != 0)
468 		alpha_mb();
469 	else if ((f & BUS_BARRIER_WRITE) != 0)
470 		alpha_wmb();
471 }
472 
473 inline u_int8_t
474 __C(CHIP,_io_read_1)(v, ioh, off)
475 	void *v;
476 	bus_space_handle_t ioh;
477 	bus_size_t off;
478 {
479 	register bus_space_handle_t tmpioh;
480 	register u_int32_t *port, val;
481 	register u_int8_t rval;
482 	register int offset;
483 
484 	alpha_mb();
485 
486 	tmpioh = ioh + off;
487 	offset = tmpioh & 3;
488 	port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
489 	val = *port;
490 	rval = ((val) >> (8 * offset)) & 0xff;
491 
492 	return rval;
493 }
494 
495 inline u_int16_t
496 __C(CHIP,_io_read_2)(v, ioh, off)
497 	void *v;
498 	bus_space_handle_t ioh;
499 	bus_size_t off;
500 {
501 	register bus_space_handle_t tmpioh;
502 	register u_int32_t *port, val;
503 	register u_int16_t rval;
504 	register int offset;
505 
506 	alpha_mb();
507 
508 	tmpioh = ioh + off;
509 	offset = tmpioh & 3;
510 	port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
511 	val = *port;
512 	rval = ((val) >> (8 * offset)) & 0xffff;
513 
514 	return rval;
515 }
516 
517 inline u_int32_t
518 __C(CHIP,_io_read_4)(v, ioh, off)
519 	void *v;
520 	bus_space_handle_t ioh;
521 	bus_size_t off;
522 {
523 	register bus_space_handle_t tmpioh;
524 	register u_int32_t *port, val;
525 	register u_int32_t rval;
526 	register int offset;
527 
528 	alpha_mb();
529 
530 	tmpioh = ioh + off;
531 	offset = tmpioh & 3;
532 	port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
533 	val = *port;
534 #if 0
535 	rval = ((val) >> (8 * offset)) & 0xffffffff;
536 #else
537 	rval = val;
538 #endif
539 
540 	return rval;
541 }
542 
543 inline u_int64_t
544 __C(CHIP,_io_read_8)(v, ioh, off)
545 	void *v;
546 	bus_space_handle_t ioh;
547 	bus_size_t off;
548 {
549 
550 	/* XXX XXX XXX */
551 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
552 }
553 
554 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
555 void									\
556 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
557 	void *v;							\
558 	bus_space_handle_t h;						\
559 	bus_size_t o, c;						\
560 	TYPE *a;							\
561 {									\
562 									\
563 	while (c-- > 0) {						\
564 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
565 		    BUS_BARRIER_READ);					\
566 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
567 	}								\
568 }
569 CHIP_io_read_multi_N(1,u_int8_t)
570 CHIP_io_read_multi_N(2,u_int16_t)
571 CHIP_io_read_multi_N(4,u_int32_t)
572 CHIP_io_read_multi_N(8,u_int64_t)
573 
574 #define CHIP_io_read_region_N(BYTES,TYPE)				\
575 void									\
576 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
577 	void *v;							\
578 	bus_space_handle_t h;						\
579 	bus_size_t o, c;						\
580 	TYPE *a;							\
581 {									\
582 									\
583 	while (c-- > 0) {						\
584 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
585 		o += sizeof *a;						\
586 	}								\
587 }
588 CHIP_io_read_region_N(1,u_int8_t)
589 CHIP_io_read_region_N(2,u_int16_t)
590 CHIP_io_read_region_N(4,u_int32_t)
591 CHIP_io_read_region_N(8,u_int64_t)
592 
593 inline void
594 __C(CHIP,_io_write_1)(v, ioh, off, val)
595 	void *v;
596 	bus_space_handle_t ioh;
597 	bus_size_t off;
598 	u_int8_t val;
599 {
600 	register bus_space_handle_t tmpioh;
601 	register u_int32_t *port, nval;
602 	register int offset;
603 
604 	tmpioh = ioh + off;
605 	offset = tmpioh & 3;
606         nval = val << (8 * offset);
607         port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
608         *port = nval;
609         alpha_mb();
610 }
611 
612 inline void
613 __C(CHIP,_io_write_2)(v, ioh, off, val)
614 	void *v;
615 	bus_space_handle_t ioh;
616 	bus_size_t off;
617 	u_int16_t val;
618 {
619 	register bus_space_handle_t tmpioh;
620 	register u_int32_t *port, nval;
621 	register int offset;
622 
623 	tmpioh = ioh + off;
624 	offset = tmpioh & 3;
625         nval = val << (8 * offset);
626         port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
627         *port = nval;
628         alpha_mb();
629 }
630 
631 inline void
632 __C(CHIP,_io_write_4)(v, ioh, off, val)
633 	void *v;
634 	bus_space_handle_t ioh;
635 	bus_size_t off;
636 	u_int32_t val;
637 {
638 	register bus_space_handle_t tmpioh;
639 	register u_int32_t *port, nval;
640 	register int offset;
641 
642 	tmpioh = ioh + off;
643 	offset = tmpioh & 3;
644         nval = val /*<< (8 * offset)*/;
645         port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
646         *port = nval;
647         alpha_mb();
648 }
649 
650 inline void
651 __C(CHIP,_io_write_8)(v, ioh, off, val)
652 	void *v;
653 	bus_space_handle_t ioh;
654 	bus_size_t off;
655 	u_int64_t val;
656 {
657 
658 	/* XXX XXX XXX */
659 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
660 	alpha_mb();
661 }
662 
663 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
664 void									\
665 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
666 	void *v;							\
667 	bus_space_handle_t h;						\
668 	bus_size_t o, c;						\
669 	const TYPE *a;							\
670 {									\
671 									\
672 	while (c-- > 0) {						\
673 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
674 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
675 		    BUS_BARRIER_WRITE);					\
676 	}								\
677 }
678 CHIP_io_write_multi_N(1,u_int8_t)
679 CHIP_io_write_multi_N(2,u_int16_t)
680 CHIP_io_write_multi_N(4,u_int32_t)
681 CHIP_io_write_multi_N(8,u_int64_t)
682 
683 #define CHIP_io_write_region_N(BYTES,TYPE)				\
684 void									\
685 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
686 	void *v;							\
687 	bus_space_handle_t h;						\
688 	bus_size_t o, c;						\
689 	const TYPE *a;							\
690 {									\
691 									\
692 	while (c-- > 0) {						\
693 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
694 		o += sizeof *a;						\
695 	}								\
696 }
697 CHIP_io_write_region_N(1,u_int8_t)
698 CHIP_io_write_region_N(2,u_int16_t)
699 CHIP_io_write_region_N(4,u_int32_t)
700 CHIP_io_write_region_N(8,u_int64_t)
701 
702 #define CHIP_io_set_multi_N(BYTES,TYPE)					\
703 void									\
704 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c)			\
705 	void *v;							\
706 	bus_space_handle_t h;						\
707 	bus_size_t o, c;						\
708 	TYPE val;							\
709 {									\
710 									\
711 	while (c-- > 0) {						\
712 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
713 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
714 		    BUS_BARRIER_WRITE);					\
715 	}								\
716 }
717 CHIP_io_set_multi_N(1,u_int8_t)
718 CHIP_io_set_multi_N(2,u_int16_t)
719 CHIP_io_set_multi_N(4,u_int32_t)
720 CHIP_io_set_multi_N(8,u_int64_t)
721 
722 #define CHIP_io_set_region_N(BYTES,TYPE)				\
723 void									\
724 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c)			\
725 	void *v;							\
726 	bus_space_handle_t h;						\
727 	bus_size_t o, c;						\
728 	TYPE val;							\
729 {									\
730 									\
731 	while (c-- > 0) {						\
732 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
733 		o += sizeof val;					\
734 	}								\
735 }
736 CHIP_io_set_region_N(1,u_int8_t)
737 CHIP_io_set_region_N(2,u_int16_t)
738 CHIP_io_set_region_N(4,u_int32_t)
739 CHIP_io_set_region_N(8,u_int64_t)
740 
741 #define	CHIP_io_copy_N(BYTES)						\
742 void									\
743 __C(__C(CHIP,_io_copy_),BYTES)(v, h1, o1, h2, o2, c)			\
744 	void *v;							\
745 	bus_space_handle_t h1, h2;					\
746 	bus_size_t o1, o2, c;						\
747 {									\
748 	bus_size_t i, o;						\
749 									\
750 	for (i = 0, o = 0; i < c; i++, o += BYTES)			\
751 		__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,		\
752 		    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o));	\
753 }
754 CHIP_io_copy_N(1)
755 CHIP_io_copy_N(2)
756 CHIP_io_copy_N(4)
757 CHIP_io_copy_N(8)
758 
759 #define CHIP_io_read_raw_multi_N(BYTES,TYPE)				\
760 void									\
761 __C(__C(CHIP,_io_read_raw_multi_),BYTES)(v, h, o, a, c)			\
762 	void *v;							\
763 	bus_space_handle_t h;						\
764 	bus_size_t o, c;						\
765 	u_int8_t *a;							\
766 {									\
767 	TYPE temp;							\
768 	int i;								\
769 									\
770 	while (c > 0) {							\
771 		__C(CHIP,_io_barrier)(v, h, o, BYTES, BUS_BARRIER_READ); \
772 		temp = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
773 		i = MIN(c, BYTES);					\
774 		c -= i;							\
775 		while (i--) {						\
776 			*a++ = temp & 0xff;				\
777 			temp >>= 8;					\
778 		}							\
779 	}								\
780 }
781 CHIP_io_read_raw_multi_N(2,u_int16_t)
782 CHIP_io_read_raw_multi_N(4,u_int32_t)
783 CHIP_io_read_raw_multi_N(8,u_int64_t)
784 
785 #define CHIP_io_write_raw_multi_N(BYTES,TYPE)				\
786 void									\
787 __C(__C(CHIP,_io_write_raw_multi_),BYTES)(v, h, o, a, c)		\
788 	void *v;							\
789 	bus_space_handle_t h;						\
790 	bus_size_t o, c;						\
791 	const u_int8_t *a;						\
792 {									\
793 	TYPE temp;							\
794 	int i;								\
795 									\
796 	while (c > 0) {							\
797 		temp = 0;						\
798 		for (i = BYTES - 1; i >= 0; i--) {			\
799 			temp <<= 8;					\
800 			if (i < c)					\
801 				temp |= *(a + i);			\
802 		}							\
803 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, temp);		\
804 		__C(CHIP,_io_barrier)(v, h, o, BYTES, BUS_BARRIER_WRITE); \
805 		i = MIN(c, BYTES); 					\
806 		c -= i;							\
807 		a += i;							\
808 	}								\
809 }
810 CHIP_io_write_raw_multi_N(2,u_int16_t)
811 CHIP_io_write_raw_multi_N(4,u_int32_t)
812 CHIP_io_write_raw_multi_N(8,u_int64_t)
813