| /* |
| * SPDX-FileCopyrightText: Copyright OpenBMC Authors |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #pragma once |
| |
| #include "NvidiaEventReporting.hpp" |
| #include "NvidiaGpuMctpVdm.hpp" |
| #include "OcpMctpVdm.hpp" |
| |
| #include <MessagePackUnpackUtils.hpp> |
| |
| #include <concepts> |
| #include <cstddef> |
| #include <cstdint> |
| #include <vector> |
| |
| namespace test_utils |
| { |
| |
| constexpr uint8_t defaultEid = 10; |
| |
| // Header(5) + command(1) + cc(1) + reasonCode(2) |
| constexpr size_t errorResponseSize = |
| ocp::accelerator_management::messageHeaderSize + 4; |
| |
| // Build a SUCCESS PLATFORM_ENVIRONMENTAL response with a single integral |
| // payload appended after the common response header. Used by the temperature, |
| // power, energy, voltage and peak-power sensor tests. |
| template <std::integral Payload> |
| inline std::vector<uint8_t> buildPlatformEnvSuccessResponse( |
| gpu::PlatformEnvironmentalCommands command, Payload payload) |
| { |
| std::vector<uint8_t> buf( |
| ocp::accelerator_management::commonResponseSize + sizeof(Payload)); |
| PackBuffer pack(buf); |
| ocp::accelerator_management::packHeader( |
| pack, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 0, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pack.pack(static_cast<uint8_t>(command)); |
| pack.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pack.pack(static_cast<uint16_t>(0)); // reserved |
| pack.pack(static_cast<uint16_t>(sizeof(Payload))); |
| pack.pack(payload); |
| return buf; |
| } |
| |
| // Build an error PLATFORM_ENVIRONMENTAL response: header + command + cc + |
| // reasonCode (no dataSize / payload). |
| inline std::vector<uint8_t> buildPlatformEnvErrorResponse( |
| gpu::PlatformEnvironmentalCommands command, uint8_t cc, uint16_t reasonCode) |
| { |
| std::vector<uint8_t> buf(errorResponseSize); |
| PackBuffer pack(buf); |
| ocp::accelerator_management::packHeader( |
| pack, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 0, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pack.pack(static_cast<uint8_t>(command)); |
| pack.pack(cc); |
| pack.pack(reasonCode); |
| return buf; |
| } |
| |
| // Build a SUCCESS QueryScalarGroupTelemetryV2 response on the PCIE_LINK |
| // message type with the supplied uint32_t telemetry values appended after the |
| // common response header. |
| inline std::vector<uint8_t> buildPcieScalarTelemetryResponse( |
| const std::vector<uint32_t>& values) |
| { |
| const size_t dataSize = values.size() * sizeof(uint32_t); |
| std::vector<uint8_t> buf( |
| ocp::accelerator_management::commonResponseSize + dataSize); |
| PackBuffer pack(buf); |
| ocp::accelerator_management::packHeader( |
| pack, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 0, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pack.pack(static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV2)); |
| pack.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pack.pack(static_cast<uint16_t>(0)); // reserved |
| pack.pack(static_cast<uint16_t>(dataSize)); |
| for (const uint32_t val : values) |
| { |
| pack.pack(val); |
| } |
| return buf; |
| } |
| |
| // Event class the device uses for a deferred long-running response. |
| constexpr uint8_t longRunningResponseEventClass = 128; |
| |
| // Build a long-running response event data buffer: |
| // instanceId(1) + completionCode(1) + reasonCode(2 LE) + payload |
| inline std::vector<uint8_t> buildLongRunningEventData( |
| uint8_t instanceId, uint8_t cc, uint16_t reasonCode, |
| const std::vector<uint8_t>& payload) |
| { |
| std::vector<uint8_t> buf; |
| buf.push_back(instanceId); |
| buf.push_back(cc); |
| buf.push_back(static_cast<uint8_t>(reasonCode & 0xFF)); |
| buf.push_back(static_cast<uint8_t>((reasonCode >> 8) & 0xFF)); |
| buf.insert(buf.end(), payload.begin(), payload.end()); |
| return buf; |
| } |
| |
| // Build the EventInfo carrying a long-running response: the originating |
| // command and message type are packed into eventState. |
| inline EventInfo makeEventInfo(uint8_t eventClass, uint8_t messageType, |
| uint8_t command) |
| { |
| EventInfo info{}; |
| info.eventClass = eventClass; |
| info.eventState = static_cast<uint16_t>( |
| (static_cast<uint16_t>(command) << 8) | messageType); |
| return info; |
| } |
| |
| } // namespace test_utils |