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