| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 1 | #pragma once | 
 | 2 |  | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 3 | #include "occ_pass_through.hpp" | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 4 | #include "occ_status.hpp" | 
| Tom Joseph | 815f9f5 | 2020-07-27 12:12:13 +0530 | [diff] [blame] | 5 | #ifdef PLDM | 
 | 6 | #include "pldm.hpp" | 
 | 7 | #endif | 
| Vishwanatha Subbanna | dfc7ec7 | 2017-09-07 18:18:01 +0530 | [diff] [blame] | 8 | #include "powercap.hpp" | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 9 | #include "utils.hpp" | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 10 | #ifdef POWER10 | 
 | 11 | #include "powermode.hpp" | 
 | 12 | #endif | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 13 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 14 | #include <cstring> | 
 | 15 | #include <functional> | 
 | 16 | #include <sdbusplus/bus.hpp> | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 17 | #include <sdeventplus/event.hpp> | 
 | 18 | #include <sdeventplus/utility/timer.hpp> | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 19 | #include <vector> | 
 | 20 |  | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 21 | namespace sdbusRule = sdbusplus::bus::match::rules; | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 22 | namespace open_power | 
 | 23 | { | 
 | 24 | namespace occ | 
 | 25 | { | 
 | 26 |  | 
| Chicago Duan | bb895cb | 2021-06-18 19:37:16 +0800 | [diff] [blame] | 27 | #ifdef READ_OCC_SENSORS | 
 | 28 | enum occFruType | 
 | 29 | { | 
 | 30 |     processorCore = 0, | 
 | 31 |     internalMemCtlr = 1, | 
 | 32 |     dimm = 2, | 
 | 33 |     memCtrlAndDimm = 3, | 
 | 34 |     VRMVdd = 6, | 
 | 35 |     PMIC = 7, | 
 | 36 |     memCtlrExSensor = 8 | 
 | 37 | }; | 
 | 38 | #endif | 
 | 39 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 40 | /** @brief Default time, in seconds, between OCC poll commands */ | 
| Chicago Duan | bb895cb | 2021-06-18 19:37:16 +0800 | [diff] [blame] | 41 | constexpr unsigned int defaultPollingInterval = 1; | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 42 |  | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 43 | /** @class Manager | 
 | 44 |  *  @brief Builds and manages OCC objects | 
 | 45 |  */ | 
 | 46 | struct Manager | 
 | 47 | { | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 48 |   public: | 
 | 49 |     Manager() = delete; | 
 | 50 |     Manager(const Manager&) = delete; | 
 | 51 |     Manager& operator=(const Manager&) = delete; | 
 | 52 |     Manager(Manager&&) = delete; | 
 | 53 |     Manager& operator=(Manager&&) = delete; | 
 | 54 |     ~Manager() = default; | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 55 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 56 |     /** @brief Adds OCC pass-through and status objects on the bus | 
 | 57 |      *         when corresponding CPU inventory is created. | 
 | 58 |      * | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 59 |      *  @param[in] event - Unique ptr reference to sd_event | 
 | 60 |      */ | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 61 |     Manager(EventPtr& event) : | 
 | 62 |         event(event), pollInterval(defaultPollingInterval), | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 63 |         sdpEvent(sdeventplus::Event::get_default()), | 
 | 64 |         _pollTimer( | 
 | 65 |             std::make_unique< | 
 | 66 |                 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>( | 
 | 67 |                 sdpEvent, std::bind(&Manager::pollerTimerExpired, this))) | 
| Tom Joseph | 815f9f5 | 2020-07-27 12:12:13 +0530 | [diff] [blame] | 68 | #ifdef PLDM | 
 | 69 |         , | 
 | 70 |         pldmHandle(std::make_unique<pldm::Interface>( | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 71 |             std::bind(std::mem_fn(&Manager::updateOCCActive), this, | 
 | 72 |                       std::placeholders::_1, std::placeholders::_2))) | 
| Tom Joseph | 815f9f5 | 2020-07-27 12:12:13 +0530 | [diff] [blame] | 73 | #endif | 
 | 74 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 75 |     { | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 76 | #ifdef I2C_OCC | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 77 |         // I2C OCC status objects are initialized directly | 
 | 78 |         initStatusObjects(); | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 79 | #else | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 80 |         findAndCreateObjects(); | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 81 | #endif | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 82 |     } | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 83 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 84 |     /** @brief Return the number of bound OCCs */ | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 85 |     inline auto getNumOCCs() const | 
 | 86 |     { | 
 | 87 |         return activeCount; | 
 | 88 |     } | 
| Edward A. James | 636577f | 2017-10-06 10:53:55 -0500 | [diff] [blame] | 89 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 90 |   private: | 
 | 91 |     /** @brief Checks if the CPU inventory is present and if so, creates | 
 | 92 |      *         the occ D-Bus objects. Else, registers a handler to be | 
 | 93 |      *         called when inventory is created. | 
 | 94 |      */ | 
 | 95 |     void findAndCreateObjects(); | 
| Vishwanatha Subbanna | dfc7ec7 | 2017-09-07 18:18:01 +0530 | [diff] [blame] | 96 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 97 |     /** @brief Callback that responds to cpu creation in the inventory - | 
 | 98 |      *         by creating the needed objects. | 
 | 99 |      * | 
 | 100 |      *  @param[in] msg - bus message | 
 | 101 |      * | 
 | 102 |      *  @returns 0 to indicate success | 
 | 103 |      */ | 
 | 104 |     int cpuCreated(sdbusplus::message::message& msg); | 
| Deepak Kodihalli | 5f031f3 | 2017-07-26 08:25:59 -0500 | [diff] [blame] | 105 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 106 |     /** @brief Create child OCC objects. | 
 | 107 |      * | 
 | 108 |      *  @param[in] occ - the occ name, such as occ0. | 
 | 109 |      */ | 
 | 110 |     void createObjects(const std::string& occ); | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 111 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 112 |     /** @brief Callback handler invoked by Status object when the OccActive | 
 | 113 |      *         property is changed. This is needed to make sure that the | 
 | 114 |      *         error detection is started only after all the OCCs are bound. | 
 | 115 |      *         Similarly, when one of the OCC gets its OccActive property | 
 | 116 |      *         un-set, then the OCC error detection needs to be stopped on | 
 | 117 |      *         all the OCCs | 
 | 118 |      * | 
 | 119 |      *  @param[in] status - OccActive status | 
 | 120 |      */ | 
 | 121 |     void statusCallBack(bool status); | 
| Vishwanatha Subbanna | 2dc9b1a | 2017-08-18 18:29:41 +0530 | [diff] [blame] | 122 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 123 |     /** @brief Sends a Heartbeat command to host control command handler */ | 
 | 124 |     void sendHeartBeat(); | 
| Vishwanatha Subbanna | 2dc9b1a | 2017-08-18 18:29:41 +0530 | [diff] [blame] | 125 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 126 |     /** @brief reference to sd_event wrapped in unique_ptr */ | 
 | 127 |     EventPtr& event; | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 128 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 129 |     /** @brief OCC pass-through objects */ | 
 | 130 |     std::vector<std::unique_ptr<PassThrough>> passThroughObjects; | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 131 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 132 |     /** @brief OCC Status objects */ | 
 | 133 |     std::vector<std::unique_ptr<Status>> statusObjects; | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 134 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 135 |     /** @brief Power cap monitor and occ notification object */ | 
 | 136 |     std::unique_ptr<open_power::occ::powercap::PowerCap> pcap; | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 137 |  | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 138 | #ifdef POWER10 | 
 | 139 |     /** @brief Power mode monitor and notification object */ | 
 | 140 |     std::unique_ptr<open_power::occ::powermode::PowerMode> pmode; | 
 | 141 | #endif | 
 | 142 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 143 |     /** @brief sbdbusplus match objects */ | 
 | 144 |     std::vector<sdbusplus::bus::match_t> cpuMatches; | 
| Vishwanatha Subbanna | 2dc9b1a | 2017-08-18 18:29:41 +0530 | [diff] [blame] | 145 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 146 |     /** @brief Number of OCCs that are bound */ | 
 | 147 |     uint8_t activeCount = 0; | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 148 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 149 |     /** @brief Number of seconds between poll commands */ | 
 | 150 |     uint8_t pollInterval; | 
 | 151 |  | 
 | 152 |     /** @brief Poll timer event */ | 
 | 153 |     sdeventplus::Event sdpEvent; | 
 | 154 |  | 
 | 155 |     /** | 
 | 156 |      * @brief The timer to be used once the OCC goes active.  When it expires, | 
 | 157 |      *        a POLL command will be sent to the OCC and then timer restarted. | 
 | 158 |      */ | 
 | 159 |     std::unique_ptr< | 
 | 160 |         sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> | 
 | 161 |         _pollTimer; | 
 | 162 |  | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 163 | #ifdef I2C_OCC | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 164 |     /** @brief Init Status objects for I2C OCC devices | 
 | 165 |      * | 
 | 166 |      * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices | 
 | 167 |      * and creates status objects. | 
 | 168 |      */ | 
 | 169 |     void initStatusObjects(); | 
| Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 170 | #endif | 
| Tom Joseph | 815f9f5 | 2020-07-27 12:12:13 +0530 | [diff] [blame] | 171 |  | 
 | 172 | #ifdef PLDM | 
 | 173 |     /** @brief Callback handler invoked by the PLDM event handler when state of | 
 | 174 |      *         the OCC is toggled by the host. The caller passes the instance | 
 | 175 |      *         of the OCC and state of the OCC. | 
 | 176 |      * | 
 | 177 |      *  @param[in] instance - instance of the OCC | 
 | 178 |      *  @param[in] status - true when the OCC goes active and false when the OCC | 
 | 179 |      *                      goes inactive | 
 | 180 |      * | 
 | 181 |      *  @return true if setting the state of OCC is successful and false if it | 
 | 182 |      *          fails. | 
 | 183 |      */ | 
 | 184 |     bool updateOCCActive(instanceID instance, bool status); | 
 | 185 |  | 
 | 186 |     std::unique_ptr<pldm::Interface> pldmHandle = nullptr; | 
 | 187 | #endif | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 188 |  | 
 | 189 |     /** | 
 | 190 |      * @brief Called when poll timer expires and forces a POLL command to the | 
 | 191 |      * OCC. The poll timer will then be restarted. | 
 | 192 |      * */ | 
 | 193 |     void pollerTimerExpired(); | 
| Chicago Duan | bb895cb | 2021-06-18 19:37:16 +0800 | [diff] [blame] | 194 |  | 
 | 195 | #ifdef READ_OCC_SENSORS | 
 | 196 |     /** | 
 | 197 |      * @brief Gets the occ sensor values. | 
 | 198 |      * @param[in] id - Id of the OCC. | 
 | 199 |      * @param[in] masterOcc - Is this OCC the master OCC. | 
 | 200 |      * */ | 
 | 201 |     void getSensorValues(uint32_t id, bool masterOcc); | 
 | 202 |  | 
 | 203 |     /** | 
 | 204 |      * @brief Trigger OCC driver to read the temperature sensors. | 
 | 205 |      * @param[in] path - path of the OCC sensors. | 
 | 206 |      * @param[in] id - Id of the OCC. | 
 | 207 |      * */ | 
 | 208 |     void readTempSensors(const fs::path& path, uint32_t id); | 
 | 209 |  | 
 | 210 |     /** | 
 | 211 |      * @brief Trigger OCC driver to read the power sensors. | 
 | 212 |      * @param[in] path - path of the OCC sensors. | 
 | 213 |      * @param[in] id - Id of the OCC. | 
 | 214 |      * */ | 
 | 215 |     void readPowerSensors(const fs::path& path, uint32_t id); | 
 | 216 |  | 
 | 217 |     /** | 
 | 218 |      * @brief Set all sensor values of this OCC to NaN. | 
 | 219 |      * @param[in] id - Id of the OCC. | 
 | 220 |      * */ | 
 | 221 |     void setSensorValueToNaN(uint32_t id); | 
 | 222 |  | 
 | 223 |     /** @brief Store the existing OCC sensors on D-BUS */ | 
 | 224 |     std::map<std::string, uint32_t> existingSensors; | 
 | 225 |  | 
 | 226 |     /** @brief Get FunctionID from the `powerX_label` file. | 
 | 227 |      *  @param[in] value - the value of the `powerX_label` file. | 
 | 228 |      *  @returns FunctionID of the power sensors. | 
 | 229 |      */ | 
 | 230 |     std::optional<std::string> | 
 | 231 |         getPowerLabelFunctionID(const std::string& value); | 
 | 232 |  | 
 | 233 |     /** @brief The power sensor names map */ | 
 | 234 |     const std::map<std::string, std::string> powerSensorName = { | 
 | 235 |         {"system", "total_power"}, {"1", "p0_mem_power"}, | 
 | 236 |         {"2", "p1_mem_power"},     {"3", "p2_mem_power"}, | 
 | 237 |         {"4", "p3_mem_power"},     {"5", "p0_power"}, | 
 | 238 |         {"6", "p1_power"},         {"7", "p2_power"}, | 
 | 239 |         {"8", "p3_power"},         {"9", "p0_cache_power"}, | 
 | 240 |         {"10", "p1_cache_power"},  {"11", "p2_cache_power"}, | 
 | 241 |         {"12", "p3_cache_power"},  {"13", "io_a_power"}, | 
 | 242 |         {"14", "io_b_power"},      {"15", "io_c_power"}, | 
 | 243 |         {"16", "fans_a_power"},    {"17", "fans_b_power"}, | 
 | 244 |         {"18", "storage_a_power"}, {"19", "storage_b_power"}, | 
 | 245 |         {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"}, | 
 | 246 |         {"26", "p0_mem_1_power"},  {"27", "p0_mem_2_power"}}; | 
 | 247 |  | 
 | 248 |     /** @brief The dimm temperature sensor names map */ | 
 | 249 |     const std::map<uint32_t, std::string> dimmTempSensorName = { | 
 | 250 |         {internalMemCtlr, "_intmb_temp"}, | 
 | 251 |         {dimm, "_dram_temp"}, | 
 | 252 |         {memCtrlAndDimm, "_dram_extmb_temp"}, | 
 | 253 |         {PMIC, "_pmic_temp"}, | 
 | 254 |         {memCtlrExSensor, "_extmb_temp"}}; | 
 | 255 | #endif | 
| Vishwanatha Subbanna | 2180b2d | 2017-06-28 14:05:57 +0530 | [diff] [blame] | 256 | }; | 
 | 257 |  | 
 | 258 | } // namespace occ | 
 | 259 | } // namespace open_power |