pci_bwx_bus_mem_chipdep.c revision 1.25 1 /* $NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.25 2012/02/06 02:14:15 matt Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
35 * All rights reserved.
36 *
37 * Author: Chris G. Demetriou
38 *
39 * Permission to use, copy, modify and distribute this software and
40 * its documentation is hereby granted, provided that both the copyright
41 * notice and this permission notice appear in all copies of the
42 * software, derivative works or modified versions, and any portions
43 * thereof, and that both notices appear in supporting documentation.
44 *
45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 *
49 * Carnegie Mellon requests users of this software to return to
50 *
51 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
52 * School of Computer Science
53 * Carnegie Mellon University
54 * Pittsburgh PA 15213-3890
55 *
56 * any improvements or extensions that they make and grant Carnegie the
57 * rights to redistribute these changes.
58 */
59
60 /*
61 * Common PCI Chipset "bus I/O" functions, for chipsets which have to
62 * deal with only a single PCI interface chip in a machine.
63 *
64 * uses:
65 * CHIP name of the 'chip' it's being compiled for.
66 * CHIP_MEM_BASE Mem space base to use.
67 * CHIP_MEM_EX_STORE
68 * If defined, device-provided static storage area
69 * for the memory space extent. If this is
70 * defined, CHIP_MEM_EX_STORE_SIZE must also be
71 * defined. If this is not defined, a static area
72 * will be declared.
73 * CHIP_MEM_EX_STORE_SIZE
74 * Size of the device-provided static storage area
75 * for the memory space extent.
76 */
77
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.25 2012/02/06 02:14:15 matt Exp $");
80
81 #include <sys/extent.h>
82
83 #include <machine/bwx.h>
84
85 #define __C(A,B) __CONCAT(A,B)
86 #define __S(S) __STRING(S)
87
88 /* mapping/unmapping */
89 int __C(CHIP,_mem_map)(void *, bus_addr_t, bus_size_t, int,
90 bus_space_handle_t *, int);
91 void __C(CHIP,_mem_unmap)(void *, bus_space_handle_t,
92 bus_size_t, int);
93 int __C(CHIP,_mem_subregion)(void *, bus_space_handle_t,
94 bus_size_t, bus_size_t, bus_space_handle_t *);
95
96 int __C(CHIP,_mem_translate)(void *, bus_addr_t, bus_size_t,
97 int, struct alpha_bus_space_translation *);
98 int __C(CHIP,_mem_get_window)(void *, int,
99 struct alpha_bus_space_translation *);
100
101 /* allocation/deallocation */
102 int __C(CHIP,_mem_alloc)(void *, bus_addr_t, bus_addr_t,
103 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
104 bus_space_handle_t *);
105 void __C(CHIP,_mem_free)(void *, bus_space_handle_t,
106 bus_size_t);
107
108 /* get kernel virtual address */
109 void * __C(CHIP,_mem_vaddr)(void *, bus_space_handle_t);
110
111 /* mmap for user */
112 paddr_t __C(CHIP,_mem_mmap)(void *, bus_addr_t, off_t, int, int);
113
114 /* barrier */
115 static inline void __C(CHIP,_mem_barrier)(void *, bus_space_handle_t,
116 bus_size_t, bus_size_t, int);
117
118 /* read (single) */
119 static inline uint8_t __C(CHIP,_mem_read_1)(void *, bus_space_handle_t,
120 bus_size_t);
121 static inline uint16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t,
122 bus_size_t);
123 static inline uint32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t,
124 bus_size_t);
125 static inline uint64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t,
126 bus_size_t);
127
128 /* read multiple */
129 void __C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t,
130 bus_size_t, uint8_t *, bus_size_t);
131 void __C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t,
132 bus_size_t, uint16_t *, bus_size_t);
133 void __C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t,
134 bus_size_t, uint32_t *, bus_size_t);
135 void __C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t,
136 bus_size_t, uint64_t *, bus_size_t);
137
138 /* read region */
139 void __C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t,
140 bus_size_t, uint8_t *, bus_size_t);
141 void __C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t,
142 bus_size_t, uint16_t *, bus_size_t);
143 void __C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t,
144 bus_size_t, uint32_t *, bus_size_t);
145 void __C(CHIP,_mem_read_region_8)(void *, bus_space_handle_t,
146 bus_size_t, uint64_t *, bus_size_t);
147
148 /* write (single) */
149 static inline void __C(CHIP,_mem_write_1)(void *, bus_space_handle_t,
150 bus_size_t, uint8_t);
151 static inline void __C(CHIP,_mem_write_2)(void *, bus_space_handle_t,
152 bus_size_t, uint16_t);
153 static inline void __C(CHIP,_mem_write_4)(void *, bus_space_handle_t,
154 bus_size_t, uint32_t);
155 static inline void __C(CHIP,_mem_write_8)(void *, bus_space_handle_t,
156 bus_size_t, uint64_t);
157
158 /* write multiple */
159 void __C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t,
160 bus_size_t, const uint8_t *, bus_size_t);
161 void __C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t,
162 bus_size_t, const uint16_t *, bus_size_t);
163 void __C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t,
164 bus_size_t, const uint32_t *, bus_size_t);
165 void __C(CHIP,_mem_write_multi_8)(void *, bus_space_handle_t,
166 bus_size_t, const uint64_t *, bus_size_t);
167
168 /* write region */
169 void __C(CHIP,_mem_write_region_1)(void *, bus_space_handle_t,
170 bus_size_t, const uint8_t *, bus_size_t);
171 void __C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t,
172 bus_size_t, const uint16_t *, bus_size_t);
173 void __C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t,
174 bus_size_t, const uint32_t *, bus_size_t);
175 void __C(CHIP,_mem_write_region_8)(void *, bus_space_handle_t,
176 bus_size_t, const uint64_t *, bus_size_t);
177
178 /* set multiple */
179 void __C(CHIP,_mem_set_multi_1)(void *, bus_space_handle_t,
180 bus_size_t, uint8_t, bus_size_t);
181 void __C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t,
182 bus_size_t, uint16_t, bus_size_t);
183 void __C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t,
184 bus_size_t, uint32_t, bus_size_t);
185 void __C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t,
186 bus_size_t, uint64_t, bus_size_t);
187
188 /* set region */
189 void __C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t,
190 bus_size_t, uint8_t, bus_size_t);
191 void __C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t,
192 bus_size_t, uint16_t, bus_size_t);
193 void __C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t,
194 bus_size_t, uint32_t, bus_size_t);
195 void __C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t,
196 bus_size_t, uint64_t, bus_size_t);
197
198 /* copy */
199 void __C(CHIP,_mem_copy_region_1)(void *, bus_space_handle_t,
200 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
201 void __C(CHIP,_mem_copy_region_2)(void *, bus_space_handle_t,
202 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
203 void __C(CHIP,_mem_copy_region_4)(void *, bus_space_handle_t,
204 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
205 void __C(CHIP,_mem_copy_region_8)(void *, bus_space_handle_t,
206 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
207
208 #ifndef CHIP_MEM_EX_STORE
209 static long
210 __C(CHIP,_mem_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
211 #define CHIP_MEM_EX_STORE(v) (__C(CHIP,_mem_ex_storage))
212 #define CHIP_MEM_EX_STORE_SIZE(v) (sizeof __C(CHIP,_mem_ex_storage))
213 #endif
214
215 void
216 __C(CHIP,_bus_mem_init)(
217 bus_space_tag_t t,
218 void *v)
219 {
220 struct extent *ex;
221
222 /*
223 * Initialize the bus space tag.
224 */
225
226 /* cookie */
227 t->abs_cookie = v;
228
229 /* mapping/unmapping */
230 t->abs_map = __C(CHIP,_mem_map);
231 t->abs_unmap = __C(CHIP,_mem_unmap);
232 t->abs_subregion = __C(CHIP,_mem_subregion);
233
234 t->abs_translate = __C(CHIP,_mem_translate);
235 t->abs_get_window = __C(CHIP,_mem_get_window);
236
237 /* allocation/deallocation */
238 t->abs_alloc = __C(CHIP,_mem_alloc);
239 t->abs_free = __C(CHIP,_mem_free);
240
241 /* get kernel virtual address */
242 t->abs_vaddr = __C(CHIP,_mem_vaddr);
243
244 /* mmap for user */
245 t->abs_mmap = __C(CHIP,_mem_mmap);
246
247 /* barrier */
248 t->abs_barrier = __C(CHIP,_mem_barrier);
249
250 /* read (single) */
251 t->abs_r_1 = __C(CHIP,_mem_read_1);
252 t->abs_r_2 = __C(CHIP,_mem_read_2);
253 t->abs_r_4 = __C(CHIP,_mem_read_4);
254 t->abs_r_8 = __C(CHIP,_mem_read_8);
255
256 /* read multiple */
257 t->abs_rm_1 = __C(CHIP,_mem_read_multi_1);
258 t->abs_rm_2 = __C(CHIP,_mem_read_multi_2);
259 t->abs_rm_4 = __C(CHIP,_mem_read_multi_4);
260 t->abs_rm_8 = __C(CHIP,_mem_read_multi_8);
261
262 /* read region */
263 t->abs_rr_1 = __C(CHIP,_mem_read_region_1);
264 t->abs_rr_2 = __C(CHIP,_mem_read_region_2);
265 t->abs_rr_4 = __C(CHIP,_mem_read_region_4);
266 t->abs_rr_8 = __C(CHIP,_mem_read_region_8);
267
268 /* write (single) */
269 t->abs_w_1 = __C(CHIP,_mem_write_1);
270 t->abs_w_2 = __C(CHIP,_mem_write_2);
271 t->abs_w_4 = __C(CHIP,_mem_write_4);
272 t->abs_w_8 = __C(CHIP,_mem_write_8);
273
274 /* write multiple */
275 t->abs_wm_1 = __C(CHIP,_mem_write_multi_1);
276 t->abs_wm_2 = __C(CHIP,_mem_write_multi_2);
277 t->abs_wm_4 = __C(CHIP,_mem_write_multi_4);
278 t->abs_wm_8 = __C(CHIP,_mem_write_multi_8);
279
280 /* write region */
281 t->abs_wr_1 = __C(CHIP,_mem_write_region_1);
282 t->abs_wr_2 = __C(CHIP,_mem_write_region_2);
283 t->abs_wr_4 = __C(CHIP,_mem_write_region_4);
284 t->abs_wr_8 = __C(CHIP,_mem_write_region_8);
285
286 /* set multiple */
287 t->abs_sm_1 = __C(CHIP,_mem_set_multi_1);
288 t->abs_sm_2 = __C(CHIP,_mem_set_multi_2);
289 t->abs_sm_4 = __C(CHIP,_mem_set_multi_4);
290 t->abs_sm_8 = __C(CHIP,_mem_set_multi_8);
291
292 /* set region */
293 t->abs_sr_1 = __C(CHIP,_mem_set_region_1);
294 t->abs_sr_2 = __C(CHIP,_mem_set_region_2);
295 t->abs_sr_4 = __C(CHIP,_mem_set_region_4);
296 t->abs_sr_8 = __C(CHIP,_mem_set_region_8);
297
298 /* copy */
299 t->abs_c_1 = __C(CHIP,_mem_copy_region_1);
300 t->abs_c_2 = __C(CHIP,_mem_copy_region_2);
301 t->abs_c_4 = __C(CHIP,_mem_copy_region_4);
302 t->abs_c_8 = __C(CHIP,_mem_copy_region_8);
303
304 ex = extent_create(__S(__C(CHIP,_bus_mem)), 0x0UL, 0xffffffffUL,
305 (void *)CHIP_MEM_EX_STORE(v), CHIP_MEM_EX_STORE_SIZE(v),
306 EX_NOWAIT|EX_NOCOALESCE);
307
308 CHIP_MEM_EXTENT(v) = ex;
309 }
310
311 int
312 __C(CHIP,_mem_translate)(
313 void *v,
314 bus_addr_t memaddr,
315 bus_size_t memlen,
316 int flags,
317 struct alpha_bus_space_translation *abst)
318 {
319
320 /* XXX */
321 return (EOPNOTSUPP);
322 }
323
324 int
325 __C(CHIP,_mem_get_window)(
326 void *v,
327 int window,
328 struct alpha_bus_space_translation *abst)
329 {
330
331 switch (window) {
332 case 0:
333 abst->abst_bus_start = 0;
334 abst->abst_bus_end = 0xffffffffUL;
335 abst->abst_sys_start = CHIP_MEM_SYS_START(v);
336 abst->abst_sys_end = CHIP_MEM_SYS_START(v) + abst->abst_bus_end;
337 abst->abst_addr_shift = 0;
338 abst->abst_size_shift = 0;
339 abst->abst_flags = ABST_DENSE|ABST_BWX;
340 break;
341
342 default:
343 panic(__S(__C(CHIP,_mem_get_window)) ": invalid window %d",
344 window);
345 }
346
347 return (0);
348 }
349
350 int
351 __C(CHIP,_mem_map)(
352 void *v,
353 bus_addr_t memaddr,
354 bus_size_t memsize,
355 int flags,
356 bus_space_handle_t *memhp,
357 int acct)
358 {
359 int error;
360
361 if (acct == 0)
362 goto mapit;
363
364 #ifdef EXTENT_DEBUG
365 printf("mem: allocating 0x%lx to 0x%lx\n", memaddr,
366 memaddr + memsize - 1);
367 #endif
368 error = extent_alloc_region(CHIP_MEM_EXTENT(v), memaddr, memsize,
369 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
370 if (error) {
371 #ifdef EXTENT_DEBUG
372 printf("mem: allocation failed (%d)\n", error);
373 extent_print(CHIP_MEM_EXTENT(v));
374 #endif
375 return (error);
376 }
377
378 mapit:
379 *memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
380
381 return (0);
382 }
383
384 void
385 __C(CHIP,_mem_unmap)(
386 void *v,
387 bus_space_handle_t memh,
388 bus_size_t memsize,
389 int acct)
390 {
391 bus_addr_t memaddr;
392 int error;
393
394 if (acct == 0)
395 return;
396
397 #ifdef EXTENT_DEBUG
398 printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize);
399 #endif
400
401 memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v));
402
403 #ifdef EXTENT_DEBUG
404 printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1);
405 #endif
406
407 error = extent_free(CHIP_MEM_EXTENT(v), memaddr, memsize,
408 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
409 if (error) {
410 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
411 __S(__C(CHIP,_mem_unmap)), memaddr, memaddr + memsize - 1,
412 error);
413 #ifdef EXTENT_DEBUG
414 extent_print(CHIP_MEM_EXTENT(v));
415 #endif
416 }
417 }
418
419 int
420 __C(CHIP,_mem_subregion)(
421 void *v,
422 bus_space_handle_t memh,
423 bus_size_t offset,
424 bus_size_t size,
425 bus_space_handle_t *nmemh)
426 {
427
428 *nmemh = memh + offset;
429 return (0);
430 }
431
432 int
433 __C(CHIP,_mem_alloc)(
434 void *v,
435 bus_addr_t rstart,
436 bus_addr_t rend,
437 bus_size_t size,
438 bus_size_t align,
439 bus_size_t boundary,
440 int flags,
441 bus_addr_t *addrp,
442 bus_space_handle_t *bshp)
443 {
444 bus_addr_t memaddr;
445 int error;
446
447 /*
448 * Do the requested allocation.
449 */
450 #ifdef EXTENT_DEBUG
451 printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend);
452 #endif
453 error = extent_alloc_subregion(CHIP_MEM_EXTENT(v), rstart, rend,
454 size, align, boundary,
455 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
456 &memaddr);
457 if (error) {
458 #ifdef EXTENT_DEBUG
459 printf("mem: allocation failed (%d)\n", error);
460 extent_print(CHIP_MEM_EXTENT(v));
461 #endif
462 }
463
464 #ifdef EXTENT_DEBUG
465 printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1);
466 #endif
467
468 *addrp = memaddr;
469 *bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
470
471 return (0);
472 }
473
474 void
475 __C(CHIP,_mem_free)(
476 void *v,
477 bus_space_handle_t bsh,
478 bus_size_t size)
479 {
480
481 /* Unmap does all we need to do. */
482 __C(CHIP,_mem_unmap)(v, bsh, size, 1);
483 }
484
485 void *
486 __C(CHIP,_mem_vaddr)(
487 void *v,
488 bus_space_handle_t bsh)
489 {
490
491 return ((void *)bsh);
492 }
493
494 paddr_t
495 __C(CHIP,_mem_mmap)(
496 void *v,
497 bus_addr_t addr,
498 off_t off,
499 int prot,
500 int flags)
501 {
502
503 return (alpha_btop(CHIP_MEM_SYS_START(v) + addr + off));
504 }
505
506 static inline void
507 __C(CHIP,_mem_barrier)(
508 void *v,
509 bus_space_handle_t h,
510 bus_size_t o,
511 bus_size_t l,
512 int f)
513 {
514
515 if ((f & BUS_SPACE_BARRIER_READ) != 0)
516 alpha_mb();
517 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
518 alpha_wmb();
519 }
520
521 static inline uint8_t
522 __C(CHIP,_mem_read_1)(
523 void *v,
524 bus_space_handle_t memh,
525 bus_size_t off)
526 {
527 bus_addr_t addr;
528
529 addr = memh + off;
530 alpha_mb();
531 return (alpha_ldbu((uint8_t *)addr));
532 }
533
534 static inline uint16_t
535 __C(CHIP,_mem_read_2)(
536 void *v,
537 bus_space_handle_t memh,
538 bus_size_t off)
539 {
540 bus_addr_t addr;
541
542 addr = memh + off;
543 #ifdef DIAGNOSTIC
544 if (addr & 1)
545 panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned",
546 addr);
547 #endif
548 alpha_mb();
549 return (alpha_ldwu((uint16_t *)addr));
550 }
551
552 static inline uint32_t
553 __C(CHIP,_mem_read_4)(
554 void *v,
555 bus_space_handle_t memh,
556 bus_size_t off)
557 {
558 bus_addr_t addr;
559
560 addr = memh + off;
561 #ifdef DIAGNOSTIC
562 if (addr & 3)
563 panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned",
564 addr);
565 #endif
566 alpha_mb();
567 return (*(uint32_t *)addr);
568 }
569
570 static inline uint64_t
571 __C(CHIP,_mem_read_8)(
572 void *v,
573 bus_space_handle_t memh,
574 bus_size_t off)
575 {
576
577 alpha_mb();
578
579 /* XXX XXX XXX */
580 panic("%s not implemented", __S(__C(CHIP,_mem_read_8)));
581 }
582
583 #define CHIP_mem_read_multi_N(BYTES,TYPE) \
584 void \
585 __C(__C(CHIP,_mem_read_multi_),BYTES)( \
586 void *v, \
587 bus_space_handle_t h, \
588 bus_size_t o, \
589 TYPE *a, \
590 bus_size_t c) \
591 { \
592 \
593 while (c-- > 0) { \
594 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \
595 BUS_SPACE_BARRIER_READ); \
596 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \
597 } \
598 }
599 CHIP_mem_read_multi_N(1,uint8_t)
600 CHIP_mem_read_multi_N(2,uint16_t)
601 CHIP_mem_read_multi_N(4,uint32_t)
602 CHIP_mem_read_multi_N(8,uint64_t)
603
604 #define CHIP_mem_read_region_N(BYTES,TYPE) \
605 void \
606 __C(__C(CHIP,_mem_read_region_),BYTES)( \
607 void *v, \
608 bus_space_handle_t h, \
609 bus_size_t o, \
610 TYPE *a, \
611 bus_size_t c) \
612 { \
613 \
614 while (c-- > 0) { \
615 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \
616 o += sizeof *a; \
617 } \
618 }
619 CHIP_mem_read_region_N(1,uint8_t)
620 CHIP_mem_read_region_N(2,uint16_t)
621 CHIP_mem_read_region_N(4,uint32_t)
622 CHIP_mem_read_region_N(8,uint64_t)
623
624 static inline void
625 __C(CHIP,_mem_write_1)(
626 void *v,
627 bus_space_handle_t memh,
628 bus_size_t off,
629 uint8_t val)
630 {
631 bus_addr_t addr;
632
633 addr = memh + off;
634 alpha_stb((uint8_t *)addr, val);
635 alpha_mb();
636 }
637
638 static inline void
639 __C(CHIP,_mem_write_2)(
640 void *v,
641 bus_space_handle_t memh,
642 bus_size_t off,
643 uint16_t val)
644 {
645 bus_addr_t addr;
646
647 addr = memh + off;
648 #ifdef DIAGNOSTIC
649 if (addr & 1)
650 panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned",
651 addr);
652 #endif
653 alpha_stw((uint16_t *)addr, val);
654 alpha_mb();
655 }
656
657 static inline void
658 __C(CHIP,_mem_write_4)(
659 void *v,
660 bus_space_handle_t memh,
661 bus_size_t off,
662 uint32_t val)
663 {
664 bus_addr_t addr;
665
666 addr = memh + off;
667 #ifdef DIAGNOSTIC
668 if (addr & 3)
669 panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned",
670 addr);
671 #endif
672 *(uint32_t *)addr = val;
673 alpha_mb();
674 }
675
676 static inline void
677 __C(CHIP,_mem_write_8)(
678 void *v,
679 bus_space_handle_t memh,
680 bus_size_t off,
681 uint64_t val)
682 {
683
684 /* XXX XXX XXX */
685 panic("%s not implemented", __S(__C(CHIP,_mem_write_8)));
686 alpha_mb();
687 }
688
689 #define CHIP_mem_write_multi_N(BYTES,TYPE) \
690 void \
691 __C(__C(CHIP,_mem_write_multi_),BYTES)( \
692 void *v, \
693 bus_space_handle_t h, \
694 bus_size_t o, \
695 const TYPE *a, \
696 bus_size_t c) \
697 { \
698 \
699 while (c-- > 0) { \
700 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \
701 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \
702 BUS_SPACE_BARRIER_WRITE); \
703 } \
704 }
705 CHIP_mem_write_multi_N(1,uint8_t)
706 CHIP_mem_write_multi_N(2,uint16_t)
707 CHIP_mem_write_multi_N(4,uint32_t)
708 CHIP_mem_write_multi_N(8,uint64_t)
709
710 #define CHIP_mem_write_region_N(BYTES,TYPE) \
711 void \
712 __C(__C(CHIP,_mem_write_region_),BYTES)( \
713 void *v, \
714 bus_space_handle_t h, \
715 bus_size_t o, \
716 const TYPE *a, \
717 bus_size_t c) \
718 { \
719 \
720 while (c-- > 0) { \
721 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \
722 o += sizeof *a; \
723 } \
724 }
725 CHIP_mem_write_region_N(1,uint8_t)
726 CHIP_mem_write_region_N(2,uint16_t)
727 CHIP_mem_write_region_N(4,uint32_t)
728 CHIP_mem_write_region_N(8,uint64_t)
729
730 #define CHIP_mem_set_multi_N(BYTES,TYPE) \
731 void \
732 __C(__C(CHIP,_mem_set_multi_),BYTES)( \
733 void *v, \
734 bus_space_handle_t h, \
735 bus_size_t o, \
736 TYPE val, \
737 bus_size_t c) \
738 { \
739 \
740 while (c-- > 0) { \
741 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \
742 __C(CHIP,_mem_barrier)(v, h, o, sizeof val, \
743 BUS_SPACE_BARRIER_WRITE); \
744 } \
745 }
746 CHIP_mem_set_multi_N(1,uint8_t)
747 CHIP_mem_set_multi_N(2,uint16_t)
748 CHIP_mem_set_multi_N(4,uint32_t)
749 CHIP_mem_set_multi_N(8,uint64_t)
750
751 #define CHIP_mem_set_region_N(BYTES,TYPE) \
752 void \
753 __C(__C(CHIP,_mem_set_region_),BYTES)( \
754 void *v, \
755 bus_space_handle_t h, \
756 bus_size_t o, \
757 TYPE val, \
758 bus_size_t c) \
759 { \
760 \
761 while (c-- > 0) { \
762 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \
763 o += sizeof val; \
764 } \
765 }
766 CHIP_mem_set_region_N(1,uint8_t)
767 CHIP_mem_set_region_N(2,uint16_t)
768 CHIP_mem_set_region_N(4,uint32_t)
769 CHIP_mem_set_region_N(8,uint64_t)
770
771 #define CHIP_mem_copy_region_N(BYTES) \
772 void \
773 __C(__C(CHIP,_mem_copy_region_),BYTES)( \
774 void *v, \
775 bus_space_handle_t h1, \
776 bus_size_t o1, \
777 bus_space_handle_t h2, \
778 bus_size_t o2, \
779 bus_size_t c) \
780 { \
781 bus_size_t o; \
782 \
783 if ((h1 + o1) >= (h2 + o2)) { \
784 /* src after dest: copy forward */ \
785 for (o = 0; c != 0; c--, o += BYTES) { \
786 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \
787 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
788 } \
789 } else { \
790 /* dest after src: copy backwards */ \
791 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \
792 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \
793 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
794 } \
795 } \
796 }
797 CHIP_mem_copy_region_N(1)
798 CHIP_mem_copy_region_N(2)
799 CHIP_mem_copy_region_N(4)
800 CHIP_mem_copy_region_N(8)
801