blob: 17f71e051b757b51cb7bd652228179605cbb57d0 [file] [log] [blame]
Harshit Aghera560e6af2025-04-21 20:04:56 +05301/*
2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3 * AFFILIATES. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include "NvidiaGpuMctpVdm.hpp"
8
9#include "OcpMctpVdm.hpp"
10
11#include <endian.h>
12
13#include <cerrno>
14#include <cstdint>
15#include <cstring>
16#include <span>
17
18namespace gpu
19{
20// These functions encode/decode data communicated over the network
21// The use of reinterpret_cast enables direct memory access to raw byte buffers
22// without doing unnecessary data copying
23// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
24int packHeader(const ocp::accelerator_management::BindingPciVidInfo& hdr,
25 ocp::accelerator_management::BindingPciVid& msg)
26{
27 return ocp::accelerator_management::packHeader(nvidiaPciVendorId, hdr, msg);
28}
29
30int encodeQueryDeviceIdentificationRequest(uint8_t instanceId,
31 const std::span<uint8_t> buf)
32{
33 if (buf.size() < sizeof(QueryDeviceIdentificationRequest))
34 {
35 return EINVAL;
36 }
37
38 auto* msg = reinterpret_cast<QueryDeviceIdentificationRequest*>(buf.data());
39
40 ocp::accelerator_management::BindingPciVidInfo header{};
41
42 header.ocp_accelerator_management_msg_type =
43 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
44 header.instance_id = instanceId &
45 ocp::accelerator_management::instanceIdBitMask;
46 header.msg_type =
47 static_cast<uint8_t>(MessageType::DEVICE_CAPABILITY_DISCOVERY);
48
49 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
50
51 if (rc != 0)
52 {
53 return rc;
54 }
55
56 msg->hdr.command = static_cast<uint8_t>(
57 DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
58 msg->hdr.data_size = 0;
59
60 return 0;
61}
62
63int decodeQueryDeviceIdentificationResponse(
64 const std::span<const uint8_t> buf,
65 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
66 uint8_t& deviceIdentification, uint8_t& deviceInstance)
67{
68 auto rc =
69 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
70
71 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
72 {
73 return rc;
74 }
75
76 if (buf.size() < sizeof(QueryDeviceIdentificationResponse))
77 {
78 return EINVAL;
79 }
80
81 const auto* response =
82 reinterpret_cast<const QueryDeviceIdentificationResponse*>(buf.data());
83
84 deviceIdentification = response->device_identification;
85 deviceInstance = response->instance_id;
86
87 return 0;
88}
89
90int encodeGetTemperatureReadingRequest(uint8_t instanceId, uint8_t sensorId,
91 std::span<uint8_t> buf)
92{
93 if (buf.size() < sizeof(GetTemperatureReadingRequest))
94 {
95 return EINVAL;
96 }
97
98 auto* msg = reinterpret_cast<GetTemperatureReadingRequest*>(buf.data());
99
100 ocp::accelerator_management::BindingPciVidInfo header{};
101 header.ocp_accelerator_management_msg_type =
102 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
103 header.instance_id = instanceId &
104 ocp::accelerator_management::instanceIdBitMask;
105 header.msg_type = static_cast<uint8_t>(MessageType::PLATFORM_ENVIRONMENTAL);
106
107 auto rc = packHeader(header, msg->hdr.msgHdr.hdr);
108
109 if (rc != 0)
110 {
111 return rc;
112 }
113
114 msg->hdr.command = static_cast<uint8_t>(
115 PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
116 msg->hdr.data_size = sizeof(sensorId);
117 msg->sensor_id = sensorId;
118
119 return 0;
120}
121
122int decodeGetTemperatureReadingResponse(
123 const std::span<const uint8_t> buf,
124 ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
125 double& temperatureReading)
126{
127 auto rc =
128 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
129
130 if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
131 {
132 return rc;
133 }
134
135 if (buf.size() < sizeof(GetTemperatureReadingResponse))
136 {
137 return EINVAL;
138 }
139
140 const auto* response =
141 reinterpret_cast<const GetTemperatureReadingResponse*>(buf.data());
142
143 uint16_t dataSize = le16toh(response->hdr.data_size);
144
145 if (dataSize != sizeof(int32_t))
146 {
147 return EINVAL;
148 }
149
150 int32_t reading = le32toh(response->reading);
151 temperatureReading = reading / static_cast<double>(1 << 8);
152
153 return 0;
154}
155// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
156} // namespace gpu