[v0.11] Adding uarch backend for intel iGPUs

This commit is contained in:
Dr-Noob
2021-11-26 12:52:45 +01:00
parent ce004725ad
commit 8740337145
16 changed files with 176 additions and 48 deletions

View File

@@ -54,7 +54,7 @@ set(CMAKE_CXX_FLAGS "${SANITY_FLAGS} -Wall -Wextra -pedantic -fstack-protector-a
if(ENABLE_INTEL_BACKEND) if(ENABLE_INTEL_BACKEND)
target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL) target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL)
add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp) add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp ${INTEL_DIR}/pci.cpp ${INTEL_DIR}/uarch.cpp)
if(NOT ${PCIUTILS_FOUND}) if(NOT ${PCIUTILS_FOUND})
add_dependencies(intel_backend pciutils) add_dependencies(intel_backend pciutils)

View File

@@ -20,6 +20,8 @@ struct gpu_list* get_gpu_list() {
list->gpus = (struct gpu_info**) malloc(sizeof(struct info*) * MAX_GPUS); list->gpus = (struct gpu_info**) malloc(sizeof(struct info*) * MAX_GPUS);
#ifdef BACKEND_CUDA #ifdef BACKEND_CUDA
bool valid = true;
while(valid) { while(valid) {
list->gpus[idx] = get_gpu_info_cuda(idx); list->gpus[idx] = get_gpu_info_cuda(idx);
if(list->gpus[idx] != NULL) idx++; if(list->gpus[idx] != NULL) idx++;

View File

@@ -2,33 +2,39 @@
#include "pci.hpp" #include "pci.hpp"
#include <cstddef> #include <cstddef>
/*
* doc: https://wiki.osdev.org/PCI#Class_Codes
* https://pci-ids.ucw.cz/read/PC
*/
#define VENDOR_ID_NVIDIA 0x10de
#define CLASS_VGA_CONTROLLER 0x0300 #define CLASS_VGA_CONTROLLER 0x0300
uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices) { uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices, int id) {
for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) { for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) {
if(dev->vendor_id == VENDOR_ID_NVIDIA && dev->device_class == CLASS_VGA_CONTROLLER) { if(dev->vendor_id == id && dev->device_class == CLASS_VGA_CONTROLLER) {
return dev->vendor_id; return dev->vendor_id;
} }
} }
printErr("Unable to find a CUDA device using pciutils");
printErr("Unable to find a valid device for id %d using pciutils", id);
return 0; return 0;
} }
uint16_t pciutils_get_pci_device_id(struct pci_dev *devices) { uint16_t pciutils_get_pci_device_id(struct pci_dev *devices, int id) {
for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) { for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) {
if(dev->vendor_id == VENDOR_ID_NVIDIA && dev->device_class == CLASS_VGA_CONTROLLER) { if(dev->vendor_id == id && dev->device_class == CLASS_VGA_CONTROLLER) {
return dev->device_id; return dev->device_id;
} }
} }
printErr("Unable to find a CUDA device using pciutils");
printErr("Unable to find a valid device for id %d using pciutils", id);
return 0; return 0;
} }
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id) {
struct pci* pci = (struct pci*) emalloc(sizeof(struct pci));
pci->vendor_id = pciutils_get_pci_vendor_id(devices, id);
pci->device_id = pciutils_get_pci_device_id(devices, id);
return pci;
}
struct pci_dev *get_pci_devices_from_pciutils() { struct pci_dev *get_pci_devices_from_pciutils() {
struct pci_access *pacc; struct pci_access *pacc;
struct pci_dev *dev; struct pci_dev *dev;

View File

@@ -6,8 +6,12 @@ extern "C" {
#include <pci/pci.h> #include <pci/pci.h>
} }
uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices); struct pci {
uint16_t pciutils_get_pci_device_id(struct pci_dev *devices); uint16_t vendor_id;
uint16_t device_id;
};
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id);
struct pci_dev *get_pci_devices_from_pciutils(); struct pci_dev *get_pci_devices_from_pciutils();
#endif #endif

20
src/common/uarch.hpp Normal file
View File

@@ -0,0 +1,20 @@
#ifndef __COMMON_UARCH__
#define __COMMON_UARCH__
typedef uint32_t GPUCHIP;
typedef uint32_t MICROARCH;
struct uarch {
int32_t cc_major;
int32_t cc_minor;
int32_t compute_capability;
MICROARCH uarch;
GPUCHIP chip;
int32_t process;
char* uarch_str;
char* chip_str;
};
#endif

