1 /* $Id: at91dbgu.c,v 1.10 2014/03/16 05:20:22 dholland Exp $ */ 2 /* $NetBSD: at91dbgu.c,v 1.10 2014/03/16 05:20:22 dholland 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.10 2014/03/16 05:20:22 dholland 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 .d_open = at91dbgu_open, 186 .d_close = at91dbgu_close, 187 .d_read = at91dbgu_read, 188 .d_write = at91dbgu_write, 189 .d_ioctl = at91dbgu_ioctl, 190 .d_stop = at91dbgu_stop, 191 .d_tty = at91dbgu_tty, 192 .d_poll = at91dbgu_poll, 193 .d_mmap = nommap, 194 .d_kqfilter = ttykqfilter, 195 .d_flag = D_TTY 196 }; 197 198 struct consdev at91dbgu_cons = { 199 at91dbgu_cn_probe, NULL, at91dbgu_cn_getc, at91dbgu_cn_putc, at91dbgu_cn_pollc, NULL, 200 NULL, NULL, NODEV, CN_REMOTE 201 }; 202 203 #ifndef DEFAULT_COMSPEED 204 #define DEFAULT_COMSPEED 115200 205 #endif 206 207 #define COMUNIT_MASK 0x7ffff 208 #define COMDIALOUT_MASK 0x80000 209 210 #define COMUNIT(x) (minor(x) & COMUNIT_MASK) 211 #define COMDIALOUT(x) (minor(x) & COMDIALOUT_MASK) 212 213 #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) 214 215 static int 216 at91dbgu_match(device_t parent, cfdata_t match, void *aux) 217 { 218 if (strcmp(match->cf_name, "at91dbgu") == 0) 219 return 2; 220 return 0; 221 } 222 223 static int 224 dbgu_intr(void* arg); 225 226 static void 227 at91dbgu_attach(device_t parent, device_t self, void *aux) 228 { 229 struct at91dbgu_softc *sc = device_private(self); 230 struct at91bus_attach_args *sa = aux; 231 struct tty *tp; 232 233 printf("\n"); 234 235 sc->sc_dev = self; 236 bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh); 237 sc->sc_iot = sa->sa_iot; 238 sc->sc_hwbase = sa->sa_addr; 239 240 DBGUREG(DBGU_IDR) = -1; 241 at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc); 242 DBGU_INIT(AT91_MSTCLK, 115200U); 243 244 if (sc->sc_iot == dbgu_cn_sc.sc_iot 245 && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) { 246 dbgu_cn_sc.sc_attached = 1; 247 /* Make sure the console is always "hardwired". */ 248 delay(10000); /* wait for output to finish */ 249 SET(sc->sc_hwflags, COM_HW_CONSOLE); 250 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 251 SET(sc->sc_ier, DBGU_INT_RXRDY); 252 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@ 253 } 254 255 tp = tty_alloc(); 256 tp->t_oproc = at91dbgu_start; 257 tp->t_param = at91dbgu_param; 258 tp->t_hwiflow = at91dbgu_hwiflow; 259 260 sc->sc_tty = tp; 261 sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); 262 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 263 sc->sc_rbavail = AT91DBGU_RING_SIZE; 264 if (sc->sc_rbuf == NULL) { 265 printf("%s: unable to allocate ring buffer\n", 266 device_xname(sc->sc_dev)); 267 return; 268 } 269 sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1); 270 sc->sc_tbc = 0; 271 272 tty_attach(tp); 273 274 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 275 int maj; 276 277 /* locate the major number */ 278 maj = cdevsw_lookup_major(&at91dbgu_cdevsw); 279 280 cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); 281 282 aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n", 283 device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), 284 cn_tab->cn_dev); 285 } 286 287 sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc); 288 289 #ifdef RND_COM 290 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 291 RND_TYPE_TTY, 0); 292 #endif 293 294 /* if there are no enable/disable functions, assume the device 295 is always enabled */ 296 if (!sc->enable) 297 sc->enabled = 1; 298 299 /* XXX configure register */ 300 /* xxx_config(sc) */ 301 302 SET(sc->sc_hwflags, COM_HW_DEV_OK); 303 } 304 305 static int 306 at91dbgu_param(struct tty *tp, struct termios *t) 307 { 308 struct at91dbgu_softc *sc 309 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 310 int s; 311 312 if (COM_ISALIVE(sc) == 0) 313 return (EIO); 314 315 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 316 return (EINVAL); 317 318 /* 319 * For the console, always force CLOCAL and !HUPCL, so that the port 320 * is always active. 321 */ 322 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 323 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 324 SET(t->c_cflag, CLOCAL); 325 CLR(t->c_cflag, HUPCL); 326 } 327 328 /* 329 * If there were no changes, don't do anything. This avoids dropping 330 * input and improves performance when all we did was frob things like 331 * VMIN and VTIME. 332 */ 333 if (tp->t_ospeed == t->c_ospeed && 334 tp->t_cflag == t->c_cflag) 335 return (0); 336 337 s = splserial(); 338 339 sc->sc_brgr = (AT91_MSTCLK / 16 + t->c_ospeed / 2) / t->c_ospeed; 340 341 /* And copy to tty. */ 342 tp->t_ispeed = 0; 343 tp->t_ospeed = t->c_ospeed; 344 tp->t_cflag = t->c_cflag; 345 at91dbgu_set(sc); 346 347 splx(s); 348 349 /* 350 * Update the tty layer's idea of the carrier bit. 351 * We tell tty the carrier is always on. 352 */ 353 (void) (*tp->t_linesw->l_modem)(tp, 1); 354 355 #ifdef COM_DEBUG 356 if (com_debug) 357 comstatus(sc, "comparam "); 358 #endif 359 360 if (!ISSET(t->c_cflag, CHWFLOW)) { 361 if (sc->sc_tx_stopped) { 362 sc->sc_tx_stopped = 0; 363 at91dbgu_start(tp); 364 } 365 } 366 367 return (0); 368 } 369 370 static int 371 at91dbgu_hwiflow(struct tty *tp, int block) 372 { 373 return (0); 374 } 375 376 static void 377 at91dbgu_filltx(struct at91dbgu_softc *sc) 378 { 379 #if 0 380 bus_space_tag_t iot = sc->sc_iot; 381 bus_space_handle_t ioh = sc->sc_ioh; 382 #endif 383 int n; 384 385 n = 0; 386 while (DBGUREG(DBGU_SR) & DBGU_SR_TXRDY) { 387 if (n >= sc->sc_tbc) 388 break; 389 DBGUREG(DBGU_THR) = *(sc->sc_tba + n) & 0xff; 390 n++; 391 } 392 sc->sc_tbc -= n; 393 sc->sc_tba += n; 394 } 395 396 static void 397 at91dbgu_start(struct tty *tp) 398 { 399 struct at91dbgu_softc *sc 400 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 401 int s; 402 403 if (COM_ISALIVE(sc) == 0) 404 return; 405 406 s = spltty(); 407 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 408 goto out; 409 if (sc->sc_tx_stopped) 410 goto out; 411 if (!ttypull(tp)) 412 goto out; 413 414 /* Grab the first contiguous region of buffer space. */ 415 { 416 u_char *tba; 417 int tbc; 418 419 tba = tp->t_outq.c_cf; 420 tbc = ndqb(&tp->t_outq, 0); 421 422 (void)splserial(); 423 424 sc->sc_tba = tba; 425 sc->sc_tbc = tbc; 426 } 427 428 SET(tp->t_state, TS_BUSY); 429 sc->sc_tx_busy = 1; 430 431 /* Output the first chunk of the contiguous buffer. */ 432 at91dbgu_filltx(sc); 433 434 SET(sc->sc_ier, DBGU_INT_TXRDY); 435 DBGUREG(DBGU_IER) = DBGU_INT_TXRDY; 436 437 out: 438 splx(s); 439 return; 440 } 441 442 static void 443 at91dbgu_break(struct at91dbgu_softc *sc, int onoff) 444 { 445 // @@@ we must disconnect the TX pin from the DBGU and control 446 // @@@ the pin directly to support this... 447 } 448 449 static void 450 at91dbgu_shutdown(struct at91dbgu_softc *sc) 451 { 452 int s; 453 454 s = splserial(); 455 456 /* Turn off interrupts. */ 457 DBGUREG(DBGU_IDR) = -1; 458 459 /* Clear any break condition set with TIOCSBRK. */ 460 at91dbgu_break(sc, 0); 461 at91dbgu_set(sc); 462 463 if (sc->disable) { 464 #ifdef DIAGNOSTIC 465 if (!sc->enabled) 466 panic("at91dbgu_shutdown: not enabled?"); 467 #endif 468 (*sc->disable)(sc); 469 sc->enabled = 0; 470 } 471 splx(s); 472 } 473 474 int 475 at91dbgu_open(dev_t dev, int flag, int mode, struct lwp *l) 476 { 477 struct at91dbgu_softc *sc; 478 struct tty *tp; 479 int s, s2; 480 int error; 481 482 sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 483 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) || 484 sc->sc_rbuf == NULL) 485 return (ENXIO); 486 487 if (!device_is_active(sc->sc_dev)) 488 return (ENXIO); 489 490 #ifdef KGDB 491 /* 492 * If this is the kgdb port, no other use is permitted. 493 */ 494 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) 495 return (EBUSY); 496 #endif 497 498 tp = sc->sc_tty; 499 500 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 501 return (EBUSY); 502 503 s = spltty(); 504 505 /* 506 * Do the following iff this is a first open. 507 */ 508 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 509 struct termios t; 510 511 tp->t_dev = dev; 512 513 s2 = splserial(); 514 515 if (sc->enable) { 516 if ((*sc->enable)(sc)) { 517 splx(s2); 518 splx(s); 519 printf("%s: device enable failed\n", 520 device_xname(sc->sc_dev)); 521 return (EIO); 522 } 523 sc->enabled = 1; 524 #if 0 525 /* XXXXXXXXXXXXXXX */ 526 com_config(sc); 527 #endif 528 } 529 530 /* Turn on interrupts. */ 531 sc->sc_ier |= DBGU_INT_RXRDY; 532 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 533 534 #if 0 535 /* Fetch the current modem control status, needed later. */ 536 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); 537 538 /* Clear PPS capture state on first open. */ 539 sc->sc_ppsmask = 0; 540 sc->ppsparam.mode = 0; 541 #endif 542 543 splx(s2); 544 545 /* 546 * Initialize the termios status to the defaults. Add in the 547 * sticky bits from TIOCSFLAGS. 548 */ 549 t.c_ispeed = 0; 550 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 551 t.c_ospeed = dbgu_cn_sc.sc_ospeed; 552 t.c_cflag = dbgu_cn_sc.sc_cflag; 553 } else { 554 t.c_ospeed = TTYDEF_SPEED; 555 t.c_cflag = TTYDEF_CFLAG; 556 } 557 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 558 SET(t.c_cflag, CLOCAL); 559 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 560 SET(t.c_cflag, CRTSCTS); 561 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 562 SET(t.c_cflag, MDMBUF); 563 /* Make sure at91dbgu_param() will do something. */ 564 tp->t_ospeed = 0; 565 (void) at91dbgu_param(tp, &t); 566 tp->t_iflag = TTYDEF_IFLAG; 567 tp->t_oflag = TTYDEF_OFLAG; 568 tp->t_lflag = TTYDEF_LFLAG; 569 ttychars(tp); 570 ttsetwater(tp); 571 572 s2 = splserial(); 573 574 /* Clear the input ring, and unblock. */ 575 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 576 sc->sc_rbavail = AT91DBGU_RING_SIZE; 577 at91dbgu_iflush(sc); 578 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 579 580 #ifdef COM_DEBUG 581 if (at91dbgu_debug) 582 comstatus(sc, "at91dbgu_open "); 583 #endif 584 585 splx(s2); 586 } 587 588 splx(s); 589 590 error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 591 if (error) 592 goto bad; 593 594 error = (*tp->t_linesw->l_open)(dev, tp); 595 if (error) 596 goto bad; 597 598 return (0); 599 600 bad: 601 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 602 /* 603 * We failed to open the device, and nobody else had it opened. 604 * Clean up the state as appropriate. 605 */ 606 at91dbgu_shutdown(sc); 607 } 608 609 return (error); 610 } 611 612 int 613 at91dbgu_close(dev_t dev, int flag, int mode, struct lwp *l) 614 { 615 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 616 struct tty *tp = sc->sc_tty; 617 618 /* XXX This is for cons.c. */ 619 if (!ISSET(tp->t_state, TS_ISOPEN)) 620 return (0); 621 622 (*tp->t_linesw->l_close)(tp, flag); 623 ttyclose(tp); 624 625 if (COM_ISALIVE(sc) == 0) 626 return (0); 627 628 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 629 /* 630 * Although we got a last close, the device may still be in 631 * use; e.g. if this was the dialout node, and there are still 632 * processes waiting for carrier on the non-dialout node. 633 */ 634 at91dbgu_shutdown(sc); 635 } 636 637 return (0); 638 } 639 640 int 641 at91dbgu_read(dev_t dev, struct uio *uio, int flag) 642 { 643 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 644 struct tty *tp = sc->sc_tty; 645 646 if (COM_ISALIVE(sc) == 0) 647 return (EIO); 648 649 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 650 } 651 652 int 653 at91dbgu_write(dev_t dev, struct uio *uio, int flag) 654 { 655 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 656 struct tty *tp = sc->sc_tty; 657 658 if (COM_ISALIVE(sc) == 0) 659 return (EIO); 660 661 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 662 } 663 664 int 665 at91dbgu_poll(dev_t dev, int events, struct lwp *l) 666 { 667 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 668 struct tty *tp = sc->sc_tty; 669 670 if (COM_ISALIVE(sc) == 0) 671 return (EIO); 672 673 return ((*tp->t_linesw->l_poll)(tp, events, l)); 674 } 675 676 struct tty * 677 at91dbgu_tty(dev_t dev) 678 { 679 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 680 struct tty *tp = sc->sc_tty; 681 682 return (tp); 683 } 684 685 int 686 at91dbgu_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 687 { 688 struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); 689 struct tty *tp = sc->sc_tty; 690 int error; 691 int s; 692 693 if (COM_ISALIVE(sc) == 0) 694 return (EIO); 695 696 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 697 if (error != EPASSTHROUGH) 698 return (error); 699 700 error = ttioctl(tp, cmd, data, flag, l); 701 if (error != EPASSTHROUGH) 702 return (error); 703 704 error = 0; 705 706 s = splserial(); 707 708 switch (cmd) { 709 case TIOCSBRK: 710 at91dbgu_break(sc, 1); 711 break; 712 713 case TIOCCBRK: 714 at91dbgu_break(sc, 0); 715 break; 716 717 case TIOCGFLAGS: 718 *(int *)data = sc->sc_swflags; 719 break; 720 721 case TIOCSFLAGS: 722 error = kauth_authorize_device_tty(l->l_cred, 723 KAUTH_DEVICE_TTY_PRIVSET, tp); 724 if (error) 725 break; 726 sc->sc_swflags = *(int *)data; 727 break; 728 729 default: 730 error = EPASSTHROUGH; 731 break; 732 } 733 734 splx(s); 735 736 return (error); 737 } 738 739 /* 740 * Stop output on a line. 741 */ 742 void 743 at91dbgu_stop(struct tty *tp, int flag) 744 { 745 struct at91dbgu_softc *sc 746 = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); 747 int s; 748 749 s = splserial(); 750 if (ISSET(tp->t_state, TS_BUSY)) { 751 /* Stop transmitting at the next chunk. */ 752 sc->sc_tbc = 0; 753 if (!ISSET(tp->t_state, TS_TTSTOP)) 754 SET(tp->t_state, TS_FLUSH); 755 } 756 splx(s); 757 } 758 759 #if 0 760 static u_int 761 cflag2lcrhi(tcflag_t cflag) 762 { 763 uint32_t mr; 764 765 switch (cflag & CSIZE) { 766 default: 767 mr = 0x0; 768 break; 769 } 770 #if 0 771 mr |= (cflag & PARENB) ? LinCtrlHigh_PEN : 0; 772 mr |= (cflag & PARODD) ? 0 : LinCtrlHigh_EPS; 773 mr |= (cflag & CSTOPB) ? LinCtrlHigh_STP2 : 0; 774 mr |= LinCtrlHigh_FEN; /* FIFO always enabled */ 775 #endif 776 mr |= DBGU_MR_PAR_NONE; 777 return (mr); 778 } 779 #endif 780 781 static void 782 at91dbgu_iflush(struct at91dbgu_softc *sc) 783 { 784 #if 0 785 bus_space_tag_t iot = sc->sc_iot; 786 bus_space_handle_t ioh = sc->sc_ioh; 787 #endif 788 #ifdef DIAGNOSTIC 789 int reg; 790 #endif 791 int timo; 792 793 #ifdef DIAGNOSTIC 794 reg = 0xffff; 795 #endif 796 timo = 50000; 797 /* flush any pending I/O */ 798 while (DBGUREG(DBGU_SR) & DBGU_SR_RXRDY 799 && --timo) 800 #ifdef DIAGNOSTIC 801 reg = 802 #else 803 (void) 804 #endif 805 DBGUREG(DBGU_RHR); 806 #ifdef DIAGNOSTIC 807 if (!timo) 808 printf("%s: com_iflush timeout %02x\n", device_xname(sc->sc_dev), 809 reg); 810 #endif 811 } 812 813 static void 814 at91dbgu_set(struct at91dbgu_softc *sc) 815 { 816 DBGUREG(DBGU_MR) = DBGU_MR_PAR_NONE; 817 DBGUREG(DBGU_BRGR) = sc->sc_brgr; 818 DBGUREG(DBGU_CR) = DBGU_CR_TXEN | DBGU_CR_RXEN; // @@@ just in case 819 } 820 821 void 822 at91dbgu_cn_attach(bus_space_tag_t iot, bus_addr_t iobase, bus_space_handle_t ioh, 823 int ospeed, tcflag_t cflag); 824 void 825 at91dbgu_cn_attach(bus_space_tag_t iot, bus_addr_t iobase, bus_space_handle_t ioh, 826 int ospeed, tcflag_t cflag) 827 { 828 cn_tab = &at91dbgu_cons; 829 cn_init_magic(&at91dbgu_cnm_state); 830 cn_set_magic("\047\001"); 831 832 dbgu_cn_sc.sc_iot = iot; 833 dbgu_cn_sc.sc_ioh = ioh; 834 dbgu_cn_sc.sc_hwbase = iobase; 835 dbgu_cn_sc.sc_ospeed = ospeed; 836 dbgu_cn_sc.sc_cflag = cflag; 837 838 DBGU_INIT(AT91_MSTCLK, ospeed); 839 } 840 841 void at91dbgu_attach_cn(bus_space_tag_t iot, int ospeed, int cflag) 842 { 843 bus_space_handle_t ioh; 844 bus_space_map(iot, AT91DBGU_BASE, AT91DBGU_SIZE, 0, &ioh); 845 at91dbgu_cn_attach(iot, AT91DBGU_BASE, ioh, ospeed, cflag); 846 } 847 848 void 849 at91dbgu_cn_probe(struct consdev *cp) 850 { 851 cp->cn_pri = CN_REMOTE; 852 } 853 854 void 855 at91dbgu_cn_pollc(dev_t dev, int on) 856 { 857 if (on) { 858 // enable polling mode 859 DBGUREG(DBGU_IDR) = DBGU_INT_RXRDY; 860 } else { 861 // disable polling mode 862 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 863 } 864 } 865 866 void 867 at91dbgu_cn_putc(dev_t dev, int c) 868 { 869 #if 0 870 bus_space_tag_t iot = dbgu_cn_sc.sc_iot; 871 bus_space_handle_t ioh = dbgu_cn_sc.sc_ioh; 872 #endif 873 DBGU_PUTC(c); 874 875 #ifdef DEBUG 876 if (c == '\r') { 877 int s = splserial(); 878 while((DBGUREG(DBGU_SR) & DBGU_SR_TXEMPTY) == 0) { 879 splx(s); 880 s = splserial(); 881 } 882 splx(s); 883 } 884 #endif 885 886 } 887 888 int 889 at91dbgu_cn_getc(dev_t dev) 890 { 891 int c, sr; 892 int s; 893 #if 0 894 bus_space_tag_t iot = dbgu_cn_sc.sc_iot; 895 bus_space_handle_t ioh = dbgu_cn_sc.sc_ioh; 896 #endif 897 898 s = splserial(); 899 900 while ((c = DBGU_PEEKC()) == -1) { 901 splx(s); 902 s = splserial(); 903 } 904 ; 905 sr = DBGUREG(DBGU_SR); 906 if (ISSET(sr, DBGU_SR_FRAME) && c == 0) { 907 DBGUREG(DBGU_CR) = DBGU_CR_RSTSTA; // reset status bits 908 c = CNC_BREAK; 909 } 910 #ifdef DDB 911 extern int db_active; 912 if (!db_active) 913 #endif 914 { 915 int cn_trapped = 0; /* unused */ 916 917 cn_check_magic(dev, c, at91dbgu_cnm_state); 918 } 919 splx(s); 920 921 c &= 0xff; 922 923 return (c); 924 } 925 926 inline static void 927 at91dbgu_txsoft(struct at91dbgu_softc *sc, struct tty *tp) 928 { 929 CLR(tp->t_state, TS_BUSY); 930 if (ISSET(tp->t_state, TS_FLUSH)) 931 CLR(tp->t_state, TS_FLUSH); 932 else 933 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 934 (*tp->t_linesw->l_start)(tp); 935 } 936 937 inline static void 938 at91dbgu_rxsoft(struct at91dbgu_softc *sc, struct tty *tp) 939 { 940 int (*rint)(int, struct tty *) = tp->t_linesw->l_rint; 941 u_char *get, *end; 942 u_int cc, scc; 943 u_char sts; 944 int code; 945 int s; 946 947 end = sc->sc_ebuf; 948 get = sc->sc_rbget; 949 scc = cc = AT91DBGU_RING_SIZE - sc->sc_rbavail; 950 #if 0 951 if (cc == AT91DBGU_RING_SIZE) { 952 sc->sc_floods++; 953 if (sc->sc_errors++ == 0) 954 callout_reset(&sc->sc_diag_callout, 60 * hz, 955 comdiag, sc); 956 } 957 #endif 958 while (cc) { 959 code = get[0]; 960 sts = get[1]; 961 if (ISSET(sts, DBGU_SR_PARE | DBGU_SR_FRAME | DBGU_SR_OVRE)) { 962 #if 0 963 if (ISSET(lsr, DR_ROR)) { 964 sc->sc_overflows++; 965 if (sc->sc_errors++ == 0) 966 callout_reset(&sc->sc_diag_callout, 967 60 * hz, comdiag, sc); 968 } 969 #endif 970 if (ISSET(sts, (DBGU_SR_FRAME | DBGU_SR_OVRE))) 971 SET(code, TTY_FE); 972 if (ISSET(sts, DBGU_SR_PARE)) 973 SET(code, TTY_PE); 974 } 975 if ((*rint)(code, tp) == -1) { 976 /* 977 * The line discipline's buffer is out of space. 978 */ 979 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 980 /* 981 * We're either not using flow control, or the 982 * line discipline didn't tell us to block for 983 * some reason. Either way, we have no way to 984 * know when there's more space available, so 985 * just drop the rest of the data. 986 */ 987 get += cc << 1; 988 if (get >= end) 989 get -= AT91DBGU_RING_SIZE << 1; 990 cc = 0; 991 } else { 992 /* 993 * Don't schedule any more receive processing 994 * until the line discipline tells us there's 995 * space available (through comhwiflow()). 996 * Leave the rest of the data in the input 997 * buffer. 998 */ 999 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1000 } 1001 break; 1002 } 1003 get += 2; 1004 if (get >= end) 1005 get = sc->sc_rbuf; 1006 cc--; 1007 } 1008 1009 if (cc != scc) { 1010 sc->sc_rbget = get; 1011 s = splserial(); 1012 1013 cc = sc->sc_rbavail += scc - cc; 1014 /* Buffers should be ok again, release possible block. */ 1015 if (cc >= 1) { 1016 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1017 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1018 DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; 1019 } 1020 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1021 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1022 #if 0 1023 com_hwiflow(sc); 1024 #endif 1025 } 1026 } 1027 splx(s); 1028 } 1029 } 1030 1031 static void 1032 at91dbgu_soft(void* arg) 1033 { 1034 struct at91dbgu_softc *sc = arg; 1035 1036 if (COM_ISALIVE(sc) == 0) 1037 return; 1038 1039 if (sc->sc_rx_ready) { 1040 sc->sc_rx_ready = 0; 1041 at91dbgu_rxsoft(sc, sc->sc_tty); 1042 } 1043 if (sc->sc_tx_done) { 1044 sc->sc_tx_done = 0; 1045 at91dbgu_txsoft(sc, sc->sc_tty); 1046 } 1047 } 1048 1049 1050 static int 1051 dbgu_intr(void* arg) 1052 { 1053 struct at91dbgu_softc *sc = arg; 1054 #if 0 1055 bus_space_tag_t iot = sc->sc_iot; 1056 bus_space_handle_t ioh = sc->sc_ioh; 1057 #endif 1058 u_char *put, *end; 1059 u_int cc; 1060 uint32_t imr, sr; 1061 int c = 0; 1062 imr = DBGUREG(DBGU_IMR); 1063 #if 0 1064 if (!imr) 1065 return 0; 1066 #endif 1067 sr = DBGUREG(DBGU_SR); 1068 if (!(sr & imr)) { 1069 if (sr & DBGU_SR_RXRDY) { 1070 // printf("sr=0x%08x imr=0x%08x\n", sr, imr); 1071 } 1072 return 0; 1073 } 1074 1075 end = sc->sc_ebuf; 1076 put = sc->sc_rbput; 1077 cc = sc->sc_rbavail; 1078 1079 // ok, we DO have some interrupts to serve! 1080 if (sr & DBGU_SR_RXRDY) { 1081 int cn_trapped = 0; 1082 1083 c = DBGUREG(DBGU_RHR); 1084 if (ISSET(sr, (DBGU_SR_OVRE | DBGU_SR_FRAME | DBGU_SR_PARE))) 1085 DBGUREG(DBGU_CR) = DBGU_CR_RSTSTA; 1086 if (ISSET(sr, DBGU_SR_FRAME) && c == 0) { 1087 c = CNC_BREAK; 1088 } 1089 #ifdef DDB 1090 extern int db_active; 1091 if (!db_active) 1092 #endif 1093 cn_check_magic(cn_tab->cn_dev, c, at91dbgu_cnm_state); 1094 if (!cn_trapped && cc) { 1095 put[0] = c & 0xff; 1096 put[1] = sr & 0xff; 1097 put += 2; 1098 if (put >= end) 1099 put = sc->sc_rbuf; 1100 cc--; 1101 /* 1102 * Current string of incoming characters ended because 1103 * no more data was available or we ran out of space. 1104 * Schedule a receive event if any data was received. 1105 * If we're out of space, turn off receive interrupts. 1106 */ 1107 sc->sc_rbput = put; 1108 sc->sc_rbavail = cc; 1109 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1110 sc->sc_rx_ready = 1; 1111 1112 /* 1113 * See if we are in danger of overflowing a buffer. If 1114 * so, use hardware flow control to ease the pressure. 1115 */ 1116 1117 /* but at91dbgu cannot (yet). X-( */ 1118 1119 /* 1120 * If we're out of space, disable receive interrupts 1121 * until the queue has drained a bit. 1122 */ 1123 if (!cc) { 1124 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1125 } 1126 } 1127 } 1128 1129 /* 1130 * Done handling any receive interrupts. See if data can be 1131 * transmitted as well. Schedule tx done event if no data left 1132 * and tty was marked busy. 1133 */ 1134 1135 if (ISSET(sr, DBGU_SR_TXRDY) && sc->sc_tbc > 0) { 1136 /* Output the next chunk of the contiguous buffer, if any. */ 1137 at91dbgu_filltx(sc); 1138 } else { 1139 /* Disable transmit completion interrupts if necessary. */ 1140 DBGUREG(DBGU_IDR) = DBGU_INT_TXRDY; 1141 if (sc->sc_tx_busy) { 1142 sc->sc_tx_busy = 0; 1143 sc->sc_tx_done = 1; 1144 } 1145 } 1146 1147 /* Wake up the poller. */ 1148 softint_schedule(sc->sc_si); 1149 #if 0 1150 #ifdef RND_COM 1151 rnd_add_uint32(&sc->rnd_source, imr ^ sr ^ c); 1152 #endif 1153 #endif 1154 1155 return (1); 1156 } 1157