1 /*	$OpenBSD: pci_swiz_bus_io_chipdep.c,v 1.8 2009/09/17 19:28:20 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, flags, iohp)
305 	void *v;
306 	bus_addr_t ioaddr;
307 	bus_size_t iosize;
308 	int flags;
309 	bus_space_handle_t *iohp;
310 {
311 	bus_addr_t ioend = ioaddr + (iosize - 1);
312 	int error;
313 
314 	/*
315 	 * Can't map i/o space linearly.
316 	 */
317 	if (flags & BUS_SPACE_MAP_LINEAR)
318 		return (EOPNOTSUPP);
319 
320 #ifdef EXTENT_DEBUG
321 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
322 #endif
323         error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
324             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
325 	if (error) {
326 #ifdef EXTENT_DEBUG
327 		printf("io: allocation failed (%d)\n", error);
328 		extent_print(CHIP_IO_EXTENT(v));
329 #endif
330 		return (error);
331 	}
332 
333 #ifdef CHIP_IO_W1_BUS_START
334 	if (ioaddr >= CHIP_IO_W1_BUS_START(v) &&
335 	    ioend <= CHIP_IO_W1_BUS_END(v)) {
336 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_SYS_START(v)) >> 5) +
337 		    (ioaddr - CHIP_IO_W1_BUS_START(v));
338 	} else
339 #endif
340 #ifdef CHIP_IO_W2_BUS_START
341 	if (ioaddr >= CHIP_IO_W2_BUS_START(v) &&
342 	    ioend <= CHIP_IO_W2_BUS_END(v)) {
343 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_SYS_START(v)) >> 5) +
344 		    (ioaddr - CHIP_IO_W2_BUS_START(v));
345 	} else
346 #endif
347 	{
348 #ifdef EXTENT_DEBUG
349 		printf("\n");
350 #ifdef CHIP_IO_W1_BUS_START
351 		printf("%s: window[1]=0x%lx-0x%lx\n",
352 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v),
353 		    CHIP_IO_W1_BUS_END(v));
354 #endif
355 #ifdef CHIP_IO_W2_BUS_START
356 		printf("%s: window[2]=0x%lx-0x%lx\n",
357 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v),
358 		    CHIP_IO_W2_BUS_END(v));
359 #endif
360 		panic("%s: don't know how to map %lx",
361 		    __S(__C(CHIP,_io_map)), ioaddr);
362 #endif
363 		return (EINVAL);
364 	}
365 
366 	return (0);
367 }
368 
369 void
370 __C(CHIP,_io_unmap)(v, ioh, iosize)
371 	void *v;
372 	bus_space_handle_t ioh;
373 	bus_size_t iosize;
374 {
375 	bus_addr_t ioaddr;
376 	int error;
377 
378 #ifdef EXTENT_DEBUG
379 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
380 #endif
381 
382 	ioh = ALPHA_K0SEG_TO_PHYS(ioh << 5) >> 5;
383 
384 #ifdef CHIP_IO_W1_BUS_START
385 	if ((ioh << 5) >= CHIP_IO_W1_SYS_START(v) &&
386 	    (ioh << 5) <= CHIP_IO_W1_SYS_END(v)) {
387 		ioaddr = CHIP_IO_W1_BUS_START(v) +
388 		    (ioh - (CHIP_IO_W1_SYS_START(v) >> 5));
389 	} else
390 #endif
391 #ifdef CHIP_IO_W2_BUS_START
392 	if ((ioh << 5) >= CHIP_IO_W2_SYS_START(v) &&
393 	    (ioh << 5) <= CHIP_IO_W2_SYS_END(v)) {
394 		ioaddr = CHIP_IO_W2_BUS_START(v) +
395 		    (ioh - (CHIP_IO_W2_SYS_START(v) >> 5));
396 	} else
397 #endif
398 	{
399 		printf("\n");
400 #ifdef CHIP_IO_W1_BUS_START
401 		printf("%s: sys window[1]=0x%lx-0x%lx\n",
402 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v),
403 		    CHIP_IO_W1_SYS_END(v));
404 #endif
405 #ifdef CHIP_IO_W2_BUS_START
406 		printf("%s: sys window[2]=0x%lx-0x%lx\n",
407 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v),
408 		    CHIP_IO_W2_SYS_END(v));
409 #endif
410 		panic("%s: don't know how to unmap %lx",
411 		    __S(__C(CHIP,_io_unmap)), (ioh << 5));
412 	}
413 
414 #ifdef EXTENT_DEBUG
415 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
416 #endif
417         error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
418             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
419 	if (error) {
420 		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
421 		   __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
422 		   error);
423 #ifdef EXTENT_DEBUG
424 		extent_print(CHIP_IO_EXTENT(v));
425 #endif
426 	}
427 }
428 
429 int
430 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
431 	void *v;
432 	bus_space_handle_t ioh, *nioh;
433 	bus_size_t offset, size;
434 {
435 
436 	*nioh = ioh + offset;
437 	return (0);
438 }
439 
440 int
441 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags,
442     addrp, bshp)
443 	void *v;
444 	bus_addr_t rstart, rend, *addrp;
445 	bus_size_t size, align, boundary;
446 	int flags;
447 	bus_space_handle_t *bshp;
448 {
449 
450 	/* XXX XXX XXX XXX XXX XXX */
451 	panic("%s not implemented", __S(__C(CHIP,_io_alloc)));
452 }
453 
454 void
455 __C(CHIP,_io_free)(v, bsh, size)
456 	void *v;
457 	bus_space_handle_t bsh;
458 	bus_size_t size;
459 {
460 
461 	/* XXX XXX XXX XXX XXX XXX */
462 	panic("%s not implemented", __S(__C(CHIP,_io_free)));
463 }
464 
465 inline void
466 __C(CHIP,_io_barrier)(v, h, o, l, f)
467 	void *v;
468 	bus_space_handle_t h;
469 	bus_size_t o, l;
470 	int f;
471 {
472 
473 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
474 		alpha_mb();
475 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
476 		alpha_wmb();
477 }
478 
479 inline u_int8_t
480 __C(CHIP,_io_read_1)(v, ioh, off)
481 	void *v;
482 	bus_space_handle_t ioh;
483 	bus_size_t off;
484 {
485 	register bus_space_handle_t tmpioh;
486 	register u_int32_t *port, val;
487 	register u_int8_t rval;
488 	register int offset;
489 
490 	alpha_mb();
491 
492 	tmpioh = ioh + off;
493 	offset = tmpioh & 3;
494 	port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
495 	val = *port;
496 	rval = ((val) >> (8 * offset)) & 0xff;
497 
498 	return rval;
499 }
500 
501 inline u_int16_t
502 __C(CHIP,_io_read_2)(v, ioh, off)
503 	void *v;
504 	bus_space_handle_t ioh;
505 	bus_size_t off;
506 {
507 	register bus_space_handle_t tmpioh;
508 	register u_int32_t *port, val;
509 	register u_int16_t rval;
510 	register int offset;
511 
512 	alpha_mb();
513 
514 	tmpioh = ioh + off;
515 	offset = tmpioh & 3;
516 	port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
517 	val = *port;
518 	rval = ((val) >> (8 * offset)) & 0xffff;
519 
520 	return rval;
521 }
522 
523 inline u_int32_t
524 __C(CHIP,_io_read_4)(v, ioh, off)
525 	void *v;
526 	bus_space_handle_t ioh;
527 	bus_size_t off;
528 {
529 	register bus_space_handle_t tmpioh;
530 	register u_int32_t *port, val;
531 	register u_int32_t rval;
532 	register int offset;
533 
534 	alpha_mb();
535 
536 	tmpioh = ioh + off;
537 	offset = tmpioh & 3;
538 	port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
539 	val = *port;
540 #if 0
541 	rval = ((val) >> (8 * offset)) & 0xffffffff;
542 #else
543 	rval = val;
544 #endif
545 
546 	return rval;
547 }
548 
549 inline u_int64_t
550 __C(CHIP,_io_read_8)(v, ioh, off)
551 	void *v;
552 	bus_space_handle_t ioh;
553 	bus_size_t off;
554 {
555 
556 	/* XXX XXX XXX */
557 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
558 }
559 
560 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
561 void									\
562 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
563 	void *v;							\
564 	bus_space_handle_t h;						\
565 	bus_size_t o, c;						\
566 	TYPE *a;							\
567 {									\
568 									\
569 	while (c-- > 0) {						\
570 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
571 		    BUS_SPACE_BARRIER_READ);				\
572 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
573 	}								\
574 }
575 CHIP_io_read_multi_N(1,u_int8_t)
576 CHIP_io_read_multi_N(2,u_int16_t)
577 CHIP_io_read_multi_N(4,u_int32_t)
578 CHIP_io_read_multi_N(8,u_int64_t)
579 
580 #define CHIP_io_read_region_N(BYTES,TYPE)				\
581 void									\
582 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
583 	void *v;							\
584 	bus_space_handle_t h;						\
585 	bus_size_t o, c;						\
586 	TYPE *a;							\
587 {									\
588 									\
589 	while (c-- > 0) {						\
590 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
591 		o += sizeof *a;						\
592 	}								\
593 }
594 CHIP_io_read_region_N(1,u_int8_t)
595 CHIP_io_read_region_N(2,u_int16_t)
596 CHIP_io_read_region_N(4,u_int32_t)
597 CHIP_io_read_region_N(8,u_int64_t)
598 
599 inline void
600 __C(CHIP,_io_write_1)(v, ioh, off, val)
601 	void *v;
602 	bus_space_handle_t ioh;
603 	bus_size_t off;
604 	u_int8_t val;
605 {
606 	register bus_space_handle_t tmpioh;
607 	register u_int32_t *port, nval;
608 	register int offset;
609 
610 	tmpioh = ioh + off;
611 	offset = tmpioh & 3;
612         nval = val << (8 * offset);
613         port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
614         *port = nval;
615         alpha_mb();
616 }
617 
618 inline void
619 __C(CHIP,_io_write_2)(v, ioh, off, val)
620 	void *v;
621 	bus_space_handle_t ioh;
622 	bus_size_t off;
623 	u_int16_t val;
624 {
625 	register bus_space_handle_t tmpioh;
626 	register u_int32_t *port, nval;
627 	register int offset;
628 
629 	tmpioh = ioh + off;
630 	offset = tmpioh & 3;
631         nval = val << (8 * offset);
632         port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
633         *port = nval;
634         alpha_mb();
635 }
636 
637 inline void
638 __C(CHIP,_io_write_4)(v, ioh, off, val)
639 	void *v;
640 	bus_space_handle_t ioh;
641 	bus_size_t off;
642 	u_int32_t val;
643 {
644 	register bus_space_handle_t tmpioh;
645 	register u_int32_t *port, nval;
646 	register int offset;
647 
648 	tmpioh = ioh + off;
649 	offset = tmpioh & 3;
650         nval = val /*<< (8 * offset)*/;
651         port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
652         *port = nval;
653         alpha_mb();
654 }
655 
656 inline void
657 __C(CHIP,_io_write_8)(v, ioh, off, val)
658 	void *v;
659 	bus_space_handle_t ioh;
660 	bus_size_t off;
661 	u_int64_t val;
662 {
663 
664 	/* XXX XXX XXX */
665 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
666 	alpha_mb();
667 }
668 
669 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
670 void									\
671 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
672 	void *v;							\
673 	bus_space_handle_t h;						\
674 	bus_size_t o, c;						\
675 	const TYPE *a;							\
676 {									\
677 									\
678 	while (c-- > 0) {						\
679 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
680 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
681 		    BUS_SPACE_BARRIER_WRITE);				\
682 	}								\
683 }
684 CHIP_io_write_multi_N(1,u_int8_t)
685 CHIP_io_write_multi_N(2,u_int16_t)
686 CHIP_io_write_multi_N(4,u_int32_t)
687 CHIP_io_write_multi_N(8,u_int64_t)
688 
689 #define CHIP_io_write_region_N(BYTES,TYPE)				\
690 void									\
691 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
692 	void *v;							\
693 	bus_space_handle_t h;						\
694 	bus_size_t o, c;						\
695 	const TYPE *a;							\
696 {									\
697 									\
698 	while (c-- > 0) {						\
699 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
700 		o += sizeof *a;						\
701 	}								\
702 }
703 CHIP_io_write_region_N(1,u_int8_t)
704 CHIP_io_write_region_N(2,u_int16_t)
705 CHIP_io_write_region_N(4,u_int32_t)
706 CHIP_io_write_region_N(8,u_int64_t)
707 
708 #define CHIP_io_set_multi_N(BYTES,TYPE)					\
709 void									\
710 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c)			\
711 	void *v;							\
712 	bus_space_handle_t h;						\
713 	bus_size_t o, c;						\
714 	TYPE val;							\
715 {									\
716 									\
717 	while (c-- > 0) {						\
718 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
719 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
720 		    BUS_SPACE_BARRIER_WRITE);				\
721 	}								\
722 }
723 CHIP_io_set_multi_N(1,u_int8_t)
724 CHIP_io_set_multi_N(2,u_int16_t)
725 CHIP_io_set_multi_N(4,u_int32_t)
726 CHIP_io_set_multi_N(8,u_int64_t)
727 
728 #define CHIP_io_set_region_N(BYTES,TYPE)				\
729 void									\
730 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c)			\
731 	void *v;							\
732 	bus_space_handle_t h;						\
733 	bus_size_t o, c;						\
734 	TYPE val;							\
735 {									\
736 									\
737 	while (c-- > 0) {						\
738 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
739 		o += sizeof val;					\
740 	}								\
741 }
742 CHIP_io_set_region_N(1,u_int8_t)
743 CHIP_io_set_region_N(2,u_int16_t)
744 CHIP_io_set_region_N(4,u_int32_t)
745 CHIP_io_set_region_N(8,u_int64_t)
746 
747 #define	CHIP_io_copy_N(BYTES)						\
748 void									\
749 __C(__C(CHIP,_io_copy_),BYTES)(v, h1, o1, h2, o2, c)			\
750 	void *v;							\
751 	bus_space_handle_t h1, h2;					\
752 	bus_size_t o1, o2, c;						\
753 {									\
754 	bus_size_t i, o;						\
755 									\
756 	for (i = 0, o = 0; i < c; i++, o += BYTES)			\
757 		__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,		\
758 		    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o));	\
759 }
760 CHIP_io_copy_N(1)
761 CHIP_io_copy_N(2)
762 CHIP_io_copy_N(4)
763 CHIP_io_copy_N(8)
764 
765 #define CHIP_io_read_raw_multi_N(BYTES,TYPE)				\
766 void									\
767 __C(__C(CHIP,_io_read_raw_multi_),BYTES)(v, h, o, a, c)			\
768 	void *v;							\
769 	bus_space_handle_t h;						\
770 	bus_size_t o, c;						\
771 	u_int8_t *a;							\
772 {									\
773 	TYPE temp;							\
774 	int i;								\
775 									\
776 	while (c > 0) {							\
777 		__C(CHIP,_io_barrier)(v, h, o, BYTES,			\
778 		    BUS_SPACE_BARRIER_READ);				\
779 		temp = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
780 		i = MIN(c, BYTES);					\
781 		c -= i;							\
782 		while (i--) {						\
783 			*a++ = temp & 0xff;				\
784 			temp >>= 8;					\
785 		}							\
786 	}								\
787 }
788 CHIP_io_read_raw_multi_N(2,u_int16_t)
789 CHIP_io_read_raw_multi_N(4,u_int32_t)
790 CHIP_io_read_raw_multi_N(8,u_int64_t)
791 
792 #define CHIP_io_write_raw_multi_N(BYTES,TYPE)				\
793 void									\
794 __C(__C(CHIP,_io_write_raw_multi_),BYTES)(v, h, o, a, c)		\
795 	void *v;							\
796 	bus_space_handle_t h;						\
797 	bus_size_t o, c;						\
798 	const u_int8_t *a;						\
799 {									\
800 	TYPE temp;							\
801 	int i;								\
802 									\
803 	while (c > 0) {							\
804 		temp = 0;						\
805 		for (i = BYTES - 1; i >= 0; i--) {			\
806 			temp <<= 8;					\
807 			if (i < c)					\
808 				temp |= *(a + i);			\
809 		}							\
810 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, temp);		\
811 		__C(CHIP,_io_barrier)(v, h, o, BYTES,			\
812 		    BUS_SPACE_BARRIER_WRITE);				\
813 		i = MIN(c, BYTES); 					\
814 		c -= i;							\
815 		a += i;							\
816 	}								\
817 }
818 CHIP_io_write_raw_multi_N(2,u_int16_t)
819 CHIP_io_write_raw_multi_N(4,u_int32_t)
820 CHIP_io_write_raw_multi_N(8,u_int64_t)
821