1 /* $NetBSD: plcom.c,v 1.69 2023/04/11 12:58:03 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 ARM Ltd 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the company may not be used to endorse or promote 16 * products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * Copyright (c) 1998, 1999, 2012 The NetBSD Foundation, Inc. 32 * All rights reserved. 33 * 34 * This code is derived from software contributed to The NetBSD Foundation 35 * by Charles M. Hannum and Nick Hudson. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 48 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 50 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 51 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 54 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 56 * POSSIBILITY OF SUCH DAMAGE. 57 */ 58 59 /* 60 * Copyright (c) 1991 The Regents of the University of California. 61 * All rights reserved. 62 * 63 * Redistribution and use in source and binary forms, with or without 64 * modification, are permitted provided that the following conditions 65 * are met: 66 * 1. Redistributions of source code must retain the above copyright 67 * notice, this list of conditions and the following disclaimer. 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in the 70 * documentation and/or other materials provided with the distribution. 71 * 3. Neither the name of the University nor the names of its contributors 72 * may be used to endorse or promote products derived from this software 73 * without specific prior written permission. 74 * 75 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 76 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 78 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 81 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 82 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 83 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 84 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 85 * SUCH DAMAGE. 86 * 87 * @(#)com.c 7.5 (Berkeley) 5/16/91 88 */ 89 90 /* 91 * COM driver for the Prime Cell PL010 and PL011 UARTs. Both are is similar to 92 * the 16C550, but have a completely different programmer's model. 93 * Derived from the NS16550AF com driver. 94 * 95 * Lock order: 96 * ttylock (IPL_VM) 97 * -> sc->sc_lock (IPL_HIGH) 98 * -> timecounter_lock (IPL_HIGH) 99 */ 100 101 #include <sys/cdefs.h> 102 __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.69 2023/04/11 12:58:03 riastradh Exp $"); 103 104 #include "opt_plcom.h" 105 #include "opt_kgdb.h" 106 #include "opt_lockdebug.h" 107 #include "opt_multiprocessor.h" 108 109 /* 110 * Override cnmagic(9) macro before including <sys/systm.h>. 111 * We need to know if cn_check_magic triggered debugger, so set a flag. 112 * Callers of cn_check_magic must declare int cn_trapped = 0; 113 * XXX: this is *ugly*! 114 */ 115 #define cn_trap() \ 116 do { \ 117 console_debugger(); \ 118 cn_trapped = 1; \ 119 } while (/* CONSTCOND */ 0) 120 121 #include <sys/param.h> 122 #include <sys/systm.h> 123 #include <sys/ioctl.h> 124 #include <sys/select.h> 125 #include <sys/tty.h> 126 #include <sys/proc.h> 127 #include <sys/conf.h> 128 #include <sys/file.h> 129 #include <sys/uio.h> 130 #include <sys/kernel.h> 131 #include <sys/syslog.h> 132 #include <sys/types.h> 133 #include <sys/device.h> 134 #include <sys/kmem.h> 135 #include <sys/timepps.h> 136 #include <sys/vnode.h> 137 #include <sys/kauth.h> 138 #include <sys/intr.h> 139 #include <sys/bus.h> 140 #ifdef RND_COM 141 #include <sys/rndsource.h> 142 #endif 143 144 #include <ddb/db_active.h> 145 146 #include <evbarm/dev/plcomreg.h> 147 #include <evbarm/dev/plcomvar.h> 148 149 #include <dev/cons.h> 150 151 static void plcom_enable_debugport (struct plcom_softc *); 152 153 void plcom_config (struct plcom_softc *); 154 void plcom_shutdown (struct plcom_softc *); 155 int pl010comspeed (long, long); 156 int pl011comspeed (long, long); 157 static uint32_t cflag2lcr (tcflag_t); 158 int plcomparam (struct tty *, struct termios *); 159 void plcomstart (struct tty *); 160 int plcomhwiflow (struct tty *, int); 161 162 void plcom_loadchannelregs (struct plcom_softc *); 163 void plcom_hwiflow (struct plcom_softc *); 164 void plcom_break (struct plcom_softc *, int); 165 void plcom_modem (struct plcom_softc *, int); 166 void tiocm_to_plcom (struct plcom_softc *, u_long, int); 167 int plcom_to_tiocm (struct plcom_softc *); 168 void plcom_iflush (struct plcom_softc *); 169 170 int plcom_common_getc (dev_t, struct plcom_instance *); 171 void plcom_common_putc (dev_t, struct plcom_instance *, int); 172 173 int plcominit (struct plcom_instance *, int, int, tcflag_t); 174 175 dev_type_open(plcomopen); 176 dev_type_close(plcomclose); 177 dev_type_read(plcomread); 178 dev_type_write(plcomwrite); 179 dev_type_ioctl(plcomioctl); 180 dev_type_stop(plcomstop); 181 dev_type_tty(plcomtty); 182 dev_type_poll(plcompoll); 183 184 int plcomcngetc (dev_t); 185 void plcomcnputc (dev_t, int); 186 void plcomcnpollc (dev_t, int); 187 void plcomcnhalt (dev_t); 188 189 void plcomsoft (void *); 190 static inline void plcom_rxsoft (struct plcom_softc *, struct tty *); 191 static inline void plcom_txsoft (struct plcom_softc *, struct tty *); 192 static inline void plcom_stsoft (struct plcom_softc *, struct tty *); 193 static inline void plcom_schedrx (struct plcom_softc *); 194 void plcomdiag (void *); 195 196 bool plcom_intstatus(struct plcom_instance *, u_int *); 197 198 extern struct cfdriver plcom_cd; 199 200 const struct cdevsw plcom_cdevsw = { 201 .d_open = plcomopen, 202 .d_close = plcomclose, 203 .d_read = plcomread, 204 .d_write = plcomwrite, 205 .d_ioctl = plcomioctl, 206 .d_stop = plcomstop, 207 .d_tty = plcomtty, 208 .d_poll = plcompoll, 209 .d_mmap = nommap, 210 .d_kqfilter = ttykqfilter, 211 .d_discard = nodiscard, 212 .d_flag = D_TTY 213 }; 214 215 /* 216 * Make this an option variable one can patch. 217 * But be warned: this must be a power of 2! 218 */ 219 u_int plcom_rbuf_size = PLCOM_RING_SIZE; 220 221 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 222 u_int plcom_rbuf_hiwat = (PLCOM_RING_SIZE * 1) / 4; 223 u_int plcom_rbuf_lowat = (PLCOM_RING_SIZE * 3) / 4; 224 225 static int plcomconsunit = -1; 226 static struct plcom_instance plcomcons_info; 227 228 static int plcomconsattached; 229 static int plcomconsrate; 230 static tcflag_t plcomconscflag; 231 static struct cnm_state plcom_cnm_state; 232 233 static int ppscap = 234 PPS_TSFMT_TSPEC | 235 PPS_CAPTUREASSERT | 236 PPS_CAPTURECLEAR | 237 #ifdef PPS_SYNC 238 PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR | 239 #endif /* PPS_SYNC */ 240 PPS_OFFSETASSERT | PPS_OFFSETCLEAR; 241 242 #ifdef KGDB 243 #include <sys/kgdb.h> 244 245 static struct plcom_instance plcomkgdb_info; 246 static int plcom_kgdb_attached; 247 248 int plcom_kgdb_getc (void *); 249 void plcom_kgdb_putc (void *, int); 250 #endif /* KGDB */ 251 252 #define PLCOMDIALOUT_MASK TTDIALOUT_MASK 253 254 #define PLCOMUNIT(x) TTUNIT(x) 255 #define PLCOMDIALOUT(x) TTDIALOUT(x) 256 257 #define PLCOM_ISALIVE(sc) ((sc)->enabled != 0 && \ 258 device_is_active((sc)->sc_dev)) 259 260 #define BR BUS_SPACE_BARRIER_READ 261 #define BW BUS_SPACE_BARRIER_WRITE 262 #define PLCOM_BARRIER(pi, f) \ 263 bus_space_barrier((pi)->pi_iot, (pi)->pi_ioh, 0, (pi)->pi_size, (f)) 264 265 static uint8_t 266 pread1(struct plcom_instance *pi, bus_size_t reg) 267 { 268 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) 269 return bus_space_read_1(pi->pi_iot, pi->pi_ioh, reg); 270 271 return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >> 272 (8 * (reg & 3)); 273 } 274 275 static uint16_t 276 pread2(struct plcom_instance *pi, bus_size_t reg) 277 { 278 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) 279 return bus_space_read_2(pi->pi_iot, pi->pi_ioh, reg); 280 281 return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >> 282 (8 * (reg & 3)); 283 } 284 285 static void 286 pwrite1(struct plcom_instance *pi, bus_size_t o, uint8_t val) 287 { 288 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) { 289 bus_space_write_1(pi->pi_iot, pi->pi_ioh, o, val); 290 } else { 291 const size_t shift = 8 * (o & 3); 292 o &= -4; 293 uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o); 294 tmp = (val << shift) | (tmp & ~(0xff << shift)); 295 bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp); 296 } 297 } 298 299 static void 300 pwrite2(struct plcom_instance *pi, bus_size_t o, uint16_t val) 301 { 302 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) { 303 bus_space_write_2(pi->pi_iot, pi->pi_ioh, o, val); 304 } else { 305 const size_t shift = 8 * (o & 3); 306 o &= -4; 307 uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o); 308 tmp = (val << shift) | (tmp & ~(0xffff << shift)); 309 bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp); 310 } 311 } 312 313 static void 314 pwritem1(struct plcom_instance *pi, bus_size_t o, const uint8_t *datap, 315 bus_size_t count) 316 { 317 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) { 318 bus_space_write_multi_1(pi->pi_iot, pi->pi_ioh, o, datap, count); 319 } else { 320 KASSERT((o & 3) == 0); 321 while (count--) { 322 bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, *datap++); 323 }; 324 } 325 } 326 327 #define PREAD1(pi, reg) pread1(pi, reg) 328 #define PREAD2(pi, reg) pread2(pi, reg) 329 #define PREAD4(pi, reg) \ 330 bus_space_read_4((pi)->pi_iot, (pi)->pi_ioh, (reg)) 331 332 #define PWRITE1(pi, reg, val) pwrite1(pi, reg, val) 333 #define PWRITEM1(pi, reg, d, c) pwritem1(pi, reg, d, c) 334 #define PWRITE2(pi, reg, val) pwrite2(pi, reg, val) 335 #define PWRITE4(pi, reg, val) \ 336 bus_space_write_4((pi)->pi_iot, (pi)->pi_ioh, (reg), (val)) 337 338 int 339 pl010comspeed(long speed, long frequency) 340 { 341 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 342 343 int x, err; 344 345 #if 0 346 if (speed == 0) 347 return 0; 348 #endif 349 if (speed <= 0) 350 return -1; 351 x = divrnd(frequency / 16, speed); 352 if (x <= 0) 353 return -1; 354 err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000; 355 if (err < 0) 356 err = -err; 357 if (err > PLCOM_TOLERANCE) 358 return -1; 359 return x; 360 361 #undef divrnd 362 } 363 364 int 365 pl011comspeed(long speed, long frequency) 366 { 367 int denom = 16 * speed; 368 int div = frequency / denom; 369 int rem = frequency % denom; 370 371 int ibrd = div << 6; 372 int fbrd = (((8 * rem) / speed) + 1) / 2; 373 374 /* Tolerance? */ 375 return ibrd | fbrd; 376 } 377 378 #ifdef PLCOM_DEBUG 379 int plcom_debug = 0; 380 381 void plcomstatus (struct plcom_softc *, const char *); 382 void 383 plcomstatus(struct plcom_softc *sc, const char *str) 384 { 385 struct tty *tp = sc->sc_tty; 386 387 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n", 388 device_xname(sc->sc_dev), str, 389 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-", 390 ISSET(sc->sc_msr, PL01X_MSR_DCD) ? "+" : "-", 391 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-", 392 ISSET(sc->sc_mcr, PL01X_MCR_DTR) ? "+" : "-", 393 sc->sc_tx_stopped ? "+" : "-"); 394 395 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n", 396 device_xname(sc->sc_dev), str, 397 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-", 398 ISSET(sc->sc_msr, PL01X_MSR_CTS) ? "+" : "-", 399 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-", 400 ISSET(sc->sc_mcr, PL01X_MCR_RTS) ? "+" : "-", 401 sc->sc_rx_flags); 402 } 403 #endif 404 405 #if 0 406 int 407 plcomprobe1(bus_space_tag_t iot, bus_space_handle_t ioh) 408 { 409 int data; 410 411 /* Disable the UART. */ 412 bus_space_write_1(iot, ioh, plcom_cr, 0); 413 /* Make sure the FIFO is off. */ 414 bus_space_write_4(iot, ioh, plcom_lcr, PL01X_LCR_8BITS); 415 /* Disable interrupts. */ 416 bus_space_write_1(iot, ioh, plcom_iir, 0); 417 418 /* Make sure we swallow anything in the receiving register. */ 419 data = bus_space_read_1(iot, ioh, plcom_dr); 420 421 if (bus_space_read_4(iot, ioh, plcom_lcr) != PL01X_LCR_8BITS) 422 return 0; 423 424 data = bus_space_read_1(iot, ioh, plcom_fr) & (PL01X_FR_RXFF | PL01X_FR_RXFE); 425 426 if (data != PL01X_FR_RXFE) 427 return 0; 428 429 return 1; 430 } 431 #endif 432 433 /* 434 * No locking in this routine; it is only called during attach, 435 * or with the port already locked. 436 */ 437 static void 438 plcom_enable_debugport(struct plcom_softc *sc) 439 { 440 struct plcom_instance *pi = &sc->sc_pi; 441 442 sc->sc_cr = PL01X_CR_UARTEN; 443 SET(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS); 444 445 /* Turn on line break interrupt, set carrier. */ 446 switch (pi->pi_type) { 447 case PLCOM_TYPE_PL010: 448 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 449 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 450 if (sc->sc_set_mcr) { 451 /* XXX device_unit() abuse */ 452 sc->sc_set_mcr(sc->sc_set_mcr_arg, 453 device_unit(sc->sc_dev), sc->sc_mcr); 454 } 455 break; 456 case PLCOM_TYPE_PL011: 457 case PLCOM_TYPE_GENERIC_UART: 458 sc->sc_imsc = PL011_INT_RX | PL011_INT_RT; 459 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 460 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr)); 461 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 462 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 463 break; 464 } 465 466 } 467 468 void 469 plcom_attach_subr(struct plcom_softc *sc) 470 { 471 struct plcom_instance *pi = &sc->sc_pi; 472 struct tty *tp; 473 474 callout_init(&sc->sc_diag_callout, 0); 475 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH); 476 477 switch (pi->pi_type) { 478 case PLCOM_TYPE_PL010: 479 case PLCOM_TYPE_PL011: 480 case PLCOM_TYPE_GENERIC_UART: 481 break; 482 default: 483 aprint_error_dev(sc->sc_dev, 484 "Unknown plcom type: %d\n", pi->pi_type); 485 return; 486 } 487 488 /* Disable interrupts before configuring the device. */ 489 sc->sc_cr = 0; 490 sc->sc_imsc = 0; 491 492 if (bus_space_is_equal(pi->pi_iot, plcomcons_info.pi_iot) && 493 pi->pi_iobase == plcomcons_info.pi_iobase) { 494 plcomconsattached = 1; 495 496 /* Make sure the console is always "hardwired". */ 497 delay(1000); /* wait for output to finish */ 498 SET(sc->sc_hwflags, PLCOM_HW_CONSOLE); 499 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 500 /* 501 * Must re-enable the console immediately, or we will 502 * hang when trying to print. 503 */ 504 sc->sc_cr = PL01X_CR_UARTEN; 505 switch (pi->pi_type) { 506 case PLCOM_TYPE_PL011: 507 case PLCOM_TYPE_GENERIC_UART: 508 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 509 break; 510 } 511 } 512 513 switch (pi->pi_type) { 514 case PLCOM_TYPE_PL011: 515 if (pi->pi_periphid == 0) { 516 pi->pi_periphid = PREAD1(pi, PL011COM_PID0) << 0 517 | PREAD1(pi, PL011COM_PID1) << 8 518 | PREAD1(pi, PL011COM_PID2) << 16 519 | PREAD1(pi, PL011COM_PID3) << 24; 520 } 521 aprint_debug_dev(sc->sc_dev, "PID %08x\n", pi->pi_periphid); 522 break; 523 } 524 525 switch (pi->pi_type) { 526 case PLCOM_TYPE_PL010: 527 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 528 break; 529 530 case PLCOM_TYPE_PL011: 531 case PLCOM_TYPE_GENERIC_UART: 532 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 533 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 534 break; 535 } 536 537 if (sc->sc_fifolen == 0) { 538 switch (pi->pi_type) { 539 case PLCOM_TYPE_PL010: 540 /* 541 * The PL010 has a 16-byte fifo, but the tx interrupt 542 * triggers when there is space for 8 more bytes. 543 */ 544 sc->sc_fifolen = 8; 545 break; 546 case PLCOM_TYPE_PL011: 547 /* Some revisions have a 32 byte TX FIFO */ 548 switch (pi->pi_periphid & (PL011_DESIGNER_MASK | PL011_HWREV_MASK)) { 549 case PL011_DESIGNER_ARM | __SHIFTIN(0, PL011_HWREV_MASK): 550 case PL011_DESIGNER_ARM | __SHIFTIN(1, PL011_HWREV_MASK): 551 case PL011_DESIGNER_ARM | __SHIFTIN(2, PL011_HWREV_MASK): 552 sc->sc_fifolen = 16; 553 break; 554 default: 555 sc->sc_fifolen = 32; 556 break; 557 } 558 break; 559 case PLCOM_TYPE_GENERIC_UART: 560 /* At least 32 byte TX FIFO */ 561 sc->sc_fifolen = 32; 562 break; 563 } 564 } 565 566 /* Safe amount of bytes to fill when TX FIFO signals empty */ 567 sc->sc_burstlen = 1; 568 569 if (ISSET(sc->sc_hwflags, PLCOM_HW_TXFIFO_DISABLE)) { 570 sc->sc_fifolen = 1; 571 aprint_normal_dev(sc->sc_dev, "txfifo disabled\n"); 572 } 573 574 if (sc->sc_fifolen > 1) { 575 SET(sc->sc_hwflags, PLCOM_HW_FIFO); 576 aprint_normal_dev(sc->sc_dev, "txfifo %u bytes\n", sc->sc_fifolen); 577 } 578 579 tp = tty_alloc(); 580 tp->t_oproc = plcomstart; 581 tp->t_param = plcomparam; 582 tp->t_hwiflow = plcomhwiflow; 583 584 sc->sc_tty = tp; 585 sc->sc_rbuf = kmem_alloc(plcom_rbuf_size << 1, KM_SLEEP); 586 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 587 sc->sc_rbavail = plcom_rbuf_size; 588 sc->sc_ebuf = sc->sc_rbuf + (plcom_rbuf_size << 1); 589 590 tty_attach(tp); 591 592 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 593 int maj; 594 595 /* locate the major number */ 596 maj = cdevsw_lookup_major(&plcom_cdevsw); 597 598 tp->t_dev = cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); 599 600 aprint_normal_dev(sc->sc_dev, "console\n"); 601 } 602 603 #ifdef KGDB 604 /* 605 * Allow kgdb to "take over" this port. If this is 606 * the kgdb device, it has exclusive use. 607 */ 608 if (bus_space_is_equal(pi->pi_iot, plcomkgdb_info.pi_iot) && 609 pi->pi_iobase == plcomkgdb_info.pi_iobase) { 610 if (!ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 611 plcom_kgdb_attached = 1; 612 613 SET(sc->sc_hwflags, PLCOM_HW_KGDB); 614 } 615 aprint_normal_dev(sc->sc_dev, "kgdb\n"); 616 } 617 #endif 618 619 sc->sc_si = softint_establish(SOFTINT_SERIAL, plcomsoft, sc); 620 621 #ifdef RND_COM 622 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 623 RND_TYPE_TTY, RND_FLAG_DEFAULT); 624 #endif 625 626 /* 627 * if there are no enable/disable functions, assume the device 628 * is always enabled 629 */ 630 if (!sc->enable) 631 sc->enabled = 1; 632 633 plcom_config(sc); 634 635 SET(sc->sc_hwflags, PLCOM_HW_DEV_OK); 636 } 637 638 void 639 plcom_config(struct plcom_softc *sc) 640 { 641 struct plcom_instance *pi = &sc->sc_pi; 642 643 /* Disable interrupts before configuring the device. */ 644 sc->sc_cr = 0; 645 sc->sc_imsc = 0; 646 switch (pi->pi_type) { 647 case PLCOM_TYPE_PL010: 648 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 649 break; 650 651 case PLCOM_TYPE_PL011: 652 case PLCOM_TYPE_GENERIC_UART: 653 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 654 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 655 break; 656 } 657 658 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE|PLCOM_HW_KGDB)) 659 plcom_enable_debugport(sc); 660 } 661 662 int 663 plcom_detach(device_t self, int flags) 664 { 665 struct plcom_softc *sc = device_private(self); 666 int maj, mn; 667 668 if (sc->sc_hwflags & (PLCOM_HW_CONSOLE|PLCOM_HW_KGDB)) 669 return EBUSY; 670 671 if (sc->disable != NULL && sc->enabled != 0) { 672 (*sc->disable)(sc); 673 sc->enabled = 0; 674 } 675 676 /* locate the major number */ 677 maj = cdevsw_lookup_major(&plcom_cdevsw); 678 679 /* Nuke the vnodes for any open instances. */ 680 mn = device_unit(self); 681 vdevgone(maj, mn, mn, VCHR); 682 683 mn |= PLCOMDIALOUT_MASK; 684 vdevgone(maj, mn, mn, VCHR); 685 686 if (sc->sc_rbuf == NULL) { 687 /* 688 * Ring buffer allocation failed in the plcom_attach_subr, 689 * only the tty is allocated, and nothing else. 690 */ 691 tty_free(sc->sc_tty); 692 return 0; 693 } 694 695 /* Free the receive buffer. */ 696 kmem_free(sc->sc_rbuf, sc->sc_ebuf - sc->sc_rbuf); 697 698 /* Detach and free the tty. */ 699 tty_detach(sc->sc_tty); 700 tty_free(sc->sc_tty); 701 702 /* Unhook the soft interrupt handler. */ 703 softint_disestablish(sc->sc_si); 704 705 #ifdef RND_COM 706 /* Unhook the entropy source. */ 707 rnd_detach_source(&sc->rnd_source); 708 #endif 709 callout_destroy(&sc->sc_diag_callout); 710 711 /* Destroy the lock. */ 712 mutex_destroy(&sc->sc_lock); 713 714 return 0; 715 } 716 717 int 718 plcom_activate(device_t self, enum devact act) 719 { 720 struct plcom_softc *sc = device_private(self); 721 722 switch (act) { 723 case DVACT_DEACTIVATE: 724 sc->enabled = 0; 725 return 0; 726 default: 727 return EOPNOTSUPP; 728 } 729 } 730 731 void 732 plcom_shutdown(struct plcom_softc *sc) 733 { 734 struct plcom_instance *pi = &sc->sc_pi; 735 struct tty *tp = sc->sc_tty; 736 mutex_spin_enter(&sc->sc_lock); 737 738 /* If we were asserting flow control, then deassert it. */ 739 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 740 plcom_hwiflow(sc); 741 742 /* Clear any break condition set with TIOCSBRK. */ 743 plcom_break(sc, 0); 744 745 /* Turn off PPS capture on last close. */ 746 mutex_spin_enter(&timecounter_lock); 747 sc->sc_ppsmask = 0; 748 sc->ppsparam.mode = 0; 749 mutex_spin_exit(&timecounter_lock); 750 751 /* 752 * Hang up if necessary. Record when we hung up, so if we 753 * immediately open the port again, we will wait a bit until 754 * the other side has had time to notice that we hung up. 755 */ 756 if (ISSET(tp->t_cflag, HUPCL)) { 757 plcom_modem(sc, 0); 758 microuptime(&sc->sc_hup_pending); 759 sc->sc_hup_pending.tv_sec++; 760 } 761 762 sc->sc_cr = 0; 763 sc->sc_imsc = 0; 764 /* Turn off interrupts. */ 765 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 766 /* interrupt on break */ 767 768 sc->sc_cr = PL01X_CR_UARTEN; 769 sc->sc_imsc = 0; 770 switch (pi->pi_type) { 771 case PLCOM_TYPE_PL010: 772 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 773 break; 774 case PLCOM_TYPE_PL011: 775 case PLCOM_TYPE_GENERIC_UART: 776 SET(sc->sc_cr, PL011_CR_RXE); 777 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX); 778 break; 779 } 780 } 781 switch (pi->pi_type) { 782 case PLCOM_TYPE_PL010: 783 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 784 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 785 break; 786 case PLCOM_TYPE_PL011: 787 case PLCOM_TYPE_GENERIC_UART: 788 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 789 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX); 790 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 791 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 792 break; 793 } 794 795 mutex_spin_exit(&sc->sc_lock); 796 if (sc->disable) { 797 #ifdef DIAGNOSTIC 798 if (!sc->enabled) 799 panic("plcom_shutdown: not enabled?"); 800 #endif 801 (*sc->disable)(sc); 802 sc->enabled = 0; 803 } 804 } 805 806 int 807 plcomopen(dev_t dev, int flag, int mode, struct lwp *l) 808 { 809 struct plcom_softc *sc; 810 struct plcom_instance *pi; 811 struct tty *tp; 812 int s; 813 int error; 814 815 sc = device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 816 if (sc == NULL || !ISSET(sc->sc_hwflags, PLCOM_HW_DEV_OK) || 817 sc->sc_rbuf == NULL) 818 return ENXIO; 819 820 if (!device_is_active(sc->sc_dev)) 821 return ENXIO; 822 823 pi = &sc->sc_pi; 824 825 #ifdef KGDB 826 /* 827 * If this is the kgdb port, no other use is permitted. 828 */ 829 if (ISSET(sc->sc_hwflags, PLCOM_HW_KGDB)) 830 return EBUSY; 831 #endif 832 833 tp = sc->sc_tty; 834 835 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 836 return (EBUSY); 837 838 s = spltty(); 839 840 /* 841 * Do the following iff this is a first open. 842 */ 843 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 844 struct termios t; 845 struct timeval now, diff; 846 847 tp->t_dev = dev; 848 849 if (sc->enable) { 850 if ((*sc->enable)(sc)) { 851 splx(s); 852 aprint_error_dev(sc->sc_dev, 853 "device enable failed\n"); 854 return EIO; 855 } 856 mutex_spin_enter(&sc->sc_lock); 857 sc->enabled = 1; 858 plcom_config(sc); 859 } else { 860 mutex_spin_enter(&sc->sc_lock); 861 } 862 863 if (timerisset(&sc->sc_hup_pending)) { 864 microuptime(&now); 865 while (timercmp(&now, &sc->sc_hup_pending, <)) { 866 timersub(&sc->sc_hup_pending, &now, &diff); 867 const int ms = diff.tv_sec * 100 + 868 diff.tv_usec / 1000; 869 kpause(ttclos, false, uimax(mstohz(ms), 1), 870 &sc->sc_lock); 871 microuptime(&now); 872 } 873 timerclear(&sc->sc_hup_pending); 874 } 875 876 /* Turn on interrupts. */ 877 /* IER_ERXRDY | IER_ERLS | IER_EMSC; */ 878 /* Fetch the current modem control status, needed later. */ 879 sc->sc_cr = PL01X_CR_UARTEN; 880 switch (pi->pi_type) { 881 case PLCOM_TYPE_PL010: 882 SET(sc->sc_cr, 883 PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE); 884 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 885 sc->sc_msr = PREAD1(pi, PL01XCOM_FR); 886 break; 887 case PLCOM_TYPE_PL011: 888 case PLCOM_TYPE_GENERIC_UART: 889 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 890 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX | 891 PL011_INT_MSMASK); 892 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 893 sc->sc_msr = PREAD4(pi, PL01XCOM_FR); 894 break; 895 } 896 897 /* Clear PPS capture state on first open. */ 898 899 mutex_spin_enter(&timecounter_lock); 900 sc->sc_ppsmask = 0; 901 sc->ppsparam.mode = 0; 902 mutex_spin_exit(&timecounter_lock); 903 904 mutex_spin_exit(&sc->sc_lock); 905 906 /* 907 * Initialize the termios status to the defaults. Add in the 908 * sticky bits from TIOCSFLAGS. 909 */ 910 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 911 t.c_ospeed = plcomconsrate; 912 t.c_cflag = plcomconscflag; 913 } else { 914 t.c_ospeed = TTYDEF_SPEED; 915 t.c_cflag = TTYDEF_CFLAG; 916 } 917 t.c_ispeed = t.c_ospeed; 918 919 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 920 SET(t.c_cflag, CLOCAL); 921 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 922 SET(t.c_cflag, CRTSCTS); 923 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 924 SET(t.c_cflag, MDMBUF); 925 /* Make sure plcomparam() will do something. */ 926 tp->t_ospeed = 0; 927 (void) plcomparam(tp, &t); 928 tp->t_iflag = TTYDEF_IFLAG; 929 tp->t_oflag = TTYDEF_OFLAG; 930 tp->t_lflag = TTYDEF_LFLAG; 931 ttychars(tp); 932 ttsetwater(tp); 933 934 mutex_spin_enter(&sc->sc_lock); 935 936 /* 937 * Turn on DTR. We must always do this, even if carrier is not 938 * present, because otherwise we'd have to use TIOCSDTR 939 * immediately after setting CLOCAL, which applications do not 940 * expect. We always assert DTR while the device is open 941 * unless explicitly requested to deassert it. 942 */ 943 plcom_modem(sc, 1); 944 945 /* Clear the input ring, and unblock. */ 946 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 947 sc->sc_rbavail = plcom_rbuf_size; 948 plcom_iflush(sc); 949 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 950 plcom_hwiflow(sc); 951 952 #ifdef PLCOM_DEBUG 953 if (plcom_debug) 954 plcomstatus(sc, "plcomopen "); 955 #endif 956 957 mutex_spin_exit(&sc->sc_lock); 958 } 959 960 splx(s); 961 962 error = ttyopen(tp, PLCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 963 if (error) 964 goto bad; 965 966 error = (*tp->t_linesw->l_open)(dev, tp); 967 if (error) 968 goto bad; 969 970 return 0; 971 972 bad: 973 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 974 /* 975 * We failed to open the device, and nobody else had it opened. 976 * Clean up the state as appropriate. 977 */ 978 plcom_shutdown(sc); 979 } 980 981 return error; 982 } 983 984 int 985 plcomclose(dev_t dev, int flag, int mode, struct lwp *l) 986 { 987 struct plcom_softc *sc = 988 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 989 struct tty *tp = sc->sc_tty; 990 991 /* XXX This is for cons.c. */ 992 if (!ISSET(tp->t_state, TS_ISOPEN)) 993 return 0; 994 995 (*tp->t_linesw->l_close)(tp, flag); 996 ttyclose(tp); 997 998 if (PLCOM_ISALIVE(sc) == 0) 999 return 0; 1000 1001 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 1002 /* 1003 * Although we got a last close, the device may still be in 1004 * use; e.g. if this was the dialout node, and there are still 1005 * processes waiting for carrier on the non-dialout node. 1006 */ 1007 plcom_shutdown(sc); 1008 } 1009 1010 return 0; 1011 } 1012 1013 int 1014 plcomread(dev_t dev, struct uio *uio, int flag) 1015 { 1016 struct plcom_softc *sc = 1017 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 1018 struct tty *tp = sc->sc_tty; 1019 1020 if (PLCOM_ISALIVE(sc) == 0) 1021 return EIO; 1022 1023 return (*tp->t_linesw->l_read)(tp, uio, flag); 1024 } 1025 1026 int 1027 plcomwrite(dev_t dev, struct uio *uio, int flag) 1028 { 1029 struct plcom_softc *sc = 1030 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 1031 struct tty *tp = sc->sc_tty; 1032 1033 if (PLCOM_ISALIVE(sc) == 0) 1034 return EIO; 1035 1036 return (*tp->t_linesw->l_write)(tp, uio, flag); 1037 } 1038 1039 int 1040 plcompoll(dev_t dev, int events, struct lwp *l) 1041 { 1042 struct plcom_softc *sc = 1043 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 1044 struct tty *tp = sc->sc_tty; 1045 1046 if (PLCOM_ISALIVE(sc) == 0) 1047 return EIO; 1048 1049 return (*tp->t_linesw->l_poll)(tp, events, l); 1050 } 1051 1052 struct tty * 1053 plcomtty(dev_t dev) 1054 { 1055 struct plcom_softc *sc = 1056 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 1057 struct tty *tp = sc->sc_tty; 1058 1059 return tp; 1060 } 1061 1062 int 1063 plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 1064 { 1065 struct plcom_softc *sc = 1066 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 1067 struct tty *tp; 1068 int error; 1069 1070 if (sc == NULL) 1071 return ENXIO; 1072 if (PLCOM_ISALIVE(sc) == 0) 1073 return EIO; 1074 1075 tp = sc->sc_tty; 1076 1077 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 1078 if (error != EPASSTHROUGH) 1079 return error; 1080 1081 error = ttioctl(tp, cmd, data, flag, l); 1082 if (error != EPASSTHROUGH) 1083 return error; 1084 1085 error = 0; 1086 switch (cmd) { 1087 case TIOCSFLAGS: 1088 error = kauth_authorize_device_tty(l->l_cred, 1089 KAUTH_DEVICE_TTY_PRIVSET, tp); 1090 break; 1091 default: 1092 /* nothing */ 1093 break; 1094 } 1095 if (error) { 1096 return error; 1097 } 1098 1099 mutex_spin_enter(&sc->sc_lock); 1100 switch (cmd) { 1101 case TIOCSBRK: 1102 plcom_break(sc, 1); 1103 break; 1104 1105 case TIOCCBRK: 1106 plcom_break(sc, 0); 1107 break; 1108 1109 case TIOCSDTR: 1110 plcom_modem(sc, 1); 1111 break; 1112 1113 case TIOCCDTR: 1114 plcom_modem(sc, 0); 1115 break; 1116 1117 case TIOCGFLAGS: 1118 *(int *)data = sc->sc_swflags; 1119 break; 1120 1121 case TIOCSFLAGS: 1122 sc->sc_swflags = *(int *)data; 1123 break; 1124 1125 case TIOCMSET: 1126 case TIOCMBIS: 1127 case TIOCMBIC: 1128 tiocm_to_plcom(sc, cmd, *(int *)data); 1129 break; 1130 1131 case TIOCMGET: 1132 *(int *)data = plcom_to_tiocm(sc); 1133 break; 1134 1135 case PPS_IOC_CREATE: 1136 break; 1137 1138 case PPS_IOC_DESTROY: 1139 break; 1140 1141 case PPS_IOC_GETPARAMS: { 1142 pps_params_t *pp; 1143 pp = (pps_params_t *)data; 1144 mutex_spin_enter(&timecounter_lock); 1145 *pp = sc->ppsparam; 1146 mutex_spin_exit(&timecounter_lock); 1147 break; 1148 } 1149 1150 case PPS_IOC_SETPARAMS: { 1151 pps_params_t *pp; 1152 int mode; 1153 pp = (pps_params_t *)data; 1154 mutex_spin_enter(&timecounter_lock); 1155 if (pp->mode & ~ppscap) { 1156 error = EINVAL; 1157 mutex_spin_exit(&timecounter_lock); 1158 break; 1159 } 1160 sc->ppsparam = *pp; 1161 /* 1162 * Compute msr masks from user-specified timestamp state. 1163 */ 1164 mode = sc->ppsparam.mode; 1165 #ifdef PPS_SYNC 1166 if (mode & PPS_HARDPPSONASSERT) { 1167 mode |= PPS_CAPTUREASSERT; 1168 /* XXX revoke any previous HARDPPS source */ 1169 } 1170 if (mode & PPS_HARDPPSONCLEAR) { 1171 mode |= PPS_CAPTURECLEAR; 1172 /* XXX revoke any previous HARDPPS source */ 1173 } 1174 #endif /* PPS_SYNC */ 1175 switch (mode & PPS_CAPTUREBOTH) { 1176 case 0: 1177 sc->sc_ppsmask = 0; 1178 break; 1179 1180 case PPS_CAPTUREASSERT: 1181 sc->sc_ppsmask = PL01X_MSR_DCD; 1182 sc->sc_ppsassert = PL01X_MSR_DCD; 1183 sc->sc_ppsclear = -1; 1184 break; 1185 1186 case PPS_CAPTURECLEAR: 1187 sc->sc_ppsmask = PL01X_MSR_DCD; 1188 sc->sc_ppsassert = -1; 1189 sc->sc_ppsclear = 0; 1190 break; 1191 1192 case PPS_CAPTUREBOTH: 1193 sc->sc_ppsmask = PL01X_MSR_DCD; 1194 sc->sc_ppsassert = PL01X_MSR_DCD; 1195 sc->sc_ppsclear = 0; 1196 break; 1197 1198 default: 1199 error = EINVAL; 1200 break; 1201 } 1202 mutex_spin_exit(&timecounter_lock); 1203 break; 1204 } 1205 1206 case PPS_IOC_GETCAP: 1207 *(int*)data = ppscap; 1208 break; 1209 1210 case PPS_IOC_FETCH: { 1211 pps_info_t *pi; 1212 pi = (pps_info_t *)data; 1213 mutex_spin_enter(&timecounter_lock); 1214 *pi = sc->ppsinfo; 1215 mutex_spin_exit(&timecounter_lock); 1216 break; 1217 } 1218 1219 case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ 1220 /* 1221 * Some GPS clocks models use the falling rather than 1222 * rising edge as the on-the-second signal. 1223 * The old API has no way to specify PPS polarity. 1224 */ 1225 mutex_spin_enter(&timecounter_lock); 1226 sc->sc_ppsmask = PL01X_MSR_DCD; 1227 #ifndef PPS_TRAILING_EDGE 1228 sc->sc_ppsassert = PL01X_MSR_DCD; 1229 sc->sc_ppsclear = -1; 1230 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 1231 &sc->ppsinfo.assert_timestamp); 1232 #else 1233 sc->sc_ppsassert = -1 1234 sc->sc_ppsclear = 0; 1235 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 1236 &sc->ppsinfo.clear_timestamp); 1237 #endif 1238 mutex_spin_exit(&timecounter_lock); 1239 break; 1240 1241 default: 1242 error = EPASSTHROUGH; 1243 break; 1244 } 1245 1246 mutex_spin_exit(&sc->sc_lock); 1247 1248 #ifdef PLCOM_DEBUG 1249 if (plcom_debug) 1250 plcomstatus(sc, "plcomioctl "); 1251 #endif 1252 1253 return error; 1254 } 1255 1256 static inline void 1257 plcom_schedrx(struct plcom_softc *sc) 1258 { 1259 1260 sc->sc_rx_ready = 1; 1261 1262 /* Wake up the poller. */ 1263 softint_schedule(sc->sc_si); 1264 } 1265 1266 void 1267 plcom_break(struct plcom_softc *sc, int onoff) 1268 { 1269 1270 if (onoff) 1271 SET(sc->sc_lcr, PL01X_LCR_BRK); 1272 else 1273 CLR(sc->sc_lcr, PL01X_LCR_BRK); 1274 1275 if (!sc->sc_heldchange) { 1276 if (sc->sc_tx_busy) { 1277 sc->sc_heldtbc = sc->sc_tbc; 1278 sc->sc_tbc = 0; 1279 sc->sc_heldchange = 1; 1280 } else 1281 plcom_loadchannelregs(sc); 1282 } 1283 } 1284 1285 void 1286 plcom_modem(struct plcom_softc *sc, int onoff) 1287 { 1288 1289 if (sc->sc_mcr_dtr == 0) 1290 return; 1291 1292 if (onoff) 1293 SET(sc->sc_mcr, sc->sc_mcr_dtr); 1294 else 1295 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 1296 1297 if (!sc->sc_heldchange) { 1298 if (sc->sc_tx_busy) { 1299 sc->sc_heldtbc = sc->sc_tbc; 1300 sc->sc_tbc = 0; 1301 sc->sc_heldchange = 1; 1302 } else 1303 plcom_loadchannelregs(sc); 1304 } 1305 } 1306 1307 void 1308 tiocm_to_plcom(struct plcom_softc *sc, u_long how, int ttybits) 1309 { 1310 u_char plcombits; 1311 1312 plcombits = 0; 1313 if (ISSET(ttybits, TIOCM_DTR)) 1314 SET(plcombits, PL01X_MCR_DTR); 1315 if (ISSET(ttybits, TIOCM_RTS)) 1316 SET(plcombits, PL01X_MCR_RTS); 1317 1318 switch (how) { 1319 case TIOCMBIC: 1320 CLR(sc->sc_mcr, plcombits); 1321 break; 1322 1323 case TIOCMBIS: 1324 SET(sc->sc_mcr, plcombits); 1325 break; 1326 1327 case TIOCMSET: 1328 CLR(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS); 1329 SET(sc->sc_mcr, plcombits); 1330 break; 1331 } 1332 1333 if (!sc->sc_heldchange) { 1334 if (sc->sc_tx_busy) { 1335 sc->sc_heldtbc = sc->sc_tbc; 1336 sc->sc_tbc = 0; 1337 sc->sc_heldchange = 1; 1338 } else 1339 plcom_loadchannelregs(sc); 1340 } 1341 } 1342 1343 int 1344 plcom_to_tiocm(struct plcom_softc *sc) 1345 { 1346 u_char plcombits; 1347 int ttybits = 0; 1348 1349 plcombits = sc->sc_mcr; 1350 if (ISSET(plcombits, PL01X_MCR_DTR)) 1351 SET(ttybits, TIOCM_DTR); 1352 if (ISSET(plcombits, PL01X_MCR_RTS)) 1353 SET(ttybits, TIOCM_RTS); 1354 1355 plcombits = sc->sc_msr; 1356 if (ISSET(plcombits, PL01X_MSR_DCD)) 1357 SET(ttybits, TIOCM_CD); 1358 if (ISSET(plcombits, PL01X_MSR_CTS)) 1359 SET(ttybits, TIOCM_CTS); 1360 if (ISSET(plcombits, PL01X_MSR_DSR)) 1361 SET(ttybits, TIOCM_DSR); 1362 if (ISSET(plcombits, PL011_MSR_RI)) 1363 SET(ttybits, TIOCM_RI); 1364 1365 if (sc->sc_cr != 0) 1366 SET(ttybits, TIOCM_LE); 1367 1368 return ttybits; 1369 } 1370 1371 static uint32_t 1372 cflag2lcr(tcflag_t cflag) 1373 { 1374 uint32_t lcr = 0; 1375 1376 switch (ISSET(cflag, CSIZE)) { 1377 case CS5: 1378 SET(lcr, PL01X_LCR_5BITS); 1379 break; 1380 case CS6: 1381 SET(lcr, PL01X_LCR_6BITS); 1382 break; 1383 case CS7: 1384 SET(lcr, PL01X_LCR_7BITS); 1385 break; 1386 case CS8: 1387 SET(lcr, PL01X_LCR_8BITS); 1388 break; 1389 } 1390 if (ISSET(cflag, PARENB)) { 1391 SET(lcr, PL01X_LCR_PEN); 1392 if (!ISSET(cflag, PARODD)) 1393 SET(lcr, PL01X_LCR_EPS); 1394 } 1395 if (ISSET(cflag, CSTOPB)) 1396 SET(lcr, PL01X_LCR_STP2); 1397 1398 return lcr; 1399 } 1400 1401 int 1402 plcomparam(struct tty *tp, struct termios *t) 1403 { 1404 struct plcom_softc *sc = 1405 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1406 struct plcom_instance *pi = &sc->sc_pi; 1407 int ospeed = -1, lvl; 1408 uint32_t lcr; 1409 1410 if (PLCOM_ISALIVE(sc) == 0) 1411 return EIO; 1412 1413 switch (pi->pi_type) { 1414 case PLCOM_TYPE_PL010: 1415 ospeed = pl010comspeed(t->c_ospeed, sc->sc_frequency); 1416 break; 1417 case PLCOM_TYPE_PL011: 1418 case PLCOM_TYPE_GENERIC_UART: 1419 ospeed = pl011comspeed(t->c_ospeed, sc->sc_frequency); 1420 break; 1421 } 1422 1423 /* Check requested parameters. */ 1424 if (ospeed < 0) 1425 return EINVAL; 1426 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 1427 return EINVAL; 1428 1429 /* 1430 * For the console, always force CLOCAL and !HUPCL, so that the port 1431 * is always active. 1432 */ 1433 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 1434 ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 1435 SET(t->c_cflag, CLOCAL); 1436 CLR(t->c_cflag, HUPCL); 1437 } 1438 1439 /* 1440 * If there were no changes, don't do anything. This avoids dropping 1441 * input and improves performance when all we did was frob things like 1442 * VMIN and VTIME. 1443 */ 1444 if (tp->t_ospeed == t->c_ospeed && 1445 tp->t_cflag == t->c_cflag) 1446 return 0; 1447 1448 lcr = ISSET(sc->sc_lcr, PL01X_LCR_BRK) | cflag2lcr(t->c_cflag); 1449 1450 mutex_spin_enter(&sc->sc_lock); 1451 1452 sc->sc_lcr = lcr; 1453 1454 /* 1455 * PL010 has a fixed-length FIFO trigger point. 1456 */ 1457 if (ISSET(sc->sc_hwflags, PLCOM_HW_FIFO)) 1458 sc->sc_fifo = 1; 1459 else 1460 sc->sc_fifo = 0; 1461 1462 if (sc->sc_fifo) { 1463 SET(sc->sc_lcr, PL01X_LCR_FEN); 1464 1465 switch (pi->pi_type) { 1466 case PLCOM_TYPE_PL010: 1467 sc->sc_ifls = 0; 1468 break; 1469 case PLCOM_TYPE_PL011: 1470 case PLCOM_TYPE_GENERIC_UART: 1471 lvl = PL011_IFLS_3QUARTERS; 1472 sc->sc_ifls = PL011_IFLS_RXIFLS(lvl); 1473 1474 lvl = PL011_IFLS_1QUARTER; 1475 sc->sc_ifls |= PL011_IFLS_TXIFLS(lvl); 1476 sc->sc_burstlen = uimin(sc->sc_fifolen * 3 / 4, 1); 1477 break; 1478 } 1479 } else 1480 sc->sc_ifls = 0; 1481 1482 /* 1483 * If we're not in a mode that assumes a connection is present, then 1484 * ignore carrier changes. 1485 */ 1486 if (ISSET(t->c_cflag, CLOCAL | MDMBUF)) 1487 sc->sc_msr_dcd = 0; 1488 else 1489 sc->sc_msr_dcd = PL01X_MSR_DCD; 1490 /* 1491 * Set the flow control pins depending on the current flow control 1492 * mode. 1493 */ 1494 if (ISSET(t->c_cflag, CRTSCTS)) { 1495 sc->sc_mcr_dtr = PL01X_MCR_DTR; 1496 1497 switch (pi->pi_type) { 1498 case PLCOM_TYPE_PL010: 1499 sc->sc_mcr_rts = PL01X_MCR_RTS; 1500 sc->sc_msr_cts = PL01X_MSR_CTS; 1501 break; 1502 case PLCOM_TYPE_PL011: 1503 case PLCOM_TYPE_GENERIC_UART: 1504 sc->sc_mcr_rts = 0; 1505 sc->sc_msr_cts = 0; 1506 SET(sc->sc_cr, PL011_CR_CTSEN | PL011_CR_RTSEN); 1507 break; 1508 } 1509 } else if (ISSET(t->c_cflag, MDMBUF)) { 1510 /* 1511 * For DTR/DCD flow control, make sure we don't toggle DTR for 1512 * carrier detection. 1513 */ 1514 sc->sc_mcr_dtr = 0; 1515 sc->sc_mcr_rts = PL01X_MCR_DTR; 1516 sc->sc_msr_cts = PL01X_MSR_DCD; 1517 1518 switch (pi->pi_type) { 1519 case PLCOM_TYPE_PL011: 1520 CLR(sc->sc_cr, PL011_CR_CTSEN | PL011_CR_RTSEN); 1521 break; 1522 } 1523 } else { 1524 /* 1525 * If no flow control, then always set RTS. This will make 1526 * the other side happy if it mistakenly thinks we're doing 1527 * RTS/CTS flow control. 1528 */ 1529 sc->sc_mcr_dtr = PL01X_MCR_DTR | PL01X_MCR_RTS; 1530 sc->sc_mcr_rts = 0; 1531 sc->sc_msr_cts = 0; 1532 if (ISSET(sc->sc_mcr, PL01X_MCR_DTR)) 1533 SET(sc->sc_mcr, PL01X_MCR_RTS); 1534 else 1535 CLR(sc->sc_mcr, PL01X_MCR_RTS); 1536 switch (pi->pi_type) { 1537 case PLCOM_TYPE_PL011: 1538 case PLCOM_TYPE_GENERIC_UART: 1539 CLR(sc->sc_cr, PL011_CR_CTSEN | PL011_CR_RTSEN); 1540 break; 1541 } 1542 } 1543 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd; 1544 1545 #if 0 1546 if (ospeed == 0) 1547 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 1548 else 1549 SET(sc->sc_mcr, sc->sc_mcr_dtr); 1550 #endif 1551 1552 switch (pi->pi_type) { 1553 case PLCOM_TYPE_PL010: 1554 sc->sc_ratel = ospeed & 0xff; 1555 sc->sc_rateh = (ospeed >> 8) & 0xff; 1556 break; 1557 case PLCOM_TYPE_PL011: 1558 case PLCOM_TYPE_GENERIC_UART: 1559 sc->sc_ratel = ospeed & ((1 << 6) - 1); 1560 sc->sc_rateh = ospeed >> 6; 1561 break; 1562 } 1563 1564 /* And copy to tty. */ 1565 tp->t_ispeed = t->c_ospeed; 1566 tp->t_ospeed = t->c_ospeed; 1567 tp->t_cflag = t->c_cflag; 1568 1569 if (!sc->sc_heldchange) { 1570 if (sc->sc_tx_busy) { 1571 sc->sc_heldtbc = sc->sc_tbc; 1572 sc->sc_tbc = 0; 1573 sc->sc_heldchange = 1; 1574 } else 1575 plcom_loadchannelregs(sc); 1576 } 1577 1578 if (!ISSET(t->c_cflag, CHWFLOW)) { 1579 /* Disable the high water mark. */ 1580 sc->sc_r_hiwat = 0; 1581 sc->sc_r_lowat = 0; 1582 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1583 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1584 plcom_schedrx(sc); 1585 } 1586 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 1587 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 1588 plcom_hwiflow(sc); 1589 } 1590 } else { 1591 sc->sc_r_hiwat = plcom_rbuf_hiwat; 1592 sc->sc_r_lowat = plcom_rbuf_lowat; 1593 } 1594 1595 mutex_spin_exit(&sc->sc_lock); 1596 1597 /* 1598 * Update the tty layer's idea of the carrier bit, in case we changed 1599 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 1600 * explicit request. 1601 */ 1602 (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, PL01X_MSR_DCD)); 1603 1604 #ifdef PLCOM_DEBUG 1605 if (plcom_debug) 1606 plcomstatus(sc, "plcomparam "); 1607 #endif 1608 1609 if (!ISSET(t->c_cflag, CHWFLOW)) { 1610 if (sc->sc_tx_stopped) { 1611 sc->sc_tx_stopped = 0; 1612 plcomstart(tp); 1613 } 1614 } 1615 1616 return 0; 1617 } 1618 1619 void 1620 plcom_iflush(struct plcom_softc *sc) 1621 { 1622 struct plcom_instance *pi = &sc->sc_pi; 1623 #ifdef DIAGNOSTIC 1624 int reg; 1625 #endif 1626 int timo; 1627 1628 #ifdef DIAGNOSTIC 1629 reg = 0xffff; 1630 #endif 1631 timo = 50000; 1632 /* flush any pending I/O */ 1633 while (! ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE) 1634 && --timo) 1635 #ifdef DIAGNOSTIC 1636 reg = 1637 #else 1638 (void) 1639 #endif 1640 PREAD1(pi, PL01XCOM_DR); 1641 #ifdef DIAGNOSTIC 1642 if (!timo) 1643 aprint_error_dev(sc->sc_dev, ": %s timeout %02x\n", __func__, 1644 reg); 1645 #endif 1646 } 1647 1648 void 1649 plcom_loadchannelregs(struct plcom_softc *sc) 1650 { 1651 struct plcom_instance *pi = &sc->sc_pi; 1652 uint16_t ifls; 1653 1654 /* XXXXX necessary? */ 1655 plcom_iflush(sc); 1656 1657 switch (pi->pi_type) { 1658 case PLCOM_TYPE_PL010: 1659 PWRITE1(pi, PL010COM_CR, 0); 1660 if (sc->sc_frequency != 0) { 1661 PWRITE1(pi, PL010COM_DLBL, sc->sc_ratel); 1662 PWRITE1(pi, PL010COM_DLBH, sc->sc_rateh); 1663 } 1664 PWRITE1(pi, PL010COM_LCR, sc->sc_lcr); 1665 1666 /* XXX device_unit() abuse */ 1667 if (sc->sc_set_mcr) 1668 sc->sc_set_mcr(sc->sc_set_mcr_arg, 1669 device_unit(sc->sc_dev), 1670 sc->sc_mcr_active = sc->sc_mcr); 1671 1672 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1673 break; 1674 1675 case PLCOM_TYPE_PL011: 1676 case PLCOM_TYPE_GENERIC_UART: 1677 PWRITE2(pi, PL011COM_CR, 0); 1678 if (sc->sc_frequency != 0) { 1679 PWRITE1(pi, PL011COM_FBRD, sc->sc_ratel); 1680 PWRITE4(pi, PL011COM_IBRD, sc->sc_rateh); 1681 } 1682 1683 /* Bits 6..15 are reserved, don't modify, read as zero */ 1684 ifls = PREAD2(pi, PL011COM_IFLS) & ~PL011_IFLS_MASK; 1685 ifls |= sc->sc_ifls & PL011_IFLS_MASK; 1686 PWRITE2(pi, PL011COM_IFLS, ifls); 1687 1688 PWRITE1(pi, PL011COM_LCRH, sc->sc_lcr); 1689 sc->sc_mcr_active = sc->sc_mcr; 1690 CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR)); 1691 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active)); 1692 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 1693 break; 1694 } 1695 } 1696 1697 int 1698 plcomhwiflow(struct tty *tp, int block) 1699 { 1700 struct plcom_softc *sc = 1701 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1702 1703 if (PLCOM_ISALIVE(sc) == 0) 1704 return 0; 1705 1706 if (sc->sc_mcr_rts == 0) 1707 return 0; 1708 1709 mutex_spin_enter(&sc->sc_lock); 1710 1711 if (block) { 1712 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1713 SET(sc->sc_rx_flags, RX_TTY_BLOCKED); 1714 plcom_hwiflow(sc); 1715 } 1716 } else { 1717 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1718 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1719 plcom_schedrx(sc); 1720 } 1721 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1722 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED); 1723 plcom_hwiflow(sc); 1724 } 1725 } 1726 1727 mutex_spin_exit(&sc->sc_lock); 1728 return 1; 1729 } 1730 1731 /* 1732 * (un)block input via hw flowcontrol 1733 */ 1734 void 1735 plcom_hwiflow(struct plcom_softc *sc) 1736 { 1737 struct plcom_instance *pi = &sc->sc_pi; 1738 1739 if (sc->sc_mcr_rts == 0) 1740 return; 1741 1742 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) { 1743 CLR(sc->sc_mcr, sc->sc_mcr_rts); 1744 CLR(sc->sc_mcr_active, sc->sc_mcr_rts); 1745 } else { 1746 SET(sc->sc_mcr, sc->sc_mcr_rts); 1747 SET(sc->sc_mcr_active, sc->sc_mcr_rts); 1748 } 1749 switch (pi->pi_type) { 1750 case PLCOM_TYPE_PL010: 1751 if (sc->sc_set_mcr) 1752 /* XXX device_unit() abuse */ 1753 sc->sc_set_mcr(sc->sc_set_mcr_arg, 1754 device_unit(sc->sc_dev), sc->sc_mcr_active); 1755 break; 1756 case PLCOM_TYPE_PL011: 1757 case PLCOM_TYPE_GENERIC_UART: 1758 CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR)); 1759 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active)); 1760 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 1761 break; 1762 } 1763 } 1764 1765 1766 void 1767 plcomstart(struct tty *tp) 1768 { 1769 struct plcom_softc *sc = 1770 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1771 struct plcom_instance *pi = &sc->sc_pi; 1772 1773 if (PLCOM_ISALIVE(sc) == 0) 1774 return; 1775 1776 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 1777 return; 1778 if (sc->sc_tx_stopped) 1779 return; 1780 1781 if (!ttypull(tp)) 1782 return; 1783 1784 /* Grab the first contiguous region of buffer space. */ 1785 { 1786 u_char *tba; 1787 int tbc; 1788 1789 tba = tp->t_outq.c_cf; 1790 tbc = ndqb(&tp->t_outq, 0); 1791 1792 mutex_spin_enter(&sc->sc_lock); 1793 1794 sc->sc_tba = tba; 1795 sc->sc_tbc = tbc; 1796 } 1797 1798 SET(tp->t_state, TS_BUSY); 1799 sc->sc_tx_busy = 1; 1800 1801 /* Enable transmit completion interrupts if necessary. */ 1802 switch (pi->pi_type) { 1803 case PLCOM_TYPE_PL010: 1804 if (!ISSET(sc->sc_cr, PL010_CR_TIE)) { 1805 SET(sc->sc_cr, PL010_CR_TIE); 1806 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1807 } 1808 break; 1809 case PLCOM_TYPE_PL011: 1810 case PLCOM_TYPE_GENERIC_UART: 1811 if (!ISSET(sc->sc_imsc, PL011_INT_TX)) { 1812 SET(sc->sc_imsc, PL011_INT_TX); 1813 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 1814 } 1815 break; 1816 } 1817 1818 /* Output the first chunk of the contiguous buffer. */ 1819 { 1820 int n; 1821 1822 n = sc->sc_tbc; 1823 if (n > sc->sc_burstlen) 1824 n = sc->sc_burstlen; 1825 PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n); 1826 sc->sc_tbc -= n; 1827 sc->sc_tba += n; 1828 } 1829 mutex_spin_exit(&sc->sc_lock); 1830 } 1831 1832 /* 1833 * Stop output on a line. 1834 */ 1835 void 1836 plcomstop(struct tty *tp, int flag) 1837 { 1838 struct plcom_softc *sc = 1839 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1840 1841 mutex_spin_enter(&sc->sc_lock); 1842 if (ISSET(tp->t_state, TS_BUSY)) { 1843 /* Stop transmitting at the next chunk. */ 1844 sc->sc_tbc = 0; 1845 sc->sc_heldtbc = 0; 1846 if (!ISSET(tp->t_state, TS_TTSTOP)) 1847 SET(tp->t_state, TS_FLUSH); 1848 } 1849 mutex_spin_exit(&sc->sc_lock); 1850 } 1851 1852 void 1853 plcomdiag(void *arg) 1854 { 1855 struct plcom_softc *sc = arg; 1856 int overflows, floods; 1857 1858 mutex_spin_enter(&sc->sc_lock); 1859 overflows = sc->sc_overflows; 1860 sc->sc_overflows = 0; 1861 floods = sc->sc_floods; 1862 sc->sc_floods = 0; 1863 sc->sc_errors = 0; 1864 mutex_spin_exit(&sc->sc_lock); 1865 1866 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1867 device_xname(sc->sc_dev), 1868 overflows, overflows == 1 ? "" : "s", 1869 floods, floods == 1 ? "" : "s"); 1870 } 1871 1872 static inline void 1873 plcom_rxsoft(struct plcom_softc *sc, struct tty *tp) 1874 { 1875 int (*rint) (int, struct tty *) = tp->t_linesw->l_rint; 1876 struct plcom_instance *pi = &sc->sc_pi; 1877 u_char *get, *end; 1878 u_int cc, scc; 1879 u_char rsr; 1880 int code; 1881 1882 end = sc->sc_ebuf; 1883 get = sc->sc_rbget; 1884 scc = cc = plcom_rbuf_size - sc->sc_rbavail; 1885 1886 if (cc == plcom_rbuf_size) { 1887 sc->sc_floods++; 1888 if (sc->sc_errors++ == 0) 1889 callout_reset(&sc->sc_diag_callout, 60 * hz, 1890 plcomdiag, sc); 1891 } 1892 1893 while (cc) { 1894 code = get[0]; 1895 rsr = get[1]; 1896 if (ISSET(rsr, PL01X_RSR_ERROR)) { 1897 if (ISSET(rsr, PL01X_RSR_OE)) { 1898 sc->sc_overflows++; 1899 if (sc->sc_errors++ == 0) 1900 callout_reset(&sc->sc_diag_callout, 1901 60 * hz, plcomdiag, sc); 1902 } 1903 if (ISSET(rsr, PL01X_RSR_BE | PL01X_RSR_FE)) 1904 SET(code, TTY_FE); 1905 if (ISSET(rsr, PL01X_RSR_PE)) 1906 SET(code, TTY_PE); 1907 } 1908 if ((*rint)(code, tp) == -1) { 1909 /* 1910 * The line discipline's buffer is out of space. 1911 */ 1912 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1913 /* 1914 * We're either not using flow control, or the 1915 * line discipline didn't tell us to block for 1916 * some reason. Either way, we have no way to 1917 * know when there's more space available, so 1918 * just drop the rest of the data. 1919 */ 1920 get += cc << 1; 1921 if (get >= end) 1922 get -= plcom_rbuf_size << 1; 1923 cc = 0; 1924 } else { 1925 /* 1926 * Don't schedule any more receive processing 1927 * until the line discipline tells us there's 1928 * space available (through plcomhwiflow()). 1929 * Leave the rest of the data in the input 1930 * buffer. 1931 */ 1932 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1933 } 1934 break; 1935 } 1936 get += 2; 1937 if (get >= end) 1938 get = sc->sc_rbuf; 1939 cc--; 1940 } 1941 if (cc != scc) { 1942 sc->sc_rbget = get; 1943 mutex_spin_enter(&sc->sc_lock); 1944 1945 cc = sc->sc_rbavail += scc - cc; 1946 /* Buffers should be ok again, release possible block. */ 1947 if (cc >= sc->sc_r_lowat) { 1948 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1949 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1950 switch (pi->pi_type) { 1951 case PLCOM_TYPE_PL010: 1952 SET(sc->sc_cr, 1953 PL010_CR_RIE | PL010_CR_RTIE); 1954 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1955 break; 1956 case PLCOM_TYPE_PL011: 1957 case PLCOM_TYPE_GENERIC_UART: 1958 SET(sc->sc_imsc, 1959 PL011_INT_RX | PL011_INT_RT); 1960 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 1961 break; 1962 } 1963 } 1964 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1965 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1966 plcom_hwiflow(sc); 1967 } 1968 } 1969 mutex_spin_exit(&sc->sc_lock); 1970 } 1971 } 1972 1973 static inline void 1974 plcom_txsoft(struct plcom_softc *sc, struct tty *tp) 1975 { 1976 1977 CLR(tp->t_state, TS_BUSY); 1978 if (ISSET(tp->t_state, TS_FLUSH)) 1979 CLR(tp->t_state, TS_FLUSH); 1980 else 1981 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1982 (*tp->t_linesw->l_start)(tp); 1983 } 1984 1985 static inline void 1986 plcom_stsoft(struct plcom_softc *sc, struct tty *tp) 1987 { 1988 u_char msr, delta; 1989 1990 mutex_spin_enter(&sc->sc_lock); 1991 msr = sc->sc_msr; 1992 delta = sc->sc_msr_delta; 1993 sc->sc_msr_delta = 0; 1994 mutex_spin_exit(&sc->sc_lock); 1995 1996 if (ISSET(delta, sc->sc_msr_dcd)) { 1997 /* 1998 * Inform the tty layer that carrier detect changed. 1999 */ 2000 (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, PL01X_MSR_DCD)); 2001 } 2002 2003 if (ISSET(delta, sc->sc_msr_cts)) { 2004 /* Block or unblock output according to flow control. */ 2005 if (ISSET(msr, sc->sc_msr_cts)) { 2006 sc->sc_tx_stopped = 0; 2007 (*tp->t_linesw->l_start)(tp); 2008 } else { 2009 sc->sc_tx_stopped = 1; 2010 } 2011 } 2012 2013 #ifdef PLCOM_DEBUG 2014 if (plcom_debug) 2015 plcomstatus(sc, "plcom_stsoft"); 2016 #endif 2017 } 2018 2019 void 2020 plcomsoft(void *arg) 2021 { 2022 struct plcom_softc *sc = arg; 2023 struct tty *tp; 2024 2025 if (PLCOM_ISALIVE(sc) == 0) 2026 return; 2027 2028 tp = sc->sc_tty; 2029 2030 if (sc->sc_rx_ready) { 2031 sc->sc_rx_ready = 0; 2032 plcom_rxsoft(sc, tp); 2033 } 2034 2035 if (sc->sc_st_check) { 2036 sc->sc_st_check = 0; 2037 plcom_stsoft(sc, tp); 2038 } 2039 2040 if (sc->sc_tx_done) { 2041 sc->sc_tx_done = 0; 2042 plcom_txsoft(sc, tp); 2043 } 2044 } 2045 2046 bool 2047 plcom_intstatus(struct plcom_instance *pi, u_int *istatus) 2048 { 2049 bool ret = false; 2050 u_int stat = 0; 2051 2052 switch (pi->pi_type) { 2053 case PLCOM_TYPE_PL010: 2054 stat = PREAD1(pi, PL010COM_IIR); 2055 ret = ISSET(stat, PL010_IIR_IMASK); 2056 break; 2057 case PLCOM_TYPE_PL011: 2058 case PLCOM_TYPE_GENERIC_UART: 2059 stat = PREAD4(pi, PL011COM_MIS); 2060 ret = ISSET(stat, PL011_INT_ALLMASK); 2061 break; 2062 } 2063 *istatus = stat; 2064 2065 return ret; 2066 } 2067 2068 int 2069 plcomintr(void *arg) 2070 { 2071 struct plcom_softc *sc = arg; 2072 struct plcom_instance *pi = &sc->sc_pi; 2073 u_char *put, *end; 2074 u_int cc; 2075 u_int istatus = 0; 2076 u_char rsr; 2077 bool intr = false; 2078 2079 PLCOM_BARRIER(pi, BR | BW); 2080 2081 if (PLCOM_ISALIVE(sc) == 0) 2082 return 0; 2083 2084 mutex_spin_enter(&sc->sc_lock); 2085 intr = plcom_intstatus(pi, &istatus); 2086 if (!intr) { 2087 mutex_spin_exit(&sc->sc_lock); 2088 return 0; 2089 } 2090 2091 end = sc->sc_ebuf; 2092 put = sc->sc_rbput; 2093 cc = sc->sc_rbavail; 2094 2095 do { 2096 u_int msr = 0, delta, fr; 2097 bool rxintr = false, txintr = false, msintr; 2098 2099 /* don't need RI here*/ 2100 fr = PREAD1(pi, PL01XCOM_FR); 2101 2102 if (!ISSET(fr, PL01X_FR_RXFE) && 2103 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 2104 while (cc > 0) { 2105 int cn_trapped = 0; 2106 put[0] = PREAD1(pi, PL01XCOM_DR); 2107 rsr = PREAD1(pi, PL01XCOM_RSR); 2108 /* Clear any error status. */ 2109 if (ISSET(rsr, PL01X_RSR_ERROR)) 2110 PWRITE1(pi, PL01XCOM_ECR, 0); 2111 2112 if (ISSET(rsr, PL01X_RSR_BE)) { 2113 cn_trapped = 0; 2114 cn_check_magic(sc->sc_tty->t_dev, 2115 CNC_BREAK, plcom_cnm_state); 2116 if (cn_trapped) 2117 continue; 2118 #if defined(KGDB) 2119 if (ISSET(sc->sc_hwflags, 2120 PLCOM_HW_KGDB)) { 2121 kgdb_connect(1); 2122 continue; 2123 } 2124 #endif 2125 } 2126 2127 put[1] = rsr; 2128 cn_trapped = 0; 2129 cn_check_magic(sc->sc_tty->t_dev, put[0], 2130 plcom_cnm_state); 2131 if (cn_trapped) { 2132 fr = PREAD1(pi, PL01XCOM_FR); 2133 if (ISSET(fr, PL01X_FR_RXFE)) 2134 break; 2135 2136 continue; 2137 } 2138 put += 2; 2139 if (put >= end) 2140 put = sc->sc_rbuf; 2141 cc--; 2142 2143 /* don't need RI here*/ 2144 fr = PREAD1(pi, PL01XCOM_FR); 2145 if (ISSET(fr, PL01X_FR_RXFE)) 2146 break; 2147 } 2148 2149 /* 2150 * Current string of incoming characters ended because 2151 * no more data was available or we ran out of space. 2152 * Schedule a receive event if any data was received. 2153 * If we're out of space, turn off receive interrupts. 2154 */ 2155 sc->sc_rbput = put; 2156 sc->sc_rbavail = cc; 2157 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 2158 sc->sc_rx_ready = 1; 2159 2160 /* 2161 * See if we are in danger of overflowing a buffer. If 2162 * so, use hardware flow control to ease the pressure. 2163 */ 2164 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 2165 cc < sc->sc_r_hiwat) { 2166 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 2167 plcom_hwiflow(sc); 2168 } 2169 2170 /* 2171 * If we're out of space, disable receive interrupts 2172 * until the queue has drained a bit. 2173 */ 2174 if (!cc) { 2175 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 2176 switch (pi->pi_type) { 2177 case PLCOM_TYPE_PL010: 2178 CLR(sc->sc_cr, 2179 PL010_CR_RIE | PL010_CR_RTIE); 2180 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 2181 break; 2182 case PLCOM_TYPE_PL011: 2183 case PLCOM_TYPE_GENERIC_UART: 2184 CLR(sc->sc_imsc, 2185 PL011_INT_RT | PL011_INT_RX); 2186 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 2187 break; 2188 } 2189 } 2190 } else { 2191 switch (pi->pi_type) { 2192 case PLCOM_TYPE_PL010: 2193 rxintr = ISSET(istatus, PL010_IIR_RIS); 2194 if (rxintr) { 2195 PWRITE1(pi, PL010COM_CR, 0); 2196 delay(10); 2197 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 2198 continue; 2199 } 2200 break; 2201 case PLCOM_TYPE_PL011: 2202 case PLCOM_TYPE_GENERIC_UART: 2203 rxintr = ISSET(istatus, PL011_INT_RX); 2204 if (rxintr) { 2205 PWRITE2(pi, PL011COM_CR, 0); 2206 delay(10); 2207 PWRITE2(pi, PL011COM_CR, sc->sc_cr); 2208 continue; 2209 } 2210 break; 2211 } 2212 } 2213 2214 switch (pi->pi_type) { 2215 case PLCOM_TYPE_PL010: 2216 msr = PREAD1(pi, PL01XCOM_FR); 2217 break; 2218 case PLCOM_TYPE_PL011: 2219 case PLCOM_TYPE_GENERIC_UART: 2220 msr = PREAD4(pi, PL01XCOM_FR); 2221 break; 2222 } 2223 delta = msr ^ sc->sc_msr; 2224 sc->sc_msr = msr; 2225 2226 /* Clear any pending modem status interrupt. */ 2227 switch (pi->pi_type) { 2228 case PLCOM_TYPE_PL010: 2229 msintr = ISSET(istatus, PL010_IIR_MIS); 2230 if (msintr) { 2231 PWRITE1(pi, PL010COM_ICR, 0); 2232 } 2233 break; 2234 case PLCOM_TYPE_PL011: 2235 case PLCOM_TYPE_GENERIC_UART: 2236 msintr = ISSET(istatus, PL011_INT_MSMASK); 2237 if (msintr) { 2238 PWRITE4(pi, PL011COM_ICR, PL011_INT_MSMASK); 2239 } 2240 break; 2241 } 2242 /* 2243 * Pulse-per-second (PSS) signals on edge of DCD? 2244 * Process these even if line discipline is ignoring DCD. 2245 */ 2246 if (delta & sc->sc_ppsmask) { 2247 struct timeval tv; 2248 mutex_spin_enter(&timecounter_lock); 2249 if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) { 2250 /* XXX nanotime() */ 2251 microtime(&tv); 2252 TIMEVAL_TO_TIMESPEC(&tv, 2253 &sc->ppsinfo.assert_timestamp); 2254 if (sc->ppsparam.mode & PPS_OFFSETASSERT) { 2255 timespecadd(&sc->ppsinfo.assert_timestamp, 2256 &sc->ppsparam.assert_offset, 2257 &sc->ppsinfo.assert_timestamp); 2258 } 2259 2260 #ifdef PPS_SYNC 2261 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) 2262 hardpps(&tv, tv.tv_usec); 2263 #endif 2264 sc->ppsinfo.assert_sequence++; 2265 sc->ppsinfo.current_mode = sc->ppsparam.mode; 2266 2267 } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) { 2268 /* XXX nanotime() */ 2269 microtime(&tv); 2270 TIMEVAL_TO_TIMESPEC(&tv, 2271 &sc->ppsinfo.clear_timestamp); 2272 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) { 2273 timespecadd(&sc->ppsinfo.clear_timestamp, 2274 &sc->ppsparam.clear_offset, 2275 &sc->ppsinfo.clear_timestamp); 2276 } 2277 2278 #ifdef PPS_SYNC 2279 if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR) 2280 hardpps(&tv, tv.tv_usec); 2281 #endif 2282 sc->ppsinfo.clear_sequence++; 2283 sc->ppsinfo.current_mode = sc->ppsparam.mode; 2284 } 2285 mutex_spin_exit(&timecounter_lock); 2286 } 2287 2288 /* 2289 * Process normal status changes 2290 */ 2291 if (ISSET(delta, sc->sc_msr_mask)) { 2292 SET(sc->sc_msr_delta, delta); 2293 2294 /* 2295 * Stop output immediately if we lose the output 2296 * flow control signal or carrier detect. 2297 */ 2298 if (ISSET(~msr, sc->sc_msr_mask)) { 2299 sc->sc_tbc = 0; 2300 sc->sc_heldtbc = 0; 2301 #ifdef PLCOM_DEBUG 2302 if (plcom_debug) 2303 plcomstatus(sc, "plcomintr "); 2304 #endif 2305 } 2306 2307 sc->sc_st_check = 1; 2308 } 2309 2310 /* 2311 * Done handling any receive interrupts. See if data 2312 * can be transmitted as well. Schedule tx done 2313 * event if no data left and tty was marked busy. 2314 */ 2315 2316 switch (pi->pi_type) { 2317 case PLCOM_TYPE_PL010: 2318 txintr = ISSET(istatus, PL010_IIR_TIS); 2319 break; 2320 case PLCOM_TYPE_PL011: 2321 txintr = ISSET(istatus, PL011_INT_TX); 2322 break; 2323 } 2324 if (txintr) { 2325 /* 2326 * If we've delayed a parameter change, do it 2327 * now, and restart * output. 2328 */ 2329 // PWRITE4(pi, PL011COM_ICR, PL011_INT_TX); 2330 if (sc->sc_heldchange) { 2331 plcom_loadchannelregs(sc); 2332 sc->sc_heldchange = 0; 2333 sc->sc_tbc = sc->sc_heldtbc; 2334 sc->sc_heldtbc = 0; 2335 } 2336 2337 /* 2338 * Output the next chunk of the contiguous 2339 * buffer, if any. 2340 */ 2341 if (sc->sc_tbc > 0) { 2342 int n; 2343 2344 n = sc->sc_tbc; 2345 if (n > sc->sc_burstlen) 2346 n = sc->sc_burstlen; 2347 PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n); 2348 sc->sc_tbc -= n; 2349 sc->sc_tba += n; 2350 } else { 2351 /* 2352 * Disable transmit completion 2353 * interrupts if necessary. 2354 */ 2355 switch (pi->pi_type) { 2356 case PLCOM_TYPE_PL010: 2357 if (ISSET(sc->sc_cr, PL010_CR_TIE)) { 2358 CLR(sc->sc_cr, PL010_CR_TIE); 2359 PWRITE1(pi, PL010COM_CR, 2360 sc->sc_cr); 2361 } 2362 break; 2363 case PLCOM_TYPE_PL011: 2364 case PLCOM_TYPE_GENERIC_UART: 2365 if (ISSET(sc->sc_imsc, PL011_INT_TX)) { 2366 CLR(sc->sc_imsc, PL011_INT_TX); 2367 PWRITE4(pi, PL011COM_IMSC, 2368 sc->sc_imsc); 2369 } 2370 break; 2371 } 2372 if (sc->sc_tx_busy) { 2373 sc->sc_tx_busy = 0; 2374 sc->sc_tx_done = 1; 2375 } 2376 } 2377 } 2378 2379 } while (plcom_intstatus(pi, &istatus)); 2380 2381 mutex_spin_exit(&sc->sc_lock); 2382 2383 /* Wake up the poller. */ 2384 if ((sc->sc_rx_ready | sc->sc_st_check | sc->sc_tx_done) != 0) 2385 softint_schedule(sc->sc_si); 2386 2387 #ifdef RND_COM 2388 rnd_add_uint32(&sc->rnd_source, istatus | rsr); 2389 #endif 2390 2391 PLCOM_BARRIER(pi, BR | BW); 2392 2393 return 1; 2394 } 2395 2396 /* 2397 * The following functions are polled getc and putc routines, shared 2398 * by the console and kgdb glue. 2399 * 2400 * The read-ahead code is so that you can detect pending in-band 2401 * cn_magic in polled mode while doing output rather than having to 2402 * wait until the kernel decides it needs input. 2403 */ 2404 2405 #define MAX_READAHEAD 20 2406 static int plcom_readahead[MAX_READAHEAD]; 2407 static int plcom_readaheadcount = 0; 2408 2409 int 2410 plcom_common_getc(dev_t dev, struct plcom_instance *pi) 2411 { 2412 int s = splserial(); 2413 u_char c; 2414 2415 /* got a character from reading things earlier */ 2416 if (plcom_readaheadcount > 0) { 2417 int i; 2418 2419 c = plcom_readahead[0]; 2420 for (i = 1; i < plcom_readaheadcount; i++) { 2421 plcom_readahead[i-1] = plcom_readahead[i]; 2422 } 2423 plcom_readaheadcount--; 2424 splx(s); 2425 return c; 2426 } 2427 2428 if (ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) { 2429 splx(s); 2430 return -1; 2431 } 2432 2433 c = PREAD1(pi, PL01XCOM_DR); 2434 { 2435 int cn_trapped __unused = 0; 2436 2437 if (!db_active) 2438 cn_check_magic(dev, c, plcom_cnm_state); 2439 } 2440 splx(s); 2441 return c; 2442 } 2443 2444 void 2445 plcom_common_putc(dev_t dev, struct plcom_instance *pi, int c) 2446 { 2447 int s = splserial(); 2448 int timo; 2449 2450 int cin, stat; 2451 if (plcom_readaheadcount < MAX_READAHEAD 2452 && !ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) { 2453 int cn_trapped __unused = 0; 2454 cin = PREAD1(pi, PL01XCOM_DR); 2455 cn_check_magic(dev, cin, plcom_cnm_state); 2456 plcom_readahead[plcom_readaheadcount++] = cin; 2457 } 2458 2459 /* wait for any pending transmission to finish */ 2460 timo = 150000; 2461 while (ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFF) && --timo) 2462 continue; 2463 2464 PWRITE1(pi, PL01XCOM_DR, c); 2465 PLCOM_BARRIER(pi, BR | BW); 2466 2467 splx(s); 2468 } 2469 2470 /* 2471 * Initialize UART for use as console or KGDB line. 2472 */ 2473 int 2474 plcominit(struct plcom_instance *pi, int rate, int frequency, tcflag_t cflag) 2475 { 2476 uint32_t lcr; 2477 2478 switch (pi->pi_type) { 2479 case PLCOM_TYPE_PL010: 2480 if (pi->pi_size == 0) 2481 pi->pi_size = PL010COM_UART_SIZE; 2482 break; 2483 case PLCOM_TYPE_PL011: 2484 case PLCOM_TYPE_GENERIC_UART: 2485 if (pi->pi_size == 0) 2486 pi->pi_size = PL011COM_UART_SIZE; 2487 break; 2488 default: 2489 panic("Unknown plcom type"); 2490 } 2491 2492 if (bus_space_map(pi->pi_iot, pi->pi_iobase, pi->pi_size, 0, 2493 &pi->pi_ioh)) 2494 return ENOMEM; /* ??? */ 2495 2496 lcr = cflag2lcr(cflag) | PL01X_LCR_FEN; 2497 switch (pi->pi_type) { 2498 case PLCOM_TYPE_PL010: 2499 PWRITE1(pi, PL010COM_CR, 0); 2500 2501 if (rate && frequency) { 2502 rate = pl010comspeed(rate, frequency); 2503 PWRITE1(pi, PL010COM_DLBL, (rate & 0xff)); 2504 PWRITE1(pi, PL010COM_DLBH, ((rate >> 8) & 0xff)); 2505 } 2506 PWRITE1(pi, PL010COM_LCR, lcr); 2507 PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN); 2508 break; 2509 case PLCOM_TYPE_PL011: 2510 case PLCOM_TYPE_GENERIC_UART: 2511 PWRITE2(pi, PL011COM_CR, 0); 2512 2513 if (rate && frequency) { 2514 rate = pl011comspeed(rate, frequency); 2515 PWRITE1(pi, PL011COM_FBRD, rate & ((1 << 6) - 1)); 2516 PWRITE4(pi, PL011COM_IBRD, rate >> 6); 2517 } 2518 PWRITE1(pi, PL011COM_LCRH, lcr); 2519 PWRITE2(pi, PL011COM_CR, 2520 PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE); 2521 break; 2522 } 2523 2524 #if 0 2525 /* Ought to do something like this, but we have no sc to 2526 dereference. */ 2527 /* XXX device_unit() abuse */ 2528 sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev), 2529 PL01X_MCR_DTR | PL01X_MCR_RTS); 2530 #endif 2531 2532 return 0; 2533 } 2534 2535 /* 2536 * Following are all routines needed for PLCOM to act as console 2537 */ 2538 struct consdev plcomcons = { 2539 NULL, NULL, plcomcngetc, plcomcnputc, plcomcnpollc, NULL, 2540 plcomcnhalt, NULL, NODEV, CN_NORMAL 2541 }; 2542 2543 int 2544 plcomcnattach(struct plcom_instance *pi, int rate, int frequency, 2545 tcflag_t cflag, int unit) 2546 { 2547 int res; 2548 2549 plcomcons_info = *pi; 2550 2551 res = plcominit(&plcomcons_info, rate, frequency, cflag); 2552 if (res) 2553 return res; 2554 2555 cn_tab = &plcomcons; 2556 cn_init_magic(&plcom_cnm_state); 2557 cn_set_magic("\047\001"); /* default magic is BREAK */ 2558 2559 plcomconsunit = unit; 2560 plcomconsrate = rate; 2561 plcomconscflag = cflag; 2562 2563 return 0; 2564 } 2565 2566 void 2567 plcomcndetach(void) 2568 { 2569 2570 bus_space_unmap(plcomcons_info.pi_iot, plcomcons_info.pi_ioh, 2571 plcomcons_info.pi_size); 2572 plcomcons_info.pi_iot = NULL; 2573 2574 cn_tab = NULL; 2575 } 2576 2577 int 2578 plcomcngetc(dev_t dev) 2579 { 2580 return plcom_common_getc(dev, &plcomcons_info); 2581 } 2582 2583 /* 2584 * Console kernel output character routine. 2585 */ 2586 void 2587 plcomcnputc(dev_t dev, int c) 2588 { 2589 plcom_common_putc(dev, &plcomcons_info, c); 2590 } 2591 2592 void 2593 plcomcnpollc(dev_t dev, int on) 2594 { 2595 2596 plcom_readaheadcount = 0; 2597 } 2598 2599 void 2600 plcomcnhalt(dev_t dev) 2601 { 2602 struct plcom_instance *pi = &plcomcons_info; 2603 2604 switch (pi->pi_type) { 2605 case PLCOM_TYPE_PL010: 2606 PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN); 2607 break; 2608 case PLCOM_TYPE_PL011: 2609 case PLCOM_TYPE_GENERIC_UART: 2610 PWRITE2(pi, PL011COM_CR, 2611 PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE); 2612 PWRITE4(pi, PL011COM_IMSC, 0); 2613 break; 2614 } 2615 } 2616 2617 #ifdef KGDB 2618 int 2619 plcom_kgdb_attach(struct plcom_instance *pi, int rate, int frequency, 2620 tcflag_t cflag, int unit) 2621 { 2622 int res; 2623 2624 if (pi->pi_iot == plcomcons_info.pi_iot && 2625 pi->pi_iobase == plcomcons_info.pi_iobase) 2626 return EBUSY; /* cannot share with console */ 2627 2628 res = plcominit(pi, rate, frequency, cflag); 2629 if (res) 2630 return res; 2631 2632 kgdb_attach(plcom_kgdb_getc, plcom_kgdb_putc, NULL); 2633 kgdb_dev = 123; /* unneeded, only to satisfy some tests */ 2634 2635 plcomkgdb_info.pi_iot = pi->pi_iot; 2636 plcomkgdb_info.pi_ioh = pi->pi_ioh; 2637 plcomkgdb_info.pi_iobase = pi->pi_iobase; 2638 2639 return 0; 2640 } 2641 2642 /* ARGSUSED */ 2643 int 2644 plcom_kgdb_getc(void *arg) 2645 { 2646 return plcom_common_getc(NODEV, &plcomkgdb_info); 2647 } 2648 2649 /* ARGSUSED */ 2650 void 2651 plcom_kgdb_putc(void *arg, int c) 2652 { 2653 plcom_common_putc(NODEV, &plcomkgdb_info, c); 2654 } 2655 #endif /* KGDB */ 2656 2657 /* helper function to identify the plcom ports used by 2658 console or KGDB (and not yet autoconf attached) */ 2659 int 2660 plcom_is_console(bus_space_tag_t iot, bus_addr_t iobase, 2661 bus_space_handle_t *ioh) 2662 { 2663 bus_space_handle_t help; 2664 2665 if (!plcomconsattached && 2666 bus_space_is_equal(iot, plcomcons_info.pi_iot) && 2667 iobase == plcomcons_info.pi_iobase) 2668 help = plcomcons_info.pi_ioh; 2669 #ifdef KGDB 2670 else if (!plcom_kgdb_attached && 2671 bus_space_is_equal(iot, plcomkgdb_info.pi_iot) && 2672 iobase == plcomkgdb_info.pi_iobase) 2673 help = plcomkgdb_info.pi_ioh; 2674 #endif 2675 else 2676 return 0; 2677 2678 if (ioh) 2679 *ioh = help; 2680 return 1; 2681 } 2682