From owner-svn-src-projects@FreeBSD.ORG Tue Nov 24 07:50:20 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7C9221065672; Tue, 24 Nov 2009 07:50:20 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6AEEB8FC13; Tue, 24 Nov 2009 07:50:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAO7oKMG009623; Tue, 24 Nov 2009 07:50:20 GMT (envelope-from imp@svn.freebsd.org) Received: (from imp@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAO7oK13009620; Tue, 24 Nov 2009 07:50:20 GMT (envelope-from imp@svn.freebsd.org) Message-Id: <200911240750.nAO7oK13009620@svn.freebsd.org> From: Warner Losh Date: Tue, 24 Nov 2009 07:50:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199738 - projects/mips/sys/mips/octeon1 X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Nov 2009 07:50:20 -0000 Author: imp Date: Tue Nov 24 07:50:19 2009 New Revision: 199738 URL: http://svn.freebsd.org/changeset/base/199738 Log: Rewrite to try to be more sane: o Introduce a uart bus space so that we don't have to hack dev/uart to do 8 byte reads. This also handles the shift properly, so reset the shift we want dev/uart doing to 0. In effect, this bus space makes the octeon registers have an interface to dev/uart that looks just like the old ISA bus, but does the necessary 64-bit read/write to the bus. We only support read/write operations. We do all the widths, but likely could get away with only 64-bit and 8-bit given the restricted nature of use of this bus. o use bus_space_map to set the .bsh rather than a direct assignment. o Minor cleanup of uart_cpu_getdev to make it conform more to the other implementations. o Add some coments for future work. # with these changes, we now make it through cninit, but there's still some # problem that's preventing output, as well as another problem that causes # us to call panic just after we return from cninit() in platform_start. Modified: projects/mips/sys/mips/octeon1/uart_bus_octeonusart.c projects/mips/sys/mips/octeon1/uart_cpu_octeonusart.c Modified: projects/mips/sys/mips/octeon1/uart_bus_octeonusart.c ============================================================================== --- projects/mips/sys/mips/octeon1/uart_bus_octeonusart.c Tue Nov 24 07:41:15 2009 (r199737) +++ projects/mips/sys/mips/octeon1/uart_bus_octeonusart.c Tue Nov 24 07:50:19 2009 (r199738) @@ -92,23 +92,23 @@ uart_octeon_probe(device_t dev) struct uart_softc *sc; int unit; -/* - * Note that both tty0 & tty1 are viable consoles. We add child devices - * such that ttyu0 ends up front of queue. - */ unit = device_get_unit(dev); sc = device_get_softc(dev); - sc->sc_sysdev = NULL; + sc->sc_class = &uart_oct16550_class; + +#if 1 + /* + * We inherit the settings from the systme console. Note, the bst + * bad bus_space_map are bogus here, but obio doesn't yet support + * them, it seems. + */ sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - if (!unit) { - sc->sc_sysdev->bas.bst = 0; - sc->sc_sysdev->bas.bsh = OCTEON_UART0ADR; - } - sc->sc_class = &uart_oct16550_class; - sc->sc_bas.bst = 0; - sc->sc_bas.bsh = unit ? OCTEON_UART1ADR : OCTEON_UART0ADR; - sc->sc_bas.regshft = 0x3; + sc->sc_bas.bst = uart_bus_space_mem; + if (bus_space_map(sc->sc_bas.bst, OCTEON_UART0ADR, OCTEON_UART_SIZE, + 0, &sc->sc_bas.bsh) != 0) + return (ENXIO); +#endif return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit)); } @@ -118,6 +118,4 @@ octeon_uart_identify(driver_t * drv, dev BUS_ADD_CHILD(parent, 0, "uart", 0); } - - DRIVER_MODULE(uart, obio, uart_octeon_driver, uart_devclass, 0, 0); Modified: projects/mips/sys/mips/octeon1/uart_cpu_octeonusart.c ============================================================================== --- projects/mips/sys/mips/octeon1/uart_cpu_octeonusart.c Tue Nov 24 07:41:15 2009 (r199737) +++ projects/mips/sys/mips/octeon1/uart_cpu_octeonusart.c Tue Nov 24 07:50:19 2009 (r199738) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009 M. Warner Losh * Copyright (c) 2006 Wojciech A. Koszek * All rights reserved. * @@ -25,14 +26,6 @@ * * $Id$ */ -/* - * Skeleton of this file was based on respective code for ARM - * code written by Olivier Houchard. - */ -/* - * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is - * experimental and was written for MIPS32 port. - */ #include "opt_uart.h" #include @@ -49,42 +42,150 @@ __FBSDID("$FreeBSD$"); #include #include +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* + * Specailized uart bus space. We present a 1 apart byte oriented + * bus to the outside world, but internally translate to/from the 8-apart + * 64-bit word bus that's on the octeon. We only support simple read/write + * in this space. Everything else is undefined. + */ + +static uint8_t +ou_bs_r_1(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint16_t +ou_bs_r_2(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint32_t +ou_bs_r_4(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint64_t +ou_bs_r_8(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static void +ou_bs_w_1(void *t, bus_space_handle_t bsh, bus_size_t offset, uint8_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_2(void *t, bus_space_handle_t bsh, bus_size_t offset, uint16_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_4(void *t, bus_space_handle_t bsh, bus_size_t offset, uint32_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_8(void *t, bus_space_handle_t bsh, bus_size_t offset, uint64_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static struct bus_space octeon_uart_tag = { + .bs_map = generic_bs_map, + .bs_unmap = generic_bs_unmap, + .bs_subregion = generic_bs_subregion, + .bs_barrier = generic_bs_barrier, + .bs_r_1 = ou_bs_r_1, + .bs_r_2 = ou_bs_r_2, + .bs_r_4 = ou_bs_r_4, + .bs_r_8 = ou_bs_r_8, + .bs_w_1 = ou_bs_w_1, + .bs_w_2 = ou_bs_w_2, + .bs_w_4 = ou_bs_w_4, + .bs_w_8 = ou_bs_w_8, +}; + extern struct uart_class uart_oct16550_class; -extern struct uart_ops octeon_usart_ops; -extern struct bus_space octeon_bs_tag; int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); - return (0); } int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - struct uart_class *class; + struct uart_class *class = &uart_oct16550_class; - class = &uart_oct16550_class; + /* + * These fields need to be setup corretly for uart_getenv to + * work in all cases. + */ + uart_bus_space_io = NULL; /* No io map for this device */ + uart_bus_space_mem = &octeon_uart_tag; + di->bas.bst = uart_bus_space_mem; + + /* + * If env specification for UART exists it takes precedence: + * hw.uart.console="mm:0xf1012000" or similar + */ + if (uart_getenv(devtype, di, class) == 0) + return (0); + + /* + * Fallback to UART0 for console. + */ di->ops = uart_getops(class); - di->bas.bst = 0; di->bas.chan = 0; - di->bas.regshft = 3; /* Each UART reg is 8 byte addresss apart. 1 - * << 3 */ + if (bus_space_map(di->bas.bst, OCTEON_UART0ADR, OCTEON_UART_SIZE, + 0, &di->bas.bsh) != 0) + return (ENXIO); + di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; - di->bas.bsh = OCTEON_UART0ADR; - uart_getenv(devtype, di, class); - - uart_bus_space_io = NULL; - uart_bus_space_mem = mips_bus_space_generic; return (0); }