Add serial uart mux interface class
1. This change adds the multi-host serial uart mux interface class.
In a multi-host system when the host position is changed,
then the serial uart mux is configured to enable the
respective host's serial console which is accessed via
OCP debug card.
2. Introduced two new methods in gpio.cpp
setGpioState - set state for gpio fd based on polarity
getGpiostate - get state for gpio fd based on polarity
3. Updated the readme file about details on the new gpio
configs
design : https://github.com/openbmc/docs/blob/master/designs/multihost-phosphor-buttons.md
Testing : This change is verified in yosemiteV2 platform.
Signed-off-by: Naveen Moses <naveen.mosess@hcl.com>
Change-Id: I861d70570650d7dfcab842a35bdcf63a9fdd3bd0
diff --git a/inc/gpio.hpp b/inc/gpio.hpp
index 6a63056..9cfd57d 100644
--- a/inc/gpio.hpp
+++ b/inc/gpio.hpp
@@ -21,10 +21,24 @@
#include <string>
#include <vector>
+// enum to represent gpio states
enum class GpioState
{
- low,
- high
+ assert,
+ deassert,
+ invalid
+};
+// enum to represent gpio polarity
+enum class GpioPolarity
+{
+ activeLow,
+ activeHigh
+};
+
+struct GPIOBufferValue
+{
+ char assert;
+ char deassert;
};
// this struct has the gpio config for single gpio
@@ -32,7 +46,9 @@
{
int fd; // io fd mapped with the gpio
uint32_t number;
+ std::string name;
std::string direction;
+ GpioPolarity polarity;
};
// this struct represents button interface
@@ -60,6 +76,11 @@
int configGpio(gpioInfo& gpioConfig);
uint32_t getGpioNum(const std::string& gpioPin);
+// Set gpio state based on polarity
+void setGpioState(int fd, GpioPolarity polarity, GpioState state);
+// Get gpio state based on polarity
+GpioState getGpioState(int fd, GpioPolarity polarity);
+
void closeGpio(int fd);
// global json object which holds gpio_defs.json configs
extern nlohmann::json gpioDefs;
diff --git a/inc/serial_uart_mux.hpp b/inc/serial_uart_mux.hpp
new file mode 100644
index 0000000..5c506b9
--- /dev/null
+++ b/inc/serial_uart_mux.hpp
@@ -0,0 +1,83 @@
+
+#pragma once
+#include "config.h"
+
+#include "button_factory.hpp"
+#include "button_interface.hpp"
+#include "common.hpp"
+#include "gpio.hpp"
+#include "xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp"
+#include "xyz/openbmc_project/Chassis/Common/error.hpp"
+#include "xyz/openbmc_project/Inventory/Item/server.hpp"
+
+#include <unistd.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+static constexpr std::string_view DEBUG_CARD_PRESENT_GPIO =
+ "debug_card_present";
+static constexpr std::string_view SERIAL_CONSOLE_SWITCH = "SERIAL_UART_MUX";
+
+class SerialUartMux final : public ButtonIface
+{
+ public:
+ SerialUartMux(sdbusplus::bus_t& bus, [[maybe_unused]] const char* path,
+ EventPtr& event, buttonConfig& buttonCfg) :
+ ButtonIface(bus, event, buttonCfg)
+ {
+ init();
+
+ // read the platform specific config of host number to uart mux map
+ std::unordered_map<std::string, size_t> uartMuxMapJson =
+ buttonCfg.extraJsonInfo.at("serial_uart_mux_map")
+ .get<decltype(uartMuxMapJson)>();
+ for (auto& [key, value] : uartMuxMapJson)
+ {
+ auto index = std::stoi(key);
+ serialUartMuxMap[index] = value;
+ }
+ if (buttonCfg.gpios.size() < 3)
+ {
+ throw std::runtime_error("not enough gpio configs found");
+ }
+
+ for (auto& gpio : buttonCfg.gpios)
+ {
+ if (gpio.name == DEBUG_CARD_PRESENT_GPIO)
+ {
+ debugCardPresentGpio = gpio;
+ break;
+ }
+ }
+
+ gpioLineCount = buttonCfg.gpios.size() - 1;
+ }
+
+ ~SerialUartMux()
+ {
+ deInit();
+ }
+ void init() override;
+ static const std::string_view getFormFactorName()
+ {
+ return SERIAL_CONSOLE_SWITCH;
+ }
+ static const char* getDbusObjectPath()
+ {
+ return "NO_DBUS_OBJECT";
+ }
+
+ void hostSelectorPositionChanged(sdbusplus::message_t& msg);
+ void configSerialConsoleMux(size_t position);
+ bool isOCPDebugCardPresent();
+
+ void handleEvent(sd_event_source*, int, uint32_t)
+ {}
+
+ protected:
+ size_t gpioLineCount;
+ std::unique_ptr<sdbusplus::bus::match_t> hostPositionChanged;
+ gpioInfo debugCardPresentGpio;
+ std::unordered_map<size_t, size_t> serialUartMuxMap;
+};