1 /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.22 2021/05/05 02:15:18 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_IO_BASE I/O space base to use.
67 * CHIP_IO_EX_STORE
68 * If defined, device-provided static storage area
69 * for the I/O space extent. If this is defined,
70 * CHIP_IO_EX_STORE_SIZE must also be defined. If
71 * this is not defined, a static area will be
72 * declared.
73 * CHIP_IO_EX_STORE_SIZE
74 * Size of the device-provided static storage area
75 * for the I/O memory space extent.
76 */
77
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_io_chipdep.c,v 1.22 2021/05/05 02:15:18 thorpej 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 static int __C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int,
90 bus_space_handle_t *, int);
91 static void __C(CHIP,_io_unmap)(void *, bus_space_handle_t,
92 bus_size_t, int);
93 static int __C(CHIP,_io_subregion)(void *, bus_space_handle_t,
94 bus_size_t, bus_size_t, bus_space_handle_t *);
95
96 static int __C(CHIP,_io_translate)(void *, bus_addr_t, bus_size_t,
97 int, struct alpha_bus_space_translation *);
98 static int __C(CHIP,_io_get_window)(void *, int,
99 struct alpha_bus_space_translation *);
100
101 /* allocation/deallocation */
102 static int __C(CHIP,_io_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 static void __C(CHIP,_io_free)(void *, bus_space_handle_t,
106 bus_size_t);
107
108 /* get kernel virtual address */
109 static void * __C(CHIP,_io_vaddr)(void *, bus_space_handle_t);
110
111 /* mmap for user */
112 static paddr_t __C(CHIP,_io_mmap)(void *, bus_addr_t, off_t, int, int);
113
114 /* barrier */
115 static inline void __C(CHIP,_io_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,_io_read_1)(void *, bus_space_handle_t,
120 bus_size_t);
121 static inline uint16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t,
122 bus_size_t);
123 static inline uint32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t,
124 bus_size_t);
125 static inline uint64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t,
126 bus_size_t);
127
128 /* read multiple */
129 static void __C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t,
130 bus_size_t, uint8_t *, bus_size_t);
131 static void __C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t,
132 bus_size_t, uint16_t *, bus_size_t);
133 static void __C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t,
134 bus_size_t, uint32_t *, bus_size_t);
135 static void __C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t,
136 bus_size_t, uint64_t *, bus_size_t);
137
138 /* read region */
139 static void __C(CHIP,_io_read_region_1)(void *, bus_space_handle_t,
140 bus_size_t, uint8_t *, bus_size_t);
141 static void __C(CHIP,_io_read_region_2)(void *, bus_space_handle_t,
142 bus_size_t, uint16_t *, bus_size_t);
143 static void __C(CHIP,_io_read_region_4)(void *, bus_space_handle_t,
144 bus_size_t, uint32_t *, bus_size_t);
145 static void __C(CHIP,_io_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,_io_write_1)(void *, bus_space_handle_t,
150 bus_size_t, uint8_t);
151 static inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t,
152 bus_size_t, uint16_t);
153 static inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t,
154 bus_size_t, uint32_t);
155 static inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t,
156 bus_size_t, uint64_t);
157
158 /* write multiple */
159 static void __C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t,
160 bus_size_t, const uint8_t *, bus_size_t);
161 static void __C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t,
162 bus_size_t, const uint16_t *, bus_size_t);
163 static void __C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t,
164 bus_size_t, const uint32_t *, bus_size_t);
165 static void __C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t,
166 bus_size_t, const uint64_t *, bus_size_t);
167
168 /* write region */
169 static void __C(CHIP,_io_write_region_1)(void *, bus_space_handle_t,
170 bus_size_t, const uint8_t *, bus_size_t);
171 static void __C(CHIP,_io_write_region_2)(void *, bus_space_handle_t,
172 bus_size_t, const uint16_t *, bus_size_t);
173 static void __C(CHIP,_io_write_region_4)(void *, bus_space_handle_t,
174 bus_size_t, const uint32_t *, bus_size_t);
175 static void __C(CHIP,_io_write_region_8)(void *, bus_space_handle_t,
176 bus_size_t, const uint64_t *, bus_size_t);
177
178 /* set multiple */
179 static void __C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t,
180 bus_size_t, uint8_t, bus_size_t);
181 static void __C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t,
182 bus_size_t, uint16_t, bus_size_t);
183 static void __C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t,
184 bus_size_t, uint32_t, bus_size_t);
185 static void __C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t,
186 bus_size_t, uint64_t, bus_size_t);
187
188 /* set region */
189 static void __C(CHIP,_io_set_region_1)(void *, bus_space_handle_t,
190 bus_size_t, uint8_t, bus_size_t);
191 static void __C(CHIP,_io_set_region_2)(void *, bus_space_handle_t,
192 bus_size_t, uint16_t, bus_size_t);
193 static void __C(CHIP,_io_set_region_4)(void *, bus_space_handle_t,
194 bus_size_t, uint32_t, bus_size_t);
195 static void __C(CHIP,_io_set_region_8)(void *, bus_space_handle_t,
196 bus_size_t, uint64_t, bus_size_t);
197
198 /* copy */
199 static void __C(CHIP,_io_copy_region_1)(void *, bus_space_handle_t,
200 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
201 static void __C(CHIP,_io_copy_region_2)(void *, bus_space_handle_t,
202 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
203 static void __C(CHIP,_io_copy_region_4)(void *, bus_space_handle_t,
204 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
205 static void __C(CHIP,_io_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_IO_EX_STORE
209 static long
210 __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
211 #define CHIP_IO_EX_STORE(v) (__C(CHIP, _io_ex_storage))
212 #define CHIP_IO_EX_STORE_SIZE(v) (sizeof __C(CHIP, _io_ex_storage))
213 #endif
214
215 void
__C(CHIP,_bus_io_init)216 __C(CHIP,_bus_io_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,_io_map);
231 t->abs_unmap = __C(CHIP,_io_unmap);
232 t->abs_subregion = __C(CHIP,_io_subregion);
233
234 t->abs_translate = __C(CHIP,_io_translate);
235 t->abs_get_window = __C(CHIP,_io_get_window);
236
237 /* allocation/deallocation */
238 t->abs_alloc = __C(CHIP,_io_alloc);
239 t->abs_free = __C(CHIP,_io_free);
240
241 /* get kernel virtual address */
242 t->abs_vaddr = __C(CHIP,_io_vaddr);
243
244 /* mmap for user */
245 t->abs_mmap = __C(CHIP,_io_mmap);
246
247 /* barrier */
248 t->abs_barrier = __C(CHIP,_io_barrier);
249
250 /* read (single) */
251 t->abs_r_1 = __C(CHIP,_io_read_1);
252 t->abs_r_2 = __C(CHIP,_io_read_2);
253 t->abs_r_4 = __C(CHIP,_io_read_4);
254 t->abs_r_8 = __C(CHIP,_io_read_8);
255
256 /* read multiple */
257 t->abs_rm_1 = __C(CHIP,_io_read_multi_1);
258 t->abs_rm_2 = __C(CHIP,_io_read_multi_2);
259 t->abs_rm_4 = __C(CHIP,_io_read_multi_4);
260 t->abs_rm_8 = __C(CHIP,_io_read_multi_8);
261
262 /* read region */
263 t->abs_rr_1 = __C(CHIP,_io_read_region_1);
264 t->abs_rr_2 = __C(CHIP,_io_read_region_2);
265 t->abs_rr_4 = __C(CHIP,_io_read_region_4);
266 t->abs_rr_8 = __C(CHIP,_io_read_region_8);
267
268 /* write (single) */
269 t->abs_w_1 = __C(CHIP,_io_write_1);
270 t->abs_w_2 = __C(CHIP,_io_write_2);
271 t->abs_w_4 = __C(CHIP,_io_write_4);
272 t->abs_w_8 = __C(CHIP,_io_write_8);
273
274 /* write multiple */
275 t->abs_wm_1 = __C(CHIP,_io_write_multi_1);
276 t->abs_wm_2 = __C(CHIP,_io_write_multi_2);
277 t->abs_wm_4 = __C(CHIP,_io_write_multi_4);
278 t->abs_wm_8 = __C(CHIP,_io_write_multi_8);
279
280 /* write region */
281 t->abs_wr_1 = __C(CHIP,_io_write_region_1);
282 t->abs_wr_2 = __C(CHIP,_io_write_region_2);
283 t->abs_wr_4 = __C(CHIP,_io_write_region_4);
284 t->abs_wr_8 = __C(CHIP,_io_write_region_8);
285
286 /* set multiple */
287 t->abs_sm_1 = __C(CHIP,_io_set_multi_1);
288 t->abs_sm_2 = __C(CHIP,_io_set_multi_2);
289 t->abs_sm_4 = __C(CHIP,_io_set_multi_4);
290 t->abs_sm_8 = __C(CHIP,_io_set_multi_8);
291
292 /* set region */
293 t->abs_sr_1 = __C(CHIP,_io_set_region_1);
294 t->abs_sr_2 = __C(CHIP,_io_set_region_2);
295 t->abs_sr_4 = __C(CHIP,_io_set_region_4);
296 t->abs_sr_8 = __C(CHIP,_io_set_region_8);
297
298 /* copy */
299 t->abs_c_1 = __C(CHIP,_io_copy_region_1);
300 t->abs_c_2 = __C(CHIP,_io_copy_region_2);
301 t->abs_c_4 = __C(CHIP,_io_copy_region_4);
302 t->abs_c_8 = __C(CHIP,_io_copy_region_8);
303
304 ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL,
305 (void *)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v),
306 EX_NOWAIT|EX_NOCOALESCE);
307
308 CHIP_IO_EXTENT(v) = ex;
309 }
310
311 static int
__C(CHIP,_io_translate)312 __C(CHIP,_io_translate)(
313 void *v,
314 bus_addr_t ioaddr,
315 bus_size_t iolen,
316 int flags,
317 struct alpha_bus_space_translation *abst)
318 {
319 int linear = flags & BUS_SPACE_MAP_LINEAR;
320
321 /*
322 * Can't map i/o space linearly.
323 */
324 if (linear)
325 return (EOPNOTSUPP);
326
327 return (__C(CHIP,_io_get_window)(v, 0, abst));
328 }
329
330 static int
__C(CHIP,_io_get_window)331 __C(CHIP,_io_get_window)(
332 void *v,
333 int window,
334 struct alpha_bus_space_translation *abst)
335 {
336
337 switch (window) {
338 case 0:
339 abst->abst_bus_start = 0;
340 abst->abst_bus_end = 0xffffffffUL;
341 abst->abst_sys_start = CHIP_IO_SYS_START(v);
342 abst->abst_sys_end = CHIP_IO_SYS_START(v) + abst->abst_bus_end;
343 abst->abst_addr_shift = 0;
344 abst->abst_size_shift = 0;
345 abst->abst_flags = ABST_DENSE|ABST_BWX;
346 break;
347
348 default:
349 panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d",
350 window);
351 }
352
353 return (0);
354 }
355
356 static int
__C(CHIP,_io_map)357 __C(CHIP,_io_map)(
358 void *v,
359 bus_addr_t ioaddr,
360 bus_size_t iosize,
361 int flags,
362 bus_space_handle_t *iohp,
363 int acct)
364 {
365 struct alpha_bus_space_translation abst;
366 int error;
367
368 /*
369 * Get the translation for this address.
370 */
371 error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst);
372 if (error)
373 return (error);
374
375 if (acct == 0)
376 goto mapit;
377
378 #ifdef EXTENT_DEBUG
379 printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
380 #endif
381 error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
382 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
383 if (error) {
384 #ifdef EXTENT_DEBUG
385 printf("io: allocation failed (%d)\n", error);
386 extent_print(CHIP_IO_EXTENT(v));
387 #endif
388 return (error);
389 }
390
391 mapit:
392 *iohp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
393
394 return (0);
395 }
396
397 static void
__C(CHIP,_io_unmap)398 __C(CHIP,_io_unmap)(
399 void *v,
400 bus_space_handle_t ioh,
401 bus_size_t iosize,
402 int acct)
403 {
404 bus_addr_t ioaddr;
405 int error;
406
407 if (acct == 0)
408 return;
409
410 #ifdef EXTENT_DEBUG
411 printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
412 #endif
413
414 ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v));
415
416 #ifdef EXTENT_DEBUG
417 printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
418 #endif
419 error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
420 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
421 if (error) {
422 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
423 __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
424 error);
425 #ifdef EXTENT_DEBUG
426 extent_print(CHIP_IO_EXTENT(v));
427 #endif
428 }
429 }
430
431 static int
__C(CHIP,_io_subregion)432 __C(CHIP,_io_subregion)(
433 void *v,
434 bus_space_handle_t ioh,
435 bus_size_t offset,
436 bus_size_t size,
437 bus_space_handle_t *nioh)
438 {
439
440 *nioh = ioh + offset;
441 return (0);
442 }
443
444 static int
__C(CHIP,_io_alloc)445 __C(CHIP,_io_alloc)(
446 void *v,
447 bus_addr_t rstart,
448 bus_addr_t rend,
449 bus_size_t size,
450 bus_size_t align,
451 bus_size_t boundary,
452 int flags,
453 bus_addr_t *addrp,
454 bus_space_handle_t *bshp)
455 {
456 struct alpha_bus_space_translation abst;
457 int linear = flags & BUS_SPACE_MAP_LINEAR;
458 bus_addr_t ioaddr;
459 int error;
460
461 /*
462 * Can't map i/o space linearly.
463 */
464 if (linear)
465 return (EOPNOTSUPP);
466
467 /*
468 * Do the requested allocation.
469 */
470 #ifdef EXTENT_DEBUG
471 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend);
472 #endif
473 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend,
474 size, align, boundary,
475 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
476 &ioaddr);
477 if (error) {
478 #ifdef EXTENT_DEBUG
479 printf("io: allocation failed (%d)\n", error);
480 extent_print(CHIP_IO_EXTENT(v));
481 #endif
482 return (error);
483 }
484
485 #ifdef EXTENT_DEBUG
486 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1);
487 #endif
488
489 error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst);
490 if (error) {
491 (void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size,
492 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
493 return (error);
494 }
495
496 *addrp = ioaddr;
497 *bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
498
499 return (0);
500 }
501
502 static void
__C(CHIP,_io_free)503 __C(CHIP,_io_free)(
504 void *v,
505 bus_space_handle_t bsh,
506 bus_size_t size)
507 {
508
509 /* Unmap does all we need to do. */
510 __C(CHIP,_io_unmap)(v, bsh, size, 1);
511 }
512
513 static void *
__C(CHIP,_io_vaddr)514 __C(CHIP,_io_vaddr)(
515 void *v,
516 bus_space_handle_t bsh)
517 {
518 /*
519 * _io_translate() catches BUS_SPACE_MAP_LINEAR,
520 * so we shouldn't get here
521 */
522 panic("_io_vaddr");
523 }
524
525 static paddr_t
__C(CHIP,_io_mmap)526 __C(CHIP,_io_mmap)(
527 void *v,
528 bus_addr_t addr,
529 off_t off,
530 int prot,
531 int flags)
532 {
533
534 /* Not supported for I/O space. */
535 return (-1);
536 }
537
538 static inline void
__C(CHIP,_io_barrier)539 __C(CHIP,_io_barrier)(
540 void *v,
541 bus_space_handle_t h,
542 bus_size_t o,
543 bus_size_t l,
544 int f)
545 {
546
547 if ((f & BUS_SPACE_BARRIER_READ) != 0)
548 alpha_mb();
549 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
550 alpha_wmb();
551 }
552
553 static inline uint8_t
__C(CHIP,_io_read_1)554 __C(CHIP,_io_read_1)(
555 void *v,
556 bus_space_handle_t ioh,
557 bus_size_t off)
558 {
559 bus_addr_t addr;
560
561 addr = ioh + off;
562 alpha_mb();
563 return (alpha_ldbu((uint8_t *)addr));
564 }
565
566 static inline uint16_t
__C(CHIP,_io_read_2)567 __C(CHIP,_io_read_2)(
568 void *v,
569 bus_space_handle_t ioh,
570 bus_size_t off)
571 {
572 bus_addr_t addr;
573
574 addr = ioh + off;
575 #ifdef DIAGNOSTIC
576 if (addr & 1)
577 panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned",
578 addr);
579 #endif
580 alpha_mb();
581 return (alpha_ldwu((uint16_t *)addr));
582 }
583
584 static inline uint32_t
__C(CHIP,_io_read_4)585 __C(CHIP,_io_read_4)(
586 void *v,
587 bus_space_handle_t ioh,
588 bus_size_t off)
589 {
590 bus_addr_t addr;
591
592 addr = ioh + off;
593 #ifdef DIAGNOSTIC
594 if (addr & 3)
595 panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned",
596 addr);
597 #endif
598 alpha_mb();
599 return (*(uint32_t *)addr);
600 }
601
602 static inline uint64_t
__C(CHIP,_io_read_8)603 __C(CHIP,_io_read_8)(
604 void *v,
605 bus_space_handle_t ioh,
606 bus_size_t off)
607 {
608
609 /* XXX XXX XXX */
610 panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
611 }
612
613 #define CHIP_io_read_multi_N(BYTES,TYPE) \
614 static void \
615 __C(__C(CHIP,_io_read_multi_),BYTES)( \
616 void *v, \
617 bus_space_handle_t h, \
618 bus_size_t o, \
619 TYPE *a, \
620 bus_size_t c) \
621 { \
622 \
623 while (c-- > 0) { \
624 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
625 BUS_SPACE_BARRIER_READ); \
626 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
627 } \
628 }
629 CHIP_io_read_multi_N(1,uint8_t)
630 CHIP_io_read_multi_N(2,uint16_t)
631 CHIP_io_read_multi_N(4,uint32_t)
632 CHIP_io_read_multi_N(8,uint64_t)
633
634 #define CHIP_io_read_region_N(BYTES,TYPE) \
635 static void \
636 __C(__C(CHIP,_io_read_region_),BYTES)( \
637 void *v, \
638 bus_space_handle_t h, \
639 bus_size_t o, \
640 TYPE *a, \
641 bus_size_t c) \
642 { \
643 \
644 while (c-- > 0) { \
645 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \
646 o += sizeof *a; \
647 } \
648 }
649 CHIP_io_read_region_N(1,uint8_t)
650 CHIP_io_read_region_N(2,uint16_t)
651 CHIP_io_read_region_N(4,uint32_t)
652 CHIP_io_read_region_N(8,uint64_t)
653
654 static inline void
__C(CHIP,_io_write_1)655 __C(CHIP,_io_write_1)(
656 void *v,
657 bus_space_handle_t ioh,
658 bus_size_t off,
659 uint8_t val)
660 {
661 bus_addr_t addr;
662
663 addr = ioh + off;
664 alpha_stb((uint8_t *)addr, val);
665 alpha_mb();
666 }
667
668 static inline void
__C(CHIP,_io_write_2)669 __C(CHIP,_io_write_2)(
670 void *v,
671 bus_space_handle_t ioh,
672 bus_size_t off,
673 uint16_t val)
674 {
675 bus_addr_t addr;
676
677 addr = ioh + off;
678 #ifdef DIAGNOSTIC
679 if (addr & 1)
680 panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned",
681 addr);
682 #endif
683 alpha_stw((uint16_t *)addr, val);
684 alpha_mb();
685 }
686
687 static inline void
__C(CHIP,_io_write_4)688 __C(CHIP,_io_write_4)(
689 void *v,
690 bus_space_handle_t ioh,
691 bus_size_t off,
692 uint32_t val)
693 {
694 bus_addr_t addr;
695
696 addr = ioh + off;
697 #ifdef DIAGNOSTIC
698 if (addr & 3)
699 panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned",
700 addr);
701 #endif
702 *(uint32_t *)addr = val;
703 alpha_mb();
704 }
705
706 static inline void
__C(CHIP,_io_write_8)707 __C(CHIP,_io_write_8)(
708 void *v,
709 bus_space_handle_t ioh,
710 bus_size_t off,
711 uint64_t val)
712 {
713
714 /* XXX XXX XXX */
715 panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
716 alpha_mb();
717 }
718
719 #define CHIP_io_write_multi_N(BYTES,TYPE) \
720 static void \
721 __C(__C(CHIP,_io_write_multi_),BYTES)( \
722 void *v, \
723 bus_space_handle_t h, \
724 bus_size_t o, \
725 const TYPE *a, \
726 bus_size_t c) \
727 { \
728 \
729 while (c-- > 0) { \
730 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
731 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \
732 BUS_SPACE_BARRIER_WRITE); \
733 } \
734 }
735 CHIP_io_write_multi_N(1,uint8_t)
736 CHIP_io_write_multi_N(2,uint16_t)
737 CHIP_io_write_multi_N(4,uint32_t)
738 CHIP_io_write_multi_N(8,uint64_t)
739
740 #define CHIP_io_write_region_N(BYTES,TYPE) \
741 static void \
742 __C(__C(CHIP,_io_write_region_),BYTES)( \
743 void *v, \
744 bus_space_handle_t h, \
745 bus_size_t o, \
746 const TYPE *a, \
747 bus_size_t c) \
748 { \
749 \
750 while (c-- > 0) { \
751 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \
752 o += sizeof *a; \
753 } \
754 }
755 CHIP_io_write_region_N(1,uint8_t)
756 CHIP_io_write_region_N(2,uint16_t)
757 CHIP_io_write_region_N(4,uint32_t)
758 CHIP_io_write_region_N(8,uint64_t)
759
760 #define CHIP_io_set_multi_N(BYTES,TYPE) \
761 static void \
762 __C(__C(CHIP,_io_set_multi_),BYTES)( \
763 void *v, \
764 bus_space_handle_t h, \
765 bus_size_t o, \
766 TYPE val, \
767 bus_size_t c) \
768 { \
769 \
770 while (c-- > 0) { \
771 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \
772 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \
773 BUS_SPACE_BARRIER_WRITE); \
774 } \
775 }
776 CHIP_io_set_multi_N(1,uint8_t)
777 CHIP_io_set_multi_N(2,uint16_t)
778 CHIP_io_set_multi_N(4,uint32_t)
779 CHIP_io_set_multi_N(8,uint64_t)
780
781 #define CHIP_io_set_region_N(BYTES,TYPE) \
782 static void \
783 __C(__C(CHIP,_io_set_region_),BYTES)( \
784 void *v, \
785 bus_space_handle_t h, \
786 bus_size_t o, \
787 TYPE val, \
788 bus_size_t c) \
789 { \
790 \
791 while (c-- > 0) { \
792 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \
793 o += sizeof val; \
794 } \
795 }
796 CHIP_io_set_region_N(1,uint8_t)
797 CHIP_io_set_region_N(2,uint16_t)
798 CHIP_io_set_region_N(4,uint32_t)
799 CHIP_io_set_region_N(8,uint64_t)
800
801 #define CHIP_io_copy_region_N(BYTES) \
802 static void \
803 __C(__C(CHIP,_io_copy_region_),BYTES)( \
804 void *v, \
805 bus_space_handle_t h1, \
806 bus_size_t o1, \
807 bus_space_handle_t h2, \
808 bus_size_t o2, \
809 bus_size_t c) \
810 { \
811 bus_size_t o; \
812 \
813 if ((h1 + o1) >= (h2 + o2)) { \
814 /* src after dest: copy forward */ \
815 for (o = 0; c != 0; c--, o += BYTES) { \
816 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \
817 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
818 } \
819 } else { \
820 /* dest after src: copy backwards */ \
821 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \
822 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \
823 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
824 } \
825 } \
826 }
827 CHIP_io_copy_region_N(1)
828 CHIP_io_copy_region_N(2)
829 CHIP_io_copy_region_N(4)
830 CHIP_io_copy_region_N(8)
831