[BACK]Return to kdb.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / bi

Annotation of sys/arch/vax/bi/kdb.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: kdb.c,v 1.11 2007/05/11 10:06:55 pedro Exp $ */
        !             2: /*     $NetBSD: kdb.c,v 1.26 2001/11/13 12:51:34 lukem Exp $ */
        !             3: /*
        !             4:  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
        !             5:  * 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 at Ludd, University of
        !            18:  *     Lule}, Sweden and its contributors.
        !            19:  * 4. The name of the author may not be used to endorse or promote products
        !            20:  *    derived from this software without specific prior written permission
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: /*
        !            35:  * KDB50 disk device driver
        !            36:  */
        !            37: /*
        !            38:  * TODO
        !            39:  *   Implement node reset routine.
        !            40:  *   Nices hardware error handling.
        !            41:  */
        !            42:
        !            43: #include <sys/param.h>
        !            44: #include <sys/kernel.h>
        !            45: #include <sys/buf.h>
        !            46: #include <sys/device.h>
        !            47: #include <sys/proc.h>
        !            48: #include <sys/user.h>
        !            49: #include <sys/malloc.h>
        !            50: #include <sys/systm.h>
        !            51: #include <sys/sched.h>
        !            52:
        !            53: #include <uvm/uvm_extern.h>
        !            54:
        !            55: #ifdef __vax__
        !            56: #include <machine/pte.h>
        !            57: #include <machine/pcb.h>
        !            58: #endif
        !            59: #include <machine/bus.h>
        !            60:
        !            61: #include <dev/bi/bireg.h>
        !            62: #include <dev/bi/bivar.h>
        !            63: #include <dev/bi/kdbreg.h>
        !            64:
        !            65: #include <dev/mscp/mscp.h>
        !            66: #include <dev/mscp/mscpreg.h>
        !            67: #include <dev/mscp/mscpvar.h>
        !            68:
        !            69: #define KDB_WL(adr, val) bus_space_write_4(sc->sc_iot, sc->sc_ioh, adr, val)
        !            70: #define KDB_RL(adr) bus_space_read_4(sc->sc_iot, sc->sc_ioh, adr)
        !            71: #define KDB_RS(adr) bus_space_read_2(sc->sc_iot, sc->sc_ioh, adr)
        !            72:
        !            73: #define            b_forw  b_hash.le_next
        !            74: /*
        !            75:  * Software status, per controller.
        !            76:  */
        !            77: struct kdb_softc {
        !            78:        struct  device sc_dev;          /* Autoconfig info */
        !            79:        caddr_t sc_kdb;                 /* Struct for kdb communication */
        !            80:        struct  mscp_softc *sc_softc;   /* MSCP info (per mscpvar.h) */
        !            81:        bus_dma_tag_t sc_dmat;
        !            82:        bus_dmamap_t sc_cmap;           /* Control structures */
        !            83:        bus_space_tag_t sc_iot;
        !            84:        bus_space_handle_t sc_ioh;
        !            85: };
        !            86:
        !            87: int    kdbmatch(struct device *, struct cfdata *, void *);
        !            88: void   kdbattach(struct device *, struct device *, void *);
        !            89: void   kdbreset(int);
        !            90: void   kdbintr(void *);
        !            91: void   kdbctlrdone(struct device *);
        !            92: int    kdbprint(void *, const char *);
        !            93: void   kdbsaerror(struct device *, int);
        !            94: void   kdbgo(struct device *, struct mscp_xi *);
        !            95:
        !            96: struct cfattach kdb_ca = {
        !            97:        sizeof(struct kdb_softc), kdbmatch, kdbattach
        !            98: };
        !            99:
        !           100: /*
        !           101:  * More driver definitions, for generic MSCP code.
        !           102:  */
        !           103: struct mscp_ctlr kdb_mscp_ctlr = {
        !           104:        kdbctlrdone,
        !           105:        kdbgo,
        !           106:        kdbsaerror,
        !           107: };
        !           108:
        !           109: int
        !           110: kdbprint(aux, name)
        !           111:        void    *aux;
        !           112:        const char      *name;
        !           113: {
        !           114:        if (name)
        !           115:                printf("%s: mscpbus", name);
        !           116:        return UNCONF;
        !           117: }
        !           118:
        !           119: /*
        !           120:  * Poke at a supposed KDB to see if it is there.
        !           121:  */
        !           122: int
        !           123: kdbmatch(parent, cf, aux)
        !           124:        struct  device *parent;
        !           125:        struct  cfdata *cf;
        !           126:        void    *aux;
        !           127: {
        !           128:        struct bi_attach_args *ba = aux;
        !           129:
        !           130:        if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_KDB50)
        !           131:                return 0;
        !           132:
        !           133:        if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
        !           134:            cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
        !           135:                return 0;
        !           136:
        !           137:        return 1;
        !           138: }
        !           139:
        !           140: void
        !           141: kdbattach(parent, self, aux)
        !           142:        struct device *parent, *self;
        !           143:        void *aux;
        !           144: {
        !           145:        struct  kdb_softc *sc = (void *)self;
        !           146:        struct  bi_attach_args *ba = aux;
        !           147:        struct  mscp_attach_args ma;
        !           148:        volatile int i = 10000;
        !           149:        int error, rseg;
        !           150:        bus_dma_segment_t seg;
        !           151:
        !           152:        printf("\n");
        !           153:        bi_intr_establish(ba->ba_icookie, ba->ba_ivec, kdbintr, sc);
        !           154:
        !           155:        sc->sc_iot = ba->ba_iot;
        !           156:        sc->sc_ioh = ba->ba_ioh;
        !           157:        sc->sc_dmat = ba->ba_dmat;
        !           158:
        !           159:        /*
        !           160:         * Map the communication area and command and
        !           161:         * response packets into Unibus space.
        !           162:         */
        !           163:        if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mscp_pack),
        !           164:            NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
        !           165:                printf("Alloc ctrl area %d\n", error);
        !           166:                return;
        !           167:        }
        !           168:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
        !           169:            sizeof(struct mscp_pack), &sc->sc_kdb,
        !           170:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
        !           171:                printf("Map ctrl area %d\n", error);
        !           172: err:           bus_dmamem_free(sc->sc_dmat, &seg, rseg);
        !           173:                return;
        !           174:        }
        !           175:        if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct mscp_pack),
        !           176:            1, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT, &sc->sc_cmap))) {
        !           177:                printf("Create DMA map %d\n", error);
        !           178: err2:          bus_dmamem_unmap(sc->sc_dmat, sc->sc_kdb,
        !           179:                    sizeof(struct mscp_pack));
        !           180:                goto err;
        !           181:        }
        !           182:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
        !           183:            sc->sc_kdb, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT))) {
        !           184:                printf("Load ctrl map %d\n", error);
        !           185:                bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
        !           186:                goto err2;
        !           187:        }
        !           188:        memset(sc->sc_kdb, 0, sizeof(struct mscp_pack));
        !           189:
        !           190:        ma.ma_mc = &kdb_mscp_ctlr;
        !           191:        ma.ma_type = MSCPBUS_DISK|MSCPBUS_KDB;
        !           192:        ma.ma_uda = (struct mscp_pack *)sc->sc_kdb;
        !           193:        ma.ma_softc = &sc->sc_softc;
        !           194:        ma.ma_iot = sc->sc_iot;
        !           195:        ma.ma_iph = sc->sc_ioh + KDB_IP;
        !           196:        ma.ma_sah = sc->sc_ioh + KDB_SA;
        !           197:        ma.ma_swh = sc->sc_ioh + KDB_SW;
        !           198:        ma.ma_dmat = sc->sc_dmat;
        !           199:        ma.ma_dmam = sc->sc_cmap;
        !           200:        ma.ma_ivec = ba->ba_ivec;
        !           201:        ma.ma_ctlrnr = ba->ba_nodenr;
        !           202:        ma.ma_adapnr = ba->ba_busnr;
        !           203:
        !           204:        KDB_WL(BIREG_VAXBICSR, KDB_RL(BIREG_VAXBICSR) | BICSR_NRST);
        !           205:        while (i--) /* Need delay??? */
        !           206:                ;
        !           207:        KDB_WL(BIREG_INTRDES, ba->ba_intcpu); /* Interrupt on CPU # */
        !           208:        KDB_WL(BIREG_BCICSR, KDB_RL(BIREG_BCICSR) |
        !           209:            BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | BCI_INTEN);
        !           210:        KDB_WL(BIREG_UINTRCSR, ba->ba_ivec);
        !           211:        config_found(&sc->sc_dev, &ma, kdbprint);
        !           212: }
        !           213:
        !           214: void
        !           215: kdbgo(usc, mxi)
        !           216:        struct device *usc;
        !           217:        struct mscp_xi *mxi;
        !           218: {
        !           219:        struct kdb_softc *sc = (void *)usc;
        !           220:        struct buf *bp = mxi->mxi_bp;
        !           221:        struct mscp *mp = mxi->mxi_mp;
        !           222:        u_int32_t addr = (u_int32_t)bp->b_data;
        !           223:        u_int32_t mapaddr;
        !           224:        int err;
        !           225:
        !           226:        /*
        !           227:         * The KDB50 wants to read VAX Page tables directly, therefore
        !           228:         * the result from bus_dmamap_load() is uninteresting. (But it
        !           229:         * should never fail!).
        !           230:         *
        !           231:         * On VAX, point to the corresponding page tables. (user/sys)
        !           232:         * On other systems, do something else...
        !           233:         */
        !           234:        err = bus_dmamap_load(sc->sc_dmat, mxi->mxi_dmam, bp->b_data,
        !           235:            bp->b_bcount, (bp->b_flags & B_PHYS ? bp->b_proc : 0),
        !           236:            BUS_DMA_NOWAIT);
        !           237:
        !           238:        if (err) /* Shouldn't happen */
        !           239:                panic("kdbgo: bus_dmamap_load: error %d", err);
        !           240:
        !           241: #ifdef __vax__
        !           242:        /*
        !           243:         * Get a pointer to the pte pointing out the first virtual address.
        !           244:         * Use different ways in kernel and user space.
        !           245:         */
        !           246:        if ((bp->b_flags & B_PHYS) == 0) {
        !           247:                mapaddr = ((u_int32_t)kvtopte(addr)) & ~KERNBASE;
        !           248:        } else {
        !           249:                struct pcb *pcb;
        !           250:                u_int32_t eaddr;
        !           251:
        !           252:                /*
        !           253:                 * We check if the PTE's needed crosses a page boundary.
        !           254:                 * If they do; only transfer the amount of data that is
        !           255:                 * mapped by the first PTE page and led the system handle
        !           256:                 * the rest of the data.
        !           257:                 */
        !           258:                pcb = &bp->b_proc->p_addr->u_pcb;
        !           259:                mapaddr = (u_int32_t)uvtopte(addr, pcb);
        !           260:                eaddr = (u_int32_t)uvtopte(addr + (bp->b_bcount - 1), pcb);
        !           261:                if (trunc_page(mapaddr) != trunc_page(eaddr)) {
        !           262:                        mp->mscp_seq.seq_bytecount =
        !           263:                            (((round_page(mapaddr) - mapaddr)/4) * 512);
        !           264:                }
        !           265:                mapaddr = kvtophys(mapaddr);
        !           266:        }
        !           267: #else
        !           268: #error Must write code to handle KDB50 on non-vax.
        !           269: #endif
        !           270:
        !           271:        mp->mscp_seq.seq_mapbase = mapaddr;
        !           272:        mxi->mxi_dmam->dm_segs[0].ds_addr = (addr & 511) | KDB_MAP;
        !           273:        mscp_dgo(sc->sc_softc, mxi);
        !           274: }
        !           275:
        !           276: void
        !           277: kdbsaerror(usc, doreset)
        !           278:        struct device *usc;
        !           279:        int doreset;
        !           280: {
        !           281:        struct  kdb_softc *sc = (void *)usc;
        !           282:
        !           283:        if ((KDB_RS(KDB_SA) & MP_ERR) == 0)
        !           284:                return;
        !           285:        printf("%s: controller error, sa=0x%x\n", sc->sc_dev.dv_xname,
        !           286:            KDB_RS(KDB_SA));
        !           287:        /* What to do now??? */
        !           288: }
        !           289:
        !           290: /*
        !           291:  * Interrupt routine.  Depending on the state of the controller,
        !           292:  * continue initialisation, or acknowledge command and response
        !           293:  * interrupts, and process responses.
        !           294:  */
        !           295: void
        !           296: kdbintr(void *arg)
        !           297: {
        !           298:        struct kdb_softc *sc = arg;
        !           299:
        !           300:        if (KDB_RS(KDB_SA) & MP_ERR) {  /* ctlr fatal error */
        !           301:                kdbsaerror(&sc->sc_dev, 1);
        !           302:                return;
        !           303:        }
        !           304:        KERNEL_LOCK();
        !           305:        mscp_intr(sc->sc_softc);
        !           306:        KERNEL_UNLOCK();
        !           307: }
        !           308:
        !           309: #ifdef notyet
        !           310: /*
        !           311:  * The KDB50 has been reset.  Reinitialise the controller
        !           312:  * and requeue outstanding I/O.
        !           313:  */
        !           314: void
        !           315: kdbreset(ctlr)
        !           316:        int ctlr;
        !           317: {
        !           318:        struct kdb_softc *sc;
        !           319:
        !           320:        sc = kdb_cd.cd_devs[ctlr];
        !           321:        printf(" kdb%d", ctlr);
        !           322:
        !           323:
        !           324:        /* reset queues and requeue pending transfers */
        !           325:        mscp_requeue(sc->sc_softc);
        !           326:
        !           327:        /*
        !           328:         * If it fails to initialise we will notice later and
        !           329:         * try again (and again...).  Do not call kdbstart()
        !           330:         * here; it will be done after the controller finishes
        !           331:         * initialisation.
        !           332:         */
        !           333:        if (kdbinit(sc))
        !           334:                printf(" (hung)");
        !           335: }
        !           336: #endif
        !           337:
        !           338: void
        !           339: kdbctlrdone(usc)
        !           340:        struct device *usc;
        !           341: {
        !           342: }

CVSweb