xref: /openbmc/openpower-occ-control/pldm.hpp (revision 05e95596)
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 
75     /** @brief Fetch the OCC state sensor PDRs and populate the cache with
76      *         sensorId to OCC instance mapping information and the sensor
77      *         offset for Operational Running Status.
78      *
79      *  @param[in] pdrs - OCC state sensor PDRs
80      *  @param[out] sensorInstanceMap - map of sensorID to OCC instance
81      *  @param[out] sensorOffset - sensor offset of interested state set ID
82      */
83     void fetchOCCSensorInfo(const PdrList& pdrs,
84                             SensorToOCCInstance& sensorInstanceMap,
85                             SensorOffset& sensorOffset);
86 
87     /** @brief Fetch the OCC state effecter PDRs and populate the cache with
88      *         OCC instance to EffecterID information.
89      *
90      *  @param[in] pdrs - OCC state effecter PDRs
91      *  @param[out] instanceToEffecterMap - map of OCC instance to effecterID
92      *  @param[out] count - sensor offset of interested state set ID
93      *  @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID
94      */
95     void fetchOCCEffecterInfo(const PdrList& pdrs,
96                               OccInstanceToEffecter& instanceToEffecterMap,
97                               CompositeEffecterCount& count,
98                               uint8_t& bootRestartPos);
99 
100     /** @brief Prepare the request for SetStateEffecterStates command
101      *
102      *  @param[in] instanceId - PLDM instanceID
103      *  @param[in] instanceToEffecterMap - map of OCC instance to effecterID
104      *  @param[in] count - compositeEffecterCount for OCC reset effecter PDR
105      *  @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID
106      *
107      *  @return PLDM request message to be sent to host for OCC reset, empty
108      *          response in the case of failure.
109      */
110     std::vector<uint8_t>
111         prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
112                               CompositeEffecterCount effecterCount,
113                               uint8_t bootRestartPos);
114 
115     /** @brief Send the PLDM message to reset the OCC
116      *
117      *  @param[in] instanceId - OCC instance to reset
118      *
119      */
120     void resetOCC(open_power::occ::instanceID occInstanceId);
121 
122   private:
123     /** @brief Callback handler to be invoked when the state of the OCC
124      *         changes
125      */
126     std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
127 
128     /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
129      *         processes if the event corresponds to OCC state change.
130      */
131     sdbusplus::bus::match_t pldmEventSignal;
132 
133     /** @brief Used to subscribe for host state change signal */
134     sdbusplus::bus::match_t hostStateSignal;
135 
136     /** @brief PLDM Sensor ID to OCC Instance mapping
137      */
138     SensorToOCCInstance sensorToOCCInstance;
139 
140     /** @brief Sensor offset of state set ID
141      * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
142      */
143     SensorOffset sensorOffset;
144 
145     /** @brief OCC Instance mapping to PLDM Effecter ID
146      */
147     OccInstanceToEffecter occInstanceToEffecter;
148 
149     /** @brief compositeEffecterCount for OCC reset state effecter PDR */
150     CompositeEffecterCount effecterCount = 0;
151 
152     /** @brief Position of Boot/Restart Cause stateSetID in OCC state
153      *         effecter PDR
154      */
155     uint8_t bootRestartPosition = 0;
156 
157     /** @brief When the OCC state changes host sends PlatformEventMessage
158      *         StateSensorEvent, this function processes the D-Bus signal
159      *         with the sensor event information and invokes the callback
160      *         to change the OCC state.
161      *
162      *  @param[in] msg - data associated with the subscribed signal
163      */
164     void sensorEvent(sdbusplus::message::message& msg);
165 
166     /** @brief When the host state changes and if the CurrentHostState is
167      *         xyz.openbmc_project.State.Host.HostState.Off then
168      *         the cache of OCC sensors and effecters mapping is cleared.
169      *
170      *  @param[in] msg - data associated with the subscribed signal
171      */
172     void hostStateEvent(sdbusplus::message::message& msg);
173 
174     /** @brief Check if the PDR cache for PLDM OCC sensors is valid
175      *
176      *  @return true if cache is populated and false if the cache is not
177      *          populated.
178      */
179     auto isOCCSensorCacheValid()
180     {
181         return (sensorToOCCInstance.empty() ? false : true);
182     }
183 
184     /** @brief Check if the PDR cache for PLDM OCC effecters is valid
185      *
186      *  @return true if cache is populated and false if the cache is not
187      *          populated.
188      */
189     auto isPDREffecterCacheValid()
190     {
191         return (occInstanceToEffecter.empty() ? false : true);
192     }
193 };
194 
195 } // namespace pldm
196