Skip site navigation (1)Skip section navigation (2)
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", &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>