1 #pragma once 2 3 #include "config.h" 4 5 #include "libpldm/platform.h" 6 #include "libpldm/pldm.h" 7 8 #include "requester/handler.hpp" 9 #include "requester/mctp_endpoint_discovery.hpp" 10 #include "terminus.hpp" 11 12 #include <limits> 13 #include <map> 14 #include <memory> 15 #include <optional> 16 #include <queue> 17 #include <utility> 18 #include <vector> 19 20 namespace pldm 21 { 22 23 enum class SupportedTransportLayer 24 { 25 MCTP 26 }; 27 28 namespace platform_mc 29 { 30 31 /** @brief Size of TID Pool in pldmd */ 32 constexpr size_t tidPoolSize = std::numeric_limits<pldm_tid_t>::max() + 1; 33 /** @brief Type definition for Requester request handler */ 34 using RequesterHandler = requester::Handler<requester::Request>; 35 /** @brief Type definition for Terminus handler mapper */ 36 using TerminiMapper = std::map<pldm_tid_t, std::shared_ptr<Terminus>>; 37 38 class Manager; 39 /** 40 * @brief TerminusManager 41 * 42 * TerminusManager class to discover and initialize PLDM terminus. 43 */ 44 class TerminusManager 45 { 46 public: 47 TerminusManager() = delete; 48 TerminusManager(const TerminusManager&) = delete; 49 TerminusManager(TerminusManager&&) = delete; 50 TerminusManager& operator=(const TerminusManager&) = delete; 51 TerminusManager& operator=(TerminusManager&&) = delete; 52 virtual ~TerminusManager() = default; 53 54 explicit TerminusManager(sdeventplus::Event& /* event */, 55 RequesterHandler& handler, 56 pldm::InstanceIdDb& instanceIdDb, 57 TerminiMapper& termini, Manager* manager) : 58 handler(handler), instanceIdDb(instanceIdDb), termini(termini), 59 tidPool(tidPoolSize, false), manager(manager) 60 { 61 // DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved 62 tidPool[0] = true; 63 tidPool[PLDM_TID_RESERVED] = true; 64 } 65 66 /** @brief start a coroutine to discover terminus 67 * 68 * @param[in] mctpInfos - list information of the MCTP endpoints 69 */ 70 void discoverMctpTerminus(const MctpInfos& mctpInfos); 71 72 /** @brief remove MCTP endpoints 73 * 74 * @param[in] mctpInfos - list information of the MCTP endpoints 75 */ 76 void removeMctpTerminus(const MctpInfos& mctpInfos); 77 78 /** @brief Send request PLDM message to tid. The function will return when 79 * received the response message from terminus. The function will 80 * auto get the instanceID from libmctp and update to request 81 * message. 82 * 83 * @param[in] tid - Destination TID 84 * @param[in] request - request PLDM message 85 * @param[out] responseMsg - response PLDM message 86 * @param[out] responseLen - length of response PLDM message 87 * @return coroutine return_value - PLDM completion code 88 */ 89 exec::task<int> sendRecvPldmMsg(pldm_tid_t tid, Request& request, 90 const pldm_msg** responseMsg, 91 size_t* responseLen); 92 93 /** @brief Send request PLDM message to eid. The function will 94 * return when received the response message from terminus. 95 * 96 * @param[in] eid - Destination EID 97 * @param[in] request - request PLDM message 98 * @param[out] responseMsg - response PLDM message 99 * @param[out] responseLen - length of response PLDM message 100 * @return coroutine return_value - PLDM completion code 101 */ 102 virtual exec::task<int> sendRecvPldmMsgOverMctp( 103 mctp_eid_t eid, Request& request, const pldm_msg** responseMsg, 104 size_t* responseLen); 105 106 /** @brief member functions to map/unmap tid 107 */ 108 std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid); 109 110 /** @brief Member functions to response the TID of specific MCTP interface 111 * 112 * @param[in] mctpInfos - list information of the MCTP endpoints 113 * 114 * @return tid - Terminus tid 115 */ 116 std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const; 117 118 /** @brief Member functions to find the TID for MCTP interface. Response the 119 * Terminus TID when mctpInfo is already in the data base. Response 120 * new tid from pool when mctpInfo is new. 121 * 122 * @param[in] mctpInfos - list information of the MCTP endpoints 123 * 124 * @return tid - Terminus tid 125 */ 126 std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo); 127 128 /** @brief Member functions to store the mctp info and tid to terminus info 129 * list. 130 * 131 * @param[in] mctpInfos - list information of the MCTP endpoints 132 * @param[in] tid - Destination TID 133 * 134 * @return tid - Terminus tid 135 */ 136 std::optional<pldm_tid_t> 137 storeTerminusInfo(const MctpInfo& mctpInfo, pldm_tid_t tid); 138 139 /** @brief Member functions to remove the TID from the transportLayer and 140 * mctpInfo table 141 * 142 * @param[in] tid - Destination TID 143 * 144 * @return true/false - True when tid in the table otherwise return false 145 */ 146 bool unmapTid(const pldm_tid_t& tid); 147 148 private: 149 /** @brief Find the terminus object pointer in termini list. 150 * 151 * @param[in] mctpInfos - list information of the MCTP endpoints 152 */ 153 TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo); 154 155 /** @brief The coroutine task execute by discoverMctpTerminus() 156 * 157 * @return coroutine return_value - PLDM completion code 158 */ 159 exec::task<int> discoverMctpTerminusTask(); 160 161 /** @brief Initialize terminus and then instantiate terminus object to keeps 162 * the data fetched from terminus 163 * 164 * @param[in] mctpInfo - information of the MCTP endpoints 165 * @return coroutine return_value - PLDM completion code 166 */ 167 exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo); 168 169 /** @brief Send getTID PLDM command to destination EID and then return the 170 * value of tid in reference parameter. 171 * 172 * @param[in] eid - Destination EID 173 * @param[out] tid - Terminus TID 174 * @return coroutine return_value - PLDM completion code 175 */ 176 exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid); 177 178 /** @brief Send setTID command to destination EID. 179 * 180 * @param[in] eid - Destination EID 181 * @param[in] tid - Destination TID 182 * @return coroutine return_value - PLDM completion code 183 */ 184 exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid); 185 186 /** @brief Send getPLDMTypes command to destination TID and then return the 187 * value of supportedTypes in reference parameter. 188 * 189 * @param[in] tid - Destination TID 190 * @param[out] supportedTypes - Supported Types returned from terminus 191 * @return coroutine return_value - PLDM completion code 192 */ 193 exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes); 194 195 /** @brief Send getPLDMCommands command to destination TID and then return 196 * the value of supportedCommands in reference parameter. 197 * 198 * @param[in] tid - Destination TID 199 * @param[in] type - PLDM Type 200 * @param[in] supportedCmds - Supported commands returned from terminus 201 * for specific type 202 * @return coroutine return_value - PLDM completion code 203 */ 204 exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type, 205 bitfield8_t* supportedCmds); 206 207 /** @brief Reference to a Handler object that manages the request/response 208 * logic. 209 */ 210 RequesterHandler& handler; 211 212 /** @brief Reference to the instanceID data base from libpldm */ 213 pldm::InstanceIdDb& instanceIdDb; 214 215 /** @brief Managed termini list */ 216 TerminiMapper& termini; 217 218 /** @brief tables for maintaining assigned TID */ 219 std::vector<bool> tidPool; 220 221 /** @brief Store the supported transport layers of specific TID */ 222 std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable; 223 224 /** @brief Store the supported MCTP interface info of specific TID */ 225 std::map<pldm_tid_t, MctpInfo> mctpInfoTable; 226 227 /** @brief A queue of MctpInfos to be discovered **/ 228 std::queue<MctpInfos> queuedMctpInfos{}; 229 230 /** @brief coroutine handle of discoverTerminusTask */ 231 std::optional<std::pair<exec::async_scope, std::optional<int>>> 232 discoverMctpTerminusTaskHandle{}; 233 234 /** @brief A Manager interface for calling the hook functions **/ 235 Manager* manager; 236 }; 237 } // namespace platform_mc 238 } // namespace pldm 239