Date: Tue, 24 Nov 2009 07:50:20 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r199738 - projects/mips/sys/mips/octeon1 Message-ID: <200911240750.nAO7oK13009620@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <imp@FreeBSD.org> * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> * 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 <sys/cdefs.h> @@ -49,42 +42,150 @@ __FBSDID("$FreeBSD$"); #include <dev/uart/uart_cpu.h> #include <mips/octeon1/octeonreg.h> +#include <mips/octeon1/octeon_pcmap_regs.h> bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/ktr.h> + +#include <vm/vm.h> +#include <vm/pmap.h> +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> + +#include <machine/bus.h> +#include <machine/cache.h> + +/* + * 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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911240750.nAO7oK13009620>