From e4a5febf0732d72f89965830d89ff79235db20b6 Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Wed, 13 May 2026 12:52:19 -0500 Subject: [PATCH] pldm: PollForPlatformEventMessage for Debug Ids When PlatformEventMessage is received, along with the PollForPlatformEventMessage for the data for the received data transfer handle, ask for PollForPlatformEventMessage data for Debug Ids such as 1, 2, 3, and 23 amongst them before sending Ack. Signed-off-by: Shirish Pargaonkar --- common/utils.cpp | 16 ++--- common/utils.hpp | 10 ++- platform-mc/event_manager.cpp | 123 +++++++++++++++++++++++++++++----- platform-mc/event_manager.hpp | 31 +++++++-- 4 files changed, 149 insertions(+), 31 deletions(-) diff --git a/common/utils.cpp b/common/utils.cpp index b181ba52a2..79d726abf7 100644 --- a/common/utils.cpp +++ b/common/utils.cpp @@ -617,10 +617,12 @@ int emitRDEDeviceDetectedSignal( return PLDM_SUCCESS; } +#ifdef OEM_AMD void emitPldmMessagePollEventSignal( uint8_t formatVersion, uint8_t tid, const std::string& tName, - uint8_t eventClass, uint32_t dataTransferHandle, uint16_t eventId, - uint16_t eventDataSize, int fd) { + uint8_t eventClass, uint16_t eventId, + const std::vector& dataTransferHandles, + const std::vector& eventDataSizes, int fd) { try { @@ -641,8 +643,8 @@ void emitPldmMessagePollEventSignal( formatVersion, eventClass, eventId, - dataTransferHandle, - eventDataSize, + dataTransferHandles, + eventDataSizes, sdbusplus::message::unix_fd(fd)); msg.signal_send(); } @@ -655,15 +657,12 @@ void emitPldmMessagePollEventSignal( lg2::info("Emitting PLDM Message Poll Event signal: FormatVersion={FV}, TID={TID}, " "TerminusName={NAME}, EventClass={CLASS}, EventId={ID}, " - "DataTransferHandlee={DTH}, " - "Size={SIZE}, FD={FD}", + "FD={FD}", "FV", formatVersion, "TID", tid, "NAME", tName, "CLASS", lg2::hex, eventClass, "ID", lg2::hex, eventId, - "DTH", lg2::hex, dataTransferHandle, - "SIZE", lg2::hex, eventDataSize, "FD", fd); } @@ -698,6 +697,7 @@ int create_mem_fd(const std::vector& data) return fd; } +#endif void recoverMctpEndpoint(const std::string& endpointObjPath) { diff --git a/common/utils.hpp b/common/utils.hpp index 6b74445373..a12bcd5618 100644 --- a/common/utils.hpp +++ b/common/utils.hpp @@ -581,6 +581,7 @@ int emitRDEDeviceDetectedSignal( uint8_t tid, eid mctpEid, pldm::UUID devUUID, const std::vector>& pdrPayloads); +#ifdef OEM_AMD /** @brief Emit a D-Bus signal for a PLDM Message Poll event. * * This signal notifies subscribers that a message poll event has been @@ -591,21 +592,24 @@ int emitRDEDeviceDetectedSignal( * @param[in] tid - Terminal ID of the source * @param[in] tName - Terminal name or identifier string * @param[in] eventClass - The class of the event being polled - * @param[in] dataTransferHandle - Handle used to identify the data transfer * @param[in] eventId - The unique identifier for the event + * @param[in] dataTransferHandle - Handle used to identify the data transfer * @param[in] eventDataSize - The size of the event data in bytes * @param[in] fd - File descriptor for the data transfer, if applicable */ void emitPldmMessagePollEventSignal( uint8_t formatVersion, uint8_t tid, const std::string& tName, - uint8_t eventClass, uint32_t dataTransferHandle, - uint16_t eventId, uint16_t eventDataSize, int fd); + uint8_t eventClass, uint16_t eventId, + const std::vector& dataTransferHandles, + const std::vector& eventDataSizes, + int fd); /** @brief Create a memfd and write data to it * @param[in] data - data to write to the memfd * @return fd - the file descriptor of the memfd */ int create_mem_fd(const std::vector& data); +#endif /** * @brief call Recover() method to recover an MCTP Endpoint diff --git a/platform-mc/event_manager.cpp b/platform-mc/event_manager.cpp index 5a95aa453c..090a347d30 100644 --- a/platform-mc/event_manager.cpp +++ b/platform-mc/event_manager.cpp @@ -623,8 +623,8 @@ std::string EventManager::getTerminusName(pldm_tid_t tid) const } void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass, - uint8_t formatVersion, uint32_t dataTransferHandle, - uint16_t eventId, std::vector& eventMessage) + uint16_t eventId, + std::vector& eventMessage) { try { @@ -638,18 +638,6 @@ void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass, lg2::error( "Failed to handle platform event msg for terminus {TID}, event {EVENTID} return {RET}", "TID", tid, "EVENTID", eventId, "RET", rc); - } else { - lg2::info("Handle platform event msg for terminus {TID}, event {EVENTID}, size {EVSIZE}", - "TID", tid, "EVENTID", lg2::hex, eventId, "EVSIZE", lg2::hex, eventMessage.size()); - - int fd = pldm::utils::create_mem_fd(eventMessage); - if (fd != -1) { - std::string tName = getTerminusName(tid); - pldm::utils::emitPldmMessagePollEventSignal( - formatVersion, tid, tName, eventClass, dataTransferHandle, - eventId, eventMessage.size(), fd); - close(fd); - } } } } @@ -661,6 +649,40 @@ void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass, } } +#ifdef OEM_AMD +void EventManager::handlePollEventData(pldm_tid_t tid, uint8_t formatVersion, + uint8_t eventClass, uint16_t eventId, + const std::vector& dataTransferHandles, + const std::vector& eventDataSizes, + std::vector& eventMessage) +{ + int fd = pldm::utils::create_mem_fd(eventMessage); + if (fd == -1) + { + lg2::error("Failed to create memory file descriptor for TID {TID}", "TID", tid); + return; + } + + try + { + std::string tName = getTerminusName(tid); + + pldm::utils::emitPldmMessagePollEventSignal( + formatVersion, tid, tName, eventClass, eventId, + dataTransferHandles, eventDataSizes, fd); + } + catch (const std::exception& e) + { + lg2::error("Failed to process message poll event for terminus {TID}, event {EVENTID}, error: {ERROR}", + "TID", tid, + "EVENTID", lg2::hex, eventId, + "ERROR", e.what()); + } + + close(fd); +} +#endif + exec::task EventManager::pollForPlatformEventTask( pldm_tid_t tid, uint32_t pollDataTransferHandle) { @@ -677,6 +699,18 @@ exec::task EventManager::pollForPlatformEventTask( std::vector eventMessage{}; +#ifdef OEM_AMD + constexpr uint8_t dbgLogDump = 0x5C; + constexpr uint8_t pldmEvent = 0x4C; + constexpr uint8_t syncFlood = 0x01; + constexpr uint8_t coreShutDown = 0x41; + + std::vector completeEventMessage{}; + std::vector dataTransferHandles{}, eventDataSizes{}; + uint32_t currentDataTransferHandle = pollDataTransferHandle; + std::deque debugIds = {0, 1, 2, 3, 23, 24, 25, 33, 36, 37, 38, 40}; +#endif + // Reset and mark terminus as available updateAvailableState(tid, true); @@ -701,6 +735,42 @@ exec::task EventManager::pollForPlatformEventTask( co_await stdexec::just_stopped(); } +#ifdef OEM_AMD + /* + * Before sending Ack, check whether there are any remaining debug ids + * for which data needs to be fetched in case event id has 0x4c as msb + * and either 0x1 or 0x41 as lsb. + */ + if (transferOperationFlag == PLDM_ACKNOWLEDGEMENT_ONLY) { + uint32_t dataSize = eventMessage.size(); + if (dataSize > 0) + { + dataTransferHandles.push_back(currentDataTransferHandle); + eventDataSizes.push_back(dataSize); + completeEventMessage.insert(completeEventMessage.end(), + eventMessage.begin(), eventMessage.end()); + } + if ((polledEventId >> 8 == pldmEvent) && + ((polledEventId & 0xFF) == syncFlood || (polledEventId & 0xFF) == coreShutDown) && + !debugIds.empty()) + { + uint8_t nextId = debugIds.front(); + debugIds.pop_front(); + dataTransferHandle = (dbgLogDump << 24) | (nextId << 16); + + transferOperationFlag = PLDM_GET_FIRSTPART; + eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NONE; + currentDataTransferHandle = dataTransferHandle; + eventMessage.clear(); + } + else { // No more remaining debug ids + eventId = polledEventId; + eventIdToAcknowledge = polledEventId; + dataTransferHandle = 0x0; + eventMessage = completeEventMessage; + } + } +#endif rc = co_await pollForPlatformEventMessage( tid, formatVersion, transferOperationFlag, dataTransferHandle, eventIdToAcknowledge, completionCode, eventTid, eventId, @@ -714,6 +784,23 @@ exec::task EventManager::pollForPlatformEventTask( co_return rc; } +#ifdef OEM_AMD + /* + * If a debug id has no data, BMC receives tid and event id as 0. + * The specification does not mandate either End or StartandEnd + * in the response in which case, pldmd code would not set + * dataTransferHandle as PLDM_ACKNOWLEDGEMENT_ONLY. + * So we need to force a check for data for remaining debug ids, + * if any. + */ + if ((eventId == 0 && eventDataSize == 0) && + transferOperationFlag != PLDM_ACKNOWLEDGEMENT_ONLY) + { + transferOperationFlag = PLDM_ACKNOWLEDGEMENT_ONLY; + eventId = polledEventId; + continue; + } +#endif if (eventDataSize > 0) { eventMessage.insert(eventMessage.end(), eventData, @@ -726,8 +813,14 @@ exec::task EventManager::pollForPlatformEventTask( if (eventHandlers.contains(polledEventClass)) { callPolledEventHandlers(polledEventTid, polledEventClass, - formatVersion, pollDataTransferHandle, polledEventId, eventMessage); +#ifdef OEM_AMD + handlePollEventData(polledEventTid, formatVersion, + polledEventClass, eventId, + dataTransferHandles, eventDataSizes, + eventMessage); +#endif + } eventMessage.clear(); diff --git a/platform-mc/event_manager.hpp b/platform-mc/event_manager.hpp index 5cf412a3f3..0261bbef9d 100644 --- a/platform-mc/event_manager.hpp +++ b/platform-mc/event_manager.hpp @@ -213,16 +213,37 @@ class EventManager * * @param[in] tid - terminus ID * @param[out] eventClass - Event class - * @param[in] formatVersion - The PLDM version/format of the event data - * @param[in] dataTransferHandle - Handle identifying the specific data block - * in the event transfer * @param[out] eventId - Event ID * @param[in] eventMessage - event data of response message * */ void callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass, - uint8_t formatVersion, uint32_t dataTransferHandle, - uint16_t eventId, std::vector& eventMessage); + uint16_t eventId, + std::vector& eventMessage); + +#ifdef OEM_AMD + /** @brief Handles incoming PLDM Message Poll Event data chunks specific to AMD platforms. + * + * This function aggregates and processes data transfer handles, event sizes, + * and raw event payloads retrieved from a platform endpoint during message polling loops. + * + * @param[in] tid - The Terminus ID of the source PLDM endpoint + * @param[in] formatVersion - The PLDM event format version specification + * @param[in] eventClass - The classification identifier of the incoming event + * @param[in] eventId - Unique sequence identifier for the multi-part event message + * @param[in] dataTransferHandles - Vector of tokens identifying individual data transfer blocks + * @param[in] eventDataSizes - Vector containing the corresponding byte size of each data chunk + * @param[in] eventMessage - Buffered reference to append or mutate the raw payload byte stream + * + * @return None + */ + void handlePollEventData(pldm_tid_t tid, uint8_t formatVersion, + uint8_t eventClass, uint16_t eventId, + const std::vector& dataTransferHandles, + const std::vector& eventDataSizes, + std::vector& eventMessage); +#endif + /** @brief Get the terminus name for a given TID *