From 3b316bdd3f71e4eade372e2e2b446ff1a0cf2b37 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 1 Sep 2022 17:14:50 +0200 Subject: [PATCH] Refactor pci code --- presets/verbose | 2 +- src/detection/temps.c | 4 +- src/detection/temps.h | 2 +- src/detection/vulkan.c | 4 +- src/detection/vulkan.h | 4 +- src/fastfetch.c | 4 +- src/modules/cpu.c | 6 +- src/modules/gpu.c | 271 +++++++++++++++++++++++------------------ 8 files changed, 164 insertions(+), 133 deletions(-) diff --git a/presets/verbose b/presets/verbose index 4ac51c653..ff116bc0b 100644 --- a/presets/verbose +++ b/presets/verbose @@ -19,7 +19,7 @@ --terminal-font-format "Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}" --cpu-format "Name: {}; Pretty: {}; Vendor: {}; Logical online: {}; Logical configured: {}; Physical: {}; Cores: {}; temperature: {}; bios: {}; scaling max: {}; scaling min: {}; info max: {}; info min: {}; cpuinfo: {}; frequency: {}" --cpu-usage-format "Percentage: {}" ---gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}; Temperature: {}" +--gpu-format "Vendor: {}; Name: {}; Driver: {}; Temperature: {}" --memory-format "Percentage: {}; Used KiB: {}, Total KiB: {}, Used MiB: {}, Total MiB: {}, Used GiB: {}, Total GiB: {}" --disk-format "Used: {}; Total: {}; Files: {}; Percentage: {}" --battery-format "Manufactor: {}; Model: {}; Technology: {}; Capacaty: {}; Status: {}" diff --git a/src/detection/temps.c b/src/detection/temps.c index 3f5bc47d5..d31198e48 100644 --- a/src/detection/temps.c +++ b/src/detection/temps.c @@ -63,10 +63,8 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) return value->name.length > 0 || value->deviceClass.length > 0; } -const FFTempsResult* ffDetectTemps(const FFinstance* instance) +const FFTempsResult* ffDetectTemps() { - FF_UNUSED(instance) - static FFTempsResult result; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static bool init = false; diff --git a/src/detection/temps.h b/src/detection/temps.h index 3f923b0ff..5866843c2 100644 --- a/src/detection/temps.h +++ b/src/detection/temps.h @@ -17,6 +17,6 @@ typedef struct FFTempsResult FFlist values; //List of FFTempValue } FFTempsResult; -const FFTempsResult* ffDetectTemps(const FFinstance* instance); +const FFTempsResult* ffDetectTemps(); #endif diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 1c61ee30b..4eb49f4c7 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -177,10 +177,10 @@ static void detectVulkan(const FFinstance* instance, FFVulkanResult* result) FFGPUResult* gpu = ffListAdd(&result->devices); ffStrbufInit(&gpu->vendor); - ffStrbufInit(&gpu->name); + ffStrbufInit(&gpu->device); ffStrbufInit(&gpu->driver); gpu->temperature = 0.0 / 0.0; //NaN, no way to detect temperature using vulkan - ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName); + ffStrbufAppendS(&gpu->device, physicalDeviceProperties.properties.deviceName); } //If the highest device version is lower than the instance version, use it as our vulkan version diff --git a/src/detection/vulkan.h b/src/detection/vulkan.h index e4a9a4889..ebc0c7eba 100644 --- a/src/detection/vulkan.h +++ b/src/detection/vulkan.h @@ -5,10 +5,12 @@ #include "fastfetch.h" +#define FF_GPU_TEMP_UNSET (0/0.0) + typedef struct FFGPUResult { FFstrbuf vendor; - FFstrbuf name; + FFstrbuf device; FFstrbuf driver; double temperature; } FFGPUResult; diff --git a/src/fastfetch.c b/src/fastfetch.c index e95436257..f6a274672 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -273,11 +273,9 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "gpu-format") == 0) { - constructAndPrintCommandHelpFormat("gpu", "{2} {4}", 6, + constructAndPrintCommandHelpFormat("gpu", "{} {}", 4, "GPU vendor", - "GPU vendor pretty", "GPU name", - "GPU name pretty", "GPU driver", "GPU temperature" ); diff --git a/src/modules/cpu.c b/src/modules/cpu.c index e237484d2..f4fc2060a 100644 --- a/src/modules/cpu.c +++ b/src/modules/cpu.c @@ -31,9 +31,9 @@ static double getGhz(const char* policyFile, const char* cpuFile) return herz / 1000.0; //to GHz } -static double detectCPUTemp(const FFinstance* instance) +static double detectCPUTemp() { - const FFTempsResult *temps = ffDetectTemps(instance); + const FFTempsResult *temps = ffDetectTemps(); for(uint32_t i = 0; i < temps->values.length; i++) { @@ -166,7 +166,7 @@ void ffPrintCPU(FFinstance* instance) double cpuTemp; if(instance->config.cpu.outputFormat.length > 0) - cpuTemp = detectCPUTemp(instance); + cpuTemp = detectCPUTemp(); FFstrbuf cpu; ffStrbufInitA(&cpu, 128); diff --git a/src/modules/gpu.c b/src/modules/gpu.c index 932e23b58..c9f016ee9 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -9,54 +9,33 @@ #include #define FF_GPU_MODULE_NAME "GPU" -#define FF_GPU_NUM_FORMAT_ARGS 6 +#define FF_GPU_NUM_FORMAT_ARGS 4 -#define FF_PCI_VENDOR_AMD "Advanced Micro Devices, Inc. [AMD/ATI]" -#define FF_PCI_VENDOR_NVIDIA "NVIDIA Corporation" -#define FF_PCI_VENDOR_INTEL "Intel Corporation" +#define FF_PCI_VENDOR_NAME_AMD "AMD" +#define FF_PCI_VENDOR_NAME_INTEL "Intel" +#define FF_PCI_VENDOR_NAME_NVIDIA "NVIDIA" static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* result) { - const char* vendorPretty; - if(ffStrbufIgnCaseCompS(&result->vendor, FF_PCI_VENDOR_AMD) == 0) - vendorPretty = "AMD/ATI"; - else if(ffStrbufIgnCaseCompS(&result->vendor, FF_PCI_VENDOR_NVIDIA) == 0) - vendorPretty = "Nvidia"; - else if(ffStrbufIgnCaseCompS(&result->vendor, FF_PCI_VENDOR_INTEL) == 0) - vendorPretty = "Intel"; - else - vendorPretty = result->vendor.chars; - - FFstrbuf namePretty; - ffStrbufInitCopy(&namePretty, &result->name); - ffStrbufSubstrBeforeLastC(&namePretty, ']'); - ffStrbufSubstrAfterFirstC(&namePretty, '['); - FFstrbuf gpu; - ffStrbufInitA(&gpu, result->vendor.length + 1 + namePretty.length); + ffStrbufInitA(&gpu, result->vendor.length + 1 + result->device.length); - if(ffStrSet(vendorPretty)) + if(result->vendor.length > 0) { - ffStrbufAppendS(&gpu, vendorPretty); + ffStrbufAppend(&gpu, &result->vendor); ffStrbufAppendC(&gpu, ' '); } - ffStrbufAppend(&gpu, &namePretty); + ffStrbufAppend(&gpu, &result->device); ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, cache, &gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor}, - {FF_FORMAT_ARG_TYPE_STRING, vendorPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->device}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->driver}, {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature} }); - ffStrbufDestroy(&result->vendor); - ffStrbufDestroy(&result->name); - ffStrbufDestroy(&result->driver); ffStrbufDestroy(&gpu); - ffStrbufDestroy(&namePretty); } static void printGPUList(FFinstance* instance, const FFlist* list) @@ -76,35 +55,107 @@ static void printGPUList(FFinstance* instance, const FFlist* list) #include #include -//see https://github.com/pciutils/pciutils/blob/5bdf63b6b1bc35b59c4b3f47f7ca83ca1868155b/ls-kernel.c#L220 -static void pciGetDriver(struct pci_dev* dev, FFstrbuf* driver, char*(*ffpci_get_param)(struct pci_access*, char*)) +typedef struct PCIData { - if(dev->access->method != PCI_ACCESS_SYS_BUS_PCI) + struct pci_access* access; + FF_LIBRARY_SYMBOL(pci_read_byte); + FF_LIBRARY_SYMBOL(pci_read_word); + FF_LIBRARY_SYMBOL(pci_lookup_name); + FF_LIBRARY_SYMBOL(pci_get_param); +} PCIData; + +static bool pciIDsContains(u16 searched, const u16* ids) +{ + while(*ids != 0) + { + if(*ids == searched) + return true; + ids++; + } + return false; +} + +static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + if(pciIDsContains(device->vendor_id, (const u16[]) {0x1002, 0x1022, 0})) + ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD); + else if(pciIDsContains(device->vendor_id, (const u16[]) {0x03e7, 0x8086, 0x8087, 0})) + ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_INTEL); + else if(pciIDsContains(device->vendor_id, (const u16[]) {0x0955, 0x10de, 0x12d2, 0})) + ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_NVIDIA); + + if(gpu->vendor.length > 0) return; - const char* base = ffpci_get_param(dev->access, "sysfs.path"); + pci->ffpci_lookup_name(pci->access, gpu->vendor.chars, (int) ffStrbufGetFree(&gpu->vendor), PCI_LOOKUP_VENDOR, device->vendor_id); + ffStrbufRecalculateLength(&gpu->vendor); + + if(ffStrbufFirstIndexS(&gpu->vendor, "AMD") < gpu->vendor.length || ffStrbufFirstIndexS(&gpu->vendor, "ATI") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD); + else if(ffStrbufFirstIndexS(&gpu->vendor, "Intel") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_INTEL); + else if(ffStrbufFirstIndexS(&gpu->vendor, "NVIDIA") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_NVIDIA); +} + +static void drmDetectDeviceName(FFGPUResult* gpu, struct pci_dev* device) +{ + FFstrbuf query; + ffStrbufInit(&query); + ffStrbufAppendF(&query, "%X, %X,", device->device_id, device->rev_id); + + ffParsePropFile("/usr/share/libdrm/amdgpu.ids", query.chars, &gpu->device); + + ffStrbufDestroy(&query); + + if(ffStrbufStartsWithIgnCaseS(&gpu->device, "AMD ") || ffStrbufStartsWithIgnCaseS(&gpu->device, "ATI ")) + ffStrbufSubstrAfter(&gpu->device, 3); + + const char* removeStrings[] = { + " (TM)", "(TM)", + " Graphics Adapter", " Graphics", " Series", " Edition" + }; + ffStrbufRemoveStringsA(&gpu->device, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); +} + +static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + if(ffStrbufCompS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD) == 0) + { + drmDetectDeviceName(gpu, device); + if(gpu->device.length > 0) + return; + } + + pci->ffpci_lookup_name(pci->access, gpu->device.chars, (int) ffStrbufGetFree(&gpu->device), PCI_LOOKUP_DEVICE, device->vendor_id, device->device_id); + ffStrbufRecalculateLength(&gpu->device); +} + +static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + const char* base = pci->ffpci_get_param(pci->access, "sysfs.path"); if(!ffStrSet(base)) return; FFstrbuf path; ffStrbufInitA(&path, 64); - ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, dev->domain, dev->bus, dev->dev, dev->func); + ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); - ffStrbufEnsureFree(driver, 1023); - ssize_t resultLength = readlink(path.chars, driver->chars, driver->allocated - 1); //-1 for null terminator + ffStrbufEnsureFree(&gpu->driver, 1023); + ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator if(resultLength > 0) { - driver->length = (uint32_t) resultLength; - driver->chars[resultLength] = '\0'; - ffStrbufSubstrAfterLastC(driver, '/'); + gpu->driver.length = (uint32_t) resultLength; + gpu->driver.chars[resultLength] = '\0'; + ffStrbufSubstrAfterLastC(&gpu->driver, '/'); } ffStrbufDestroy(&path); } -static double pciGetTemperatur(const FFinstance* instance, uint16_t deviceClass) +static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) { - const FFTempsResult* tempsResult = ffDetectTemps(instance); + const FFTempsResult* tempsResult = ffDetectTemps(); for(uint32_t i = 0; i < tempsResult->values.length; i++) { @@ -115,108 +166,90 @@ static double pciGetTemperatur(const FFinstance* instance, uint16_t deviceClass) continue; //The kernel exposes the device class multiplied by 256 for some reason - if(tempClass == deviceClass * 256) - return tempValue->value; + if(tempClass == device->device_class * 256) + { + gpu->temperature = tempValue->value; + return; + } } - - return 0.0 / 0.0; //NaN } -static void getAMDfromDRM(FFGPUResult* result, struct pci_dev* dev, u8(*ffpci_read_byte)(struct pci_dev*, int)) +static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* device) { - //Older versions don't support PCI_FILL_CLASS_EXT - u8 revision = ffpci_read_byte(dev, PCI_REVISION_ID); + device->device_class = pci->ffpci_read_word(device, PCI_CLASS_DEVICE); - FFstrbuf query; - ffStrbufInit(&query); - ffStrbufAppendF(&query, "%X, %X,", dev->device_id, revision); + char class[1024]; + pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class); - ffParsePropFile("/usr/share/libdrm/amdgpu.ids", query.chars, &result->name); + if( + strcasecmp("VGA compatible controller", class) != 0 && + strcasecmp("3D controller", class) != 0 && + strcasecmp("Display controller", class) != 0 + ) return; - if(ffStrbufStartsWithIgnCaseS(&result->name, "AMD ") || ffStrbufStartsWithIgnCaseS(&result->name, "ATI ")) - ffStrbufSubstrAfter(&result->name, 3); + device->vendor_id = pci->ffpci_read_word(device, PCI_VENDOR_ID); + device->device_id = pci->ffpci_read_word(device, PCI_DEVICE_ID); + device->rev_id = pci->ffpci_read_byte(device, PCI_REVISION_ID); - const char* removeStrings[] = { - " (TM)", "(TM)", - " Graphics Adapter", " Graphics", " Series", " Edition" - }; - ffStrbufRemoveStringsA(&result->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); + FFGPUResult* gpu = ffListAdd(results); - ffStrbufDestroy(&query); + ffStrbufInit(&gpu->vendor); + pciDetectVendorName(gpu, pci, device); + + ffStrbufInit(&gpu->device); + pciDetectDeviceName(gpu, pci, device); + + ffStrbufInit(&gpu->driver); + pciDetectDriverName(gpu, pci, device); + + gpu->temperature = FF_GPU_TEMP_UNSET; + pciDetectTemperatur(gpu, device); } static bool pciPrintGPUs(FFinstance* instance) { - FF_LIBRARY_LOAD(pci, instance->config.libPCI, false, "libpci.so", 4) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_alloc, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_init, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_scan_bus, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_fill_info, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_lookup_name, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_get_param, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_read_byte, false) - FF_LIBRARY_LOAD_SYMBOL(pci, pci_cleanup, false) + PCIData pci; + + FF_LIBRARY_LOAD(libpci, instance->config.libPCI, false, "libpci.so", 4) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, false) + + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_byte, pci_read_byte, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_word, pci_read_word, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_lookup_name, pci_lookup_name, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_get_param, pci_get_param, false) FFlist results; ffListInit(&results, sizeof(FFGPUResult)); - struct pci_access *pacc = ffpci_alloc(); - ffpci_init(pacc); - ffpci_scan_bus(pacc); + pci.access = ffpci_alloc(); + ffpci_init(pci.access); + ffpci_scan_bus(pci.access); - struct pci_dev* dev; - for (dev=pacc->devices; dev; dev=dev->next) + struct pci_dev* device = pci.access->devices; + while(device != NULL) { - ffpci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS); - char class[1024]; - ffpci_lookup_name(pacc, class, sizeof(class), PCI_LOOKUP_CLASS, dev->device_class); - if( - strcasecmp("VGA compatible controller", class) == 0 || - strcasecmp("3D controller", class) == 0 || - strcasecmp("Display controller", class) == 0 - ) { - FFGPUResult* result = ffListAdd(&results); - - //Vendor - ffStrbufInitA(&result->vendor, 256); - ffpci_lookup_name(pacc, result->vendor.chars, (int) ffStrbufGetFree(&result->vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id); - ffStrbufRecalculateLength(&result->vendor); - - //Name - ffStrbufInitA(&result->name, 256); - if(ffStrbufIgnCaseCompS(&result->vendor, FF_PCI_VENDOR_AMD) == 0) - getAMDfromDRM(result, dev, ffpci_read_byte); - if(result->name.length == 0) - { - ffpci_lookup_name(pacc, result->name.chars, (int) ffStrbufGetFree(&result->name), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id); - ffStrbufRecalculateLength(&result->name); - } - - //Driver - ffStrbufInit(&result->driver); - if(instance->config.gpu.outputFormat.length > 0) - pciGetDriver(dev, &result->driver, ffpci_get_param); - - //Temperature - result->temperature = 0; - if(instance->config.gpu.outputFormat.length > 0) - result->temperature = pciGetTemperatur(instance, dev->device_class); - }; + pciHandleDevice(&results, &pci, device); + device = device->next; } - ffpci_cleanup(pacc); - dlclose(pci); - - if(results.length == 0) - { - ffListDestroy(&results); - return false; - } + ffpci_cleanup(pci.access); + dlclose(libpci); printGPUList(instance, &results); + for(uint32_t i = 0; i < results.length; i++) + { + FFGPUResult* gpu = ffListGet(&results, i); + ffStrbufDestroy(&gpu->vendor); + ffStrbufDestroy(&gpu->device); + ffStrbufDestroy(&gpu->driver); + } + ffListDestroy(&results); - return true; + return results.length > 0; } #endif