tc_bus_mem.c revision 1.14 1 /* $NetBSD: tc_bus_mem.c,v 1.14 1997/04/06 22:32:04 cgd Exp $ */
2
3 /*
4 * Copyright (c) 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 TurboChannel Chipset "bus memory" functions.
32 */
33
34 #include <machine/options.h> /* Pull in config options headers */
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/syslog.h>
40 #include <sys/device.h>
41 #include <vm/vm.h>
42
43 #include <machine/bus.h>
44 #include <dev/tc/tcvar.h>
45
46 /* mapping/unmapping */
47 int tc_mem_map __P((void *, bus_addr_t, bus_size_t, int,
48 bus_space_handle_t *));
49 void tc_mem_unmap __P((void *, bus_space_handle_t, bus_size_t));
50 int tc_mem_subregion __P((void *, bus_space_handle_t, bus_size_t,
51 bus_size_t, bus_space_handle_t *));
52
53 /* allocation/deallocation */
54 int tc_mem_alloc __P((void *, bus_addr_t, bus_addr_t, bus_size_t,
55 bus_size_t, bus_addr_t, int, bus_addr_t *,
56 bus_space_handle_t *));
57 void tc_mem_free __P((void *, bus_space_handle_t, bus_size_t));
58
59 /* barrier */
60 inline void tc_mem_barrier __P((void *, bus_space_handle_t,
61 bus_size_t, bus_size_t, int));
62
63 /* read (single) */
64 inline u_int8_t tc_mem_read_1 __P((void *, bus_space_handle_t, bus_size_t));
65 inline u_int16_t tc_mem_read_2 __P((void *, bus_space_handle_t, bus_size_t));
66 inline u_int32_t tc_mem_read_4 __P((void *, bus_space_handle_t, bus_size_t));
67 inline u_int64_t tc_mem_read_8 __P((void *, bus_space_handle_t, bus_size_t));
68
69 /* read multiple */
70 void tc_mem_read_multi_1 __P((void *, bus_space_handle_t,
71 bus_size_t, u_int8_t *, bus_size_t));
72 void tc_mem_read_multi_2 __P((void *, bus_space_handle_t,
73 bus_size_t, u_int16_t *, bus_size_t));
74 void tc_mem_read_multi_4 __P((void *, bus_space_handle_t,
75 bus_size_t, u_int32_t *, bus_size_t));
76 void tc_mem_read_multi_8 __P((void *, bus_space_handle_t,
77 bus_size_t, u_int64_t *, bus_size_t));
78
79 /* read region */
80 void tc_mem_read_region_1 __P((void *, bus_space_handle_t,
81 bus_size_t, u_int8_t *, bus_size_t));
82 void tc_mem_read_region_2 __P((void *, bus_space_handle_t,
83 bus_size_t, u_int16_t *, bus_size_t));
84 void tc_mem_read_region_4 __P((void *, bus_space_handle_t,
85 bus_size_t, u_int32_t *, bus_size_t));
86 void tc_mem_read_region_8 __P((void *, bus_space_handle_t,
87 bus_size_t, u_int64_t *, bus_size_t));
88
89 /* write (single) */
90 inline void tc_mem_write_1 __P((void *, bus_space_handle_t, bus_size_t,
91 u_int8_t));
92 inline void tc_mem_write_2 __P((void *, bus_space_handle_t, bus_size_t,
93 u_int16_t));
94 inline void tc_mem_write_4 __P((void *, bus_space_handle_t, bus_size_t,
95 u_int32_t));
96 inline void tc_mem_write_8 __P((void *, bus_space_handle_t, bus_size_t,
97 u_int64_t));
98
99 /* write multiple */
100 void tc_mem_write_multi_1 __P((void *, bus_space_handle_t,
101 bus_size_t, const u_int8_t *, bus_size_t));
102 void tc_mem_write_multi_2 __P((void *, bus_space_handle_t,
103 bus_size_t, const u_int16_t *, bus_size_t));
104 void tc_mem_write_multi_4 __P((void *, bus_space_handle_t,
105 bus_size_t, const u_int32_t *, bus_size_t));
106 void tc_mem_write_multi_8 __P((void *, bus_space_handle_t,
107 bus_size_t, const u_int64_t *, bus_size_t));
108
109 /* write region */
110 void tc_mem_write_region_1 __P((void *, bus_space_handle_t,
111 bus_size_t, const u_int8_t *, bus_size_t));
112 void tc_mem_write_region_2 __P((void *, bus_space_handle_t,
113 bus_size_t, const u_int16_t *, bus_size_t));
114 void tc_mem_write_region_4 __P((void *, bus_space_handle_t,
115 bus_size_t, const u_int32_t *, bus_size_t));
116 void tc_mem_write_region_8 __P((void *, bus_space_handle_t,
117 bus_size_t, const u_int64_t *, bus_size_t));
118
119 /* set multiple */
120 void tc_mem_set_multi_1 __P((void *, bus_space_handle_t,
121 bus_size_t, u_int8_t, bus_size_t));
122 void tc_mem_set_multi_2 __P((void *, bus_space_handle_t,
123 bus_size_t, u_int16_t, bus_size_t));
124 void tc_mem_set_multi_4 __P((void *, bus_space_handle_t,
125 bus_size_t, u_int32_t, bus_size_t));
126 void tc_mem_set_multi_8 __P((void *, bus_space_handle_t,
127 bus_size_t, u_int64_t, bus_size_t));
128
129 /* set region */
130 void tc_mem_set_region_1 __P((void *, bus_space_handle_t,
131 bus_size_t, u_int8_t, bus_size_t));
132 void tc_mem_set_region_2 __P((void *, bus_space_handle_t,
133 bus_size_t, u_int16_t, bus_size_t));
134 void tc_mem_set_region_4 __P((void *, bus_space_handle_t,
135 bus_size_t, u_int32_t, bus_size_t));
136 void tc_mem_set_region_8 __P((void *, bus_space_handle_t,
137 bus_size_t, u_int64_t, bus_size_t));
138
139 /* copy */
140 void tc_mem_copy_1 __P((void *, bus_space_handle_t,
141 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
142 void tc_mem_copy_2 __P((void *, bus_space_handle_t,
143 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
144 void tc_mem_copy_4 __P((void *, bus_space_handle_t,
145 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
146 void tc_mem_copy_8 __P((void *, bus_space_handle_t,
147 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
148
149 static struct alpha_bus_space tc_mem_space = {
150 /* cookie */
151 NULL,
152
153 /* mapping/unmapping */
154 tc_mem_map,
155 tc_mem_unmap,
156 tc_mem_subregion,
157
158 /* allocation/deallocation */
159 tc_mem_alloc,
160 tc_mem_free,
161
162 /* barrier */
163 tc_mem_barrier,
164
165 /* read (single) */
166 tc_mem_read_1,
167 tc_mem_read_2,
168 tc_mem_read_4,
169 tc_mem_read_8,
170
171 /* read multiple */
172 tc_mem_read_multi_1,
173 tc_mem_read_multi_2,
174 tc_mem_read_multi_4,
175 tc_mem_read_multi_8,
176
177 /* read region */
178 tc_mem_read_region_1,
179 tc_mem_read_region_2,
180 tc_mem_read_region_4,
181 tc_mem_read_region_8,
182
183 /* write (single) */
184 tc_mem_write_1,
185 tc_mem_write_2,
186 tc_mem_write_4,
187 tc_mem_write_8,
188
189 /* write multiple */
190 tc_mem_write_multi_1,
191 tc_mem_write_multi_2,
192 tc_mem_write_multi_4,
193 tc_mem_write_multi_8,
194
195 /* write region */
196 tc_mem_write_region_1,
197 tc_mem_write_region_2,
198 tc_mem_write_region_4,
199 tc_mem_write_region_8,
200
201 /* set multiple */
202 tc_mem_set_multi_1,
203 tc_mem_set_multi_2,
204 tc_mem_set_multi_4,
205 tc_mem_set_multi_8,
206
207 /* set region */
208 tc_mem_set_region_1,
209 tc_mem_set_region_2,
210 tc_mem_set_region_4,
211 tc_mem_set_region_8,
212
213 /* copy */
214 tc_mem_copy_1,
215 tc_mem_copy_2,
216 tc_mem_copy_4,
217 tc_mem_copy_8,
218 };
219
220 bus_space_tag_t
221 tc_bus_mem_init(memv)
222 void *memv;
223 {
224 bus_space_tag_t h = &tc_mem_space;
225
226 h->abs_cookie = memv;
227 return (h);
228 }
229
230 int
231 tc_mem_map(v, memaddr, memsize, cacheable, memhp)
232 void *v;
233 bus_addr_t memaddr;
234 bus_size_t memsize;
235 int cacheable;
236 bus_space_handle_t *memhp;
237 {
238
239 if (memaddr & 0x7)
240 panic("tc_mem_map needs 8 byte alignment");
241 if (cacheable)
242 *memhp = ALPHA_PHYS_TO_K0SEG(memaddr);
243 else
244 *memhp = ALPHA_PHYS_TO_K0SEG(TC_DENSE_TO_SPARSE(memaddr));
245 return (0);
246 }
247
248 void
249 tc_mem_unmap(v, memh, memsize)
250 void *v;
251 bus_space_handle_t memh;
252 bus_size_t memsize;
253 {
254
255 /* XXX XX XXX nothing to do. */
256 }
257
258 int
259 tc_mem_subregion(v, memh, offset, size, nmemh)
260 void *v;
261 bus_space_handle_t memh, *nmemh;
262 bus_size_t offset, size;
263 {
264
265 /* Disallow subregioning that would make the handle unaligned. */
266 if ((offset & 0x7) != 0)
267 return (1);
268
269 if ((memh & TC_SPACE_SPARSE) != 0)
270 *nmemh = memh + (offset << 1);
271 else
272 *nmemh = memh + offset;
273
274 return (0);
275 }
276
277 int
278 tc_mem_alloc(v, rstart, rend, size, align, boundary, cacheable, addrp, bshp)
279 void *v;
280 bus_addr_t rstart, rend, *addrp;
281 bus_size_t size, align, boundary;
282 int cacheable;
283 bus_space_handle_t *bshp;
284 {
285
286 /* XXX XXX XXX XXX XXX XXX */
287 panic("tc_mem_alloc unimplemented");
288 }
289
290 void
291 tc_mem_free(v, bsh, size)
292 void *v;
293 bus_space_handle_t bsh;
294 bus_size_t size;
295 {
296
297 /* XXX XXX XXX XXX XXX XXX */
298 panic("tc_mem_free unimplemented");
299 }
300
301 inline void
302 tc_mem_barrier(v, h, o, l, f)
303 void *v;
304 bus_space_handle_t h;
305 bus_size_t o, l;
306 int f;
307 {
308
309 if ((f & BUS_BARRIER_READ) != 0)
310 alpha_mb();
311 else if ((f & BUS_BARRIER_WRITE) != 0)
312 alpha_wmb();
313 }
314
315 inline u_int8_t
316 tc_mem_read_1(v, memh, off)
317 void *v;
318 bus_space_handle_t memh;
319 bus_size_t off;
320 {
321 volatile u_int8_t *p;
322
323 alpha_mb(); /* XXX XXX XXX */
324
325 if ((memh & TC_SPACE_SPARSE) != 0)
326 panic("tc_mem_read_1 not implemented for sparse space");
327
328 p = (u_int8_t *)(memh + off);
329 return (*p);
330 }
331
332 inline u_int16_t
333 tc_mem_read_2(v, memh, off)
334 void *v;
335 bus_space_handle_t memh;
336 bus_size_t off;
337 {
338 volatile u_int16_t *p;
339
340 alpha_mb(); /* XXX XXX XXX */
341
342 if ((memh & TC_SPACE_SPARSE) != 0)
343 panic("tc_mem_read_2 not implemented for sparse space");
344
345 p = (u_int16_t *)(memh + off);
346 return (*p);
347 }
348
349 inline u_int32_t
350 tc_mem_read_4(v, memh, off)
351 void *v;
352 bus_space_handle_t memh;
353 bus_size_t off;
354 {
355 volatile u_int32_t *p;
356
357 alpha_mb(); /* XXX XXX XXX */
358
359 if ((memh & TC_SPACE_SPARSE) != 0)
360 /* Nothing special to do for 4-byte sparse space accesses */
361 p = (u_int32_t *)(memh + (off << 1));
362 else
363 p = (u_int32_t *)(memh + off);
364 return (*p);
365 }
366
367 inline u_int64_t
368 tc_mem_read_8(v, memh, off)
369 void *v;
370 bus_space_handle_t memh;
371 bus_size_t off;
372 {
373 volatile u_int64_t *p;
374
375 alpha_mb(); /* XXX XXX XXX */
376
377 if ((memh & TC_SPACE_SPARSE) != 0)
378 panic("tc_mem_read_8 not implemented for sparse space");
379
380 p = (u_int64_t *)(memh + off);
381 return (*p);
382 }
383
384 #define tc_mem_read_multi_N(BYTES,TYPE) \
385 void \
386 __abs_c(tc_mem_read_multi_,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 tc_mem_barrier(v, h, o, sizeof *a, BUS_BARRIER_READ); \
395 *a++ = __abs_c(tc_mem_read_,BYTES)(v, h, o); \
396 } \
397 }
398 tc_mem_read_multi_N(1,u_int8_t)
399 tc_mem_read_multi_N(2,u_int16_t)
400 tc_mem_read_multi_N(4,u_int32_t)
401 tc_mem_read_multi_N(8,u_int64_t)
402
403 #define tc_mem_read_region_N(BYTES,TYPE) \
404 void \
405 __abs_c(tc_mem_read_region_,BYTES)(v, h, o, a, c) \
406 void *v; \
407 bus_space_handle_t h; \
408 bus_size_t o, c; \
409 TYPE *a; \
410 { \
411 \
412 while (c-- > 0) { \
413 *a++ = __abs_c(tc_mem_read_,BYTES)(v, h, o); \
414 o += sizeof *a; \
415 } \
416 }
417 tc_mem_read_region_N(1,u_int8_t)
418 tc_mem_read_region_N(2,u_int16_t)
419 tc_mem_read_region_N(4,u_int32_t)
420 tc_mem_read_region_N(8,u_int64_t)
421
422 inline void
423 tc_mem_write_1(v, memh, off, val)
424 void *v;
425 bus_space_handle_t memh;
426 bus_size_t off;
427 u_int8_t val;
428 {
429
430 if ((memh & TC_SPACE_SPARSE) != 0) {
431 volatile u_int64_t *p, v;
432 u_int64_t shift, msk;
433
434 shift = off & 0x3;
435 off &= 0x3;
436
437 p = (u_int64_t *)(memh + (off << 1));
438
439 msk = ~(0x1 << shift) & 0xf;
440 v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
441
442 *p = val;
443 } else {
444 volatile u_int8_t *p;
445
446 p = (u_int8_t *)(memh + off);
447 *p = val;
448 }
449 alpha_mb(); /* XXX XXX XXX */
450 }
451
452 inline void
453 tc_mem_write_2(v, memh, off, val)
454 void *v;
455 bus_space_handle_t memh;
456 bus_size_t off;
457 u_int16_t val;
458 {
459
460 if ((memh & TC_SPACE_SPARSE) != 0) {
461 volatile u_int64_t *p, v;
462 u_int64_t shift, msk;
463
464 shift = off & 0x2;
465 off &= 0x3;
466
467 p = (u_int64_t *)(memh + (off << 1));
468
469 msk = ~(0x3 << shift) & 0xf;
470 v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
471
472 *p = val;
473 } else {
474 volatile u_int16_t *p;
475
476 p = (u_int16_t *)(memh + off);
477 *p = val;
478 }
479 alpha_mb(); /* XXX XXX XXX */
480 }
481
482 inline void
483 tc_mem_write_4(v, memh, off, val)
484 void *v;
485 bus_space_handle_t memh;
486 bus_size_t off;
487 u_int32_t val;
488 {
489 volatile u_int32_t *p;
490
491 if ((memh & TC_SPACE_SPARSE) != 0)
492 /* Nothing special to do for 4-byte sparse space accesses */
493 p = (u_int32_t *)(memh + (off << 1));
494 else
495 p = (u_int32_t *)(memh + off);
496 *p = val;
497 alpha_mb(); /* XXX XXX XXX */
498 }
499
500 inline void
501 tc_mem_write_8(v, memh, off, val)
502 void *v;
503 bus_space_handle_t memh;
504 bus_size_t off;
505 u_int64_t val;
506 {
507 volatile u_int64_t *p;
508
509 if ((memh & TC_SPACE_SPARSE) != 0)
510 panic("tc_mem_read_8 not implemented for sparse space");
511
512 p = (u_int64_t *)(memh + off);
513 *p = val;
514 alpha_mb(); /* XXX XXX XXX */
515 }
516
517 #define tc_mem_write_multi_N(BYTES,TYPE) \
518 void \
519 __abs_c(tc_mem_write_multi_,BYTES)(v, h, o, a, c) \
520 void *v; \
521 bus_space_handle_t h; \
522 bus_size_t o, c; \
523 const TYPE *a; \
524 { \
525 \
526 while (c-- > 0) { \
527 __abs_c(tc_mem_write_,BYTES)(v, h, o, *a++); \
528 tc_mem_barrier(v, h, o, sizeof *a, BUS_BARRIER_WRITE); \
529 } \
530 }
531 tc_mem_write_multi_N(1,u_int8_t)
532 tc_mem_write_multi_N(2,u_int16_t)
533 tc_mem_write_multi_N(4,u_int32_t)
534 tc_mem_write_multi_N(8,u_int64_t)
535
536 #define tc_mem_write_region_N(BYTES,TYPE) \
537 void \
538 __abs_c(tc_mem_write_region_,BYTES)(v, h, o, a, c) \
539 void *v; \
540 bus_space_handle_t h; \
541 bus_size_t o, c; \
542 const TYPE *a; \
543 { \
544 \
545 while (c-- > 0) { \
546 __abs_c(tc_mem_write_,BYTES)(v, h, o, *a++); \
547 o += sizeof *a; \
548 } \
549 }
550 tc_mem_write_region_N(1,u_int8_t)
551 tc_mem_write_region_N(2,u_int16_t)
552 tc_mem_write_region_N(4,u_int32_t)
553 tc_mem_write_region_N(8,u_int64_t)
554
555 #define tc_mem_set_multi_N(BYTES,TYPE) \
556 void \
557 __abs_c(tc_mem_set_multi_,BYTES)(v, h, o, val, c) \
558 void *v; \
559 bus_space_handle_t h; \
560 bus_size_t o, c; \
561 TYPE val; \
562 { \
563 \
564 while (c-- > 0) { \
565 __abs_c(tc_mem_write_,BYTES)(v, h, o, val); \
566 tc_mem_barrier(v, h, o, sizeof val, BUS_BARRIER_WRITE); \
567 } \
568 }
569 tc_mem_set_multi_N(1,u_int8_t)
570 tc_mem_set_multi_N(2,u_int16_t)
571 tc_mem_set_multi_N(4,u_int32_t)
572 tc_mem_set_multi_N(8,u_int64_t)
573
574 #define tc_mem_set_region_N(BYTES,TYPE) \
575 void \
576 __abs_c(tc_mem_set_region_,BYTES)(v, h, o, val, c) \
577 void *v; \
578 bus_space_handle_t h; \
579 bus_size_t o, c; \
580 TYPE val; \
581 { \
582 \
583 while (c-- > 0) { \
584 __abs_c(tc_mem_write_,BYTES)(v, h, o, val); \
585 o += sizeof val; \
586 } \
587 }
588 tc_mem_set_region_N(1,u_int8_t)
589 tc_mem_set_region_N(2,u_int16_t)
590 tc_mem_set_region_N(4,u_int32_t)
591 tc_mem_set_region_N(8,u_int64_t)
592
593 #define tc_mem_copy_N(BYTES) \
594 void \
595 __abs_c(tc_mem_copy_,BYTES)(v, h1, o1, h2, o2, c) \
596 void *v; \
597 bus_space_handle_t h1, h2; \
598 bus_size_t o1, o2, c; \
599 { \
600 bus_size_t i, o; \
601 \
602 if ((h1 & TC_SPACE_SPARSE) != 0 && \
603 (h2 & TC_SPACE_SPARSE) != 0) { \
604 bcopy((void *)(h1 + o1), (void *)(h2 + o2), c * BYTES); \
605 return; \
606 } \
607 \
608 for (i = 0, o = 0; i < c; i++, o += BYTES) \
609 __abs_c(tc_mem_write_,BYTES)(v, h2, o2 + o, \
610 __abs_c(tc_mem_read_,BYTES)(v, h1, o1 + o)); \
611 }
612 tc_mem_copy_N(1)
613 tc_mem_copy_N(2)
614 tc_mem_copy_N(4)
615 tc_mem_copy_N(8)
616