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 open_power::occ::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 open_power::occ::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 /** @brief Fetch the OCC state sensor PDRs and populate the cache with 75 * sensorId to OCC instance mapping information and the sensor 76 * offset for Operational Running Status. 77 * 78 * @param[in] pdrs - OCC state sensor PDRs 79 * @param[out] sensorInstanceMap - map of sensorID to OCC instance 80 * @param[out] sensorOffset - sensor offset of interested state set ID 81 */ 82 void fetchOCCSensorInfo(const PdrList& pdrs, 83 SensorToOCCInstance& sensorInstanceMap, 84 SensorOffset& sensorOffset); 85 86 /** @brief Fetch the OCC state effecter PDRs and populate the cache with 87 * OCC instance to EffecterID information. 88 * 89 * @param[in] pdrs - OCC state effecter PDRs 90 * @param[out] instanceToEffecterMap - map of OCC instance to effecterID 91 * @param[out] count - sensor offset of interested state set ID 92 * @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID 93 */ 94 void fetchOCCEffecterInfo(const PdrList& pdrs, 95 OccInstanceToEffecter& instanceToEffecterMap, 96 CompositeEffecterCount& count, 97 uint8_t& bootRestartPos); 98 99 /** @brief Prepare the request for SetStateEffecterStates command 100 * 101 * @param[in] instanceId - PLDM instanceID 102 * @param[in] instanceToEffecterMap - map of OCC instance to effecterID 103 * @param[in] count - compositeEffecterCount for OCC reset effecter PDR 104 * @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID 105 * 106 * @return PLDM request message to be sent to host for OCC reset, empty 107 * response in the case of failure. 108 */ 109 std::vector<uint8_t> 110 prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId, 111 CompositeEffecterCount effecterCount, 112 uint8_t bootRestartPos); 113 114 /** @brief Send the PLDM message to reset the OCC 115 * 116 * @param[in] instanceId - OCC instance to reset 117 * 118 */ 119 void resetOCC(open_power::occ::instanceID occInstanceId); 120 121 private: 122 /** @brief Callback handler to be invoked when the state of the OCC 123 * changes 124 */ 125 std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr; 126 127 /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and 128 * processes if the event corresponds to OCC state change. 129 */ 130 sdbusplus::bus::match_t pldmEventSignal; 131 132 /** @brief Used to subscribe for host state change signal */ 133 sdbusplus::bus::match_t hostStateSignal; 134 135 /** @brief PLDM Sensor ID to OCC Instance mapping 136 */ 137 SensorToOCCInstance sensorToOCCInstance; 138 139 /** @brief Sensor offset of state set ID 140 * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR. 141 */ 142 SensorOffset sensorOffset; 143 144 /** @brief OCC Instance mapping to PLDM Effecter ID 145 */ 146 OccInstanceToEffecter occInstanceToEffecter; 147 148 /** @brief compositeEffecterCount for OCC reset state effecter PDR */ 149 CompositeEffecterCount effecterCount = 0; 150 151 /** @brief Position of Boot/Restart Cause stateSetID in OCC state 152 * effecter PDR 153 */ 154 uint8_t bootRestartPosition = 0; 155 156 /** @brief When the OCC state changes host sends PlatformEventMessage 157 * StateSensorEvent, this function processes the D-Bus signal 158 * with the sensor event information and invokes the callback 159 * to change the OCC state. 160 * 161 * @param[in] msg - data associated with the subscribed signal 162 */ 163 void sensorEvent(sdbusplus::message::message& msg); 164 165 /** @brief When the host state changes and if the CurrentHostState is 166 * xyz.openbmc_project.State.Host.HostState.Off then 167 * the cache of OCC sensors and effecters mapping is cleared. 168 * 169 * @param[in] msg - data associated with the subscribed signal 170 */ 171 void hostStateEvent(sdbusplus::message::message& msg); 172 173 /** @brief Check if the PDR cache for PLDM OCC sensors is valid 174 * 175 * @return true if cache is populated and false if the cache is not 176 * populated. 177 */ 178 auto isOCCSensorCacheValid() 179 { 180 return (sensorToOCCInstance.empty() ? false : true); 181 } 182 183 /** @brief Check if the PDR cache for PLDM OCC effecters is valid 184 * 185 * @return true if cache is populated and false if the cache is not 186 * populated. 187 */ 188 auto isPDREffecterCacheValid() 189 { 190 return (occInstanceToEffecter.empty() ? false : true); 191 } 192 }; 193 194 } // namespace pldm 195