1f60ac27eSMatt Spinler #pragma once 2f60ac27eSMatt Spinler 3f60ac27eSMatt Spinler #include "host_interface.hpp" 4f60ac27eSMatt Spinler #include "pel.hpp" 5f60ac27eSMatt Spinler #include "repository.hpp" 6f60ac27eSMatt Spinler 7f60ac27eSMatt Spinler #include <deque> 8f869fcf8SMatt Spinler #include <sdeventplus/clock.hpp> 9f869fcf8SMatt Spinler #include <sdeventplus/utility/timer.hpp> 10f60ac27eSMatt Spinler 11f60ac27eSMatt Spinler namespace openpower::pels 12f60ac27eSMatt Spinler { 13f60ac27eSMatt Spinler 14f60ac27eSMatt Spinler /** 15f60ac27eSMatt Spinler * @class HostNotifier 16f60ac27eSMatt Spinler * 17f60ac27eSMatt Spinler * This class handles notifying the host firmware of new PELs. 18f60ac27eSMatt Spinler */ 19f60ac27eSMatt Spinler class HostNotifier 20f60ac27eSMatt Spinler { 21f60ac27eSMatt Spinler public: 22f60ac27eSMatt Spinler HostNotifier() = delete; 23f60ac27eSMatt Spinler HostNotifier(const HostNotifier&) = delete; 24f60ac27eSMatt Spinler HostNotifier& operator=(const HostNotifier&) = delete; 25f60ac27eSMatt Spinler HostNotifier(HostNotifier&&) = delete; 26f60ac27eSMatt Spinler HostNotifier& operator=(HostNotifier&&) = delete; 27f60ac27eSMatt Spinler 28f60ac27eSMatt Spinler /** 29f60ac27eSMatt Spinler * @brief Constructor 30f60ac27eSMatt Spinler * 31f60ac27eSMatt Spinler * @param[in] repo - The PEL repository object 32f60ac27eSMatt Spinler * @param[in] dataIface - The data interface object 33f60ac27eSMatt Spinler * @param[in] hostIface - The host interface object 34f60ac27eSMatt Spinler */ 35f60ac27eSMatt Spinler HostNotifier(Repository& repo, DataInterfaceBase& dataIface, 36f60ac27eSMatt Spinler std::unique_ptr<HostInterface> hostIface); 37f60ac27eSMatt Spinler 38f60ac27eSMatt Spinler /** 39f60ac27eSMatt Spinler * @brief Destructor 40f60ac27eSMatt Spinler */ 41f60ac27eSMatt Spinler ~HostNotifier(); 42f60ac27eSMatt Spinler 43f60ac27eSMatt Spinler /** 44f60ac27eSMatt Spinler * @brief Returns the PEL queue size. 45f60ac27eSMatt Spinler * 46f60ac27eSMatt Spinler * For testing. 47f60ac27eSMatt Spinler * 48f60ac27eSMatt Spinler * @return size_t - The queue size 49f60ac27eSMatt Spinler */ 50f60ac27eSMatt Spinler size_t queueSize() const 51f60ac27eSMatt Spinler { 52f60ac27eSMatt Spinler return _pelQueue.size(); 53f60ac27eSMatt Spinler } 54f60ac27eSMatt Spinler 55f60ac27eSMatt Spinler /** 56f60ac27eSMatt Spinler * @brief Specifies if the PEL needs to go onto the queue to be 57f60ac27eSMatt Spinler * set to the host. 58f60ac27eSMatt Spinler * 59a943b15bSMatt Spinler * Only returns false if: 60a943b15bSMatt Spinler * - Already acked by the host (or they didn't like it) 61a943b15bSMatt Spinler * - Hidden and the HMC already got it 62a943b15bSMatt Spinler * - The 'do not report to host' bit is set 63a943b15bSMatt Spinler * 64f60ac27eSMatt Spinler * @param[in] id - The PEL ID 65f60ac27eSMatt Spinler * 66f60ac27eSMatt Spinler * @return bool - If enqueue is required 67f60ac27eSMatt Spinler */ 68f60ac27eSMatt Spinler bool enqueueRequired(uint32_t id) const; 69f60ac27eSMatt Spinler 70*f77debb9SMatt Spinler /** 71*f77debb9SMatt Spinler * @brief If the host still needs to be notified of the PEL 72*f77debb9SMatt Spinler * at the time of the notification. 73*f77debb9SMatt Spinler * 74*f77debb9SMatt Spinler * Only returns false if: 75*f77debb9SMatt Spinler * - Already acked by the host 76*f77debb9SMatt Spinler * - It's hidden, and the HMC already got or will get it. 77*f77debb9SMatt Spinler * 78*f77debb9SMatt Spinler * @param[in] id - The PEL ID 79*f77debb9SMatt Spinler * 80*f77debb9SMatt Spinler * @return bool - If the notify is required 81*f77debb9SMatt Spinler */ 82*f77debb9SMatt Spinler bool notifyRequired(uint32_t id) const; 83*f77debb9SMatt Spinler 84f60ac27eSMatt Spinler private: 85f60ac27eSMatt Spinler /** 86f60ac27eSMatt Spinler * @brief This function gets called by the Repository class 87f60ac27eSMatt Spinler * when a new PEL is added to it. 88f60ac27eSMatt Spinler * 89f60ac27eSMatt Spinler * @param[in] pel - The new PEL 90f60ac27eSMatt Spinler */ 91f60ac27eSMatt Spinler void newLogCallback(const PEL& pel); 92f60ac27eSMatt Spinler 93f60ac27eSMatt Spinler /** 94f60ac27eSMatt Spinler * @brief This function runs on every existing PEL at startup 95f60ac27eSMatt Spinler * and puts the PEL on the queue to send if necessary. 96f60ac27eSMatt Spinler * 97f60ac27eSMatt Spinler * @param[in] pel - The PEL 98f60ac27eSMatt Spinler * 99f60ac27eSMatt Spinler * @return bool - This is an indicator to the Repository::for_each 100f60ac27eSMatt Spinler * function to traverse every PEL. Always false. 101f60ac27eSMatt Spinler */ 102f60ac27eSMatt Spinler bool addPELToQueue(const PEL& pel); 103f60ac27eSMatt Spinler 104f60ac27eSMatt Spinler /** 105*f77debb9SMatt Spinler * @brief Takes the first PEL from the queue that needs to be 106*f77debb9SMatt Spinler * sent, and issues the send if conditions are right. 107f60ac27eSMatt Spinler */ 108f60ac27eSMatt Spinler void doNewLogNotify(); 109f60ac27eSMatt Spinler 110f60ac27eSMatt Spinler /** 111f60ac27eSMatt Spinler * @brief Called when the host changes state. 112f60ac27eSMatt Spinler * 1133019c6fbSMatt Spinler * If the new state is host up and there are PELs to send, it 1143019c6fbSMatt Spinler * will trigger the first command. If the new state is off, then 1153019c6fbSMatt Spinler * it will transfer any PELs that were sent but not acked yet back 1163019c6fbSMatt Spinler * to the queue to be sent again. 1173019c6fbSMatt Spinler * 118f60ac27eSMatt Spinler * @param[in] hostUp - The new host state 119f60ac27eSMatt Spinler */ 120f60ac27eSMatt Spinler void hostStateChange(bool hostUp); 121f60ac27eSMatt Spinler 122f60ac27eSMatt Spinler /** 123f60ac27eSMatt Spinler * @brief The callback function invoked after the asynchronous 124f60ac27eSMatt Spinler * PLDM receive function is complete. 125f60ac27eSMatt Spinler * 126f869fcf8SMatt Spinler * If the command was successful, the state of that PEL will 127f869fcf8SMatt Spinler * be set to 'sent', and the next send will be triggered. 128f869fcf8SMatt Spinler * 129f869fcf8SMatt Spinler * If the command failed, a retry timer will be started so it 130f869fcf8SMatt Spinler * can be sent again. 131f869fcf8SMatt Spinler * 132f60ac27eSMatt Spinler * @param[in] status - The response status 133f60ac27eSMatt Spinler */ 134f60ac27eSMatt Spinler void commandResponse(ResponseStatus status); 135f60ac27eSMatt Spinler 136f60ac27eSMatt Spinler /** 137f869fcf8SMatt Spinler * @brief The function called when the command failure retry 138f869fcf8SMatt Spinler * time is up. 139f869fcf8SMatt Spinler * 140f869fcf8SMatt Spinler * It will issue a send of the previous PEL and increment the 141f869fcf8SMatt Spinler * retry count. 142f869fcf8SMatt Spinler */ 143f869fcf8SMatt Spinler void retryTimerExpired(); 144f869fcf8SMatt Spinler 145f869fcf8SMatt Spinler /** 1463019c6fbSMatt Spinler * @brief Stops an in progress command 1473019c6fbSMatt Spinler * 1483019c6fbSMatt Spinler * In progress meaning after the send but before the response. 1493019c6fbSMatt Spinler */ 1503019c6fbSMatt Spinler void stopCommand(); 1513019c6fbSMatt Spinler 1523019c6fbSMatt Spinler /** 153f60ac27eSMatt Spinler * @brief The PEL repository object 154f60ac27eSMatt Spinler */ 155f60ac27eSMatt Spinler Repository& _repo; 156f60ac27eSMatt Spinler 157f60ac27eSMatt Spinler /** 158f60ac27eSMatt Spinler * @brief The data interface object 159f60ac27eSMatt Spinler */ 160f60ac27eSMatt Spinler DataInterfaceBase& _dataIface; 161f60ac27eSMatt Spinler 162f60ac27eSMatt Spinler /** 163f60ac27eSMatt Spinler * @brief Base class pointer for the host command interface 164f60ac27eSMatt Spinler */ 165f60ac27eSMatt Spinler std::unique_ptr<HostInterface> _hostIface; 166f60ac27eSMatt Spinler 167f60ac27eSMatt Spinler /** 168f60ac27eSMatt Spinler * @brief The list of PEL IDs that need to be sent. 169f60ac27eSMatt Spinler */ 170f60ac27eSMatt Spinler std::deque<uint32_t> _pelQueue; 171f869fcf8SMatt Spinler 172f869fcf8SMatt Spinler /** 173f869fcf8SMatt Spinler * @brief The list of IDs that were sent, but not acked yet. 174f869fcf8SMatt Spinler * 175f869fcf8SMatt Spinler * These move back to _pelQueue on a power off. 176f869fcf8SMatt Spinler */ 177f869fcf8SMatt Spinler std::vector<uint32_t> _sentPELs; 178f869fcf8SMatt Spinler 179f869fcf8SMatt Spinler /** 180f869fcf8SMatt Spinler * @brief The ID the PEL where the notification has 181f869fcf8SMatt Spinler * been kicked off but the asynchronous response 182f869fcf8SMatt Spinler * hasn't been received yet. 183f869fcf8SMatt Spinler */ 184f869fcf8SMatt Spinler uint32_t _inProgressPEL = 0; 185f869fcf8SMatt Spinler 186f869fcf8SMatt Spinler /** 187f869fcf8SMatt Spinler * @brief The command retry count 188f869fcf8SMatt Spinler */ 189f869fcf8SMatt Spinler size_t _retryCount = 0; 190f869fcf8SMatt Spinler 191f869fcf8SMatt Spinler /** 192f869fcf8SMatt Spinler * @brief The command retry timer. 193f869fcf8SMatt Spinler */ 194f869fcf8SMatt Spinler sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _retryTimer; 195f60ac27eSMatt Spinler }; 196f60ac27eSMatt Spinler 197f60ac27eSMatt Spinler } // namespace openpower::pels 198