125540Sdfr/*- 225540Sdfr * Copyright (c) 2008 TAKAHASHI Yoshihiro 325540Sdfr * Copyright (c) 2003 M. Warner Losh, Marcel Moolenaar 425540Sdfr * All rights reserved. 525540Sdfr * 625540Sdfr * Redistribution and use in source and binary forms, with or without 725540Sdfr * modification, are permitted provided that the following conditions 825540Sdfr * are met: 925540Sdfr * 1025540Sdfr * 1. Redistributions of source code must retain the above copyright 1125540Sdfr * notice, this list of conditions and the following disclaimer. 1225540Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1325540Sdfr * notice, this list of conditions and the following disclaimer in the 1425540Sdfr * documentation and/or other materials provided with the distribution. 1525540Sdfr * 1625540Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1725540Sdfr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1825540Sdfr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1925540Sdfr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2025540Sdfr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2125540Sdfr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2225540Sdfr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2325540Sdfr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2425540Sdfr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2525540Sdfr * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2630573Sjmg */ 2725540Sdfr 2825540Sdfr#include <sys/cdefs.h> 2930573Sjmg__FBSDID("$FreeBSD$"); 3025540Sdfr 3130573Sjmg#include <sys/param.h> 3225540Sdfr#include <sys/systm.h> 3325540Sdfr#include <sys/bus.h> 3425540Sdfr 3525540Sdfr#include <machine/bus.h> 3625540Sdfr 3725540Sdfr#include <dev/uart/uart.h> 3830573Sjmg#include <dev/uart/uart_cpu.h> 3930573Sjmg 4030573Sjmgbus_space_tag_t uart_bus_space_io = X86_BUS_SPACE_IO; 4125540Sdfrbus_space_tag_t uart_bus_space_mem = X86_BUS_SPACE_MEM; 4225540Sdfr 4325540Sdfrstatic struct { 4425540Sdfr u_long iobase; 4525540Sdfr struct uart_class *class; 4625540Sdfr} uart_pc98_devs[] = { 4725540Sdfr { 0x238, &uart_ns8250_class }, 4825540Sdfr { 0, NULL } 4930573Sjmg}; 5025540Sdfr 5125540Sdfrstruct uart_class * 5225540Sdfruart_pc98_getdev(u_long port) 5325540Sdfr{ 5425540Sdfr int i; 5525540Sdfr 5625540Sdfr for (i = 0; uart_pc98_devs[i].iobase; i++) { 5725540Sdfr if (port == uart_pc98_devs[i].iobase) 5825540Sdfr return (uart_pc98_devs[i].class); 5925540Sdfr } 6025540Sdfr return (NULL); 6130573Sjmg} 6225540Sdfr 6330573Sjmgint 6425540Sdfruart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) 6525540Sdfr{ 6625540Sdfr 6725540Sdfr if (bus_space_compare(b1->bst, b1->bsh, b2->bst, b2->bsh) == 0) 6825540Sdfr return (1); 6925540Sdfr 7025540Sdfr return (0); 7125540Sdfr} 7225540Sdfr 7325540Sdfrint 7425540Sdfruart_cpu_getdev(int devtype, struct uart_devinfo *di) 7525540Sdfr{ 7625540Sdfr struct uart_class *class; 7725540Sdfr unsigned int i, ivar; 7825540Sdfr 7925540Sdfr class = &uart_ns8250_class; 8025540Sdfr if (class == NULL) 8125540Sdfr return (ENXIO); 8225540Sdfr 8325540Sdfr /* Check the environment. */ 8425540Sdfr if (uart_getenv(devtype, di, class) == 0) 8525540Sdfr return (0); 8625540Sdfr 8725540Sdfr /* 8825540Sdfr * There is a serial port on all pc98 hardware. It is 8251 or 8925540Sdfr * an enhance version of that. Some pc98 have the second serial 9025540Sdfr * port which is 16550A compatible. 9125540Sdfr */ 9225540Sdfr for (i = 0; i < 2; i++) { 9325540Sdfr if (resource_int_value("uart", i, "flags", &ivar)) 9425540Sdfr continue; 9525540Sdfr if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar)) 9625540Sdfr continue; 9725540Sdfr if (devtype == UART_DEV_DBGPORT && !UART_FLAGS_DBGPORT(ivar)) 9825540Sdfr continue; 9925540Sdfr /* 10025540Sdfr * We have a possible device. Make sure it's enabled and 10125540Sdfr * that we have an I/O port. 10225540Sdfr */ 10325540Sdfr if (resource_int_value("uart", i, "disabled", &ivar) == 0 && 10425540Sdfr ivar != 0) 10525540Sdfr continue; 10625540Sdfr if (resource_int_value("uart", i, "port", &ivar) != 0 || 10725540Sdfr ivar == 0) 10825540Sdfr continue; 10925540Sdfr 11025540Sdfr class = uart_pc98_getdev(ivar); 11125540Sdfr if (class == NULL) 11225540Sdfr continue; 11325540Sdfr 11425540Sdfr di->ops = uart_getops(class); 11525540Sdfr di->bas.chan = 0; 11625540Sdfr di->bas.bst = uart_bus_space_io; 11725540Sdfr if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0, 11825540Sdfr &di->bas.bsh) != 0) 11925540Sdfr continue; 12025540Sdfr di->bas.regshft = 0; 12125540Sdfr di->bas.rclk = 0; 12225540Sdfr if (resource_int_value("uart", i, "baud", &ivar) != 0) 12325540Sdfr ivar = 0; 12425540Sdfr di->baudrate = ivar; 125 di->databits = 8; 126 di->stopbits = 1; 127 di->parity = UART_PARITY_NONE; 128 return (0); 129 } 130 131 return (ENXIO); 132} 133