xref: /openbmc/openpower-occ-control/occ_command.hpp (revision 37abe9be91df2bb173c9642a2740a425904d7921)
1a8857c50SChris Cain #pragma once
2a8857c50SChris Cain 
3a8857c50SChris Cain #include "occ_errors.hpp"
4f3b7514eSGeorge Liu #include "utils.hpp"
5a8857c50SChris Cain 
6a8857c50SChris Cain #include <org/open_power/OCC/PassThrough/server.hpp>
7a8857c50SChris Cain #include <sdbusplus/bus.hpp>
8a8857c50SChris Cain #include <sdbusplus/server/object.hpp>
9b5ca1015SGeorge Liu 
1048002498SPatrick Williams #include <format>
11a8857c50SChris Cain #include <string>
1248002498SPatrick Williams #include <utility>
13a8857c50SChris Cain 
14a8857c50SChris Cain namespace open_power
15a8857c50SChris Cain {
16a8857c50SChris Cain namespace occ
17a8857c50SChris Cain {
18a8857c50SChris Cain 
19a8857c50SChris Cain // For waiting on signals
20a8857c50SChris Cain namespace sdbusRule = sdbusplus::bus::match::rules;
21a8857c50SChris Cain 
2278e86012SChris Cain enum class CmdType
2378e86012SChris Cain {
2478e86012SChris Cain     POLL = 0x00,
2578e86012SChris Cain     CLEAR_ERROR_LOG = 0x12,
2678e86012SChris Cain     SET_MODE_AND_STATE = 0x20,
2778e86012SChris Cain     SET_CONFIG_DATA = 0x21,
2878e86012SChris Cain     SET_USER_PCAP = 0x22,
2978e86012SChris Cain     RESET_PREP = 0x25,
3017257673SChris Cain     SEND_AMBIENT = 0x30,
3178e86012SChris Cain     DEBUG_PASS_THROUGH = 0x40,
3278e86012SChris Cain     AME_PASS_THROUGH = 0x41,
3378e86012SChris Cain     GET_FIELD_DEBUG_DATA = 0x42,
3478e86012SChris Cain     MFG_TEST = 0x53
3578e86012SChris Cain };
3678e86012SChris Cain 
3778e86012SChris Cain enum class OccState
3878e86012SChris Cain {
3978e86012SChris Cain     NO_CHANGE = 0x00,
4078e86012SChris Cain     STANDBY = 0x01,
4178e86012SChris Cain     OBSERVATION = 0x02,
4278e86012SChris Cain     ACTIVE = 0x03,
4378e86012SChris Cain     SAFE = 0x04,
44373af757SSheldon Bailey     CHARACTERIZATION = 0x05
4578e86012SChris Cain };
4678e86012SChris Cain 
4778e86012SChris Cain enum class SysPwrMode
4878e86012SChris Cain {
4978e86012SChris Cain     NO_CHANGE = 0,
5036f9cdedSChris Cain     STATIC = 0x01,            // Static Base Frequencey
512ff2886bSChris Cain     NON_DETERMINISTIC = 0x02, // Non-Deterministic
5278e86012SChris Cain     SFP = 0x03,               // Static Frequency Point (requires freqPt)
5378e86012SChris Cain     SAFE = 0x04,         // reported when system is in SAFE mode (not settable)
5478e86012SChris Cain     POWER_SAVING = 0x05, // Static Power Saving
552ff2886bSChris Cain     EFF_FAVOR_POWER = 0x06, // Efficiency - Favor Power
562ff2886bSChris Cain     EFF_FAVOR_PERF = 0x07,  // Efficiency - Favor Performance
5736f9cdedSChris Cain     MAX_FREQ = 0x09,        // Maximum Frequency (per chip)
582ff2886bSChris Cain     BALANCED_PERF = 0x0A,   // Balanced Performance
5978e86012SChris Cain     FFO = 0x0B,             // Fixed Frequency Override (requires freqPt)
6078e86012SChris Cain     MAX_PERF = 0x0C         // Maximum Performance
6178e86012SChris Cain };
6278e86012SChris Cain 
6378e86012SChris Cain enum class RspStatus
6478e86012SChris Cain {
6578e86012SChris Cain     SUCCESS = 0x00,
6678e86012SChris Cain     CONDITIONAL_SUCCESS = 0x01,
6778e86012SChris Cain     INVALID_COMMAND = 0x11,
6878e86012SChris Cain     INVALID_COMMAND_LENGTH = 0x12,
6978e86012SChris Cain     INVALID_DATA_FIELD = 0x13,
7078e86012SChris Cain     CHECKSUM_FAILURE = 0x14,
7178e86012SChris Cain     INTERNAL_ERROR = 0x15,
7278e86012SChris Cain     PRESENT_STATE_PROHIBITS = 0x16,
7378e86012SChris Cain     COMMAND_IN_PROGRESS = 0xFF
7478e86012SChris Cain };
7578e86012SChris Cain 
76a8857c50SChris Cain enum class CmdStatus
77a8857c50SChris Cain {
78c567dc8dSChris Cain     SUCCESS = 0x00,
79c567dc8dSChris Cain     FAILURE = 0x02,
80c567dc8dSChris Cain     COMM_FAILURE = 0x03
81a8857c50SChris Cain };
82a8857c50SChris Cain 
83*37abe9beSChris Cain /** @brief Trace block of data in hex with lg2:info()
84a8857c50SChris Cain  *
85a8857c50SChris Cain  *  @param[in] data - vector containing data to trace
86a8857c50SChris Cain  *  @param[in] data_len - optional number of bytes to trace
87a8857c50SChris Cain  *  If 0, entire vector will be traced.
88a8857c50SChris Cain  */
89a8857c50SChris Cain void dump_hex(const std::vector<std::uint8_t>& data,
90a8857c50SChris Cain               const unsigned int data_len = 0);
91a8857c50SChris Cain 
92a8857c50SChris Cain /** @class OccCommand
93a8857c50SChris Cain  *  @brief Send commands and process respsonses from the OCC
94a8857c50SChris Cain  */
95a8857c50SChris Cain class OccCommand
96a8857c50SChris Cain {
97a8857c50SChris Cain   public:
98a8857c50SChris Cain     OccCommand() = delete;
99a8857c50SChris Cain     OccCommand(const OccCommand&) = delete;
100a8857c50SChris Cain     OccCommand& operator=(const OccCommand&) = delete;
101a8857c50SChris Cain     OccCommand(OccCommand&&) = default;
102a8857c50SChris Cain     OccCommand& operator=(OccCommand&&) = default;
103a8857c50SChris Cain 
104a8857c50SChris Cain     /** @brief Ctor to set up which OCC the command will go to
105a8857c50SChris Cain      *
106a8857c50SChris Cain      *  @param[in] instance - OCC instance
107a8857c50SChris Cain      *  @param[in] path - Path to attach at
108a8857c50SChris Cain      */
109f3b7514eSGeorge Liu     OccCommand(uint8_t instance, const char* path);
110a8857c50SChris Cain 
111a8857c50SChris Cain     /** @brief Dtor to clean up and close device */
~OccCommand()112a8857c50SChris Cain     ~OccCommand()
113a8857c50SChris Cain     {
114a8857c50SChris Cain         closeDevice();
115a8857c50SChris Cain     }
116a8857c50SChris Cain 
117a8857c50SChris Cain     /** @brief Send the command to the OCC and collect the response.
118a8857c50SChris Cain      * The checksum will be validated and removed from the response.
119a8857c50SChris Cain      *
120a8857c50SChris Cain      *  @param[in] command - command to pass-through
121a8857c50SChris Cain      *  @param[out] response - response
122a8857c50SChris Cain      *  returns SUCCESS if response was received
123a8857c50SChris Cain      */
124a8857c50SChris Cain     CmdStatus send(const std::vector<std::uint8_t>& command,
125a8857c50SChris Cain                    std::vector<std::uint8_t>& response);
126a8857c50SChris Cain 
127a8857c50SChris Cain   private:
128a8857c50SChris Cain     /** @brief Instance number of the target OCC */
129a8857c50SChris Cain     uint8_t occInstance;
130a8857c50SChris Cain 
131a8857c50SChris Cain     /** @brief OCC path on the bus */
132a8857c50SChris Cain     std::string path;
133a8857c50SChris Cain 
134a8857c50SChris Cain     /** @brief OCC device path
135a8857c50SChris Cain      *  For now, here is the hard-coded mapping until
136a8857c50SChris Cain      *  the udev rule is in.
137a8857c50SChris Cain      *  occ0 --> /dev/occ1
138a8857c50SChris Cain      *  occ1 --> /dev/occ2
139a8857c50SChris Cain      *  ...
140a8857c50SChris Cain      */
141a8857c50SChris Cain     std::string devicePath;
142a8857c50SChris Cain 
143a8857c50SChris Cain     /** @brief Indicates whether or not the OCC is currently active */
144a8857c50SChris Cain     bool occActive = false;
145a8857c50SChris Cain 
146a8857c50SChris Cain     /** brief file descriptor associated with occ device */
147a8857c50SChris Cain     int fd = -1;
148a8857c50SChris Cain 
149a8857c50SChris Cain     /** @brief Subscribe to OCC Status signal
150a8857c50SChris Cain      *
151a8857c50SChris Cain      *  Once the OCC status gets to active, only then we will get /dev/occ2
152a8857c50SChris Cain      *  populated and hence need to wait on that before opening that
153a8857c50SChris Cain      */
154a8857c50SChris Cain     sdbusplus::bus::match_t activeStatusSignal;
155a8857c50SChris Cain 
156a8857c50SChris Cain     /** Opens devicePath and populates file descriptor */
157a8857c50SChris Cain     void openDevice();
158a8857c50SChris Cain 
159a8857c50SChris Cain     /** Closed the fd associated with opened device */
160a8857c50SChris Cain     void closeDevice();
161a8857c50SChris Cain 
162a8857c50SChris Cain     /** @brief Callback function on OCC Status change signals
163a8857c50SChris Cain      *
164a8857c50SChris Cain      *  @param[in]  msg - Data associated with subscribed signal
165a8857c50SChris Cain      */
166af40808fSPatrick Williams     void activeStatusEvent(sdbusplus::message_t& msg);
167a8857c50SChris Cain };
168a8857c50SChris Cain 
169a8857c50SChris Cain } // namespace occ
170a8857c50SChris Cain } // namespace open_power
171c0e2d824SPatrick Williams 
172c0e2d824SPatrick Williams template <>
173c0e2d824SPatrick Williams struct std::formatter<open_power::occ::SysPwrMode> : formatter<int>
174c0e2d824SPatrick Williams {
formatstd::formatter175c0e2d824SPatrick Williams     auto format(open_power::occ::SysPwrMode f, format_context& ctx) const
176c0e2d824SPatrick Williams     {
177c0e2d824SPatrick Williams         return formatter<int>::format(std::to_underlying(f), ctx);
178c0e2d824SPatrick Williams     }
179c0e2d824SPatrick Williams };
180c0e2d824SPatrick Williams 
181c0e2d824SPatrick Williams template <>
182c0e2d824SPatrick Williams struct std::formatter<open_power::occ::CmdStatus> : formatter<int>
183c0e2d824SPatrick Williams {
formatstd::formatter184c0e2d824SPatrick Williams     auto format(open_power::occ::CmdStatus f, format_context& ctx) const
185c0e2d824SPatrick Williams     {
186c0e2d824SPatrick Williams         return formatter<int>::format(std::to_underlying(f), ctx);
187c0e2d824SPatrick Williams     }
188c0e2d824SPatrick Williams };
189