pci_swiz_bus_io_chipdep.c revision 1.31.6.1 1 /* $NetBSD: pci_swiz_bus_io_chipdep.c,v 1.31.6.1 2001/09/21 22:34:58 nathanw 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 /* mmap for user */
114 paddr_t __C(CHIP,_io_mmap) __P((void *, bus_addr_t, off_t, int, int));
115
116 /* barrier */
117 inline void __C(CHIP,_io_barrier) __P((void *, bus_space_handle_t,
118 bus_size_t, bus_size_t, int));
119
120 /* read (single) */
121 inline u_int8_t __C(CHIP,_io_read_1) __P((void *, bus_space_handle_t,
122 bus_size_t));
123 inline u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t,
124 bus_size_t));
125 inline u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t,
126 bus_size_t));
127 inline u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t,
128 bus_size_t));
129
130 /* read multiple */
131 void __C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t,
132 bus_size_t, u_int8_t *, bus_size_t));
133 void __C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t,
134 bus_size_t, u_int16_t *, bus_size_t));
135 void __C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t,
136 bus_size_t, u_int32_t *, bus_size_t));
137 void __C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t,
138 bus_size_t, u_int64_t *, bus_size_t));
139
140 /* read region */
141 void __C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t,
142 bus_size_t, u_int8_t *, bus_size_t));
143 void __C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t,
144 bus_size_t, u_int16_t *, bus_size_t));
145 void __C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t,
146 bus_size_t, u_int32_t *, bus_size_t));
147 void __C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t,
148 bus_size_t, u_int64_t *, bus_size_t));
149
150 /* write (single) */
151 inline void __C(CHIP,_io_write_1) __P((void *, bus_space_handle_t,
152 bus_size_t, u_int8_t));
153 inline void __C(CHIP,_io_write_2) __P((void *, bus_space_handle_t,
154 bus_size_t, u_int16_t));
155 inline void __C(CHIP,_io_write_4) __P((void *, bus_space_handle_t,
156 bus_size_t, u_int32_t));
157 inline void __C(CHIP,_io_write_8) __P((void *, bus_space_handle_t,
158 bus_size_t, u_int64_t));
159
160 /* write multiple */
161 void __C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t,
162 bus_size_t, const u_int8_t *, bus_size_t));
163 void __C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t,
164 bus_size_t, const u_int16_t *, bus_size_t));
165 void __C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t,
166 bus_size_t, const u_int32_t *, bus_size_t));
167 void __C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t,
168 bus_size_t, const u_int64_t *, bus_size_t));
169
170 /* write region */
171 void __C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t,
172 bus_size_t, const u_int8_t *, bus_size_t));
173 void __C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t,
174 bus_size_t, const u_int16_t *, bus_size_t));
175 void __C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t,
176 bus_size_t, const u_int32_t *, bus_size_t));
177 void __C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t,
178 bus_size_t, const u_int64_t *, bus_size_t));
179
180 /* set multiple */
181 void __C(CHIP,_io_set_multi_1) __P((void *, bus_space_handle_t,
182 bus_size_t, u_int8_t, bus_size_t));
183 void __C(CHIP,_io_set_multi_2) __P((void *, bus_space_handle_t,
184 bus_size_t, u_int16_t, bus_size_t));
185 void __C(CHIP,_io_set_multi_4) __P((void *, bus_space_handle_t,
186 bus_size_t, u_int32_t, bus_size_t));
187 void __C(CHIP,_io_set_multi_8) __P((void *, bus_space_handle_t,
188 bus_size_t, u_int64_t, bus_size_t));
189
190 /* set region */
191 void __C(CHIP,_io_set_region_1) __P((void *, bus_space_handle_t,
192 bus_size_t, u_int8_t, bus_size_t));
193 void __C(CHIP,_io_set_region_2) __P((void *, bus_space_handle_t,
194 bus_size_t, u_int16_t, bus_size_t));
195 void __C(CHIP,_io_set_region_4) __P((void *, bus_space_handle_t,
196 bus_size_t, u_int32_t, bus_size_t));
197 void __C(CHIP,_io_set_region_8) __P((void *, bus_space_handle_t,
198 bus_size_t, u_int64_t, bus_size_t));
199
200 /* copy */
201 void __C(CHIP,_io_copy_region_1) __P((void *, bus_space_handle_t,
202 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
203 void __C(CHIP,_io_copy_region_2) __P((void *, bus_space_handle_t,
204 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
205 void __C(CHIP,_io_copy_region_4) __P((void *, bus_space_handle_t,
206 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
207 void __C(CHIP,_io_copy_region_8) __P((void *, bus_space_handle_t,
208 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
209
210 #ifndef CHIP_IO_EX_STORE
211 static long
212 __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
213 #define CHIP_IO_EX_STORE(v) (__C(CHIP, _io_ex_storage))
214 #define CHIP_IO_EX_STORE_SIZE(v) (sizeof __C(CHIP, _io_ex_storage))
215 #endif
216
217 #ifndef CHIP_ADDR_SHIFT
218 #define CHIP_ADDR_SHIFT 5
219 #endif
220
221 #ifndef CHIP_SIZE_SHIFT
222 #define CHIP_SIZE_SHIFT 3
223 #endif
224
225 void
226 __C(CHIP,_bus_io_init)(t, v)
227 bus_space_tag_t t;
228 void *v;
229 {
230 struct extent *ex;
231
232 /*
233 * Initialize the bus space tag.
234 */
235
236 /* cookie */
237 t->abs_cookie = v;
238
239 /* mapping/unmapping */
240 t->abs_map = __C(CHIP,_io_map);
241 t->abs_unmap = __C(CHIP,_io_unmap);
242 t->abs_subregion = __C(CHIP,_io_subregion);
243
244 t->abs_translate = __C(CHIP,_io_translate);
245 t->abs_get_window = __C(CHIP,_io_get_window);
246
247 /* allocation/deallocation */
248 t->abs_alloc = __C(CHIP,_io_alloc);
249 t->abs_free = __C(CHIP,_io_free);
250
251 /* get kernel virtual address */
252 t->abs_vaddr = __C(CHIP,_io_vaddr);
253
254 /* mmap for user */
255 t->abs_mmap = __C(CHIP,_io_mmap);
256
257 /* barrier */
258 t->abs_barrier = __C(CHIP,_io_barrier);
259
260 /* read (single) */
261 t->abs_r_1 = __C(CHIP,_io_read_1);
262 t->abs_r_2 = __C(CHIP,_io_read_2);
263 t->abs_r_4 = __C(CHIP,_io_read_4);
264 t->abs_r_8 = __C(CHIP,_io_read_8);
265
266 /* read multiple */
267 t->abs_rm_1 = __C(CHIP,_io_read_multi_1);
268 t->abs_rm_2 = __C(CHIP,_io_read_multi_2);
269 t->abs_rm_4 = __C(CHIP,_io_read_multi_4);
270 t->abs_rm_8 = __C(CHIP,_io_read_multi_8);
271
272 /* read region */
273 t->abs_rr_1 = __C(CHIP,_io_read_region_1);
274 t->abs_rr_2 = __C(CHIP,_io_read_region_2);
275 t->abs_rr_4 = __C(CHIP,_io_read_region_4);
276 t->abs_rr_8 = __C(CHIP,_io_read_region_8);
277
278 /* write (single) */
279 t->abs_w_1 = __C(CHIP,_io_write_1);
280 t->abs_w_2 = __C(CHIP,_io_write_2);
281 t->abs_w_4 = __C(CHIP,_io_write_4);
282 t->abs_w_8 = __C(CHIP,_io_write_8);
283
284 /* write multiple */
285 t->abs_wm_1 = __C(CHIP,_io_write_multi_1);
286 t->abs_wm_2 = __C(CHIP,_io_write_multi_2);
287 t->abs_wm_4 = __C(CHIP,_io_write_multi_4);
288 t->abs_wm_8 = __C(CHIP,_io_write_multi_8);
289
290 /* write region */
291 t->abs_wr_1 = __C(CHIP,_io_write_region_1);
292 t->abs_wr_2 = __C(CHIP,_io_write_region_2);
293 t->abs_wr_4 = __C(CHIP,_io_write_region_4);
294 t->abs_wr_8 = __C(CHIP,_io_write_region_8);
295
296 /* set multiple */
297 t->abs_sm_1 = __C(CHIP,_io_set_multi_1);
298 t->abs_sm_2 = __C(CHIP,_io_set_multi_2);
299 t->abs_sm_4 = __C(CHIP,_io_set_multi_4);
300 t->abs_sm_8 = __C(CHIP,_io_set_multi_8);
301
302 /* set region */
303 t->abs_sr_1 = __C(CHIP,_io_set_region_1);
304 t->abs_sr_2 = __C(CHIP,_io_set_region_2);
305 t->abs_sr_4 = __C(CHIP,_io_set_region_4);
306 t->abs_sr_8 = __C(CHIP,_io_set_region_8);
307
308 /* copy */
309 t->abs_c_1 = __C(CHIP,_io_copy_region_1);
310 t->abs_c_2 = __C(CHIP,_io_copy_region_2);
311 t->abs_c_4 = __C(CHIP,_io_copy_region_4);
312 t->abs_c_8 = __C(CHIP,_io_copy_region_8);
313
314 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */
315 ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL,
316 M_DEVBUF, (caddr_t)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v),
317 EX_NOWAIT);
318 extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT);
319
320 #ifdef CHIP_IO_W1_BUS_START
321 #ifdef EXTENT_DEBUG
322 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W1_BUS_START(v),
323 CHIP_IO_W1_BUS_END(v));
324 #endif
325 extent_free(ex, CHIP_IO_W1_BUS_START(v),
326 CHIP_IO_W1_BUS_END(v) - CHIP_IO_W1_BUS_START(v) + 1, EX_NOWAIT);
327 #endif
328 #ifdef CHIP_IO_W2_BUS_START
329 #ifdef EXTENT_DEBUG
330 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W2_BUS_START(v),
331 CHIP_IO_W2_BUS_END(v));
332 #endif
333 extent_free(ex, CHIP_IO_W2_BUS_START(v),
334 CHIP_IO_W2_BUS_END(v) - CHIP_IO_W2_BUS_START(v) + 1, EX_NOWAIT);
335 #endif
336
337 #ifdef EXTENT_DEBUG
338 extent_print(ex);
339 #endif
340 CHIP_IO_EXTENT(v) = ex;
341 }
342
343 int
344 __C(CHIP,_io_translate)(v, ioaddr, iolen, flags, abst)
345 void *v;
346 bus_addr_t ioaddr;
347 bus_size_t iolen;
348 int flags;
349 struct alpha_bus_space_translation *abst;
350 {
351 bus_addr_t ioend = ioaddr + (iolen - 1);
352 int linear = flags & BUS_SPACE_MAP_LINEAR;
353
354 /*
355 * Can't map i/o space linearly.
356 */
357 if (linear)
358 return (EOPNOTSUPP);
359
360 #ifdef CHIP_IO_W1_BUS_START
361 if (ioaddr >= CHIP_IO_W1_BUS_START(v) &&
362 ioend <= CHIP_IO_W1_BUS_END(v))
363 return (__C(CHIP,_io_get_window)(v, 0, abst));
364 #endif
365
366 #ifdef CHIP_IO_W2_BUS_START
367 if (ioaddr >= CHIP_IO_W2_BUS_START(v) &&
368 ioend <= CHIP_IO_W2_BUS_END(v))
369 return (__C(CHIP,_io_get_window)(v, 1, abst));
370 #endif
371
372 #ifdef EXTENT_DEBUG
373 printf("\n");
374 #ifdef CHIP_IO_W1_BUS_START
375 printf("%s: window[1]=0x%lx-0x%lx\n",
376 __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v),
377 CHIP_IO_W1_BUS_END(v));
378 #endif
379 #ifdef CHIP_IO_W2_BUS_START
380 printf("%s: window[2]=0x%lx-0x%lx\n",
381 __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v),
382 CHIP_IO_W2_BUS_END(v));
383 #endif
384 #endif /* EXTENT_DEBUG */
385 /* No translation. */
386 return (EINVAL);
387 }
388
389 int
390 __C(CHIP,_io_get_window)(v, window, abst)
391 void *v;
392 int window;
393 struct alpha_bus_space_translation *abst;
394 {
395
396 switch (window) {
397 #ifdef CHIP_IO_W1_BUS_START
398 case 0:
399 abst->abst_bus_start = CHIP_IO_W1_BUS_START(v);
400 abst->abst_bus_end = CHIP_IO_W1_BUS_END(v);
401 abst->abst_sys_start = CHIP_IO_W1_SYS_START(v);
402 abst->abst_sys_end = CHIP_IO_W1_SYS_END(v);
403 abst->abst_addr_shift = CHIP_ADDR_SHIFT;
404 abst->abst_size_shift = CHIP_SIZE_SHIFT;
405 abst->abst_flags = 0;
406 break;
407 #endif
408
409 #ifdef CHIP_IO_W2_BUS_START
410 case 1:
411 abst->abst_bus_start = CHIP_IO_W2_BUS_START(v);
412 abst->abst_bus_end = CHIP_IO_W2_BUS_END(v);
413 abst->abst_sys_start = CHIP_IO_W2_SYS_START(v);
414 abst->abst_sys_end = CHIP_IO_W2_SYS_END(v);
415 abst->abst_addr_shift = CHIP_ADDR_SHIFT;
416 abst->abst_size_shift = CHIP_SIZE_SHIFT;
417 abst->abst_flags = 0;
418 break;
419 #endif
420
421 default:
422 panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d",
423 window);
424 }
425
426 return (0);
427 }
428
429 int
430 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct)
431 void *v;
432 bus_addr_t ioaddr;
433 bus_size_t iosize;
434 int flags;
435 bus_space_handle_t *iohp;
436 int acct;
437 {
438 struct alpha_bus_space_translation abst;
439 int error;
440
441 /*
442 * Get the translation for this address.
443 */
444 error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst);
445 if (error)
446 return (error);
447
448 if (acct == 0)
449 goto mapit;
450
451 #ifdef EXTENT_DEBUG
452 printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
453 #endif
454 error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
455 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
456 if (error) {
457 #ifdef EXTENT_DEBUG
458 printf("io: allocation failed (%d)\n", error);
459 extent_print(CHIP_IO_EXTENT(v));
460 #endif
461 return (error);
462 }
463
464 mapit:
465 *iohp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >>
466 CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start);
467
468 return (0);
469 }
470
471 void
472 __C(CHIP,_io_unmap)(v, ioh, iosize, acct)
473 void *v;
474 bus_space_handle_t ioh;
475 bus_size_t iosize;
476 int acct;
477 {
478 bus_addr_t ioaddr;
479 int error;
480
481 if (acct == 0)
482 return;
483
484 #ifdef EXTENT_DEBUG
485 printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
486 #endif
487
488 ioh = ALPHA_K0SEG_TO_PHYS(ioh << CHIP_ADDR_SHIFT) >> CHIP_ADDR_SHIFT;
489
490 #ifdef CHIP_IO_W1_BUS_START
491 if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W1_SYS_START(v) &&
492 (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W1_SYS_END(v)) {
493 ioaddr = CHIP_IO_W1_BUS_START(v) +
494 (ioh - (CHIP_IO_W1_SYS_START(v) >> CHIP_ADDR_SHIFT));
495 } else
496 #endif
497 #ifdef CHIP_IO_W2_BUS_START
498 if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W2_SYS_START(v) &&
499 (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W2_SYS_END(v)) {
500 ioaddr = CHIP_IO_W2_BUS_START(v) +
501 (ioh - (CHIP_IO_W2_SYS_START(v) >> CHIP_ADDR_SHIFT));
502 } else
503 #endif
504 {
505 printf("\n");
506 #ifdef CHIP_IO_W1_BUS_START
507 printf("%s: sys window[1]=0x%lx-0x%lx\n",
508 __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v),
509 CHIP_IO_W1_SYS_END(v));
510 #endif
511 #ifdef CHIP_IO_W2_BUS_START
512 printf("%s: sys window[2]=0x%lx-0x%lx\n",
513 __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v),
514 CHIP_IO_W2_SYS_END(v));
515 #endif
516 panic("%s: don't know how to unmap %lx",
517 __S(__C(CHIP,_io_unmap)), (ioh << CHIP_ADDR_SHIFT));
518 }
519
520 #ifdef EXTENT_DEBUG
521 printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
522 #endif
523 error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
524 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
525 if (error) {
526 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
527 __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
528 error);
529 #ifdef EXTENT_DEBUG
530 extent_print(CHIP_IO_EXTENT(v));
531 #endif
532 }
533 }
534
535 int
536 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
537 void *v;
538 bus_space_handle_t ioh, *nioh;
539 bus_size_t offset, size;
540 {
541
542 *nioh = ioh + offset;
543 return (0);
544 }
545
546 int
547 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags,
548 addrp, bshp)
549 void *v;
550 bus_addr_t rstart, rend, *addrp;
551 bus_size_t size, align, boundary;
552 int flags;
553 bus_space_handle_t *bshp;
554 {
555 struct alpha_bus_space_translation abst;
556 int linear = flags & BUS_SPACE_MAP_LINEAR;
557 bus_addr_t ioaddr;
558 int error;
559
560 /*
561 * Can't map i/o space linearly.
562 */
563 if (linear)
564 return (EOPNOTSUPP);
565
566 /*
567 * Do the requested allocation.
568 */
569 #ifdef EXTENT_DEBUG
570 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend);
571 #endif
572 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend,
573 size, align, boundary,
574 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
575 &ioaddr);
576 if (error) {
577 #ifdef EXTENT_DEBUG
578 printf("io: allocation failed (%d)\n", error);
579 extent_print(CHIP_IO_EXTENT(v));
580 #endif
581 return (error);
582 }
583
584 #ifdef EXTENT_DEBUG
585 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1);
586 #endif
587
588 error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst);
589 if (error) {
590 (void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size,
591 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
592 return (error);
593 }
594
595 *addrp = ioaddr;
596 *bshp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >>
597 CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start);
598
599 return (0);
600 }
601
602 void
603 __C(CHIP,_io_free)(v, bsh, size)
604 void *v;
605 bus_space_handle_t bsh;
606 bus_size_t size;
607 {
608
609 /* Unmap does all we need to do. */
610 __C(CHIP,_io_unmap)(v, bsh, size, 1);
611 }
612
613 void *
614 __C(CHIP,_io_vaddr)(v, bsh)
615 void *v;
616 bus_space_handle_t bsh;
617 {
618 /*
619 * _io_translate() catches BUS_SPACE_MAP_LINEAR,
620 * so we shouldn't get here
621 */
622 panic("_io_vaddr");
623 }
624
625 paddr_t
626 __C(CHIP,_io_mmap)(v, addr, off, prot, flags)
627 void *v;
628 bus_addr_t addr;
629 off_t off;
630 int prot;
631 int flags;
632 {
633
634 /* Not supported for I/O space. */
635 return (-1);
636 }
637
638 inline void
639 __C(CHIP,_io_barrier)(v, h, o, l, f)
640 void *v;
641 bus_space_handle_t h;
642 bus_size_t o, l;
643 int f;
644 {
645
646 if ((f & BUS_SPACE_BARRIER_READ) != 0)
647 alpha_mb();
648 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
649 alpha_wmb();
650 }
651
652 inline u_int8_t
653 __C(CHIP,_io_read_1)(v, ioh, off)
654 void *v;
655 bus_space_handle_t ioh;
656 bus_size_t off;
657 {
658 register bus_space_handle_t tmpioh;
659 register u_int32_t *port, val;
660 register u_int8_t rval;
661 register int offset;
662
663 alpha_mb();
664
665 tmpioh = ioh + off;
666 offset = tmpioh & 3;
667 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
668 (0 << CHIP_SIZE_SHIFT));
669 val = *port;
670 rval = ((val) >> (8 * offset)) & 0xff;
671
672 return rval;
673 }
674
675 inline u_int16_t
676 __C(CHIP,_io_read_2)(v, ioh, off)
677 void *v;
678 bus_space_handle_t ioh;
679 bus_size_t off;
680 {
681 register bus_space_handle_t tmpioh;
682 register u_int32_t *port, val;
683 register u_int16_t rval;
684 register int offset;
685
686 alpha_mb();
687
688 tmpioh = ioh + off;
689 offset = tmpioh & 3;
690 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
691 (1 << CHIP_SIZE_SHIFT));
692 val = *port;
693 rval = ((val) >> (8 * offset)) & 0xffff;
694
695 return rval;
696 }
697
698 inline u_int32_t
699 __C(CHIP,_io_read_4)(v, ioh, off)
700 void *v;
701 bus_space_handle_t ioh;
702 bus_size_t off;
703 {
704 register bus_space_handle_t tmpioh;
705 register u_int32_t *port, val;
706 register u_int32_t rval;
707 register int offset;
708
709 alpha_mb();
710
711 tmpioh = ioh + off;
712 offset = tmpioh & 3;
713 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
714 (3 << CHIP_SIZE_SHIFT));
715 val = *port;
716 #if 0
717 rval = ((val) >> (8 * offset)) & 0xffffffff;
718 #else
719 rval = val;
720 #endif
721
722 return rval;
723 }
724
725 inline u_int64_t
726 __C(CHIP,_io_read_8)(v, ioh, off)
727 void *v;
728 bus_space_handle_t ioh;
729 bus_size_t off;
730 {
731
732 /* XXX XXX XXX */
733 panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
734 }
735
736 #define CHIP_io_read_multi_N(BYTES,TYPE) \
737 void \
738 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c) \
739 void *v; \
740 bus_space_handle_t h; \
741 bus_size_t o, c; \
742 TYPE *a; \
743 { \
744 \
745 while (c-- > 0) { \
746 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
747 BUS_SPACE_BARRIER_READ); \
748 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
749 } \
750 }
751 CHIP_io_read_multi_N(1,u_int8_t)
752 CHIP_io_read_multi_N(2,u_int16_t)
753 CHIP_io_read_multi_N(4,u_int32_t)
754 CHIP_io_read_multi_N(8,u_int64_t)
755
756 #define CHIP_io_read_region_N(BYTES,TYPE) \
757 void \
758 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c) \
759 void *v; \
760 bus_space_handle_t h; \
761 bus_size_t o, c; \
762 TYPE *a; \
763 { \
764 \
765 while (c-- > 0) { \
766 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
767 o += sizeof *a; \
768 } \
769 }
770 CHIP_io_read_region_N(1,u_int8_t)
771 CHIP_io_read_region_N(2,u_int16_t)
772 CHIP_io_read_region_N(4,u_int32_t)
773 CHIP_io_read_region_N(8,u_int64_t)
774
775 inline void
776 __C(CHIP,_io_write_1)(v, ioh, off, val)
777 void *v;
778 bus_space_handle_t ioh;
779 bus_size_t off;
780 u_int8_t val;
781 {
782 register bus_space_handle_t tmpioh;
783 register u_int32_t *port, nval;
784 register int offset;
785
786 tmpioh = ioh + off;
787 offset = tmpioh & 3;
788 nval = val << (8 * offset);
789 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
790 (0 << CHIP_SIZE_SHIFT));
791 *port = nval;
792 alpha_mb();
793 }
794
795 inline void
796 __C(CHIP,_io_write_2)(v, ioh, off, val)
797 void *v;
798 bus_space_handle_t ioh;
799 bus_size_t off;
800 u_int16_t val;
801 {
802 register bus_space_handle_t tmpioh;
803 register u_int32_t *port, nval;
804 register int offset;
805
806 tmpioh = ioh + off;
807 offset = tmpioh & 3;
808 nval = val << (8 * offset);
809 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
810 (1 << CHIP_SIZE_SHIFT));
811 *port = nval;
812 alpha_mb();
813 }
814
815 inline void
816 __C(CHIP,_io_write_4)(v, ioh, off, val)
817 void *v;
818 bus_space_handle_t ioh;
819 bus_size_t off;
820 u_int32_t val;
821 {
822 register bus_space_handle_t tmpioh;
823 register u_int32_t *port, nval;
824 register int offset;
825
826 tmpioh = ioh + off;
827 offset = tmpioh & 3;
828 nval = val /*<< (8 * offset)*/;
829 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
830 (3 << CHIP_SIZE_SHIFT));
831 *port = nval;
832 alpha_mb();
833 }
834
835 inline void
836 __C(CHIP,_io_write_8)(v, ioh, off, val)
837 void *v;
838 bus_space_handle_t ioh;
839 bus_size_t off;
840 u_int64_t val;
841 {
842
843 /* XXX XXX XXX */
844 panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
845 alpha_mb();
846 }
847
848 #define CHIP_io_write_multi_N(BYTES,TYPE) \
849 void \
850 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c) \
851 void *v; \
852 bus_space_handle_t h; \
853 bus_size_t o, c; \
854 const TYPE *a; \
855 { \
856 \
857 while (c-- > 0) { \
858 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
859 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
860 BUS_SPACE_BARRIER_WRITE); \
861 } \
862 }
863 CHIP_io_write_multi_N(1,u_int8_t)
864 CHIP_io_write_multi_N(2,u_int16_t)
865 CHIP_io_write_multi_N(4,u_int32_t)
866 CHIP_io_write_multi_N(8,u_int64_t)
867
868 #define CHIP_io_write_region_N(BYTES,TYPE) \
869 void \
870 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c) \
871 void *v; \
872 bus_space_handle_t h; \
873 bus_size_t o, c; \
874 const TYPE *a; \
875 { \
876 \
877 while (c-- > 0) { \
878 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
879 o += sizeof *a; \
880 } \
881 }
882 CHIP_io_write_region_N(1,u_int8_t)
883 CHIP_io_write_region_N(2,u_int16_t)
884 CHIP_io_write_region_N(4,u_int32_t)
885 CHIP_io_write_region_N(8,u_int64_t)
886
887 #define CHIP_io_set_multi_N(BYTES,TYPE) \
888 void \
889 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c) \
890 void *v; \
891 bus_space_handle_t h; \
892 bus_size_t o, c; \
893 TYPE val; \
894 { \
895 \
896 while (c-- > 0) { \
897 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \
898 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \
899 BUS_SPACE_BARRIER_WRITE); \
900 } \
901 }
902 CHIP_io_set_multi_N(1,u_int8_t)
903 CHIP_io_set_multi_N(2,u_int16_t)
904 CHIP_io_set_multi_N(4,u_int32_t)
905 CHIP_io_set_multi_N(8,u_int64_t)
906
907 #define CHIP_io_set_region_N(BYTES,TYPE) \
908 void \
909 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c) \
910 void *v; \
911 bus_space_handle_t h; \
912 bus_size_t o, c; \
913 TYPE val; \
914 { \
915 \
916 while (c-- > 0) { \
917 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \
918 o += sizeof val; \
919 } \
920 }
921 CHIP_io_set_region_N(1,u_int8_t)
922 CHIP_io_set_region_N(2,u_int16_t)
923 CHIP_io_set_region_N(4,u_int32_t)
924 CHIP_io_set_region_N(8,u_int64_t)
925
926 #define CHIP_io_copy_region_N(BYTES) \
927 void \
928 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c) \
929 void *v; \
930 bus_space_handle_t h1, h2; \
931 bus_size_t o1, o2, c; \
932 { \
933 bus_size_t o; \
934 \
935 if ((h1 + o1) >= (h2 + o2)) { \
936 /* src after dest: copy forward */ \
937 for (o = 0; c != 0; c--, o += BYTES) \
938 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \
939 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
940 } else { \
941 /* dest after src: copy backwards */ \
942 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
943 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \
944 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
945 } \
946 }
947 CHIP_io_copy_region_N(1)
948 CHIP_io_copy_region_N(2)
949 CHIP_io_copy_region_N(4)
950 CHIP_io_copy_region_N(8)
951