Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / alpha / pci / a12c_bus_mem.c
blob05c04a58a8fc85aab227b07d892366cd6992fe2a
1 /* $NetBSD: a12c_bus_mem.c,v 1.6 2009/03/14 14:45:53 dsl Exp $ */
3 /* [Notice revision 2.0]
4 * Copyright (c) 1997 Avalon Computer Systems, Inc.
5 * All rights reserved.
7 * Author: Ross Harvey
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright and
13 * author notice, this list of conditions, and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Avalon Computer Systems, Inc. nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 * 4. This copyright will be assigned to The NetBSD Foundation on
21 * 1/1/2000 unless these terms (including possibly the assignment
22 * date) are updated in writing by Avalon prior to the latest specified
23 * assignment date.
25 * THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
38 #include "opt_avalon_a12.h" /* Config options headers */
39 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <machine/bus.h>
44 #include <alpha/pci/a12creg.h>
45 #include <alpha/pci/a12cvar.h>
47 #define A12C_BUS_MEM() /* Generate ctags(1) key */
49 __KERNEL_RCSID(0, "$NetBSD: a12c_bus_mem.c,v 1.6 2009/03/14 14:45:53 dsl Exp $");
51 /* Memory barrier */
52 void pci_a12c_mem_barrier(void *, bus_space_handle_t,
53 bus_size_t, bus_size_t, int);
55 /* Memory read (single) */
56 u_int8_t pci_a12c_mem_read_1(void *, bus_space_handle_t,
57 bus_size_t);
58 u_int16_t pci_a12c_mem_read_2(void *, bus_space_handle_t,
59 bus_size_t);
60 u_int32_t pci_a12c_mem_read_4(void *, bus_space_handle_t,
61 bus_size_t);
62 u_int64_t pci_a12c_mem_read_8(void *, bus_space_handle_t,
63 bus_size_t);
65 /* Memory read multiple */
66 void pci_a12c_mem_read_multi_1(void *, bus_space_handle_t,
67 bus_size_t, u_int8_t *, bus_size_t);
68 void pci_a12c_mem_read_multi_2(void *, bus_space_handle_t,
69 bus_size_t, u_int16_t *, bus_size_t);
70 void pci_a12c_mem_read_multi_4(void *, bus_space_handle_t,
71 bus_size_t, u_int32_t *, bus_size_t);
72 void pci_a12c_mem_read_multi_8(void *, bus_space_handle_t,
73 bus_size_t, u_int64_t *, bus_size_t);
75 /* Memory read region */
76 void pci_a12c_mem_read_region_1(void *, bus_space_handle_t,
77 bus_size_t, u_int8_t *, bus_size_t);
78 void pci_a12c_mem_read_region_2(void *, bus_space_handle_t,
79 bus_size_t, u_int16_t *, bus_size_t);
80 void pci_a12c_mem_read_region_4(void *, bus_space_handle_t,
81 bus_size_t, u_int32_t *, bus_size_t);
82 void pci_a12c_mem_read_region_8(void *, bus_space_handle_t,
83 bus_size_t, u_int64_t *, bus_size_t);
85 /* Memory write (single) */
86 void pci_a12c_mem_write_1(void *, bus_space_handle_t,
87 bus_size_t, u_int8_t);
88 void pci_a12c_mem_write_2(void *, bus_space_handle_t,
89 bus_size_t, u_int16_t);
90 void pci_a12c_mem_write_4(void *, bus_space_handle_t,
91 bus_size_t, u_int32_t);
92 void pci_a12c_mem_write_8(void *, bus_space_handle_t,
93 bus_size_t, u_int64_t);
95 /* Memory write multiple */
96 void pci_a12c_mem_write_multi_1(void *, bus_space_handle_t,
97 bus_size_t, const u_int8_t *, bus_size_t);
98 void pci_a12c_mem_write_multi_2(void *, bus_space_handle_t,
99 bus_size_t, const u_int16_t *, bus_size_t);
100 void pci_a12c_mem_write_multi_4(void *, bus_space_handle_t,
101 bus_size_t, const u_int32_t *, bus_size_t);
102 void pci_a12c_mem_write_multi_8(void *, bus_space_handle_t,
103 bus_size_t, const u_int64_t *, bus_size_t);
105 /* Memory write region */
106 void pci_a12c_mem_write_region_1(void *, bus_space_handle_t,
107 bus_size_t, const u_int8_t *, bus_size_t);
108 void pci_a12c_mem_write_region_2(void *, bus_space_handle_t,
109 bus_size_t, const u_int16_t *, bus_size_t);
110 void pci_a12c_mem_write_region_4(void *, bus_space_handle_t,
111 bus_size_t, const u_int32_t *, bus_size_t);
112 void pci_a12c_mem_write_region_8(void *, bus_space_handle_t,
113 bus_size_t, const u_int64_t *, bus_size_t);
115 /* Memory set multiple */
116 void pci_a12c_mem_set_multi_1(void *, bus_space_handle_t,
117 bus_size_t, u_int8_t, bus_size_t);
118 void pci_a12c_mem_set_multi_2(void *, bus_space_handle_t,
119 bus_size_t, u_int16_t, bus_size_t);
120 void pci_a12c_mem_set_multi_4(void *, bus_space_handle_t,
121 bus_size_t, u_int32_t, bus_size_t);
122 void pci_a12c_mem_set_multi_8(void *, bus_space_handle_t,
123 bus_size_t, u_int64_t, bus_size_t);
125 /* Memory set region */
126 void pci_a12c_mem_set_region_1(void *, bus_space_handle_t,
127 bus_size_t, u_int8_t, bus_size_t);
128 void pci_a12c_mem_set_region_2(void *, bus_space_handle_t,
129 bus_size_t, u_int16_t, bus_size_t);
130 void pci_a12c_mem_set_region_4(void *, bus_space_handle_t,
131 bus_size_t, u_int32_t, bus_size_t);
132 void pci_a12c_mem_set_region_8(void *, bus_space_handle_t,
133 bus_size_t, u_int64_t, bus_size_t);
135 /* Memory copy */
136 void pci_a12c_mem_copy_region_1(void *, bus_space_handle_t,
137 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
138 void pci_a12c_mem_copy_region_2(void *, bus_space_handle_t,
139 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
140 void pci_a12c_mem_copy_region_4(void *, bus_space_handle_t,
141 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
142 void pci_a12c_mem_copy_region_8(void *, bus_space_handle_t,
143 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
145 #define __S(S) __STRING(S)
147 /* mapping/unmapping */
148 int pci_a12c_mem_map(void *, bus_addr_t, bus_size_t, int,
149 bus_space_handle_t *, int);
150 void pci_a12c_mem_unmap(void *, bus_space_handle_t,
151 bus_size_t, int);
152 int pci_a12c_mem_subregion(void *, bus_space_handle_t,
153 bus_size_t, bus_size_t, bus_space_handle_t *);
155 /* allocation/deallocation */
156 int pci_a12c_mem_alloc(void *, bus_addr_t, bus_addr_t,
157 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
158 bus_space_handle_t *);
159 void pci_a12c_mem_free(void *, bus_space_handle_t,
160 bus_size_t);
162 /* get kernel virtual address*/
163 void *pci_a12c_mem_vaddr(void *, bus_space_handle_t);
165 static struct alpha_bus_space pci_a12c_mem_space = {
166 /* cookie */
167 NULL,
169 /* mapping/unmapping */
170 pci_a12c_mem_map,
171 pci_a12c_mem_unmap,
172 pci_a12c_mem_subregion,
174 /* allocation/deallocation */
175 pci_a12c_mem_alloc,
176 pci_a12c_mem_free,
178 /* get kernel virtual address */
179 pci_a12c_mem_vaddr,
181 /* barrier */
182 pci_a12c_mem_barrier,
184 /* read (single) */
185 pci_a12c_mem_read_1,
186 pci_a12c_mem_read_2,
187 pci_a12c_mem_read_4,
188 pci_a12c_mem_read_8,
190 /* read multiple */
191 pci_a12c_mem_read_multi_1,
192 pci_a12c_mem_read_multi_2,
193 pci_a12c_mem_read_multi_4,
194 pci_a12c_mem_read_multi_8,
196 /* read region */
197 pci_a12c_mem_read_region_1,
198 pci_a12c_mem_read_region_2,
199 pci_a12c_mem_read_region_4,
200 pci_a12c_mem_read_region_8,
202 /* write (single) */
203 pci_a12c_mem_write_1,
204 pci_a12c_mem_write_2,
205 pci_a12c_mem_write_4,
206 pci_a12c_mem_write_8,
208 /* write multiple */
209 pci_a12c_mem_write_multi_1,
210 pci_a12c_mem_write_multi_2,
211 pci_a12c_mem_write_multi_4,
212 pci_a12c_mem_write_multi_8,
214 /* write region */
215 pci_a12c_mem_write_region_1,
216 pci_a12c_mem_write_region_2,
217 pci_a12c_mem_write_region_4,
218 pci_a12c_mem_write_region_8,
220 /* set multiple */
221 pci_a12c_mem_set_multi_1,
222 pci_a12c_mem_set_multi_2,
223 pci_a12c_mem_set_multi_4,
224 pci_a12c_mem_set_multi_8,
226 /* set region */
227 pci_a12c_mem_set_region_1,
228 pci_a12c_mem_set_region_2,
229 pci_a12c_mem_set_region_4,
230 pci_a12c_mem_set_region_8,
232 /* copy */
233 pci_a12c_mem_copy_region_1,
234 pci_a12c_mem_copy_region_2,
235 pci_a12c_mem_copy_region_4,
236 pci_a12c_mem_copy_region_8,
239 bus_space_tag_t
240 a12c_bus_mem_init(void *v)
242 bus_space_tag_t t;
244 t = &pci_a12c_mem_space;
245 t->abs_cookie = v;
246 return (t);
250 pci_a12c_mem_map(void *v, bus_addr_t memaddr, bus_size_t memsize, int flags, bus_space_handle_t *memhp, int acct)
252 if(flags & BUS_SPACE_MAP_LINEAR)
253 printf("warning, linear a12 pci map requested\n");
254 if(memaddr >= 1L<<28 || memaddr<0)
255 return -1;
256 *memhp = memaddr;
257 return 0;
260 void
261 pci_a12c_mem_unmap(void *v, bus_space_handle_t memh, bus_size_t memsize, int acct)
266 pci_a12c_mem_subregion(void *v, bus_space_handle_t memh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nmemh)
268 *nmemh = memh + offset;
269 return 0;
273 pci_a12c_mem_alloc(v, rstart, rend, size, align, boundary, flags,
274 addrp, bshp)
275 void *v;
276 bus_addr_t rstart, rend, *addrp;
277 bus_size_t size, align, boundary;
278 int flags;
279 bus_space_handle_t *bshp;
281 return -1;
284 void
285 pci_a12c_mem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
289 void *
290 pci_a12c_mem_vaddr(void *v, bus_space_handle_t bsh)
292 /* not supported (could panic() if pci_a12c_mem_map() caught it) */
293 return (0);
296 void
297 pci_a12c_mem_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f)
299 /* optimize for wmb-only case but fall back to the more general mb */
301 if (f == BUS_SPACE_BARRIER_WRITE)
302 alpha_wmb();
303 else alpha_mb();
306 * Don't worry about calling small subroutines on the alpha. In the
307 * time it takes to do a PCI bus target transfer, the 21164-400 can execute
308 * 160 cycles, and up to 320 integer instructions.
310 static void *
311 setup_target_transfer(bus_space_handle_t memh, bus_size_t off)
313 register u_int64_t addr,t;
315 alpha_mb();
316 addr = memh + off;
317 t = REGVAL(A12_OMR) & ~A12_OMR_PCIAddr2;
318 if (addr & 4)
319 t |= A12_OMR_PCIAddr2;
320 REGVAL(A12_OMR) = t;
321 alpha_mb();
322 return (void *)ALPHA_PHYS_TO_K0SEG(A12_PCITarget | (addr & ~4L));
325 #define TARGET_EA(t,memh,off) ((t *)setup_target_transfer((memh),(off)))
327 #define TARGET_READ(n,t) \
330 __CONCAT(pci_a12c_mem_read_,n)(void *v, \
331 bus_space_handle_t memh, \
332 bus_size_t off) \
334 return *TARGET_EA(t,memh,off); \
337 TARGET_READ(1, u_int8_t)
338 TARGET_READ(2, u_int16_t)
339 TARGET_READ(4, u_int32_t)
340 TARGET_READ(8, u_int64_t)
342 #define pci_a12c_mem_read_multi_N(BYTES,TYPE) \
343 void \
344 __CONCAT(pci_a12c_mem_read_multi_,BYTES)(v, h, o, a, c) \
345 void *v; \
346 bus_space_handle_t h; \
347 bus_size_t o, c; \
348 TYPE *a; \
351 while (c-- > 0) { \
352 alpha_mb(); \
353 *a++ = __CONCAT(pci_a12c_mem_read_,BYTES)(v, h, o); \
357 pci_a12c_mem_read_multi_N(1,u_int8_t)
358 pci_a12c_mem_read_multi_N(2,u_int16_t)
359 pci_a12c_mem_read_multi_N(4,u_int32_t)
360 pci_a12c_mem_read_multi_N(8,u_int64_t)
363 * In this case, we _really_ don't want all those barriers that the
364 * bus_space_read's once did, and that we have carried over into
365 * the A12 version. Perhaps we need a gratuitous barrier-on mode.
366 * The only reason to have the bus_space_r/w functions do barriers is
367 * to make up for call sites that incorrectly omit the bus_space_barrier
368 * calls.
371 #define pci_a12c_mem_read_region_N(BYTES,TYPE) \
372 void \
373 __CONCAT(pci_a12c_mem_read_region_,BYTES)(v, h, o, a, c) \
374 void *v; \
375 bus_space_handle_t h; \
376 bus_size_t o, c; \
377 TYPE *a; \
380 while (c-- > 0) { \
381 *a++ = __CONCAT(pci_a12c_mem_read_,BYTES)(v, h, o); \
382 o += sizeof *a; \
385 pci_a12c_mem_read_region_N(1,u_int8_t)
386 pci_a12c_mem_read_region_N(2,u_int16_t)
387 pci_a12c_mem_read_region_N(4,u_int32_t)
388 pci_a12c_mem_read_region_N(8,u_int64_t)
390 #define TARGET_WRITE(n,t) \
391 void \
392 __CONCAT(pci_a12c_mem_write_,n)(v, memh, off, val) \
393 void *v; \
394 bus_space_handle_t memh; \
395 bus_size_t off; \
396 t val; \
398 alpha_wmb(); \
399 *TARGET_EA(t,memh,off) = val; \
400 alpha_wmb(); \
403 TARGET_WRITE(1,u_int8_t)
404 TARGET_WRITE(2,u_int16_t)
405 TARGET_WRITE(4,u_int32_t)
406 TARGET_WRITE(8,u_int64_t)
408 #define pci_a12c_mem_write_multi_N(BYTES,TYPE) \
409 void \
410 __CONCAT(pci_a12c_mem_write_multi_,BYTES)(v, h, o, a, c) \
411 void *v; \
412 bus_space_handle_t h; \
413 bus_size_t o, c; \
414 const TYPE *a; \
417 while (c-- > 0) { \
418 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, *a++); \
419 alpha_wmb(); \
423 pci_a12c_mem_write_multi_N(1,u_int8_t)
424 pci_a12c_mem_write_multi_N(2,u_int16_t)
425 pci_a12c_mem_write_multi_N(4,u_int32_t)
426 pci_a12c_mem_write_multi_N(8,u_int64_t)
428 #define pci_a12c_mem_write_region_N(BYTES,TYPE) \
429 void \
430 __CONCAT(pci_a12c_mem_write_region_,BYTES)(v, h, o, a, c) \
431 void *v; \
432 bus_space_handle_t h; \
433 bus_size_t o, c; \
434 const TYPE *a; \
437 while (c-- > 0) { \
438 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, *a++); \
439 o += sizeof *a; \
443 pci_a12c_mem_write_region_N(1,u_int8_t)
444 pci_a12c_mem_write_region_N(2,u_int16_t)
445 pci_a12c_mem_write_region_N(4,u_int32_t)
446 pci_a12c_mem_write_region_N(8,u_int64_t)
448 #define pci_a12c_mem_set_multi_N(BYTES,TYPE) \
449 void \
450 __CONCAT(pci_a12c_mem_set_multi_,BYTES)(v, h, o, val, c) \
451 void *v; \
452 bus_space_handle_t h; \
453 bus_size_t o, c; \
454 TYPE val; \
457 while (c-- > 0) { \
458 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, val); \
459 alpha_wmb(); \
463 pci_a12c_mem_set_multi_N(1,u_int8_t)
464 pci_a12c_mem_set_multi_N(2,u_int16_t)
465 pci_a12c_mem_set_multi_N(4,u_int32_t)
466 pci_a12c_mem_set_multi_N(8,u_int64_t)
468 #define pci_a12c_mem_set_region_N(BYTES,TYPE) \
469 void \
470 __CONCAT(pci_a12c_mem_set_region_,BYTES)(v, h, o, val, c) \
471 void *v; \
472 bus_space_handle_t h; \
473 bus_size_t o, c; \
474 TYPE val; \
477 while (c-- > 0) { \
478 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, val); \
479 o += sizeof val; \
483 pci_a12c_mem_set_region_N(1,u_int8_t)
484 pci_a12c_mem_set_region_N(2,u_int16_t)
485 pci_a12c_mem_set_region_N(4,u_int32_t)
486 pci_a12c_mem_set_region_N(8,u_int64_t)
488 #define pci_a12c_mem_copy_region_N(BYTES) \
489 void \
490 __CONCAT(pci_a12c_mem_copy_region_,BYTES)(v, h1, o1, h2, o2, c) \
491 void *v; \
492 bus_space_handle_t h1, h2; \
493 bus_size_t o1, o2, c; \
495 bus_size_t o; \
497 if ((h1 >> 63) != 0 && (h2 >> 63) != 0) { \
498 memmove((void *)(h2 + o2), (void *)(h1 + o1), c * BYTES); \
499 return; \
502 if (h1 + o1 >= h2 + o2) \
503 /* src after dest: copy forward */ \
504 for (o = 0; c > 0; c--, o += BYTES) \
505 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h2, o2 + o, \
506 __CONCAT(pci_a12c_mem_read_,BYTES)(v, h1, o1 + o)); \
507 else \
508 /* dest after src: copy backwards */ \
509 for (o = (c - 1) * BYTES; c > 0; c--, o -= BYTES) \
510 __CONCAT(pci_a12c_mem_write_,BYTES)(v, h2, o2 + o, \
511 __CONCAT(pci_a12c_mem_read_,BYTES)(v, h1, o1 + o)); \
513 pci_a12c_mem_copy_region_N(1)
514 pci_a12c_mem_copy_region_N(2)
515 pci_a12c_mem_copy_region_N(4)
516 pci_a12c_mem_copy_region_N(8)