blob: ccfb3f90083723b7f78892c31b9d11ac2caf9469 [file] [log] [blame]
Patrick Williams05e95592021-09-02 09:28:14 -05001#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
10namespace pldm
11{
12
13namespace MatchRules = sdbusplus::bus::match::rules;
14
15using CompositeEffecterCount = uint8_t;
16using EffecterID = uint16_t;
17using EntityType = uint16_t;
18using EntityInstance = uint16_t;
19using EventState = uint8_t;
Eddie Jamescbad2192021-10-07 09:39:39 -050020using InstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
Patrick Williams05e95592021-09-02 09:28:14 -050021using PdrList = std::vector<std::vector<uint8_t>>;
22using SensorID = uint16_t;
23using SensorOffset = uint8_t;
Eddie Jamescbad2192021-10-07 09:39:39 -050024using SensorToInstance = std::map<SensorID, open_power::occ::instanceID>;
Patrick Williams05e95592021-09-02 09:28:14 -050025using TerminusID = uint8_t;
26
27/** @brief Hardcoded TID */
28constexpr TerminusID tid = 0;
29
30/** @brief OCC instance starts with 0 for example "occ0" */
31constexpr open_power::occ::instanceID start = 0;
32
33/** @brief Hardcoded mctpEid for HBRT */
34constexpr mctp_eid_t mctpEid = 10;
35
36/** @class Interface
37 *
38 * @brief Abstracts the PLDM details related to the OCC
39 */
40class 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(
Eddie Jamescbad2192021-10-07 09:39:39 -050056 std::function<bool(open_power::occ::instanceID, bool)> callBack,
57 std::function<void(open_power::occ::instanceID, bool)> sbeCallBack) :
Patrick Williams05e95592021-09-02 09:28:14 -050058 callBack(callBack),
Eddie Jamescbad2192021-10-07 09:39:39 -050059 sbeCallBack(sbeCallBack),
Patrick Williams05e95592021-09-02 09:28:14 -050060 pldmEventSignal(
61 open_power::occ::utils::getBus(),
62 MatchRules::type::signal() +
63 MatchRules::member("StateSensorEvent") +
64 MatchRules::path("/xyz/openbmc_project/pldm") +
65 MatchRules::interface("xyz.openbmc_project.PLDM.Event"),
66 std::bind(std::mem_fn(&Interface::sensorEvent), this,
67 std::placeholders::_1)),
68 hostStateSignal(
69 open_power::occ::utils::getBus(),
70 MatchRules::propertiesChanged("/xyz/openbmc_project/state/host0",
71 "xyz.openbmc_project.State.Host"),
72 std::bind(std::mem_fn(&Interface::hostStateEvent), this,
73 std::placeholders::_1))
George Liub5ca1012021-09-10 12:53:11 +080074 {}
Patrick Williams05e95592021-09-02 09:28:14 -050075
Eddie Jamescbad2192021-10-07 09:39:39 -050076 /** @brief Fetch the state sensor PDRs and populate the cache with
77 * sensorId to OCC/SBE instance mapping information and the sensor
78 * offset for the relevent state set.
Patrick Williams05e95592021-09-02 09:28:14 -050079 *
Eddie Jamescbad2192021-10-07 09:39:39 -050080 * @param[in] stateSetId - the state set ID to look for
81 * @param[out] sensorInstanceMap - map of sensorID to instance
Patrick Williams05e95592021-09-02 09:28:14 -050082 * @param[out] sensorOffset - sensor offset of interested state set ID
83 */
Eddie Jamescbad2192021-10-07 09:39:39 -050084 void fetchSensorInfo(uint16_t stateSetId,
85 SensorToInstance& sensorInstanceMap,
86 SensorOffset& sensorOffset);
Patrick Williams05e95592021-09-02 09:28:14 -050087
Eddie Jamescbad2192021-10-07 09:39:39 -050088 /** @brief Fetch the OCC/SBE state effecter PDRs and populate the cache
89 * with OCC/SBE instance to EffecterID information.
Patrick Williams05e95592021-09-02 09:28:14 -050090 *
Eddie Jamescbad2192021-10-07 09:39:39 -050091 * @param[in] stateSetId - the state set ID to look for
92 * @param[out] instanceToEffecterMap - map of instance to effecterID
Patrick Williams05e95592021-09-02 09:28:14 -050093 * @param[out] count - sensor offset of interested state set ID
Eddie Jamescbad2192021-10-07 09:39:39 -050094 * @param[out] stateIdPos - position of the stateSetID
Patrick Williams05e95592021-09-02 09:28:14 -050095 */
Eddie James432dc482021-11-19 15:29:31 -060096 void fetchEffecterInfo(uint16_t stateSetId,
Eddie Jamescbad2192021-10-07 09:39:39 -050097 InstanceToEffecter& instanceToEffecterMap,
98 CompositeEffecterCount& count, uint8_t& stateIdPos);
Patrick Williams05e95592021-09-02 09:28:14 -050099
100 /** @brief Prepare the request for SetStateEffecterStates command
101 *
102 * @param[in] instanceId - PLDM instanceID
Eddie Jamescbad2192021-10-07 09:39:39 -0500103 * @param[in] effecterId - the instance effecter ID
104 * @param[in] effecterCount - compositeEffecterCount for the effecter PDR
105 * @param[in] stateIdPos - position of the stateSetID
106 * @param[in] stateSetValue - the value to set the state set to
Patrick Williams05e95592021-09-02 09:28:14 -0500107 *
Eddie Jamescbad2192021-10-07 09:39:39 -0500108 * @return PLDM request message to be sent to host for OCC reset or SBE
109 * HRESET, empty response in the case of failure.
Patrick Williams05e95592021-09-02 09:28:14 -0500110 */
111 std::vector<uint8_t>
112 prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
113 CompositeEffecterCount effecterCount,
Eddie Jamescbad2192021-10-07 09:39:39 -0500114 uint8_t stateIdPos, uint8_t stateSetValue);
Patrick Williams05e95592021-09-02 09:28:14 -0500115
116 /** @brief Send the PLDM message to reset the OCC
117 *
118 * @param[in] instanceId - OCC instance to reset
119 *
120 */
121 void resetOCC(open_power::occ::instanceID occInstanceId);
122
Eddie Jamescbad2192021-10-07 09:39:39 -0500123 /** @brief Send the PLDM message to perform the HRESET
124 *
125 * @param[in] instanceID - SBE instance to HRESET
126 */
127 void sendHRESET(open_power::occ::instanceID sbeInstanceId);
128
Patrick Williams05e95592021-09-02 09:28:14 -0500129 private:
130 /** @brief Callback handler to be invoked when the state of the OCC
131 * changes
132 */
133 std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
134
Eddie Jamescbad2192021-10-07 09:39:39 -0500135 /** @brief Callback handler to be invoked when the maintenance state of the
136 * SBE changes
137 */
138 std::function<void(open_power::occ::instanceID, bool)> sbeCallBack =
139 nullptr;
140
Patrick Williams05e95592021-09-02 09:28:14 -0500141 /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
142 * processes if the event corresponds to OCC state change.
143 */
144 sdbusplus::bus::match_t pldmEventSignal;
145
146 /** @brief Used to subscribe for host state change signal */
147 sdbusplus::bus::match_t hostStateSignal;
148
149 /** @brief PLDM Sensor ID to OCC Instance mapping
150 */
Eddie Jamescbad2192021-10-07 09:39:39 -0500151 SensorToInstance sensorToOCCInstance;
Patrick Williams05e95592021-09-02 09:28:14 -0500152
Eddie Jamescbad2192021-10-07 09:39:39 -0500153 /** @brief PLDM Sensor ID to SBE Instance mapping
154 */
155 SensorToInstance sensorToSBEInstance;
156
157 /** @brief Sensor offset of OCC state set ID
Patrick Williams05e95592021-09-02 09:28:14 -0500158 * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
159 */
George Liuf3a4a692021-12-28 13:59:51 +0800160 SensorOffset OCCSensorOffset = 0;
Eddie Jamescbad2192021-10-07 09:39:39 -0500161
162 /** @brief Sensor offset of the SBE state set ID
163 * PLDM_OEM_IBM_SBE_HRESET_STATE in state sensor PDR.
164 */
George Liuf3a4a692021-12-28 13:59:51 +0800165 SensorOffset SBESensorOffset = 0;
Patrick Williams05e95592021-09-02 09:28:14 -0500166
167 /** @brief OCC Instance mapping to PLDM Effecter ID
168 */
Eddie Jamescbad2192021-10-07 09:39:39 -0500169 InstanceToEffecter occInstanceToEffecter;
170
171 /** @brief SBE instance mapping to PLDM Effecter ID
172 */
173 InstanceToEffecter sbeInstanceToEffecter;
Patrick Williams05e95592021-09-02 09:28:14 -0500174
175 /** @brief compositeEffecterCount for OCC reset state effecter PDR */
Eddie Jamescbad2192021-10-07 09:39:39 -0500176 CompositeEffecterCount OCCEffecterCount = 0;
177
178 /** @brief compositeEffecterCount for SBE HRESET state effecter PDR */
179 CompositeEffecterCount SBEEffecterCount = 0;
Patrick Williams05e95592021-09-02 09:28:14 -0500180
181 /** @brief Position of Boot/Restart Cause stateSetID in OCC state
182 * effecter PDR
183 */
184 uint8_t bootRestartPosition = 0;
185
Eddie Jamescbad2192021-10-07 09:39:39 -0500186 /** @brief Position of the SBE maintenance stateSetID in the state
187 * effecter PDR
188 */
189 uint8_t sbeMaintenanceStatePosition = 0;
190
Patrick Williams05e95592021-09-02 09:28:14 -0500191 /** @brief When the OCC state changes host sends PlatformEventMessage
192 * StateSensorEvent, this function processes the D-Bus signal
193 * with the sensor event information and invokes the callback
194 * to change the OCC state.
195 *
196 * @param[in] msg - data associated with the subscribed signal
197 */
198 void sensorEvent(sdbusplus::message::message& msg);
199
200 /** @brief When the host state changes and if the CurrentHostState is
201 * xyz.openbmc_project.State.Host.HostState.Off then
202 * the cache of OCC sensors and effecters mapping is cleared.
203 *
204 * @param[in] msg - data associated with the subscribed signal
205 */
206 void hostStateEvent(sdbusplus::message::message& msg);
207
208 /** @brief Check if the PDR cache for PLDM OCC sensors is valid
209 *
210 * @return true if cache is populated and false if the cache is not
211 * populated.
212 */
213 auto isOCCSensorCacheValid()
214 {
215 return (sensorToOCCInstance.empty() ? false : true);
216 }
217
218 /** @brief Check if the PDR cache for PLDM OCC effecters is valid
219 *
220 * @return true if cache is populated and false if the cache is not
221 * populated.
222 */
223 auto isPDREffecterCacheValid()
224 {
225 return (occInstanceToEffecter.empty() ? false : true);
226 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500227
228 /** @brief Query PLDM for the MCTP requester instance id
229 *
230 * @param[out] - the instance id
231 *
232 * @return true if the id was found and false if not
233 */
234 bool getMctpInstanceId(uint8_t& instanceId);
235
236 /** @brief Send the PLDM request
237 *
238 * @param[in] - the request data
239 */
240 void sendPldm(const std::vector<uint8_t>& request);
Patrick Williams05e95592021-09-02 09:28:14 -0500241};
242
243} // namespace pldm