6 Commits
6 changed files with 48 additions and 39 deletions
+3
View File
@@ -36,6 +36,9 @@ Add the make flag `USE_NVML=1` and the it will also display the main GPU tempera
### VRAM and Hotspot temperature ### VRAM and Hotspot temperature
Add the make flag `USE_LIBPCI=1` and you can also read the VRAM and "hotspot" temperatures. These require direct memory access to the PCI device so you must run as root and also enable the kernel parameter `iomem=relaxed`. These sensors are **extremely** undocumented so I can't say anything about their accuracy. Add the make flag `USE_LIBPCI=1` and you can also read the VRAM and "hotspot" temperatures. These require direct memory access to the PCI device so you must run as root and also enable the kernel parameter `iomem=relaxed`. These sensors are **extremely** undocumented so I can't say anything about their accuracy.
### Hardware monitoring
This program can also monitor hardware sensors using the standard linux `hwmon` API. See board-sensors.h for examples of how to configure these, they must be staticlly compiled in.
## Usage ## Usage
Note that when controlling fans directly through iCX3 they will fall offline from the Nvidia driver and show as 0 RPM until you return them to automatic mode. Note that when controlling fans directly through iCX3 they will fall offline from the Nvidia driver and show as 0 RPM until you return them to automatic mode.
+14 -14
View File
@@ -20,14 +20,14 @@ static struct hwmon_sensor hwmon_sensor_info[] =
{ {
{"zenpower", "temp1", "CPU ", "CPU", "°C", 1000.0, -40.0 }, /* Tdie */ {"zenpower", "temp1", "CPU ", "CPU", "°C", 1000.0, -40.0 }, /* Tdie */
{"asusec", "temp2", "Motherboard ", "CPU", "°C", 1000.0, -40.0 }, /* CPU */ {"asusec", "temp2", "Motherboard ", "CPU", "°C", 1000.0, -40.0 }, /* CPU */
{"zenpower", "temp3", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd1 */ {"zenpower", "temp3", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd1 */
{"zenpower", "temp4", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd2 */ {"zenpower", "temp4", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd2 */
{"zenpower", "temp5", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd3 */ {"zenpower", "temp5", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd3 */
{"zenpower", "temp6", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd4 */ {"zenpower", "temp6", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd4 */
{"zenpower", "temp7", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd5 */ {"zenpower", "temp7", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd5 */
{"zenpower", "temp8", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd6 */ {"zenpower", "temp8", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd6 */
{"zenpower", "temp9", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd7 */ {"zenpower", "temp9", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd7 */
{"zenpower", "temp10", "CPU ", "CCX", "°C", 1000.0, -40.0 }, /* Tccd8 */ {"zenpower", "temp10", "CPU ", "CCD", "°C", 1000.0, -40.0 }, /* Tccd8 */
{"zen-rapl", "", "CPU ", "POW", " W", 0.0, 0.0 }, /* Zen RAPL placeholder */ {"zen-rapl", "", "CPU ", "POW", " W", 0.0, 0.0 }, /* Zen RAPL placeholder */
{"asusec", "temp1", "Motherboard ", "CHIP", "°C", 1000.0, -40.0 }, /* Chipset */ {"asusec", "temp1", "Motherboard ", "CHIP", "°C", 1000.0, -40.0 }, /* Chipset */
{"asusec", "temp5", "Motherboard ", "VRM", "°C", 1000.0, -40.0 }, /* VRM */ {"asusec", "temp5", "Motherboard ", "VRM", "°C", 1000.0, -40.0 }, /* VRM */
@@ -36,12 +36,12 @@ static struct hwmon_sensor hwmon_sensor_info[] =
{"asusec", "temp6", "Motherboard ", "H2O", "°C", 1000.0, -40.0 }, /* Water_In */ {"asusec", "temp6", "Motherboard ", "H2O", "°C", 1000.0, -40.0 }, /* Water_In */
{"asusec", "temp7", "Motherboard ", "H2O", "°C", 1000.0, -40.0 }, /* Water_Out */ {"asusec", "temp7", "Motherboard ", "H2O", "°C", 1000.0, -40.0 }, /* Water_Out */
{"nvme", "temp1", "NVMe ", "NVME", "°C", 1000.0, -40.0 }, /* NVME Composite */ {"nvme", "temp1", "NVMe ", "NVME", "°C", 1000.0, -40.0 }, /* NVME Composite */
{"nct6798", "fan2", "CPU fan", "CPU", "%", 15.0, 0.0 }, /* cpu_fan */ {"nct6798", "fan2", "CPU fan", "CPU", "%", 15.0, 0.0 }, /* cpu_fan, cpu mid */
{"asusec", "fan1", "", "CPU", "%", 15.0, 0.0 }, /* cpu_opt */ {"asusec", "fan1", "", "CPU", "%", 15.0, 0.0 }, /* cpu_opt, cpu front */
{"nct6798", "fan1", "Chassis 1", "CHA", "%", 12.0, 0.0 }, /* cha1? */ {"nct6798", "fan5", "H amp", "CHA", "%", 12.0, 0.0 }, /* h_amp, front fan */
{"nct6798", "fan3", "Chassis 2", "CHA", "%", 12.0, 0.0 }, /* cha2? */ {"nct6798", "fan3", "Chassis 2", "CHA", "%", 12.0, 0.0 }, /* cha2, top front */
{"nct6798", "fan4", "Chassis 3", "CHA", "%", 13.0, 0.0 }, /* cha3 */ {"nct6798", "fan1", "Chassis 1", "CHA", "%", 12.0, 0.0 }, /* cha1, top rear */
{"nct6798", "fan5", "H amp", "CHA", "%", 12.0, 0.0 }, /* h_amp? */ {"nct6798", "fan4", "Chassis 3", "CHA", "%", 13.0, 0.0 }, /* cha3, rear */
{"nct6798", "fan6", "AIO pump", "CHA", "%", 12.0, 0.0 }, /* aio_pump? */ {"nct6798", "fan6", "AIO pump", "CHA", "%", 12.0, 0.0 }, /* aio_pump? */
{"nct6798", "fan7", "W pump", "CHA", "%", 12.0, 0.0 }, /* w_pump+? */ {"nct6798", "fan7", "W pump", "CHA", "%", 12.0, 0.0 }, /* w_pump+? */
{"asusec", "fan2", "", "CHIP", "%", 35.0, 0.0 }, /* chipset */ {"asusec", "fan2", "", "CHIP", "%", 35.0, 0.0 }, /* chipset */
+14 -9
View File
@@ -10,9 +10,10 @@
and respond with the correct iCX3 version information */ and respond with the correct iCX3 version information */
int find_evga_gpu_i2cs(struct card_info *infos, int max_gpus, int i2c_bus) int find_evga_gpu_i2cs(struct card_info *infos, int max_gpus, int i2c_bus)
{ {
char i2c_devices_path[NAME_MAX]; char i2c_devices_path[PATH_MAX];
char device_path[NAME_MAX]; char device_path[PATH_MAX];
char dev_file[NAME_MAX]; char dev_file[PATH_MAX];
char pci_path[PATH_MAX];
char *pci_addr; char *pci_addr;
FILE *test_fd; FILE *test_fd;
@@ -55,10 +56,14 @@ int find_evga_gpu_i2cs(struct card_info *infos, int max_gpus, int i2c_bus)
continue; continue;
/* Read the PCI info for the underlying device */ /* Read the PCI info for the underlying device */
pci_vendor = read_pci_id(device_path, "/device/vendor"); strcat(device_path, "/../");
pci_device = read_pci_id(device_path, "/device/device"); if (realpath(device_path, pci_path) == NULL)
pci_subsystem_vendor = read_pci_id(device_path, "/device/subsystem_vendor"); continue;
pci_subsystem_device = read_pci_id(device_path, "/device/subsystem_device");
pci_vendor = read_pci_id(pci_path, "/vendor");
pci_device = read_pci_id(pci_path, "/device");
pci_subsystem_vendor = read_pci_id(pci_path, "/subsystem_vendor");
pci_subsystem_device = read_pci_id(pci_path, "/subsystem_device");
/* See if it's a matching device for a supported EVGA card */ /* See if it's a matching device for a supported EVGA card */
for (int i = 0; i < (sizeof(evga_pci_ids) / sizeof(struct gpu_pci_info)); i++) { for (int i = 0; i < (sizeof(evga_pci_ids) / sizeof(struct gpu_pci_info)); i++) {
@@ -97,7 +102,7 @@ int find_evga_gpu_i2cs(struct card_info *infos, int max_gpus, int i2c_bus)
unsigned short read_pci_id(char *device_path, char *field) unsigned short read_pci_id(char *device_path, char *field)
{ {
char buf[16]; char buf[16];
char file_path[NAME_MAX]; char file_path[PATH_MAX];
strcpy(file_path, device_path); strcpy(file_path, device_path);
strcat(file_path, field); strcat(file_path, field);
@@ -119,7 +124,7 @@ unsigned short read_pci_id(char *device_path, char *field)
char *read_nvidia_pci_address(char *device_path) char *read_nvidia_pci_address(char *device_path)
{ {
char file_path[NAME_MAX]; char file_path[PATH_MAX];
char *ret = calloc(16 + 1, sizeof(char)); /* assuming pci ids could look as large as 00000000:0C:00.0 */ char *ret = calloc(16 + 1, sizeof(char)); /* assuming pci ids could look as large as 00000000:0C:00.0 */
+1 -1
View File
@@ -46,7 +46,7 @@ static const char helpstring[] = "Available options:\n"
"--overwrite : Overwrite previously displayed info with --watch and --compact instead of continuously logging\n" "--overwrite : Overwrite previously displayed info with --watch and --compact instead of continuously logging\n"
"--color : Print headers in color in --compact mode for better readability\n" "--color : Print headers in color in --compact mode for better readability\n"
"--no-reasons : Do not query NVML for clock reasons (can cause stuttering)\n" "--no-reasons : Do not query NVML for clock reasons (can cause stuttering)\n"
"--board : Also print temperatures from the CPU, motherboard, and other sensors"; "--board : Also print temperatures from the CPU, motherboard, and other sensors\n";
void print_gpu_info(int gpu_num, struct card_info gpus[]); void print_gpu_info(int gpu_num, struct card_info gpus[]);
void print_board_info(struct hwmon_avail_sensor *board_sensors, int num_sensors); void print_board_info(struct hwmon_avail_sensor *board_sensors, int num_sensors);
+15 -14
View File
@@ -1,6 +1,7 @@
#ifndef ICX3_H #ifndef ICX3_H
#define ICX3_H #define ICX3_H
#include <stdint.h>
#include "evga-card.h" #include "evga-card.h"
#define ICX3_I2C_ADDR 0x2D #define ICX3_I2C_ADDR 0x2D
@@ -22,26 +23,26 @@
#define ICX3_WRITE_DISABLED 0xFE #define ICX3_WRITE_DISABLED 0xFE
struct icx3_fan_control { struct icx3_fan_control {
unsigned char length; uint8_t length;
unsigned char fanmode; uint8_t fanmode;
unsigned short rpm_offset; uint16_t rpm_offset;
unsigned char duty; uint8_t duty;
unsigned char duty_status; uint8_t duty_status;
unsigned short rpm_status; uint16_t rpm_status;
}; };
struct icx3_temp_sensors { struct icx3_temp_sensors {
unsigned char length; uint8_t length;
unsigned char data[18]; uint8_t data[18];
}; };
struct icx3_info { struct icx3_info {
unsigned char length; uint8_t length;
unsigned char reserved; uint8_t reserved;
unsigned char slave_address; uint8_t slave_address;
unsigned char product_id; uint8_t product_id;
unsigned char major_version; uint8_t major_version;
unsigned char minor_version; uint8_t minor_version;
}; };
enum icx3_product_id { enum icx3_product_id {
+1 -1
View File
@@ -36,7 +36,7 @@ void print_nvml_clock_reason(int compact, struct card_info *card)
single_reason = 0; single_reason = 0;
if (compact) if (compact)
printf("%s", clock_reason_names[i].short_name); printf("%-15s", clock_reason_names[i].short_name);
else else
printf("%s", clock_reason_names[i].long_name); printf("%s", clock_reason_names[i].long_name);
} }