This commit is contained in:
moosecrap 2025-01-19 23:27:43 -08:00
commit 23a734cf0a
8 changed files with 633 additions and 0 deletions

78
.gitignore vendored Normal file
View File

@ -0,0 +1,78 @@
evga-icx
decrypt-gpuinfo
GpuInfo.bin
GpuInfo.txt
# Created by https://www.toptal.com/developers/gitignore/api/c,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=c,linux
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# End of https://www.toptal.com/developers/gitignore/api/c,linux

22
decrypt-gpuinfo.c Normal file
View File

@ -0,0 +1,22 @@
#include <stdio.h>
#include <string.h>
int main (int argc, char **argv) {
char *key = "GpuInfo";
int keylen = strlen(key);
int c, m;
FILE *fin = fopen("GpuInfo.bin", "r");
FILE *fout = fopen("GpuInfo.txt", "w");
if (!fin || !fout) return 1;
for (int i = 0; (c = fgetc(fin)) != EOF; i++) {
m = key[i % keylen] + i;
fputc(c ^ m, fout);
}
fclose(fin);
fclose(fout);
return 0;
}

169
evga-card.c Normal file
View File

@ -0,0 +1,169 @@
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include "evga-card.h"
#include "icx3.h"
/* Search all i2c device files for ones are on a PCI device of a supported GPU,
and respond with the correct iCX3 version information */
int find_evga_gpu_i2cs(struct card_info **infos, int max_gpus)
{
char i2c_devices_path[NAME_MAX];
char device_path[NAME_MAX];
FILE *test_fd;
int num_gpus = 0;
unsigned short pci_vendor, pci_device, pci_subsystem_vendor, pci_subsystem_device = 0;
/* Start looking for I2C adapters in /sys/bus/i2c/devices/ */
strcpy(i2c_devices_path, "/sys/bus/i2c/devices/");
dir = opendir(i2c_devices_path);
/* make sure we can open the i2c device */
if(dir == NULL)
{
return -1;
}
/* loop over all i2c devices */
while((ent = readdir(dir)) != NULL)
{
/* Don't check any non-i2c devices */
if(strncmp(ent->d_name, "i2c-", 4) != 0)
continue;
strcpy(device_path, i2c_devices_path);
strcat(device_path, ent->d_name);
/* Read the PCI info for the underlying device */
pci_vendor = read_pci_id(device_path, "/vendor");
pci_device = read_pci_id(device_path, "/device");
pci_subsystem_vendor = read_pci_id(device_path, "/subsystem_vendor");
pci_subsystem_device = read_pci_id(device_path, "/subsystem_device");
/* 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++) {
if (pci_vendor == evga_pci_ids[i]->vendor_id &&
pci_device == evga_pci_ids[i]->device_id &&
pci_subsystem_vendor == evga_pci_ids[i]->subvendor_id &&
pci_subsystem_device == evga_pci_ids[i]->subdevice_id) {
/* Matched all PCI IDs, check for good firmware read */
strcpy(device_path, "/dev/");
strcat(device_path, ent->d_name);
if (check_for_icx3(device_path)) {
/* Write our card info into the provided struct array */
card_info[num_gpus]->card_name = &evga_pci_ids[i]->card_name;
card_info[num_gpus]->pci_id
card_info[num_gpus]->i2c_dev_path = calloc(strlen(device_path) + 1, sizeof(char));
strcpy(card_info[num_gpus]->i2c_dev_path, device_path);
break;
}
}
}
strcat(device_string, "/name");
if(strncmp(ent->d_name, "i2c-", 4) == 0)
{
strcpy(device_string, i2c_devices_path);
strcat(device_string, ent->d_name);
strcat(device_string, "/name");
test_fd = fopen(device_string, O_RDONLY);
if(test_fd)
{
memset(device_string, 0x00, sizeof(device_string));
if(read(test_fd, device_string, sizeof(device_string)) < 0)
{
printf("Failed to read i2c device name\n");
return -1;
}
device_string[strlen(device_string) - 1] = 0x00;
close(test_fd);
// Clear PCI Information
pci_vendor = 0;
pci_device = 0;
pci_subsystem_vendor = 0;
pci_subsystem_device = 0;
port_id = 0;
// Get port ID for NVidia GPUs
sscanf(device_string, "NVIDIA i2c adapter %hu at", &port_id);
// Get device path
strcpy(path, i2c_devices_path);
strcat(path, ent->d_name);
if(ent->d_type == DT_LNK)
{
ptr = realpath(path, NULL);
if(ptr == NULL)
continue;
strcpy(path, ptr);
strcat(path, "/..");
free(ptr);
}
else
{
strcat(path, "/device");
}
ptr = path + strlen(path);
if (pci_vendor == NVIDIA_VEN && pci_subsystem_vendor == EVGA_SUB_VEN) {
strcpy(device_string, "/dev/");
strcat(device_string, ent->d_name);
test_fd = open(device_string, O_RDWR);
if (test_fd < 0)
{
printf("Failed to open device file %s, are you root or have permissions for i2c?\n", device_string);
return -1;
} else {
} else {
printf("Bad FW version read %s\n", device_string);
}
}
}
}
}
}
}
}
unsigned short read_pci_id(char *device_path, char *field)
{
char *buf[16];
char file_path[NAME_MAX];
strcpy(file_path, device_path);
strcat(file_path, field);
FILE *fp = fopen(file_path, "r");
if (fp == NULL)
return 0;
if (fgets(buf, sizeof(buf), fp) == NULL) {
fclose(fp);
return 0;
}
fclose(fp);
return (unsigned short)strtoul(buf, NULL, 16);
}

