obio.c revision 1.10 1 /* $NetBSD: obio.c,v 1.10 2021/04/24 23:36:40 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.10 2021/04/24 23:36:40 thorpej Exp $");
34
35 #include "btn_obio.h"
36 #include "pwrsw_obio.h"
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41
42 #include <uvm/uvm_extern.h>
43
44 #include <sh3/devreg.h>
45 #include <sh3/mmu.h>
46 #include <sh3/pmap.h>
47 #include <sh3/pte.h>
48
49 #include <sys/bus.h>
50 #include <machine/cpu.h>
51 #include <machine/intr.h>
52
53 #include <landisk/dev/obiovar.h>
54
55 #if (NPWRSW_OBIO > 0) || (NBTN_OBIO > 0)
56 #include <dev/sysmon/sysmonvar.h>
57 #include <dev/sysmon/sysmon_taskq.h>
58 #endif
59
60 #include "locators.h"
61
62
63 struct obio_softc {
64 device_t sc_dev;
65
66 bus_space_tag_t sc_iot; /* io space tag */
67 bus_space_tag_t sc_memt; /* mem space tag */
68 };
69
70 static int obio_match(device_t, cfdata_t, void *);
71 static void obio_attach(device_t, device_t, void *);
72 static int obio_print(void *, const char *);
73 static int obio_search(device_t, cfdata_t, const int *, void *);
74
75 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
76 obio_match, obio_attach, NULL, NULL);
77
78 static int
79 obio_match(device_t parent, cfdata_t cf, void *aux)
80 {
81 struct obiobus_attach_args *oba = aux;
82
83 if (strcmp(oba->oba_busname, cf->cf_name))
84 return (0);
85
86 return (1);
87 }
88
89 static void
90 obio_attach(device_t parent, device_t self, void *aux)
91 {
92 struct obio_softc *sc = device_private(self);
93 struct obiobus_attach_args *oba = aux;
94
95 aprint_naive("\n");
96 aprint_normal("\n");
97
98 sc->sc_dev = self;
99
100 sc->sc_iot = oba->oba_iot;
101 sc->sc_memt = oba->oba_memt;
102
103 #if (NPWRSW_OBIO > 0) || (NBTN_OBIO > 0)
104 sysmon_power_settype("landisk");
105 sysmon_task_queue_init();
106 #endif
107
108 config_search(self, NULL,
109 CFARG_SEARCH, obio_search,
110 CFARG_EOL);
111 }
112
113 static int
114 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
115 {
116 struct obio_io res_io[1];
117 struct obio_iomem res_mem[1];
118 struct obio_irq res_irq[1];
119 struct obio_softc *sc = device_private(parent);
120 struct obio_attach_args oa;
121 int tryagain;
122
123 do {
124 oa.oa_iot = sc->sc_iot;
125 oa.oa_memt = sc->sc_memt;
126
127 res_io[0].or_addr = cf->cf_iobase;
128 res_io[0].or_size = cf->cf_iosize;
129
130 res_mem[0].or_addr = cf->cf_maddr;
131 res_mem[0].or_size = cf->cf_msize;
132
133 res_irq[0].or_irq = cf->cf_irq;
134
135 oa.oa_io = res_io;
136 oa.oa_nio = 1;
137
138 oa.oa_iomem = res_mem;
139 oa.oa_niomem = 1;
140
141 oa.oa_irq = res_irq;
142 oa.oa_nirq = 1;
143
144 tryagain = 0;
145 if (config_probe(parent, cf, &oa)) {
146 config_attach(parent, cf, &oa, obio_print, CFARG_EOL);
147 tryagain = (cf->cf_fstate == FSTATE_STAR);
148 }
149 } while (tryagain);
150
151 return (0);
152 }
153
154 static int
155 obio_print(void *args, const char *name)
156 {
157 struct obio_attach_args *oa = args;
158 const char *sep;
159 int i;
160
161 if (oa->oa_nio) {
162 sep = "";
163 aprint_normal(" port ");
164 for (i = 0; i < oa->oa_nio; i++) {
165 if (oa->oa_io[i].or_size == 0)
166 continue;
167 aprint_normal("%s0x%x", sep, oa->oa_io[i].or_addr);
168 if (oa->oa_io[i].or_size > 1)
169 aprint_normal("-0x%x", oa->oa_io[i].or_addr +
170 oa->oa_io[i].or_size - 1);
171 sep = ",";
172 }
173 }
174
175 if (oa->oa_niomem) {
176 sep = "";
177 aprint_normal(" iomem ");
178 for (i = 0; i < oa->oa_niomem; i++) {
179 if (oa->oa_iomem[i].or_size == 0)
180 continue;
181 aprint_normal("%s0x%x", sep, oa->oa_iomem[i].or_addr);
182 if (oa->oa_iomem[i].or_size > 1)
183 aprint_normal("-0x%x", oa->oa_iomem[i].or_addr +
184 oa->oa_iomem[i].or_size - 1);
185 sep = ",";
186 }
187 }
188
189 if (oa->oa_nirq) {
190 sep = "";
191 aprint_normal(" irq ");
192 for (i = 0; i < oa->oa_nirq; i++) {
193 if (oa->oa_irq[i].or_irq == IRQUNK)
194 continue;
195 aprint_normal("%s%d", sep, oa->oa_irq[i].or_irq);
196 sep = ",";
197 }
198 }
199
200 return (UNCONF);
201 }
202
203 /*
204 * Set up an interrupt handler to start being called.
205 */
206 void *
207 obio_intr_establish(int irq, int level, int (*ih_fun)(void *), void *ih_arg)
208 {
209
210 return extintr_establish(irq, level, ih_fun, ih_arg);
211 }
212
213 /*
214 * Deregister an interrupt handler.
215 */
216 void
217 obio_intr_disestablish(void *arg)
218 {
219
220 extintr_disestablish(arg);
221 }
222
223 /*
224 * on-board I/O bus space
225 */
226 #define OBIO_IOMEM_IO 0 /* space is i/o space */
227 #define OBIO_IOMEM_MEM 1 /* space is mem space */
228 #define OBIO_IOMEM_PCMCIA_IO 2 /* PCMCIA IO space */
229 #define OBIO_IOMEM_PCMCIA_MEM 3 /* PCMCIA Mem space */
230 #define OBIO_IOMEM_PCMCIA_ATT 4 /* PCMCIA Attr space */
231 #define OBIO_IOMEM_PCMCIA_8BIT 0x8000 /* PCMCIA BUS 8 BIT WIDTH */
232 #define OBIO_IOMEM_PCMCIA_IO8 \
233 (OBIO_IOMEM_PCMCIA_IO|OBIO_IOMEM_PCMCIA_8BIT)
234 #define OBIO_IOMEM_PCMCIA_MEM8 \
235 (OBIO_IOMEM_PCMCIA_MEM|OBIO_IOMEM_PCMCIA_8BIT)
236 #define OBIO_IOMEM_PCMCIA_ATT8 \
237 (OBIO_IOMEM_PCMCIA_ATT|OBIO_IOMEM_PCMCIA_8BIT)
238
239 int obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, int flags,
240 bus_space_handle_t *bshp);
241 void obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size);
242 int obio_iomem_subregion(void *v, bus_space_handle_t bsh,
243 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
244 int obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
245 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
246 bus_addr_t *bpap, bus_space_handle_t *bshp);
247 void obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size);
248 paddr_t obio_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot,
249 int flags);
250
251 static int obio_iomem_add_mapping(bus_addr_t, bus_size_t, int,
252 bus_space_handle_t *);
253
254 static int
255 obio_iomem_add_mapping(bus_addr_t bpa, bus_size_t size, int type,
256 bus_space_handle_t *bshp)
257 {
258 u_long pa, endpa;
259 vaddr_t va;
260 pt_entry_t *pte;
261 unsigned int m = 0;
262 int io_type = type & ~OBIO_IOMEM_PCMCIA_8BIT;
263
264 pa = sh3_trunc_page(bpa);
265 endpa = sh3_round_page(bpa + size);
266
267 #ifdef DIAGNOSTIC
268 if (endpa <= pa)
269 panic("obio_iomem_add_mapping: overflow");
270 #endif
271
272 va = uvm_km_alloc(kernel_map, endpa - pa, 0, UVM_KMF_VAONLY);
273 if (va == 0){
274 printf("obio_iomem_add_mapping: nomem\n");
275 return (ENOMEM);
276 }
277
278 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
279
280 #define MODE(t, s) \
281 ((t) & OBIO_IOMEM_PCMCIA_8BIT) ? \
282 _PG_PCMCIA_ ## s ## 8 : \
283 _PG_PCMCIA_ ## s ## 16
284 switch (io_type) {
285 default:
286 panic("unknown pcmcia space.");
287 /* NOTREACHED */
288 case OBIO_IOMEM_PCMCIA_IO:
289 m = MODE(type, IO);
290 break;
291 case OBIO_IOMEM_PCMCIA_MEM:
292 m = MODE(type, MEM);
293 break;
294 case OBIO_IOMEM_PCMCIA_ATT:
295 m = MODE(type, ATTR);
296 break;
297 }
298 #undef MODE
299
300 for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
301 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
302 pte = __pmap_kpte_lookup(va);
303 KDASSERT(pte);
304 *pte |= m; /* PTEA PCMCIA assistant bit */
305 sh_tlb_update(0, va, *pte);
306 }
307
308 return (0);
309 }
310
311 int
312 obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
313 int flags, bus_space_handle_t *bshp)
314 {
315 bus_addr_t addr = SH3_PHYS_TO_P2SEG(bpa);
316 int error;
317
318 KASSERT((bpa & SH3_PHYS_MASK) == bpa);
319
320 if (bpa < 0x14000000 || bpa >= 0x1c000000) {
321 /* CS0,1,2,3,4,7 */
322 *bshp = (bus_space_handle_t)addr;
323 return (0);
324 }
325
326 /* CS5,6 */
327 error = obio_iomem_add_mapping(addr, size, (int)(u_long)v, bshp);
328
329 return (error);
330 }
331
332 void
333 obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
334 {
335 u_long va, endva;
336 bus_addr_t bpa;
337
338 if (bsh >= SH3_P2SEG_BASE && bsh <= SH3_P2SEG_END) {
339 /* maybe CS0,1,2,3,4,7 */
340 return;
341 }
342
343 /* CS5,6 */
344 va = sh3_trunc_page(bsh);
345 endva = sh3_round_page(bsh + size);
346
347 #ifdef DIAGNOSTIC
348 if (endva <= va)
349 panic("obio_io_unmap: overflow");
350 #endif
351
352 pmap_extract(pmap_kernel(), va, &bpa);
353 bpa += bsh & PGOFSET;
354
355 pmap_kremove(va, endva - va);
356
357 /*
358 * Free the kernel virtual mapping.
359 */
360 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
361 }
362
363 int
364 obio_iomem_subregion(void *v, bus_space_handle_t bsh,
365 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
366 {
367
368 *nbshp = bsh + offset;
369
370 return (0);
371 }
372
373 int
374 obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
375 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
376 bus_addr_t *bpap, bus_space_handle_t *bshp)
377 {
378
379 *bshp = *bpap = rstart;
380
381 return (0);
382 }
383
384 void
385 obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
386 {
387
388 obio_iomem_unmap(v, bsh, size);
389 }
390
391 paddr_t
392 obio_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
393 {
394
395 return (paddr_t)-1;
396 }
397
398 /*
399 * on-board I/O bus space read/write
400 */
401 uint8_t obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset);
402 uint16_t obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset);
403 uint32_t obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset);
404 void obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
405 bus_size_t offset, uint8_t *addr, bus_size_t count);
406 void obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
407 bus_size_t offset, uint16_t *addr, bus_size_t count);
408 void obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
409 bus_size_t offset, uint32_t *addr, bus_size_t count);
410 void obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
411 bus_size_t offset, uint8_t *addr, bus_size_t count);
412 void obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
413 bus_size_t offset, uint16_t *addr, bus_size_t count);
414 void obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
415 bus_size_t offset, uint32_t *addr, bus_size_t count);
416 void obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
417 uint8_t value);
418 void obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
419 uint16_t value);
420 void obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
421 uint32_t value);
422 void obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
423 bus_size_t offset, const uint8_t *addr, bus_size_t count);
424 void obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
425 bus_size_t offset, const uint16_t *addr, bus_size_t count);
426 void obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
427 bus_size_t offset, const uint32_t *addr, bus_size_t count);
428 void obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
429 bus_size_t offset, const uint8_t *addr, bus_size_t count);
430 void obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
431 bus_size_t offset, const uint16_t *addr, bus_size_t count);
432 void obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
433 bus_size_t offset, const uint32_t *addr, bus_size_t count);
434 void obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
435 uint8_t val, bus_size_t count);
436 void obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
437 uint16_t val, bus_size_t count);
438 void obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
439 uint32_t val, bus_size_t count);
440 void obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
441 bus_size_t offset, uint8_t val, bus_size_t count);
442 void obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
443 bus_size_t offset, uint16_t val, bus_size_t count);
444 void obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
445 bus_size_t offset, uint32_t val, bus_size_t count);
446 void obio_iomem_copy_region_1(void *v, bus_space_handle_t h1, bus_size_t o1,
447 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
448 void obio_iomem_copy_region_2(void *v, bus_space_handle_t h1, bus_size_t o1,
449 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
450 void obio_iomem_copy_region_4(void *v, bus_space_handle_t h1, bus_size_t o1,
451 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
452
453 struct _bus_space obio_bus_io =
454 {
455 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_IO,
456
457 .bs_map = obio_iomem_map,
458 .bs_unmap = obio_iomem_unmap,
459 .bs_subregion = obio_iomem_subregion,
460
461 .bs_alloc = obio_iomem_alloc,
462 .bs_free = obio_iomem_free,
463
464 .bs_mmap = obio_iomem_mmap,
465
466 .bs_r_1 = obio_iomem_read_1,
467 .bs_r_2 = obio_iomem_read_2,
468 .bs_r_4 = obio_iomem_read_4,
469
470 .bs_rm_1 = obio_iomem_read_multi_1,
471 .bs_rm_2 = obio_iomem_read_multi_2,
472 .bs_rm_4 = obio_iomem_read_multi_4,
473
474 .bs_rr_1 = obio_iomem_read_region_1,
475 .bs_rr_2 = obio_iomem_read_region_2,
476 .bs_rr_4 = obio_iomem_read_region_4,
477
478 .bs_w_1 = obio_iomem_write_1,
479 .bs_w_2 = obio_iomem_write_2,
480 .bs_w_4 = obio_iomem_write_4,
481
482 .bs_wm_1 = obio_iomem_write_multi_1,
483 .bs_wm_2 = obio_iomem_write_multi_2,
484 .bs_wm_4 = obio_iomem_write_multi_4,
485
486 .bs_wr_1 = obio_iomem_write_region_1,
487 .bs_wr_2 = obio_iomem_write_region_2,
488 .bs_wr_4 = obio_iomem_write_region_4,
489
490 .bs_sm_1 = obio_iomem_set_multi_1,
491 .bs_sm_2 = obio_iomem_set_multi_2,
492 .bs_sm_4 = obio_iomem_set_multi_4,
493
494 .bs_sr_1 = obio_iomem_set_region_1,
495 .bs_sr_2 = obio_iomem_set_region_2,
496 .bs_sr_4 = obio_iomem_set_region_4,
497
498 .bs_c_1 = obio_iomem_copy_region_1,
499 .bs_c_2 = obio_iomem_copy_region_2,
500 .bs_c_4 = obio_iomem_copy_region_4,
501 };
502
503 struct _bus_space obio_bus_mem =
504 {
505 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_MEM,
506
507 .bs_map = obio_iomem_map,
508 .bs_unmap = obio_iomem_unmap,
509 .bs_subregion = obio_iomem_subregion,
510
511 .bs_alloc = obio_iomem_alloc,
512 .bs_free = obio_iomem_free,
513
514 .bs_r_1 = obio_iomem_read_1,
515 .bs_r_2 = obio_iomem_read_2,
516 .bs_r_4 = obio_iomem_read_4,
517
518 .bs_rm_1 = obio_iomem_read_multi_1,
519 .bs_rm_2 = obio_iomem_read_multi_2,
520 .bs_rm_4 = obio_iomem_read_multi_4,
521
522 .bs_rr_1 = obio_iomem_read_region_1,
523 .bs_rr_2 = obio_iomem_read_region_2,
524 .bs_rr_4 = obio_iomem_read_region_4,
525
526 .bs_w_1 = obio_iomem_write_1,
527 .bs_w_2 = obio_iomem_write_2,
528 .bs_w_4 = obio_iomem_write_4,
529
530 .bs_wm_1 = obio_iomem_write_multi_1,
531 .bs_wm_2 = obio_iomem_write_multi_2,
532 .bs_wm_4 = obio_iomem_write_multi_4,
533
534 .bs_wr_1 = obio_iomem_write_region_1,
535 .bs_wr_2 = obio_iomem_write_region_2,
536 .bs_wr_4 = obio_iomem_write_region_4,
537
538 .bs_sm_1 = obio_iomem_set_multi_1,
539 .bs_sm_2 = obio_iomem_set_multi_2,
540 .bs_sm_4 = obio_iomem_set_multi_4,
541
542 .bs_sr_1 = obio_iomem_set_region_1,
543 .bs_sr_2 = obio_iomem_set_region_2,
544 .bs_sr_4 = obio_iomem_set_region_4,
545
546 .bs_c_1 = obio_iomem_copy_region_1,
547 .bs_c_2 = obio_iomem_copy_region_2,
548 .bs_c_4 = obio_iomem_copy_region_4,
549 };
550
551 /* read */
552 uint8_t
553 obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
554 {
555
556 return *(volatile uint8_t *)(bsh + offset);
557 }
558
559 uint16_t
560 obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
561 {
562
563 return *(volatile uint16_t *)(bsh + offset);
564 }
565
566 uint32_t
567 obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
568 {
569
570 return *(volatile uint32_t *)(bsh + offset);
571 }
572
573 void
574 obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
575 bus_size_t offset, uint8_t *addr, bus_size_t count)
576 {
577 volatile uint8_t *p = (void *)(bsh + offset);
578
579 while (count--) {
580 *addr++ = *p;
581 }
582 }
583
584 void
585 obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
586 bus_size_t offset, uint16_t *addr, bus_size_t count)
587 {
588 volatile uint16_t *p = (void *)(bsh + offset);
589
590 while (count--) {
591 *addr++ = *p;
592 }
593 }
594
595 void
596 obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
597 bus_size_t offset, uint32_t *addr, bus_size_t count)
598 {
599 volatile uint32_t *p = (void *)(bsh + offset);
600
601 while (count--) {
602 *addr++ = *p;
603 }
604 }
605
606 void
607 obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
608 bus_size_t offset, uint8_t *addr, bus_size_t count)
609 {
610 volatile uint8_t *p = (void *)(bsh + offset);
611
612 while (count--) {
613 *addr++ = *p++;
614 }
615 }
616
617 void
618 obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
619 bus_size_t offset, uint16_t *addr, bus_size_t count)
620 {
621 volatile uint16_t *p = (void *)(bsh + offset);
622
623 while (count--) {
624 *addr++ = *p++;
625 }
626 }
627
628 void
629 obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
630 bus_size_t offset, uint32_t *addr, bus_size_t count)
631 {
632 volatile uint32_t *p = (void *)(bsh + offset);
633
634 while (count--) {
635 *addr++ = *p++;
636 }
637 }
638
639 /* write */
640 void
641 obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
642 uint8_t value)
643 {
644
645 *(volatile uint8_t *)(bsh + offset) = value;
646 }
647
648 void
649 obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
650 uint16_t value)
651 {
652
653 *(volatile uint16_t *)(bsh + offset) = value;
654 }
655
656 void
657 obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
658 uint32_t value)
659 {
660
661 *(volatile uint32_t *)(bsh + offset) = value;
662 }
663
664 void
665 obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
666 bus_size_t offset, const uint8_t *addr, bus_size_t count)
667 {
668 volatile uint8_t *p = (void *)(bsh + offset);
669
670 while (count--) {
671 *p = *addr++;
672 }
673 }
674
675 void
676 obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
677 bus_size_t offset, const uint16_t *addr, bus_size_t count)
678 {
679 volatile uint16_t *p = (void *)(bsh + offset);
680
681 while (count--) {
682 *p = *addr++;
683 }
684 }
685
686 void
687 obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
688 bus_size_t offset, const uint32_t *addr, bus_size_t count)
689 {
690 volatile uint32_t *p = (void *)(bsh + offset);
691
692 while (count--) {
693 *p = *addr++;
694 }
695 }
696
697 void
698 obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
699 bus_size_t offset, const uint8_t *addr, bus_size_t count)
700 {
701 volatile uint8_t *p = (void *)(bsh + offset);
702
703 while (count--) {
704 *p++ = *addr++;
705 }
706 }
707
708 void
709 obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
710 bus_size_t offset, const uint16_t *addr, bus_size_t count)
711 {
712 volatile uint16_t *p = (void *)(bsh + offset);
713
714 while (count--) {
715 *p++ = *addr++;
716 }
717 }
718
719 void
720 obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
721 bus_size_t offset, const uint32_t *addr, bus_size_t count)
722 {
723 volatile uint32_t *p = (void *)(bsh + offset);
724
725 while (count--) {
726 *p++ = *addr++;
727 }
728 }
729
730 void
731 obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh,
732 bus_size_t offset, uint8_t val, bus_size_t count)
733 {
734 volatile uint8_t *p = (void *)(bsh + offset);
735
736 while (count--) {
737 *p = val;
738 }
739 }
740
741 void
742 obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh,
743 bus_size_t offset, uint16_t val, bus_size_t count)
744 {
745 volatile uint16_t *p = (void *)(bsh + offset);
746
747 while (count--) {
748 *p = val;
749 }
750 }
751
752 void
753 obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh,
754 bus_size_t offset, uint32_t val, bus_size_t count)
755 {
756 volatile uint32_t *p = (void *)(bsh + offset);
757
758 while (count--) {
759 *p = val;
760 }
761 }
762
763 void
764 obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
765 bus_size_t offset, uint8_t val, bus_size_t count)
766 {
767 volatile uint8_t *addr = (void *)(bsh + offset);
768
769 while (count--) {
770 *addr++ = val;
771 }
772 }
773
774 void
775 obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
776 bus_size_t offset, uint16_t val, bus_size_t count)
777 {
778 volatile uint16_t *addr = (void *)(bsh + offset);
779
780 while (count--) {
781 *addr++ = val;
782 }
783 }
784
785 void
786 obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
787 bus_size_t offset, uint32_t val, bus_size_t count)
788 {
789 volatile uint32_t *addr = (void *)(bsh + offset);
790
791 while (count--) {
792 *addr++ = val;
793 }
794 }
795
796 void
797 obio_iomem_copy_region_1(void *v, bus_space_handle_t h1, bus_size_t o1,
798 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
799 {
800 volatile uint8_t *addr1 = (void *)(h1 + o1);
801 volatile uint8_t *addr2 = (void *)(h2 + o2);
802
803 if (addr1 >= addr2) { /* src after dest: copy forward */
804 while (count--) {
805 *addr2++ = *addr1++;
806 }
807 } else { /* dest after src: copy backwards */
808 addr1 += count - 1;
809 addr2 += count - 1;
810 while (count--) {
811 *addr2-- = *addr1--;
812 }
813 }
814 }
815
816 void
817 obio_iomem_copy_region_2(void *v, bus_space_handle_t h1, bus_size_t o1,
818 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
819 {
820 volatile uint16_t *addr1 = (void *)(h1 + o1);
821 volatile uint16_t *addr2 = (void *)(h2 + o2);
822
823 if (addr1 >= addr2) { /* src after dest: copy forward */
824 while (count--) {
825 *addr2++ = *addr1++;
826 }
827 } else { /* dest after src: copy backwards */
828 addr1 += count - 1;
829 addr2 += count - 1;
830 while (count--) {
831 *addr2-- = *addr1--;
832 }
833 }
834 }
835
836 void
837 obio_iomem_copy_region_4(void *v, bus_space_handle_t h1, bus_size_t o1,
838 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
839 {
840 volatile uint32_t *addr1 = (void *)(h1 + o1);
841 volatile uint32_t *addr2 = (void *)(h2 + o2);
842
843 if (addr1 >= addr2) { /* src after dest: copy forward */
844 while (count--) {
845 *addr2++ = *addr1++;
846 }
847 } else { /* dest after src: copy backwards */
848 addr1 += count - 1;
849 addr2 += count - 1;
850 while (count--) {
851 *addr2-- = *addr1--;
852 }
853 }
854 }
855