mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 16:00:39 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e9d308bea | ||
|
|
9018a3b98e | ||
|
|
4f081ef1a2 | ||
|
|
1b746bc67d |
4
Makefile
4
Makefile
@@ -32,8 +32,8 @@ ifneq ($(OS),Windows_NT)
|
|||||||
CFLAGS += -DARCH_PPC -std=gnu99 -fstack-protector-all -Wno-language-extension-token
|
CFLAGS += -DARCH_PPC -std=gnu99 -fstack-protector-all -Wno-language-extension-token
|
||||||
else ifeq ($(arch), $(filter $(arch), arm aarch64_be aarch64 arm64 armv8b armv8l armv7l armv6l))
|
else ifeq ($(arch), $(filter $(arch), arm aarch64_be aarch64 arm64 armv8b armv8l armv7l armv6l))
|
||||||
SRC_DIR=src/arm/
|
SRC_DIR=src/arm/
|
||||||
SOURCE += $(COMMON_SRC) $(SRC_DIR)midr.c $(SRC_DIR)uarch.c $(SRC_COMMON)soc.c $(SRC_DIR)soc.c $(SRC_DIR)udev.c
|
SOURCE += $(COMMON_SRC) $(SRC_DIR)midr.c $(SRC_DIR)uarch.c $(SRC_COMMON)soc.c $(SRC_DIR)soc.c $(SRC_COMMON)pci.c $(SRC_DIR)udev.c
|
||||||
HEADERS += $(COMMON_HDR) $(SRC_DIR)midr.h $(SRC_DIR)uarch.h $(SRC_COMMON)soc.h $(SRC_DIR)soc.h $(SRC_DIR)udev.c $(SRC_DIR)socs.h
|
HEADERS += $(COMMON_HDR) $(SRC_DIR)midr.h $(SRC_DIR)uarch.h $(SRC_COMMON)soc.h $(SRC_DIR)soc.h $(SRC_COMMON)pci.h $(SRC_DIR)udev.c $(SRC_DIR)socs.h
|
||||||
CFLAGS += -DARCH_ARM -Wno-unused-parameter -std=c99 -fstack-protector-all
|
CFLAGS += -DARCH_ARM -Wno-unused-parameter -std=c99 -fstack-protector-all
|
||||||
|
|
||||||
os := $(shell uname -s)
|
os := $(shell uname -s)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
#include "uarch.h"
|
#include "uarch.h"
|
||||||
#include "../common/global.h"
|
#include "../common/global.h"
|
||||||
|
#include "../common/pci.h"
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__MACH__)
|
#if defined(__APPLE__) || defined(__MACH__)
|
||||||
#include "sysctl.h"
|
#include "sysctl.h"
|
||||||
@@ -834,6 +835,43 @@ struct system_on_chip* guess_soc_from_uarch(struct system_on_chip* soc, struct c
|
|||||||
return soc;
|
return soc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct system_on_chip* guess_soc_from_pci(struct system_on_chip* soc, struct cpuInfo* cpu) {
|
||||||
|
struct pci_devices * pci = get_pci_devices();
|
||||||
|
if (pci == NULL) {
|
||||||
|
printWarn("guess_soc_from_pci: Unable to find suitable PCI devices");
|
||||||
|
return soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t vendor_id;
|
||||||
|
uint16_t device_id;
|
||||||
|
struct system_on_chip soc;
|
||||||
|
} pciToSoC;
|
||||||
|
|
||||||
|
pciToSoC socFromPCI[] = {
|
||||||
|
{PCI_VENDOR_NVIDIA, PCI_DEVICE_TEGRA_X1, {SOC_TEGRA_X1, SOC_VENDOR_NVIDIA, 20, "Tegra X1", NULL} },
|
||||||
|
// {PCI_VENDOR_NVIDIA, PCI_DEVICE_GH_200,{SOC_GH_200, SOC_VENDOR_NVIDIA, ?, "Grace Hopper", NULL} },
|
||||||
|
{0x0000, 0x0000, {UNKNOWN, SOC_VENDOR_UNKNOWN, -1, "", NULL} }
|
||||||
|
};
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
while (socFromPCI[index].vendor_id != 0x0) {
|
||||||
|
for (int i=0; i < pci->num_devices; i++) {
|
||||||
|
struct pci_device * dev = pci->devices[i];
|
||||||
|
|
||||||
|
if (socFromPCI[index].vendor_id == dev->vendor_id &&
|
||||||
|
socFromPCI[index].device_id == dev->device_id) {
|
||||||
|
fill_soc(soc, socFromPCI[index].soc.soc_name, socFromPCI[index].soc.soc_model, socFromPCI[index].soc.process);
|
||||||
|
return soc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printWarn("guess_soc_from_pci: No PCI device matched the list");
|
||||||
|
return soc;
|
||||||
|
}
|
||||||
|
|
||||||
int hex2int(char c) {
|
int hex2int(char c) {
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9')
|
||||||
return c - '0';
|
return c - '0';
|
||||||
@@ -1004,14 +1042,18 @@ struct system_on_chip* get_soc(struct cpuInfo* cpu) {
|
|||||||
printWarn("SoC detection failed using Android: Found '%s' string", soc->raw_name);
|
printWarn("SoC detection failed using Android: Found '%s' string", soc->raw_name);
|
||||||
}
|
}
|
||||||
#endif // ifdef __ANDROID__
|
#endif // ifdef __ANDROID__
|
||||||
// If cpufinfo/Android (if available) detection fails, try with nvmem
|
// If previous steps failed, try with nvmem
|
||||||
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
|
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
|
||||||
soc = guess_soc_from_nvmem(soc);
|
soc = guess_soc_from_nvmem(soc);
|
||||||
}
|
}
|
||||||
// If everything else failed, try infering it from the microarchitecture
|
// If previous steps failed, try infering it from the microarchitecture
|
||||||
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
|
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
|
||||||
soc = guess_soc_from_uarch(soc, cpu);
|
soc = guess_soc_from_uarch(soc, cpu);
|
||||||
}
|
}
|
||||||
|
// If previous steps failed, try infering it from the pci device id
|
||||||
|
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
|
||||||
|
soc = guess_soc_from_pci(soc, cpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined __APPLE__ || __MACH__
|
#elif defined __APPLE__ || __MACH__
|
||||||
soc = guess_soc_apple(soc);
|
soc = guess_soc_apple(soc);
|
||||||
|
|||||||
@@ -363,6 +363,8 @@ enum {
|
|||||||
SOC_GOOGLE_TENSOR,
|
SOC_GOOGLE_TENSOR,
|
||||||
SOC_GOOGLE_TENSOR_G2,
|
SOC_GOOGLE_TENSOR_G2,
|
||||||
SOC_GOOGLE_TENSOR_G3,
|
SOC_GOOGLE_TENSOR_G3,
|
||||||
|
// NVIDIA,
|
||||||
|
SOC_TEGRA_X1,
|
||||||
// UNKNOWN
|
// UNKNOWN
|
||||||
SOC_MODEL_UNKNOWN
|
SOC_MODEL_UNKNOWN
|
||||||
};
|
};
|
||||||
@@ -378,6 +380,7 @@ inline static VENDOR get_soc_vendor_from_soc(SOC soc) {
|
|||||||
else if(soc >= SOC_ALLWINNER_A10 && soc <= SOC_ALLWINNER_R328) return SOC_VENDOR_ALLWINNER;
|
else if(soc >= SOC_ALLWINNER_A10 && soc <= SOC_ALLWINNER_R328) return SOC_VENDOR_ALLWINNER;
|
||||||
else if(soc >= SOC_ROCKCHIP_3288 && soc <= SOC_ROCKCHIP_3588) return SOC_VENDOR_ROCKCHIP;
|
else if(soc >= SOC_ROCKCHIP_3288 && soc <= SOC_ROCKCHIP_3588) return SOC_VENDOR_ROCKCHIP;
|
||||||
else if(soc >= SOC_GOOGLE_TENSOR && soc <= SOC_GOOGLE_TENSOR_G3) return SOC_VENDOR_GOOGLE;
|
else if(soc >= SOC_GOOGLE_TENSOR && soc <= SOC_GOOGLE_TENSOR_G3) return SOC_VENDOR_GOOGLE;
|
||||||
|
else if(soc >= SOC_TEGRA_X1 && soc <= SOC_TEGRA_X1) return SOC_VENDOR_NVIDIA;
|
||||||
return SOC_VENDOR_UNKNOWN;
|
return SOC_VENDOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,19 @@ $C1 MMM :MMM NMM dMMK dMMX MMN \
|
|||||||
$C1 MMM :MMM NMM dMMMoo OMM0....:Nx. MMN \
|
$C1 MMM :MMM NMM dMMMoo OMM0....:Nx. MMN \
|
||||||
$C1 MMM :WWW XWW lONMM 'xXMMMMNOc MMN "
|
$C1 MMM :WWW XWW lONMM 'xXMMMMNOc MMN "
|
||||||
|
|
||||||
|
#define ASCII_HYGON \
|
||||||
|
"$C1 \
|
||||||
|
$C1 \
|
||||||
|
$C1 \
|
||||||
|
$C1 ## ## ## ## ###### ###### ## # \
|
||||||
|
$C1 ##....## ## ## ## ## ## #### # \
|
||||||
|
$C1 ######## ## ## ##. ## ## # #### \
|
||||||
|
$C1 ## ## ## *######. ###### # ## \
|
||||||
|
$C1 \
|
||||||
|
$C1 \
|
||||||
|
$C1 \
|
||||||
|
$C1 "
|
||||||
|
|
||||||
#define ASCII_SNAPD \
|
#define ASCII_SNAPD \
|
||||||
" $C1@@$C2######## \
|
" $C1@@$C2######## \
|
||||||
$C1@@@@@$C2########### \
|
$C1@@@@@$C2########### \
|
||||||
@@ -360,6 +373,27 @@ $C1##########@@@@@@@@@@@@@@@@############## \
|
|||||||
$C1######################################## \
|
$C1######################################## \
|
||||||
$C1 #################################### "
|
$C1 #################################### "
|
||||||
|
|
||||||
|
#define ASCII_NVIDIA \
|
||||||
|
"$C1 'cccccccccccccccccccccccccc \
|
||||||
|
$C1 ;oooooooooooooooooooooooool \
|
||||||
|
$C1 .:::. .oooooooooooooooooool \
|
||||||
|
$C1 .:cll; ,c:::. cooooooooooooool \
|
||||||
|
$C1 ,clo' ;. oolc: ooooooooooool \
|
||||||
|
$C1.cloo ;cclo . .olc. coooooooool \
|
||||||
|
$C1oooo :lo, ;ll; looc :oooooooool \
|
||||||
|
$C1 oooc ool. ;oooc;clol :looooooooool \
|
||||||
|
$C1 :ooc ,ol; ;oooooo. .cloo; loool \
|
||||||
|
$C1 ool; .olc. ,:lool .lool \
|
||||||
|
$C1 ool:. ,::::ccloo. :clooool \
|
||||||
|
$C1 oolc::. ':cclooooooool \
|
||||||
|
$C1 ;oooooooooooooooooooooooool \
|
||||||
|
$C1 \
|
||||||
|
$C1 \
|
||||||
|
$C2######. ## ## ## ###### ## ### \
|
||||||
|
$C2## ## ## ## ## ## ## ## #: :# \
|
||||||
|
$C2## ## ## ## ## ## ## ## ####### \
|
||||||
|
$C2## ## ### ## ###### ## ## ## "
|
||||||
|
|
||||||
// --------------------- LONG LOGOS ------------------------- //
|
// --------------------- LONG LOGOS ------------------------- //
|
||||||
#define ASCII_AMD_L \
|
#define ASCII_AMD_L \
|
||||||
"$C1 \
|
"$C1 \
|
||||||
@@ -492,6 +526,23 @@ $C1 ###########. ############ \
|
|||||||
$C1 ################ \
|
$C1 ################ \
|
||||||
$C1 ####### "
|
$C1 ####### "
|
||||||
|
|
||||||
|
#define ASCII_NVIDIA_L \
|
||||||
|
"$C1 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM \
|
||||||
|
$C1 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM \
|
||||||
|
$C1 .:: 'MMMMMMMMMMMMMMMMMMMMMMMMM \
|
||||||
|
$C1 ccllooo;:;. ;MMMMMMMMMMMMMMMMMM \
|
||||||
|
$C1 cloc :ooollcc: :MMMMMMMMMMMMMMM \
|
||||||
|
$C1 cloc :ccl; lolc, ;MMMMMMMMMMMM \
|
||||||
|
$C1.cloo: :clo ;c: .ool; MMMMMMMMMMM \
|
||||||
|
$C1 ooo: ooo :ool, .cloo. ;lMMMMMMMMMMM \
|
||||||
|
$C1 ooo: ooc :ooooccooo. :MMMM lMMMMMMM \
|
||||||
|
$C1 ooc. ool: :oooooo' ,cloo. MMMM \
|
||||||
|
$C1 ool:. olc: .:cloo. :MMMM \
|
||||||
|
$C1 olc, ;:::cccloo. :MMMMMMMM \
|
||||||
|
$C1 olcc::; ,:ccloMMMMMMMMM \
|
||||||
|
$C1 :......oMMMMMMMMMMMMMMMMMMMMMM \
|
||||||
|
$C1 :lllMMMMMMMMMMMMMMMMMMMMMMMMMM "
|
||||||
|
|
||||||
typedef struct ascii_logo asciiL;
|
typedef struct ascii_logo asciiL;
|
||||||
|
|
||||||
// +-----------------------------------------------------------------------------------------------------------------+
|
// +-----------------------------------------------------------------------------------------------------------------+
|
||||||
@@ -500,6 +551,7 @@ typedef struct ascii_logo asciiL;
|
|||||||
asciiL logo_amd = { ASCII_AMD, 39, 15, false, {C_FG_WHITE, C_FG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
asciiL logo_amd = { ASCII_AMD, 39, 15, false, {C_FG_WHITE, C_FG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
||||||
asciiL logo_intel = { ASCII_INTEL, 48, 14, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
asciiL logo_intel = { ASCII_INTEL, 48, 14, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
||||||
asciiL logo_intel_new = { ASCII_INTEL_NEW, 51, 9, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
asciiL logo_intel_new = { ASCII_INTEL_NEW, 51, 9, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
||||||
|
asciiL logo_hygon = { ASCII_HYGON, 51, 11, false, {C_FG_RED}, {C_FG_RED, C_FG_WHITE} };
|
||||||
asciiL logo_snapd = { ASCII_SNAPD, 39, 16, false, {C_FG_RED, C_FG_WHITE}, {C_FG_RED, C_FG_WHITE} };
|
asciiL logo_snapd = { ASCII_SNAPD, 39, 16, false, {C_FG_RED, C_FG_WHITE}, {C_FG_RED, C_FG_WHITE} };
|
||||||
asciiL logo_mtk = { ASCII_MTK, 59, 5, false, {C_FG_BLUE, C_FG_YELLOW}, {C_FG_BLUE, C_FG_YELLOW} };
|
asciiL logo_mtk = { ASCII_MTK, 59, 5, false, {C_FG_BLUE, C_FG_YELLOW}, {C_FG_BLUE, C_FG_YELLOW} };
|
||||||
asciiL logo_exynos = { ASCII_EXYNOS, 22, 13, true, {C_BG_BLUE, C_FG_WHITE}, {C_FG_BLUE, C_FG_WHITE} };
|
asciiL logo_exynos = { ASCII_EXYNOS, 22, 13, true, {C_BG_BLUE, C_FG_WHITE}, {C_FG_BLUE, C_FG_WHITE} };
|
||||||
@@ -516,6 +568,7 @@ asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_Y
|
|||||||
asciiL logo_sifive = { ASCII_SIFIVE, 48, 19, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_BLUE} };
|
asciiL logo_sifive = { ASCII_SIFIVE, 48, 19, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_BLUE} };
|
||||||
asciiL logo_starfive = { ASCII_STARFIVE, 33, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} };
|
asciiL logo_starfive = { ASCII_STARFIVE, 33, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} };
|
||||||
asciiL logo_sipeed = { ASCII_SIPEED, 41, 16, true, {C_BG_RED, C_BG_WHITE}, {C_FG_RED, C_FG_WHITE} };
|
asciiL logo_sipeed = { ASCII_SIPEED, 41, 16, true, {C_BG_RED, C_BG_WHITE}, {C_FG_RED, C_FG_WHITE} };
|
||||||
|
asciiL logo_nvidia = { ASCII_NVIDIA, 45, 19, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||||
|
|
||||||
// Long variants | ----------------------------------------------------------------------------------------------------------------|
|
// Long variants | ----------------------------------------------------------------------------------------------------------------|
|
||||||
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
||||||
@@ -525,6 +578,7 @@ asciiL logo_arm_l = { ASCII_ARM_L, 60, 8, true, {C_BG_CYAN},
|
|||||||
asciiL logo_ibm_l = { ASCII_IBM_L, 62, 13, true, {C_BG_CYAN, C_FG_WHITE}, {C_FG_CYAN, C_FG_WHITE} };
|
asciiL logo_ibm_l = { ASCII_IBM_L, 62, 13, true, {C_BG_CYAN, C_FG_WHITE}, {C_FG_CYAN, C_FG_WHITE} };
|
||||||
asciiL logo_starfive_l = { ASCII_STARFIVE_L, 50, 22, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} };
|
asciiL logo_starfive_l = { ASCII_STARFIVE_L, 50, 22, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} };
|
||||||
asciiL logo_sifive_l = { ASCII_SIFIVE_L, 53, 21, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_CYAN} };
|
asciiL logo_sifive_l = { ASCII_SIFIVE_L, 53, 21, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_CYAN} };
|
||||||
|
asciiL logo_nvidia_l = { ASCII_NVIDIA_L, 50, 15, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||||
asciiL logo_unknown = { NULL, 0, 0, false, {COLOR_NONE}, {COLOR_NONE, COLOR_NONE} };
|
asciiL logo_unknown = { NULL, 0, 0, false, {COLOR_NONE}, {COLOR_NONE, COLOR_NONE} };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ enum {
|
|||||||
// ARCH_X86
|
// ARCH_X86
|
||||||
CPU_VENDOR_INTEL,
|
CPU_VENDOR_INTEL,
|
||||||
CPU_VENDOR_AMD,
|
CPU_VENDOR_AMD,
|
||||||
|
CPU_VENDOR_HYGON,
|
||||||
// ARCH_ARM
|
// ARCH_ARM
|
||||||
CPU_VENDOR_ARM,
|
CPU_VENDOR_ARM,
|
||||||
CPU_VENDOR_APPLE,
|
CPU_VENDOR_APPLE,
|
||||||
|
|||||||
178
src/common/pci.c
Normal file
178
src/common/pci.c
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "udev.h"
|
||||||
|
#include "global.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PCI_PATH "/sys/bus/pci/devices/"
|
||||||
|
#define MAX_LENGTH_PCI_DIR_NAME 1024
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doc: https://wiki.osdev.org/PCI#Class_Codes
|
||||||
|
* https://pci-ids.ucw.cz/read/PC
|
||||||
|
*/
|
||||||
|
#define PCI_VENDOR_ID_AMD 0x1002
|
||||||
|
#define CLASS_VGA_CONTROLLER 0x0300
|
||||||
|
#define CLASS_3D_CONTROLLER 0x0302
|
||||||
|
|
||||||
|
// Return a list of PCI devices containing only
|
||||||
|
// the sysfs path
|
||||||
|
struct pci_devices * get_pci_paths(void) {
|
||||||
|
DIR *dirp;
|
||||||
|
|
||||||
|
if ((dirp = opendir(PCI_PATH)) == NULL) {
|
||||||
|
perror("opendir");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *dp;
|
||||||
|
int numDirs = 0;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
|
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
|
||||||
|
numDirs++;
|
||||||
|
}
|
||||||
|
if (errno != 0) {
|
||||||
|
perror("readdir");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewinddir(dirp);
|
||||||
|
|
||||||
|
struct pci_devices * pci = emalloc(sizeof(struct pci_devices));
|
||||||
|
pci->num_devices = numDirs;
|
||||||
|
pci->devices = emalloc(sizeof(struct pci_device) * pci->num_devices);
|
||||||
|
char * full_path = emalloc(PATH_MAX * sizeof(char));
|
||||||
|
struct stat stbuf;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
|
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strlen(dp->d_name) > MAX_LENGTH_PCI_DIR_NAME) {
|
||||||
|
printErr("Directory name is too long: %s", dp->d_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(full_path, 0, PATH_MAX * sizeof(char));
|
||||||
|
snprintf(full_path, min(strlen(PCI_PATH) + strlen(dp->d_name) + 1, PATH_MAX), "%s%s", PCI_PATH, dp->d_name);
|
||||||
|
|
||||||
|
if (stat(full_path, &stbuf) == -1) {
|
||||||
|
perror("stat");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
|
||||||
|
int strLen = min(MAX_LENGTH_PCI_DIR_NAME, strlen(dp->d_name)) + 1;
|
||||||
|
pci->devices[i] = emalloc(sizeof(struct pci_device));
|
||||||
|
pci->devices[i]->path = ecalloc(sizeof(char), strLen);
|
||||||
|
strncpy(pci->devices[i]->path, dp->d_name, strLen);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno != 0) {
|
||||||
|
perror("readdir");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pci;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each PCI device in the list pci, fetch its vendor and
|
||||||
|
// device id using sysfs (e.g., /sys/bus/pci/devices/XXX/{vendor/device})
|
||||||
|
void populate_pci_devices(struct pci_devices * pci) {
|
||||||
|
int filelen;
|
||||||
|
char* buf;
|
||||||
|
|
||||||
|
for (int i=0; i < pci->num_devices; i++) {
|
||||||
|
struct pci_device* dev = pci->devices[i];
|
||||||
|
int path_size = strlen(PCI_PATH) + strlen(dev->path) + 2;
|
||||||
|
|
||||||
|
// Read vendor_id
|
||||||
|
char *vendor_id_path = emalloc(sizeof(char) * (path_size + strlen("vendor")));
|
||||||
|
sprintf(vendor_id_path, "%s/%s/%s", PCI_PATH, dev->path, "vendor");
|
||||||
|
|
||||||
|
if ((buf = read_file(vendor_id_path, &filelen)) == NULL) {
|
||||||
|
printWarn("read_file: %s: %s\n", vendor_id_path, strerror(errno));
|
||||||
|
dev->vendor_id = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dev->vendor_id = strtol(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read device_id
|
||||||
|
char *device_id_path = emalloc(sizeof(char) * (path_size + strlen("device")));
|
||||||
|
sprintf(device_id_path, "%s/%s/%s", PCI_PATH, dev->path, "device");
|
||||||
|
|
||||||
|
if ((buf = read_file(device_id_path, &filelen)) == NULL) {
|
||||||
|
printWarn("read_file: %s: %s\n", device_id_path, strerror(errno));
|
||||||
|
dev->device_id = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dev->device_id = strtol(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(vendor_id_path);
|
||||||
|
free(device_id_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right now, we are interested in PCI devices which
|
||||||
|
// vendor is NVIDIA (to be extended in the future).
|
||||||
|
// Should we also restrict to VGA controllers only?
|
||||||
|
bool pci_device_is_useful(struct pci_device* dev) {
|
||||||
|
return dev->vendor_id == PCI_VENDOR_NVIDIA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter the input list in order to get only those PCI devices which
|
||||||
|
// we are interested in (decided by pci_device_is_useful)
|
||||||
|
// and return the filtered result.
|
||||||
|
struct pci_devices * filter_pci_devices(struct pci_devices * pci) {
|
||||||
|
int * devices_to_get = emalloc(sizeof(int) * pci->num_devices);
|
||||||
|
int dev_ptr = 0;
|
||||||
|
|
||||||
|
for (int i=0; i < pci->num_devices; i++) {
|
||||||
|
if (pci_device_is_useful(pci->devices[i])) {
|
||||||
|
devices_to_get[dev_ptr] = i;
|
||||||
|
dev_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pci_devices * pci_filtered = emalloc(sizeof(struct pci_devices));
|
||||||
|
pci_filtered->num_devices = dev_ptr;
|
||||||
|
|
||||||
|
if (pci_filtered->num_devices == 0) {
|
||||||
|
pci_filtered->devices = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pci_filtered->devices = emalloc(sizeof(struct pci_device) * pci_filtered->num_devices);
|
||||||
|
|
||||||
|
for (int i=0; i < pci_filtered->num_devices; i++)
|
||||||
|
pci_filtered->devices[i] = pci->devices[devices_to_get[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return pci_filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a list of PCI devices that could be used to infer the SoC.
|
||||||
|
// The criteria to determine which devices are suitable for this task
|
||||||
|
// is decided in filter_pci_devices.
|
||||||
|
struct pci_devices * get_pci_devices(void) {
|
||||||
|
struct pci_devices * pci = get_pci_paths();
|
||||||
|
|
||||||
|
if (pci == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
populate_pci_devices(pci);
|
||||||
|
|
||||||
|
return filter_pci_devices(pci);
|
||||||
|
}
|
||||||
20
src/common/pci.h
Normal file
20
src/common/pci.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef __PCI__
|
||||||
|
#define __PCI__
|
||||||
|
|
||||||
|
#define PCI_VENDOR_NVIDIA 0x10de
|
||||||
|
#define PCI_DEVICE_TEGRA_X1 0x0faf
|
||||||
|
|
||||||
|
struct pci_device {
|
||||||
|
char * path;
|
||||||
|
uint16_t vendor_id;
|
||||||
|
uint16_t device_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pci_devices {
|
||||||
|
struct pci_device ** devices;
|
||||||
|
int num_devices;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pci_devices * get_pci_devices(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -357,6 +357,9 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
|
|||||||
else if(art->vendor == CPU_VENDOR_AMD) {
|
else if(art->vendor == CPU_VENDOR_AMD) {
|
||||||
art->art = choose_ascii_art_aux(&logo_amd_l, &logo_amd, term, lf);
|
art->art = choose_ascii_art_aux(&logo_amd_l, &logo_amd, term, lf);
|
||||||
}
|
}
|
||||||
|
else if(art->vendor == CPU_VENDOR_HYGON) {
|
||||||
|
art->art = &logo_hygon;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
art->art = &logo_unknown;
|
art->art = &logo_unknown;
|
||||||
}
|
}
|
||||||
@@ -383,6 +386,8 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
|
|||||||
art->art = &logo_allwinner;
|
art->art = &logo_allwinner;
|
||||||
else if(art->vendor == SOC_VENDOR_ROCKCHIP)
|
else if(art->vendor == SOC_VENDOR_ROCKCHIP)
|
||||||
art->art = &logo_rockchip;
|
art->art = &logo_rockchip;
|
||||||
|
else if(art->vendor == SOC_VENDOR_NVIDIA)
|
||||||
|
art->art = choose_ascii_art_aux(&logo_nvidia_l, &logo_nvidia, term, lf);
|
||||||
else {
|
else {
|
||||||
art->art = choose_ascii_art_aux(&logo_arm_l, &logo_arm, term, lf);
|
art->art = choose_ascii_art_aux(&logo_arm_l, &logo_arm, term, lf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ static char* soc_trademark_string[] = {
|
|||||||
[SOC_VENDOR_APPLE] = "Apple ",
|
[SOC_VENDOR_APPLE] = "Apple ",
|
||||||
[SOC_VENDOR_ROCKCHIP] = "Rockchip ",
|
[SOC_VENDOR_ROCKCHIP] = "Rockchip ",
|
||||||
[SOC_VENDOR_GOOGLE] = "Google ",
|
[SOC_VENDOR_GOOGLE] = "Google ",
|
||||||
|
[SOC_VENDOR_NVIDIA] = "NVIDIA ",
|
||||||
// RISC-V
|
// RISC-V
|
||||||
[SOC_VENDOR_SIFIVE] = "SiFive ",
|
[SOC_VENDOR_SIFIVE] = "SiFive ",
|
||||||
[SOC_VENDOR_STARFIVE] = "StarFive ",
|
[SOC_VENDOR_STARFIVE] = "StarFive ",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ enum {
|
|||||||
SOC_VENDOR_APPLE,
|
SOC_VENDOR_APPLE,
|
||||||
SOC_VENDOR_ROCKCHIP,
|
SOC_VENDOR_ROCKCHIP,
|
||||||
SOC_VENDOR_GOOGLE,
|
SOC_VENDOR_GOOGLE,
|
||||||
|
SOC_VENDOR_NVIDIA,
|
||||||
// RISC-V
|
// RISC-V
|
||||||
SOC_VENDOR_SIFIVE,
|
SOC_VENDOR_SIFIVE,
|
||||||
SOC_VENDOR_STARFIVE,
|
SOC_VENDOR_STARFIVE,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
|
#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
|
||||||
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
|
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
|
||||||
|
#define CPU_VENDOR_HYGON_STRING "HygonGenuine"
|
||||||
|
|
||||||
static const char *hv_vendors_string[] = {
|
static const char *hv_vendors_string[] = {
|
||||||
[HV_VENDOR_KVM] = "KVMKVMKVM",
|
[HV_VENDOR_KVM] = "KVMKVMKVM",
|
||||||
@@ -470,6 +471,8 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
cpu->cpu_vendor = CPU_VENDOR_INTEL;
|
cpu->cpu_vendor = CPU_VENDOR_INTEL;
|
||||||
else if (strcmp(CPU_VENDOR_AMD_STRING,name) == 0)
|
else if (strcmp(CPU_VENDOR_AMD_STRING,name) == 0)
|
||||||
cpu->cpu_vendor = CPU_VENDOR_AMD;
|
cpu->cpu_vendor = CPU_VENDOR_AMD;
|
||||||
|
else if (strcmp(CPU_VENDOR_HYGON_STRING,name) == 0)
|
||||||
|
cpu->cpu_vendor = CPU_VENDOR_HYGON;
|
||||||
else {
|
else {
|
||||||
cpu->cpu_vendor = CPU_VENDOR_INVALID;
|
cpu->cpu_vendor = CPU_VENDOR_INVALID;
|
||||||
printErr("Unknown CPU vendor: %s", name);
|
printErr("Unknown CPU vendor: %s", name);
|
||||||
@@ -718,6 +721,7 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CPU_VENDOR_AMD:
|
case CPU_VENDOR_AMD:
|
||||||
|
case CPU_VENDOR_HYGON:
|
||||||
if (cpu->maxExtendedLevels >= 0x80000008) {
|
if (cpu->maxExtendedLevels >= 0x80000008) {
|
||||||
eax = 0x80000008;
|
eax = 0x80000008;
|
||||||
cpuid(&eax, &ebx, &ecx, &edx);
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|||||||
@@ -392,6 +392,25 @@ struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uin
|
|||||||
return arch;
|
return arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct uarch* get_uarch_from_cpuid_hygon(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
|
||||||
|
struct uarch* arch = emalloc(sizeof(struct uarch));
|
||||||
|
|
||||||
|
// EF: Extended Family //
|
||||||
|
// F: Family //
|
||||||
|
// EM: Extended Model //
|
||||||
|
// M: Model //
|
||||||
|
// S: Stepping //
|
||||||
|
// ----------------------------------------------------------------------------- //
|
||||||
|
// EF F EM M S //
|
||||||
|
UARCH_START
|
||||||
|
// https://www.phoronix.com/news/Hygon-Dhyana-AMD-China-CPUs
|
||||||
|
CHECK_UARCH(arch, 9, 15, 0, 1, NA, "Zen", UARCH_ZEN, UNK) // https://github.com/Dr-Noob/cpufetch/issues/244
|
||||||
|
// CHECK_UARCH(arch, 9, 15, 0, 2, NA, "???", ?????????, UNK) // http://instlatx64.atw.hu/
|
||||||
|
UARCH_END
|
||||||
|
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
|
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
|
||||||
if(cpu->cpu_vendor == CPU_VENDOR_INTEL) {
|
if(cpu->cpu_vendor == CPU_VENDOR_INTEL) {
|
||||||
struct uarch* arch = emalloc(sizeof(struct uarch));
|
struct uarch* arch = emalloc(sizeof(struct uarch));
|
||||||
@@ -436,8 +455,16 @@ struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t
|
|||||||
}
|
}
|
||||||
return get_uarch_from_cpuid_intel(ef, f, em, m, s);
|
return get_uarch_from_cpuid_intel(ef, f, em, m, s);
|
||||||
}
|
}
|
||||||
else
|
else if(cpu->cpu_vendor == CPU_VENDOR_AMD) {
|
||||||
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
|
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
|
||||||
|
}
|
||||||
|
else if(cpu->cpu_vendor == CPU_VENDOR_HYGON) {
|
||||||
|
return get_uarch_from_cpuid_hygon(ef, f, em, m, s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printBug("Invalid CPU vendor: %d", cpu->cpu_vendor);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cannot get the CPU name from CPUID, try to infer it from uarch
|
// If we cannot get the CPU name from CPUID, try to infer it from uarch
|
||||||
|
|||||||
Reference in New Issue
Block a user