Annotation of sys/arch/alpha/tc/tc_bus_mem.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: tc_bus_mem.c,v 1.13 2002/05/02 22:56:06 miod Exp $ */
2: /* $NetBSD: tc_bus_mem.c,v 1.25 2001/09/04 05:31:28 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1996 Carnegie-Mellon University.
6: * All rights reserved.
7: *
8: * Author: Chris G. Demetriou
9: *
10: * Permission to use, copy, modify and distribute this software and
11: * its documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: /*
32: * Common TurboChannel Chipset "bus memory" functions.
33: */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/malloc.h>
38: #include <sys/syslog.h>
39: #include <sys/device.h>
40:
41: #include <uvm/uvm_extern.h>
42:
43: #include <machine/bus.h>
44: #include <dev/tc/tcvar.h>
45:
46: #define __C(A,B) __CONCAT(A,B)
47:
48: /* mapping/unmapping */
49: int tc_mem_map(void *, bus_addr_t, bus_size_t, int,
50: bus_space_handle_t *);
51: void tc_mem_unmap(void *, bus_space_handle_t, bus_size_t);
52: int tc_mem_subregion(void *, bus_space_handle_t, bus_size_t,
53: bus_size_t, bus_space_handle_t *);
54:
55: /* allocation/deallocation */
56: int tc_mem_alloc(void *, bus_addr_t, bus_addr_t, bus_size_t,
57: bus_size_t, bus_addr_t, int, bus_addr_t *,
58: bus_space_handle_t *);
59: void tc_mem_free(void *, bus_space_handle_t, bus_size_t);
60:
61: /* barrier */
62: inline void tc_mem_barrier(void *, bus_space_handle_t,
63: bus_size_t, bus_size_t, int);
64:
65: /* read (single) */
66: inline u_int8_t tc_mem_read_1(void *, bus_space_handle_t, bus_size_t);
67: inline u_int16_t tc_mem_read_2(void *, bus_space_handle_t, bus_size_t);
68: inline u_int32_t tc_mem_read_4(void *, bus_space_handle_t, bus_size_t);
69: inline u_int64_t tc_mem_read_8(void *, bus_space_handle_t, bus_size_t);
70:
71: /* read multiple */
72: void tc_mem_read_multi_1(void *, bus_space_handle_t,
73: bus_size_t, u_int8_t *, bus_size_t);
74: void tc_mem_read_multi_2(void *, bus_space_handle_t,
75: bus_size_t, u_int16_t *, bus_size_t);
76: void tc_mem_read_multi_4(void *, bus_space_handle_t,
77: bus_size_t, u_int32_t *, bus_size_t);
78: void tc_mem_read_multi_8(void *, bus_space_handle_t,
79: bus_size_t, u_int64_t *, bus_size_t);
80:
81: /* read region */
82: void tc_mem_read_region_1(void *, bus_space_handle_t,
83: bus_size_t, u_int8_t *, bus_size_t);
84: void tc_mem_read_region_2(void *, bus_space_handle_t,
85: bus_size_t, u_int16_t *, bus_size_t);
86: void tc_mem_read_region_4(void *, bus_space_handle_t,
87: bus_size_t, u_int32_t *, bus_size_t);
88: void tc_mem_read_region_8(void *, bus_space_handle_t,
89: bus_size_t, u_int64_t *, bus_size_t);
90:
91: /* write (single) */
92: inline void tc_mem_write_1(void *, bus_space_handle_t, bus_size_t,
93: u_int8_t);
94: inline void tc_mem_write_2(void *, bus_space_handle_t, bus_size_t,
95: u_int16_t);
96: inline void tc_mem_write_4(void *, bus_space_handle_t, bus_size_t,
97: u_int32_t);
98: inline void tc_mem_write_8(void *, bus_space_handle_t, bus_size_t,
99: u_int64_t);
100:
101: /* write multiple */
102: void tc_mem_write_multi_1(void *, bus_space_handle_t,
103: bus_size_t, const u_int8_t *, bus_size_t);
104: void tc_mem_write_multi_2(void *, bus_space_handle_t,
105: bus_size_t, const u_int16_t *, bus_size_t);
106: void tc_mem_write_multi_4(void *, bus_space_handle_t,
107: bus_size_t, const u_int32_t *, bus_size_t);
108: void tc_mem_write_multi_8(void *, bus_space_handle_t,
109: bus_size_t, const u_int64_t *, bus_size_t);
110:
111: /* write region */
112: void tc_mem_write_region_1(void *, bus_space_handle_t,
113: bus_size_t, const u_int8_t *, bus_size_t);
114: void tc_mem_write_region_2(void *, bus_space_handle_t,
115: bus_size_t, const u_int16_t *, bus_size_t);
116: void tc_mem_write_region_4(void *, bus_space_handle_t,
117: bus_size_t, const u_int32_t *, bus_size_t);
118: void tc_mem_write_region_8(void *, bus_space_handle_t,
119: bus_size_t, const u_int64_t *, bus_size_t);
120:
121: /* set multiple */
122: void tc_mem_set_multi_1(void *, bus_space_handle_t,
123: bus_size_t, u_int8_t, bus_size_t);
124: void tc_mem_set_multi_2(void *, bus_space_handle_t,
125: bus_size_t, u_int16_t, bus_size_t);
126: void tc_mem_set_multi_4(void *, bus_space_handle_t,
127: bus_size_t, u_int32_t, bus_size_t);
128: void tc_mem_set_multi_8(void *, bus_space_handle_t,
129: bus_size_t, u_int64_t, bus_size_t);
130:
131: /* set region */
132: void tc_mem_set_region_1(void *, bus_space_handle_t,
133: bus_size_t, u_int8_t, bus_size_t);
134: void tc_mem_set_region_2(void *, bus_space_handle_t,
135: bus_size_t, u_int16_t, bus_size_t);
136: void tc_mem_set_region_4(void *, bus_space_handle_t,
137: bus_size_t, u_int32_t, bus_size_t);
138: void tc_mem_set_region_8(void *, bus_space_handle_t,
139: bus_size_t, u_int64_t, bus_size_t);
140:
141: /* copy */
142: void tc_mem_copy_region_1(void *, bus_space_handle_t,
143: bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
144: void tc_mem_copy_region_2(void *, bus_space_handle_t,
145: bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
146: void tc_mem_copy_region_4(void *, bus_space_handle_t,
147: bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
148: void tc_mem_copy_region_8(void *, bus_space_handle_t,
149: bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
150:
151: struct alpha_bus_space tc_mem_space = {
152: /* cookie */
153: NULL,
154:
155: /* mapping/unmapping */
156: tc_mem_map,
157: tc_mem_unmap,
158: tc_mem_subregion,
159:
160: /* allocation/deallocation */
161: tc_mem_alloc,
162: tc_mem_free,
163:
164: /* barrier */
165: tc_mem_barrier,
166:
167: /* read (single) */
168: tc_mem_read_1,
169: tc_mem_read_2,
170: tc_mem_read_4,
171: tc_mem_read_8,
172:
173: /* read multiple */
174: tc_mem_read_multi_1,
175: tc_mem_read_multi_2,
176: tc_mem_read_multi_4,
177: tc_mem_read_multi_8,
178:
179: /* read region */
180: tc_mem_read_region_1,
181: tc_mem_read_region_2,
182: tc_mem_read_region_4,
183: tc_mem_read_region_8,
184:
185: /* write (single) */
186: tc_mem_write_1,
187: tc_mem_write_2,
188: tc_mem_write_4,
189: tc_mem_write_8,
190:
191: /* write multiple */
192: tc_mem_write_multi_1,
193: tc_mem_write_multi_2,
194: tc_mem_write_multi_4,
195: tc_mem_write_multi_8,
196:
197: /* write region */
198: tc_mem_write_region_1,
199: tc_mem_write_region_2,
200: tc_mem_write_region_4,
201: tc_mem_write_region_8,
202:
203: /* set multiple */
204: tc_mem_set_multi_1,
205: tc_mem_set_multi_2,
206: tc_mem_set_multi_4,
207: tc_mem_set_multi_8,
208:
209: /* set region */
210: tc_mem_set_region_1,
211: tc_mem_set_region_2,
212: tc_mem_set_region_4,
213: tc_mem_set_region_8,
214:
215: /* copy */
216: tc_mem_copy_region_1,
217: tc_mem_copy_region_2,
218: tc_mem_copy_region_4,
219: tc_mem_copy_region_8,
220: };
221:
222: bus_space_tag_t
223: tc_bus_mem_init(memv)
224: void *memv;
225: {
226: bus_space_tag_t h = &tc_mem_space;
227:
228: h->abs_cookie = memv;
229: return (h);
230: }
231:
232: /* ARGSUSED */
233: int
234: tc_mem_map(v, memaddr, memsize, cacheable, memhp)
235: void *v;
236: bus_addr_t memaddr;
237: bus_size_t memsize;
238: int cacheable;
239: bus_space_handle_t *memhp;
240: {
241:
242: if (memaddr & 0x7)
243: panic("tc_mem_map needs 8 byte alignment");
244: if (cacheable)
245: *memhp = ALPHA_PHYS_TO_K0SEG(memaddr);
246: else
247: *memhp = ALPHA_PHYS_TO_K0SEG(TC_DENSE_TO_SPARSE(memaddr));
248: return (0);
249: }
250:
251: /* ARGSUSED */
252: void
253: tc_mem_unmap(v, memh, memsize)
254: void *v;
255: bus_space_handle_t memh;
256: bus_size_t memsize;
257: {
258:
259: /* XXX XX XXX nothing to do. */
260: }
261:
262: int
263: tc_mem_subregion(v, memh, offset, size, nmemh)
264: void *v;
265: bus_space_handle_t memh, *nmemh;
266: bus_size_t offset, size;
267: {
268:
269: /* Disallow subregioning that would make the handle unaligned. */
270: if ((offset & 0x7) != 0)
271: return (1);
272:
273: if ((memh & TC_SPACE_SPARSE) != 0)
274: *nmemh = memh + (offset << 1);
275: else
276: *nmemh = memh + offset;
277:
278: return (0);
279: }
280:
281: int
282: tc_mem_alloc(v, rstart, rend, size, align, boundary, flags, addrp, bshp)
283: void *v;
284: bus_addr_t rstart, rend, *addrp;
285: bus_size_t size, align, boundary;
286: int flags;
287: bus_space_handle_t *bshp;
288: {
289:
290: /* XXX XXX XXX XXX XXX XXX */
291: panic("tc_mem_alloc unimplemented");
292: }
293:
294: void
295: tc_mem_free(v, bsh, size)
296: void *v;
297: bus_space_handle_t bsh;
298: bus_size_t size;
299: {
300:
301: /* XXX XXX XXX XXX XXX XXX */
302: panic("tc_mem_free unimplemented");
303: }
304:
305: inline void
306: tc_mem_barrier(v, h, o, l, f)
307: void *v;
308: bus_space_handle_t h;
309: bus_size_t o, l;
310: int f;
311: {
312:
313: if ((f & BUS_SPACE_BARRIER_READ) != 0)
314: alpha_mb();
315: else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
316: alpha_wmb();
317: }
318:
319: inline u_int8_t
320: tc_mem_read_1(v, memh, off)
321: void *v;
322: bus_space_handle_t memh;
323: bus_size_t off;
324: {
325: volatile u_int8_t *p;
326:
327: alpha_mb(); /* XXX XXX XXX */
328:
329: if ((memh & TC_SPACE_SPARSE) != 0)
330: panic("tc_mem_read_1 not implemented for sparse space");
331:
332: p = (u_int8_t *)(memh + off);
333: return (*p);
334: }
335:
336: inline u_int16_t
337: tc_mem_read_2(v, memh, off)
338: void *v;
339: bus_space_handle_t memh;
340: bus_size_t off;
341: {
342: volatile u_int16_t *p;
343:
344: alpha_mb(); /* XXX XXX XXX */
345:
346: if ((memh & TC_SPACE_SPARSE) != 0)
347: panic("tc_mem_read_2 not implemented for sparse space");
348:
349: p = (u_int16_t *)(memh + off);
350: return (*p);
351: }
352:
353: inline u_int32_t
354: tc_mem_read_4(v, memh, off)
355: void *v;
356: bus_space_handle_t memh;
357: bus_size_t off;
358: {
359: volatile u_int32_t *p;
360:
361: alpha_mb(); /* XXX XXX XXX */
362:
363: if ((memh & TC_SPACE_SPARSE) != 0)
364: /* Nothing special to do for 4-byte sparse space accesses */
365: p = (u_int32_t *)(memh + (off << 1));
366: else
367: p = (u_int32_t *)(memh + off);
368: return (*p);
369: }
370:
371: inline u_int64_t
372: tc_mem_read_8(v, memh, off)
373: void *v;
374: bus_space_handle_t memh;
375: bus_size_t off;
376: {
377: volatile u_int64_t *p;
378:
379: alpha_mb(); /* XXX XXX XXX */
380:
381: if ((memh & TC_SPACE_SPARSE) != 0)
382: panic("tc_mem_read_8 not implemented for sparse space");
383:
384: p = (u_int64_t *)(memh + off);
385: return (*p);
386: }
387:
388: #define tc_mem_read_multi_N(BYTES,TYPE) \
389: void \
390: __C(tc_mem_read_multi_,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: tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_READ); \
399: *a++ = __C(tc_mem_read_,BYTES)(v, h, o); \
400: } \
401: }
402: tc_mem_read_multi_N(1,u_int8_t)
403: tc_mem_read_multi_N(2,u_int16_t)
404: tc_mem_read_multi_N(4,u_int32_t)
405: tc_mem_read_multi_N(8,u_int64_t)
406:
407: #define tc_mem_read_region_N(BYTES,TYPE) \
408: void \
409: __C(tc_mem_read_region_,BYTES)(v, h, o, a, c) \
410: void *v; \
411: bus_space_handle_t h; \
412: bus_size_t o, c; \
413: TYPE *a; \
414: { \
415: \
416: while (c-- > 0) { \
417: *a++ = __C(tc_mem_read_,BYTES)(v, h, o); \
418: o += sizeof *a; \
419: } \
420: }
421: tc_mem_read_region_N(1,u_int8_t)
422: tc_mem_read_region_N(2,u_int16_t)
423: tc_mem_read_region_N(4,u_int32_t)
424: tc_mem_read_region_N(8,u_int64_t)
425:
426: inline void
427: tc_mem_write_1(v, memh, off, val)
428: void *v;
429: bus_space_handle_t memh;
430: bus_size_t off;
431: u_int8_t val;
432: {
433:
434: if ((memh & TC_SPACE_SPARSE) != 0) {
435: volatile u_int64_t *p, v;
436: u_int64_t shift, msk;
437:
438: shift = off & 0x3;
439: off &= 0x3;
440:
441: p = (u_int64_t *)(memh + (off << 1));
442:
443: msk = ~(0x1 << shift) & 0xf;
444: v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
445:
446: *p = val;
447: } else {
448: volatile u_int8_t *p;
449:
450: p = (u_int8_t *)(memh + off);
451: *p = val;
452: }
453: alpha_mb(); /* XXX XXX XXX */
454: }
455:
456: inline void
457: tc_mem_write_2(v, memh, off, val)
458: void *v;
459: bus_space_handle_t memh;
460: bus_size_t off;
461: u_int16_t val;
462: {
463:
464: if ((memh & TC_SPACE_SPARSE) != 0) {
465: volatile u_int64_t *p, v;
466: u_int64_t shift, msk;
467:
468: shift = off & 0x2;
469: off &= 0x3;
470:
471: p = (u_int64_t *)(memh + (off << 1));
472:
473: msk = ~(0x3 << shift) & 0xf;
474: v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
475:
476: *p = val;
477: } else {
478: volatile u_int16_t *p;
479:
480: p = (u_int16_t *)(memh + off);
481: *p = val;
482: }
483: alpha_mb(); /* XXX XXX XXX */
484: }
485:
486: inline void
487: tc_mem_write_4(v, memh, off, val)
488: void *v;
489: bus_space_handle_t memh;
490: bus_size_t off;
491: u_int32_t val;
492: {
493: volatile u_int32_t *p;
494:
495: if ((memh & TC_SPACE_SPARSE) != 0)
496: /* Nothing special to do for 4-byte sparse space accesses */
497: p = (u_int32_t *)(memh + (off << 1));
498: else
499: p = (u_int32_t *)(memh + off);
500: *p = val;
501: alpha_mb(); /* XXX XXX XXX */
502: }
503:
504: inline void
505: tc_mem_write_8(v, memh, off, val)
506: void *v;
507: bus_space_handle_t memh;
508: bus_size_t off;
509: u_int64_t val;
510: {
511: volatile u_int64_t *p;
512:
513: if ((memh & TC_SPACE_SPARSE) != 0)
514: panic("tc_mem_read_8 not implemented for sparse space");
515:
516: p = (u_int64_t *)(memh + off);
517: *p = val;
518: alpha_mb(); /* XXX XXX XXX */
519: }
520:
521: #define tc_mem_write_multi_N(BYTES,TYPE) \
522: void \
523: __C(tc_mem_write_multi_,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: __C(tc_mem_write_,BYTES)(v, h, o, *a++); \
532: tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_WRITE); \
533: } \
534: }
535: tc_mem_write_multi_N(1,u_int8_t)
536: tc_mem_write_multi_N(2,u_int16_t)
537: tc_mem_write_multi_N(4,u_int32_t)
538: tc_mem_write_multi_N(8,u_int64_t)
539:
540: #define tc_mem_write_region_N(BYTES,TYPE) \
541: void \
542: __C(tc_mem_write_region_,BYTES)(v, h, o, a, c) \
543: void *v; \
544: bus_space_handle_t h; \
545: bus_size_t o, c; \
546: const TYPE *a; \
547: { \
548: \
549: while (c-- > 0) { \
550: __C(tc_mem_write_,BYTES)(v, h, o, *a++); \
551: o += sizeof *a; \
552: } \
553: }
554: tc_mem_write_region_N(1,u_int8_t)
555: tc_mem_write_region_N(2,u_int16_t)
556: tc_mem_write_region_N(4,u_int32_t)
557: tc_mem_write_region_N(8,u_int64_t)
558:
559: #define tc_mem_set_multi_N(BYTES,TYPE) \
560: void \
561: __C(tc_mem_set_multi_,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: __C(tc_mem_write_,BYTES)(v, h, o, val); \
570: tc_mem_barrier(v, h, o, sizeof val, BUS_SPACE_BARRIER_WRITE); \
571: } \
572: }
573: tc_mem_set_multi_N(1,u_int8_t)
574: tc_mem_set_multi_N(2,u_int16_t)
575: tc_mem_set_multi_N(4,u_int32_t)
576: tc_mem_set_multi_N(8,u_int64_t)
577:
578: #define tc_mem_set_region_N(BYTES,TYPE) \
579: void \
580: __C(tc_mem_set_region_,BYTES)(v, h, o, val, c) \
581: void *v; \
582: bus_space_handle_t h; \
583: bus_size_t o, c; \
584: TYPE val; \
585: { \
586: \
587: while (c-- > 0) { \
588: __C(tc_mem_write_,BYTES)(v, h, o, val); \
589: o += sizeof val; \
590: } \
591: }
592: tc_mem_set_region_N(1,u_int8_t)
593: tc_mem_set_region_N(2,u_int16_t)
594: tc_mem_set_region_N(4,u_int32_t)
595: tc_mem_set_region_N(8,u_int64_t)
596:
597: #define tc_mem_copy_region_N(BYTES) \
598: void \
599: __C(tc_mem_copy_region_,BYTES)(v, h1, o1, h2, o2, c) \
600: void *v; \
601: bus_space_handle_t h1, h2; \
602: bus_size_t o1, o2, c; \
603: { \
604: bus_size_t o; \
605: \
606: if ((h1 & TC_SPACE_SPARSE) != 0 && \
607: (h2 & TC_SPACE_SPARSE) != 0) { \
608: bcopy((void *)(h1 + o1), (void *)(h2 + o2), c * BYTES); \
609: return; \
610: } \
611: \
612: if (h1 + o1 >= h2 + o2) \
613: /* src after dest: copy forward */ \
614: for (o = 0; c > 0; c--, o += BYTES) \
615: __C(tc_mem_write_,BYTES)(v, h2, o2 + o, \
616: __C(tc_mem_read_,BYTES)(v, h1, o1 + o)); \
617: else \
618: /* dest after src: copy backwards */ \
619: for (o = (c - 1) * BYTES; c > 0; c--, o -= BYTES) \
620: __C(tc_mem_write_,BYTES)(v, h2, o2 + o, \
621: __C(tc_mem_read_,BYTES)(v, h1, o1 + o)); \
622: }
623: tc_mem_copy_region_N(1)
624: tc_mem_copy_region_N(2)
625: tc_mem_copy_region_N(4)
626: tc_mem_copy_region_N(8)
CVSweb