pci_swiz_bus_io_chipdep.c revision 1.9 1 /* $NetBSD: pci_swiz_bus_io_chipdep.c,v 1.9 1996/10/23 04:12:31 cgd Exp $ */
2
3 /*
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 /*
31 * Common PCI Chipset "bus I/O" functions, for chipsets which have to
32 * deal with only a single PCI interface chip in a machine.
33 *
34 * uses:
35 * CHIP name of the 'chip' it's being compiled for.
36 * CHIP_IO_BASE Sparse I/O space base to use.
37 */
38
39 #define __C(A,B) __CONCAT(A,B)
40 #define __S(S) __STRING(S)
41
42 /* mapping/unmapping */
43 int __C(CHIP,_io_map) __P((void *, bus_addr_t, bus_size_t, int,
44 bus_space_handle_t *));
45 void __C(CHIP,_io_unmap) __P((void *, bus_space_handle_t,
46 bus_size_t));
47 int __C(CHIP,_io_subregion) __P((void *, bus_space_handle_t,
48 bus_size_t, bus_size_t, bus_space_handle_t *));
49
50 /* allocation/deallocation */
51 int __C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t,
52 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
53 bus_space_handle_t *));
54 void __C(CHIP,_io_free) __P((void *, bus_space_handle_t,
55 bus_size_t));
56
57 /* read (single) */
58 u_int8_t __C(CHIP,_io_read_1) __P((void *, bus_space_handle_t,
59 bus_size_t));
60 u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t,
61 bus_size_t));
62 u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t,
63 bus_size_t));
64 u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t,
65 bus_size_t));
66
67 /* read multiple */
68 void __C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t,
69 bus_size_t, u_int8_t *, bus_size_t));
70 void __C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t,
71 bus_size_t, u_int16_t *, bus_size_t));
72 void __C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t,
73 bus_size_t, u_int32_t *, bus_size_t));
74 void __C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t,
75 bus_size_t, u_int64_t *, bus_size_t));
76
77 /* read region */
78 void __C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t,
79 bus_size_t, u_int8_t *, bus_size_t));
80 void __C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t,
81 bus_size_t, u_int16_t *, bus_size_t));
82 void __C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t,
83 bus_size_t, u_int32_t *, bus_size_t));
84 void __C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t,
85 bus_size_t, u_int64_t *, bus_size_t));
86
87 /* write (single) */
88 void __C(CHIP,_io_write_1) __P((void *, bus_space_handle_t,
89 bus_size_t, u_int8_t));
90 void __C(CHIP,_io_write_2) __P((void *, bus_space_handle_t,
91 bus_size_t, u_int16_t));
92 void __C(CHIP,_io_write_4) __P((void *, bus_space_handle_t,
93 bus_size_t, u_int32_t));
94 void __C(CHIP,_io_write_8) __P((void *, bus_space_handle_t,
95 bus_size_t, u_int64_t));
96
97 /* write multiple */
98 void __C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t,
99 bus_size_t, const u_int8_t *, bus_size_t));
100 void __C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t,
101 bus_size_t, const u_int16_t *, bus_size_t));
102 void __C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t,
103 bus_size_t, const u_int32_t *, bus_size_t));
104 void __C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t,
105 bus_size_t, const u_int64_t *, bus_size_t));
106
107 /* write region */
108 void __C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t,
109 bus_size_t, const u_int8_t *, bus_size_t));
110 void __C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t,
111 bus_size_t, const u_int16_t *, bus_size_t));
112 void __C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t,
113 bus_size_t, const u_int32_t *, bus_size_t));
114 void __C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t,
115 bus_size_t, const u_int64_t *, bus_size_t));
116
117 /* barrier */
118 void __C(CHIP,_io_barrier) __P((void *, bus_space_handle_t,
119 bus_size_t, bus_size_t, int));
120
121 static struct alpha_bus_space __C(CHIP,_io_space) = {
122 /* cookie */
123 NULL,
124
125 /* mapping/unmapping */
126 __C(CHIP,_io_map),
127 __C(CHIP,_io_unmap),
128 __C(CHIP,_io_subregion),
129
130 /* allocation/deallocation */
131 __C(CHIP,_io_alloc),
132 __C(CHIP,_io_free),
133
134 /* read (single) */
135 __C(CHIP,_io_read_1),
136 __C(CHIP,_io_read_2),
137 __C(CHIP,_io_read_4),
138 __C(CHIP,_io_read_8),
139
140 /* read multi */
141 __C(CHIP,_io_read_multi_1),
142 __C(CHIP,_io_read_multi_2),
143 __C(CHIP,_io_read_multi_4),
144 __C(CHIP,_io_read_multi_8),
145
146 /* read region */
147 __C(CHIP,_io_read_region_1),
148 __C(CHIP,_io_read_region_2),
149 __C(CHIP,_io_read_region_4),
150 __C(CHIP,_io_read_region_8),
151
152 /* write (single) */
153 __C(CHIP,_io_write_1),
154 __C(CHIP,_io_write_2),
155 __C(CHIP,_io_write_4),
156 __C(CHIP,_io_write_8),
157
158 /* write multi */
159 __C(CHIP,_io_write_multi_1),
160 __C(CHIP,_io_write_multi_2),
161 __C(CHIP,_io_write_multi_4),
162 __C(CHIP,_io_write_multi_8),
163
164 /* write region */
165 __C(CHIP,_io_write_region_1),
166 __C(CHIP,_io_write_region_2),
167 __C(CHIP,_io_write_region_4),
168 __C(CHIP,_io_write_region_8),
169
170 /* set multi */
171 /* XXX IMPLEMENT */
172
173 /* set region */
174 /* XXX IMPLEMENT */
175
176 /* copy */
177 /* XXX IMPLEMENT */
178
179 /* barrier */
180 __C(CHIP,_io_barrier),
181 };
182
183 bus_space_tag_t
184 __C(CHIP,_bus_io_init)(iov)
185 void *iov;
186 {
187 bus_space_tag_t h = &__C(CHIP,_io_space);;
188
189 h->abs_cookie = iov;
190 return (h);
191 }
192
193 int
194 __C(CHIP,_io_map)(v, ioaddr, iosize, cacheable, iohp)
195 void *v;
196 bus_addr_t ioaddr;
197 bus_size_t iosize;
198 int cacheable;
199 bus_space_handle_t *iohp;
200 {
201
202 #ifdef CHIP_IO_W1_START
203 if (ioaddr >= CHIP_IO_W1_START(v) &&
204 ioaddr <= CHIP_IO_W1_END(v)) {
205 *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_BASE(v)) >> 5) +
206 (ioaddr & CHIP_IO_W1_MASK(v));
207 } else
208 #endif
209 #ifdef CHIP_IO_W2_START
210 if (ioaddr >= CHIP_IO_W2_START(v) &&
211 ioaddr <= CHIP_IO_W2_END(v)) {
212 *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_BASE(v)) >> 5) +
213 (ioaddr & CHIP_IO_W2_MASK(v));
214 } else
215 #endif
216 {
217 printf("\n");
218 #ifdef CHIP_IO_W1_START
219 printf("%s: window[1]=0x%lx-0x%lx\n",
220 __S(__C(CHIP,_io_map)), CHIP_IO_W1_START(v),
221 CHIP_IO_W1_END(v)-1);
222 #endif
223 #ifdef CHIP_IO_W2_START
224 printf("%s: window[2]=0x%lx-0x%lx\n",
225 __S(__C(CHIP,_io_map)), CHIP_IO_W2_START(v),
226 CHIP_IO_W2_END(v)-1);
227 #endif
228 panic("%s: don't know how to map %lx non-cacheable",
229 __S(__C(CHIP,_io_map)), ioaddr);
230 }
231
232 /* XXX XXX XXX XXX XXX XXX */
233 return (0);
234 }
235
236 void
237 __C(CHIP,_io_unmap)(v, ioh, iosize)
238 void *v;
239 bus_space_handle_t ioh;
240 bus_size_t iosize;
241 {
242
243 /* XXX nothing to do. */
244 /* XXX XXX XXX XXX XXX XXX */
245 }
246
247 int
248 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
249 void *v;
250 bus_space_handle_t ioh, *nioh;
251 bus_size_t offset, size;
252 {
253
254 *nioh = ioh + offset;
255 return (0);
256 }
257
258 int
259 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, cacheable,
260 addrp, bshp)
261 void *v;
262 bus_addr_t rstart, rend, *addrp;
263 bus_size_t size, align, boundary;
264 int cacheable;
265 bus_space_handle_t *bshp;
266 {
267
268 /* XXX XXX XXX XXX XXX XXX */
269 panic("%s not implemented", __S(__C(CHIP,_io_alloc)));
270 }
271
272 void
273 __C(CHIP,_io_free)(v, bsh, size)
274 void *v;
275 bus_space_handle_t bsh;
276 bus_size_t size;
277 {
278
279 /* XXX XXX XXX XXX XXX XXX */
280 panic("%s not implemented", __S(__C(CHIP,_io_free)));
281 }
282
283 u_int8_t
284 __C(CHIP,_io_read_1)(v, ioh, off)
285 void *v;
286 bus_space_handle_t ioh;
287 bus_size_t off;
288 {
289 register bus_space_handle_t tmpioh;
290 register u_int32_t *port, val;
291 register u_int8_t rval;
292 register int offset;
293
294 alpha_mb();
295
296 tmpioh = ioh + off;
297 offset = tmpioh & 3;
298 port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
299 val = *port;
300 rval = ((val) >> (8 * offset)) & 0xff;
301
302 return rval;
303 }
304
305 u_int16_t
306 __C(CHIP,_io_read_2)(v, ioh, off)
307 void *v;
308 bus_space_handle_t ioh;
309 bus_size_t off;
310 {
311 register bus_space_handle_t tmpioh;
312 register u_int32_t *port, val;
313 register u_int16_t rval;
314 register int offset;
315
316 alpha_mb();
317
318 tmpioh = ioh + off;
319 offset = tmpioh & 3;
320 port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
321 val = *port;
322 rval = ((val) >> (8 * offset)) & 0xffff;
323
324 return rval;
325 }
326
327 u_int32_t
328 __C(CHIP,_io_read_4)(v, ioh, off)
329 void *v;
330 bus_space_handle_t ioh;
331 bus_size_t off;
332 {
333 register bus_space_handle_t tmpioh;
334 register u_int32_t *port, val;
335 register u_int32_t rval;
336 register int offset;
337
338 alpha_mb();
339
340 tmpioh = ioh + off;
341 offset = tmpioh & 3;
342 port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
343 val = *port;
344 #if 0
345 rval = ((val) >> (8 * offset)) & 0xffffffff;
346 #else
347 rval = val;
348 #endif
349
350 return rval;
351 }
352
353 u_int64_t
354 __C(CHIP,_io_read_8)(v, ioh, off)
355 void *v;
356 bus_space_handle_t ioh;
357 bus_size_t off;
358 {
359
360 /* XXX XXX XXX */
361 panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
362 }
363
364 #define CHIP_io_read_multi_N(BYTES,TYPE) \
365 void \
366 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c) \
367 void *v; \
368 bus_space_handle_t h; \
369 bus_size_t o, c; \
370 TYPE *a; \
371 { \
372 \
373 while (c-- > 0) { \
374 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
375 BUS_BARRIER_READ); \
376 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
377 } \
378 }
379 CHIP_io_read_multi_N(1,u_int8_t)
380 CHIP_io_read_multi_N(2,u_int16_t)
381 CHIP_io_read_multi_N(4,u_int32_t)
382 CHIP_io_read_multi_N(8,u_int64_t)
383
384 #define CHIP_io_read_region_N(BYTES,TYPE) \
385 void \
386 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c) \
387 void *v; \
388 bus_space_handle_t h; \
389 bus_size_t o, c; \
390 TYPE *a; \
391 { \
392 \
393 while (c-- > 0) { \
394 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
395 o += sizeof *a; \
396 } \
397 }
398 CHIP_io_read_region_N(1,u_int8_t)
399 CHIP_io_read_region_N(2,u_int16_t)
400 CHIP_io_read_region_N(4,u_int32_t)
401 CHIP_io_read_region_N(8,u_int64_t)
402
403 void
404 __C(CHIP,_io_write_1)(v, ioh, off, val)
405 void *v;
406 bus_space_handle_t ioh;
407 bus_size_t off;
408 u_int8_t val;
409 {
410 register bus_space_handle_t tmpioh;
411 register u_int32_t *port, nval;
412 register int offset;
413
414 tmpioh = ioh + off;
415 offset = tmpioh & 3;
416 nval = val << (8 * offset);
417 port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
418 *port = nval;
419 alpha_mb();
420 }
421
422 void
423 __C(CHIP,_io_write_2)(v, ioh, off, val)
424 void *v;
425 bus_space_handle_t ioh;
426 bus_size_t off;
427 u_int16_t val;
428 {
429 register bus_space_handle_t tmpioh;
430 register u_int32_t *port, nval;
431 register int offset;
432
433 tmpioh = ioh + off;
434 offset = tmpioh & 3;
435 nval = val << (8 * offset);
436 port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
437 *port = nval;
438 alpha_mb();
439 }
440
441 void
442 __C(CHIP,_io_write_4)(v, ioh, off, val)
443 void *v;
444 bus_space_handle_t ioh;
445 bus_size_t off;
446 u_int32_t val;
447 {
448 register bus_space_handle_t tmpioh;
449 register u_int32_t *port, nval;
450 register int offset;
451
452 tmpioh = ioh + off;
453 offset = tmpioh & 3;
454 nval = val /*<< (8 * offset)*/;
455 port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
456 *port = nval;
457 alpha_mb();
458 }
459
460 void
461 __C(CHIP,_io_write_8)(v, ioh, off, val)
462 void *v;
463 bus_space_handle_t ioh;
464 bus_size_t off;
465 u_int64_t val;
466 {
467
468 /* XXX XXX XXX */
469 panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
470 alpha_mb();
471 }
472
473 #define CHIP_io_write_multi_N(BYTES,TYPE) \
474 void \
475 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c) \
476 void *v; \
477 bus_space_handle_t h; \
478 bus_size_t o, c; \
479 const TYPE *a; \
480 { \
481 \
482 while (c-- > 0) { \
483 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
484 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
485 BUS_BARRIER_WRITE); \
486 } \
487 }
488 CHIP_io_write_multi_N(1,u_int8_t)
489 CHIP_io_write_multi_N(2,u_int16_t)
490 CHIP_io_write_multi_N(4,u_int32_t)
491 CHIP_io_write_multi_N(8,u_int64_t)
492
493 #define CHIP_io_write_region_N(BYTES,TYPE) \
494 void \
495 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c) \
496 void *v; \
497 bus_space_handle_t h; \
498 bus_size_t o, c; \
499 const TYPE *a; \
500 { \
501 \
502 while (c-- > 0) { \
503 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
504 o += sizeof *a; \
505 } \
506 }
507 CHIP_io_write_region_N(1,u_int8_t)
508 CHIP_io_write_region_N(2,u_int16_t)
509 CHIP_io_write_region_N(4,u_int32_t)
510 CHIP_io_write_region_N(8,u_int64_t)
511
512 void
513 __C(CHIP,_io_barrier)(v, h, o, l, f)
514 void *v;
515 bus_space_handle_t h;
516 bus_size_t o, l;
517 int f;
518 {
519
520 if ((f & BUS_BARRIER_READ) != 0)
521 alpha_mb();
522 else if ((f & BUS_BARRIER_WRITE) != 0)
523 alpha_wmb();
524 }
525