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