From e758782ca79a59706a840107db2662d15f1634a6 Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Sun, 21 Jun 2026 23:28:56 -0500 Subject: [PATCH] pldmd: Changes for 2X1P Changes for 2X1P and Set Event Receiver code. Rely on interface and endpoint properties to identify local BMC eid for an interface and use the eid for Set Event Receiver command instead of relying bmceid files under /var/run. Rely on UUID and Network Interface name to identify processor id such as 0 and 1 since in 2x1P mode, both the SoC emit the same UUID. Signed-off-by: Shirish Pargaonkar --- common/types.hpp | 21 +++-- .../com.amd.Hardware.Chassis/pdr_config.json | 10 ++- fw-update/manager.hpp | 2 +- oem/amd/platform-mc/platform_manager.cpp | 26 ++++-- platform-mc/platform_manager.cpp | 20 ++++- platform-mc/platform_manager.hpp | 4 +- platform-mc/terminus_manager.cpp | 37 ++------ platform-mc/terminus_manager.hpp | 26 ++---- requester/mctp_endpoint_discovery.cpp | 85 +++++++++++++++---- requester/mctp_endpoint_discovery.hpp | 7 ++ 10 files changed, 151 insertions(+), 87 deletions(-) diff --git a/common/types.hpp b/common/types.hpp index 68d3c3c755..312565152b 100644 --- a/common/types.hpp +++ b/common/types.hpp @@ -31,20 +31,25 @@ using MctpMedium = std::string; * uint32_t is used as defined in MCTP Endpoint D-Bus Interface */ using NetworkId = uint32_t; +using NetworkInterface = std::string; +using LocalEid = uint8_t; /** @brief Type definition of MCTP name in string */ using MctpInfoName = std::optional; /** @brief Type definition of MCTP interface information between two endpoints. - * eid : Endpoint EID in byte. Defined to match with MCTP D-Bus - * interface - * UUID : Endpoint UUID which is used to different the endpoints - * MctpMedium: Endpoint MCTP Medium info (Resersed) - * NetworkId: MCTP network index - * name: Alias name of the endpoint, e.g. BMC, NIC, etc. + * + * eid : Endpoint EID (byte). Matches MCTP D-Bus endpoint EID. + * UUID : Endpoint UUID used to uniquely identify endpoints. + * MctpMedium : Endpoint MCTP medium information (reserved/transport-specific). + * NetworkId : MCTP network index identifying the MCTP network. + * MctpInfoName : Alias name of the endpoint (e.g. BMC, NIC, etc.). + * NetworkInterface : Underlying transport interface used for MCTP communication + * (e.g. mctpi3c4, mctppcie0). + * LocalEid : Host-assigned identifier associated with the interface. */ -using MctpInfo = std::tuple; +using MctpInfo = std::tuple; /** @brief Type definition of MCTP endpoint D-Bus properties in * xyz.openbmc_project.MCTP.Endpoint D-Bus interface. @@ -54,7 +59,7 @@ using MctpInfo = std::tuple; * interface * MCTPMsgTypes: MCTP message types */ -using MctpEndpointProps = std::tuple; +using MctpEndpointProps = std::tuple; /** @brief Type defined for list of MCTP interface information */ diff --git a/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json b/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json index e068623a78..b3e1073f61 100644 --- a/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json +++ b/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json @@ -1,7 +1,13 @@ { "uuids": { - "28318908-bc42-4463-a8f8-f0cc7b43c5e6": 0, - "8bc76e13-94c1-4e52-992b-d4d845e3572a": 1 + "28318908-bc42-4463-a8f8-f0cc7b43c5e6": { + "mctpi3c4": 0, + "mctpi3c5": 1 + }, + "8bc76e13-94c1-4e52-992b-d4d845e3572a": { + "mctpi3c4": 0, + "mctpi3c5": 1 + } }, "excludeNumericEffecterPDRs": [ diff --git a/fw-update/manager.hpp b/fw-update/manager.hpp index db5cb64744..9d738b0952 100644 --- a/fw-update/manager.hpp +++ b/fw-update/manager.hpp @@ -56,7 +56,7 @@ class Manager : public pldm::MctpDiscoveryHandlerIntf std::vector eids; for (const auto& mctpInfo : mctpInfos) { - eids.emplace_back(std::get(mctpInfo)); + eids.emplace_back(std::get<0>(mctpInfo)); } inventoryMgr.discoverFDs(eids); diff --git a/oem/amd/platform-mc/platform_manager.cpp b/oem/amd/platform-mc/platform_manager.cpp index 9e8cca46ff..faebf93031 100644 --- a/oem/amd/platform-mc/platform_manager.cpp +++ b/oem/amd/platform-mc/platform_manager.cpp @@ -324,7 +324,8 @@ std::optional> decode_compact_numeric_sensor_pdr( /* Setting default values when getPDRRepositoryInfo fails or does not support */ exec::task PlatformManager::get_pdr_from_json( - std::shared_ptr terminus, std::string targetUuid) + std::shared_ptr terminus, std::string targetUuid, + std::string networkInterface) { pldm_tid_t tid = terminus->getTid(); @@ -345,15 +346,24 @@ exec::task PlatformManager::get_pdr_from_json( throw std::runtime_error("Could not open UUID mapping file"); } - // 2. Parse directly into a map + using InterfaceMap = std::unordered_map; + using UuidMap = std::unordered_map; + + // Parse JSON auto j = nlohmann::json::parse(uuidFile); - auto uuid_map = j["uuids"].get>(); + auto uuidMap = j["uuids"].get(); + + // Find UUID + auto uuidIt = uuidMap.find(targetUuid); + if (uuidIt == uuidMap.end()) + { + co_return PLDM_ERROR_INVALID_DATA; + } - // Early exit if the UUID is not in the map - auto it = uuid_map.find(targetUuid); - if (it == uuid_map.end()) + // Find interface + auto ifaceIt = uuidIt->second.find(networkInterface); + if (ifaceIt == uuidIt->second.end()) { - // UUID not found in the mapping co_return PLDM_ERROR_INVALID_DATA; } @@ -378,7 +388,7 @@ exec::task PlatformManager::get_pdr_from_json( } #endif - int processorIndex = it->second; + int processorIndex = ifaceIt->second; std::string procName = "Processor" + std::to_string(processorIndex); std::string procPdrDir = pdrDir + "/" + procName; lg2::info("Loading PDRs for TID {TID} from {PATH}", "TID", tid, "PATH", procPdrDir); diff --git a/platform-mc/platform_manager.cpp b/platform-mc/platform_manager.cpp index fc5a0b301e..a6fffeac9f 100644 --- a/platform-mc/platform_manager.cpp +++ b/platform-mc/platform_manager.cpp @@ -77,7 +77,8 @@ exec::task PlatformManager::initTerminus() auto mctpInfo = terminusManager.getMctpInfoForTid(tid); if (mctpInfo.has_value()) { std::string uuid = std::get<1>(*mctpInfo); - auto rc = co_await get_pdr_from_json(terminus, uuid); + std::string networkInterface = std::get<2>(*mctpInfo); + auto rc = co_await get_pdr_from_json(terminus, uuid, networkInterface); if (rc) { lg2::error( @@ -140,7 +141,7 @@ exec::task PlatformManager::initTerminus() if (info) { pldm::utils::emitRDEDeviceDetectedSignal( - tid, info->first, info->second, redfishResources); + tid, std::get<0>(*info), std::get<1>(*info), redfishResources); } else { @@ -541,6 +542,7 @@ exec::task PlatformManager::setEventReceiver( pldm_tid_t tid, pldm_event_message_global_enable eventMessageGlobalEnable, pldm_transport_protocol_type protocolType, uint16_t heartbeatTimer) { + uint8_t localEid = 0; size_t requestBytes = PLDM_SET_EVENT_RECEIVER_REQ_BYTES; /** * Ignore heartbeatTimer bytes when eventMessageGlobalEnable is not @@ -553,9 +555,21 @@ exec::task PlatformManager::setEventReceiver( } Request request(sizeof(pldm_msg_hdr) + requestBytes); auto requestMsg = new (request.data()) pldm_msg; + + auto info = terminusManager.getMctpInfoForTid(tid); + if (info) + { + localEid = std::get<3>(*info); + } + else + { + lg2::error("Failed to find Mctp Info for terminus with TID: {TID}", "TID", tid); + } + lg2::info("Set event receiver: LocalEid {LID} for tid: {TID}", "LID", localEid, "TID", tid); + auto rc = encode_set_event_receiver_req( 0, eventMessageGlobalEnable, protocolType, - terminusManager.getLocalEid(), heartbeatTimer, requestMsg); + localEid, heartbeatTimer, requestMsg); if (rc) { lg2::error( diff --git a/platform-mc/platform_manager.hpp b/platform-mc/platform_manager.hpp index 6e30be8d89..16dba5f0d8 100644 --- a/platform-mc/platform_manager.hpp +++ b/platform-mc/platform_manager.hpp @@ -57,7 +57,9 @@ class PlatformManager exec::task getPDRs(std::shared_ptr terminus); #ifdef OEM_AMD - exec::task get_pdr_from_json(std::shared_ptr terminus, std::string targetUuid); + exec::task get_pdr_from_json( + std::shared_ptr terminus, std::string targetUuid, + std::string networkInterface); #endif /** @brief Fetch PDR from terminus diff --git a/platform-mc/terminus_manager.cpp b/platform-mc/terminus_manager.cpp index 935cdd8f22..8f2b4c49e2 100644 --- a/platform-mc/terminus_manager.cpp +++ b/platform-mc/terminus_manager.cpp @@ -780,8 +780,8 @@ std::optional TerminusManager::getActiveEidByName( return std::nullopt; } -std::optional> TerminusManager::getMctpInfoForTid( - pldm_tid_t tid) +std::optional> +TerminusManager::getMctpInfoForTid(pldm_tid_t tid) { auto it = mctpInfoTable.find(tid); if (it == mctpInfoTable.end()) @@ -790,33 +790,14 @@ std::optional> TerminusManager::getMctpInfoForTid( } const auto& mctpInfo = it->second; - return std::make_pair(std::get<0>(mctpInfo), std::get<1>(mctpInfo)); -} - -std::optional TerminusManager::getBmcMctpEid() -{ - const std::string fileName = "/var/run/bmceid0"; - - try - { - std::ifstream toDevice; - - toDevice.exceptions(std::ios::failbit | std::ios::badbit); - toDevice.open(fileName); - - uint8_t bmcMctpEid = 0; - toDevice.read(reinterpret_cast(&bmcMctpEid), sizeof(bmcMctpEid)); - return bmcMctpEid; - } - - catch (const std::ios_base::failure& iose) - { - std::cerr << "In file I/O error: " << iose.what() << fileName - << std::endl; - } - - return std::nullopt; + return std::make_tuple( + std::get<0>(mctpInfo), // eid + std::get<1>(mctpInfo), // uuid + std::get<5>(mctpInfo), // interface + std::get<6>(mctpInfo) // hostid + ); } + } // namespace platform_mc } // namespace pldm diff --git a/platform-mc/terminus_manager.hpp b/platform-mc/terminus_manager.hpp index 250fe995ce..b0e53eb0d8 100644 --- a/platform-mc/terminus_manager.hpp +++ b/platform-mc/terminus_manager.hpp @@ -146,20 +146,6 @@ class TerminusManager */ bool unmapTid(const pldm_tid_t& tid); - /** @brief getter of local EID - * - * @return uint8_t - local EID - */ - mctp_eid_t getLocalEid() - { - auto hostEid = getBmcMctpEid(); - - if (hostEid.has_value()) - return *hostEid; - - return localEid; - } - /** @brief Helper function to invoke registered handlers for * updating the availability status of the MCTP endpoint * @@ -196,18 +182,20 @@ class TerminusManager * @return std::optional> Returns a pair of EID and * UUID if the TID is found, or std::nullopt if not found. */ - std::optional> getMctpInfoForTid(pldm_tid_t tid); + std::optional> getMctpInfoForTid( + pldm_tid_t tid); /** * @brief Get the BMC Host EID stored in a file * - * This function looks up the a file and if the file exists and + * This function looks up a file and, if the file exists and * can be read, reads the MCTP EID stored in that file. * - * @return std::optional Returns a BMC MCTP EID - * stored in the file and in case of any errors, return NULL value. + * @param[in] hostNumber The identifier of the specific host. + * @return std::optional Returns the BMC MCTP EID stored + * in the file, or std::nullopt in case of any errors. */ - std::optional getBmcMctpEid(); + std::optional getBmcMctpEid(const int hostNumber); private: /** @brief Find the terminus object pointer in termini list. diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp index db764bfe75..393ada58ca 100644 --- a/requester/mctp_endpoint_discovery.cpp +++ b/requester/mctp_endpoint_discovery.cpp @@ -75,18 +75,26 @@ void MctpDiscovery::getMctpInfos(std::map& mctpInfoMap) for (const auto& serviceIter : services) { const std::string& service = serviceIter.first; - const MctpEndpointProps& epProps = + const MctpEndpointProps epProps = getMctpEndpointProps(service, path); const UUID& uuid = getEndpointUUIDProp(service, path); const Availability& availability = getEndpointConnectivityProp(path); auto types = std::get(epProps); + + const auto& networkInterface = std::get<3>(epProps); + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(service, localEidPath); + if (std::find(types.begin(), types.end(), mctpTypePLDM) != types.end()) { auto mctpInfo = - MctpInfo(std::get(epProps), uuid, "", - std::get(epProps), std::nullopt); + MctpInfo(std::get<1>(epProps), uuid, "", + std::get<0>(epProps), std::nullopt, + std::get<3>(epProps), + localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); mctpInfoMap[std::move(mctpInfo)] = availability; } @@ -103,13 +111,16 @@ MctpEndpointProps MctpDiscovery::getMctpEndpointProps( service.c_str(), path.c_str(), MCTPInterface); if (properties.contains("NetworkId") && properties.contains("EID") && + properties.contains("NetworkInterface") && properties.contains("SupportedMessageTypes")) { auto networkId = std::get(properties.at("NetworkId")); auto eid = std::get(properties.at("EID")); auto types = std::get>( properties.at("SupportedMessageTypes")); - return MctpEndpointProps(networkId, eid, types); + auto networkInterface = std::get(properties.at("NetworkInterface")); + + return MctpEndpointProps(networkId, eid, types, networkInterface); } } catch (const sdbusplus::exception_t& e) @@ -117,10 +128,10 @@ MctpEndpointProps MctpDiscovery::getMctpEndpointProps( error( "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}", "SERVICE", service, "PATH", path, "ERROR", e); - return MctpEndpointProps(0, MCTP_ADDR_ANY, {}); + return MctpEndpointProps(0, MCTP_ADDR_ANY, {}, ""); } - return MctpEndpointProps(0, MCTP_ADDR_ANY, {}); + return MctpEndpointProps(0, MCTP_ADDR_ANY, {}, ""); } UUID MctpDiscovery::getEndpointUUIDProp(const std::string& service, @@ -170,6 +181,30 @@ Availability MctpDiscovery::getEndpointConnectivityProp(const std::string& path) return available; } +LocalEid MctpDiscovery::getInterfaceLocalEidProp(const std::string& service, + const std::string& path) +{ + try + { + auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant( + service.c_str(), path.c_str(), LocalEidInterface); + + if (properties.contains("LocalEid")) + { + return std::get(properties.at("LocalEid")); + } + } + catch (const sdbusplus::exception_t& e) + { + error( + "Error reading Interface LocalEid property at path '{PATH}' and service '{SERVICE}', error - {ERROR}", + "SERVICE", service, "PATH", path, "ERROR", e); + return static_cast(0); + } + + return static_cast(0); +} + void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, MctpInfos& mctpInfos) { @@ -212,6 +247,7 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, { if (properties.contains("NetworkId") && properties.contains("EID") && + properties.contains("NetworkInterface") && properties.contains("SupportedMessageTypes")) { auto networkId = @@ -219,6 +255,12 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, auto eid = std::get(properties.at("EID")); auto types = std::get>( properties.at("SupportedMessageTypes")); + auto networkInterface = + std::get(properties.at("NetworkInterface")); + + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(MCTPService, localEidPath); if (!availability) { @@ -232,10 +274,12 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, types.end()) { info( - "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' UUID '{UUID}'", - "NETWORK", networkId, "EID", eid, "UUID", uuid); + "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' " + "UUID '{UUID}' Interface '{NINTF}' LocalEid '{LID}'", + "NETWORK", networkId, "EID", eid, + "UUID", uuid, "NINTF", networkInterface, "LID", localEid); auto mctpInfo = - MctpInfo(eid, uuid, "", networkId, std::nullopt); + MctpInfo(eid, uuid, "", networkId, std::nullopt, networkInterface, localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); mctpInfos.emplace_back(std::move(mctpInfo)); @@ -312,18 +356,25 @@ void MctpDiscovery::propertiesChangedCb(sdbusplus::message_t& msg) { service = pldm::utils::DBusHandler().getService(objPath.c_str(), MCTPInterface); - const MctpEndpointProps& epProps = + const MctpEndpointProps epProps = getMctpEndpointProps(service, objPath); - auto types = std::get(epProps); + auto types = std::get<2>(epProps); if (!std::ranges::contains(types, mctpTypePLDM)) { return; } const UUID& uuid = getEndpointUUIDProp(service, objPath); - MctpInfo mctpInfo(std::get(epProps), uuid, "", - std::get(epProps), std::nullopt); + const auto& networkInterface = std::get<3>(epProps); + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(service, localEidPath); + + MctpInfo mctpInfo(std::get<1>(epProps), uuid, "", + std::get<0>(epProps), std::nullopt, + std::get<3>(epProps), + localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); if (!std::ranges::contains(existingMctpInfos, mctpInfo)) { @@ -420,8 +471,8 @@ std::string MctpDiscovery::getNameFromProperties( std::string MctpDiscovery::constructMctpReactorObjectPath( const MctpInfo& mctpInfo) { - const auto networkId = std::get(mctpInfo); - const auto eid = std::get(mctpInfo); + const auto networkId = std::get<3>(mctpInfo); + const auto eid = std::get<0>(mctpInfo); return std::string{MCTPPath} + "/networks/" + std::to_string(networkId) + "/endpoints/" + std::to_string(eid) + "/configured_by"; } @@ -498,10 +549,10 @@ void MctpDiscovery::removeConfigs(const MctpInfos& removedInfos) { for (const auto& mctpInfo : removedInfos) { - auto eidToRemove = std::get(mctpInfo); + auto eidToRemove = std::get<0>(mctpInfo); std::erase_if(configurations, [eidToRemove](const auto& config) { auto& [__, mctpInfo] = config; - auto eidValue = std::get(mctpInfo); + auto eidValue = std::get<0>(mctpInfo); return eidValue == eidToRemove; }); } diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp index 76928492f6..3123a63942 100644 --- a/requester/mctp_endpoint_discovery.hpp +++ b/requester/mctp_endpoint_discovery.hpp @@ -20,6 +20,8 @@ const std::string emptyUUID = "00000000-0000-0000-0000-000000000000"; constexpr const char* MCTPService = "au.com.codeconstruct.MCTP1"; constexpr const char* MCTPInterface = "xyz.openbmc_project.MCTP.Endpoint"; constexpr const char* EndpointUUID = "xyz.openbmc_project.Common.UUID"; +constexpr const char* LocalEidInterface = "au.com.codeconstruct.MCTP.Interface1"; +constexpr const char* LocalEidInterfacePath = "/au/com/codeconstruct/mctp1/interfaces/"; constexpr const char* MCTPPath = "/au/com/codeconstruct/mctp1"; constexpr const char* MCTPInterfaceCC = "au.com.codeconstruct.MCTP.Endpoint1"; constexpr const char* MCTPConnectivityProp = "Connectivity"; @@ -191,6 +193,11 @@ class MctpDiscovery UUID getEndpointUUIDProp(const std::string& service, const std::string& path); + + LocalEid getInterfaceLocalEidProp(const std::string& service, + const std::string& path); + + /** @brief Get Endpoint Availability status from `Connectivity` D-Bus * property in the `au.com.codeconstruct.MCTP.Endpoint1` D-Bus * interface.