blob: df6495fadb54c749075aa8b5d7afc91160f43edb [file] [edit]
/*
* 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