161
evga-card.h Normal file
View File

@ -0,0 +1,161 @@
#define NVIDIA_VEN 0x10DE
#define NVIDIA_RTX3060_DEV 0x2503
#define NVIDIA_RTX3060_GA104_DEV 0x2487
#define NVIDIA_RTX3060_GA106_DEV 0x2503
#define NVIDIA_RTX3060_LHR_DEV 0x2504
#define NVIDIA_RTX3060TI_DEV 0x2486
#define NVIDIA_RTX3060TI_GDDR6X_DEV 0x24C9
#define NVIDIA_RTX3060TI_LHR_DEV 0x2489
#define NVIDIA_RTX3060TI_V1_LHR_DEV 0x2414
#define NVIDIA_RTX3070_DEV 0x2484
#define NVIDIA_RTX3070_LHR_DEV 0x2488
#define NVIDIA_RTX3070TI_DEV 0x2482
#define NVIDIA_RTX3070TI_GA102_DEV 0x2207
#define NVIDIA_RTX3080_DEV 0x2206
#define NVIDIA_RTX3080_LHR_DEV 0x2216
#define NVIDIA_RTX3080_12G_LHR_DEV 0x220A
#define NVIDIA_RTX3080TI_DEV 0x2208
#define NVIDIA_RTX3090_DEV 0x2204
#define NVIDIA_RTX3090TI_DEV 0x2203
#define EVGA_SUB_VEN 0x3842
#define EVGA_RTX3060TI_FTW3_GAMING_SUB_DEV 0x3665
#define EVGA_RTX3060TI_FTW3_ULTRA_SUB_DEV 0x3667
#define EVGA_RTX3060TI_FTW3_ULTRA_KL_SUB_DEV 0x4667
#define EVGA_RTX3070_XC3_BLACK_SUB_DEV 0x3751
#define EVGA_RTX3070_XC3_GAMING_SUB_DEV 0x3753
#define EVGA_RTX3070_XC3_ULTRA_SUB_DEV 0x3755
#define EVGA_RTX3070_XC3_ULTRA_LHR_SUB_DEV 0x4755
#define EVGA_RTX3070_XC3_ULTRA_GAMING_LHR_SUB_DEV 0x4455
#define EVGA_RTX3070_FTW3_ULTRA_SUB_DEV 0x3767
#define EVGA_RTX3070_FTW3_ULTRA_LHR_SUB_DEV 0x4767
#define EVGA_RTX3070TI_XC3_GAMING_SUB_DEV 0x3783
#define EVGA_RTX3070TI_XC3_ULTRA_SUB_DEV 0x3785
#define EVGA_RTX3070TI_XC3_ULTRA_V2_SUB_DEV 0x3485
#define EVGA_RTX3070TI_FTW3_ULTRA_SUB_DEV 0x3797
#define EVGA_RTX3070TI_FTW3_ULTRA_V2_SUB_DEV 0x3497
#define EVGA_RTX3080_XC3_BLACK_SUB_DEV 0x3881
#define EVGA_RTX3080_XC3_BLACK_LHR_SUB_DEV 0x4881
#define EVGA_RTX3080_XC3_GAMING_SUB_DEV 0x3883
#define EVGA_RTX3080_XC3_GAMING_LHR_SUB_DEV 0x4883
#define EVGA_RTX3080_XC3_ULTRA_SUB_DEV 0x3885
#define EVGA_RTX3080_XC3_ULTRA_LHR_SUB_DEV 0x4885
#define EVGA_RTX3080_XC3_ULTRA_HYBRID_SUB_DEV 0x3888
#define EVGA_RTX3080_XC3_ULTRA_HYBRID_LHR_SUB_DEV 0x4888
#define EVGA_RTX3080_XC3_ULTRA_HC_SUB_DEV 0x3889
#define EVGA_RTX3080_FTW3_GAMING_SUB_DEV 0x3895
#define EVGA_RTX3080_FTW3_ULTRA_SUB_DEV 0x3897
#define EVGA_RTX3080_FTW3_ULTRA_LHR_SUB_DEV 0x4897
#define EVGA_RTX3080_FTW3_ULTRA_LHR_V2_SUB_DEV 0x4297
#define EVGA_RTX3080_FTW3_ULTRA_HYBRID_SUB_DEV 0x3898
#define EVGA_RTX3080_FTW3_ULTRA_HYBRID_LHR_SUB_DEV 0x4898
#define EVGA_RTX3080_FTW3_ULTRA_HYBRID_GAMING_SUB_DEV 0x4878
#define EVGA_RTX3080_FTW3_ULTRA_HC_SUB_DEV 0x3899
#define EVGA_RTX3080_12G_XC3_ULTRA_SUB_DEV 0x4865
#define EVGA_RTX3080_12G_FTW3_ULTRA_SUB_DEV 0x4877
#define EVGA_RTX3080_12G_FTW3_ULTRA_HC_SUB_DEV 0x4879
#define EVGA_RTX3080TI_XC3_GAMING_SUB_DEV 0x3953
#define EVGA_RTX3080TI_XC3_ULTRA_GAMING_SUB_DEV 0x3955
#define EVGA_RTX3080TI_XC3_GAMING_HYBRID_SUB_DEV 0x3958
#define EVGA_RTX3080TI_XC3_GAMING_HC_SUB_DEV 0x3959
#define EVGA_RTX3080TI_FTW3_ULTRA_SUB_DEV 0x3967
#define EVGA_RTX3080TI_FTW3_ULTRA_HYBRID_SUB_DEV 0x3968
#define EVGA_RTX3080TI_FTW3_ULTRA_HC_SUB_DEV 0x3969
#define EVGA_RTX3090_XC3_BLACK_SUB_DEV 0x3971
#define EVGA_RTX3090_XC3_GAMING_SUB_DEV 0x3973
#define EVGA_RTX3090_XC3_ULTRA_SUB_DEV 0x3975
#define EVGA_RTX3090_XC3_ULTRA_HYBRID_SUB_DEV 0x3978
#define EVGA_RTX3090_XC3_ULTRA_HC_SUB_DEV 0x3979
#define EVGA_RTX3090_FTW3_GAMING_SUB_DEV 0x3985
#define EVGA_RTX3090_FTW3_ULTRA_SUB_DEV 0x3987
#define EVGA_RTX3090_FTW3_ULTRA_V2_SUB_DEV 0x3982
#define EVGA_RTX3090_FTW3_ULTRA_V3_SUB_DEV 0x3387
#define EVGA_RTX3090_FTW3_ULTRA_HYBRID_SUB_DEV 0x3988
#define EVGA_RTX3090_FTW3_ULTRA_HC_SUB_DEV 0x3989
#define EVGA_RTX3090_KINGPIN_HYBRID_SUB_DEV 0x3998
#define EVGA_RTX3090_KINGPIN_HC_SUB_DEV 0x3999
#define EVGA_RTX3090TI_FTW3_BLACK_SUB_DEV 0x4981
#define EVGA_RTX3090TI_FTW3_GAMING_SUB_DEV 0x4983
#define EVGA_RTX3090TI_FTW3_ULTRA_GAMING_SUB_DEV 0x4985
#define MAX_GPUS 16
int find_evga_gpu_i2cs(struct card_info **infos, int max_gpus);
unsigned short read_pci_id(char *path);
struct card_info (
char *card_name;
char *pci_id;
char *i2c_dev_path;
);
struct gpu_pci_info {
char *card_name;
unsigned short vendor_id;
unsigned short device_id;
unsigned short subvendor_id;
unsigned short subdevice_id;
};
struct gpu_pci_info evga_pci_ids[] =
{
{"EVGA GeForce RTX 3060 Ti FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3060 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3060 Ti FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_ULTRA_KL_SUB_DEV },
{"EVGA GeForce RTX 3070 Black Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_BLACK_SUB_DEV },
{"EVGA GeForce RTX 3070 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3070 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3070 XC3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_LHR_SUB_DEV },
{"EVGA GeForce RTX 3070 XC3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_GAMING_LHR_SUB_DEV },
{"EVGA GeForce RTX 3070 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3070 FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_FTW3_ULTRA_LHR_SUB_DEV },
{"EVGA GeForce RTX 3070 Ti XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3070 Ti XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3070 Ti XC3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_ULTRA_V2_SUB_DEV },
{"EVGA GeForce RTX 3070 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3070 Ti FTW3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_FTW3_ULTRA_V2_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Black" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_BLACK_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Black LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_BLACK_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Gaming LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_GAMING_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra Hybrid LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HYBRID_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra v2 LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_LHR_V2_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_LHR_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid Gaming LHR" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3080 XC3 Ultra 12G" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_XC3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra 12GB" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3080 FTW3 Ultra Hydro Copper 12G" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_FTW3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti XC3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_ULTRA_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti XC3 Gaming Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti XC3 Gaming Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_HC_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3080 Ti FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3090 XC3 Black" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_BLACK_SUB_DEV },
{"EVGA GeForce RTX 3090 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3090 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3090 XC3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3090 XC3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3090 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_SUB_DEV },
{"EVGA GeForce RTX 3090 FTW3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_V2_SUB_DEV },
{"EVGA GeForce RTX 3090 FTW3 Ultra v3" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_V3_SUB_DEV },
{"EVGA GeForce RTX 3090 FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3090 FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_HC_SUB_DEV },
{"EVGA GeForce RTX 3090 K|NGP|N Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_KINGPIN_HYBRID_SUB_DEV },
{"EVGA GeForce RTX 3090 K|NGP|N Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_KINGPIN_HC_SUB_DEV },
{"EVGA GeForce RTX 3090 Ti FTW3 Black Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_BLACK_SUB_DEV },
{"EVGA GeForce RTX 3090 Ti FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_GAMING_SUB_DEV },
{"EVGA GeForce RTX 3090 Ti FTW3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_ULTRA_GAMING_SUB_DEV },
}

21
evga-icx.c Normal file
View File

@ -0,0 +1,21 @@
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include "icx3.h"
#include "nvidia_pci.h"
int main (int argc, char **argv)
{
int *gpus[MAX_GPUS];
if (find_evga_gpu_i2c(gpus) == -1) {
return -1;
}
}
}

72
icx3.c Normal file
View File

@ -0,0 +1,72 @@
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <i2c/smbus.h>
#include "icx3.h"
void *print_icx3_temp(int fp)
{
int read_result;
char buff[1024];
struct icx3_fancontrol *fanstatus;
for (int i=0; i < ICX3_MAX_FANS; i++) {
read_result = i2c_smbus_read_i2c_block_data(fp, ICX3_REG_FANCONTROL + i, ICX3_FANCONTROL_SIZE, buff);
if (read_result != ICX3_FANCONTROL_SIZE) {
return 0;
}
fanstatus = (struct icx3_fancontrol*) &buff;
printf("%s: %d RPM (%d/%d%%, %s)\n",
icx3_fan_names[i],
fanstatus->rpm_status,
fanstatus->duty_status,
fanstatus->duty,
icx3_fan_mode_names[fanstatus->fanmode]
);
}
struct icx3_tempsensors *tempsensors;
read_result = i2c_smbus_read_i2c_block_data(fp, ICX3_REG_TEMPSENSOR, ICX3_TEMPSENSOR_SIZE, buff);
if (read_result != ICX3_TEMPSENSOR_SIZE) {
return 0;
}
tempsensors = (struct icx3_tempsensors*) &buff;
float cur_temp;
short cur_data;
for (int i=0; i<ICX3_NUM_TEMP_SENSORS; i++) {
cur_data = (short)(tempsensors->data[2*i+1] << 8) | (short)(tempsensors->data[2*i]);
cur_temp = (float)cur_data/10;
printf("%s %.1f C\n",
icx3_temp_sensor_names[i],
cur_temp);
}
}
/* Check an I2C device file for an ICX3 controller, returs the product id. */
enum icx3_product_id check_for_icx3(char *i2c_dev_path)
{
char data[I2C_SMBUS_BLOCK_MAX] = {};
int test_fd, read_result;
struct icx3_info *temp_info;
test_fd = fopen(i2c_dev_path, O_RDONLY);
if (!test_fd)
return ICX3_NONE;
if (ioctl(test_fd, I2C_SLAVE, ICX3_I2C_ADDR) < 0) {
close(test_fd);
return ICX3_NONE;
}
read_result = i2c_smbus_read_i2c_block_data(test_fd, ICX3_REG_READINFORMATION, ICX3_READINFORMATION_SIZE, buff);
if (read_result == ICX3_READINFORMATION_SIZE) {
temp_info = (struct *icx3_info)&buff;
if (temp_info->slave_address == ICX3_I2C_ADDR)
return temp_info->product_id;
}
return ICX3_NONE;
}

97
icx3.h Normal file
View File

@ -0,0 +1,97 @@
#define ICX3_I2C_ADDR 0x2D
#define ICX3_REG_FANCONTROL 80
#define ICX3_REG_TEMPSENSOR 102
#define ICX3_REG_READINFORMATION 177
#define ICX3_FANCONTROL_SIZE 0x09
#define ICX3_TEMPSENSOR_SIZE 0x13
#define ICX3_READINFORMATION_SIZE 0x06
#define ICX3_MAX_FANS 4
#define ICX3_NUM_TEMP_SENSORS 9
struct icx3_fancontrol {
unsigned char length;
unsigned char fanmode;
unsigned short rpm_offset;
unsigned char duty;
unsigned char duty_status;
unsigned short rpm_status;
};
struct icx3_tempsensors {
unsigned char length;
unsigned char data[18];
};
struct icx3_info {
unsigned char reserved;
unsigned char slave_address;
unsigned char product_id;
unsigned char major_version;
unsigned char minor_version;
};
enum icx3_product_id {
ICX3_IAP = 160,
ICX3_E227_E228_FTW3 = 2,
ICX3_E230_FTW3 = 4,
ICX3_E227_E228_FTW3_HYBRID = 8,
ICX3_E227_E228_FTW3_HC = 9,
ICX3_E221_E222_XC3 = 1,
ICX3_E229_XC3 = 5,
ICX3_E221_E222_XC3_HYBRID = 6,
ICX3_E221_E222_XC3_HC = 7,
ICX3_IAP_KINGPIN = 161,
ICX3_E223_KINGPIN_HYBRID = 3,
ICX3_E223_KINGPIN_HC = 10,
ICX3_IAP_KINGPIN_E251 = 165,
ICX3_E251_KINGPIN_HYBRID = 19,
ICX3_E251_KINGPIN_HC = 26,
ICX3_IAP_LPC5516 = 164,
ICX3_E250_FTW3 = 50,
ICX3_E250_FTW3_HYBRID = 56,
ICX3_IAP_LPC54113 = 162,
ICX3_E227_E228_FTW3_LPC54113 = 18,
ICX3_E227_E228_FTW3_HYBRID_LPC54113 = 24,
ICX3_E230_FTW3_LPC54113 = 20,
ICX3_E222_XC3_LPC54113 = 17,
ICX3_E229_XC3_LPC54113 = 21,
ICX3_IAP_STM32L431 = 163,
ICX3_E230_E238_FTW3_STM32L431 = 36,
ICX3_E221_XC3_STM32L431 = 33,
ICX3_E229_E237_XC3_STM32L431 = 37,
ICX3_NONE = 0
}
const char *icx3_fan_names[] = {
"Fan 1",
"Fan 2",
"Fan 3",
"Ext. fan"
};
const char *icx3_fan_mode_names[] = {
"Default",
"Auto",
"Manual",
"Offset",
"MCU curve",
"Mode 3"
};
const char *icx3_temp_sensor_names[] = {
"GPU2",
"MEM1",
"MEM2",
"MEM3",
"PWR1",
"PWR2",
"PWR3",
"PWR4",
"PWR5",
};
enum icx3_product_id check_for_icx3(char *i2c_dev_path);

13
makefile Normal file
View File

@ -0,0 +1,13 @@
.PHONY : clean debug
LDLIBS = -li2c
objects = evga-icx.o
evga-icx : $(objects)
debug : CFLAGS += -g -O0
debug : evga-icx
clean :
rm evga-icx $(objects)