1 /* $OpenBSD: obio.c,v 1.12 2024/11/05 18:58:59 miod Exp $ */
2 /* $NetBSD: obio.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
3
4 /*-
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum.
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 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/device.h>
36
37 #include <uvm/uvm_extern.h>
38
39 #include <sh/devreg.h>
40 #include <sh/mmu.h>
41 #include <sh/pmap.h>
42 #include <sh/pte.h>
43
44 #include <machine/bus.h>
45 #include <machine/cpu.h>
46 #include <machine/intr.h>
47
48 #include <landisk/dev/obiovar.h>
49
50 int obio_match(struct device *, void *, void *);
51 void obio_attach(struct device *, struct device *, void *);
52 int obio_print(void *, const char *);
53 int obio_search(struct device *, void *, void *);
54
55 const struct cfattach obio_ca = {
56 sizeof(struct obio_softc), obio_match, obio_attach
57 };
58
59 struct cfdriver obio_cd = {
60 NULL, "obio", DV_DULL
61 };
62
63 int
obio_match(struct device * parent,void * vcf,void * aux)64 obio_match(struct device *parent, void *vcf, void *aux)
65 {
66 struct obiobus_attach_args *oba = aux;
67
68 if (strcmp(oba->oba_busname, obio_cd.cd_name) != 0)
69 return (0);
70
71 return (1);
72 }
73
74 void
obio_attach(struct device * parent,struct device * self,void * aux)75 obio_attach(struct device *parent, struct device *self, void *aux)
76 {
77 struct obio_softc *sc = (struct obio_softc *)self;
78 struct obiobus_attach_args *oba = aux;
79
80 printf("\n");
81
82 sc->sc_iot = oba->oba_iot;
83 sc->sc_memt = oba->oba_memt;
84
85 config_search(obio_search, self, NULL);
86 }
87
88 int
obio_search(struct device * parent,void * vcf,void * aux)89 obio_search(struct device *parent, void *vcf, void *aux)
90 {
91 struct obio_softc *sc = (struct obio_softc *)parent;
92 struct cfdata *cf = vcf;
93 struct obio_attach_args oa;
94 struct obio_io res_io[1];
95 struct obio_iomem res_mem[1];
96 struct obio_irq res_irq[1];
97
98 oa.oa_iot = sc->sc_iot;
99 oa.oa_memt = sc->sc_memt;
100 oa.oa_nio = oa.oa_niomem = oa.oa_nirq = 0;
101
102 if (cf->cf_iobase != IOBASEUNK) {
103 res_io[0].or_addr = cf->cf_iobase;
104 res_io[0].or_size = cf->cf_iosize;
105 oa.oa_io = res_io;
106 oa.oa_nio = 1;
107 }
108
109 if (cf->cf_maddr != MADDRUNK) {
110 res_mem[0].or_addr = cf->cf_maddr;
111 res_mem[0].or_size = cf->cf_msize;
112 oa.oa_iomem = res_mem;
113 oa.oa_niomem = 1;
114 }
115
116 if (cf->cf_irq != IRQUNK) {
117 res_irq[0].or_irq = cf->cf_irq;
118 oa.oa_irq = res_irq;
119 oa.oa_nirq = 1;
120 }
121
122 if ((*cf->cf_attach->ca_match)(parent, cf, &oa) == 0)
123 return (0);
124
125 config_attach(parent, cf, &oa, obio_print);
126 return (1);
127 }
128
129 int
obio_print(void * args,const char * name)130 obio_print(void *args, const char *name)
131 {
132 struct obio_attach_args *oa = args;
133 const char *sep;
134 int i;
135
136 if (oa->oa_nio) {
137 sep = "";
138 printf(" port ");
139 for (i = 0; i < oa->oa_nio; i++) {
140 if (oa->oa_io[i].or_size == 0)
141 continue;
142 printf("%s0x%x", sep, oa->oa_io[i].or_addr);
143 if (oa->oa_io[i].or_size > 1)
144 printf("-0x%x", oa->oa_io[i].or_addr +
145 oa->oa_io[i].or_size - 1);
146 sep = ",";
147 }
148 }
149
150 if (oa->oa_niomem) {
151 sep = "";
152 printf(" iomem ");
153 for (i = 0; i < oa->oa_niomem; i++) {
154 if (oa->oa_iomem[i].or_size == 0)
155 continue;
156 printf("%s0x%x", sep, oa->oa_iomem[i].or_addr);
157 if (oa->oa_iomem[i].or_size > 1)
158 printf("-0x%x", oa->oa_iomem[i].or_addr +
159 oa->oa_iomem[i].or_size - 1);
160 sep = ",";
161 }
162 }
163
164 if (oa->oa_nirq) {
165 sep = "";
166 printf(" irq ");
167 for (i = 0; i < oa->oa_nirq; i++) {
168 if (oa->oa_irq[i].or_irq == IRQUNK)
169 continue;
170 printf("%s%d", sep, oa->oa_irq[i].or_irq);
171 sep = ",";
172 }
173 }
174
175 return (UNCONF);
176 }
177
178 /*
179 * Set up an interrupt handler to start being called.
180 */
181 void *
obio_intr_establish(int irq,int level,int (* ih_fun)(void *),void * ih_arg,const char * ih_name)182 obio_intr_establish(int irq, int level, int (*ih_fun)(void *), void *ih_arg,
183 const char *ih_name)
184 {
185 return extintr_establish(irq, level, ih_fun, ih_arg, ih_name);
186 }
187
188 /*
189 * Deregister an interrupt handler.
190 */
191 void
obio_intr_disestablish(void * arg)192 obio_intr_disestablish(void *arg)
193 {
194 extintr_disestablish(arg);
195 }
196
197 /*
198 * on-board I/O bus space
199 */
200 #define OBIO_IOMEM_IO 0 /* space is i/o space */
201 #define OBIO_IOMEM_MEM 1 /* space is mem space */
202 #define OBIO_IOMEM_PCMCIA_IO 2 /* PCMCIA IO space */
203 #define OBIO_IOMEM_PCMCIA_MEM 3 /* PCMCIA Mem space */
204 #define OBIO_IOMEM_PCMCIA_ATT 4 /* PCMCIA Attr space */
205 #define OBIO_IOMEM_PCMCIA_8BIT 0x8000 /* PCMCIA BUS 8 BIT WIDTH */
206 #define OBIO_IOMEM_PCMCIA_IO8 \
207 (OBIO_IOMEM_PCMCIA_IO|OBIO_IOMEM_PCMCIA_8BIT)
208 #define OBIO_IOMEM_PCMCIA_MEM8 \
209 (OBIO_IOMEM_PCMCIA_MEM|OBIO_IOMEM_PCMCIA_8BIT)
210 #define OBIO_IOMEM_PCMCIA_ATT8 \
211 (OBIO_IOMEM_PCMCIA_ATT|OBIO_IOMEM_PCMCIA_8BIT)
212
213 int obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, int flags,
214 bus_space_handle_t *bshp);
215 void obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size);
216 int obio_iomem_subregion(void *v, bus_space_handle_t bsh,
217 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
218 int obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
219 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
220 bus_addr_t *bpap, bus_space_handle_t *bshp);
221 void obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size);
222 void *obio_iomem_vaddr(void *v, bus_space_handle_t bsh);
223
224 int obio_iomem_add_mapping(bus_addr_t, bus_size_t, int,
225 bus_space_handle_t *);
226
227 int
obio_iomem_add_mapping(bus_addr_t bpa,bus_size_t size,int type,bus_space_handle_t * bshp)228 obio_iomem_add_mapping(bus_addr_t bpa, bus_size_t size, int type,
229 bus_space_handle_t *bshp)
230 {
231 u_long pa, endpa;
232 vaddr_t va;
233 pt_entry_t *pte;
234 unsigned int m = 0;
235 int io_type = type & ~OBIO_IOMEM_PCMCIA_8BIT;
236
237 pa = trunc_page(bpa);
238 endpa = round_page(bpa + size);
239
240 #ifdef DIAGNOSTIC
241 if (endpa <= pa)
242 panic("obio_iomem_add_mapping: overflow");
243 #endif
244
245 va = (vaddr_t)km_alloc(endpa - pa, &kv_any, &kp_none, &kd_nowait);
246 if (va == 0)
247 return (ENOMEM);
248
249 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
250
251 #define MODE(t, s) \
252 ((t) & OBIO_IOMEM_PCMCIA_8BIT) ? \
253 _PG_PCMCIA_ ## s ## 8 : \
254 _PG_PCMCIA_ ## s ## 16
255 switch (io_type) {
256 default:
257 panic("unknown pcmcia space.");
258 /* NOTREACHED */
259 case OBIO_IOMEM_PCMCIA_IO:
260 m = MODE(type, IO);
261 break;
262 case OBIO_IOMEM_PCMCIA_MEM:
263 m = MODE(type, MEM);
264 break;
265 case OBIO_IOMEM_PCMCIA_ATT:
266 m = MODE(type, ATTR);
267 break;
268 }
269 #undef MODE
270
271 for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
272 pmap_kenter_pa(va, pa, PROT_READ | PROT_WRITE);
273 pte = __pmap_kpte_lookup(va);
274 KDASSERT(pte);
275 *pte |= m; /* PTEA PCMCIA assistant bit */
276 sh_tlb_update(0, va, *pte);
277 }
278
279 return (0);
280 }
281
282 int
obio_iomem_map(void * v,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)283 obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
284 int flags, bus_space_handle_t *bshp)
285 {
286 bus_addr_t addr = SH3_PHYS_TO_P2SEG(bpa);
287 int error;
288
289 KASSERT((bpa & SH3_PHYS_MASK) == bpa);
290
291 if (bpa < 0x14000000 || bpa >= 0x1c000000) {
292 /* CS0,1,2,3,4,7 */
293 *bshp = (bus_space_handle_t)addr;
294 return (0);
295 }
296
297 /* CS5,6 */
298 error = obio_iomem_add_mapping(addr, size, (int)(u_long)v, bshp);
299
300 return (error);
301 }
302
303 void
obio_iomem_unmap(void * v,bus_space_handle_t bsh,bus_size_t size)304 obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
305 {
306 u_long va, endva;
307 bus_addr_t bpa;
308
309 if (bsh >= SH3_P2SEG_BASE && bsh <= SH3_P2SEG_END) {
310 /* maybe CS0,1,2,3,4,7 */
311 return;
312 }
313
314 /* CS5,6 */
315 va = trunc_page(bsh);
316 endva = round_page(bsh + size);
317
318 #ifdef DIAGNOSTIC
319 if (endva <= va)
320 panic("obio_io_unmap: overflow");
321 #endif
322
323 pmap_extract(pmap_kernel(), va, &bpa);
324 bpa += bsh & PGOFSET;
325
326 pmap_kremove(va, endva - va);
327
328 /*
329 * Free the kernel virtual mapping.
330 */
331 km_free((void *)va, endva - va, &kv_any, &kp_none);
332 }
333
334 int
obio_iomem_subregion(void * v,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)335 obio_iomem_subregion(void *v, bus_space_handle_t bsh,
336 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
337 {
338 *nbshp = bsh + offset;
339
340 return (0);
341 }
342
343 int
obio_iomem_alloc(void * v,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t alignment,bus_size_t boundary,int flags,bus_addr_t * bpap,bus_space_handle_t * bshp)344 obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
345 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
346 bus_addr_t *bpap, bus_space_handle_t *bshp)
347 {
348 *bshp = *bpap = rstart;
349
350 return (0);
351 }
352
353 void
obio_iomem_free(void * v,bus_space_handle_t bsh,bus_size_t size)354 obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
355 {
356 obio_iomem_unmap(v, bsh, size);
357 }
358
359 void *
obio_iomem_vaddr(void * v,bus_space_handle_t bsh)360 obio_iomem_vaddr(void *v, bus_space_handle_t bsh)
361 {
362 return ((void *)bsh);
363 }
364
365 /*
366 * on-board I/O bus space read/write
367 */
368 uint8_t obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset);
369 uint16_t obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset);
370 uint32_t obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset);
371 void obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
372 bus_size_t offset, uint8_t *addr, bus_size_t count);
373 void obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
374 bus_size_t offset, uint16_t *addr, bus_size_t count);
375 void obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
376 bus_size_t offset, uint32_t *addr, bus_size_t count);
377 void obio_iomem_read_raw_multi_2(void *v, bus_space_handle_t bsh,
378 bus_size_t offset, uint8_t *addr, bus_size_t count);
379 void obio_iomem_read_raw_multi_4(void *v, bus_space_handle_t bsh,
380 bus_size_t offset, uint8_t *addr, bus_size_t count);
381 void obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
382 bus_size_t offset, uint8_t *addr, bus_size_t count);
383 void obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
384 bus_size_t offset, uint16_t *addr, bus_size_t count);
385 void obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
386 bus_size_t offset, uint32_t *addr, bus_size_t count);
387 void obio_iomem_read_raw_region_2(void *v, bus_space_handle_t bsh,
388 bus_size_t offset, uint8_t *addr, bus_size_t count);
389 void obio_iomem_read_raw_region_4(void *v, bus_space_handle_t bsh,
390 bus_size_t offset, uint8_t *addr, bus_size_t count);
391 void obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
392 uint8_t value);
393 void obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
394 uint16_t value);
395 void obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
396 uint32_t value);
397 void obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
398 bus_size_t offset, const uint8_t *addr, bus_size_t count);
399 void obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
400 bus_size_t offset, const uint16_t *addr, bus_size_t count);
401 void obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
402 bus_size_t offset, const uint32_t *addr, bus_size_t count);
403 void obio_iomem_write_raw_multi_2(void *v, bus_space_handle_t bsh,
404 bus_size_t offset, const uint8_t *addr, bus_size_t count);
405 void obio_iomem_write_raw_multi_4(void *v, bus_space_handle_t bsh,
406 bus_size_t offset, const uint8_t *addr, bus_size_t count);
407 void obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
408 bus_size_t offset, const uint8_t *addr, bus_size_t count);
409 void obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
410 bus_size_t offset, const uint16_t *addr, bus_size_t count);
411 void obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
412 bus_size_t offset, const uint32_t *addr, bus_size_t count);
413 void obio_iomem_write_raw_region_2(void *v, bus_space_handle_t bsh,
414 bus_size_t offset, const uint8_t *addr, bus_size_t count);
415 void obio_iomem_write_raw_region_4(void *v, bus_space_handle_t bsh,
416 bus_size_t offset, const uint8_t *addr, bus_size_t count);
417 void obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
418 uint8_t val, bus_size_t count);
419 void obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
420 uint16_t val, bus_size_t count);
421 void obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
422 uint32_t val, bus_size_t count);
423 void obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
424 bus_size_t offset, uint8_t val, bus_size_t count);
425 void obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
426 bus_size_t offset, uint16_t val, bus_size_t count);
427 void obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
428 bus_size_t offset, uint32_t val, bus_size_t count);
429 void obio_iomem_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1,
430 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
431 void obio_iomem_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1,
432 bus_space_handle_t h2, bus_size_t o2, bus_size_t count);
433 void obio_iomem_copy_4(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
436 struct _bus_space obio_bus_io =
437 {
438 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_IO,
439
440 .bs_map = obio_iomem_map,
441 .bs_unmap = obio_iomem_unmap,
442 .bs_subregion = obio_iomem_subregion,
443
444 .bs_alloc = obio_iomem_alloc,
445 .bs_free = obio_iomem_free,
446
447 .bs_vaddr = obio_iomem_vaddr,
448
449 .bs_r_1 = obio_iomem_read_1,
450 .bs_r_2 = obio_iomem_read_2,
451 .bs_r_4 = obio_iomem_read_4,
452
453 .bs_rm_1 = obio_iomem_read_multi_1,
454 .bs_rm_2 = obio_iomem_read_multi_2,
455 .bs_rm_4 = obio_iomem_read_multi_4,
456
457 .bs_rrm_2 = obio_iomem_read_raw_multi_2,
458 .bs_rrm_4 = obio_iomem_read_raw_multi_4,
459
460 .bs_rr_1 = obio_iomem_read_region_1,
461 .bs_rr_2 = obio_iomem_read_region_2,
462 .bs_rr_4 = obio_iomem_read_region_4,
463
464 .bs_rrr_2 = obio_iomem_read_raw_region_2,
465 .bs_rrr_4 = obio_iomem_read_raw_region_4,
466
467 .bs_w_1 = obio_iomem_write_1,
468 .bs_w_2 = obio_iomem_write_2,
469 .bs_w_4 = obio_iomem_write_4,
470
471 .bs_wm_1 = obio_iomem_write_multi_1,
472 .bs_wm_2 = obio_iomem_write_multi_2,
473 .bs_wm_4 = obio_iomem_write_multi_4,
474
475 .bs_wrm_2 = obio_iomem_write_raw_multi_2,
476 .bs_wrm_4 = obio_iomem_write_raw_multi_4,
477
478 .bs_wr_1 = obio_iomem_write_region_1,
479 .bs_wr_2 = obio_iomem_write_region_2,
480 .bs_wr_4 = obio_iomem_write_region_4,
481
482 .bs_wrr_2 = obio_iomem_write_raw_region_2,
483 .bs_wrr_4 = obio_iomem_write_raw_region_4,
484
485 .bs_sm_1 = obio_iomem_set_multi_1,
486 .bs_sm_2 = obio_iomem_set_multi_2,
487 .bs_sm_4 = obio_iomem_set_multi_4,
488
489 .bs_sr_1 = obio_iomem_set_region_1,
490 .bs_sr_2 = obio_iomem_set_region_2,
491 .bs_sr_4 = obio_iomem_set_region_4,
492
493 .bs_c_1 = obio_iomem_copy_1,
494 .bs_c_2 = obio_iomem_copy_2,
495 .bs_c_4 = obio_iomem_copy_4,
496 };
497
498 struct _bus_space obio_bus_mem =
499 {
500 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_MEM,
501
502 .bs_map = obio_iomem_map,
503 .bs_unmap = obio_iomem_unmap,
504 .bs_subregion = obio_iomem_subregion,
505
506 .bs_alloc = obio_iomem_alloc,
507 .bs_free = obio_iomem_free,
508
509 .bs_vaddr = obio_iomem_vaddr,
510
511 .bs_r_1 = obio_iomem_read_1,
512 .bs_r_2 = obio_iomem_read_2,
513 .bs_r_4 = obio_iomem_read_4,
514
515 .bs_rm_1 = obio_iomem_read_multi_1,
516 .bs_rm_2 = obio_iomem_read_multi_2,
517 .bs_rm_4 = obio_iomem_read_multi_4,
518
519 .bs_rrm_2 = obio_iomem_read_raw_multi_2,
520 .bs_rrm_4 = obio_iomem_read_raw_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_rrr_2 = obio_iomem_read_raw_region_2,
527 .bs_rrr_4 = obio_iomem_read_raw_region_4,
528
529 .bs_w_1 = obio_iomem_write_1,
530 .bs_w_2 = obio_iomem_write_2,
531 .bs_w_4 = obio_iomem_write_4,
532
533 .bs_wm_1 = obio_iomem_write_multi_1,
534 .bs_wm_2 = obio_iomem_write_multi_2,
535 .bs_wm_4 = obio_iomem_write_multi_4,
536
537 .bs_wrm_2 = obio_iomem_write_raw_multi_2,
538 .bs_wrm_4 = obio_iomem_write_raw_multi_4,
539
540 .bs_wr_1 = obio_iomem_write_region_1,
541 .bs_wr_2 = obio_iomem_write_region_2,
542 .bs_wr_4 = obio_iomem_write_region_4,
543
544 .bs_wrr_2 = obio_iomem_write_raw_region_2,
545 .bs_wrr_4 = obio_iomem_write_raw_region_4,
546
547 .bs_sm_1 = obio_iomem_set_multi_1,
548 .bs_sm_2 = obio_iomem_set_multi_2,
549 .bs_sm_4 = obio_iomem_set_multi_4,
550
551 .bs_sr_1 = obio_iomem_set_region_1,
552 .bs_sr_2 = obio_iomem_set_region_2,
553 .bs_sr_4 = obio_iomem_set_region_4,
554
555 .bs_c_1 = obio_iomem_copy_1,
556 .bs_c_2 = obio_iomem_copy_2,
557 .bs_c_4 = obio_iomem_copy_4,
558 };
559
560 /* read */
561 uint8_t
obio_iomem_read_1(void * v,bus_space_handle_t bsh,bus_size_t offset)562 obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
563 {
564 return *(volatile uint8_t *)(bsh + offset);
565 }
566
567 uint16_t
obio_iomem_read_2(void * v,bus_space_handle_t bsh,bus_size_t offset)568 obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
569 {
570 return *(volatile uint16_t *)(bsh + offset);
571 }
572
573 uint32_t
obio_iomem_read_4(void * v,bus_space_handle_t bsh,bus_size_t offset)574 obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
575 {
576 return *(volatile uint32_t *)(bsh + offset);
577 }
578
579 void
obio_iomem_read_multi_1(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)580 obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh,
581 bus_size_t offset, uint8_t *addr, bus_size_t count)
582 {
583 volatile uint8_t *p = (void *)(bsh + offset);
584
585 while (count--) {
586 *addr++ = *p;
587 }
588 }
589
590 void
obio_iomem_read_multi_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint16_t * addr,bus_size_t count)591 obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh,
592 bus_size_t offset, uint16_t *addr, bus_size_t count)
593 {
594 volatile uint16_t *p = (void *)(bsh + offset);
595
596 while (count--) {
597 *addr++ = *p;
598 }
599 }
600
601 void
obio_iomem_read_multi_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint32_t * addr,bus_size_t count)602 obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh,
603 bus_size_t offset, uint32_t *addr, bus_size_t count)
604 {
605 volatile uint32_t *p = (void *)(bsh + offset);
606
607 while (count--) {
608 *addr++ = *p;
609 }
610 }
611
612 void
obio_iomem_read_raw_multi_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)613 obio_iomem_read_raw_multi_2(void *v, bus_space_handle_t bsh,
614 bus_size_t offset, uint8_t *addr, bus_size_t count)
615 {
616 volatile uint16_t *p = (void *)(bsh + offset);
617
618 count >>= 1;
619 while (count--) {
620 *(uint16_t *)addr = *p;
621 addr += 2;
622 }
623 }
624
625 void
obio_iomem_read_raw_multi_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)626 obio_iomem_read_raw_multi_4(void *v, bus_space_handle_t bsh,
627 bus_size_t offset, uint8_t *addr, bus_size_t count)
628 {
629 volatile uint32_t *p = (void *)(bsh + offset);
630
631 count >>= 2;
632 while (count--) {
633 *(uint32_t *)addr = *p;
634 addr += 4;
635 }
636 }
637
638 void
obio_iomem_read_region_1(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)639 obio_iomem_read_region_1(void *v, bus_space_handle_t bsh,
640 bus_size_t offset, uint8_t *addr, bus_size_t count)
641 {
642 volatile uint8_t *p = (void *)(bsh + offset);
643
644 while (count--) {
645 *addr++ = *p++;
646 }
647 }
648
649 void
obio_iomem_read_region_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint16_t * addr,bus_size_t count)650 obio_iomem_read_region_2(void *v, bus_space_handle_t bsh,
651 bus_size_t offset, uint16_t *addr, bus_size_t count)
652 {
653 volatile uint16_t *p = (void *)(bsh + offset);
654
655 while (count--) {
656 *addr++ = *p++;
657 }
658 }
659
660 void
obio_iomem_read_region_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint32_t * addr,bus_size_t count)661 obio_iomem_read_region_4(void *v, bus_space_handle_t bsh,
662 bus_size_t offset, uint32_t *addr, bus_size_t count)
663 {
664 volatile uint32_t *p = (void *)(bsh + offset);
665
666 while (count--) {
667 *addr++ = *p++;
668 }
669 }
670
671 void
obio_iomem_read_raw_region_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)672 obio_iomem_read_raw_region_2(void *v, bus_space_handle_t bsh,
673 bus_size_t offset, uint8_t *addr, bus_size_t count)
674 {
675 volatile uint16_t *p = (void *)(bsh + offset);
676
677 count >>= 1;
678 while (count--) {
679 *(uint16_t *)addr = *p++;
680 addr += 2;
681 }
682 }
683
684 void
obio_iomem_read_raw_region_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t * addr,bus_size_t count)685 obio_iomem_read_raw_region_4(void *v, bus_space_handle_t bsh,
686 bus_size_t offset, uint8_t *addr, bus_size_t count)
687 {
688 volatile uint32_t *p = (void *)(bsh + offset);
689
690 count >>= 2;
691 while (count--) {
692 *(uint32_t *)addr = *p++;
693 addr += 4;
694 }
695 }
696
697 /* write */
698 void
obio_iomem_write_1(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t value)699 obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset,
700 uint8_t value)
701 {
702 *(volatile uint8_t *)(bsh + offset) = value;
703 }
704
705 void
obio_iomem_write_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint16_t value)706 obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset,
707 uint16_t value)
708 {
709 *(volatile uint16_t *)(bsh + offset) = value;
710 }
711
712 void
obio_iomem_write_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint32_t value)713 obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset,
714 uint32_t value)
715 {
716 *(volatile uint32_t *)(bsh + offset) = value;
717 }
718
719 void
obio_iomem_write_multi_1(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)720 obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh,
721 bus_size_t offset, const uint8_t *addr, bus_size_t count)
722 {
723 volatile uint8_t *p = (void *)(bsh + offset);
724
725 while (count--) {
726 *p = *addr++;
727 }
728 }
729
730 void
obio_iomem_write_multi_2(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * addr,bus_size_t count)731 obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh,
732 bus_size_t offset, const uint16_t *addr, bus_size_t count)
733 {
734 volatile uint16_t *p = (void *)(bsh + offset);
735
736 while (count--) {
737 *p = *addr++;
738 }
739 }
740
741 void
obio_iomem_write_multi_4(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * addr,bus_size_t count)742 obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh,
743 bus_size_t offset, const uint32_t *addr, bus_size_t count)
744 {
745 volatile uint32_t *p = (void *)(bsh + offset);
746
747 while (count--) {
748 *p = *addr++;
749 }
750 }
751
752 void
obio_iomem_write_raw_multi_2(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)753 obio_iomem_write_raw_multi_2(void *v, bus_space_handle_t bsh,
754 bus_size_t offset, const uint8_t *addr, bus_size_t count)
755 {
756 volatile uint16_t *p = (void *)(bsh + offset);
757
758 count >>= 1;
759 while (count--) {
760 *p = *(uint16_t *)addr;
761 addr += 2;
762 }
763 }
764
765 void
obio_iomem_write_raw_multi_4(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)766 obio_iomem_write_raw_multi_4(void *v, bus_space_handle_t bsh,
767 bus_size_t offset, const uint8_t *addr, bus_size_t count)
768 {
769 volatile uint32_t *p = (void *)(bsh + offset);
770
771 count >>= 2;
772 while (count--) {
773 *p = *(uint32_t *)addr;
774 addr += 4;
775 }
776 }
777
778 void
obio_iomem_write_region_1(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)779 obio_iomem_write_region_1(void *v, bus_space_handle_t bsh,
780 bus_size_t offset, const uint8_t *addr, bus_size_t count)
781 {
782 volatile uint8_t *p = (void *)(bsh + offset);
783
784 while (count--) {
785 *p++ = *addr++;
786 }
787 }
788
789 void
obio_iomem_write_region_2(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * addr,bus_size_t count)790 obio_iomem_write_region_2(void *v, bus_space_handle_t bsh,
791 bus_size_t offset, const uint16_t *addr, bus_size_t count)
792 {
793 volatile uint16_t *p = (void *)(bsh + offset);
794
795 while (count--) {
796 *p++ = *addr++;
797 }
798 }
799
800 void
obio_iomem_write_region_4(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * addr,bus_size_t count)801 obio_iomem_write_region_4(void *v, bus_space_handle_t bsh,
802 bus_size_t offset, const uint32_t *addr, bus_size_t count)
803 {
804 volatile uint32_t *p = (void *)(bsh + offset);
805
806 while (count--) {
807 *p++ = *addr++;
808 }
809 }
810
811 void
obio_iomem_write_raw_region_2(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)812 obio_iomem_write_raw_region_2(void *v, bus_space_handle_t bsh,
813 bus_size_t offset, const uint8_t *addr, bus_size_t count)
814 {
815 volatile uint16_t *p = (void *)(bsh + offset);
816
817 count >>= 1;
818 while (count--) {
819 *p++ = *(uint16_t *)addr;
820 addr += 2;
821 }
822 }
823
824 void
obio_iomem_write_raw_region_4(void * v,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * addr,bus_size_t count)825 obio_iomem_write_raw_region_4(void *v, bus_space_handle_t bsh,
826 bus_size_t offset, const uint8_t *addr, bus_size_t count)
827 {
828 volatile uint32_t *p = (void *)(bsh + offset);
829
830 count >>= 2;
831 while (count--) {
832 *p++ = *(uint32_t *)addr;
833 addr += 4;
834 }
835 }
836
837 void
obio_iomem_set_multi_1(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t val,bus_size_t count)838 obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh,
839 bus_size_t offset, uint8_t val, bus_size_t count)
840 {
841 volatile uint8_t *p = (void *)(bsh + offset);
842
843 while (count--) {
844 *p = val;
845 }
846 }
847
848 void
obio_iomem_set_multi_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint16_t val,bus_size_t count)849 obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh,
850 bus_size_t offset, uint16_t val, bus_size_t count)
851 {
852 volatile uint16_t *p = (void *)(bsh + offset);
853
854 while (count--) {
855 *p = val;
856 }
857 }
858
859 void
obio_iomem_set_multi_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint32_t val,bus_size_t count)860 obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh,
861 bus_size_t offset, uint32_t val, bus_size_t count)
862 {
863 volatile uint32_t *p = (void *)(bsh + offset);
864
865 while (count--) {
866 *p = val;
867 }
868 }
869
870 void
obio_iomem_set_region_1(void * v,bus_space_handle_t bsh,bus_size_t offset,uint8_t val,bus_size_t count)871 obio_iomem_set_region_1(void *v, bus_space_handle_t bsh,
872 bus_size_t offset, uint8_t val, bus_size_t count)
873 {
874 volatile uint8_t *addr = (void *)(bsh + offset);
875
876 while (count--) {
877 *addr++ = val;
878 }
879 }
880
881 void
obio_iomem_set_region_2(void * v,bus_space_handle_t bsh,bus_size_t offset,uint16_t val,bus_size_t count)882 obio_iomem_set_region_2(void *v, bus_space_handle_t bsh,
883 bus_size_t offset, uint16_t val, bus_size_t count)
884 {
885 volatile uint16_t *addr = (void *)(bsh + offset);
886
887 while (count--) {
888 *addr++ = val;
889 }
890 }
891
892 void
obio_iomem_set_region_4(void * v,bus_space_handle_t bsh,bus_size_t offset,uint32_t val,bus_size_t count)893 obio_iomem_set_region_4(void *v, bus_space_handle_t bsh,
894 bus_size_t offset, uint32_t val, bus_size_t count)
895 {
896 volatile uint32_t *addr = (void *)(bsh + offset);
897
898 while (count--) {
899 *addr++ = val;
900 }
901 }
902
903 void
obio_iomem_copy_1(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t count)904 obio_iomem_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1,
905 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
906 {
907 volatile uint8_t *addr1 = (void *)(h1 + o1);
908 volatile uint8_t *addr2 = (void *)(h2 + o2);
909
910 if (addr1 >= addr2) { /* src after dest: copy forward */
911 while (count--) {
912 *addr2++ = *addr1++;
913 }
914 } else { /* dest after src: copy backwards */
915 addr1 += count - 1;
916 addr2 += count - 1;
917 while (count--) {
918 *addr2-- = *addr1--;
919 }
920 }
921 }
922
923 void
obio_iomem_copy_2(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t count)924 obio_iomem_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1,
925 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
926 {
927 volatile uint16_t *addr1 = (void *)(h1 + o1);
928 volatile uint16_t *addr2 = (void *)(h2 + o2);
929
930 if (addr1 >= addr2) { /* src after dest: copy forward */
931 while (count--) {
932 *addr2++ = *addr1++;
933 }
934 } else { /* dest after src: copy backwards */
935 addr1 += count - 1;
936 addr2 += count - 1;
937 while (count--) {
938 *addr2-- = *addr1--;
939 }
940 }
941 }
942
943 void
obio_iomem_copy_4(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t count)944 obio_iomem_copy_4(void *v, bus_space_handle_t h1, bus_size_t o1,
945 bus_space_handle_t h2, bus_size_t o2, bus_size_t count)
946 {
947 volatile uint32_t *addr1 = (void *)(h1 + o1);
948 volatile uint32_t *addr2 = (void *)(h2 + o2);
949
950 if (addr1 >= addr2) { /* src after dest: copy forward */
951 while (count--) {
952 *addr2++ = *addr1++;
953 }
954 } else { /* dest after src: copy backwards */
955 addr1 += count - 1;
956 addr2 += count - 1;
957 while (count--) {
958 *addr2-- = *addr1--;
959 }
960 }
961 }
962