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