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