blob: 3add821a42b74ce7678e58ba5f226bc8b35cfed3 [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] entityId - the entity ID to query
92 * @param[in] stateSetId - the state set ID to look for
93 * @param[out] instanceToEffecterMap - map of instance to effecterID
Patrick Williams05e95592021-09-02 09:28:14 -050094 * @param[out] count - sensor offset of interested state set ID
Eddie Jamescbad2192021-10-07 09:39:39 -050095 * @param[out] stateIdPos - position of the stateSetID
Patrick Williams05e95592021-09-02 09:28:14 -050096 */
Eddie Jamescbad2192021-10-07 09:39:39 -050097 void fetchEffecterInfo(uint16_t entityId, uint16_t stateSetId,
98 InstanceToEffecter& instanceToEffecterMap,
99 CompositeEffecterCount& count, uint8_t& stateIdPos);
Patrick Williams05e95592021-09-02 09:28:14 -0500100
101 /** @brief Prepare the request for SetStateEffecterStates command
102 *
103 * @param[in] instanceId - PLDM instanceID
Eddie Jamescbad2192021-10-07 09:39:39 -0500104 * @param[in] effecterId - the instance effecter ID
105 * @param[in] effecterCount - compositeEffecterCount for the effecter PDR
106 * @param[in] stateIdPos - position of the stateSetID
107 * @param[in] stateSetValue - the value to set the state set to
Patrick Williams05e95592021-09-02 09:28:14 -0500108 *
Eddie Jamescbad2192021-10-07 09:39:39 -0500109 * @return PLDM request message to be sent to host for OCC reset or SBE
110 * HRESET, empty response in the case of failure.
Patrick Williams05e95592021-09-02 09:28:14 -0500111 */
112 std::vector<uint8_t>
113 prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
114 CompositeEffecterCount effecterCount,
Eddie Jamescbad2192021-10-07 09:39:39 -0500115 uint8_t stateIdPos, uint8_t stateSetValue);
Patrick Williams05e95592021-09-02 09:28:14 -0500116
117 /** @brief Send the PLDM message to reset the OCC
118 *
119 * @param[in] instanceId - OCC instance to reset
120 *
121 */
122 void resetOCC(open_power::occ::instanceID occInstanceId);
123
Eddie Jamescbad2192021-10-07 09:39:39 -0500124 /** @brief Send the PLDM message to perform the HRESET
125 *
126 * @param[in] instanceID - SBE instance to HRESET
127 */
128 void sendHRESET(open_power::occ::instanceID sbeInstanceId);
129
Patrick Williams05e95592021-09-02 09:28:14 -0500130 private:
131 /** @brief Callback handler to be invoked when the state of the OCC
132 * changes
133 */
134 std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
135
Eddie Jamescbad2192021-10-07 09:39:39 -0500136 /** @brief Callback handler to be invoked when the maintenance state of the
137 * SBE changes
138 */
139 std::function<void(open_power::occ::instanceID, bool)> sbeCallBack =
140 nullptr;
141
Patrick Williams05e95592021-09-02 09:28:14 -0500142 /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
143 * processes if the event corresponds to OCC state change.
144 */
145 sdbusplus::bus::match_t pldmEventSignal;
146
147 /** @brief Used to subscribe for host state change signal */
148 sdbusplus::bus::match_t hostStateSignal;
149
150 /** @brief PLDM Sensor ID to OCC Instance mapping
151 */
Eddie Jamescbad2192021-10-07 09:39:39 -0500152 SensorToInstance sensorToOCCInstance;
Patrick Williams05e95592021-09-02 09:28:14 -0500153
Eddie Jamescbad2192021-10-07 09:39:39 -0500154 /** @brief PLDM Sensor ID to SBE Instance mapping
155 */
156 SensorToInstance sensorToSBEInstance;
157
158 /** @brief Sensor offset of OCC state set ID
Patrick Williams05e95592021-09-02 09:28:14 -0500159 * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
160 */
Eddie Jamescbad2192021-10-07 09:39:39 -0500161 SensorOffset OCCSensorOffset;
162
163 /** @brief Sensor offset of the SBE state set ID
164 * PLDM_OEM_IBM_SBE_HRESET_STATE in state sensor PDR.
165 */
166 SensorOffset SBESensorOffset;
Patrick Williams05e95592021-09-02 09:28:14 -0500167
168 /** @brief OCC Instance mapping to PLDM Effecter ID
169 */
Eddie Jamescbad2192021-10-07 09:39:39 -0500170 InstanceToEffecter occInstanceToEffecter;
171
172 /** @brief SBE instance mapping to PLDM Effecter ID
173 */
174 InstanceToEffecter sbeInstanceToEffecter;
Patrick Williams05e95592021-09-02 09:28:14 -0500175
176 /** @brief compositeEffecterCount for OCC reset state effecter PDR */
Eddie Jamescbad2192021-10-07 09:39:39 -0500177 CompositeEffecterCount OCCEffecterCount = 0;
178
179 /** @brief compositeEffecterCount for SBE HRESET state effecter PDR */
180 CompositeEffecterCount SBEEffecterCount = 0;
Patrick Williams05e95592021-09-02 09:28:14 -0500181
182 /** @brief Position of Boot/Restart Cause stateSetID in OCC state
183 * effecter PDR
184 */
185 uint8_t bootRestartPosition = 0;
186
Eddie Jamescbad2192021-10-07 09:39:39 -0500187 /** @brief Position of the SBE maintenance stateSetID in the state
188 * effecter PDR
189 */
190 uint8_t sbeMaintenanceStatePosition = 0;
191
Patrick Williams05e95592021-09-02 09:28:14 -0500192 /** @brief When the OCC state changes host sends PlatformEventMessage
193 * StateSensorEvent, this function processes the D-Bus signal
194 * with the sensor event information and invokes the callback
195 * to change the OCC state.
196 *
197 * @param[in] msg - data associated with the subscribed signal
198 */
199 void sensorEvent(sdbusplus::message::message& msg);
200
201 /** @brief When the host state changes and if the CurrentHostState is
202 * xyz.openbmc_project.State.Host.HostState.Off then
203 * the cache of OCC sensors and effecters mapping is cleared.
204 *
205 * @param[in] msg - data associated with the subscribed signal
206 */
207 void hostStateEvent(sdbusplus::message::message& msg);
208
209 /** @brief Check if the PDR cache for PLDM OCC sensors is valid
210 *
211 * @return true if cache is populated and false if the cache is not
212 * populated.
213 */
214 auto isOCCSensorCacheValid()
215 {
216 return (sensorToOCCInstance.empty() ? false : true);
217 }
218
219 /** @brief Check if the PDR cache for PLDM OCC effecters is valid
220 *
221 * @return true if cache is populated and false if the cache is not
222 * populated.
223 */
224 auto isPDREffecterCacheValid()
225 {
226 return (occInstanceToEffecter.empty() ? false : true);
227 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500228
229 /** @brief Query PLDM for the MCTP requester instance id
230 *
231 * @param[out] - the instance id
232 *
233 * @return true if the id was found and false if not
234 */
235 bool getMctpInstanceId(uint8_t& instanceId);
236
237 /** @brief Send the PLDM request
238 *
239 * @param[in] - the request data
240 */
241 void sendPldm(const std::vector<uint8_t>& request);
Patrick Williams05e95592021-09-02 09:28:14 -0500242};
243
244} // namespace pldm