blob: 1afc6caa830dae7fcfe64e1b0280a48c62b746bb [file] [log] [blame]
Harshit Agheraa3f24f42025-04-21 20:04:56 +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 "GpuMctpVdm.hpp"
7
8#include "OcpMctpVdm.hpp"
9
10#include <endian.h>
11
12#include <cstdint>
13#include <cstring>
14
15namespace gpu
16{
17
18ocp::accelerator_management::CompletionCode packHeader(
19 const ocp::accelerator_management::BindingPciVidInfo& hdr,
20 ocp::accelerator_management::BindingPciVid& msg)
21{
22 return ocp::accelerator_management::packHeader(nvidiaPciVendorId, hdr, msg);
23}
24
25ocp::accelerator_management::CompletionCode encodeReasonCode(
26 uint8_t cc, uint16_t reasonCode, uint8_t commandCode,
27 ocp::accelerator_management::Message& msg)
28{
29 return ocp::accelerator_management::encodeReasonCode(cc, reasonCode,
30 commandCode, msg);
31}
32
33ocp::accelerator_management::CompletionCode decodeReasonCodeAndCC(
34 const ocp::accelerator_management::Message& msg, size_t msgLen, uint8_t& cc,
35 uint16_t& reasonCode)
36{
37 if (be16toh(msg.hdr.pci_vendor_id) != nvidiaPciVendorId)
38 {
39 return ocp::accelerator_management::CompletionCode::ERR_INVALID_DATA;
40 }
41
42 return ocp::accelerator_management::decodeReasonCodeAndCC(
43 msg, msgLen, cc, reasonCode);
44}
45
46ocp::accelerator_management::CompletionCode
47 encodeQueryDeviceIdentificationRequest(
48 uint8_t instanceId, ocp::accelerator_management::Message& msg)
49{
50 ocp::accelerator_management::BindingPciVidInfo header{};
51 header.ocp_accelerator_management_msg_type =
52 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
53 header.instance_id = instanceId &
54 ocp::accelerator_management::instanceIdMask;
55 header.msg_type =
56 static_cast<uint8_t>(MessageType::DEVICE_CAPABILITY_DISCOVERY);
57
58 auto rc = packHeader(header, msg.hdr);
59 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
60 {
61 return rc;
62 }
63
64 QueryDeviceIdentificationRequest request{};
65 request.hdr.command = static_cast<uint8_t>(
66 DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
67 request.hdr.data_size = 0;
68
69 std::memcpy(&msg.data, &request, sizeof(request));
70
71 return ocp::accelerator_management::CompletionCode::SUCCESS;
72}
73
74ocp::accelerator_management::CompletionCode
75 encodeQueryDeviceIdentificationResponse(
76 uint8_t instanceId, uint8_t cc, uint16_t reasonCode,
77 uint8_t deviceIdentification, uint8_t deviceInstance,
78 ocp::accelerator_management::Message& msg)
79{
80 ocp::accelerator_management::BindingPciVidInfo header{};
81 header.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
82 ocp::accelerator_management::MessageType::RESPONSE);
83 header.instance_id = instanceId &
84 ocp::accelerator_management::instanceIdMask;
85 header.msg_type =
86 static_cast<uint8_t>(MessageType::DEVICE_CAPABILITY_DISCOVERY);
87
88 auto rc = packHeader(header, msg.hdr);
89 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
90 {
91 return rc;
92 }
93
94 if (cc != static_cast<uint8_t>(
95 ocp::accelerator_management::CompletionCode::SUCCESS))
96 {
97 return gpu::encodeReasonCode(
98 cc, reasonCode,
99 static_cast<uint8_t>(
100 DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION),
101 msg);
102 }
103
104 QueryDeviceIdentificationResponse response{};
105 response.hdr.command = static_cast<uint8_t>(
106 DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
107 response.hdr.completion_code = cc;
108 response.hdr.data_size = htole16(2);
109 response.device_identification = deviceIdentification;
110 response.instance_id = deviceInstance;
111
112 std::memcpy(&msg.data, &response, sizeof(response));
113
114 return ocp::accelerator_management::CompletionCode::SUCCESS;
115}
116
117ocp::accelerator_management::CompletionCode
118 decodeQueryDeviceIdentificationResponse(
119 const ocp::accelerator_management::Message& msg, size_t msgLen,
120 uint8_t& cc, uint16_t& reasonCode, uint8_t& deviceIdentification,
121 uint8_t& deviceInstance)
122{
123 auto rc = gpu::decodeReasonCodeAndCC(msg, msgLen, cc, reasonCode);
124 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS ||
125 cc != static_cast<uint8_t>(
126 ocp::accelerator_management::CompletionCode::SUCCESS))
127 {
128 return rc;
129 }
130
131 if (msgLen < sizeof(ocp::accelerator_management::BindingPciVid) +
132 sizeof(QueryDeviceIdentificationResponse))
133 {
134 return ocp::accelerator_management::CompletionCode::
135 ERR_INVALID_DATA_LENGTH;
136 }
137
138 QueryDeviceIdentificationResponse response{};
139 std::memcpy(&response, &msg.data, sizeof(response));
140
141 deviceIdentification = response.device_identification;
142 deviceInstance = response.instance_id;
143
144 return ocp::accelerator_management::CompletionCode::SUCCESS;
145}
146
147ocp::accelerator_management::CompletionCode encodeGetTemperatureReadingRequest(
148 uint8_t instanceId, uint8_t sensorId,
149 ocp::accelerator_management::Message& msg)
150{
151 ocp::accelerator_management::BindingPciVidInfo header{};
152 header.ocp_accelerator_management_msg_type =
153 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
154 header.instance_id = instanceId &
155 ocp::accelerator_management::instanceIdMask;
156 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
157
158 auto rc = packHeader(header, msg.hdr);
159 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
160 {
161 return rc;
162 }
163
164 GetTemperatureReadingRequest request{};
165 request.hdr.command = static_cast<uint8_t>(
166 PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
167 request.hdr.data_size = sizeof(sensorId);
168 request.sensor_id = sensorId;
169
170 std::memcpy(&msg.data, &request, sizeof(request));
171
172 return ocp::accelerator_management::CompletionCode::SUCCESS;
173}
174
175ocp::accelerator_management::CompletionCode decodeGetTemperatureReadingRequest(
176 const ocp::accelerator_management::Message& msg, size_t msgLen,
177 uint8_t& sensorId)
178{
179 if (msgLen < sizeof(ocp::accelerator_management::BindingPciVid) +
180 sizeof(GetTemperatureReadingRequest))
181 {
182 return ocp::accelerator_management::CompletionCode::
183 ERR_INVALID_DATA_LENGTH;
184 }
185
186 GetTemperatureReadingRequest request{};
187 std::memcpy(&request, &msg.data, sizeof(request));
188
189 if (request.hdr.data_size < sizeof(request.sensor_id))
190 {
191 return ocp::accelerator_management::CompletionCode::ERR_INVALID_DATA;
192 }
193
194 sensorId = request.sensor_id;
195
196 return ocp::accelerator_management::CompletionCode::SUCCESS;
197}
198
199ocp::accelerator_management::CompletionCode encodeGetTemperatureReadingResponse(
200 uint8_t instanceId, uint8_t cc, uint16_t reasonCode,
201 double temperatureReading, ocp::accelerator_management::Message& msg)
202{
203 ocp::accelerator_management::BindingPciVidInfo header{};
204 header.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
205 ocp::accelerator_management::MessageType::RESPONSE);
206 header.instance_id = instanceId &
207 ocp::accelerator_management::instanceIdMask;
208 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
209
210 auto rc = packHeader(header, msg.hdr);
211 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
212 {
213 return rc;
214 }
215
216 if (cc != static_cast<uint8_t>(
217 ocp::accelerator_management::CompletionCode::SUCCESS))
218 {
219 return gpu::encodeReasonCode(
220 cc, reasonCode,
221 static_cast<uint8_t>(
222 PlatformEnvironmentalCommands::GET_TEMPERATURE_READING),
223 msg);
224 }
225
226 GetTemperatureReadingResponse response{};
227 response.hdr.command = static_cast<uint8_t>(
228 PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
229 response.hdr.completion_code = cc;
230 response.hdr.data_size = htole16(sizeof(uint32_t));
231
232 int32_t reading = static_cast<int32_t>(temperatureReading * (1 << 8));
233 response.reading = htole32(reading);
234
235 std::memcpy(&msg.data, &response, sizeof(response));
236
237 return ocp::accelerator_management::CompletionCode::SUCCESS;
238}
239
240ocp::accelerator_management::CompletionCode decodeGetTemperatureReadingResponse(
241 const ocp::accelerator_management::Message& msg, size_t msgLen, uint8_t& cc,
242 uint16_t& reasonCode, double& temperatureReading)
243{
244 auto rc = gpu::decodeReasonCodeAndCC(msg, msgLen, cc, reasonCode);
245 if (rc != ocp::accelerator_management::CompletionCode::SUCCESS ||
246 cc != static_cast<uint8_t>(
247 ocp::accelerator_management::CompletionCode::SUCCESS))
248 {
249 return rc;
250 }
251
252 if (msgLen < sizeof(ocp::accelerator_management::BindingPciVid) +
253 sizeof(GetTemperatureReadingResponse))
254 {
255 return ocp::accelerator_management::CompletionCode::
256 ERR_INVALID_DATA_LENGTH;
257 }
258
259 GetTemperatureReadingResponse response{};
260 std::memcpy(&response, &msg.data, sizeof(response));
261
262 uint16_t dataSize = le16toh(response.hdr.data_size);
263 if (dataSize != sizeof(int32_t))
264 {
265 return ocp::accelerator_management::CompletionCode::ERR_INVALID_DATA;
266 }
267
268 int32_t reading = le32toh(response.reading);
269 temperatureReading = reading / static_cast<double>(1 << 8);
270
271 return ocp::accelerator_management::CompletionCode::SUCCESS;
272}
273} // namespace gpu