View File

@@ -1,5 +1,5 @@
#ifndef __GPUCHIPS__ #ifndef __CUDA_GPUCHIPS__
#define __GPUCHIPS__ #define __CUDA_GPUCHIPS__
typedef uint32_t GPUCHIP; typedef uint32_t GPUCHIP;

View File

@@ -133,7 +133,7 @@ struct gpu_info* get_gpu_info_cuda(int gpu_idx) {
strcpy(gpu->name, deviceProp.name); strcpy(gpu->name, deviceProp.name);
struct pci_dev *devices = get_pci_devices_from_pciutils(); struct pci_dev *devices = get_pci_devices_from_pciutils();
gpu->pci = get_pci_from_pciutils(devices); gpu->pci = get_pci_from_pciutils(devices, PCI_VENDOR_ID_NVIDIA);
gpu->arch = get_uarch_from_cuda(gpu); gpu->arch = get_uarch_from_cuda(gpu);
gpu->cach = get_cache_info(deviceProp); gpu->cach = get_cache_info(deviceProp);
gpu->mem = get_memory_info(gpu, deviceProp); gpu->mem = get_memory_info(gpu, deviceProp);

View File

@@ -10,20 +10,6 @@
else if (pci->device_id == id) return chip; else if (pci->device_id == id) return chip;
#define CHECK_PCI_END else { printBug("TODOO"); return CHIP_UNKNOWN; } #define CHECK_PCI_END else { printBug("TODOO"); return CHIP_UNKNOWN; }
struct pci {
uint16_t vendor_id;
uint16_t device_id;
};
struct pci* get_pci_from_pciutils(struct pci_dev *devices) {
struct pci* pci = (struct pci*) emalloc(sizeof(struct pci));
pci->vendor_id = pciutils_get_pci_vendor_id(devices);
pci->device_id = pciutils_get_pci_device_id(devices);
return pci;
}
/* /*
* pci ids were retrieved using https://github.com/pciutils/pciids * pci ids were retrieved using https://github.com/pciutils/pciids
* and parsed using a custom script to take only the relevant * and parsed using a custom script to take only the relevant

View File

@@ -6,6 +6,12 @@
#include "../common/pci.hpp" #include "../common/pci.hpp"
#include "chips.hpp" #include "chips.hpp"
/*
* doc: https://wiki.osdev.org/PCI#Class_Codes
* https://pci-ids.ucw.cz/read/PC
*/
#define PCI_VENDOR_ID_NVIDIA 0x10de
struct pci; struct pci;
struct pci* get_pci_from_pciutils(struct pci_dev *devices); struct pci* get_pci_from_pciutils(struct pci_dev *devices);

View File

@@ -3,12 +3,11 @@
#include <stdint.h> #include <stdint.h>
#include <cstddef> #include <cstddef>
#include "../common/uarch.hpp"
#include "../common/global.hpp" #include "../common/global.hpp"
#include "../common/gpu.hpp" #include "../common/gpu.hpp"
#include "chips.hpp" #include "chips.hpp"
typedef uint32_t MICROARCH;
// Any clock multiplier // Any clock multiplier
#define CM_ANY -1 #define CM_ANY -1
@@ -43,19 +42,6 @@ static const char *uarch_str[] = {
/*[ARCH_AMPERE] = */ "Ampere", /*[ARCH_AMPERE] = */ "Ampere",
}; };
struct uarch {
int32_t cc_major;
int32_t cc_minor;
int32_t compute_capability;
MICROARCH uarch;
GPUCHIP chip;
int32_t process;
char* uarch_str;
char* chip_str;
};
#define CHECK_UARCH_START if (false) {} #define CHECK_UARCH_START if (false) {}
#define CHECK_UARCH(arch, chip_, str, uarch, process) \ #define CHECK_UARCH(arch, chip_, str, uarch, process) \
else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process); else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process);

13
src/intel/chips.hpp Normal file
View File

@@ -0,0 +1,13 @@
#ifndef __INTEL_GPUCHIPS__
#define __INTEL_GPUCHIPS__
#include <stdint.h>
typedef uint32_t GPUCHIP;
enum {
CHIP_UNKNOWN_INTEL,
CHIP_UHDG_620,
};
#endif

View File

