1 #pragma once 2 3 #include "occ_pass_through.hpp" 4 #include "occ_status.hpp" 5 #ifdef PLDM 6 #include "pldm.hpp" 7 #endif 8 #include "powercap.hpp" 9 10 #include <cstring> 11 #include <functional> 12 #include <sdbusplus/bus.hpp> 13 #include <sdeventplus/event.hpp> 14 #include <sdeventplus/utility/timer.hpp> 15 #include <vector> 16 17 namespace sdbusRule = sdbusplus::bus::match::rules; 18 namespace open_power 19 { 20 namespace occ 21 { 22 23 /** @brief Default time, in seconds, between OCC poll commands */ 24 constexpr unsigned int defaultPollingInterval = 10; 25 26 /** @class Manager 27 * @brief Builds and manages OCC objects 28 */ 29 struct Manager 30 { 31 public: 32 Manager() = delete; 33 Manager(const Manager&) = delete; 34 Manager& operator=(const Manager&) = delete; 35 Manager(Manager&&) = delete; 36 Manager& operator=(Manager&&) = delete; 37 ~Manager() = default; 38 39 /** @brief Adds OCC pass-through and status objects on the bus 40 * when corresponding CPU inventory is created. 41 * 42 * @param[in] bus - handle to the bus 43 * @param[in] event - Unique ptr reference to sd_event 44 */ 45 Manager(sdbusplus::bus::bus& bus, EventPtr& event) : 46 bus(bus), event(event), pollInterval(defaultPollingInterval), 47 sdpEvent(sdeventplus::Event::get_default()), 48 _pollTimer( 49 std::make_unique< 50 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>( 51 sdpEvent, std::bind(&Manager::pollerTimerExpired, this))) 52 #ifdef PLDM 53 , 54 pldmHandle(std::make_unique<pldm::Interface>( 55 bus, std::bind(std::mem_fn(&Manager::updateOCCActive), this, 56 std::placeholders::_1, std::placeholders::_2))) 57 #endif 58 59 { 60 #ifdef I2C_OCC 61 // I2C OCC status objects are initialized directly 62 initStatusObjects(); 63 #else 64 findAndCreateObjects(); 65 #endif 66 } 67 68 /** @brief Return the number of bound OCCs */ 69 inline auto getNumOCCs() const 70 { 71 return activeCount; 72 } 73 74 private: 75 /** @brief Checks if the CPU inventory is present and if so, creates 76 * the occ D-Bus objects. Else, registers a handler to be 77 * called when inventory is created. 78 */ 79 void findAndCreateObjects(); 80 81 /** @brief Callback that responds to cpu creation in the inventory - 82 * by creating the needed objects. 83 * 84 * @param[in] msg - bus message 85 * 86 * @returns 0 to indicate success 87 */ 88 int cpuCreated(sdbusplus::message::message& msg); 89 90 /** @brief Create child OCC objects. 91 * 92 * @param[in] occ - the occ name, such as occ0. 93 */ 94 void createObjects(const std::string& occ); 95 96 /** @brief Callback handler invoked by Status object when the OccActive 97 * property is changed. This is needed to make sure that the 98 * error detection is started only after all the OCCs are bound. 99 * Similarly, when one of the OCC gets its OccActive property 100 * un-set, then the OCC error detection needs to be stopped on 101 * all the OCCs 102 * 103 * @param[in] status - OccActive status 104 */ 105 void statusCallBack(bool status); 106 107 /** @brief Sends a Heartbeat command to host control command handler */ 108 void sendHeartBeat(); 109 110 /** @brief reference to the bus */ 111 sdbusplus::bus::bus& bus; 112 113 /** @brief reference to sd_event wrapped in unique_ptr */ 114 EventPtr& event; 115 116 /** @brief OCC pass-through objects */ 117 std::vector<std::unique_ptr<PassThrough>> passThroughObjects; 118 119 /** @brief OCC Status objects */ 120 std::vector<std::unique_ptr<Status>> statusObjects; 121 122 /** @brief Power cap monitor and occ notification object */ 123 std::unique_ptr<open_power::occ::powercap::PowerCap> pcap; 124 125 /** @brief sbdbusplus match objects */ 126 std::vector<sdbusplus::bus::match_t> cpuMatches; 127 128 /** @brief Number of OCCs that are bound */ 129 uint8_t activeCount = 0; 130 131 /** @brief Number of seconds between poll commands */ 132 uint8_t pollInterval; 133 134 /** @brief Poll timer event */ 135 sdeventplus::Event sdpEvent; 136 137 /** 138 * @brief The timer to be used once the OCC goes active. When it expires, 139 * a POLL command will be sent to the OCC and then timer restarted. 140 */ 141 std::unique_ptr< 142 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 143 _pollTimer; 144 145 #ifdef I2C_OCC 146 /** @brief Init Status objects for I2C OCC devices 147 * 148 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices 149 * and creates status objects. 150 */ 151 void initStatusObjects(); 152 #endif 153 154 #ifdef PLDM 155 /** @brief Callback handler invoked by the PLDM event handler when state of 156 * the OCC is toggled by the host. The caller passes the instance 157 * of the OCC and state of the OCC. 158 * 159 * @param[in] instance - instance of the OCC 160 * @param[in] status - true when the OCC goes active and false when the OCC 161 * goes inactive 162 * 163 * @return true if setting the state of OCC is successful and false if it 164 * fails. 165 */ 166 bool updateOCCActive(instanceID instance, bool status); 167 168 std::unique_ptr<pldm::Interface> pldmHandle = nullptr; 169 #endif 170 171 /** 172 * @brief Called when poll timer expires and forces a POLL command to the 173 * OCC. The poll timer will then be restarted. 174 * */ 175 void pollerTimerExpired(); 176 }; 177 178 } // namespace occ 179 } // namespace open_power 180