blob: 5b19e822304d02dbeb6482391a7aae10c9c73e3d [file]
/*
* SPDX-FileCopyrightText: Copyright OpenBMC Authors
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <OcpMctpVdm.hpp>
#include <array>
#include <cstddef>
#include <cstdint>
#include <span>
#include <string>
#include <utility>
#include <variant>
#include <vector>
namespace gpu
{
using InventoryValue =
std::variant<std::string, std::vector<uint8_t>, uint32_t>;
constexpr uint16_t nvidiaPciVendorId = 0x10de;
enum class MessageType : uint8_t
{
DEVICE_CAPABILITY_DISCOVERY = 0,
NETWORK_PORT = 1,
PCIE_LINK = 2,
PLATFORM_ENVIRONMENTAL = 3
};
enum class DeviceCapabilityDiscoveryCommands : uint8_t
{
GET_SUPPORTED_MESSAGE_TYPES = 0x01,
GET_SUPPORTED_COMMAND_CODES = 0x02,
SET_CURRENT_EVENT_SOURCES = 0x5,
SET_EVENT_SUBSCRIPTION = 0x6,
QUERY_DEVICE_IDENTIFICATION = 0x09,
};
enum class DeviceCapabilityDiscoveryEvents : uint8_t
{
LONG_RUNNING_RESPONSE = 0x02,
};
enum class PlatformEnvironmentalCommands : uint8_t
{
GET_TEMPERATURE_READING = 0x00,
READ_THERMAL_PARAMETERS = 0x02,
GET_CURRENT_POWER_DRAW = 0x03,
GET_MAX_OBSERVED_POWER = 0x04,
GET_CURRENT_ENERGY_COUNTER = 0x06,
GET_POWER_LIMITS = 0x07,
SET_POWER_LIMITS = 0x08,
GET_CURRENT_CLOCK_FREQUENCY = 0x0B,
GET_INVENTORY_INFORMATION = 0x0C,
GET_DRIVER_INFORMATION = 0x0E,
GET_VOLTAGE = 0x0F,
SET_CLOCK_LIMIT = 0x10,
GET_CLOCK_LIMIT = 0x11,
GET_LEAK_DETECTION_INFO = 0x17,
GET_VIOLATION_DURATION = 0x45,
GET_CURRENT_UTILIZATION = 0x47,
GET_ECC_MODE = 0x4F,
GET_ECC_ERROR_COUNTS = 0x7D,
GET_MEMORY_CAPACITY_UTILIZATION = 0xAD,
};
enum class PlatformEnvironmentalEvent : uint8_t
{
RESET_REQUIRED = 0x00,
XID = 0x01,
};
enum class NetworkPortCommands : uint8_t
{
GetEthernetPortTelemetryCounters = 0x0F,
GetPortNetworkAddresses = 0x11,
};
enum class PcieLinkCommands : uint8_t
{
QueryScalarGroupTelemetryV1 = 0x04,
ListPCIePorts = 0x07,
QueryScalarGroupTelemetryV2 = 0x24,
};
enum class PcieScalarGroupId : uint8_t
{
PciIdentity = 0,
LinkSpeedWidth = 1,
AerErrorCounters = 2,
RecoveryCounter = 3,
DetailedErrorCounters = 4,
ThroughputCounters = 5,
LtssmState = 6,
BarInformation = 7,
PerLaneErrorCounts = 8,
AerStatus = 9,
OutboundTlpCounters = 10,
};
enum class DeviceIdentification : uint8_t
{
DEVICE_GPU = 0,
DEVICE_PCIE = 2,
DEVICE_SMA = 5
};
enum class InventoryPropertyId : uint8_t
{
BOARD_PART_NUMBER = 0,
SERIAL_NUMBER = 1,
MARKETING_NAME = 2,
DEVICE_PART_NUMBER = 3,
FRU_PART_NUMBER = 4,
MEMORY_VENDOR = 5,
MEMORY_PART_NUMBER = 6,
MAX_MEMORY_CAPACITY = 7,
BUILD_DATE = 8,
FIRMWARE_VERSION = 9,
DEVICE_GUID = 10,
INFOROM_VERSION = 11,
PRODUCT_LENGTH = 12,
PRODUCT_WIDTH = 13,
PRODUCT_HEIGHT = 14,
RATED_DEVICE_POWER_LIMIT = 15,
MIN_DEVICE_POWER_LIMIT = 16,
MAX_DEVICE_POWER_LIMIT = 17,
MAX_MODULE_POWER_LIMIT = 18,
MIN_MODULE_POWER_LIMIT = 19,
RATED_MODULE_POWER_LIMIT = 20,
DEFAULT_BOOST_CLOCKS = 21,
DEFAULT_BASE_CLOCKS = 22,
DEFAULT_EDPP_SCALING = 23,
MIN_EDPP_SCALING = 24,
MAX_EDPP_SCALING = 25,
MIN_GRAPHICS_CLOCK = 26,
MAX_GRAPHICS_CLOCK = 27,
MIN_MEMORY_CLOCK = 28,
MAX_MEMORY_CLOCK = 29,
INFINIBAND_GUID = 30,
RACK_GUID = 31,
RACK_SLOT_NUMBER = 32,
COMPUTE_SLOT_INDEX = 33,
NODE_INDEX = 34,
GPU_NODE_ID = 35,
NVLINK_PEER_TYPE = 36
};
enum class PciePortType : uint8_t
{
UPSTREAM = 0,
DOWNSTREAM = 1,
};
enum class SetPowerLimitsAction : uint8_t
{
NEW_LIMIT = 0,
DEFAULT_LIMIT = 1,
};
enum class SetPowerLimitsPersistence : uint8_t
{
ONE_SHOT = 0,
PERSISTENT = 1,
};
enum class DriverState : uint8_t
{
DRIVER_STATE_UNKNOWN = 0,
DRIVER_STATE_NOT_LOADED = 1,
DRIVER_STATE_LOADED = 2,
};
enum class NetworkPortLinkType : uint8_t
{
ETHERNET = 0,
INFINIBAND = 1,
UNKNOWN = 0xFF,
};
enum class ClockType : uint8_t
{
GRAPHICS_CLOCK = 0,
MEMORY_CLOCK = 1,
};
enum class ClockLimitFlag : uint8_t
{
PERSISTENCE = 1,
CLEAR = 3,
};
constexpr size_t maxInventoryDataSize = 256;
constexpr size_t queryDeviceIdentificationRequestSize =
ocp::accelerator_management::commonRequestSize;
// Type 0 supported-message-types / supported-command-codes responses carry a
// bitfield8[32]: 256 bits, bit N set means item N is supported.
constexpr size_t supportedListBitfieldSize = 32;
constexpr size_t getSupportedMessageTypesRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t getSupportedCommandCodesRequestSize =
ocp::accelerator_management::commonRequestSize + 1;
constexpr size_t getLeakDetectionInfoRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t getNumericSensorReadingRequestSize =
ocp::accelerator_management::commonRequestSize + 1;
constexpr size_t getTemperatureReadingRequestSize =
getNumericSensorReadingRequestSize;
constexpr size_t readThermalParametersRequestSize =
getNumericSensorReadingRequestSize;
constexpr size_t getPowerDrawRequestSize =
ocp::accelerator_management::commonRequestSize + 2;
constexpr size_t getPowerLimitsRequestSize =
ocp::accelerator_management::commonRequestSize + 4;
constexpr size_t setPowerLimitsRequestSize =
ocp::accelerator_management::commonRequestSize + 10;
constexpr size_t getCurrentEnergyCounterRequestSize =
getNumericSensorReadingRequestSize;
constexpr size_t getVoltageRequestSize = getNumericSensorReadingRequestSize;
constexpr size_t getCurrentUtilizationRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t getViolationDurationRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t getMemoryCapacityUtilizationRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t queryScalarGroupTelemetryV1RequestSize =
ocp::accelerator_management::commonRequestSize + 2;
constexpr size_t queryScalarGroupTelemetryV2RequestSize =
ocp::accelerator_management::commonRequestSize + 3;
constexpr size_t getPortNetworkAddressesRequestSize =
ocp::accelerator_management::commonRequestSize + 2;
constexpr size_t getEthernetPortTelemetryCountersRequestSize =
ocp::accelerator_management::commonRequestSize + 2;
constexpr size_t getInventoryInformationRequestSize =
ocp::accelerator_management::commonRequestSize + 1;
constexpr size_t getDriverInformationResponseMinSize =
ocp::accelerator_management::commonResponseSize + 2;
constexpr size_t getCurrentClockFrequencyRequestSize =
ocp::accelerator_management::commonRequestSize + sizeof(uint8_t);
constexpr size_t getEccErrorCountsRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t getEccModeRequestSize =
ocp::accelerator_management::commonRequestSize;
constexpr size_t setEventSubscriptionRequestSize =
ocp::accelerator_management::commonRequestSize + 2;
constexpr size_t setEventSourcesRequestSize =
ocp::accelerator_management::commonRequestSize + 9;
constexpr size_t longRunningResponseEventSize = 4;
constexpr size_t xidEventMinDataSize = 20;
constexpr size_t getClockLimitRequestSize =
ocp::accelerator_management::commonRequestSize + sizeof(uint8_t);
constexpr size_t setClockLimitRequestSize =
ocp::accelerator_management::commonRequestSize + sizeof(uint8_t) +
sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t);
int encodeRequestCommonHeader(PackBuffer& buffer, gpu::MessageType msgType,
uint8_t command, uint8_t instanceId);
int decodeResponseCommonHeader(
UnpackBuffer& buffer, gpu::MessageType msgType, uint8_t command,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode);
int encodeQueryDeviceIdentificationRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int encodeSetEventSubscriptionRequest(uint8_t generationSetting, uint8_t eid,
std::span<uint8_t> buf);
int decodeSetEventSubscriptionResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode);
int encodeSetEventSourcesRequest(uint64_t sources, uint8_t messageType,
std::span<uint8_t> buf);
int decodeSetEventSourcesResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode);
int decodeXidEvent(std::span<const uint8_t> buf, uint8_t& flags,
uint32_t& eventMessageReason, uint32_t& sequenceNumber,
uint64_t& timestamp, std::string_view& messageTextString);
int decodeQueryDeviceIdentificationResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint8_t& deviceIdentification, uint8_t& deviceInstance);
int encodeGetSupportedMessageTypesRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int decodeGetSupportedMessageTypesResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
std::array<uint8_t, supportedListBitfieldSize>& supportedTypes);
int encodeGetSupportedCommandCodesRequest(
uint8_t instanceId, uint8_t nvidiaMessageType, std::span<uint8_t> buf);
int decodeGetSupportedCommandCodesResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
std::array<uint8_t, supportedListBitfieldSize>& supportedCommands);
int encodeGetTemperatureReadingRequest(uint8_t instanceId, uint8_t sensorId,
std::span<uint8_t> buf);
int decodeGetTemperatureReadingResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
double& temperatureReading);
int encodeReadThermalParametersRequest(uint8_t instanceId, uint8_t sensorId,
std::span<uint8_t> buf);
int decodeReadThermalParametersResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
int32_t& threshold);
int encodeGetPowerDrawRequest(
PlatformEnvironmentalCommands commandCode, uint8_t instanceId,
uint8_t sensorId, uint8_t averagingInterval, std::span<uint8_t> buf);
int decodeGetPowerDrawResponse(std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc,
uint16_t& reasonCode, uint32_t& power);
int encodeGetCurrentEnergyCounterRequest(uint8_t instanceId, uint8_t sensorId,
std::span<uint8_t> buf);
int decodeGetCurrentEnergyCounterResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint64_t& energy);
int encodeGetVoltageRequest(uint8_t instanceId, uint8_t sensorId,
std::span<uint8_t> buf);
int decodeGetVoltageResponse(std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc,
uint16_t& reasonCode, uint32_t& voltage);
int encodeGetDriverInformationRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int decodeGetDriverInformationResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
DriverState& driverState, std::string& driverVersion);
int encodeGetPowerLimitsRequest(uint8_t instanceId, uint32_t powerLimitId,
std::span<uint8_t> buf);
int decodeGetPowerLimitsResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint32_t& persistentPowerLimitRequested,
uint32_t& oneshotPowerLimitRequested, uint32_t& powerLimitEnforced);
int encodeSetPowerLimitsRequest(
uint8_t instanceId, uint32_t powerLimitId, SetPowerLimitsAction action,
SetPowerLimitsPersistence persistence, uint32_t powerLimitMilliwatts,
std::span<uint8_t> buf);
int decodeSetPowerLimitsResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode);
int encodeGetInventoryInformationRequest(uint8_t instanceId, uint8_t propertyId,
std::span<uint8_t> buf);
int decodeGetInventoryInformationResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
InventoryPropertyId propertyId, InventoryValue& value);
int encodeGetClockLimitRequest(uint8_t instanceId, ClockType clockType,
std::span<uint8_t> buf);
int decodeGetClockLimitResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint32_t& requestedLimitMin, uint32_t& requestedLimitMax,
uint32_t& presentLimitMin, uint32_t& presentLimitMax);
int encodeSetClockLimitRequest(uint8_t instanceId, ClockType clockType,
ClockLimitFlag flag, uint32_t limitMinMHz,
uint32_t limitMaxMHz, std::span<uint8_t> buf);
int decodeSetClockLimitResponse(std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc,
uint16_t& reasonCode);
int encodeQueryScalarGroupTelemetryV1Request(
uint8_t instanceId, uint8_t deviceIndex, PcieScalarGroupId groupId,
std::span<uint8_t> buf);
int encodeGetViolationDurationRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int decodeGetViolationDurationResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint64_t& hwViolationDuration, uint64_t& globalSwViolationDuration,
uint64_t& powerViolationDuration, uint64_t& thermalViolationDuration);
// Overload for the long-running response event payload, which contains
// only the four violation duration values (no OCP/common response header).
int decodeGetViolationDurationResponse(
std::span<const uint8_t> buf, uint64_t& hwViolationDuration,
uint64_t& globalSwViolationDuration, uint64_t& powerViolationDuration,
uint64_t& thermalViolationDuration);
int encodeGetCurrentUtilizationModeRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int decodeGetCurrentUtilizationModeResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint32_t& gpuUtilization, uint32_t& memoryUtilization);
// Overload for the long-running response event payload, which contains
// only the two utilization values (no OCP/common response header).
int decodeGetCurrentUtilizationModeResponse(std::span<const uint8_t> buf,
uint32_t& gpuUtilization,
uint32_t& memoryUtilization);
int encodeGetMemoryCapacityUtilizationRequest(uint8_t instanceId,
std::span<uint8_t> buf);
int decodeGetMemoryCapacityUtilizationResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint32_t& reservedMemory, uint32_t& usedMemory);
// Overload for the long-running response event payload, which contains
// only the reserved and used memory values (no OCP/common response header).
int decodeGetMemoryCapacityUtilizationResponse(std::span<const uint8_t> buf,
uint32_t& reservedMemory,
uint32_t& usedMemory);
int decodeLongRunningResponseEvent(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint8_t& instanceId, std::span<const uint8_t>& responseData);
int encodeQueryScalarGroupTelemetryV2Request(
uint8_t instanceId, PciePortType portType, uint8_t upstreamPortNumber,
uint8_t portNumber, PcieScalarGroupId groupId, std::span<uint8_t> buf);
int decodeQueryScalarGroupTelemetryV1Response(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
size_t& numTelemetryValues, std::vector<uint32_t>& telemetryValues);
int decodeQueryScalarGroupTelemetryV2Response(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
size_t& numTelemetryValues, std::vector<uint32_t>& telemetryValues);
int encodeListPciePortsRequest(uint8_t instanceId, std::span<uint8_t> buf);
int decodeListPciePortsResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint16_t& numUpstreamPorts, std::vector<uint8_t>& numDownstreamPorts);
int encodeGetPortNetworkAddressesRequest(
uint8_t instanceId, uint16_t portNumber, std::span<uint8_t> buf);
int decodeGetPortNetworkAddressesResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
NetworkPortLinkType& linkType,
std::vector<std::pair<uint8_t, uint64_t>>& addresses);
int encodeGetEthernetPortTelemetryCountersRequest(
uint8_t instanceId, uint16_t portNumber, std::span<uint8_t> buf);
int decodeGetEthernetPortTelemetryCountersResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
std::vector<std::pair<uint8_t, uint64_t>>& telemetryValues);
int encodeGetCurrentClockFrequencyRequest(uint8_t instanceId, ClockType clockId,
std::span<uint8_t> buf);
int decodeGetCurrentClockFrequencyResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint32_t& clockFreqMHz);
int encodeGetEccErrorCountsRequest(uint8_t instanceId, std::span<uint8_t> buf);
int decodeGetEccErrorCountsResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
uint16_t& flags, uint32_t& sramCorrected, uint32_t& sramUncorrectedSecded,
uint32_t& sramUncorrectedParity, uint32_t& dramCorrected,
uint32_t& dramUncorrected);
int encodeGetEccModeRequest(uint8_t instanceId, std::span<uint8_t> buf);
int decodeGetEccModeResponse(std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc,
uint16_t& reasonCode, bool& currentEccModeEnabled,
bool& pendingEccModeEnabled);
// Overload for the long-running response event payload, which contains only
// the ECC mode flag byte (no OCP/common response header).
int decodeGetEccModeResponse(std::span<const uint8_t> buf,
bool& currentEccModeEnabled,
bool& pendingEccModeEnabled);
int encodeGetLeakDetectionInfoRequest(uint8_t instanceId,
std::span<uint8_t> buf);
struct LeakSensorData
{
uint8_t sensorId{};
uint8_t leakState{};
std::vector<uint16_t> thresholds;
uint16_t adcReadingMv{};
};
int decodeGetLeakDetectionInfoResponse(
std::span<const uint8_t> buf,
ocp::accelerator_management::CompletionCode& cc, uint16_t& reasonCode,
std::vector<LeakSensorData>& parsedSensors);
} // namespace gpu