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