blob: ed88718bc41032cfbefb5078a563705555578c32 [file] [log] [blame] [edit]
/*
* SPDX-FileCopyrightText: Copyright OpenBMC Authors
* SPDX-License-Identifier: Apache-2.0
*/
#include "NvidiaDriverInformation.hpp"
#include "Utils.hpp"
#include <MctpRequester.hpp>
#include <NvidiaGpuMctpVdm.hpp>
#include <OcpMctpVdm.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <cstdint>
#include <memory>
#include <span>
#include <string>
#include <system_error>
#include <vector>
const std::string softwareInventoryPath = "/xyz/openbmc_project/software/";
NvidiaDriverInformation::NvidiaDriverInformation(
std::shared_ptr<sdbusplus::asio::connection>& conn,
mctp::MctpRequester& mctpRequester, const std::string& name,
const sdbusplus::message::object_path& path, const uint8_t eid,
sdbusplus::asio::object_server& objectServer) :
eid(eid), conn(conn), mctpRequester(mctpRequester)
{
const std::string dbusPath = softwareInventoryPath + escapeName(name);
versionInterface = objectServer.add_interface(
dbusPath, "xyz.openbmc_project.Software.Version");
versionInterface->register_property<std::string>("Version", "");
versionInterface->register_property<std::string>(
"Purpose", "xyz.openbmc_project.Software.Version.VersionPurpose.Other");
if (!versionInterface->initialize())
{
lg2::error(
"Failed to initialize Version interface for Driver Information for eid {EID}",
"EID", eid);
}
std::vector<Association> associations;
associations.emplace_back("running", "ran_on", path.parent_path());
associationInterface =
objectServer.add_interface(dbusPath, association::interface);
associationInterface->register_property("Associations", associations);
if (!associationInterface->initialize())
{
lg2::error(
"Failed to initialize Association interface for Driver Information for eid {EID}",
"EID", eid);
}
}
void NvidiaDriverInformation::processResponse(const std::error_code& ec,
std::span<const uint8_t> buffer)
{
if (ec)
{
lg2::error(
"Error updating Driver Information for eid {EID} : sending message over MCTP failed, rc={RC}",
"EID", eid, "RC", ec.message());
return;
}
ocp::accelerator_management::CompletionCode cc{};
uint16_t reasonCode = 0;
gpu::DriverState driverState{};
std::string driverVersion;
const int rc = gpu::decodeGetDriverInformationResponse(
buffer, cc, reasonCode, driverState, driverVersion);
if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
{
lg2::error(
"Error updating Driver Information for eid {EID} : decode failed, rc={RC}, cc={CC}, reasonCode={REASON}",
"EID", eid, "RC", rc, "CC", static_cast<uint8_t>(cc), "REASON",
reasonCode);
return;
}
versionInterface->set_property("Version", driverVersion);
}
void NvidiaDriverInformation::update()
{
const int rc = gpu::encodeGetDriverInformationRequest(0, request);
if (rc != 0)
{
lg2::error(
"Error updating Driver Information for eid {EID} : encode failed, rc={RC}",
"EID", eid, "RC", rc);
return;
}
mctpRequester.sendRecvMsg(
eid, request,
[weak{weak_from_this()}](const std::error_code& ec,
std::span<const uint8_t> buffer) {
std::shared_ptr<NvidiaDriverInformation> self = weak.lock();
if (!self)
{
lg2::error("invalid reference to NvidiaDriverInformation");
return;
}
self->processResponse(ec, buffer);
});
}