From 23a734cf0afb882e96041acb403d1a86190273ae Mon Sep 17 00:00:00 2001 From: moosecrap Date: Sun, 19 Jan 2025 23:27:43 -0800 Subject: [PATCH] WIP --- .gitignore | 78 +++++++++++++++++++++ decrypt-gpuinfo.c | 22 ++++++ evga-card.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++ evga-card.h | 161 +++++++++++++++++++++++++++++++++++++++++++ evga-icx.c | 21 ++++++ icx3.c | 72 ++++++++++++++++++++ icx3.h | 97 ++++++++++++++++++++++++++ makefile | 13 ++++ 8 files changed, 633 insertions(+) create mode 100644 .gitignore create mode 100644 decrypt-gpuinfo.c create mode 100644 evga-card.c create mode 100644 evga-card.h create mode 100644 evga-icx.c create mode 100644 icx3.c create mode 100644 icx3.h create mode 100644 makefile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1916085 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/decrypt-gpuinfo.c b/decrypt-gpuinfo.c new file mode 100644 index 0000000..07c2ada --- /dev/null +++ b/decrypt-gpuinfo.c @@ -0,0 +1,22 @@ +#include +#include + +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; +} \ No newline at end of file diff --git a/evga-card.c b/evga-card.c new file mode 100644 index 0000000..b4742a3 --- /dev/null +++ b/evga-card.c @@ -0,0 +1,169 @@ +#include +#include +#include + +#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); +} + + diff --git a/evga-card.h b/evga-card.h new file mode 100644 index 0000000..ba98308 --- /dev/null +++ b/evga-card.h @@ -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 }, +} \ No newline at end of file diff --git a/evga-icx.c b/evga-icx.c new file mode 100644 index 0000000..b2002ee --- /dev/null +++ b/evga-icx.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include + + +#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; + } + + } +} + \ No newline at end of file diff --git a/icx3.c b/icx3.c new file mode 100644 index 0000000..b56290e --- /dev/null +++ b/icx3.c @@ -0,0 +1,72 @@ +#include +#include +#include + +#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; idata[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; + +} diff --git a/icx3.h b/icx3.h new file mode 100644 index 0000000..3771162 --- /dev/null +++ b/icx3.h @@ -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); \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..c530f65 --- /dev/null +++ b/makefile @@ -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) + \ No newline at end of file