UART Mux Support: Documentation
This commit adds markdown documentation of how uart-mux support is
implemented in obmc-console. The supported hardware configuration and
example config files are shown.
Change-Id: I19cd3de0f9cb6b98742fc264c4e2963c06ff9db1
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/README.md b/README.md
index 76fd158..d16f7f5 100644
--- a/README.md
+++ b/README.md
@@ -60,3 +60,29 @@
The server needs to know this because it needs to know what to name the pipe;
the client needs to know it as it needs to form the abstract socket name to
which to connect.
+
+## Mux Support
+
+In some hardware designs, multiple UARTS may be available behind a Mux. Please
+reference
+[docs/mux-support.md](https://github.com/openbmc/obmc-console/blob/master/docs/mux-support.md)
+in that case.
+
+## Sample Development Setup
+
+For developing obmc-console, we can use pseudo terminals (pty's) in Linux.
+
+The socat command will output names of 2 pty's, one of which is the master and
+the other one is the slave. The master pty can be used to emulate a UART.
+
+```
+$ socat -d -d pty,raw,echo=0,link=pty1 pty,raw,echo=0,link=pty2
+
+$ obmc-console-server --console-id dev $(realpath pty2)
+
+$ obmc-console-client -i dev
+
+# this message should appear for the client
+$ echo "hi" > pty1
+
+```
diff --git a/docs/mux-support.md b/docs/mux-support.md
new file mode 100644
index 0000000..3d0b876
--- /dev/null
+++ b/docs/mux-support.md
@@ -0,0 +1,182 @@
+## Mux Support
+
+In some hardware designs, multiple UARTS may be available behind a Mux, which
+requires obmc-console to select one at a time.
+
+For example, let's say behind `/dev/ttyS0` there are `UART1` and `UART2`, behind
+a mux. GPIO `UART-MUX-CTL` can be used to select one. This scenario is shown in
+the [Example Diagram](#example-diagram)
+
+Then there will be one obmc-console-server process, and 2 consoles will be
+created in this server process.
+
+The obmc-console-server will receive configuration for both consoles detailing
+the gpios to be used to control the mux and the values they should have when
+they are active.
+
+The implementation documented here has been made based on the
+[design document](https://github.com/openbmc/docs/blob/master/designs/uart-mux-support.md)
+
+## Userspace Implementation
+
+The kernel will not be aware of this mux and the support can be implemented in
+userspace.
+
+Reasons for this are that the hardware this is for is not static (blade server)
+and thus cannot be represented by devicetree. Also, it is unclear how the
+virtual uart should notify a process that the mux state has changed.
+
+When a userspace implementation is available for reference, this may later pave
+the way for a kernel implementation if someone wants to do that.
+
+## Configuration Example
+
+The configuration is similar to i2c-mux-gpio in the linux kernel.
+
+The order of GPIOs listed in 'mux-gpios' forms the LSB-first bit representation
+of an N-bit number that is taken from 'mux-index'.
+
+For declaring the different consoles, the section name, e.g. `[host1]` must be
+the same as the console-id. All of the section names need to be unique.
+
+```
+$ cat server.conf
+mux-gpios = MUX_CTL
+
+[host1]
+mux-index = 0
+logfile = /var/log/console-host1.log
+
+[host2]
+mux-index = 1
+logfile = /var/log/console-host2.log
+```
+
+Now the server can be started. See the [Dbus Interface](#dbus-interface-example)
+and [Example Diagram](#example-diagram)
+
+```
+$ obmc-console-server --config server.conf /dev/ttyS0
+```
+
+## Mux Control
+
+Mux Control happens implicitly via connections. When a client connects to a
+console, the new connection is accepted and the console-server switches the mux
+to this console. Any clients connected to other consoles are disconnected.
+
+### Mux Control - Example
+
+```
+$ obmc-console-client -i host2 &
+[1] 3422
+$ obmc-console-client -i host1
+```
+
+Connecting to console 'host1' will cause console 'host2' to:
+
+1. stop forwarding bytes
+2. print a log message to its clients, if the server was connected before, see
+ [Mux Control Log](#mux-control-log)
+
+Then the following happens for console 'host1':
+
+1. switch the mux using the gpios
+2. print a log message to its clients, if the server was disconnected before,
+ see [Mux Control Log](#mux-control-log)
+3. start forwarding bytes.
+
+## Mux Control Log
+
+Whenever the mux is switched, there should be a way for people reading the log
+to know that that console was (dis)connected, and at which time. Otherwise there
+may be confusion as to why there is a gap in the logs.
+
+So obmc-console-server will print one of these messages to all clients:
+
+```
+[obmc-console] %Y-%m-%d %H:%M:%S UTC CONNECTED
+```
+
+```
+[obmc-console] %Y-%m-%d %H:%M:%S UTC DISCONNECTED
+```
+
+### Mux Control Log Disclaimer
+
+Note that this log message is not a reliable source of information, and is only
+provided as a convenience feature. This same log message could be printed by
+anything that's connected to the uart on the other side.
+
+The exact format of this log message is not fixed and could change.
+
+## Dbus Interface Example
+
+```
+$ busctl list
+...
+xyz.openbmc_project.Console.host1 926 obmc-console-server root ...
+xyz.openbmc_project.Console.host2 926 obmc-console-server root ...
+...
+```
+
+```
+$ busctl tree xyz.openbmc_project.Console.host2
+└─ /xyz
+ └─ /xyz/openbmc_project
+ └─ /xyz/openbmc_project/console
+ └─ /xyz/openbmc_project/console/host1
+ └─ /xyz/openbmc_project/console/host2
+
+$ busctl tree xyz.openbmc_project.Console.host1
+└─ /xyz
+ └─ /xyz/openbmc_project
+ └─ /xyz/openbmc_project/console
+ └─ /xyz/openbmc_project/console/host1
+ └─ /xyz/openbmc_project/console/host2
+```
+
+```
+$ busctl introspect xyz.openbmc_project.Console.host1 /xyz/openbmc_project/console/host1
+NAME TYPE SIGNATURE RESULT/VALUE FLAGS
+org.freedesktop.DBus.Introspectable interface - - -
+.Introspect method - s -
+org.freedesktop.DBus.Peer interface - - -
+.GetMachineId method - s -
+.Ping method - - -
+org.freedesktop.DBus.Properties interface - - -
+.Get method ss v -
+.GetAll method s a{sv} -
+.Set method ssv - -
+.PropertiesChanged signal sa{sv}as - -
+xyz.openbmc_project.Console.Access interface - - -
+.Connect method - h -
+```
+
+## Example Diagram
+
+```
+ +--------------------+
+ | server.conf |
+ +--------------------+
+ |
+ |
+ |
+ |
+ +----+----+ +-----+ +-------+
+ | | | | | |
+ | | +-------+ +-------+ | +-----+ UART1 |
++-----------------------------------+ | | | | | | | | | |
+| xyz.openbmc_project.Console.host1 +-----+ +-----+ ttyS0 +-----+ UART0 +-----+ | +-------+
++-----------------------------------+ | | | | | | | |
+ | obmc | +-------+ +-------+ | |
+ | console | | MUX |
+ | server | +-------+ | |
++-----------------------------------+ | | | | | |
+| xyz.openbmc_project.Console.host2 +-----+ +-------------------+ GPIO +-----+ | +-------+
++-----------------------------------+ | | | | | | | |
+ | | +-------+ | +-----+ UART2 |
+ | | | | | |
+ +----+----+ +-----+ +-------+
+
+```