blob: 0ec22a5f5d2b7b3e53188bf2e9486ca757ee62c8 [file] [log] [blame]
Chris Cain78e86012021-03-04 16:15:31 -06001#pragma once
2
Chris Cain78e86012021-03-04 16:15:31 -06003#include "config.h"
4
George Liubddcf852021-09-08 08:46:22 +08005#ifdef POWER10
Chris Cain36f9cde2021-11-22 11:18:21 -06006#include "occ_command.hpp"
Chris Cain78e86012021-03-04 16:15:31 -06007
Chris Cain36f9cde2021-11-22 11:18:21 -06008#include <cereal/archives/json.hpp>
9//#include <cereal/archives/binary.hpp>
10#include <cereal/cereal.hpp>
11#include <cereal/types/string.hpp>
12#include <cereal/types/tuple.hpp>
13#include <cereal/types/vector.hpp>
Chris Cain78e86012021-03-04 16:15:31 -060014#include <sdbusplus/bus.hpp>
15#include <sdbusplus/bus/match.hpp>
16
George Liubcef3b42021-09-10 12:39:02 +080017#include <filesystem>
George Liub5ca1012021-09-10 12:53:11 +080018
Chris Cain78e86012021-03-04 16:15:31 -060019namespace open_power
20{
21namespace occ
22{
Chris Cain36f9cde2021-11-22 11:18:21 -060023
24class Manager;
25
Chris Cain78e86012021-03-04 16:15:31 -060026namespace powermode
27{
28
29constexpr auto PMODE_PATH = "/xyz/openbmc_project/control/host0/power_mode";
30constexpr auto PMODE_INTERFACE = "xyz.openbmc_project.Control.Power.Mode";
31constexpr auto POWER_MODE_PROP = "PowerMode";
32
Chris Cain1d51da22021-09-21 14:13:41 -050033constexpr auto PIPS_PATH = "/xyz/openbmc_project/control/host0/power_ips";
34constexpr auto PIPS_INTERFACE =
35 "xyz.openbmc_project.Control.Power.IdlePowerSaver";
36constexpr auto IPS_ENABLED_PROP = "Enabled";
37constexpr auto IPS_ENTER_UTIL = "EnterUtilizationPercent";
38constexpr auto IPS_ENTER_TIME = "EnterDwellTime";
39constexpr auto IPS_EXIT_UTIL = "ExitUtilizationPercent";
40constexpr auto IPS_EXIT_TIME = "ExitDwellTime";
41
Chris Cain36f9cde2021-11-22 11:18:21 -060042/** @brief Query the current Hypervisor target
43 * @return true if the current Hypervisor target is PowerVM
44 */
45bool isPowerVM();
46
Chris Cain78e86012021-03-04 16:15:31 -060047/** @brief Convert power mode string to OCC SysPwrMode value
48 *
49 * @param[in] i_modeString - power mode string
50 *
51 * @return SysPwrMode or SysPwrMode::NO_CHANGE if not found
52 */
53SysPwrMode convertStringToMode(const std::string& i_modeString);
54
Chris Cain36f9cde2021-11-22 11:18:21 -060055struct OemModeData
56{
57 SysPwrMode oemMode = SysPwrMode::NO_CHANGE;
58 uint16_t oemModeFreq = 0x0000;
59
60 /** @brief Function specifying data to archive for cereal.
61 */
62 template <class Archive>
63 void serialize(Archive& archive)
64 {
65 archive(oemMode, oemModeFreq);
66 }
67};
68
69/** @class OccPersistData
70 * @brief Provides persistent container to store data for OCC
71 *
72 * Data is stored via cereal
73 */
74class OccPersistData
75{
76 public:
77 ~OccPersistData() = default;
78 OccPersistData(const OccPersistData&) = default;
79 OccPersistData& operator=(const OccPersistData&) = default;
80 OccPersistData(OccPersistData&&) = default;
81 OccPersistData& operator=(OccPersistData&&) = default;
82
83 /** @brief Loads any saved OEM mode data */
84 OccPersistData()
85 {
86 load();
87 }
88
89 /** @brief Save Power Mode data to persistent file
90 *
91 * @param[in] newMode - desired OEM Power Mode
92 * @param[in] modeData - data required by some OEM Power Modes
93 */
94 void writeModeFile(const SysPwrMode newMode, const uint16_t modeData)
95 {
96 oemData.oemMode = newMode;
97 oemData.oemModeFreq = modeData;
98 oemSet = true;
99 save();
100 }
101
102 /** @brief Return the OEM Power Mode and frequency if enabled
103 *
104 * @param[out] newMode - OEM mode (if set, else data not changed)
105 * @param[out] oemFreq - Frequency data for OEM mode
106 *
107 * @returns true if OEM mode was set
108 */
109 bool getOemMode(SysPwrMode& mode, uint16_t& freq) const
110 {
111 if (!oemSet)
112 {
113 return false;
114 }
115
116 mode = oemData.oemMode;
117 freq = oemData.oemModeFreq;
118 return true;
119 }
120
121 /** @brief Saves the Power Mode data in the filesystem using cereal. */
122 void save();
123
124 /** @brief Removes the OEM mode data. */
125 void purge();
126
127 inline void print();
128
129 private:
130 static constexpr auto oemModeFilename = "oemModeData";
131
132 /** @brief true if an OEM Power Mode was set */
133 bool oemSet = false;
134
135 /** @brief OEM Power Mode data */
136 OemModeData oemData;
137
138 /** @brief Loads the OEM mode data in the filesystem using cereal. */
139 void load();
140};
141
Chris Cain78e86012021-03-04 16:15:31 -0600142/** @class PowerMode
143 * @brief Monitors for changes to the power mode and notifies occ
144 *
145 * The customer power mode is provided to the OCC by host TMGT when the occ
146 * first goes active or is reset. This code is responsible for sending
147 * the power mode to the OCC if the mode is changed while the occ is active.
148 */
149
150class PowerMode
151{
152 public:
153 /** @brief PowerMode object to inform occ of changes to mode
154 *
155 * This object will monitor for changes to the power mode setting.
156 * If a change is detected, and the occ is active, then this object will
157 * notify the OCC of the change.
158 *
Chris Cain36f9cde2021-11-22 11:18:21 -0600159 * @param[in] managerRef -
160 * @param[in] path -
Chris Cain78e86012021-03-04 16:15:31 -0600161 */
Chris Cain6fa848a2022-01-24 14:54:38 -0600162 explicit PowerMode(const Manager& managerRef) :
163 manager(managerRef), occInstance(0),
Chris Cain78e86012021-03-04 16:15:31 -0600164 pmodeMatch(utils::getBus(),
165 sdbusplus::bus::match::rules::propertiesChanged(
166 PMODE_PATH, PMODE_INTERFACE),
Chris Cain36f9cde2021-11-22 11:18:21 -0600167 [this](auto& msg) { this->modeChanged(msg); }),
168 ipsMatch(utils::getBus(),
169 sdbusplus::bus::match::rules::propertiesChanged(
170 PIPS_PATH, PIPS_INTERFACE),
171 [this](auto& msg) { this->ipsChanged(msg); }),
Chris Cain6fa848a2022-01-24 14:54:38 -0600172 masterOccSet(false), masterActive(false){};
Chris Cain36f9cde2021-11-22 11:18:21 -0600173
174 bool setMode(const SysPwrMode newMode, const uint16_t modedata);
175
176 /** @brief Send mode change command to the master OCC
177 * @return SUCCESS on success
178 */
179 CmdStatus sendModeChange();
180
181 /** @brief Send Idle Power Saver config data to the master OCC
182 * @return SUCCESS on success
183 */
184 CmdStatus sendIpsData();
185
Chris Cain6fa848a2022-01-24 14:54:38 -0600186 /** @brief Set the master OCC path
187 *
188 * @param[in] occPath - hwmon path for master OCC
189 */
190 void setMasterOcc(const std::string& occPath);
191
Chris Cain36f9cde2021-11-22 11:18:21 -0600192 /** @brief Notify object of master OCC state. If not acitve, no
193 * commands will be sent to the master OCC
194 *
195 * @param[in] isActive - true when master OCC is active
196 */
197 void setMasterActive(const bool isActive = true)
198 {
199 masterActive = isActive;
200 };
Chris Cain78e86012021-03-04 16:15:31 -0600201
202 private:
Chris Cain36f9cde2021-11-22 11:18:21 -0600203 /** @brief OCC manager object */
204 const Manager& manager;
205
206 /** @brief Pass-through occ path on the bus */
207 std::string path;
208
209 /** @brief OCC instance number */
210 int occInstance;
211
212 /** @brief Object to send commands to the OCC */
Chris Cain6fa848a2022-01-24 14:54:38 -0600213 std::unique_ptr<open_power::occ::OccCommand> occCmd;
Chris Cain36f9cde2021-11-22 11:18:21 -0600214
215 /** @brief Used to subscribe to dbus pmode property changes **/
216 sdbusplus::bus::match_t pmodeMatch;
217
218 /** @brief Used to subscribe to dbus IPS property changes **/
219 sdbusplus::bus::match_t ipsMatch;
220
221 OccPersistData persistedData;
222
Chris Cain6fa848a2022-01-24 14:54:38 -0600223 /** @brief True when the master OCC has been established */
224 bool masterOccSet;
225
226 /** @brief True when the master OCC is active */
Chris Cain36f9cde2021-11-22 11:18:21 -0600227 bool masterActive;
228
Chris Cain78e86012021-03-04 16:15:31 -0600229 /** @brief Callback for pmode setting changes
230 *
231 * Process change and inform OCC
232 *
233 * @param[in] msg - Data associated with pmode change signal
234 *
235 */
236 void modeChanged(sdbusplus::message::message& msg);
237
Chris Cain36f9cde2021-11-22 11:18:21 -0600238 /** @brief Get the current power mode property from DBus
239 * @return Power mode
Chris Cain1d51da22021-09-21 14:13:41 -0500240 */
Chris Cain36f9cde2021-11-22 11:18:21 -0600241 SysPwrMode getDbusMode();
Chris Cain1d51da22021-09-21 14:13:41 -0500242
Chris Cain36f9cde2021-11-22 11:18:21 -0600243 /** @brief Update the power mode property on DBus
244 *
245 * @param[in] newMode - desired power mode
246 *
247 * @return true on success
248 */
249 bool updateDbusMode(const SysPwrMode newMode);
250
Chris Cain1d51da22021-09-21 14:13:41 -0500251 /** @brief Callback for IPS setting changes
252 *
253 * Process change and inform OCC
254 *
Chris Cain36f9cde2021-11-22 11:18:21 -0600255 * @param[in] msg - Data associated with IPS change signal
Chris Cain1d51da22021-09-21 14:13:41 -0500256 *
257 */
258 void ipsChanged(sdbusplus::message::message& msg);
259
Chris Cain36f9cde2021-11-22 11:18:21 -0600260 /** @brief Get the Idle Power Saver properties from DBus
261 * @return true if IPS is enabled
262 */
263 bool getIPSParms(uint8_t& enterUtil, uint16_t& enterTime, uint8_t& exitUtil,
264 uint16_t& exitTime);
Chris Cain1d51da22021-09-21 14:13:41 -0500265};
266
Chris Cain78e86012021-03-04 16:15:31 -0600267} // namespace powermode
268
269} // namespace occ
270
271} // namespace open_power
272#endif