| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 1 | #include "pldm.hpp" | 
 | 2 |  | 
 | 3 | #include "file.hpp" | 
 | 4 |  | 
 | 5 | #include <fmt/core.h> | 
 | 6 | #include <libpldm/entity.h> | 
 | 7 | #include <libpldm/platform.h> | 
 | 8 | #include <libpldm/state_set.h> | 
| Eddie James | 36313c7 | 2021-11-18 08:27:03 -0600 | [diff] [blame] | 9 | #include <libpldm/state_set_oem_ibm.h> | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 10 |  | 
 | 11 | #include <phosphor-logging/log.hpp> | 
 | 12 |  | 
 | 13 | namespace pldm | 
 | 14 | { | 
 | 15 |  | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 16 | using namespace phosphor::logging; | 
 | 17 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 18 | void Interface::fetchSensorInfo(uint16_t stateSetId, | 
 | 19 |                                 SensorToInstance& sensorInstanceMap, | 
 | 20 |                                 SensorOffset& sensorOffset) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 21 | { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 22 |     PdrList pdrs{}; | 
 | 23 |  | 
 | 24 |     auto& bus = open_power::occ::utils::getBus(); | 
 | 25 |     try | 
 | 26 |     { | 
 | 27 |         auto method = bus.new_method_call( | 
 | 28 |             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm", | 
 | 29 |             "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR"); | 
 | 30 |         method.append(tid, (uint16_t)PLDM_ENTITY_PROC, stateSetId); | 
 | 31 |  | 
 | 32 |         auto responseMsg = bus.call(method); | 
 | 33 |         responseMsg.read(pdrs); | 
 | 34 |     } | 
 | 35 |     catch (const sdbusplus::exception::exception& e) | 
 | 36 |     { | 
 | 37 |         log<level::ERR>("pldm: Failed to fetch the state sensor PDRs", | 
 | 38 |                         entry("ERROR=%s", e.what())); | 
 | 39 |     } | 
 | 40 |  | 
 | 41 |     if (pdrs.empty()) | 
 | 42 |     { | 
 | 43 |         log<level::ERR>("pldm: state sensor PDRs not present"); | 
 | 44 |         return; | 
 | 45 |     } | 
 | 46 |  | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 47 |     bool offsetFound = false; | 
| George Liu | f3a4a69 | 2021-12-28 13:59:51 +0800 | [diff] [blame] | 48 |     auto stateSensorPDR = | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 49 |         reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data()); | 
| George Liu | f3a4a69 | 2021-12-28 13:59:51 +0800 | [diff] [blame] | 50 |     auto possibleStatesPtr = stateSensorPDR->possible_states; | 
 | 51 |     for (auto offset = 0; offset < stateSensorPDR->composite_sensor_count; | 
 | 52 |          offset++) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 53 |     { | 
 | 54 |         auto possibleStates = | 
 | 55 |             reinterpret_cast<const state_sensor_possible_states*>( | 
 | 56 |                 possibleStatesPtr); | 
 | 57 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 58 |         if (possibleStates->state_set_id == stateSetId) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 59 |         { | 
 | 60 |             sensorOffset = offset; | 
 | 61 |             offsetFound = true; | 
 | 62 |             break; | 
 | 63 |         } | 
 | 64 |         possibleStatesPtr += sizeof(possibleStates->state_set_id) + | 
 | 65 |                              sizeof(possibleStates->possible_states_size) + | 
 | 66 |                              possibleStates->possible_states_size; | 
 | 67 |     } | 
 | 68 |  | 
 | 69 |     if (!offsetFound) | 
 | 70 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 71 |         log<level::ERR>("pldm: state sensor PDR not found"); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 72 |         return; | 
 | 73 |     } | 
 | 74 |  | 
 | 75 |     // To order SensorID based on the EntityInstance. | 
 | 76 |     // Note that when a proc is on a DCM, the PDRs for these sensors | 
 | 77 |     // could have the same instance IDs but different container IDs. | 
 | 78 |     std::map<uint32_t, SensorID> entityInstMap{}; | 
 | 79 |     for (auto& pdr : pdrs) | 
 | 80 |     { | 
 | 81 |         auto pdrPtr = | 
 | 82 |             reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data()); | 
 | 83 |         uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) | | 
 | 84 |                        static_cast<uint32_t>(pdrPtr->entity_instance); | 
 | 85 |         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id)); | 
 | 86 |     } | 
 | 87 |  | 
 | 88 |     open_power::occ::instanceID count = start; | 
 | 89 |     for (auto const& pair : entityInstMap) | 
 | 90 |     { | 
 | 91 |         sensorInstanceMap.emplace(pair.second, count); | 
 | 92 |         count++; | 
 | 93 |     } | 
 | 94 | } | 
 | 95 |  | 
 | 96 | void Interface::sensorEvent(sdbusplus::message::message& msg) | 
 | 97 | { | 
 | 98 |     if (!isOCCSensorCacheValid()) | 
 | 99 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 100 |         fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS, | 
 | 101 |                         sensorToOCCInstance, OCCSensorOffset); | 
 | 102 |     } | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 103 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 104 |     if (sensorToSBEInstance.empty()) | 
 | 105 |     { | 
 | 106 |         fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSBEInstance, | 
 | 107 |                         SBESensorOffset); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 108 |     } | 
 | 109 |  | 
 | 110 |     TerminusID tid{}; | 
 | 111 |     SensorID sensorId{}; | 
 | 112 |     SensorOffset msgSensorOffset{}; | 
 | 113 |     EventState eventState{}; | 
 | 114 |     EventState previousEventState{}; | 
 | 115 |  | 
 | 116 |     msg.read(tid, sensorId, msgSensorOffset, eventState, previousEventState); | 
 | 117 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 118 |     if (msgSensorOffset == OCCSensorOffset) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 119 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 120 |         auto sensorEntry = sensorToOCCInstance.find(sensorId); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 121 |  | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 122 |         if (sensorEntry != sensorToOCCInstance.end()) | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 123 |         { | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 124 |             if (eventState == | 
 | 125 |                 static_cast<EventState>( | 
 | 126 |                     PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE)) | 
 | 127 |             { | 
 | 128 |                 log<level::INFO>( | 
 | 129 |                     fmt::format("PLDM: OCC{} is RUNNING", sensorEntry->second) | 
 | 130 |                         .c_str()); | 
 | 131 |                 callBack(sensorEntry->second, true); | 
 | 132 |             } | 
 | 133 |             else if (eventState == | 
 | 134 |                      static_cast<EventState>( | 
 | 135 |                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED)) | 
 | 136 |             { | 
 | 137 |                 log<level::INFO>(fmt::format("PLDM: OCC{} has now STOPPED", | 
 | 138 |                                              sensorEntry->second) | 
 | 139 |                                      .c_str()); | 
 | 140 |                 callBack(sensorEntry->second, false); | 
 | 141 |             } | 
 | 142 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 143 |             return; | 
 | 144 |         } | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 145 |     } | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 146 |  | 
 | 147 |     if (msgSensorOffset == SBESensorOffset) | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 148 |     { | 
 | 149 |         auto sensorEntry = sensorToSBEInstance.find(sensorId); | 
 | 150 |  | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 151 |         if (sensorEntry != sensorToSBEInstance.end()) | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 152 |         { | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 153 |             if (eventState == static_cast<EventState>(SBE_HRESET_NOT_READY)) | 
 | 154 |             { | 
 | 155 |                 log<level::INFO>("pldm: HRESET is NOT READY", | 
 | 156 |                                  entry("SBE=%d", sensorEntry->second)); | 
 | 157 |             } | 
 | 158 |             else if (eventState == static_cast<EventState>(SBE_HRESET_READY)) | 
 | 159 |             { | 
 | 160 |                 sbeCallBack(sensorEntry->second, true); | 
 | 161 |             } | 
 | 162 |             else if (eventState == static_cast<EventState>(SBE_HRESET_FAILED)) | 
 | 163 |             { | 
 | 164 |                 sbeCallBack(sensorEntry->second, false); | 
 | 165 |             } | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 166 |         } | 
 | 167 |     } | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 168 | } | 
 | 169 |  | 
 | 170 | void Interface::hostStateEvent(sdbusplus::message::message& msg) | 
 | 171 | { | 
 | 172 |     std::map<std::string, std::variant<std::string>> properties{}; | 
 | 173 |     std::string interface; | 
 | 174 |     msg.read(interface, properties); | 
 | 175 |     const auto stateEntry = properties.find("CurrentHostState"); | 
 | 176 |     if (stateEntry != properties.end()) | 
 | 177 |     { | 
 | 178 |         auto stateEntryValue = stateEntry->second; | 
 | 179 |         auto propVal = std::get<std::string>(stateEntryValue); | 
 | 180 |         if (propVal == "xyz.openbmc_project.State.Host.HostState.Off") | 
 | 181 |         { | 
 | 182 |             sensorToOCCInstance.clear(); | 
 | 183 |             occInstanceToEffecter.clear(); | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 184 |  | 
 | 185 |             sensorToSBEInstance.clear(); | 
 | 186 |             sbeInstanceToEffecter.clear(); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 187 |         } | 
 | 188 |     } | 
 | 189 | } | 
 | 190 |  | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 191 | void Interface::fetchEffecterInfo(uint16_t stateSetId, | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 192 |                                   InstanceToEffecter& instanceToEffecterMap, | 
 | 193 |                                   CompositeEffecterCount& effecterCount, | 
 | 194 |                                   uint8_t& stateIdPos) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 195 | { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 196 |     PdrList pdrs{}; | 
 | 197 |  | 
 | 198 |     auto& bus = open_power::occ::utils::getBus(); | 
 | 199 |     try | 
 | 200 |     { | 
 | 201 |         auto method = bus.new_method_call( | 
 | 202 |             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm", | 
 | 203 |             "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR"); | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 204 |         method.append(tid, (uint16_t)PLDM_ENTITY_PROC, stateSetId); | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 205 |  | 
 | 206 |         auto responseMsg = bus.call(method); | 
 | 207 |         responseMsg.read(pdrs); | 
 | 208 |     } | 
 | 209 |     catch (const sdbusplus::exception::exception& e) | 
 | 210 |     { | 
 | 211 |         log<level::ERR>("pldm: Failed to fetch the state effecter PDRs", | 
 | 212 |                         entry("ERROR=%s", e.what())); | 
 | 213 |     } | 
 | 214 |  | 
 | 215 |     if (!pdrs.size()) | 
 | 216 |     { | 
 | 217 |         log<level::ERR>("pldm: state effecter PDRs not present"); | 
 | 218 |         return; | 
 | 219 |     } | 
 | 220 |  | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 221 |     bool offsetFound = false; | 
| George Liu | f3a4a69 | 2021-12-28 13:59:51 +0800 | [diff] [blame] | 222 |     auto stateEffecterPDR = | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 223 |         reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data()); | 
| George Liu | f3a4a69 | 2021-12-28 13:59:51 +0800 | [diff] [blame] | 224 |     auto possibleStatesPtr = stateEffecterPDR->possible_states; | 
 | 225 |     for (auto offset = 0; offset < stateEffecterPDR->composite_effecter_count; | 
 | 226 |          offset++) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 227 |     { | 
 | 228 |         auto possibleStates = | 
 | 229 |             reinterpret_cast<const state_effecter_possible_states*>( | 
 | 230 |                 possibleStatesPtr); | 
 | 231 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 232 |         if (possibleStates->state_set_id == stateSetId) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 233 |         { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 234 |             stateIdPos = offset; | 
| George Liu | f3a4a69 | 2021-12-28 13:59:51 +0800 | [diff] [blame] | 235 |             effecterCount = stateEffecterPDR->composite_effecter_count; | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 236 |             offsetFound = true; | 
 | 237 |             break; | 
 | 238 |         } | 
 | 239 |         possibleStatesPtr += sizeof(possibleStates->state_set_id) + | 
 | 240 |                              sizeof(possibleStates->possible_states_size) + | 
 | 241 |                              possibleStates->possible_states_size; | 
 | 242 |     } | 
 | 243 |  | 
 | 244 |     if (!offsetFound) | 
 | 245 |     { | 
 | 246 |         return; | 
 | 247 |     } | 
 | 248 |  | 
 | 249 |     std::map<EntityInstance, EffecterID> entityInstMap{}; | 
 | 250 |     for (auto& pdr : pdrs) | 
 | 251 |     { | 
 | 252 |         auto pdrPtr = | 
 | 253 |             reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data()); | 
 | 254 |         uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) | | 
 | 255 |                        static_cast<uint32_t>(pdrPtr->entity_instance); | 
 | 256 |         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id)); | 
 | 257 |     } | 
 | 258 |  | 
 | 259 |     open_power::occ::instanceID position = start; | 
 | 260 |     for (auto const& pair : entityInstMap) | 
 | 261 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 262 |         instanceToEffecterMap.emplace(position, pair.second); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 263 |         position++; | 
 | 264 |     } | 
 | 265 | } | 
 | 266 |  | 
 | 267 | std::vector<uint8_t> | 
 | 268 |     Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId, | 
 | 269 |                                      CompositeEffecterCount effecterCount, | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 270 |                                      uint8_t stateIdPos, uint8_t stateSetValue) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 271 | { | 
 | 272 |     std::vector<uint8_t> request( | 
 | 273 |         sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) + | 
 | 274 |         (effecterCount * sizeof(set_effecter_state_field))); | 
 | 275 |     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); | 
 | 276 |     std::vector<set_effecter_state_field> stateField; | 
 | 277 |  | 
 | 278 |     for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++) | 
 | 279 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 280 |         if (effecterPos == stateIdPos) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 281 |         { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 282 |             stateField.emplace_back( | 
 | 283 |                 set_effecter_state_field{PLDM_REQUEST_SET, stateSetValue}); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 284 |         } | 
 | 285 |         else | 
 | 286 |         { | 
 | 287 |             stateField.emplace_back( | 
 | 288 |                 set_effecter_state_field{PLDM_NO_CHANGE, 0}); | 
 | 289 |         } | 
 | 290 |     } | 
 | 291 |     auto rc = encode_set_state_effecter_states_req( | 
 | 292 |         instanceId, effecterId, effecterCount, stateField.data(), requestMsg); | 
 | 293 |     if (rc != PLDM_SUCCESS) | 
 | 294 |     { | 
 | 295 |         log<level::ERR>("encode set effecter states request returned error ", | 
 | 296 |                         entry("RC=%d", rc)); | 
 | 297 |         request.clear(); | 
 | 298 |     } | 
 | 299 |     return request; | 
 | 300 | } | 
 | 301 |  | 
 | 302 | void Interface::resetOCC(open_power::occ::instanceID occInstanceId) | 
 | 303 | { | 
 | 304 |     if (!isPDREffecterCacheValid()) | 
 | 305 |     { | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 306 |         fetchEffecterInfo(PLDM_STATE_SET_BOOT_RESTART_CAUSE, | 
 | 307 |                           occInstanceToEffecter, OCCEffecterCount, | 
 | 308 |                           bootRestartPosition); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 309 |     } | 
 | 310 |  | 
 | 311 |     // Find the matching effecter for the OCC instance | 
 | 312 |     auto effecterEntry = occInstanceToEffecter.find(occInstanceId); | 
 | 313 |     if (effecterEntry == occInstanceToEffecter.end()) | 
 | 314 |     { | 
 | 315 |         log<level::ERR>( | 
 | 316 |             "pldm: Failed to find a matching effecter for OCC instance", | 
 | 317 |             entry("OCC_INSTANCE_ID=%d", occInstanceId)); | 
 | 318 |  | 
 | 319 |         return; | 
 | 320 |     } | 
 | 321 |  | 
 | 322 |     uint8_t instanceId{}; | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 323 |     if (!getMctpInstanceId(instanceId)) | 
 | 324 |     { | 
 | 325 |         return; | 
 | 326 |     } | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 327 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 328 |     // Prepare the SetStateEffecterStates request to reset the OCC | 
 | 329 |     auto request = prepareSetEffecterReq( | 
 | 330 |         instanceId, effecterEntry->second, OCCEffecterCount, | 
 | 331 |         bootRestartPosition, PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET); | 
 | 332 |  | 
 | 333 |     if (request.empty()) | 
 | 334 |     { | 
 | 335 |         log<level::ERR>("pldm: SetStateEffecterStates OCC reset request empty"); | 
 | 336 |         return; | 
 | 337 |     } | 
 | 338 |  | 
 | 339 |     sendPldm(request); | 
 | 340 | } | 
 | 341 |  | 
 | 342 | void Interface::sendHRESET(open_power::occ::instanceID sbeInstanceId) | 
 | 343 | { | 
 | 344 |     if (sbeInstanceToEffecter.empty()) | 
 | 345 |     { | 
| Eddie James | 432dc48 | 2021-11-19 15:29:31 -0600 | [diff] [blame] | 346 |         fetchEffecterInfo(PLDM_OEM_IBM_SBE_MAINTENANCE_STATE, | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 347 |                           sbeInstanceToEffecter, SBEEffecterCount, | 
 | 348 |                           sbeMaintenanceStatePosition); | 
 | 349 |     } | 
 | 350 |  | 
 | 351 |     auto effecterEntry = sbeInstanceToEffecter.find(sbeInstanceId); | 
 | 352 |     if (effecterEntry == sbeInstanceToEffecter.end()) | 
 | 353 |     { | 
 | 354 |         log<level::ERR>( | 
 | 355 |             "pldm: Failed to find a matching effecter for SBE instance", | 
 | 356 |             entry("SBE=%d", sbeInstanceId)); | 
 | 357 |         return; | 
 | 358 |     } | 
 | 359 |  | 
 | 360 |     uint8_t instanceId{}; | 
 | 361 |     if (!getMctpInstanceId(instanceId)) | 
 | 362 |     { | 
 | 363 |         return; | 
 | 364 |     } | 
 | 365 |  | 
 | 366 |     // Prepare the SetStateEffecterStates request to HRESET the SBE | 
 | 367 |     auto request = prepareSetEffecterReq( | 
 | 368 |         instanceId, effecterEntry->second, SBEEffecterCount, | 
 | 369 |         sbeMaintenanceStatePosition, SBE_RETRY_REQUIRED); | 
 | 370 |  | 
 | 371 |     if (request.empty()) | 
 | 372 |     { | 
 | 373 |         log<level::ERR>("pldm: SetStateEffecterStates HRESET request empty"); | 
 | 374 |         return; | 
 | 375 |     } | 
 | 376 |  | 
 | 377 |     sendPldm(request); | 
 | 378 | } | 
 | 379 |  | 
 | 380 | bool Interface::getMctpInstanceId(uint8_t& instanceId) | 
 | 381 | { | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 382 |     auto& bus = open_power::occ::utils::getBus(); | 
 | 383 |     try | 
 | 384 |     { | 
 | 385 |         auto method = bus.new_method_call( | 
 | 386 |             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm", | 
 | 387 |             "xyz.openbmc_project.PLDM.Requester", "GetInstanceId"); | 
 | 388 |         method.append(mctpEid); | 
 | 389 |         auto reply = bus.call(method); | 
 | 390 |         reply.read(instanceId); | 
 | 391 |     } | 
| Patrick Williams | 2561362 | 2021-09-02 09:29:54 -0500 | [diff] [blame] | 392 |     catch (const sdbusplus::exception::exception& e) | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 393 |     { | 
 | 394 |         log<level::ERR>("pldm: GetInstanceId returned error", | 
 | 395 |                         entry("ERROR=%s", e.what())); | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 396 |         return false; | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 397 |     } | 
 | 398 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 399 |     return true; | 
 | 400 | } | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 401 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 402 | void Interface::sendPldm(const std::vector<uint8_t>& request) | 
 | 403 | { | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 404 |     // Connect to MCTP scoket | 
 | 405 |     int fd = pldm_open(); | 
 | 406 |     if (fd == -1) | 
 | 407 |     { | 
 | 408 |         log<level::ERR>("pldm: Failed to connect to MCTP socket"); | 
 | 409 |         return; | 
 | 410 |     } | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 411 |  | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 412 |     open_power::occ::FileDescriptor fileFd(fd); | 
 | 413 |  | 
 | 414 |     // Send the PLDM request message to HBRT | 
 | 415 |     uint8_t* response = nullptr; | 
 | 416 |     size_t responseSize{}; | 
 | 417 |     auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(), | 
 | 418 |                              &response, &responseSize); | 
 | 419 |     std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response, | 
 | 420 |                                                                std::free}; | 
 | 421 |     if (rc) | 
 | 422 |     { | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 423 |         log<level::ERR>("pldm: pldm_send_recv failed", entry("RC=%d", rc)); | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 424 |     } | 
 | 425 |  | 
 | 426 |     uint8_t completionCode{}; | 
 | 427 |     auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get()); | 
 | 428 |     auto rcDecode = decode_set_state_effecter_states_resp( | 
 | 429 |         responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode); | 
 | 430 |     if (rcDecode || completionCode) | 
 | 431 |     { | 
 | 432 |         log<level::ERR>( | 
 | 433 |             "pldm: decode_set_state_effecter_states_resp returned error", | 
 | 434 |             entry("RC=%d", rcDecode), | 
 | 435 |             entry("COMPLETION_CODE=%d", completionCode)); | 
 | 436 |     } | 
| Patrick Williams | 05e9559 | 2021-09-02 09:28:14 -0500 | [diff] [blame] | 437 | } | 
 | 438 |  | 
 | 439 | } // namespace pldm |