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