/* * SPDX-FileCopyrightText: Copyright (c) 2022-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _cl00de_h_ #define _cl00de_h_ #ifdef __cplusplus extern "C" { #endif #include "nvmisc.h" #include "nvfixedtypes.h" #include "ctrl/ctrl2080/ctrl2080ecc.h" #define RM_USER_SHARED_DATA (0x000000de) #define RUSD_TIMESTAMP_WRITE_IN_PROGRESS (NV_U64_MAX) #define RUSD_TIMESTAMP_INVALID 0 #define RUSD_SEQ_START (0xFF00000000000000LLU) #define RUSD_SEQ_DATA_VALID(x) \ ((((x) < RUSD_SEQ_START) && ((x) != RUSD_TIMESTAMP_INVALID)) || \ (((x) >= RUSD_SEQ_START) && (((x) & 0x1LLU) == 0x0LLU))) // // Helper macros to check seq before reading RUSD. // No dowhile wrap as it is using continue/break // #define RUSD_SEQ_CHECK1(dataField) \ NvU64 RUSD_SEQ = (dataField)->lastModifiedTimestamp; \ portAtomicMemoryFenceLoad(); \ if (!RUSD_SEQ_DATA_VALID(RUSD_SEQ)) \ continue; // Clear lastModifiedTimestamp on failure in case of reaching loop limit #define RUSD_SEQ_CHECK2(dataField) \ portAtomicMemoryFenceLoad(); \ if (RUSD_SEQ == (dataField)->lastModifiedTimestamp) \ break; \ // // Read RUSD data field `dataField` from NV00DE_SHARED_DATA struct `pSharedData` into destination pointer `pDst` // `pDst` should be the data struct type matching `dataField` // Check (pDst)->lastModifiedTimestamp using RUSD_IS_DATA_STALE to verify data validity. // #define RUSD_READ_DATA(pSharedData,dataField,pDst) \ do { \ portMemSet((pDst), 0, sizeof(*pDst)); \ for (NvU32 RUSD_READ_DATA_ATTEMPTS = 0; RUSD_READ_DATA_ATTEMPTS < 10; ++RUSD_READ_DATA_ATTEMPTS) \ { \ RUSD_SEQ_CHECK1(&((pSharedData)->dataField)); \ portMemCopy((pDst), sizeof(*pDst), &((pSharedData)->dataField), sizeof(*pDst)); \ RUSD_SEQ_CHECK2(&((pSharedData)->dataField)); \ (pDst)->lastModifiedTimestamp = RUSD_TIMESTAMP_INVALID; \ } \ } while(0); // // Check if RUSD data timestamp is stale. // For polled data, returns true if data is older than `staleThreshold` // For non-polled data, returns true if data was successfully read // #define RUSD_IS_DATA_STALE(timestamp,currentTime,staleThreshold) \ ((((timestamp) < (RUSD_SEQ_START)) && /* Polled Data */ \ (((timestamp) == (RUSD_TIMESTAMP_INVALID)) || /* Invalid */ \ (((currentTime) - (timestamp)) > (staleThreshold)))) || \ (((timestamp) >= (RUSD_SEQ_START)) && /* Non-Polled Data */ \ (((timestamp) & (0x1LLU)) == 1LLU))) enum { RUSD_CLK_THROTTLE_REASON_GPU_IDLE = NVBIT(0), RUSD_CLK_THROTTLE_REASON_APPLICATION_CLOCK_SETTING = NVBIT(1), RUSD_CLK_THROTTLE_REASON_SW_POWER_CAP = NVBIT(2), RUSD_CLK_THROTTLE_REASON_HW_SLOWDOWN = NVBIT(3), RUSD_CLK_THROTTLE_REASON_SYNC_BOOST = NVBIT(4), RUSD_CLK_THROTTLE_REASON_SW_THERMAL_SLOWDOWN = NVBIT(5), RUSD_CLK_THROTTLE_REASON_HW_THERMAL_SLOWDOWN = NVBIT(6), RUSD_CLK_THROTTLE_REASON_HW_POWER_BRAKES_SLOWDOWN = NVBIT(7), RUSD_CLK_THROTTLE_REASON_DISPLAY_CLOCK_SETTING = NVBIT(8), }; typedef struct RUSD_BAR1_MEMORY_INFO { volatile NvU64 lastModifiedTimestamp; // // Non-polled data, not tied to any specific RM API // Total size and available memory in Bar1 // NvU32 bar1Size; NvU32 bar1AvailSize; } RUSD_BAR1_MEMORY_INFO; typedef struct RUSD_PMA_MEMORY_INFO { volatile NvU64 lastModifiedTimestamp; // // Non-polled data, not tied to any specific RM API // Total size and available memory in PMA // NvU64 totalPmaMemory; NvU64 freePmaMemory; } RUSD_PMA_MEMORY_INFO; enum { RUSD_CLK_PUBLIC_DOMAIN_GRAPHICS = 0, RUSD_CLK_PUBLIC_DOMAIN_MEMORY, RUSD_CLK_PUBLIC_DOMAIN_VIDEO, // Put at the end. See bug 1000230 NVML doesn't report SM frequency on Kepler RUSD_CLK_PUBLIC_DOMAIN_SM, RUSD_CLK_PUBLIC_DOMAIN_MAX_TYPE, }; typedef struct RUSD_CLK_PUBLIC_DOMAIN_INFO { NvU32 targetClkMHz; NvU32 actualClkKHz; } RUSD_CLK_PUBLIC_DOMAIN_INFO; typedef struct RUSD_CLK_PUBLIC_DOMAIN_INFOS { volatile NvU64 lastModifiedTimestamp; RUSD_CLK_PUBLIC_DOMAIN_INFO info[RUSD_CLK_PUBLIC_DOMAIN_MAX_TYPE]; } RUSD_CLK_PUBLIC_DOMAIN_INFOS; typedef struct RUSD_ENG_UTILIZATION { NvU32 clkPercentBusy; NvU32 samplingPeriodUs; } RUSD_ENG_UTILIZATION; #define RUSD_ENG_UTILIZATION_VID_ENG_NVENC 0 #define RUSD_ENG_UTILIZATION_VID_ENG_NVDEC 1 #define RUSD_ENG_UTILIZATION_VID_ENG_NVJPG 2 #define RUSD_ENG_UTILIZATION_VID_ENG_NVOFA 3 #define RUSD_ENG_UTILIZATION_COUNT 4 typedef struct RUSD_PERF_DEVICE_UTILIZATION_INFO { NvU32 gpuPercentBusy; NvU32 memoryPercentBusy; RUSD_ENG_UTILIZATION engUtil[RUSD_ENG_UTILIZATION_COUNT]; } RUSD_PERF_DEVICE_UTILIZATION_INFO; typedef struct RUSD_PERF_DEVICE_UTILIZATION { volatile NvU64 lastModifiedTimestamp; RUSD_PERF_DEVICE_UTILIZATION_INFO info; } RUSD_PERF_DEVICE_UTILIZATION; typedef struct RUSD_PERF_CURRENT_PSTATE { volatile NvU64 lastModifiedTimestamp; // Provided from NV2080_CTRL_CMD_PERF_GET_CURRENT_PSTATE NvU32 currentPstate; } RUSD_PERF_CURRENT_PSTATE; #define RUSD_CLK_VIOLATION_NUM 32 #define RUSD_PERF_POINT_MAX_CLOCK 0 #define RUSD_PERF_POINT_TURBO_BOOST 1 #define RUSD_PERF_POINT_3D_BOOST 2 #define RUSD_PERF_POINT_RATED_TDP 3 #define RUSD_PERF_POINT_MAX_CUSTOMER_BOOST 4 #define RUSD_PERF_POINT_DISPLAY_CLOCK_INTERSECT 5 #define RUSD_PERF_POINT_NUM 6 typedef struct RUSD_CLK_VIOLATION_STATUS { NvU32 perfPointMask; NvU64 timeNs[RUSD_PERF_POINT_NUM]; } RUSD_CLK_VIOLATION_STATUS; typedef struct RUSD_CLK_THROTTLE_INFO { volatile NvU64 lastModifiedTimestamp; NvU32 reasonMask; // Bitmask of RUSD_CLK_THROTTLE_REASON_* NvU64 referenceTimeNs; NvU32 supportedViolationTimeMask; RUSD_CLK_VIOLATION_STATUS violation[RUSD_CLK_VIOLATION_NUM]; RUSD_CLK_VIOLATION_STATUS globalViolation; } RUSD_CLK_THROTTLE_INFO; typedef struct RUSD_CLK_THROTTLE_INFO RUSD_CLK_THROTTLE_REASON; typedef struct RUSD_MEM_ERROR_COUNTS { NvU64 correctedVolatile; NvU64 correctedAggregate; NvU64 uncorrectedVolatile; NvU64 uncorrectedAggregate; } RUSD_MEM_ERROR_COUNTS; #define RUSD_MEMORY_ERROR_TYPE_TOTAL 0 #define RUSD_MEMORY_ERROR_TYPE_DRAM 1 #define RUSD_MEMORY_ERROR_TYPE_SRAM 2 #define RUSD_MEMORY_ERROR_TYPE_COUNT 3 typedef struct RUSD_ECC_COUNTS { NV2080_CTRL_ECC_GET_VOLATILE_COUNTS_PARAMS volatileCounts; NV2080_CTRL_ECC_GET_CLIENT_EXPOSED_COUNTERS_PARAMS clientExposedCounts; } RUSD_ECC_INFO; typedef struct RUSD_MEM_ECC { volatile NvU64 lastModifiedTimestamp; RUSD_MEM_ERROR_COUNTS count[RUSD_MEMORY_ERROR_TYPE_COUNT]; // TODO: Due to incapability of getting voteup for X driver update with // existing RM APIs, need to resolve bug 5138911 before fully updating // RUSD_MEM_ECC and removing deprecated RUSD_MEM_ERROR_COUNTS. RUSD_ECC_INFO info; } RUSD_MEM_ECC; typedef struct RUSD_POWER_LIMIT_INFO { NvU32 requestedmW; NvU32 enforcedmW; } RUSD_POWER_LIMIT_INFO; typedef struct RUSD_POWER_LIMITS { volatile NvU64 lastModifiedTimestamp; RUSD_POWER_LIMIT_INFO info; } RUSD_POWER_LIMITS; typedef enum RUSD_TEMPERATURE_SENSOR { RUSD_TEMPERATURE_SENSOR_GPU, RUSD_TEMPERATURE_SENSOR_MEMORY, RUSD_TEMPERATURE_SENSOR_BOARD, RUSD_TEMPERATURE_SENSOR_POWER_SUPPLY, // Should always be last entry RUSD_TEMPERATURE_SENSOR_MAX } RUSD_TEMPERATURE_SENSOR; typedef enum RUSD_TEMPERATURE_TYPE { RUSD_TEMPERATURE_TYPE_GPU, RUSD_TEMPERATURE_TYPE_MEMORY, RUSD_TEMPERATURE_TYPE_BOARD, RUSD_TEMPERATURE_TYPE_POWER_SUPPLY, RUSD_TEMPERATURE_TYPE_HBM, RUSD_TEMPERATURE_TYPE_MAX } RUSD_TEMPERATURE_TYPE; typedef struct RUSD_TEMPERATURE { volatile NvU64 lastModifiedTimestamp; NvTemp temperature; } RUSD_TEMPERATURE; typedef struct RUSD_MEM_ROW_REMAP_INFO { // Provided from NV2080_CTRL_CMD_FB_GET_ROW_REMAPPER_HISTOGRAM NvU32 histogramMax; // No remapped row is used. NvU32 histogramHigh; // One remapped row is used. NvU32 histogramPartial; // More than one remapped rows are used. NvU32 histogramLow; // One remapped row is available. NvU32 histogramNone; // All remapped rows are used. NvU32 correctableRows; NvU32 uncorrectableRows; NvU32 correctableRowsInactive; NvU32 uncorrectableRowsInactive; NvBool isPending; NvBool hasFailureOccurred; } RUSD_MEM_ROW_REMAP_INFO; typedef struct RUSD_MEM_ROW_REMAP { volatile NvU64 lastModifiedTimestamp; RUSD_MEM_ROW_REMAP_INFO info; } RUSD_MEM_ROW_REMAP; typedef struct RUSD_AVG_POWER_INFO { NvU32 averageGpuPower; // mW NvU32 averageModulePower; // mW NvU32 averageMemoryPower; // mW } RUSD_AVG_POWER_INFO; typedef struct RUSD_AVG_POWER_USAGE { volatile NvU64 lastModifiedTimestamp; RUSD_AVG_POWER_INFO info; } RUSD_AVG_POWER_USAGE; typedef struct RUSD_INST_POWER_INFO { NvU32 instGpuPower; // mW NvU32 instModulePower; // mW NvU32 instCpuPower; // mW } RUSD_INST_POWER_INFO; typedef struct RUSD_INST_POWER_USAGE { volatile NvU64 lastModifiedTimestamp; RUSD_INST_POWER_INFO info; } RUSD_INST_POWER_USAGE; typedef struct RUSD_POWER_POLICY_STATUS_INFO { NvU32 tgpmW; // Total GPU power in mW } RUSD_POWER_POLICY_STATUS_INFO; typedef struct RUSD_POWER_POLICY_STATUS { volatile NvU64 lastModifiedTimestamp; RUSD_POWER_POLICY_STATUS_INFO info; } RUSD_POWER_POLICY_STATUS; #define RUSD_FAN_COOLER_MAX_COOLERS 16U typedef struct RUSD_FAN_COOLER_INFO { NvU32 rpmCurr[RUSD_FAN_COOLER_MAX_COOLERS]; } RUSD_FAN_COOLER_INFO; typedef struct RUSD_FAN_COOLER_STATUS { volatile NvU64 lastModifiedTimestamp; RUSD_FAN_COOLER_INFO info; } RUSD_FAN_COOLER_STATUS; typedef struct RUSD_SHADOW_ERR_CONT { volatile NvU64 lastModifiedTimestamp; // // Non-polled data, not tied to any specific RM API // Shadowed ERR_CONT register value // NvU32 shadowErrContVal; } RUSD_SHADOW_ERR_CONT; // Each RUSD_BUS_DATA_* define corresponds to the equivalent NV2080_CTRL_BUS_INFO_INDEX_* #define RUSD_BUS_DATA_PCIE_GEN_INFO 0 #define RUSD_BUS_DATA_PCIE_GPU_LINK_LINECODE_ERRORS 1 #define RUSD_BUS_DATA_PCIE_GPU_LINK_CRC_ERRORS 2 #define RUSD_BUS_DATA_PCIE_GPU_LINK_NAKS_RECEIVED 3 #define RUSD_BUS_DATA_PCIE_GPU_LINK_FAILED_L0S_EXITS 4 #define RUSD_BUS_DATA_PCIE_GPU_LINK_CORRECTABLE_ERRORS 5 #define RUSD_BUS_DATA_PCIE_GPU_LINK_NONFATAL_ERRORS 6 #define RUSD_BUS_DATA_PCIE_GPU_LINK_FATAL_ERRORS 7 #define RUSD_BUS_DATA_PCIE_GPU_LINK_UNSUPPORTED_REQUESTS 8 #define RUSD_BUS_DATA_COUNT 9 typedef struct RUSD_PCIE_DATA_INFO { // Provided from NV2080_CTRL_CMD_BUS_GET_INFO_V2 NvU32 data[RUSD_BUS_DATA_COUNT]; } RUSD_PCIE_DATA_INFO; typedef struct RUSD_PCIE_DATA { volatile NvU64 lastModifiedTimestamp; RUSD_PCIE_DATA_INFO info; } RUSD_PCIE_DATA; typedef struct RUSD_GR_INFO { volatile NvU64 lastModifiedTimestamp; NvBool bCtxswLoggingEnabled; } RUSD_GR_INFO; #define RUSD_PROC_UTIL_SAMPLE_COUNT 5 // // RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE is NV2080_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE // without subProcessName and pOsPidInfo // typedef struct { /*! * Percentage during the sample that the engine remains busy. This * is in units of pct*100. */ NvU32 util; /*! * Scaling factor to convert utilization from full GPU to per vGPU. */ NvU32 vgpuScale; /*! * Process ID of the process that was active on the engine when the * sample was taken. If no process is active then NV2080_GPUMON_PID_INVALID * will be returned. */ NvU32 procId; /*! * Process ID of the process in the vGPU VM that was active on the engine when * the sample was taken. If no process is active then NV2080_GPUMON_PID_INVALID * will be returned. */ NvU32 subProcessID; } RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE; typedef struct { NvU64 timeStamp; // Original is NV2080_CTRL_GPUMON_SAMPLE /*! * FB bandwidth utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE fb; /*! * GR utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE gr; /*! * NV ENCODER utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE nvenc; /*! * NV DECODER utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE nvdec; /*! * NV JPEG utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE nvjpg; /*! * NV OFA utilization sample. */ RUSD_CTRL_PERF_GPUMON_ENGINE_UTIL_SAMPLE nvofa; } RUSD_CTRL_PERF_GPUMON_PERFMON_UTIL_SAMPLE; typedef struct { RUSD_CTRL_PERF_GPUMON_PERFMON_UTIL_SAMPLE samples[RUSD_PROC_UTIL_SAMPLE_COUNT]; } RUSD_PROC_UTIL_INFO; typedef struct { volatile NvU64 lastModifiedTimestamp; RUSD_PROC_UTIL_INFO info; } RUSD_PROC_UTIL; typedef struct NV00DE_SHARED_DATA { NV_DECLARE_ALIGNED(RUSD_BAR1_MEMORY_INFO bar1MemoryInfo, 8); NV_DECLARE_ALIGNED(RUSD_PMA_MEMORY_INFO pmaMemoryInfo, 8); NV_DECLARE_ALIGNED(RUSD_SHADOW_ERR_CONT shadowErrCont, 8); NV_DECLARE_ALIGNED(RUSD_GR_INFO grInfo, 8); // gpuUpdateUserSharedData is sensitive to these two sections being contiguous // // Polled data section // All data structs are a volatile NvU64 timestamp followed by data contents. // Access by reading timestamp, then copying the struct contents, then reading the timestamp again. // If time0 matches time1, data has not changed during the read, and contents are valid. // If timestamp is RUSD_TIMESTAMP_WRITE_IN_PROGRESS, data was edited during the read, retry. // If timestamp is RUSD_TIMESTAMP_INVALID, data is not available or not supported on this platform. // // POLL_CLOCK NV_DECLARE_ALIGNED(RUSD_CLK_PUBLIC_DOMAIN_INFOS clkPublicDomainInfos, 8); // POLL_PERF NV_DECLARE_ALIGNED(RUSD_CLK_THROTTLE_INFO clkThrottleInfo, 8); // POLL_PERF NV_DECLARE_ALIGNED(RUSD_PERF_DEVICE_UTILIZATION perfDevUtil, 8); // POLL_MEMORY NV_DECLARE_ALIGNED(RUSD_MEM_ECC memEcc, 8); // POLL_PERF NV_DECLARE_ALIGNED(RUSD_PERF_CURRENT_PSTATE perfCurrentPstate, 8); // POLL_POWER // Module Limit is not supported on Ampere/Hopper NV_DECLARE_ALIGNED(RUSD_POWER_LIMITS powerLimitGpu, 8); // POLL_THERMAL NV_DECLARE_ALIGNED(RUSD_TEMPERATURE temperatures[RUSD_TEMPERATURE_TYPE_MAX], 8); // POLL_MEMORY NV_DECLARE_ALIGNED(RUSD_MEM_ROW_REMAP memRowRemap, 8); // POLL_POWER NV_DECLARE_ALIGNED(RUSD_AVG_POWER_USAGE avgPowerUsage, 8); // POLL_POWER NV_DECLARE_ALIGNED(RUSD_INST_POWER_USAGE instPowerUsage, 8); // POLL_POWER NV_DECLARE_ALIGNED(RUSD_POWER_POLICY_STATUS powerPolicyStatus, 8); // POLL_PCI NV_DECLARE_ALIGNED(RUSD_PCIE_DATA pciBusData, 8); // POLL_FAN NV_DECLARE_ALIGNED(RUSD_FAN_COOLER_STATUS fanCoolerStatus, 8); // POLL_PROC_UTIL NV_DECLARE_ALIGNED(RUSD_PROC_UTIL procUtil, 8); } NV00DE_SHARED_DATA; // // Polling mask bits, pass into ALLOC_PARAMETERS or NV00DE_CTRL_REQEUSET_DATA_POLL // to request above polled data to be provided // #define NV00DE_RUSD_POLL_CLOCK 0x1 #define NV00DE_RUSD_POLL_PERF 0x2 #define NV00DE_RUSD_POLL_MEMORY 0x4 #define NV00DE_RUSD_POLL_POWER 0x8 #define NV00DE_RUSD_POLL_THERMAL 0x10 #define NV00DE_RUSD_POLL_PCI 0x20 #define NV00DE_RUSD_POLL_FAN 0x40 #define NV00DE_RUSD_POLL_PROC_UTIL 0x80 typedef struct NV00DE_ALLOC_PARAMETERS { NvU64 polledDataMask; // Bitmask of data to request polling at alloc time, 0 if not needed } NV00DE_ALLOC_PARAMETERS; #ifdef __cplusplus }; /* extern "C" */ #endif #endif /* _cl00de_h_ */