Date: Mon, 16 Jan 2012 21:50:20 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r230236 - projects/pseries/powerpc/pseries Message-ID: <201201162150.q0GLoKHG053304@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Mon Jan 16 21:50:20 2012 New Revision: 230236 URL: http://svn.freebsd.org/changeset/base/230236 Log: Rudimentary attachment of the POWER hypervisor console to a newbus device. This will need enhancement to make it safe with respect to multiple devices and to implement various useful operations. This change does not yet seem to entirely work: while init does in fact start and begin running the RC scripts (determined by tracing syscalls and process changes), it doesn't seem to like sending its output to the console. A mystery for another day. Modified: projects/pseries/powerpc/pseries/phyp_console.c Modified: projects/pseries/powerpc/pseries/phyp_console.c ============================================================================== --- projects/pseries/powerpc/pseries/phyp_console.c Mon Jan 16 21:31:03 2012 (r230235) +++ projects/pseries/powerpc/pseries/phyp_console.c Mon Jan 16 21:50:20 2012 (r230236) @@ -30,13 +30,17 @@ __FBSDID("$FreeBSD: projects/pseries/pow #include <sys/kernel.h> #include <sys/priv.h> #include <sys/systm.h> +#include <sys/module.h> #include <sys/types.h> #include <sys/conf.h> #include <sys/cons.h> #include <sys/consio.h> #include <sys/tty.h> +#include <machine/bus.h> #include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> #include <dev/uart/uart.h> #include <dev/uart/uart_cpu.h> #include <dev/uart/uart_bus.h> @@ -66,6 +70,38 @@ enum { #define VS_QUERY_RESPONSE_PACKET_HEADER 0xfc /* + * High-level interface + */ + +static int uart_phyp_probe(device_t dev); +static int phyp_uart_bus_probe(struct uart_softc *); +static int phyp_uart_bus_attach(struct uart_softc *); +static int phyp_uart_bus_transmit(struct uart_softc *sc); +static int phyp_uart_bus_receive(struct uart_softc *sc); +static int phyp_uart_bus_ipend(struct uart_softc *sc); +static int phyp_uart_bus_flush(struct uart_softc *, int); +static int phyp_uart_bus_getsig(struct uart_softc *); +static int phyp_uart_bus_ioctl(struct uart_softc *, int, intptr_t); +static int phyp_uart_bus_param(struct uart_softc *, int, int, int, int); +static int phyp_uart_bus_setsig(struct uart_softc *, int); + +static device_method_t uart_phyp_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_phyp_probe), + DEVMETHOD(device_attach, uart_bus_attach), + + DEVMETHOD_END +}; + +static driver_t uart_phyp_driver = { + uart_driver_name, + uart_phyp_methods, + sizeof(struct uart_softc), +}; + +DRIVER_MODULE(uart, vdevice, uart_phyp_driver, uart_devclass, 0, 0); + +/* * Low-level UART interface */ static int phyp_uart_probe(struct uart_bas *bas); @@ -85,9 +121,23 @@ static struct uart_ops phyp_uart_ops = { .getc = phyp_uart_getc, }; +static kobj_method_t phyp_uart_methods[] = { + KOBJMETHOD(uart_probe, phyp_uart_bus_probe), + KOBJMETHOD(uart_attach, phyp_uart_bus_attach), + KOBJMETHOD(uart_transmit, phyp_uart_bus_transmit), + KOBJMETHOD(uart_receive, phyp_uart_bus_receive), + KOBJMETHOD(uart_ipend, phyp_uart_bus_ipend), + KOBJMETHOD(uart_flush, phyp_uart_bus_flush), + KOBJMETHOD(uart_getsig, phyp_uart_bus_getsig), + KOBJMETHOD(uart_ioctl, phyp_uart_bus_ioctl), + KOBJMETHOD(uart_param, phyp_uart_bus_param), + KOBJMETHOD(uart_setsig, phyp_uart_bus_setsig), + { 0, 0 } +}; + struct uart_class uart_phyp_class = { "uart", - NULL, + phyp_uart_methods, sizeof(struct uart_softc), .uc_ops = &phyp_uart_ops, .uc_range = 1, @@ -123,6 +173,36 @@ phyp_uart_probe(struct uart_bas *bas) return (ENXIO); } +static int +phyp_uart_bus_probe(struct uart_softc *sc) +{ + return (phyp_uart_probe(&sc->sc_bas)); +} + +static int +uart_phyp_probe(device_t dev) +{ + const char *name; + struct uart_softc *sc; + cell_t reg; + + name = ofw_bus_get_name(dev); + if (name == NULL || strcmp(name, "vty") != 0) + return (ENXIO); + + sc = device_get_softc(dev); + sc->sc_class = &uart_phyp_class; + OF_getprop(ofw_bus_get_node(dev), "reg", ®, sizeof(reg)); + sc->sc_bas.bsh = reg; + sc->sc_bas.bst = NULL; + sc->sc_bas.chan = ofw_bus_get_node(dev); + + device_set_desc(dev, "POWER Hypervisor Virtual Serial Port"); + + return (uart_bus_probe(dev, 0, 0, 0, ofw_bus_get_node(dev))); +} + + static void phyp_uart_init(struct uart_bas *bas, int baudrate __unused, int databits __unused, int stopbits __unused, int parity __unused) @@ -197,3 +277,70 @@ phyp_uart_rxready(struct uart_bas *bas) { return (1); } + +static int +phyp_uart_bus_attach(struct uart_softc *sc) +{ + return (0); +} + +static int +phyp_uart_bus_transmit(struct uart_softc *sc) +{ + int i; + + uart_lock(sc->sc_hwmtx); + for (i = 0; i < sc->sc_txdatasz; i++) + phyp_uart_putc(&sc->sc_bas, sc->sc_txbuf[i]); + uart_unlock(sc->sc_hwmtx); + + return (0); +} + +static int +phyp_uart_bus_receive(struct uart_softc *sc) +{ + int c; + while ((c = phyp_uart_getc(&sc->sc_bas, sc->sc_hwmtx)) != -1) + uart_rx_put(sc, c); + + return (0); +} + +static int +phyp_uart_bus_ipend(struct uart_softc *sc) +{ + return (0); +} + +static int +phyp_uart_bus_flush(struct uart_softc *sc, int what) +{ + return (0); +} + +static int +phyp_uart_bus_getsig(struct uart_softc *sc) +{ + return (0); +} + +static int +phyp_uart_bus_ioctl(struct uart_softc *sc, int req, intptr_t data) +{ + return (EINVAL); +} + +static int +phyp_uart_bus_param(struct uart_softc *sc, int baud, int db, int sb, int par) +{ + return (0); +} + +static int +phyp_uart_bus_setsig(struct uart_softc *sc, int sig) +{ + return (0); +} + +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201162150.q0GLoKHG053304>