Index: dev/zsvar.h =================================================================== RCS file: /cvsroot/syssrc/sys/arch/mvme68k/dev/zsvar.h,v retrieving revision 1.7 diff -c -r1.7 zsvar.h *** dev/zsvar.h 2000/09/06 19:51:44 1.7 --- dev/zsvar.h 2000/09/16 12:43:19 *************** *** 5,11 **** * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation ! * by Jason R. Thorpe. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions --- 5,11 ---- * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation ! * by Jason R. Thorpe and Steve C. Woodford. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions *************** *** 36,41 **** --- 36,44 ---- * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef _MVME68K_ZSVAR_H + #define _MVME68K_ZSVAR_H + /* * Non-exported definitons common to the different attachment * types for the SCC on the Motorola MVME series of computers. *************** *** 44,94 **** /* * The MVME-147 provides a 4.9152 MHz clock to the SCC chips. */ ! #define PCLK_147 (9600 * 512) /* PCLK pin input clock rate */ /* * The MVME-162 provides a 9.8304 MHz clock to the SCC chips. - */ - #define PCLK_162 (9600 * 1024) /* PCLK pin input clock rate */ - - /* - * SCC should interrupt host at level 4. */ ! #define ZSHARD_PRI 4 /* ! * No delay needed when writing SCC registers. */ ! #define ZS_DELAY() /* * XXX Make cnprobe a little easier. */ ! #define NZSC 2 ! /* ! * The layout of this is hardware-dependent (padding, order). ! */ ! struct zschan { ! volatile u_char *zc_csr; /* ctrl,status, and indirect access */ ! volatile u_char *zc_data; /* data */ }; ! struct zsdevice { ! /* Yes, they are backwards. */ ! struct zschan zs_chan_b; ! struct zschan zs_chan_a; }; /* Globals exported from zs.c */ ! extern u_char zs_init_reg[]; /* Functions exported to ASIC-specific drivers. */ ! void zs_config __P((struct zsc_softc *, struct zsdevice *, int, int)); ! void zs_cnconfig __P((int, int, struct zsdevice *, int)); ! #ifdef MVME147 ! int zshard_shared __P((void *)); ! #endif ! #ifdef MVME162 ! int zshard_unshared(void *); ! #endif --- 47,94 ---- /* * The MVME-147 provides a 4.9152 MHz clock to the SCC chips. */ ! #define ZSMVME_PCLK_147 (9600 * 512) /* PCLK pin input clock rate */ /* * The MVME-162 provides a 9.8304 MHz clock to the SCC chips. */ ! #define ZSMVME_PCLK_162 (9600 * 1024) /* PCLK pin input clock rate */ /* ! * ZS should interrupt host at level 4. */ ! #define ZSMVME_HARD_PRI 4 /* * XXX Make cnprobe a little easier. */ ! #define NZSMVMEC 2 ! ! struct zsmvme_softc { ! struct zsc_softc sc_zsc; ! struct zs_chanstate sc_cs_store[2]; ! void *sc_softintr_cookie; }; ! struct zsmvme_config { ! bus_space_tag_t zc_bt; ! struct { ! bus_space_handle_t zc_csrbh; ! bus_space_handle_t zc_databh; ! } zc_s[2]; ! int zc_vector; ! int zc_pclk; }; /* Globals exported from zs.c */ ! extern u_char zsmvme_init_reg[]; ! extern struct zs_chanstate *zsmvme_conschan; /* Functions exported to ASIC-specific drivers. */ ! void zsmvme_config __P((struct zsmvme_softc *, struct zsmvme_config *)); ! void zsmvme_cnconfig __P((int, int, struct zsmvme_config *)); ! int zsmvme_getc(void *); ! void zsmvme_putc(void *, int); ! ! #endif /* _MVME68K_ZSVAR_H */ Index: dev/zs.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/mvme68k/dev/zs.c,v retrieving revision 1.22 diff -c -r1.22 zs.c *** dev/zs.c 2000/09/06 19:51:44 1.22 --- dev/zs.c 2000/09/16 12:43:20 *************** *** 43,48 **** --- 43,49 ---- * Plain tty/async lines use the zs_async slave. * * Modified for NetBSD/mvme68k by Jason R. Thorpe + * Modified for bus_space'd ZS driver by Steve Woodford. */ #include *************** *** 57,86 **** #include #include - #include - #include - #include - #include #include #include #include - /* - * Some warts needed by z8530tty.c - - * The default parity REALLY needs to be the same as the PROM uses, - * or you can not see messages done with printf during boot-up... - */ - int zs_def_cflag = (CREAD | CS8 | HUPCL); - /* XXX Shouldn't hardcode the minor number... */ - int zs_major = 12; /* Flags from zscnprobe() */ ! static int zs_hwflags[NZSC][2]; /* Default speed for each channel */ ! static int zs_defspeed[NZSC][2] = { { 9600, /* port 1 */ 9600 }, /* port 2 */ { 9600, /* port 3 */ --- 58,79 ---- #include #include #include #include #include + #include + #include + #include + #include /* Flags from zscnprobe() */ ! static int zs_hwflags[NZSMVMEC][2]; /* Default speed for each channel */ ! static int zs_defspeed[NZSMVMEC][2] = { { 9600, /* port 1 */ 9600 }, /* port 2 */ { 9600, /* port 3 */ *************** *** 88,110 **** }; static struct zs_chanstate zs_conschan_store; ! static struct zs_chanstate *zs_conschan; ! u_char zs_init_reg[16] = { ! 0, /* 0: CMD (reset, etc.) */ ! 0, /* 1: No interrupts yet. */ ! 0x18 + ZSHARD_PRI, /* IVECT */ ZSWR3_RX_8 | ZSWR3_RX_ENABLE, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, ZSWR5_TX_8 | ZSWR5_TX_ENABLE, ! 0, /* 6: TXSYNC/SYNCLO */ ! 0, /* 7: RXSYNC/SYNCHI */ ! 0, /* 8: alias for data port */ ZSWR9_MASTER_IE, ! 0, /*10: Misc. TX/RX control bits */ ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, ! 0, /*12: BAUDLO (default=9600) */ ! 0, /*13: BAUDHI (default=9600) */ ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK, ZSWR15_BREAK_IE, }; --- 81,103 ---- }; static struct zs_chanstate zs_conschan_store; ! struct zs_chanstate *zsmvme_conschan; ! u_char zsmvme_init_reg[16] = { ! 0, /* 0: CMD (reset, etc.) */ ! 0, /* 1: No interrupts yet. */ ! 0x18 + ZSMVME_HARD_PRI, /* IVECT */ ZSWR3_RX_8 | ZSWR3_RX_ENABLE, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, ZSWR5_TX_8 | ZSWR5_TX_ENABLE, ! 0, /* 6: TXSYNC/SYNCLO */ ! 0, /* 7: RXSYNC/SYNCHI */ ! 0, /* 8: alias for data port */ ZSWR9_MASTER_IE, ! 0, /*10: Misc TX/RX control bits */ ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, ! 0, /*12: BAUDLO (default=9600) */ ! 0, /*13: BAUDHI (default=9600) */ ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK, ZSWR15_BREAK_IE, }; *************** *** 116,149 **** /* Definition of the driver for autoconfig. */ static int zsc_print __P((void *, const char *name)); - int zs_getc __P((void *)); - void zs_putc __P((void *, int)); - - #if 0 - static int zs_get_speed __P((struct zs_chanstate *)); - #endif - - extern struct cfdriver zsc_cd; ! cons_decl(zsc_pcc); - /* * Configure children of an SCC. */ void ! zs_config(zsc, zs, vector, pclk) ! struct zsc_softc *zsc; ! struct zsdevice *zs; ! int vector, pclk; { struct zsc_attach_args zsc_args; - volatile struct zschan *zc; struct zs_chanstate *cs; int zsc_unit, channel, s; ! zsc_unit = zsc->zsc_dev.dv_unit; ! printf(": Zilog 8530 SCC at vector 0x%x\n", vector); /* * Initialize software state for each channel. --- 109,138 ---- /* Definition of the driver for autoconfig. */ static int zsc_print __P((void *, const char *name)); ! /* MD service routines */ ! static int zsmvme_set_speed(struct zs_chanstate *, int); ! static int zsmvme_set_modes(struct zs_chanstate *, int); ! static void zsmvme_abort(struct zs_chanstate *); /* * Configure children of an SCC. */ void ! zsmvme_config(sc, zc) ! struct zsmvme_softc *sc; ! struct zsmvme_config *zc; { struct zsc_attach_args zsc_args; struct zs_chanstate *cs; int zsc_unit, channel, s; + + zsc_unit = sc->sc_zsc.zsc_dev.dv_unit; + printf(" vector 0x%x: Zilog 8530 SCC\n", zc->zc_vector); ! sc->sc_zsc.zsc_set_speed = zsmvme_set_speed; ! sc->sc_zsc.zsc_set_modes = zsmvme_set_modes; ! sc->sc_zsc.zsc_abort = zsmvme_abort; /* * Initialize software state for each channel. *************** *** 151,177 **** for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; ! cs = &zsc->zsc_cs_store[channel]; ! zsc->zsc_cs[channel] = cs; /* * If we're the console, copy the channel state, and * adjust the console channel pointer. */ if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) { ! bcopy(zs_conschan, cs, sizeof(struct zs_chanstate)); ! zs_conschan = cs; } else { ! zc = (channel == 0) ? &zs->zs_chan_a : &zs->zs_chan_b; ! cs->cs_reg_csr = zc->zc_csr; ! cs->cs_reg_data = zc->zc_data; ! bcopy(zs_init_reg, cs->cs_creg, 16); ! bcopy(zs_init_reg, cs->cs_preg, 16); cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; } ! cs->cs_creg[2] = cs->cs_preg[2] = vector; ! cs->cs_creg[12] = cs->cs_preg[12] = ((pclk / 32) / 9600) - 1; ! cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; --- 140,167 ---- for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; ! cs = &sc->sc_cs_store[channel]; ! sc->sc_zsc.zsc_cs[channel] = cs; /* * If we're the console, copy the channel state, and * adjust the console channel pointer. */ if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) { ! bcopy(zsmvme_conschan, cs, sizeof(struct zs_chanstate)); ! zsmvme_conschan = cs; } else { ! cs->cs_bt = zc->zc_bt; ! cs->cs_csrbh = zc->zc_s[channel].zc_csrbh; ! cs->cs_databh = zc->zc_s[channel].zc_databh; ! bcopy(zsmvme_init_reg, cs->cs_creg, 16); ! bcopy(zsmvme_init_reg, cs->cs_preg, 16); cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; } ! cs->cs_creg[2] = cs->cs_preg[2] = zc->zc_vector; ! cs->cs_creg[12] = cs->cs_preg[12] = ! ((zc->zc_pclk / 32) / 9600) - 1; ! cs->cs_defcflag = CREAD | CS8 | HUPCL; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; *************** *** 182,188 **** cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; ! cs->cs_brg_clk = pclk / 16; /* * Clear the master interrupt enable. --- 172,180 ---- cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; ! cs->cs_brg_clk = zc->zc_pclk / 16; ! cs->cs_delay = 0; ! cs->cs_cts_is_backwards = 0; /* * Clear the master interrupt enable. *************** *** 192,209 **** */ if (channel == 0) { zs_write_reg(cs, 9, 0); ! zs_write_reg(cs, 2, vector); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ ! if (!config_found(&zsc->zsc_dev, (void *)&zsc_args, zsc_print)) { /* No sub-driver. Just reset it. */ u_char reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; ! s = splzs(); zs_write_reg(cs, 9, reset); splx(s); } --- 184,202 ---- */ if (channel == 0) { zs_write_reg(cs, 9, 0); ! zs_write_reg(cs, 2, zc->zc_vector); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ ! if (!config_found(&sc->sc_zsc.zsc_dev, ! (void *)&zsc_args, zsc_print)) { /* No sub-driver. Just reset it. */ u_char reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; ! s = splserial(); zs_write_reg(cs, 9, reset); splx(s); } *************** *** 212,221 **** /* * Allocate a software interrupt cookie. */ ! zsc->zsc_softintr_cookie = softintr_establish(IPL_SOFTSERIAL, ! (void (*)(void *)) zsc_intr_soft, zsc); #ifdef DEBUG ! assert(zsc->zsc_softintr_cookie); #endif } --- 205,214 ---- /* * Allocate a software interrupt cookie. */ ! sc->sc_softintr_cookie = softintr_establish(IPL_SOFTSERIAL, ! (void (*)(void *)) zsc_intr_soft, sc); #ifdef DEBUG ! assert(sc->sc_softintr_cookie); #endif } *************** *** 235,309 **** return UNCONF; } - #ifdef MVME162 - /* - * Our ZS chips each have their own interrupt vector. - */ - int - zshard_unshared(arg) - void *arg; - { - struct zsc_softc *zsc = arg; - int rval; - - rval = zsc_intr_hard(zsc); - - if ((zsc->zsc_cs[0]->cs_softreq) || - (zsc->zsc_cs[1]->cs_softreq)) - softintr_schedule(zsc->zsc_softintr_cookie); - - return (rval); - } - #endif - - #ifdef MVME147 /* - * Our ZS chips all share a common, PCC-vectored interrupt, - * so we have to look at all of them on each interrupt. - */ - int - zshard_shared(arg) - void *arg; - { - struct zsc_softc *zsc; - int unit, rval; - - rval = 0; - for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) { - zsc = zsc_cd.cd_devs[unit]; - if (zsc == NULL) - continue; - rval |= zsc_intr_hard(zsc); - if ((zsc->zsc_cs[0]->cs_softreq) || - (zsc->zsc_cs[1]->cs_softreq)) - softintr_schedule(zsc->zsc_softintr_cookie); - } - return (rval); - } - #endif - - - #if 0 - /* - * Compute the current baud rate given a ZSCC channel. - */ - static int - zs_get_speed(cs) - struct zs_chanstate *cs; - { - int tconst; - - tconst = zs_read_reg(cs, 12); - tconst |= zs_read_reg(cs, 13) << 8; - return (TCONST_TO_BPS(cs->cs_brg_clk, tconst)); - } - #endif - - /* * MD functions for setting the baud rate and control modes. */ ! int ! zs_set_speed(cs, bps) struct zs_chanstate *cs; int bps; /* bits per second */ { --- 228,238 ---- return UNCONF; } /* * MD functions for setting the baud rate and control modes. */ ! static int ! zsmvme_set_speed(cs, bps) struct zs_chanstate *cs; int bps; /* bits per second */ { *************** *** 335,342 **** return (0); } ! int ! zs_set_modes(cs, cflag) struct zs_chanstate *cs; int cflag; /* bits per second */ { --- 264,271 ---- return (0); } ! static int ! zsmvme_set_modes(cs, cflag) struct zs_chanstate *cs; int cflag; /* bits per second */ { *************** *** 349,355 **** * Therefore, NEVER set the HFC bit, and instead use the * status interrupt to detect CTS changes. */ ! s = splzs(); cs->cs_rr0_pps = 0; if ((cflag & (CLOCAL | MDMBUF)) != 0) { cs->cs_rr0_dcd = 0; --- 278,284 ---- * Therefore, NEVER set the HFC bit, and instead use the * status interrupt to detect CTS changes. */ ! s = splserial(); cs->cs_rr0_pps = 0; if ((cflag & (CLOCAL | MDMBUF)) != 0) { cs->cs_rr0_dcd = 0; *************** *** 376,445 **** return (0); } - /* ! * Read or write the chip with suitable delays. */ ! ! u_char ! zs_read_reg(cs, reg) struct zs_chanstate *cs; - u_char reg; { - u_char val; - - *cs->cs_reg_csr = reg; - ZS_DELAY(); - val = *cs->cs_reg_csr; - ZS_DELAY(); - return val; - } ! void ! zs_write_reg(cs, reg, val) ! struct zs_chanstate *cs; ! u_char reg, val; ! { ! *cs->cs_reg_csr = reg; ! ZS_DELAY(); ! *cs->cs_reg_csr = val; ! ZS_DELAY(); ! } ! ! u_char zs_read_csr(cs) ! struct zs_chanstate *cs; ! { ! u_char val; ! ! val = *cs->cs_reg_csr; ! ZS_DELAY(); ! return val; ! } ! ! void zs_write_csr(cs, val) ! struct zs_chanstate *cs; ! u_char val; ! { ! *cs->cs_reg_csr = val; ! ZS_DELAY(); ! } ! ! u_char zs_read_data(cs) ! struct zs_chanstate *cs; ! { ! u_char val; ! val = *cs->cs_reg_data; ! ZS_DELAY(); ! return val; ! } ! void zs_write_data(cs, val) ! struct zs_chanstate *cs; ! u_char val; ! { ! *cs->cs_reg_data = val; ! ZS_DELAY(); } /**************************************************************** --- 305,325 ---- return (0); } /* ! * Handle user request to enter kernel debugger. */ ! static void ! zsmvme_abort(cs) struct zs_chanstate *cs; { ! /* Wait for end of break to avoid PROM abort. */ ! /* XXX - Limit the wait? */ ! while ((zs_read_csr(cs) & ZSRR0_BREAK) != 0) ! /* Nothing */ ; ! mvme68k_abort("SERIAL LINE ABORT"); } /**************************************************************** *************** *** 450,479 **** * Polled input char. */ int ! zs_getc(arg) void *arg; { struct zs_chanstate *cs = arg; ! int s, c, rr0, stat; s = splhigh(); top: /* Wait for a character to arrive. */ ! do { ! rr0 = *cs->cs_reg_csr; ! ZS_DELAY(); ! } while ((rr0 & ZSRR0_RX_READY) == 0); /* Read error register. */ ! stat = zs_read_reg(cs, 1) & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE); ! if (stat) { zs_write_csr(cs, ZSM_RESET_ERR); goto top; } /* Read character. */ ! c = *cs->cs_reg_data; ! ZS_DELAY(); splx(s); return (c); --- 330,355 ---- * Polled input char. */ int ! zsmvme_getc(arg) void *arg; { struct zs_chanstate *cs = arg; ! int s, c; s = splhigh(); top: /* Wait for a character to arrive. */ ! while ((zs_read_csr(cs) & ZSRR0_RX_READY) == 0) ! /* Nothing */ ; /* Read error register. */ ! if ((zs_read_reg(cs, 1) & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) != 0) { zs_write_csr(cs, ZSM_RESET_ERR); goto top; } /* Read character. */ ! c = zs_read_data(cs); splx(s); return (c); *************** *** 483,504 **** * Polled output char. */ void ! zs_putc(arg, c) void *arg; int c; { struct zs_chanstate *cs = arg; ! int s, rr0; s = splhigh(); /* Wait for transmitter to become ready. */ ! do { ! rr0 = *cs->cs_reg_csr; ! ZS_DELAY(); ! } while ((rr0 & ZSRR0_TX_READY) == 0); ! *cs->cs_reg_data = c; ! ZS_DELAY(); splx(s); } --- 359,377 ---- * Polled output char. */ void ! zsmvme_putc(arg, c) void *arg; int c; { struct zs_chanstate *cs = arg; ! int s; s = splhigh(); /* Wait for transmitter to become ready. */ ! while ((zs_read_csr(cs) & ZSRR0_TX_READY) == 0) ! /* Nothing */ ; ! zs_write_data(cs, c); splx(s); } *************** *** 506,545 **** * Common parts of console init. */ void ! zs_cnconfig(zsc_unit, channel, zs, pclk) int zsc_unit, channel; ! struct zsdevice *zs; ! int pclk; { struct zs_chanstate *cs; - struct zschan *zc; - zc = (channel == 0) ? &zs->zs_chan_a : &zs->zs_chan_b; - /* * Pointer to channel state. Later, the console channel * state is copied into the softc, and the console channel * pointer adjusted to point to the new copy. */ ! zs_conschan = cs = &zs_conschan_store; zs_hwflags[zsc_unit][channel] = ZS_HWFLAG_CONSOLE; /* Setup temporary chanstate. */ ! cs->cs_reg_csr = zc->zc_csr; ! cs->cs_reg_data = zc->zc_data; /* Initialize the pending registers. */ ! bcopy(zs_init_reg, cs->cs_preg, 16); cs->cs_preg[5] |= (ZSWR5_DTR | ZSWR5_RTS); ! cs->cs_preg[12] = ((pclk / 32) / 9600) - 1; ! ! #if 0 ! /* XXX: Preserve BAUD rate from boot loader. */ ! /* XXX: Also, why reset the chip here? -gwr */ ! cs->cs_defspeed = zs_get_speed(cs); ! #else cs->cs_defspeed = 9600; /* XXX */ - #endif /* Clear the master interrupt enable. */ zs_write_reg(cs, 9, 0); --- 379,409 ---- * Common parts of console init. */ void ! zsmvme_cnconfig(zsc_unit, channel, zc) int zsc_unit, channel; ! struct zsmvme_config *zc; { struct zs_chanstate *cs; /* * Pointer to channel state. Later, the console channel * state is copied into the softc, and the console channel * pointer adjusted to point to the new copy. */ ! zsmvme_conschan = cs = &zs_conschan_store; zs_hwflags[zsc_unit][channel] = ZS_HWFLAG_CONSOLE; /* Setup temporary chanstate. */ ! cs->cs_bt = zc->zc_bt; ! cs->cs_csrbh = zc->zc_s[channel].zc_csrbh; ! cs->cs_databh = zc->zc_s[channel].zc_databh; ! cs->cs_delay = 0; /* Initialize the pending registers. */ ! bcopy(zsmvme_init_reg, cs->cs_preg, 16); cs->cs_preg[5] |= (ZSWR5_DTR | ZSWR5_RTS); ! cs->cs_preg[12] = ((zc->zc_pclk / 32) / 9600) - 1; cs->cs_defspeed = 9600; /* XXX */ /* Clear the master interrupt enable. */ zs_write_reg(cs, 9, 0); *************** *** 549,598 **** /* Copy "pending" to "current" and H/W. */ zs_loadchannelregs(cs); - } - - /* - * Polled console input putchar. - */ - int - zsc_pcccngetc(dev) - dev_t dev; - { - struct zs_chanstate *cs = zs_conschan; - int c; - - c = zs_getc(cs); - return (c); - } - - /* - * Polled console output putchar. - */ - void - zsc_pcccnputc(dev, c) - dev_t dev; - int c; - { - struct zs_chanstate *cs = zs_conschan; - - zs_putc(cs, c); - } - - /* - * Handle user request to enter kernel debugger. - */ - void - zs_abort(cs) - struct zs_chanstate *cs; - { - int rr0; - - /* Wait for end of break to avoid PROM abort. */ - /* XXX - Limit the wait? */ - do { - rr0 = *cs->cs_reg_csr; - ZS_DELAY(); - } while (rr0 & ZSRR0_BREAK); - - mvme68k_abort("SERIAL LINE ABORT"); } --- 413,416 ---- Index: dev/zs_pcc.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/mvme68k/dev/zs_pcc.c,v retrieving revision 1.10 diff -c -r1.10 zs_pcc.c *** dev/zs_pcc.c 2000/09/06 19:51:44 1.10 --- dev/zs_pcc.c 2000/09/16 12:43:20 *************** *** 5,11 **** * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation ! * by Gordon W. Ross and Jason R. Thorpe. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions --- 5,11 ---- * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation ! * by Gordon W. Ross, Jason R. Thorpe and Steve C. Woodford. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions *************** *** 43,48 **** --- 43,49 ---- * Plain tty/async lines use the zs_async slave. * * Modified for NetBSD/mvme68k by Jason R. Thorpe + * Modified for bus_space'd ZS driver by Steve Woodford. */ #include *************** *** 57,69 **** #include #include - #include - #include - #include - #include #include #include #include #include --- 58,70 ---- #include #include #include #include + #include + #include + #include + #include #include #include *************** *** 75,87 **** static void zsc_pcc_attach __P((struct device *, struct device *, void *)); struct cfattach zsc_pcc_ca = { ! sizeof(struct zsc_softc), zsc_pcc_match, zsc_pcc_attach }; extern struct cfdriver zsc_cd; cons_decl(zsc_pcc); /* * Is the zs chip present? --- 76,91 ---- static void zsc_pcc_attach __P((struct device *, struct device *, void *)); struct cfattach zsc_pcc_ca = { ! sizeof(struct zsmvme_softc), zsc_pcc_match, zsc_pcc_attach }; extern struct cfdriver zsc_cd; + cdev_decl(zs); /* For zsopen() */ cons_decl(zsc_pcc); + static int zsc_pcc_intr(void *); + static struct zsmvme_softc *zsc_pcc_chips[NZSMVMEC]; /* * Is the zs chip present? *************** *** 94,113 **** { struct pcc_attach_args *pa = aux; ! if (strcmp(pa->pa_name, zsc_cd.cd_name)) return (0); pa->pa_ipl = cf->pcccf_ipl; if (pa->pa_ipl == -1) ! pa->pa_ipl = ZSHARD_PRI; return (1); } /* * Attach a found zs. - * - * Match slave number to zs unit number, so that misconfiguration will - * not set up the keyboard as ttya, etc. */ static void zsc_pcc_attach(parent, self, aux) --- 98,114 ---- { struct pcc_attach_args *pa = aux; ! if (machineid != MVME_147 || strcmp(pa->pa_name, zsc_cd.cd_name)) return (0); pa->pa_ipl = cf->pcccf_ipl; if (pa->pa_ipl == -1) ! pa->pa_ipl = ZSMVME_HARD_PRI; return (1); } /* * Attach a found zs. */ static void zsc_pcc_attach(parent, self, aux) *************** *** 115,169 **** struct device *self; void *aux; { ! struct zsc_softc *zsc = (void *) self; struct pcc_attach_args *pa = aux; ! struct zsdevice zs; bus_space_handle_t bush; ! int zs_level, ir; ! static int didintr; /* Map the device's registers */ bus_space_map(pa->pa_bust, pa->pa_offset, 4, 0, &bush); ! zs_level = pa->pa_ipl; - /* XXX: This is a gross hack. I need to bus-space zs.c ... */ - zs.zs_chan_b.zc_csr = (volatile u_char *) bush; - zs.zs_chan_b.zc_data = (volatile u_char *) bush + 1; - zs.zs_chan_a.zc_csr = (volatile u_char *) bush + 2; - zs.zs_chan_a.zc_data = (volatile u_char *) bush + 3; - /* * Do common parts of SCC configuration. * Note that the vector is not actually used by the ZS chip on * MVME-147. We set up the PCC so that it provides the vector. * This is just here so the real vector is printed at config time. */ ! zs_config(zsc, &zs, PCC_VECBASE + PCCV_ZS, PCLK_147); /* * Now safe to install interrupt handlers. Note the arguments * to the interrupt handlers aren't used. Note, we only do this * once since both SCCs interrupt at the same level and vector. */ ! if (didintr == 0) { ! didintr = 1; ! pccintr_establish(PCCV_ZS, zshard_shared, zs_level, zsc); } ! ! /* Sanity check the interrupt levels. */ ! ir = pcc_reg_read(sys_pcc, PCCREG_SERIAL_INTR_CTRL); ! if (((ir & PCC_IMASK) != 0) && ! ((ir & PCC_IMASK) != zs_level)) ! panic("zs_pcc_attach: zs configured at different IPLs"); /* * Set master interrupt enable. Vector is supplied by the PCC. */ pcc_reg_write(sys_pcc, PCCREG_SERIAL_INTR_CTRL, ! zs_level | PCC_IENABLE | PCC_ZSEXTERN); ! zs_write_reg(zsc->zsc_cs[0], 2, PCC_VECBASE + PCCV_ZS); ! zs_write_reg(zsc->zsc_cs[0], 9, zs_init_reg[9]); } /**************************************************************** --- 116,203 ---- struct device *self; void *aux; { ! struct zsmvme_softc *sc = (void *) self; struct pcc_attach_args *pa = aux; ! struct zsmvme_config zc; bus_space_handle_t bush; ! static int nzs; ! ! #ifdef DIAGNOSTIC ! if (nzs == NZSMVMEC) ! panic("zsc_pcc_attach: attaching more than two zs chips!"); ! #endif /* Map the device's registers */ bus_space_map(pa->pa_bust, pa->pa_offset, 4, 0, &bush); ! /* Get handles to the CSR and DATA registers for both channels */ ! bus_space_subregion(pa->pa_bust, bush, 0, 1, &zc.zc_s[1].zc_csrbh); ! bus_space_subregion(pa->pa_bust, bush, 1, 1, &zc.zc_s[1].zc_databh); ! bus_space_subregion(pa->pa_bust, bush, 2, 1, &zc.zc_s[0].zc_csrbh); ! bus_space_subregion(pa->pa_bust, bush, 3, 1, &zc.zc_s[0].zc_databh); ! ! zc.zc_bt = pa->pa_bust; ! zc.zc_vector = PCC_VECBASE + PCCV_ZS; ! zc.zc_pclk = ZSMVME_PCLK_147; /* * Do common parts of SCC configuration. * Note that the vector is not actually used by the ZS chip on * MVME-147. We set up the PCC so that it provides the vector. * This is just here so the real vector is printed at config time. */ ! zsmvme_config(sc, &zc); /* * Now safe to install interrupt handlers. Note the arguments * to the interrupt handlers aren't used. Note, we only do this * once since both SCCs interrupt at the same level and vector. */ ! zsc_pcc_chips[nzs] = sc; ! if (nzs++ == 0) ! pccintr_establish(PCCV_ZS, zsc_pcc_intr, pa->pa_ipl, sc); ! #ifdef DIAGNOSTIC ! else { ! int ir; ! /* Sanity check the interrupt levels. */ ! ir = pcc_reg_read(sys_pcc, PCCREG_SERIAL_INTR_CTRL); ! if (((ir & PCC_IMASK) != 0) && ! ((ir & PCC_IMASK) != pa->pa_ipl)) ! panic("zs_pcc_attach: zs configured at different IPLs"); } ! #endif /* * Set master interrupt enable. Vector is supplied by the PCC. */ pcc_reg_write(sys_pcc, PCCREG_SERIAL_INTR_CTRL, ! pa->pa_ipl | PCC_IENABLE | PCC_ZSEXTERN); ! zs_write_reg(sc->sc_zsc.zsc_cs[0], 2, PCC_VECBASE + PCCV_ZS); ! zs_write_reg(sc->sc_zsc.zsc_cs[0], 9, zsmvme_init_reg[9]); ! } ! ! /* ! * Our ZS chips all share a common, PCC-vectored interrupt, ! * so we have to look at all of them on each interrupt. ! */ ! /* ARGSUSED */ ! int ! zsc_pcc_intr(arg) ! void *arg; ! { ! struct zsmvme_softc *sc; ! int unit, rval; ! ! rval = 0; ! for (unit = 0; unit < NZSMVMEC; unit++) { ! if ((sc = zsc_pcc_chips[unit]) == NULL) ! continue; ! rval |= zsc_intr_hard(&sc->sc_zsc); ! if ((sc->sc_zsc.zsc_cs[0]->cs_softreq) || ! (sc->sc_zsc.zsc_cs[1]->cs_softreq)) ! softintr_schedule(sc->sc_softintr_cookie); ! } ! return (rval); } /**************************************************************** *************** *** 177,189 **** zsc_pcccnprobe(cp) struct consdev *cp; { if (machineid != MVME_147) { cp->cn_pri = CN_DEAD; return; } /* Initialize required fields. */ ! cp->cn_dev = makedev(zs_major, 0); cp->cn_pri = CN_NORMAL; } --- 211,229 ---- zsc_pcccnprobe(cp) struct consdev *cp; { + int maj; + if (machineid != MVME_147) { cp->cn_pri = CN_DEAD; return; } + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == zsopen) + break; + /* Initialize required fields. */ ! cp->cn_dev = makedev(maj, 0); cp->cn_pri = CN_NORMAL; } *************** *** 191,208 **** zsc_pcccninit(cp) struct consdev *cp; { - bus_space_tag_t bust = MVME68K_INTIO_BUS_SPACE; bus_space_handle_t bush; ! struct zsdevice zs; ! bus_space_map(bust, MAINBUS_PCC_OFFSET + PCC_ZS0_OFF, 4, 0, &bush); ! /* XXX: This is a gross hack. I need to bus-space zs.c ... */ ! zs.zs_chan_b.zc_csr = (volatile u_char *) bush; ! zs.zs_chan_b.zc_data = (volatile u_char *) bush + 1; ! zs.zs_chan_a.zc_csr = (volatile u_char *) bush + 2; ! zs.zs_chan_a.zc_data = (volatile u_char *) bush + 3; /* Do common parts of console init. */ ! zs_cnconfig(0, 0, &zs, PCLK_147); } --- 231,275 ---- zsc_pcccninit(cp) struct consdev *cp; { bus_space_handle_t bush; ! struct zsmvme_config zc; ! bus_space_map(MVME68K_INTIO_BUS_SPACE, ! MAINBUS_PCC_OFFSET + PCC_ZS0_OFF, 4, 0, &bush); ! /* Get handles to the CSR and DATA registers for channel 0 */ ! bus_space_subregion(MVME68K_INTIO_BUS_SPACE, ! bush, 2, 1, &zc.zc_s[0].zc_csrbh); ! bus_space_subregion(MVME68K_INTIO_BUS_SPACE, ! bush, 3, 1, &zc.zc_s[0].zc_databh); ! ! zc.zc_bt = MVME68K_INTIO_BUS_SPACE; ! zc.zc_vector = 0; ! zc.zc_pclk = ZSMVME_PCLK_147; /* Do common parts of console init. */ ! zsmvme_cnconfig(0, 0, &zc); ! } ! ! /* ! * Polled console input putchar. ! */ ! int ! zsc_pcccngetc(dev) ! dev_t dev; ! { ! ! return (zsmvme_getc(zsmvme_conschan)); ! } ! ! /* ! * Polled console output putchar. ! */ ! void ! zsc_pcccnputc(dev, c) ! dev_t dev; ! int c; ! { ! ! zsmvme_putc(zsmvme_conschan, c); } Index: dev/zs_pcctwo.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/mvme68k/dev/zs_pcctwo.c,v retrieving revision 1.1 diff -c -r1.1 zs_pcctwo.c *** dev/zs_pcctwo.c 2000/09/06 19:51:44 1.1 --- dev/zs_pcctwo.c 2000/09/16 12:43:20 *************** *** 59,71 **** #include #include - #include - #include - #include - #include #include #include #include #include --- 59,71 ---- #include #include #include #include + #include + #include + #include + #include #include #include *************** *** 77,90 **** static void zsc_pcctwo_attach(struct device *, struct device *, void *); struct cfattach zsc_pcctwo_ca = { ! sizeof(struct zsc_softc), zsc_pcctwo_match, zsc_pcctwo_attach }; extern struct cfdriver zsc_cd; cons_decl(zsc_pcctwo); /* * Is the zs chip present? */ --- 77,93 ---- static void zsc_pcctwo_attach(struct device *, struct device *, void *); struct cfattach zsc_pcctwo_ca = { ! sizeof(struct zsmvme_softc), zsc_pcctwo_match, zsc_pcctwo_attach }; extern struct cfdriver zsc_cd; + cdev_decl(zs); /* For zsopen() */ cons_decl(zsc_pcctwo); + static int zsc_pcctwo_intr(void *); + /* * Is the zs chip present? */ *************** *** 96,107 **** { struct pcctwo_attach_args *pa = aux; ! if (strcmp(pa->pa_name, zsc_cd.cd_name) || machineid != MVME_162) return (0); pa->pa_ipl = cf->pcctwocf_ipl; if (pa->pa_ipl == -1) ! pa->pa_ipl = ZSHARD_PRI; return (1); } --- 99,110 ---- { struct pcctwo_attach_args *pa = aux; ! if (machineid != MVME_162 || strcmp(pa->pa_name, zsc_cd.cd_name)) return (0); pa->pa_ipl = cf->pcctwocf_ipl; if (pa->pa_ipl == -1) ! pa->pa_ipl = ZSMVME_HARD_PRI; return (1); } *************** *** 114,153 **** struct device *self; void *aux; { ! struct zsc_softc *zsc = (void *) self; struct pcctwo_attach_args *pa = aux; ! struct zsdevice zs; bus_space_handle_t bush; - int zs_level; static int vector = MCCHIPV_ZS0; /* Map the device's registers */ bus_space_map(pa->pa_bust, pa->pa_offset, 8, 0, &bush); - - zs_level = pa->pa_ipl; ! /* XXX: This is a gross hack. I need to bus-space zs.c ... */ ! zs.zs_chan_b.zc_csr = (volatile u_char *) bush + 1; ! zs.zs_chan_b.zc_data = (volatile u_char *) bush + 3; ! zs.zs_chan_a.zc_csr = (volatile u_char *) bush + 5; ! zs.zs_chan_a.zc_data = (volatile u_char *) bush + 7; /* Do common parts of SCC configuration. */ ! zs_config(zsc, &zs, vector + PCCTWO_VECBASE, PCLK_162); /* * Now safe to install interrupt handlers. */ ! pcctwointr_establish(vector++, zshard_unshared, zs_level, zsc); /* * Set master interrupt enable. */ ! zs_write_reg(zsc->zsc_cs[0], 9, zs_init_reg[9]); } /**************************************************************** ! * Console support functions (MVME PCC specific!) ****************************************************************/ /* --- 117,177 ---- struct device *self; void *aux; { ! struct zsmvme_softc *sc = (void *) self; struct pcctwo_attach_args *pa = aux; ! struct zsmvme_config zc; bus_space_handle_t bush; static int vector = MCCHIPV_ZS0; /* Map the device's registers */ bus_space_map(pa->pa_bust, pa->pa_offset, 8, 0, &bush); ! /* Get handles to the CSR and DATA registers for both channels */ ! bus_space_subregion(pa->pa_bust, bush, 1, 1, &zc.zc_s[1].zc_csrbh); ! bus_space_subregion(pa->pa_bust, bush, 3, 1, &zc.zc_s[1].zc_databh); ! bus_space_subregion(pa->pa_bust, bush, 5, 1, &zc.zc_s[0].zc_csrbh); ! bus_space_subregion(pa->pa_bust, bush, 7, 1, &zc.zc_s[0].zc_databh); ! ! zc.zc_bt = pa->pa_bust; ! zc.zc_vector = vector + PCCTWO_VECBASE; ! zc.zc_pclk = ZSMVME_PCLK_162; /* Do common parts of SCC configuration. */ ! zsmvme_config(sc, &zc); /* * Now safe to install interrupt handlers. */ ! pcctwointr_establish(vector++, zsc_pcctwo_intr, pa->pa_ipl, sc); /* * Set master interrupt enable. */ ! zs_write_reg(sc->sc_zsc.zsc_cs[0], 9, zsmvme_init_reg[9]); ! } ! ! /* ! * Our ZS chips each have their own interrupt vector, so no ! * need to scan them every time. ! */ ! static int ! zsc_pcctwo_intr(arg) ! void *arg; ! { ! struct zsmvme_softc *sc = arg; ! int rval; ! ! rval = zsc_intr_hard(&sc->sc_zsc); ! ! if ((sc->sc_zsc.zsc_cs[0]->cs_softreq) || ! (sc->sc_zsc.zsc_cs[1]->cs_softreq)) ! softintr_schedule(sc->sc_softintr_cookie); ! ! return (rval); } /**************************************************************** ! * Console support functions (MVME PCC2/MCCHIP specific!) ****************************************************************/ /* *************** *** 157,169 **** zsc_pcctwocnprobe(cp) struct consdev *cp; { if (machineid != MVME_162) { cp->cn_pri = CN_DEAD; return; } /* Initialize required fields. */ ! cp->cn_dev = makedev(zs_major, 0); cp->cn_pri = CN_NORMAL; } --- 181,199 ---- zsc_pcctwocnprobe(cp) struct consdev *cp; { + int maj; + if (machineid != MVME_162) { cp->cn_pri = CN_DEAD; return; } + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == zsopen) + break; + /* Initialize required fields. */ ! cp->cn_dev = makedev(maj, 0); cp->cn_pri = CN_NORMAL; } *************** *** 171,188 **** zsc_pcctwocninit(cp) struct consdev *cp; { - bus_space_tag_t bust = MVME68K_INTIO_BUS_SPACE; bus_space_handle_t bush; ! struct zsdevice zs; ! bus_space_map(bust, MAINBUS_PCCTWO_OFFSET + MCCHIP_ZS0_OFF, 8, 0,&bush); ! /* XXX: This is a gross hack. I need to bus-space zs.c ... */ ! zs.zs_chan_b.zc_csr = (volatile u_char *) bush + 1; ! zs.zs_chan_b.zc_data = (volatile u_char *) bush + 3; ! zs.zs_chan_a.zc_csr = (volatile u_char *) bush + 5; ! zs.zs_chan_a.zc_data = (volatile u_char *) bush + 7; /* Do common parts of console init. */ ! zs_cnconfig(0, 0, &zs, PCLK_162); } --- 201,245 ---- zsc_pcctwocninit(cp) struct consdev *cp; { bus_space_handle_t bush; ! struct zsmvme_config zc; ! bus_space_map(MVME68K_INTIO_BUS_SPACE, ! MAINBUS_PCCTWO_OFFSET + MCCHIP_ZS0_OFF, 8, 0,&bush); ! /* Get handles to the CSR and DATA registers for channel 0 */ ! bus_space_subregion(MVME68K_INTIO_BUS_SPACE, ! bush, 5, 1, &zc.zc_s[0].zc_csrbh); ! bus_space_subregion(MVME68K_INTIO_BUS_SPACE, ! bush, 7, 1, &zc.zc_s[0].zc_databh); ! ! zc.zc_bt = MVME68K_INTIO_BUS_SPACE; ! zc.zc_vector = 0; ! zc.zc_pclk = ZSMVME_PCLK_162; /* Do common parts of console init. */ ! zsmvme_cnconfig(0, 0, &zc); ! } ! ! /* ! * Polled console input putchar. ! */ ! int ! zsc_pcctwocngetc(dev) ! dev_t dev; ! { ! ! return (zsmvme_getc(zsmvme_conschan)); ! } ! ! /* ! * Polled console output putchar. ! */ ! void ! zsc_pcctwocnputc(dev, c) ! dev_t dev; ! int c; ! { ! ! zsmvme_putc(zsmvme_conschan, c); } Index: include/Makefile =================================================================== RCS file: /cvsroot/syssrc/sys/arch/mvme68k/include/Makefile,v retrieving revision 1.10 diff -c -r1.10 Makefile *** include/Makefile 2000/06/26 15:42:50 1.10 --- include/Makefile 2000/09/16 12:43:20 *************** *** 8,13 **** float.h frame.h ieee.h ieeefp.h int_types.h intr.h kcore.h limits.h \ lock.h math.h param.h pcb.h pmap.h proc.h profile.h prom.h psl.h \ pte.h ptrace.h reg.h setjmp.h signal.h stdarg.h svr4_machdep.h trap.h \ ! types.h varargs.h vmparam.h z8530var.h .include --- 8,13 ---- float.h frame.h ieee.h ieeefp.h int_types.h intr.h kcore.h limits.h \ lock.h math.h param.h pcb.h pmap.h proc.h profile.h prom.h psl.h \ pte.h ptrace.h reg.h setjmp.h signal.h stdarg.h svr4_machdep.h trap.h \ ! types.h varargs.h vmparam.h .include