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