1 /* $NetBSD: dz_vsbus.c,v 1.22 2002/04/30 12:33:32 ragge Exp $ */ 2 /* 3 * Copyright (c) 1998 Ludd, University of Lule}, Sweden. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed at Ludd, University of 17 * Lule}, Sweden and its contributors. 18 * 4. The name of the author 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 35 #include <sys/param.h> 36 #include <sys/proc.h> 37 #include <sys/systm.h> 38 #include <sys/ioctl.h> 39 #include <sys/tty.h> 40 #include <sys/file.h> 41 #include <sys/conf.h> 42 #include <sys/device.h> 43 #include <sys/reboot.h> 44 45 #include <dev/cons.h> 46 47 #include <machine/mtpr.h> 48 #include <machine/sid.h> 49 #include <machine/uvax.h> 50 #include <machine/vsbus.h> 51 #include <machine/cpu.h> 52 #include <machine/scb.h> 53 54 #include <arch/vax/vax/gencons.h> 55 56 #include <dev/dec/dzreg.h> 57 #include <dev/dec/dzvar.h> 58 59 #include "ioconf.h" 60 #include "dzkbd.h" 61 #include "dzms.h" 62 #include "opt_cputype.h" 63 64 #if NDZKBD > 0 || NDZMS > 0 65 #include <dev/dec/dzkbdvar.h> 66 67 #if 0 68 static struct dz_linestate dz_conslinestate = { NULL, -1, NULL, NULL, NULL }; 69 #endif 70 #endif 71 72 static int dz_vsbus_match(struct device *, struct cfdata *, void *); 73 static void dz_vsbus_attach(struct device *, struct device *, void *); 74 75 static vaddr_t dz_regs; /* Used for console */ 76 77 struct cfattach dz_vsbus_ca = { 78 sizeof(struct dz_softc), dz_vsbus_match, dz_vsbus_attach 79 }; 80 81 #define REG(name) short name; short X##name##X; 82 static volatile struct ss_dz {/* base address of DZ-controller: 0x200A0000 */ 83 REG(csr); /* 00 Csr: control/status register */ 84 REG(rbuf); /* 04 Rbuf/Lpr: receive buffer/line param reg. */ 85 REG(tcr); /* 08 Tcr: transmit console register */ 86 REG(tdr); /* 0C Msr/Tdr: modem status reg/transmit data reg */ 87 REG(lpr0); /* 10 Lpr0: */ 88 REG(lpr1); /* 14 Lpr0: */ 89 REG(lpr2); /* 18 Lpr0: */ 90 REG(lpr3); /* 1C Lpr0: */ 91 } *dz; 92 #undef REG 93 94 cons_decl(dz); 95 cdev_decl(dz); 96 97 #if NDZKBD > 0 || NDZMS > 0 98 static int 99 dz_print(void *aux, const char *name) 100 { 101 #if 0 102 #if NDZKBD > 0 || NDZMS > 0 103 struct dz_attach_args *dz_args = aux; 104 if (name == NULL) { 105 printf (" line %d", dz_args->line); 106 if (dz_args->hwflags & DZ_HWFLAG_CONSOLE) 107 printf (" (console)"); 108 } 109 return (QUIET); 110 #else 111 if (name) 112 printf ("lkc at %s", name); 113 return (UNCONF); 114 #endif 115 #endif 116 return (UNCONF); 117 } 118 #endif 119 120 static int 121 dz_vsbus_match(struct device *parent, struct cfdata *cf, void *aux) 122 { 123 struct vsbus_attach_args *va = aux; 124 struct ss_dz *dzP; 125 short i; 126 127 #if VAX53 || VAX49 || VAXANY 128 if (vax_boardtype == VAX_BTYP_53 || vax_boardtype == VAX_BTYP_49) 129 if (cf->cf_loc[0] != 0x25000000) 130 return 0; /* Ugly */ 131 #endif 132 133 dzP = (struct ss_dz *)va->va_addr; 134 i = dzP->tcr; 135 dzP->csr = DZ_CSR_MSE|DZ_CSR_TXIE; 136 dzP->tcr = 0; 137 DELAY(1000); 138 dzP->tcr = 1; 139 DELAY(100000); 140 dzP->tcr = i; 141 142 /* If the device doesn't exist, no interrupt has been generated */ 143 return 1; 144 } 145 146 static void 147 dz_vsbus_attach(struct device *parent, struct device *self, void *aux) 148 { 149 struct dz_softc *sc = (void *)self; 150 struct vsbus_attach_args *va = aux; 151 #if NDZKBD > 0 || NDZMS > 0 152 struct dzkm_attach_args daa; 153 #endif 154 int s; 155 156 /* 157 * XXX - This is evil and ugly, but... 158 * due to the nature of how bus_space_* works on VAX, this will 159 * be perfectly good until everything is converted. 160 */ 161 if (dz_regs == 0) /* This isn't console */ 162 dz_regs = vax_map_physmem(va->va_paddr, 1); 163 sc->sc_ioh = dz_regs; 164 sc->sc_dr.dr_csr = 0; 165 sc->sc_dr.dr_rbuf = 4; 166 sc->sc_dr.dr_dtr = 9; 167 sc->sc_dr.dr_break = 13; 168 sc->sc_dr.dr_tbuf = 12; 169 sc->sc_dr.dr_tcr = 8; 170 sc->sc_dr.dr_dcd = 13; 171 sc->sc_dr.dr_ring = 13; 172 173 sc->sc_type = DZ_DZV; 174 175 sc->sc_dsr = 0x0f; /* XXX check if VS has modem ctrl bits */ 176 177 scb_vecalloc(va->va_cvec, dzxint, sc, SCB_ISTACK, &sc->sc_tintrcnt); 178 scb_vecalloc(va->va_cvec - 4, dzrint, sc, SCB_ISTACK, &sc->sc_rintrcnt); 179 180 printf("\n%s: 4 lines", self->dv_xname); 181 182 dzattach(sc, NULL); 183 DELAY(10000); 184 185 #if NDZKBD > 0 186 /* Don't change speed if this is the console */ 187 if (cn_tab->cn_dev != makedev(getmajor(dzopen), 0)) 188 dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) 189 | DZ_LPR_8_BIT_CHAR; 190 daa.daa_line = 0; 191 daa.daa_flags = (cn_tab->cn_pri == CN_INTERNAL ? DZKBD_CONSOLE : 0); 192 config_found(self, &daa, dz_print); 193 #endif 194 #if NDZMS > 0 195 dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) | DZ_LPR_7_BIT_CHAR \ 196 | DZ_LPR_PARENB | DZ_LPR_OPAR | 1 /* line */; 197 daa.daa_line = 1; 198 daa.daa_flags = 0; 199 config_found(self, &daa, dz_print); 200 #endif 201 s = spltty(); 202 dzrint(sc); 203 dzxint(sc); 204 splx(s); 205 } 206 207 int 208 dzcngetc(dev_t dev) 209 { 210 int c = 0; 211 int mino = minor(dev); 212 u_short rbuf; 213 214 do { 215 while ((dz->csr & 0x80) == 0) 216 ; /* Wait for char */ 217 rbuf = dz->rbuf; 218 if (((rbuf >> 8) & 3) != mino) 219 continue; 220 c = rbuf & 0x7f; 221 } while (c == 17 || c == 19); /* ignore XON/XOFF */ 222 223 if (c == 13) 224 c = 10; 225 226 return (c); 227 } 228 229 void 230 dzcnprobe(struct consdev *cndev) 231 { 232 extern vaddr_t iospace; 233 int diagcons; 234 paddr_t ioaddr = 0x200A0000; 235 236 switch (vax_boardtype) { 237 case VAX_BTYP_410: 238 case VAX_BTYP_420: 239 case VAX_BTYP_43: 240 diagcons = (vax_confdata & 0x20 ? 3 : 0); 241 break; 242 243 case VAX_BTYP_46: 244 case VAX_BTYP_48: 245 diagcons = (vax_confdata & 0x100 ? 3 : 0); 246 break; 247 248 case VAX_BTYP_49: 249 case VAX_BTYP_53: 250 ioaddr = 0x25000000; 251 diagcons = 3; 252 break; 253 254 default: 255 cndev->cn_pri = CN_DEAD; 256 return; 257 } 258 if (diagcons) 259 cndev->cn_pri = CN_REMOTE; 260 else 261 cndev->cn_pri = CN_NORMAL; 262 cndev->cn_dev = makedev(getmajor(dzopen), diagcons); 263 (vaddr_t)dz = dz_regs = iospace; 264 ioaccess(iospace, ioaddr, 1); 265 } 266 267 void 268 dzcninit(struct consdev *cndev) 269 { 270 dz = (void*)dz_regs; 271 272 dz->csr = 0; /* Disable scanning until initting is done */ 273 dz->tcr = (1 << minor(cndev->cn_dev)); /* Turn on xmitter */ 274 dz->csr = 0x20; /* Turn scanning back on */ 275 } 276 277 278 void 279 dzcnputc(dev_t dev, int ch) 280 { 281 int timeout = 1<<15; /* don't hang the machine! */ 282 int mino = minor(dev); 283 u_short tcr; 284 285 if (mfpr(PR_MAPEN) == 0) 286 return; 287 288 tcr = dz->tcr; /* remember which lines to scan */ 289 dz->tcr = (1 << mino); 290 291 while ((dz->csr & 0x8000) == 0) /* Wait until ready */ 292 if (--timeout < 0) 293 break; 294 dz->tdr = ch; /* Put the character */ 295 timeout = 1<<15; 296 while ((dz->csr & 0x8000) == 0) /* Wait until ready */ 297 if (--timeout < 0) 298 break; 299 300 dz->tcr = tcr; 301 } 302 303 void 304 dzcnpollc(dev_t dev, int pollflag) 305 { 306 static u_char mask; 307 308 if (pollflag) 309 mask = vsbus_setmask(0); 310 else 311 vsbus_setmask(mask); 312 } 313 314 #if NDZKBD > 0 || NDZMS > 0 315 int 316 dzgetc(struct dz_linestate *ls) 317 { 318 int line = ls->dz_line; 319 u_short rbuf; 320 321 for (;;) { 322 for(; (dz->csr & DZ_CSR_RX_DONE) == 0;); 323 rbuf = dz->rbuf; 324 if (((rbuf >> 8) & 3) == line) 325 return (rbuf & 0xff); 326 } 327 } 328 329 void 330 dzputc(struct dz_linestate *ls, int ch) 331 { 332 int line = 0; /* = ls->dz_line; */ 333 u_short tcr; 334 int s; 335 336 /* if the dz has already been attached, the MI 337 driver will do the transmitting: */ 338 if (ls && ls->dz_sc) { 339 s = spltty(); 340 putc(ch, &ls->dz_sc->sc_dz[line].dz_tty->t_outq); 341 tcr = dz->tcr; 342 if (!(tcr & (1 << line))) 343 dz->tcr = tcr | (1 << line); 344 dzxint(ls->dz_sc); 345 splx(s); 346 return; 347 } 348 349 /* use dzcnputc to do the transmitting: */ 350 dzcnputc(makedev(getmajor(dzopen), line), ch); 351 } 352 #endif /* NDZKBD > 0 || NDZMS > 0 */ 353