277 lines
12 KiB
C++
277 lines
12 KiB
C++
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
#include "../common/uarch.hpp"
|
|
#include "../common/global.hpp"
|
|
#include "../common/gpu.hpp"
|
|
#include "chips.hpp"
|
|
#include "pci.hpp"
|
|
#include "cpuid.hpp"
|
|
|
|
// Data not available
|
|
#define NA -1
|
|
|
|
// Unknown manufacturing process
|
|
#define UNK -1
|
|
|
|
/*
|
|
* Mapping between iGPU and CPU uarchs
|
|
* -----------------------------------
|
|
* Gen6: Sandy Bridge (2th Gen)
|
|
* Gen7: Ivy Brdige (3th Gen)
|
|
* Gen7.5: Haswell (4th Gen)
|
|
* Gen8: Broadwell (5th Gen)
|
|
* Gen9: Skylake (6th Gen)
|
|
* Gen9.5: Kaby Lake
|
|
* Gen11: Ice Lake (10th Gen)
|
|
* Gen12: Rocket/Tiger Lake (11th Gen)
|
|
* Gen12: Alder Lake (12th Gen)
|
|
*/
|
|
enum {
|
|
UARCH_UNKNOWN,
|
|
UARCH_GEN6,
|
|
UARCH_GEN7,
|
|
UARCH_GEN7_5,
|
|
UARCH_GEN8,
|
|
UARCH_GEN9,
|
|
UARCH_GEN9_5,
|
|
UARCH_GEN11,
|
|
UARCH_GEN12_RKL,
|
|
UARCH_GEN12_TGL,
|
|
UARCH_GEN12_ALD,
|
|
};
|
|
|
|
static const char *uarch_str[] = {
|
|
/*[ARCH_UNKNOWN = */ STRING_UNKNOWN,
|
|
/*[ARCH_GEN6] = */ "Gen6",
|
|
/*[ARCH_GEN7] = */ "Gen7",
|
|
/*[ARCH_GEN7_5] = */ "Gen7.5",
|
|
/*[ARCH_GEN8] = */ "Gen8",
|
|
/*[ARCH_GEN9] = */ "Gen9",
|
|
/*[ARCH_GEN9_5] = */ "Gen9.5",
|
|
/*[ARCH_GEN11] = */ "Gen11",
|
|
/*[ARCH_GEN12_RKL] = */ "Xe",
|
|
/*[ARCH_GEN12_TGL] = */ "Xe",
|
|
/*[ARCH_GEN12_ALD] = */ "Xe",
|
|
};
|
|
|
|
// Graphic Tiers (GT)
|
|
enum {
|
|
GT_UNKNOWN,
|
|
GT0_5, // Saw that 0.5 thing in iris_pci_ids.h
|
|
GT1,
|
|
GT1_4, // GT1 with 4 EUs
|
|
GT1_5,
|
|
GT2,
|
|
GT3,
|
|
GT3e,
|
|
GT4e
|
|
};
|
|
|
|
static const char *gt_str[] = {
|
|
/*[GT_UNKNOWN] = */ STRING_UNKNOWN,
|
|
/*[GT0_5] = */ "GT0.5",
|
|
/*[GT1] = */ "GT1",
|
|
/*[GT1_4] = */ "GT1",
|
|
/*[GT1_5] = */ "GT1.5",
|
|
/*[GT2] = */ "GT2",
|
|
/*[GT3] = */ "GT3",
|
|
/*[GT3e] = */ "GT3e",
|
|
/*[GT4e] = */ "GT4e",
|
|
};
|
|
|
|
#define CHECK_UARCH_START if (false) {}
|
|
#define CHECK_UARCH(arch, chip_, str, uarch, gt, process) \
|
|
else if (arch->chip == chip_) fill_uarch(arch, str, uarch, gt, process);
|
|
#define CHECK_UARCH_END else { printBug("map_chip_to_uarch_intel: Unknown chip id: %d", arch->chip); fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, GT_UNKNOWN, 0); }
|
|
|
|
#define CHECK_TOPO_START if (false) {}
|
|
#define CHECK_TOPO(topo, arch, uarch_, gt_, eu_sub, sub, sli) \
|
|
else if(arch->uarch == uarch_ && arch->gt == gt_) fill_topo(topo, eu_sub, sub, sli);
|
|
#define CHECK_TOPO_CHIP(topo, arch, uarch_, chip_, eu_sub, sub, sli) \
|
|
else if(arch->uarch == uarch_ && arch->chip == chip_) fill_topo(topo, eu_sub, sub, sli);
|
|
#define CHECK_TOPO_END else { printBug("get_topology_info: Invalid uarch and gt combination: '%s' and '%s'", arch->chip_str, get_str_gt(arch)); fill_topo(topo, UNK, UNK, UNK); }
|
|
|
|
void fill_topo(struct topology_i* topo_i, int32_t eu_sub, int32_t sub, int32_t sli) {
|
|
topo_i->slices = sli;
|
|
topo_i->subslices = sub;
|
|
topo_i->eu_subslice = eu_sub;
|
|
}
|
|
|
|
void fill_uarch(struct uarch* arch, char const *str, MICROARCH u, int32_t gt, uint32_t process) {
|
|
arch->chip_str = (char *) emalloc(sizeof(char) * (strlen(str)+1));
|
|
strcpy(arch->chip_str, str);
|
|
arch->uarch = u;
|
|
arch->process = process;
|
|
arch->gt = gt;
|
|
}
|
|
|
|
void map_chip_to_uarch_intel(struct uarch* arch) {
|
|
CHECK_UARCH_START
|
|
// Gen6
|
|
CHECK_UARCH(arch, CHIP_HD_SANDY, "HD Graphics (Sandy Bridge)", UARCH_GEN6, GT1, 32)
|
|
CHECK_UARCH(arch, CHIP_HD_2000, "HD Graphics 2000", UARCH_GEN6, GT1, 32)
|
|
CHECK_UARCH(arch, CHIP_HD_3000, "HD Graphics 3000", UARCH_GEN6, GT2, 32)
|
|
// Gen7
|
|
CHECK_UARCH(arch, CHIP_HD_IVY, "HD Graphics (Ivy Bridge)", UARCH_GEN7, GT1, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_SILVER, "HD Graphics (Silvermont)", UARCH_GEN7, GT1_4, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_2500, "HD Graphics 2500", UARCH_GEN7, GT1, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_4000, "HD Graphics 4000", UARCH_GEN7, GT2, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_P4000, "HD Graphics P4000", UARCH_GEN7, GT2, 22)
|
|
// Gen7.5
|
|
CHECK_UARCH(arch, CHIP_HD_HASWELL, "HD Graphics (Haswell)", UARCH_GEN7_5, GT1, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_4200, "HD Graphics 4200", UARCH_GEN7_5, GT2, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_4400, "HD Graphics 4400", UARCH_GEN7_5, GT2, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_4600, "HD Graphics 4600", UARCH_GEN7_5, GT2, 22)
|
|
CHECK_UARCH(arch, CHIP_HD_P4600, "HD Graphics P4600", UARCH_GEN7_5, GT2, 22)
|
|
CHECK_UARCH(arch, CHIP_IRIS_5100, "HD Iris 5100", UARCH_GEN7_5, GT3, 22)
|
|
CHECK_UARCH(arch, CHIP_IRISP_5200, "HD Iris Pro 5200", UARCH_GEN7_5, GT3, 22)
|
|
CHECK_UARCH(arch, CHIP_IRISP_P5200, "HD Iris Pro P5200", UARCH_GEN7_5, GT3, 22)
|
|
// Gen8
|
|
CHECK_UARCH(arch, CHIP_HD_BROADWELL, "HD Graphics (Broadwell)", UARCH_GEN8, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_5300, "HD Graphics 5300", UARCH_GEN8, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_5500, "HD Graphics 5500", UARCH_GEN8, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_5600, "HD Graphics 5600", UARCH_GEN8, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_P5700, "HD Graphics P5700", UARCH_GEN8, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_6000, "HD Graphics 6000", UARCH_GEN8, GT3, 14)
|
|
CHECK_UARCH(arch, CHIP_IRIS_6100, "Iris Graphics 6100", UARCH_GEN8, GT3, 14)
|
|
CHECK_UARCH(arch, CHIP_IRISP_6200, "Iris Pro Graphics 6200", UARCH_GEN8, GT3, 14)
|
|
CHECK_UARCH(arch, CHIP_IRISP_P6300, "Iris Pro Graphics P6300", UARCH_GEN8, GT3, 14)
|
|
// Gen9
|
|
CHECK_UARCH(arch, CHIP_HD_510, "HD Graphics 510", UARCH_GEN9, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_515, "HD Graphics 515", UARCH_GEN9, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_520, "HD Graphics 520", UARCH_GEN9, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_530, "HD Graphics 530", UARCH_GEN9, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_P530, "HD Graphics P530", UARCH_GEN9, GT2, 14)
|
|
// Gen9.5
|
|
CHECK_UARCH(arch, CHIP_UHD_600, "UHD Graphics 600", UARCH_GEN9_5, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_605, "UHD Graphics 605", UARCH_GEN9_5, GT1_5, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_620, "UHD Graphics 620", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_630, "UHD Graphics 630", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_KBL_GT1, "UHD Graphics", UARCH_GEN9_5, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_KBL_GT2, "UHD Graphics", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_610, "HD Graphics 610", UARCH_GEN9_5, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_615, "HD Graphics 615", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_630, "HD Graphics 630", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_HD_P630, "HD Graphics P630", UARCH_GEN9_5, GT2, 14)
|
|
CHECK_UARCH(arch, CHIP_IRISP_640, "Iris Plus Graphics 640", UARCH_GEN9_5, GT3e, 14)
|
|
CHECK_UARCH(arch, CHIP_IRISP_640, "Iris Plus Graphics 650", UARCH_GEN9_5, GT3e, 14)
|
|
// Gen11
|
|
CHECK_UARCH(arch, CHIP_UHD_G1, "UHD Graphics G1", UARCH_GEN11, GT1, 10)
|
|
CHECK_UARCH(arch, CHIP_IRISP_G4, "Iris Plus Graphics G4", UARCH_GEN11, GT1_5, 10)
|
|
CHECK_UARCH(arch, CHIP_IRISP_G7, "Iris Plus Graphics G7", UARCH_GEN11, GT2, 10)
|
|
// Xe (Gen12)
|
|
CHECK_UARCH(arch, CHIP_UHD_710, "UHD Graphics 710", UARCH_GEN12_ALD, GT1, 10)
|
|
CHECK_UARCH(arch, CHIP_UHD_730_ALD, "UHD Graphics 730", UARCH_GEN12_ALD, GT1, 10)
|
|
CHECK_UARCH(arch, CHIP_UHD_770, "UHD Graphics 770", UARCH_GEN12_ALD, GT1, 10)
|
|
CHECK_UARCH(arch, CHIP_UHD_730_RKL, "UHD Graphics 730", UARCH_GEN12_RKL, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_UHD_750, "UHD Graphics 750", UARCH_GEN12_RKL, GT1, 14)
|
|
CHECK_UARCH(arch, CHIP_XE_G4, "Iris Xe G4", UARCH_GEN12_TGL, GT2, 10)
|
|
CHECK_UARCH(arch, CHIP_XE_G7, "Iris Xe G7", UARCH_GEN12_TGL, GT2, 10)
|
|
CHECK_UARCH_END
|
|
}
|
|
|
|
const char* get_str_uarch_intel(struct uarch* arch) {
|
|
return uarch_str[arch->uarch];
|
|
}
|
|
|
|
const char* get_str_gt(struct uarch* arch) {
|
|
return gt_str[arch->gt];
|
|
}
|
|
|
|
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_intel(pci);
|
|
if(arch->chip == CHIP_UNKNOWN_INTEL) {
|
|
return NULL;
|
|
}
|
|
else {
|
|
map_chip_to_uarch_intel(arch);
|
|
return arch;
|
|
}
|
|
}
|
|
|
|
char* get_name_from_uarch(struct uarch* arch) {
|
|
char* name = (char *) emalloc(sizeof(char) * (strlen(arch->chip_str) + 6 + 1));
|
|
sprintf(name, "%s", arch->chip_str);
|
|
return name;
|
|
}
|
|
|
|
/*
|
|
* Refs:
|
|
* Gen6: https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen6
|
|
* Gen7/7.5: https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen7
|
|
"The Compute Architecture of Intel Processor Graphics Gen7.5, v1.0"
|
|
* Gen8: https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen8
|
|
"The Compute Architecture of Intel Processor Graphics Gen8, v1.1"
|
|
* Gen9: https://en.wikichip.org/wiki/intel/microarchitectures/gen9#Configuration
|
|
"The Compute Architecture of Intel Processor Graphics Gen9, v1.0"
|
|
* Gen9.5: https://en.wikichip.org/wiki/intel/microarchitectures/gen9.5#Configuration
|
|
|
|
* Also: https://www.techpowerup.com/gpu-specs/intel-rocket-lake-gt1.g993
|
|
https://www.techpowerup.com/gpu-specs/?architecture=Generation%2012.1
|
|
https://elixir.bootlin.com/linux/latest/source/include/drm/i915_pciids.h
|
|
*/
|
|
struct topology_i* get_topology_info(struct uarch* arch) {
|
|
struct topology_i* topo = (struct topology_i*) emalloc(sizeof(struct topology_i));
|
|
|
|
// Syntax: (EU per subslice, Subslices, Slices)
|
|
CHECK_TOPO_START
|
|
// Gen6
|
|
CHECK_TOPO(topo, arch, UARCH_GEN6, GT1, 6, 1, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN6, GT2, 6, 2, 1)
|
|
// Gen7
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7, GT1_4, 4, 1, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7, GT1, 6, 1, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7, GT2, 8, 2, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7, GT3, 6, 1, 1)
|
|
// Gen7.5
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7_5, GT1, 10, 1, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7_5, GT2, 10, 2, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN7_5, GT3, 10, 4, 1)
|
|
// Gen8
|
|
CHECK_TOPO(topo, arch, UARCH_GEN8, GT1, 6, 2, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN8, GT2, 8, 3, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN8, GT3, 8, 6, 2)
|
|
// Gen9
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9, GT1, 6, 2, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9, GT2, 8, 3, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9, GT3, 8, 6, 2)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9, GT4e, 8, 9, 3)
|
|
// Gen9.5
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9_5, GT1, 6, 2, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9_5, GT1_5, 6, 3, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9_5, GT2, 8, 3, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9_5, GT3, 8, 6, 2)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN9_5, GT3e, 8, 6, 2) // Same as GT3, but has eDRAM cache
|
|
// Gen11
|
|
CHECK_TOPO(topo, arch, UARCH_GEN11, GT1, 8, 4, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN11, GT1_5, 8, 6, 1)
|
|
CHECK_TOPO(topo, arch, UARCH_GEN11, GT2, 8, 8, 1)
|
|
// Xe (Gen12)
|
|
// NOTE: Instead of checking for uarch + graphics tier,
|
|
// we have to check for uarch + exact chip
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_RKL, CHIP_UHD_730_RKL, 8, 3, 1)
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_RKL, CHIP_UHD_750, 8, 4, 1)
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_TGL, CHIP_XE_G4, 8, 6, 1)
|
|
else if(arch->uarch == UARCH_GEN12_TGL && arch->chip == CHIP_XE_G7) {
|
|
// Special case: TigerLake GT2 needs to check if is i5/i7 to know the exact topology
|
|
if(is_corei5()) {
|
|
fill_topo(topo, 10, 8, 1); // Should be 80 EUs, but not sure about the organization
|
|
}
|
|
else {
|
|
fill_topo(topo, 16, 6, 1);
|
|
}
|
|
}
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_ALD, CHIP_UHD_710, 8, 2, 1)
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_ALD, CHIP_UHD_730_ALD, 8, 3, 1)
|
|
CHECK_TOPO_CHIP(topo, arch, UARCH_GEN12_ALD, CHIP_UHD_770, 8, 4, 1)
|
|
// TODO: Add ALD UHD Graphics/Xe Graphics
|
|
CHECK_TOPO_END
|
|
return topo;
|
|
}
|