[BACK]Return to zs_kgdb.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/zs_kgdb.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: zs_kgdb.c,v 1.2 2005/11/11 15:21:59 fgsch Exp $       */
        !             2: /*     $NetBSD: zs_kgdb.c,v 1.1 1997/10/18 00:00:51 gwr Exp $  */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1996 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Gordon W. Ross.
        !            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: /*
        !            41:  * Hooks for kgdb when attached via the z8530 driver
        !            42:  *
        !            43:  * To use this, build a kernel with: option KGDB, and
        !            44:  * boot that kernel with "-d".  (The kernel will call
        !            45:  * zs_kgdb_init, kgdb_connect.)  When the console prints
        !            46:  * "kgdb waiting..." you run "gdb -k kernel" and do:
        !            47:  *   (gdb) set remotebaud 19200
        !            48:  *   (gdb) target remote /dev/ttyb
        !            49:  */
        !            50:
        !            51: #include <sys/param.h>
        !            52: #include <sys/systm.h>
        !            53: #include <sys/proc.h>
        !            54: #include <sys/device.h>
        !            55: #include <sys/conf.h>
        !            56: #include <sys/ioctl.h>
        !            57: #include <sys/kernel.h>
        !            58: #include <sys/syslog.h>
        !            59: #include <sys/kgdb.h>
        !            60:
        !            61: #include <sparc/dev/z8530reg.h>
        !            62: #include <machine/z8530var.h>
        !            63: #include <sparc/dev/cons.h>
        !            64:
        !            65: /* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */
        !            66: #define PCLK   (9600 * 512)    /* PCLK pin input clock rate */
        !            67: #define ZSHARD_PRI     6       /* Wired on the CPU board... */
        !            68:
        !            69: #define        ZS_DELAY()              (CPU_ISSUN4C ? (0) : delay(2))
        !            70:
        !            71: /* The layout of this is hardware-dependent (padding, order). */
        !            72: struct zschan {
        !            73:        volatile u_char zc_csr;         /* ctrl,status, and indirect access */
        !            74:        u_char          zc_xxx0;
        !            75:        volatile u_char zc_data;        /* data */
        !            76:        u_char          zc_xxx1;
        !            77: };
        !            78:
        !            79: void zs_setparam(struct zs_chanstate *, int, int);
        !            80: struct zsops zsops_kgdb;
        !            81:
        !            82: u_char zs_kgdb_regs[16] = {
        !            83:        0,      /* 0: CMD (reset, etc.) */
        !            84:        0,      /* 1: ~(ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE) */
        !            85:        0,      /* 2: IVECT */
        !            86:        ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
        !            87:        ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
        !            88:        ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
        !            89:        0,      /* 6: TXSYNC/SYNCLO */
        !            90:        0,      /* 7: RXSYNC/SYNCHI */
        !            91:        0,      /* 8: alias for data port */
        !            92:        ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR,
        !            93:        0,      /*10: Misc. TX/RX control bits */
        !            94:        ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
        !            95:        14,     /*12: BAUDLO (default=9600) */
        !            96:        0,      /*13: BAUDHI (default=9600) */
        !            97:        ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
        !            98:        ZSWR15_BREAK_IE | ZSWR15_DCD_IE,
        !            99: };
        !           100:
        !           101: /*
        !           102:  * This replaces "zs_reset()" in the sparc driver.
        !           103:  */
        !           104: void
        !           105: zs_setparam(cs, iena, rate)
        !           106:        struct zs_chanstate *cs;
        !           107:        int iena;
        !           108:        int rate;
        !           109: {
        !           110:        int s, tconst;
        !           111:
        !           112:        bcopy(zs_kgdb_regs, cs->cs_preg, 16);
        !           113:
        !           114:        if (iena) {
        !           115:                cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
        !           116:        }
        !           117:
        !           118:        /* Initialize the speed, etc. */
        !           119:        tconst = BPS_TO_TCONST(cs->cs_brg_clk, rate);
        !           120:        cs->cs_preg[5] |= ZSWR5_DTR | ZSWR5_RTS;
        !           121:        cs->cs_preg[12] = tconst;
        !           122:        cs->cs_preg[13] = tconst >> 8;
        !           123:
        !           124:        s = splhigh();
        !           125:        zs_loadchannelregs(cs);
        !           126:        splx(s);
        !           127: }
        !           128:
        !           129: /*
        !           130:  * Set up for kgdb; called at boot time before configuration.
        !           131:  * KGDB interrupts will be enabled later when zs0 is configured.
        !           132:  * Called after cninit(), so printf() etc. works.
        !           133:  */
        !           134: void
        !           135: zs_kgdb_init()
        !           136: {
        !           137:        struct zs_chanstate cs;
        !           138:        volatile struct zschan *zc;
        !           139:        int channel, zsc_unit;
        !           140:
        !           141:        /* printf("zs_kgdb_init: kgdb_dev=0x%x\n", kgdb_dev); */
        !           142:        if (major(kgdb_dev) != zs_major)
        !           143:                return;
        !           144:
        !           145:        /* Note: (ttya,ttyb) on zsc1, and (ttyc,ttyd) on zsc0 */
        !           146:        zsc_unit = (kgdb_dev & 2) ? 0 : 1;
        !           147:        channel  =  kgdb_dev & 1;
        !           148:        printf("zs_kgdb_init: attaching tty%c at %d baud\n",
        !           149:                   'a' + (kgdb_dev & 3), kgdb_rate);
        !           150:
        !           151:        /* Setup temporary chanstate. */
        !           152:        bzero((caddr_t)&cs, sizeof(cs));
        !           153:        zc = zs_get_chan_addr(zsc_unit, channel);
        !           154:        if (zc == NULL) {
        !           155:                printf("zs_kgdb_init: zs not mapped.\n");
        !           156:                kgdb_dev = -1;
        !           157:                return;
        !           158:        }
        !           159:
        !           160:        cs.cs_channel = channel;
        !           161:        cs.cs_brg_clk = PCLK / 16;
        !           162:        cs.cs_reg_csr  = &zc->zc_csr;
        !           163:        cs.cs_reg_data = &zc->zc_data;
        !           164:
        !           165:        /* Now set parameters. (interrupts disabled) */
        !           166:        zs_setparam(&cs, 0, kgdb_rate);
        !           167:
        !           168:        /* Store the getc/putc functions and arg. */
        !           169:        kgdb_attach(zs_getc, zs_putc, (void *)zc);
        !           170: }
        !           171:
        !           172: /*
        !           173:  * This is a "hook" called by zstty_attach to allow the tty
        !           174:  * to be "taken over" for exclusive use by kgdb.
        !           175:  * Return non-zero if this is the kgdb port.
        !           176:  *
        !           177:  * Set the speed to kgdb_rate, CS8, etc.
        !           178:  */
        !           179: int
        !           180: zs_check_kgdb(cs, dev)
        !           181:        struct zs_chanstate *cs;
        !           182:        int dev;
        !           183: {
        !           184:
        !           185:        if (dev != kgdb_dev)
        !           186:                return (0);
        !           187:
        !           188:        /*
        !           189:         * Yes, this is port in use by kgdb.
        !           190:         */
        !           191:        cs->cs_private = NULL;
        !           192:        cs->cs_ops = &zsops_kgdb;
        !           193:
        !           194:        /* Now set parameters. (interrupts enabled) */
        !           195:        zs_setparam(cs, 1, kgdb_rate);
        !           196:
        !           197:        return (1);
        !           198: }
        !           199:
        !           200: /*
        !           201:  * KGDB framing character received: enter kernel debugger.  This probably
        !           202:  * should time out after a few seconds to avoid hanging on spurious input.
        !           203:  */
        !           204: void
        !           205: zskgdb(cs)
        !           206:        struct zs_chanstate *cs;
        !           207: {
        !           208:        int unit = minor(kgdb_dev);
        !           209:
        !           210:        printf("zstty%d: kgdb interrupt\n", unit);
        !           211:        /* This will trap into the debugger. */
        !           212:        kgdb_connect(1);
        !           213: }
        !           214:
        !           215:
        !           216: /****************************************************************
        !           217:  * Interface to the lower layer (zscc)
        !           218:  ****************************************************************/
        !           219:
        !           220: void zs_kgdb_rxint(struct zs_chanstate *);
        !           221: void zs_kgdb_txint(struct zs_chanstate *);
        !           222: void zs_kgdb_stint(struct zs_chanstate *, int);
        !           223: void zs_kgdb_softint(struct zs_chanstate *);
        !           224:
        !           225: int kgdb_input_lost;
        !           226:
        !           227: void
        !           228: zs_kgdb_rxint(cs)
        !           229:        struct zs_chanstate *cs;
        !           230: {
        !           231:        register u_char c, rr1;
        !           232:
        !           233:        /*
        !           234:         * First read the status, because reading the received char
        !           235:         * destroys the status of this char.
        !           236:         */
        !           237:        rr1 = zs_read_reg(cs, 1);
        !           238:        c = zs_read_data(cs);
        !           239:
        !           240:        if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
        !           241:                /* Clear the receive error. */
        !           242:                zs_write_csr(cs, ZSWR0_RESET_ERRORS);
        !           243:        }
        !           244:
        !           245:        if (c == KGDB_START) {
        !           246:                zskgdb(cs);
        !           247:        } else {
        !           248:                kgdb_input_lost++;
        !           249:        }
        !           250: }
        !           251:
        !           252: void
        !           253: zs_kgdb_txint(cs)
        !           254:        register struct zs_chanstate *cs;
        !           255: {
        !           256:        register int rr0;
        !           257:
        !           258:        rr0 = zs_read_csr(cs);
        !           259:        zs_write_csr(cs, ZSWR0_RESET_TXINT);
        !           260: }
        !           261:
        !           262: void
        !           263: zs_kgdb_stint(cs, force)
        !           264:        register struct zs_chanstate *cs;
        !           265:        int force;
        !           266: {
        !           267:        register int rr0;
        !           268:
        !           269:        rr0 = zs_read_csr(cs);
        !           270:        zs_write_csr(cs, ZSWR0_RESET_STATUS);
        !           271:
        !           272:        /*
        !           273:         * Check here for console break, so that we can abort
        !           274:         * even when interrupts are locking up the machine.
        !           275:         */
        !           276:        if (rr0 & ZSRR0_BREAK) {
        !           277:                zskgdb(cs);
        !           278:        }
        !           279: }
        !           280:
        !           281: void
        !           282: zs_kgdb_softint(cs)
        !           283:        struct zs_chanstate *cs;
        !           284: {
        !           285:        printf("zs_kgdb_softint?\n");
        !           286: }
        !           287:
        !           288: struct zsops zsops_kgdb = {
        !           289:        zs_kgdb_rxint,  /* receive char available */
        !           290:        zs_kgdb_stint,  /* external/status */
        !           291:        zs_kgdb_txint,  /* xmit buffer empty */
        !           292:        zs_kgdb_softint,        /* process software interrupt */
        !           293: };

CVSweb