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