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