xref: /openbmc/openpower-occ-control/pldm.hpp (revision 00325238)
1 #pragma once
2 
3 #include "occ_status.hpp"
4 
5 #include <libpldm/pldm.h>
6 
7 #include <sdbusplus/bus/match.hpp>
8 
9 namespace pldm
10 {
11 
12 namespace MatchRules = sdbusplus::bus::match::rules;
13 
14 using CompositeEffecterCount = uint8_t;
15 using EffecterID = uint16_t;
16 using EntityType = uint16_t;
17 using EntityInstance = uint16_t;
18 using EventState = uint8_t;
19 using OccInstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
20 using PdrList = std::vector<std::vector<uint8_t>>;
21 using SensorID = uint16_t;
22 using SensorOffset = uint8_t;
23 using SensorToOCCInstance = std::map<SensorID, open_power::occ::instanceID>;
24 using TerminusID = uint8_t;
25 
26 /** @brief Hardcoded TID */
27 constexpr TerminusID tid = 0;
28 
29 /** @brief OCC instance starts with 0 for example "occ0" */
30 constexpr open_power::occ::instanceID start = 0;
31 
32 /** @brief Hardcoded mctpEid for HBRT */
33 constexpr mctp_eid_t mctpEid = 10;
34 
35 /** @class Interface
36  *
37  *  @brief Abstracts the PLDM details related to the OCC
38  */
39 class Interface
40 {
41   public:
42     Interface() = delete;
43     ~Interface() = default;
44     Interface(const Interface&) = delete;
45     Interface& operator=(const Interface&) = delete;
46     Interface(Interface&&) = delete;
47     Interface& operator=(Interface&&) = delete;
48 
49     /** @brief Constructs the PLDM Interface object for OCC functions
50      *
51      *  @param[in] bus      - reference to systemd bus
52      *  @param[in] callBack - callBack handler to invoke when the OCC state
53      *                        changes.
54      */
55     explicit Interface(
56         sdbusplus::bus::bus& bus,
57         std::function<bool(open_power::occ::instanceID, bool)> callBack) :
58         bus(bus),
59         callBack(callBack),
60         pldmEventSignal(
61             bus,
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             bus,
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))
74     {
75     }
76 
77     /** @brief Fetch the OCC state sensor PDRs and populate the cache with
78      *         sensorId to OCC instance mapping information and the sensor
79      *         offset for Operational Running Status.
80      *
81      *  @param[in] pdrs - OCC state sensor PDRs
82      *  @param[out] sensorInstanceMap - map of sensorID to OCC instance
83      *  @param[out] sensorOffset - sensor offset of interested state set ID
84      */
85     void fetchOCCSensorInfo(const PdrList& pdrs,
86                             SensorToOCCInstance& sensorInstanceMap,
87                             SensorOffset& sensorOffset);
88 
89     /** @brief Fetch the OCC state effecter PDRs and populate the cache with
90      *         OCC instance to EffecterID information.
91      *
92      *  @param[in] pdrs - OCC state effecter PDRs
93      *  @param[out] instanceToEffecterMap - map of OCC instance to effecterID
94      *  @param[out] count - sensor offset of interested state set ID
95      *  @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID
96      */
97     void fetchOCCEffecterInfo(const PdrList& pdrs,
98                               OccInstanceToEffecter& instanceToEffecterMap,
99                               CompositeEffecterCount& count,
100                               uint8_t& bootRestartPos);
101 
102     /** @brief Prepare the request for SetStateEffecterStates command
103      *
104      *  @param[in] instanceId - PLDM instanceID
105      *  @param[in] instanceToEffecterMap - map of OCC instance to effecterID
106      *  @param[in] count - compositeEffecterCount for OCC reset effecter PDR
107      *  @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID
108      *
109      *  @return PLDM request message to be sent to host for OCC reset, empty
110      *          response in the case of failure.
111      */
112     std::vector<uint8_t>
113         prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
114                               CompositeEffecterCount effecterCount,
115                               uint8_t bootRestartPos);
116 
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 
124   private:
125     /** @brief reference to the systemd bus*/
126     sdbusplus::bus::bus& bus;
127 
128     /** @brief Callback handler to be invoked when the state of the OCC
129      *         changes
130      */
131     std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
132 
133     /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
134      *         processes if the event corresponds to OCC state change.
135      */
136     sdbusplus::bus::match_t pldmEventSignal;
137 
138     /** @brief Used to subscribe for host state change signal */
139     sdbusplus::bus::match_t hostStateSignal;
140 
141     /** @brief PLDM Sensor ID to OCC Instance mapping
142      */
143     SensorToOCCInstance sensorToOCCInstance;
144 
145     /** @brief Sensor offset of state set ID
146      * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
147      */
148     SensorOffset sensorOffset;
149 
150     /** @brief OCC Instance mapping to PLDM Effecter ID
151      */
152     OccInstanceToEffecter occInstanceToEffecter;
153 
154     /** @brief compositeEffecterCount for OCC reset state effecter PDR */
155     CompositeEffecterCount effecterCount = 0;
156 
157     /** @brief Position of Boot/Restart Cause stateSetID in OCC state
158      *         effecter PDR
159      */
160     uint8_t bootRestartPosition = 0;
161 
162     /** @brief When the OCC state changes host sends PlatformEventMessage
163      *         StateSensorEvent, this function processes the D-Bus signal
164      *         with the sensor event information and invokes the callback
165      *         to change the OCC state.
166      *
167      *  @param[in] msg - data associated with the subscribed signal
168      */
169     void sensorEvent(sdbusplus::message::message& msg);
170 
171     /** @brief When the host state changes and if the CurrentHostState is
172      *         xyz.openbmc_project.State.Host.HostState.Off then
173      *         the cache of OCC sensors and effecters mapping is cleared.
174      *
175      *  @param[in] msg - data associated with the subscribed signal
176      */
177     void hostStateEvent(sdbusplus::message::message& msg);
178 
179     /** @brief Check if the PDR cache for PLDM OCC sensors is valid
180      *
181      *  @return true if cache is populated and false if the cache is not
182      *          populated.
183      */
184     auto isOCCSensorCacheValid()
185     {
186         return (sensorToOCCInstance.empty() ? false : true);
187     }
188 
189     /** @brief Check if the PDR cache for PLDM OCC effecters is valid
190      *
191      *  @return true if cache is populated and false if the cache is not
192      *          populated.
193      */
194     auto isPDREffecterCacheValid()
195     {
196         return (occInstanceToEffecter.empty() ? false : true);
197     }
198 };
199 
200 } // namespace pldm
201