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 *