1 /* $Id: at91dbgu.c,v 1.3 2009/03/14 15:36:01 dsl Exp $ */
2 /* $NetBSD: at91dbgu.c,v 1.2 2008/07/03 01:15:38 matt Exp $ */
6 * Copyright (c) 1998, 1999, 2001, 2002, 2004 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
12 * This code is derived from software contributed to The NetBSD Foundation
13 * by Ichiro FUKUHARA and Naoto Shimazaki.
15 * This code is derived from software contributed to The NetBSD Foundation
16 * by IWAMOTO Toshihiro.
18 * This code is derived from software contributed to The NetBSD Foundation
19 * by Charles M. Hannum.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
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.
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.
51 * Copyright (c) 1991 The Regents of the University of California.
52 * All rights reserved.
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
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.
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
78 * @(#)com.c 7.5 (Berkeley) 5/16/91
82 * TODO: hardware flow control
85 #include <sys/cdefs.h>
86 __KERNEL_RCSID(0, "$NetBSD: at91dbgu.c,v 1.2 2008/07/03 01:15:38 matt Exp $");
92 #if NRND > 0 && defined(RND_COM)
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*!
104 console_debugger(); \
106 } while (/* CONSTCOND */ 0)
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>
119 #include <sys/vnode.h>
120 #include <sys/kauth.h>
122 #include <machine/intr.h>
123 #include <machine/bus.h>
125 #include <arm/at91/at91reg.h>
126 #include <arm/at91/at91var.h>
127 #include <arm/at91/at91dbguvar.h>
128 #include <arm/at91/at91dbgureg.h>
130 #include <dev/cons.h>
132 static int at91dbgu_match(device_t
, cfdata_t
, void *);
133 static void at91dbgu_attach(device_t
, device_t
, void *);
135 static int at91dbgu_param(struct tty
*, struct termios
*);
136 static void at91dbgu_start(struct tty
*);
137 static int at91dbgu_hwiflow(struct tty
*, int);
140 static u_int
cflag2lcrhi(tcflag_t
);
142 static void at91dbgu_iflush(struct at91dbgu_softc
*);
143 static void at91dbgu_set(struct at91dbgu_softc
*);
145 int at91dbgu_cn_getc(dev_t
);
146 void at91dbgu_cn_putc(dev_t
, int);
147 void at91dbgu_cn_pollc(dev_t
, int);
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
*);
153 void at91dbgu_cn_probe(struct consdev
*);
154 void at91dbgu_cn_init(struct consdev
*);
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
;
165 u_int8_t sc_rx_fifo
[64];
168 static struct cnm_state at91dbgu_cnm_state
;
170 CFATTACH_DECL(at91dbgu
, sizeof(struct at91dbgu_softc
),
171 at91dbgu_match
, at91dbgu_attach
, NULL
, NULL
);
173 extern struct cfdriver at91dbgu_cd
;
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
);
184 const struct cdevsw at91dbgu_cdevsw
= {
185 at91dbgu_open
, at91dbgu_close
, at91dbgu_read
, at91dbgu_write
, at91dbgu_ioctl
,
186 at91dbgu_stop
, at91dbgu_tty
, at91dbgu_poll
, nommap
, ttykqfilter
, D_TTY
189 struct consdev at91dbgu_cons
= {
190 at91dbgu_cn_probe
, NULL
, at91dbgu_cn_getc
, at91dbgu_cn_putc
, at91dbgu_cn_pollc
, NULL
,
191 NULL
, NULL
, NODEV
, CN_REMOTE
194 #ifndef DEFAULT_COMSPEED
195 #define DEFAULT_COMSPEED 115200
198 #define COMUNIT_MASK 0x7ffff
199 #define COMDIALOUT_MASK 0x80000
201 #define COMUNIT(x) (minor(x) & COMUNIT_MASK)
202 #define COMDIALOUT(x) (minor(x) & COMDIALOUT_MASK)
204 #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev))
207 at91dbgu_match(device_t parent
, cfdata_t match
, void *aux
)
209 if (strcmp(match
->cf_name
, "at91dbgu") == 0)
215 dbgu_intr(void* arg
);
218 at91dbgu_attach(device_t parent
, device_t self
, void *aux
)
220 struct at91dbgu_softc
*sc
= device_private(self
);
221 struct at91bus_attach_args
*sa
= aux
;
227 bus_space_map(sa
->sa_iot
, sa
->sa_addr
, sa
->sa_size
, 0, &sc
->sc_ioh
);
228 sc
->sc_iot
= sa
->sa_iot
;
229 sc
->sc_hwbase
= sa
->sa_addr
;
231 DBGUREG(DBGU_IDR
) = -1;
232 at91_intr_establish(sa
->sa_pid
, IPL_SERIAL
, INTR_HIGH_LEVEL
, dbgu_intr
, sc
);
233 DBGU_INIT(AT91_MSTCLK
, 115200U);
235 if (sc
->sc_iot
== dbgu_cn_sc
.sc_iot
236 && sc
->sc_hwbase
== dbgu_cn_sc
.sc_hwbase
) {
237 dbgu_cn_sc
.sc_attached
= 1;
238 /* Make sure the console is always "hardwired". */
239 delay(10000); /* wait for output to finish */
240 SET(sc
->sc_hwflags
, COM_HW_CONSOLE
);
241 SET(sc
->sc_swflags
, TIOCFLAG_SOFTCAR
);
242 SET(sc
->sc_ier
, DBGU_INT_RXRDY
);
243 DBGUREG(DBGU_IER
) = DBGU_INT_RXRDY
; // @@@@@
247 tp
->t_oproc
= at91dbgu_start
;
248 tp
->t_param
= at91dbgu_param
;
249 tp
->t_hwiflow
= at91dbgu_hwiflow
;
252 sc
->sc_rbuf
= malloc(AT91DBGU_RING_SIZE
<< 1, M_DEVBUF
, M_NOWAIT
);
253 sc
->sc_rbput
= sc
->sc_rbget
= sc
->sc_rbuf
;
254 sc
->sc_rbavail
= AT91DBGU_RING_SIZE
;
255 if (sc
->sc_rbuf
== NULL
) {
256 printf("%s: unable to allocate ring buffer\n",
257 device_xname(sc
->sc_dev
));
260 sc
->sc_ebuf
= sc
->sc_rbuf
+ (AT91DBGU_RING_SIZE
<< 1);
265 if (ISSET(sc
->sc_hwflags
, COM_HW_CONSOLE
)) {
268 /* locate the major number */
269 maj
= cdevsw_lookup_major(&at91dbgu_cdevsw
);
271 cn_tab
->cn_dev
= makedev(maj
, device_unit(sc
->sc_dev
));
273 aprint_normal("%s: console (maj %u min %u cn_dev %u)\n",
274 device_xname(sc
->sc_dev
), maj
, device_unit(sc
->sc_dev
),
278 sc
->sc_si
= softint_establish(SOFTINT_SERIAL
, at91dbgu_soft
, sc
);
280 #if NRND > 0 && defined(RND_COM)
281 rnd_attach_source(&sc
->rnd_source
, device_xname(sc
->sc_dev
),
285 /* if there are no enable/disable functions, assume the device
290 /* XXX configure register */
293 SET(sc
->sc_hwflags
, COM_HW_DEV_OK
);
297 at91dbgu_param(struct tty
*tp
, struct termios
*t
)
299 struct at91dbgu_softc
*sc
300 = device_lookup_private(&at91dbgu_cd
, COMUNIT(tp
->t_dev
));
303 if (COM_ISALIVE(sc
) == 0)
306 if (t
->c_ispeed
&& t
->c_ispeed
!= t
->c_ospeed
)
310 * For the console, always force CLOCAL and !HUPCL, so that the port
313 if (ISSET(sc
->sc_swflags
, TIOCFLAG_SOFTCAR
) ||
314 ISSET(sc
->sc_hwflags
, COM_HW_CONSOLE
)) {
315 SET(t
->c_cflag
, CLOCAL
);
316 CLR(t
->c_cflag
, HUPCL
);
320 * If there were no changes, don't do anything. This avoids dropping
321 * input and improves performance when all we did was frob things like
324 if (tp
->t_ospeed
== t
->c_ospeed
&&
325 tp
->t_cflag
== t
->c_cflag
)
330 sc
->sc_brgr
= (AT91_MSTCLK
/ 16 + t
->c_ospeed
/ 2) / t
->c_ospeed
;
332 /* And copy to tty. */
334 tp
->t_ospeed
= t
->c_ospeed
;
335 tp
->t_cflag
= t
->c_cflag
;
341 * Update the tty layer's idea of the carrier bit.
342 * We tell tty the carrier is always on.
344 (void) (*tp
->t_linesw
->l_modem
)(tp
, 1);
348 comstatus(sc
, "comparam ");
351 if (!ISSET(t
->c_cflag
, CHWFLOW
)) {
352 if (sc
->sc_tx_stopped
) {
353 sc
->sc_tx_stopped
= 0;
362 at91dbgu_hwiflow(struct tty
*tp
, int block
)
368 at91dbgu_filltx(struct at91dbgu_softc
*sc
)
371 bus_space_tag_t iot
= sc
->sc_iot
;
372 bus_space_handle_t ioh
= sc
->sc_ioh
;
377 while (DBGUREG(DBGU_SR
) & DBGU_SR_TXRDY
) {
380 DBGUREG(DBGU_THR
) = *(sc
->sc_tba
+ n
) & 0xff;
388 at91dbgu_start(struct tty
*tp
)
390 struct at91dbgu_softc
*sc
391 = device_lookup_private(&at91dbgu_cd
, COMUNIT(tp
->t_dev
));
394 if (COM_ISALIVE(sc
) == 0)
398 if (ISSET(tp
->t_state
, TS_BUSY
| TS_TIMEOUT
| TS_TTSTOP
))
400 if (sc
->sc_tx_stopped
)
405 /* Grab the first contiguous region of buffer space. */
410 tba
= tp
->t_outq
.c_cf
;
411 tbc
= ndqb(&tp
->t_outq
, 0);
419 SET(tp
->t_state
, TS_BUSY
);
422 /* Output the first chunk of the contiguous buffer. */
425 SET(sc
->sc_ier
, DBGU_INT_TXRDY
);
426 DBGUREG(DBGU_IER
) = DBGU_INT_TXRDY
;
434 at91dbgu_break(struct at91dbgu_softc
*sc
, int onoff
)
436 // @@@ we must disconnect the TX pin from the DBGU and control
437 // @@@ the pin directly to support this...
441 at91dbgu_shutdown(struct at91dbgu_softc
*sc
)
447 /* Turn off interrupts. */
448 DBGUREG(DBGU_IDR
) = -1;
450 /* Clear any break condition set with TIOCSBRK. */
451 at91dbgu_break(sc
, 0);
457 panic("at91dbgu_shutdown: not enabled?");
466 at91dbgu_open(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
468 struct at91dbgu_softc
*sc
;
473 sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
474 if (sc
== NULL
|| !ISSET(sc
->sc_hwflags
, COM_HW_DEV_OK
) ||
478 if (!device_is_active(sc
->sc_dev
))
483 * If this is the kgdb port, no other use is permitted.
485 if (ISSET(sc
->sc_hwflags
, COM_HW_KGDB
))
491 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
497 * Do the following iff this is a first open.
499 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
507 if ((*sc
->enable
)(sc
)) {
510 printf("%s: device enable failed\n",
511 device_xname(sc
->sc_dev
));
516 /* XXXXXXXXXXXXXXX */
521 /* Turn on interrupts. */
522 sc
->sc_ier
|= DBGU_INT_RXRDY
;
523 DBGUREG(DBGU_IER
) = DBGU_INT_RXRDY
;
526 /* Fetch the current modem control status, needed later. */
527 sc
->sc_msr
= bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, com_msr
);
529 /* Clear PPS capture state on first open. */
531 sc
->ppsparam
.mode
= 0;
537 * Initialize the termios status to the defaults. Add in the
538 * sticky bits from TIOCSFLAGS.
541 if (ISSET(sc
->sc_hwflags
, COM_HW_CONSOLE
)) {
542 t
.c_ospeed
= dbgu_cn_sc
.sc_ospeed
;
543 t
.c_cflag
= dbgu_cn_sc
.sc_cflag
;
545 t
.c_ospeed
= TTYDEF_SPEED
;
546 t
.c_cflag
= TTYDEF_CFLAG
;
548 if (ISSET(sc
->sc_swflags
, TIOCFLAG_CLOCAL
))
549 SET(t
.c_cflag
, CLOCAL
);
550 if (ISSET(sc
->sc_swflags
, TIOCFLAG_CRTSCTS
))
551 SET(t
.c_cflag
, CRTSCTS
);
552 if (ISSET(sc
->sc_swflags
, TIOCFLAG_MDMBUF
))
553 SET(t
.c_cflag
, MDMBUF
);
554 /* Make sure at91dbgu_param() will do something. */
556 (void) at91dbgu_param(tp
, &t
);
557 tp
->t_iflag
= TTYDEF_IFLAG
;
558 tp
->t_oflag
= TTYDEF_OFLAG
;
559 tp
->t_lflag
= TTYDEF_LFLAG
;
565 /* Clear the input ring, and unblock. */
566 sc
->sc_rbput
= sc
->sc_rbget
= sc
->sc_rbuf
;
567 sc
->sc_rbavail
= AT91DBGU_RING_SIZE
;
569 CLR(sc
->sc_rx_flags
, RX_ANY_BLOCK
);
573 comstatus(sc
, "at91dbgu_open ");
581 error
= ttyopen(tp
, COMDIALOUT(dev
), ISSET(flag
, O_NONBLOCK
));
585 error
= (*tp
->t_linesw
->l_open
)(dev
, tp
);
592 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
594 * We failed to open the device, and nobody else had it opened.
595 * Clean up the state as appropriate.
597 at91dbgu_shutdown(sc
);
604 at91dbgu_close(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
606 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
607 struct tty
*tp
= sc
->sc_tty
;
609 /* XXX This is for cons.c. */
610 if (!ISSET(tp
->t_state
, TS_ISOPEN
))
613 (*tp
->t_linesw
->l_close
)(tp
, flag
);
616 if (COM_ISALIVE(sc
) == 0)
619 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
621 * Although we got a last close, the device may still be in
622 * use; e.g. if this was the dialout node, and there are still
623 * processes waiting for carrier on the non-dialout node.
625 at91dbgu_shutdown(sc
);
632 at91dbgu_read(dev_t dev
, struct uio
*uio
, int flag
)
634 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
635 struct tty
*tp
= sc
->sc_tty
;
637 if (COM_ISALIVE(sc
) == 0)
640 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
644 at91dbgu_write(dev_t dev
, struct uio
*uio
, int flag
)
646 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
647 struct tty
*tp
= sc
->sc_tty
;
649 if (COM_ISALIVE(sc
) == 0)
652 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
656 at91dbgu_poll(dev_t dev
, int events
, struct lwp
*l
)
658 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
659 struct tty
*tp
= sc
->sc_tty
;
661 if (COM_ISALIVE(sc
) == 0)
664 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
668 at91dbgu_tty(dev_t dev
)
670 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
671 struct tty
*tp
= sc
->sc_tty
;
677 at91dbgu_ioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
679 struct at91dbgu_softc
*sc
= device_lookup_private(&at91dbgu_cd
, COMUNIT(dev
));
680 struct tty
*tp
= sc
->sc_tty
;
684 if (COM_ISALIVE(sc
) == 0)
687 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, l
);
688 if (error
!= EPASSTHROUGH
)
691 error
= ttioctl(tp
, cmd
, data
, flag
, l
);
692 if (error
!= EPASSTHROUGH
)
701 at91dbgu_break(sc
, 1);
705 at91dbgu_break(sc
, 0);
709 *(int *)data
= sc
->sc_swflags
;
713 error
= kauth_authorize_device_tty(l
->l_cred
,
714 KAUTH_DEVICE_TTY_PRIVSET
, tp
);
717 sc
->sc_swflags
= *(int *)data
;
721 error
= EPASSTHROUGH
;
731 * Stop output on a line.
734 at91dbgu_stop(struct tty
*tp
, int flag
)
736 struct at91dbgu_softc
*sc
737 = device_lookup_private(&at91dbgu_cd
, COMUNIT(tp
->t_dev
));
741 if (ISSET(tp
->t_state
, TS_BUSY
)) {
742 /* Stop transmitting at the next chunk. */
744 if (!ISSET(tp
->t_state
, TS_TTSTOP
))
745 SET(tp
->t_state
, TS_FLUSH
);
752 cflag2lcrhi(tcflag_t cflag
)
756 switch (cflag
& CSIZE
) {
762 mr
|= (cflag
& PARENB
) ? LinCtrlHigh_PEN
: 0;
763 mr
|= (cflag
& PARODD
) ? 0 : LinCtrlHigh_EPS
;
764 mr
|= (cflag
& CSTOPB
) ? LinCtrlHigh_STP2
: 0;
765 mr
|= LinCtrlHigh_FEN
; /* FIFO always enabled */
767 mr
|= DBGU_MR_PAR_NONE
;
773 at91dbgu_iflush(struct at91dbgu_softc
*sc
)
776 bus_space_tag_t iot
= sc
->sc_iot
;
777 bus_space_handle_t ioh
= sc
->sc_ioh
;
788 /* flush any pending I/O */
789 while (DBGUREG(DBGU_SR
) & DBGU_SR_RXRDY
799 printf("%s: com_iflush timeout %02x\n", device_xname(sc
->sc_dev
),
805 at91dbgu_set(struct at91dbgu_softc
*sc
)
807 DBGUREG(DBGU_MR
) = DBGU_MR_PAR_NONE
;
808 DBGUREG(DBGU_BRGR
) = sc
->sc_brgr
;
809 DBGUREG(DBGU_CR
) = DBGU_CR_TXEN
| DBGU_CR_RXEN
; // @@@ just in case
813 at91dbgu_cn_attach(bus_space_tag_t iot
, bus_addr_t iobase
, bus_space_handle_t ioh
,
814 int ospeed
, tcflag_t cflag
);
816 at91dbgu_cn_attach(bus_space_tag_t iot
, bus_addr_t iobase
, bus_space_handle_t ioh
,
817 int ospeed
, tcflag_t cflag
)
819 cn_tab
= &at91dbgu_cons
;
820 cn_init_magic(&at91dbgu_cnm_state
);
821 cn_set_magic("\047\001");
823 dbgu_cn_sc
.sc_iot
= iot
;
824 dbgu_cn_sc
.sc_ioh
= ioh
;
825 dbgu_cn_sc
.sc_hwbase
= iobase
;
826 dbgu_cn_sc
.sc_ospeed
= ospeed
;
827 dbgu_cn_sc
.sc_cflag
= cflag
;
829 DBGU_INIT(AT91_MSTCLK
, ospeed
);
832 void at91dbgu_attach_cn(bus_space_tag_t iot
, int ospeed
, int cflag
)
834 bus_space_handle_t ioh
;
835 bus_space_map(iot
, AT91DBGU_BASE
, AT91DBGU_SIZE
, 0, &ioh
);
836 at91dbgu_cn_attach(iot
, AT91DBGU_BASE
, ioh
, ospeed
, cflag
);
840 at91dbgu_cn_probe(struct consdev
*cp
)
842 cp
->cn_pri
= CN_REMOTE
;
846 at91dbgu_cn_pollc(dev_t dev
, int on
)
849 // enable polling mode
850 DBGUREG(DBGU_IDR
) = DBGU_INT_RXRDY
;
852 // disable polling mode
853 DBGUREG(DBGU_IER
) = DBGU_INT_RXRDY
;
858 at91dbgu_cn_putc(dev_t dev
, int c
)
861 bus_space_tag_t iot
= dbgu_cn_sc
.sc_iot
;
862 bus_space_handle_t ioh
= dbgu_cn_sc
.sc_ioh
;
869 while((DBGUREG(DBGU_SR
) & DBGU_SR_TXEMPTY
) == 0) {
880 at91dbgu_cn_getc(dev_t dev
)
885 bus_space_tag_t iot
= dbgu_cn_sc
.sc_iot
;
886 bus_space_handle_t ioh
= dbgu_cn_sc
.sc_ioh
;
891 while ((c
= DBGU_PEEKC()) == -1) {
896 sr
= DBGUREG(DBGU_SR
);
897 if (ISSET(sr
, DBGU_SR_FRAME
) && c
== 0) {
898 DBGUREG(DBGU_CR
) = DBGU_CR_RSTSTA
; // reset status bits
902 extern int db_active
;
906 int cn_trapped
= 0; /* unused */
908 cn_check_magic(dev
, c
, at91dbgu_cnm_state
);
918 at91dbgu_txsoft(struct at91dbgu_softc
*sc
, struct tty
*tp
)
920 CLR(tp
->t_state
, TS_BUSY
);
921 if (ISSET(tp
->t_state
, TS_FLUSH
))
922 CLR(tp
->t_state
, TS_FLUSH
);
924 ndflush(&tp
->t_outq
, (int)(sc
->sc_tba
- tp
->t_outq
.c_cf
));
925 (*tp
->t_linesw
->l_start
)(tp
);
929 at91dbgu_rxsoft(struct at91dbgu_softc
*sc
, struct tty
*tp
)
931 int (*rint
)(int, struct tty
*) = tp
->t_linesw
->l_rint
;
940 scc
= cc
= AT91DBGU_RING_SIZE
- sc
->sc_rbavail
;
942 if (cc
== AT91DBGU_RING_SIZE
) {
944 if (sc
->sc_errors
++ == 0)
945 callout_reset(&sc
->sc_diag_callout
, 60 * hz
,
952 if (ISSET(sts
, DBGU_SR_PARE
| DBGU_SR_FRAME
| DBGU_SR_OVRE
)) {
954 if (ISSET(lsr
, DR_ROR
)) {
956 if (sc
->sc_errors
++ == 0)
957 callout_reset(&sc
->sc_diag_callout
,
958 60 * hz
, comdiag
, sc
);
961 if (ISSET(sts
, (DBGU_SR_FRAME
| DBGU_SR_OVRE
)))
963 if (ISSET(sts
, DBGU_SR_PARE
))
966 if ((*rint
)(code
, tp
) == -1) {
968 * The line discipline's buffer is out of space.
970 if (!ISSET(sc
->sc_rx_flags
, RX_TTY_BLOCKED
)) {
972 * We're either not using flow control, or the
973 * line discipline didn't tell us to block for
974 * some reason. Either way, we have no way to
975 * know when there's more space available, so
976 * just drop the rest of the data.
980 get
-= AT91DBGU_RING_SIZE
<< 1;
984 * Don't schedule any more receive processing
985 * until the line discipline tells us there's
986 * space available (through comhwiflow()).
987 * Leave the rest of the data in the input
990 SET(sc
->sc_rx_flags
, RX_TTY_OVERFLOWED
);
1004 cc
= sc
->sc_rbavail
+= scc
- cc
;
1005 /* Buffers should be ok again, release possible block. */
1007 if (ISSET(sc
->sc_rx_flags
, RX_IBUF_OVERFLOWED
)) {
1008 CLR(sc
->sc_rx_flags
, RX_IBUF_OVERFLOWED
);
1009 DBGUREG(DBGU_IER
) = DBGU_INT_RXRDY
;
1011 if (ISSET(sc
->sc_rx_flags
, RX_IBUF_BLOCKED
)) {
1012 CLR(sc
->sc_rx_flags
, RX_IBUF_BLOCKED
);
1023 at91dbgu_soft(void* arg
)
1025 struct at91dbgu_softc
*sc
= arg
;
1027 if (COM_ISALIVE(sc
) == 0)
1030 if (sc
->sc_rx_ready
) {
1031 sc
->sc_rx_ready
= 0;
1032 at91dbgu_rxsoft(sc
, sc
->sc_tty
);
1034 if (sc
->sc_tx_done
) {
1036 at91dbgu_txsoft(sc
, sc
->sc_tty
);
1042 dbgu_intr(void* arg
)
1044 struct at91dbgu_softc
*sc
= arg
;
1046 bus_space_tag_t iot
= sc
->sc_iot
;
1047 bus_space_handle_t ioh
= sc
->sc_ioh
;
1053 imr
= DBGUREG(DBGU_IMR
);
1058 sr
= DBGUREG(DBGU_SR
);
1060 if (sr
& DBGU_SR_RXRDY
) {
1061 // printf("sr=0x%08x imr=0x%08x\n", sr, imr);
1068 cc
= sc
->sc_rbavail
;
1070 // ok, we DO have some interrupts to serve!
1071 if (sr
& DBGU_SR_RXRDY
) {
1074 c
= DBGUREG(DBGU_RHR
);
1075 if (ISSET(sr
, (DBGU_SR_OVRE
| DBGU_SR_FRAME
| DBGU_SR_PARE
)))
1076 DBGUREG(DBGU_CR
) = DBGU_CR_RSTSTA
;
1077 if (ISSET(sr
, DBGU_SR_FRAME
) && c
== 0) {
1081 extern int db_active
;
1084 cn_check_magic(cn_tab
->cn_dev
, c
, at91dbgu_cnm_state
);
1085 if (!cn_trapped
&& cc
) {
1093 * Current string of incoming characters ended because
1094 * no more data was available or we ran out of space.
1095 * Schedule a receive event if any data was received.
1096 * If we're out of space, turn off receive interrupts.
1099 sc
->sc_rbavail
= cc
;
1100 if (!ISSET(sc
->sc_rx_flags
, RX_TTY_OVERFLOWED
))
1101 sc
->sc_rx_ready
= 1;
1104 * See if we are in danger of overflowing a buffer. If
1105 * so, use hardware flow control to ease the pressure.
1108 /* but at91dbgu cannot (yet). X-( */
1111 * If we're out of space, disable receive interrupts
1112 * until the queue has drained a bit.
1115 SET(sc
->sc_rx_flags
, RX_IBUF_OVERFLOWED
);
1121 * Done handling any receive interrupts. See if data can be
1122 * transmitted as well. Schedule tx done event if no data left
1123 * and tty was marked busy.
1126 if (ISSET(sr
, DBGU_SR_TXRDY
) && sc
->sc_tbc
> 0) {
1127 /* Output the next chunk of the contiguous buffer, if any. */
1128 at91dbgu_filltx(sc
);
1130 /* Disable transmit completion interrupts if necessary. */
1131 DBGUREG(DBGU_IDR
) = DBGU_INT_TXRDY
;
1132 if (sc
->sc_tx_busy
) {
1138 /* Wake up the poller. */
1139 softint_schedule(sc
->sc_si
);
1141 #if NRND > 0 && defined(RND_COM)
1142 rnd_add_uint32(&sc
->rnd_source
, imr
^ sr
^ c
);