1a90a31a9SAndrew Geissler #pragma once 2a90a31a9SAndrew Geissler 3e426b589SAndrew Geissler #include "config.h" 4e426b589SAndrew Geissler 5e426b589SAndrew Geissler #include "xyz/openbmc_project/State/Chassis/server.hpp" 6e426b589SAndrew Geissler #include "xyz/openbmc_project/State/PowerOnHours/server.hpp" 7e426b589SAndrew Geissler 8cb781fe1SNagaraju Goruganti #include <cereal/cereal.hpp> 9a90a31a9SAndrew Geissler #include <sdbusplus/bus.hpp> 10d998f82bSWilliam A. Kennington III #include <sdeventplus/clock.hpp> 11d998f82bSWilliam A. Kennington III #include <sdeventplus/event.hpp> 12d998f82bSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp> 13e426b589SAndrew Geissler 14e426b589SAndrew Geissler #include <chrono> 156ed41eabSPatrick Williams #include <filesystem> 16a90a31a9SAndrew Geissler 17a90a31a9SAndrew Geissler namespace phosphor 18a90a31a9SAndrew Geissler { 19a90a31a9SAndrew Geissler namespace state 20a90a31a9SAndrew Geissler { 21a90a31a9SAndrew Geissler namespace manager 22a90a31a9SAndrew Geissler { 23a90a31a9SAndrew Geissler 24f053e6feSPatrick Williams using ChassisInherit = sdbusplus::server::object_t< 25cb781fe1SNagaraju Goruganti sdbusplus::xyz::openbmc_project::State::server::Chassis, 26cb781fe1SNagaraju Goruganti sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>; 278f8ba39fSPatrick Williams namespace sdbusRule = sdbusplus::bus::match::rules; 286ed41eabSPatrick Williams namespace fs = std::filesystem; 298f8ba39fSPatrick Williams 30a90a31a9SAndrew Geissler /** @class Chassis 31a90a31a9SAndrew Geissler * @brief OpenBMC chassis state management implementation. 32a90a31a9SAndrew Geissler * @details A concrete implementation for xyz.openbmc_project.State.Chassis 33a90a31a9SAndrew Geissler * DBus API. 34a90a31a9SAndrew Geissler */ 358f8ba39fSPatrick Williams class Chassis : public ChassisInherit 36a90a31a9SAndrew Geissler { 37a90a31a9SAndrew Geissler public: 38a90a31a9SAndrew Geissler /** @brief Constructs Chassis State Manager 39a90a31a9SAndrew Geissler * 40dff50ed6SAndrew Geissler * @note This constructor passes 'true' to the base class in order to 41dff50ed6SAndrew Geissler * defer dbus object registration until we can run 42dff50ed6SAndrew Geissler * determineInitialState() and set our properties 43dff50ed6SAndrew Geissler * 44a90a31a9SAndrew Geissler * @param[in] bus - The Dbus bus object 45a90a31a9SAndrew Geissler * @param[in] objPath - The Dbus object path 4670f36d8eSPotin Lai * @param[in] id - Chassis id 47a90a31a9SAndrew Geissler */ 48f053e6feSPatrick Williams Chassis(sdbusplus::bus_t& bus, const char* objPath, size_t id) : 4976070747SPatrick Williams ChassisInherit(bus, objPath, ChassisInherit::action::defer_emit), 5076070747SPatrick Williams bus(bus), 5158a18013SAndrew Geissler systemdSignals( 5258a18013SAndrew Geissler bus, 5358a18013SAndrew Geissler sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 548f8ba39fSPatrick Williams sdbusRule::path("/org/freedesktop/systemd1") + 5558a18013SAndrew Geissler sdbusRule::interface("org.freedesktop.systemd1.Manager"), 56*bd28f025SWilliam A. Kennington III [this](sdbusplus::message_t& m) { sysStateChange(m); }), 57*bd28f025SWilliam A. Kennington III id(id), 58*bd28f025SWilliam A. Kennington III pohTimer( 59*bd28f025SWilliam A. Kennington III sdeventplus::Event::get_default(), [this](auto&) { pohCallback(); }, 6070f36d8eSPotin Lai std::chrono::hours{1}, std::chrono::minutes{1}) 61dff50ed6SAndrew Geissler { 620029a5d2SAndrew Geissler subscribeToSystemdSignals(); 630029a5d2SAndrew Geissler 6470f36d8eSPotin Lai createSystemdTargetTable(); 6570f36d8eSPotin Lai 669eab9861SMatt Spinler restoreChassisStateChangeTime(); 679eab9861SMatt Spinler 6877a91831SAndrew Geissler // No default in PDI so start at Good, skip D-Bus signal for now 6977a91831SAndrew Geissler currentPowerStatus(PowerStatus::Good, true); 70dff50ed6SAndrew Geissler determineInitialState(); 71dff50ed6SAndrew Geissler 72cb781fe1SNagaraju Goruganti restorePOHCounter(); // restore POHCounter from persisted file 73cb781fe1SNagaraju Goruganti 74dff50ed6SAndrew Geissler // We deferred this until we could get our property correct 75dff50ed6SAndrew Geissler this->emit_object_added(); 76dff50ed6SAndrew Geissler } 77dff50ed6SAndrew Geissler 78a90a31a9SAndrew Geissler /** @brief Set value of RequestedPowerTransition */ 79a90a31a9SAndrew Geissler Transition requestedPowerTransition(Transition value) override; 80a90a31a9SAndrew Geissler 81a90a31a9SAndrew Geissler /** @brief Set value of CurrentPowerState */ 82a90a31a9SAndrew Geissler PowerState currentPowerState(PowerState value) override; 83a90a31a9SAndrew Geissler 84cb781fe1SNagaraju Goruganti /** @brief Get value of POHCounter */ 8545a1ed71SPatrick Williams using ChassisInherit::pohCounter; 86cb781fe1SNagaraju Goruganti 87cb781fe1SNagaraju Goruganti /** @brief Increment POHCounter if Chassis Power state is ON */ 88cb781fe1SNagaraju Goruganti void startPOHCounter(); 89cb781fe1SNagaraju Goruganti 90a90a31a9SAndrew Geissler private: 9170f36d8eSPotin Lai /** @brief Create systemd target instance names and mapping table */ 9270f36d8eSPotin Lai void createSystemdTargetTable(); 9370f36d8eSPotin Lai 940029a5d2SAndrew Geissler /** @brief Determine initial chassis state and set internally */ 950029a5d2SAndrew Geissler void determineInitialState(); 960029a5d2SAndrew Geissler 97396ed8a5SAdriana Kobylak /** @brief Determine status of power into system by examining all the 98396ed8a5SAdriana Kobylak * power-related interfaces of interest 99396ed8a5SAdriana Kobylak */ 1008b1f8620SAndrew Geissler void determineStatusOfPower(); 1018b1f8620SAndrew Geissler 102396ed8a5SAdriana Kobylak /** @brief Determine status of power provided by an Uninterruptible Power 103396ed8a5SAdriana Kobylak * Supply into the system 10466aacdc4SAndrew Geissler * 10566aacdc4SAndrew Geissler * @return True if UPS power is good, false otherwise 106396ed8a5SAdriana Kobylak */ 10766aacdc4SAndrew Geissler bool determineStatusOfUPSPower(); 108396ed8a5SAdriana Kobylak 109396ed8a5SAdriana Kobylak /** @brief Determine status of power provided by the power supply units into 110396ed8a5SAdriana Kobylak * the system 11166aacdc4SAndrew Geissler * 11266aacdc4SAndrew Geissler * @return True if PSU power is good, false otherwise 113396ed8a5SAdriana Kobylak */ 11466aacdc4SAndrew Geissler bool determineStatusOfPSUPower(); 115396ed8a5SAdriana Kobylak 1160029a5d2SAndrew Geissler /** 1170029a5d2SAndrew Geissler * @brief subscribe to the systemd signals 1180029a5d2SAndrew Geissler * 1190029a5d2SAndrew Geissler * This object needs to capture when it's systemd targets complete 1200029a5d2SAndrew Geissler * so it can keep it's state updated 1210029a5d2SAndrew Geissler * 1220029a5d2SAndrew Geissler **/ 1230029a5d2SAndrew Geissler void subscribeToSystemdSignals(); 1240029a5d2SAndrew Geissler 125be6efabcSMatthew Barth /** @brief Start the systemd unit requested 126ce80f24cSAndrew Geissler * 127be6efabcSMatthew Barth * This function calls `StartUnit` on the systemd unit given. 128ce80f24cSAndrew Geissler * 129be6efabcSMatthew Barth * @param[in] sysdUnit - Systemd unit 130ce80f24cSAndrew Geissler */ 131be6efabcSMatthew Barth void startUnit(const std::string& sysdUnit); 132ce80f24cSAndrew Geissler 13377a91831SAndrew Geissler /** @brief Restart the systemd unit requested 13477a91831SAndrew Geissler * 13577a91831SAndrew Geissler * This function calls `RestartUnit` on the systemd unit given. 13677a91831SAndrew Geissler * This is useful when needing to restart a service that is already running 13777a91831SAndrew Geissler * 13877a91831SAndrew Geissler * @param[in] sysdUnit - Systemd unit to restart 13977a91831SAndrew Geissler */ 14077a91831SAndrew Geissler void restartUnit(const std::string& sysdUnit); 14177a91831SAndrew Geissler 142697474c5SJosh D. King /** 143697474c5SJosh D. King * @brief Determine if target is active 144697474c5SJosh D. King * 145697474c5SJosh D. King * This function determines if the target is active and 146697474c5SJosh D. King * helps prevent misleading log recorded states. 147697474c5SJosh D. King * 148697474c5SJosh D. King * @param[in] target - Target string to check on 149697474c5SJosh D. King * 150697474c5SJosh D. King * @return boolean corresponding to state active 151697474c5SJosh D. King **/ 152697474c5SJosh D. King bool stateActive(const std::string& target); 153697474c5SJosh D. King 1540029a5d2SAndrew Geissler /** @brief Check if systemd state change is relevant to this object 1552ec3a7e9SAndrew Geissler * 1560029a5d2SAndrew Geissler * Instance specific interface to handle the detected systemd state 1570029a5d2SAndrew Geissler * change 1582ec3a7e9SAndrew Geissler * 1592ec3a7e9SAndrew Geissler * @param[in] msg - Data associated with subscribed signal 1602ec3a7e9SAndrew Geissler * 1612ec3a7e9SAndrew Geissler */ 162f053e6feSPatrick Williams int sysStateChange(sdbusplus::message_t& msg); 1632ec3a7e9SAndrew Geissler 164a90a31a9SAndrew Geissler /** @brief Persistent sdbusplus DBus connection. */ 165f053e6feSPatrick Williams sdbusplus::bus_t& bus; 1662ec3a7e9SAndrew Geissler 1670029a5d2SAndrew Geissler /** @brief Used to subscribe to dbus systemd signals **/ 1688f8ba39fSPatrick Williams sdbusplus::bus::match_t systemdSignals; 169cb781fe1SNagaraju Goruganti 1702cf2a268SAndrew Geissler /** @brief Watch for any changes to UPS properties **/ 1712cf2a268SAndrew Geissler std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal; 1722cf2a268SAndrew Geissler 173396ed8a5SAdriana Kobylak /** @brief Watch for any changes to PowerSystemInputs properties **/ 174396ed8a5SAdriana Kobylak std::unique_ptr<sdbusplus::bus::match_t> powerSysInputsPropChangeSignal; 175396ed8a5SAdriana Kobylak 17670f36d8eSPotin Lai /** @brief Chassis id. **/ 17770f36d8eSPotin Lai const size_t id = 0; 17870f36d8eSPotin Lai 17970f36d8eSPotin Lai /** @brief Transition state to systemd target mapping table. **/ 18070f36d8eSPotin Lai std::map<Transition, std::string> systemdTargetTable; 18170f36d8eSPotin Lai 182cb781fe1SNagaraju Goruganti /** @brief Used to Set value of POHCounter */ 18345a1ed71SPatrick Williams uint32_t pohCounter(uint32_t value) override; 184cb781fe1SNagaraju Goruganti 185d998f82bSWilliam A. Kennington III /** @brief Used by the timer to update the POHCounter */ 18645a1ed71SPatrick Williams void pohCallback(); 187d998f82bSWilliam A. Kennington III 188cb781fe1SNagaraju Goruganti /** @brief Used to restore POHCounter value from persisted file */ 189cb781fe1SNagaraju Goruganti void restorePOHCounter(); 190cb781fe1SNagaraju Goruganti 191cb781fe1SNagaraju Goruganti /** @brief Serialize and persist requested POH counter. 192cb781fe1SNagaraju Goruganti * 193cb781fe1SNagaraju Goruganti * @return fs::path - pathname of persisted requested POH counter. 194cb781fe1SNagaraju Goruganti */ 195ba182f0cSAllen.Wang fs::path serializePOH(); 196cb781fe1SNagaraju Goruganti 19781957841SMatt Spinler /** @brief Deserialize a persisted requested POH counter. 198cb781fe1SNagaraju Goruganti * 199cb781fe1SNagaraju Goruganti * @param[in] retCounter - deserialized POH counter value 200cb781fe1SNagaraju Goruganti * 201cb781fe1SNagaraju Goruganti * @return bool - true if the deserialization was successful, false 202cb781fe1SNagaraju Goruganti * otherwise. 203cb781fe1SNagaraju Goruganti */ 204ba182f0cSAllen.Wang bool deserializePOH(uint32_t& retCounter); 205cb781fe1SNagaraju Goruganti 2069eab9861SMatt Spinler /** @brief Sets the LastStateChangeTime property and persists it. */ 2079eab9861SMatt Spinler void setStateChangeTime(); 2089eab9861SMatt Spinler 2099eab9861SMatt Spinler /** @brief Serialize the last power state change time. 2109eab9861SMatt Spinler * 2119eab9861SMatt Spinler * Save the time the state changed and the state itself. 2129eab9861SMatt Spinler * The state needs to be saved as well so that during rediscovery 2139eab9861SMatt Spinler * on reboots there's a way to know not to update the time again. 2149eab9861SMatt Spinler */ 2159eab9861SMatt Spinler void serializeStateChangeTime(); 2169eab9861SMatt Spinler 2179eab9861SMatt Spinler /** @brief Deserialize the last power state change time. 2189eab9861SMatt Spinler * 2199eab9861SMatt Spinler * @param[out] time - Deserialized time 2209eab9861SMatt Spinler * @param[out] state - Deserialized power state 2219eab9861SMatt Spinler * 2229eab9861SMatt Spinler * @return bool - true if successful, false otherwise. 2239eab9861SMatt Spinler */ 2249eab9861SMatt Spinler bool deserializeStateChangeTime(uint64_t& time, PowerState& state); 2259eab9861SMatt Spinler 2269eab9861SMatt Spinler /** @brief Restores the power state change time. 2279eab9861SMatt Spinler * 2289eab9861SMatt Spinler * The time is loaded into the LastStateChangeTime D-Bus property. 2299eab9861SMatt Spinler * On the very first start after this code has been applied but 2309eab9861SMatt Spinler * before the state has changed, the LastStateChangeTime value 2319eab9861SMatt Spinler * will be zero. 2329eab9861SMatt Spinler */ 2339eab9861SMatt Spinler void restoreChassisStateChangeTime(); 2349eab9861SMatt Spinler 235d998f82bSWilliam A. Kennington III /** @brief Timer used for tracking power on hours */ 23645a1ed71SPatrick Williams sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer; 2372c36e5adSBen Tyner 2382c36e5adSBen Tyner /** @brief Function to check for a standby voltage regulator fault 2392c36e5adSBen Tyner * 2402c36e5adSBen Tyner * Determine if a standby voltage regulator fault was detected and 2412c36e5adSBen Tyner * return true or false accordingly. 2422c36e5adSBen Tyner * 2432c36e5adSBen Tyner * @return true if fault detected, else false 2442c36e5adSBen Tyner */ 2452c36e5adSBen Tyner bool standbyVoltageRegulatorFault(); 2462cf2a268SAndrew Geissler 2472cf2a268SAndrew Geissler /** @brief Process UPS property changes 2482cf2a268SAndrew Geissler * 2492cf2a268SAndrew Geissler * Instance specific interface to monitor for changes to the UPS 2502cf2a268SAndrew Geissler * properties which may impact CurrentPowerStatus 2512cf2a268SAndrew Geissler * 2522cf2a268SAndrew Geissler * @param[in] msg - Data associated with subscribed signal 2532cf2a268SAndrew Geissler * 2542cf2a268SAndrew Geissler */ 255f053e6feSPatrick Williams void uPowerChangeEvent(sdbusplus::message_t& msg); 256396ed8a5SAdriana Kobylak 257396ed8a5SAdriana Kobylak /** @brief Process PowerSystemInputs property changes 258396ed8a5SAdriana Kobylak * 259396ed8a5SAdriana Kobylak * Instance specific interface to monitor for changes to the 260396ed8a5SAdriana Kobylak * PowerSystemInputs properties which may impact CurrentPowerStatus 261396ed8a5SAdriana Kobylak * 262396ed8a5SAdriana Kobylak * @param[in] msg - Data associated with subscribed signal 263396ed8a5SAdriana Kobylak * 264396ed8a5SAdriana Kobylak */ 265f053e6feSPatrick Williams void powerSysInputsChangeEvent(sdbusplus::message_t& msg); 266a90a31a9SAndrew Geissler }; 267a90a31a9SAndrew Geissler 268a90a31a9SAndrew Geissler } // namespace manager 269a90a31a9SAndrew Geissler } // namespace state 270a90a31a9SAndrew Geissler } // namespace phosphor 271