Detecting CPU vendor. Support for printing ascii

This commit is contained in:
Dr-Noob
2018-03-30 11:58:27 +02:00
parent 4e1ee88c4c
commit 3e1f6af8ae
8 changed files with 248 additions and 23 deletions

47
01h.c
View File

@@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include "01h.h" #include "01h.h"
#include "cpuid.h" #include "cpuid.h"
@@ -40,6 +41,7 @@ struct cpuInfo {
int AES; int AES;
int SHA; int SHA;
VENDOR cpu_vendor;
/*** Number of threads ***/ /*** Number of threads ***/
int nThreads; int nThreads;
/*** Threads per core(Intel HyperThreading) ***/ /*** Threads per core(Intel HyperThreading) ***/
@@ -67,16 +69,54 @@ void initializeCpuInfo(struct cpuInfo* cpu) {
cpu->SHA = BOOLEAN_FALSE; cpu->SHA = BOOLEAN_FALSE;
} }
#define MASK 0xFF
VENDOR getCPUVendor(unsigned eax,unsigned ebx,unsigned ecx,unsigned edx) {
char name[13];
name[__COUNTER__] = ebx & MASK;
name[__COUNTER__] = (ebx>>8) & MASK;
name[__COUNTER__] = (ebx>>16) & MASK;
name[__COUNTER__] = (ebx>>24) & MASK;
name[__COUNTER__] = edx & MASK;
name[__COUNTER__] = (edx>>8) & MASK;
name[__COUNTER__] = (edx>>16) & MASK;
name[__COUNTER__] = (edx>>24) & MASK;
name[__COUNTER__] = ecx & MASK;
name[__COUNTER__] = (ecx>>8) & MASK;
name[__COUNTER__] = (ecx>>16) & MASK;
name[__COUNTER__] = (ecx>>24) & MASK;
name[__COUNTER__] = '\0';
if(strcmp(VENDOR_INTEL_STRING,name) == 0)
return VENDOR_INTEL;
else if (strcmp(VENDOR_AMD_STRING,name) == 0)
return VENDOR_AMD;
return VENDOR_INVALID;
}
struct cpuInfo* getCPUInfo() { struct cpuInfo* getCPUInfo() {
struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo));
initializeCpuInfo(cpu); initializeCpuInfo(cpu);
unsigned eax, ebx, ecx, edx; unsigned eax, ebx, ecx, edx;
//Get max cpuid level
eax = 0x0000000; eax = 0x0000000;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
cpu->maxLevels = eax; cpu->maxLevels = eax;
//Fill vendor
cpu->cpu_vendor = getCPUVendor(eax,ebx,ecx,edx);
if(cpu->cpu_vendor == VENDOR_INVALID) {
printf("ERROR: CPU vendor is neither AMD nor INTEL\n");
return NULL;
}
//Get max extended level
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
cpu->maxExtendedLevels = eax; cpu->maxExtendedLevels = eax;
@@ -202,7 +242,10 @@ char* getPeakPerformance(struct cpuInfo* cpu, long freq) {
return string; return string;
} }
//4 cores(8 threads) VENDOR getCPUVendorInternal(struct cpuInfo* cpu) {
return cpu->cpu_vendor;
}
char* getString_NumberCores(struct cpuInfo* cpu) { char* getString_NumberCores(struct cpuInfo* cpu) {
if(cpu->HT > 1) { if(cpu->HT > 1) {
//2(N.Cores)7(' cores(')2(N.Threads)9(' threads)') //2(N.Cores)7(' cores(')2(N.Threads)9(' threads)')
@@ -213,7 +256,7 @@ char* getString_NumberCores(struct cpuInfo* cpu) {
} }
else { else {
char* string = malloc(sizeof(char)*2+1); char* string = malloc(sizeof(char)*2+1);
snprintf(string,2+1,"%d cores",cpu->nThreads); snprintf(string,2+7+1,"%d cores",cpu->nThreads);
return string; return string;
} }

13
01h.h
View File

@@ -3,13 +3,24 @@
#define STRING_YES "Yes" #define STRING_YES "Yes"
#define STRING_NO "No" #define STRING_NO "No"
#define VENDOR_EMPTY 0
#define VENDOR_INTEL 1
#define VENDOR_AMD 2
#define VENDOR_INVALID 3
#define VENDOR_INTEL_STRING "GenuineIntel"
#define VENDOR_AMD_STRING "AuthenticAMD"
typedef int VENDOR;
struct cpuInfo; struct cpuInfo;
struct cpuInfo* getCPUInfo(); struct cpuInfo* getCPUInfo();
void debugCpuInfo(struct cpuInfo* cpu); void debugCpuInfo(struct cpuInfo* cpu);
char* getString_NumberCores(struct cpuInfo* cpu); VENDOR getCPUVendorInternal(struct cpuInfo* cpu);
char* getPeakPerformance(struct cpuInfo* cpu, long freq); char* getPeakPerformance(struct cpuInfo* cpu, long freq);
char* getString_NumberCores(struct cpuInfo* cpu);
char* getString_AVX(struct cpuInfo* cpu); char* getString_AVX(struct cpuInfo* cpu);
char* getString_SSE(struct cpuInfo* cpu); char* getString_SSE(struct cpuInfo* cpu);
char* getString_FMA(struct cpuInfo* cpu); char* getString_FMA(struct cpuInfo* cpu);

View File

@@ -2,8 +2,8 @@ CXX=gcc
CXXFLAGS=-g CXXFLAGS=-g
SOURCE=main.c 01h.c 02h.c extended.c cpuid.c udev.c SOURCE=main.c 01h.c 02h.c extended.c cpuid.c udev.c printer.c
HEADERS=01h.c 02h.h extended.h cpuid.h udev.h printer.h HEADERS=01h.c 02h.h extended.h cpuid.h udev.h printer.h ascii.h
OUTPUT=cpufetch OUTPUT=cpufetch

49
ascii.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef __ASCII__
#define __ASCII__
#define NUMBER_OF_LINES 20
#define LINE_SIZE 63
#define AMD1 " \0"
#define AMD2 " \0"
#define AMD3 " \0"
#define AMD4 " \0"
#define AMD5 " \0"
#define AMD6 " \0"
#define AMD7 " @@@@ @@@% @@@. @@@@@@@@( .############ \0"
#define AMD8 " @@@@@@ @@@@@ %@@@@. @@@ @@@@ .((((((#### \0"
#define AMD9 " @@@ @@@ @@@/@@@@@@&@@. @@@ %@@% # #### \0"
#define AMD10 " @@@, (@@# @@@ @@@/ @@@. @@@ .@@@ ### #### \0"
#define AMD11 " ,@@@@@@@@@@, @@@ @@@. @@@ @@@ #### #### \0"
#define AMD12 " @@@ @@@ @@@ @@@. @@@@@@@@@& #######/ .## \0"
#define AMD13 " \0"
#define AMD14 " \0"
#define AMD15 " \0"
#define AMD16 " \0"
#define AMD17 " \0"
#define AMD18 " \0"
#define AMD19 " \0"
#define AMD20 " \0"
#define INTEL1 " ################ \0"
#define INTEL2 " ####### ####### \0"
#define INTEL3 " #### #### \0"
#define INTEL4 " ### #### \0"
#define INTEL5 " ### ### \0"
#define INTEL6 " ### ### \0"
#define INTEL7 " # ### ### ### \0"
#define INTEL8 " ## ### ######### ###### ###### ### ### \0"
#define INTEL9 " ## ### ### ### ### #### #### ### ### \0"
#define INTEL10 " ## ### ### ### ### ### ### ### ### \0"
#define INTEL11 "## ### ### ### ### ########## ### #### \0"
#define INTEL12 "## ### ### ### ### ### ### ##### \0"
#define INTEL13 "## ## ### ### ##### ######### ## ### \0"
#define INTEL14 "### \0"
#define INTEL15 "(### \0"
#define INTEL16 " #### #### \0"
#define INTEL17 " ##### ########## \0"
#define INTEL18 " ########## ################ \0"
#define INTEL19 " ############################### \0"
#define INTEL20 " \0"
#endif

View File

@@ -1,17 +1,22 @@
#include <stdio.h>
#include <string.h>
#include "extended.h" #include "extended.h"
char* getString_CPUName() { char* getString_CPUName() {
unsigned eax, ebx, ecx, edx; unsigned eax, ebx, ecx, edx;
char* name = malloc(sizeof(char)*64);
memset(name,0,64);
//First, check we can use extended //First, check we can use extended
eax = 0x80000000; eax = 0x80000000;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
if(eax < 0x80000001) if(eax < 0x80000001) {
return NULL; sprintf(name,"Unknown");
return name;
}
//We can, fetch name //We can, fetch name
char* name = malloc(sizeof(char)*64);
eax = 0x80000002; eax = 0x80000002;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);

50
main.c
View File

@@ -26,8 +26,12 @@ Peak FLOPS: 512 GFLOP/s(in simple precision)
int main() { int main() {
struct cpuInfo* cpu = getCPUInfo(cpu); struct cpuInfo* cpu = getCPUInfo(cpu);
if(cpu == NULL)
return EXIT_FAILURE;
struct cache* cach = new_cache(cach); struct cache* cach = new_cache(cach);
struct frequency* freq = new_frequency(freq); struct frequency* freq = new_frequency(freq);
struct ascii* ascii = set_ascii(getCPUVendorInternal(cpu));
char* cpuName = getString_CPUName(); char* cpuName = getString_CPUName();
char* maxFrequency = getString_MaxFrequency(freq); char* maxFrequency = getString_MaxFrequency(freq);
@@ -41,20 +45,66 @@ int main() {
char* l2 = getString_L2(cach); char* l2 = getString_L2(cach);
char* l3 = getString_L3(cach); char* l3 = getString_L3(cach);
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf(TITLE_NAME"%s\n",cpuName); printf(TITLE_NAME"%s\n",cpuName);
print_ascii(ascii,__COUNTER__);
printf(TITLE_ARCH"%s\n","x86_64"); printf(TITLE_ARCH"%s\n","x86_64");
print_ascii(ascii,__COUNTER__);
printf(TITLE_FREQUENCY"%s\n",maxFrequency); printf(TITLE_FREQUENCY"%s\n",maxFrequency);
print_ascii(ascii,__COUNTER__);
printf(TITLE_NCORES"%s\n",nCores); printf(TITLE_NCORES"%s\n",nCores);
print_ascii(ascii,__COUNTER__);
printf(TITLE_AVX"%s\n",avx); printf(TITLE_AVX"%s\n",avx);
print_ascii(ascii,__COUNTER__);
printf(TITLE_SSE"%s\n",sse); printf(TITLE_SSE"%s\n",sse);
print_ascii(ascii,__COUNTER__);
printf(TITLE_FMA"%s\n",fma); printf(TITLE_FMA"%s\n",fma);
print_ascii(ascii,__COUNTER__);
printf(TITLE_AES"%s\n",aes); printf(TITLE_AES"%s\n",aes);
print_ascii(ascii,__COUNTER__);
printf(TITLE_SHA"%s\n",sha); printf(TITLE_SHA"%s\n",sha);
print_ascii(ascii,__COUNTER__);
printf(TITLE_L1"%s\n",l1); printf(TITLE_L1"%s\n",l1);
print_ascii(ascii,__COUNTER__);
printf(TITLE_L2"%s\n",l2); printf(TITLE_L2"%s\n",l2);
print_ascii(ascii,__COUNTER__);
printf(TITLE_L3"%s\n",l3); printf(TITLE_L3"%s\n",l3);
print_ascii(ascii,__COUNTER__);
printf(TITLE_PEAK"%s\n",getPeakPerformance(cpu,getFrequency(freq))); printf(TITLE_PEAK"%s\n",getPeakPerformance(cpu,getFrequency(freq)));
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf("\n");
print_ascii(ascii,__COUNTER__);
printf("\n");
free(cpuName); free(cpuName);
free(maxFrequency); free(maxFrequency);
free(nCores); free(nCores);

63
printer.c Normal file
View File

@@ -0,0 +1,63 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "printer.h"
#include "ascii.h"
struct ascii {
char art[NUMBER_OF_LINES][LINE_SIZE];
};
struct ascii* set_ascii(VENDOR cpuVendor) {
struct ascii* art = malloc(sizeof(struct ascii));
if(cpuVendor == VENDOR_INTEL) {
strcpy(art->art[0],INTEL1);
strcpy(art->art[1],INTEL2);
strcpy(art->art[2],INTEL3);
strcpy(art->art[3],INTEL4);
strcpy(art->art[4],INTEL5);
strcpy(art->art[5],INTEL6);
strcpy(art->art[6],INTEL7);
strcpy(art->art[7],INTEL8);
strcpy(art->art[8],INTEL9);
strcpy(art->art[9],INTEL10);
strcpy(art->art[10],INTEL11);
strcpy(art->art[11],INTEL12);
strcpy(art->art[12],INTEL13);
strcpy(art->art[13],INTEL14);
strcpy(art->art[14],INTEL15);
strcpy(art->art[15],INTEL16);
strcpy(art->art[16],INTEL17);
strcpy(art->art[17],INTEL18);
strcpy(art->art[18],INTEL19);
strcpy(art->art[19],INTEL20);
}
else {
strcpy(art->art[0],AMD1);
strcpy(art->art[1],AMD2);
strcpy(art->art[2],AMD3);
strcpy(art->art[3],AMD4);
strcpy(art->art[4],AMD5);
strcpy(art->art[5],AMD6);
strcpy(art->art[6],AMD7);
strcpy(art->art[7],AMD8);
strcpy(art->art[8],AMD9);
strcpy(art->art[9],AMD10);
strcpy(art->art[10],AMD11);
strcpy(art->art[11],AMD12);
strcpy(art->art[12],AMD13);
strcpy(art->art[13],AMD14);
strcpy(art->art[14],AMD15);
strcpy(art->art[15],AMD16);
strcpy(art->art[16],AMD17);
strcpy(art->art[17],AMD18);
strcpy(art->art[18],AMD19);
strcpy(art->art[19],AMD20);
}
return art;
}
void print_ascii(struct ascii* art, int n) {
printf("%s",art->art[n]);
}

View File

@@ -1,9 +1,13 @@
#ifndef __PRINTER__ #ifndef __PRINTER__
#define __PRINTER__ #define __PRINTER__
//#include "ascii.h" #include "01h.h"
#include "ascii.h"
//void print_ascii(int n); struct ascii;
struct ascii* set_ascii(VENDOR cpuVendor);
void print_ascii(struct ascii* art, int n);
#define TITLE_NAME "Name: " #define TITLE_NAME "Name: "
#define TITLE_ARCH "Arch: " #define TITLE_ARCH "Arch: "