1 /* $Id: at91dbgu.c,v 1.9 2012/11/12 18:00:36 skrll Exp $ */ 2 /* $NetBSD: at91dbgu.c,v 1.9 2012/11/12 18:00:36 skrll Exp $ */ 3 4 /* 5 * 6 * Copyright (c) 1998, 1999, 2001, 2002, 2004 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by Jesse Off 11 * 12 * This code is derived from software contributed to The NetBSD Foundation 13 * by Ichiro FUKUHARA and Naoto Shimazaki. 14 * 15 * This code is derived from software contributed to The NetBSD Foundation 16 * by IWAMOTO Toshihiro. 17 * 18 * This code is derived from software contributed to The NetBSD Foundation 19 * by Charles M. Hannum. 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 3. All advertising materials mentioning features or use of this software 30 * must display the following acknowledgement: 31 * This product includes software developed by the NetBSD 32 * Foundation, Inc. and its contributors. 33 * 4. Neither the name of The NetBSD Foundation nor the names of its 34 * contributors may be used to endorse or promote products derived 35 * from this software without specific prior written permission. 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 38 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 39 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 41 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 * POSSIBILITY OF SUCH DAMAGE. 48 */ 49 50 /* 51 * Copyright (c) 1991 The Regents of the University of California. 52 * All rights reserved. 53 * 54 * Redistribution and use in source and binary forms, with or without 55 * modification, are permitted provided that the following conditions 56 * are met: 57 * 1. Redistributions of source code must retain the above copyright 58 * notice, this list of conditions and the following disclaimer. 59 * 2. Redistributions in binary form must reproduce the above copyright 60 * notice, this list of conditions and the following disclaimer in the 61 * documentation and/or other materials provided with the distribution. 62 * 3. Neither the name of the University nor the names of its contributors 63 * may be used to endorse or promote products derived from this software 64 * without specific prior written permission. 65 * 66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 76 * SUCH DAMAGE. 77 * 78 * @(#)com.c 7.5 (Berkeley) 5/16/91 79 */ 80 81 /* 82 * TODO: hardware flow control 83 */ 84 85 #include <sys/cdefs.h> 86 __KERNEL_RCSID(0, "$NetBSD: at91dbgu.c,v 1.9 2012/11/12 18:00:36 skrll Exp $"); 87 88 #include "opt_ddb.h" 89 #include "opt_kgdb.h" 90 91 #include "rnd.h" 92 #ifdef RND_COM 93 #include <sys/rnd.h> 94 #endif 95 96 /* 97 * Override cnmagic(9) macro before including <sys/systm.h>. 98 * We need to know if cn_check_magic triggered debugger, so set a flag. 99 * Callers of cn_check_magic must declare int cn_trapped = 0; 100 * XXX: this is *ugly*! 101 */ 102 #define cn_trap() \ 103 do { \ 104 console_debugger(); \ 105 cn_trapped = 1; \ 106 } while (/* CONSTCOND */ 0) 107 108 109 #include <sys/param.h> 110 #include <sys/systm.h> 111 #include <sys/types.h> 112 #include <sys/conf.h> 113 #include <sys/file.h> 114 #include <sys/device.h> 115 #include <sys/kernel.h> 116 #include <sys/malloc.h> 117 #include <sys/tty.h> 118 #include <sys/uio.h> 119 #include <sys/vnode.h> 120 #include <sys/kauth.h> 121 122 #include <machine/intr.h> 123 #include <sys/bus.h> 124 125 #include <arm/at91/at91reg.h> 126 #include <arm/at91/at91var.h> 127 #include <arm/at91/at91dbguvar.h> 128 #include <arm/at91/at91dbgureg.h> 129 130 #include <dev/cons.h> 131 132 static int at91dbgu_match(device_t, cfdata_t, void *); 133 static void at91dbgu_attach(device_t, device_t, void *); 134 135 static int at91dbgu_param(struct tty *, struct termios *); 136 static void at91dbgu_start(struct tty *); 137 static int at91dbgu_hwiflow(struct tty *, int); 138 139 #if 0 140 static u_int cflag2lcrhi(tcflag_t); 141 #endif 142 static void at91dbgu_iflush(struct at91dbgu_softc *); 143 static void at91dbgu_set(struct at91dbgu_softc *); 144 145 int at91dbgu_cn_getc(dev_t); 146 void at91dbgu_cn_putc(dev_t, int); 147 void at91dbgu_cn_pollc(dev_t, int); 148 149 static void at91dbgu_soft(void* arg); 150 inline static void at91dbgu_txsoft(struct at91dbgu_softc *, struct tty *); 151 inline static void at91dbgu_rxsoft(struct at91dbgu_softc *, struct tty *); 152 153 void at91dbgu_cn_probe(struct consdev *); 154 void at91dbgu_cn_init(struct consdev *); 155 156 static struct at91dbgu_cons_softc { 157 bus_space_tag_t sc_iot; 158 bus_space_handle_t sc_ioh; 159 bus_addr_t sc_hwbase; 160 int sc_ospeed; 161 tcflag_t sc_cflag; 162 int sc_attached; 163 164 uint8_t *sc_rx_ptr; 165 uint8_t sc_rx_fifo[64]; 166 } dbgu_cn_sc; 167 168 static struct cnm_state at91dbgu_cnm_state; 169 170 CFATTACH_DECL_NEW(at91dbgu, sizeof(struct at91dbgu_softc), 171 at91dbgu_match, at91dbgu_attach, NULL, NULL); 172 173 extern struct cfdriver at91dbgu_cd; 174 175 dev_type_open(at91dbgu_open); 176 dev_type_close(at91dbgu_close); 177 dev_type_read(at91dbgu_read); 178 dev_type_write(at91dbgu_write); 179 dev_type_ioctl(at91dbgu_ioctl); 180 dev_type_stop(at91dbgu_stop); 181 dev_type_tty(at91dbgu_tty); 182 dev_type_poll(at91dbgu_poll); 183 184 const struct cdevsw at91dbgu_cdevsw = { 185 at91dbgu_open, at91dbgu_close, at91dbgu_read, at91dbgu_write, at91dbgu_ioctl, 186 at91dbgu_stop, at91dbgu_tty, at91dbgu_poll, nommap, ttykqfilter, D_TTY 187 }; 188 189 struct consdev at91dbgu_cons = { 190 at91dbgu_cn_probe, NULL, at91dbgu_cn_getc, at91dbgu_cn_putc, at91dbgu_cn_pollc, NULL, 191 NULL, NULL, NODEV, CN_REMOTE 192 }; 193 194 #ifndef DEFAULT_COMSPEED 195 #define DEFAULT_COMSPEED 115200 196 #endif 197 198 #define COMUNIT_MASK 0x7ffff 199 #define COMDIALOUT_MASK 0x80000 200 201 #define COMUNIT(x) (minor(x) & COMUNIT_MASK) 202 #define COMDIALOUT(x) (minor(x) & COMDIALOUT_MASK) 203 204 #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) 205 206 static int 207 at91dbgu_match(device_t parent, cfdata_t match, void *aux) 208 { 209 if (strcmp(match->cf_name, "at91dbgu") == 0) 210 return 2; 211 return 0; 212 } 213 214 static int 215 dbgu_intr(void* arg); 216 217 static void 218 at91dbgu_attach(device_t parent, device_t self, void *aux) 219 { 220 struct at91dbgu_softc *sc = device_private(self); 221 struct at91bus_attach_args *sa = aux; 222 struct tty *tp; 223 224 printf("\n"); 225 226 sc->sc_dev = self; 227 bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh); 228 sc->sc_iot = sa->sa_iot; 229 sc->sc_hwbase = sa->sa_addr; 230 231 DBGUREG(DBGU_IDR) = -1; 232 at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc); 233 DBGU_INIT(AT91_MSTCLK, 115200U); 234 235 if (sc->sc_iot == dbgu_cn_sc.sc_iot 236 && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) { 237 dbgu_cn_sc.sc_attached = 1; 238 /* Make sure the console is always "hardwired". */ 239 delay(10000); /* wait for output to finish */ 240 SET(sc->sc_hwflags, COM_HW_CONSOLE); 241 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 242 SET(sc->sc_ier, DBGU_INT_RXRDY); 243 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@ 244 } 245 246 tp = tty_alloc(); 247 tp->t_oproc = at91dbgu_start; 248 tp->t_param = at91dbgu_param; 249 tp->t_hwiflow = at91dbgu_hwiflow; 250 251 sc->sc_tty = tp; 252 sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); 253 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 254 sc->sc_rbavail = AT91DBGU_RING_SIZE; 255 if (sc->sc_rbuf == NULL) { 256 printf("%s: unable to allocate ring buffer\n", 257 device_xname(sc->sc_dev)); 258 return; 259 } 260 sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1); 261 sc->sc_tbc = 0; 262 263 tty_attach(tp); 264 265 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 266 int maj; 267 268 /* locate the major number */ 269 maj = cdevsw_lookup_major(&at91dbgu_cdevsw); 270 271 cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); 272 273 aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n", 274 device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), 275 cn_tab->cn_dev); 276 } 277 278 sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc); 279 280 #ifdef RND_COM 281 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 282 RND_TYPE_TTY, 0); 283 #endif 284 285 /* if there are no enable/disable functions, assume the device 286 is always enabled */ 287 if (!sc->enable) 288 sc->enabled = 1; 289 290 /* XXX configure register */ 291 /* xxx_config(sc) */ 292 293 SET(sc->sc_hwflags, COM_HW_DEV_OK); 294 } 295 296 static int 297 at91dbgu_param(struct tty *tp, struct termios *t) 298 { 299 struct at91dbgu_softc *sc 300 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 301 int s; 302 303 if (COM_ISALIVE(sc) == 0) 304 return (EIO); 305 306 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 307 return (EINVAL); 308 309 /* 310 * For the console, always force CLOCAL and !HUPCL, so that the port 311 * is always active. 312 */ 313 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 314 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 315 SET(t->c_cflag, CLOCAL); 316 CLR(t->c_cflag, HUPCL); 317 } 318 319 /* 320 * If there were no changes, don't do anything. This avoids dropping 321 * input and improves performance when all we did was frob things like 322 * VMIN and VTIME. 323 */ 324 if (tp->t_ospeed == t->c_ospeed && 325 tp->t_cflag == t->c_cflag) 326 return (0); 327 328 s = splserial(); 329 330 sc->sc_brgr = (AT91_MSTCLK / 16 + t->c_ospeed / 2) / t->c_ospeed; 331 332 /* And copy to tty. */ 333 tp->t_ispeed = 0; 334 tp->t_ospeed = t->c_ospeed; 335 tp->t_cflag = t->c_cflag; 336 at91dbgu_set(sc); 337 338 splx(s); 339 340 /* 341 * Update the tty layer's idea of the carrier bit. 342 * We tell tty the carrier is always on. 343 */ 344 (void) (*tp->t_linesw->l_modem)(tp, 1); 345 346 #ifdef COM_DEBUG 347 if (com_debug) 348 comstatus(sc, "comparam "); 349 #endif 350 351 if (!ISSET(t->c_cflag, CHWFLOW)) { 352 if (sc->sc_tx_stopped) { 353 sc->sc_tx_stopped = 0; 354 at91dbgu_start(tp); 355 } 356 } 357 358 return (0); 359 } 360 361 static int 362 at91dbgu_hwiflow(struct tty *tp, int block) 363 { 364 return (0); 365 } 366 367 static void 368 at91dbgu_filltx(struct at91dbgu_softc *sc) 369 { 370 #if 0 371 bus_space_tag_t iot = sc->sc_iot; 372 bus_space_handle_t ioh = sc->sc_ioh; 373 #endif 374 int n; 375 376 n = 0; 377 while (DBGUREG(DBGU_SR) & DBGU_SR_TXRDY) { 378 if (n >= sc->sc_tbc) 379 break; 380 DBGUREG(DBGU_THR) = *(sc->sc_tba + n) & 0xff; 381 n++; 382 } 383 sc->sc_tbc -= n; 384 sc->sc_tba += n; 385 } 386 387 static void 388 at91dbgu_start(struct tty *tp) 389 { 390 struct at91dbgu_softc *sc 391 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 392 int s; 393 394 if (COM_ISALIVE(sc) == 0) 395 return; 396 397 s = spltty(); 398 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 399 goto out; 400 if (sc->sc_tx_stopped) 401 goto out; 402 if (!ttypull(tp)) 403 goto out; 404 405 /* Grab the first contiguous region of buffer space. */ 406 { 407 u_char *tba; 408 int tbc; 409 410 tba = tp->t_outq.c_cf; 411 tbc = ndqb(&tp->t_outq, 0); 412 413 (void)splserial(); 414 415 sc->sc_tba = tba; 416 sc->sc_tbc = tbc; 417 } 418 419 SET(tp->t_state, TS_BUSY); 420 sc->sc_tx_busy = 1; 421 422 /* Output the first chunk of the contiguous buffer. */ 423 at91dbgu_filltx(sc); 424 425 SET(sc->sc_ier, DBGU_INT_TXRDY); 426 DBGUREG(DBGU_IER) = DBGU_INT_TXRDY; 427 428 out: 429 splx(s); 430 return; 431 } 432 433 static void 434 at91dbgu_break(struct at91dbgu_softc *sc, int onoff) 435 { 436 // @@@ we must disconnect the TX pin from the DBGU and control 437 // @@@ the pin directly to support this... 438 } 439 440 static void 441 at91dbgu_shutdown(struct at91dbgu_softc *sc) 442 { 443 int s; 444 445 s = splserial(); 446 447 /* Turn off interrupts. */ 448 DBGUREG(DBGU_IDR) = -1; 449 450 /* Clear any break condition set with TIOCSBRK. */ 451 at91dbgu_break(sc, 0); 452 at91dbgu_set(sc); 453 454 if (sc->disable) { 455 #ifdef DIAGNOSTIC 456 if (!sc->enabled) 457 panic("at91dbgu_shutdown: not enabled?"); 458 #endif 459 (*sc->disable)(sc); 460 sc->enabled = 0; 461 } 462 splx(s); 463 } 464 465 int 466 at91dbgu_open(dev_t dev, int flag, int mode, struct lwp *l) 467 { 468 struct at91dbgu_softc *sc; 469 struct tty *tp; 470 int s, s2; 471 int error; 472 473 sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 474 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) || 475 sc->sc_rbuf == NULL) 476 return (ENXIO); 477 478 if (!device_is_active(sc->sc_dev)) 479 return (ENXIO); 480 481 #ifdef KGDB 482 /* 483 * If this is the kgdb port, no other use is permitted. 484 */ 485 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) 486 return (EBUSY); 487 #endif 488 489 tp = sc->sc_tty; 490 491 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 492 return (EBUSY); 493 494 s = spltty(); 495 496 /* 497 * Do the following iff this is a first open. 498 */ 499 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 500 struct termios t; 501 502 tp->t_dev = dev; 503 504 s2 = splserial(); 505 506 if (sc->enable) { 507 if ((*sc->enable)(sc)) { 508 splx(s2); 509 splx(s); 510 printf("%s: device enable failed\n", 511 device_xname(sc->sc_dev)); 512 return (EIO); 513 } 514 sc->enabled = 1; 515 #if 0 516 /* XXXXXXXXXXXXXXX */ 517 com_config(sc); 518 #endif 519 } 520 521 /* Turn on interrupts. */ 522 sc->sc_ier |= DBGU_INT_RXRDY; 523 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 524 525 #if 0 526 /* Fetch the current modem control status, needed later. */ 527 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); 528 529 /* Clear PPS capture state on first open. */ 530 sc->sc_ppsmask = 0; 531 sc->ppsparam.mode = 0; 532 #endif 533 534 splx(s2); 535 536 /* 537 * Initialize the termios status to the defaults. Add in the 538 * sticky bits from TIOCSFLAGS. 539 */ 540 t.c_ispeed = 0; 541 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 542 t.c_ospeed = dbgu_cn_sc.sc_ospeed; 543 t.c_cflag = dbgu_cn_sc.sc_cflag; 544 } else { 545 t.c_ospeed = TTYDEF_SPEED; 546 t.c_cflag = TTYDEF_CFLAG; 547 } 548 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 549 SET(t.c_cflag, CLOCAL); 550 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 551 SET(t.c_cflag, CRTSCTS); 552 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 553 SET(t.c_cflag, MDMBUF); 554 /* Make sure at91dbgu_param() will do something. */ 555 tp->t_ospeed = 0; 556 (void) at91dbgu_param(tp, &t); 557 tp->t_iflag = TTYDEF_IFLAG; 558 tp->t_oflag = TTYDEF_OFLAG; 559 tp->t_lflag = TTYDEF_LFLAG; 560 ttychars(tp); 561 ttsetwater(tp); 562 563 s2 = splserial(); 564 565 /* Clear the input ring, and unblock. */ 566 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 567 sc->sc_rbavail = AT91DBGU_RING_SIZE; 568 at91dbgu_iflush(sc); 569 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 570 571 #ifdef COM_DEBUG 572 if (at91dbgu_debug) 573 comstatus(sc, "at91dbgu_open "); 574 #endif 575 576 splx(s2); 577 } 578 579 splx(s); 580 581 error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 582 if (error) 583 goto bad; 584 585 error = (*tp->t_linesw->l_open)(dev, tp); 586 if (error) 587 goto bad; 588 589 return (0); 590 591 bad: 592 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 593 /* 594 * We failed to open the device, and nobody else had it opened. 595 * Clean up the state as appropriate. 596 */ 597 at91dbgu_shutdown(sc); 598 } 599 600 return (error); 601 } 602 603 int 604 at91dbgu_close(dev_t dev, int flag, int mode, struct lwp *l) 605 { 606 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 607 struct tty *tp = sc->sc_tty; 608 609 /* XXX This is for cons.c. */ 610 if (!ISSET(tp->t_state, TS_ISOPEN)) 611 return (0); 612 613 (*tp->t_linesw->l_close)(tp, flag); 614 ttyclose(tp); 615 616 if (COM_ISALIVE(sc) == 0) 617 return (0); 618 619 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 620 /* 621 * Although we got a last close, the device may still be in 622 * use; e.g. if this was the dialout node, and there are still 623 * processes waiting for carrier on the non-dialout node. 624 */ 625 at91dbgu_shutdown(sc); 626 } 627 628 return (0); 629 } 630 631 int 632 at91dbgu_read(dev_t dev, struct uio *uio, int flag) 633 { 634 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 635 struct tty *tp = sc->sc_tty; 636 637 if (COM_ISALIVE(sc) == 0) 638 return (EIO); 639 640 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 641 } 642 643 int 644 at91dbgu_write(dev_t dev, struct uio *uio, int flag) 645 { 646 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 647 struct tty *tp = sc->sc_tty; 648 649 if (COM_ISALIVE(sc) == 0) 650 return (EIO); 651 652 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 653 } 654 655 int 656 at91dbgu_poll(dev_t dev, int events, struct lwp *l) 657 { 658 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 659 struct tty *tp = sc->sc_tty; 660 661 if (COM_ISALIVE(sc) == 0) 662 return (EIO); 663 664 return ((*tp->t_linesw->l_poll)(tp, events, l)); 665 } 666 667 struct tty * 668 at91dbgu_tty(dev_t dev) 669 { 670 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 671 struct tty *tp = sc->sc_tty; 672 673 return (tp); 674 } 675 676 int 677 at91dbgu_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 678 { 679 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 680 struct tty *tp = sc->sc_tty; 681 int error; 682 int s; 683 684 if (COM_ISALIVE(sc) == 0) 685 return (EIO); 686 687 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 688 if (error != EPASSTHROUGH) 689 return (error); 690 691 error = ttioctl(tp, cmd, data, flag, l); 692 if (error != EPASSTHROUGH) 693 return (error); 694 695 error = 0; 696 697 s = splserial(); 698 699 switch (cmd) { 700 case TIOCSBRK: 701 at91dbgu_break(sc, 1); 702 break; 703 704 case TIOCCBRK: 705 at91dbgu_break(sc, 0); 706 break; 707 708 case TIOCGFLAGS: 709 *(int *)data = sc->sc_swflags; 710 break; 711 712 case TIOCSFLAGS: 713 error = kauth_authorize_device_tty(l->l_cred, 714 KAUTH_DEVICE_TTY_PRIVSET, tp); 715 if (error) 716 break; 717 sc->sc_swflags = *(int *)data; 718 break; 719 720 default: 721 error = EPASSTHROUGH; 722 break; 723 } 724 725 splx(s); 726 727 return (error); 728 } 729 730 /* 731 * Stop output on a line. 732 */ 733 void 734 at91dbgu_stop(struct tty *tp, int flag) 735 { 736 struct at91dbgu_softc *sc 737 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 738 int s; 739 740 s = splserial(); 741 if (ISSET(tp->t_state, TS_BUSY)) { 742 /* Stop transmitting at the next chunk. */ 743 sc->sc_tbc = 0; 744 if (!ISSET(tp->t_state, TS_TTSTOP)) 745 SET(tp->t_state, TS_FLUSH); 746 } 747 splx(s); 748 } 749 750 #if 0 751 static u_int 752 cflag2lcrhi(tcflag_t cflag) 753 { 754 uint32_t mr; 755 756 switch (cflag & CSIZE) { 757 default: 758 mr = 0x0; 759 break; 760 } 761 #if 0 762 mr |= (cflag & PARENB) ? LinCtrlHigh_PEN : 0; 763 mr |= (cflag & PARODD) ? 0 : LinCtrlHigh_EPS; 764 mr |= (cflag & CSTOPB) ? LinCtrlHigh_STP2 : 0; 765 mr |= LinCtrlHigh_FEN; /* FIFO always enabled */ 766 #endif 767 mr |= DBGU_MR_PAR_NONE; 768 return (mr); 769 } 770 #endif 771 772 static void 773 at91dbgu_iflush(struct at91dbgu_softc *sc) 774 { 775 #if 0 776 bus_space_tag_t iot = sc->sc_iot; 777 bus_space_handle_t ioh = sc->sc_ioh; 778 #endif 779 #ifdef DIAGNOSTIC 780 int reg; 781 #endif 782 int timo; 783 784 #ifdef DIAGNOSTIC 785 reg = 0xffff; 786 #endif 787 timo = 50000; 788 /* flush any pending I/O */ 789 while (DBGUREG(DBGU_SR) & DBGU_SR_RXRDY 790 && --timo) 791 #ifdef DIAGNOSTIC 792 reg = 793 #else 794 (void) 795 #endif 796 DBGUREG(DBGU_RHR); 797 #ifdef DIAGNOSTIC 798 if (!timo) 799 printf("%s: com_iflush timeout %02x\n", device_xname(sc->sc_dev), 800 reg); 801 #endif 802 } 803 804 static void 805 at91dbgu_set(struct at91dbgu_softc *sc) 806 { 807 DBGUREG(DBGU_MR) = DBGU_MR_PAR_NONE; 808 DBGUREG(DBGU_BRGR) = sc->sc_brgr; 809 DBGUREG(DBGU_CR) = DBGU_CR_TXEN | DBGU_CR_RXEN; // @@@ just in case 810 } 811 812 void 813 at91dbgu_cn_attach(bus_space_tag_t iot, bus_addr_t iobase, bus_space_handle_t ioh, 814 int ospeed, tcflag_t cflag); 815 void 816 at91dbgu_cn_attach(bus_space_tag_t iot, bus_addr_t iobase, bus_space_handle_t ioh, 817 int ospeed, tcflag_t cflag) 818 { 819 cn_tab = &at91dbgu_cons; 820 cn_init_magic(&at91dbgu_cnm_state); 821 cn_set_magic("\047\001"); 822 823 dbgu_cn_sc.sc_iot = iot; 824 dbgu_cn_sc.sc_ioh = ioh; 825 dbgu_cn_sc.sc_hwbase = iobase; 826 dbgu_cn_sc.sc_ospeed = ospeed; 827 dbgu_cn_sc.sc_cflag = cflag; 828 829 DBGU_INIT(AT91_MSTCLK, ospeed); 830 } 831 832 void at91dbgu_attach_cn(bus_space_tag_t iot, int ospeed, int cflag) 833 { 834 bus_space_handle_t ioh; 835 bus_space_map(iot, AT91DBGU_BASE, AT91DBGU_SIZE, 0, &ioh); 836 at91dbgu_cn_attach(iot, AT91DBGU_BASE, ioh, ospeed, cflag); 837 } 838 839 void 840 at91dbgu_cn_probe(struct consdev *cp) 841 { 842 cp->cn_pri = CN_REMOTE; 843 } 844 845 void 846 at91dbgu_cn_pollc(dev_t dev, int on) 847 { 848 if (on) { 849 // enable polling mode 850 DBGUREG(DBGU_IDR) = DBGU_INT_RXRDY; 851 } else { 852 // disable polling mode 853 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 854 } 855 } 856 857 void 858 at91dbgu_cn_putc(dev_t dev, int c) 859 { 860 #if 0 861 bus_space_tag_t iot = dbgu_cn_sc.sc_iot; 862 bus_space_handle_t ioh = dbgu_cn_sc.sc_ioh; 863 #endif 864 DBGU_PUTC(c); 865 866 #ifdef DEBUG 867 if (c == '\r') { 868 int s = splserial(); 869 while((DBGUREG(DBGU_SR) & DBGU_SR_TXEMPTY) == 0) { 870 splx(s); 871 s = splserial(); 872 } 873 splx(s); 874 } 875 #endif 876 877 } 878 879 int 880 at91dbgu_cn_getc(dev_t dev) 881 { 882 int c, sr; 883 int s; 884 #if 0 885 bus_space_tag_t iot = dbgu_cn_sc.sc_iot; 886 bus_space_handle_t ioh = dbgu_cn_sc.sc_ioh; 887 #endif 888 889 s = splserial(); 890 891 while ((c = DBGU_PEEKC()) == -1) { 892 splx(s); 893 s = splserial(); 894 } 895 ; 896 sr = DBGUREG(DBGU_SR); 897 if (ISSET(sr, DBGU_SR_FRAME) && c == 0) { 898 DBGUREG(DBGU_CR) = DBGU_CR_RSTSTA; // reset status bits 899 c = CNC_BREAK; 900 } 901 #ifdef DDB 902 extern int db_active; 903 if (!db_active) 904 #endif 905 { 906 int cn_trapped = 0; /* unused */ 907 908 cn_check_magic(dev, c, at91dbgu_cnm_state); 909 } 910 splx(s); 911 912 c &= 0xff; 913 914 return (c); 915 } 916 917 inline static void 918 at91dbgu_txsoft(struct at91dbgu_softc *sc, struct tty *tp) 919 { 920 CLR(tp->t_state, TS_BUSY); 921 if (ISSET(tp->t_state, TS_FLUSH)) 922 CLR(tp->t_state, TS_FLUSH); 923 else 924 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 925 (*tp->t_linesw->l_start)(tp); 926 } 927 928 inline static void 929 at91dbgu_rxsoft(struct at91dbgu_softc *sc, struct tty *tp) 930 { 931 int (*rint)(int, struct tty *) = tp->t_linesw->l_rint; 932 u_char *get, *end; 933 u_int cc, scc; 934 u_char sts; 935 int code; 936 int s; 937 938 end = sc->sc_ebuf; 939 get = sc->sc_rbget; 940 scc = cc = AT91DBGU_RING_SIZE - sc->sc_rbavail; 941 #if 0 942 if (cc == AT91DBGU_RING_SIZE) { 943 sc->sc_floods++; 944 if (sc->sc_errors++ == 0) 945 callout_reset(&sc->sc_diag_callout, 60 * hz, 946 comdiag, sc); 947 } 948 #endif 949 while (cc) { 950 code = get[0]; 951 sts = get[1]; 952 if (ISSET(sts, DBGU_SR_PARE | DBGU_SR_FRAME | DBGU_SR_OVRE)) { 953 #if 0 954 if (ISSET(lsr, DR_ROR)) { 955 sc->sc_overflows++; 956 if (sc->sc_errors++ == 0) 957 callout_reset(&sc->sc_diag_callout, 958 60 * hz, comdiag, sc); 959 } 960 #endif 961 if (ISSET(sts, (DBGU_SR_FRAME | DBGU_SR_OVRE))) 962 SET(code, TTY_FE); 963 if (ISSET(sts, DBGU_SR_PARE)) 964 SET(code, TTY_PE); 965 } 966 if ((*rint)(code, tp) == -1) { 967 /* 968 * The line discipline's buffer is out of space. 969 */ 970 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 971 /* 972 * We're either not using flow control, or the 973 * line discipline didn't tell us to block for 974 * some reason. Either way, we have no way to 975 * know when there's more space available, so 976 * just drop the rest of the data. 977 */ 978 get += cc << 1; 979 if (get >= end) 980 get -= AT91DBGU_RING_SIZE << 1; 981 cc = 0; 982 } else { 983 /* 984 * Don't schedule any more receive processing 985 * until the line discipline tells us there's 986 * space available (through comhwiflow()). 987 * Leave the rest of the data in the input 988 * buffer. 989 */ 990 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 991 } 992 break; 993 } 994 get += 2; 995 if (get >= end) 996 get = sc->sc_rbuf; 997 cc--; 998 } 999 1000 if (cc != scc) { 1001 sc->sc_rbget = get; 1002 s = splserial(); 1003 1004 cc = sc->sc_rbavail += scc - cc; 1005 /* Buffers should be ok again, release possible block. */ 1006 if (cc >= 1) { 1007 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1008 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1009 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 1010 } 1011 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1012 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1013 #if 0 1014 com_hwiflow(sc); 1015 #endif 1016 } 1017 } 1018 splx(s); 1019 } 1020 } 1021 1022 static void 1023 at91dbgu_soft(void* arg) 1024 { 1025 struct at91dbgu_softc *sc = arg; 1026 1027 if (COM_ISALIVE(sc) == 0) 1028 return; 1029 1030 if (sc->sc_rx_ready) { 1031 sc->sc_rx_ready = 0; 1032 at91dbgu_rxsoft(sc, sc->sc_tty); 1033 } 1034 if (sc->sc_tx_done) { 1035 sc->sc_tx_done = 0; 1036 at91dbgu_txsoft(sc, sc->sc_tty); 1037 } 1038 } 1039 1040 1041 static int 1042 dbgu_intr(void* arg) 1043 { 1044 struct at91dbgu_softc *sc = arg; 1045 #if 0 1046 bus_space_tag_t iot = sc->sc_iot; 1047 bus_space_handle_t ioh = sc->sc_ioh; 1048 #endif 1049 u_char *put, *end; 1050 u_int cc; 1051 uint32_t imr, sr; 1052 int c = 0; 1053 imr = DBGUREG(DBGU_IMR); 1054 #if 0 1055 if (!imr) 1056 return 0; 1057 #endif 1058 sr = DBGUREG(DBGU_SR); 1059 if (!(sr & imr)) { 1060 if (sr & DBGU_SR_RXRDY) { 1061 // printf("sr=0x%08x imr=0x%08x\n", sr, imr); 1062 } 1063 return 0; 1064 } 1065 1066 end = sc->sc_ebuf; 1067 put = sc->sc_rbput; 1068 cc = sc->sc_rbavail; 1069 1070 // ok, we DO have some interrupts to serve! 1071 if (sr & DBGU_SR_RXRDY) { 1072 int cn_trapped = 0; 1073 1074 c = DBGUREG(DBGU_RHR); 1075 if (ISSET(sr, (DBGU_SR_OVRE | DBGU_SR_FRAME | DBGU_SR_PARE))) 1076 DBGUREG(DBGU_CR) = DBGU_CR_RSTSTA; 1077 if (ISSET(sr, DBGU_SR_FRAME) && c == 0) { 1078 c = CNC_BREAK; 1079 } 1080 #ifdef DDB 1081 extern int db_active; 1082 if (!db_active) 1083 #endif 1084 cn_check_magic(cn_tab->cn_dev, c, at91dbgu_cnm_state); 1085 if (!cn_trapped && cc) { 1086 put[0] = c & 0xff; 1087 put[1] = sr & 0xff; 1088 put += 2; 1089 if (put >= end) 1090 put = sc->sc_rbuf; 1091 cc--; 1092 /* 1093 * Current string of incoming characters ended because 1094 * no more data was available or we ran out of space. 1095 * Schedule a receive event if any data was received. 1096 * If we're out of space, turn off receive interrupts. 1097 */ 1098 sc->sc_rbput = put; 1099 sc->sc_rbavail = cc; 1100 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1101 sc->sc_rx_ready = 1; 1102 1103 /* 1104 * See if we are in danger of overflowing a buffer. If 1105 * so, use hardware flow control to ease the pressure. 1106 */ 1107 1108 /* but at91dbgu cannot (yet). X-( */ 1109 1110 /* 1111 * If we're out of space, disable receive interrupts 1112 * until the queue has drained a bit. 1113 */ 1114 if (!cc) { 1115 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1116 } 1117 } 1118 } 1119 1120 /* 1121 * Done handling any receive interrupts. See if data can be 1122 * transmitted as well. Schedule tx done event if no data left 1123 * and tty was marked busy. 1124 */ 1125 1126 if (ISSET(sr, DBGU_SR_TXRDY) && sc->sc_tbc > 0) { 1127 /* Output the next chunk of the contiguous buffer, if any. */ 1128 at91dbgu_filltx(sc); 1129 } else { 1130 /* Disable transmit completion interrupts if necessary. */ 1131 DBGUREG(DBGU_IDR) = DBGU_INT_TXRDY; 1132 if (sc->sc_tx_busy) { 1133 sc->sc_tx_busy = 0; 1134 sc->sc_tx_done = 1; 1135 } 1136 } 1137 1138 /* Wake up the poller. */ 1139 softint_schedule(sc->sc_si); 1140 #if 0 1141 #ifdef RND_COM 1142 rnd_add_uint32(&sc->rnd_source, imr ^ sr ^ c); 1143 #endif 1144 #endif 1145 1146 return (1); 1147 } 1148