Annotation of sys/arch/arm/xscale/i80321_space.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: i80321_space.c,v 1.4 2006/06/01 03:46:01 drahn Exp $ */
! 2: /* $NetBSD: i80321_space.c,v 1.9 2005/11/24 13:08:32 yamt Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
! 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 for the NetBSD Project by
! 21: * Wasabi Systems, Inc.
! 22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
! 23: * or promote products derived from this software without specific prior
! 24: * written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
! 27: * 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 WASABI SYSTEMS, INC
! 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: /*
! 40: * bus_space functions for i80321 I/O Processor.
! 41: */
! 42:
! 43: #include <sys/param.h>
! 44: #include <sys/systm.h>
! 45:
! 46: #include <uvm/uvm_extern.h>
! 47:
! 48: #include <machine/bus.h>
! 49:
! 50: #include <arm/xscale/i80321reg.h>
! 51: #include <arm/xscale/i80321var.h>
! 52:
! 53: /* Prototypes for all the bus_space structure functions */
! 54: bs_protos(i80321);
! 55: bs_protos(i80321_io);
! 56: bs_protos(i80321_mem);
! 57: bs_protos(generic);
! 58: bs_protos(generic_armv4);
! 59: bs_protos(bs_notimpl);
! 60:
! 61: /*
! 62: * Template bus_space -- copied, and the bits that are NULL are
! 63: * filled in.
! 64: */
! 65: const struct bus_space i80321_bs_tag_template = {
! 66: /* cookie */
! 67: (void *) 0,
! 68:
! 69: /* mapping/unmapping */
! 70: i80321_bs_map,
! 71: i80321_bs_unmap,
! 72: i80321_bs_subregion,
! 73:
! 74: /* allocation/deallocation */
! 75: NULL,
! 76: NULL,
! 77:
! 78: /* get kernel virtual address */
! 79: i80321_bs_vaddr,
! 80:
! 81: /* mmap */
! 82: i80321_bs_mmap,
! 83:
! 84: /* barrier */
! 85: i80321_bs_barrier,
! 86:
! 87: /* read (single) */
! 88: generic_bs_r_1,
! 89: generic_armv4_bs_r_2,
! 90: generic_bs_r_4,
! 91: bs_notimpl_bs_r_8,
! 92:
! 93: /* read multiple */
! 94: generic_bs_rm_1,
! 95: generic_armv4_bs_rm_2,
! 96: generic_bs_rm_4,
! 97: bs_notimpl_bs_rm_8,
! 98:
! 99: /* read region */
! 100: generic_bs_rr_1,
! 101: generic_armv4_bs_rr_2,
! 102: generic_bs_rr_4,
! 103: bs_notimpl_bs_rr_8,
! 104:
! 105: /* write (single) */
! 106: generic_bs_w_1,
! 107: generic_armv4_bs_w_2,
! 108: generic_bs_w_4,
! 109: bs_notimpl_bs_w_8,
! 110:
! 111: /* write multiple */
! 112: generic_bs_wm_1,
! 113: generic_armv4_bs_wm_2,
! 114: generic_bs_wm_4,
! 115: bs_notimpl_bs_wm_8,
! 116:
! 117: /* write region */
! 118: generic_bs_wr_1,
! 119: generic_armv4_bs_wr_2,
! 120: generic_bs_wr_4,
! 121: bs_notimpl_bs_wr_8,
! 122:
! 123: /* set multiple */
! 124: bs_notimpl_bs_sm_1,
! 125: bs_notimpl_bs_sm_2,
! 126: bs_notimpl_bs_sm_4,
! 127: bs_notimpl_bs_sm_8,
! 128:
! 129: /* set region */
! 130: bs_notimpl_bs_sr_1,
! 131: generic_armv4_bs_sr_2,
! 132: generic_bs_sr_4,
! 133: bs_notimpl_bs_sr_8,
! 134:
! 135: /* copy */
! 136: bs_notimpl_bs_c_1,
! 137: generic_armv4_bs_c_2,
! 138: bs_notimpl_bs_c_4,
! 139: bs_notimpl_bs_c_8,
! 140: };
! 141:
! 142: void
! 143: i80321_bs_init(bus_space_tag_t bs, void *cookie)
! 144: {
! 145:
! 146: *bs = i80321_bs_tag_template;
! 147: bs->bs_cookie = cookie;
! 148: }
! 149:
! 150: void
! 151: i80321_io_bs_init(bus_space_tag_t bs, void *cookie)
! 152: {
! 153:
! 154: *bs = i80321_bs_tag_template;
! 155: bs->bs_cookie = cookie;
! 156:
! 157: bs->bs_map = i80321_io_bs_map;
! 158: bs->bs_unmap = i80321_io_bs_unmap;
! 159: bs->bs_alloc = i80321_io_bs_alloc;
! 160: bs->bs_free = i80321_io_bs_free;
! 161:
! 162: bs->bs_vaddr = i80321_io_bs_vaddr;
! 163: }
! 164:
! 165: void
! 166: i80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
! 167: {
! 168:
! 169: *bs = i80321_bs_tag_template;
! 170: bs->bs_cookie = cookie;
! 171:
! 172: bs->bs_map = i80321_mem_bs_map;
! 173: bs->bs_unmap = i80321_mem_bs_unmap;
! 174: bs->bs_alloc = i80321_mem_bs_alloc;
! 175: bs->bs_free = i80321_mem_bs_free;
! 176:
! 177: bs->bs_mmap = i80321_mem_bs_mmap;
! 178: }
! 179:
! 180: int
! 181: i80321_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag,
! 182: bus_space_handle_t *bshp)
! 183: {
! 184: const struct pmap_devmap *pd;
! 185: paddr_t startpa, endpa, pa, pagecnt;
! 186: vaddr_t va;
! 187: pt_entry_t *pte;
! 188:
! 189: if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) {
! 190: /* Device was statically mapped. */
! 191: *bshp = pd->pd_va + (bpa - pd->pd_pa);
! 192: return (0);
! 193: }
! 194:
! 195: #if 0
! 196: printf("i80321_bs_map bpa %x, size %x flag %x\n", bpa, size, flag);
! 197: #endif
! 198: endpa = round_page(bpa + size);
! 199: startpa = trunc_page(bpa);
! 200: pagecnt = endpa - startpa;
! 201:
! 202: va = uvm_km_valloc(kernel_map, endpa - startpa);
! 203: if (va == 0)
! 204: return(ENOMEM);
! 205: #if 0
! 206: printf("i80321_bs_map va %x pa %x, endpa %x, sz %x\n", va, startpa,
! 207: endpa, endpa-startpa);
! 208: #endif
! 209:
! 210: *bshp = (bus_space_handle_t)(va + (bpa - startpa));
! 211:
! 212: for (pa = startpa; pagecnt > 0;
! 213: pa += PAGE_SIZE, va += PAGE_SIZE, pagecnt -= PAGE_SIZE) {
! 214: pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
! 215: if ((flag & BUS_SPACE_MAP_CACHEABLE) == 0) {
! 216: pte = vtopte(va);
! 217: *pte &= ~L2_S_CACHE_MASK;
! 218: PTE_SYNC(pte);
! 219: }
! 220: }
! 221: pmap_update(pmap_kernel());
! 222:
! 223: return (0);
! 224: }
! 225:
! 226: void
! 227: i80321_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
! 228: {
! 229: vaddr_t va, endva;
! 230:
! 231: if (pmap_devmap_find_va(bsh, size) != NULL) {
! 232: /* Device was statically mapped; nothing to do. */
! 233: return;
! 234: }
! 235:
! 236: endva = round_page(bsh + size);
! 237: va = trunc_page(bsh);
! 238:
! 239: pmap_kremove(va, endva - va);
! 240: uvm_km_free(kernel_map, va, endva - va);
! 241: }
! 242:
! 243:
! 244: /* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
! 245:
! 246: int
! 247: i80321_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
! 248: bus_size_t size, bus_space_handle_t *nbshp)
! 249: {
! 250: *nbshp = bsh + offset;
! 251: return (0);
! 252: }
! 253:
! 254: void
! 255: i80321_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
! 256: bus_size_t len, int flags)
! 257: {
! 258:
! 259: /* Nothing to do. */
! 260: }
! 261:
! 262: void *
! 263: i80321_bs_vaddr(void *t, bus_space_handle_t bsh)
! 264: {
! 265:
! 266: return ((void *)bsh);
! 267: }
! 268:
! 269: paddr_t
! 270: i80321_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
! 271: {
! 272:
! 273: /* Not supported. */
! 274: return (-1);
! 275: }
! 276:
! 277: /* *** Routines for PCI IO. *** */
! 278:
! 279: int
! 280: i80321_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
! 281: bus_space_handle_t *bshp)
! 282: {
! 283: struct i80321_softc *sc = t;
! 284: uint32_t busbase;
! 285:
! 286: if (bpa >= sc->sc_ioout_xlate &&
! 287: bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
! 288: busbase = sc->sc_ioout_xlate;
! 289: } else
! 290: return (EINVAL);
! 291:
! 292: if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
! 293: return (EINVAL);
! 294:
! 295: /*
! 296: * Found the window -- PCI I/O space is mapped at a fixed
! 297: * virtual address by board-specific code. Translate the
! 298: * bus address to the virtual address.
! 299: */
! 300: bus_space_subregion(sc->sc_st, sc->sc_io_sh, (bpa - busbase), size,
! 301: bshp);
! 302: return (0);
! 303: }
! 304:
! 305: void
! 306: i80321_io_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
! 307: {
! 308:
! 309: /* Nothing to do. */
! 310: }
! 311:
! 312: int
! 313: i80321_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
! 314: bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
! 315: bus_addr_t *bpap, bus_space_handle_t *bshp)
! 316: {
! 317:
! 318: panic("i80321_io_bs_alloc(): not implemented");
! 319: }
! 320:
! 321: void
! 322: i80321_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
! 323: {
! 324:
! 325: panic("i80321_io_bs_free(): not implemented");
! 326: }
! 327:
! 328: void *
! 329: i80321_io_bs_vaddr(void *t, bus_space_handle_t bsh)
! 330: {
! 331:
! 332: /* Not supported. */
! 333: return (NULL);
! 334: }
! 335:
! 336: /* *** Routines for PCI MEM. *** */
! 337:
! 338: int
! 339: i80321_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag,
! 340: bus_space_handle_t *bshp)
! 341: {
! 342:
! 343: struct i80321_softc *sc = t;
! 344: vaddr_t va;
! 345: uint32_t busbase;
! 346: paddr_t pa, endpa, physbase;
! 347: pt_entry_t *pte;
! 348:
! 349: #if 0
! 350: printf("i80321_bs_map bpa %x, size %x flag %x : %x %x \n", bpa, size, flag,
! 351: sc->sc_owin[0].owin_xlate_lo,
! 352: sc->sc_owin[0].owin_xlate_lo+ VERDE_OUT_XLATE_MEM_WIN_SIZE);
! 353: #endif
! 354:
! 355: if (bpa >= sc->sc_owin[0].owin_xlate_lo &&
! 356: bpa < (sc->sc_owin[0].owin_xlate_lo +
! 357: VERDE_OUT_XLATE_MEM_WIN_SIZE)) {
! 358: busbase = sc->sc_iwin[1].iwin_xlate;
! 359: physbase = sc->sc_owin[0].owin_xlate_lo;
! 360: } else
! 361: return (EINVAL);
! 362:
! 363: if ((bpa + size) >= ( sc->sc_owin[0].owin_xlate_lo +
! 364: VERDE_OUT_XLATE_MEM_WIN_SIZE))
! 365: return (EINVAL);
! 366:
! 367: /*
! 368: * Found the window -- PCI MEM space is now mapped by allocating
! 369: * some kernel VA space and mapping the pages with pmap_enter().
! 370: * pmap_enter() will map unmanaged pages as non-cacheable.
! 371: */
! 372: pa = trunc_page((bpa - busbase) + physbase);
! 373: endpa = round_page(((bpa - busbase) + physbase) + size);
! 374:
! 375: va = uvm_km_valloc(kernel_map, endpa - pa);
! 376: if (va == 0)
! 377: return (ENOMEM);
! 378: //printf("i80321_mem_bs_map bpa %x pa %x va %x sz %x\n", bpa, pa, va, endpa-pa);
! 379:
! 380: #if 0
! 381: printf("i80321_bs_map va %x pa %x, endpa %x, sz %x\n", va, pa,
! 382: endpa, endpa-pa);
! 383: #endif
! 384:
! 385: *bshp = va + (bpa & PAGE_MASK);
! 386:
! 387: for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
! 388: pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
! 389: if ((flag & BUS_SPACE_MAP_CACHEABLE) == 0) {
! 390: pte = vtopte(va);
! 391: *pte &= ~L2_S_CACHE_MASK;
! 392: PTE_SYNC(pte);
! 393: }
! 394: }
! 395: pmap_update(pmap_kernel());
! 396:
! 397: return (0);
! 398: }
! 399:
! 400: void
! 401: i80321_mem_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
! 402: {
! 403: vaddr_t va, endva;
! 404:
! 405: va = trunc_page(bsh);
! 406: endva = round_page(bsh + size);
! 407:
! 408: pmap_kremove(va, endva - va);
! 409: pmap_update(pmap_kernel());
! 410:
! 411: /* Free the kernel virtual mapping. */
! 412: uvm_km_free(kernel_map, va, endva - va);
! 413: }
! 414:
! 415: int
! 416: i80321_mem_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
! 417: bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
! 418: bus_addr_t *bpap, bus_space_handle_t *bshp)
! 419: {
! 420:
! 421: panic("i80321_mem_bs_alloc(): not implemented");
! 422: }
! 423:
! 424: void
! 425: i80321_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
! 426: {
! 427:
! 428: panic("i80321_mem_bs_free(): not implemented");
! 429: }
! 430:
! 431: paddr_t
! 432: i80321_mem_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
! 433: {
! 434:
! 435: /* XXX */
! 436: return (-1);
! 437: }
CVSweb