comconsole.c revision 120118
118334Speter/* 2169689Skan * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) 390075Sobrien * 418334Speter * Redistribution and use in source and binary forms, with or without 590075Sobrien * modification, are permitted provided that the following conditions 618334Speter * are met: 790075Sobrien * 1. Redistributions of source code must retain the above copyright 890075Sobrien * notice, this list of conditions and the following disclaimer. 990075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1090075Sobrien * notice, this list of conditions and the following disclaimer in the 1118334Speter * documentation and/or other materials provided with the distribution. 1290075Sobrien * 1390075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1490075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1590075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1618334Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1718334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1890075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19169689Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20169689Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2118334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2290075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2390075Sobrien * SUCH DAMAGE. 2418334Speter */ 2550397Sobrien 2652284Sobrien#include <sys/cdefs.h> 2752284Sobrien__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/comconsole.c 120118 2003-09-16 11:24:23Z bde $"); 2890075Sobrien 29117395Skan#include <stand.h> 30169689Skan#include <bootstrap.h> 31169689Skan#include <machine/cpufunc.h> 32169689Skan#include <dev/ic/ns16550.h> 3318334Speter#include "libi386.h" 3490075Sobrien 3590075Sobrien#define COMC_FMT 0x3 /* 8N1 */ 36169689Skan#define COMC_TXWAIT 0x40000 /* transmit timeout */ 3790075Sobrien#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */ 3890075Sobrien 3918334Speter#ifndef COMPORT 40169689Skan#ifdef PC98 41169689Skan#define COMPORT 0x238 42169689Skan#else 43169689Skan#define COMPORT 0x3f8 44169689Skan#endif 45169689Skan#endif 4690075Sobrien#ifndef COMSPEED 47169689Skan#define COMSPEED 9600 4890075Sobrien#endif 4950397Sobrien 5050397Sobrienstatic void comc_probe(struct console *cp); 5118334Speterstatic int comc_init(int arg); 5250397Sobrienstatic void comc_putchar(int c); 5350397Sobrienstatic int comc_getchar(void); 5418334Speterstatic int comc_ischar(void); 5590075Sobrien 5690075Sobrienstatic int comc_started; 5790075Sobrien 5850397Sobrienstruct console comconsole = { 59169689Skan "comconsole", 6018334Speter "serial port", 6150397Sobrien 0, 62169689Skan comc_probe, 6318334Speter comc_init, 6450397Sobrien comc_putchar, 65169689Skan comc_getchar, 6618334Speter comc_ischar 6790075Sobrien}; 68169689Skan 6990075Sobrienstatic void 7050397Sobriencomc_probe(struct console *cp) 7150397Sobrien{ 72169689Skan /* XXX check the BIOS equipment list? */ 7318334Speter cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); 7450397Sobrien} 7550397Sobrien 7650397Sobrienstatic int 7750397Sobriencomc_init(int arg) 7850397Sobrien{ 7950397Sobrien if (comc_started && arg == 0) 8050397Sobrien return 0; 8150397Sobrien comc_started = 1; 8250397Sobrien 8350397Sobrien outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT); 84132718Skan outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff); 8550397Sobrien outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8); 8650397Sobrien outb(COMPORT + com_cfcr, COMC_FMT); 8750397Sobrien outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR); 8890075Sobrien 8950397Sobrien do 9050397Sobrien inb(COMPORT + com_data); 91169689Skan while (inb(COMPORT + com_lsr) & LSR_RXRDY); 92169689Skan 9350397Sobrien return(0); 9490075Sobrien} 95169689Skan 96169689Skanstatic void 9750397Sobriencomc_putchar(int c) 9850397Sobrien{ 9950397Sobrien int wait; 10090075Sobrien 101169689Skan for (wait = COMC_TXWAIT; wait > 0; wait--) 102169689Skan if (inb(COMPORT + com_lsr) & LSR_TXRDY) { 10350397Sobrien outb(COMPORT + com_data, (u_char)c); 10450397Sobrien break; 10550397Sobrien } 10690075Sobrien} 107169689Skan 108169689Skanstatic int 10950397Sobriencomc_getchar(void) 110132718Skan{ 111132718Skan return(comc_ischar() ? inb(COMPORT + com_data) : -1); 112132718Skan} 113132718Skan 114132718Skanstatic int 11590075Sobriencomc_ischar(void) 11690075Sobrien{ 11752284Sobrien return(inb(COMPORT + com_lsr) & LSR_RXRDY); 118169689Skan} 119169689Skan