obio.c revision 1.9.68.1 1 /* $NetBSD: obio.c,v 1.9.68.1 2021/03/20 19:33:36 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.9.68.1 2021/03/20 19:33:36 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_SUBMATCH, obio_search,
110 CFARG_IATTR, "obio",
111 CFARG_EOL);
112 }
113
114 static int
115 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
116 {
117 struct obio_io res_io[1];
118 struct obio_iomem res_mem[1];
119 struct obio_irq res_irq[1];
120 struct obio_softc *sc = device_private(parent);
121 struct obio_attach_args oa;
122 int tryagain;
123
124 do {
125 oa.oa_iot = sc->sc_iot;
126 oa.oa_memt = sc->sc_memt;
127
128 res_io[0].or_addr = cf->cf_iobase;
129 res_io[0].or_size = cf->cf_iosize;
130
131 res_mem[0].or_addr = cf->cf_maddr;
132 res_mem[0].or_size = cf->cf_msize;
133
134 res_irq[0].or_irq = cf->cf_irq;
135
136 oa.oa_io = res_io;
137 oa.oa_nio = 1;
138
139 oa.oa_iomem = res_mem;
140 oa.oa_niomem = 1;
141
142 oa.oa_irq = res_irq;
143 oa.oa_nirq = 1;
144
145 tryagain = 0;
146 if (config_match(parent, cf, &oa) > 0) {
147 config_attach(parent, cf, &oa, obio_print);
148 tryagain = (cf->cf_fstate == FSTATE_STAR);
149 }
150 } while (tryagain);
151
152 return (0);
153 }
154
155 static int
156 obio_print(void *args, const char *name)
157 {
158 struct obio_attach_args *oa = args;
159 const char *sep;
160 int i;
161
162 if (oa->oa_nio) {
163 sep = "";
164 aprint_normal(" port ");
165 for (i = 0; i < oa->oa_nio; i++) {
166 if (oa->oa_io[i].or_size == 0)
167 continue;
168 aprint_normal("%s0x%x", sep, oa->oa_io[i].or_addr);
169 if (oa->oa_io[i].or_size > 1)
170 aprint_normal("-0x%x", oa->oa_io[i].or_addr +
171 oa->oa_io[i].or_size - 1);
172 sep = ",";
173 }
174 }
175
176 if (oa->oa_niomem) {
177 sep = "";
178 aprint_normal(" iomem ");
179 for (i = 0; i < oa->oa_niomem; i++) {
180 if (oa->oa_iomem[i].or_size == 0)
181 continue;
182 aprint_normal("%s0x%x", sep, oa->oa_iomem[i].or_addr);
183 if (oa->oa_iomem[i].or_size > 1)
184 aprint_normal("-0x%x", oa->oa_iomem[i].or_addr +
185 oa->oa_iomem[i].or_size - 1);
186 sep = ",";
187 }
188 }
189
190 if (oa->oa_nirq) {
191 sep = "";
192 aprint_normal(" irq ");
193 for (i = 0; i < oa->oa_nirq; i++) {
194 if (oa->oa_irq[i].or_irq == IRQUNK)
195 continue;
196 aprint_normal("%s%d", sep, oa->oa_irq[i].or_irq);
197 sep = ",";
198 }
199 }
200
201 return (UNCONF);
202 }
203
204 /*
205 * Set up an interrupt handler to start being called.
206 */
207 void *
208 obio_intr_establish(int irq, int level, int (*ih_fun)(void *), void *ih_arg)
209 {
210
211 return extintr_establish(irq, level, ih_fun, ih_arg);
212 }
213
214 /*
215 * Deregister an interrupt handler.
216 */
217 void
218 obio_intr_disestablish(void *arg)
219 {
220
221 extintr_disestablish(arg);
222 }
223
224 /*
225 * on-board I/O bus space
226 */
227 #define OBIO_IOMEM_IO 0 /* space is i/o space */
228 #define OBIO_IOMEM_MEM 1 /* space is mem space */
229 #define OBIO_IOMEM_PCMCIA_IO 2 /* PCMCIA IO space */
230 #define OBIO_IOMEM_PCMCIA_MEM 3 /* PCMCIA Mem space */
231 #define OBIO_IOMEM_PCMCIA_ATT 4 /* PCMCIA Attr space */
232 #define OBIO_IOMEM_PCMCIA_8BIT 0x8000 /* PCMCIA BUS 8 BIT WIDTH */
233 #define OBIO_IOMEM_PCMCIA_IO8 \
234 (OBIO_IOMEM_PCMCIA_IO|OBIO_IOMEM_PCMCIA_8BIT)
235 #define OBIO_IOMEM_PCMCIA_MEM8 \
236 (OBIO_IOMEM_PCMCIA_MEM|OBIO_IOMEM_PCMCIA_8BIT)
237 #define OBIO_IOMEM_PCMCIA_ATT8 \
238 (OBIO_IOMEM_PCMCIA_ATT|OBIO_IOMEM_PCMCIA_8BIT)
239
240 int obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, int flags,
241 bus_space_handle_t *bshp);
242 void obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size);
243 int obio_iomem_subregion(void *v, bus_space_handle_t bsh,
244 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
245 int obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
246 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
247 bus_addr_t *bpap, bus_space_handle_t *bshp);
248 void obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size);
249 paddr_t obio_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot,
250 int flags);
251
252 static int obio_iomem_add_mapping(bus_addr_t, bus_size_t, int,
253 bus_space_handle_t *);
254
255 static int
256 obio_iomem_add_mapping(bus_addr_t bpa, bus_size_t size, int type,
257 bus_space_handle_t *bshp)
258 {
259 u_long pa, endpa;
260 vaddr_t va;
261 pt_entry_t *pte;
262 unsigned int m = 0;
263 int io_type = type & ~OBIO_IOMEM_PCMCIA_8BIT;
264
265 pa = sh3_trunc_page(bpa);
266 endpa = sh3_round_page(bpa + size);
267
268 #ifdef DIAGNOSTIC
269 if (endpa <= pa)
270 panic("obio_iomem_add_mapping: overflow");
271 #endif
272
273 va = uvm_km_alloc(kernel_map, endpa - pa, 0, UVM_KMF_VAONLY);
274 if (va == 0){
275 printf("obio_iomem_add_mapping: nomem\n");
276 return (ENOMEM);
277 }
278
279 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
280
281 #define MODE(t, s) \
282 ((t) & OBIO_IOMEM_PCMCIA_8BIT) ? \
283 _PG_PCMCIA_ ## s ## 8 : \
284 _PG_PCMCIA_ ## s ## 16
285 switch (io_type) {
286 default:
287 panic("unknown pcmcia space.");
288 /* NOTREACHED */
289 case OBIO_IOMEM_PCMCIA_IO:
290 m = MODE(type, IO);
291 break;
292 case OBIO_IOMEM_PCMCIA_MEM:
293 m = MODE(type, MEM);
294 break;
295 case OBIO_IOMEM_PCMCIA_ATT:
296 m = MODE(type, ATTR);
297 break;
298 }
299 #undef MODE
300
301 for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
302 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
303 pte = __pmap_kpte_lookup(va);
304 KDASSERT(pte);
305 *pte |= m; /* PTEA PCMCIA assistant bit */
306 sh_tlb_update(0, va, *pte);
307 }
308
309 return (0);
310 }
311
312 int
313 obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
314 int flags, bus_space_handle_t *bshp)
315 {
316 bus_addr_t addr = SH3_PHYS_TO_P2SEG(bpa);
317 int error;
318
319 KASSERT((bpa & SH3_PHYS_MASK) == bpa);
320
321 if (bpa < 0x14000000 || bpa >= 0x1c000000) {
322 /* CS0,1,2,3,4,7 */
323 *bshp = (bus_space_handle_t)addr;
324 return (0);
325 }
326
327 /* CS5,6 */
328 error = obio_iomem_add_mapping(addr, size, (int)(u_long)v, bshp);
329
330 return (error);
331 }
332
333 void
334 obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
335 {
336 u_long va, endva;
337 bus_addr_t bpa;
338
339 if (bsh >= SH3_P2SEG_BASE && bsh <= SH3_P2SEG_END) {
340 /* maybe CS0,1,2,3,4,7 */
341 return;
342 }
343
344 /* CS5,6 */
345 va = sh3_trunc_page(bsh);
346 endva = sh3_round_page(bsh + size);
347
348 #ifdef DIAGNOSTIC
349 if (endva <= va)
350 panic("obio_io_unmap: overflow");
351 #endif
352
353 pmap_extract(pmap_kernel(), va, &bpa);
354 bpa += bsh & PGOFSET;
355
356 pmap_kremove(va, endva - va);
357
358 /*
359 * Free the kernel virtual mapping.
360 */
361 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
362 }
363
364 int
365 obio_iomem_subregion(void *v, bus_space_handle_t bsh,
366 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
367 {
368
369 *nbshp = bsh + offset;
370
371 return (0);
372 }
373
374 int
375 obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
376 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
377 bus_addr_t *bpap, bus_space_handle_t *bshp)
378 {
379
380 *bshp = *bpap = rstart;
381
382 return (0);
383 }
384
385 void
386 obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
387 {
388
389 obio_iomem_unmap(v, bsh, size);
390 }
391
392 paddr_t
393 obio_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
394 {
395
396 return (paddr_t)-1;
397 }
398
399 /*
400 * on-board I/O bus space read/write
401 */
402 uint8_t obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset);
403 uint16_t obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset);
404 uint32_t obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset);
405 void obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
406 bus_size_t offset, uint8_t *addr, bus_size_t count);
407 void obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
408 bus_size_t offset, uint16_t *addr, bus_size_t count);
409 void obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
410 bus_size_t offset, uint32_t *addr, bus_size_t count);
411 void obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
412 bus_size_t offset, uint8_t *addr, bus_size_t count);
413 void obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
414 bus_size_t offset, uint16_t *addr, bus_size_t count);
415 void obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
416 bus_size_t offset, uint32_t *addr, bus_size_t count);
417 void obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
418 uint8_t value);
419 void obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
420 uint16_t value);
421 void obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
422 uint32_t value);
423 void obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
424 bus_size_t offset, const uint8_t *addr, bus_size_t count);
425 void obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
426 bus_size_t offset, const uint16_t *addr, bus_size_t count);
427 void obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
428 bus_size_t offset, const uint32_t *addr, bus_size_t count);
429 void obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
430 bus_size_t offset, const uint8_t *addr, bus_size_t count);
431 void obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
432 bus_size_t offset, const uint16_t *addr, bus_size_t count);
433 void obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
434 bus_size_t offset, const uint32_t *addr, bus_size_t count);
435 void obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
436 uint8_t val, bus_size_t count);
437 void obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
438 uint16_t val, bus_size_t count);
439 void obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
440 uint32_t val, bus_size_t count);
441 void obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
442 bus_size_t offset, uint8_t val, bus_size_t count);
443 void obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
444 bus_size_t offset, uint16_t val, bus_size_t count);
445 void obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
446 bus_size_t offset, uint32_t val, bus_size_t count);
447 void obio_iomem_copy_region_1(void *v, bus_space_handle_t h1, bus_size_t o1,
448 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
449 void obio_iomem_copy_region_2(void *v, bus_space_handle_t h1, bus_size_t o1,
450 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
451 void obio_iomem_copy_region_4(void *v, bus_space_handle_t h1, bus_size_t o1,
452 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
453
454 struct _bus_space obio_bus_io =
455 {
456 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_IO,
457
458 .bs_map = obio_iomem_map,
459 .bs_unmap = obio_iomem_unmap,
460 .bs_subregion = obio_iomem_subregion,
461
462 .bs_alloc = obio_iomem_alloc,
463 .bs_free = obio_iomem_free,
464
465 .bs_mmap = obio_iomem_mmap,
466
467 .bs_r_1 = obio_iomem_read_1,
468 .bs_r_2 = obio_iomem_read_2,
469 .bs_r_4 = obio_iomem_read_4,
470
471 .bs_rm_1 = obio_iomem_read_multi_1,
472 .bs_rm_2 = obio_iomem_read_multi_2,
473 .bs_rm_4 = obio_iomem_read_multi_4,
474
475 .bs_rr_1 = obio_iomem_read_region_1,
476 .bs_rr_2 = obio_iomem_read_region_2,
477 .bs_rr_4 = obio_iomem_read_region_4,
478
479 .bs_w_1 = obio_iomem_write_1,
480 .bs_w_2 = obio_iomem_write_2,
481 .bs_w_4 = obio_iomem_write_4,
482
483 .bs_wm_1 = obio_iomem_write_multi_1,
484 .bs_wm_2 = obio_iomem_write_multi_2,
485 .bs_wm_4 = obio_iomem_write_multi_4,
486
487 .bs_wr_1 = obio_iomem_write_region_1,
488 .bs_wr_2 = obio_iomem_write_region_2,
489 .bs_wr_4 = obio_iomem_write_region_4,
490
491 .bs_sm_1 = obio_iomem_set_multi_1,
492 .bs_sm_2 = obio_iomem_set_multi_2,
493 .bs_sm_4 = obio_iomem_set_multi_4,
494
495 .bs_sr_1 = obio_iomem_set_region_1,
496 .bs_sr_2 = obio_iomem_set_region_2,
497 .bs_sr_4 = obio_iomem_set_region_4,
498
499 .bs_c_1 = obio_iomem_copy_region_1,
500 .bs_c_2 = obio_iomem_copy_region_2,
501 .bs_c_4 = obio_iomem_copy_region_4,
502 };
503
504 struct _bus_space obio_bus_mem =
505 {
506 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_MEM,
507
508 .bs_map = obio_iomem_map,
509 .bs_unmap = obio_iomem_unmap,
510 .bs_subregion = obio_iomem_subregion,
511
512 .bs_alloc = obio_iomem_alloc,
513 .bs_free = obio_iomem_free,
514
515 .bs_r_1 = obio_iomem_read_1,
516 .bs_r_2 = obio_iomem_read_2,
517 .bs_r_4 = obio_iomem_read_4,
518
519 .bs_rm_1 = obio_iomem_read_multi_1,
520 .bs_rm_2 = obio_iomem_read_multi_2,
521 .bs_rm_4 = obio_iomem_read_multi_4,
522
523 .bs_rr_1 = obio_iomem_read_region_1,
524 .bs_rr_2 = obio_iomem_read_region_2,
525 .bs_rr_4 = obio_iomem_read_region_4,
526
527 .bs_w_1 = obio_iomem_write_1,
528 .bs_w_2 = obio_iomem_write_2,
529 .bs_w_4 = obio_iomem_write_4,
530
531 .bs_wm_1 = obio_iomem_write_multi_1,
532 .bs_wm_2 = obio_iomem_write_multi_2,
533 .bs_wm_4 = obio_iomem_write_multi_4,
534
535 .bs_wr_1 = obio_iomem_write_region_1,
536 .bs_wr_2 = obio_iomem_write_region_2,
537 .bs_wr_4 = obio_iomem_write_region_4,
538
539 .bs_sm_1 = obio_iomem_set_multi_1,
540 .bs_sm_2 = obio_iomem_set_multi_2,
541 .bs_sm_4 = obio_iomem_set_multi_4,
542
543 .bs_sr_1 = obio_iomem_set_region_1,
544 .bs_sr_2 = obio_iomem_set_region_2,
545 .bs_sr_4 = obio_iomem_set_region_4,
546
547 .bs_c_1 = obio_iomem_copy_region_1,
548 .bs_c_2 = obio_iomem_copy_region_2,
549 .bs_c_4 = obio_iomem_copy_region_4,
550 };
551
552 /* read */
553 uint8_t
554 obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
555 {
556
557 return *(volatile uint8_t *)(bsh + offset);
558 }
559
560 uint16_t
561 obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
562 {
563
564 return *(volatile uint16_t *)(bsh + offset);
565 }
566
567 uint32_t
568 obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
569 {
570
571 return *(volatile uint32_t *)(bsh + offset);
572 }
573
574 void
575 obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
576 bus_size_t offset, uint8_t *addr, bus_size_t count)
577 {
578 volatile uint8_t *p = (void *)(bsh + offset);
579
580 while (count--) {
581 *addr++ = *p;
582 }
583 }
584
585 void
586 obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
587 bus_size_t offset, uint16_t *addr, bus_size_t count)
588 {
589 volatile uint16_t *p = (void *)(bsh + offset);
590
591 while (count--) {
592 *addr++ = *p;
593 }
594 }
595
596 void
597 obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
598 bus_size_t offset, uint32_t *addr, bus_size_t count)
599 {
600 volatile uint32_t *p = (void *)(bsh + offset);
601
602 while (count--) {
603 *addr++ = *p;
604 }
605 }
606
607 void
608 obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
609 bus_size_t offset, uint8_t *addr, bus_size_t count)
610 {
611 volatile uint8_t *p = (void *)(bsh + offset);
612
613 while (count--) {
614 *addr++ = *p++;
615 }
616 }
617
618 void
619 obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
620 bus_size_t offset, uint16_t *addr, bus_size_t count)
621 {
622 volatile uint16_t *p = (void *)(bsh + offset);
623
624 while (count--) {
625 *addr++ = *p++;
626 }
627 }
628
629 void
630 obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
631 bus_size_t offset, uint32_t *addr, bus_size_t count)
632 {
633 volatile uint32_t *p = (void *)(bsh + offset);
634
635 while (count--) {
636 *addr++ = *p++;
637 }
638 }
639
640 /* write */
641 void
642 obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
643 uint8_t value)
644 {
645
646 *(volatile uint8_t *)(bsh + offset) = value;
647 }
648
649 void
650 obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
651 uint16_t value)
652 {
653
654 *(volatile uint16_t *)(bsh + offset) = value;
655 }
656
657 void
658 obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
659 uint32_t value)
660 {
661
662 *(volatile uint32_t *)(bsh + offset) = value;
663 }
664
665 void
666 obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
667 bus_size_t offset, const uint8_t *addr, bus_size_t count)
668 {
669 volatile uint8_t *p = (void *)(bsh + offset);
670
671 while (count--) {
672 *p = *addr++;
673 }
674 }
675
676 void
677 obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
678 bus_size_t offset, const uint16_t *addr, bus_size_t count)
679 {
680 volatile uint16_t *p = (void *)(bsh + offset);
681
682 while (count--) {
683 *p = *addr++;
684 }
685 }
686
687 void
688 obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
689 bus_size_t offset, const uint32_t *addr, bus_size_t count)
690 {
691 volatile uint32_t *p = (void *)(bsh + offset);
692
693 while (count--) {
694 *p = *addr++;
695 }
696 }
697
698 void
699 obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
700 bus_size_t offset, const uint8_t *addr, bus_size_t count)
701 {
702 volatile uint8_t *p = (void *)(bsh + offset);
703
704 while (count--) {
705 *p++ = *addr++;
706 }
707 }
708
709 void
710 obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
711 bus_size_t offset, const uint16_t *addr, bus_size_t count)
712 {
713 volatile uint16_t *p = (void *)(bsh + offset);
714
715 while (count--) {
716 *p++ = *addr++;
717 }
718 }
719
720 void
721 obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
722 bus_size_t offset, const uint32_t *addr, bus_size_t count)
723 {
724 volatile uint32_t *p = (void *)(bsh + offset);
725
726 while (count--) {
727 *p++ = *addr++;
728 }
729 }
730
731 void
732 obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh,
733 bus_size_t offset, uint8_t val, bus_size_t count)
734 {
735 volatile uint8_t *p = (void *)(bsh + offset);
736
737 while (count--) {
738 *p = val;
739 }
740 }
741
742 void
743 obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh,
744 bus_size_t offset, uint16_t val, bus_size_t count)
745 {
746 volatile uint16_t *p = (void *)(bsh + offset);
747
748 while (count--) {
749 *p = val;
750 }
751 }
752
753 void
754 obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh,
755 bus_size_t offset, uint32_t val, bus_size_t count)
756 {
757 volatile uint32_t *p = (void *)(bsh + offset);
758
759 while (count--) {
760 *p = val;
761 }
762 }
763
764 void
765 obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
766 bus_size_t offset, uint8_t val, bus_size_t count)
767 {
768 volatile uint8_t *addr = (void *)(bsh + offset);
769
770 while (count--) {
771 *addr++ = val;
772 }
773 }
774
775 void
776 obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
777 bus_size_t offset, uint16_t val, bus_size_t count)
778 {
779 volatile uint16_t *addr = (void *)(bsh + offset);
780
781 while (count--) {
782 *addr++ = val;
783 }
784 }
785
786 void
787 obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
788 bus_size_t offset, uint32_t val, bus_size_t count)
789 {
790 volatile uint32_t *addr = (void *)(bsh + offset);
791
792 while (count--) {
793 *addr++ = val;
794 }
795 }
796
797 void
798 obio_iomem_copy_region_1(void *v, bus_space_handle_t h1, bus_size_t o1,
799 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
800 {
801 volatile uint8_t *addr1 = (void *)(h1 + o1);
802 volatile uint8_t *addr2 = (void *)(h2 + o2);
803
804 if (addr1 >= addr2) { /* src after dest: copy forward */
805 while (count--) {
806 *addr2++ = *addr1++;
807 }
808 } else { /* dest after src: copy backwards */
809 addr1 += count - 1;
810 addr2 += count - 1;
811 while (count--) {
812 *addr2-- = *addr1--;
813 }
814 }
815 }
816
817 void
818 obio_iomem_copy_region_2(void *v, bus_space_handle_t h1, bus_size_t o1,
819 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
820 {
821 volatile uint16_t *addr1 = (void *)(h1 + o1);
822 volatile uint16_t *addr2 = (void *)(h2 + o2);
823
824 if (addr1 >= addr2) { /* src after dest: copy forward */
825 while (count--) {
826 *addr2++ = *addr1++;
827 }
828 } else { /* dest after src: copy backwards */
829 addr1 += count - 1;
830 addr2 += count - 1;
831 while (count--) {
832 *addr2-- = *addr1--;
833 }
834 }
835 }
836
837 void
838 obio_iomem_copy_region_4(void *v, bus_space_handle_t h1, bus_size_t o1,
839 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
840 {
841 volatile uint32_t *addr1 = (void *)(h1 + o1);
842 volatile uint32_t *addr2 = (void *)(h2 + o2);
843
844 if (addr1 >= addr2) { /* src after dest: copy forward */
845 while (count--) {
846 *addr2++ = *addr1++;
847 }
848 } else { /* dest after src: copy backwards */
849 addr1 += count - 1;
850 addr2 += count - 1;
851 while (count--) {
852 *addr2-- = *addr1--;
853 }
854 }
855 }
856