1 #pragma once 2 3 #include "occ_status.hpp" 4 #include "utils.hpp" 5 6 #include <libpldm/pldm.h> 7 8 #include <sdbusplus/bus/match.hpp> 9 10 namespace pldm 11 { 12 13 namespace MatchRules = sdbusplus::bus::match::rules; 14 15 using CompositeEffecterCount = uint8_t; 16 using EffecterID = uint16_t; 17 using EntityType = uint16_t; 18 using EntityInstance = uint16_t; 19 using EventState = uint8_t; 20 using OccInstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>; 21 using PdrList = std::vector<std::vector<uint8_t>>; 22 using SensorID = uint16_t; 23 using SensorOffset = uint8_t; 24 using SensorToOCCInstance = std::map<SensorID, open_power::occ::instanceID>; 25 using TerminusID = uint8_t; 26 27 /** @brief Hardcoded TID */ 28 constexpr TerminusID tid = 0; 29 30 /** @brief OCC instance starts with 0 for example "occ0" */ 31 constexpr open_power::occ::instanceID start = 0; 32 33 /** @brief Hardcoded mctpEid for HBRT */ 34 constexpr mctp_eid_t mctpEid = 10; 35 36 /** @class Interface 37 * 38 * @brief Abstracts the PLDM details related to the OCC 39 */ 40 class Interface 41 { 42 public: 43 Interface() = delete; 44 ~Interface() = default; 45 Interface(const Interface&) = delete; 46 Interface& operator=(const Interface&) = delete; 47 Interface(Interface&&) = delete; 48 Interface& operator=(Interface&&) = delete; 49 50 /** @brief Constructs the PLDM Interface object for OCC functions 51 * 52 * @param[in] callBack - callBack handler to invoke when the OCC state 53 * changes. 54 */ 55 explicit Interface( 56 std::function<bool(open_power::occ::instanceID, bool)> callBack) : 57 callBack(callBack), 58 pldmEventSignal( 59 utils::getBus(), 60 MatchRules::type::signal() + 61 MatchRules::member("StateSensorEvent") + 62 MatchRules::path("/xyz/openbmc_project/pldm") + 63 MatchRules::interface("xyz.openbmc_project.PLDM.Event"), 64 std::bind(std::mem_fn(&Interface::sensorEvent), this, 65 std::placeholders::_1)), 66 hostStateSignal( 67 utils::getBus(), 68 MatchRules::propertiesChanged("/xyz/openbmc_project/state/host0", 69 "xyz.openbmc_project.State.Host"), 70 std::bind(std::mem_fn(&Interface::hostStateEvent), this, 71 std::placeholders::_1)) 72 { 73 } 74 75 /** @brief Fetch the OCC state sensor PDRs and populate the cache with 76 * sensorId to OCC instance mapping information and the sensor 77 * offset for Operational Running Status. 78 * 79 * @param[in] pdrs - OCC state sensor PDRs 80 * @param[out] sensorInstanceMap - map of sensorID to OCC instance 81 * @param[out] sensorOffset - sensor offset of interested state set ID 82 */ 83 void fetchOCCSensorInfo(const PdrList& pdrs, 84 SensorToOCCInstance& sensorInstanceMap, 85 SensorOffset& sensorOffset); 86 87 /** @brief Fetch the OCC state effecter PDRs and populate the cache with 88 * OCC instance to EffecterID information. 89 * 90 * @param[in] pdrs - OCC state effecter PDRs 91 * @param[out] instanceToEffecterMap - map of OCC instance to effecterID 92 * @param[out] count - sensor offset of interested state set ID 93 * @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID 94 */ 95 void fetchOCCEffecterInfo(const PdrList& pdrs, 96 OccInstanceToEffecter& instanceToEffecterMap, 97 CompositeEffecterCount& count, 98 uint8_t& bootRestartPos); 99 100 /** @brief Prepare the request for SetStateEffecterStates command 101 * 102 * @param[in] instanceId - PLDM instanceID 103 * @param[in] instanceToEffecterMap - map of OCC instance to effecterID 104 * @param[in] count - compositeEffecterCount for OCC reset effecter PDR 105 * @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID 106 * 107 * @return PLDM request message to be sent to host for OCC reset, empty 108 * response in the case of failure. 109 */ 110 std::vector<uint8_t> 111 prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId, 112 CompositeEffecterCount effecterCount, 113 uint8_t bootRestartPos); 114 115 /** @brief Send the PLDM message to reset the OCC 116 * 117 * @param[in] instanceId - OCC instance to reset 118 * 119 */ 120 void resetOCC(open_power::occ::instanceID occInstanceId); 121 122 private: 123 /** @brief Callback handler to be invoked when the state of the OCC 124 * changes 125 */ 126 std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr; 127 128 /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and 129 * processes if the event corresponds to OCC state change. 130 */ 131 sdbusplus::bus::match_t pldmEventSignal; 132 133 /** @brief Used to subscribe for host state change signal */ 134 sdbusplus::bus::match_t hostStateSignal; 135 136 /** @brief PLDM Sensor ID to OCC Instance mapping 137 */ 138 SensorToOCCInstance sensorToOCCInstance; 139 140 /** @brief Sensor offset of state set ID 141 * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR. 142 */ 143 SensorOffset sensorOffset; 144 145 /** @brief OCC Instance mapping to PLDM Effecter ID 146 */ 147 OccInstanceToEffecter occInstanceToEffecter; 148 149 /** @brief compositeEffecterCount for OCC reset state effecter PDR */ 150 CompositeEffecterCount effecterCount = 0; 151 152 /** @brief Position of Boot/Restart Cause stateSetID in OCC state 153 * effecter PDR 154 */ 155 uint8_t bootRestartPosition = 0; 156 157 /** @brief When the OCC state changes host sends PlatformEventMessage 158 * StateSensorEvent, this function processes the D-Bus signal 159 * with the sensor event information and invokes the callback 160 * to change the OCC state. 161 * 162 * @param[in] msg - data associated with the subscribed signal 163 */ 164 void sensorEvent(sdbusplus::message::message& msg); 165 166 /** @brief When the host state changes and if the CurrentHostState is 167 * xyz.openbmc_project.State.Host.HostState.Off then 168 * the cache of OCC sensors and effecters mapping is cleared. 169 * 170 * @param[in] msg - data associated with the subscribed signal 171 */ 172 void hostStateEvent(sdbusplus::message::message& msg); 173 174 /** @brief Check if the PDR cache for PLDM OCC sensors is valid 175 * 176 * @return true if cache is populated and false if the cache is not 177 * populated. 178 */ 179 auto isOCCSensorCacheValid() 180 { 181 return (sensorToOCCInstance.empty() ? false : true); 182 } 183 184 /** @brief Check if the PDR cache for PLDM OCC effecters is valid 185 * 186 * @return true if cache is populated and false if the cache is not 187 * populated. 188 */ 189 auto isPDREffecterCacheValid() 190 { 191 return (occInstanceToEffecter.empty() ? false : true); 192 } 193 }; 194 195 } // namespace pldm 196