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