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