[BACK]Return to tsp_dma.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / pci

Annotation of sys/arch/alpha/pci/tsp_dma.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: tsp_dma.c,v 1.5 2006/04/04 21:20:40 brad Exp $ */
        !             2: /* $NetBSD: tsp_dma.c,v 1.1 1999/06/29 06:46:47 ross Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1999 by Ross Harvey.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *     This product includes software developed by Ross Harvey.
        !            18:  * 4. The name of Ross Harvey may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY ROSS HARVEY ``AS IS'' AND ANY EXPRESS
        !            22:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            23:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY
        !            25:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  */
        !            34:
        !            35: /*-
        !            36:  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
        !            37:  * All rights reserved.
        !            38:  *
        !            39:  * This code is derived from software contributed to The NetBSD Foundation
        !            40:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
        !            41:  * NASA Ames Research Center.
        !            42:  *
        !            43:  * Redistribution and use in source and binary forms, with or without
        !            44:  * modification, are permitted provided that the following conditions
        !            45:  * are met:
        !            46:  * 1. Redistributions of source code must retain the above copyright
        !            47:  *    notice, this list of conditions and the following disclaimer.
        !            48:  * 2. Redistributions in binary form must reproduce the above copyright
        !            49:  *    notice, this list of conditions and the following disclaimer in the
        !            50:  *    documentation and/or other materials provided with the distribution.
        !            51:  * 3. All advertising materials mentioning features or use of this software
        !            52:  *    must display the following acknowledgement:
        !            53:  *     This product includes software developed by the NetBSD
        !            54:  *     Foundation, Inc. and its contributors.
        !            55:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            56:  *    contributors may be used to endorse or promote products derived
        !            57:  *    from this software without specific prior written permission.
        !            58:  *
        !            59:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            60:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            61:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            62:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            63:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            64:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            65:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            66:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            67:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            68:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            69:  * POSSIBILITY OF SUCH DAMAGE.
        !            70:  */
        !            71:
        !            72: #define _ALPHA_BUS_DMA_PRIVATE
        !            73:
        !            74: #include <sys/param.h>
        !            75: #include <sys/systm.h>
        !            76: #include <sys/kernel.h>
        !            77: #include <sys/device.h>
        !            78: #include <sys/malloc.h>
        !            79:
        !            80: #include <uvm/uvm_extern.h>
        !            81:
        !            82: #include <machine/autoconf.h>
        !            83:
        !            84: #include <machine/bus.h>
        !            85: #include <machine/rpb.h>
        !            86:
        !            87: #include <dev/pci/pcireg.h>
        !            88: #include <dev/pci/pcivar.h>
        !            89: #include <alpha/pci/tsreg.h>
        !            90: #include <alpha/pci/tsvar.h>
        !            91:
        !            92: #define tsp_dma() { Generate ctags(1) key. }
        !            93:
        !            94: #define        EDIFF(a, b) (((a) | WSBA_ENA | WSBA_SG) != ((b) | WSBA_ENA | WSBA_SG))
        !            95:
        !            96: bus_dma_tag_t tsp_dma_get_tag(bus_dma_tag_t, alpha_bus_t);
        !            97:
        !            98: int    tsp_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *,
        !            99:            bus_size_t, struct proc *, int);
        !           100:
        !           101: int    tsp_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t,
        !           102:            struct mbuf *, int);
        !           103:
        !           104: int    tsp_bus_dmamap_load_uio_sgmap(bus_dma_tag_t, bus_dmamap_t,
        !           105:            struct uio *, int);
        !           106:
        !           107: int    tsp_bus_dmamap_load_raw_sgmap(bus_dma_tag_t, bus_dmamap_t,
        !           108:            bus_dma_segment_t *, int, bus_size_t, int);
        !           109:
        !           110: void   tsp_bus_dmamap_unload_sgmap(bus_dma_tag_t, bus_dmamap_t);
        !           111:
        !           112: void   tsp_tlb_invalidate(struct tsp_config *);
        !           113:
        !           114: /*
        !           115:  * XXX Need to figure out what this is, if any.  Initialize it to
        !           116:  * XXX something that should be safe.
        !           117:  */
        !           118: #define        TSP_SGMAP_PFTHRESH      256
        !           119:
        !           120: void
        !           121: tsp_dma_init(pcp)
        !           122:        struct tsp_config *pcp;
        !           123: {
        !           124:        int i;
        !           125:        bus_dma_tag_t t;
        !           126:        struct ts_pchip *pccsr = pcp->pc_csr;
        !           127:        bus_addr_t dwbase, dwlen, sgwbase, sgwlen, tbase;
        !           128:        static struct map_expected {
        !           129:                u_int32_t base, mask, enables;
        !           130:        } premap[4] = {
        !           131:                { 0x800000,                0x700000, WSBA_ENA | WSBA_SG },
        !           132:                { 0x80000000 | WSBA_ENA, 0x3ff00000, WSBA_ENA           },
        !           133:                { 0, 0 },
        !           134:                { 0, 0 }
        !           135:        };
        !           136:
        !           137:        alpha_mb();
        !           138:        for(i = 0; i < 4; ++i) {
        !           139:                if (EDIFF(pccsr->tsp_wsba[i].tsg_r, premap[i].base) ||
        !           140:                    EDIFF(pccsr->tsp_wsm[i].tsg_r, premap[i].mask))
        !           141:                        printf("tsp%d: window %d: %lx/base %lx/mask %lx"
        !           142:                            " reinitialized\n",
        !           143:                            pcp->pc_pslot, i,
        !           144:                            pccsr->tsp_wsba[i].tsg_r,
        !           145:                            pccsr->tsp_wsm[i].tsg_r,
        !           146:                            pccsr->tsp_tba[i].tsg_r);
        !           147:                pccsr->tsp_wsba[i].tsg_r = premap[i].base | premap[i].enables;
        !           148:                pccsr->tsp_wsm[i].tsg_r = premap[i].mask;
        !           149:        }
        !           150:        alpha_mb();
        !           151:
        !           152:        /*
        !           153:         * Initialize the DMA tag used for direct-mapped DMA.
        !           154:         */
        !           155:        t = &pcp->pc_dmat_direct;
        !           156:        t->_cookie = pcp;
        !           157:        t->_wbase = dwbase = WSBA_ADDR(pccsr->tsp_wsba[1].tsg_r);
        !           158:        t->_wsize = dwlen = WSM_LEN(pccsr->tsp_wsm[1].tsg_r);
        !           159:        t->_next_window = &pcp->pc_dmat_sgmap;
        !           160:        t->_boundary = 0;
        !           161:        t->_sgmap = NULL;
        !           162:        t->_get_tag = tsp_dma_get_tag;
        !           163:        t->_dmamap_create = _bus_dmamap_create;
        !           164:        t->_dmamap_destroy = _bus_dmamap_destroy;
        !           165:        t->_dmamap_load = _bus_dmamap_load_direct;
        !           166:        t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct;
        !           167:        t->_dmamap_load_uio = _bus_dmamap_load_uio_direct;
        !           168:        t->_dmamap_load_raw = _bus_dmamap_load_raw_direct;
        !           169:        t->_dmamap_unload = _bus_dmamap_unload;
        !           170:        t->_dmamap_sync = _bus_dmamap_sync;
        !           171:
        !           172:        t->_dmamem_alloc = _bus_dmamem_alloc;
        !           173:        t->_dmamem_free = _bus_dmamem_free;
        !           174:        t->_dmamem_map = _bus_dmamem_map;
        !           175:        t->_dmamem_unmap = _bus_dmamem_unmap;
        !           176:        t->_dmamem_mmap = _bus_dmamem_mmap;
        !           177:
        !           178:        /*
        !           179:         * Initialize the DMA tag used for sgmap-mapped DMA.
        !           180:         */
        !           181:        t = &pcp->pc_dmat_sgmap;
        !           182:        t->_cookie = pcp;
        !           183:        t->_wbase = sgwbase = WSBA_ADDR(pccsr->tsp_wsba[0].tsg_r);
        !           184:        t->_wsize = sgwlen = WSM_LEN(pccsr->tsp_wsm[0].tsg_r);
        !           185:        t->_next_window = NULL;
        !           186:        t->_boundary = 0;
        !           187:        t->_sgmap = &pcp->pc_sgmap;
        !           188:        t->_pfthresh = TSP_SGMAP_PFTHRESH;
        !           189:        t->_get_tag = tsp_dma_get_tag;
        !           190:        t->_dmamap_create = alpha_sgmap_dmamap_create;
        !           191:        t->_dmamap_destroy = alpha_sgmap_dmamap_destroy;
        !           192:        t->_dmamap_load = tsp_bus_dmamap_load_sgmap;
        !           193:        t->_dmamap_load_mbuf = tsp_bus_dmamap_load_mbuf_sgmap;
        !           194:        t->_dmamap_load_uio = tsp_bus_dmamap_load_uio_sgmap;
        !           195:        t->_dmamap_load_raw = tsp_bus_dmamap_load_raw_sgmap;
        !           196:        t->_dmamap_unload = tsp_bus_dmamap_unload_sgmap;
        !           197:        t->_dmamap_sync = _bus_dmamap_sync;
        !           198:
        !           199:        t->_dmamem_alloc = _bus_dmamem_alloc;
        !           200:        t->_dmamem_free = _bus_dmamem_free;
        !           201:        t->_dmamem_map = _bus_dmamem_map;
        !           202:        t->_dmamem_unmap = _bus_dmamem_unmap;
        !           203:        t->_dmamem_mmap = _bus_dmamem_mmap;
        !           204:
        !           205:        /*
        !           206:         * Initialize the SGMAP.  Align page table to 32k in case
        !           207:         * window is somewhat larger than expected.
        !           208:         */
        !           209:        alpha_sgmap_init(t, &pcp->pc_sgmap, "tsp_sgmap",
        !           210:            sgwbase, 0, sgwlen, sizeof(u_int64_t), NULL, (32*1024));
        !           211:
        !           212:        /*
        !           213:         * Enable window 0 and enable SG PTE mapping.
        !           214:         */
        !           215:        alpha_mb();
        !           216:        pccsr->tsp_wsba[0].tsg_r |= WSBA_SG | WSBA_ENA;
        !           217:        alpha_mb();
        !           218:
        !           219:        /*
        !           220:         * Check windows for sanity, especially if we later decide to
        !           221:         * use the firmware's initialization in some cases.
        !           222:         */
        !           223:        if ((sgwbase <= dwbase && dwbase < sgwbase + sgwlen) ||
        !           224:            (dwbase <= sgwbase && sgwbase < dwbase + dwlen))
        !           225:                panic("tsp_dma_init: overlap");
        !           226:
        !           227:        tbase = pcp->pc_sgmap.aps_ptpa;
        !           228:        if (tbase & ~0x7fffffc00UL)
        !           229:                panic("tsp_dma_init: bad page table address");
        !           230:        alpha_mb();
        !           231:        pccsr->tsp_tba[0].tsg_r = tbase;
        !           232:        alpha_mb();
        !           233:
        !           234:        tsp_tlb_invalidate(pcp);
        !           235:        alpha_mb();
        !           236:
        !           237:        /* XXX XXX BEGIN XXX XXX */
        !           238:        {                                                       /* XXX */
        !           239:                extern paddr_t alpha_XXX_dmamap_or;             /* XXX */
        !           240:                alpha_XXX_dmamap_or = dwbase;                   /* XXX */
        !           241:        }                                                       /* XXX */
        !           242:        /* XXX XXX END XXX XXX */
        !           243: }
        !           244:
        !           245: /*
        !           246:  * Return the bus dma tag to be used for the specified bus type.
        !           247:  * INTERNAL USE ONLY!
        !           248:  */
        !           249: bus_dma_tag_t
        !           250: tsp_dma_get_tag(t, bustype)
        !           251:        bus_dma_tag_t t;
        !           252:        alpha_bus_t bustype;
        !           253: {
        !           254:        struct tsp_config *pcp = t->_cookie;
        !           255:
        !           256:        switch (bustype) {
        !           257:        case ALPHA_BUS_PCI:
        !           258:        case ALPHA_BUS_EISA:
        !           259:                /*
        !           260:                 * The direct mapped window will work for most systems,
        !           261:                 * most of the time. When it doesn't, we chain to the sgmap
        !           262:                 * window automatically.
        !           263:                 */
        !           264:                return (&pcp->pc_dmat_direct);
        !           265:
        !           266:        case ALPHA_BUS_ISA:
        !           267:                /*
        !           268:                 * ISA doesn't have enough address bits to use
        !           269:                 * the direct-mapped DMA window, so we must use
        !           270:                 * SGMAPs.
        !           271:                 */
        !           272:                return (&pcp->pc_dmat_sgmap);
        !           273:
        !           274:        default:
        !           275:                panic("tsp_dma_get_tag: shouldn't be here, really...");
        !           276:        }
        !           277: }
        !           278:
        !           279: /*
        !           280:  * Load a TSP SGMAP-mapped DMA map with a linear buffer.
        !           281:  */
        !           282: int
        !           283: tsp_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
        !           284:        bus_dma_tag_t t;
        !           285:        bus_dmamap_t map;
        !           286:        void *buf;
        !           287:        bus_size_t buflen;
        !           288:        struct proc *p;
        !           289:        int flags;
        !           290: {
        !           291:        int error;
        !           292:
        !           293:        error = pci_sgmap_pte64_load(t, map, buf, buflen, p, flags,
        !           294:            t->_sgmap);
        !           295:        if (error == 0)
        !           296:                tsp_tlb_invalidate(t->_cookie);
        !           297:
        !           298:        return (error);
        !           299: }
        !           300:
        !           301: /*
        !           302:  * Load a TSP SGMAP-mapped DMA map with an mbuf chain.
        !           303:  */
        !           304: int
        !           305: tsp_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
        !           306:        bus_dma_tag_t t;
        !           307:        bus_dmamap_t map;
        !           308:        struct mbuf *m;
        !           309:        int flags;
        !           310: {
        !           311:        int error;
        !           312:
        !           313:        error = pci_sgmap_pte64_load_mbuf(t, map, m, flags, t->_sgmap);
        !           314:        if (error == 0)
        !           315:                tsp_tlb_invalidate(t->_cookie);
        !           316:
        !           317:        return (error);
        !           318: }
        !           319:
        !           320: /*
        !           321:  * Load a TSP SGMAP-mapped DMA map with a uio.
        !           322:  */
        !           323: int
        !           324: tsp_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
        !           325:        bus_dma_tag_t t;
        !           326:        bus_dmamap_t map;
        !           327:        struct uio *uio;
        !           328:        int flags;
        !           329: {
        !           330:        int error;
        !           331:
        !           332:        error = pci_sgmap_pte64_load_uio(t, map, uio, flags, t->_sgmap);
        !           333:        if (error == 0)
        !           334:                tsp_tlb_invalidate(t->_cookie);
        !           335:
        !           336:        return (error);
        !           337: }
        !           338:
        !           339: /*
        !           340:  * Load a TSP SGMAP-mapped DMA map with raw memory.
        !           341:  */
        !           342: int
        !           343: tsp_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
        !           344:        bus_dma_tag_t t;
        !           345:        bus_dmamap_t map;
        !           346:        bus_dma_segment_t *segs;
        !           347:        int nsegs;
        !           348:        bus_size_t size;
        !           349:        int flags;
        !           350: {
        !           351:        int error;
        !           352:
        !           353:        error = pci_sgmap_pte64_load_raw(t, map, segs, nsegs, size, flags,
        !           354:            t->_sgmap);
        !           355:        if (error == 0)
        !           356:                tsp_tlb_invalidate(t->_cookie);
        !           357:
        !           358:        return (error);
        !           359: }
        !           360:
        !           361: /*
        !           362:  * Unload a TSP DMA map.
        !           363:  */
        !           364: void
        !           365: tsp_bus_dmamap_unload_sgmap(t, map)
        !           366:        bus_dma_tag_t t;
        !           367:        bus_dmamap_t map;
        !           368: {
        !           369:
        !           370:        /*
        !           371:         * Invalidate any SGMAP page table entries used by this
        !           372:         * mapping.
        !           373:         */
        !           374:        pci_sgmap_pte64_unload(t, map, t->_sgmap);
        !           375:        tsp_tlb_invalidate(t->_cookie);
        !           376:
        !           377:        /*
        !           378:         * Do the generic bits of the unload.
        !           379:         */
        !           380:        _bus_dmamap_unload(t, map);
        !           381: }
        !           382:
        !           383: /*
        !           384:  * Flush the TSP scatter/gather TLB.
        !           385:  */
        !           386: void
        !           387: tsp_tlb_invalidate(pcp)
        !           388:        struct tsp_config *pcp;
        !           389: {
        !           390:
        !           391:        alpha_mb();
        !           392:        pcp->pc_csr->tsp_tlbia.tsg_r = 0;
        !           393:        alpha_mb();
        !           394: }

CVSweb