1 /*
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 #include "OcpMctpVdm.hpp"
9
10 #include <endian.h>
11
12 #include <array>
13 #include <cerrno>
14 #include <cstdint>
15 #include <cstring>
16 #include <vector>
17
18 #include <gtest/gtest.h>
19
20 namespace ocp_mctp_tests
21 {
22
23 class OcpMctpVdmTests : public ::testing::Test
24 {
25 protected:
SetUp()26 void SetUp() override
27 {
28 // Initialize common test data here
29 }
30 };
31
32 // Tests for OcpMctpVdm::packHeader function
TEST_F(OcpMctpVdmTests,PackHeaderRequestSuccess)33 TEST_F(OcpMctpVdmTests, PackHeaderRequestSuccess)
34 {
35 const uint16_t pciVendorId = 0x1234;
36 ocp::accelerator_management::BindingPciVidInfo hdr{};
37 ocp::accelerator_management::BindingPciVid msg{};
38
39 hdr.ocp_accelerator_management_msg_type =
40 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
41 hdr.instance_id = 5;
42 hdr.msg_type = 0x7E;
43
44 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
45
46 EXPECT_EQ(result, 0);
47 EXPECT_EQ(msg.pci_vendor_id, htobe16(pciVendorId));
48 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
49 5);
50 EXPECT_NE(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
51 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
52 EXPECT_EQ((msg.ocp_version & 0xF0) >>
53 ocp::accelerator_management::ocpTypeBitOffset,
54 ocp::accelerator_management::ocpType);
55 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
56 }
57
TEST_F(OcpMctpVdmTests,PackHeaderResponseSuccess)58 TEST_F(OcpMctpVdmTests, PackHeaderResponseSuccess)
59 {
60 const uint16_t pciVendorId = 0x1234;
61 ocp::accelerator_management::BindingPciVidInfo hdr{};
62 ocp::accelerator_management::BindingPciVid msg{};
63
64 hdr.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
65 ocp::accelerator_management::MessageType::RESPONSE);
66 hdr.instance_id = 10;
67 hdr.msg_type = 0x7E;
68
69 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
70
71 EXPECT_EQ(result, 0);
72 EXPECT_EQ(msg.pci_vendor_id, htobe16(pciVendorId));
73 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
74 10);
75 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
76 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
77 EXPECT_EQ((msg.ocp_version & 0xF0) >>
78 ocp::accelerator_management::ocpTypeBitOffset,
79 ocp::accelerator_management::ocpType);
80 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
81 }
82
TEST_F(OcpMctpVdmTests,PackHeaderInvalidMessageType)83 TEST_F(OcpMctpVdmTests, PackHeaderInvalidMessageType)
84 {
85 const uint16_t pciVendorId = 0x1234;
86 ocp::accelerator_management::BindingPciVidInfo hdr{};
87 ocp::accelerator_management::BindingPciVid msg{};
88
89 hdr.ocp_accelerator_management_msg_type = 3; // Invalid message type
90 hdr.instance_id = 5;
91 hdr.msg_type = 0x7E;
92
93 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
94
95 EXPECT_EQ(result, EINVAL);
96 }
97
TEST_F(OcpMctpVdmTests,PackHeaderInvalidInstanceId)98 TEST_F(OcpMctpVdmTests, PackHeaderInvalidInstanceId)
99 {
100 const uint16_t pciVendorId = 0x1234;
101 ocp::accelerator_management::BindingPciVidInfo hdr{};
102 ocp::accelerator_management::BindingPciVid msg{};
103
104 hdr.ocp_accelerator_management_msg_type =
105 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
106 hdr.instance_id = 32; // Out of range (0-31 valid)
107 hdr.msg_type = 0x7E;
108
109 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
110
111 EXPECT_EQ(result, EINVAL);
112 }
113
114 // Tests for OcpMctpVdm::decodeReasonCodeAndCC function
TEST_F(OcpMctpVdmTests,DecodeReasonCodeAndCCSuccessCase)115 TEST_F(OcpMctpVdmTests, DecodeReasonCodeAndCCSuccessCase)
116 {
117 ocp::accelerator_management::CommonNonSuccessResponse response{};
118 response.command = 0x42;
119 response.completion_code = static_cast<uint8_t>(
120 ocp::accelerator_management::CompletionCode::SUCCESS);
121 response.reason_code = htole16(0x1234);
122
123 ocp::accelerator_management::CompletionCode cc{};
124 uint16_t reasonCode{};
125
126 std::array<uint8_t, sizeof(response)> buf{};
127 std::memcpy(buf.data(), &response, sizeof(response));
128
129 int result =
130 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
131
132 EXPECT_EQ(result, 0);
133 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
134 EXPECT_EQ(reasonCode, 0); // Should be 0 for SUCCESS
135 }
136
TEST_F(OcpMctpVdmTests,DecodeReasonCodeAndCCErrorCase)137 TEST_F(OcpMctpVdmTests, DecodeReasonCodeAndCCErrorCase)
138 {
139 ocp::accelerator_management::CommonNonSuccessResponse response{};
140 response.command = 0x42;
141 response.completion_code = static_cast<uint8_t>(
142 ocp::accelerator_management::CompletionCode::ERROR);
143 response.reason_code = htole16(0x5678);
144
145 ocp::accelerator_management::CompletionCode cc{};
146 uint16_t reasonCode{};
147
148 std::array<uint8_t, sizeof(response)> buf{};
149 std::memcpy(buf.data(), &response, sizeof(response));
150
151 int result =
152 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
153
154 EXPECT_EQ(result, 0);
155 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR);
156 EXPECT_EQ(reasonCode, 0x5678);
157 }
158
159 } // namespace ocp_mctp_tests
160
161 namespace gpu_mctp_tests
162 {
163
164 class GpuMctpVdmTests : public ::testing::Test
165 {
166 protected:
SetUp()167 void SetUp() override
168 {
169 // Initialize common test data here
170 }
171 };
172
173 // Tests for GpuMctpVdm::packHeader function
TEST_F(GpuMctpVdmTests,PackHeaderSuccess)174 TEST_F(GpuMctpVdmTests, PackHeaderSuccess)
175 {
176 ocp::accelerator_management::BindingPciVidInfo hdr{};
177 ocp::accelerator_management::BindingPciVid msg{};
178
179 hdr.ocp_accelerator_management_msg_type =
180 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
181 hdr.instance_id = 5;
182 hdr.msg_type = 0x7E;
183
184 int result = gpu::packHeader(hdr, msg);
185
186 EXPECT_EQ(result, 0);
187 EXPECT_EQ(msg.pci_vendor_id, htobe16(gpu::nvidiaPciVendorId));
188 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
189 5);
190 EXPECT_NE(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
191 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
192 EXPECT_EQ((msg.ocp_version & 0xF0) >>
193 ocp::accelerator_management::ocpTypeBitOffset,
194 ocp::accelerator_management::ocpType);
195 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
196 }
197
198 // Tests for GpuMctpVdm::encodeQueryDeviceIdentificationRequest function
TEST_F(GpuMctpVdmTests,EncodeQueryDeviceIdentificationRequestSuccess)199 TEST_F(GpuMctpVdmTests, EncodeQueryDeviceIdentificationRequestSuccess)
200 {
201 const uint8_t instanceId = 3;
202 std::vector<uint8_t> buf(256);
203
204 int result = gpu::encodeQueryDeviceIdentificationRequest(instanceId, buf);
205
206 EXPECT_EQ(result, 0);
207
208 gpu::QueryDeviceIdentificationRequest request{};
209 std::memcpy(&request, buf.data(), sizeof(request));
210
211 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
212 htobe16(gpu::nvidiaPciVendorId));
213 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
214 ocp::accelerator_management::instanceIdBitMask,
215 instanceId & ocp::accelerator_management::instanceIdBitMask);
216 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
217 ocp::accelerator_management::requestBitMask,
218 0);
219
220 EXPECT_EQ(request.hdr.command,
221 static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands::
222 QUERY_DEVICE_IDENTIFICATION));
223 EXPECT_EQ(request.hdr.data_size, 0);
224 }
225
226 // Tests for GpuMctpVdm::decodeQueryDeviceIdentificationResponse function
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseSuccess)227 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseSuccess)
228 {
229 // Create a mock successful response
230 std::vector<uint8_t> buf(sizeof(gpu::QueryDeviceIdentificationResponse));
231
232 gpu::QueryDeviceIdentificationResponse response{};
233 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
234 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
235 ocp::accelerator_management::MessageType::RESPONSE);
236 headerInfo.instance_id = 3;
237 headerInfo.msg_type =
238 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
239
240 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
241
242 // Populate response data
243 response.hdr.command = static_cast<uint8_t>(
244 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
245 response.hdr.completion_code = static_cast<uint8_t>(
246 ocp::accelerator_management::CompletionCode::SUCCESS);
247 response.hdr.reserved = 0;
248 response.hdr.data_size =
249 htole16(2); // Size of device_identification + instance_id
250 response.device_identification =
251 static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU);
252 response.instance_id = 7;
253
254 std::memcpy(buf.data(), &response, sizeof(response));
255
256 // Test decoding
257 ocp::accelerator_management::CompletionCode cc{};
258 uint16_t reasonCode{};
259 uint8_t deviceIdentification{};
260 uint8_t deviceInstance{};
261
262 int result = gpu::decodeQueryDeviceIdentificationResponse(
263 buf, cc, reasonCode, deviceIdentification, deviceInstance);
264
265 EXPECT_EQ(result, 0);
266 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
267 EXPECT_EQ(reasonCode, 0);
268 EXPECT_EQ(deviceIdentification,
269 static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU));
270 EXPECT_EQ(deviceInstance, 7);
271 }
272
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseError)273 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseError)
274 {
275 // Create a mock successful response
276 std::vector<uint8_t> buf(
277 sizeof(ocp::accelerator_management::CommonNonSuccessResponse));
278
279 ocp::accelerator_management::CommonNonSuccessResponse response{};
280 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
281 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
282 ocp::accelerator_management::MessageType::RESPONSE);
283 headerInfo.instance_id = 3;
284 headerInfo.msg_type =
285 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
286
287 gpu::packHeader(headerInfo, response.msgHdr.hdr);
288
289 // Populate response data
290 response.command = static_cast<uint8_t>(
291 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
292 response.command = static_cast<uint8_t>(
293 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
294 response.completion_code = static_cast<uint8_t>(
295 ocp::accelerator_management::CompletionCode::ERROR);
296 response.reason_code = htole16(0x1234);
297
298 std::memcpy(buf.data(), &response, sizeof(response));
299
300 // Test decoding
301 ocp::accelerator_management::CompletionCode cc{};
302 uint16_t reasonCode{};
303 uint8_t deviceIdentification{};
304 uint8_t deviceInstance{};
305
306 int result = gpu::decodeQueryDeviceIdentificationResponse(
307 buf, cc, reasonCode, deviceIdentification, deviceInstance);
308
309 EXPECT_EQ(result, 0);
310 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR);
311 EXPECT_EQ(reasonCode, 0x1234);
312 }
313
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseInvalidSize)314 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseInvalidSize)
315 {
316 // Create a too-small buffer
317 std::vector<uint8_t> buf(
318 sizeof(ocp::accelerator_management::Message) + 2); // Too small
319
320 // Populate Message header only
321 ocp::accelerator_management::Message msg{};
322 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
323 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
324 ocp::accelerator_management::MessageType::RESPONSE);
325 headerInfo.instance_id = 3;
326 headerInfo.msg_type =
327 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
328
329 gpu::packHeader(headerInfo, msg.hdr);
330 std::memcpy(buf.data(), &msg, sizeof(msg));
331
332 // Test decoding with insufficient data
333 ocp::accelerator_management::CompletionCode cc{};
334 uint16_t reasonCode{};
335 uint8_t deviceIdentification{};
336 uint8_t deviceInstance{};
337
338 int result = gpu::decodeQueryDeviceIdentificationResponse(
339 buf, cc, reasonCode, deviceIdentification, deviceInstance);
340
341 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid size
342 }
343
344 // Tests for GpuMctpVdm::encodeGetTemperatureReadingRequest function
TEST_F(GpuMctpVdmTests,EncodeGetTemperatureReadingRequestSuccess)345 TEST_F(GpuMctpVdmTests, EncodeGetTemperatureReadingRequestSuccess)
346 {
347 const uint8_t instanceId = 4;
348 const uint8_t sensorId = 0;
349 std::vector<uint8_t> buf(256);
350
351 int result =
352 gpu::encodeGetTemperatureReadingRequest(instanceId, sensorId, buf);
353
354 EXPECT_EQ(result, 0);
355
356 gpu::GetTemperatureReadingRequest request{};
357 std::memcpy(&request, buf.data(), sizeof(request));
358
359 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
360 htobe16(gpu::nvidiaPciVendorId));
361 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
362 ocp::accelerator_management::instanceIdBitMask,
363 instanceId & ocp::accelerator_management::instanceIdBitMask);
364 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
365 ocp::accelerator_management::requestBitMask,
366 0);
367 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
368 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
369
370 // Verify request data
371 EXPECT_EQ(request.hdr.command,
372 static_cast<uint8_t>(
373 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING));
374 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
375 EXPECT_EQ(request.sensor_id, sensorId);
376 }
377
378 // Tests for GpuMctpVdm::decodeGetTemperatureReadingResponse function
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseSuccess)379 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseSuccess)
380 {
381 // Create a mock successful response
382 std::vector<uint8_t> buf(sizeof(gpu::GetTemperatureReadingResponse));
383
384 gpu::GetTemperatureReadingResponse response{};
385 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
386 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
387 ocp::accelerator_management::MessageType::RESPONSE);
388 headerInfo.instance_id = 4;
389 headerInfo.msg_type =
390 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
391
392 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
393
394 // Populate response data
395 response.hdr.command = static_cast<uint8_t>(
396 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
397 response.hdr.completion_code = static_cast<uint8_t>(
398 ocp::accelerator_management::CompletionCode::SUCCESS);
399 response.hdr.reserved = 0;
400 response.hdr.data_size = htole16(sizeof(int32_t));
401
402 // Set a temperature value of 75.5°C (75.5 * 256 = 19328)
403 response.reading = htole32(19328);
404
405 std::memcpy(buf.data(), &response, sizeof(response));
406
407 // Test decoding
408 ocp::accelerator_management::CompletionCode cc{};
409 uint16_t reasonCode{};
410 double temperatureReading{};
411
412 int result = gpu::decodeGetTemperatureReadingResponse(
413 buf, cc, reasonCode, temperatureReading);
414
415 EXPECT_EQ(result, 0);
416 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
417 EXPECT_EQ(reasonCode, 0);
418 EXPECT_NEAR(temperatureReading, 75.5, 0.01);
419 }
420
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseError)421 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseError)
422 {
423 std::vector<uint8_t> buf(
424 sizeof(ocp::accelerator_management::CommonNonSuccessResponse));
425
426 // Populate error response data
427 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
428 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
429 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
430 ocp::accelerator_management::MessageType::RESPONSE);
431 headerInfo.instance_id = 3;
432 headerInfo.msg_type =
433 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
434
435 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
436
437 errorResponse.command = static_cast<uint8_t>(
438 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
439 errorResponse.completion_code = static_cast<uint8_t>(
440 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
441 errorResponse.reason_code = htole16(0x4321);
442
443 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
444
445 // Test decoding
446 ocp::accelerator_management::CompletionCode cc{};
447 uint16_t reasonCode{};
448 double temperatureReading{};
449
450 int result = gpu::decodeGetTemperatureReadingResponse(
451 buf, cc, reasonCode, temperatureReading);
452
453 EXPECT_EQ(result, 0);
454 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
455 EXPECT_EQ(reasonCode, 0x4321);
456 }
457
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseInvalidSize)458 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseInvalidSize)
459 {
460 // Create a mock response with invalid data_size
461 std::vector<uint8_t> buf(sizeof(gpu::GetTemperatureReadingResponse));
462
463 gpu::GetTemperatureReadingResponse response{};
464 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
465 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
466 ocp::accelerator_management::MessageType::RESPONSE);
467 headerInfo.instance_id = 4;
468 headerInfo.msg_type =
469 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
470
471 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
472
473 response.hdr.command = static_cast<uint8_t>(
474 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
475 response.hdr.completion_code = static_cast<uint8_t>(
476 ocp::accelerator_management::CompletionCode::SUCCESS);
477 response.hdr.reserved = 0;
478 response.hdr.data_size = htole16(1); // Invalid - should be sizeof(int32_t)
479 response.reading = htole32(19328);
480
481 std::memcpy(buf.data(), &response, sizeof(response));
482
483 // Test decoding
484 ocp::accelerator_management::CompletionCode cc{};
485 uint16_t reasonCode{};
486 double temperatureReading{};
487
488 int result = gpu::decodeGetTemperatureReadingResponse(
489 buf, cc, reasonCode, temperatureReading);
490
491 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
492 }
493
494 // Tests for GpuMctpVdm::encodeReadThermalParametersRequest function
TEST_F(GpuMctpVdmTests,EncodeReadThermalParametersRequestSuccess)495 TEST_F(GpuMctpVdmTests, EncodeReadThermalParametersRequestSuccess)
496 {
497 const uint8_t instanceId = 5;
498 const uint8_t sensorId = 1;
499 std::array<uint8_t, sizeof(gpu::ReadThermalParametersRequest)> buf{};
500
501 int result =
502 gpu::encodeReadThermalParametersRequest(instanceId, sensorId, buf);
503
504 EXPECT_EQ(result, 0);
505
506 gpu::ReadThermalParametersRequest request{};
507 std::memcpy(&request, buf.data(), sizeof(request));
508
509 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
510 htobe16(gpu::nvidiaPciVendorId));
511 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
512 ocp::accelerator_management::instanceIdBitMask,
513 instanceId & ocp::accelerator_management::instanceIdBitMask);
514 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
515 ocp::accelerator_management::requestBitMask,
516 0);
517 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
518 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
519
520 // Verify request data
521 EXPECT_EQ(request.hdr.command,
522 static_cast<uint8_t>(
523 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS));
524 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
525 EXPECT_EQ(request.sensor_id, sensorId);
526 }
527
528 // Tests for GpuMctpVdm::decodeReadThermalParametersResponse function
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseSuccess)529 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseSuccess)
530 {
531 // Create a mock successful response
532 std::array<uint8_t, sizeof(gpu::ReadThermalParametersResponse)> buf{};
533
534 gpu::ReadThermalParametersResponse response{};
535 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
536 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
537 ocp::accelerator_management::MessageType::RESPONSE);
538 headerInfo.instance_id = 5;
539 headerInfo.msg_type =
540 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
541
542 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
543
544 // Populate response data
545 response.hdr.command = static_cast<uint8_t>(
546 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
547 response.hdr.completion_code = static_cast<uint8_t>(
548 ocp::accelerator_management::CompletionCode::SUCCESS);
549 response.hdr.reserved = 0;
550 response.hdr.data_size = htole16(sizeof(int32_t));
551
552 // Set a threshold value of 85°C (85 * 256 = 21760)
553 response.threshold = htole32(21760);
554
555 std::memcpy(buf.data(), &response, sizeof(response));
556
557 // Test decoding
558 ocp::accelerator_management::CompletionCode cc{};
559 uint16_t reasonCode{};
560 int32_t threshold{};
561
562 int result = gpu::decodeReadThermalParametersResponse(
563 buf, cc, reasonCode, threshold);
564
565 EXPECT_EQ(result, 0);
566 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
567 EXPECT_EQ(reasonCode, 0);
568 EXPECT_EQ(threshold, 21760);
569 }
570
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseError)571 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseError)
572 {
573 std::array<uint8_t,
574 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
575 buf{};
576
577 // Populate error response data
578 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
579 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
580 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
581 ocp::accelerator_management::MessageType::RESPONSE);
582 headerInfo.instance_id = 5;
583 headerInfo.msg_type =
584 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
585
586 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
587
588 errorResponse.command = static_cast<uint8_t>(
589 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
590 errorResponse.completion_code = static_cast<uint8_t>(
591 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
592 errorResponse.reason_code = htole16(0x5678);
593
594 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
595
596 // Test decoding
597 ocp::accelerator_management::CompletionCode cc{};
598 uint16_t reasonCode{};
599 int32_t threshold{};
600
601 int result = gpu::decodeReadThermalParametersResponse(
602 buf, cc, reasonCode, threshold);
603
604 EXPECT_EQ(result, 0);
605 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
606 EXPECT_EQ(reasonCode, 0x5678);
607 }
608
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseInvalidSize)609 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseInvalidSize)
610 {
611 // Create a mock response with invalid data_size
612 std::array<uint8_t, sizeof(gpu::ReadThermalParametersResponse)> buf{};
613
614 gpu::ReadThermalParametersResponse response{};
615 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
616 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
617 ocp::accelerator_management::MessageType::RESPONSE);
618 headerInfo.instance_id = 5;
619 headerInfo.msg_type =
620 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
621
622 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
623
624 response.hdr.command = static_cast<uint8_t>(
625 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
626 response.hdr.completion_code = static_cast<uint8_t>(
627 ocp::accelerator_management::CompletionCode::SUCCESS);
628 response.hdr.reserved = 0;
629 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(int32_t)
630 response.threshold = htole32(21760);
631
632 std::memcpy(buf.data(), &response, sizeof(response));
633
634 // Test decoding
635 ocp::accelerator_management::CompletionCode cc{};
636 uint16_t reasonCode{};
637 int32_t threshold{};
638
639 int result = gpu::decodeReadThermalParametersResponse(
640 buf, cc, reasonCode, threshold);
641
642 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
643 }
644
645 // Tests for GpuMctpVdm::encodeGetCurrentPowerDrawRequest function
TEST_F(GpuMctpVdmTests,EncodeGetCurrentPowerDrawRequestSuccess)646 TEST_F(GpuMctpVdmTests, EncodeGetCurrentPowerDrawRequestSuccess)
647 {
648 const uint8_t instanceId = 6;
649 const uint8_t sensorId = 2;
650 const uint8_t averagingInterval = 10;
651 std::array<uint8_t, sizeof(gpu::GetCurrentPowerDrawRequest)> buf{};
652
653 int result = gpu::encodeGetCurrentPowerDrawRequest(instanceId, sensorId,
654 averagingInterval, buf);
655
656 EXPECT_EQ(result, 0);
657
658 gpu::GetCurrentPowerDrawRequest request{};
659 std::memcpy(&request, buf.data(), sizeof(request));
660
661 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
662 htobe16(gpu::nvidiaPciVendorId));
663 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
664 ocp::accelerator_management::instanceIdBitMask,
665 instanceId & ocp::accelerator_management::instanceIdBitMask);
666 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
667 ocp::accelerator_management::requestBitMask,
668 0);
669 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
670 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
671
672 // Verify request data
673 EXPECT_EQ(request.hdr.command,
674 static_cast<uint8_t>(
675 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW));
676 EXPECT_EQ(request.hdr.data_size,
677 sizeof(sensorId) + sizeof(averagingInterval));
678 EXPECT_EQ(request.sensorId, sensorId);
679 EXPECT_EQ(request.averagingInterval, averagingInterval);
680 }
681
682 // Tests for GpuMctpVdm::decodeGetCurrentPowerDrawResponse function
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseSuccess)683 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseSuccess)
684 {
685 // Create a mock successful response
686 std::array<uint8_t, sizeof(gpu::GetCurrentPowerDrawResponse)> buf{};
687
688 gpu::GetCurrentPowerDrawResponse response{};
689 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
690 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
691 ocp::accelerator_management::MessageType::RESPONSE);
692 headerInfo.instance_id = 6;
693 headerInfo.msg_type =
694 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
695
696 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
697
698 // Populate response data
699 response.hdr.command = static_cast<uint8_t>(
700 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
701 response.hdr.completion_code = static_cast<uint8_t>(
702 ocp::accelerator_management::CompletionCode::SUCCESS);
703 response.hdr.reserved = 0;
704 response.hdr.data_size = htole16(sizeof(uint32_t));
705
706 // Set a power value of 250W
707 response.power = htole32(250);
708
709 std::memcpy(buf.data(), &response, sizeof(response));
710
711 // Test decoding
712 ocp::accelerator_management::CompletionCode cc{};
713 uint16_t reasonCode{};
714 uint32_t power{};
715
716 int result =
717 gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
718
719 EXPECT_EQ(result, 0);
720 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
721 EXPECT_EQ(reasonCode, 0);
722 EXPECT_EQ(power, 250U);
723 }
724
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseError)725 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseError)
726 {
727 std::array<uint8_t,
728 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
729 buf{};
730
731 // Populate error response data
732 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
733 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
734 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
735 ocp::accelerator_management::MessageType::RESPONSE);
736 headerInfo.instance_id = 6;
737 headerInfo.msg_type =
738 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
739
740 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
741
742 errorResponse.command = static_cast<uint8_t>(
743 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
744 errorResponse.completion_code = static_cast<uint8_t>(
745 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
746 errorResponse.reason_code = htole16(0x9ABC);
747
748 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
749
750 // Test decoding
751 ocp::accelerator_management::CompletionCode cc{};
752 uint16_t reasonCode{};
753 uint32_t power{};
754
755 int result =
756 gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
757
758 EXPECT_EQ(result, 0);
759 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
760 EXPECT_EQ(reasonCode, 0x9ABC);
761 }
762
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseInvalidSize)763 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseInvalidSize)
764 {
765 // Create a mock response with invalid data_size
766 std::array<uint8_t, sizeof(gpu::GetCurrentPowerDrawResponse)> buf{};
767
768 gpu::GetCurrentPowerDrawResponse response{};
769 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
770 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
771 ocp::accelerator_management::MessageType::RESPONSE);
772 headerInfo.instance_id = 6;
773 headerInfo.msg_type =
774 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
775
776 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
777
778 response.hdr.command = static_cast<uint8_t>(
779 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
780 response.hdr.completion_code = static_cast<uint8_t>(
781 ocp::accelerator_management::CompletionCode::SUCCESS);
782 response.hdr.reserved = 0;
783 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
784 response.power = htole32(250);
785
786 std::memcpy(buf.data(), &response, sizeof(response));
787
788 // Test decoding
789 ocp::accelerator_management::CompletionCode cc{};
790 uint16_t reasonCode{};
791 uint32_t power{};
792
793 int result =
794 gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
795
796 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
797 }
798
799 // Tests for GpuMctpVdm::encodeGetCurrentEnergyCounterRequest function
TEST_F(GpuMctpVdmTests,EncodeGetCurrentEnergyCounterRequestSuccess)800 TEST_F(GpuMctpVdmTests, EncodeGetCurrentEnergyCounterRequestSuccess)
801 {
802 const uint8_t instanceId = 7;
803 const uint8_t sensorId = 3;
804 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterRequest)> buf{};
805
806 int result =
807 gpu::encodeGetCurrentEnergyCounterRequest(instanceId, sensorId, buf);
808
809 EXPECT_EQ(result, 0);
810
811 gpu::GetCurrentEnergyCounterRequest request{};
812 std::memcpy(&request, buf.data(), sizeof(request));
813
814 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
815 htobe16(gpu::nvidiaPciVendorId));
816 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
817 ocp::accelerator_management::instanceIdBitMask,
818 instanceId & ocp::accelerator_management::instanceIdBitMask);
819 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
820 ocp::accelerator_management::requestBitMask,
821 0);
822 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
823 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
824
825 // Verify request data
826 EXPECT_EQ(
827 request.hdr.command,
828 static_cast<uint8_t>(
829 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER));
830 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
831 EXPECT_EQ(request.sensor_id, sensorId);
832 }
833
834 // Tests for GpuMctpVdm::decodeGetCurrentEnergyCounterResponse function
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseSuccess)835 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseSuccess)
836 {
837 // Create a mock successful response
838 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
839
840 gpu::GetCurrentEnergyCounterResponse response{};
841 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
842 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
843 ocp::accelerator_management::MessageType::RESPONSE);
844 headerInfo.instance_id = 7;
845 headerInfo.msg_type =
846 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
847
848 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
849
850 // Populate response data
851 response.hdr.command = static_cast<uint8_t>(
852 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
853 response.hdr.completion_code = static_cast<uint8_t>(
854 ocp::accelerator_management::CompletionCode::SUCCESS);
855 response.hdr.reserved = 0;
856 response.hdr.data_size = htole16(sizeof(uint64_t));
857
858 // Set an energy value of 1000 Wh (1000 * 3600 = 3600000 Joules)
859 response.energy = htole64(3600000);
860
861 std::memcpy(buf.data(), &response, sizeof(response));
862
863 // Test decoding
864 ocp::accelerator_management::CompletionCode cc{};
865 uint16_t reasonCode{};
866 uint64_t energy{};
867
868 int result =
869 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
870
871 EXPECT_EQ(result, 0);
872 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
873 EXPECT_EQ(reasonCode, 0);
874 EXPECT_EQ(energy, 3600000U);
875 }
876
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseError)877 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseError)
878 {
879 std::array<uint8_t,
880 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
881 buf{};
882
883 // Populate error response data
884 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
885 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
886 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
887 ocp::accelerator_management::MessageType::RESPONSE);
888 headerInfo.instance_id = 7;
889 headerInfo.msg_type =
890 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
891
892 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
893
894 errorResponse.command = static_cast<uint8_t>(
895 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
896 errorResponse.completion_code = static_cast<uint8_t>(
897 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
898 errorResponse.reason_code = htole16(0xDEF0);
899
900 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
901
902 // Test decoding
903 ocp::accelerator_management::CompletionCode cc{};
904 uint16_t reasonCode{};
905 uint64_t energy{};
906
907 int result =
908 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
909
910 EXPECT_EQ(result, 0);
911 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
912 EXPECT_EQ(reasonCode, 0xDEF0);
913 }
914
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseInvalidSize)915 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseInvalidSize)
916 {
917 // Create a mock response with invalid data_size
918 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
919
920 gpu::GetCurrentEnergyCounterResponse response{};
921 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
922 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
923 ocp::accelerator_management::MessageType::RESPONSE);
924 headerInfo.instance_id = 7;
925 headerInfo.msg_type =
926 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
927
928 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
929
930 response.hdr.command = static_cast<uint8_t>(
931 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
932 response.hdr.completion_code = static_cast<uint8_t>(
933 ocp::accelerator_management::CompletionCode::SUCCESS);
934 response.hdr.reserved = 0;
935 response.hdr.data_size = htole16(4); // Invalid - should be sizeof(uint64_t)
936 response.energy = htole64(3600000);
937
938 std::memcpy(buf.data(), &response, sizeof(response));
939
940 // Test decoding
941 ocp::accelerator_management::CompletionCode cc{};
942 uint16_t reasonCode{};
943 uint64_t energy{};
944
945 int result =
946 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
947
948 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
949 }
950
951 // Tests for GpuMctpVdm::encodeGetVoltageRequest function
TEST_F(GpuMctpVdmTests,EncodeGetVoltageRequestSuccess)952 TEST_F(GpuMctpVdmTests, EncodeGetVoltageRequestSuccess)
953 {
954 const uint8_t instanceId = 8;
955 const uint8_t sensorId = 4;
956 std::array<uint8_t, sizeof(gpu::GetVoltageRequest)> buf{};
957
958 int result = gpu::encodeGetVoltageRequest(instanceId, sensorId, buf);
959
960 EXPECT_EQ(result, 0);
961
962 gpu::GetVoltageRequest request{};
963 std::memcpy(&request, buf.data(), sizeof(request));
964
965 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
966 htobe16(gpu::nvidiaPciVendorId));
967 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
968 ocp::accelerator_management::instanceIdBitMask,
969 instanceId & ocp::accelerator_management::instanceIdBitMask);
970 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
971 ocp::accelerator_management::requestBitMask,
972 0);
973 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
974 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
975
976 // Verify request data
977 EXPECT_EQ(
978 request.hdr.command,
979 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE));
980 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
981 EXPECT_EQ(request.sensor_id, sensorId);
982 }
983
984 // Tests for GpuMctpVdm::decodeGetVoltageResponse function
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseSuccess)985 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseSuccess)
986 {
987 // Create a mock successful response
988 std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
989
990 gpu::GetVoltageResponse response{};
991 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
992 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
993 ocp::accelerator_management::MessageType::RESPONSE);
994 headerInfo.instance_id = 8;
995 headerInfo.msg_type =
996 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
997
998 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
999
1000 // Populate response data
1001 response.hdr.command =
1002 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1003 response.hdr.completion_code = static_cast<uint8_t>(
1004 ocp::accelerator_management::CompletionCode::SUCCESS);
1005 response.hdr.reserved = 0;
1006 response.hdr.data_size = htole16(sizeof(uint32_t));
1007
1008 // Set a voltage value of 12.5V (12.5 * 1000 = 12500 mV)
1009 response.voltage = htole32(12500);
1010
1011 std::memcpy(buf.data(), &response, sizeof(response));
1012
1013 // Test decoding
1014 ocp::accelerator_management::CompletionCode cc{};
1015 uint16_t reasonCode{};
1016 uint32_t voltage{};
1017
1018 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1019
1020 EXPECT_EQ(result, 0);
1021 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
1022 EXPECT_EQ(reasonCode, 0);
1023 EXPECT_EQ(voltage, 12500U);
1024 }
1025
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseError)1026 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseError)
1027 {
1028 std::array<uint8_t,
1029 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
1030 buf{};
1031
1032 // Populate error response data
1033 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
1034 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1035 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1036 ocp::accelerator_management::MessageType::RESPONSE);
1037 headerInfo.instance_id = 8;
1038 headerInfo.msg_type =
1039 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1040
1041 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
1042
1043 errorResponse.command =
1044 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1045 errorResponse.completion_code = static_cast<uint8_t>(
1046 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1047 errorResponse.reason_code = htole16(0x1234);
1048
1049 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
1050
1051 // Test decoding
1052 ocp::accelerator_management::CompletionCode cc{};
1053 uint16_t reasonCode{};
1054 uint32_t voltage{};
1055
1056 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1057
1058 EXPECT_EQ(result, 0);
1059 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1060 EXPECT_EQ(reasonCode, 0x1234);
1061 }
1062
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseInvalidSize)1063 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseInvalidSize)
1064 {
1065 // Create a mock response with invalid data_size
1066 std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
1067
1068 gpu::GetVoltageResponse response{};
1069 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1070 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1071 ocp::accelerator_management::MessageType::RESPONSE);
1072 headerInfo.instance_id = 8;
1073 headerInfo.msg_type =
1074 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1075
1076 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
1077
1078 response.hdr.command =
1079 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1080 response.hdr.completion_code = static_cast<uint8_t>(
1081 ocp::accelerator_management::CompletionCode::SUCCESS);
1082 response.hdr.reserved = 0;
1083 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
1084 response.voltage = htole32(12500);
1085
1086 std::memcpy(buf.data(), &response, sizeof(response));
1087
1088 // Test decoding
1089 ocp::accelerator_management::CompletionCode cc{};
1090 uint16_t reasonCode{};
1091 uint32_t voltage{};
1092
1093 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1094
1095 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
1096 }
1097 } // namespace gpu_mctp_tests
1098