123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /**
- * Unit to read cpu informations
- *
- * tpruvot 2014
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- #include "miner.h"
- #ifndef WIN32
- #define HWMON_PATH \
- "/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input"
- #define HWMON_ALT \
- "/sys/class/hwmon/hwmon1/temp1_input"
- #define HWMON_ALT2 \
- "/sys/class/hwmon/hwmon0/temp1_input"
- #define HWMON_ALT3 \
- "/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input"
- #define HWMON_ALT4 \
- "/sys/class/hwmon/hwmon0/temp2_input"
- #define HWMON_ALT5 \
- "/sys/class/hwmon/hwmon0/device/temp1_input"
- #define HWMON_ALT6 \
- "/sys/class/thermal/thermal_zone0/temp"
- static float linux_cputemp(int core)
- {
- float tc = 0.0;
- FILE *fd = fopen(HWMON_PATH, "r");
- uint32_t val = 0;
- if (!fd)
- fd = fopen(HWMON_ALT, "r");
- if (!fd)
- fd = fopen(HWMON_ALT2, "r");
- if (!fd)
- fd = fopen(HWMON_ALT3, "r");
- if (!fd)
- fd = fopen(HWMON_ALT4, "r");
- if (!fd)
- fd = fopen(HWMON_ALT5, "r");
- if (!fd)
- fd = fopen(HWMON_ALT6, "r");
- if (!fd)
- return tc;
- if (fscanf(fd, "%d", &val))
- tc = val / 1000.0;
- fclose(fd);
- return tc;
- }
- #define CPUFREQ_PATH \
- "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq"
- static uint32_t linux_cpufreq(int core)
- {
- FILE *fd = fopen(CPUFREQ_PATH, "r");
- uint32_t freq = 0;
- if (!fd)
- return freq;
- if (!fscanf(fd, "%d", &freq))
- return freq;
- fclose(fd);
- return freq;
- }
- #else /* WIN32 */
- static float win32_cputemp(int core)
- {
- // todo
- return 0.0;
- }
- #endif /* !WIN32 */
- /* exports */
- float cpu_temp(int core)
- {
- #ifdef WIN32
- return win32_cputemp(core);
- #else
- return linux_cputemp(core);
- #endif
- }
- uint32_t cpu_clock(int core)
- {
- #ifdef WIN32
- return 0;
- #else
- return linux_cpufreq(core);
- #endif
- }
- int cpu_fanpercent()
- {
- return 0;
- }
- #if !defined(__arm__) && !defined(__aarch64__)
- static inline void cpuid(int functionnumber, int output[4]) {
- #ifdef _MSC_VER
- // Microsoft compiler, intrin.h included
- __cpuidex(output, functionnumber, 0);
- #elif defined(__INTEL_COMPILER)
- __cpuid(output, functionnumber);
- #elif defined(__GNUC__) || defined(__clang__)
- // use inline assembly, Gnu/AT&T syntax
- int a, b, c, d;
- asm volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(functionnumber), "c"(0));
- output[0] = a;
- output[1] = b;
- output[2] = c;
- output[3] = d;
- #else
- // unknown platform. try inline assembly with masm/intel syntax
- __asm {
- mov eax, functionnumber
- xor ecx, ecx
- cpuid;
- mov esi, output
- mov[esi], eax
- mov[esi + 4], ebx
- mov[esi + 8], ecx
- mov[esi + 12], edx
- }
- #endif
- }
- #else /* !__arm__ */
- #define cpuid(fn, out) out[0] = 0;
- #endif
- // For the i7-5775C will output : Intel(R) Core(TM) i7-5775C CPU @ 3.30GHz
- void cpu_getname(char *outbuf, size_t maxsz)
- {
- memset(outbuf, 0, maxsz);
- #ifdef WIN32
- char brand[0xC0] = { 0 };
- int output[4] = { 0 }, ext;
- cpuid(0x80000000, output);
- ext = output[0];
- if (ext >= 0x80000004) {
- for (int i = 2; i <= (ext & 0xF); i++) {
- cpuid(0x80000000+i, output);
- memcpy(&brand[(i-2) * 4*sizeof(int)], output, 4*sizeof(int));
- }
- snprintf(outbuf, maxsz, "%s", brand);
- } else {
- // Fallback, for the i7-5775C will output
- // Intel64 Family 6 Model 71 Stepping 1, GenuineIntel
- snprintf(outbuf, maxsz, "%s", getenv("PROCESSOR_IDENTIFIER"));
- }
- #else
- // Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz
- FILE *fd = fopen("/proc/cpuinfo", "rb");
- char *buf = NULL, *p, *eol;
- size_t size = 0;
- if (!fd) return;
- while(getdelim(&buf, &size, 0, fd) != -1) {
- if (buf && (p = strstr(buf, "model name\t")) && strstr(p, ":")) {
- p = strstr(p, ":");
- if (p) {
- p += 2;
- eol = strstr(p, "\n"); if (eol) *eol = '\0';
- snprintf(outbuf, maxsz, "%s", p);
- }
- break;
- }
- }
- free(buf);
- fclose(fd);
- #endif
- }
- void cpu_getmodelid(char *outbuf, size_t maxsz)
- {
- memset(outbuf, 0, maxsz);
- #ifdef WIN32
- // For the i7-5775C will output 6:4701:8
- snprintf(outbuf, maxsz, "%s:%s:%s", getenv("PROCESSOR_LEVEL"), // hexa ?
- getenv("PROCESSOR_REVISION"), getenv("NUMBER_OF_PROCESSORS"));
- #else
- FILE *fd = fopen("/proc/cpuinfo", "rb");
- char *buf = NULL, *p, *eol;
- int cpufam = 0, model = 0, stepping = 0;
- size_t size = 0;
- if (!fd) return;
- while(getdelim(&buf, &size, 0, fd) != -1) {
- if (buf && (p = strstr(buf, "cpu family\t")) && strstr(p, ":")) {
- p = strstr(p, ":");
- if (p) {
- p += 2;
- cpufam = atoi(p);
- }
- }
- if (buf && (p = strstr(buf, "model\t")) && strstr(p, ":")) {
- p = strstr(p, ":");
- if (p) {
- p += 2;
- model = atoi(p);
- }
- }
- if (buf && (p = strstr(buf, "stepping\t")) && strstr(p, ":")) {
- p = strstr(p, ":");
- if (p) {
- p += 2;
- stepping = atoi(p);
- }
- }
- if (cpufam && model && stepping) {
- snprintf(outbuf, maxsz, "%x:%02x%02x:%d", cpufam, model, stepping, num_cpus);
- outbuf[maxsz-1] = '\0';
- break;
- }
- }
- free(buf);
- fclose(fd);
- #endif
- }
- // http://en.wikipedia.org/wiki/CPUID
- #define OSXSAVE_Flag (1 << 27)
- #define AVX1_Flag ((1 << 28)|OSXSAVE_Flag)
- #define XOP_Flag (1 << 11)
- #define FMA3_Flag ((1 << 12)|AVX1_Flag|OSXSAVE_Flag)
- #define AES_Flag (1 << 25)
- #define SSE42_Flag (1 << 20)
- #define SSE_Flag (1 << 25) // EDX
- #define SSE2_Flag (1 << 26) // EDX
- #define AVX2_Flag (1 << 5) // ADV EBX
- bool has_aes_ni()
- {
- #if defined(__arm__) || defined(__aarch64__)
- return false;
- #else
- int cpu_info[4] = { 0 };
- cpuid(1, cpu_info);
- return cpu_info[2] & AES_Flag;
- #endif
- }
- void cpu_bestfeature(char *outbuf, size_t maxsz)
- {
- #if defined(__arm__) || defined(__aarch64__)
- sprintf(outbuf, "ARM");
- #else
- int cpu_info[4] = { 0 };
- int cpu_info_adv[4] = { 0 };
- cpuid(1, cpu_info);
- cpuid(7, cpu_info_adv);
- if ((cpu_info[2] & AVX1_Flag) && (cpu_info_adv[1] & AVX2_Flag))
- sprintf(outbuf, "AVX2");
- else if (cpu_info[2] & AVX1_Flag)
- sprintf(outbuf, "AVX");
- else if (cpu_info[2] & FMA3_Flag)
- sprintf(outbuf, "FMA3");
- else if (cpu_info[2] & XOP_Flag)
- sprintf(outbuf, "XOP");
- else if (cpu_info[2] & SSE42_Flag)
- sprintf(outbuf, "SSE42");
- else if (cpu_info[3] & SSE2_Flag)
- sprintf(outbuf, "SSE2");
- else if (cpu_info[3] & SSE_Flag)
- sprintf(outbuf, "SSE");
- else
- *outbuf = '\0';
- #endif
- }
|