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