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