1*b341fa2bSHarshit Aghera /*
2*b341fa2bSHarshit Aghera * SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*b341fa2bSHarshit Aghera * SPDX-License-Identifier: Apache-2.0
4*b341fa2bSHarshit Aghera */
5*b341fa2bSHarshit Aghera
6*b341fa2bSHarshit Aghera #include "NvidiaDriverInformation.hpp"
7*b341fa2bSHarshit Aghera
8*b341fa2bSHarshit Aghera #include "Utils.hpp"
9*b341fa2bSHarshit Aghera
10*b341fa2bSHarshit Aghera #include <MctpRequester.hpp>
11*b341fa2bSHarshit Aghera #include <NvidiaGpuMctpVdm.hpp>
12*b341fa2bSHarshit Aghera #include <OcpMctpVdm.hpp>
13*b341fa2bSHarshit Aghera #include <phosphor-logging/lg2.hpp>
14*b341fa2bSHarshit Aghera #include <sdbusplus/asio/connection.hpp>
15*b341fa2bSHarshit Aghera #include <sdbusplus/asio/object_server.hpp>
16*b341fa2bSHarshit Aghera #include <sdbusplus/message/native_types.hpp>
17*b341fa2bSHarshit Aghera
18*b341fa2bSHarshit Aghera #include <cstdint>
19*b341fa2bSHarshit Aghera #include <memory>
20*b341fa2bSHarshit Aghera #include <span>
21*b341fa2bSHarshit Aghera #include <string>
22*b341fa2bSHarshit Aghera #include <system_error>
23*b341fa2bSHarshit Aghera #include <vector>
24*b341fa2bSHarshit Aghera
25*b341fa2bSHarshit Aghera const std::string softwareInventoryPath = "/xyz/openbmc_project/software/";
26*b341fa2bSHarshit Aghera
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)27*b341fa2bSHarshit Aghera NvidiaDriverInformation::NvidiaDriverInformation(
28*b341fa2bSHarshit Aghera std::shared_ptr<sdbusplus::asio::connection>& conn,
29*b341fa2bSHarshit Aghera mctp::MctpRequester& mctpRequester, const std::string& name,
30*b341fa2bSHarshit Aghera const sdbusplus::message::object_path& path, const uint8_t eid,
31*b341fa2bSHarshit Aghera sdbusplus::asio::object_server& objectServer) :
32*b341fa2bSHarshit Aghera eid(eid), conn(conn), mctpRequester(mctpRequester)
33*b341fa2bSHarshit Aghera {
34*b341fa2bSHarshit Aghera const std::string dbusPath = softwareInventoryPath + escapeName(name);
35*b341fa2bSHarshit Aghera
36*b341fa2bSHarshit Aghera versionInterface = objectServer.add_interface(
37*b341fa2bSHarshit Aghera dbusPath, "xyz.openbmc_project.Software.Version");
38*b341fa2bSHarshit Aghera
39*b341fa2bSHarshit Aghera versionInterface->register_property<std::string>("Version", "");
40*b341fa2bSHarshit Aghera
41*b341fa2bSHarshit Aghera versionInterface->register_property<std::string>(
42*b341fa2bSHarshit Aghera "Purpose", "xyz.openbmc_project.Software.Version.VersionPurpose.Other");
43*b341fa2bSHarshit Aghera
44*b341fa2bSHarshit Aghera if (!versionInterface->initialize())
45*b341fa2bSHarshit Aghera {
46*b341fa2bSHarshit Aghera lg2::error(
47*b341fa2bSHarshit Aghera "Failed to initialize Version interface for Driver Information for eid {EID}",
48*b341fa2bSHarshit Aghera "EID", eid);
49*b341fa2bSHarshit Aghera }
50*b341fa2bSHarshit Aghera
51*b341fa2bSHarshit Aghera std::vector<Association> associations;
52*b341fa2bSHarshit Aghera associations.emplace_back("running", "ran_on", path.parent_path());
53*b341fa2bSHarshit Aghera
54*b341fa2bSHarshit Aghera associationInterface =
55*b341fa2bSHarshit Aghera objectServer.add_interface(dbusPath, association::interface);
56*b341fa2bSHarshit Aghera
57*b341fa2bSHarshit Aghera associationInterface->register_property("Associations", associations);
58*b341fa2bSHarshit Aghera
59*b341fa2bSHarshit Aghera if (!associationInterface->initialize())
60*b341fa2bSHarshit Aghera {
61*b341fa2bSHarshit Aghera lg2::error(
62*b341fa2bSHarshit Aghera "Failed to initialize Association interface for Driver Information for eid {EID}",
63*b341fa2bSHarshit Aghera "EID", eid);
64*b341fa2bSHarshit Aghera }
65*b341fa2bSHarshit Aghera }
66*b341fa2bSHarshit Aghera
processResponse(const std::error_code & ec,std::span<const uint8_t> buffer)67*b341fa2bSHarshit Aghera void NvidiaDriverInformation::processResponse(const std::error_code& ec,
68*b341fa2bSHarshit Aghera std::span<const uint8_t> buffer)
69*b341fa2bSHarshit Aghera {
70*b341fa2bSHarshit Aghera if (ec)
71*b341fa2bSHarshit Aghera {
72*b341fa2bSHarshit Aghera lg2::error(
73*b341fa2bSHarshit Aghera "Error updating Driver Information for eid {EID} : sending message over MCTP failed, rc={RC}",
74*b341fa2bSHarshit Aghera "EID", eid, "RC", ec.message());
75*b341fa2bSHarshit Aghera return;
76*b341fa2bSHarshit Aghera }
77*b341fa2bSHarshit Aghera
78*b341fa2bSHarshit Aghera ocp::accelerator_management::CompletionCode cc{};
79*b341fa2bSHarshit Aghera uint16_t reasonCode = 0;
80*b341fa2bSHarshit Aghera gpu::DriverState driverState{};
81*b341fa2bSHarshit Aghera std::string driverVersion;
82*b341fa2bSHarshit Aghera
83*b341fa2bSHarshit Aghera const int rc = gpu::decodeGetDriverInformationResponse(
84*b341fa2bSHarshit Aghera buffer, cc, reasonCode, driverState, driverVersion);
85*b341fa2bSHarshit Aghera
86*b341fa2bSHarshit Aghera if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
87*b341fa2bSHarshit Aghera {
88*b341fa2bSHarshit Aghera lg2::error(
89*b341fa2bSHarshit Aghera "Error updating Driver Information for eid {EID} : decode failed, rc={RC}, cc={CC}, reasonCode={REASON}",
90*b341fa2bSHarshit Aghera "EID", eid, "RC", rc, "CC", static_cast<uint8_t>(cc), "REASON",
91*b341fa2bSHarshit Aghera reasonCode);
92*b341fa2bSHarshit Aghera return;
93*b341fa2bSHarshit Aghera }
94*b341fa2bSHarshit Aghera
95*b341fa2bSHarshit Aghera versionInterface->set_property("Version", driverVersion);
96*b341fa2bSHarshit Aghera }
97*b341fa2bSHarshit Aghera
update()98*b341fa2bSHarshit Aghera void NvidiaDriverInformation::update()
99*b341fa2bSHarshit Aghera {
100*b341fa2bSHarshit Aghera const int rc = gpu::encodeGetDriverInformationRequest(0, request);
101*b341fa2bSHarshit Aghera
102*b341fa2bSHarshit Aghera if (rc != 0)
103*b341fa2bSHarshit Aghera {
104*b341fa2bSHarshit Aghera lg2::error(
105*b341fa2bSHarshit Aghera "Error updating Driver Information for eid {EID} : encode failed, rc={RC}",
106*b341fa2bSHarshit Aghera "EID", eid, "RC", rc);
107*b341fa2bSHarshit Aghera return;
108*b341fa2bSHarshit Aghera }
109*b341fa2bSHarshit Aghera
110*b341fa2bSHarshit Aghera mctpRequester.sendRecvMsg(
111*b341fa2bSHarshit Aghera eid, request,
112*b341fa2bSHarshit Aghera [weak{weak_from_this()}](const std::error_code& ec,
113*b341fa2bSHarshit Aghera std::span<const uint8_t> buffer) {
114*b341fa2bSHarshit Aghera std::shared_ptr<NvidiaDriverInformation> self = weak.lock();
115*b341fa2bSHarshit Aghera if (!self)
116*b341fa2bSHarshit Aghera {
117*b341fa2bSHarshit Aghera lg2::error("invalid reference to NvidiaDriverInformation");
118*b341fa2bSHarshit Aghera return;
119*b341fa2bSHarshit Aghera }
120*b341fa2bSHarshit Aghera self->processResponse(ec, buffer);
121*b341fa2bSHarshit Aghera });
122*b341fa2bSHarshit Aghera }
123