comconsole.c revision 119482
1119482Sobrien/*-
238465Smsmith * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
338465Smsmith *
438465Smsmith * Redistribution and use in source and binary forms, with or without
538465Smsmith * modification, are permitted provided that the following conditions
638465Smsmith * are met:
738465Smsmith * 1. Redistributions of source code must retain the above copyright
838465Smsmith *    notice, this list of conditions and the following disclaimer.
938465Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1038465Smsmith *    notice, this list of conditions and the following disclaimer in the
1138465Smsmith *    documentation and/or other materials provided with the distribution.
1238465Smsmith *
1338465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1438465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1538465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1638465Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1738465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1838465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1938465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2038465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2138465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2238465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2338465Smsmith * SUCH DAMAGE.
2438465Smsmith */
2538465Smsmith
26119482Sobrien#include <sys/cdefs.h>
27119482Sobrien__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/comconsole.c 119482 2003-08-25 23:28:32Z obrien $");
28119482Sobrien
2938465Smsmith#include <stand.h>
3039441Smsmith#include <bootstrap.h>
3141285Srnordier#include <machine/cpufunc.h>
3239441Smsmith#include "libi386.h"
3338465Smsmith
3441285Srnordier/* selected defines from ns16550.h */
3541285Srnordier#define	com_data	0	/* data register (R/W) */
3641285Srnordier#define	com_dlbl	0	/* divisor latch low (W) */
3741285Srnordier#define	com_dlbh	1	/* divisor latch high (W) */
3841285Srnordier#define	com_ier		1	/* interrupt enable (W) */
3941285Srnordier#define	com_iir		2	/* interrupt identification (R) */
4041285Srnordier#define	com_fifo	2	/* FIFO control (W) */
4141285Srnordier#define	com_lctl	3	/* line control register (R/W) */
4241285Srnordier#define	com_cfcr	3	/* line control register (R/W) */
4341285Srnordier#define	com_mcr		4	/* modem control register (R/W) */
4441285Srnordier#define	com_lsr		5	/* line status register (R/W) */
4541285Srnordier#define	com_msr		6	/* modem status register (R/W) */
4641285Srnordier
4741285Srnordier/* selected defines from sioreg.h */
4841285Srnordier#define	CFCR_DLAB	0x80
4941285Srnordier#define	MCR_RTS		0x02
5041285Srnordier#define	MCR_DTR		0x01
5141285Srnordier#define	LSR_TXRDY	0x20
5241285Srnordier#define	LSR_RXRDY	0x01
5341285Srnordier
5441285Srnordier#define COMC_FMT	0x3		/* 8N1 */
5541285Srnordier#define COMC_TXWAIT	0x40000		/* transmit timeout */
5641285Srnordier#define COMC_BPS(x)	(115200 / (x))	/* speed to DLAB divisor */
5741285Srnordier
5842480Srnordier#ifndef	COMPORT
5941285Srnordier#define COMPORT		0x3f8
6042480Srnordier#endif
6142480Srnordier#ifndef	COMSPEED
6241285Srnordier#define COMSPEED	9600
6342480Srnordier#endif
6441285Srnordier
6538465Smsmithstatic void	comc_probe(struct console *cp);
6638465Smsmithstatic int	comc_init(int arg);
6739441Smsmithstatic void	comc_putchar(int c);
6839441Smsmithstatic int	comc_getchar(void);
6939441Smsmithstatic int	comc_ischar(void);
7038465Smsmith
7140211Speterstatic int	comc_started;
7240211Speter
7338465Smsmithstruct console comconsole = {
7438465Smsmith    "comconsole",
7541285Srnordier    "serial port",
7638465Smsmith    0,
7738465Smsmith    comc_probe,
7838465Smsmith    comc_init,
7939441Smsmith    comc_putchar,
8039441Smsmith    comc_getchar,
8139441Smsmith    comc_ischar
8238465Smsmith};
8338465Smsmith
8438465Smsmithstatic void
8538465Smsmithcomc_probe(struct console *cp)
8638465Smsmith{
8738465Smsmith    /* XXX check the BIOS equipment list? */
8838465Smsmith    cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
8938465Smsmith}
9038465Smsmith
9138465Smsmithstatic int
9238465Smsmithcomc_init(int arg)
9338465Smsmith{
9440211Speter    if (comc_started && arg == 0)
9540211Speter	return 0;
9640211Speter    comc_started = 1;
9740211Speter
9841285Srnordier    outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
9941285Srnordier    outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff);
10041285Srnordier    outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8);
10141285Srnordier    outb(COMPORT + com_cfcr, COMC_FMT);
10241285Srnordier    outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
10340211Speter
10441285Srnordier    do
10541285Srnordier        inb(COMPORT + com_data);
10641285Srnordier    while (inb(COMPORT + com_lsr) & LSR_RXRDY);
10741285Srnordier
10840211Speter    return(0);
10938465Smsmith}
11038465Smsmith
11139441Smsmithstatic void
11239441Smsmithcomc_putchar(int c)
11339441Smsmith{
11441285Srnordier    int wait;
11541285Srnordier
11641285Srnordier    for (wait = COMC_TXWAIT; wait > 0; wait--)
11741285Srnordier        if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
11864187Sjhb	    outb(COMPORT + com_data, (u_char)c);
11941285Srnordier	    break;
12041285Srnordier	}
12139441Smsmith}
12239441Smsmith
12338465Smsmithstatic int
12439441Smsmithcomc_getchar(void)
12538465Smsmith{
12641285Srnordier    return(comc_ischar() ? inb(COMPORT + com_data) : -1);
12738465Smsmith}
12839441Smsmith
12939441Smsmithstatic int
13039441Smsmithcomc_ischar(void)
13139441Smsmith{
13241285Srnordier    return(inb(COMPORT + com_lsr) & LSR_RXRDY);
13339441Smsmith}
134