From d19039fd7f7a6af5a8376b4e8d188edf8e150bb5 Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Sun, 26 Jun 2016 03:29:40 +0200 Subject: [PATCH] nvapi: read pascal voltage + show meminfo in -Dn also add perf stats api, unsure what it is exactly.. --- compat/nvapi/nvapi_ccminer.h | 63 +++++++++++++++++++++++----------- nvapi.cpp | 66 ++++++++++++++++++++++++++---------- nvml.cpp | 37 ++++++++++++++++---- 3 files changed, 123 insertions(+), 43 deletions(-) diff --git a/compat/nvapi/nvapi_ccminer.h b/compat/nvapi/nvapi_ccminer.h index 7b07bf7..2bad8f0 100644 --- a/compat/nvapi/nvapi_ccminer.h +++ b/compat/nvapi/nvapi_ccminer.h @@ -70,15 +70,26 @@ typedef struct { } NVAPI_GPU_THERMAL_LIMIT; #define NVAPI_GPU_THERMAL_LIMIT_VER MAKE_NVAPI_VERSION(NVAPI_GPU_THERMAL_LIMIT, 2) +// Maxwell gpu core voltage reading typedef struct { NvU32 version; NvU32 flags; - struct { - NvU32 voltage_domain; - NvU32 current_voltage; - } entries[16]; -} NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS; -#define NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS_VER MAKE_NVAPI_VERSION(NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS, 1) + NvU32 count; // unsure + NvU32 unknown; + NvU32 value_uV; + NvU32 buf1[30]; +} NVAPI_VOLT_STATUS; // 140 bytes (1-008c) +#define NVAPI_VOLT_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_VOLT_STATUS, 1) + +// Pascal gpu core voltage reading +typedef struct { + NvU32 version; + NvU32 flags; + NvU32 nul[8]; + NvU32 value_uV; + NvU32 buf1[8]; +} NVAPI_VOLTAGE_STATUS; // 76 bytes (1-004c) +#define NVAPI_VOLTAGE_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_VOLTAGE_STATUS, 1) typedef struct { NvU32 version; @@ -127,7 +138,7 @@ typedef struct { // contains the gpu/mem clocks deltas typedef struct { NvU32 version; - NvU32 mask[4]; // 80 bits mask + NvU32 mask[4]; // 80 bits mask (could be 8x 32bits) NvU32 buf0[12]; struct { NvU32 a; @@ -172,16 +183,6 @@ typedef struct { } NVAPI_VFP_CURVE; // 7208 bytes (1-1c28) #define NVAPI_VFP_CURVE_VER MAKE_NVAPI_VERSION(NVAPI_VFP_CURVE, 1) -typedef struct { - NvU32 version; - NvU32 flags; - NvU32 count; // unsure - NvU32 unknown; - NvU32 value_uV; - NvU32 buf1[30]; -} NVAPI_VOLT_STATUS; // 140 bytes (1-008c) -#define NVAPI_VOLT_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_VOLT_STATUS, 1) - typedef struct { NvU32 version; NvU32 flags; @@ -195,8 +196,32 @@ typedef struct { } NVAPI_VOLTAGES_TABLE; // 16588 bytes (1-40cc) #define NVAPI_VOLTAGES_TABLE_VER MAKE_NVAPI_VERSION(NVAPI_VOLTAGES_TABLE, 1) +typedef struct { + NvU32 version; + NvU32 val1; // 7 + NvU32 val2; // 0x3F (63.) + NvU32 pad[16]; +} NVAPI_GPU_PERF_INFO; // 76 bytes (1-004c) +#define NVAPI_GPU_PERF_INFO_VER MAKE_NVAPI_VERSION(NVAPI_GPU_PERF_INFO, 1) + +typedef struct { + NvU32 version; + NvU32 flags; // 0 + NvU64 timeRef; // increment with time + NvU64 val1; // seen 1 4 5 while mining, 16 else + NvU64 val2; // seen 7 and 3 + NvU64 values[3]; // increment with time + NvU32 pad[326]; // empty +} +NVAPI_GPU_PERF_STATUS; // 1360 bytes (1-0550) +#define NVAPI_GPU_PERF_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_GPU_PERF_STATUS, 1) + + NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string); +NvAPI_Status NvAPI_DLL_PerfPoliciesGetInfo(NvPhysicalGpuHandle, NVAPI_GPU_PERF_INFO*); // 409D9841 1-004c +NvAPI_Status NvAPI_DLL_PerfPoliciesGetStatus(NvPhysicalGpuHandle, NVAPI_GPU_PERF_STATUS*); // 3D358A0C 1-0550 + NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetInfo(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_INFO*); NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetStatus(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_STATUS*); NvAPI_Status NvAPI_DLL_ClientPowerPoliciesSetStatus(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_STATUS*); @@ -206,13 +231,13 @@ NvAPI_Status NvAPI_DLL_ClientThermalPoliciesGetInfo(NvPhysicalGpuHandle hPhysica NvAPI_Status NvAPI_DLL_ClientThermalPoliciesGetLimit(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_THERMAL_LIMIT*); NvAPI_Status NvAPI_DLL_ClientThermalPoliciesSetLimit(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_THERMAL_LIMIT*); -NvAPI_Status NvAPI_DLL_GetVoltageDomainsStatus(NvPhysicalGpuHandle hPhysicalGpu, NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS*); - // Pascal GTX only NvAPI_Status NvAPI_DLL_GetClockBoostRanges(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_CLOCKS_RANGE*); NvAPI_Status NvAPI_DLL_GetClockBoostMask(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_CLOCK_MASKS*); // 0x507B4B59 NvAPI_Status NvAPI_DLL_GetClockBoostTable(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_CLOCK_TABLE*); // 0x23F1B133 +NvAPI_Status NvAPI_DLL_SetClockBoostTable(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_CLOCK_TABLE*); // 0x0733E009 NvAPI_Status NvAPI_DLL_GetVFPCurve(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_VFP_CURVE*); // 0x21537AD4 +NvAPI_Status NvAPI_DLL_GetCurrentVoltage(NvPhysicalGpuHandle handle, NVAPI_VOLTAGE_STATUS* status); // 0x465F9BCF 1-004c // Maxwell only NvAPI_Status NvAPI_DLL_GetVoltageDomainsStatus(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_VOLT_STATUS*); // 0xC16C7E2C diff --git a/nvapi.cpp b/nvapi.cpp index e15995e..2f08120 100644 --- a/nvapi.cpp +++ b/nvapi.cpp @@ -89,6 +89,26 @@ NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string) { return (*pointer)(string); } +#define NVAPI_ID_PERF_INFO 0x409D9841 +NvAPI_Status NvAPI_DLL_PerfPoliciesGetInfo(NvPhysicalGpuHandle handle, NVAPI_GPU_PERF_INFO* pInfo) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_PERF_INFO*) = NULL; + if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; + if(!pointer) { + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_GPU_PERF_INFO*))nvidia_handle->query(NVAPI_ID_PERF_INFO); + } + return (*pointer)(handle, pInfo); +} + +#define NVAPI_ID_PERF_STATS 0x3D358A0C +NvAPI_Status NvAPI_DLL_PerfPoliciesGetStatus(NvPhysicalGpuHandle handle, NVAPI_GPU_PERF_STATUS* pStatus) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_PERF_STATUS*) = NULL; + if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; + if(!pointer) { + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_GPU_PERF_STATUS*))nvidia_handle->query(NVAPI_ID_PERF_STATS); + } + return (*pointer)(handle, pStatus); +} + #define NVAPI_ID_POWER_INFO 0x34206D86 NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetInfo(NvPhysicalGpuHandle handle, NVAPI_GPU_POWER_INFO* pInfo) { static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_INFO*) = NULL; @@ -169,16 +189,26 @@ NvAPI_Status NvAPI_DLL_GetSerialNumber(NvPhysicalGpuHandle handle, NvAPI_ShortSt return (*pointer)(handle, serial); } -#define NVAPI_ID_VDOMAINS_GET 0xC16C7E2C -NvAPI_Status NvAPI_DLL_GetVoltageDomainsStatus(NvPhysicalGpuHandle handle, NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS* status) { - static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS*) = NULL; +#define NVAPI_ID_VOLTAGE_GET 0x465F9BCF +NvAPI_Status NvAPI_DLL_GetCurrentVoltage(NvPhysicalGpuHandle handle, NVAPI_VOLTAGE_STATUS* status) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_VOLTAGE_STATUS*) = NULL; if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; if(!pointer) { - pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVIDIA_GPU_VOLTAGE_DOMAINS_STATUS*))nvidia_handle->query(NVAPI_ID_SERIALNUM_GET); + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_VOLTAGE_STATUS*))nvidia_handle->query(NVAPI_ID_VOLTAGE_GET); } return (*pointer)(handle, status); } +#define NVAPI_ID_VOLT_STATUS_GET 0xC16C7E2C +NvAPI_Status NvAPI_DLL_GetVoltageDomainsStatus(NvPhysicalGpuHandle handle, NVAPI_VOLT_STATUS* data) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_VOLT_STATUS*) = NULL; + if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; + if(!pointer) { + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_VOLT_STATUS*))nvidia_handle->query(NVAPI_ID_VOLT_STATUS_GET); + } + return (*pointer)(handle, data); +} + #define NVAPI_ID_CLK_RANGE_GET 0x64B43A6A // Pascal NvAPI_Status NvAPI_DLL_GetClockBoostRanges(NvPhysicalGpuHandle handle, NVAPI_CLOCKS_RANGE* range) { static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_CLOCKS_RANGE*) = NULL; @@ -199,34 +229,34 @@ NvAPI_Status NvAPI_DLL_GetClockBoostMask(NvPhysicalGpuHandle handle, NVAPI_CLOCK return (*pointer)(handle, range); } -#define NVAPI_ID_CLK_BOOST_TABLE 0x23F1B133 // Pascal -NvAPI_Status NvAPI_DLL_GetClockBoostTable(NvPhysicalGpuHandle handle, NVAPI_CLOCK_TABLE* range) { +#define NVAPI_ID_CLK_BOOST_TABLE_GET 0x23F1B133 // Pascal +NvAPI_Status NvAPI_DLL_GetClockBoostTable(NvPhysicalGpuHandle handle, NVAPI_CLOCK_TABLE* table) { static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_CLOCK_TABLE*) = NULL; if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; if(!pointer) { - pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_CLOCK_TABLE*))nvidia_handle->query(NVAPI_ID_CLK_BOOST_TABLE); + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_CLOCK_TABLE*))nvidia_handle->query(NVAPI_ID_CLK_BOOST_TABLE_GET); } - return (*pointer)(handle, range); + return (*pointer)(handle, table); } -#define NVAPI_ID_VFP_CURVE_GET 0x21537AD4 // Pascal 39442CFB to check also, Set ? -NvAPI_Status NvAPI_DLL_GetVFPCurve(NvPhysicalGpuHandle handle, NVAPI_VFP_CURVE* curve) { - static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_VFP_CURVE*) = NULL; +#define NVAPI_ID_CLK_BOOST_TABLE_SET 0x0733E009 // Pascal +NvAPI_Status NvAPI_DLL_SetClockBoostTable(NvPhysicalGpuHandle handle, NVAPI_CLOCK_TABLE* table) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_CLOCK_TABLE*) = NULL; if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; if(!pointer) { - pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_VFP_CURVE*))nvidia_handle->query(NVAPI_ID_VFP_CURVE_GET); + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_CLOCK_TABLE*))nvidia_handle->query(NVAPI_ID_CLK_BOOST_TABLE_SET); } - return (*pointer)(handle, curve); + return (*pointer)(handle, table); } -#define NVAPI_ID_VOLT_STATUS_GET 0xC16C7E2C -NvAPI_Status NvAPI_DLL_GetVoltageDomainsStatus(NvPhysicalGpuHandle handle, NVAPI_VOLT_STATUS* data) { - static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_VOLT_STATUS*) = NULL; +#define NVAPI_ID_VFP_CURVE_GET 0x21537AD4 // Pascal 39442CFB to check also, Set ? +NvAPI_Status NvAPI_DLL_GetVFPCurve(NvPhysicalGpuHandle handle, NVAPI_VFP_CURVE* curve) { + static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_VFP_CURVE*) = NULL; if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED; if(!pointer) { - pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_VOLT_STATUS*))nvidia_handle->query(NVAPI_ID_VOLT_STATUS_GET); + pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_VFP_CURVE*))nvidia_handle->query(NVAPI_ID_VFP_CURVE_GET); } - return (*pointer)(handle, data); + return (*pointer)(handle, curve); } #define NVAPI_ID_PERFCLOCKS_GET 0x1EA54A3B diff --git a/nvml.cpp b/nvml.cpp index 7447812..97f7ec9 100644 --- a/nvml.cpp +++ b/nvml.cpp @@ -968,12 +968,12 @@ int nvapi_pstateinfo(unsigned int devNum) uint32_t* buf = (uint32_t*) calloc(1, 0x8000); for (int i=8; i < 0x8000 && buf; i+=4) { buf[0] = 0x10000 + i; - if ((ret = NvAPI_DLL_XXX(phys[devNum], buf)) != NVAPI_INCOMPATIBLE_STRUCT_VERSION) { + if ((ret = NvAPI_DLL_GetXXX(phys[devNum], buf)) != NVAPI_INCOMPATIBLE_STRUCT_VERSION) { NvAPI_ShortString string; NvAPI_GetErrorMessage(ret, string); applog(LOG_BLUE, "struct size is %06x : %s", buf[0], string); for (int n=0; n < i/32; n++) - applog_hex(&buf[n*(32/4)], 80); + applog_hex(&buf[n*(32/4)], 32); break; } } @@ -1049,9 +1049,16 @@ int nvapi_pstateinfo(unsigned int devNum) (double) freqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency / 1000); // Maxwell only - NVAPI_VOLT_STATUS pvdom = { 0 }; - pvdom.version = NVAPI_VOLT_STATUS_VER; - if ((ret = NvAPI_DLL_GetVoltageDomainsStatus(phys[devNum], &pvdom)) == NVAPI_OK) { + NVAPI_VOLT_STATUS mvdom = { 0 }; + mvdom.version = NVAPI_VOLT_STATUS_VER; + if ((ret = NvAPI_DLL_GetVoltageDomainsStatus(phys[devNum], &mvdom)) == NVAPI_OK) { + if (mvdom.value_uV) + applog(LOG_RAW, " GPU Voltage is %u mV", mvdom.value_uV/1000); + } + // Pascal only + NVAPI_VOLTAGE_STATUS pvdom = { 0 }; + pvdom.version = NVAPI_VOLTAGE_STATUS_VER; + if ((ret = NvAPI_DLL_GetCurrentVoltage(phys[devNum], &pvdom)) == NVAPI_OK) { if (pvdom.value_uV) applog(LOG_RAW, " GPU Voltage is %u mV", pvdom.value_uV/1000); } @@ -1150,6 +1157,24 @@ int nvapi_pstateinfo(unsigned int devNum) } applog(LOG_RAW, " Volts table contains %d gpu levels.", entries); } + + NV_DISPLAY_DRIVER_MEMORY_INFO mem = { 0 }; + mem.version = NV_DISPLAY_DRIVER_MEMORY_INFO_VER; + if ((ret = NvAPI_GPU_GetMemoryInfo(phys[devNum], &mem)) == NVAPI_OK) { + applog(LOG_RAW, " Memory: %u MB, %.1f used", mem.dedicatedVideoMemory/1024, + (double) (mem.availableDedicatedVideoMemory - mem.curAvailableDedicatedVideoMemory)/1024); + } +#if 0 /* some undetermined stats */ + NVAPI_GPU_PERF_INFO pi = { 0 }; + pi.version = NVAPI_GPU_PERF_INFO_VER; + ret = NvAPI_DLL_PerfPoliciesGetInfo(phys[devNum], &pi); + + NVAPI_GPU_PERF_STATUS ps = { 0 }; + ps.version = NVAPI_GPU_PERF_STATUS_VER; + ret = NvAPI_DLL_PerfPoliciesGetStatus(phys[devNum], &ps); + applog(LOG_BLUE, "%llx %lld. %lld. %llx %llx %llx", ps.timeRef, ps.val1, ps.val2, ps.values[0], ps.values[1], ps.values[2]); +#endif + #endif return 0; } @@ -1263,7 +1288,7 @@ int nvapi_set_gpuclock(unsigned int devNum, uint32_t clock) cudaDeviceProp props = { 0 }; NvU32 busId = 0xFFFF; ret = NvAPI_GPU_GetBusId(phys[devNum], &busId); - for (int d=0; d