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