1 #include "serial_uart_mux.hpp"
2
3 #include "xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp"
4
5 #include <error.h>
6
7 #include <phosphor-logging/lg2.hpp>
8 namespace sdbusRule = sdbusplus::bus::match::rules;
9 // add the button iface class to registry
10 static ButtonIFRegister<SerialUartMux> buttonRegister;
11 using HostSelectorServerObj =
12 sdbusplus::server::xyz::openbmc_project::chassis::buttons::HostSelector;
13 using HostSelectorClientObj =
14 sdbusplus::common::xyz::openbmc_project::chassis::buttons::HostSelector;
15
16 static constexpr auto SERIAL_UART_RX_GPIO = "serial_uart_rx";
init()17 void SerialUartMux::init()
18 {
19 try
20 {
21 // when Host Selector Position is changed call the handler
22
23 std::string matchPattern = sdbusRule::propertiesChanged(
24 HS_DBUS_OBJECT_NAME, HostSelectorClientObj::interface);
25
26 hostPositionChanged = std::make_unique<sdbusplus::bus::match_t>(
27 bus, matchPattern,
28 std::bind(std::mem_fn(&SerialUartMux::hostSelectorPositionChanged),
29 this, std::placeholders::_1));
30 }
31 catch (const std::exception& e)
32 {
33 lg2::error(
34 "Failed binding to matching function : {BUTTON_TYPE},Exception : {ERROR}",
35 "BUTTON_TYPE", getFormFactorName(), "ERROR", e);
36 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
37 IOError();
38 }
39 }
40 // check the debug card present pin
isOCPDebugCardPresent()41 bool SerialUartMux::isOCPDebugCardPresent()
42 {
43 auto gpioState =
44 getGpioState(debugCardPresentGpio.fd, debugCardPresentGpio.polarity);
45 return (gpioState == GpioState::assert);
46 }
47 // set the serial uart MUX to select the console w.r.t host selector position
configSerialConsoleMux(size_t position)48 void SerialUartMux::configSerialConsoleMux(size_t position)
49 {
50 auto debugCardPresent = isOCPDebugCardPresent();
51
52 if (debugCardPresent)
53 {
54 lg2::info("Debug card is present ");
55 }
56 else
57 {
58 lg2::info("Debug card not present ");
59 }
60
61 for (size_t uartMuxSel = 0; uartMuxSel < gpioLineCount; uartMuxSel++)
62 {
63 auto gpioState = GpioState::invalid;
64 GpioInfo gpioConfig = config.gpios[uartMuxSel];
65
66 if (gpioConfig.name == SERIAL_UART_RX_GPIO)
67 {
68 gpioState =
69 debugCardPresent ? GpioState::assert : GpioState::deassert;
70 }
71 else
72 {
73 gpioState = (serialUartMuxMap[position] & (0x1 << uartMuxSel))
74 ? GpioState::assert
75 : GpioState::deassert;
76 }
77 setGpioState(gpioConfig.fd, gpioConfig.polarity, gpioState);
78 }
79 }
80
hostSelectorPositionChanged(sdbusplus::message_t & msg)81 void SerialUartMux::hostSelectorPositionChanged(sdbusplus::message_t& msg)
82 {
83 std::string interface;
84 std::map<std::string, HostSelectorServerObj::PropertiesVariant>
85 propertiesChanged;
86 lg2::info("hostSelectorPositionChanged callback : {BUTTON_TYPE}",
87 "BUTTON_TYPE", getFormFactorName());
88
89 try
90 {
91 msg.read(interface, propertiesChanged);
92 for (auto& property : propertiesChanged)
93 {
94 auto propertyName = property.first;
95 if (propertyName == "Position")
96 {
97 size_t hostPosition = std::get<size_t>(property.second);
98 lg2::debug("property changed : {VALUE}", "VALUE", hostPosition);
99 configSerialConsoleMux(hostPosition);
100 return;
101 }
102 }
103 }
104 catch (const std::exception& e)
105 {
106 lg2::error("exception while reading dbus property : {ERROR}", "ERROR",
107 e.what());
108 return;
109 }
110 }
111