blob: 5a02326b71ff9993877dce079aded271fbdb15d2 [file] [log] [blame]
Harshit Aghera32e3b2b2025-05-05 12:26:35 +05301/*
2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
4 */
5
6#include "GpuTLimitSensor.hpp"
7
8#include "SensorPaths.hpp"
9#include "Thresholds.hpp"
10#include "UpdatableSensor.hpp"
11#include "Utils.hpp"
12
13#include <bits/basic_string.h>
14
15#include <GpuDevice.hpp>
16#include <GpuMctpVdm.hpp>
17#include <MctpRequester.hpp>
18#include <OcpMctpVdm.hpp>
19#include <phosphor-logging/lg2.hpp>
20#include <sdbusplus/asio/connection.hpp>
21#include <sdbusplus/asio/object_server.hpp>
22
23#include <cstddef>
24#include <cstdint>
25#include <functional>
26#include <memory>
27#include <string>
28#include <utility>
29#include <vector>
30
31using namespace std::literals;
32
33constexpr uint8_t gpuTLimitSensorIdm{2};
34static constexpr double gpuTLimitSensorMaxReading = 127;
35static constexpr double gpuTLimitSensorMinReading = -128;
36
37GpuTLimitSensor::GpuTLimitSensor(
38 std::shared_ptr<sdbusplus::asio::connection>& conn,
39 mctp::MctpRequester& mctpRequester, const std::string& name,
40 const std::string& sensorConfiguration, uint8_t eid,
41 sdbusplus::asio::object_server& objectServer,
42 std::vector<thresholds::Threshold>&& thresholdData) :
43 GpuSensor(escapeName(name), std::move(thresholdData), sensorConfiguration,
44 "temperature", false, true, gpuTLimitSensorMaxReading,
45 gpuTLimitSensorMinReading, conn),
46 eid(eid), sensorId{gpuTLimitSensorIdm}, mctpRequester(mctpRequester),
47 objectServer(objectServer)
48{
49 std::string dbusPath =
50 sensorPathPrefix + "temperature/"s + escapeName(name);
51
52 sensorInterface = objectServer.add_interface(
53 dbusPath, "xyz.openbmc_project.Sensor.Value");
54
55 for (const auto& threshold : thresholds)
56 {
57 std::string interface = thresholds::getInterface(threshold.level);
58 thresholdInterfaces[static_cast<size_t>(threshold.level)] =
59 objectServer.add_interface(dbusPath, interface);
60 }
61
62 association = objectServer.add_interface(dbusPath, association::interface);
63
64 setInitialProperties(sensor_paths::unitDegreesC);
65}
66
67GpuTLimitSensor::~GpuTLimitSensor()
68{
69 for (const auto& iface : thresholdInterfaces)
70 {
71 objectServer.remove_interface(iface);
72 }
73 objectServer.remove_interface(sensorInterface);
74 objectServer.remove_interface(association);
75}
76
77void GpuTLimitSensor::checkThresholds()
78{
79 thresholds::checkThresholds(this);
80}
81
82void GpuTLimitSensor::update()
83{
84 std::vector<uint8_t> reqMsg(
85 sizeof(ocp::accelerator_management::BindingPciVid) +
86 sizeof(gpu::GetTemperatureReadingRequest));
87
88 auto* msg = new (reqMsg.data()) ocp::accelerator_management::Message;
89
90 auto rc = gpu::encodeGetTemperatureReadingRequest(0, sensorId, *msg);
91 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
92 {
93 lg2::error(
94 "GpuTLimitSensor::update(): gpuEncodeGetTemperatureReadingRequest failed, rc={RC}",
95 "RC", static_cast<int>(rc));
96 return;
97 }
98
99 mctpRequester.sendRecvMsg(
100 eid, reqMsg,
101 [this](int sendRecvMsgResult, std::vector<uint8_t> respMsg) {
102 if (sendRecvMsgResult != 0)
103 {
104 lg2::error(
105 "GpuTLimitSensor::update(): MctpRequester::sendRecvMsg() failed, rc={RC}",
106 "RC", sendRecvMsgResult);
107 return;
108 }
109
110 if (respMsg.empty())
111 {
112 lg2::error(
113 "GpuTLimitSensor::update(): MctpRequester::sendRecvMsg() failed, respMsgLen=0");
114 return;
115 }
116
117 uint8_t cc = 0;
118 uint16_t reasonCode = 0;
119 double tempValue = 0;
120
121 auto rc = gpu::decodeGetTemperatureReadingResponse(
122 *new (respMsg.data()) ocp::accelerator_management::Message,
123 respMsg.size(), cc, reasonCode, tempValue);
124
125 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS ||
126 cc != static_cast<uint8_t>(
127 ocp::accelerator_management::CompletionCode::SUCCESS))
128 {
129 lg2::error(
130 "GpuTLimitSensor::update(): gpuDecodeGetTemperatureReadingResponse() failed, rc={RC} cc={CC} reasonCode={RESC}",
131 "RC", static_cast<int>(rc), "CC", cc, "RESC", reasonCode);
132 return;
133 }
134
135 updateValue(tempValue);
136 });
137}