xref: /openbmc/openpower-occ-control/pldm.hpp (revision b5ca1015)
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