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