@@ -3,6 +3,7 @@
#include "intel.hpp" #include "intel.hpp"
#include "uarch.hpp" #include "uarch.hpp"
#include "chips.hpp"
#include "../common/pci.hpp" #include "../common/pci.hpp"
#include "../common/global.hpp" #include "../common/global.hpp"
@@ -11,8 +12,11 @@ struct gpu_info* get_gpu_info_intel() {
const char* name = "UHD Graphics XXX"; const char* name = "UHD Graphics XXX";
gpu->vendor = GPU_VENDOR_INTEL; gpu->vendor = GPU_VENDOR_INTEL;
gpu->name = (char *) emalloc(sizeof(char) * (strlen(name) + 1));
strcpy(gpu->name, name); struct pci_dev *devices = get_pci_devices_from_pciutils();
gpu->pci = get_pci_from_pciutils(devices, PCI_VENDOR_ID_INTEL);
gpu->arch = get_uarch_from_pci(gpu->pci);
gpu->name = get_name_from_uarch(gpu->arch);
return gpu; return gpu;
} }

17
src/intel/pci.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include <stdio.h>
#include "pci.hpp"
#include "chips.hpp"
#include "../common/global.hpp"
#include "../common/pci.hpp"
#define CHECK_PCI_START if (false) {}
#define CHECK_PCI(pci, id, chip) \
else if (pci->device_id == id) return chip;
#define CHECK_PCI_END else { printBug("TODOO"); return CHIP_UNKNOWN_INTEL; }
GPUCHIP get_chip_from_pci(struct pci* pci) {
CHECK_PCI_START
CHECK_PCI(pci, 0x5917, CHIP_UHDG_620)
CHECK_PCI_END
}

20
src/intel/pci.hpp Normal file
View File

@@ -0,0 +1,20 @@
#ifndef __PCI_INTEL__
#define __PCI_INTEL__
#include <stdint.h>
#include "../common/pci.hpp"
#include "chips.hpp"
/*
* doc: https://wiki.osdev.org/PCI#Class_Codes
* https://pci-ids.ucw.cz/read/PC
*/
#define PCI_VENDOR_ID_INTEL 0x8086
struct pci;
struct pci* get_pci_from_pciutils(struct pci_dev *devices);
GPUCHIP get_chip_from_pci(struct pci* pci);
#endif

59
src/intel/uarch.cpp Normal file
View File

@@ -0,0 +1,59 @@
#include <stdint.h>
#include <cstddef>
#include <string.h>
#include "../common/uarch.hpp"
#include "../common/global.hpp"
#include "../common/gpu.hpp"
#include "chips.hpp"
// Data not available
#define NA -1
// Unknown manufacturing process
#define UNK -1
// MICROARCH values
enum {
UARCH_UNKNOWN,
UARCH_GEN9,
UARCH_GEN9_5,
};
static const char *uarch_str[] = {
/*[ARCH_UNKNOWN = */ STRING_UNKNOWN,
/*[ARCH_GEN9] = */ "Gen9",
/*[ARCH_GEN9.5] = */ "Gen9.5",
};
#define CHECK_UARCH_START if (false) {}
#define CHECK_UARCH(arch, chip_, str, uarch, process) \
else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process);
#define CHECK_UARCH_END else { printBug("map_chip_to_uarch: Unknown chip id: %d", arch->chip); fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, 0); }
void fill_uarch(struct uarch* arch, char const *str, MICROARCH u, uint32_t process) {
arch->chip_str = (char *) emalloc(sizeof(char) * (strlen(str)+1));
strcpy(arch->chip_str, str);
arch->uarch = u;
arch->process = process;
}
void map_chip_to_uarch(struct uarch* arch) {
CHECK_UARCH_START
CHECK_UARCH(arch, CHIP_UHDG_620, "UHD Graphics 620", UARCH_GEN9_5, 14)
CHECK_UARCH_END
}
struct uarch* get_uarch_from_pci(struct pci* pci) {
struct uarch* arch = (struct uarch*) emalloc(sizeof(struct uarch));
arch->chip_str = NULL;
arch->chip = get_chip_from_pci(pci);
map_chip_to_uarch(arch);
return arch;
}
char* get_name_from_uarch(struct uarch* arch) {
return arch->chip_str;
}

View File

@@ -3,4 +3,9 @@
#include "../common/gpu.hpp" #include "../common/gpu.hpp"
struct uarch;
struct uarch* get_uarch_from_pci(struct pci* pci);
char* get_name_from_uarch(struct uarch* arch);
#endif #endif