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