1 /* $NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.30 2023/12/06 01:46:34 thorpej 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@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_ARENA_STORE
68 * If defined, device-provided static storage area
69 * for the memory space arena. If this is
70 * defined, CHIP_MEM_BTAG_STORE and CHIP_MEM_BTAG_COUNT
71 * must also be defined. If this is not defined, a
72 * static area will be declared.
73 * CHIP_MEM_BTAG_STORE
74 * Device-provided static storage area for the
75 * memory space arena's boundary tags. Ignored
76 * unless CHIP_MEM_ARENA_STORE is defined.
77 * CHIP_MEM_BTAG_COUNT
78 * The number of device-provided static memory
79 * space boundary tags. Ignored unless
80 * CHIP_MEM_ARENA_STORE is defined.
81 */
82
83 #include <sys/cdefs.h>
84 __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.30 2023/12/06 01:46:34 thorpej Exp $");
85
86 #include <sys/vmem_impl.h>
87
88 #include <machine/bwx.h>
89
90 #define __C(A,B) __CONCAT(A,B)
91 #define __S(S) __STRING(S)
92
93 /* mapping/unmapping */
94 static int __C(CHIP,_mem_map)(void *, bus_addr_t, bus_size_t, int,
95 bus_space_handle_t *, int);
96 static void __C(CHIP,_mem_unmap)(void *, bus_space_handle_t,
97 bus_size_t, int);
98 static int __C(CHIP,_mem_subregion)(void *, bus_space_handle_t,
99 bus_size_t, bus_size_t, bus_space_handle_t *);
100
101 static int __C(CHIP,_mem_translate)(void *, bus_addr_t, bus_size_t,
102 int, struct alpha_bus_space_translation *);
103 static int __C(CHIP,_mem_get_window)(void *, int,
104 struct alpha_bus_space_translation *);
105
106 /* allocation/deallocation */
107 static int __C(CHIP,_mem_alloc)(void *, bus_addr_t, bus_addr_t,
108 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
109 bus_space_handle_t *);
110 static void __C(CHIP,_mem_free)(void *, bus_space_handle_t,
111 bus_size_t);
112
113 /* get kernel virtual address */
114 static void * __C(CHIP,_mem_vaddr)(void *, bus_space_handle_t);
115
116 /* mmap for user */
117 static paddr_t __C(CHIP,_mem_mmap)(void *, bus_addr_t, off_t, int, int);
118
119 /* barrier */
120 static inline void __C(CHIP,_mem_barrier)(void *, bus_space_handle_t,
121 bus_size_t, bus_size_t, int);
122
123 /* read (single) */
124 static inline uint8_t __C(CHIP,_mem_read_1)(void *, bus_space_handle_t,
125 bus_size_t);
126 static inline uint16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t,
127 bus_size_t);
128 static inline uint32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t,
129 bus_size_t);
130 static inline uint64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t,
131 bus_size_t);
132
133 /* read multiple */
134 static void __C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t,
135 bus_size_t, uint8_t *, bus_size_t);
136 static void __C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t,
137 bus_size_t, uint16_t *, bus_size_t);
138 static void __C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t,
139 bus_size_t, uint32_t *, bus_size_t);
140 static void __C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t,
141 bus_size_t, uint64_t *, bus_size_t);
142
143 /* read region */
144 static void __C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t,
145 bus_size_t, uint8_t *, bus_size_t);
146 static void __C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t,
147 bus_size_t, uint16_t *, bus_size_t);
148 static void __C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t,
149 bus_size_t, uint32_t *, bus_size_t);
150 static void __C(CHIP,_mem_read_region_8)(void *, bus_space_handle_t,
151 bus_size_t, uint64_t *, bus_size_t);
152
153 /* write (single) */
154 static inline void __C(CHIP,_mem_write_1)(void *, bus_space_handle_t,
155 bus_size_t, uint8_t);
156 static inline void __C(CHIP,_mem_write_2)(void *, bus_space_handle_t,
157 bus_size_t, uint16_t);
158 static inline void __C(CHIP,_mem_write_4)(void *, bus_space_handle_t,
159 bus_size_t, uint32_t);
160 static inline void __C(CHIP,_mem_write_8)(void *, bus_space_handle_t,
161 bus_size_t, uint64_t);
162
163 /* write multiple */
164 static void __C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t,
165 bus_size_t, const uint8_t *, bus_size_t);
166 static void __C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t,
167 bus_size_t, const uint16_t *, bus_size_t);
168 static void __C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t,
169 bus_size_t, const uint32_t *, bus_size_t);
170 static void __C(CHIP,_mem_write_multi_8)(void *, bus_space_handle_t,
171 bus_size_t, const uint64_t *, bus_size_t);
172
173 /* write region */
174 static void __C(CHIP,_mem_write_region_1)(void *, bus_space_handle_t,
175 bus_size_t, const uint8_t *, bus_size_t);
176 static void __C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t,
177 bus_size_t, const uint16_t *, bus_size_t);
178 static void __C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t,
179 bus_size_t, const uint32_t *, bus_size_t);
180 static void __C(CHIP,_mem_write_region_8)(void *, bus_space_handle_t,
181 bus_size_t, const uint64_t *, bus_size_t);
182
183 /* set multiple */
184 static void __C(CHIP,_mem_set_multi_1)(void *, bus_space_handle_t,
185 bus_size_t, uint8_t, bus_size_t);
186 static void __C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t,
187 bus_size_t, uint16_t, bus_size_t);
188 static void __C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t,
189 bus_size_t, uint32_t, bus_size_t);
190 static void __C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t,
191 bus_size_t, uint64_t, bus_size_t);
192
193 /* set region */
194 static void __C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t,
195 bus_size_t, uint8_t, bus_size_t);
196 static void __C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t,
197 bus_size_t, uint16_t, bus_size_t);
198 static void __C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t,
199 bus_size_t, uint32_t, bus_size_t);
200 static void __C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t,
201 bus_size_t, uint64_t, bus_size_t);
202
203 /* copy */
204 static void __C(CHIP,_mem_copy_region_1)(void *, bus_space_handle_t,
205 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
206 static void __C(CHIP,_mem_copy_region_2)(void *, bus_space_handle_t,
207 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
208 static void __C(CHIP,_mem_copy_region_4)(void *, bus_space_handle_t,
209 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
210 static void __C(CHIP,_mem_copy_region_8)(void *, bus_space_handle_t,
211 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
212
213 #ifndef CHIP_MEM_ARENA_STORE
214 #define CHIP_MEM_BTAG_COUNT(v) VMEM_EST_BTCOUNT(1, 8)
215 #define CHIP_MEM_BTAG_STORE(v) __C(CHIP,_mem_btag_store)
216 #define CHIP_MEM_ARENA_STORE(v) (&(__C(CHIP,_mem_arena_store)))
217
218 static struct vmem __C(CHIP,_mem_arena_store);
219 static struct vmem_btag __C(CHIP,_mem_btag_store)[CHIP_MEM_BTAG_COUNT(xxx)];
220 #endif /* CHIP_MEM_ARENA_STORE */
221
222 void
__C(CHIP,_bus_mem_init)223 __C(CHIP,_bus_mem_init)(
224 bus_space_tag_t t,
225 void *v)
226 {
227 vmem_t *vm;
228 int error __diagused;
229
230 /*
231 * Initialize the bus space tag.
232 */
233
234 /* cookie */
235 t->abs_cookie = v;
236
237 /* mapping/unmapping */
238 t->abs_map = __C(CHIP,_mem_map);
239 t->abs_unmap = __C(CHIP,_mem_unmap);
240 t->abs_subregion = __C(CHIP,_mem_subregion);
241
242 t->abs_translate = __C(CHIP,_mem_translate);
243 t->abs_get_window = __C(CHIP,_mem_get_window);
244
245 /* allocation/deallocation */
246 t->abs_alloc = __C(CHIP,_mem_alloc);
247 t->abs_free = __C(CHIP,_mem_free);
248
249 /* get kernel virtual address */
250 t->abs_vaddr = __C(CHIP,_mem_vaddr);
251
252 /* mmap for user */
253 t->abs_mmap = __C(CHIP,_mem_mmap);
254
255 /* barrier */
256 t->abs_barrier = __C(CHIP,_mem_barrier);
257
258 /* read (single) */
259 t->abs_r_1 = __C(CHIP,_mem_read_1);
260 t->abs_r_2 = __C(CHIP,_mem_read_2);
261 t->abs_r_4 = __C(CHIP,_mem_read_4);
262 t->abs_r_8 = __C(CHIP,_mem_read_8);
263
264 /* read multiple */
265 t->abs_rm_1 = __C(CHIP,_mem_read_multi_1);
266 t->abs_rm_2 = __C(CHIP,_mem_read_multi_2);
267 t->abs_rm_4 = __C(CHIP,_mem_read_multi_4);
268 t->abs_rm_8 = __C(CHIP,_mem_read_multi_8);
269
270 /* read region */
271 t->abs_rr_1 = __C(CHIP,_mem_read_region_1);
272 t->abs_rr_2 = __C(CHIP,_mem_read_region_2);
273 t->abs_rr_4 = __C(CHIP,_mem_read_region_4);
274 t->abs_rr_8 = __C(CHIP,_mem_read_region_8);
275
276 /* write (single) */
277 t->abs_w_1 = __C(CHIP,_mem_write_1);
278 t->abs_w_2 = __C(CHIP,_mem_write_2);
279 t->abs_w_4 = __C(CHIP,_mem_write_4);
280 t->abs_w_8 = __C(CHIP,_mem_write_8);
281
282 /* write multiple */
283 t->abs_wm_1 = __C(CHIP,_mem_write_multi_1);
284 t->abs_wm_2 = __C(CHIP,_mem_write_multi_2);
285 t->abs_wm_4 = __C(CHIP,_mem_write_multi_4);
286 t->abs_wm_8 = __C(CHIP,_mem_write_multi_8);
287
288 /* write region */
289 t->abs_wr_1 = __C(CHIP,_mem_write_region_1);
290 t->abs_wr_2 = __C(CHIP,_mem_write_region_2);
291 t->abs_wr_4 = __C(CHIP,_mem_write_region_4);
292 t->abs_wr_8 = __C(CHIP,_mem_write_region_8);
293
294 /* set multiple */
295 t->abs_sm_1 = __C(CHIP,_mem_set_multi_1);
296 t->abs_sm_2 = __C(CHIP,_mem_set_multi_2);
297 t->abs_sm_4 = __C(CHIP,_mem_set_multi_4);
298 t->abs_sm_8 = __C(CHIP,_mem_set_multi_8);
299
300 /* set region */
301 t->abs_sr_1 = __C(CHIP,_mem_set_region_1);
302 t->abs_sr_2 = __C(CHIP,_mem_set_region_2);
303 t->abs_sr_4 = __C(CHIP,_mem_set_region_4);
304 t->abs_sr_8 = __C(CHIP,_mem_set_region_8);
305
306 /* copy */
307 t->abs_c_1 = __C(CHIP,_mem_copy_region_1);
308 t->abs_c_2 = __C(CHIP,_mem_copy_region_2);
309 t->abs_c_4 = __C(CHIP,_mem_copy_region_4);
310 t->abs_c_8 = __C(CHIP,_mem_copy_region_8);
311
312 vm = vmem_init(CHIP_MEM_ARENA_STORE(v),
313 __S(__C(CHIP,_bus_mem)), /* name */
314 0, /* addr */
315 0, /* size */
316 1, /* quantum */
317 NULL, /* importfn */
318 NULL, /* releasefn */
319 NULL, /* source */
320 0, /* qcache_max */
321 VM_NOSLEEP | VM_PRIVTAGS,
322 IPL_NONE);
323 KASSERT(vm != NULL);
324
325 vmem_add_bts(vm, CHIP_MEM_BTAG_STORE(v), CHIP_MEM_BTAG_COUNT(v));
326 error = vmem_add(vm, 0, 0x100000000UL, VM_NOSLEEP);
327 KASSERT(error == 0);
328
329 CHIP_MEM_ARENA(v) = vm;
330 }
331
332 static int
__C(CHIP,_mem_translate)333 __C(CHIP,_mem_translate)(
334 void *v,
335 bus_addr_t memaddr,
336 bus_size_t memlen,
337 int flags,
338 struct alpha_bus_space_translation *abst)
339 {
340
341 /* XXX */
342 return (EOPNOTSUPP);
343 }
344
345 static int
__C(CHIP,_mem_get_window)346 __C(CHIP,_mem_get_window)(
347 void *v,
348 int window,
349 struct alpha_bus_space_translation *abst)
350 {
351
352 switch (window) {
353 case 0:
354 abst->abst_bus_start = 0;
355 abst->abst_bus_end = 0xffffffffUL;
356 abst->abst_sys_start = CHIP_MEM_SYS_START(v);
357 abst->abst_sys_end = CHIP_MEM_SYS_START(v) + abst->abst_bus_end;
358 abst->abst_addr_shift = 0;
359 abst->abst_size_shift = 0;
360 abst->abst_flags = ABST_DENSE|ABST_BWX;
361 break;
362
363 default:
364 panic(__S(__C(CHIP,_mem_get_window)) ": invalid window %d",
365 window);
366 }
367
368 return (0);
369 }
370
371 static int
__C(CHIP,_mem_map)372 __C(CHIP,_mem_map)(
373 void *v,
374 bus_addr_t memaddr,
375 bus_size_t memsize,
376 int flags,
377 bus_space_handle_t *memhp,
378 int acct)
379 {
380 int error;
381
382 if (acct == 0)
383 goto mapit;
384
385 #ifdef EXTENT_DEBUG
386 printf("mem: allocating 0x%lx to 0x%lx\n", memaddr,
387 memaddr + memsize - 1);
388 #endif
389 error = vmem_xalloc_addr(CHIP_MEM_ARENA(v), memaddr, memsize,
390 VM_NOSLEEP);
391 if (error) {
392 #ifdef EXTENT_DEBUG
393 printf("mem: allocation failed (%d)\n", error);
394 /* vmem_print(CHIP_MEM_ARENA(v)); XXX */
395 #endif
396 return (error);
397 }
398
399 mapit:
400 *memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
401
402 return (0);
403 }
404
405 static void
__C(CHIP,_mem_unmap)406 __C(CHIP,_mem_unmap)(
407 void *v,
408 bus_space_handle_t memh,
409 bus_size_t memsize,
410 int acct)
411 {
412 bus_addr_t memaddr;
413
414 if (acct == 0)
415 return;
416
417 #ifdef EXTENT_DEBUG
418 printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize);
419 #endif
420
421 memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v));
422
423 #ifdef EXTENT_DEBUG
424 printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1);
425 #endif
426
427 vmem_xfree(CHIP_MEM_ARENA(v), memaddr, memsize);
428 }
429
430 static int
__C(CHIP,_mem_subregion)431 __C(CHIP,_mem_subregion)(
432 void *v,
433 bus_space_handle_t memh,
434 bus_size_t offset,
435 bus_size_t size,
436 bus_space_handle_t *nmemh)
437 {
438
439 *nmemh = memh + offset;
440 return (0);
441 }
442
443 static int
__C(CHIP,_mem_alloc)444 __C(CHIP,_mem_alloc)(
445 void *v,
446 bus_addr_t rstart,
447 bus_addr_t rend,
448 bus_size_t size,
449 bus_size_t align,
450 bus_size_t boundary,
451 int flags,
452 bus_addr_t *addrp,
453 bus_space_handle_t *bshp)
454 {
455 vmem_addr_t memaddr;
456 int error;
457
458 /*
459 * Do the requested allocation.
460 */
461 #ifdef EXTENT_DEBUG
462 printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend);
463 #endif
464 error = vmem_xalloc(CHIP_MEM_ARENA(v), size,
465 align, /* align */
466 0, /* phase */
467 boundary, /* nocross */
468 rstart, /* minaddr */
469 rend, /* maxaddr */
470 VM_BESTFIT | VM_NOSLEEP,
471 &memaddr);
472 if (error) {
473 #ifdef EXTENT_DEBUG
474 printf("mem: allocation failed (%d)\n", error);
475 /* vmem_print(CHIP_MEM_ARENA(v)); XXX */
476 #endif
477 }
478
479 #ifdef EXTENT_DEBUG
480 printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1);
481 #endif
482
483 *addrp = memaddr;
484 *bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
485
486 return (0);
487 }
488
489 static void
__C(CHIP,_mem_free)490 __C(CHIP,_mem_free)(
491 void *v,
492 bus_space_handle_t bsh,
493 bus_size_t size)
494 {
495
496 /* Unmap does all we need to do. */
497 __C(CHIP,_mem_unmap)(v, bsh, size, 1);
498 }
499
500 static void *
__C(CHIP,_mem_vaddr)501 __C(CHIP,_mem_vaddr)(
502 void *v,
503 bus_space_handle_t bsh)
504 {
505
506 return ((void *)bsh);
507 }
508
509 static paddr_t
__C(CHIP,_mem_mmap)510 __C(CHIP,_mem_mmap)(
511 void *v,
512 bus_addr_t addr,
513 off_t off,
514 int prot,
515 int flags)
516 {
517
518 return (alpha_btop(CHIP_MEM_SYS_START(v) + addr + off));
519 }
520
521 static inline void
__C(CHIP,_mem_barrier)522 __C(CHIP,_mem_barrier)(
523 void *v,
524 bus_space_handle_t h,
525 bus_size_t o,
526 bus_size_t l,
527 int f)
528 {
529
530 if ((f & BUS_SPACE_BARRIER_READ) != 0)
531 alpha_mb();
532 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
533 alpha_wmb();
534 }
535
536 static inline uint8_t
__C(CHIP,_mem_read_1)537 __C(CHIP,_mem_read_1)(
538 void *v,
539 bus_space_handle_t memh,
540 bus_size_t off)
541 {
542 bus_addr_t addr;
543
544 addr = memh + off;
545 alpha_mb();
546 return (alpha_ldbu((uint8_t *)addr));
547 }
548
549 static inline uint16_t
__C(CHIP,_mem_read_2)550 __C(CHIP,_mem_read_2)(
551 void *v,
552 bus_space_handle_t memh,
553 bus_size_t off)
554 {
555 bus_addr_t addr;
556
557 addr = memh + off;
558 #ifdef DIAGNOSTIC
559 if (addr & 1)
560 panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned",
561 addr);
562 #endif
563 alpha_mb();
564 return (alpha_ldwu((uint16_t *)addr));
565 }
566
567 static inline uint32_t
__C(CHIP,_mem_read_4)568 __C(CHIP,_mem_read_4)(
569 void *v,
570 bus_space_handle_t memh,
571 bus_size_t off)
572 {
573 bus_addr_t addr;
574
575 addr = memh + off;
576 #ifdef DIAGNOSTIC
577 if (addr & 3)
578 panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned",
579 addr);
580 #endif
581 alpha_mb();
582 return (*(uint32_t *)addr);
583 }
584
585 static inline uint64_t
__C(CHIP,_mem_read_8)586 __C(CHIP,_mem_read_8)(
587 void *v,
588 bus_space_handle_t memh,
589 bus_size_t off)
590 {
591
592 alpha_mb();
593
594 /* XXX XXX XXX */
595 panic("%s not implemented", __S(__C(CHIP,_mem_read_8)));
596 }
597
598 #define CHIP_mem_read_multi_N(BYTES,TYPE) \
599 static void \
600 __C(__C(CHIP,_mem_read_multi_),BYTES)( \
601 void *v, \
602 bus_space_handle_t h, \
603 bus_size_t o, \
604 TYPE *a, \
605 bus_size_t c) \
606 { \
607 \
608 while (c-- > 0) { \
609 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \
610 BUS_SPACE_BARRIER_READ); \
611 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \
612 } \
613 }
614 CHIP_mem_read_multi_N(1,uint8_t)
615 CHIP_mem_read_multi_N(2,uint16_t)
616 CHIP_mem_read_multi_N(4,uint32_t)
617 CHIP_mem_read_multi_N(8,uint64_t)
618
619 #define CHIP_mem_read_region_N(BYTES,TYPE) \
620 static void \
621 __C(__C(CHIP,_mem_read_region_),BYTES)( \
622 void *v, \
623 bus_space_handle_t h, \
624 bus_size_t o, \
625 TYPE *a, \
626 bus_size_t c) \
627 { \
628 \
629 while (c-- > 0) { \
630 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \
631 o += sizeof *a; \
632 } \
633 }
634 CHIP_mem_read_region_N(1,uint8_t)
635 CHIP_mem_read_region_N(2,uint16_t)
636 CHIP_mem_read_region_N(4,uint32_t)
637 CHIP_mem_read_region_N(8,uint64_t)
638
639 static inline void
__C(CHIP,_mem_write_1)640 __C(CHIP,_mem_write_1)(
641 void *v,
642 bus_space_handle_t memh,
643 bus_size_t off,
644 uint8_t val)
645 {
646 bus_addr_t addr;
647
648 addr = memh + off;
649 alpha_stb((uint8_t *)addr, val);
650 alpha_mb();
651 }
652
653 static inline void
__C(CHIP,_mem_write_2)654 __C(CHIP,_mem_write_2)(
655 void *v,
656 bus_space_handle_t memh,
657 bus_size_t off,
658 uint16_t val)
659 {
660 bus_addr_t addr;
661
662 addr = memh + off;
663 #ifdef DIAGNOSTIC
664 if (addr & 1)
665 panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned",
666 addr);
667 #endif
668 alpha_stw((uint16_t *)addr, val);
669 alpha_mb();
670 }
671
672 static inline void
__C(CHIP,_mem_write_4)673 __C(CHIP,_mem_write_4)(
674 void *v,
675 bus_space_handle_t memh,
676 bus_size_t off,
677 uint32_t val)
678 {
679 bus_addr_t addr;
680
681 addr = memh + off;
682 #ifdef DIAGNOSTIC
683 if (addr & 3)
684 panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned",
685 addr);
686 #endif
687 *(uint32_t *)addr = val;
688 alpha_mb();
689 }
690
691 static inline void
__C(CHIP,_mem_write_8)692 __C(CHIP,_mem_write_8)(
693 void *v,
694 bus_space_handle_t memh,
695 bus_size_t off,
696 uint64_t val)
697 {
698
699 /* XXX XXX XXX */
700 panic("%s not implemented", __S(__C(CHIP,_mem_write_8)));
701 alpha_mb();
702 }
703
704 #define CHIP_mem_write_multi_N(BYTES,TYPE) \
705 static void \
706 __C(__C(CHIP,_mem_write_multi_),BYTES)( \
707 void *v, \
708 bus_space_handle_t h, \
709 bus_size_t o, \
710 const TYPE *a, \
711 bus_size_t c) \
712 { \
713 \
714 while (c-- > 0) { \
715 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \
716 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \
717 BUS_SPACE_BARRIER_WRITE); \
718 } \
719 }
720 CHIP_mem_write_multi_N(1,uint8_t)
721 CHIP_mem_write_multi_N(2,uint16_t)
722 CHIP_mem_write_multi_N(4,uint32_t)
723 CHIP_mem_write_multi_N(8,uint64_t)
724
725 #define CHIP_mem_write_region_N(BYTES,TYPE) \
726 static void \
727 __C(__C(CHIP,_mem_write_region_),BYTES)( \
728 void *v, \
729 bus_space_handle_t h, \
730 bus_size_t o, \
731 const TYPE *a, \
732 bus_size_t c) \
733 { \
734 \
735 while (c-- > 0) { \
736 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \
737 o += sizeof *a; \
738 } \
739 }
740 CHIP_mem_write_region_N(1,uint8_t)
741 CHIP_mem_write_region_N(2,uint16_t)
742 CHIP_mem_write_region_N(4,uint32_t)
743 CHIP_mem_write_region_N(8,uint64_t)
744
745 #define CHIP_mem_set_multi_N(BYTES,TYPE) \
746 static void \
747 __C(__C(CHIP,_mem_set_multi_),BYTES)( \
748 void *v, \
749 bus_space_handle_t h, \
750 bus_size_t o, \
751 TYPE val, \
752 bus_size_t c) \
753 { \
754 \
755 while (c-- > 0) { \
756 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \
757 __C(CHIP,_mem_barrier)(v, h, o, sizeof val, \
758 BUS_SPACE_BARRIER_WRITE); \
759 } \
760 }
761 CHIP_mem_set_multi_N(1,uint8_t)
762 CHIP_mem_set_multi_N(2,uint16_t)
763 CHIP_mem_set_multi_N(4,uint32_t)
764 CHIP_mem_set_multi_N(8,uint64_t)
765
766 #define CHIP_mem_set_region_N(BYTES,TYPE) \
767 static void \
768 __C(__C(CHIP,_mem_set_region_),BYTES)( \
769 void *v, \
770 bus_space_handle_t h, \
771 bus_size_t o, \
772 TYPE val, \
773 bus_size_t c) \
774 { \
775 \
776 while (c-- > 0) { \
777 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \
778 o += sizeof val; \
779 } \
780 }
781 CHIP_mem_set_region_N(1,uint8_t)
782 CHIP_mem_set_region_N(2,uint16_t)
783 CHIP_mem_set_region_N(4,uint32_t)
784 CHIP_mem_set_region_N(8,uint64_t)
785
786 #define CHIP_mem_copy_region_N(BYTES) \
787 static void \
788 __C(__C(CHIP,_mem_copy_region_),BYTES)( \
789 void *v, \
790 bus_space_handle_t h1, \
791 bus_size_t o1, \
792 bus_space_handle_t h2, \
793 bus_size_t o2, \
794 bus_size_t c) \
795 { \
796 bus_size_t o; \
797 \
798 if ((h1 + o1) >= (h2 + o2)) { \
799 /* src after dest: copy forward */ \
800 for (o = 0; c != 0; c--, o += BYTES) { \
801 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \
802 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
803 } \
804 } else { \
805 /* dest after src: copy backwards */ \
806 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \
807 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \
808 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
809 } \
810 } \
811 }
812 CHIP_mem_copy_region_N(1)
813 CHIP_mem_copy_region_N(2)
814 CHIP_mem_copy_region_N(4)
815 CHIP_mem_copy_region_N(8)
816