blob: 2355bf9e16dc31040163604ce780fb20a81864d7 [file] [log] [blame]
Harshit Aghera560e6af2025-04-21 20:04:56 +05301/*
2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3 * AFFILIATES. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include "NvidiaGpuMctpVdm.hpp"
8
9#include "OcpMctpVdm.hpp"
10
11#include <endian.h>
12
13#include <cerrno>
14#include <cstdint>
15#include <cstring>
16#include <span>
17
18namespace gpu
19{
20// These functions encode/decode data communicated over the network
21// The use of reinterpret_cast enables direct memory access to raw byte buffers
22// without doing unnecessary data copying
23// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
24int packHeader(const ocp::accelerator_management::BindingPciVidInfo& hdr,
25 ocp::accelerator_management::BindingPciVid& msg)
26{
27 return ocp::accelerator_management::packHeader(nvidiaPciVendorId, hdr, msg);
28}
29
30int encodeQueryDeviceIdentificationRequest(uint8_t instanceId,
31 const std::span<uint8_t> buf)
32{
33 if (buf.size() < sizeof(QueryDeviceIdentificationRequest))
34 {
35 return EINVAL;
36 }
37
38 auto* msg = reinterpret_cast<QueryDeviceIdentificationRequest*>(buf.data());
39
40 ocp::accelerator_management::BindingPciVidInfo header{};
41
42 header.ocp_accelerator_management_msg_type =
43 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
44 header.instance_id = instanceId &
45 ocp::accelerator_management::instanceIdBitMask;
46 header.msg_type =
47 static_cast<uint8_t>(MessageType::DEVICE_CAPABILITY_DISCOVERY);
48
49 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
50
51 if (rc != 0)
52 {
53 return rc;
54 }
55
56 msg->hdr.command = static_cast<uint8_t>(
57 DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
58 msg->hdr.data_size = 0;
59
60 return 0;
61}
62
63int decodeQueryDeviceIdentificationResponse(
64 const std::span<const uint8_t> buf,
65 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
66 uint8_t& deviceIdentification, uint8_t& deviceInstance)
67{
68 auto rc =
69 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
70
71 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
72 {
73 return rc;
74 }
75
76 if (buf.size() < sizeof(QueryDeviceIdentificationResponse))
77 {
78 return EINVAL;
79 }
80
81 const auto* response =
82 reinterpret_cast<const QueryDeviceIdentificationResponse*>(buf.data());
83
84 deviceIdentification = response->device_identification;
85 deviceInstance = response->instance_id;
86
87 return 0;
88}
89
90int encodeGetTemperatureReadingRequest(uint8_t instanceId, uint8_t sensorId,
91 std::span<uint8_t> buf)
92{
93 if (buf.size() < sizeof(GetTemperatureReadingRequest))
94 {
95 return EINVAL;
96 }
97
98 auto* msg = reinterpret_cast<GetTemperatureReadingRequest*>(buf.data());
99
100 ocp::accelerator_management::BindingPciVidInfo header{};
101 header.ocp_accelerator_management_msg_type =
102 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
103 header.instance_id = instanceId &
104 ocp::accelerator_management::instanceIdBitMask;
105 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
106
107 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
108
109 if (rc != 0)
110 {
111 return rc;
112 }
113
114 msg->hdr.command = static_cast<uint8_t>(
115 PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
116 msg->hdr.data_size = sizeof(sensorId);
117 msg->sensor_id = sensorId;
118
119 return 0;
120}
121
122int decodeGetTemperatureReadingResponse(
123 const std::span<const uint8_t> buf,
124 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
125 double& temperatureReading)
126{
127 auto rc =
128 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
129
130 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
131 {
132 return rc;
133 }
134
135 if (buf.size() < sizeof(GetTemperatureReadingResponse))
136 {
137 return EINVAL;
138 }
139
140 const auto* response =
141 reinterpret_cast<const GetTemperatureReadingResponse*>(buf.data());
142
143 uint16_t dataSize = le16toh(response->hdr.data_size);
144
145 if (dataSize != sizeof(int32_t))
146 {
147 return EINVAL;
148 }
149
150 int32_t reading = le32toh(response->reading);
151 temperatureReading = reading / static_cast<double>(1 << 8);
152
153 return 0;
154}
Harshit Aghera5e7decc2025-05-07 16:20:16 +0530155
156int encodeReadThermalParametersRequest(uint8_t instanceId, uint8_t sensorId,
157 std::span<uint8_t> buf)
158{
159 if (buf.size() < sizeof(ReadThermalParametersRequest))
160 {
161 return EINVAL;
162 }
163
164 auto* msg = reinterpret_cast<ReadThermalParametersRequest*>(buf.data());
165
166 ocp::accelerator_management::BindingPciVidInfo header{};
167 header.ocp_accelerator_management_msg_type =
168 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
169 header.instance_id = instanceId &
170 ocp::accelerator_management::instanceIdBitMask;
171 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
172
173 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
174
175 if (rc != 0)
176 {
177 return rc;
178 }
179
180 msg->hdr.command = static_cast<uint8_t>(
181 PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
182 msg->hdr.data_size = sizeof(sensorId);
183 msg->sensor_id = sensorId;
184
185 return 0;
186}
187
188int decodeReadThermalParametersResponse(
189 std::span<const uint8_t> buf,
190 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
191 int32_t& threshold)
192{
193 auto rc =
194 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
195
196 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
197 {
198 return rc;
199 }
200
201 if (buf.size() < sizeof(ReadThermalParametersResponse))
202 {
203 return EINVAL;
204 }
205
206 const auto* response =
207 reinterpret_cast<const ReadThermalParametersResponse*>(buf.data());
208
209 uint16_t dataSize = le16toh(response->hdr.data_size);
210
211 if (dataSize != sizeof(int32_t))
212 {
213 return EINVAL;
214 }
215
216 threshold = le32toh(response->threshold);
217
218 return 0;
219}
Harshit Aghera902c6492025-05-08 15:57:42 +0530220
221int encodeGetCurrentPowerDrawRequest(uint8_t instanceId, uint8_t sensorId,
222 uint8_t averagingInterval,
223 std::span<uint8_t> buf)
224{
225 if (buf.size() < sizeof(GetCurrentPowerDrawRequest))
226 {
227 return EINVAL;
228 }
229
230 auto* msg = reinterpret_cast<GetCurrentPowerDrawRequest*>(buf.data());
231
232 ocp::accelerator_management::BindingPciVidInfo header{};
233 header.ocp_accelerator_management_msg_type =
234 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
235 header.instance_id = instanceId &
236 ocp::accelerator_management::instanceIdBitMask;
237 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
238
239 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
240
241 if (rc != 0)
242 {
243 return rc;
244 }
245
246 msg->hdr.command = static_cast<uint8_t>(
247 PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
248 msg->hdr.data_size = sizeof(sensorId) + sizeof(averagingInterval);
249 msg->sensorId = sensorId;
250 msg->averagingInterval = averagingInterval;
251
252 return 0;
253}
254
255int decodeGetCurrentPowerDrawResponse(
256 std::span<const uint8_t> buf,
257 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
258 uint32_t& power)
259{
260 auto rc =
261 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
262
263 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
264 {
265 return rc;
266 }
267
268 if (buf.size() < sizeof(GetCurrentPowerDrawResponse))
269 {
270 return EINVAL;
271 }
272
273 const auto* response =
274 reinterpret_cast<const GetCurrentPowerDrawResponse*>(buf.data());
275
276 const uint16_t dataSize = le16toh(response->hdr.data_size);
277
278 if (dataSize != sizeof(uint32_t))
279 {
280 return EINVAL;
281 }
282
283 power = le32toh(response->power);
284
285 return 0;
286}
Harshit Aghera560e6af2025-04-21 20:04:56 +0530287// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
288} // namespace gpu